summaryrefslogtreecommitdiff
path: root/common
diff options
context:
space:
mode:
authorDaisuke Nojiri <dnojiri@chromium.org>2017-07-07 09:49:36 -0700
committerchrome-bot <chrome-bot@chromium.org>2017-07-13 19:45:57 -0700
commit4ec4975d90713b58557beca7ed2a94745d7476e3 (patch)
treeb6f5cf7601f271944de4793cfd2392b5954659e5 /common
parent7630636a0fe8ceb2dbba2b175564a17900d175cf (diff)
downloadchrome-ec-4ec4975d90713b58557beca7ed2a94745d7476e3.tar.gz
vboot: Move common code under common/vboot
This patch moves the code which can be shared with other data verification schemes (e.g. RWSIG) under common/vboot. It also adds unit tests for it. BUG=b:38462249 BRANCH=none TEST=make run-vboot. Verify verification succeeds on Fizz. Change-Id: Icab4d96dd2c154a12b01c41ebe9b46286b4b590e Signed-off-by: Daisuke Nojiri <dnojiri@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/563463 Reviewed-by: Randall Spangler <rspangler@chromium.org>
Diffstat (limited to 'common')
-rw-r--r--common/build.mk5
-rw-r--r--common/vboot/common.c60
-rw-r--r--common/vboot/vb21_lib.c44
-rw-r--r--common/vboot/vboot.c (renamed from common/vboot.c)105
4 files changed, 119 insertions, 95 deletions
diff --git a/common/build.mk b/common/build.mk
index 7907a87e30..9ceef96bc1 100644
--- a/common/build.mk
+++ b/common/build.mk
@@ -87,7 +87,8 @@ common-$(CONFIG_PWM_KBLIGHT)+=pwm_kblight.o
common-$(CONFIG_RMA_AUTH)+=rma_auth.o
common-$(CONFIG_RSA)+=rsa.o
common-$(CONFIG_ROLLBACK)+=rollback.o
-common-$(CONFIG_RWSIG)+=rwsig.o
+common-$(CONFIG_RWSIG)+=rwsig.o vboot/common.o
+common-$(CONFIG_RWSIG_TYPE_RWSIG)+=vboot/vb21_lib.o
common-$(CONFIG_MATH_UTIL)+=math_util.o
common-$(CONFIG_SHA1)+= sha1.o
common-$(CONFIG_SHA256)+=sha256.o
@@ -112,7 +113,7 @@ common-$(CONFIG_USB_POWER_DELIVERY)+=usb_pd_protocol.o usb_pd_policy.o
common-$(CONFIG_USB_PD_LOGGING)+=pd_log.o
common-$(CONFIG_USB_PD_TCPC)+=usb_pd_tcpc.o
common-$(CONFIG_USB_UPDATE)+=usb_update.o update_fw.o
-common-$(CONFIG_VBOOT_EC)+=vboot.o
+common-$(CONFIG_VBOOT_EC)+=vboot/vboot.o
common-$(CONFIG_VBOOT_HASH)+=sha256.o vboot_hash.o
common-$(CONFIG_VSTORE)+=vstore.o
common-$(CONFIG_WIRELESS)+=wireless.o
diff --git a/common/vboot/common.c b/common/vboot/common.c
new file mode 100644
index 0000000000..3a75a297e6
--- /dev/null
+++ b/common/vboot/common.c
@@ -0,0 +1,60 @@
+/* Copyright 2017 The Chromium OS Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "common.h"
+#include "console.h"
+#include "rsa.h"
+#include "sha256.h"
+#include "shared_mem.h"
+#include "vboot.h"
+
+#define CPRINTS(format, args...) cprints(CC_VBOOT, format, ## args)
+#define CPRINTF(format, args...) cprintf(CC_VBOOT, format, ## args)
+
+int vboot_is_padding_valid(const uint8_t *data, uint32_t start, uint32_t end)
+{
+ const uint32_t *data32 = (const uint32_t *)data;
+ int i;
+
+ if (start > end)
+ return EC_ERROR_INVAL;
+
+ if (start % 4 || end % 4)
+ return EC_ERROR_INVAL;
+
+ for (i = start / 4; i < end / 4; i++) {
+ if (data32[i] != 0xffffffff)
+ return EC_ERROR_INVAL;
+ }
+
+ return EC_SUCCESS;
+}
+
+int vboot_verify(const uint8_t *data, int len,
+ const struct rsa_public_key *key, const uint8_t *sig)
+{
+ struct sha256_ctx ctx;
+ uint8_t *hash;
+ uint32_t *workbuf;
+ int err = EC_SUCCESS;
+
+ if (shared_mem_acquire(3 * RSANUMBYTES, (char **)&workbuf)) {
+ CPRINTS("Failed to allocate memory");
+ return EC_ERROR_UNKNOWN;
+ }
+
+ /* Compute hash of the RW firmware */
+ SHA256_init(&ctx);
+ SHA256_update(&ctx, data, len);
+ hash = SHA256_final(&ctx);
+
+ /* Verify the data */
+ if (rsa_verify(key, sig, hash, workbuf) != 1)
+ err = EC_ERROR_INVAL;
+
+ shared_mem_release(workbuf);
+
+ return err;
+}
diff --git a/common/vboot/vb21_lib.c b/common/vboot/vb21_lib.c
new file mode 100644
index 0000000000..11242a3038
--- /dev/null
+++ b/common/vboot/vb21_lib.c
@@ -0,0 +1,44 @@
+/* Copyright 2017 The Chromium OS Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+/*
+ * Common utility APIs for vboot 2.1
+ */
+
+#include "common.h"
+#include "rsa.h"
+#include "rwsig.h"
+#include "vb21_struct.h"
+#include "vboot.h"
+
+int vb21_is_packed_key_valid(const struct vb21_packed_key *key)
+{
+ if (key->c.magic != VB21_MAGIC_PACKED_KEY)
+ return EC_ERROR_INVAL;
+ if (key->key_size != sizeof(struct rsa_public_key))
+ return EC_ERROR_INVAL;
+ return EC_SUCCESS;
+}
+
+int vb21_is_signature_valid(const struct vb21_signature *sig,
+ const struct vb21_packed_key *key)
+{
+ if (sig->c.magic != VB21_MAGIC_SIGNATURE)
+ return EC_ERROR_INVAL;
+ if (sig->sig_size != RSANUMBYTES)
+ return EC_ERROR_INVAL;
+ if (key->sig_alg != sig->sig_alg)
+ return EC_ERROR_INVAL;
+ if (key->hash_alg != sig->hash_alg)
+ return EC_ERROR_INVAL;
+ /* Sanity check signature offset and data size. */
+ if (sig->sig_offset < sizeof(*sig))
+ return EC_ERROR_INVAL;
+ if (sig->sig_offset + RSANUMBYTES > CONFIG_RW_SIG_SIZE)
+ return EC_ERROR_INVAL;
+ if (sig->data_size > CONFIG_RW_SIZE - CONFIG_RW_SIG_SIZE)
+ return EC_ERROR_INVAL;
+ return EC_SUCCESS;
+}
diff --git a/common/vboot.c b/common/vboot/vboot.c
index 1e92572c5b..27c57b27c2 100644
--- a/common/vboot.c
+++ b/common/vboot/vboot.c
@@ -22,6 +22,7 @@
#include "vb21_struct.h"
#define CPRINTS(format, args...) cprints(CC_VBOOT, format, ## args)
+#define CPRINTF(format, args...) cprintf(CC_VBOOT, format, ## args)
enum vboot_ec_slot {
VBOOT_EC_SLOT_A,
@@ -47,93 +48,14 @@ static int is_low_power_ap_boot_supported(void)
return 0;
}
-static int is_vb21_packed_key_valid(const struct vb21_packed_key *key)
-{
- if (key->c.magic != VB21_MAGIC_PACKED_KEY)
- return EC_ERROR_INVAL;
- if (key->key_size != sizeof(struct rsa_public_key))
- return EC_ERROR_INVAL;
- return EC_SUCCESS;
-}
-
-static int is_vb21_signature_valid(const struct vb21_signature *sig,
- const struct vb21_packed_key *key)
-{
- if (sig->c.magic != VB21_MAGIC_SIGNATURE)
- return EC_ERROR_INVAL;
- if (sig->sig_size != RSANUMBYTES)
- return EC_ERROR_INVAL;
- if (key->sig_alg != sig->sig_alg)
- return EC_ERROR_INVAL;
- if (key->hash_alg != sig->hash_alg)
- return EC_ERROR_INVAL;
- /* Sanity check signature offset and data size. */
- if (sig->sig_offset < sizeof(*sig))
- return EC_ERROR_INVAL;
- if (sig->sig_offset + RSANUMBYTES > CONFIG_RW_SIG_SIZE)
- return EC_ERROR_INVAL;
- if (sig->data_size > CONFIG_RW_SIZE - CONFIG_RW_SIG_SIZE)
- return EC_ERROR_INVAL;
- return EC_SUCCESS;
-}
-
-static int is_padding_valid(const uint8_t *data, unsigned int start, int len)
-{
- const uint32_t *data32 = (const uint32_t *)data;
- int i;
-
- if (len < 0)
- return EC_ERROR_INVAL;
-
- if ((start % 4) != 0 || (len % 4) != 0)
- return EC_ERROR_INVAL;
-
- for (i = start/4; i < len/4; i++) {
- if (data32[i] != 0xffffffff)
- return EC_ERROR_INVAL;
- }
-
- return EC_SUCCESS;
-}
-
-static int vboot_verify(const uint8_t *data, int len,
- const struct rsa_public_key *key, const uint8_t *sig)
-{
- struct sha256_ctx ctx;
- uint8_t *hash;
- uint32_t *workbuf;
- int err = EC_SUCCESS;
-
- if (shared_mem_acquire(3 * RSANUMBYTES, (char **)&workbuf)) {
- CPRINTS("Failed to allocate memory");
- return EC_ERROR_UNKNOWN;
- }
-
- /* Compute hash of the RW firmware */
- SHA256_init(&ctx);
- SHA256_update(&ctx, data, len);
- hash = SHA256_final(&ctx);
-
- /* Verify the data */
- if (rsa_verify(key, sig, hash, workbuf) != 1) {
- CPRINTS("Invalid data");
- err = EC_ERROR_INVAL;
- }
-
- shared_mem_release(workbuf);
-
- return err;
-}
-
static int verify_slot(int slot)
{
- const uint8_t *data;
const struct vb21_packed_key *vb21_key;
const struct vb21_signature *vb21_sig;
const struct rsa_public_key *key;
const uint8_t *sig;
+ const uint8_t *data;
int len;
- int rv = EC_ERROR_INVAL;
CPRINTS("Verifying RW_%c", slot == VBOOT_EC_SLOT_A ? 'A' : 'B');
@@ -141,9 +63,9 @@ static int verify_slot(int slot)
CONFIG_MAPPED_STORAGE_BASE +
CONFIG_EC_PROTECTED_STORAGE_OFF +
CONFIG_RO_PUBKEY_STORAGE_OFF);
- if (is_vb21_packed_key_valid(vb21_key)) {
+ if (vb21_is_packed_key_valid(vb21_key)) {
CPRINTS("Invalid key");
- goto exit;
+ return EC_ERROR_INVAL;
}
key = (const struct rsa_public_key *)
((const uint8_t *)vb21_key + vb21_key->key_offset);
@@ -166,28 +88,25 @@ static int verify_slot(int slot)
CONFIG_RW_B_SIGN_STORAGE_OFF);
}
- if (is_vb21_signature_valid(vb21_sig, vb21_key)) {
+ if (vb21_is_signature_valid(vb21_sig, vb21_key)) {
CPRINTS("Invalid signature");
- goto exit;
+ return EC_ERROR_INVAL;
}
sig = (const uint8_t *)vb21_sig + vb21_sig->sig_offset;
len = vb21_sig->data_size;
- if (is_padding_valid(data, len,
- CONFIG_RW_SIZE - len - CONFIG_RW_SIG_SIZE)) {
+ if (vboot_is_padding_valid(data, len,
+ CONFIG_RW_SIZE - CONFIG_RW_SIG_SIZE)) {
CPRINTS("Invalid padding");
- goto exit;
+ return EC_ERROR_INVAL;
}
if (vboot_verify(data, len, key, sig)) {
CPRINTS("Invalid data");
- goto exit;
+ return EC_ERROR_INVAL;
}
- rv = EC_SUCCESS;
-
-exit:
- return rv;
+ return EC_SUCCESS;
}
static int verify_and_jump(void)
@@ -238,7 +157,7 @@ static int is_manual_recovery(void)
return host_get_events() & EC_HOST_EVENT_KEYBOARD_RECOVERY;
}
-void vboot_ec(void)
+void vboot_main(void)
{
int port = charge_manager_get_active_charge_port();