diff --git a/board/cr50/board.c b/board/cr50/board.c index 20c9dce02b..c4e2bb1529 100644 --- a/board/cr50/board.c +++ b/board/cr50/board.c @@ -1293,17 +1293,9 @@ int board_is_first_factory_boot(void) } /* Determine key type based on the key ID. */ -static const char *key_type(uint32_t key_id) +static const char *key_type(const struct SignedHeader *h) { - - /* - * It is a mere convention, but all prod keys are required to have key - * IDs such, that bit D2 is set, and all dev keys are required to have - * key IDs such, that bit D2 is not set. - * - * This convention is enforced at the key generation time. - */ - if (key_id & (1 << 2)) + if (G_SIGNED_FOR_PROD(h)) return "prod"; else return "dev"; @@ -1330,12 +1322,12 @@ static int command_sysinfo(int argc, char **argv) active = system_get_ro_image_copy(); vaddr = get_program_memory_addr(active); h = (const struct SignedHeader *)vaddr; - ccprintf("RO keyid: 0x%08x(%s)\n", h->keyid, key_type(h->keyid)); + ccprintf("RO keyid: 0x%08x(%s)\n", h->keyid, key_type(h)); active = system_get_image_copy(); vaddr = get_program_memory_addr(active); h = (const struct SignedHeader *)vaddr; - ccprintf("RW keyid: 0x%08x(%s)\n", h->keyid, key_type(h->keyid)); + ccprintf("RW keyid: 0x%08x(%s)\n", h->keyid, key_type(h)); ccprintf("DEV_ID: 0x%08x 0x%08x\n", GREG32(FUSE, DEV_ID0), GREG32(FUSE, DEV_ID1)); diff --git a/board/cr50/tpm2/endorsement.c b/board/cr50/tpm2/endorsement.c index 62f6893fa5..a9751d43fb 100644 --- a/board/cr50/tpm2/endorsement.c +++ b/board/cr50/tpm2/endorsement.c @@ -24,6 +24,7 @@ #include "flash_info.h" #include "printf.h" #include "registers.h" +#include "system.h" #include "tpm_manufacture.h" #include "tpm_registers.h" @@ -610,10 +611,10 @@ enum manufacturing_status tpm_endorse(void) HASH_update(&hmac.hash, p, RO_CERTS_REGION_SIZE - 32); if (!DCRYPTO_equals(p + RO_CERTS_REGION_SIZE - 32, DCRYPTO_HMAC_final(&hmac), 32)) { -#ifdef CR50_INCLUDE_FALLBACK_CERT - CPRINTF("%s: bad cert region hmac; falling back\n" - " to fixed endorsement\n", __func__); + const struct SignedHeader *h; + CPRINTF("%s: bad cert region hmac;", __func__); +#ifdef CR50_INCLUDE_FALLBACK_CERT /* HMAC verification failure indicates either * a manufacture fault, or mis-match in * production mode and currently running @@ -625,21 +626,39 @@ enum manufacturing_status tpm_endorse(void) * by production infrastructure. */ if (!install_fixed_certs()) { - CPRINTF("%s: failed to install fixed " - "endorsement certs; \n" - " unknown endorsement state\n", - __func__); + CPRINTF(" failed to install fixed " + "endorsement certs;"); + result = mnf_hmac_mismatch; + break; } #else - CPRINTF("%s: bad cert region hmac; no certs installed!" - "\n", __func__); -#endif + h = (const struct SignedHeader *) + get_program_memory_addr + (system_get_image_copy()); + if (G_SIGNED_FOR_PROD(h)) { - /* TODO(ngm): is this state considered - * endorsement failure? + /* TODO(ngm): is this state considered + * endorsement failure? + */ + CPRINTF("NO certs installed\n"); + result = mnf_hmac_mismatch; + break; + } + + /* + * This will install bogus certificate, will happen + * only when Cr50 image is signed with dev key. + * + * Installing bogus certificate helps with simple TPM + * operations, as it allows to prevent TPM going + * through manufacturing process after every reset, + * but the generated RSA endorsement will not + * correspond to the certificate, which will cause + * problems when TPM identity is required. */ - result = mnf_hmac_mismatch; - break; + result = mnf_unverified_cert; + CPRINTF("instaling UNVERIFIED certs\n"); +#endif } if (!handle_cert( diff --git a/chip/g/signed_header.h b/chip/g/signed_header.h index 5f274f3a0b..26a85aebf3 100644 --- a/chip/g/signed_header.h +++ b/chip/g/signed_header.h @@ -67,4 +67,15 @@ BUILD_ASSERT(sizeof(struct SignedHeader) == 1024); BUILD_ASSERT(offsetof(struct SignedHeader, info_chk_) == 1020); #define TOP_IMAGE_SIZE_BIT (1 << \ (sizeof(((struct SignedHeader *)0)->image_size) * 8 - 1)) + +/* + * It is a mere convention, but all prod keys are required to have key IDs + * such, that bit D2 is set, and all dev keys are required to have key IDs + * such, that bit D2 is not set. + * + * This convention is enforced at the key generation time. + */ +#define G_SIGNED_FOR_PROD(h) ((h)->keyid & (1 << 2)) + + #endif /* __CROS_EC_SIGNED_HEADER_H */ diff --git a/include/tpm_manufacture.h b/include/tpm_manufacture.h index df43bcc886..4d62bb0e3b 100644 --- a/include/tpm_manufacture.h +++ b/include/tpm_manufacture.h @@ -28,6 +28,7 @@ enum manufacturing_status { mnf_ecc_proc = 9, mnf_store = 10, mnf_manufactured = 11, + mnf_unverified_cert = 12, }; enum manufacturing_status tpm_endorse(void);