From 5c3a7824c2d68745a8f51c8502a12a716ee90bb0 Mon Sep 17 00:00:00 2001 From: Yi Chou Date: Fri, 15 Jan 2021 17:48:57 +0800 Subject: tpm2_lite: implement TlclExtend Implement TlclExtend, which sends a TPM2_PCR_Extend command to extend the indicated PCR. BUG=b:174807059 BRANCH=none TEST=After stopped trunksd run "tpmc pcrextend " to extend the PCR. Start trunksd and run "trunks_client --read_pcr --index=" would see the PCR value changed. Disallow-Recycled-Builds: test-failures Signed-off-by: Yi Chou Change-Id: I5b11fcf7de83186a29e1abed43f443ac9ca426fb Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/vboot_reference/+/2632019 Reviewed-by: Leo Lai --- firmware/include/tpm2_tss_constants.h | 31 +++++++++++++++++++++- firmware/lib/tpm2_lite/marshaling.c | 50 ++++++++++++++++++++++++++++++++++- firmware/lib/tpm2_lite/tlcl.c | 11 ++++++-- 3 files changed, 88 insertions(+), 4 deletions(-) diff --git a/firmware/include/tpm2_tss_constants.h b/firmware/include/tpm2_tss_constants.h index 73747352..becd710c 100644 --- a/firmware/include/tpm2_tss_constants.h +++ b/firmware/include/tpm2_tss_constants.h @@ -34,9 +34,13 @@ extern "C" { #define TPM2_NV_ReadPublic ((TPM_CC)0x00000169) #define TPM2_GetCapability ((TPM_CC)0x0000017A) #define TPM2_GetRandom ((TPM_CC)0x0000017B) +#define TPM2_PCR_Extend ((TPM_CC)0x00000182) -#define HR_SHIFT 24 +#define TPM_HT_PCR 0x00 #define TPM_HT_NV_INDEX 0x01 + +#define HR_SHIFT 24 +#define HR_PCR (TPM_HT_PCR << HR_SHIFT) #define HR_NV_INDEX (TPM_HT_NV_INDEX << HR_SHIFT) #define TPM_RH_OWNER 0x40000001 #define TPM_RH_PLATFORM 0x4000000C @@ -110,9 +114,15 @@ extern "C" { #define TPMI_RH_NV_INDEX_TCG_WG_START ((TPMI_RH_NV_INDEX)0x01C40000) #define TPMI_RH_NV_INDEX_RESERVED_START ((TPMI_RH_NV_INDEX)0x01C90000) +#define HASH_COUNT 1 /* Only SHA-256 is supported */ + +/* Table 206 - Defines for SHA256 Hash Values */ +#define SHA256_DIGEST_SIZE 32 + typedef uint8_t TPMI_YES_NO; typedef uint32_t TPM_CC; typedef uint32_t TPM_HANDLE; +typedef TPM_HANDLE TPMI_DH_PCR; typedef TPM_HANDLE TPMI_RH_NV_INDEX; typedef TPM_HANDLE TPMI_RH_ENABLES; typedef uint32_t TPM_CAP; @@ -145,6 +155,20 @@ typedef struct { TPMS_TAGGED_PROPERTY tpm_property[1]; } TPML_TAGGED_TPM_PROPERTY; +typedef union { + uint8_t sha256[SHA256_DIGEST_SIZE]; +} TPMU_HA; + +typedef struct { + TPMI_ALG_HASH hashAlg; + TPMU_HA digest; +} TPMT_HA; + +typedef struct { + uint32_t count; + TPMT_HA digests[HASH_COUNT]; +} TPML_DIGEST_VALUES; + typedef union { TPML_TAGGED_TPM_PROPERTY tpm_properties; } TPMU_CAPABILITIES; @@ -223,6 +247,11 @@ struct tpm2_shutdown_cmd { TPM_SU shutdown_type; }; +struct tpm2_pcr_extend_cmd { + TPMI_DH_PCR pcrHandle; + TPML_DIGEST_VALUES digests; +}; + /* Common command/response header. */ struct tpm_header { uint16_t tpm_tag; diff --git a/firmware/lib/tpm2_lite/marshaling.c b/firmware/lib/tpm2_lite/marshaling.c index ef3606b9..b9857d47 100644 --- a/firmware/lib/tpm2_lite/marshaling.c +++ b/firmware/lib/tpm2_lite/marshaling.c @@ -283,7 +283,7 @@ static void marshal_blob(void **buffer, void *blob, } memcpy(*buffer, blob, blob_size); - buffer_space -= blob_size; + *buffer_space -= blob_size; *buffer = (void *)((uintptr_t)(*buffer) + blob_size); } @@ -327,6 +327,7 @@ static void marshal_u32(void **buffer, uint32_t value, int *buffer_space) #define marshal_TPM_HANDLE(a, b, c) marshal_u32(a, b, c) #define marshal_TPM_SU(a, b, c) marshal_u16(a, b, c) #define marshal_ALG_ID(a, b, c) marshal_u16(a, b, c) +#define marshal_TPMI_ALG_HASH(a, b, c) marshal_u16(a, b, c) /* * For TPM2B* structures the size field (16 or 32 bits) goes before the data. @@ -671,6 +672,48 @@ static void marshal_shutdown(void **buffer, marshal_TPM_SU(buffer, command_body->shutdown_type, buffer_space); } +static void marshal_TPMT_HA(void **buffer, + TPMT_HA *data, + int *buffer_space) +{ + if (data->hashAlg != TPM_ALG_SHA256) + { + VB2_DEBUG("Unsupported TPMT_HA hash algorithm: %#x\n", + data->hashAlg); + *buffer_space = -1; + return; + } + marshal_TPMI_ALG_HASH(buffer, data->hashAlg, buffer_space); + /* We only support SHA256 now. */ + marshal_blob(buffer, data->digest.sha256, + SHA256_DIGEST_SIZE, buffer_space); +} + +static void marshal_TPML_DIGEST_VALUES(void **buffer, + TPML_DIGEST_VALUES *data, + int *buffer_space) +{ + int i; + + marshal_u32(buffer, data->count, buffer_space); + for (i = 0; i < data->count; i++) + marshal_TPMT_HA(buffer, &data->digests[i], buffer_space); +} + +static void marshal_pcr_extend(void **buffer, + struct tpm2_pcr_extend_cmd *command_body, + int *buffer_space) +{ + struct tpm2_session_header session_header; + + tpm_tag = TPM_ST_SESSIONS; + marshal_TPM_HANDLE(buffer, command_body->pcrHandle, buffer_space); + memset(&session_header, 0, sizeof(session_header)); + session_header.session_handle = TPM_RS_PW; + marshal_session_header(buffer, &session_header, buffer_space); + marshal_TPML_DIGEST_VALUES(buffer, &command_body->digests, buffer_space); +} + int tpm_marshal_command(TPM_CC command, void *tpm_command_body, void *buffer, int buffer_size) { @@ -740,6 +783,10 @@ int tpm_marshal_command(TPM_CC command, void *tpm_command_body, marshal_shutdown(&cmd_body, tpm_command_body, &body_size); break; + case TPM2_PCR_Extend: + marshal_pcr_extend(&cmd_body, tpm_command_body, &body_size); + break; + default: body_size = -1; VB2_DEBUG("Request to marshal unsupported command %#x\n", @@ -811,6 +858,7 @@ int tpm_unmarshal_response(TPM_CC command, case TPM2_Shutdown: case TPM2_NV_DefineSpace: case TPM2_NV_UndefineSpace: + case TPM2_PCR_Extend: /* Session data included in response can be safely ignored. */ cr_size = 0; break; diff --git a/firmware/lib/tpm2_lite/tlcl.c b/firmware/lib/tpm2_lite/tlcl.c index e4695d12..b91119b7 100644 --- a/firmware/lib/tpm2_lite/tlcl.c +++ b/firmware/lib/tpm2_lite/tlcl.c @@ -314,8 +314,15 @@ int TlclIsOwned(void) uint32_t TlclExtend(int pcr_num, const uint8_t *in_digest, uint8_t *out_digest) { - VB2_DEBUG("NOT YET IMPLEMENTED\n"); - return TPM_SUCCESS; + struct tpm2_pcr_extend_cmd pcr_ext_cmd; + + pcr_ext_cmd.pcrHandle = HR_PCR + pcr_num; + pcr_ext_cmd.digests.count = 1; + pcr_ext_cmd.digests.digests[0].hashAlg = TPM_ALG_SHA256; + memcpy(pcr_ext_cmd.digests.digests[0].digest.sha256, in_digest, + sizeof(pcr_ext_cmd.digests.digests[0].digest.sha256)); + + return tpm_get_response_code(TPM2_PCR_Extend, &pcr_ext_cmd); } -- cgit v1.2.1