diff options
author | Stephen Boyd <swboyd@chromium.org> | 2018-11-07 22:43:19 -0800 |
---|---|---|
committer | chrome-bot <chrome-bot@chromium.org> | 2018-11-27 00:34:09 -0800 |
commit | 8fbb4b8c7b9311e7a816cc529cdcffbb2e315ff9 (patch) | |
tree | abe7e989907451f9f16bd117f470847d39674ed8 | |
parent | aa7bf63978082e4e55c0e11836964d8996f22c53 (diff) | |
download | vboot-8fbb4b8c7b9311e7a816cc529cdcffbb2e315ff9.tar.gz |
firmware: tpm2_lite: Implement TlclGetRandom()
Implement support for getting random bytes from the TPM in the tpm2
library. The intent is to use this to seed the kaslr-seed DT property on
ARM devices.
BRANCH=None
BUG=None
TEST=Generate some random bytes in depthcharge using this API,
and 'stop trunksd; tpmc rand <size>' with sizes (0, 1, 0xf0, and
0xf1) on the device and see the last one fail
Change-Id: Ied0dc1ead70ac4daa2cee315516160ec100039be
Signed-off-by: Stephen Boyd <swboyd@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/1327187
Commit-Ready: ChromeOS CL Exonerator Bot <chromiumos-cl-exonerator@appspot.gserviceaccount.com>
Reviewed-by: Andrey Pronin <apronin@chromium.org>
-rw-r--r-- | firmware/include/tpm2_tss_constants.h | 10 | ||||
-rw-r--r-- | firmware/lib/tpm2_lite/marshaling.c | 23 | ||||
-rw-r--r-- | firmware/lib/tpm2_lite/tlcl.c | 27 |
3 files changed, 57 insertions, 3 deletions
diff --git a/firmware/include/tpm2_tss_constants.h b/firmware/include/tpm2_tss_constants.h index cb920c01..162993e2 100644 --- a/firmware/include/tpm2_tss_constants.h +++ b/firmware/include/tpm2_tss_constants.h @@ -34,6 +34,7 @@ extern "C" { #define TPM2_NV_ReadLock ((TPM_CC)0x0000014F) #define TPM2_NV_ReadPublic ((TPM_CC)0x00000169) #define TPM2_GetCapability ((TPM_CC)0x0000017A) +#define TPM2_GetRandom ((TPM_CC)0x0000017B) #define HR_SHIFT 24 #define TPM_HT_NV_INDEX 0x01 @@ -207,6 +208,10 @@ struct tpm2_get_capability_cmd { uint32_t property_count; }; +struct tpm2_get_random_cmd { + uint16_t bytes_requested; +}; + struct tpm2_self_test_cmd { TPMI_YES_NO full_test; }; @@ -258,6 +263,10 @@ struct get_capability_response { TPMS_CAPABILITY_DATA capability_data; } __attribute__((packed)); +struct get_random_response { + TPM2B_DIGEST random_bytes; +} __attribute__((packed)); + struct nv_read_public_response { TPMS_NV_PUBLIC nvPublic; TPM2B_NAME nvName; @@ -269,6 +278,7 @@ struct tpm2_response { struct nv_read_response nvr; struct tpm2_session_header def_space; struct get_capability_response cap; + struct get_random_response random; 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 df938662..e20bcda6 100644 --- a/firmware/lib/tpm2_lite/marshaling.c +++ b/firmware/lib/tpm2_lite/marshaling.c @@ -261,6 +261,11 @@ static void unmarshal_get_capability(void **buffer, int *size, unmarshal_TPMS_CAPABILITY_DATA(buffer, size, &cap->capability_data); } +static void unmarshal_get_random(void **buffer, int *size, + struct get_random_response *random) +{ + unmarshal_TPM2B(buffer, size, &random->random_bytes); +} /* * Each marshaling function receives a pointer to the buffer to marshal into, @@ -620,6 +625,15 @@ static void marshal_get_capability(void **buffer, marshal_u32(buffer, command_body->property_count, buffer_space); } +static void marshal_get_random(void **buffer, struct tpm2_get_random_cmd + *command_body, + int *buffer_space) +{ + tpm_tag = TPM_ST_NO_SESSIONS; + + marshal_u16(buffer, command_body->bytes_requested, buffer_space); +} + static void marshal_clear(void **buffer, void *command_body, int *buffer_space) @@ -709,6 +723,10 @@ int tpm_marshal_command(TPM_CC command, void *tpm_command_body, marshal_get_capability(&cmd_body, tpm_command_body, &body_size); break; + case TPM2_GetRandom: + marshal_get_random(&cmd_body, tpm_command_body, &body_size); + break; + case TPM2_Clear: marshal_clear(&cmd_body, tpm_command_body, &body_size); break; @@ -781,6 +799,11 @@ int tpm_unmarshal_response(TPM_CC command, &response->cap); break; + case TPM2_GetRandom: + unmarshal_get_random(&response_body, &cr_size, + &response->random); + 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 8e5fbeac..61c4c414 100644 --- a/firmware/lib/tpm2_lite/tlcl.c +++ b/firmware/lib/tpm2_lite/tlcl.c @@ -572,9 +572,30 @@ uint32_t TlclReadLock(uint32_t index) uint32_t TlclGetRandom(uint8_t *data, uint32_t length, uint32_t *size) { - *size = 0; - VB2_DEBUG("NOT YET IMPLEMENTED\n"); - return TPM_E_IOERROR; + uint32_t rv; + struct tpm2_get_random_cmd random; + struct get_random_response *response = &tpm2_resp.random; + size_t max_len, offset; + + offset = offsetof(struct tpm2_response, random.random_bytes.buffer); + max_len = TPM_BUFFER_SIZE - offset; + + if (length > max_len) + return TPM_E_BUFFER_SIZE; + + random.bytes_requested = length; + + rv = tpm_send_receive(TPM2_GetRandom, &random, &tpm2_resp); + if (rv != TPM_SUCCESS) + return rv; + + *size = response->random_bytes.size; + if (*size > length) + return TPM_E_RESPONSE_TOO_LARGE; + + memcpy(data, response->random_bytes.buffer, *size); + + return rv; } // Converts TPM_PT_VENDOR_STRING_x |value| to an array of bytes in |buf|. |