diff options
author | Meng-Huan Yu <menghuan@google.com> | 2018-10-19 21:03:35 +0800 |
---|---|---|
committer | chrome-bot <chrome-bot@chromium.org> | 2018-11-01 02:17:42 -0700 |
commit | 737e34e377dfb547e64c278470a224bfcde3b97c (patch) | |
tree | f81d8d509233a74ba142ea66662e3eb9adc8e67d | |
parent | 7283689dbd93502519edf47199b203b62da46ec1 (diff) | |
download | vboot-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.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"); |