From 08f93599a9728682783505fe7e6fa3e3b025a497 Mon Sep 17 00:00:00 2001 From: Vadim Bendebury Date: Wed, 21 Jun 2017 12:23:22 -0700 Subject: cr50: process uninitialized values gracefully The vboot code tries reading rollback protection indices from the TPM, and if the attempt to read returns TPM_E_BADINDEX, it decides that the TPM has not yet been initialized for the Chromebook use, and needs to be taken through the factory initialization sequence. TPM_E_BADINDEX is an internal representation of the TPM error 0x28b, generated on attempts to read a non existing NVMEM space. If the space exists, but has never been written the TPM returns error 0x14a. This condition (the space exists but not written) could happen if the previous factory initialization attempt was interrupted right after the space was created. Let's map this error to the same internal representation (TPM_E_BADINDEX) so that the Chrome OS device could recover when this condition occurs. BRANCH=reef, gru BUG=b:37443842 TEST=verified that the Pyro device stuck in TPM error state recovered when this patch was applied. Change-Id: I6ff976c839efcd23ae26cef3ee428e7ae02e68f8 Signed-off-by: Vadim Bendebury Reviewed-on: https://review.coreboot.org/20299 Tested-by: build bot (Jenkins) Reviewed-by: Aaron Durbin --- src/lib/tpm2_tlcl.c | 8 +++++++- src/lib/tpm2_tlcl_structures.h | 10 ++++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/lib/tpm2_tlcl.c b/src/lib/tpm2_tlcl.c index 754f835719..fde90a002a 100644 --- a/src/lib/tpm2_tlcl.c +++ b/src/lib/tpm2_tlcl.c @@ -210,7 +210,13 @@ uint32_t tlcl_read(uint32_t index, void *data, uint32_t length) case 0: break; - case 0x28b: + /* Uninitialized, returned if the space hasn't been written. */ + case TPM_RC_NV_UNINITIALIZED: + /* + * Bad index, cr50 specific value, returned if the space + * hasn't been defined. + */ + case TPM_RC_CR50_NV_UNDEFINED: return TPM_E_BADINDEX; default: diff --git a/src/lib/tpm2_tlcl_structures.h b/src/lib/tpm2_tlcl_structures.h index 2d6164b1b7..4ea20783e5 100644 --- a/src/lib/tpm2_tlcl_structures.h +++ b/src/lib/tpm2_tlcl_structures.h @@ -121,8 +121,18 @@ struct tpm_header { #define TPM_ST_NO_SESSIONS 0x8001 #define TPM_ST_SESSIONS 0x8002 +/* Values copied from tpm2/tpm_types.h */ #define RC_VER1 0x100 #define TPM_RC_INITIALIZE ((TPM_RC)(RC_VER1 + 0x000)) +#define TPM_RC_NV_UNINITIALIZED ((TPM_RC)(RC_VER1 + 0x04A)) + +/* + * Cr50 returns this code when an attempt is made to read an NV location which + * has not yet been defined. This is an aggregation of various return code + * extensions which may or may not match if a different TPM2 device is + * used. + */ +#define TPM_RC_CR50_NV_UNDEFINED 0x28b /* TPM command structures. */ -- cgit v1.2.3