From c2434ec5eb46b6c28fd22c8f10ae6dd43c48475d Mon Sep 17 00:00:00 2001 From: Vadim Bendebury Date: Sat, 16 Jul 2016 18:14:02 -0700 Subject: [PATCH] CR50: do not try searching in uninitialized TPM NV RAM. The manufacturing status check verifies if the proper certificates are found in the device NV RAM. This check can not succeed unless NV RAM metadata is initialized by calling _TPM_Init(). If the check shows that the device has not been through manufacturing sequence yet, TPM_Manufacture() needs to be invoked to make sure that all relevant TPM structures are initialized and properly stored in NV RAM. _TPM_Init() needs to be invoked again after that. BRANCH=ToT BUG=chrome-os-partner:43025 TEST=restarting Kevin device with pre-manufactured CR50 takes it through factory initialization on every reboot. Restarting Kevin once TPM is through manufacturing process shows that the previously saved rollback counters are preserved. Signed-off-by: Vadim Bendebury Reviewed-on: https://chromium-review.googlesource.com/361093 Reviewed-by: Nagendra Modadugu (cherry picked from commit 61a0fe734e808d1dbdf56fb6023e04adf66553b3) (cherry picked from commit 3207a57fb2f5957b6e833d9ab1f9ea46021c5e1e) Change-Id: I80b69f2c4b8d0e4cca154db510867df39c707ce2 Reviewed-on: https://chromium-review.googlesource.com/362084 --- common/tpm_registers.c | 29 ++++++++++++++--------------- 1 file changed, 14 insertions(+), 15 deletions(-) diff --git a/common/tpm_registers.c b/common/tpm_registers.c index 5a71dea1b2..66b6bcbf81 100644 --- a/common/tpm_registers.c +++ b/common/tpm_registers.c @@ -17,6 +17,7 @@ #include "signed_header.h" #include "system.h" #include "task.h" +#include "tpm_manufacture.h" #include "tpm_registers.h" #include "util.h" #include "watchdog.h" @@ -447,12 +448,8 @@ void tpm_register_get(uint32_t regaddr, uint8_t *dest, uint32_t data_size) CPRINTF("\n"); } - static void tpm_init(void) { - uint32_t saved_value; - const uint32_t manufacturing_done = 0x12344321; - set_tpm_state(tpm_state_idle); tpm_.regs.access = tpm_reg_valid_sts; tpm_.regs.sts = (tpm_family_tpm2 << tpm_family_shift) | @@ -463,22 +460,24 @@ static void tpm_init(void) /* - * TODO(ngm): CRBUG/50115, initialize state expected by TPM2 - * compliance tests. + * Make sure NV RAM metadata is initialized, needed to check + * manufactured status. This is a speculative call which will have to + * be repeated in case the TPM has not been through the manufacturing + * sequence yet. * - * Until it is done properly, use location at offset 0 in the generic - * section of NVRAM to store the manufacturing status. Otherwise the - * NV RAM is wiped out on every reboot. + * No harm in calling it twice in that case. */ - nvmem_read(0, sizeof(saved_value), &saved_value, NVMEM_CR50); - if (saved_value != manufacturing_done) { + _TPM_Init(); + + if (!tpm_manufactured()) { + /* + * If tpm has not been manufactured yet - this needs to run on + * every startup. It will wipe out NV RAM, among other things. + */ TPM_Manufacture(1); - saved_value = manufacturing_done; - nvmem_write(0, sizeof(saved_value), &saved_value, NVMEM_CR50); - nvmem_commit(); + _TPM_Init(); } - _TPM_Init(); _plat__SetNvAvail(); }