/* 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 "ec_commands.h" #include "rsa.h" #include "sha256.h" #include "shared_mem.h" #include "system.h" #include "usb_pd.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) /* RW firmware reset vector */ static uint32_t * const rw_rst = (uint32_t *)(CONFIG_PROGRAM_MEMORY_BASE + CONFIG_RW_MEM_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; CPRINTS("Verifying RW image..."); /* 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 */ /* TODO(crosbug.com/p/44803): Do we have to hash the whole region? */ SHA256_init(&ctx); SHA256_update(&ctx, (void *)CONFIG_PROGRAM_MEMORY_BASE + CONFIG_RW_MEM_OFF, CONFIG_RW_SIZE - CONFIG_RW_SIG_SIZE); hash = SHA256_final(&ctx); good = rsa_verify((const struct rsa_public_key *)CONFIG_RO_PUBKEY_ADDR, (const uint8_t *)CONFIG_RW_SIG_ADDR, hash, rsa_workbuf); if (good) { CPRINTS("RW image verified"); /* Jump to the RW firmware */ system_run_image_copy(SYSTEM_IMAGE_RW); } else { CPRINTS("RSA verify FAILED"); pd_log_event(PD_EVENT_ACC_RW_FAIL, 0, 0, NULL); /* RW firmware is invalid : do not jump there */ if (system_is_locked()) system_disable_jump(); } shared_mem_release(rsa_workbuf); }