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