diff --git a/board/cr50/tpm2/endorsement.c b/board/cr50/tpm2/endorsement.c index c3e818501c..1d189e8a78 100644 --- a/board/cr50/tpm2/endorsement.c +++ b/board/cr50/tpm2/endorsement.c @@ -392,6 +392,9 @@ int tpm_endorse(void) /* 2-kB RO cert region is setup like so: * * | struct ro_cert | rsa_cert | struct ro_cert | ecc_cert | + * + * last 32 bytes is hmac over (2048 - 32) preceding bytes. + * using hmac(eps, "RSA", 4) as key */ const uint8_t *p = (const uint8_t *) RO_CERTS_START_ADDR; const uint32_t *c = (const uint32_t *) RO_CERTS_START_ADDR; @@ -400,6 +403,8 @@ int tpm_endorse(void) int result = 0; uint8_t eps[PRIMARY_SEED_SIZE]; + LITE_HMAC_CTX hmac; + flash_cert_region_enable(); /* First boot, certs not yet installed. */ @@ -437,6 +442,21 @@ int tpm_endorse(void) return 0; } + /* Check cert region hmac. + * + * This will fail if we are not running w/ expected keyladder. + */ + DCRYPTO_HMAC_SHA256_init(&hmac, eps, sizeof(eps)); + HASH_update(&hmac.hash, "RSA", 4); + DCRYPTO_HMAC_SHA256_init(&hmac, DCRYPTO_HMAC_final(&hmac), 32); + HASH_update(&hmac.hash, p, RO_CERTS_REGION_SIZE - 32); + if (memcmp( + p + RO_CERTS_REGION_SIZE - 32, + DCRYPTO_HMAC_final(&hmac), 32) != 0) { + CPRINTF("%s: bad cert region hmac\n", __func__); + return 0; + } + do { if (!handle_cert( &rsa_cert->cert_info,