summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/vboot/secdata_tpm.c44
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;
}