From 85025bfe2db45b0ccdc9cdb72a61398f36eecca5 Mon Sep 17 00:00:00 2001 From: Marius Schilder Date: Tue, 4 Oct 2016 22:47:54 -0700 Subject: [PATCH] Make sure endorsement cert matches current keyladder. Endorsement registration is done with 0 for FWR keyladder branch. The certificate packet has hmac with key derived from keyladder. Thus RW can check that the certificate packet it is about to load does indeed match its current keyladder status. If not, reject. BUG=none BRANCH=none TEST=launch RW that has 1 for FWR and observe fail; 0 for FWR RW succeeds. Change-Id: I820892a54fbf9aa52a6f778595b5b7ef4389cff3 Reviewed-on: https://chromium-review.googlesource.com/393233 Reviewed-by: Vadim Bendebury Reviewed-by: Marius Schilder Tested-by: Vadim Bendebury Tested-by: Marius Schilder Commit-Queue: Marius Schilder --- board/cr50/tpm2/endorsement.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) 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,