xref: /aosp_15_r20/external/gsc-utils/docs/write_protection.md (revision 4f2df630800bdcf1d4f0decf95d8a1cb87344f5f)
1# Firmware Write Protection
2
3[TOC]
4
5This is a somewhat tricky topic since write protection implementations can
6differ between chips and the hardware write protection has changed over time,
7so please edit or open a bug if something is not clear.
8
9## Terminology
10
11## RO and RW
12
13MCUs running the EC code have read-only (RO) and read-write (RW) firmware.
14Coming out of reset, the MCU boots into its RO firmware.
15
16In the case of the EC, the RO firmware boots the host and asks it verify a hash
17of the RW firmware (software sync). If the RW firmware is invalid, it is
18updated from a copy in the host's RW firmware.
19
20In the case of the FPMCU, the RO firmware uses the public key embedded in it to
21validate the signature of the RW firmware. If the RW firmware is invalid it
22does not jump to the RW firmware.
23
24Once the RW firmware is validated, the MCU jumps to it (without rebooting). The
25RO firmware is locked in the factory and is never changed. The RW firmware can
26be updated later by pushing a new system firmware containing an updated RW
27region.
28
29Note that both the RO and RW firmware regions are normally protected once write
30protect has been turned on.
31
32In the case of the EC, the RW region is unprotected at MCU boot until it has
33been verified by the host. The RW region is protected before the Linux kernel
34is loaded.
35
36In the case of the FPMCU, the RW region is protected before jumping the RO
37firmware jumps to it.
38
39## Hardware Write Protect {#hw_wp}
40
41On modern Chrome OS devices, the Cr50 (aka GSC / TPM) provides a "hardware
42write protect" GPIO that is connected to the AP SPI flash, EC SPI flash,
43EEPROM, and FPMCU via a [GPIO][write_protect_gpio].  This "hardware write
44protect" can only be disabled with servo or suzyq (["CCD open"]) and
45corresponds to [`OverrideWP`] in ccd. Disabling this write protect disables it
46for everything connected to this signal.
47
48In the case of the FPMCU, the hardware write protect GPIO is tied to the STM32
49`BOOT0` pin, which is what tells the MCU to enter the STM32 bootloader mode.
50
51You may see various references to a [write protect screw in
52documentation][wp_screw]. Older Chrome OS devices had a write protect screw
53that had to be physically removed. More details on this history can be found
54here: http://go/cros-wp-status.
55
56Another way of disabling hardware write protection is to remove the battery;
57this method is mainly used during bringup.
58
59Additional reference:
60https://www.google.com/chromeos/partner/fe/docs/cpfe/firmwaretestmanual.html#hardware-write-protect
61
62## Changing Hardware Write Protection
63
64Modifying the state of hardware write protection (via Cr50 GPIO) can be done
65if the ["CCD open"] process has been completed.
66
67*** note
68`servod` *must* be running for `dut-control` to work. See the [Servo] page for
69details.
70***
71
72### Enable Hardware Write Protection
73
74```bash
75(chroot)$ dut-control fw_wp_state:force_on
76```
77
78### Disable Hardware Write Protection
79
80```bash
81(chroot)$ dut-control fw_wp_state:force_off
82```
83
84### Enable/Disable Hardware Write Protection via Cr50 Console
85
86You can use the following commands from the [Cr50 console]:
87
88```bash
89wp disable
90```
91
92```bash
93wp enable
94```
95
96```bash
97wp follow_batt_pres
98```
99
100## Software Write Protect
101
102Software-based write protect state stored in non-volatile memory. If hardware
103write protect is enabled, software write protect can be enabled but can’t be
104disabled. If hardware write protect is disabled, software write protect can be
105enabled or disabled (note that some implementations require an EC reset to
106disable software write protect).
107
108The underlying mechanism implementing software write protect may differ between
109EC chips. However the common requirements are that software write protect can
110only be disabled when hardware write protect is off and that the RO firmware
111must be protected before jumping to RW firmware if protection is enabled.
112
113*** note
114*WARNING*: If you disable HW write protect *and* then reboot the FPMCU, it will do
115a mass erase of the chip, due to [RDP1](#rdp1).
116***
117
118Additional reference:
119https://www.google.com/chromeos/partner/fe/docs/cpfe/firmwaretestmanual.html#software-write-protect
120
121## Changing Software Write Protection
122
123*** note
124*NOTE*: You cannot disable software write protect if hardware write protect is
125enabled.
126***
127
128Software write protection can be toggled with `ectool --name=cros_fp flashprotect
129enable/disable`, which sends the `EC_CMD_FLASH_PROTECT` command toggling
130`EC_FLASH_PROTECT_RO_AT_BOOT` (changing `--name` to target different ECs).
131
132### Changing Software Write Protection with `ectool`
133
134#### `ectool flashprotect`
135
136Print out current flash protection state.
137
138```
139Flash protect flags: 0x0000000f wp_gpio_asserted ro_at_boot ro_now all_now
140Valid flags:         0x0000003f wp_gpio_asserted ro_at_boot ro_now all_now STUCK INCONSISTENT
141Writable flags:      0x00000000
142```
143
144`Flash protect flags` - Current flags that are set.
145
146`Valid flags` - All the options for flash protection.
147
148`Writable flags` - The flags that currently can be changed. (In this case, no
149flags can be changed).
150
151Flags:
152
153*   `wp_gpio_asserted` - Whether the hardware write protect GPIO is currently
154    asserted (read only).
155
156*   `ro_at_boot` - Whether the EC will write protect the RO firmware on the next
157    boot of the EC.
158
159*   `ro_now` - Protect the read-only portion of flash immediately. Requires
160    hardware WP be enabled.
161
162*   `all_now` - Protect the entire flash (including RW) immediately. Requires
163    hardware WP be enabled.
164
165*   `STUCK` - Flash protection settings have been fused and can’t be cleared
166    (should not happen during normal operation. Read only.)
167
168*   `INCONSISTENT` - One or more banks of flash is not protected when it should
169    be (should not happen during normal operation. Read only.).
170
171#### `ectool flashprotect enable`
172
173Set `ro_at_boot` flag. The next time the EC is reset it will protect the flash.
174Note that this requires a cold reset.
175
176#### `ectool flashprotect enable now`
177
178Set `ro_at_boot` `ro_now all_now` flags and immediately protect the flash. Note
179that this will fail if hardware write protect is disabled.
180
181#### `ectool flashprotect disable`
182
183Clear `ro_at_boot` flag. This can only be cleared if the EC booted without
184hardware write protect enabled.
185
186Note that you must reset the EC to clear write protect after removing the screw.
187If the `ro_at_boot` flag set and the EC resets with the HW gpio disabled, the EC
188will leave the flash unprotected (`ro_now` and `all_now` flags are not set) but
189leave `ro_at_boot` flag set.
190
191## `system_is_locked()`
192
193The [`system_is_locked()`] function in the EC code returns false if the HW
194write protect GPIO is disabled or the read-only firmware is not protected.
195
196One way this is used in the FPMCU source is to compile test or debug
197functionality into the firmware. Guarding the test functionality with
198`system_is_locked` allows us to execute the test code in automated testing by
199disabling the hardware write protection; this means we can run the automated
200tests against the exact same firmware we ship, rather than a different version
201that has test functionality compiled in or out.
202
203## RDP1 {#rdp1}
204
205Stands for Readout Protection Level 1.
206
207Protects user flash memory against a debugger (JTAG/SWD) or potential malicious
208code stored in RAM by disabling access (a bus error is generated when read
209access is requested). Otherwise (no debugger connected and no boot in RAM set),
210all read/program/erase operations from/to flash are allowed.
211
212When switching to a lower level of RDP (i.e., setting to 0), the user flash
213memory is mass erased (set to all `0xFF`).
214
215Note that this completely destroys *all* of the firmware, including the RO
216section.
217
218### Additional References
219
220https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/1222094
221
222## EC Flash Read/Write Command Write Protection Checks
223
224The EC code command handlers (`command_flash_erase`, `command_flash_write`,
225etc.) return an error if `EC_FLASH_PROTECT_ALL_NOW` is set.
226
227[write_protect_gpio]: https://chromium.googlesource.com/chromiumos/platform/ec/+/aaba1d5efd51082d143ce2ac64e6caf9cb14d5e5/include/ec_commands.h#1599
228["CCD open"]: ./case_closed_debugging_gsc.md#Open-CCD
229[Cr50 console]: ./case_closed_debugging_gsc.md#Consoles
230[`OverrideWP`]: ./case_closed_debugging_gsc.md
231[wp_screw]: https://www.chromium.org/chromium-os/firmware-porting-guide/firmware-ec-write-protection
232[`system_is_locked()`]: https://chromium.googlesource.com/chromiumos/platform/ec/+/aaba1d5efd51082d143ce2ac64e6caf9cb14d5e5/common/system.c#195
233[Servo]: https://www.chromium.org/chromium-os/servo
234