keys, trusted: seal/unseal with TPM 2.0 chips
authorJarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
Fri, 26 Jun 2015 19:28:26 +0000 (22:28 +0300)
committerPeter Huewe <peterhuewe@gmx.de>
Sun, 18 Oct 2015 23:01:22 +0000 (01:01 +0200)
Call tpm_seal_trusted() and tpm_unseal_trusted() for TPM 2.0 chips.
We require explicit 'keyhandle=' option because there's no a fixed
storage root key inside TPM2 chips.

Signed-off-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
Reviewed-by: Andreas Fuchs <andreas.fuchs@sit.fraunhofer.de>
Tested-by: Mimi Zohar <zohar@linux.vnet.ibm.com> (on TPM 1.2)
Tested-by: Chris J Arges <chris.j.arges@canonical.com>
Tested-by: Colin Ian King <colin.king@canonical.com>
Tested-by: Kevin Strasser <kevin.strasser@intel.com>
Signed-off-by: Peter Huewe <peterhuewe@gmx.de>
security/keys/trusted.c

index c0594cb..d3633cf 100644 (file)
@@ -862,12 +862,19 @@ static int datablob_parse(char *datablob, struct trusted_key_payload *p,
 static struct trusted_key_options *trusted_options_alloc(void)
 {
        struct trusted_key_options *options;
+       int tpm2;
+
+       tpm2 = tpm_is_tpm2(TPM_ANY_NUM);
+       if (tpm2 < 0)
+               return NULL;
 
        options = kzalloc(sizeof *options, GFP_KERNEL);
        if (options) {
                /* set any non-zero defaults */
                options->keytype = SRK_keytype;
-               options->keyhandle = SRKHANDLE;
+
+               if (!tpm2)
+                       options->keyhandle = SRKHANDLE;
        }
        return options;
 }
@@ -905,6 +912,11 @@ static int trusted_instantiate(struct key *key,
        int ret = 0;
        int key_cmd;
        size_t key_len;
+       int tpm2;
+
+       tpm2 = tpm_is_tpm2(TPM_ANY_NUM);
+       if (tpm2 < 0)
+               return tpm2;
 
        if (datalen <= 0 || datalen > 32767 || !prep->data)
                return -EINVAL;
@@ -932,12 +944,20 @@ static int trusted_instantiate(struct key *key,
                goto out;
        }
 
+       if (!options->keyhandle) {
+               ret = -EINVAL;
+               goto out;
+       }
+
        dump_payload(payload);
        dump_options(options);
 
        switch (key_cmd) {
        case Opt_load:
-               ret = key_unseal(payload, options);
+               if (tpm2)
+                       ret = tpm_unseal_trusted(TPM_ANY_NUM, payload, options);
+               else
+                       ret = key_unseal(payload, options);
                dump_payload(payload);
                dump_options(options);
                if (ret < 0)
@@ -950,7 +970,10 @@ static int trusted_instantiate(struct key *key,
                        pr_info("trusted_key: key_create failed (%d)\n", ret);
                        goto out;
                }
-               ret = key_seal(payload, options);
+               if (tpm2)
+                       ret = tpm_seal_trusted(TPM_ANY_NUM, payload, options);
+               else
+                       ret = key_seal(payload, options);
                if (ret < 0)
                        pr_info("trusted_key: key_seal failed (%d)\n", ret);
                break;
@@ -1018,6 +1041,13 @@ static int trusted_update(struct key *key, struct key_preparsed_payload *prep)
                kfree(new_p);
                goto out;
        }
+
+       if (!new_o->keyhandle) {
+               ret = -EINVAL;
+               kfree(new_p);
+               goto out;
+       }
+
        /* copy old key values, and reseal with new pcrs */
        new_p->migratable = p->migratable;
        new_p->key_len = p->key_len;