diff options
author | Vincent Palatin <vpalatin@chromium.org> | 2014-11-13 08:28:50 -0800 |
---|---|---|
committer | chrome-internal-fetch <chrome-internal-fetch@google.com> | 2014-12-01 20:30:46 +0000 |
commit | 902a07b5c8efa59e03e57b3c45f17fc1d17e3125 (patch) | |
tree | 74d3759bcc147a49ecefbc51e566860ecc1f4ac6 /common/rwsig.c | |
parent | b41a0632db0abd010331b507cba4b472dd8e2fd8 (diff) | |
download | chrome-ec-902a07b5c8efa59e03e57b3c45f17fc1d17e3125.tar.gz |
Add RW firmware signature verification for common runtime
For accessories without software-sync mechanism, add the option to do a
RSA-based signature verification of the Read-Write firmware.
Signed-off-by: Vincent Palatin <vpalatin@chromium.org>
BRANCH=samus
BUG=chrome-os-partner:31192
TEST=enable the configuration on Fruitpie and see the RW firmware
validated and jump to. Tried with good and bad RW images.
Change-Id: I3c886c2cbe17ca9543e19bf8599061c3f9751d4f
Reviewed-on: https://chromium-review.googlesource.com/229594
Reviewed-by: Todd Broch <tbroch@chromium.org>
Commit-Queue: Todd Broch <tbroch@chromium.org>
Tested-by: Todd Broch <tbroch@chromium.org>
Diffstat (limited to 'common/rwsig.c')
-rw-r--r-- | common/rwsig.c | 72 |
1 files changed, 72 insertions, 0 deletions
diff --git a/common/rwsig.c b/common/rwsig.c new file mode 100644 index 0000000000..92b8d1838c --- /dev/null +++ b/common/rwsig.c @@ -0,0 +1,72 @@ +/* Copyright (c) 2014 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. + */ + +/* + * Implementation of the RW firmware signature verification and jump. + */ + +#include "console.h" +#include "rsa.h" +#include "sha256.h" +#include "shared_mem.h" +#include "system.h" +#include "util.h" + +/* Console output macros */ +#define CPRINTF(format, args...) cprintf(CC_SYSTEM, format, ## args) +#define CPRINTS(format, args...) cprints(CC_SYSTEM, format, ## args) + +/* Insert the RSA public key definition */ +const struct rsa_public_key pkey __attribute__((section(".rsa_pubkey"))) = +#include "gen_pub_key.h" + +/* The RSA signature is stored at the end of the RW firmware */ +static const void *rw_sig = (void *)CONFIG_FLASH_BASE + CONFIG_FW_RW_OFF + + CONFIG_FW_RW_SIZE - RSANUMBYTES; + +/* RW firmware reset vector */ +static uint32_t * const rw_rst = + (uint32_t *)(CONFIG_FLASH_BASE+CONFIG_FW_RW_OFF+4); + +void check_rw_signature(void) +{ + struct sha256_ctx ctx; + int good, res; + uint8_t *hash; + uint32_t *rsa_workbuf; + + /* Only the Read-Only firmware needs to do the signature check */ + if (system_get_image_copy() != SYSTEM_IMAGE_RO) + return; + + /* Check if we have a RW firmware flashed */ + if (*rw_rst == 0xffffffff) + return; + + /* Large buffer for RSA computation : could be re-use afterwards... */ + res = shared_mem_acquire(3 * RSANUMBYTES, (char **)&rsa_workbuf); + if (res) { + CPRINTS("No memory for RW verification"); + return; + } + + /* SHA-256 Hash of the RW firmware */ + SHA256_init(&ctx); + SHA256_update(&ctx, (void *)CONFIG_FLASH_BASE + CONFIG_FW_RW_OFF, + CONFIG_FW_RW_SIZE - RSANUMBYTES); + hash = SHA256_final(&ctx); + good = rsa_verify(&pkey, (void *)rw_sig, (void *)hash, rsa_workbuf); + if (good) { + CPRINTS("RW image verified\n"); + /* Jump to the RW firmware */ + system_run_image_copy(SYSTEM_IMAGE_RW); + } else { + CPRINTS("RSA verify FAILED\n"); + /* RW firmware is invalid : do not jump there */ + if (system_is_locked()) + system_disable_jump(); + } + shared_mem_release(rsa_workbuf); +} |