summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYi Chou <yich@google.com>2023-02-06 12:01:58 +0800
committerChromeos LUCI <chromeos-scoped@luci-project-accounts.iam.gserviceaccount.com>2023-04-10 08:58:24 +0000
commitc2491cfab74685fb5a0f30dc3e7c1fadbc47adb3 (patch)
tree3cc394f5f556119f0b581ca3516fddbef63955b4
parent39f0d38bcd104fd4d1ffbcc6aa3a754566c97070 (diff)
downloadvboot-c2491cfab74685fb5a0f30dc3e7c1fadbc47adb3.tar.gz
tlcl: Add `TlclReadPublic()` support
Add support for the TPM2_ReadPublic command to the TLCL. This command is used to read the public area data of an object with the object handle. BUG=b:249552664 BRANCH=None TEST=TlclReadPublic works. Signed-off-by: Yi Chou <yich@google.com> Change-Id: I5d72b8f19e02c6bdcc39f1c20ff7100f5dd0eda1 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/vboot_reference/+/4218847 Reviewed-by: Yu-Ping Wu <yupingso@chromium.org>
-rw-r--r--firmware/include/tlcl.h7
-rw-r--r--firmware/include/tpm2_tss_constants.h19
-rw-r--r--firmware/lib/tpm2_lite/marshaling.c49
-rw-r--r--firmware/lib/tpm2_lite/tlcl.c39
4 files changed, 114 insertions, 0 deletions
diff --git a/firmware/include/tlcl.h b/firmware/include/tlcl.h
index 42e3bab9..c4d0c153 100644
--- a/firmware/include/tlcl.h
+++ b/firmware/include/tlcl.h
@@ -264,6 +264,13 @@ uint32_t TlclGetVersion(uint32_t* vendor, uint64_t* firmware_version,
*/
uint32_t TlclIFXFieldUpgradeInfo(TPM_IFX_FIELDUPGRADEINFO *info);
+/**
+ * Read the public area of object. Put at most [length] bytes public area
+ * into [data], and the format of [data] is TPM2B_PUBLIC. The TPM error code
+ * is returned.
+ */
+uint32_t TlclReadPublic(uint32_t handle, uint8_t *data, uint32_t *length);
+
#ifdef CHROMEOS_ENVIRONMENT
/**
diff --git a/firmware/include/tpm2_tss_constants.h b/firmware/include/tpm2_tss_constants.h
index f215a3c5..91bcbec6 100644
--- a/firmware/include/tpm2_tss_constants.h
+++ b/firmware/include/tpm2_tss_constants.h
@@ -32,6 +32,7 @@ extern "C" {
#define TPM2_NV_Read ((TPM_CC)0x0000014E)
#define TPM2_NV_ReadLock ((TPM_CC)0x0000014F)
#define TPM2_NV_ReadPublic ((TPM_CC)0x00000169)
+#define TPM2_ReadPublic ((TPM_CC)0x00000173)
#define TPM2_GetCapability ((TPM_CC)0x0000017A)
#define TPM2_GetRandom ((TPM_CC)0x0000017B)
#define TPM2_PCR_Extend ((TPM_CC)0x00000182)
@@ -122,6 +123,7 @@ extern "C" {
typedef uint8_t TPMI_YES_NO;
typedef uint32_t TPM_CC;
typedef uint32_t TPM_HANDLE;
+typedef TPM_HANDLE TPMI_DH_OBJECT;
typedef TPM_HANDLE TPMI_DH_PCR;
typedef TPM_HANDLE TPMI_RH_NV_INDEX;
typedef TPM_HANDLE TPMI_RH_ENABLES;
@@ -145,6 +147,14 @@ typedef union {
TPM2B b;
} TPM2B_MAX_NV_BUFFER;
+typedef union {
+ struct {
+ uint16_t size;
+ const uint8_t *buffer;
+ } t;
+ TPM2B b;
+} TPM2B_PUBLIC;
+
typedef struct {
TPM_PT property;
uint32_t value;
@@ -252,6 +262,10 @@ struct tpm2_pcr_extend_cmd {
TPML_DIGEST_VALUES digests;
};
+struct tpm2_read_public_cmd {
+ TPMI_DH_OBJECT object_handle;
+};
+
/* Common command/response header. */
struct tpm_header {
uint16_t tpm_tag;
@@ -264,6 +278,10 @@ struct nv_read_response {
TPM2B_MAX_NV_BUFFER buffer;
};
+struct read_public_response {
+ TPM2B_PUBLIC buffer;
+};
+
struct tpm2_session_attrs {
uint8_t continueSession : 1;
uint8_t auditExclusive : 1;
@@ -308,6 +326,7 @@ struct tpm2_response {
struct get_capability_response cap;
struct get_random_response random;
struct nv_read_public_response nv_read_public;
+ struct read_public_response read_pub;
};
};
diff --git a/firmware/lib/tpm2_lite/marshaling.c b/firmware/lib/tpm2_lite/marshaling.c
index 2517b458..ea261d3c 100644
--- a/firmware/lib/tpm2_lite/marshaling.c
+++ b/firmware/lib/tpm2_lite/marshaling.c
@@ -121,6 +121,26 @@ static void unmarshal_TPM2B_MAX_NV_BUFFER(void **buffer,
*size -= nv_buffer->t.size;
}
+static void unmarshal_TPM2B_PUBLIC(void **buffer, int *size,
+ TPM2B_PUBLIC *pub_buffer)
+{
+ pub_buffer->t.size = unmarshal_u16(buffer, size);
+ if (pub_buffer->t.size > *size) {
+ VB2_DEBUG("size mismatch: expected %d, remaining %d\n",
+ pub_buffer->t.size, *size);
+ pub_buffer->t.buffer = NULL;
+ pub_buffer->t.size = 0;
+ *buffer = NULL;
+ *size = -1;
+ return;
+ }
+
+ pub_buffer->t.buffer = *buffer;
+
+ *buffer = ((uint8_t *)(*buffer)) + pub_buffer->t.size;
+ *size -= pub_buffer->t.size;
+}
+
static void unmarshal_authorization_section(void **buffer, int *size,
const char *cmd_name)
{
@@ -156,6 +176,19 @@ static void unmarshal_nv_read(void **buffer, int *size,
unmarshal_authorization_section(buffer, size, "NV_Read");
}
+static void unmarshal_read_public(void **buffer, int *size,
+ struct read_public_response *rpr)
+{
+ unmarshal_TPM2B_PUBLIC(buffer, size, &rpr->buffer);
+
+ if (*size < 0)
+ return;
+
+ /* Drain the name & authorization sections. */
+ *buffer = ((uint8_t *)(*buffer)) + *size;
+ *size = 0;
+}
+
static void unmarshal_TPM2B(void **buffer,
int *size,
TPM2B *tpm2b)
@@ -611,6 +644,13 @@ static void marshal_hierarchy_control(void **buffer,
marshal_u8(buffer, command_body->state, buffer_space);
}
+static void marshal_read_public(void **buffer,
+ struct tpm2_read_public_cmd *command_body,
+ int *buffer_space)
+{
+ marshal_u32(buffer, command_body->object_handle, buffer_space);
+}
+
static void marshal_get_capability(void **buffer,
struct tpm2_get_capability_cmd
*command_body,
@@ -787,6 +827,10 @@ int tpm_marshal_command(TPM_CC command, void *tpm_command_body,
marshal_pcr_extend(&cmd_body, tpm_command_body, &body_size);
break;
+ case TPM2_ReadPublic:
+ marshal_read_public(&cmd_body, tpm_command_body, &body_size);
+ break;
+
default:
body_size = -1;
VB2_DEBUG("Request to marshal unsupported command %#x\n",
@@ -848,6 +892,11 @@ int tpm_unmarshal_response(TPM_CC command,
&response->random);
break;
+ case TPM2_ReadPublic:
+ unmarshal_read_public(&response_body, &cr_size,
+ &response->read_pub);
+ 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 954717fe..156c6199 100644
--- a/firmware/lib/tpm2_lite/tlcl.c
+++ b/firmware/lib/tpm2_lite/tlcl.c
@@ -688,3 +688,42 @@ uint32_t TlclIFXFieldUpgradeInfo(TPM_IFX_FIELDUPGRADEINFO* info)
VB2_DEBUG("NOT YET IMPLEMENTED\n");
return TPM_E_IOERROR;
}
+
+uint32_t TlclReadPublic(uint32_t handle, uint8_t *data, uint32_t *length)
+{
+ struct tpm2_read_public_cmd cmd;
+ struct tpm2_response *response = &tpm2_resp;
+ uint32_t rv;
+
+ memset(&cmd, 0, sizeof(cmd));
+
+ cmd.object_handle = handle;
+
+ rv = tpm_send_receive(TPM2_ReadPublic, &cmd, response);
+
+ /* Need to map tpm error codes into internal values. */
+ switch (rv) {
+ case TPM_SUCCESS:
+ break;
+
+ case 0x8b:
+ case 0x18b:
+ return TPM_E_BADINDEX;
+
+ default:
+ return rv;
+ }
+
+ if (*length < response->read_pub.buffer.t.size + 2)
+ return TPM_E_RESPONSE_TOO_LARGE;
+
+ *length = response->read_pub.buffer.t.size + 2;
+
+ data[0] = (response->read_pub.buffer.t.size >> 8) & 0xff;
+ data[1] = response->read_pub.buffer.t.size & 0xff;
+
+ memcpy(data + 2, response->read_pub.buffer.t.buffer,
+ response->read_pub.buffer.t.size);
+
+ return TPM_SUCCESS;
+}