summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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");