diff options
author | Julius Werner <jwerner@chromium.org> | 2020-02-04 17:44:33 -0800 |
---|---|---|
committer | Commit Bot <commit-bot@chromium.org> | 2020-02-13 21:52:14 +0000 |
commit | 821b5486a5df9ab403e6ac227c0a4f1ade2c0400 (patch) | |
tree | dd16b7807580831de03edae1c8b84f16e303d8c5 | |
parent | e14a2c466ed75f14e8e144bbf40681f31617b40f (diff) | |
download | vboot-821b5486a5df9ab403e6ac227c0a4f1ade2c0400.tar.gz |
2lib: Add vb2api_is_developer_signed() to replace old dev key check
This patch removes the old check for developer keys from the firmware
verification path and instead inserts a similar (but faster) check into
vb2api_kernel_phase1(). This has the advantage that we can export the
check function to the calling firmware which could use it to display
this information in a more user-visible manner.
BRANCH=None
BUG=None
TEST=Booted in normal and recovery mode with developer keys, confirmed
they were recognized.
Change-Id: I00af0d10e31b2789574c8e4f1875ccd8d01eb0d5
Signed-off-by: Julius Werner <jwerner@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/vboot_reference/+/2038245
Reviewed-by: Joel Kitching <kitching@chromium.org>
-rw-r--r-- | firmware/2lib/include/2api.h | 14 | ||||
-rw-r--r-- | firmware/lib20/api_kernel.c | 29 | ||||
-rw-r--r-- | firmware/lib20/misc.c | 54 |
3 files changed, 43 insertions, 54 deletions
diff --git a/firmware/2lib/include/2api.h b/firmware/2lib/include/2api.h index 5470b308..2a87ab12 100644 --- a/firmware/2lib/include/2api.h +++ b/firmware/2lib/include/2api.h @@ -744,6 +744,20 @@ vb2_gbb_flags_t vb2api_gbb_get_flags(struct vb2_context *ctx); uint32_t vb2api_get_firmware_size(struct vb2_context *ctx); /** + * Check if this firmware was bundled with the well-known public developer key + * set (more specifically, checks the recovery key in recovery mode and the + * kernel subkey from the firmware preamble in other modes). This is a best + * effort check that could be misled by a specifically crafted key. + * + * May only be called after vb2api_kernel_phase1() has run. + * + * @param ctx Vboot context + * + * @return 1 for developer keys, 0 for any others. + */ +int vb2api_is_developer_signed(struct vb2_context *ctx); + +/** * If no display is available, set DISPLAY_REQUEST in nvdata. * * @param ctx Vboot2 context diff --git a/firmware/lib20/api_kernel.c b/firmware/lib20/api_kernel.c index 3748420f..1e96f281 100644 --- a/firmware/lib20/api_kernel.c +++ b/firmware/lib20/api_kernel.c @@ -16,6 +16,32 @@ #include "vb2_common.h" #include "vboot_struct.h" +int vb2api_is_developer_signed(struct vb2_context *ctx) +{ + struct vb2_shared_data *sd = vb2_get_sd(ctx); + + if (!sd->kernel_key_offset || !sd->kernel_key_size) { + VB2_REC_OR_DIE(ctx, "Cannot call this before kernel_phase1!\n"); + return 0; + } + + struct vb2_public_key key; + if (vb2_unpack_key(&key, vb2_member_of(sd, sd->kernel_key_offset))) + return 0; + + /* This is a debugging aid, not a security-relevant feature. There's no + reason to hardcode the whole key or waste time computing a hash. Just + spot check the starting bytes of the pseudorandom part of the key. */ + uint32_t devkey_n0inv = ctx->flags & VB2_CONTEXT_RECOVERY_MODE ? + 0x18cebcf5 : /* recovery_key.vbpubk @0x24 */ + 0xe0cd87d9; /* kernel_subkey.vbpubk @0x24 */ + + if (key.n0inv == devkey_n0inv) + return 1; + + return 0; +} + vb2_error_t vb2api_kernel_phase1(struct vb2_context *ctx) { struct vb2_shared_data *sd = vb2_get_sd(ctx); @@ -82,6 +108,9 @@ vb2_error_t vb2api_kernel_phase1(struct vb2_context *ctx) vb2_set_workbuf_used(ctx, vb2_offset_of(sd, wb.buf)); + if (vb2api_is_developer_signed(ctx)) + VB2_DEBUG("This is developer-signed firmware.\n"); + return VB2_SUCCESS; } diff --git a/firmware/lib20/misc.c b/firmware/lib20/misc.c index c81c3fed..da12f028 100644 --- a/firmware/lib20/misc.c +++ b/firmware/lib20/misc.c @@ -14,57 +14,6 @@ #include "2sysincludes.h" #include "vb2_common.h" -/* - * The blob below is the sha1 digest calculated over the packed developer - * root public key structure. - */ - -static const uint8_t dev_key_digest[] = { - 0xb1, 0x1d, 0x74, 0xed, 0xd2, 0x86, 0xc1, 0x44, - 0xe1, 0x13, 0x5b, 0x49, 0xe7, 0xf0, 0xbc, 0x20, - 0xcf, 0x04, 0x1f, 0x10, -}; - -/** - * Determine if the root key is the developer key checked into the - * vboot_reference repository. Has no effect on boot; just logs this to the - * debug console. - * - * @param root Root key - */ -static void vb2_report_dev_firmware(struct vb2_public_key *root) -{ - struct vb2_digest_context dc; - uint8_t digest[sizeof(dev_key_digest)]; - int size = root->arrsize * 4; - - if (!root->arrsize) - return; /* Must be a test run. */ - - if (vb2_digest_init(&dc, VB2_HASH_SHA1) != VB2_SUCCESS) - return; - - if (vb2_digest_extend(&dc, (uint8_t *)&root->arrsize, - sizeof(root->arrsize)) != VB2_SUCCESS) - return; - - if (vb2_digest_extend(&dc, (uint8_t *)&root->n0inv, - sizeof(root->n0inv)) != VB2_SUCCESS) - return; - - if (vb2_digest_extend(&dc, (uint8_t *)root->n, size) != VB2_SUCCESS) - return; - - if (vb2_digest_extend(&dc, (uint8_t *)root->rr, size) != VB2_SUCCESS) - return; - - if (vb2_digest_finalize(&dc, digest, sizeof(digest)) != VB2_SUCCESS) - return; - - if (!memcmp(digest, dev_key_digest, sizeof(dev_key_digest))) - VB2_DEBUG("This is developer signed firmware\n"); -} - vb2_error_t vb2_load_fw_keyblock(struct vb2_context *ctx) { struct vb2_shared_data *sd = vb2_get_sd(ctx); @@ -98,9 +47,6 @@ vb2_error_t vb2_load_fw_keyblock(struct vb2_context *ctx) if (rv) return rv; - /* If that's the checked-in root key, this is dev-signed firmware */ - vb2_report_dev_firmware(&root_key); - /* Load the firmware keyblock header after the root key */ kb = vb2_workbuf_alloc(&wb, sizeof(*kb)); if (!kb) |