[PATCH 2/2] Add TPM2 Unseal command and supporting functions
GlovePuppet
touched.by.his.noodley.appendage at gmail.com
Tue Oct 27 16:44:55 CET 2020
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 at 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,
¶meter_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/
More information about the U-Boot
mailing list