diff options
-rw-r--r-- | board/cr50/tpm2/platform.c | 58 |
1 files changed, 58 insertions, 0 deletions
diff --git a/board/cr50/tpm2/platform.c b/board/cr50/tpm2/platform.c index ce0a559390..e02b95e445 100644 --- a/board/cr50/tpm2/platform.c +++ b/board/cr50/tpm2/platform.c @@ -10,6 +10,7 @@ #include "console.h" #include "pinweaver.h" #include "tpm_nvmem.h" +#include "tpm_nvmem_ops.h" #include "dcrypto.h" #include "u2f_impl.h" #include "util.h" @@ -17,6 +18,41 @@ #define CPRINTF(format, args...) cprintf(CC_EXTENSION, format, ## args) +/* + * PCR0 values for the states when FWMP updates are allowed. + * For the source of the specific values see b/140958855#comment25. + */ +static const uint8_t allowed_states_for_fwmp[][SHA256_DIGEST_SIZE] = { + /* normal mode (rec=0, dev=0) */ + { + 0x89, 0xEA, 0xF3, 0x51, 0x34, 0xB4, 0xB3, 0xC6, + 0x49, 0xF4, 0x4C, 0x0C, 0x76, 0x5B, 0x96, 0xAE, + 0xAB, 0x8B, 0xB3, 0x4E, 0xE8, 0x3C, 0xC7, 0xA6, + 0x83, 0xC4, 0xE5, 0x3D, 0x15, 0x81, 0xC8, 0xC7 + }, + /* dev mode (rec=0, dev=1) */ + { + 0x23, 0xE1, 0x4D, 0xD9, 0xBB, 0x51, 0xA5, 0x0E, + 0x16, 0x91, 0x1F, 0x7E, 0x11, 0xDF, 0x1E, 0x1A, + 0xAF, 0x0B, 0x17, 0x13, 0x4D, 0xC7, 0x39, 0xC5, + 0x65, 0x36, 0x07, 0xA1, 0xEC, 0x8D, 0xD3, 0x7A + }, + /* recovery mode (rec=1, dev=0) */ + { + 0x9F, 0x9E, 0xA8, 0x66, 0xD3, 0xF3, 0x4F, 0xE3, + 0xA3, 0x11, 0x2A, 0xE9, 0xCB, 0x1F, 0xBA, 0xBC, + 0x6F, 0xFE, 0x8C, 0xD2, 0x61, 0xD4, 0x24, 0x93, + 0xBC, 0x68, 0x42, 0xA9, 0xE4, 0xF9, 0x3B, 0x3D + }, + /* initial PCR0 state at reset - all zeroes */ + { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + } +}; + uint16_t _cpri__GenerateRandom(size_t random_size, uint8_t *buffer) { @@ -105,7 +141,29 @@ void _plat__OwnerClearCallback(void) CPRINTF("%s: failed (%d)\n", __func__, rv); } +/* Returns TRUE if FWMP is allowed to be updated in the current state */ +static BOOL fwmp_update_allowed(void) +{ + uint8_t pcr0_value[SHA256_DIGEST_SIZE]; + int i; + + if (!get_tpm_pcr_value(0, pcr0_value)) + return FALSE; /* something went wrong, let's be strict */ + + for (i = 0; i < ARRAY_SIZE(allowed_states_for_fwmp); ++i) { + if (memcmp(pcr0_value, + allowed_states_for_fwmp[i], + SHA256_DIGEST_SIZE) == 0) + return TRUE; + } + + return FALSE; +} + BOOL _plat__NvUpdateAllowed(uint32_t handle) { + if (handle == HR_NV_INDEX + FWMP_NV_INDEX) + return fwmp_update_allowed(); + return TRUE; } |