Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) #define pr_fmt(fmt) "ASYM-TPM: "fmt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5) #include <linux/export.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7) #include <linux/seq_file.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8) #include <linux/scatterlist.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9) #include <linux/tpm.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10) #include <linux/tpm_command.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11) #include <crypto/akcipher.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) #include <crypto/hash.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) #include <crypto/sha.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) #include <asm/unaligned.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) #include <keys/asymmetric-subtype.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) #include <keys/trusted_tpm.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) #include <crypto/asym_tpm_subtype.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) #include <crypto/public_key.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) #define TPM_ORD_FLUSHSPECIFIC	186
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) #define TPM_ORD_LOADKEY2	65
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) #define TPM_ORD_UNBIND		30
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) #define TPM_ORD_SIGN		60
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) #define TPM_RT_KEY                      0x00000001
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28)  * Load a TPM key from the blob provided by userspace
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) static int tpm_loadkey2(struct tpm_buf *tb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) 			uint32_t keyhandle, unsigned char *keyauth,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) 			const unsigned char *keyblob, int keybloblen,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) 			uint32_t *newhandle)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) 	unsigned char nonceodd[TPM_NONCE_SIZE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) 	unsigned char enonce[TPM_NONCE_SIZE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) 	unsigned char authdata[SHA1_DIGEST_SIZE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) 	uint32_t authhandle = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) 	unsigned char cont = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) 	uint32_t ordinal;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) 	ordinal = htonl(TPM_ORD_LOADKEY2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) 	/* session for loading the key */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) 	ret = oiap(tb, &authhandle, enonce);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) 	if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) 		pr_info("oiap failed (%d)\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) 	/* generate odd nonce */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) 	ret = tpm_get_random(NULL, nonceodd, TPM_NONCE_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) 	if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) 		pr_info("tpm_get_random failed (%d)\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) 	/* calculate authorization HMAC value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) 	ret = TSS_authhmac(authdata, keyauth, SHA1_DIGEST_SIZE, enonce,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) 			   nonceodd, cont, sizeof(uint32_t), &ordinal,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) 			   keybloblen, keyblob, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) 	/* build the request buffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) 	tpm_buf_reset(tb, TPM_TAG_RQU_AUTH1_COMMAND, TPM_ORD_LOADKEY2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) 	tpm_buf_append_u32(tb, keyhandle);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) 	tpm_buf_append(tb, keyblob, keybloblen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) 	tpm_buf_append_u32(tb, authhandle);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) 	tpm_buf_append(tb, nonceodd, TPM_NONCE_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) 	tpm_buf_append_u8(tb, cont);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) 	tpm_buf_append(tb, authdata, SHA1_DIGEST_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) 	ret = trusted_tpm_send(tb->data, MAX_BUF_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) 	if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) 		pr_info("authhmac failed (%d)\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 	ret = TSS_checkhmac1(tb->data, ordinal, nonceodd, keyauth,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 			     SHA1_DIGEST_SIZE, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 	if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 		pr_info("TSS_checkhmac1 failed (%d)\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 	*newhandle = LOAD32(tb->data, TPM_DATA_OFFSET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93)  * Execute the FlushSpecific TPM command
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) static int tpm_flushspecific(struct tpm_buf *tb, uint32_t handle)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 	tpm_buf_reset(tb, TPM_TAG_RQU_COMMAND, TPM_ORD_FLUSHSPECIFIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 	tpm_buf_append_u32(tb, handle);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) 	tpm_buf_append_u32(tb, TPM_RT_KEY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 	return trusted_tpm_send(tb->data, MAX_BUF_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105)  * Decrypt a blob provided by userspace using a specific key handle.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106)  * The handle is a well known handle or previously loaded by e.g. LoadKey2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) static int tpm_unbind(struct tpm_buf *tb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 			uint32_t keyhandle, unsigned char *keyauth,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) 			const unsigned char *blob, uint32_t bloblen,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 			void *out, uint32_t outlen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 	unsigned char nonceodd[TPM_NONCE_SIZE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 	unsigned char enonce[TPM_NONCE_SIZE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) 	unsigned char authdata[SHA1_DIGEST_SIZE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 	uint32_t authhandle = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 	unsigned char cont = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) 	uint32_t ordinal;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 	uint32_t datalen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 	ordinal = htonl(TPM_ORD_UNBIND);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) 	datalen = htonl(bloblen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) 	/* session for loading the key */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) 	ret = oiap(tb, &authhandle, enonce);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) 	if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) 		pr_info("oiap failed (%d)\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) 	/* generate odd nonce */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) 	ret = tpm_get_random(NULL, nonceodd, TPM_NONCE_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) 	if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) 		pr_info("tpm_get_random failed (%d)\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) 	/* calculate authorization HMAC value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) 	ret = TSS_authhmac(authdata, keyauth, SHA1_DIGEST_SIZE, enonce,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) 			   nonceodd, cont, sizeof(uint32_t), &ordinal,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) 			   sizeof(uint32_t), &datalen,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) 			   bloblen, blob, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) 	/* build the request buffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) 	tpm_buf_reset(tb, TPM_TAG_RQU_AUTH1_COMMAND, TPM_ORD_UNBIND);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) 	tpm_buf_append_u32(tb, keyhandle);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) 	tpm_buf_append_u32(tb, bloblen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) 	tpm_buf_append(tb, blob, bloblen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) 	tpm_buf_append_u32(tb, authhandle);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) 	tpm_buf_append(tb, nonceodd, TPM_NONCE_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) 	tpm_buf_append_u8(tb, cont);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) 	tpm_buf_append(tb, authdata, SHA1_DIGEST_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) 	ret = trusted_tpm_send(tb->data, MAX_BUF_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) 	if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) 		pr_info("authhmac failed (%d)\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) 	datalen = LOAD32(tb->data, TPM_DATA_OFFSET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) 	ret = TSS_checkhmac1(tb->data, ordinal, nonceodd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) 			     keyauth, SHA1_DIGEST_SIZE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) 			     sizeof(uint32_t), TPM_DATA_OFFSET,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) 			     datalen, TPM_DATA_OFFSET + sizeof(uint32_t),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) 			     0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) 	if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) 		pr_info("TSS_checkhmac1 failed (%d)\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) 	memcpy(out, tb->data + TPM_DATA_OFFSET + sizeof(uint32_t),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) 	       min(outlen, datalen));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) 	return datalen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182)  * Sign a blob provided by userspace (that has had the hash function applied)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183)  * using a specific key handle.  The handle is assumed to have been previously
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184)  * loaded by e.g. LoadKey2.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186)  * Note that the key signature scheme of the used key should be set to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187)  * TPM_SS_RSASSAPKCS1v15_DER.  This allows the hashed input to be of any size
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188)  * up to key_length_in_bytes - 11 and not be limited to size 20 like the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189)  * TPM_SS_RSASSAPKCS1v15_SHA1 signature scheme.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) static int tpm_sign(struct tpm_buf *tb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) 		    uint32_t keyhandle, unsigned char *keyauth,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) 		    const unsigned char *blob, uint32_t bloblen,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) 		    void *out, uint32_t outlen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) 	unsigned char nonceodd[TPM_NONCE_SIZE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) 	unsigned char enonce[TPM_NONCE_SIZE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) 	unsigned char authdata[SHA1_DIGEST_SIZE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) 	uint32_t authhandle = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) 	unsigned char cont = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) 	uint32_t ordinal;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) 	uint32_t datalen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) 	ordinal = htonl(TPM_ORD_SIGN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) 	datalen = htonl(bloblen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) 	/* session for loading the key */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) 	ret = oiap(tb, &authhandle, enonce);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) 	if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) 		pr_info("oiap failed (%d)\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) 	/* generate odd nonce */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) 	ret = tpm_get_random(NULL, nonceodd, TPM_NONCE_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) 	if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) 		pr_info("tpm_get_random failed (%d)\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) 	/* calculate authorization HMAC value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) 	ret = TSS_authhmac(authdata, keyauth, SHA1_DIGEST_SIZE, enonce,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) 			   nonceodd, cont, sizeof(uint32_t), &ordinal,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) 			   sizeof(uint32_t), &datalen,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) 			   bloblen, blob, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) 	/* build the request buffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) 	tpm_buf_reset(tb, TPM_TAG_RQU_AUTH1_COMMAND, TPM_ORD_SIGN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) 	tpm_buf_append_u32(tb, keyhandle);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) 	tpm_buf_append_u32(tb, bloblen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) 	tpm_buf_append(tb, blob, bloblen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) 	tpm_buf_append_u32(tb, authhandle);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) 	tpm_buf_append(tb, nonceodd, TPM_NONCE_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) 	tpm_buf_append_u8(tb, cont);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) 	tpm_buf_append(tb, authdata, SHA1_DIGEST_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) 	ret = trusted_tpm_send(tb->data, MAX_BUF_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) 	if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) 		pr_info("authhmac failed (%d)\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) 	datalen = LOAD32(tb->data, TPM_DATA_OFFSET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) 	ret = TSS_checkhmac1(tb->data, ordinal, nonceodd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) 			     keyauth, SHA1_DIGEST_SIZE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) 			     sizeof(uint32_t), TPM_DATA_OFFSET,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) 			     datalen, TPM_DATA_OFFSET + sizeof(uint32_t),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) 			     0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) 	if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) 		pr_info("TSS_checkhmac1 failed (%d)\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) 	memcpy(out, tb->data + TPM_DATA_OFFSET + sizeof(uint32_t),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) 	       min(datalen, outlen));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) 	return datalen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) /* Room to fit two u32 zeros for algo id and parameters length. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) #define SETKEY_PARAMS_SIZE (sizeof(u32) * 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268)  * Maximum buffer size for the BER/DER encoded public key.  The public key
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269)  * is of the form SEQUENCE { INTEGER n, INTEGER e } where n is a maximum 2048
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270)  * bit key and e is usually 65537
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271)  * The encoding overhead is:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272)  * - max 4 bytes for SEQUENCE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273)  *   - max 4 bytes for INTEGER n type/length
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274)  *     - 257 bytes of n
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275)  *   - max 2 bytes for INTEGER e type/length
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276)  *     - 3 bytes of e
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277)  * - 4+4 of zeros for set_pub_key parameters (SETKEY_PARAMS_SIZE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) #define PUB_KEY_BUF_SIZE (4 + 4 + 257 + 2 + 3 + SETKEY_PARAMS_SIZE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282)  * Provide a part of a description of the key for /proc/keys.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) static void asym_tpm_describe(const struct key *asymmetric_key,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) 			      struct seq_file *m)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) 	struct tpm_key *tk = asymmetric_key->payload.data[asym_crypto];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) 	if (!tk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) 	seq_printf(m, "TPM1.2/Blob");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) static void asym_tpm_destroy(void *payload0, void *payload3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) 	struct tpm_key *tk = payload0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) 	if (!tk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) 	kfree(tk->blob);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) 	tk->blob_len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) 	kfree(tk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) /* How many bytes will it take to encode the length */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) static inline uint32_t definite_length(uint32_t len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) 	if (len <= 127)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) 		return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) 	if (len <= 255)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) 		return 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) 	return 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) static inline uint8_t *encode_tag_length(uint8_t *buf, uint8_t tag,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) 					 uint32_t len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) 	*buf++ = tag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) 	if (len <= 127) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) 		buf[0] = len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) 		return buf + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) 	if (len <= 255) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) 		buf[0] = 0x81;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) 		buf[1] = len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) 		return buf + 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) 	buf[0] = 0x82;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) 	put_unaligned_be16(len, buf + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) 	return buf + 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) static uint32_t derive_pub_key(const void *pub_key, uint32_t len, uint8_t *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) 	uint8_t *cur = buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) 	uint32_t n_len = definite_length(len) + 1 + len + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) 	uint32_t e_len = definite_length(3) + 1 + 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) 	uint8_t e[3] = { 0x01, 0x00, 0x01 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) 	/* SEQUENCE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) 	cur = encode_tag_length(cur, 0x30, n_len + e_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) 	/* INTEGER n */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) 	cur = encode_tag_length(cur, 0x02, len + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) 	cur[0] = 0x00;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) 	memcpy(cur + 1, pub_key, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) 	cur += len + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) 	cur = encode_tag_length(cur, 0x02, sizeof(e));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) 	memcpy(cur, e, sizeof(e));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) 	cur += sizeof(e);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) 	/* Zero parameters to satisfy set_pub_key ABI. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) 	memzero_explicit(cur, SETKEY_PARAMS_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) 	return cur - buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363)  * Determine the crypto algorithm name.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) static int determine_akcipher(const char *encoding, const char *hash_algo,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) 			      char alg_name[CRYPTO_MAX_ALG_NAME])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) 	if (strcmp(encoding, "pkcs1") == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) 		if (!hash_algo) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) 			strcpy(alg_name, "pkcs1pad(rsa)");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) 			return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) 		if (snprintf(alg_name, CRYPTO_MAX_ALG_NAME, "pkcs1pad(rsa,%s)",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) 			     hash_algo) >= CRYPTO_MAX_ALG_NAME)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) 	if (strcmp(encoding, "raw") == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) 		strcpy(alg_name, "rsa");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) 	return -ENOPKG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390)  * Query information about a key.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) static int tpm_key_query(const struct kernel_pkey_params *params,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) 			 struct kernel_pkey_query *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) 	struct tpm_key *tk = params->key->payload.data[asym_crypto];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) 	char alg_name[CRYPTO_MAX_ALG_NAME];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) 	struct crypto_akcipher *tfm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) 	uint8_t der_pub_key[PUB_KEY_BUF_SIZE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) 	uint32_t der_pub_key_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) 	int len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) 	/* TPM only works on private keys, public keys still done in software */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) 	ret = determine_akcipher(params->encoding, params->hash_algo, alg_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) 	tfm = crypto_alloc_akcipher(alg_name, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) 	if (IS_ERR(tfm))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) 		return PTR_ERR(tfm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) 	der_pub_key_len = derive_pub_key(tk->pub_key, tk->pub_key_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) 					 der_pub_key);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) 	ret = crypto_akcipher_set_pub_key(tfm, der_pub_key, der_pub_key_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) 		goto error_free_tfm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) 	len = crypto_akcipher_maxsize(tfm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) 	info->key_size = tk->key_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) 	info->max_data_size = tk->key_len / 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) 	info->max_sig_size = len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) 	info->max_enc_size = len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) 	info->max_dec_size = tk->key_len / 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) 	info->supported_ops = KEYCTL_SUPPORTS_ENCRYPT |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) 			      KEYCTL_SUPPORTS_DECRYPT |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) 			      KEYCTL_SUPPORTS_VERIFY |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) 			      KEYCTL_SUPPORTS_SIGN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) 	ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) error_free_tfm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) 	crypto_free_akcipher(tfm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) 	pr_devel("<==%s() = %d\n", __func__, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440)  * Encryption operation is performed with the public key.  Hence it is done
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441)  * in software
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) static int tpm_key_encrypt(struct tpm_key *tk,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) 			   struct kernel_pkey_params *params,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) 			   const void *in, void *out)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) 	char alg_name[CRYPTO_MAX_ALG_NAME];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) 	struct crypto_akcipher *tfm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) 	struct akcipher_request *req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) 	struct crypto_wait cwait;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) 	struct scatterlist in_sg, out_sg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) 	uint8_t der_pub_key[PUB_KEY_BUF_SIZE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) 	uint32_t der_pub_key_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) 	pr_devel("==>%s()\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) 	ret = determine_akcipher(params->encoding, params->hash_algo, alg_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) 	tfm = crypto_alloc_akcipher(alg_name, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) 	if (IS_ERR(tfm))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) 		return PTR_ERR(tfm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) 	der_pub_key_len = derive_pub_key(tk->pub_key, tk->pub_key_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) 					 der_pub_key);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) 	ret = crypto_akcipher_set_pub_key(tfm, der_pub_key, der_pub_key_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) 		goto error_free_tfm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) 	ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) 	req = akcipher_request_alloc(tfm, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) 	if (!req)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) 		goto error_free_tfm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) 	sg_init_one(&in_sg, in, params->in_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) 	sg_init_one(&out_sg, out, params->out_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) 	akcipher_request_set_crypt(req, &in_sg, &out_sg, params->in_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) 				   params->out_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) 	crypto_init_wait(&cwait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) 	akcipher_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) 				      CRYPTO_TFM_REQ_MAY_SLEEP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) 				      crypto_req_done, &cwait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) 	ret = crypto_akcipher_encrypt(req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) 	ret = crypto_wait_req(ret, &cwait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) 	if (ret == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) 		ret = req->dst_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) 	akcipher_request_free(req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) error_free_tfm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) 	crypto_free_akcipher(tfm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) 	pr_devel("<==%s() = %d\n", __func__, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501)  * Decryption operation is performed with the private key in the TPM.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) static int tpm_key_decrypt(struct tpm_key *tk,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) 			   struct kernel_pkey_params *params,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) 			   const void *in, void *out)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) 	struct tpm_buf tb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) 	uint32_t keyhandle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) 	uint8_t srkauth[SHA1_DIGEST_SIZE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) 	uint8_t keyauth[SHA1_DIGEST_SIZE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) 	int r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) 	pr_devel("==>%s()\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) 	if (params->hash_algo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) 		return -ENOPKG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) 	if (strcmp(params->encoding, "pkcs1"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) 		return -ENOPKG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) 	r = tpm_buf_init(&tb, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) 	if (r)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) 		return r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) 	/* TODO: Handle a non-all zero SRK authorization */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) 	memset(srkauth, 0, sizeof(srkauth));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) 	r = tpm_loadkey2(&tb, SRKHANDLE, srkauth,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) 				tk->blob, tk->blob_len, &keyhandle);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) 	if (r < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) 		pr_devel("loadkey2 failed (%d)\n", r);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) 		goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) 	/* TODO: Handle a non-all zero key authorization */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) 	memset(keyauth, 0, sizeof(keyauth));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) 	r = tpm_unbind(&tb, keyhandle, keyauth,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) 		       in, params->in_len, out, params->out_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) 	if (r < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) 		pr_devel("tpm_unbind failed (%d)\n", r);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) 	if (tpm_flushspecific(&tb, keyhandle) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) 		pr_devel("flushspecific failed (%d)\n", r);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) 	tpm_buf_destroy(&tb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) 	pr_devel("<==%s() = %d\n", __func__, r);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) 	return r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553)  * Hash algorithm OIDs plus ASN.1 DER wrappings [RFC4880 sec 5.2.2].
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) static const u8 digest_info_md5[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) 	0x30, 0x20, 0x30, 0x0c, 0x06, 0x08,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) 	0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x02, 0x05, /* OID */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) 	0x05, 0x00, 0x04, 0x10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) static const u8 digest_info_sha1[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) 	0x30, 0x21, 0x30, 0x09, 0x06, 0x05,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) 	0x2b, 0x0e, 0x03, 0x02, 0x1a,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) 	0x05, 0x00, 0x04, 0x14
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) static const u8 digest_info_rmd160[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) 	0x30, 0x21, 0x30, 0x09, 0x06, 0x05,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) 	0x2b, 0x24, 0x03, 0x02, 0x01,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) 	0x05, 0x00, 0x04, 0x14
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) static const u8 digest_info_sha224[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) 	0x30, 0x2d, 0x30, 0x0d, 0x06, 0x09,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) 	0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x04,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) 	0x05, 0x00, 0x04, 0x1c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) static const u8 digest_info_sha256[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) 	0x30, 0x31, 0x30, 0x0d, 0x06, 0x09,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) 	0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) 	0x05, 0x00, 0x04, 0x20
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) static const u8 digest_info_sha384[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) 	0x30, 0x41, 0x30, 0x0d, 0x06, 0x09,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) 	0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x02,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) 	0x05, 0x00, 0x04, 0x30
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) static const u8 digest_info_sha512[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) 	0x30, 0x51, 0x30, 0x0d, 0x06, 0x09,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) 	0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) 	0x05, 0x00, 0x04, 0x40
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) static const struct asn1_template {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) 	const char	*name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) 	const u8	*data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) 	size_t		size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) } asn1_templates[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) #define _(X) { #X, digest_info_##X, sizeof(digest_info_##X) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) 	_(md5),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) 	_(sha1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) 	_(rmd160),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) 	_(sha256),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) 	_(sha384),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) 	_(sha512),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) 	_(sha224),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) 	{ NULL }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) #undef _
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) static const struct asn1_template *lookup_asn1(const char *name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) 	const struct asn1_template *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) 	for (p = asn1_templates; p->name; p++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) 		if (strcmp(name, p->name) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) 			return p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) 	return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625)  * Sign operation is performed with the private key in the TPM.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) static int tpm_key_sign(struct tpm_key *tk,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) 			struct kernel_pkey_params *params,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) 			const void *in, void *out)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) 	struct tpm_buf tb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) 	uint32_t keyhandle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) 	uint8_t srkauth[SHA1_DIGEST_SIZE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) 	uint8_t keyauth[SHA1_DIGEST_SIZE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) 	void *asn1_wrapped = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) 	uint32_t in_len = params->in_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) 	int r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) 	pr_devel("==>%s()\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) 	if (strcmp(params->encoding, "pkcs1"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) 		return -ENOPKG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) 	if (params->hash_algo) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) 		const struct asn1_template *asn1 =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) 						lookup_asn1(params->hash_algo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) 		if (!asn1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) 			return -ENOPKG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) 		/* request enough space for the ASN.1 template + input hash */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) 		asn1_wrapped = kzalloc(in_len + asn1->size, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) 		if (!asn1_wrapped)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) 			return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) 		/* Copy ASN.1 template, then the input */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) 		memcpy(asn1_wrapped, asn1->data, asn1->size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) 		memcpy(asn1_wrapped + asn1->size, in, in_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) 		in = asn1_wrapped;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) 		in_len += asn1->size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) 	if (in_len > tk->key_len / 8 - 11) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) 		r = -EOVERFLOW;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) 		goto error_free_asn1_wrapped;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) 	r = tpm_buf_init(&tb, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) 	if (r)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) 		goto error_free_asn1_wrapped;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) 	/* TODO: Handle a non-all zero SRK authorization */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) 	memset(srkauth, 0, sizeof(srkauth));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) 	r = tpm_loadkey2(&tb, SRKHANDLE, srkauth,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) 			 tk->blob, tk->blob_len, &keyhandle);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) 	if (r < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) 		pr_devel("loadkey2 failed (%d)\n", r);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) 		goto error_free_tb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) 	/* TODO: Handle a non-all zero key authorization */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) 	memset(keyauth, 0, sizeof(keyauth));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) 	r = tpm_sign(&tb, keyhandle, keyauth, in, in_len, out, params->out_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) 	if (r < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) 		pr_devel("tpm_sign failed (%d)\n", r);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) 	if (tpm_flushspecific(&tb, keyhandle) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) 		pr_devel("flushspecific failed (%d)\n", r);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) error_free_tb:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) 	tpm_buf_destroy(&tb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) error_free_asn1_wrapped:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) 	kfree(asn1_wrapped);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) 	pr_devel("<==%s() = %d\n", __func__, r);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) 	return r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702)  * Do encryption, decryption and signing ops.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) static int tpm_key_eds_op(struct kernel_pkey_params *params,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) 			  const void *in, void *out)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) 	struct tpm_key *tk = params->key->payload.data[asym_crypto];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) 	int ret = -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) 	/* Perform the encryption calculation. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) 	switch (params->op) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) 	case kernel_pkey_encrypt:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) 		ret = tpm_key_encrypt(tk, params, in, out);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) 	case kernel_pkey_decrypt:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) 		ret = tpm_key_decrypt(tk, params, in, out);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) 	case kernel_pkey_sign:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) 		ret = tpm_key_sign(tk, params, in, out);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) 		BUG();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729)  * Verify a signature using a public key.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) static int tpm_key_verify_signature(const struct key *key,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) 				    const struct public_key_signature *sig)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) 	const struct tpm_key *tk = key->payload.data[asym_crypto];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) 	struct crypto_wait cwait;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) 	struct crypto_akcipher *tfm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) 	struct akcipher_request *req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) 	struct scatterlist src_sg[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) 	char alg_name[CRYPTO_MAX_ALG_NAME];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) 	uint8_t der_pub_key[PUB_KEY_BUF_SIZE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) 	uint32_t der_pub_key_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) 	pr_devel("==>%s()\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) 	BUG_ON(!tk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) 	BUG_ON(!sig);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) 	BUG_ON(!sig->s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) 	if (!sig->digest)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) 		return -ENOPKG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) 	ret = determine_akcipher(sig->encoding, sig->hash_algo, alg_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) 	tfm = crypto_alloc_akcipher(alg_name, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) 	if (IS_ERR(tfm))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) 		return PTR_ERR(tfm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) 	der_pub_key_len = derive_pub_key(tk->pub_key, tk->pub_key_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) 					 der_pub_key);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) 	ret = crypto_akcipher_set_pub_key(tfm, der_pub_key, der_pub_key_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) 		goto error_free_tfm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) 	ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) 	req = akcipher_request_alloc(tfm, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) 	if (!req)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) 		goto error_free_tfm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) 	sg_init_table(src_sg, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) 	sg_set_buf(&src_sg[0], sig->s, sig->s_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) 	sg_set_buf(&src_sg[1], sig->digest, sig->digest_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) 	akcipher_request_set_crypt(req, src_sg, NULL, sig->s_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) 				   sig->digest_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) 	crypto_init_wait(&cwait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) 	akcipher_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) 				      CRYPTO_TFM_REQ_MAY_SLEEP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) 				      crypto_req_done, &cwait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) 	ret = crypto_wait_req(crypto_akcipher_verify(req), &cwait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) 	akcipher_request_free(req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) error_free_tfm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) 	crypto_free_akcipher(tfm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) 	pr_devel("<==%s() = %d\n", __func__, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) 	if (WARN_ON_ONCE(ret > 0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) 		ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794)  * Parse enough information out of TPM_KEY structure:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795)  * TPM_STRUCT_VER -> 4 bytes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796)  * TPM_KEY_USAGE -> 2 bytes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797)  * TPM_KEY_FLAGS -> 4 bytes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798)  * TPM_AUTH_DATA_USAGE -> 1 byte
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799)  * TPM_KEY_PARMS -> variable
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800)  * UINT32 PCRInfoSize -> 4 bytes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801)  * BYTE* -> PCRInfoSize bytes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802)  * TPM_STORE_PUBKEY
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803)  * UINT32 encDataSize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804)  * BYTE* -> encDataSize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806)  * TPM_KEY_PARMS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807)  * TPM_ALGORITHM_ID -> 4 bytes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808)  * TPM_ENC_SCHEME -> 2 bytes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809)  * TPM_SIG_SCHEME -> 2 bytes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810)  * UINT32 parmSize -> 4 bytes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811)  * BYTE* -> variable
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) static int extract_key_parameters(struct tpm_key *tk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) 	const void *cur = tk->blob;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) 	uint32_t len = tk->blob_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) 	const void *pub_key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) 	uint32_t sz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) 	uint32_t key_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) 	if (len < 11)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) 		return -EBADMSG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) 	/* Ensure this is a legacy key */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) 	if (get_unaligned_be16(cur + 4) != 0x0015)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) 		return -EBADMSG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) 	/* Skip to TPM_KEY_PARMS */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) 	cur += 11;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) 	len -= 11;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) 	if (len < 12)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) 		return -EBADMSG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) 	/* Make sure this is an RSA key */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) 	if (get_unaligned_be32(cur) != 0x00000001)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) 		return -EBADMSG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) 	/* Make sure this is TPM_ES_RSAESPKCSv15 encoding scheme */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) 	if (get_unaligned_be16(cur + 4) != 0x0002)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) 		return -EBADMSG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) 	/* Make sure this is TPM_SS_RSASSAPKCS1v15_DER signature scheme */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) 	if (get_unaligned_be16(cur + 6) != 0x0003)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) 		return -EBADMSG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) 	sz = get_unaligned_be32(cur + 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) 	if (len < sz + 12)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) 		return -EBADMSG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) 	/* Move to TPM_RSA_KEY_PARMS */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) 	len -= 12;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) 	cur += 12;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) 	/* Grab the RSA key length */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) 	key_len = get_unaligned_be32(cur);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) 	switch (key_len) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) 	case 512:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) 	case 1024:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) 	case 1536:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) 	case 2048:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) 	/* Move just past TPM_KEY_PARMS */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) 	cur += sz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) 	len -= sz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) 	if (len < 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) 		return -EBADMSG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) 	sz = get_unaligned_be32(cur);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) 	if (len < 4 + sz)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) 		return -EBADMSG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) 	/* Move to TPM_STORE_PUBKEY */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) 	cur += 4 + sz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) 	len -= 4 + sz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) 	/* Grab the size of the public key, it should jive with the key size */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) 	sz = get_unaligned_be32(cur);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) 	if (sz > 256)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) 	pub_key = cur + 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) 	tk->key_len = key_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) 	tk->pub_key = pub_key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) 	tk->pub_key_len = sz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) /* Given the blob, parse it and load it into the TPM */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) struct tpm_key *tpm_key_create(const void *blob, uint32_t blob_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) 	int r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) 	struct tpm_key *tk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) 	r = tpm_is_tpm2(NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) 	if (r < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) 		goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) 	/* We don't support TPM2 yet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) 	if (r > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) 		r = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) 		goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) 	r = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) 	tk = kzalloc(sizeof(struct tpm_key), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) 	if (!tk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) 		goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) 	tk->blob = kmemdup(blob, blob_len, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) 	if (!tk->blob)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) 		goto error_memdup;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) 	tk->blob_len = blob_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) 	r = extract_key_parameters(tk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) 	if (r < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) 		goto error_extract;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) 	return tk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) error_extract:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) 	kfree(tk->blob);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) 	tk->blob_len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) error_memdup:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) 	kfree(tk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) 	return ERR_PTR(r);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) EXPORT_SYMBOL_GPL(tpm_key_create);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941)  * TPM-based asymmetric key subtype
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) struct asymmetric_key_subtype asym_tpm_subtype = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) 	.owner			= THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) 	.name			= "asym_tpm",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) 	.name_len		= sizeof("asym_tpm") - 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) 	.describe		= asym_tpm_describe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) 	.destroy		= asym_tpm_destroy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) 	.query			= tpm_key_query,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) 	.eds_op			= tpm_key_eds_op,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) 	.verify_signature	= tpm_key_verify_signature,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) EXPORT_SYMBOL_GPL(asym_tpm_subtype);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) MODULE_DESCRIPTION("TPM based asymmetric key subtype");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) MODULE_AUTHOR("Intel Corporation");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) MODULE_LICENSE("GPL v2");