diff options
author | Nicolas Boichat <drinkcat@google.com> | 2017-03-30 17:40:18 +0800 |
---|---|---|
committer | chrome-bot <chrome-bot@chromium.org> | 2017-04-11 20:22:31 -0700 |
commit | 3f0714c1e29dab5817dfe1aa8733c7235ea85ee4 (patch) | |
tree | 21342a7fce6ee2c7686117211ca05ecfe9a3d2e4 /common/rwsig.c | |
parent | bcc4e087a13727755482b13b44f1ab7bfd361beb (diff) | |
download | chrome-ec-3f0714c1e29dab5817dfe1aa8733c7235ea85ee4.tar.gz |
rollback: Update and lock rollback block as part of rwsig verification
This is done at RO stage. If the rollback region is unprotected, update
it to match the version in the RW image.
If the rollback region is protected, we can't do that update, so we wait
for RW to unlock that region (presumably after AP has verified that image
is somewhat functional) before updating it.
BRANCH=none
BUG=b:35586219
TEST=flashwp true; reboot => hammer reboots twice
flashinfo shows RO+rollback protected:
Flags: wp_gpio_asserted ro_at_boot ro_now rollback_at_boot rollback_now
Protected now:
YYYYYYYY YYYYYYYY Y....... ........
TEST=Hack version.c to add "+1" to rollback_version, check that RO updates
ROLLBACK info block on first boot.
TEST=Use hack above, convert rwsig to separate task, add 5000 ms delay in
rwsig just before rollback information is updated. Then:
Quickly type: flashwp true; reboot; flashwp all; reboot
=> Wait for system to jump to RW
rollbackinfo => minimum version 0
flashwp norb; reboot; wait for jump to RW
rollbackinfo => minimum version 1
Change-Id: I78e502315c611c5edaf34b8d70a12fedd3e57bdf
Reviewed-on: https://chromium-review.googlesource.com/452816
Commit-Ready: Nicolas Boichat <drinkcat@chromium.org>
Tested-by: Nicolas Boichat <drinkcat@chromium.org>
Reviewed-by: Vincent Palatin <vpalatin@chromium.org>
Diffstat (limited to 'common/rwsig.c')
-rw-r--r-- | common/rwsig.c | 34 |
1 files changed, 32 insertions, 2 deletions
diff --git a/common/rwsig.c b/common/rwsig.c index f7d9429270..d2218ba77e 100644 --- a/common/rwsig.c +++ b/common/rwsig.c @@ -152,13 +152,43 @@ void check_rw_signature(void) hash = SHA256_final(&ctx); good = rsa_verify(key, sig, hash, rsa_workbuf); + if (!good) + goto out; + +#ifdef CONFIG_ROLLBACK + /* + * Signature verified: we know that rw_rollback_version is valid, check + * if rollback information should be updated. + */ + if (rw_rollback_version != min_rollback_version) { + /* + * This will fail if the rollback block is protected (RW image + * will unprotect that block later on). + */ + int ret = rollback_update(rw_rollback_version); + + if (ret == 0) { + CPRINTS("Rollback updated to %d", + rw_rollback_version); + } else if (ret != EC_ERROR_ACCESS_DENIED) { + CPRINTS("Rollback update error %d", ret); + good = 0; + } + } + + /* + * Lock the ROLLBACK region, this will cause the board to reboot if the + * region is not already protected. + */ + rollback_lock(); +#endif out: + CPRINTS("RW verify %s", good ? "OK" : "FAILED"); + 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()) |