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 <vbendeb@chromium.org>
Reviewed-on: https://review.coreboot.org/20299
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Aaron Durbin <adurbin@chromium.org>
This commit is contained in:
Vadim Bendebury 2017-06-21 12:23:22 -07:00
parent ca117e7f49
commit 08f93599a9
2 changed files with 17 additions and 1 deletions

View File

@ -210,7 +210,13 @@ uint32_t tlcl_read(uint32_t index, void *data, uint32_t length)
case 0: case 0:
break; 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; return TPM_E_BADINDEX;
default: default:

View File

@ -121,8 +121,18 @@ struct tpm_header {
#define TPM_ST_NO_SESSIONS 0x8001 #define TPM_ST_NO_SESSIONS 0x8001
#define TPM_ST_SESSIONS 0x8002 #define TPM_ST_SESSIONS 0x8002
/* Values copied from tpm2/tpm_types.h */
#define RC_VER1 0x100 #define RC_VER1 0x100
#define TPM_RC_INITIALIZE ((TPM_RC)(RC_VER1 + 0x000)) #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. */ /* TPM command structures. */