summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrey Pronin <apronin@chromium.org>2016-11-09 20:19:32 -0800
committerchrome-bot <chrome-bot@chromium.org>2016-11-11 10:05:28 -0800
commit1afcfc13661b4f34a2afbeae8e740cd61ae571be (patch)
tree000d85153cfc3b1968930fc117409dd37ae13f13
parentd28b4e1444372e709729787be6e81490e46c202d (diff)
downloadvboot-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>
-rw-r--r--firmware/include/tpm2_tss_constants.h13
-rw-r--r--firmware/lib/tpm2_lite/marshaling.c84
-rw-r--r--firmware/lib/tpm2_lite/tlcl.c28
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;
}