diff options
-rw-r--r-- | firmware/include/tlcl.h | 19 | ||||
-rw-r--r-- | firmware/include/tpm2_tss_constants.h | 6 | ||||
-rw-r--r-- | firmware/lib/tpm2_lite/marshaling.c | 31 | ||||
-rw-r--r-- | firmware/lib/tpm2_lite/tlcl.c | 31 | ||||
-rw-r--r-- | firmware/lib/tpm_lite/tlcl.c | 19 | ||||
-rw-r--r-- | firmware/linktest/main.c | 1 | ||||
-rw-r--r-- | tests/tlcl_tests.c | 5 |
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"); |