diff options
author | Simon Glass <sjg@chromium.org> | 2021-07-18 14:18:03 -0600 |
---|---|---|
committer | Simon Glass <sjg@chromium.org> | 2021-08-01 09:05:24 -0600 |
commit | d8f105dd7170bcb0370b8ce18503834cdeeec7c1 (patch) | |
tree | e5b08bbef92a14f1e518f2fe392a21ccc7ccbc6b /drivers/tpm | |
parent | 0c0ddada656f9d642a5c3904bc225b2b4fb49fe4 (diff) | |
download | u-boot-d8f105dd7170bcb0370b8ce18503834cdeeec7c1.tar.gz u-boot-d8f105dd7170bcb0370b8ce18503834cdeeec7c1.tar.bz2 u-boot-d8f105dd7170bcb0370b8ce18503834cdeeec7c1.zip |
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.c | 68 |
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; |