^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");