]> git.dujemihanovic.xyz Git - u-boot.git/commitdiff
sandbox: tpm: Support nvdata in TPM2
authorSimon Glass <sjg@chromium.org>
Sun, 18 Jul 2021 20:18:03 +0000 (14:18 -0600)
committerSimon Glass <sjg@chromium.org>
Sun, 1 Aug 2021 15:05:24 +0000 (09:05 -0600)
Add support for this feature in the TPM2 emulator, to support Chromium OS
vboot.

Signed-off-by: Simon Glass <sjg@chromium.org>
drivers/tpm/tpm2_tis_sandbox.c
include/tpm-v2.h

index c287ca2278fc4ecc5ff05ae3703f9402ebcc11bf..1d38a79a867db82b366abc52efbb07829c3224c4 100644 (file)
@@ -11,6 +11,7 @@
 #include <asm/unaligned.h>
 #include <linux/bitops.h>
 #include <u-boot/crc.h>
+#include "sandbox_common.h"
 
 /* Hierarchies */
 enum tpm2_hierarchy {
@@ -73,6 +74,7 @@ struct sandbox_tpm2 {
        u32 properties[TPM2_PROPERTY_NB];
        u8 pcr[SANDBOX_TPM_PCR_NB][TPM2_DIGEST_LEN];
        u32 pcr_extensions[SANDBOX_TPM_PCR_NB];
+       struct nvdata_state nvdata[NV_SEQ_COUNT];
 };
 
 static struct sandbox_tpm2 s_state, *g_state;
@@ -109,6 +111,10 @@ static int sandbox_tpm2_check_session(struct udevice *dev, u32 command, u16 tag,
        case TPM2_CC_DAM_RESET:
        case TPM2_CC_DAM_PARAMETERS:
        case TPM2_CC_PCR_EXTEND:
+       case TPM2_CC_NV_READ:
+       case TPM2_CC_NV_WRITE:
+       case TPM2_CC_NV_WRITELOCK:
+       case TPM2_CC_NV_DEFINE_SPACE:
                if (tag != TPM2_ST_SESSIONS) {
                        printf("Session required for command 0x%x\n", command);
                        return TPM2_RC_AUTH_CONTEXT;
@@ -137,6 +143,10 @@ static int sandbox_tpm2_check_session(struct udevice *dev, u32 command, u16 tag,
                        break;
                case TPM2_RH_PLATFORM:
                        *hierarchy = TPM2_HIERARCHY_PLATFORM;
+                       if (command == TPM2_CC_NV_READ ||
+                           command == TPM2_CC_NV_WRITE ||
+                           command == TPM2_CC_NV_WRITELOCK)
+                               *auth += sizeof(u32);
                        break;
                default:
                        printf("Wrong handle 0x%x\n", handle);
@@ -573,6 +583,64 @@ static int sandbox_tpm2_xfer(struct udevice *dev, const u8 *sendbuf,
                sandbox_tpm2_fill_buf(recv, recv_len, tag, rc);
                break;
 
+       case TPM2_CC_NV_READ: {
+               int index, seq;
+
+               index = get_unaligned_be32(sendbuf + TPM2_HDR_LEN + 4);
+               length = get_unaligned_be16(sent);
+               /* ignore offset */
+               seq = sb_tpm_index_to_seq(index);
+               if (seq < 0)
+                       return log_msg_ret("index", -EINVAL);
+               printf("tpm: nvread index=%#02x, len=%#02x, seq=%#02x\n", index,
+                      length, seq);
+               *recv_len = TPM2_HDR_LEN + 6 + length;
+               memset(recvbuf, '\0', *recv_len);
+               put_unaligned_be32(length, recvbuf + 2);
+               sb_tpm_read_data(tpm->nvdata, seq, recvbuf,
+                                TPM2_HDR_LEN + 4 + 2, length);
+               break;
+       }
+       case TPM2_CC_NV_WRITE: {
+               int index, seq;
+
+               index = get_unaligned_be32(sendbuf + TPM2_HDR_LEN + 4);
+               length = get_unaligned_be16(sent);
+               sent += sizeof(u16);
+
+               /* ignore offset */
+               seq = sb_tpm_index_to_seq(index);
+               if (seq < 0)
+                       return log_msg_ret("index", -EINVAL);
+               printf("tpm: nvwrite index=%#02x, len=%#02x, seq=%#02x\n", index,
+                      length, seq);
+               memcpy(&tpm->nvdata[seq].data, sent, length);
+               tpm->nvdata[seq].present = true;
+               *recv_len = TPM2_HDR_LEN + 2;
+               memset(recvbuf, '\0', *recv_len);
+               break;
+       }
+       case TPM2_CC_NV_DEFINE_SPACE: {
+               int policy_size, index, seq;
+
+               policy_size = get_unaligned_be16(sent + 12);
+               index = get_unaligned_be32(sent + 2);
+               sent += 14 + policy_size;
+               length = get_unaligned_be16(sent);
+               seq = sb_tpm_index_to_seq(index);
+               if (seq < 0)
+                       return -EINVAL;
+               printf("tpm: define_space index=%x, len=%x, seq=%x, policy_size=%x\n",
+                      index, length, seq, policy_size);
+               sb_tpm_define_data(tpm->nvdata, seq, length);
+               *recv_len = 12;
+               memset(recvbuf, '\0', *recv_len);
+               break;
+       }
+       case TPM2_CC_NV_WRITELOCK:
+               *recv_len = 12;
+               memset(recvbuf, '\0', *recv_len);
+               break;
        default:
                printf("TPM2 command %02x unknown in Sandbox\n", command);
                rc = TPM2_RC_COMMAND_CODE;
index 247b386967669a460750b856d44b0b75ae2ae790..949a13c917afa2f2f8841a887fc765e22c04f7e2 100644 (file)
@@ -32,6 +32,8 @@ struct udevice;
 #define TPM2_MAX_TPM_PROPERTIES ((TPM2_MAX_CAP_BUFFER - sizeof(u32) /* TPM2_CAP */ - \
                                 sizeof(u32)) / sizeof(struct tpms_tagged_property))
 
+#define TPM2_HDR_LEN           10
+
 /*
  *  We deviate from this draft of the specification by increasing the value of
  *  TPM2_NUM_PCR_BANKS from 3 to 16 to ensure compatibility with TPM2