summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJulius Werner <jwerner@chromium.org>2020-02-04 17:44:33 -0800
committerCommit Bot <commit-bot@chromium.org>2020-02-13 21:52:14 +0000
commit821b5486a5df9ab403e6ac227c0a4f1ade2c0400 (patch)
treedd16b7807580831de03edae1c8b84f16e303d8c5
parente14a2c466ed75f14e8e144bbf40681f31617b40f (diff)
downloadvboot-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.h14
-rw-r--r--firmware/lib20/api_kernel.c29
-rw-r--r--firmware/lib20/misc.c54
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)