summaryrefslogtreecommitdiff
path: root/common
diff options
context:
space:
mode:
authorRandall Spangler <rspangler@chromium.org>2012-08-07 15:43:57 -0700
committerGerrit <chrome-bot@google.com>2012-08-07 19:06:33 -0700
commit45cd8463a3e1611e4721ccb9f1beef8f4ab897af (patch)
treee5e17df16d7b145dd5321e29a37fe9c45552fd07 /common
parent29cbe516631f15d548be1da101b6f04f692982d4 (diff)
downloadchrome-ec-45cd8463a3e1611e4721ccb9f1beef8f4ab897af.tar.gz
Remove signature-based vboot support
Superseded by EC software sync (hash-based). Sig-based vboot was correctly implemented, but ended up being too slow to be useful given the limited processing power of the EC chips, and we also couldn't come up with a manageable way to handle A/B autoupdate of signed EC firmware. This change and an associated vboot_reference change shrinks the EC binary by ~2KB. BUG=chrome-os-partner:11232 TEST=build link,snow; boot link and check that 'hash' command still works. Change-Id: I3f03ae2d0a4030977826980d6ec5613181e154c2 Signed-off-by: Randall Spangler <rspangler@chromium.org> Reviewed-on: https://gerrit.chromium.org/gerrit/29496 Reviewed-by: Bill Richardson <wfrichar@chromium.org>
Diffstat (limited to 'common')
-rw-r--r--common/build.mk17
-rw-r--r--common/fmap.c29
-rw-r--r--common/main.c20
-rw-r--r--common/vboot.c46
-rw-r--r--common/vboot_sig.c163
-rw-r--r--common/vboot_stub.c149
6 files changed, 3 insertions, 421 deletions
diff --git a/common/build.mk b/common/build.mk
index 10dbb23d8c..3bfe81210d 100644
--- a/common/build.mk
+++ b/common/build.mk
@@ -40,28 +40,15 @@ VBOOT_DEVKEYS?=/usr/share/vboot/devkeys
CFLAGS_$(CONFIG_VBOOT)+= -DCHROMEOS_ENVIRONMENT -DCHROMEOS_EC
# CFLAGS_$(CONFIG_VBOOT)+= -DVBOOT_DEBUG
-common-$(CONFIG_VBOOT)+=vboot.o vboot_stub.o
-common-$(CONFIG_VBOOT_HASH)+=vboot_hash.o
-common-$(CONFIG_VBOOT_SIG)+=vboot_sig.o
+common-$(CONFIG_VBOOT)+=vboot_stub.o vboot_hash.o
includes-$(CONFIG_VBOOT)+= \
$(VBOOT_SOURCE)/include \
$(VBOOT_SOURCE)/lib/include \
$(VBOOT_SOURCE)/lib/cryptolib/include
-dirs-$(CONFIG_VBOOT)+= \
- vboot/lib vboot/lib/cryptolib
+dirs-$(CONFIG_VBOOT)+=vboot/lib vboot/lib/cryptolib
vboot-$(CONFIG_VBOOT)+= \
lib/cryptolib/padding.o \
- lib/cryptolib/sha_utility.o \
lib/cryptolib/sha256.o
-
-vboot-$(CONFIG_VBOOT_SIG)+= \
- lib/vboot_common.o \
- lib/utility.o \
- lib/cryptolib/rsa_utility.o \
- lib/cryptolib/rsa.o \
- lib/stateful_util.o
-
-sign-$(CONFIG_VBOOT_SIG)+=sign_image
diff --git a/common/fmap.c b/common/fmap.c
index 3adb1c1c6f..8035653128 100644
--- a/common/fmap.c
+++ b/common/fmap.c
@@ -45,11 +45,7 @@ typedef struct _FmapAreaHeader {
uint16_t area_flags;
} __packed FmapAreaHeader;
-#ifdef CONFIG_VBOOT_SIG
-#define NUM_EC_FMAP_AREAS (7 + 3)
-#else
#define NUM_EC_FMAP_AREAS 7
-#endif
const struct _ec_fmap {
FmapHeader header;
@@ -112,16 +108,8 @@ const struct _ec_fmap {
.area_size = CONFIG_SECTION_RO_SIZE,
.area_flags = FMAP_AREA_STATIC | FMAP_AREA_RO,
},
-#ifdef CONFIG_VBOOT_SIG
- {
- .area_name = "ROOT_KEY",
- .area_offset = CONFIG_VBOOT_ROOTKEY_OFF,
- .area_size = CONFIG_VBOOT_ROOTKEY_SIZE,
- .area_flags = FMAP_AREA_STATIC | FMAP_AREA_RO,
- },
-#endif
- /* RW Firmware */
+ /* RW Firmware */
{
/* The range of RW firmware to be auto-updated. */
.area_name = "EC_RW",
@@ -139,20 +127,5 @@ const struct _ec_fmap {
.area_size = sizeof(version_data.version),
.area_flags = FMAP_AREA_STATIC,
},
-
-#ifdef CONFIG_VBOOT_SIG
- {
- .area_name = "FW_MAIN",
- .area_offset = CONFIG_FW_RW_OFF,
- .area_size = CONFIG_FW_RW_SIZE,
- .area_flags = FMAP_AREA_STATIC,
- },
- {
- .area_name = "VBLOCK",
- .area_offset = CONFIG_VBLOCK_RW_OFF,
- .area_size = CONFIG_VBLOCK_SIZE,
- .area_flags = FMAP_AREA_STATIC,
- },
-#endif
}
};
diff --git a/common/main.c b/common/main.c
index 682ecf1e5c..79ad7bfac2 100644
--- a/common/main.c
+++ b/common/main.c
@@ -20,7 +20,6 @@
#include "task.h"
#include "timer.h"
#include "uart.h"
-#include "vboot.h"
#include "watchdog.h"
int main(void)
@@ -115,25 +114,6 @@ int main(void)
keyboard_scan_init();
#endif
-#ifdef CONFIG_VBOOT_SIG
- /*
- * Verified boot signature check. This may jump to another image, which
- * will need to reconfigure / reinitialize the system, so as little as
- * possible should be done above this step.
- *
- * Note that steps above here may be done TWICE per boot, once in the
- * RO image and once in the RW image.
- */
- vboot_check_signature();
-
- /*
- * If system is locked, disable system jumps now that vboot has had its
- * chance to jump to a RW image.
- */
- if (system_is_locked())
- system_disable_jump();
-#endif
-
/*
* Initialize other driver modules. These can occur in any order.
* Non-driver modules with tasks do their inits from their task
diff --git a/common/vboot.c b/common/vboot.c
deleted file mode 100644
index 3d3518a942..0000000000
--- a/common/vboot.c
+++ /dev/null
@@ -1,46 +0,0 @@
-/* Copyright (c) 2012 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.
- */
-
-/* Verified boot module for Chrome EC */
-
-#include "common.h"
-#include "console.h"
-#include "host_command.h"
-#include "system.h"
-#include "vboot.h"
-
-/* Console output macros */
-#define CPUTS(outstr) cputs(CC_VBOOT, outstr)
-#define CPRINTF(format, args...) cprintf(CC_VBOOT, format, ## args)
-
-/****************************************************************************/
-/* Host commands */
-
-static int host_cmd_vboot(struct host_cmd_handler_args *args)
-{
- const struct ec_params_vboot_cmd *p = args->params;
- struct ec_params_vboot_cmd *r = args->response;
- uint8_t v;
-
- switch (p->in.cmd) {
- case VBOOT_CMD_GET_FLAGS:
- v = VBOOT_FLAGS_IMAGE_MASK & system_get_image_copy();
- r->out.get_flags.val = v;
- args->response_size = sizeof(r);
- break;
- case VBOOT_CMD_SET_FLAGS:
- v = p->in.set_flags.val;
- break;
- default:
- CPRINTF("[%T LB bad cmd 0x%x]\n", p->in.cmd);
- return EC_RES_INVALID_PARAM;
- }
-
- return EC_RES_SUCCESS;
-}
-
-DECLARE_HOST_COMMAND(EC_CMD_VBOOT_CMD,
- host_cmd_vboot,
- EC_VER_MASK(0));
diff --git a/common/vboot_sig.c b/common/vboot_sig.c
deleted file mode 100644
index ae2ddb199e..0000000000
--- a/common/vboot_sig.c
+++ /dev/null
@@ -1,163 +0,0 @@
-/* Copyright (c) 2012 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.
- */
-
-/* Verified boot module for Chrome EC */
-
-#include "board.h"
-#include "config.h"
-#include "console.h"
-#include "cryptolib.h"
-#include "gpio.h"
-#include "system.h"
-#include "timer.h"
-#include "util.h"
-#include "vboot.h"
-#include "vboot_api.h"
-#include "vboot_common.h"
-#include "vboot_struct.h"
-#include "watchdog.h"
-
-/* Console output macros */
-#define CPUTS(outstr) cputs(CC_VBOOT, outstr)
-#define CPRINTF(format, args...) cprintf(CC_VBOOT, format, ## args)
-
-enum howgood {
- IMAGE_IS_BAD,
- IMAGE_IS_GOOD,
- IMAGE_IS_GOOD_BUT_USE_RO_ANYWAY,
-};
-
-static enum howgood good_image(uint8_t *key_data,
- uint8_t *vblock_data, uint32_t vblock_size,
- uint8_t *fv_data, uint32_t fv_size) {
- VbPublicKey *sign_key;
- VbKeyBlockHeader *key_block;
- VbECPreambleHeader *preamble;
- uint32_t now = 0;
- RSAPublicKey *rsa;
-
- key_block = (VbKeyBlockHeader *)vblock_data;
- sign_key = (VbPublicKey *)key_data;
-
- watchdog_reload();
- if (0 != KeyBlockVerify(key_block, vblock_size, sign_key, 0)) {
- CPRINTF("[Error verifying key block]\n");
- return IMAGE_IS_BAD;
- }
-
- now += key_block->key_block_size;
- rsa = PublicKeyToRSA(&key_block->data_key);
- if (!rsa) {
- CPRINTF("[Error parsing data key]\n");
- return IMAGE_IS_BAD;
- }
-
- watchdog_reload();
- preamble = (VbECPreambleHeader *)(vblock_data + now);
- if (0 != VerifyECPreamble(preamble, vblock_size - now, rsa)) {
- CPRINTF("[Error verifying preamble]\n");
- RSAPublicKeyFree(rsa);
- return IMAGE_IS_BAD;
- }
-
- if (preamble->flags & VB_FIRMWARE_PREAMBLE_USE_RO_NORMAL) {
- CPRINTF("[Flags says USE_RO_NORMAL]\n");
- RSAPublicKeyFree(rsa);
- return IMAGE_IS_GOOD_BUT_USE_RO_ANYWAY;
- }
-
- watchdog_reload();
- if (0 != EqualData(fv_data, fv_size, &preamble->body_digest, rsa)) {
- CPRINTF("Error verifying firmware body]\n");
- RSAPublicKeyFree(rsa);
- return IMAGE_IS_BAD;
- }
-
- RSAPublicKeyFree(rsa);
-
- watchdog_reload();
- CPRINTF("[Verified!]\n");
- return IMAGE_IS_GOOD;
-}
-
-/* Might I want to jump to one of the RW images? */
-static int maybe_jump_to_other_image(void)
-{
- /* We'll only jump to another image if we're currently in RO */
- if (system_get_image_copy() != SYSTEM_IMAGE_RO)
- return 0;
-
-#ifdef CONFIG_TASK_KEYSCAN
- /* Don't jump if recovery requested */
- if (keyboard_scan_recovery_pressed()) {
- CPUTS("[Vboot staying in RO because recovery key pressed]\n");
- return 0;
- }
-#endif
-
- /*
- * Don't jump if we're in RO becuase we jumped there (this keeps us
- * from jumping to RO only to jump right back).
- */
- if (system_jumped_to_this_image())
- return 0;
-
-#if !defined(CHIP_stm32)
- /*
- * TODO: (crosbug.com/p/8572) Daisy and Snow don't define a GPIO for
- * the recovery signal from servo, so we can't check it. BDS uses the
- * DOWN button.
- */
- if (gpio_get_level(GPIO_RECOVERYn) == 0) {
- CPUTS("[Vboot staying in RO due to recovery signal]\n");
- return 0;
- }
-#endif
-
- /* Okay, we might want to jump to a RW image. */
- return 1;
-}
-
-int vboot_check_signature(void)
-{
- enum howgood r;
- timestamp_t ts1, ts2;
-
- CPRINTF("[%T Vboot init]\n");
-
- if (!maybe_jump_to_other_image())
- return EC_SUCCESS;
-
- CPRINTF("[%T Vboot check RW image...]\n");
-
- ts1 = get_time();
- r = good_image((uint8_t *)CONFIG_VBOOT_ROOTKEY_OFF,
- (uint8_t *)CONFIG_VBLOCK_RW_OFF, CONFIG_VBLOCK_SIZE,
- (uint8_t *)CONFIG_FW_RW_OFF, CONFIG_FW_RW_SIZE);
- ts2 = get_time();
-
- CPRINTF("[%T Vboot result=%d, elapsed time=%ld us]\n",
- r, ts2.val - ts1.val);
-
- switch (r) {
- case IMAGE_IS_GOOD:
- CPRINTF("[RW image verified]\n");
- system_run_image_copy(SYSTEM_IMAGE_RW);
- CPRINTF("[ERROR: Unable to jump to RW image]\n");
- goto bad;
- case IMAGE_IS_GOOD_BUT_USE_RO_ANYWAY:
- CPRINTF("[RW image verified]\n");
- CPRINTF("[Staying in RO mode]\n");
- return EC_SUCCESS;
- default:
- CPRINTF("[RW image is invalid]\n");
- }
-
-bad:
- CPRINTF("[Staying in RO mode]\n");
- CPRINTF("[FIXME: How to trigger recovery mode?]\n");
- return EC_ERROR_UNKNOWN;
-}
-
diff --git a/common/vboot_stub.c b/common/vboot_stub.c
index a04d050c63..be25031171 100644
--- a/common/vboot_stub.c
+++ b/common/vboot_stub.c
@@ -6,24 +6,9 @@
/* Functions needed by vboot library */
#define _STUB_IMPLEMENTATION_
-#include "console.h"
-#include "shared_mem.h"
#include "util.h"
#include "utility.h"
-/* Console output macros */
-#define CPUTS(outstr) cputs(CC_VBOOT, outstr)
-#define CPRINTF(format, args...) cprintf(CC_VBOOT, format, ## args)
-
-#if 0 /* change this to debug memory usage */
-#define DPRINTF CPRINTF
-#else
-#define DPRINTF(...)
-#endif
-
-
-/****************************************************************************/
-
void *Memcpy(void *dest, const void *src, uint64_t n)
{
return memcpy(dest, src, (size_t)n);
@@ -33,137 +18,3 @@ void *Memset(void *d, const uint8_t c, uint64_t n)
{
return memset(d, c, n);
}
-
-int Memcmp(const void *src1, const void *src2, size_t n)
-{
- size_t i;
- const uint8_t *a = src1;
- const uint8_t *b = src2;
- for (i = 0; i < n; i++) {
- if (*a != *b)
- return (*a < *b) ? -1 : 1;
- a++;
- b++;
- }
-
- return 0;
-}
-
-/****************************************************************************/
-/* The vboot_api library requires some dynamic memory, but we don't have
- * malloc/free. Instead we have one chunk of shared RAM that we can gain
- * exclusive access to for a time. We'll have to experiment with various
- * algorithms to see what works best. This algorithm allocates and
- * reuses blocks, but never actually frees anything until all memory has been
- * reclaimed. */
-
-/* Since we only need this stuff to boot, don't waste run-time .bss */
-static struct {
- int bucket_size; /* total RAM available */
- uint8_t *out_base; /* malloc from here */
- int out_count; /* number of active mallocs */
- int out_size; /* high-water mark */
-
- /* We have a limited number of active mallocs. We never free, but we
- * do reuse slots. */
-#define MAX_SLOTS 8
- struct {
- int in_use; /* is this slot active? */
- void *ptr; /* starts here */
- size_t size; /* how big */
- } slots[MAX_SLOTS];
-} *bucket;
-
-
-void *VbExMalloc(size_t size)
-{
- int i, j;
- void *ptr = 0;
-
- if (!bucket) {
- i = shared_mem_size();
- if (EC_SUCCESS != shared_mem_acquire(i, 1, (char **)&bucket)) {
- CPRINTF("FAILED at %s:%d\n", __FILE__, __LINE__);
- ASSERT(0);
- }
- Memset(bucket, 0, sizeof(*bucket));
- bucket->bucket_size = i;
- bucket->out_base = (uint8_t *)(bucket + 1);
- bucket->out_size = sizeof(*bucket);
- DPRINTF("grab the bucket: at 0x%x, size 0x%x\n",
- bucket, bucket->bucket_size);
- }
-
- if (size % 8) {
- size_t tmp = (size + 8) & ~0x7ULL;
- DPRINTF(" %d -> %d\n", size, tmp);
- ASSERT(tmp >= size);
- size = tmp;
- }
-
- for (i = 0; i < MAX_SLOTS; i++) {
- if (!bucket->slots[i].in_use) {
-
- /* Found an empty one, but reuse the same size if one
- * already exists. */
- for (j = i; j < MAX_SLOTS; j++) {
- if (!bucket->slots[j].in_use &&
- size == bucket->slots[j].size) {
- /* empty AND same size */
- bucket->slots[j].in_use = 1;
- ptr = bucket->slots[j].ptr;
- DPRINTF(" = %d (%d)\n", j, size);
- goto out;
- }
- }
-
- /* no exact matches, must allocate a new chunk */
- ptr = bucket->out_base + bucket->out_size;
- bucket->out_size += size;
-
- bucket->slots[i].in_use = 1;
- bucket->slots[i].ptr = ptr;
- bucket->slots[i].size = size;
- DPRINTF(" + %d (%d)\n", i, size);
- goto out;
- }
- }
-
- CPRINTF("FAILED: no empty slots (%d/%d)\n", i, MAX_SLOTS);
- ASSERT(0);
-
-out:
- bucket->out_count++;
- if (bucket->out_size >= bucket->bucket_size) {
- CPRINTF("FAILED: out of memory (%d/%d)\n",
- bucket->out_size, bucket->bucket_size);
- ASSERT(0);
- }
-
- return ptr;
-}
-
-
-void VbExFree(void *ptr)
-{
- int i;
-
- for (i = 0; i < MAX_SLOTS; i++) {
- if (ptr == bucket->slots[i].ptr) {
- bucket->slots[i].in_use = 0;
- DPRINTF(" - %d (%d)\n", i, bucket->slots[i].size);
- break;
- }
- }
- if (MAX_SLOTS == i) {
- CPRINTF("FAILED: can't find ptr %x!\n", ptr);
- ASSERT(0);
- }
-
- bucket->out_count--;
- if (!bucket->out_count) {
- DPRINTF("dump the bucket: max used = %d\n", bucket->out_size);
- shared_mem_release(bucket);
- bucket = 0;
- }
-}