summaryrefslogtreecommitdiff
path: root/common/rollback.c
Commit message (Collapse)AuthorAgeFilesLines
* rollback: rollback region must be unlocked in order to erase itTom Hughes2020-05-291-1/+2
| | | | | | | | | | | | | | | | | | | | | | | | | | | BRANCH=none BUG=b:151105339, b:155229277 TEST=Compile and flash "rollback" test on dragonclaw with region 0 On console: "runtest" => Reboots with "Data access violation, mfar = 8020000" => PASS TEST=Compile and flash "rollback" test on dragonclaw with region 1 On console: "runtest" => Reboots with "Data access violation, mfar = 8040000" => PASS TEST=Compile and flash "rollback" test on dragontalon with region 0 On console: "runtest" => Reboots with "Data access violation, mfar = 80c0000" => PASS TEST=Compile and flash "rollback" test on dragontalon with region 1 On console: "runtest" => Reboots with "Data access violation, mfar = 80e0000" => PASS Signed-off-by: Tom Hughes <tomhughes@chromium.org> Change-Id: I1cf42fec99fa08932c2accc4604e829aaefe076f Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/2207998 Tested-by: Yicheng Li <yichengli@chromium.org> Reviewed-by: Jett Rink <jettrink@chromium.org>
* rollback: create private header file for use by unit testsTom Hughes2020-05-141-15/+2
| | | | | | | | | | | | | | | Expose definitions that we want to use in unit tests, but are internal details that should not be used by other EC code using the rollback functionality. BRANCH=none BUG=none TEST=b:151105339 Signed-off-by: Tom Hughes <tomhughes@chromium.org> Change-Id: Ib81251cce63e0a8b929b6e7a8e1fc1ec4a664f5f Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/2197619 Reviewed-by: Nicolas Boichat <drinkcat@chromium.org>
* rollback: const correctnessTom Hughes2020-05-141-3/+3
| | | | | | | | | | | | | Entropy being added is never modified. BRANCH=none BUG=none TEST=make buildall -j Signed-off-by: Tom Hughes <tomhughes@chromium.org> Change-Id: I2b54334812c9a86fad059576725e6212e88c2ec9 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/2197334 Reviewed-by: Nicolas Boichat <drinkcat@chromium.org>
* common/system: Unify ec_current_image and system_image_copy_tTom Hughes2020-02-281-2/+2
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | "enum ec_current_image" is exposed in ec_commands.h (and used by non-EC code, such as biod). We also have an "enum system_image_copy_t" that is the exact same thing (though has a few more definitions). A followup CL (I714b6bd8c0d7192386404c25a831e38438fa5238) adds the "sysinfo" host command, so we want to be able to expose all the potential image variants. Rather than maintain two enums that can potentially get out of sync, unify the code to use a single enum. We choose to keep the "enum ec_current_image", since external code depends on it. To verify that this change results in no changes to the generated binaries: ./util/compare_build.sh --board all BRANCH=none BUG=b:146447208 TEST=./util/compare_build.sh --board=all Change-Id: I13776bc3fd6e6ad635980476a35571c52b1767ac Signed-off-by: Tom Hughes <tomhughes@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/2036599 Reviewed-by: Daisuke Nojiri <dnojiri@chromium.org> Reviewed-by: Namyoon Woo <namyoon@chromium.org>
* rollback: Conditionally include cryptocCraig Hesling2019-12-111-0/+2
| | | | | | | | | | | | | | | | | | This include is not needed and not available when CONFIG_ROLLBACK_SECRET_SIZE is not defined. BRANCH=none BUG=none TEST=make buildall -j TEST=# undefine CONFIG_ROLLBACK_SECRET_SIZE in nocturne_fp board.h make BOARD=nocturne_fp # This will not compile without this fix # With this fix, no compilation errors are output Change-Id: I651f4e254189f34228f1aa2f2a2ff21808ab5d5c Signed-off-by: Craig Hesling <hesling@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/1952291 Reviewed-by: Jett Rink <jettrink@chromium.org>
* rollback: Remove unused rollback_lock functionTom Hughes2019-11-111-26/+0
| | | | | | | | | | | | | | Use of the rollback_lock function was removed in https://crrev.com/c/479176. BRANCH=none BUG=none TEST=make buildall -j Change-Id: I15bfeba9b169c7b0fae8d3c9423bc2f4817d52d8 Signed-off-by: Tom Hughes <tomhughes@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/1902460 Reviewed-by: Nicolas Boichat <drinkcat@chromium.org>
* util: Add function to check whether a buffer is trivial (all 0x00 or all 0xff)Yicheng Li2019-10-041-10/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This function's execution time depends only on the buffer length but not on the specific bytes in the buffer. BRANCH=nocturne BUG=chromium:927095 TEST=make -j buildall TEST=timed the execution of bytes_are_trivial() on a long array with the following contents: Array 1: 0x01, 0x00, 0x00, 0x00, ..., 0x00, 0x00 (first byte nontrivial) Array 2: 0x00, 0x00, 0x00, 0x00, ..., 0x00, 0x02 (last byte nontrivial) Array 3: 0x00, 0x00, ... , 0x00, 0x03, 0x00, ..., (middle byte nontrivial) Array 4: 0x00, 0x00 , ... (trivial) (These 4 arrays have the same length.) Verified that execution on these arrays take similar amount of time, proportional to the length of the array, specifically: For 256k bytes, takes 21~40 microseconds For 128k bytes, takes 10~17 microseconds For 64k bytes, takes 5~9 microseconds For 32k bytes, takes 2~5 microseconds Because the host timer inaccuracy and potential process scheduling variations, the execution time for arrays 1-4 are sometimes not exactly the same. To avoid test flakiness, this timing test is not written to unit tests. But it should prove that bytes_are_trivial() is a constant time algorithm. Change-Id: I131748e1a4ee3a3e19a105dba5dc443bb2371d30 Signed-off-by: Yicheng Li <yichengli@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/1787870
* host_command: Change host command return value to enum ec_statusTom Hughes2019-10-021-2/+4
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | If the host command handler callback function returns an int, it's easy to accidentally mix up the enum ec_error_list and enum ec_status types. The host commands always expect an enum ec_status type, so we change the return value to be of that explicit type. Compilation will then fail if you accidentally try to return an enum ec_error_list value. Ran the following commands and then manually fixed up a few remaining instances that were not caught: git grep --name-only 'static int .*(struct host_cmd_handler_args \*args)' |\ xargs sed -i 's#static int \(.*\)(struct host_cmd_handler_args \*args)#\ static enum ec_status \1(struct host_cmd_handler_args \*args)##' git grep --name-only 'int .*(struct host_cmd_handler_args \*args)' |\ xargs sed -i 's#int \(.*\)(struct host_cmd_handler_args \*args)#\ enum ec_status \1(struct host_cmd_handler_args \*args)##' BRANCH=none BUG=chromium:1004831 TEST=make buildall -j Cq-Depend: chrome-internal:1872675 Change-Id: Id93df9387ac53d016a1594dba86c6642babbfd1e Signed-off-by: Tom Hughes <tomhughes@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/1816865 Reviewed-by: Daisuke Nojiri <dnojiri@chromium.org> Reviewed-by: Jack Rosenthal <jrosenth@chromium.org>
* rollback: Remove unnecessary shadow variableCraig Hesling2019-09-171-2/+0
| | | | | | | | | | | | | | | | | | | | | | | | | BRANCH=none BUG=none TEST=make buildall -j TEST=make BOARD=nocturne_fp ssh dut1 mount -oremount,rw / scp build/nocturne_fp/ec.bin dut1:~/ # CCD Cr50 Console wp disable # Back to host ssh dut1 flash_fp_mcu '~/ec.bin' ssh dut1 touch /opt/google/biod/fw/.disable_fp_updater ssh dut1 rm -rf '/var/log/*' ssh dut1 reboot # FPMCU UART Console > version > rollback Change-Id: If88fda706198184abfc47188eec31f7817c986da Signed-off-by: Craig Hesling <hesling@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/1808066 Reviewed-by: Daisuke Nojiri <dnojiri@chromium.org> Reviewed-by: Aseda Aboagye <aaboagye@chromium.org>
* rollback: Clear temporary copies of rollback secret.Yicheng Li2019-09-051-35/+87
| | | | | | | | | | | | | | | | | After working with temporary copies of rollback secret, clear them using always_memset() in third_party/cryptoc/util.c. For boards that have CONFIG_ROLLBACK_SECRET_SIZE, configure CONFIG_LIBCRYPTOC automatically. BRANCH=nocturne BUG=chromium:968809,chromium:989594,b:130238794 TEST=make -j buildall TEST=tested fingerprint enrollment and matching on nocturne DUT, which uses rollback_get_secret(). Change-Id: I44fb5ef7d43c080e4d33c8d9a7d9298e194e1cf3 Signed-off-by: Yicheng Li <yichengli@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/1731544 Reviewed-by: Tom Hughes <tomhughes@chromium.org>
* rollback: Add rollback support for chips with varying flash bank sizesTom Hughes2019-07-031-10/+38
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | BRANCH=none BUG=b:124996507 TEST=In hatch_fp and nocturne_fp console with CONFIG_RWSIG_JUMP_TIMEOUT increased to large value and console_task stack size increased to 4096: > rollbackinfo rollback minimum version: 0 RW rollback version: 0 rollback 0: 00000000 00000000 0b112233 [00..00] * rollback 1: ffffffff ffffffff ffffffff [ff..ff] > rollbackupdate 1 > rollbackinfo rollback minimum version: 1 RW rollback version: 0 rollback 0: 00000000 00000000 0b112233 [00..00] rollback 1: 00000001 00000001 0b112233 [00..00] * > rollbackaddent 1234 > rollbackinfo rollback minimum version: 1 RW rollback version: 0 rollback 0: 00000002 00000001 0b112233 [e5..8c] * rollback 1: 00000001 00000001 0b112233 [00..00] TEST=test_that --board=nocturne <IP> firmware_Fingerprint.ObeysRollback firmware_Fingerprint.ObeysRollback [ PASSED ] firmware_Fingerprint.ObeysRollback/firmware_Fingerprint [ PASSED ] Change-Id: I90b524138ca1125e2c1b62936b9f6fbe00e957d4 Signed-off-by: Tom Hughes <tomhughes@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/1681379 Reviewed-by: Nicolas Boichat <drinkcat@chromium.org>
* fpsensor: Add unit test for derive_encryption_key().Yicheng Li2019-06-141-1/+1
| | | | | | | | | | | | | | | | | Mock rollback_get_secret() and use it to test derive_encryption_key(). BRANCH=nocturne BUG=chromium:927095 TEST=make -j buildall TEST=tested enrollment, matching and multifinger on nocturne DUT TEST=verified test key vectors by running boringSSL's HKDF (https://boringssl.googlesource.com/boringssl/+/c0b4c72b6d4c6f4828a373ec454bd646390017d4/crypto/hkdf/) locally Change-Id: Ie2f51e4f64788d938e43d0c5c18685d1cfdd001c Signed-off-by: Yicheng Li <yichengli@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/1652495 Reviewed-by: Nicolas Norvez <norvez@chromium.org>
* rollback: Unlock rollback before writing to itNicolas Boichat2018-09-211-4/+5
| | | | | | | | | | | | | | | | | | | | Unprotect the MPU before we write to the rollback block, else the EC crashes. BRANCH=nocturne BUG=b:116216642 TEST=ectool --name=cros_fp reboot_ec; sleep 0.5; \ ectool --name=cros_fp rwsigaction abort && \ ectool --name=cros_fp addentropy reset && \ ectool --name=cros_fp reboot_ec TEST=Flash EC RW with rollback version 1, no crash, rollback version is incremented Change-Id: I2f7a057d4a94be97c52a8acaa4b9d864cabf280c Signed-off-by: Nicolas Boichat <drinkcat@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/1236917 Commit-Ready: Nicolas Norvez <norvez@chromium.org> Reviewed-by: Randall Spangler <rspangler@chromium.org>
* rollback: Add host command to query rollback informationNicolas Boichat2018-09-201-0/+23
| | | | | | | | | | | | | | | | | | | | | | | Rollback id will be useful to check that the secret has actually been wiped. Min rollback version and RW rollback version might be useful in the future. BRANCH=nocturne BUG=b:115733483 TEST=ectool --name=cros_fp rollbackinfo => Rollback block id: X ectool --name=cros_fp reboot_ec; sleep 0.5; \ ectool --name=cros_fp rwsigaction abort && \ ectool --name=cros_fp addentropy reset && \ ectool --name=cros_fp reboot_ec ectool --name=cros_fp rollbackinfo => Rollback block id: X+2 Change-Id: I039d26d302d3a12b0d41acca34aa28d4a2dd096d Signed-off-by: Nicolas Boichat <drinkcat@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/1226126 Reviewed-by: Randall Spangler <rspangler@chromium.org> Reviewed-by: Nicolas Norvez <norvez@chromium.org>
* rollback: Prevent rollback region readback using MPUNicolas Boichat2018-08-151-2/+29
| | | | | | | | | | | | | | | | | | | | We want to prevent easy readout of the rollback region, so we protect it using the MPU. There is a short duration of time where the region is unprotected (when we actually need to read the information back), but we shorten it by disabling interrupts. BRANCH=none BUG=b:111330723 TEST=flashread 0xe0000, rw 0x80e0020, md 0x80e0020, ectool flashread 0xc0000 0x1000 x => All cause EC to crash and reboot TEST=rollbackinfo still works Change-Id: I85ee757b3e261de392af03bd958b36d140a1080a Signed-off-by: Nicolas Boichat <drinkcat@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/1143106 Reviewed-by: Randall Spangler <rspangler@chromium.org> Reviewed-by: Nicolas Norvez <norvez@chromium.org>
* rollback: Add host command to add entropyNicolas Boichat2018-07-311-1/+62
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | To generate a new secret, we add entropy (generated from local HW TRNG) to the existing secret (sha256(old secret || entropy)). This essentially re-keys the EC. On STM32H7, erasing rollback flash block can take up to 4 seconds, which exceeds the timeout of a normal host command. Therefore, ADD_ENTROPY command is asynchronous (adding the entropy itself is performed in a deferred hook), and its status must be checked repeatedly by the host. In some cases, it is critical that the old key is not left in the backup rollback block(s). For this purpose, we add a special action ADD_ENTROPY_RESET_ASYNC that adds entropy multiple times, until all the rollback blocks have been overwritten. BRANCH=none BUG=b:111190988 TEST=EC> rollbackinfo DUT> ./ectool --name=cros_fp reboot_ec RO && \ sleep 0.3 && ./ectool --name=cros_fp addentropy EC> rollbackinfo => See that that a single rollback block has been overridden TEST=Repeat with ./ectool --name=cros_fp addentropy reset => See that both rollback blocks have been overridden Change-Id: I3058b0a91591fab543ba6890f7356e671016edfa Signed-off-by: Nicolas Boichat <drinkcat@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/1132826 Reviewed-by: Nicolas Norvez <norvez@chromium.org>
* rollback: Ensure rollback_update writes blocks of correct sizeNicolas Boichat2018-07-101-11/+22
| | | | | | | | | | | | | | | flash_write (rightfully) fails if the size of not a multiple of CONFIG_FLASH_WRITE_SIZE. BRANCH=none BUG=b:111190988 TEST=rollbackupdate works on both whiskers and nocturne_fp Change-Id: I8e0b1f59b06d33f4171b6e09af94a5b7a60acc61 Signed-off-by: Nicolas Boichat <drinkcat@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/1127803 Reviewed-by: Randall Spangler <rspangler@chromium.org> Reviewed-by: Louis Collard <louiscollard@chromium.org>
* rollback: Fix compile warning when local entropy is disabled.Nicolas Boichat2018-07-101-0/+2
| | | | | | | | | | | BRANCH=none BUG=b:111190988 TEST=make buildall -j Change-Id: I9cea8ce0270ca8a3f4fd33663d78d7d7c5b93643 Signed-off-by: Nicolas Boichat <drinkcat@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/1128784 Reviewed-by: Randall Spangler <rspangler@chromium.org>
* rollback: Add function to fetch secretNicolas Boichat2017-06-141-0/+26
| | | | | | | | | | | | | | BRANCH=none BUG=b:38486828 TEST=Flash hammer Change-Id: I50088a78e75d6ea8d62e439fdc8bf18d46319462 Reviewed-on: https://chromium-review.googlesource.com/532474 Commit-Ready: Nicolas Boichat <drinkcat@chromium.org> Tested-by: Nicolas Boichat <drinkcat@chromium.org> Reviewed-by: Mattias Nissler <mnissler@chromium.org> Reviewed-by: Randall Spangler <rspangler@chromium.org> Reviewed-by: Vincent Palatin <vpalatin@chromium.org>
* rollback: Include board-generated entropy when adding entropyNicolas Boichat2017-06-061-4/+16
| | | | | | | | | | | | | | | | | Mix in board-generated entropy with the externally provided one, which should help make the per-device secret stronger. BRANCH=none BUG=b:38486828 TEST=reboot; rollbackaddent Hello => works fine when USB is connected, fails otherwise, as board-generated entropy relies on USB timing. Change-Id: I314f44759c5f8b859913a748db95e9d42b5cdd11 Reviewed-on: https://chromium-review.googlesource.com/518609 Commit-Ready: Nicolas Boichat <drinkcat@chromium.org> Tested-by: Nicolas Boichat <drinkcat@chromium.org> Reviewed-by: Mattias Nissler <mnissler@chromium.org> Reviewed-by: Vincent Palatin <vpalatin@chromium.org>
* rollback: Add option to store secret in rollback infoNicolas Boichat2017-05-251-31/+134
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | For pairing purpose, we want to store some secret random number in the base. The most convenient location for this is the rollback region. Since the rollback region can now be updated without incrementing rollback_min_version (when we add entropy to the secret), we need to add an increasing id to tell the code which rollback region is the latest. We also add console commands to manually add entropy. BRANCH=none BUG=b:38486828 TEST=Flash hammer (with or without CONFIG_ROLLBACK_ENTROPY_SIZE set) rollbackinfo => 1 version 0 block, 1 empty block, RW verifies correctly. rollbackupdate 0; rollbackinfo => No change rollbackupdate 1; reboot => RO refuses to jump to RW only when CONFIG_ROLLBACK_ENTROPY_SIZE is set: rollbackinfo => Secret is [00..00] on both blocks (so the data was copied correctly) rollbackupdate 2, 3, 4; rollbackinfo => Writes alternate between the 2 blocks. rollbackupdate 2 => Refuses to downgrade version TEST=From blank secret [00..00], 'rollbackaddent Hello' updates it to [ba..fa], which matches the output of: (dd if=/dev/zero bs=1 count=32; echo -n Hello) | sha256sum Change-Id: I79c3e790e56e21958cc1b4ba05bd4e5f359d3090 Reviewed-on: https://chromium-review.googlesource.com/511985 Commit-Ready: Nicolas Boichat <drinkcat@chromium.org> Tested-by: Nicolas Boichat <drinkcat@chromium.org> Reviewed-by: Vincent Palatin <vpalatin@chromium.org>
* rollback: Add CONFIG_ROLLBACK_UPDATE config optionNicolas Boichat2017-05-231-19/+21
| | | | | | | | | | | | | | | | Typically, we do not need RW section to be able to update rollback information (rollback block should be protected when RW is running), so we can save some flash space by undefining this option. BRANCH=none BUG=b:35586219 TEST=make newsizes saves ~420 bytes on hammer and staff. Change-Id: Ic457673e56ace083f2ebb1ca0f37f54bf125bfa4 Reviewed-on: https://chromium-review.googlesource.com/511983 Commit-Ready: Nicolas Boichat <drinkcat@chromium.org> Tested-by: Nicolas Boichat <drinkcat@chromium.org> Reviewed-by: Vincent Palatin <vpalatin@chromium.org>
* rollback: Print RW rollback version as wellNicolas Boichat2017-05-011-0/+4
| | | | | | | | | | | | | | | This is useful for debugging, to understand if the RW rollback version is ahead of current rollback version. BRANCH=none BUG=b:35586219 TEST=Flash hammer, rollbackinfo in EC console Change-Id: I2634199845f1b35447e0938a35b862f79cb24ffa Reviewed-on: https://chromium-review.googlesource.com/489886 Commit-Ready: Nicolas Boichat <drinkcat@chromium.org> Tested-by: Nicolas Boichat <drinkcat@chromium.org> Reviewed-by: Randall Spangler <rspangler@chromium.org>
* rollback: Update and lock rollback block as part of rwsig verificationNicolas Boichat2017-04-111-6/+40
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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>
* common/rollback: Add support for rollback protectionNicolas Boichat2017-04-061-0/+179
Implement actual rollback protection. First, we add a new field in the version structure, which is an incrementing integer (we'll start by shipping images with version 0, and gradually increase the number as required). This allows us to release new versions of the EC without necessarily bumping the rollback protection. For the rollback protection block itself, it contains 2 sub-blocks of equal size (normally, 2k), that are individually erasable. The rollback code looks at both, and takes the most restrictive one to determine the desired rollback minimum version. The blocks are also allowed to be erased (full of 1's), in which case the rollback minimum version is assumed to be 0. We also add an FMAP entry, in case we later decide to allow the signer to increment the rollback version. Also note that, like any version_data struct change, this change breaks compatibility between old and new RO/RW. Follow-up code will take care of auto-updating the rollback block as required, and properly manage block protection. BRANCH=none BUG=b:35586219 TEST=Flash hammer rollbackinfo => 1 version 0 block, 1 empty block, RW verifies correctly. rollbackupdate 0; rollbackinfo => No change rollbackupdate 1; reboot => RO refuses to jump to RW rollbackupdate 2, 3, 4; rollbackinfo => Writes alternate between the 2 blocks. rollbackupdate 2 => Refuses to downgrade version Change-Id: Ia969afb481a93deb912b9153bdd95ace01ad8fa7 Reviewed-on: https://chromium-review.googlesource.com/452815 Commit-Ready: Nicolas Boichat <drinkcat@chromium.org> Tested-by: Nicolas Boichat <drinkcat@chromium.org> Reviewed-by: Randall Spangler <rspangler@chromium.org> Reviewed-by: Vincent Palatin <vpalatin@chromium.org>