summaryrefslogtreecommitdiff
path: root/drivers/tpm
diff options
context:
space:
mode:
authorSimon Glass <sjg@chromium.org>2021-07-18 14:18:03 -0600
committerSimon Glass <sjg@chromium.org>2021-08-01 09:05:24 -0600
commitd8f105dd7170bcb0370b8ce18503834cdeeec7c1 (patch)
treee5b08bbef92a14f1e518f2fe392a21ccc7ccbc6b /drivers/tpm
parent0c0ddada656f9d642a5c3904bc225b2b4fb49fe4 (diff)
sandbox: tpm: Support nvdata in TPM2
Add support for this feature in the TPM2 emulator, to support Chromium OS vboot. Signed-off-by: Simon Glass <sjg@chromium.org>
Diffstat (limited to 'drivers/tpm')
-rw-r--r--drivers/tpm/tpm2_tis_sandbox.c68
1 files changed, 68 insertions, 0 deletions
diff --git a/drivers/tpm/tpm2_tis_sandbox.c b/drivers/tpm/tpm2_tis_sandbox.c
index c287ca2278..1d38a79a86 100644
--- a/drivers/tpm/tpm2_tis_sandbox.c
+++ b/drivers/tpm/tpm2_tis_sandbox.c
@@ -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;