All of lore.kernel.org
 help / color / mirror / Atom feed
From: GlovePuppet <touched.by.his.noodley.appendage@gmail.com>
To: u-boot@lists.denx.de
Subject: [PATCH 2/2] Add TPM2 Unseal command and supporting functions
Date: Tue, 27 Oct 2020 08:44:55 -0700 (MST)	[thread overview]
Message-ID: <1603813495996-0.post@n7.nabble.com> (raw)

Unseals a loaded object, identified by handle, and returns
data at a memory location or in an environment variable

Caveats

-The PolicyPCR command only supports one PCR
-The auth request code only supports one handle

Signed-off-by: GlovePuppet <touched.by.his.noodley.appendage@gmail.com>
---

 cmd/tpm-v2.c        |  60 +++++++
 drivers/tpm/Kconfig |   7 +
 include/tpm-v2.h    |  41 +++++
 lib/tpm-v2.c        | 413 ++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 521 insertions(+)

diff --git a/cmd/tpm-v2.c b/cmd/tpm-v2.c
index e6742656f5..a94fcfabf0 100644
--- a/cmd/tpm-v2.c
+++ b/cmd/tpm-v2.c
@@ -354,6 +354,56 @@ static int do_tpm_pcr_setauthvalue(struct cmd_tbl
*cmdtp, int flag,
 							key, key_sz));
 }
 
+#if IS_ENABLED(CONFIG_TPM2_ENHANCEDAUTH_SESSIONS)
+
+static int do_tpm_unseal(struct cmd_tbl *cmdtp, int flag, int argc,
+					char *const argv[])
+{
+	struct udevice *dev;
+	u32 rc;
+	u32 handle;
+	u32 index;
+	struct tpm_chip_priv *priv;
+	u8 *data;
+	u8 buffer[129];
+	u16 data_sz;
+
+	if (argc != 4)
+		return CMD_RET_USAGE;
+
+	if (get_tpm(&dev))
+		return CMD_RET_FAILURE;
+
+	priv = dev_get_uclass_priv(dev);
+	if (!priv)
+		return CMD_RET_FAILURE;
+
+	handle = simple_strtoul(argv[1], NULL, 16);
+
+	index = simple_strtoul(argv[2], NULL, 0);
+	if (index >= priv->pcr_count)
+		return CMD_RET_USAGE;
+
+	if (*argv[3] == '*')	{
+		/* Skip the '*' */
+		data = map_sysmem(simple_strtoul(argv[3] + 1, NULL, 16), 0);
+	} else {
+		data = buffer;
+	}
+
+	rc = tpm2_do_unseal(dev, handle, index, priv->pcr_select_min, data,
&data_sz);
+
+	if (*argv[3] == '*') {
+		unmap_sysmem(data);
+	} else {
+		buffer[data_sz] = '\0';
+		env_set(argv[3], (char *)buffer);
+	}
+
+	return report_return_code(rc);
+}
+#endif /* CONFIG_TPM2_ENHANCEDAUTH_SESSIONS */
+
 static struct cmd_tbl tpm2_commands[] = {
 	U_BOOT_CMD_MKENT(device, 0, 1, do_tpm_device, "", ""),
 	U_BOOT_CMD_MKENT(info, 0, 1, do_tpm_info, "", ""),
@@ -371,6 +421,9 @@ static struct cmd_tbl tpm2_commands[] = {
 			 do_tpm_pcr_setauthpolicy, "", ""),
 	U_BOOT_CMD_MKENT(pcr_setauthvalue, 0, 1,
 			 do_tpm_pcr_setauthvalue, "", ""),
+#if IS_ENABLED(CONFIG_TPM2_ENHANCEDAUTH_SESSIONS)
+	U_BOOT_CMD_MKENT(unseal, 0, 1, do_tpm_unseal, "", ""),
+#endif /* CONFIG_TPM2_ENHANCEDAUTH_SESSIONS */
 };
 
 struct cmd_tbl *get_tpm2_commands(unsigned int *size)
@@ -442,4 +495,11 @@ U_BOOT_CMD(tpm2, CONFIG_SYS_MAXARGS, 1, do_tpm, "Issue
a TPMv2.x command",
 "    <pcr>: index of the PCR\n"
 "    <key>: secret to protect the access of PCR #<pcr>\n"
 "    <password>: optional password of the PLATFORM hierarchy\n"
+#if IS_ENABLED(CONFIG_TPM2_ENHANCEDAUTH_SESSIONS)
+"unseal <handle> <pcr> <data_addr>\n"
+"    Create a pcr policy and unseal data from the TPM, [save to env var /
*address]\n"
+"    <handle>: the handle of a loaded object\n"
+"    <pcr>: index of the pcr\n"
+"    <data_addr> env var or *address to receive the unsealed data"
+#endif /* CONFIG_TPM2_ENHANCEDAUTH_SESSIONS */
 );
diff --git a/drivers/tpm/Kconfig b/drivers/tpm/Kconfig
index 9eebab5cfd..0bdc76f181 100644
--- a/drivers/tpm/Kconfig
+++ b/drivers/tpm/Kconfig
@@ -161,6 +161,13 @@ config TPM2_FTPM_TEE
 	help
 	  This driver supports firmware TPM running in TEE.
 
+config TPM2_ENHANCEDAUTH_SESSIONS
+	bool "Enable TPM enhanced authentication session support"
+	depends on TPM_V2
+	help
+	  Enable support for enhanced authorisation commands and the TPM Unseal
+	  command.
+
 endif # TPM_V2
 
 endmenu
diff --git a/include/tpm-v2.h b/include/tpm-v2.h
index f6c045d354..ca9e11eb13 100644
--- a/include/tpm-v2.h
+++ b/include/tpm-v2.h
@@ -52,6 +52,7 @@ enum tpm2_startup_types {
  */
 enum tpm2_handles {
 	TPM2_RH_OWNER		= 0x40000001,
+	TPM2_RH_NULL        = 0x40000007,
 	TPM2_RS_PW		= 0x40000009,
 	TPM2_RH_LOCKOUT		= 0x4000000A,
 	TPM2_RH_ENDORSEMENT	= 0x4000000B,
@@ -85,9 +86,14 @@ enum tpm2_command_codes {
 	TPM2_CC_DAM_RESET	= 0x0139,
 	TPM2_CC_DAM_PARAMETERS	= 0x013A,
 	TPM2_CC_NV_READ         = 0x014E,
+	TPM2_CC_UNSEAL         = 0x015E,
+	TPM2_CC_FLUSH_CONTEXT	= 0x0165,
+	TPM2_CC_READ_PUBLIC		= 0x0173,
+	TPM2_CC_START_AUTH_SESSION = 0x0176,
 	TPM2_CC_GET_CAPABILITY	= 0x017A,
 	TPM2_CC_GET_RANDOM      = 0x017B,
 	TPM2_CC_PCR_READ	= 0x017E,
+	TPM2_CC_POLICY_PCR  = 0x017F,
 	TPM2_CC_PCR_EXTEND	= 0x0182,
 	TPM2_CC_PCR_SETAUTHVAL	= 0x0183,
 };
@@ -194,6 +200,23 @@ enum {
 	TPM_MAX_BUF_SIZE	= 1260,
 };
 
+#if IS_ENABLED(CONFIG_TPM2_ENHANCEDAUTH_SESSIONS)
+
+enum {
+	TPM_SE_HMAC		= 0,
+	TPM_SE_POLICY	= 1,
+	TPM_SE_TRIAL    = 3
+};
+
+enum {
+	TPM2_REQUEST_HEADER_LENGTH	= 10,
+	TPM2_RESPONSE_HEADER_LENGTH	= 10,
+	TPM2_REQUEST_AUTH_LENGTH	= 45,
+	TPM2_RESPONSE_AUTH_LENGTH	= 69
+};
+
+#endif /* CONFIG_TPM2_ENHANCEDAUTH_SESSIONS */
+
 /**
  * Issue a TPM2_Startup command.
  *
@@ -352,4 +375,22 @@ u32 tpm2_pcr_setauthvalue(struct udevice *dev, const
char *pw,
  */
 u32 tpm2_get_random(struct udevice *dev, void *data, u32 count);
 
+#ifdef CONFIG_TPM2_ENHANCEDAUTH_SESSIONS
+/**
+ * Perform a TPM_Unseal command sequence.
+ *
+ * @dev				 TPM device
+ * @handle			 Handle of a loaded object to be unsealed
+ * @pcr_index		 Index of the PCR
+ * @idx_min_sz		 Minimum size in bytes of the pcrSelect array
+ * @unsealed_data	 Buffer to receive the unsealed data
+ * @unsealed_data_sz Length of the unsealed data
+ *
+ * @return code of the operation
+ */
+u32 tpm2_do_unseal(struct udevice *dev, u32 handle,
+					u32 pcr_index, unsigned int idx_min_sz,
+					u8 *unsealed_data, u16 *unsealed_data_sz);
+#endif /* CONFIG_TPM2_ENHANCEDAUTH_SESSIONS */
+
 #endif /* __TPM_V2_H */
diff --git a/lib/tpm-v2.c b/lib/tpm-v2.c
index a4c352e3ef..d4b749d7aa 100644
--- a/lib/tpm-v2.c
+++ b/lib/tpm-v2.c
@@ -9,8 +9,30 @@
 #include <tpm-common.h>
 #include <tpm-v2.h>
 #include <linux/bitops.h>
+#include <u-boot/sha256.h>
 #include "tpm-utils.h"
 
+#if IS_ENABLED(CONFIG_TPM2_ENHANCEDAUTH_SESSIONS)
+
+#ifndef CONFIG_SHA256
+#error "TPM2_ENHANCEDAUTH_SESSIONS require SHA256 to be configured, too"
+#endif /* !CONFIG_SHA256 */
+
+struct session_data {
+	int valid;
+	u32 handle;
+	u8	newernonce[TPM2_DIGEST_LEN];
+	u8	oldernonce[TPM2_DIGEST_LEN];
+};
+
+struct tpm2_object {
+	u32 handle;
+	u16 hashalg;
+	u8 name[TPM2_DIGEST_LEN];
+};
+
+#endif /* CONFIG_TPM2_ENHANCEDAUTH_SESSIONS */
+
 u32 tpm2_startup(struct udevice *dev, enum tpm2_startup_types mode)
 {
 	const u8 command_v2[12] = {
@@ -466,3 +488,394 @@ u32 tpm2_get_random(struct udevice *dev, void *data,
u32 count)
 
 	return 0;
 }
+
+#if IS_ENABLED(CONFIG_TPM2_ENHANCEDAUTH_SESSIONS)
+
+static u32 tpm2_start_authsession(struct udevice *dev, u8 session_type,
const u8 *nonce,
+				  struct session_data *auth_session)
+{
+	u32 rc;
+	u16 tpm_nonce_sz;
+	size_t response_len = COMMAND_BUFFER_SIZE;
+	u8 response[COMMAND_BUFFER_SIZE];
+
+	u8 command_v2[COMMAND_BUFFER_SIZE] = {
+		tpm_u16(TPM2_ST_NO_SESSIONS),			/* TAG */
+		tpm_u32(0x1B + TPM2_DIGEST_LEN),		/* Length - fixed length nonce*/
+		tpm_u32(TPM2_CC_START_AUTH_SESSION),	/* Command code */
+
+		/* TPMI_DH_OBJECT+ */
+		tpm_u32(TPM2_RH_NULL),					/* tmpKey */
+		/* TPMI_DH_ENTITY+  */
+		tpm_u32(TPM2_RH_NULL),					/* bind */
+	};
+
+	size_t offset = 18;
+
+	if (!auth_session || auth_session->valid)
+		return TPM_LIB_ERROR;
+
+	if (pack_byte_string(command_v2, sizeof(command_v2), "wswbww",
+			     offset, TPM2_DIGEST_LEN,
+			       offset + 2, nonce, TPM2_DIGEST_LEN,
+			       offset + TPM2_DIGEST_LEN + 2, 0,
+				   offset + TPM2_DIGEST_LEN + 4, session_type,
+				   offset + TPM2_DIGEST_LEN + 5, TPM2_ALG_NULL,
+				   offset + TPM2_DIGEST_LEN + 7, TPM2_ALG_SHA256))
+		return TPM_LIB_ERROR;
+
+	rc = tpm_sendrecv_command(dev, command_v2, response, &response_len);
+	if (rc)
+		return rc;
+
+	offset = 10;
+
+	if (unpack_byte_string(response, response_len, "dw",
+			       offset, &auth_session->handle,
+			       offset + 4, &tpm_nonce_sz))
+		return TPM_LIB_ERROR;
+
+	if (unpack_byte_string(response, response_len, "s",
+			       offset + 6, auth_session->newernonce, TPM2_DIGEST_LEN))
+		return TPM_LIB_ERROR;
+
+	memcpy(auth_session->oldernonce, nonce, TPM2_DIGEST_LEN);
+	auth_session->valid = 1;
+	return rc;
+}
+
+static u32 tpm2_policypcr(struct udevice *dev, const u8 *pcr_digest, u32
idx,
+			  unsigned int idx_min_sz, u32 policy)
+{
+	u8 idx_array_sz = max(idx_min_sz, DIV_ROUND_UP(idx, 8));
+	u8 command_v2[COMMAND_BUFFER_SIZE] = {
+		tpm_u16(TPM2_ST_NO_SESSIONS),	/* TAG */
+		tpm_u32(0x1A + TPM2_DIGEST_LEN),/* Length */
+		tpm_u32(TPM2_CC_POLICY_PCR),	/* Command code */
+
+		/* TPMI_SH_POLICY */
+		tpm_u32(policy),
+
+		/* TPM2B_DIGEST */
+		tpm_u16(TPM2_DIGEST_LEN),
+	};
+
+	size_t response_len = COMMAND_BUFFER_SIZE;
+	u8 response[COMMAND_BUFFER_SIZE];
+	unsigned int pcr_sel_idx = idx / 8;
+	u8 pcr_sel_bit = BIT(idx % 8);
+
+	size_t offset = 16;
+
+	if (pack_byte_string(command_v2, COMMAND_BUFFER_SIZE, "sdwbb",
+			     offset, pcr_digest, TPM2_DIGEST_LEN,
+				 offset + TPM2_DIGEST_LEN,	1,
+				 offset + TPM2_DIGEST_LEN + 4, TPM2_ALG_SHA256,
+			     offset + TPM2_DIGEST_LEN + 4 + 2, idx_array_sz,
+			     offset + TPM2_DIGEST_LEN + 4 + 2 + 1 + pcr_sel_idx, pcr_sel_bit))
+		return TPM_LIB_ERROR;
+
+	return tpm_sendrecv_command(dev, command_v2, response, &response_len);
+}
+
+static u32 tpm2_readpublic(struct udevice *dev, u32 handle, struct
tpm2_object *object)
+{
+	size_t response_len = COMMAND_BUFFER_SIZE;
+	u32 ret;
+	u16 public_sz;
+	u16 name_sz;
+	u8 response[COMMAND_BUFFER_SIZE];
+
+	u8 command_v2[COMMAND_BUFFER_SIZE] = {
+		tpm_u16(TPM2_ST_NO_SESSIONS),			/* TAG */
+		tpm_u32(0x0E),/* Length */
+		tpm_u32(TPM2_CC_READ_PUBLIC),			/* Command code */
+		/* TPMI_SH_POLICY */
+		tpm_u32(handle)
+	};
+
+	ret = tpm_sendrecv_command(dev, command_v2, response, &response_len);
+	if (ret)
+		return ret;
+
+	size_t offset = 10;
+
+	/* skip over TPM2B_PUBLIC */
+	if (unpack_byte_string(response, response_len, "w",
+			       offset, &public_sz))
+		return TPM_LIB_ERROR;
+
+	if (unpack_byte_string(response, response_len, "ww",
+			       offset + 2 + public_sz, &name_sz,
+							offset + 2 + public_sz + 2, &object->hashalg))
+		return TPM_LIB_ERROR;
+
+	if (unpack_byte_string(response, response_len, "s",
+			       offset + 2 + public_sz + 2 + 2, object->name, TPM2_DIGEST_LEN))
+		return TPM_LIB_ERROR;
+
+	object->handle = handle;
+	return 0;
+}
+
+static u32 create_request_auth(const void *request,
+			       size_t request_len0,
+								struct tpm2_object *object,
+								struct session_data *auth_session,
+								void *request_auth,
+								const void *auth)
+{
+	size_t offset;
+	u8 names[TPM2_DIGEST_LEN + 2];
+
+	u8 hmac_data[TPM2_DIGEST_LEN * 3 + 1];
+	sha256_context ctx;
+
+	const size_t command_code_offset = 6;
+	const size_t auth_auth_offset = 45;
+	const size_t request_header_length = 10;
+
+	if (!auth_session || !auth_session->valid)
+		return TPM_LIB_ERROR;
+
+	offset = 0;
+	if (pack_byte_string(names, TPM2_DIGEST_LEN + 2, "ws",
+			     offset, object->hashalg,
+		offset + 2, object->name, TPM2_DIGEST_LEN))
+		return TPM_LIB_ERROR;
+
+	sha256_starts(&ctx);
+	sha256_update(&ctx, request + command_code_offset, 4);
+	sha256_update(&ctx, names, TPM2_DIGEST_LEN + 2);
+	if (request_len0 > request_header_length + 4)
+		sha256_update(&ctx, request + request_header_length + 4,
+			      request_len0 - request_header_length - 4);
+	sha256_finish(&ctx, hmac_data);
+
+	/* Populate the authorization session */
+	if (pack_byte_string(request_auth, TPM2_REQUEST_AUTH_LENGTH, "ddwsbw",
+			     offset, 0x49,
+							/* authHandle */
+							offset + 4, auth_session->handle,
+							/* nonceCallerSize */
+							offset + 8, TPM2_DIGEST_LEN,
+							/* nonceCaller */
+							offset + 8 + 2,	auth_session->newernonce, TPM2_DIGEST_LEN,
+							/* sessionAttributes (continueSession=1) */
+							offset + 8 + 2 + TPM2_DIGEST_LEN, 1,
+							/* hmacSize */
+							offset + 8 + 2 + TPM2_DIGEST_LEN + 1, TPM2_DIGEST_LEN))
+		return TPM_LIB_ERROR;
+
+	offset = TPM2_DIGEST_LEN;
+
+	if (pack_byte_string(hmac_data, sizeof(hmac_data), "ssb",
+			     offset, auth_session->newernonce, TPM2_DIGEST_LEN,
+			     offset + TPM2_DIGEST_LEN, auth_session->oldernonce,
TPM2_DIGEST_LEN,
+				 offset + (2 * TPM2_DIGEST_LEN), 1))	/* continue */
+		return TPM_LIB_ERROR;
+
+	sha256_hmac(auth,
+		    TPM2_DIGEST_LEN,
+			hmac_data,
+			TPM2_DIGEST_LEN * 3 + 1,
+			request_auth + auth_auth_offset);
+
+	return 0;
+}
+
+static u32 verify_response_auth(u32 command_code, const void *response,
+				size_t response_len0, size_t handles_len,
+									struct session_data *auth_session,
+									void *response_auth, const void *auth)
+{
+	u8 cc_data[4];
+	u8 hmac[TPM2_DIGEST_LEN];
+	u8 hmac_data[TPM2_DIGEST_LEN * 3 + 1];
+	u16 tpmnonce_sz;
+	u16 hmac_sz;
+	u8 auth_continue;
+
+	sha256_context ctx;
+	const size_t return_code_offset = 6;
+	const size_t response_header_length = 10;
+
+	if (!auth_session || !auth_session->valid)
+		return TPM_LIB_ERROR;
+
+	size_t offset = 0;
+
+	if (pack_byte_string(cc_data, sizeof(cc_data), "d",
+			     offset, command_code))
+		return TPM_LIB_ERROR;
+
+	sha256_starts(&ctx);
+	sha256_update(&ctx, response + return_code_offset, 4);
+	sha256_update(&ctx, cc_data, 4);
+	if (response_len0 > response_header_length + handles_len + 4)
+		sha256_update(&ctx,
+			      response + response_header_length + handles_len + 4,
+					response_len0 - response_header_length
+					- handles_len - 4);
+	sha256_finish(&ctx, hmac_data);
+
+	/* Nonce rotation */
+	memcpy(auth_session->oldernonce, auth_session->newernonce,
TPM2_DIGEST_LEN);
+
+	if (unpack_byte_string(response_auth, TPM2_RESPONSE_AUTH_LENGTH, "w",
+			       offset, &tpmnonce_sz))
+		return TPM_LIB_ERROR;
+
+	if (unpack_byte_string(response_auth, TPM2_RESPONSE_AUTH_LENGTH, "sbw",
+			       offset + 2, auth_session->newernonce, tpmnonce_sz,
+			   offset + 2 + tpmnonce_sz, &auth_continue,
+			   offset + 2 + tpmnonce_sz + 1, &hmac_sz))
+		return TPM_LIB_ERROR;
+
+	offset = TPM2_DIGEST_LEN;
+
+	if (pack_byte_string(hmac_data, sizeof(hmac_data), "ssb",
+			     offset, auth_session->newernonce, TPM2_DIGEST_LEN,
+				 offset + TPM2_DIGEST_LEN, auth_session->oldernonce, TPM2_DIGEST_LEN,
+				 offset + (2 * TPM2_DIGEST_LEN), auth_continue))
+		return TPM_LIB_ERROR;
+
+	sha256_hmac(auth, TPM2_DIGEST_LEN, hmac_data, TPM2_DIGEST_LEN * 3 + 1,
hmac);
+
+	/* Check for / fix timing leaks here */
+	return memcmp(response_auth + 2 + tpmnonce_sz + 1 + 2,
+					hmac, TPM2_DIGEST_LEN) == 0 ? 0 : TPM_LIB_ERROR;
+}
+
+static u32 tpm2_unseal(struct udevice *dev, u8 *nonce,
+		       struct session_data *auth_session,
+			struct tpm2_object *object,
+			void *data, u16 *data_sz)
+{
+	u16 parameter_sz;
+	size_t request_len0, response_len0, response_len = COMMAND_BUFFER_SIZE;
+	size_t offset;
+	u32 ret;
+	u8 response[COMMAND_BUFFER_SIZE];
+	u8 hmac_key[TPM2_DIGEST_LEN];
+
+	memset(hmac_key, 0, TPM2_DIGEST_LEN);
+
+	u8 command_v2[COMMAND_BUFFER_SIZE] = {
+		tpm_u16(TPM2_ST_SESSIONS),				/* TAG */
+		tpm_u32(0x5B),							/* Length */
+		tpm_u32(TPM2_CC_UNSEAL),				/* Command code */
+		tpm_u32(object->handle),
+	};
+
+	/* rotate the nonces */
+	memcpy(auth_session->oldernonce, auth_session->newernonce,
TPM2_DIGEST_LEN);
+	memcpy(auth_session->newernonce, nonce, TPM2_DIGEST_LEN);
+
+	request_len0 = 0x0E;
+
+	if (create_request_auth(command_v2,
+				request_len0,
+		object,
+		auth_session,
+		&command_v2[request_len0], hmac_key))
+		return TPM_LIB_ERROR;
+
+	ret = tpm_sendrecv_command(dev, command_v2, response, &response_len);
+	if (ret)
+		return ret;
+
+	offset = 10;
+	if (unpack_byte_string(response, response_len, "d", offset,
&parameter_sz))
+		return TPM_LIB_ERROR;
+
+	response_len0 = response_len - TPM2_RESPONSE_AUTH_LENGTH;
+	if (verify_response_auth(TPM2_CC_UNSEAL,
+				 response,
+						response_len0,
+						0,
+						auth_session,
+						&response[response_len0], hmac_key))
+		return TPM_LIB_ERROR;
+
+	if (unpack_byte_string(response, response_len, "w", offset + 4, data_sz))
+		return TPM_LIB_ERROR;
+
+	if (unpack_byte_string(response, response_len, "s", offset + 6, data,
*data_sz))
+		return TPM_LIB_ERROR;
+
+	return ret;
+}
+
+static u32 tpm2_flushcontext(struct udevice *dev, struct session_data
*auth_session)
+{
+	u32 rc;
+	size_t response_len = COMMAND_BUFFER_SIZE;
+	u8 response[COMMAND_BUFFER_SIZE];
+
+	u8 command_v2[COMMAND_BUFFER_SIZE] = {
+		tpm_u16(TPM2_ST_NO_SESSIONS),			/* TAG */
+		tpm_u32(0x0E),							/* Length */
+		tpm_u32(TPM2_CC_FLUSH_CONTEXT),		/* Command code */
+		/* TPMI_SH_POLICY */
+		tpm_u32(auth_session->handle)
+	};
+
+	if (!auth_session || !auth_session->valid)
+		return TPM_LIB_ERROR;
+
+	rc = tpm_sendrecv_command(dev, command_v2, response, &response_len);
+	if (rc)
+		return rc;
+
+	auth_session->valid = 0;
+
+	return 0;
+}
+
+u32 tpm2_do_unseal(struct udevice *dev, u32 handle, u32 pcr_index, unsigned
int idx_min_sz,
+		   u8 *unsealed_data, u16 *unsealed_data_sz)
+{
+	sha256_context ctx;
+	u32 rc;
+	u8 nonce[TPM2_DIGEST_LEN];
+	u8 pcr_data[TPM2_DIGEST_LEN];
+	u8 pcr_data_digest[TPM2_DIGEST_LEN];
+	unsigned int updates;
+	struct tpm2_object object;
+	struct session_data auth_session = {0, };
+
+	memset(nonce, 0, TPM2_DIGEST_LEN);
+
+	rc =  tpm2_start_authsession(dev, TPM_SE_POLICY, nonce, &auth_session);
+	if (rc)
+		return rc;
+
+	rc = tpm2_pcr_read(dev, pcr_index, idx_min_sz, pcr_data, &updates);
+	if (rc)
+		return rc;
+
+	sha256_starts(&ctx);
+	sha256_update(&ctx, pcr_data, TPM2_DIGEST_LEN);
+	sha256_finish(&ctx, pcr_data_digest);
+
+	rc = tpm2_policypcr(dev, pcr_data_digest, pcr_index, idx_min_sz,
auth_session.handle);
+	if (rc)
+		return rc;
+
+	rc = tpm2_readpublic(dev, handle, &object);
+	if (rc)
+		return rc;
+
+	rc = tpm2_unseal(dev, nonce, &auth_session, &object, unsealed_data,
unsealed_data_sz);
+	if (rc)
+		return rc;
+
+	rc = tpm2_flushcontext(dev, &auth_session);
+	if (rc)
+		return rc;
+
+	return 0;
+}
+
+#endif /* CONFIG_TPM2_ENHANCEDAUTH_SESSIONS */
-- 
2.17.1




--
Sent from: http://u-boot.10912.n7.nabble.com/

             reply	other threads:[~2020-10-27 15:44 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-10-27 15:44 GlovePuppet [this message]
2020-10-28  7:29 ` [PATCH 2/2] Add TPM2 Unseal command and supporting functions Wolfgang Denk

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1603813495996-0.post@n7.nabble.com \
    --to=touched.by.his.noodley.appendage@gmail.com \
    --cc=u-boot@lists.denx.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.