blob: 30102e5a7255c05e2939129ac22c2b98a77257d8 [file] [log] [blame] [view]
Almir Okato39eb63d2022-01-05 18:31:54 -03001# [Building and using MCUboot with Espressif's chips](#building-and-using-mcuboot-with-espressifs-chips)
Almir Okato428e2e72021-08-11 10:52:10 -03002
Almir Okato879348b2023-05-09 22:31:36 -03003The MCUBoot Espressif's port depends on HAL (Hardware Abstraction Layer) sources based on ESP-IDF or 3rd party frameworks as such as Zephyr-RTOS (`zephyrproject-rtos/hal_espressif/`) or NuttX RTOS (`espressif/esp-hal-3rdparty`). Building the MCUboot Espressif's port and its features is platform dependent, therefore, the system environment including toolchains, must be set accordingly. A standalone build version means that ESP-IDF and its toolchain are used as source. For 3rd parties framework, HAL path and toolchain must be set.
Almir Okato428e2e72021-08-11 10:52:10 -03004
5Documentation about the MCUboot bootloader design, operation and features can be found in the [design document](design.md).
6
Almir Okato39eb63d2022-01-05 18:31:54 -03007## [SoC support availability](#soc-support-availability)
Almir Okato428e2e72021-08-11 10:52:10 -03008
9The current port is available for use in the following SoCs within the OSes:
Almir Okato428e2e72021-08-11 10:52:10 -030010
Almir Okatoc1efa002023-08-09 14:47:30 -030011| | ESP32 | ESP32-S2 | ESP32-C3 | ESP32-S3 | ESP32-C2 | ESP32-C6 | ESP32-H2 |
12| :-----: | :-----: | :-----: | :-----: | :-----: | :-----: | :-----: | :-----: |
13| Zephyr | Supported | Supported | Supported | Supported | In progress | In progress | In progress |
14| NuttX | Supported | Supported | Supported | Supported | In progress | In progress | In progress |
Almir Okato879348b2023-05-09 22:31:36 -030015
16Notice that any customization in the memory layout from the OS application must be done aware of the bootloader own memory layout to avoid overlapping.
Almir Okato39eb63d2022-01-05 18:31:54 -030017
18## [Installing requirements and dependencies](#installing-requirements-and-dependencies)
Almir Okato428e2e72021-08-11 10:52:10 -030019
Almir Okato879348b2023-05-09 22:31:36 -030020The following instructions considers a MCUboot Espressif port standalone build.
21
Almir Okato428e2e72021-08-11 10:52:10 -0300221. Install additional packages required for development with MCUboot:
Almir Okato87240812022-12-21 00:05:07 -030023```bash
Almir Okato879348b2023-05-09 22:31:36 -030024cd ~/mcuboot # or to your directory where MCUboot is cloned
Almir Okato87240812022-12-21 00:05:07 -030025```
26```bash
Almir Okato879348b2023-05-09 22:31:36 -030027pip3 install --user -r scripts/requirements.txt
Almir Okato428e2e72021-08-11 10:52:10 -030028```
29
Almir Okato879348b2023-05-09 22:31:36 -0300302. Update the Mbed TLS submodule required by MCUboot:
Almir Okato87240812022-12-21 00:05:07 -030031```bash
Almir Okato428e2e72021-08-11 10:52:10 -030032git submodule update --init --recursive ext/mbedtls
33```
34
Almir Okato879348b2023-05-09 22:31:36 -0300353. If ESP-IDF is the chosen option for use as HAL layer and the system already have ESP-IDF installed, ensure that the environment is set:
Almir Okato87240812022-12-21 00:05:07 -030036```bash
Almir Okato879348b2023-05-09 22:31:36 -030037<IDF_PATH>/install.sh
Almir Okato87240812022-12-21 00:05:07 -030038```
39```bash
Almir Okato879348b2023-05-09 22:31:36 -030040. <IDF_PATH>/export.sh
Almir Okato87240812022-12-21 00:05:07 -030041```
Almir Okato879348b2023-05-09 22:31:36 -030042
43---
44***Note***
45
46*If desirable, instructions for ESP-IDF installation can be found [here](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/get-started/index.html#manual-installation)*
47
48---
49
50---
51***Note***
52
53*The other HALs mentioned above like `hal_espressif` from Zephyr RTOS or `esp-hal-3rdparty` from NuttX RTOS environments also can be used for the bootloader standalone build, however as eventually code revision may differ from what is currently expected, it is recommended using them only within their RTOS build system.*
54
55---
56
574. If ESP-IDF is not installed and will not be used, install `esptool`:
Almir Okato87240812022-12-21 00:05:07 -030058```bash
Almir Okato879348b2023-05-09 22:31:36 -030059pip3 install esptool
Almir Okato428e2e72021-08-11 10:52:10 -030060```
61
Almir Okato39eb63d2022-01-05 18:31:54 -030062## [Building the bootloader itself](#building-the-bootloader-itself)
Almir Okato428e2e72021-08-11 10:52:10 -030063
Almir Okato879348b2023-05-09 22:31:36 -030064The MCUboot Espressif port bootloader is built using the toolchain and tools provided by Espressif. Additional configuration related to MCUboot features and slot partitioning may be made using the `port/<TARGET>/bootloader.conf` file or passing a custom config file using the `-DMCUBOOT_CONFIG_FILE` argument on the first step below.
Almir Okato428e2e72021-08-11 10:52:10 -030065
Francesco Servidio2fe449d2021-10-21 12:38:36 +020066---
67***Note***
68
Almir Okato39eb63d2022-01-05 18:31:54 -030069*Replace `<TARGET>` with the target ESP32 family (like `esp32`, `esp32s2` and others).*
Francesco Servidio2fe449d2021-10-21 12:38:36 +020070
71---
Almir Okato428e2e72021-08-11 10:52:10 -030072
Almir Okatofa173df2022-04-19 01:10:30 -0300731. Compile and generate the BIN:
Almir Okato87240812022-12-21 00:05:07 -030074```bash
Almir Okato879348b2023-05-09 22:31:36 -030075cmake -DCMAKE_TOOLCHAIN_FILE=tools/toolchain-<TARGET>.cmake -DMCUBOOT_TARGET=<TARGET> -DESP_HAL_PATH=<ESP_HAL_PATH> -DMCUBOOT_FLASH_PORT=<PORT> -B build -GNinja
Almir Okato87240812022-12-21 00:05:07 -030076```
77```bash
Almir Okatoe8cbc0d2022-06-13 10:45:39 -030078ninja -C build/
Almir Okato428e2e72021-08-11 10:52:10 -030079```
80
Almir Okato879348b2023-05-09 22:31:36 -030081---
82***Note***
83
84*If using ESP-IDF as HAL layer source, `ESP_HAL_PATH` can be ommited.*
85
86---
87
Almir Okatofa173df2022-04-19 01:10:30 -0300882. Flash MCUboot in your device:
Almir Okato87240812022-12-21 00:05:07 -030089```bash
Almir Okatofa173df2022-04-19 01:10:30 -030090ninja -C build/ flash
Almir Okato428e2e72021-08-11 10:52:10 -030091```
92
Almir Okatofa173df2022-04-19 01:10:30 -030093If `MCUBOOT_FLASH_PORT` arg was not passed to `cmake`, the default `PORT` for flashing will be `/dev/ttyUSB0`.
94
95Alternatively:
Almir Okato87240812022-12-21 00:05:07 -030096```bash
Almir Okatofa173df2022-04-19 01:10:30 -030097esptool.py -p <PORT> -b <BAUD> --before default_reset --after no_reset --chip <TARGET> write_flash --flash_mode dio --flash_size <FLASH_SIZE> --flash_freq 40m <BOOTLOADER_FLASH_OFFSET> build/mcuboot_<TARGET>.bin
Almir Okato428e2e72021-08-11 10:52:10 -030098```
Sylvio Alvesd5230942022-01-20 21:35:53 -030099---
Almir Okatob365e232022-03-08 01:35:54 -0300100***Note***
Almir Okatoa1d641d2022-02-21 19:31:46 -0300101
102You may adjust the port `<PORT>` (like `/dev/ttyUSB0`) and baud rate `<BAUD>` (like `2000000`) according to the connection with your board.
Sylvio Alvesd5230942022-01-20 21:35:53 -0300103You can also skip `<PORT>` and `<BAUD>` parameters so that esptool tries to automatically detect it.
Almir Okato428e2e72021-08-11 10:52:10 -0300104
Sylvio Alvesd5230942022-01-20 21:35:53 -0300105*`<FLASH_SIZE>` can be found using the command below:*
Almir Okato87240812022-12-21 00:05:07 -0300106```bash
Sylvio Alvesd5230942022-01-20 21:35:53 -0300107esptool.py -p <PORT> -b <BAUD> flash_id
108```
Almir Okatob365e232022-03-08 01:35:54 -0300109The output contains device information and its flash size:
Sylvio Alvesd5230942022-01-20 21:35:53 -0300110```
111Detected flash size: 4MB
112```
113
114
115*`<BOOTLOADER_FLASH_OFFSET>` value must follow one of the addresses below:*
Almir Okatob365e232022-03-08 01:35:54 -0300116
Almir Okatoc1efa002023-08-09 14:47:30 -0300117| ESP32 | ESP32-S2 | ESP32-C3 | ESP32-S3 | ESP32-C2 | ESP32-C6 | ESP32-H2 |
118| :-----: | :-----: | :-----: | :-----: | :-----: | :-----: | :-----: |
119| 0x1000 | 0x1000 | 0x0000 | 0x0000 | 0x0000 | 0x0000 | 0x0000 |
Sylvio Alvesd5230942022-01-20 21:35:53 -0300120
121---
Almir Okato39eb63d2022-01-05 18:31:54 -0300122
Almir Okatofa173df2022-04-19 01:10:30 -03001233. Reset your device
124
Almir Okato39eb63d2022-01-05 18:31:54 -0300125## [Signing and flashing an application](#signing-and-flashing-an-application)
126
1271. Images can be regularly signed with the `scripts/imgtool.py` script:
Almir Okato87240812022-12-21 00:05:07 -0300128```bash
Sylvio Alvesd5230942022-01-20 21:35:53 -0300129imgtool.py sign --align 4 -v 0 -H 32 --pad-header -S <SLOT_SIZE> <BIN_IN> <SIGNED_BIN>
Almir Okato39eb63d2022-01-05 18:31:54 -0300130```
131
Sylvio Alvesd5230942022-01-20 21:35:53 -0300132---
133
Almir Okatob365e232022-03-08 01:35:54 -0300134***Note***
Almir Okatoa1d641d2022-02-21 19:31:46 -0300135
Almir Okatob365e232022-03-08 01:35:54 -0300136`<SLOT_SIZE>` is the size of the slot to be used.
Sylvio Alvesd5230942022-01-20 21:35:53 -0300137Default slot0 size is `0x100000`, but it can change as per application flash partitions.
138
139For Zephyr images, `--pad-header` is not needed as it already has the padding for MCUboot header.
Almir Okato39eb63d2022-01-05 18:31:54 -0300140
141---
Sylvio Alvesd5230942022-01-20 21:35:53 -0300142
Almir Okato39eb63d2022-01-05 18:31:54 -0300143:warning: ***ATTENTION***
144
145*This is the basic signing needed for adding MCUboot headers and trailers.
146For signing with a crypto key and guarantee the authenticity of the image being booted, see the section [MCUboot image signature verification](#mcuboot-image-signature-verification) below.*
147
148---
149
1502. Flash the signed application:
Almir Okato87240812022-12-21 00:05:07 -0300151```bash
Almir Okato39eb63d2022-01-05 18:31:54 -0300152esptool.py -p <PORT> -b <BAUD> --before default_reset --after hard_reset --chip <TARGET> write_flash --flash_mode dio --flash_size <FLASH_SIZE> --flash_freq 40m <SLOT_OFFSET> <SIGNED_BIN>
153```
154
Almir Okato84da51b2022-11-25 01:25:41 -0300155# [Downgrade prevention](#downgrade-prevention)
156
157Downgrade prevention (avoid updating of images to an older version) can be enabled using the following configuration:
158
159```
160CONFIG_ESP_DOWNGRADE_PREVENTION=y
161```
162
163MCUboot will then verify and compare the new image version number with the current one before perform an update swap.
164
165Version number is added to the image when signing it with `imgtool` (`-v` parameter, e.g. `-v 1.0.0`).
166
167### [Downgrade prevention with security counter](#downgrade-prevention-with-security-counter)
168
169It is also possible to rely on a security counter, also added to the image when signing with `imgtool` (`-s` parameter), apart from version number. This allows image downgrade at some extent, since any update must have greater or equal security counter value. Enable using the following configuration:
170
171```
172CONFIG_ESP_DOWNGRADE_PREVENTION_SECURITY_COUNTER=y
173```
174
175E.g.: if the current image was signed using `-s 1` parameter, an eventual update image must have been signed using security counter `-s 1` or greater.
176
Almir Okato39eb63d2022-01-05 18:31:54 -0300177# [Security Chain on Espressif port](#security-chain-on-espressif-port)
178
179[MCUboot encrypted images](encrypted_images.md) do not provide full code confidentiality when only external storage is available (see [Threat model](encrypted_images.md#threat-model)) since by MCUboot design the image in Primary Slot, from where the image is executed, is stored plaintext.
180Espressif chips have off-chip flash memory, so to ensure a security chain along with MCUboot image signature verification, the hardware-assisted Secure Boot and Flash Encryption were made available on the MCUboot Espressif port.
181
182## [MCUboot image signature verification](#mcuboot-image-signature-verification)
183
184The image that MCUboot is booting can be signed with 4 types of keys: RSA-2048, RSA-3072, EC256 and ED25519. In order to enable the feature, the **bootloader** must be compiled with the following configurations:
185
186---
187***Note***
Almir Okatoa1d641d2022-02-21 19:31:46 -0300188
Almir Okato39eb63d2022-01-05 18:31:54 -0300189*It is strongly recommended to generate a new signing key using `imgtool` instead of use the existent samples.*
190
191---
192
193#### For EC256 algorithm use
194```
195CONFIG_ESP_SIGN_EC256=y
196
197# Use Tinycrypt lib for EC256 or ED25519 signing
198CONFIG_ESP_USE_TINYCRYPT=y
199
200CONFIG_ESP_SIGN_KEY_FILE=<YOUR_SIGNING_KEY.pem>
201```
202
203#### For ED25519 algorithm use
204```
205CONFIG_ESP_SIGN_ED25519=y
206
207# Use Tinycrypt lib for EC256 or ED25519 signing
208CONFIG_ESP_USE_TINYCRYPT=y
209
210CONFIG_ESP_SIGN_KEY_FILE=<YOUR_SIGNING_KEY.pem>
211```
212
213#### For RSA (2048 or 3072) algorithm use
214```
215CONFIG_ESP_SIGN_RSA=y
216# RSA_LEN is 2048 or 3072
217CONFIG_ESP_SIGN_RSA_LEN=<RSA_LEN>
218
219# Use Mbed TLS lib for RSA image signing
220CONFIG_ESP_USE_MBEDTLS=y
221
222CONFIG_ESP_SIGN_KEY_FILE=<YOUR_SIGNING_KEY.pem>
223```
224
225Notice that the public key will be embedded in the bootloader code, since the hardware key storage is not supported by Espressif port.
226
227### [Signing the image](#signing-the-image)
228
229Now you need to sign the **image binary**, use the `imgtool` with `-k` parameter:
Almir Okato87240812022-12-21 00:05:07 -0300230```bash
Almir Okato39eb63d2022-01-05 18:31:54 -0300231imgtool.py sign -k <YOUR_SIGNING_KEY.pem> --pad --pad-sig --align 4 -v 0 -H 32 --pad-header -S 0x00100000 <BIN_IN> <BIN_OUT>
232```
233If signing a Zephyr image, the `--pad-header` is not needed, as it already have the padding for MCUboot header.
234
235
236## [Secure Boot](#secure-boot)
237
238The Secure Boot implementation is based on [IDF's Secure Boot V2](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/security/secure-boot-v2.html), is hardware-assisted and RSA based, and has the role for ensuring that only authorized code will be executed on the device. This is done through bootloader signature checking by the ROM bootloader. \
239***Note***: ROM bootloader is the First Stage Bootloader, while the Espressif MCUboot port is the Second Stage Bootloader.
240
Almir Okato68a29802023-08-02 01:01:19 -0300241***Note***: Currently on MCUboot Espressif Port, the Secure Boot V2 for ESP32-C2 is not supported yet.
242
Almir Okato39eb63d2022-01-05 18:31:54 -0300243### [Building bootloader with Secure Boot](#building-bootloader-with-secure-boot)
244
245In order to build the bootloader with the feature on, the following configurations must be enabled:
246```
247CONFIG_SECURE_BOOT=1
248CONFIG_SECURE_BOOT_V2_ENABLED=1
249CONFIG_SECURE_SIGNED_ON_BOOT=1
250CONFIG_SECURE_SIGNED_APPS_RSA_SCHEME=1
251CONFIG_SECURE_BOOT_SUPPORTS_RSA=1
252```
253
254---
255:warning: ***ATTENTION***
256
257*On development phase is recommended add the following configuration in order to keep the debugging enabled and also to avoid any unrecoverable/permanent state change:*
258```
259CONFIG_SECURE_BOOT_ALLOW_JTAG=1
260CONFIG_SECURE_FLASH_UART_BOOTLOADER_ALLOW_CACHE=1
261
262# Options for enabling eFuse emulation in Flash
263CONFIG_EFUSE_VIRTUAL=1
264CONFIG_EFUSE_VIRTUAL_KEEP_IN_FLASH=1
265```
266
267---
268
Almir Okatob365e232022-03-08 01:35:54 -0300269---
270:warning: ***ATTENTION***
271
272*You can disable UART Download Mode by adding the following configuration:*
273```
274CONFIG_SECURE_DISABLE_ROM_DL_MODE=1
275```
276
277*This may be suitable for **production** builds. **After disabling UART Download Mode you will not be able to flash other images through UART.***
278
279*Otherwise, you can switch the UART ROM Download Mode to the Secure Download Mode. It will limit the use of Download Mode functions to simple flash read, write and erase operations.*
280```
281CONFIG_SECURE_ENABLE_SECURE_ROM_DL_MODE=1
282```
283
284*Once the device makes its first full boot, these configurations cannot be reverted*
285
286---
287
Almir Okato39eb63d2022-01-05 18:31:54 -0300288Once the **bootloader image** is built, the resulting binary file is required to be signed with `espsecure.py` tool.
289
290First create a signing key:
Almir Okato87240812022-12-21 00:05:07 -0300291```bash
Almir Okato39eb63d2022-01-05 18:31:54 -0300292espsecure.py generate_signing_key --version 2 <BOOTLOADER_SIGNING_KEY.pem>
293```
294
295Then sign the bootloader image:
Almir Okato87240812022-12-21 00:05:07 -0300296```bash
Almir Okato39eb63d2022-01-05 18:31:54 -0300297espsecure.py sign_data --version 2 --keyfile <BOOTLOADER_SIGNING_KEY.pem> -o <BOOTLOADER_BIN_OUT> <BOOTLOADER_BIN_IN>
298```
299
300---
301:warning: ***ATTENTION***
302
303*Once the bootloader is flashed and the device resets, the **first boot will enable Secure Boot** and the bootloader and key **no longer can be modified**. So **ENSURE** that both bootloader and key are correct and you did not forget anything before flashing.*
304
305---
306
307Flash the bootloader as following, with `--after no_reset` flag, so you can reset the device only when assured:
Almir Okato87240812022-12-21 00:05:07 -0300308```bash
Almir Okato39eb63d2022-01-05 18:31:54 -0300309esptool.py -p <PORT> -b 2000000 --after no_reset --chip <ESP_CHIP> write_flash --flash_mode dio --flash_size <FLASH_SIZE> --flash_freq 40m <BOOTLOADER_FLASH_OFFSET> <SIGNED_BOOTLOADER_BIN>
310```
311
312### [Secure Boot Process](#secure-boot-process)
313
314Secure boot uses a signature block appended to the bootloader image in order to verify the authenticity. The signature block contains the RSA-3072 signature of that image and the RSA-3072 public key.
315
316On its **first boot** the Secure Boot is not enabled on the device eFuses yet, neither the key nor digests. So the first boot will have the following process:
317
3181. On startup, since it is the first boot, the ROM bootloader will not verify the bootloader image (the Secure Boot bit in the eFuse is disabled) yet, so it proceeds to execute it (our MCUboot bootloader port).
3192. Bootloader calculates the SHA-256 hash digest of the public key and writes the result to eFuse.
3203. Bootloader validates the application images and prepare the booting process (MCUboot phase).
3214. Bootloader burns eFuse to enable Secure Boot V2.
3225. Bootloader proceeds to load the Primary image.
323
324After that the Secure Boot feature is permanently enabled and on every next boot the ROM bootloader will verify the MCUboot bootloader image.
325The process of an usual boot:
326
3271. On startup, the ROM bootloader checks the Secure Boot enable bit in the eFuse. If it is enabled, the boot will proceed as following.
3282. ROM bootloader verifies the bootloader's signature block integrity (magic number and CRC). Interrupt boot if it fails.
3293. ROM bootloader verifies the bootloader image, interrupt boot if any step fails.: \
3303.1. Compare the SHA-256 hash digest of the public key embedded in the bootloader’s signature block with the digest saved in the eFuses. \
3313.2. Generate the application image digest and match it with the image digest in the signature block. \
3323.3. Use the public key to verify the signature of the bootloader image, using RSA-PSS with the image digest calculated from previous step for comparison.
3334. ROM bootloader executes the bootloader image.
3345. Bootloader does the usual verification (MCUboot phase).
3356. Proceeds to boot the Primary image.
336
337## [Flash Encryption](#flash-encryption)
338
339The Espressif Flash Encryption is hardware-assisted, transparent to the MCUboot process and is an additional security measure beyond MCUboot existent features.
340The Flash Encryption implementation is also based on [IDF](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/security/flash-encryption.html) and is intended for encrypting off-chip flash memory contents, so it is protected against physical reading.
341
342When enabling the Flash Encryption, the user can encrypt the content either using a **device generated key** (remains unknown and unreadable) or a **host generated key** (owner is responsible for keeping the key private and safe). After the flash encryption gets enabled through eFuse burning on the device, all read and write operations are decrypted/encrypted in runtime.
343
344### [Building bootloader with Flash Encryption](#building-bootloader-with-flash-encryption)
345
346In order to build the bootloader with the feature on, the following configurations must be enabled:
347
348For **release mode**:
349```
350CONFIG_SECURE_FLASH_ENC_ENABLED=1
351CONFIG_SECURE_FLASH_ENCRYPTION_MODE_RELEASE=1
352```
353
354For **development mode**:
355```
356CONFIG_SECURE_FLASH_ENC_ENABLED=1
357CONFIG_SECURE_FLASH_ENCRYPTION_MODE_DEVELOPMENT=1
358```
Almir Okatob365e232022-03-08 01:35:54 -0300359
360---
Almir Okato39eb63d2022-01-05 18:31:54 -0300361:warning: ***ATTENTION***
362
363*On development phase is strongly recommended adding the following configuration in order to keep the debugging enabled and also to avoid any unrecoverable/permanent state change:*
364```
365CONFIG_SECURE_FLASH_UART_BOOTLOADER_ALLOW_ENC=1
366CONFIG_SECURE_FLASH_UART_BOOTLOADER_ALLOW_DEC=1
367CONFIG_SECURE_FLASH_UART_BOOTLOADER_ALLOW_CACHE=1
368CONFIG_SECURE_BOOT_ALLOW_JTAG=1
369
370# Options for enabling eFuse emulation in Flash
371CONFIG_EFUSE_VIRTUAL=1
372CONFIG_EFUSE_VIRTUAL_KEEP_IN_FLASH=1
373```
Almir Okatob365e232022-03-08 01:35:54 -0300374---
Almir Okato39eb63d2022-01-05 18:31:54 -0300375
376---
377:warning: ***ATTENTION***
378
379*Unless the recommended flags for **DEVELOPMENT MODE** were enabled, the actions made by Flash Encryption process are **PERMANENT**.* \
380*Once the bootloader is flashed and the device resets, the **first boot will enable Flash Encryption, encrypt the flash content including bootloader and image slots, burn the eFuses that no longer can be modified** and if device generated the key **it will not be recoverable**.* \
381*When on **RELEASE MODE**, **ENSURE** that the application with an update agent is flashed before reset the device.*
382
Almir Okatob365e232022-03-08 01:35:54 -0300383*In the same way as Secure Boot feature, you can disable UART Download Mode by adding the following configuration:*
384```
385CONFIG_SECURE_DISABLE_ROM_DL_MODE=1
386```
387
388*This may be suitable for **production** builds. **After disabling UART Download Mode you will not be able to flash other images through UART.***
389
390*Otherwise, you can switch the UART Download Mode to the Secure Download Mode. It will limit the use of Download Mode functions to simple flash read, write and erase operations.*
391```
392CONFIG_SECURE_ENABLE_SECURE_ROM_DL_MODE=1
393```
394
395*These configurations cannot be reverted after the device's first boot*
396
Almir Okato39eb63d2022-01-05 18:31:54 -0300397---
398
Sylvio Alvesd5230942022-01-20 21:35:53 -0300399### [Signing the image when working with Flash Encryption](#signing-the-image-when-working-with-flash-encryption)
400
401When enabling flash encryption, it is required to signed the image using 32-byte alignment: `--align 32 --max-align 32`.
402
403Command example:
Almir Okato87240812022-12-21 00:05:07 -0300404```bash
Sylvio Alvesd5230942022-01-20 21:35:53 -0300405imgtool.py sign -k <YOUR_SIGNING_KEY.pem> --pad --pad-sig --align 32 --max-align 32 -v 0 -H 32 --pad-header -S <SLOT_SIZE> <BIN_IN> <BIN_OUT>
406```
407
Almir Okato39eb63d2022-01-05 18:31:54 -0300408### [Device generated key](#device-generated-key)
409
410First ensure that the application image is able to perform encrypted read and write operations to the SPI Flash.
411Flash the bootloader and application normally:
Almir Okato87240812022-12-21 00:05:07 -0300412```bash
Almir Okato39eb63d2022-01-05 18:31:54 -0300413esptool.py -p <PORT> -b 2000000 --after no_reset --chip <ESP_CHIP> write_flash --flash_mode dio --flash_size <FLASH_SIZE> --flash_freq 40m <BOOTLOADER_FLASH_OFFSET> <BOOTLOADER_BIN>
414```
Almir Okato87240812022-12-21 00:05:07 -0300415```bash
Almir Okato39eb63d2022-01-05 18:31:54 -0300416esptool.py -p <PORT> -b 2000000 --after no_reset --chip <ESP_CHIP> write_flash --flash_mode dio --flash_size <FLASH_SIZE> --flash_freq 40m <PRIMARY_SLOT_FLASH_OFFSET> <APPLICATION_BIN>
417```
418
419On the **first boot**, the bootloader will:
4201. Generate Flash Encryption key and write to eFuse.
4212. Encrypt flash in-place including bootloader, image primary/secondary slot and scratch.
4223. Burn eFuse to enable Flash Encryption.
4234. Reset system to ensure Flash Encryption cache resets properly.
424
425### [Host generated key](#host-generated-key)
426
Almir Okatob365e232022-03-08 01:35:54 -0300427First ensure that the application image is able to perform encrypted read and write operations to the SPI Flash. Also ensure that the **UART ROM Download Mode is not disabled** - or that the **Secure Download Mode is enabled**.
Almir Okato39eb63d2022-01-05 18:31:54 -0300428Before flashing, generate the encryption key using `espsecure.py` tool:
Almir Okato87240812022-12-21 00:05:07 -0300429```bash
Almir Okato39eb63d2022-01-05 18:31:54 -0300430espsecure.py generate_flash_encryption_key <FLASH_ENCRYPTION_KEY.bin>
431```
432
Almir Okatob365e232022-03-08 01:35:54 -0300433Burn the key into the device's eFuse (keep a copy on the host), this action can be done **only once**:
Almir Okato39eb63d2022-01-05 18:31:54 -0300434
435---
436:warning: ***ATTENTION***
437
Almir Okatob365e232022-03-08 01:35:54 -0300438*eFuse emulation in Flash configuration options do not have any effect, so if the key burning command below is used, it will actually burn the physical eFuse.*
Almir Okato39eb63d2022-01-05 18:31:54 -0300439
440---
441
442- ESP32
Almir Okato87240812022-12-21 00:05:07 -0300443```bash
Almir Okato39eb63d2022-01-05 18:31:54 -0300444espefuse.py --port PORT burn_key flash_encryption <FLASH_ENCRYPTION_KEY.bin>
445```
446
Sylvio Alvesd8eff812022-01-31 23:16:06 -0300447- ESP32S2, ESP32C3 and ESP32S3
Almir Okato87240812022-12-21 00:05:07 -0300448```bash
Almir Okato39eb63d2022-01-05 18:31:54 -0300449espefuse.py --port PORT burn_key BLOCK <FLASH_ENCRYPTION_KEY.bin> <KEYPURPOSE>
450```
451
452BLOCK is a free keyblock between BLOCK_KEY0 and BLOCK_KEY5. And KEYPURPOSE is either XTS_AES_128_KEY, XTS_AES_256_KEY_1, XTS_AES_256_KEY_2 (AES XTS 256 is available only in ESP32S2).
453
454Now, similar as the Device generated key, the bootloader and application can be flashed plaintext. The **first boot** will encrypt the flash content using the host key burned in the eFuse instead of generate a new one.
455
456Flashing the bootloader and application:
Almir Okato87240812022-12-21 00:05:07 -0300457```bash
Almir Okato39eb63d2022-01-05 18:31:54 -0300458esptool.py -p <PORT> -b 2000000 --after no_reset --chip <ESP_CHIP> write_flash --flash_mode dio --flash_size <FLASH_SIZE> --flash_freq 40m <BOOTLOADER_FLASH_OFFSET> <BOOTLOADER_BIN>
459```
Almir Okato87240812022-12-21 00:05:07 -0300460```bash
Almir Okato39eb63d2022-01-05 18:31:54 -0300461esptool.py -p <PORT> -b 2000000 --after no_reset --chip <ESP_CHIP> write_flash --flash_mode dio --flash_size <FLASH_SIZE> --flash_freq 40m <PRIMARY_SLOT_FLASH_OFFSET> <APPLICATION_BIN>
462```
463
464On the **first boot**, the bootloader will:
4651. Encrypt flash in-place including bootloader, image primary/secondary slot and scratch using the written key.
4662. Burn eFuse to enable Flash Encryption.
4673. Reset system to ensure Flash Encryption cache resets properly.
468
Almir Okatob365e232022-03-08 01:35:54 -0300469Encrypting data on the host:
470- ESP32
Almir Okato87240812022-12-21 00:05:07 -0300471```bash
Almir Okatob365e232022-03-08 01:35:54 -0300472espsecure.py encrypt_flash_data --keyfile <FLASH_ENCRYPTION_KEY.bin> --address <FLASH_OFFSET> --output <OUTPUT_DATA> <INPUT_DATA>
473```
474
475- ESP32-S2, ESP32-C3 and ESP32-S3
Almir Okato87240812022-12-21 00:05:07 -0300476```bash
Almir Okatob365e232022-03-08 01:35:54 -0300477espsecure.py encrypt_flash_data --aes_xts --keyfile <FLASH_ENCRYPTION_KEY.bin> --address <FLASH_OFFSET> --output <OUTPUT_DATA> <INPUT_DATA>
478```
479
480---
481***Note***
Almir Okatoe8cbc0d2022-06-13 10:45:39 -0300482
Almir Okatob365e232022-03-08 01:35:54 -0300483OTA updates are required to be sent plaintext. The reason is that, as said before, after the Flash Encryption is enabled all read/write operations are decrypted/encrypted in runtime, so as e.g. if pre-encrypted data is sent for an OTA update, it would be wrongly double-encrypted when the update agent writes to the flash.
484
485For updating with an image encrypted on the host, flash it through serial using `esptool.py` as above. **UART ROM Download Mode must not be disabled**.
486
487---
488
Almir Okato39eb63d2022-01-05 18:31:54 -0300489## [Security Chain scheme](#security-chain-scheme)
490
491Using the 3 features, Secure Boot, Image signature verification and Flash Encryption, a Security Chain can be established so only trusted code is executed, and also the code and content residing in the off-chip flash are protected against undesirable reading.
492
493The overall final process when all features are enabled:
4941. ROM bootloader validates the MCUboot bootloader using RSA signature verification.
4952. MCUboot bootloader validates the image using the chosen algorithm EC256/RSA/ED25519. It also validates an upcoming image when updating.
4963. Flash Encryption guarantees that code and data are not exposed.
497
498### [Size Limitation](#size-limitation)
499
Almir Okatoa1d641d2022-02-21 19:31:46 -0300500When all 3 features are enable at same time, the bootloader size may exceed the fixed limit for the ROM bootloader checking on the Espressif chips **depending on which algorithm** was chosen for MCUboot image signing. The issue https://github.com/mcu-tools/mcuboot/issues/1262 was created to track this limitation.
501
502## [Multi image](#multi-image)
503
504The multi image feature (currently limited to 2 images) allows the images to be updated separately (each one has its own primary and secondary slot) by MCUboot.
505
506The Espressif port bootloader handles the boot in two different approaches:
507
508### [Host OS boots second image](#host-os-boots-second-image)
509
510Host OS from the *first image* is responsible for booting the *second image*, therefore the bootloader is aware of the second image regions and can update it, however it does not load neither boots it.
511
512Configuration example (`bootloader.conf`):
513```
514CONFIG_ESP_BOOTLOADER_SIZE=0xF000
515CONFIG_ESP_MCUBOOT_WDT_ENABLE=y
516
517# Enables multi image, if it is not defined, its assumed
518# only one updatable image
519CONFIG_ESP_IMAGE_NUMBER=2
520
521# Example of values to be used when multi image is enabled
522# Notice that the OS layer and update agent must be aware
523# of these regions
524CONFIG_ESP_APPLICATION_SIZE=0x50000
525CONFIG_ESP_IMAGE0_PRIMARY_START_ADDRESS=0x10000
526CONFIG_ESP_IMAGE0_SECONDARY_START_ADDRESS=0x60000
527CONFIG_ESP_IMAGE1_PRIMARY_START_ADDRESS=0xB0000
528CONFIG_ESP_IMAGE1_SECONDARY_START_ADDRESS=0x100000
529CONFIG_ESP_SCRATCH_OFFSET=0x150000
530CONFIG_ESP_SCRATCH_SIZE=0x40000
531```
532
533### [Multi boot](#multi-boot)
534
535In the multi boot approach the bootloader is responsible for booting two different images in two different CPUs, firstly the *second image* on the APP CPU and then the *first image* on the PRO CPU (current CPU), it is also responsible for update both images as well. Thus multi boot will be only supported by Espressif multi core chips - currently only ESP32 is implemented.
536
537---
538***Note***
539
540*The host OSes in each CPU must handle how the resources are divided/controlled between then.*
541
542---
543
544Configuration example:
545```
546CONFIG_ESP_BOOTLOADER_SIZE=0xF000
547CONFIG_ESP_MCUBOOT_WDT_ENABLE=y
548
549# Enables multi image, if it is not defined, its assumed
550# only one updatable image
551CONFIG_ESP_IMAGE_NUMBER=2
552
553# Enables multi image boot on independent processors
554# (main host OS is not responsible for booting the second image)
555# Use only with CONFIG_ESP_IMAGE_NUMBER=2
556CONFIG_ESP_MULTI_PROCESSOR_BOOT=y
557
558# Example of values to be used when multi image is enabled
559# Notice that the OS layer and update agent must be aware
560# of these regions
561CONFIG_ESP_APPLICATION_SIZE=0x50000
562CONFIG_ESP_IMAGE0_PRIMARY_START_ADDRESS=0x10000
563CONFIG_ESP_IMAGE0_SECONDARY_START_ADDRESS=0x60000
564CONFIG_ESP_IMAGE1_PRIMARY_START_ADDRESS=0xB0000
565CONFIG_ESP_IMAGE1_SECONDARY_START_ADDRESS=0x100000
566CONFIG_ESP_SCRATCH_OFFSET=0x150000
567CONFIG_ESP_SCRATCH_SIZE=0x40000
568```
569
570### [Image version dependency](#image-version-dependency)
571
572MCUboot allows version dependency check between the images when updating them. As `imgtool.py` allows a version assigment when signing an image, it is also possible to add the version dependency constraint:
Almir Okato87240812022-12-21 00:05:07 -0300573```bash
Almir Okatoa1d641d2022-02-21 19:31:46 -0300574imgtool.py sign --align 4 -v <VERSION> -d "(<IMAGE_INDEX>, <VERSION_DEPENDENCY>)" -H 32 --pad-header -S <SLOT_SIZE> <BIN_IN> <SIGNED_BIN>
575```
576
577- `<VERSION>` defines the version of the image being signed.
578- `"(<IMAGE_INDEX>, <VERSION_DEPENDENCY>)"` defines the minimum version and from which image is needed to satisfy the dependency.
579
580---
581Example:
Almir Okato87240812022-12-21 00:05:07 -0300582```bash
Almir Okatoa1d641d2022-02-21 19:31:46 -0300583imgtool.py sign --align 4 -v 1.0.0 -d "(1, 0.0.1+0)" -H 32 --pad-header -S 0x100000 image0.bin image0-signed.bin
584```
585
586Supposing that the image 0 is being signed, its version is 1.0.0 and it depends on image 1 with version at least 0.0.1+0.
587
588---
Almir Okatoe8cbc0d2022-06-13 10:45:39 -0300589
590## [Serial recovery mode](#serial-recovery-mode)
591
592Serial recovery mode allows management through MCUMGR (more information and how to install it: https://github.com/apache/mynewt-mcumgr-cli) for communicating and uploading a firmware to the device.
593
Almir Okatoe8cbc0d2022-06-13 10:45:39 -0300594Configuration example:
595```
596# Enables the MCUboot Serial Recovery, that allows the use of
597# MCUMGR to upload a firmware through the serial port
598CONFIG_ESP_MCUBOOT_SERIAL=y
599# GPIO used to boot on Serial Recovery
600CONFIG_ESP_SERIAL_BOOT_GPIO_DETECT=32
601# GPIO input type (0 for Pull-down, 1 for Pull-up)
602CONFIG_ESP_SERIAL_BOOT_GPIO_INPUT_TYPE=0
603# GPIO signal value
604CONFIG_ESP_SERIAL_BOOT_GPIO_DETECT_VAL=1
605# Delay time for identify the GPIO signal
606CONFIG_ESP_SERIAL_BOOT_DETECT_DELAY_S=5
607# UART port used for serial communication
608CONFIG_ESP_SERIAL_BOOT_UART_NUM=1
609# GPIO for Serial RX signal
610CONFIG_ESP_SERIAL_BOOT_GPIO_RX=25
611# GPIO for Serial TX signal
612CONFIG_ESP_SERIAL_BOOT_GPIO_TX=26
613```
614
615When enabled, the bootloader checks the if the GPIO `<CONFIG_ESP_SERIAL_BOOT_GPIO_DETECT>` configured has the signal value `<CONFIG_ESP_SERIAL_BOOT_GPIO_DETECT_VAL>` for approximately `<CONFIG_ESP_SERIAL_BOOT_DETECT_DELAY_S>` seconds for entering the Serial recovery mode. Example: a button configured on GPIO 32 pressed for 5 seconds.
616
617Serial mode then uses the UART port configured for communication (`<CONFIG_ESP_SERIAL_BOOT_UART_NUM>`, pins `<CONFIG_ESP_SERIAL_BOOT_GPIO_RX>`, `<CONFIG_ESP_SERIAL_BOOT_GPIO_RX>`).
618
Almir Okato09cca382022-09-23 15:25:28 -0300619### [Serial Recovery through USB JTAG Serial port](#serial-recovery-through-usb-jtag-serial-port)
620
Almir Okato87240812022-12-21 00:05:07 -0300621Some chips, like ESP32-C3 and ESP32-S3 have an integrated USB JTAG Serial Controller that implements a serial port (CDC) that can also be used for handling MCUboot Serial Recovery.
622More information about the USB pins and hardware configuration:
623- ESP32-C3: https://docs.espressif.com/projects/esp-idf/en/latest/esp32c3/api-guides/usb-serial-jtag-console.html
624- ESP32-S3: https://docs.espressif.com/projects/esp-idf/en/latest/esp32s3/api-guides/usb-serial-jtag-console.html.
Almir Okatoc1efa002023-08-09 14:47:30 -0300625- ESP32-C6: https://docs.espressif.com/projects/esp-idf/en/latest/esp32c6/api-guides/usb-serial-jtag-console.html
626- ESP32-H2: https://docs.espressif.com/projects/esp-idf/en/latest/esp32h2/api-guides/usb-serial-jtag-console.html
Almir Okato09cca382022-09-23 15:25:28 -0300627
628Configuration example:
629```
630# Use Serial through USB JTAG Serial port for Serial Recovery
631CONFIG_ESP_MCUBOOT_SERIAL_USB_SERIAL_JTAG=y
632# Use sector erasing (recommended) instead of entire image size
633# erasing when uploading through Serial Recovery
634CONFIG_ESP_MCUBOOT_ERASE_PROGRESSIVELY=y
635# GPIO used to boot on Serial Recovery
636CONFIG_ESP_SERIAL_BOOT_GPIO_DETECT=5
637# GPIO input type (0 for Pull-down, 1 for Pull-up)
638CONFIG_ESP_SERIAL_BOOT_GPIO_INPUT_TYPE=0
639# GPIO signal value
640CONFIG_ESP_SERIAL_BOOT_GPIO_DETECT_VAL=1
641# Delay time for identify the GPIO signal
642CONFIG_ESP_SERIAL_BOOT_DETECT_DELAY_S=5
643```
644
Almir Okato87240812022-12-21 00:05:07 -0300645---
646:warning: ***ATTENTION***
647
648*When working with Flash Encryption enabled, `CONFIG_ESP_MCUBOOT_ERASE_PROGRESSIVELY` must be ***disabled***, although it is recommended for common Serial Recovery usage*
649
650---
651
Almir Okatoe8cbc0d2022-06-13 10:45:39 -0300652### [MCUMGR image upload example](#mcumgr-image-upload-example)
653
654After entering the Serial recovery mode on the device, MCUMGR can be used as following:
655
656Configure the connection:
Almir Okato87240812022-12-21 00:05:07 -0300657```bash
Almir Okatoe8cbc0d2022-06-13 10:45:39 -0300658mcumgr conn add esp type="serial" connstring="dev=<PORT>,baud=115200,mtu=256"
659```
660
661Upload the image (the process may take some time):
Almir Okato87240812022-12-21 00:05:07 -0300662```bash
Almir Okatoe8cbc0d2022-06-13 10:45:39 -0300663mcumgr -c esp image upload <IMAGE_BIN>
664```
665
666Reset the device:
Almir Okato87240812022-12-21 00:05:07 -0300667```bash
Almir Okatoe8cbc0d2022-06-13 10:45:39 -0300668mcumgr -c esp reset
669```
670
671---
672:warning: ***ATTENTION***
673
674*Serial recovery mode uploads the image to the PRIMARY_SLOT, therefore if the upload process gets interrupted the image may be corrupted and unable to boot*
675
676---