diff options
-rw-r--r-- | firmware/include/tpm2_tss_constants.h | 13 | ||||
-rw-r--r-- | firmware/lib/tpm2_lite/marshaling.c | 84 | ||||
-rw-r--r-- | firmware/lib/tpm2_lite/tlcl.c | 28 |
3 files changed, 122 insertions, 3 deletions
diff --git a/firmware/include/tpm2_tss_constants.h b/firmware/include/tpm2_tss_constants.h index f24c7694..454bf81a 100644 --- a/firmware/include/tpm2_tss_constants.h +++ b/firmware/include/tpm2_tss_constants.h @@ -27,6 +27,7 @@ #define TPM2_Shutdown ((TPM_CC)0x00000145) #define TPM2_NV_Read ((TPM_CC)0x0000014E) #define TPM2_NV_ReadLock ((TPM_CC)0x0000014F) +#define TPM2_NV_ReadPublic ((TPM_CC)0x00000169) #define TPM2_GetCapability ((TPM_CC)0x0000017A) /* TCG Spec defined, verify for TPM2. @@ -106,7 +107,7 @@ typedef uint32_t TPMA_NV; typedef struct { uint16_t size; uint8_t *buffer; -} TPM2B, TPM2B_DIGEST, TPM2B_AUTH; +} TPM2B, TPM2B_DIGEST, TPM2B_AUTH, TPM2B_NAME; typedef union { struct { @@ -168,6 +169,10 @@ struct tpm2_nv_write_lock_cmd { TPMI_RH_NV_INDEX nvIndex; }; +struct tpm2_nv_read_public_cmd { + TPMI_RH_NV_INDEX nvIndex; +}; + struct tpm2_hierarchy_control_cmd { TPMI_RH_ENABLES enable; TPMI_YES_NO state; @@ -230,12 +235,18 @@ struct get_capability_response { TPMS_CAPABILITY_DATA capability_data; } __attribute__((packed)); +struct nv_read_public_response { + TPMS_NV_PUBLIC nvPublic; + TPM2B_NAME nvName; +} __attribute__((packed)); + struct tpm2_response { struct tpm_header hdr; union { struct nv_read_response nvr; struct tpm2_session_header def_space; struct get_capability_response cap; + struct nv_read_public_response nv_read_public; }; }; diff --git a/firmware/lib/tpm2_lite/marshaling.c b/firmware/lib/tpm2_lite/marshaling.c index 57a05530..23a46555 100644 --- a/firmware/lib/tpm2_lite/marshaling.c +++ b/firmware/lib/tpm2_lite/marshaling.c @@ -101,6 +101,9 @@ static uint32_t unmarshal_u32(void **buffer, int *buffer_space) return value; } +#define unmarshal_TPM_HANDLE(a, b) unmarshal_u32(a, b) +#define unmarshal_ALG_ID(a, b) unmarshal_u16(a, b) + static void unmarshal_TPM2B_MAX_NV_BUFFER(void **buffer, int *size, TPM2B_MAX_NV_BUFFER *nv_buffer) @@ -156,6 +159,69 @@ static void unmarshal_nv_read(void **buffer, int *size, unmarshal_authorization_section(buffer, size, "NV_Read"); } +static void unmarshal_TPM2B(void **buffer, + int *size, + TPM2B *tpm2b) +{ + tpm2b->size = unmarshal_u16(buffer, size); + if (tpm2b->size > *size) { + VBDEBUG(("%s:%d - " + "size mismatch: expected %d, remaining %d\n", + __func__, __LINE__, tpm2b->size, *size)); + *size = -1; + return; + } + + tpm2b->buffer = *buffer; + + *buffer = ((uint8_t *)(*buffer)) + tpm2b->size; + *size -= tpm2b->size; +} + +static void unmarshal_TPMS_NV_PUBLIC(void **buffer, + int *size, + TPMS_NV_PUBLIC *pub) +{ + int tpm2b_size = unmarshal_u16(buffer, size); + if (tpm2b_size > *size) { + VBDEBUG(("%s:%d - " + "size mismatch: expected %d, remaining %d\n", + __func__, __LINE__, tpm2b_size, *size)); + *size = -1; + return; + } + *size -= tpm2b_size; + + pub->nvIndex = unmarshal_TPM_HANDLE(buffer, &tpm2b_size); + pub->nameAlg = unmarshal_ALG_ID(buffer, &tpm2b_size); + pub->attributes = unmarshal_u32(buffer, &tpm2b_size); + unmarshal_TPM2B(buffer, &tpm2b_size, &pub->authPolicy); + pub->dataSize = unmarshal_u16(buffer, &tpm2b_size); + + if (tpm2b_size != 0) { + VBDEBUG(("%s:%d - " + "TPMS_NV_PUBLIC size doesn't match the size field\n", + __func__, __LINE__)); + *size = -1; + return; + } +} + +static void unmarshal_nv_read_public(void **buffer, int *size, + struct nv_read_public_response *nv_pub) +{ + unmarshal_TPMS_NV_PUBLIC(buffer, size, &nv_pub->nvPublic); + unmarshal_TPM2B(buffer, size, &nv_pub->nvName); + + if (*size > 0) { + VBDEBUG(("%s:%d - " + "extra %d bytes after nvName\n", + __func__, __LINE__, *size)); + *size = -1; + return; + } +} + static void unmarshal_TPML_TAGGED_TPM_PROPERTY(void **buffer, int *size, TPML_TAGGED_TPM_PROPERTY *prop) { @@ -499,6 +565,15 @@ static void marshal_nv_write_lock(void **buffer, marshal_session_header(buffer, &session_header, buffer_space); } +static void marshal_nv_read_public(void **buffer, + struct tpm2_nv_read_public_cmd *command_body, + int *buffer_space) +{ + tpm_tag = TPM_ST_NO_SESSIONS; + + marshal_TPM_HANDLE(buffer, command_body->nvIndex, buffer_space); +} + static void marshal_hierarchy_control(void **buffer, struct tpm2_hierarchy_control_cmd *command_body, @@ -600,6 +675,10 @@ int tpm_marshal_command(TPM_CC command, void *tpm_command_body, marshal_nv_write_lock(&cmd_body, tpm_command_body, &body_size); break; + case TPM2_NV_ReadPublic: + marshal_nv_read_public(&cmd_body, tpm_command_body, &body_size); + break; + case TPM2_Hierarchy_Control: marshal_hierarchy_control(&cmd_body, tpm_command_body, &body_size); @@ -672,6 +751,11 @@ struct tpm2_response *tpm_unmarshal_response(TPM_CC command, &tpm2_resp.nvr); break; + case TPM2_NV_ReadPublic: + unmarshal_nv_read_public(&response_body, &cr_size, + &tpm2_resp.nv_read_public); + break; + case TPM2_GetCapability: unmarshal_get_capability(&response_body, &cr_size, &tpm2_resp.cap); diff --git a/firmware/lib/tpm2_lite/tlcl.c b/firmware/lib/tpm2_lite/tlcl.c index e4f3b53b..84929cfa 100644 --- a/firmware/lib/tpm2_lite/tlcl.c +++ b/firmware/lib/tpm2_lite/tlcl.c @@ -244,13 +244,37 @@ uint32_t TlclExtend(int pcr_num, const uint8_t *in_digest, uint8_t *out_digest) return TPM_SUCCESS; } + +static uint32_t tlcl_nv_read_public(uint32_t index, + struct nv_read_public_response **presp) +{ + struct tpm2_response *response; + struct tpm2_nv_read_public_cmd read_pub; + + memset(&read_pub, 0, sizeof(read_pub)); + read_pub.nvIndex = HR_NV_INDEX + index; + + response = tpm_process_command(TPM2_NV_ReadPublic, &read_pub); + if (!response || response->hdr.tpm_code) + return TPM_E_IOERROR; + *presp = &response->nv_read_public; + + return TPM_SUCCESS; +} + /** * Get the permission bits for the NVRAM space with |index|. */ uint32_t TlclGetPermissions(uint32_t index, uint32_t *permissions) { - *permissions = 0; - VBDEBUG(("%s called, NOT YET IMPLEMENTED\n", __func__)); + uint32_t rv; + struct nv_read_public_response *resp; + + rv = tlcl_nv_read_public(index, &resp); + if (rv != TPM_SUCCESS) + return rv; + + *permissions = resp->nvPublic.attributes; return TPM_SUCCESS; } |