summaryrefslogtreecommitdiff
path: root/docs/detachable_base_verified_boot.md
diff options
context:
space:
mode:
authorJack Rosenthal <jrosenth@chromium.org>2021-11-04 12:11:58 -0600
committerCommit Bot <commit-bot@chromium.org>2021-11-05 04:22:34 +0000
commit252457d4b21f46889eebad61d4c0a65331919cec (patch)
tree01856c4d31d710b20e85a74c8d7b5836e35c3b98 /docs/detachable_base_verified_boot.md
parent08f5a1e6fc2c9467230444ac9b582dcf4d9f0068 (diff)
downloadchrome-ec-stabilize-voshyr-14637.B-ish.tar.gz
In the interest of making long-term branch maintenance incur as little technical debt on us as possible, we should not maintain any files on the branch we are not actually using. This has the added effect of making it extremely clear when merging CLs from the main branch when changes have the possibility to affect us. The follow-on CL adds a convenience script to actually pull updates from the main branch and generate a CL for the update. BUG=b:204206272 BRANCH=ish TEST=make BOARD=arcada_ish && make BOARD=drallion_ish Signed-off-by: Jack Rosenthal <jrosenth@chromium.org> Change-Id: I17e4694c38219b5a0823e0a3e55a28d1348f4b18 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/3262038 Reviewed-by: Jett Rink <jettrink@chromium.org> Reviewed-by: Tom Hughes <tomhughes@chromium.org>
Diffstat (limited to 'docs/detachable_base_verified_boot.md')
-rw-r--r--docs/detachable_base_verified_boot.md432
1 files changed, 0 insertions, 432 deletions
diff --git a/docs/detachable_base_verified_boot.md b/docs/detachable_base_verified_boot.md
deleted file mode 100644
index c1eec3fc0b..0000000000
--- a/docs/detachable_base_verified_boot.md
+++ /dev/null
@@ -1,432 +0,0 @@
-# Detachable Base Verified Boot
-
-Authors: rspangler@google.com, drinkcat@google.com
-
-Last Updated: 2016-11-16
-
-Original: http://go/detachable-base-vboot
-
-[TOC]
-
-## Introduction
-
-### What's a Base?
-
-Detachable Chromebooks such as `Poppy` have a tablet-like `Lid` and a detachable
-keyboard `Base`. Effectively, the `Base` is a USB keyboard+trackpad which plugs
-into the `Lid`.
-
-The `Lid` contains most of the components, including:
-
-* AP
-* ECDisplay
-* Storage
-* Battery
-
-The `Base` connects to the `Lid` via USB pogo pins, and contains:
-
-* EC ([STM32F072]). To minimize confusion with the main EC in the `Lid`, this
- will always be called the `BaseEC`.
-* Matrixed keyboard
-* Touchpad
-
-The `Base` always gets its power from the `Lid` USB port. This means that
-attaching the base always triggers a power-on reset.
-
-### Verified Boot Requirements
-
-The `BaseEC` will be responsible for handling user input from the keyboard and
-touchpad. This means that a compromised `BaseEC` could implement a keylogger. To
-prevent this, we will use verified boot to protect the `BaseEC` firmware.
-
-We need a way to securely update the `BaseEC` firmware from the AP. We cannot
-use EC Software Sync as implemented on existing Chromebooks (and as still used
-in the `Lid`) because the `Base` cannot trust that it is talking to an official
-`Lid` firmware/OS. All the Base knows is that _something_ on the other end of
-USB is trying to send it an update. So the BaseEC will need to do its own public
-key verification of the firmware update. This includes rollback protection.
-
-Updating the `BaseEC` firmware should not require rebooting the lid. This means
-the update will take place after the OS has already booted on the lid. Ideally,
-it should also not require the user to detach/reattach the base during the
-update process. If the update takes longer than a few seconds, we should tell
-the user, because the keyboard and trackpad will be unavailable during the
-update.
-
-The solution should also have low (or no) BOM cost, and minimal flash size
-requirement.
-
-## Proposal
-
-`BaseEC` RO region includes a public key, whose private counterpart is kept
-safely on our signers. On boot, RO checks RW signature (RW image is signed by
-our signers), and will only jump to RW if the signature is valid.
-
-We also include a rollback region (RB) to implement rollback protection (and
-prevent rollback to a correctly signed, but compromised, RW). This region can
-only be updated by RO.
-
-We also devise a scheme to update RW firmware (the details are documented in
-[EC Update over USB]).
-
-Note: This proposal is very specific to the STM32 flash architecture. Other ECs
-(particularly ones with external SPI flash) may need additional external logic
-and/or a I2C EEPROM to hold the rollback info block.
-
-### Flash
-
-STM32F072 has 128KB flash, with 2KB erase sectors and 4KB protection blocks.
-
-We will divide flash into three sections:
-
-* `BaseEC`-RO firmware.
- * Not updatable in production.
- * Only capable of USB update, not keyboard/trackpad.
- * Contains public key to verify RW image (RSA-3072).
-* `BaseEC`-RW firmware.
- * Fully functional.
- * Updatable from AP.
- * Signature (SHA-256 + RSA-3072).
-* `BaseEC`-RB: Rollback info block (4KB).
- * Contains minimum RW version that RO will accept to jump to.
- * Updatable from RO.
-
-Each of those sections can be locked independently: In production, RO is always
-locked, and only RO can write to RB (RO will always make sure to lock RB before
-jumping to RW).
-
-Flash protection is a little entertaining on STM32:
-
-* The flash protection bits for the \*next\* boot are stored in a non-volatile
- `WRPx` register (in EC code, this is abstracted as
- `EC_FLASH_PROTECT_[REGION]_AT_BOOT` flags)..
-* On chip reset, `WRPx` is copied into a read-only `FLASH_WRPR` register; that
- controls which blocks are protected for this boot. This is abstracted as
- `EC_FLASH_PROTECT_[REGION]_NOW` in the EC code.
-
-### Rollback Info Block
-
-The Rollback Info Block (aka "RB") is a 4KB block of flash.
-
-It has two 2KB erase sectors. We will ping-pong writes to those sectors, so that
-interrupting power during an erase-write cannot cause data loss. If both sectors
-are valid, the stricter (i.e. the highest value) of the 2 sectors is used.
-
-We will use the RB to hold the following:
-
-* Minimum **RW rollback firmware** version: a 32-bit integer. Used for
- rollback protection. This number is independent of the actual EC version,
- and is stored a 32-bit integer as part of the `BaseEC`-RW region (see
- [CL:452815] for a possible implementation)
-* A magic signature that indicates that the RB section is valid.
-
-### RO Verified Boot Flow
-
-#### Write-Protect RO think test before this handles corrupt RW.
-
-Write protect of RO firmware works the same way it does now:
-
-* Early RO code looks at a write protect (WP) GPIO and a global PSTATE
- variable (part of the RO image itself). When we switch to RO that contains
- the MP key, we set the PSTATE to locked.
-* If both of those are set:
- * RO code sets `EC_FLASH_PROTECT_RO_AT_BOOT` to protect itself. This
- ensures RO code is never writable past this point.
- * If `_AT_BOOT` flags protects more than the current write protect range
- (`_NOW` flags), RO reboots so that changes take effect.
-* Otherwise, someone has physically disconnected WP. Set `WRPx=0` to unprotect
- all flash and reboot.
-
-#### Check if AP Wants To Update RW
-
-Next, RO needs to find out if the AP wants to update RW. RO initializes USB and
-starts a 1 second timer to give the AP an opportunity to send a command before
-RO jumps to RW. This delay gives us a way to regain control of the base, if the
-previous RW firmware is properly signed but bad/nonfunctional.
-
-That command can be:
-
-* `STOP_IN_RO`: Yes, I might want to update you. Stick around.
- * `UNLOCK_RW`: Tells EC to unlock RW region, if it is currently locked, so
- that it can be reprogrammed. This also locks RB region. EC reboots if
- needed.
-* `JUMP_TO_RW`: No, I don't want to update you. Go ahead and jump to your RW
- code if it verifies.
-
-RO will start verifying RW while it waits for the AP to send it a command or for
-the timeout. If a command is received, RO will stop the 1-second timer, and wait
-for more commands from the AP. This allows the AP to update RW.
-
-Verifying RW will take ~200 ms, and the AP should be able to send a command to
-the base within ~100 ms of it appearing on USB, so this check should not cause
-any delay to the base's boot process.
-
-#### Verify RW
-
-RO calculates the hash of RW.
-
-* Use the public key stored in RO to check if the hash matches the RSA-signed
- RW signature. On failure, go back to waiting for an update from the AP.
-* Check the RW rollback version against the stored minimum version in RB. If
- the RW version is too low, fail. Go back to waiting for an update from the
- AP.
-* If RO is protected, then also set `EC_FLASH_PROTECT_RW_AT_BOOT` so that RW
- will be protected on the next boot, the reboot.
-
-#### Roll Forward
-
-If `EC_FLASH_PROTECT_ROLLBACK_NOW` is set (RB is protected), do not attempt to
-roll forward. We know RW firmware is properly signed, but not if it's
-functional.
-
-If `EC_FLASH_PROTECT_ROLLBACK_NOW` is not set (RB is unprotected), \_and\_ the
-RW signature is correct, then update RB:
-
-* Erase/write the older sector of RB.
-* Set the stored minimum version to the RW rollback version.
-* If RO is protected, then also set `EC_FLASH_PROTECT_ROLLBACK_NOW` so that RB
- will be protected on the next boot.
-
-#### Jump to RW
-
-If the 1-second timer for the AP to send a command to RO has not expired, RO
-waits for it to expire or the AP to send a command, whichever happens first.
-
-If RB or RW is unprotected (`EC_FLASH_PROTECT_RW/ROLLBACK_NOW` are not set),
-protect it and reboot (we never want RW to be able to update RB on its own).
-
-Otherwise, jump to RW firmware.
-
-### RW Verified Boot Flow
-
-RW firmware provides the keyboard and trackpad functionality.
-
-#### AP Wants To Update RW
-
-At some point the AP may want to update RW. To do so, it sends `UNLOCK_RW`
-command, to ask RW to unlock itself and reboot, then follow the update steps
-above.
-
-#### AP Wants to Roll Forward RW
-
-After the update, the base boots to the new RW firmware. At that point, the AP
-knows the new RW firmware is good enough to talk to, so it tells RW to prepare
-for roll forward.
-
-* `UNLOCK_ROLLBACK` command: RW unprotects RB.
-* On next boot (not necessarily urgent, but can be forced), RO will update RB
- according to the steps above.
-
-### Write Protect GPIO
-
-The `BaseEC` needs a write protect (WP) GPIO signal to decide whether to keep RO
-firmware protected or not. This is the same requirement as on existing ECs.
-
-In an assembled base, the WP signal will be physically asserted. De-asserting
-the signal requires disassembling the base and disconnecting something.
-
-Typically, the `BaseEC` will apply a weak pull-up to the WP GPIO; the presence
-of the WP screw/flex will short the pin to ground.
-
-#### RO Updates During Development
-
-If RO is unprotected (i.e. during development), RW can also update it.
-
-If the key is \_not\_ the same (dev->premp, premp->mp updates) we can't update
-RW first (it won't verify). These steps should work though, if current RW is
-recent enough and stable enough to update RO:
-
-* Make sure RW is active
-* Update RO, reboot
-* Update RW from RO
-
-If the key is the same, we can update RW first.
-
-### Signer, image format, and verification process
-
-Memory map:
-
-RO | RB | RW
-------------------------------------------------- | --- | ---
-`...` \| `Public key` \| `...` \| `FMAP` \| `...` | | `EC code and data` \| `Blank (0xff)` \| `Signature`
-
-* RO contains an embedded RSA public key (`vb21_packed_key` format), at a
- variable location.
-* RW contains a signature (`vb21_signature`), packed at the end of the RW
- region.
- * The signature also contains the actual length of the EC code and image
- (ignoring 0xff padding)
- * RO validates signature against the provided length, then checks that the
- rest of the RW region (up to the signature itself) is filled with ones
- (padding).
- * This speeds up verification significantly, as SHA-256 is an
- expensive process.
-* RO contains an FMAP that allows futility to find the RO key, RW region, and
- RW signature location.
-
-For re-signing, `futility` (rwsig type) does this:
-
-* Look for FMAP to find RO public key RW region, and RW signature locations.
-* Resign RW region, using the length provided in existing RW signature.
-* Replace RO public key with the one used for signing.
-
-`vb21_packed_key` (public key) has a field for key version, that we can use to
-increment from dev keys, to premp, and final mp keys. BaseEC will need to report
-the key version, to avoid incorrect updates.
-
-## Example Boot / Update Flows
-
-The base starts in the following state:
-
-* Powered off
-* WP GPIO is asserted
-* PSTATE is set to protect RO firmware
-* RW firmware is valid, and currently version M
-* `EC_FLASH_PROTECT_[REGION]_AT_BOOT/_NOW` protects RO+RW+RB (that is,
- everything)
-
-All AP operations are done from the `Lid` OS.
-
-Base updates will interrupt keyboard/trackpad functionality, so the user should
-be informed when an update is taking place.
-
-Reboots of the `Base` do not cause or require reboots of the `Lid`, do not
-require action on the part of the user, and will not be visible to the user
-(other than the previously noted lack of functionality).
-
-### Power On, No Update
-
-Step | RW | RB contents | `_AT_BOOT` | `_NOW`
---------------------------------------------------------------------------------------------- | --- | ----------- | ---------- | ------
-(initial state) | M | 1/blank | RO/RW/RB | RO/RW/RB
-1. RO waits 1 second for an update request from AP | | | |
-2. RO verifies RW signature => RW is good | | | |
-3. RO notes that `_AT_BOOT` and `_NOW` already protect everything, so no reboot is necessary. | | | |
-4. RO jumps to RW | | | |
-
-### Updating RW
-
-Assume AP now has a new `BaseEC`-RW, version N>M. The base is already running RW
-version M. In this card, the rollback version in both version is identical
-("1"), so RB does not require an update.
-
-Step | RW | RB contents | `_AT_BOOT` | `_NOW`
-------------------------------------------------------- | --- | ----------- | -------------- | ------
-RW is running | M | 1/blank | RO/RW/RB | RO/RW/RB
-AP tells RW to prepare for an update (UNLOCK_RW) | | | |
-RW unsets `EC_FLASH_PROTECT_RW_AT_BOOT` to unprotect RW | | | **RO/\_\_/RB** |
-RW reboots to update `EC_FLASH_PROTECT_RW_NOW` | | | | **RO/\_\_/RB**
-
-The next base boot is where the update takes place:
-
-Step | RW | RB contents | `_AT_BOOT` | `_NOW`
----------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----- | ----------- | ------------ | ------
-RO waits 2 seconds for an update request from the AP | M | 1/blank | RO/\_\_/RB | RO/\_\_/RB
-AP tells RO an update is coming (`STOP_IN_RO`) | | | |
-AP tells the user that a base update is taking place. UI should say: "Please don't be surprised that your keyboard and trackpad won't work for a few seconds..." | | | |
-AP writes RW version N | **N** | | |
-AP tells RO to reboot (`IMMEDIATE_RESET`) | | | |
-RO reboots, verifies RW signature => RW is good | | | |
-RO checks RW rollback version N (1) and sees it's greater or equal than RB rollback version 1. So, RW is good. | | | |
-RO sets `RW_AT_BOOT` to protect RW on the next boot. | | | **RO/RW/RB** |
-RO reboots | | | | **RO/RW/RB**
-
-The next base boot is where we first run the new RW firmware.
-
-### Roll forward
-
-Now let's assume we followed the steps above, and we now have a RW version O
-that has rollback version 2.
-
-Step | RW | RB contents | `_AT_BOOT` | `_NOW`
--------------------------------------------------------------------------------------------------------------- | ----- | ----------- | -------------- | ------
-RO verifies RW signature => RW is good | **O** | 1/blank | RO/RW/RB | RO/RW/RB
-RO checks RW rollback version O (2) and sees it's greater or equal than RB rollback version 1. So, RW is good. | | | |
-RO jumps to RW | | | |
-AP is satisfied that the base works, so it tells RW to prepare for a | | | |
-roll-forward (`UNLOCK_ROLLBACK`) | | | |
-RW unsets `ROLLBACK_AT_BOOT` | | | **RO/RW/\_\_** |
-RW may reboot (or just wait for next reattach) | | | | **RO/RW/\_\_**
-
-On next boot, RB will be updated:
-
-Step | RW | RB contents | `_AT_BOOT` | `_NOW`
------------------------------------------------------------------------------------------------------------------------------------------ | --- | ----------- | ------------ | ------
-RO verifies RW signature => RW is good | O | 1/blank | RO/RW/\_\_ | RO/RW/\_\_
-RO sees that RB is unprotected, and sees RW rollback version O (2) and sees is greater than RB rollback version 1. So RB needs an update. | | | |
-RO updates RB's second block | O | **1/2** | |
-RO sets `ROLLBACK_AT_BOOT` to protect RB on the next boot. | | | **RO/RW/RB** |
-RO reboots. | | | | **RO/RW/RB**
-
-## Details
-
-### STM32 Flash Protection
-
-At a high level, flash protection works on the STM32F072 chip works in the
-following manner:
-
-* 128KB flash total flash, organized as 32 independently protectable 4KB
- blocks. Each block has 2 independently erasable 2KB sectors.
-* `FLASH_WRPR` is the register controlling flash write protect of these
- blocks. It is not directly writable. In EC common code, these bits are
- abstracted as `EC_FLASH_PROTECT_[REGION]_NOW`.
-* Instead, there is a non-volatile register called `WRPx`, which is stored in
- a separate information block of flash. This is always writable. In EC common
- code, these bits are abstracted as `EC_FLASH_PROTECT_[REGION]_AT_BOOT`. On
- chip reset, `WRPx` is copied to the `FLASH_WRPR` register.
-
-Here's the interesting part. The only way to change read-only firmware is to
-change `WRPx` and then reset the chip, so that `WRPx` is copied into
-`FLASH_WRPR`. At that point, read-only firmware could be writable. But that same
-reset also transfers control back to the read-only firmware. If the read-only
-firmware doesn't want to be writable, all it has to do is change `WRPx` back to
-protect itself, and then reboot again. We do that already on all devices which
-use the STM32 chips.
-
-Flash protection works similarly on other STM32F chips, if we need to move to a
-larger or more capable EC for the base to support a more complex base.
-
-### Flash Contents
-
-The 128KB `BaseEC` flash will be divided into three parts.
-
-* Read-only firmware (`Base`-EC-RO, or just "RO" in this document)
- * ~40KB
- * Minimal functionality, so it can be small.
- * Verifies the rewritable firmware.
- * Updates the rewritable firmware over USB.
- * Does NOT have keyboard or trackpad support.
- * Includes the `Base-EC` root key.
-* Rewritable firmware (`Base-EC`-RW, or just "RW" in this document)
- * ~84KB
- * Supports keyboard and trackpad.
- * Trackpad drivers may be non-trivial in size.
- * Future bases may include type-C ports, sensors, or batteries, all of
- which will increase RW size.
- * As with the main EC, it is unlikely we will have space for multiple
- copies of RW (so, no RW-A and RW-B).
- * Updates the read-only firmware over USB (pre-production devices only).
-* Rollback block (`Base-EC`-RB, or just "RB" in this document)
- * 4KB (one protection block)
- * Contains rollback version information for RW
- * Only writable by RO.
- * Updates alternate between the 2 2KB erase sectors. We only erase one of
- them at a time, so an interrupted erase/write will not cause data loss.
-
-Adding the RB will decrease the total amount of flash available for RO and RW,
-but doesn't require any additional external components. This is acceptable
-because RO will be smaller (since it only has update/verify functionality).
-
-### Verification Speed
-
-On a STM32F072 chip running at 48 MHz,
-
-* SHA-256 of a 64KB RW image takes 200 ms (~3 ms/KB)
- * Reducing RW image size reduces verification time almost proportionally
- (even if we need to check that the rest of the image is erased).
-* RSA-2048 (exponent 3) signature verification takes ~50 ms
-* RSA-3072 (exponent 3) signature verification takes ~100 ms
-
-[STM32F072]: http://www.st.com/content/ccc/resource/technical/document/reference_manual/c2/f8/8a/f2/18/e6/43/96/DM00031936.pdf/files/DM00031936.pdf
-[EC Update over USB]: ./usb_updater.md
-[CL:452815]: https://chromium-review.googlesource.com/c/452815/2