diff options
author | Vadim Bendebury <vbendeb@chromium.org> | 2016-11-14 16:36:26 -0800 |
---|---|---|
committer | Vadim Bendebury <vbendeb@chromium.org> | 2016-11-16 02:16:11 +0100 |
commit | 3883701d5a91f6431d4579734c022f7748249ec1 (patch) | |
tree | 06493229e2f1d42aba0ea7f866953ff3473b3500 | |
parent | af8ae93172bd793787dc3a9b81695905c1899d1f (diff) |
vboot: make TPM factory init sequence more robust.
Currently the code considers the absence of the NVRAM firmware
rollback space a a trigger for invoking the TPM factory initialization
sequence.
Note that the kernel rollback and MRC cache hash spaces are created
after the firmware rollback space. This opens an ever so narrow window
of opportunity for bricking the device, in case a startup is
interrupted after firmware space has been created, but before kernel
and MRC hash spaces are created.
The suggested solution is to create the firmware space last, and to
allow for kernel and MRC cache spaces to exist during TPM factory
initialization.
BRANCH=none
BUG=chrome-os-partner:59654
TEST=odified the code not to create the firmware space, wiped out the
TPM NVRAM and booted the device. Observed it create kernel and
MRC cache spaces on the first run, and then reporting return code
0x14c for already existing spaces on the following restarts.
Verified that the device boots fine in normal and recovery modes
and TPM NVRAM spaces are writeable in recovery mode.
Change-Id: Id0e772448d6af1340e800ec3b78ec67913aa6289
Signed-off-by: Vadim Bendebury <vbendeb@chromium.org>
Reviewed-on: https://review.coreboot.org/17398
Reviewed-by: Aaron Durbin <adurbin@chromium.org>
Tested-by: build bot (Jenkins)
-rw-r--r-- | src/vboot/secdata_tpm.c | 44 |
1 files changed, 33 insertions, 11 deletions
diff --git a/src/vboot/secdata_tpm.c b/src/vboot/secdata_tpm.c index 357d6e3fb7..4c1e128797 100644 --- a/src/vboot/secdata_tpm.c +++ b/src/vboot/secdata_tpm.c @@ -150,31 +150,53 @@ static uint32_t set_firmware_space(const void *firmware_blob) static uint32_t set_kernel_space(const void *kernel_blob) { - RETURN_ON_FAILURE(tlcl_define_space(KERNEL_NV_INDEX, - sizeof(secdata_kernel))); - RETURN_ON_FAILURE(safe_write(KERNEL_NV_INDEX, kernel_blob, - sizeof(secdata_kernel))); - return TPM_SUCCESS; + uint32_t rv; + + rv = tlcl_define_space(KERNEL_NV_INDEX, sizeof(secdata_kernel)); + if (rv == TPM_E_NV_DEFINED) { + VBDEBUG("%s: kernel space already exists\n", __func__); + return TPM_SUCCESS; + } + + if (rv != TPM_SUCCESS) + return rv; + + return safe_write(KERNEL_NV_INDEX, kernel_blob, sizeof(secdata_kernel)); } static uint32_t set_rec_hash_space(const uint8_t *data) { - RETURN_ON_FAILURE(tlcl_define_space(REC_HASH_NV_INDEX, - REC_HASH_NV_SIZE)); - RETURN_ON_FAILURE(safe_write(REC_HASH_NV_INDEX, data, - REC_HASH_NV_SIZE)); - return TPM_SUCCESS; + uint32_t rv; + + rv = tlcl_define_space(REC_HASH_NV_INDEX, REC_HASH_NV_SIZE); + if (rv == TPM_E_NV_DEFINED) { + VBDEBUG("%s: MRC Hash space already exists\n", __func__); + return TPM_SUCCESS; + } + + if (rv != TPM_SUCCESS) + return rv; + + return safe_write(REC_HASH_NV_INDEX, data, REC_HASH_NV_SIZE); } static uint32_t _factory_initialize_tpm(struct vb2_context *ctx) { RETURN_ON_FAILURE(tlcl_force_clear()); - RETURN_ON_FAILURE(set_firmware_space(ctx->secdata)); + + /* + * Of all NVRAM spaces defined by this function the firmware space + * must be defined last, because its existence is considered an + * indication that TPM factory initialization was successfully + * completed. + */ RETURN_ON_FAILURE(set_kernel_space(secdata_kernel)); if (IS_ENABLED(CONFIG_VBOOT_HAS_REC_HASH_SPACE)) RETURN_ON_FAILURE(set_rec_hash_space(rec_hash_data)); + RETURN_ON_FAILURE(set_firmware_space(ctx->secdata)); + return TPM_SUCCESS; } |