1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Copyright (C) 2004 IBM Corporation 4 * Copyright (C) 2014 Intel Corporation 5 */ 6 7 #include <linux/string.h> 8 #include <linux/err.h> 9 #include <linux/tpm.h> 10 #include <linux/tpm_command.h> 11 12 #include <keys/trusted-type.h> 13 #include <keys/trusted_tpm.h> 14 15 static struct tpm2_hash tpm2_hash_map[] = { 16 {HASH_ALGO_SHA1, TPM_ALG_SHA1}, 17 {HASH_ALGO_SHA256, TPM_ALG_SHA256}, 18 {HASH_ALGO_SHA384, TPM_ALG_SHA384}, 19 {HASH_ALGO_SHA512, TPM_ALG_SHA512}, 20 {HASH_ALGO_SM3_256, TPM_ALG_SM3_256}, 21 }; 22 23 /** 24 * tpm_buf_append_auth() - append TPMS_AUTH_COMMAND to the buffer. 25 * 26 * @buf: an allocated tpm_buf instance 27 * @session_handle: session handle 28 * @nonce: the session nonce, may be NULL if not used 29 * @nonce_len: the session nonce length, may be 0 if not used 30 * @attributes: the session attributes 31 * @hmac: the session HMAC or password, may be NULL if not used 32 * @hmac_len: the session HMAC or password length, maybe 0 if not used 33 */ 34 static void tpm2_buf_append_auth(struct tpm_buf *buf, u32 session_handle, 35 const u8 *nonce, u16 nonce_len, 36 u8 attributes, 37 const u8 *hmac, u16 hmac_len) 38 { 39 tpm_buf_append_u32(buf, 9 + nonce_len + hmac_len); 40 tpm_buf_append_u32(buf, session_handle); 41 tpm_buf_append_u16(buf, nonce_len); 42 43 if (nonce && nonce_len) 44 tpm_buf_append(buf, nonce, nonce_len); 45 46 tpm_buf_append_u8(buf, attributes); 47 tpm_buf_append_u16(buf, hmac_len); 48 49 if (hmac && hmac_len) 50 tpm_buf_append(buf, hmac, hmac_len); 51 } 52 53 /** 54 * tpm2_seal_trusted() - seal the payload of a trusted key 55 * 56 * @chip: TPM chip to use 57 * @payload: the key data in clear and encrypted form 58 * @options: authentication values and other options 59 * 60 * Return: < 0 on error and 0 on success. 61 */ 62 int tpm2_seal_trusted(struct tpm_chip *chip, 63 struct trusted_key_payload *payload, 64 struct trusted_key_options *options) 65 { 66 unsigned int blob_len; 67 struct tpm_buf buf; 68 u32 hash; 69 int i; 70 int rc; 71 72 for (i = 0; i < ARRAY_SIZE(tpm2_hash_map); i++) { 73 if (options->hash == tpm2_hash_map[i].crypto_id) { 74 hash = tpm2_hash_map[i].tpm_id; 75 break; 76 } 77 } 78 79 if (i == ARRAY_SIZE(tpm2_hash_map)) 80 return -EINVAL; 81 82 rc = tpm_buf_init(&buf, TPM2_ST_SESSIONS, TPM2_CC_CREATE); 83 if (rc) 84 return rc; 85 86 rc = tpm_buf_init(&buf, TPM2_ST_SESSIONS, TPM2_CC_CREATE); 87 if (rc) { 88 tpm_put_ops(chip); 89 return rc; 90 } 91 92 tpm_buf_append_u32(&buf, options->keyhandle); 93 tpm2_buf_append_auth(&buf, TPM2_RS_PW, 94 NULL /* nonce */, 0, 95 0 /* session_attributes */, 96 options->keyauth /* hmac */, 97 TPM_DIGEST_SIZE); 98 99 /* sensitive */ 100 tpm_buf_append_u16(&buf, 4 + options->blobauth_len + payload->key_len + 1); 101 102 tpm_buf_append_u16(&buf, options->blobauth_len); 103 if (options->blobauth_len) 104 tpm_buf_append(&buf, options->blobauth, options->blobauth_len); 105 106 tpm_buf_append_u16(&buf, payload->key_len + 1); 107 tpm_buf_append(&buf, payload->key, payload->key_len); 108 tpm_buf_append_u8(&buf, payload->migratable); 109 110 /* public */ 111 tpm_buf_append_u16(&buf, 14 + options->policydigest_len); 112 tpm_buf_append_u16(&buf, TPM_ALG_KEYEDHASH); 113 tpm_buf_append_u16(&buf, hash); 114 115 /* policy */ 116 if (options->policydigest_len) { 117 tpm_buf_append_u32(&buf, 0); 118 tpm_buf_append_u16(&buf, options->policydigest_len); 119 tpm_buf_append(&buf, options->policydigest, 120 options->policydigest_len); 121 } else { 122 tpm_buf_append_u32(&buf, TPM2_OA_USER_WITH_AUTH); 123 tpm_buf_append_u16(&buf, 0); 124 } 125 126 /* public parameters */ 127 tpm_buf_append_u16(&buf, TPM_ALG_NULL); 128 tpm_buf_append_u16(&buf, 0); 129 130 /* outside info */ 131 tpm_buf_append_u16(&buf, 0); 132 133 /* creation PCR */ 134 tpm_buf_append_u32(&buf, 0); 135 136 if (buf.flags & TPM_BUF_OVERFLOW) { 137 rc = -E2BIG; 138 goto out; 139 } 140 141 rc = tpm_transmit_cmd(chip, &buf, 4, "sealing data"); 142 if (rc) 143 goto out; 144 145 blob_len = be32_to_cpup((__be32 *) &buf.data[TPM_HEADER_SIZE]); 146 if (blob_len > MAX_BLOB_SIZE) { 147 rc = -E2BIG; 148 goto out; 149 } 150 if (tpm_buf_length(&buf) < TPM_HEADER_SIZE + 4 + blob_len) { 151 rc = -EFAULT; 152 goto out; 153 } 154 155 memcpy(payload->blob, &buf.data[TPM_HEADER_SIZE + 4], blob_len); 156 payload->blob_len = blob_len; 157 158 out: 159 tpm_buf_destroy(&buf); 160 161 if (rc > 0) { 162 if (tpm2_rc_value(rc) == TPM2_RC_HASH) 163 rc = -EINVAL; 164 else 165 rc = -EPERM; 166 } 167 168 tpm_put_ops(chip); 169 return rc; 170 } 171 172 /** 173 * tpm2_load_cmd() - execute a TPM2_Load command 174 * 175 * @chip: TPM chip to use 176 * @payload: the key data in clear and encrypted form 177 * @options: authentication values and other options 178 * @blob_handle: returned blob handle 179 * 180 * Return: 0 on success. 181 * -E2BIG on wrong payload size. 182 * -EPERM on tpm error status. 183 * < 0 error from tpm_send. 184 */ 185 static int tpm2_load_cmd(struct tpm_chip *chip, 186 struct trusted_key_payload *payload, 187 struct trusted_key_options *options, 188 u32 *blob_handle) 189 { 190 struct tpm_buf buf; 191 unsigned int private_len; 192 unsigned int public_len; 193 unsigned int blob_len; 194 int rc; 195 196 private_len = be16_to_cpup((__be16 *) &payload->blob[0]); 197 if (private_len > (payload->blob_len - 2)) 198 return -E2BIG; 199 200 public_len = be16_to_cpup((__be16 *) &payload->blob[2 + private_len]); 201 blob_len = private_len + public_len + 4; 202 if (blob_len > payload->blob_len) 203 return -E2BIG; 204 205 rc = tpm_buf_init(&buf, TPM2_ST_SESSIONS, TPM2_CC_LOAD); 206 if (rc) 207 return rc; 208 209 tpm_buf_append_u32(&buf, options->keyhandle); 210 tpm2_buf_append_auth(&buf, TPM2_RS_PW, 211 NULL /* nonce */, 0, 212 0 /* session_attributes */, 213 options->keyauth /* hmac */, 214 TPM_DIGEST_SIZE); 215 216 tpm_buf_append(&buf, payload->blob, blob_len); 217 218 if (buf.flags & TPM_BUF_OVERFLOW) { 219 rc = -E2BIG; 220 goto out; 221 } 222 223 rc = tpm_transmit_cmd(chip, &buf, 4, "loading blob"); 224 if (!rc) 225 *blob_handle = be32_to_cpup( 226 (__be32 *) &buf.data[TPM_HEADER_SIZE]); 227 228 out: 229 tpm_buf_destroy(&buf); 230 231 if (rc > 0) 232 rc = -EPERM; 233 234 return rc; 235 } 236 237 /** 238 * tpm2_unseal_cmd() - execute a TPM2_Unload command 239 * 240 * @chip: TPM chip to use 241 * @payload: the key data in clear and encrypted form 242 * @options: authentication values and other options 243 * @blob_handle: blob handle 244 * 245 * Return: 0 on success 246 * -EPERM on tpm error status 247 * < 0 error from tpm_send 248 */ 249 static int tpm2_unseal_cmd(struct tpm_chip *chip, 250 struct trusted_key_payload *payload, 251 struct trusted_key_options *options, 252 u32 blob_handle) 253 { 254 struct tpm_buf buf; 255 u16 data_len; 256 u8 *data; 257 int rc; 258 259 rc = tpm_buf_init(&buf, TPM2_ST_SESSIONS, TPM2_CC_UNSEAL); 260 if (rc) 261 return rc; 262 263 tpm_buf_append_u32(&buf, blob_handle); 264 tpm2_buf_append_auth(&buf, 265 options->policyhandle ? 266 options->policyhandle : TPM2_RS_PW, 267 NULL /* nonce */, 0, 268 TPM2_SA_CONTINUE_SESSION, 269 options->blobauth /* hmac */, 270 options->blobauth_len); 271 272 rc = tpm_transmit_cmd(chip, &buf, 6, "unsealing"); 273 if (rc > 0) 274 rc = -EPERM; 275 276 if (!rc) { 277 data_len = be16_to_cpup( 278 (__be16 *) &buf.data[TPM_HEADER_SIZE + 4]); 279 if (data_len < MIN_KEY_SIZE || data_len > MAX_KEY_SIZE + 1) { 280 rc = -EFAULT; 281 goto out; 282 } 283 284 if (tpm_buf_length(&buf) < TPM_HEADER_SIZE + 6 + data_len) { 285 rc = -EFAULT; 286 goto out; 287 } 288 data = &buf.data[TPM_HEADER_SIZE + 6]; 289 290 memcpy(payload->key, data, data_len - 1); 291 payload->key_len = data_len - 1; 292 payload->migratable = data[data_len - 1]; 293 } 294 295 out: 296 tpm_buf_destroy(&buf); 297 return rc; 298 } 299 300 /** 301 * tpm2_unseal_trusted() - unseal the payload of a trusted key 302 * 303 * @chip: TPM chip to use 304 * @payload: the key data in clear and encrypted form 305 * @options: authentication values and other options 306 * 307 * Return: Same as with tpm_send. 308 */ 309 int tpm2_unseal_trusted(struct tpm_chip *chip, 310 struct trusted_key_payload *payload, 311 struct trusted_key_options *options) 312 { 313 u32 blob_handle; 314 int rc; 315 316 rc = tpm_try_get_ops(chip); 317 if (rc) 318 return rc; 319 320 rc = tpm2_load_cmd(chip, payload, options, &blob_handle); 321 if (rc) 322 goto out; 323 324 rc = tpm2_unseal_cmd(chip, payload, options, blob_handle); 325 tpm2_flush_context(chip, blob_handle); 326 327 out: 328 tpm_put_ops(chip); 329 330 return rc; 331 } 332