tpm: pass an array of tpm_extend_digest structures to tpm_pcr_extend()
[sfrench/cifs-2.6.git] / security / keys / trusted.c
index 5b852263eae1e6b91ccc8e170c5c978ffea0873e..bcc9c6ead7fd30962cf2ac3755e61d011d62c3da 100644 (file)
@@ -35,6 +35,7 @@
 static const char hmac_alg[] = "hmac(sha1)";
 static const char hash_alg[] = "sha1";
 static struct tpm_chip *chip;
+static struct tpm_digest *digests;
 
 struct sdesc {
        struct shash_desc shash;
@@ -380,15 +381,10 @@ EXPORT_SYMBOL_GPL(trusted_tpm_send);
  */
 static int pcrlock(const int pcrnum)
 {
-       unsigned char hash[SHA1_DIGEST_SIZE];
-       int ret;
-
        if (!capable(CAP_SYS_ADMIN))
                return -EPERM;
-       ret = tpm_get_random(chip, hash, SHA1_DIGEST_SIZE);
-       if (ret != SHA1_DIGEST_SIZE)
-               return ret;
-       return tpm_pcr_extend(chip, pcrnum, hash) ? -EINVAL : 0;
+
+       return tpm_pcr_extend(chip, pcrnum, digests) ? -EINVAL : 0;
 }
 
 /*
@@ -1222,6 +1218,29 @@ hashalg_fail:
        return ret;
 }
 
+static int __init init_digests(void)
+{
+       u8 digest[TPM_MAX_DIGEST_SIZE];
+       int ret;
+       int i;
+
+       ret = tpm_get_random(chip, digest, TPM_MAX_DIGEST_SIZE);
+       if (ret < 0)
+               return ret;
+       if (ret < TPM_MAX_DIGEST_SIZE)
+               return -EFAULT;
+
+       digests = kcalloc(chip->nr_allocated_banks, sizeof(*digests),
+                         GFP_KERNEL);
+       if (!digests)
+               return -ENOMEM;
+
+       for (i = 0; i < chip->nr_allocated_banks; i++)
+               memcpy(digests[i].digest, digest, TPM_MAX_DIGEST_SIZE);
+
+       return 0;
+}
+
 static int __init init_trusted(void)
 {
        int ret;
@@ -1229,15 +1248,20 @@ static int __init init_trusted(void)
        chip = tpm_default_chip();
        if (!chip)
                return -ENOENT;
-       ret = trusted_shash_alloc();
+       ret = init_digests();
        if (ret < 0)
                goto err_put;
+       ret = trusted_shash_alloc();
+       if (ret < 0)
+               goto err_free;
        ret = register_key_type(&key_type_trusted);
        if (ret < 0)
                goto err_release;
        return 0;
 err_release:
        trusted_shash_release();
+err_free:
+       kfree(digests);
 err_put:
        put_device(&chip->dev);
        return ret;
@@ -1246,6 +1270,7 @@ err_put:
 static void __exit cleanup_trusted(void)
 {
        put_device(&chip->dev);
+       kfree(digests);
        trusted_shash_release();
        unregister_key_type(&key_type_trusted);
 }