diff options
author | Andrey Pronin <apronin@chromium.org> | 2016-11-09 20:19:32 -0800 |
---|---|---|
committer | chrome-bot <chrome-bot@chromium.org> | 2016-11-11 10:05:28 -0800 |
commit | 1afcfc13661b4f34a2afbeae8e740cd61ae571be (patch) | |
tree | 000d85153cfc3b1968930fc117409dd37ae13f13 /firmware/lib | |
parent | d28b4e1444372e709729787be6e81490e46c202d (diff) | |
download | vboot-1afcfc13661b4f34a2afbeae8e740cd61ae571be.tar.gz |
tpm2_lite: implement TlclGetPermissions
Implement TlclGetPermissions, which sends a TPM2_NV_ReadPublic command
and returns the attributes of the NV Index (TPM2 Spec, Part 3, Section 31.6).
BUG=chrome-os-partner:58873
BUG=chrome-os-partner:55210
BRANCH=none
TEST=Run "tpmc def" with various permissions to define new indexes,
verify that "tpmc getp" returns matching permissions for them.
Change-Id: I2ad7163332ae8793cd717875645f19baef513b26
Reviewed-on: https://chromium-review.googlesource.com/409618
Commit-Ready: Vadim Bendebury <vbendeb@chromium.org>
Tested-by: Andrey Pronin <apronin@chromium.org>
Reviewed-by: Vadim Bendebury <vbendeb@chromium.org>
Diffstat (limited to 'firmware/lib')
-rw-r--r-- | firmware/lib/tpm2_lite/marshaling.c | 84 | ||||
-rw-r--r-- | firmware/lib/tpm2_lite/tlcl.c | 28 |
2 files changed, 110 insertions, 2 deletions
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; } |