summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStephen Boyd <swboyd@chromium.org>2018-11-07 22:43:19 -0800
committerFurquan Shaikh <furquan@chromium.org>2018-11-30 16:00:38 +0000
commit0b3fbec00c95453de3de1747f5cb78d3f951c7a1 (patch)
treeabe7e989907451f9f16bd117f470847d39674ed8
parentee88e5efedd49e80606ef3007ee6b4e3fc3c9b1e (diff)
downloadvboot-0b3fbec00c95453de3de1747f5cb78d3f951c7a1.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> Signed-off-by: Furquan Shaikh <furquan@google.com> Reviewed-on: https://chromium-review.googlesource.com/c/1355749 Reviewed-by: Furquan Shaikh <furquan@chromium.org> Commit-Queue: Furquan Shaikh <furquan@chromium.org> Tested-by: Furquan Shaikh <furquan@chromium.org> Trybot-Ready: Furquan Shaikh <furquan@chromium.org>
-rw-r--r--firmware/include/tpm2_tss_constants.h10
-rw-r--r--firmware/lib/tpm2_lite/marshaling.c23
-rw-r--r--firmware/lib/tpm2_lite/tlcl.c27
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|.