summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVadim Bendebury <vbendeb@chromium.org>2018-05-10 21:41:33 -0700
committerchrome-bot <chrome-bot@chromium.org>2018-05-16 12:41:38 -0700
commit607865dca4965720feec5cb0d3a9148e4ab69b29 (patch)
tree104d44d8b4cd189acc71141ee5e54a5471c7bcbf
parentd9354c9cd980ce2d57b8b4ccdad921054579ae99 (diff)
downloadchrome-ec-607865dca4965720feec5cb0d3a9148e4ab69b29.tar.gz
cr50: in dev mode allow unverified certificates
When running signed with dev keys and the fallback certificate is not available, proceed installing unverified root certificate. This at least allows to keep basic TPM functions like storing objects in NVMEM to keep going. Added a new return value to indicate this condition. BRANCH=cr50, cr50-mp BUG=none TEST=verified that it is possible to switch chromebook between prod and dev modes when running with a dev signed Cr50. Change-Id: I5b16d0bcbcfb25368f65075e1d2d485a69cb729f Signed-off-by: Vadim Bendebury <vbendeb@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/1054990 Reviewed-by: Nagendra Modadugu <ngm@google.com> Reviewed-by: Andrey Pronin <apronin@chromium.org>
-rw-r--r--board/cr50/board.c16
-rw-r--r--board/cr50/tpm2/endorsement.c47
-rw-r--r--chip/g/signed_header.h11
-rw-r--r--include/tpm_manufacture.h1
4 files changed, 49 insertions, 26 deletions
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?
+ */
+ CPRINTF("NO certs installed\n");
+ result = mnf_hmac_mismatch;
+ break;
+ }
- /* TODO(ngm): is this state considered
- * endorsement failure?
+ /*
+ * 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);