summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMeng-Huan Yu <menghuan@google.com>2018-10-19 21:03:35 +0800
committerchrome-bot <chrome-bot@chromium.org>2018-11-01 02:17:42 -0700
commit737e34e377dfb547e64c278470a224bfcde3b97c (patch)
treef81d8d509233a74ba142ea66662e3eb9adc8e67d
parent7283689dbd93502519edf47199b203b62da46ec1 (diff)
downloadvboot-737e34e377dfb547e64c278470a224bfcde3b97c.tar.gz
tpmc: Add TlclUndefineSpace/Ex for TPM 1.2/2.0
For TPM 1.2, to undefine the space is just define a size 0 space. And all operation should be done under physical presence is set if NvLocked is set. Iirc, NvLocked is usually set before boot. For TPM 2.0, support to undefine space regardless platform hierarchy state. We will use platform authorization when TPMA_NV_PLATFORMCREATE of that space is set. Otherwise, we will try to use owner authorization with NULL password. For owner authorization with customized password is still not supported in UndefineSpace since it is also not support in DefineSpaceEx. BUG=chromium:895549 BRANCH=None TEST=vboot_reference unit test passed and added new link test for TPM 1.2. For TPM 2.0, there is no unit test, but passed manually test with tpmc in the following commit. Also passed depthcharge unit test for TPM 2.0 and TPM 1.2 board. Change-Id: I06dcc70c63a88a04d19f3b248666ff2492a1d2b0 Reviewed-on: https://chromium-review.googlesource.com/1291131 Commit-Ready: Meng-Huan Yu <menghuan@chromium.org> Tested-by: Meng-Huan Yu <menghuan@chromium.org> Reviewed-by: Andrey Pronin <apronin@chromium.org>
-rw-r--r--firmware/include/tlcl.h19
-rw-r--r--firmware/include/tpm2_tss_constants.h6
-rw-r--r--firmware/lib/tpm2_lite/marshaling.c31
-rw-r--r--firmware/lib/tpm2_lite/tlcl.c31
-rw-r--r--firmware/lib/tpm_lite/tlcl.c19
-rw-r--r--firmware/linktest/main.c1
-rw-r--r--tests/tlcl_tests.c5
7 files changed, 112 insertions, 0 deletions
diff --git a/firmware/include/tlcl.h b/firmware/include/tlcl.h
index 1e1e401d..383be2ef 100644
--- a/firmware/include/tlcl.h
+++ b/firmware/include/tlcl.h
@@ -265,6 +265,25 @@ uint32_t TlclGetVersion(uint32_t* vendor, uint64_t* firmware_version,
uint32_t TlclIFXFieldUpgradeInfo(TPM_IFX_FIELDUPGRADEINFO *info);
#ifdef CHROMEOS_ENVIRONMENT
+
+/**
+ * Undefine the space. [index] is the index for the space. The TPM error code
+ * is returned.
+ */
+uint32_t TlclUndefineSpace(uint32_t index);
+
+/**
+ * Undefine a space. For TPM 2.0, it will use platform authrorization when the
+ * space is created by TPMA_NV_PLATFORMCREATE flag, or use owner authorization
+ * secret [owner_auth] otherwise. For TPM 1.2, only avaible when physical
+ * presence is set or TPM_PERMANENT_FLAGS->nvLocked is not set.
+ * [index] is the index for the space
+ * The TPM error code is returned.
+ */
+uint32_t TlclUndefineSpaceEx(const uint8_t* owner_auth,
+ uint32_t owner_auth_size,
+ uint32_t index);
+
#ifndef TPM2_MODE
/**
diff --git a/firmware/include/tpm2_tss_constants.h b/firmware/include/tpm2_tss_constants.h
index 4249cf04..cb920c01 100644
--- a/firmware/include/tpm2_tss_constants.h
+++ b/firmware/include/tpm2_tss_constants.h
@@ -22,6 +22,7 @@ extern "C" {
/* TPM2 command codes. */
#define TPM2_Hierarchy_Control ((TPM_CC)0x00000121)
+#define TPM2_NV_UndefineSpace ((TPM_CC)0x00000122)
#define TPM2_Clear ((TPM_CC)0x00000126)
#define TPM2_NV_DefineSpace ((TPM_CC)0x0000012A)
#define TPM2_NV_Write ((TPM_CC)0x00000137)
@@ -166,6 +167,11 @@ struct tpm2_nv_define_space_cmd {
TPMS_NV_PUBLIC publicInfo;
};
+struct tpm2_nv_undefine_space_cmd {
+ TPMI_RH_NV_INDEX nvIndex;
+ uint8_t use_platform_auth;
+};
+
struct tpm2_nv_read_cmd {
TPMI_RH_NV_INDEX nvIndex;
uint16_t size;
diff --git a/firmware/lib/tpm2_lite/marshaling.c b/firmware/lib/tpm2_lite/marshaling.c
index 63b83937..df938662 100644
--- a/firmware/lib/tpm2_lite/marshaling.c
+++ b/firmware/lib/tpm2_lite/marshaling.c
@@ -462,6 +462,32 @@ static void marshal_nv_define_space(void **buffer,
marshal_TPMS_NV_PUBLIC(buffer, &command_body->publicInfo, buffer_space);
}
+static void marshal_nv_undefine_space(void **buffer,
+ struct tpm2_nv_undefine_space_cmd
+ *command_body,
+ int *buffer_space)
+{
+ struct tpm2_session_header session_header;
+
+ /* Use platform authorization if PLATFORMCREATE is set, and owner
+ * authorization otherwise (per TPM2 Spec. Part 2. Section 31.3.1).
+ * Owner authorization with empty password will work only until
+ * ownership is taken. Platform authorization will work only until
+ * platform hierarchy is disabled (i.e. in firmware or in recovery
+ * mode).
+ */
+ if (command_body->use_platform_auth)
+ marshal_TPM_HANDLE(buffer, TPM_RH_PLATFORM, buffer_space);
+ else
+ marshal_TPM_HANDLE(buffer, TPM_RH_OWNER, buffer_space);
+ marshal_TPM_HANDLE(buffer, command_body->nvIndex, buffer_space);
+
+ memset(&session_header, 0, sizeof(session_header));
+ session_header.session_handle = TPM_RS_PW;
+ marshal_session_header(buffer, &session_header, buffer_space);
+ tpm_tag = TPM_ST_SESSIONS;
+}
+
/* Determine which authorization should be used when writing or write-locking
* an NV index.
*
@@ -650,6 +676,10 @@ int tpm_marshal_command(TPM_CC command, void *tpm_command_body,
marshal_nv_define_space(&cmd_body, tpm_command_body, &body_size);
break;
+ case TPM2_NV_UndefineSpace:
+ marshal_nv_undefine_space(&cmd_body, tpm_command_body, &body_size);
+ break;
+
case TPM2_NV_Read:
marshal_nv_read(&cmd_body, tpm_command_body, &body_size);
break;
@@ -760,6 +790,7 @@ int tpm_unmarshal_response(TPM_CC command,
case TPM2_Startup:
case TPM2_Shutdown:
case TPM2_NV_DefineSpace:
+ case TPM2_NV_UndefineSpace:
/* Session data included in response can be safely ignored. */
cr_size = 0;
break;
diff --git a/firmware/lib/tpm2_lite/tlcl.c b/firmware/lib/tpm2_lite/tlcl.c
index a05ef77f..8e5fbeac 100644
--- a/firmware/lib/tpm2_lite/tlcl.c
+++ b/firmware/lib/tpm2_lite/tlcl.c
@@ -193,6 +193,37 @@ uint32_t TlclDefineSpace(uint32_t index, uint32_t perm, uint32_t size)
return TlclDefineSpaceEx(NULL, 0, index, perm, size, NULL, 0);
}
+#ifdef CHROMEOS_ENVIRONMENT
+
+uint32_t TlclUndefineSpace(uint32_t index)
+{
+ return TlclUndefineSpaceEx(NULL, 0, index);
+}
+
+uint32_t TlclUndefineSpaceEx(const uint8_t* owner_auth,
+ uint32_t owner_auth_size,
+ uint32_t index)
+{
+ struct tpm2_nv_undefine_space_cmd undefine_space;
+ uint32_t permissions;
+ uint32_t rv;
+
+ /* Authentication support is not implemented. */
+ VbAssert(owner_auth == NULL && owner_auth_size == 0);
+
+ /* get the publicInfo of index */
+ rv = TlclGetPermissions(index, &permissions);
+ if (rv != TPM_SUCCESS) {
+ return rv;
+ }
+ undefine_space.nvIndex = HR_NV_INDEX + index;
+ undefine_space.use_platform_auth =
+ (permissions & TPMA_NV_PLATFORMCREATE) > 0;
+ return tpm_get_response_code(TPM2_NV_UndefineSpace, &undefine_space);
+}
+
+#endif /* CHROMEOS_ENVIRONMENT */
+
uint32_t TlclDefineSpaceEx(const uint8_t* owner_auth, uint32_t owner_auth_size,
uint32_t index, uint32_t perm, uint32_t size,
const void* auth_policy, uint32_t auth_policy_size)
diff --git a/firmware/lib/tpm_lite/tlcl.c b/firmware/lib/tpm_lite/tlcl.c
index 7643ce7b..b8d83335 100644
--- a/firmware/lib/tpm_lite/tlcl.c
+++ b/firmware/lib/tpm_lite/tlcl.c
@@ -439,6 +439,25 @@ uint32_t TlclDefineSpace(uint32_t index, uint32_t perm, uint32_t size)
return TlclDefineSpaceEx(NULL, 0, index, perm, size, NULL, 0);
}
+#ifdef CHROMEOS_ENVIRONMENT
+
+uint32_t TlclUndefineSpace(uint32_t index)
+{
+ VB2_DEBUG("TPM: TlclUndefineSpace(0x%x)\n", index);
+ return TlclUndefineSpaceEx(NULL, 0, index);
+}
+
+uint32_t TlclUndefineSpaceEx(const uint8_t* owner_auth,
+ uint32_t owner_auth_size,
+ uint32_t index)
+{
+ return TlclDefineSpaceEx(owner_auth, owner_auth_size,
+ index, 0, 0,
+ NULL, 0);
+}
+
+#endif /* CHROMEOS_ENVIRONMENT */
+
uint32_t TlclDefineSpaceEx(const uint8_t* owner_auth, uint32_t owner_auth_size,
uint32_t index, uint32_t perm, uint32_t size,
const void* auth_policy, uint32_t auth_policy_size)
diff --git a/firmware/linktest/main.c b/firmware/linktest/main.c
index 472a03a2..8d6549ce 100644
--- a/firmware/linktest/main.c
+++ b/firmware/linktest/main.c
@@ -34,6 +34,7 @@ int main(void)
TlclSelfTestFull();
TlclContinueSelfTest();
TlclDefineSpace(0, 0, 0);
+ TlclUndefineSpace(0);
TlclWrite(0, 0, 0);
TlclRead(0, 0, 0);
TlclWriteLock(0);
diff --git a/tests/tlcl_tests.c b/tests/tlcl_tests.c
index 9d67671e..385350dd 100644
--- a/tests/tlcl_tests.c
+++ b/tests/tlcl_tests.c
@@ -241,6 +241,11 @@ static void ReadWriteTest(void)
TEST_EQ(calls[0].req_cmd, TPM_ORD_NV_DefineSpace, " cmd");
ResetMocks();
+ TEST_EQ(TlclUndefineSpace(1), 0, "UndefineSpace");
+ // TPM1.2 use TPM_ORD_NV_DefineSpace with size 0 to delete space
+ TEST_EQ(calls[0].req_cmd, TPM_ORD_NV_DefineSpace, " cmd");
+
+ ResetMocks();
TEST_EQ(TlclSetNvLocked(), 0, "SetNvLocked");
TEST_EQ(calls[0].req_cmd, TPM_ORD_NV_DefineSpace, " cmd");