[PATCH 6/8] tpm: Fix issues relating to NV Indexes

seanedmond
2023-09-12T09:48:06Z

From: Sean Edmond <seanedmond@microsoft.com>

The TPM 2.0 command reference states that "auth" (type TPM2B_AUTH)
should come before "publicInfo" (type TPM2B_NV_PUBLIC) in the
"TPM2_NV_DefineSpace" command. Let's add an empty "auth" (size 0), so
that this can work with compliant TPMs.

Make sure that NV index used in tpm2_nv_define_space() can be used
directly in the NV read/write/lock APIs.

Signed-off-by: Sean Edmond <seanedmond@microsoft.com>
---
lib/tpm-v2.c | 20 ++++++++++++++------
1 file changed, 14 insertions(+), 6 deletions(-)

diff --git a/lib/tpm-v2.c b/lib/tpm-v2.c
index c3c469eb35..d3ecf556d2 100644
--- a/lib/tpm-v2.c
+++ b/lib/tpm-v2.c
@@ -109,7 +109,7 @@ u32 tpm2_nv_define_space(struct udevice *dev, u32 space_index,
const int platform_len = sizeof(u32);
const int session_hdr_len = 13;
const int message_len = 14;
- uint offset = TPM2_HDR_LEN + platform_len + session_hdr_len +
+ uint offset = TPM2_HDR_LEN + platform_len + session_hdr_len + 2 +
message_len;
u8 command_v2[COMMAND_BUFFER_SIZE] = {
/* header 10 bytes */
@@ -127,6 +127,9 @@ u32 tpm2_nv_define_space(struct udevice *dev, u32 space_index,
0, /* session_attrs */
tpm_u16(0), /* auth_size */

+ /* auth value */
+ tpm_u16(0),
+
/* message 14 bytes + policy */
tpm_u16(message_len + nv_policy_size), /* size */
tpm_u32(space_index),
@@ -206,7 +209,7 @@ u32 tpm2_nv_read_value(struct udevice *dev, u32 index, void *data, u32 count)

/* handles 8 bytes */
tpm_u32(TPM2_RH_PLATFORM), /* Primary platform seed */
- tpm_u32(HR_NV_INDEX + index), /* Password authorisation */
+ tpm_u32(index), /* nvIndex */

/* AUTH_SESSION */
tpm_u32(9), /* Authorization size */
@@ -229,9 +232,14 @@ u32 tpm2_nv_read_value(struct udevice *dev, u32 index, void *data, u32 count)
ret = tpm_sendrecv_command(dev, command_v2, response, &response_len);
if (ret)
return log_msg_ret("read", ret);
+
+ const size_t tag_offset = 0;
+ const size_t size_offset = 2;
+ const size_t code_offset = 6;
+ const size_t data_offset = 16;
if (unpack_byte_string(response, response_len, "wdds",
- 0, &tag, 2, &size, 6, &code,
- 16, data, count))
+ tag_offset, &tag, size_offset, &size, code_offset, &code,
+ data_offset, data, count))
return TPM_LIB_ERROR;

return 0;
@@ -254,7 +262,7 @@ u32 tpm2_nv_write_value(struct udevice *dev, u32 index, const void *data,

/* handles 8 bytes */
tpm_u32(auth), /* Primary platform seed */
- tpm_u32(HR_NV_INDEX + index), /* Password authorisation */
+ tpm_u32(index), /* nvIndex */

/* AUTH_SESSION */
tpm_u32(9), /* Authorization size */
@@ -643,7 +651,7 @@ u32 tpm2_write_lock(struct udevice *dev, u32 index)

/* handles 8 bytes */
tpm_u32(TPM2_RH_PLATFORM), /* Primary platform seed */
- tpm_u32(HR_NV_INDEX + index), /* Password authorisation */
+ tpm_u32(index), /* nvIndex */

/* session header 9 bytes */
tpm_u32(9), /* Header size */
--
2.40.0