147f9c279SSumit Garg // SPDX-License-Identifier: GPL-2.0-only 247f9c279SSumit Garg /* 347f9c279SSumit Garg * Copyright (C) 2010 IBM Corporation 447f9c279SSumit Garg * 547f9c279SSumit Garg * Author: 647f9c279SSumit Garg * David Safford <safford@us.ibm.com> 747f9c279SSumit Garg * 847f9c279SSumit Garg * See Documentation/security/keys/trusted-encrypted.rst 947f9c279SSumit Garg */ 1047f9c279SSumit Garg 1147f9c279SSumit Garg #include <crypto/hash_info.h> 1247f9c279SSumit Garg #include <linux/uaccess.h> 1347f9c279SSumit Garg #include <linux/module.h> 1447f9c279SSumit Garg #include <linux/init.h> 1547f9c279SSumit Garg #include <linux/slab.h> 1647f9c279SSumit Garg #include <linux/parser.h> 1747f9c279SSumit Garg #include <linux/string.h> 1847f9c279SSumit Garg #include <linux/err.h> 1947f9c279SSumit Garg #include <keys/user-type.h> 2047f9c279SSumit Garg #include <keys/trusted-type.h> 2147f9c279SSumit Garg #include <linux/key-type.h> 2247f9c279SSumit Garg #include <linux/rcupdate.h> 2347f9c279SSumit Garg #include <linux/crypto.h> 2447f9c279SSumit Garg #include <crypto/hash.h> 25*a24d22b2SEric Biggers #include <crypto/sha1.h> 2647f9c279SSumit Garg #include <linux/capability.h> 2747f9c279SSumit Garg #include <linux/tpm.h> 2847f9c279SSumit Garg #include <linux/tpm_command.h> 2947f9c279SSumit Garg 3047f9c279SSumit Garg #include <keys/trusted_tpm.h> 3147f9c279SSumit Garg 3247f9c279SSumit Garg static const char hmac_alg[] = "hmac(sha1)"; 3347f9c279SSumit Garg static const char hash_alg[] = "sha1"; 3447f9c279SSumit Garg static struct tpm_chip *chip; 3547f9c279SSumit Garg static struct tpm_digest *digests; 3647f9c279SSumit Garg 3747f9c279SSumit Garg struct sdesc { 3847f9c279SSumit Garg struct shash_desc shash; 3947f9c279SSumit Garg char ctx[]; 4047f9c279SSumit Garg }; 4147f9c279SSumit Garg 4247f9c279SSumit Garg static struct crypto_shash *hashalg; 4347f9c279SSumit Garg static struct crypto_shash *hmacalg; 4447f9c279SSumit Garg 4547f9c279SSumit Garg static struct sdesc *init_sdesc(struct crypto_shash *alg) 4647f9c279SSumit Garg { 4747f9c279SSumit Garg struct sdesc *sdesc; 4847f9c279SSumit Garg int size; 4947f9c279SSumit Garg 5047f9c279SSumit Garg size = sizeof(struct shash_desc) + crypto_shash_descsize(alg); 5147f9c279SSumit Garg sdesc = kmalloc(size, GFP_KERNEL); 5247f9c279SSumit Garg if (!sdesc) 5347f9c279SSumit Garg return ERR_PTR(-ENOMEM); 5447f9c279SSumit Garg sdesc->shash.tfm = alg; 5547f9c279SSumit Garg return sdesc; 5647f9c279SSumit Garg } 5747f9c279SSumit Garg 5847f9c279SSumit Garg static int TSS_sha1(const unsigned char *data, unsigned int datalen, 5947f9c279SSumit Garg unsigned char *digest) 6047f9c279SSumit Garg { 6147f9c279SSumit Garg struct sdesc *sdesc; 6247f9c279SSumit Garg int ret; 6347f9c279SSumit Garg 6447f9c279SSumit Garg sdesc = init_sdesc(hashalg); 6547f9c279SSumit Garg if (IS_ERR(sdesc)) { 6647f9c279SSumit Garg pr_info("trusted_key: can't alloc %s\n", hash_alg); 6747f9c279SSumit Garg return PTR_ERR(sdesc); 6847f9c279SSumit Garg } 6947f9c279SSumit Garg 7047f9c279SSumit Garg ret = crypto_shash_digest(&sdesc->shash, data, datalen, digest); 71453431a5SWaiman Long kfree_sensitive(sdesc); 7247f9c279SSumit Garg return ret; 7347f9c279SSumit Garg } 7447f9c279SSumit Garg 7547f9c279SSumit Garg static int TSS_rawhmac(unsigned char *digest, const unsigned char *key, 7647f9c279SSumit Garg unsigned int keylen, ...) 7747f9c279SSumit Garg { 7847f9c279SSumit Garg struct sdesc *sdesc; 7947f9c279SSumit Garg va_list argp; 8047f9c279SSumit Garg unsigned int dlen; 8147f9c279SSumit Garg unsigned char *data; 8247f9c279SSumit Garg int ret; 8347f9c279SSumit Garg 8447f9c279SSumit Garg sdesc = init_sdesc(hmacalg); 8547f9c279SSumit Garg if (IS_ERR(sdesc)) { 8647f9c279SSumit Garg pr_info("trusted_key: can't alloc %s\n", hmac_alg); 8747f9c279SSumit Garg return PTR_ERR(sdesc); 8847f9c279SSumit Garg } 8947f9c279SSumit Garg 9047f9c279SSumit Garg ret = crypto_shash_setkey(hmacalg, key, keylen); 9147f9c279SSumit Garg if (ret < 0) 9247f9c279SSumit Garg goto out; 9347f9c279SSumit Garg ret = crypto_shash_init(&sdesc->shash); 9447f9c279SSumit Garg if (ret < 0) 9547f9c279SSumit Garg goto out; 9647f9c279SSumit Garg 9747f9c279SSumit Garg va_start(argp, keylen); 9847f9c279SSumit Garg for (;;) { 9947f9c279SSumit Garg dlen = va_arg(argp, unsigned int); 10047f9c279SSumit Garg if (dlen == 0) 10147f9c279SSumit Garg break; 10247f9c279SSumit Garg data = va_arg(argp, unsigned char *); 10347f9c279SSumit Garg if (data == NULL) { 10447f9c279SSumit Garg ret = -EINVAL; 10547f9c279SSumit Garg break; 10647f9c279SSumit Garg } 10747f9c279SSumit Garg ret = crypto_shash_update(&sdesc->shash, data, dlen); 10847f9c279SSumit Garg if (ret < 0) 10947f9c279SSumit Garg break; 11047f9c279SSumit Garg } 11147f9c279SSumit Garg va_end(argp); 11247f9c279SSumit Garg if (!ret) 11347f9c279SSumit Garg ret = crypto_shash_final(&sdesc->shash, digest); 11447f9c279SSumit Garg out: 115453431a5SWaiman Long kfree_sensitive(sdesc); 11647f9c279SSumit Garg return ret; 11747f9c279SSumit Garg } 11847f9c279SSumit Garg 11947f9c279SSumit Garg /* 12047f9c279SSumit Garg * calculate authorization info fields to send to TPM 12147f9c279SSumit Garg */ 12247f9c279SSumit Garg int TSS_authhmac(unsigned char *digest, const unsigned char *key, 12347f9c279SSumit Garg unsigned int keylen, unsigned char *h1, 12447f9c279SSumit Garg unsigned char *h2, unsigned int h3, ...) 12547f9c279SSumit Garg { 12647f9c279SSumit Garg unsigned char paramdigest[SHA1_DIGEST_SIZE]; 12747f9c279SSumit Garg struct sdesc *sdesc; 12847f9c279SSumit Garg unsigned int dlen; 12947f9c279SSumit Garg unsigned char *data; 13047f9c279SSumit Garg unsigned char c; 13147f9c279SSumit Garg int ret; 13247f9c279SSumit Garg va_list argp; 13347f9c279SSumit Garg 13447f9c279SSumit Garg if (!chip) 13547f9c279SSumit Garg return -ENODEV; 13647f9c279SSumit Garg 13747f9c279SSumit Garg sdesc = init_sdesc(hashalg); 13847f9c279SSumit Garg if (IS_ERR(sdesc)) { 13947f9c279SSumit Garg pr_info("trusted_key: can't alloc %s\n", hash_alg); 14047f9c279SSumit Garg return PTR_ERR(sdesc); 14147f9c279SSumit Garg } 14247f9c279SSumit Garg 14347f9c279SSumit Garg c = !!h3; 14447f9c279SSumit Garg ret = crypto_shash_init(&sdesc->shash); 14547f9c279SSumit Garg if (ret < 0) 14647f9c279SSumit Garg goto out; 14747f9c279SSumit Garg va_start(argp, h3); 14847f9c279SSumit Garg for (;;) { 14947f9c279SSumit Garg dlen = va_arg(argp, unsigned int); 15047f9c279SSumit Garg if (dlen == 0) 15147f9c279SSumit Garg break; 15247f9c279SSumit Garg data = va_arg(argp, unsigned char *); 15347f9c279SSumit Garg if (!data) { 15447f9c279SSumit Garg ret = -EINVAL; 15547f9c279SSumit Garg break; 15647f9c279SSumit Garg } 15747f9c279SSumit Garg ret = crypto_shash_update(&sdesc->shash, data, dlen); 15847f9c279SSumit Garg if (ret < 0) 15947f9c279SSumit Garg break; 16047f9c279SSumit Garg } 16147f9c279SSumit Garg va_end(argp); 16247f9c279SSumit Garg if (!ret) 16347f9c279SSumit Garg ret = crypto_shash_final(&sdesc->shash, paramdigest); 16447f9c279SSumit Garg if (!ret) 16547f9c279SSumit Garg ret = TSS_rawhmac(digest, key, keylen, SHA1_DIGEST_SIZE, 16647f9c279SSumit Garg paramdigest, TPM_NONCE_SIZE, h1, 16747f9c279SSumit Garg TPM_NONCE_SIZE, h2, 1, &c, 0, 0); 16847f9c279SSumit Garg out: 169453431a5SWaiman Long kfree_sensitive(sdesc); 17047f9c279SSumit Garg return ret; 17147f9c279SSumit Garg } 17247f9c279SSumit Garg EXPORT_SYMBOL_GPL(TSS_authhmac); 17347f9c279SSumit Garg 17447f9c279SSumit Garg /* 17547f9c279SSumit Garg * verify the AUTH1_COMMAND (Seal) result from TPM 17647f9c279SSumit Garg */ 17747f9c279SSumit Garg int TSS_checkhmac1(unsigned char *buffer, 17847f9c279SSumit Garg const uint32_t command, 17947f9c279SSumit Garg const unsigned char *ononce, 18047f9c279SSumit Garg const unsigned char *key, 18147f9c279SSumit Garg unsigned int keylen, ...) 18247f9c279SSumit Garg { 18347f9c279SSumit Garg uint32_t bufsize; 18447f9c279SSumit Garg uint16_t tag; 18547f9c279SSumit Garg uint32_t ordinal; 18647f9c279SSumit Garg uint32_t result; 18747f9c279SSumit Garg unsigned char *enonce; 18847f9c279SSumit Garg unsigned char *continueflag; 18947f9c279SSumit Garg unsigned char *authdata; 19047f9c279SSumit Garg unsigned char testhmac[SHA1_DIGEST_SIZE]; 19147f9c279SSumit Garg unsigned char paramdigest[SHA1_DIGEST_SIZE]; 19247f9c279SSumit Garg struct sdesc *sdesc; 19347f9c279SSumit Garg unsigned int dlen; 19447f9c279SSumit Garg unsigned int dpos; 19547f9c279SSumit Garg va_list argp; 19647f9c279SSumit Garg int ret; 19747f9c279SSumit Garg 19847f9c279SSumit Garg if (!chip) 19947f9c279SSumit Garg return -ENODEV; 20047f9c279SSumit Garg 20147f9c279SSumit Garg bufsize = LOAD32(buffer, TPM_SIZE_OFFSET); 20247f9c279SSumit Garg tag = LOAD16(buffer, 0); 20347f9c279SSumit Garg ordinal = command; 20447f9c279SSumit Garg result = LOAD32N(buffer, TPM_RETURN_OFFSET); 20547f9c279SSumit Garg if (tag == TPM_TAG_RSP_COMMAND) 20647f9c279SSumit Garg return 0; 20747f9c279SSumit Garg if (tag != TPM_TAG_RSP_AUTH1_COMMAND) 20847f9c279SSumit Garg return -EINVAL; 20947f9c279SSumit Garg authdata = buffer + bufsize - SHA1_DIGEST_SIZE; 21047f9c279SSumit Garg continueflag = authdata - 1; 21147f9c279SSumit Garg enonce = continueflag - TPM_NONCE_SIZE; 21247f9c279SSumit Garg 21347f9c279SSumit Garg sdesc = init_sdesc(hashalg); 21447f9c279SSumit Garg if (IS_ERR(sdesc)) { 21547f9c279SSumit Garg pr_info("trusted_key: can't alloc %s\n", hash_alg); 21647f9c279SSumit Garg return PTR_ERR(sdesc); 21747f9c279SSumit Garg } 21847f9c279SSumit Garg ret = crypto_shash_init(&sdesc->shash); 21947f9c279SSumit Garg if (ret < 0) 22047f9c279SSumit Garg goto out; 22147f9c279SSumit Garg ret = crypto_shash_update(&sdesc->shash, (const u8 *)&result, 22247f9c279SSumit Garg sizeof result); 22347f9c279SSumit Garg if (ret < 0) 22447f9c279SSumit Garg goto out; 22547f9c279SSumit Garg ret = crypto_shash_update(&sdesc->shash, (const u8 *)&ordinal, 22647f9c279SSumit Garg sizeof ordinal); 22747f9c279SSumit Garg if (ret < 0) 22847f9c279SSumit Garg goto out; 22947f9c279SSumit Garg va_start(argp, keylen); 23047f9c279SSumit Garg for (;;) { 23147f9c279SSumit Garg dlen = va_arg(argp, unsigned int); 23247f9c279SSumit Garg if (dlen == 0) 23347f9c279SSumit Garg break; 23447f9c279SSumit Garg dpos = va_arg(argp, unsigned int); 23547f9c279SSumit Garg ret = crypto_shash_update(&sdesc->shash, buffer + dpos, dlen); 23647f9c279SSumit Garg if (ret < 0) 23747f9c279SSumit Garg break; 23847f9c279SSumit Garg } 23947f9c279SSumit Garg va_end(argp); 24047f9c279SSumit Garg if (!ret) 24147f9c279SSumit Garg ret = crypto_shash_final(&sdesc->shash, paramdigest); 24247f9c279SSumit Garg if (ret < 0) 24347f9c279SSumit Garg goto out; 24447f9c279SSumit Garg 24547f9c279SSumit Garg ret = TSS_rawhmac(testhmac, key, keylen, SHA1_DIGEST_SIZE, paramdigest, 24647f9c279SSumit Garg TPM_NONCE_SIZE, enonce, TPM_NONCE_SIZE, ononce, 24747f9c279SSumit Garg 1, continueflag, 0, 0); 24847f9c279SSumit Garg if (ret < 0) 24947f9c279SSumit Garg goto out; 25047f9c279SSumit Garg 25147f9c279SSumit Garg if (memcmp(testhmac, authdata, SHA1_DIGEST_SIZE)) 25247f9c279SSumit Garg ret = -EINVAL; 25347f9c279SSumit Garg out: 254453431a5SWaiman Long kfree_sensitive(sdesc); 25547f9c279SSumit Garg return ret; 25647f9c279SSumit Garg } 25747f9c279SSumit Garg EXPORT_SYMBOL_GPL(TSS_checkhmac1); 25847f9c279SSumit Garg 25947f9c279SSumit Garg /* 26047f9c279SSumit Garg * verify the AUTH2_COMMAND (unseal) result from TPM 26147f9c279SSumit Garg */ 26247f9c279SSumit Garg static int TSS_checkhmac2(unsigned char *buffer, 26347f9c279SSumit Garg const uint32_t command, 26447f9c279SSumit Garg const unsigned char *ononce, 26547f9c279SSumit Garg const unsigned char *key1, 26647f9c279SSumit Garg unsigned int keylen1, 26747f9c279SSumit Garg const unsigned char *key2, 26847f9c279SSumit Garg unsigned int keylen2, ...) 26947f9c279SSumit Garg { 27047f9c279SSumit Garg uint32_t bufsize; 27147f9c279SSumit Garg uint16_t tag; 27247f9c279SSumit Garg uint32_t ordinal; 27347f9c279SSumit Garg uint32_t result; 27447f9c279SSumit Garg unsigned char *enonce1; 27547f9c279SSumit Garg unsigned char *continueflag1; 27647f9c279SSumit Garg unsigned char *authdata1; 27747f9c279SSumit Garg unsigned char *enonce2; 27847f9c279SSumit Garg unsigned char *continueflag2; 27947f9c279SSumit Garg unsigned char *authdata2; 28047f9c279SSumit Garg unsigned char testhmac1[SHA1_DIGEST_SIZE]; 28147f9c279SSumit Garg unsigned char testhmac2[SHA1_DIGEST_SIZE]; 28247f9c279SSumit Garg unsigned char paramdigest[SHA1_DIGEST_SIZE]; 28347f9c279SSumit Garg struct sdesc *sdesc; 28447f9c279SSumit Garg unsigned int dlen; 28547f9c279SSumit Garg unsigned int dpos; 28647f9c279SSumit Garg va_list argp; 28747f9c279SSumit Garg int ret; 28847f9c279SSumit Garg 28947f9c279SSumit Garg bufsize = LOAD32(buffer, TPM_SIZE_OFFSET); 29047f9c279SSumit Garg tag = LOAD16(buffer, 0); 29147f9c279SSumit Garg ordinal = command; 29247f9c279SSumit Garg result = LOAD32N(buffer, TPM_RETURN_OFFSET); 29347f9c279SSumit Garg 29447f9c279SSumit Garg if (tag == TPM_TAG_RSP_COMMAND) 29547f9c279SSumit Garg return 0; 29647f9c279SSumit Garg if (tag != TPM_TAG_RSP_AUTH2_COMMAND) 29747f9c279SSumit Garg return -EINVAL; 29847f9c279SSumit Garg authdata1 = buffer + bufsize - (SHA1_DIGEST_SIZE + 1 29947f9c279SSumit Garg + SHA1_DIGEST_SIZE + SHA1_DIGEST_SIZE); 30047f9c279SSumit Garg authdata2 = buffer + bufsize - (SHA1_DIGEST_SIZE); 30147f9c279SSumit Garg continueflag1 = authdata1 - 1; 30247f9c279SSumit Garg continueflag2 = authdata2 - 1; 30347f9c279SSumit Garg enonce1 = continueflag1 - TPM_NONCE_SIZE; 30447f9c279SSumit Garg enonce2 = continueflag2 - TPM_NONCE_SIZE; 30547f9c279SSumit Garg 30647f9c279SSumit Garg sdesc = init_sdesc(hashalg); 30747f9c279SSumit Garg if (IS_ERR(sdesc)) { 30847f9c279SSumit Garg pr_info("trusted_key: can't alloc %s\n", hash_alg); 30947f9c279SSumit Garg return PTR_ERR(sdesc); 31047f9c279SSumit Garg } 31147f9c279SSumit Garg ret = crypto_shash_init(&sdesc->shash); 31247f9c279SSumit Garg if (ret < 0) 31347f9c279SSumit Garg goto out; 31447f9c279SSumit Garg ret = crypto_shash_update(&sdesc->shash, (const u8 *)&result, 31547f9c279SSumit Garg sizeof result); 31647f9c279SSumit Garg if (ret < 0) 31747f9c279SSumit Garg goto out; 31847f9c279SSumit Garg ret = crypto_shash_update(&sdesc->shash, (const u8 *)&ordinal, 31947f9c279SSumit Garg sizeof ordinal); 32047f9c279SSumit Garg if (ret < 0) 32147f9c279SSumit Garg goto out; 32247f9c279SSumit Garg 32347f9c279SSumit Garg va_start(argp, keylen2); 32447f9c279SSumit Garg for (;;) { 32547f9c279SSumit Garg dlen = va_arg(argp, unsigned int); 32647f9c279SSumit Garg if (dlen == 0) 32747f9c279SSumit Garg break; 32847f9c279SSumit Garg dpos = va_arg(argp, unsigned int); 32947f9c279SSumit Garg ret = crypto_shash_update(&sdesc->shash, buffer + dpos, dlen); 33047f9c279SSumit Garg if (ret < 0) 33147f9c279SSumit Garg break; 33247f9c279SSumit Garg } 33347f9c279SSumit Garg va_end(argp); 33447f9c279SSumit Garg if (!ret) 33547f9c279SSumit Garg ret = crypto_shash_final(&sdesc->shash, paramdigest); 33647f9c279SSumit Garg if (ret < 0) 33747f9c279SSumit Garg goto out; 33847f9c279SSumit Garg 33947f9c279SSumit Garg ret = TSS_rawhmac(testhmac1, key1, keylen1, SHA1_DIGEST_SIZE, 34047f9c279SSumit Garg paramdigest, TPM_NONCE_SIZE, enonce1, 34147f9c279SSumit Garg TPM_NONCE_SIZE, ononce, 1, continueflag1, 0, 0); 34247f9c279SSumit Garg if (ret < 0) 34347f9c279SSumit Garg goto out; 34447f9c279SSumit Garg if (memcmp(testhmac1, authdata1, SHA1_DIGEST_SIZE)) { 34547f9c279SSumit Garg ret = -EINVAL; 34647f9c279SSumit Garg goto out; 34747f9c279SSumit Garg } 34847f9c279SSumit Garg ret = TSS_rawhmac(testhmac2, key2, keylen2, SHA1_DIGEST_SIZE, 34947f9c279SSumit Garg paramdigest, TPM_NONCE_SIZE, enonce2, 35047f9c279SSumit Garg TPM_NONCE_SIZE, ononce, 1, continueflag2, 0, 0); 35147f9c279SSumit Garg if (ret < 0) 35247f9c279SSumit Garg goto out; 35347f9c279SSumit Garg if (memcmp(testhmac2, authdata2, SHA1_DIGEST_SIZE)) 35447f9c279SSumit Garg ret = -EINVAL; 35547f9c279SSumit Garg out: 356453431a5SWaiman Long kfree_sensitive(sdesc); 35747f9c279SSumit Garg return ret; 35847f9c279SSumit Garg } 35947f9c279SSumit Garg 36047f9c279SSumit Garg /* 36147f9c279SSumit Garg * For key specific tpm requests, we will generate and send our 36247f9c279SSumit Garg * own TPM command packets using the drivers send function. 36347f9c279SSumit Garg */ 36447f9c279SSumit Garg int trusted_tpm_send(unsigned char *cmd, size_t buflen) 36547f9c279SSumit Garg { 36647f9c279SSumit Garg int rc; 36747f9c279SSumit Garg 36847f9c279SSumit Garg if (!chip) 36947f9c279SSumit Garg return -ENODEV; 37047f9c279SSumit Garg 37147f9c279SSumit Garg dump_tpm_buf(cmd); 37247f9c279SSumit Garg rc = tpm_send(chip, cmd, buflen); 37347f9c279SSumit Garg dump_tpm_buf(cmd); 37447f9c279SSumit Garg if (rc > 0) 37547f9c279SSumit Garg /* Can't return positive return codes values to keyctl */ 37647f9c279SSumit Garg rc = -EPERM; 37747f9c279SSumit Garg return rc; 37847f9c279SSumit Garg } 37947f9c279SSumit Garg EXPORT_SYMBOL_GPL(trusted_tpm_send); 38047f9c279SSumit Garg 38147f9c279SSumit Garg /* 38247f9c279SSumit Garg * Lock a trusted key, by extending a selected PCR. 38347f9c279SSumit Garg * 38447f9c279SSumit Garg * Prevents a trusted key that is sealed to PCRs from being accessed. 38547f9c279SSumit Garg * This uses the tpm driver's extend function. 38647f9c279SSumit Garg */ 38747f9c279SSumit Garg static int pcrlock(const int pcrnum) 38847f9c279SSumit Garg { 38947f9c279SSumit Garg if (!capable(CAP_SYS_ADMIN)) 39047f9c279SSumit Garg return -EPERM; 39147f9c279SSumit Garg 39247f9c279SSumit Garg return tpm_pcr_extend(chip, pcrnum, digests) ? -EINVAL : 0; 39347f9c279SSumit Garg } 39447f9c279SSumit Garg 39547f9c279SSumit Garg /* 39647f9c279SSumit Garg * Create an object specific authorisation protocol (OSAP) session 39747f9c279SSumit Garg */ 39847f9c279SSumit Garg static int osap(struct tpm_buf *tb, struct osapsess *s, 39947f9c279SSumit Garg const unsigned char *key, uint16_t type, uint32_t handle) 40047f9c279SSumit Garg { 40147f9c279SSumit Garg unsigned char enonce[TPM_NONCE_SIZE]; 40247f9c279SSumit Garg unsigned char ononce[TPM_NONCE_SIZE]; 40347f9c279SSumit Garg int ret; 40447f9c279SSumit Garg 40547f9c279SSumit Garg ret = tpm_get_random(chip, ononce, TPM_NONCE_SIZE); 40647f9c279SSumit Garg if (ret != TPM_NONCE_SIZE) 40747f9c279SSumit Garg return ret; 40847f9c279SSumit Garg 40947f9c279SSumit Garg tpm_buf_reset(tb, TPM_TAG_RQU_COMMAND, TPM_ORD_OSAP); 41047f9c279SSumit Garg tpm_buf_append_u16(tb, type); 41147f9c279SSumit Garg tpm_buf_append_u32(tb, handle); 41247f9c279SSumit Garg tpm_buf_append(tb, ononce, TPM_NONCE_SIZE); 41347f9c279SSumit Garg 41447f9c279SSumit Garg ret = trusted_tpm_send(tb->data, MAX_BUF_SIZE); 41547f9c279SSumit Garg if (ret < 0) 41647f9c279SSumit Garg return ret; 41747f9c279SSumit Garg 41847f9c279SSumit Garg s->handle = LOAD32(tb->data, TPM_DATA_OFFSET); 41947f9c279SSumit Garg memcpy(s->enonce, &(tb->data[TPM_DATA_OFFSET + sizeof(uint32_t)]), 42047f9c279SSumit Garg TPM_NONCE_SIZE); 42147f9c279SSumit Garg memcpy(enonce, &(tb->data[TPM_DATA_OFFSET + sizeof(uint32_t) + 42247f9c279SSumit Garg TPM_NONCE_SIZE]), TPM_NONCE_SIZE); 42347f9c279SSumit Garg return TSS_rawhmac(s->secret, key, SHA1_DIGEST_SIZE, TPM_NONCE_SIZE, 42447f9c279SSumit Garg enonce, TPM_NONCE_SIZE, ononce, 0, 0); 42547f9c279SSumit Garg } 42647f9c279SSumit Garg 42747f9c279SSumit Garg /* 42847f9c279SSumit Garg * Create an object independent authorisation protocol (oiap) session 42947f9c279SSumit Garg */ 43047f9c279SSumit Garg int oiap(struct tpm_buf *tb, uint32_t *handle, unsigned char *nonce) 43147f9c279SSumit Garg { 43247f9c279SSumit Garg int ret; 43347f9c279SSumit Garg 43447f9c279SSumit Garg if (!chip) 43547f9c279SSumit Garg return -ENODEV; 43647f9c279SSumit Garg 43747f9c279SSumit Garg tpm_buf_reset(tb, TPM_TAG_RQU_COMMAND, TPM_ORD_OIAP); 43847f9c279SSumit Garg ret = trusted_tpm_send(tb->data, MAX_BUF_SIZE); 43947f9c279SSumit Garg if (ret < 0) 44047f9c279SSumit Garg return ret; 44147f9c279SSumit Garg 44247f9c279SSumit Garg *handle = LOAD32(tb->data, TPM_DATA_OFFSET); 44347f9c279SSumit Garg memcpy(nonce, &tb->data[TPM_DATA_OFFSET + sizeof(uint32_t)], 44447f9c279SSumit Garg TPM_NONCE_SIZE); 44547f9c279SSumit Garg return 0; 44647f9c279SSumit Garg } 44747f9c279SSumit Garg EXPORT_SYMBOL_GPL(oiap); 44847f9c279SSumit Garg 44947f9c279SSumit Garg struct tpm_digests { 45047f9c279SSumit Garg unsigned char encauth[SHA1_DIGEST_SIZE]; 45147f9c279SSumit Garg unsigned char pubauth[SHA1_DIGEST_SIZE]; 45247f9c279SSumit Garg unsigned char xorwork[SHA1_DIGEST_SIZE * 2]; 45347f9c279SSumit Garg unsigned char xorhash[SHA1_DIGEST_SIZE]; 45447f9c279SSumit Garg unsigned char nonceodd[TPM_NONCE_SIZE]; 45547f9c279SSumit Garg }; 45647f9c279SSumit Garg 45747f9c279SSumit Garg /* 45847f9c279SSumit Garg * Have the TPM seal(encrypt) the trusted key, possibly based on 45947f9c279SSumit Garg * Platform Configuration Registers (PCRs). AUTH1 for sealing key. 46047f9c279SSumit Garg */ 46147f9c279SSumit Garg static int tpm_seal(struct tpm_buf *tb, uint16_t keytype, 46247f9c279SSumit Garg uint32_t keyhandle, const unsigned char *keyauth, 46347f9c279SSumit Garg const unsigned char *data, uint32_t datalen, 46447f9c279SSumit Garg unsigned char *blob, uint32_t *bloblen, 46547f9c279SSumit Garg const unsigned char *blobauth, 46647f9c279SSumit Garg const unsigned char *pcrinfo, uint32_t pcrinfosize) 46747f9c279SSumit Garg { 46847f9c279SSumit Garg struct osapsess sess; 46947f9c279SSumit Garg struct tpm_digests *td; 47047f9c279SSumit Garg unsigned char cont; 47147f9c279SSumit Garg uint32_t ordinal; 47247f9c279SSumit Garg uint32_t pcrsize; 47347f9c279SSumit Garg uint32_t datsize; 47447f9c279SSumit Garg int sealinfosize; 47547f9c279SSumit Garg int encdatasize; 47647f9c279SSumit Garg int storedsize; 47747f9c279SSumit Garg int ret; 47847f9c279SSumit Garg int i; 47947f9c279SSumit Garg 48047f9c279SSumit Garg /* alloc some work space for all the hashes */ 48147f9c279SSumit Garg td = kmalloc(sizeof *td, GFP_KERNEL); 48247f9c279SSumit Garg if (!td) 48347f9c279SSumit Garg return -ENOMEM; 48447f9c279SSumit Garg 48547f9c279SSumit Garg /* get session for sealing key */ 48647f9c279SSumit Garg ret = osap(tb, &sess, keyauth, keytype, keyhandle); 48747f9c279SSumit Garg if (ret < 0) 48847f9c279SSumit Garg goto out; 48947f9c279SSumit Garg dump_sess(&sess); 49047f9c279SSumit Garg 49147f9c279SSumit Garg /* calculate encrypted authorization value */ 49247f9c279SSumit Garg memcpy(td->xorwork, sess.secret, SHA1_DIGEST_SIZE); 49347f9c279SSumit Garg memcpy(td->xorwork + SHA1_DIGEST_SIZE, sess.enonce, SHA1_DIGEST_SIZE); 49447f9c279SSumit Garg ret = TSS_sha1(td->xorwork, SHA1_DIGEST_SIZE * 2, td->xorhash); 49547f9c279SSumit Garg if (ret < 0) 49647f9c279SSumit Garg goto out; 49747f9c279SSumit Garg 49847f9c279SSumit Garg ret = tpm_get_random(chip, td->nonceodd, TPM_NONCE_SIZE); 49947f9c279SSumit Garg if (ret != TPM_NONCE_SIZE) 50047f9c279SSumit Garg goto out; 50147f9c279SSumit Garg ordinal = htonl(TPM_ORD_SEAL); 50247f9c279SSumit Garg datsize = htonl(datalen); 50347f9c279SSumit Garg pcrsize = htonl(pcrinfosize); 50447f9c279SSumit Garg cont = 0; 50547f9c279SSumit Garg 50647f9c279SSumit Garg /* encrypt data authorization key */ 50747f9c279SSumit Garg for (i = 0; i < SHA1_DIGEST_SIZE; ++i) 50847f9c279SSumit Garg td->encauth[i] = td->xorhash[i] ^ blobauth[i]; 50947f9c279SSumit Garg 51047f9c279SSumit Garg /* calculate authorization HMAC value */ 51147f9c279SSumit Garg if (pcrinfosize == 0) { 51247f9c279SSumit Garg /* no pcr info specified */ 51347f9c279SSumit Garg ret = TSS_authhmac(td->pubauth, sess.secret, SHA1_DIGEST_SIZE, 51447f9c279SSumit Garg sess.enonce, td->nonceodd, cont, 51547f9c279SSumit Garg sizeof(uint32_t), &ordinal, SHA1_DIGEST_SIZE, 51647f9c279SSumit Garg td->encauth, sizeof(uint32_t), &pcrsize, 51747f9c279SSumit Garg sizeof(uint32_t), &datsize, datalen, data, 0, 51847f9c279SSumit Garg 0); 51947f9c279SSumit Garg } else { 52047f9c279SSumit Garg /* pcr info specified */ 52147f9c279SSumit Garg ret = TSS_authhmac(td->pubauth, sess.secret, SHA1_DIGEST_SIZE, 52247f9c279SSumit Garg sess.enonce, td->nonceodd, cont, 52347f9c279SSumit Garg sizeof(uint32_t), &ordinal, SHA1_DIGEST_SIZE, 52447f9c279SSumit Garg td->encauth, sizeof(uint32_t), &pcrsize, 52547f9c279SSumit Garg pcrinfosize, pcrinfo, sizeof(uint32_t), 52647f9c279SSumit Garg &datsize, datalen, data, 0, 0); 52747f9c279SSumit Garg } 52847f9c279SSumit Garg if (ret < 0) 52947f9c279SSumit Garg goto out; 53047f9c279SSumit Garg 53147f9c279SSumit Garg /* build and send the TPM request packet */ 53247f9c279SSumit Garg tpm_buf_reset(tb, TPM_TAG_RQU_AUTH1_COMMAND, TPM_ORD_SEAL); 53347f9c279SSumit Garg tpm_buf_append_u32(tb, keyhandle); 53447f9c279SSumit Garg tpm_buf_append(tb, td->encauth, SHA1_DIGEST_SIZE); 53547f9c279SSumit Garg tpm_buf_append_u32(tb, pcrinfosize); 53647f9c279SSumit Garg tpm_buf_append(tb, pcrinfo, pcrinfosize); 53747f9c279SSumit Garg tpm_buf_append_u32(tb, datalen); 53847f9c279SSumit Garg tpm_buf_append(tb, data, datalen); 53947f9c279SSumit Garg tpm_buf_append_u32(tb, sess.handle); 54047f9c279SSumit Garg tpm_buf_append(tb, td->nonceodd, TPM_NONCE_SIZE); 54147f9c279SSumit Garg tpm_buf_append_u8(tb, cont); 54247f9c279SSumit Garg tpm_buf_append(tb, td->pubauth, SHA1_DIGEST_SIZE); 54347f9c279SSumit Garg 54447f9c279SSumit Garg ret = trusted_tpm_send(tb->data, MAX_BUF_SIZE); 54547f9c279SSumit Garg if (ret < 0) 54647f9c279SSumit Garg goto out; 54747f9c279SSumit Garg 54847f9c279SSumit Garg /* calculate the size of the returned Blob */ 54947f9c279SSumit Garg sealinfosize = LOAD32(tb->data, TPM_DATA_OFFSET + sizeof(uint32_t)); 55047f9c279SSumit Garg encdatasize = LOAD32(tb->data, TPM_DATA_OFFSET + sizeof(uint32_t) + 55147f9c279SSumit Garg sizeof(uint32_t) + sealinfosize); 55247f9c279SSumit Garg storedsize = sizeof(uint32_t) + sizeof(uint32_t) + sealinfosize + 55347f9c279SSumit Garg sizeof(uint32_t) + encdatasize; 55447f9c279SSumit Garg 55547f9c279SSumit Garg /* check the HMAC in the response */ 55647f9c279SSumit Garg ret = TSS_checkhmac1(tb->data, ordinal, td->nonceodd, sess.secret, 55747f9c279SSumit Garg SHA1_DIGEST_SIZE, storedsize, TPM_DATA_OFFSET, 0, 55847f9c279SSumit Garg 0); 55947f9c279SSumit Garg 56047f9c279SSumit Garg /* copy the returned blob to caller */ 56147f9c279SSumit Garg if (!ret) { 56247f9c279SSumit Garg memcpy(blob, tb->data + TPM_DATA_OFFSET, storedsize); 56347f9c279SSumit Garg *bloblen = storedsize; 56447f9c279SSumit Garg } 56547f9c279SSumit Garg out: 566453431a5SWaiman Long kfree_sensitive(td); 56747f9c279SSumit Garg return ret; 56847f9c279SSumit Garg } 56947f9c279SSumit Garg 57047f9c279SSumit Garg /* 57147f9c279SSumit Garg * use the AUTH2_COMMAND form of unseal, to authorize both key and blob 57247f9c279SSumit Garg */ 57347f9c279SSumit Garg static int tpm_unseal(struct tpm_buf *tb, 57447f9c279SSumit Garg uint32_t keyhandle, const unsigned char *keyauth, 57547f9c279SSumit Garg const unsigned char *blob, int bloblen, 57647f9c279SSumit Garg const unsigned char *blobauth, 57747f9c279SSumit Garg unsigned char *data, unsigned int *datalen) 57847f9c279SSumit Garg { 57947f9c279SSumit Garg unsigned char nonceodd[TPM_NONCE_SIZE]; 58047f9c279SSumit Garg unsigned char enonce1[TPM_NONCE_SIZE]; 58147f9c279SSumit Garg unsigned char enonce2[TPM_NONCE_SIZE]; 58247f9c279SSumit Garg unsigned char authdata1[SHA1_DIGEST_SIZE]; 58347f9c279SSumit Garg unsigned char authdata2[SHA1_DIGEST_SIZE]; 58447f9c279SSumit Garg uint32_t authhandle1 = 0; 58547f9c279SSumit Garg uint32_t authhandle2 = 0; 58647f9c279SSumit Garg unsigned char cont = 0; 58747f9c279SSumit Garg uint32_t ordinal; 58847f9c279SSumit Garg int ret; 58947f9c279SSumit Garg 59047f9c279SSumit Garg /* sessions for unsealing key and data */ 59147f9c279SSumit Garg ret = oiap(tb, &authhandle1, enonce1); 59247f9c279SSumit Garg if (ret < 0) { 59347f9c279SSumit Garg pr_info("trusted_key: oiap failed (%d)\n", ret); 59447f9c279SSumit Garg return ret; 59547f9c279SSumit Garg } 59647f9c279SSumit Garg ret = oiap(tb, &authhandle2, enonce2); 59747f9c279SSumit Garg if (ret < 0) { 59847f9c279SSumit Garg pr_info("trusted_key: oiap failed (%d)\n", ret); 59947f9c279SSumit Garg return ret; 60047f9c279SSumit Garg } 60147f9c279SSumit Garg 60247f9c279SSumit Garg ordinal = htonl(TPM_ORD_UNSEAL); 60347f9c279SSumit Garg ret = tpm_get_random(chip, nonceodd, TPM_NONCE_SIZE); 60447f9c279SSumit Garg if (ret != TPM_NONCE_SIZE) { 60547f9c279SSumit Garg pr_info("trusted_key: tpm_get_random failed (%d)\n", ret); 60647f9c279SSumit Garg return ret; 60747f9c279SSumit Garg } 60847f9c279SSumit Garg ret = TSS_authhmac(authdata1, keyauth, TPM_NONCE_SIZE, 60947f9c279SSumit Garg enonce1, nonceodd, cont, sizeof(uint32_t), 61047f9c279SSumit Garg &ordinal, bloblen, blob, 0, 0); 61147f9c279SSumit Garg if (ret < 0) 61247f9c279SSumit Garg return ret; 61347f9c279SSumit Garg ret = TSS_authhmac(authdata2, blobauth, TPM_NONCE_SIZE, 61447f9c279SSumit Garg enonce2, nonceodd, cont, sizeof(uint32_t), 61547f9c279SSumit Garg &ordinal, bloblen, blob, 0, 0); 61647f9c279SSumit Garg if (ret < 0) 61747f9c279SSumit Garg return ret; 61847f9c279SSumit Garg 61947f9c279SSumit Garg /* build and send TPM request packet */ 62047f9c279SSumit Garg tpm_buf_reset(tb, TPM_TAG_RQU_AUTH2_COMMAND, TPM_ORD_UNSEAL); 62147f9c279SSumit Garg tpm_buf_append_u32(tb, keyhandle); 62247f9c279SSumit Garg tpm_buf_append(tb, blob, bloblen); 62347f9c279SSumit Garg tpm_buf_append_u32(tb, authhandle1); 62447f9c279SSumit Garg tpm_buf_append(tb, nonceodd, TPM_NONCE_SIZE); 62547f9c279SSumit Garg tpm_buf_append_u8(tb, cont); 62647f9c279SSumit Garg tpm_buf_append(tb, authdata1, SHA1_DIGEST_SIZE); 62747f9c279SSumit Garg tpm_buf_append_u32(tb, authhandle2); 62847f9c279SSumit Garg tpm_buf_append(tb, nonceodd, TPM_NONCE_SIZE); 62947f9c279SSumit Garg tpm_buf_append_u8(tb, cont); 63047f9c279SSumit Garg tpm_buf_append(tb, authdata2, SHA1_DIGEST_SIZE); 63147f9c279SSumit Garg 63247f9c279SSumit Garg ret = trusted_tpm_send(tb->data, MAX_BUF_SIZE); 63347f9c279SSumit Garg if (ret < 0) { 63447f9c279SSumit Garg pr_info("trusted_key: authhmac failed (%d)\n", ret); 63547f9c279SSumit Garg return ret; 63647f9c279SSumit Garg } 63747f9c279SSumit Garg 63847f9c279SSumit Garg *datalen = LOAD32(tb->data, TPM_DATA_OFFSET); 63947f9c279SSumit Garg ret = TSS_checkhmac2(tb->data, ordinal, nonceodd, 64047f9c279SSumit Garg keyauth, SHA1_DIGEST_SIZE, 64147f9c279SSumit Garg blobauth, SHA1_DIGEST_SIZE, 64247f9c279SSumit Garg sizeof(uint32_t), TPM_DATA_OFFSET, 64347f9c279SSumit Garg *datalen, TPM_DATA_OFFSET + sizeof(uint32_t), 0, 64447f9c279SSumit Garg 0); 64547f9c279SSumit Garg if (ret < 0) { 64647f9c279SSumit Garg pr_info("trusted_key: TSS_checkhmac2 failed (%d)\n", ret); 64747f9c279SSumit Garg return ret; 64847f9c279SSumit Garg } 64947f9c279SSumit Garg memcpy(data, tb->data + TPM_DATA_OFFSET + sizeof(uint32_t), *datalen); 65047f9c279SSumit Garg return 0; 65147f9c279SSumit Garg } 65247f9c279SSumit Garg 65347f9c279SSumit Garg /* 65447f9c279SSumit Garg * Have the TPM seal(encrypt) the symmetric key 65547f9c279SSumit Garg */ 65647f9c279SSumit Garg static int key_seal(struct trusted_key_payload *p, 65747f9c279SSumit Garg struct trusted_key_options *o) 65847f9c279SSumit Garg { 65947f9c279SSumit Garg struct tpm_buf tb; 66047f9c279SSumit Garg int ret; 66147f9c279SSumit Garg 66247f9c279SSumit Garg ret = tpm_buf_init(&tb, 0, 0); 66347f9c279SSumit Garg if (ret) 66447f9c279SSumit Garg return ret; 66547f9c279SSumit Garg 66647f9c279SSumit Garg /* include migratable flag at end of sealed key */ 66747f9c279SSumit Garg p->key[p->key_len] = p->migratable; 66847f9c279SSumit Garg 66947f9c279SSumit Garg ret = tpm_seal(&tb, o->keytype, o->keyhandle, o->keyauth, 67047f9c279SSumit Garg p->key, p->key_len + 1, p->blob, &p->blob_len, 67147f9c279SSumit Garg o->blobauth, o->pcrinfo, o->pcrinfo_len); 67247f9c279SSumit Garg if (ret < 0) 67347f9c279SSumit Garg pr_info("trusted_key: srkseal failed (%d)\n", ret); 67447f9c279SSumit Garg 67547f9c279SSumit Garg tpm_buf_destroy(&tb); 67647f9c279SSumit Garg return ret; 67747f9c279SSumit Garg } 67847f9c279SSumit Garg 67947f9c279SSumit Garg /* 68047f9c279SSumit Garg * Have the TPM unseal(decrypt) the symmetric key 68147f9c279SSumit Garg */ 68247f9c279SSumit Garg static int key_unseal(struct trusted_key_payload *p, 68347f9c279SSumit Garg struct trusted_key_options *o) 68447f9c279SSumit Garg { 68547f9c279SSumit Garg struct tpm_buf tb; 68647f9c279SSumit Garg int ret; 68747f9c279SSumit Garg 68847f9c279SSumit Garg ret = tpm_buf_init(&tb, 0, 0); 68947f9c279SSumit Garg if (ret) 69047f9c279SSumit Garg return ret; 69147f9c279SSumit Garg 69247f9c279SSumit Garg ret = tpm_unseal(&tb, o->keyhandle, o->keyauth, p->blob, p->blob_len, 69347f9c279SSumit Garg o->blobauth, p->key, &p->key_len); 69447f9c279SSumit Garg if (ret < 0) 69547f9c279SSumit Garg pr_info("trusted_key: srkunseal failed (%d)\n", ret); 69647f9c279SSumit Garg else 69747f9c279SSumit Garg /* pull migratable flag out of sealed key */ 69847f9c279SSumit Garg p->migratable = p->key[--p->key_len]; 69947f9c279SSumit Garg 70047f9c279SSumit Garg tpm_buf_destroy(&tb); 70147f9c279SSumit Garg return ret; 70247f9c279SSumit Garg } 70347f9c279SSumit Garg 70447f9c279SSumit Garg enum { 70547f9c279SSumit Garg Opt_err, 70647f9c279SSumit Garg Opt_new, Opt_load, Opt_update, 70747f9c279SSumit Garg Opt_keyhandle, Opt_keyauth, Opt_blobauth, 70847f9c279SSumit Garg Opt_pcrinfo, Opt_pcrlock, Opt_migratable, 70947f9c279SSumit Garg Opt_hash, 71047f9c279SSumit Garg Opt_policydigest, 71147f9c279SSumit Garg Opt_policyhandle, 71247f9c279SSumit Garg }; 71347f9c279SSumit Garg 71447f9c279SSumit Garg static const match_table_t key_tokens = { 71547f9c279SSumit Garg {Opt_new, "new"}, 71647f9c279SSumit Garg {Opt_load, "load"}, 71747f9c279SSumit Garg {Opt_update, "update"}, 71847f9c279SSumit Garg {Opt_keyhandle, "keyhandle=%s"}, 71947f9c279SSumit Garg {Opt_keyauth, "keyauth=%s"}, 72047f9c279SSumit Garg {Opt_blobauth, "blobauth=%s"}, 72147f9c279SSumit Garg {Opt_pcrinfo, "pcrinfo=%s"}, 72247f9c279SSumit Garg {Opt_pcrlock, "pcrlock=%s"}, 72347f9c279SSumit Garg {Opt_migratable, "migratable=%s"}, 72447f9c279SSumit Garg {Opt_hash, "hash=%s"}, 72547f9c279SSumit Garg {Opt_policydigest, "policydigest=%s"}, 72647f9c279SSumit Garg {Opt_policyhandle, "policyhandle=%s"}, 72747f9c279SSumit Garg {Opt_err, NULL} 72847f9c279SSumit Garg }; 72947f9c279SSumit Garg 73047f9c279SSumit Garg /* can have zero or more token= options */ 73147f9c279SSumit Garg static int getoptions(char *c, struct trusted_key_payload *pay, 73247f9c279SSumit Garg struct trusted_key_options *opt) 73347f9c279SSumit Garg { 73447f9c279SSumit Garg substring_t args[MAX_OPT_ARGS]; 73547f9c279SSumit Garg char *p = c; 73647f9c279SSumit Garg int token; 73747f9c279SSumit Garg int res; 73847f9c279SSumit Garg unsigned long handle; 73947f9c279SSumit Garg unsigned long lock; 74047f9c279SSumit Garg unsigned long token_mask = 0; 74147f9c279SSumit Garg unsigned int digest_len; 74247f9c279SSumit Garg int i; 74347f9c279SSumit Garg int tpm2; 74447f9c279SSumit Garg 74547f9c279SSumit Garg tpm2 = tpm_is_tpm2(chip); 74647f9c279SSumit Garg if (tpm2 < 0) 74747f9c279SSumit Garg return tpm2; 74847f9c279SSumit Garg 74947f9c279SSumit Garg opt->hash = tpm2 ? HASH_ALGO_SHA256 : HASH_ALGO_SHA1; 75047f9c279SSumit Garg 75147f9c279SSumit Garg while ((p = strsep(&c, " \t"))) { 75247f9c279SSumit Garg if (*p == '\0' || *p == ' ' || *p == '\t') 75347f9c279SSumit Garg continue; 75447f9c279SSumit Garg token = match_token(p, key_tokens, args); 75547f9c279SSumit Garg if (test_and_set_bit(token, &token_mask)) 75647f9c279SSumit Garg return -EINVAL; 75747f9c279SSumit Garg 75847f9c279SSumit Garg switch (token) { 75947f9c279SSumit Garg case Opt_pcrinfo: 76047f9c279SSumit Garg opt->pcrinfo_len = strlen(args[0].from) / 2; 76147f9c279SSumit Garg if (opt->pcrinfo_len > MAX_PCRINFO_SIZE) 76247f9c279SSumit Garg return -EINVAL; 76347f9c279SSumit Garg res = hex2bin(opt->pcrinfo, args[0].from, 76447f9c279SSumit Garg opt->pcrinfo_len); 76547f9c279SSumit Garg if (res < 0) 76647f9c279SSumit Garg return -EINVAL; 76747f9c279SSumit Garg break; 76847f9c279SSumit Garg case Opt_keyhandle: 76947f9c279SSumit Garg res = kstrtoul(args[0].from, 16, &handle); 77047f9c279SSumit Garg if (res < 0) 77147f9c279SSumit Garg return -EINVAL; 77247f9c279SSumit Garg opt->keytype = SEAL_keytype; 77347f9c279SSumit Garg opt->keyhandle = handle; 77447f9c279SSumit Garg break; 77547f9c279SSumit Garg case Opt_keyauth: 77647f9c279SSumit Garg if (strlen(args[0].from) != 2 * SHA1_DIGEST_SIZE) 77747f9c279SSumit Garg return -EINVAL; 77847f9c279SSumit Garg res = hex2bin(opt->keyauth, args[0].from, 77947f9c279SSumit Garg SHA1_DIGEST_SIZE); 78047f9c279SSumit Garg if (res < 0) 78147f9c279SSumit Garg return -EINVAL; 78247f9c279SSumit Garg break; 78347f9c279SSumit Garg case Opt_blobauth: 78447f9c279SSumit Garg if (strlen(args[0].from) != 2 * SHA1_DIGEST_SIZE) 78547f9c279SSumit Garg return -EINVAL; 78647f9c279SSumit Garg res = hex2bin(opt->blobauth, args[0].from, 78747f9c279SSumit Garg SHA1_DIGEST_SIZE); 78847f9c279SSumit Garg if (res < 0) 78947f9c279SSumit Garg return -EINVAL; 79047f9c279SSumit Garg break; 79147f9c279SSumit Garg case Opt_migratable: 79247f9c279SSumit Garg if (*args[0].from == '0') 79347f9c279SSumit Garg pay->migratable = 0; 79447f9c279SSumit Garg else 79547f9c279SSumit Garg return -EINVAL; 79647f9c279SSumit Garg break; 79747f9c279SSumit Garg case Opt_pcrlock: 79847f9c279SSumit Garg res = kstrtoul(args[0].from, 10, &lock); 79947f9c279SSumit Garg if (res < 0) 80047f9c279SSumit Garg return -EINVAL; 80147f9c279SSumit Garg opt->pcrlock = lock; 80247f9c279SSumit Garg break; 80347f9c279SSumit Garg case Opt_hash: 80447f9c279SSumit Garg if (test_bit(Opt_policydigest, &token_mask)) 80547f9c279SSumit Garg return -EINVAL; 80647f9c279SSumit Garg for (i = 0; i < HASH_ALGO__LAST; i++) { 80747f9c279SSumit Garg if (!strcmp(args[0].from, hash_algo_name[i])) { 80847f9c279SSumit Garg opt->hash = i; 80947f9c279SSumit Garg break; 81047f9c279SSumit Garg } 81147f9c279SSumit Garg } 81247f9c279SSumit Garg if (i == HASH_ALGO__LAST) 81347f9c279SSumit Garg return -EINVAL; 81447f9c279SSumit Garg if (!tpm2 && i != HASH_ALGO_SHA1) { 81547f9c279SSumit Garg pr_info("trusted_key: TPM 1.x only supports SHA-1.\n"); 81647f9c279SSumit Garg return -EINVAL; 81747f9c279SSumit Garg } 81847f9c279SSumit Garg break; 81947f9c279SSumit Garg case Opt_policydigest: 82047f9c279SSumit Garg digest_len = hash_digest_size[opt->hash]; 82147f9c279SSumit Garg if (!tpm2 || strlen(args[0].from) != (2 * digest_len)) 82247f9c279SSumit Garg return -EINVAL; 82347f9c279SSumit Garg res = hex2bin(opt->policydigest, args[0].from, 82447f9c279SSumit Garg digest_len); 82547f9c279SSumit Garg if (res < 0) 82647f9c279SSumit Garg return -EINVAL; 82747f9c279SSumit Garg opt->policydigest_len = digest_len; 82847f9c279SSumit Garg break; 82947f9c279SSumit Garg case Opt_policyhandle: 83047f9c279SSumit Garg if (!tpm2) 83147f9c279SSumit Garg return -EINVAL; 83247f9c279SSumit Garg res = kstrtoul(args[0].from, 16, &handle); 83347f9c279SSumit Garg if (res < 0) 83447f9c279SSumit Garg return -EINVAL; 83547f9c279SSumit Garg opt->policyhandle = handle; 83647f9c279SSumit Garg break; 83747f9c279SSumit Garg default: 83847f9c279SSumit Garg return -EINVAL; 83947f9c279SSumit Garg } 84047f9c279SSumit Garg } 84147f9c279SSumit Garg return 0; 84247f9c279SSumit Garg } 84347f9c279SSumit Garg 84447f9c279SSumit Garg /* 84547f9c279SSumit Garg * datablob_parse - parse the keyctl data and fill in the 84647f9c279SSumit Garg * payload and options structures 84747f9c279SSumit Garg * 84847f9c279SSumit Garg * On success returns 0, otherwise -EINVAL. 84947f9c279SSumit Garg */ 85047f9c279SSumit Garg static int datablob_parse(char *datablob, struct trusted_key_payload *p, 85147f9c279SSumit Garg struct trusted_key_options *o) 85247f9c279SSumit Garg { 85347f9c279SSumit Garg substring_t args[MAX_OPT_ARGS]; 85447f9c279SSumit Garg long keylen; 85547f9c279SSumit Garg int ret = -EINVAL; 85647f9c279SSumit Garg int key_cmd; 85747f9c279SSumit Garg char *c; 85847f9c279SSumit Garg 85947f9c279SSumit Garg /* main command */ 86047f9c279SSumit Garg c = strsep(&datablob, " \t"); 86147f9c279SSumit Garg if (!c) 86247f9c279SSumit Garg return -EINVAL; 86347f9c279SSumit Garg key_cmd = match_token(c, key_tokens, args); 86447f9c279SSumit Garg switch (key_cmd) { 86547f9c279SSumit Garg case Opt_new: 86647f9c279SSumit Garg /* first argument is key size */ 86747f9c279SSumit Garg c = strsep(&datablob, " \t"); 86847f9c279SSumit Garg if (!c) 86947f9c279SSumit Garg return -EINVAL; 87047f9c279SSumit Garg ret = kstrtol(c, 10, &keylen); 87147f9c279SSumit Garg if (ret < 0 || keylen < MIN_KEY_SIZE || keylen > MAX_KEY_SIZE) 87247f9c279SSumit Garg return -EINVAL; 87347f9c279SSumit Garg p->key_len = keylen; 87447f9c279SSumit Garg ret = getoptions(datablob, p, o); 87547f9c279SSumit Garg if (ret < 0) 87647f9c279SSumit Garg return ret; 87747f9c279SSumit Garg ret = Opt_new; 87847f9c279SSumit Garg break; 87947f9c279SSumit Garg case Opt_load: 88047f9c279SSumit Garg /* first argument is sealed blob */ 88147f9c279SSumit Garg c = strsep(&datablob, " \t"); 88247f9c279SSumit Garg if (!c) 88347f9c279SSumit Garg return -EINVAL; 88447f9c279SSumit Garg p->blob_len = strlen(c) / 2; 88547f9c279SSumit Garg if (p->blob_len > MAX_BLOB_SIZE) 88647f9c279SSumit Garg return -EINVAL; 88747f9c279SSumit Garg ret = hex2bin(p->blob, c, p->blob_len); 88847f9c279SSumit Garg if (ret < 0) 88947f9c279SSumit Garg return -EINVAL; 89047f9c279SSumit Garg ret = getoptions(datablob, p, o); 89147f9c279SSumit Garg if (ret < 0) 89247f9c279SSumit Garg return ret; 89347f9c279SSumit Garg ret = Opt_load; 89447f9c279SSumit Garg break; 89547f9c279SSumit Garg case Opt_update: 89647f9c279SSumit Garg /* all arguments are options */ 89747f9c279SSumit Garg ret = getoptions(datablob, p, o); 89847f9c279SSumit Garg if (ret < 0) 89947f9c279SSumit Garg return ret; 90047f9c279SSumit Garg ret = Opt_update; 90147f9c279SSumit Garg break; 90247f9c279SSumit Garg case Opt_err: 90347f9c279SSumit Garg return -EINVAL; 90447f9c279SSumit Garg break; 90547f9c279SSumit Garg } 90647f9c279SSumit Garg return ret; 90747f9c279SSumit Garg } 90847f9c279SSumit Garg 90947f9c279SSumit Garg static struct trusted_key_options *trusted_options_alloc(void) 91047f9c279SSumit Garg { 91147f9c279SSumit Garg struct trusted_key_options *options; 91247f9c279SSumit Garg int tpm2; 91347f9c279SSumit Garg 91447f9c279SSumit Garg tpm2 = tpm_is_tpm2(chip); 91547f9c279SSumit Garg if (tpm2 < 0) 91647f9c279SSumit Garg return NULL; 91747f9c279SSumit Garg 91847f9c279SSumit Garg options = kzalloc(sizeof *options, GFP_KERNEL); 91947f9c279SSumit Garg if (options) { 92047f9c279SSumit Garg /* set any non-zero defaults */ 92147f9c279SSumit Garg options->keytype = SRK_keytype; 92247f9c279SSumit Garg 92347f9c279SSumit Garg if (!tpm2) 92447f9c279SSumit Garg options->keyhandle = SRKHANDLE; 92547f9c279SSumit Garg } 92647f9c279SSumit Garg return options; 92747f9c279SSumit Garg } 92847f9c279SSumit Garg 92947f9c279SSumit Garg static struct trusted_key_payload *trusted_payload_alloc(struct key *key) 93047f9c279SSumit Garg { 93147f9c279SSumit Garg struct trusted_key_payload *p = NULL; 93247f9c279SSumit Garg int ret; 93347f9c279SSumit Garg 93447f9c279SSumit Garg ret = key_payload_reserve(key, sizeof *p); 93547f9c279SSumit Garg if (ret < 0) 93647f9c279SSumit Garg return p; 93747f9c279SSumit Garg p = kzalloc(sizeof *p, GFP_KERNEL); 93847f9c279SSumit Garg if (p) 93947f9c279SSumit Garg p->migratable = 1; /* migratable by default */ 94047f9c279SSumit Garg return p; 94147f9c279SSumit Garg } 94247f9c279SSumit Garg 94347f9c279SSumit Garg /* 94447f9c279SSumit Garg * trusted_instantiate - create a new trusted key 94547f9c279SSumit Garg * 94647f9c279SSumit Garg * Unseal an existing trusted blob or, for a new key, get a 94747f9c279SSumit Garg * random key, then seal and create a trusted key-type key, 94847f9c279SSumit Garg * adding it to the specified keyring. 94947f9c279SSumit Garg * 95047f9c279SSumit Garg * On success, return 0. Otherwise return errno. 95147f9c279SSumit Garg */ 95247f9c279SSumit Garg static int trusted_instantiate(struct key *key, 95347f9c279SSumit Garg struct key_preparsed_payload *prep) 95447f9c279SSumit Garg { 95547f9c279SSumit Garg struct trusted_key_payload *payload = NULL; 95647f9c279SSumit Garg struct trusted_key_options *options = NULL; 95747f9c279SSumit Garg size_t datalen = prep->datalen; 95847f9c279SSumit Garg char *datablob; 95947f9c279SSumit Garg int ret = 0; 96047f9c279SSumit Garg int key_cmd; 96147f9c279SSumit Garg size_t key_len; 96247f9c279SSumit Garg int tpm2; 96347f9c279SSumit Garg 96447f9c279SSumit Garg tpm2 = tpm_is_tpm2(chip); 96547f9c279SSumit Garg if (tpm2 < 0) 96647f9c279SSumit Garg return tpm2; 96747f9c279SSumit Garg 96847f9c279SSumit Garg if (datalen <= 0 || datalen > 32767 || !prep->data) 96947f9c279SSumit Garg return -EINVAL; 97047f9c279SSumit Garg 97147f9c279SSumit Garg datablob = kmalloc(datalen + 1, GFP_KERNEL); 97247f9c279SSumit Garg if (!datablob) 97347f9c279SSumit Garg return -ENOMEM; 97447f9c279SSumit Garg memcpy(datablob, prep->data, datalen); 97547f9c279SSumit Garg datablob[datalen] = '\0'; 97647f9c279SSumit Garg 97747f9c279SSumit Garg options = trusted_options_alloc(); 97847f9c279SSumit Garg if (!options) { 97947f9c279SSumit Garg ret = -ENOMEM; 98047f9c279SSumit Garg goto out; 98147f9c279SSumit Garg } 98247f9c279SSumit Garg payload = trusted_payload_alloc(key); 98347f9c279SSumit Garg if (!payload) { 98447f9c279SSumit Garg ret = -ENOMEM; 98547f9c279SSumit Garg goto out; 98647f9c279SSumit Garg } 98747f9c279SSumit Garg 98847f9c279SSumit Garg key_cmd = datablob_parse(datablob, payload, options); 98947f9c279SSumit Garg if (key_cmd < 0) { 99047f9c279SSumit Garg ret = key_cmd; 99147f9c279SSumit Garg goto out; 99247f9c279SSumit Garg } 99347f9c279SSumit Garg 99447f9c279SSumit Garg if (!options->keyhandle) { 99547f9c279SSumit Garg ret = -EINVAL; 99647f9c279SSumit Garg goto out; 99747f9c279SSumit Garg } 99847f9c279SSumit Garg 99947f9c279SSumit Garg dump_payload(payload); 100047f9c279SSumit Garg dump_options(options); 100147f9c279SSumit Garg 100247f9c279SSumit Garg switch (key_cmd) { 100347f9c279SSumit Garg case Opt_load: 100447f9c279SSumit Garg if (tpm2) 10052e19e101SSumit Garg ret = tpm2_unseal_trusted(chip, payload, options); 100647f9c279SSumit Garg else 100747f9c279SSumit Garg ret = key_unseal(payload, options); 100847f9c279SSumit Garg dump_payload(payload); 100947f9c279SSumit Garg dump_options(options); 101047f9c279SSumit Garg if (ret < 0) 101147f9c279SSumit Garg pr_info("trusted_key: key_unseal failed (%d)\n", ret); 101247f9c279SSumit Garg break; 101347f9c279SSumit Garg case Opt_new: 101447f9c279SSumit Garg key_len = payload->key_len; 101547f9c279SSumit Garg ret = tpm_get_random(chip, payload->key, key_len); 101647f9c279SSumit Garg if (ret != key_len) { 101747f9c279SSumit Garg pr_info("trusted_key: key_create failed (%d)\n", ret); 101847f9c279SSumit Garg goto out; 101947f9c279SSumit Garg } 102047f9c279SSumit Garg if (tpm2) 10212e19e101SSumit Garg ret = tpm2_seal_trusted(chip, payload, options); 102247f9c279SSumit Garg else 102347f9c279SSumit Garg ret = key_seal(payload, options); 102447f9c279SSumit Garg if (ret < 0) 102547f9c279SSumit Garg pr_info("trusted_key: key_seal failed (%d)\n", ret); 102647f9c279SSumit Garg break; 102747f9c279SSumit Garg default: 102847f9c279SSumit Garg ret = -EINVAL; 102947f9c279SSumit Garg goto out; 103047f9c279SSumit Garg } 103147f9c279SSumit Garg if (!ret && options->pcrlock) 103247f9c279SSumit Garg ret = pcrlock(options->pcrlock); 103347f9c279SSumit Garg out: 1034453431a5SWaiman Long kfree_sensitive(datablob); 1035453431a5SWaiman Long kfree_sensitive(options); 103647f9c279SSumit Garg if (!ret) 103747f9c279SSumit Garg rcu_assign_keypointer(key, payload); 103847f9c279SSumit Garg else 1039453431a5SWaiman Long kfree_sensitive(payload); 104047f9c279SSumit Garg return ret; 104147f9c279SSumit Garg } 104247f9c279SSumit Garg 104347f9c279SSumit Garg static void trusted_rcu_free(struct rcu_head *rcu) 104447f9c279SSumit Garg { 104547f9c279SSumit Garg struct trusted_key_payload *p; 104647f9c279SSumit Garg 104747f9c279SSumit Garg p = container_of(rcu, struct trusted_key_payload, rcu); 1048453431a5SWaiman Long kfree_sensitive(p); 104947f9c279SSumit Garg } 105047f9c279SSumit Garg 105147f9c279SSumit Garg /* 105247f9c279SSumit Garg * trusted_update - reseal an existing key with new PCR values 105347f9c279SSumit Garg */ 105447f9c279SSumit Garg static int trusted_update(struct key *key, struct key_preparsed_payload *prep) 105547f9c279SSumit Garg { 105647f9c279SSumit Garg struct trusted_key_payload *p; 105747f9c279SSumit Garg struct trusted_key_payload *new_p; 105847f9c279SSumit Garg struct trusted_key_options *new_o; 105947f9c279SSumit Garg size_t datalen = prep->datalen; 106047f9c279SSumit Garg char *datablob; 106147f9c279SSumit Garg int ret = 0; 106247f9c279SSumit Garg 106347f9c279SSumit Garg if (key_is_negative(key)) 106447f9c279SSumit Garg return -ENOKEY; 106547f9c279SSumit Garg p = key->payload.data[0]; 106647f9c279SSumit Garg if (!p->migratable) 106747f9c279SSumit Garg return -EPERM; 106847f9c279SSumit Garg if (datalen <= 0 || datalen > 32767 || !prep->data) 106947f9c279SSumit Garg return -EINVAL; 107047f9c279SSumit Garg 107147f9c279SSumit Garg datablob = kmalloc(datalen + 1, GFP_KERNEL); 107247f9c279SSumit Garg if (!datablob) 107347f9c279SSumit Garg return -ENOMEM; 107447f9c279SSumit Garg new_o = trusted_options_alloc(); 107547f9c279SSumit Garg if (!new_o) { 107647f9c279SSumit Garg ret = -ENOMEM; 107747f9c279SSumit Garg goto out; 107847f9c279SSumit Garg } 107947f9c279SSumit Garg new_p = trusted_payload_alloc(key); 108047f9c279SSumit Garg if (!new_p) { 108147f9c279SSumit Garg ret = -ENOMEM; 108247f9c279SSumit Garg goto out; 108347f9c279SSumit Garg } 108447f9c279SSumit Garg 108547f9c279SSumit Garg memcpy(datablob, prep->data, datalen); 108647f9c279SSumit Garg datablob[datalen] = '\0'; 108747f9c279SSumit Garg ret = datablob_parse(datablob, new_p, new_o); 108847f9c279SSumit Garg if (ret != Opt_update) { 108947f9c279SSumit Garg ret = -EINVAL; 1090453431a5SWaiman Long kfree_sensitive(new_p); 109147f9c279SSumit Garg goto out; 109247f9c279SSumit Garg } 109347f9c279SSumit Garg 109447f9c279SSumit Garg if (!new_o->keyhandle) { 109547f9c279SSumit Garg ret = -EINVAL; 1096453431a5SWaiman Long kfree_sensitive(new_p); 109747f9c279SSumit Garg goto out; 109847f9c279SSumit Garg } 109947f9c279SSumit Garg 110047f9c279SSumit Garg /* copy old key values, and reseal with new pcrs */ 110147f9c279SSumit Garg new_p->migratable = p->migratable; 110247f9c279SSumit Garg new_p->key_len = p->key_len; 110347f9c279SSumit Garg memcpy(new_p->key, p->key, p->key_len); 110447f9c279SSumit Garg dump_payload(p); 110547f9c279SSumit Garg dump_payload(new_p); 110647f9c279SSumit Garg 110747f9c279SSumit Garg ret = key_seal(new_p, new_o); 110847f9c279SSumit Garg if (ret < 0) { 110947f9c279SSumit Garg pr_info("trusted_key: key_seal failed (%d)\n", ret); 1110453431a5SWaiman Long kfree_sensitive(new_p); 111147f9c279SSumit Garg goto out; 111247f9c279SSumit Garg } 111347f9c279SSumit Garg if (new_o->pcrlock) { 111447f9c279SSumit Garg ret = pcrlock(new_o->pcrlock); 111547f9c279SSumit Garg if (ret < 0) { 111647f9c279SSumit Garg pr_info("trusted_key: pcrlock failed (%d)\n", ret); 1117453431a5SWaiman Long kfree_sensitive(new_p); 111847f9c279SSumit Garg goto out; 111947f9c279SSumit Garg } 112047f9c279SSumit Garg } 112147f9c279SSumit Garg rcu_assign_keypointer(key, new_p); 112247f9c279SSumit Garg call_rcu(&p->rcu, trusted_rcu_free); 112347f9c279SSumit Garg out: 1124453431a5SWaiman Long kfree_sensitive(datablob); 1125453431a5SWaiman Long kfree_sensitive(new_o); 112647f9c279SSumit Garg return ret; 112747f9c279SSumit Garg } 112847f9c279SSumit Garg 112947f9c279SSumit Garg /* 113047f9c279SSumit Garg * trusted_read - copy the sealed blob data to userspace in hex. 113147f9c279SSumit Garg * On success, return to userspace the trusted key datablob size. 113247f9c279SSumit Garg */ 1133d3ec10aaSWaiman Long static long trusted_read(const struct key *key, char *buffer, 113447f9c279SSumit Garg size_t buflen) 113547f9c279SSumit Garg { 113647f9c279SSumit Garg const struct trusted_key_payload *p; 113747f9c279SSumit Garg char *bufp; 113847f9c279SSumit Garg int i; 113947f9c279SSumit Garg 114047f9c279SSumit Garg p = dereference_key_locked(key); 114147f9c279SSumit Garg if (!p) 114247f9c279SSumit Garg return -EINVAL; 114347f9c279SSumit Garg 114447f9c279SSumit Garg if (buffer && buflen >= 2 * p->blob_len) { 1145d3ec10aaSWaiman Long bufp = buffer; 114647f9c279SSumit Garg for (i = 0; i < p->blob_len; i++) 114747f9c279SSumit Garg bufp = hex_byte_pack(bufp, p->blob[i]); 114847f9c279SSumit Garg } 114947f9c279SSumit Garg return 2 * p->blob_len; 115047f9c279SSumit Garg } 115147f9c279SSumit Garg 115247f9c279SSumit Garg /* 115347f9c279SSumit Garg * trusted_destroy - clear and free the key's payload 115447f9c279SSumit Garg */ 115547f9c279SSumit Garg static void trusted_destroy(struct key *key) 115647f9c279SSumit Garg { 1157453431a5SWaiman Long kfree_sensitive(key->payload.data[0]); 115847f9c279SSumit Garg } 115947f9c279SSumit Garg 116047f9c279SSumit Garg struct key_type key_type_trusted = { 116147f9c279SSumit Garg .name = "trusted", 116247f9c279SSumit Garg .instantiate = trusted_instantiate, 116347f9c279SSumit Garg .update = trusted_update, 116447f9c279SSumit Garg .destroy = trusted_destroy, 116547f9c279SSumit Garg .describe = user_describe, 116647f9c279SSumit Garg .read = trusted_read, 116747f9c279SSumit Garg }; 116847f9c279SSumit Garg 116947f9c279SSumit Garg EXPORT_SYMBOL_GPL(key_type_trusted); 117047f9c279SSumit Garg 117147f9c279SSumit Garg static void trusted_shash_release(void) 117247f9c279SSumit Garg { 117347f9c279SSumit Garg if (hashalg) 117447f9c279SSumit Garg crypto_free_shash(hashalg); 117547f9c279SSumit Garg if (hmacalg) 117647f9c279SSumit Garg crypto_free_shash(hmacalg); 117747f9c279SSumit Garg } 117847f9c279SSumit Garg 117947f9c279SSumit Garg static int __init trusted_shash_alloc(void) 118047f9c279SSumit Garg { 118147f9c279SSumit Garg int ret; 118247f9c279SSumit Garg 118347f9c279SSumit Garg hmacalg = crypto_alloc_shash(hmac_alg, 0, 0); 118447f9c279SSumit Garg if (IS_ERR(hmacalg)) { 118547f9c279SSumit Garg pr_info("trusted_key: could not allocate crypto %s\n", 118647f9c279SSumit Garg hmac_alg); 118747f9c279SSumit Garg return PTR_ERR(hmacalg); 118847f9c279SSumit Garg } 118947f9c279SSumit Garg 119047f9c279SSumit Garg hashalg = crypto_alloc_shash(hash_alg, 0, 0); 119147f9c279SSumit Garg if (IS_ERR(hashalg)) { 119247f9c279SSumit Garg pr_info("trusted_key: could not allocate crypto %s\n", 119347f9c279SSumit Garg hash_alg); 119447f9c279SSumit Garg ret = PTR_ERR(hashalg); 119547f9c279SSumit Garg goto hashalg_fail; 119647f9c279SSumit Garg } 119747f9c279SSumit Garg 119847f9c279SSumit Garg return 0; 119947f9c279SSumit Garg 120047f9c279SSumit Garg hashalg_fail: 120147f9c279SSumit Garg crypto_free_shash(hmacalg); 120247f9c279SSumit Garg return ret; 120347f9c279SSumit Garg } 120447f9c279SSumit Garg 120547f9c279SSumit Garg static int __init init_digests(void) 120647f9c279SSumit Garg { 120747f9c279SSumit Garg int i; 120847f9c279SSumit Garg 120947f9c279SSumit Garg digests = kcalloc(chip->nr_allocated_banks, sizeof(*digests), 121047f9c279SSumit Garg GFP_KERNEL); 121147f9c279SSumit Garg if (!digests) 121247f9c279SSumit Garg return -ENOMEM; 121347f9c279SSumit Garg 121447f9c279SSumit Garg for (i = 0; i < chip->nr_allocated_banks; i++) 121547f9c279SSumit Garg digests[i].alg_id = chip->allocated_banks[i].alg_id; 121647f9c279SSumit Garg 121747f9c279SSumit Garg return 0; 121847f9c279SSumit Garg } 121947f9c279SSumit Garg 122047f9c279SSumit Garg static int __init init_trusted(void) 122147f9c279SSumit Garg { 122247f9c279SSumit Garg int ret; 122347f9c279SSumit Garg 122447f9c279SSumit Garg /* encrypted_keys.ko depends on successful load of this module even if 122547f9c279SSumit Garg * TPM is not used. 122647f9c279SSumit Garg */ 122747f9c279SSumit Garg chip = tpm_default_chip(); 122847f9c279SSumit Garg if (!chip) 122947f9c279SSumit Garg return 0; 123047f9c279SSumit Garg 123147f9c279SSumit Garg ret = init_digests(); 123247f9c279SSumit Garg if (ret < 0) 123347f9c279SSumit Garg goto err_put; 123447f9c279SSumit Garg ret = trusted_shash_alloc(); 123547f9c279SSumit Garg if (ret < 0) 123647f9c279SSumit Garg goto err_free; 123747f9c279SSumit Garg ret = register_key_type(&key_type_trusted); 123847f9c279SSumit Garg if (ret < 0) 123947f9c279SSumit Garg goto err_release; 124047f9c279SSumit Garg return 0; 124147f9c279SSumit Garg err_release: 124247f9c279SSumit Garg trusted_shash_release(); 124347f9c279SSumit Garg err_free: 124447f9c279SSumit Garg kfree(digests); 124547f9c279SSumit Garg err_put: 124647f9c279SSumit Garg put_device(&chip->dev); 124747f9c279SSumit Garg return ret; 124847f9c279SSumit Garg } 124947f9c279SSumit Garg 125047f9c279SSumit Garg static void __exit cleanup_trusted(void) 125147f9c279SSumit Garg { 125247f9c279SSumit Garg if (chip) { 125347f9c279SSumit Garg put_device(&chip->dev); 125447f9c279SSumit Garg kfree(digests); 125547f9c279SSumit Garg trusted_shash_release(); 125647f9c279SSumit Garg unregister_key_type(&key_type_trusted); 125747f9c279SSumit Garg } 125847f9c279SSumit Garg } 125947f9c279SSumit Garg 126047f9c279SSumit Garg late_initcall(init_trusted); 126147f9c279SSumit Garg module_exit(cleanup_trusted); 126247f9c279SSumit Garg 126347f9c279SSumit Garg MODULE_LICENSE("GPL"); 1264