diff options
Diffstat (limited to 'security/keys/trusted.c')
-rw-r--r-- | security/keys/trusted.c | 41 |
1 files changed, 33 insertions, 8 deletions
diff --git a/security/keys/trusted.c b/security/keys/trusted.c index 5b852263eae1..bcc9c6ead7fd 100644 --- a/security/keys/trusted.c +++ b/security/keys/trusted.c @@ -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); } |