summaryrefslogtreecommitdiff
path: root/common/rwsig.c
diff options
context:
space:
mode:
authorVincent Palatin <vpalatin@chromium.org>2014-11-13 08:28:50 -0800
committerchrome-internal-fetch <chrome-internal-fetch@google.com>2014-12-01 20:30:46 +0000
commit902a07b5c8efa59e03e57b3c45f17fc1d17e3125 (patch)
tree74d3759bcc147a49ecefbc51e566860ecc1f4ac6 /common/rwsig.c
parentb41a0632db0abd010331b507cba4b472dd8e2fd8 (diff)
downloadchrome-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.c72
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);
+}