diff options
author | Yi Chou <yich@google.com> | 2023-02-06 12:01:58 +0800 |
---|---|---|
committer | Chromeos LUCI <chromeos-scoped@luci-project-accounts.iam.gserviceaccount.com> | 2023-04-10 08:58:24 +0000 |
commit | c2491cfab74685fb5a0f30dc3e7c1fadbc47adb3 (patch) | |
tree | 3cc394f5f556119f0b581ca3516fddbef63955b4 | |
parent | 39f0d38bcd104fd4d1ffbcc6aa3a754566c97070 (diff) | |
download | vboot-c2491cfab74685fb5a0f30dc3e7c1fadbc47adb3.tar.gz |
tlcl: Add `TlclReadPublic()` support
Add support for the TPM2_ReadPublic command to the TLCL.
This command is used to read the public area data of an object with the
object handle.
BUG=b:249552664
BRANCH=None
TEST=TlclReadPublic works.
Signed-off-by: Yi Chou <yich@google.com>
Change-Id: I5d72b8f19e02c6bdcc39f1c20ff7100f5dd0eda1
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/vboot_reference/+/4218847
Reviewed-by: Yu-Ping Wu <yupingso@chromium.org>
-rw-r--r-- | firmware/include/tlcl.h | 7 | ||||
-rw-r--r-- | firmware/include/tpm2_tss_constants.h | 19 | ||||
-rw-r--r-- | firmware/lib/tpm2_lite/marshaling.c | 49 | ||||
-rw-r--r-- | firmware/lib/tpm2_lite/tlcl.c | 39 |
4 files changed, 114 insertions, 0 deletions
diff --git a/firmware/include/tlcl.h b/firmware/include/tlcl.h index 42e3bab9..c4d0c153 100644 --- a/firmware/include/tlcl.h +++ b/firmware/include/tlcl.h @@ -264,6 +264,13 @@ uint32_t TlclGetVersion(uint32_t* vendor, uint64_t* firmware_version, */ uint32_t TlclIFXFieldUpgradeInfo(TPM_IFX_FIELDUPGRADEINFO *info); +/** + * Read the public area of object. Put at most [length] bytes public area + * into [data], and the format of [data] is TPM2B_PUBLIC. The TPM error code + * is returned. + */ +uint32_t TlclReadPublic(uint32_t handle, uint8_t *data, uint32_t *length); + #ifdef CHROMEOS_ENVIRONMENT /** diff --git a/firmware/include/tpm2_tss_constants.h b/firmware/include/tpm2_tss_constants.h index f215a3c5..91bcbec6 100644 --- a/firmware/include/tpm2_tss_constants.h +++ b/firmware/include/tpm2_tss_constants.h @@ -32,6 +32,7 @@ extern "C" { #define TPM2_NV_Read ((TPM_CC)0x0000014E) #define TPM2_NV_ReadLock ((TPM_CC)0x0000014F) #define TPM2_NV_ReadPublic ((TPM_CC)0x00000169) +#define TPM2_ReadPublic ((TPM_CC)0x00000173) #define TPM2_GetCapability ((TPM_CC)0x0000017A) #define TPM2_GetRandom ((TPM_CC)0x0000017B) #define TPM2_PCR_Extend ((TPM_CC)0x00000182) @@ -122,6 +123,7 @@ extern "C" { typedef uint8_t TPMI_YES_NO; typedef uint32_t TPM_CC; typedef uint32_t TPM_HANDLE; +typedef TPM_HANDLE TPMI_DH_OBJECT; typedef TPM_HANDLE TPMI_DH_PCR; typedef TPM_HANDLE TPMI_RH_NV_INDEX; typedef TPM_HANDLE TPMI_RH_ENABLES; @@ -145,6 +147,14 @@ typedef union { TPM2B b; } TPM2B_MAX_NV_BUFFER; +typedef union { + struct { + uint16_t size; + const uint8_t *buffer; + } t; + TPM2B b; +} TPM2B_PUBLIC; + typedef struct { TPM_PT property; uint32_t value; @@ -252,6 +262,10 @@ struct tpm2_pcr_extend_cmd { TPML_DIGEST_VALUES digests; }; +struct tpm2_read_public_cmd { + TPMI_DH_OBJECT object_handle; +}; + /* Common command/response header. */ struct tpm_header { uint16_t tpm_tag; @@ -264,6 +278,10 @@ struct nv_read_response { TPM2B_MAX_NV_BUFFER buffer; }; +struct read_public_response { + TPM2B_PUBLIC buffer; +}; + struct tpm2_session_attrs { uint8_t continueSession : 1; uint8_t auditExclusive : 1; @@ -308,6 +326,7 @@ struct tpm2_response { struct get_capability_response cap; struct get_random_response random; struct nv_read_public_response nv_read_public; + struct read_public_response read_pub; }; }; diff --git a/firmware/lib/tpm2_lite/marshaling.c b/firmware/lib/tpm2_lite/marshaling.c index 2517b458..ea261d3c 100644 --- a/firmware/lib/tpm2_lite/marshaling.c +++ b/firmware/lib/tpm2_lite/marshaling.c @@ -121,6 +121,26 @@ static void unmarshal_TPM2B_MAX_NV_BUFFER(void **buffer, *size -= nv_buffer->t.size; } +static void unmarshal_TPM2B_PUBLIC(void **buffer, int *size, + TPM2B_PUBLIC *pub_buffer) +{ + pub_buffer->t.size = unmarshal_u16(buffer, size); + if (pub_buffer->t.size > *size) { + VB2_DEBUG("size mismatch: expected %d, remaining %d\n", + pub_buffer->t.size, *size); + pub_buffer->t.buffer = NULL; + pub_buffer->t.size = 0; + *buffer = NULL; + *size = -1; + return; + } + + pub_buffer->t.buffer = *buffer; + + *buffer = ((uint8_t *)(*buffer)) + pub_buffer->t.size; + *size -= pub_buffer->t.size; +} + static void unmarshal_authorization_section(void **buffer, int *size, const char *cmd_name) { @@ -156,6 +176,19 @@ static void unmarshal_nv_read(void **buffer, int *size, unmarshal_authorization_section(buffer, size, "NV_Read"); } +static void unmarshal_read_public(void **buffer, int *size, + struct read_public_response *rpr) +{ + unmarshal_TPM2B_PUBLIC(buffer, size, &rpr->buffer); + + if (*size < 0) + return; + + /* Drain the name & authorization sections. */ + *buffer = ((uint8_t *)(*buffer)) + *size; + *size = 0; +} + static void unmarshal_TPM2B(void **buffer, int *size, TPM2B *tpm2b) @@ -611,6 +644,13 @@ static void marshal_hierarchy_control(void **buffer, marshal_u8(buffer, command_body->state, buffer_space); } +static void marshal_read_public(void **buffer, + struct tpm2_read_public_cmd *command_body, + int *buffer_space) +{ + marshal_u32(buffer, command_body->object_handle, buffer_space); +} + static void marshal_get_capability(void **buffer, struct tpm2_get_capability_cmd *command_body, @@ -787,6 +827,10 @@ int tpm_marshal_command(TPM_CC command, void *tpm_command_body, marshal_pcr_extend(&cmd_body, tpm_command_body, &body_size); break; + case TPM2_ReadPublic: + marshal_read_public(&cmd_body, tpm_command_body, &body_size); + break; + default: body_size = -1; VB2_DEBUG("Request to marshal unsupported command %#x\n", @@ -848,6 +892,11 @@ int tpm_unmarshal_response(TPM_CC command, &response->random); break; + case TPM2_ReadPublic: + unmarshal_read_public(&response_body, &cr_size, + &response->read_pub); + break; + case TPM2_Hierarchy_Control: case TPM2_NV_Write: case TPM2_NV_WriteLock: diff --git a/firmware/lib/tpm2_lite/tlcl.c b/firmware/lib/tpm2_lite/tlcl.c index 954717fe..156c6199 100644 --- a/firmware/lib/tpm2_lite/tlcl.c +++ b/firmware/lib/tpm2_lite/tlcl.c @@ -688,3 +688,42 @@ uint32_t TlclIFXFieldUpgradeInfo(TPM_IFX_FIELDUPGRADEINFO* info) VB2_DEBUG("NOT YET IMPLEMENTED\n"); return TPM_E_IOERROR; } + +uint32_t TlclReadPublic(uint32_t handle, uint8_t *data, uint32_t *length) +{ + struct tpm2_read_public_cmd cmd; + struct tpm2_response *response = &tpm2_resp; + uint32_t rv; + + memset(&cmd, 0, sizeof(cmd)); + + cmd.object_handle = handle; + + rv = tpm_send_receive(TPM2_ReadPublic, &cmd, response); + + /* Need to map tpm error codes into internal values. */ + switch (rv) { + case TPM_SUCCESS: + break; + + case 0x8b: + case 0x18b: + return TPM_E_BADINDEX; + + default: + return rv; + } + + if (*length < response->read_pub.buffer.t.size + 2) + return TPM_E_RESPONSE_TOO_LARGE; + + *length = response->read_pub.buffer.t.size + 2; + + data[0] = (response->read_pub.buffer.t.size >> 8) & 0xff; + data[1] = response->read_pub.buffer.t.size & 0xff; + + memcpy(data + 2, response->read_pub.buffer.t.buffer, + response->read_pub.buffer.t.size); + + return TPM_SUCCESS; +} |