mirror of https://github.com/torvalds/linux.git
KEYS: trusted_tpm1: Use SHA-1 library instead of crypto_shash
Use the SHA-1 and HMAC-SHA1 library functions instead of crypto_shash. This is simpler and faster. Replace the selection of CRYPTO, CRYPTO_HMAC, and CRYPTO_SHA1 with CRYPTO_LIB_SHA1 and CRYPTO_LIB_UTILS. The latter is needed for crypto_memneq() which was previously being pulled in via CRYPTO. Signed-off-by: Eric Biggers <ebiggers@kernel.org> Reviewed-by: Jarkko Sakkinen <jarkko@kernel.org> Signed-off-by: Jarkko Sakkinen <jarkko@kernel.org>
This commit is contained in:
parent
eed0e3d305
commit
366284cfbc
|
|
@ -5,10 +5,9 @@ config TRUSTED_KEYS_TPM
|
||||||
bool "TPM-based trusted keys"
|
bool "TPM-based trusted keys"
|
||||||
depends on TCG_TPM >= TRUSTED_KEYS
|
depends on TCG_TPM >= TRUSTED_KEYS
|
||||||
default y
|
default y
|
||||||
select CRYPTO
|
|
||||||
select CRYPTO_HMAC
|
|
||||||
select CRYPTO_SHA1
|
|
||||||
select CRYPTO_HASH_INFO
|
select CRYPTO_HASH_INFO
|
||||||
|
select CRYPTO_LIB_SHA1
|
||||||
|
select CRYPTO_LIB_UTILS
|
||||||
select ASN1_ENCODER
|
select ASN1_ENCODER
|
||||||
select OID_REGISTRY
|
select OID_REGISTRY
|
||||||
select ASN1
|
select ASN1
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <crypto/hash_info.h>
|
#include <crypto/hash_info.h>
|
||||||
|
#include <crypto/sha1.h>
|
||||||
#include <crypto/utils.h>
|
#include <crypto/utils.h>
|
||||||
#include <linux/init.h>
|
#include <linux/init.h>
|
||||||
#include <linux/slab.h>
|
#include <linux/slab.h>
|
||||||
|
|
@ -15,78 +16,24 @@
|
||||||
#include <linux/err.h>
|
#include <linux/err.h>
|
||||||
#include <keys/trusted-type.h>
|
#include <keys/trusted-type.h>
|
||||||
#include <linux/key-type.h>
|
#include <linux/key-type.h>
|
||||||
#include <linux/crypto.h>
|
|
||||||
#include <crypto/hash.h>
|
|
||||||
#include <crypto/sha1.h>
|
|
||||||
#include <linux/tpm.h>
|
#include <linux/tpm.h>
|
||||||
#include <linux/tpm_command.h>
|
#include <linux/tpm_command.h>
|
||||||
|
|
||||||
#include <keys/trusted_tpm.h>
|
#include <keys/trusted_tpm.h>
|
||||||
|
|
||||||
static const char hmac_alg[] = "hmac(sha1)";
|
|
||||||
static const char hash_alg[] = "sha1";
|
|
||||||
static struct tpm_chip *chip;
|
static struct tpm_chip *chip;
|
||||||
static struct tpm_digest *digests;
|
static struct tpm_digest *digests;
|
||||||
|
|
||||||
struct sdesc {
|
|
||||||
struct shash_desc shash;
|
|
||||||
char ctx[];
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct crypto_shash *hashalg;
|
|
||||||
static struct crypto_shash *hmacalg;
|
|
||||||
|
|
||||||
static struct sdesc *init_sdesc(struct crypto_shash *alg)
|
|
||||||
{
|
|
||||||
struct sdesc *sdesc;
|
|
||||||
int size;
|
|
||||||
|
|
||||||
size = sizeof(struct shash_desc) + crypto_shash_descsize(alg);
|
|
||||||
sdesc = kmalloc(size, GFP_KERNEL);
|
|
||||||
if (!sdesc)
|
|
||||||
return ERR_PTR(-ENOMEM);
|
|
||||||
sdesc->shash.tfm = alg;
|
|
||||||
return sdesc;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int TSS_sha1(const unsigned char *data, unsigned int datalen,
|
|
||||||
unsigned char *digest)
|
|
||||||
{
|
|
||||||
struct sdesc *sdesc;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
sdesc = init_sdesc(hashalg);
|
|
||||||
if (IS_ERR(sdesc)) {
|
|
||||||
pr_info("can't alloc %s\n", hash_alg);
|
|
||||||
return PTR_ERR(sdesc);
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = crypto_shash_digest(&sdesc->shash, data, datalen, digest);
|
|
||||||
kfree_sensitive(sdesc);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int TSS_rawhmac(unsigned char *digest, const unsigned char *key,
|
static int TSS_rawhmac(unsigned char *digest, const unsigned char *key,
|
||||||
unsigned int keylen, ...)
|
unsigned int keylen, ...)
|
||||||
{
|
{
|
||||||
struct sdesc *sdesc;
|
struct hmac_sha1_ctx hmac_ctx;
|
||||||
va_list argp;
|
va_list argp;
|
||||||
unsigned int dlen;
|
unsigned int dlen;
|
||||||
unsigned char *data;
|
unsigned char *data;
|
||||||
int ret;
|
int ret = 0;
|
||||||
|
|
||||||
sdesc = init_sdesc(hmacalg);
|
hmac_sha1_init_usingrawkey(&hmac_ctx, key, keylen);
|
||||||
if (IS_ERR(sdesc)) {
|
|
||||||
pr_info("can't alloc %s\n", hmac_alg);
|
|
||||||
return PTR_ERR(sdesc);
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = crypto_shash_setkey(hmacalg, key, keylen);
|
|
||||||
if (ret < 0)
|
|
||||||
goto out;
|
|
||||||
ret = crypto_shash_init(&sdesc->shash);
|
|
||||||
if (ret < 0)
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
va_start(argp, keylen);
|
va_start(argp, keylen);
|
||||||
for (;;) {
|
for (;;) {
|
||||||
|
|
@ -98,15 +45,11 @@ static int TSS_rawhmac(unsigned char *digest, const unsigned char *key,
|
||||||
ret = -EINVAL;
|
ret = -EINVAL;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
ret = crypto_shash_update(&sdesc->shash, data, dlen);
|
hmac_sha1_update(&hmac_ctx, data, dlen);
|
||||||
if (ret < 0)
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
va_end(argp);
|
va_end(argp);
|
||||||
if (!ret)
|
if (!ret)
|
||||||
ret = crypto_shash_final(&sdesc->shash, digest);
|
hmac_sha1_final(&hmac_ctx, digest);
|
||||||
out:
|
|
||||||
kfree_sensitive(sdesc);
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -118,26 +61,18 @@ int TSS_authhmac(unsigned char *digest, const unsigned char *key,
|
||||||
unsigned char *h2, unsigned int h3, ...)
|
unsigned char *h2, unsigned int h3, ...)
|
||||||
{
|
{
|
||||||
unsigned char paramdigest[SHA1_DIGEST_SIZE];
|
unsigned char paramdigest[SHA1_DIGEST_SIZE];
|
||||||
struct sdesc *sdesc;
|
struct sha1_ctx sha_ctx;
|
||||||
unsigned int dlen;
|
unsigned int dlen;
|
||||||
unsigned char *data;
|
unsigned char *data;
|
||||||
unsigned char c;
|
unsigned char c;
|
||||||
int ret;
|
int ret = 0;
|
||||||
va_list argp;
|
va_list argp;
|
||||||
|
|
||||||
if (!chip)
|
if (!chip)
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
|
|
||||||
sdesc = init_sdesc(hashalg);
|
|
||||||
if (IS_ERR(sdesc)) {
|
|
||||||
pr_info("can't alloc %s\n", hash_alg);
|
|
||||||
return PTR_ERR(sdesc);
|
|
||||||
}
|
|
||||||
|
|
||||||
c = !!h3;
|
c = !!h3;
|
||||||
ret = crypto_shash_init(&sdesc->shash);
|
sha1_init(&sha_ctx);
|
||||||
if (ret < 0)
|
|
||||||
goto out;
|
|
||||||
va_start(argp, h3);
|
va_start(argp, h3);
|
||||||
for (;;) {
|
for (;;) {
|
||||||
dlen = va_arg(argp, unsigned int);
|
dlen = va_arg(argp, unsigned int);
|
||||||
|
|
@ -148,19 +83,15 @@ int TSS_authhmac(unsigned char *digest, const unsigned char *key,
|
||||||
ret = -EINVAL;
|
ret = -EINVAL;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
ret = crypto_shash_update(&sdesc->shash, data, dlen);
|
sha1_update(&sha_ctx, data, dlen);
|
||||||
if (ret < 0)
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
va_end(argp);
|
va_end(argp);
|
||||||
if (!ret)
|
if (!ret)
|
||||||
ret = crypto_shash_final(&sdesc->shash, paramdigest);
|
sha1_final(&sha_ctx, paramdigest);
|
||||||
if (!ret)
|
if (!ret)
|
||||||
ret = TSS_rawhmac(digest, key, keylen, SHA1_DIGEST_SIZE,
|
ret = TSS_rawhmac(digest, key, keylen, SHA1_DIGEST_SIZE,
|
||||||
paramdigest, TPM_NONCE_SIZE, h1,
|
paramdigest, TPM_NONCE_SIZE, h1,
|
||||||
TPM_NONCE_SIZE, h2, 1, &c, 0, 0);
|
TPM_NONCE_SIZE, h2, 1, &c, 0, 0);
|
||||||
out:
|
|
||||||
kfree_sensitive(sdesc);
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(TSS_authhmac);
|
EXPORT_SYMBOL_GPL(TSS_authhmac);
|
||||||
|
|
@ -183,7 +114,7 @@ int TSS_checkhmac1(unsigned char *buffer,
|
||||||
unsigned char *authdata;
|
unsigned char *authdata;
|
||||||
unsigned char testhmac[SHA1_DIGEST_SIZE];
|
unsigned char testhmac[SHA1_DIGEST_SIZE];
|
||||||
unsigned char paramdigest[SHA1_DIGEST_SIZE];
|
unsigned char paramdigest[SHA1_DIGEST_SIZE];
|
||||||
struct sdesc *sdesc;
|
struct sha1_ctx sha_ctx;
|
||||||
unsigned int dlen;
|
unsigned int dlen;
|
||||||
unsigned int dpos;
|
unsigned int dpos;
|
||||||
va_list argp;
|
va_list argp;
|
||||||
|
|
@ -204,49 +135,29 @@ int TSS_checkhmac1(unsigned char *buffer,
|
||||||
continueflag = authdata - 1;
|
continueflag = authdata - 1;
|
||||||
enonce = continueflag - TPM_NONCE_SIZE;
|
enonce = continueflag - TPM_NONCE_SIZE;
|
||||||
|
|
||||||
sdesc = init_sdesc(hashalg);
|
sha1_init(&sha_ctx);
|
||||||
if (IS_ERR(sdesc)) {
|
sha1_update(&sha_ctx, (const u8 *)&result, sizeof(result));
|
||||||
pr_info("can't alloc %s\n", hash_alg);
|
sha1_update(&sha_ctx, (const u8 *)&ordinal, sizeof(ordinal));
|
||||||
return PTR_ERR(sdesc);
|
|
||||||
}
|
|
||||||
ret = crypto_shash_init(&sdesc->shash);
|
|
||||||
if (ret < 0)
|
|
||||||
goto out;
|
|
||||||
ret = crypto_shash_update(&sdesc->shash, (const u8 *)&result,
|
|
||||||
sizeof result);
|
|
||||||
if (ret < 0)
|
|
||||||
goto out;
|
|
||||||
ret = crypto_shash_update(&sdesc->shash, (const u8 *)&ordinal,
|
|
||||||
sizeof ordinal);
|
|
||||||
if (ret < 0)
|
|
||||||
goto out;
|
|
||||||
va_start(argp, keylen);
|
va_start(argp, keylen);
|
||||||
for (;;) {
|
for (;;) {
|
||||||
dlen = va_arg(argp, unsigned int);
|
dlen = va_arg(argp, unsigned int);
|
||||||
if (dlen == 0)
|
if (dlen == 0)
|
||||||
break;
|
break;
|
||||||
dpos = va_arg(argp, unsigned int);
|
dpos = va_arg(argp, unsigned int);
|
||||||
ret = crypto_shash_update(&sdesc->shash, buffer + dpos, dlen);
|
sha1_update(&sha_ctx, buffer + dpos, dlen);
|
||||||
if (ret < 0)
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
va_end(argp);
|
va_end(argp);
|
||||||
if (!ret)
|
sha1_final(&sha_ctx, paramdigest);
|
||||||
ret = crypto_shash_final(&sdesc->shash, paramdigest);
|
|
||||||
if (ret < 0)
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
ret = TSS_rawhmac(testhmac, key, keylen, SHA1_DIGEST_SIZE, paramdigest,
|
ret = TSS_rawhmac(testhmac, key, keylen, SHA1_DIGEST_SIZE, paramdigest,
|
||||||
TPM_NONCE_SIZE, enonce, TPM_NONCE_SIZE, ononce,
|
TPM_NONCE_SIZE, enonce, TPM_NONCE_SIZE, ononce,
|
||||||
1, continueflag, 0, 0);
|
1, continueflag, 0, 0);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
goto out;
|
return ret;
|
||||||
|
|
||||||
if (crypto_memneq(testhmac, authdata, SHA1_DIGEST_SIZE))
|
if (crypto_memneq(testhmac, authdata, SHA1_DIGEST_SIZE))
|
||||||
ret = -EINVAL;
|
return -EINVAL;
|
||||||
out:
|
return 0;
|
||||||
kfree_sensitive(sdesc);
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(TSS_checkhmac1);
|
EXPORT_SYMBOL_GPL(TSS_checkhmac1);
|
||||||
|
|
||||||
|
|
@ -274,7 +185,7 @@ static int TSS_checkhmac2(unsigned char *buffer,
|
||||||
unsigned char testhmac1[SHA1_DIGEST_SIZE];
|
unsigned char testhmac1[SHA1_DIGEST_SIZE];
|
||||||
unsigned char testhmac2[SHA1_DIGEST_SIZE];
|
unsigned char testhmac2[SHA1_DIGEST_SIZE];
|
||||||
unsigned char paramdigest[SHA1_DIGEST_SIZE];
|
unsigned char paramdigest[SHA1_DIGEST_SIZE];
|
||||||
struct sdesc *sdesc;
|
struct sha1_ctx sha_ctx;
|
||||||
unsigned int dlen;
|
unsigned int dlen;
|
||||||
unsigned int dpos;
|
unsigned int dpos;
|
||||||
va_list argp;
|
va_list argp;
|
||||||
|
|
@ -297,22 +208,9 @@ static int TSS_checkhmac2(unsigned char *buffer,
|
||||||
enonce1 = continueflag1 - TPM_NONCE_SIZE;
|
enonce1 = continueflag1 - TPM_NONCE_SIZE;
|
||||||
enonce2 = continueflag2 - TPM_NONCE_SIZE;
|
enonce2 = continueflag2 - TPM_NONCE_SIZE;
|
||||||
|
|
||||||
sdesc = init_sdesc(hashalg);
|
sha1_init(&sha_ctx);
|
||||||
if (IS_ERR(sdesc)) {
|
sha1_update(&sha_ctx, (const u8 *)&result, sizeof(result));
|
||||||
pr_info("can't alloc %s\n", hash_alg);
|
sha1_update(&sha_ctx, (const u8 *)&ordinal, sizeof(ordinal));
|
||||||
return PTR_ERR(sdesc);
|
|
||||||
}
|
|
||||||
ret = crypto_shash_init(&sdesc->shash);
|
|
||||||
if (ret < 0)
|
|
||||||
goto out;
|
|
||||||
ret = crypto_shash_update(&sdesc->shash, (const u8 *)&result,
|
|
||||||
sizeof result);
|
|
||||||
if (ret < 0)
|
|
||||||
goto out;
|
|
||||||
ret = crypto_shash_update(&sdesc->shash, (const u8 *)&ordinal,
|
|
||||||
sizeof ordinal);
|
|
||||||
if (ret < 0)
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
va_start(argp, keylen2);
|
va_start(argp, keylen2);
|
||||||
for (;;) {
|
for (;;) {
|
||||||
|
|
@ -320,35 +218,26 @@ static int TSS_checkhmac2(unsigned char *buffer,
|
||||||
if (dlen == 0)
|
if (dlen == 0)
|
||||||
break;
|
break;
|
||||||
dpos = va_arg(argp, unsigned int);
|
dpos = va_arg(argp, unsigned int);
|
||||||
ret = crypto_shash_update(&sdesc->shash, buffer + dpos, dlen);
|
sha1_update(&sha_ctx, buffer + dpos, dlen);
|
||||||
if (ret < 0)
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
va_end(argp);
|
va_end(argp);
|
||||||
if (!ret)
|
sha1_final(&sha_ctx, paramdigest);
|
||||||
ret = crypto_shash_final(&sdesc->shash, paramdigest);
|
|
||||||
if (ret < 0)
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
ret = TSS_rawhmac(testhmac1, key1, keylen1, SHA1_DIGEST_SIZE,
|
ret = TSS_rawhmac(testhmac1, key1, keylen1, SHA1_DIGEST_SIZE,
|
||||||
paramdigest, TPM_NONCE_SIZE, enonce1,
|
paramdigest, TPM_NONCE_SIZE, enonce1,
|
||||||
TPM_NONCE_SIZE, ononce, 1, continueflag1, 0, 0);
|
TPM_NONCE_SIZE, ononce, 1, continueflag1, 0, 0);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
goto out;
|
return ret;
|
||||||
if (crypto_memneq(testhmac1, authdata1, SHA1_DIGEST_SIZE)) {
|
if (crypto_memneq(testhmac1, authdata1, SHA1_DIGEST_SIZE))
|
||||||
ret = -EINVAL;
|
return -EINVAL;
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
ret = TSS_rawhmac(testhmac2, key2, keylen2, SHA1_DIGEST_SIZE,
|
ret = TSS_rawhmac(testhmac2, key2, keylen2, SHA1_DIGEST_SIZE,
|
||||||
paramdigest, TPM_NONCE_SIZE, enonce2,
|
paramdigest, TPM_NONCE_SIZE, enonce2,
|
||||||
TPM_NONCE_SIZE, ononce, 1, continueflag2, 0, 0);
|
TPM_NONCE_SIZE, ononce, 1, continueflag2, 0, 0);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
goto out;
|
return ret;
|
||||||
if (crypto_memneq(testhmac2, authdata2, SHA1_DIGEST_SIZE))
|
if (crypto_memneq(testhmac2, authdata2, SHA1_DIGEST_SIZE))
|
||||||
ret = -EINVAL;
|
return -EINVAL;
|
||||||
out:
|
return 0;
|
||||||
kfree_sensitive(sdesc);
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -499,9 +388,7 @@ static int tpm_seal(struct tpm_buf *tb, uint16_t keytype,
|
||||||
/* calculate encrypted authorization value */
|
/* calculate encrypted authorization value */
|
||||||
memcpy(td->xorwork, sess.secret, SHA1_DIGEST_SIZE);
|
memcpy(td->xorwork, sess.secret, SHA1_DIGEST_SIZE);
|
||||||
memcpy(td->xorwork + SHA1_DIGEST_SIZE, sess.enonce, SHA1_DIGEST_SIZE);
|
memcpy(td->xorwork + SHA1_DIGEST_SIZE, sess.enonce, SHA1_DIGEST_SIZE);
|
||||||
ret = TSS_sha1(td->xorwork, SHA1_DIGEST_SIZE * 2, td->xorhash);
|
sha1(td->xorwork, SHA1_DIGEST_SIZE * 2, td->xorhash);
|
||||||
if (ret < 0)
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
ret = tpm_get_random(chip, td->nonceodd, TPM_NONCE_SIZE);
|
ret = tpm_get_random(chip, td->nonceodd, TPM_NONCE_SIZE);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
|
|
@ -990,40 +877,6 @@ static int trusted_tpm_get_random(unsigned char *key, size_t key_len)
|
||||||
return tpm_get_random(chip, key, key_len);
|
return tpm_get_random(chip, key, key_len);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void trusted_shash_release(void)
|
|
||||||
{
|
|
||||||
if (hashalg)
|
|
||||||
crypto_free_shash(hashalg);
|
|
||||||
if (hmacalg)
|
|
||||||
crypto_free_shash(hmacalg);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int __init trusted_shash_alloc(void)
|
|
||||||
{
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
hmacalg = crypto_alloc_shash(hmac_alg, 0, 0);
|
|
||||||
if (IS_ERR(hmacalg)) {
|
|
||||||
pr_info("could not allocate crypto %s\n",
|
|
||||||
hmac_alg);
|
|
||||||
return PTR_ERR(hmacalg);
|
|
||||||
}
|
|
||||||
|
|
||||||
hashalg = crypto_alloc_shash(hash_alg, 0, 0);
|
|
||||||
if (IS_ERR(hashalg)) {
|
|
||||||
pr_info("could not allocate crypto %s\n",
|
|
||||||
hash_alg);
|
|
||||||
ret = PTR_ERR(hashalg);
|
|
||||||
goto hashalg_fail;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
hashalg_fail:
|
|
||||||
crypto_free_shash(hmacalg);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int __init init_digests(void)
|
static int __init init_digests(void)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
@ -1050,15 +903,10 @@ static int __init trusted_tpm_init(void)
|
||||||
ret = init_digests();
|
ret = init_digests();
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
goto err_put;
|
goto err_put;
|
||||||
ret = trusted_shash_alloc();
|
|
||||||
if (ret < 0)
|
|
||||||
goto err_free;
|
|
||||||
ret = register_key_type(&key_type_trusted);
|
ret = register_key_type(&key_type_trusted);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
goto err_release;
|
goto err_free;
|
||||||
return 0;
|
return 0;
|
||||||
err_release:
|
|
||||||
trusted_shash_release();
|
|
||||||
err_free:
|
err_free:
|
||||||
kfree(digests);
|
kfree(digests);
|
||||||
err_put:
|
err_put:
|
||||||
|
|
@ -1071,7 +919,6 @@ static void trusted_tpm_exit(void)
|
||||||
if (chip) {
|
if (chip) {
|
||||||
put_device(&chip->dev);
|
put_device(&chip->dev);
|
||||||
kfree(digests);
|
kfree(digests);
|
||||||
trusted_shash_release();
|
|
||||||
unregister_key_type(&key_type_trusted);
|
unregister_key_type(&key_type_trusted);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue