readme-espressif.md
1# [Building and using MCUboot with Espressif's chips](#building-and-using-mcuboot-with-espressifs-chips)
2
3The Espressif port is build on top of ESP-IDF HAL, therefore it is required in order to build MCUboot for Espressif SoCs.
4
5Documentation about the MCUboot bootloader design, operation and features can be found in the [design document](design.md).
6
7## [SoC support availability](#soc-support-availability)
8
9The current port is available for use in the following SoCs within the OSes:
10
11| | ESP32 | ESP32-S2 | ESP32-C3 | ESP32-S3 |
12| :-----: | :-----: | :-----: | :-----: | :-----: |
13| Zephyr | Supported | Supported | Supported | WIP |
14| NuttX | Supported | Supported | Supported | WIP |
15
16## [Installing requirements and dependencies](#installing-requirements-and-dependencies)
17
181. Install additional packages required for development with MCUboot:
19```bash
20 cd ~/mcuboot # or to your directory where MCUboot is cloned
21```
22```bash
23 pip3 install --user -r scripts/requirements.txt
24```
25
262. Update the submodules needed by the Espressif port. This may take a while.
27```bash
28git submodule update --init --recursive --checkout boot/espressif/hal/esp-idf
29```
30
313. Next, get the Mbed TLS submodule required by MCUboot.
32```bash
33git submodule update --init --recursive ext/mbedtls
34```
35
364. Now we need to install IDF dependencies and set environment variables. This step may take some time:
37```bash
38cd boot/espressif/hal/esp-idf
39```
40```bash
41./install.sh
42```
43```bash
44. ./export.sh
45```
46```bash
47cd ../..
48```
49
50## [Building the bootloader itself](#building-the-bootloader-itself)
51
52The MCUboot Espressif port bootloader is built using the toolchain and tools provided by ESP-IDF. 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.
53
54---
55***Note***
56
57*Replace `<TARGET>` with the target ESP32 family (like `esp32`, `esp32s2` and others).*
58
59---
60
611. Compile and generate the BIN:
62```bash
63cmake -DCMAKE_TOOLCHAIN_FILE=tools/toolchain-<TARGET>.cmake -DMCUBOOT_TARGET=<TARGET> -DMCUBOOT_FLASH_PORT=<PORT> -B build -GNinja
64```
65```bash
66ninja -C build/
67```
68
692. Flash MCUboot in your device:
70```bash
71ninja -C build/ flash
72```
73
74If `MCUBOOT_FLASH_PORT` arg was not passed to `cmake`, the default `PORT` for flashing will be `/dev/ttyUSB0`.
75
76Alternatively:
77```bash
78esptool.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
79```
80---
81***Note***
82
83You may adjust the port `<PORT>` (like `/dev/ttyUSB0`) and baud rate `<BAUD>` (like `2000000`) according to the connection with your board.
84You can also skip `<PORT>` and `<BAUD>` parameters so that esptool tries to automatically detect it.
85
86*`<FLASH_SIZE>` can be found using the command below:*
87```bash
88esptool.py -p <PORT> -b <BAUD> flash_id
89```
90The output contains device information and its flash size:
91```
92Detected flash size: 4MB
93```
94
95
96*`<BOOTLOADER_FLASH_OFFSET>` value must follow one of the addresses below:*
97
98| ESP32 | ESP32-S2 | ESP32-C3 | ESP32-S3 |
99| :-----: | :-----: | :-----: | :-----: |
100| 0x1000 | 0x1000 | 0x0000 | 0x0000 |
101
102---
103
1043. Reset your device
105
106## [Signing and flashing an application](#signing-and-flashing-an-application)
107
1081. Images can be regularly signed with the `scripts/imgtool.py` script:
109```bash
110imgtool.py sign --align 4 -v 0 -H 32 --pad-header -S <SLOT_SIZE> <BIN_IN> <SIGNED_BIN>
111```
112
113---
114
115***Note***
116
117`<SLOT_SIZE>` is the size of the slot to be used.
118Default slot0 size is `0x100000`, but it can change as per application flash partitions.
119
120For Zephyr images, `--pad-header` is not needed as it already has the padding for MCUboot header.
121
122---
123
124:warning: ***ATTENTION***
125
126*This is the basic signing needed for adding MCUboot headers and trailers.
127For 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.*
128
129---
130
1312. Flash the signed application:
132```bash
133esptool.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>
134```
135
136# [Downgrade prevention](#downgrade-prevention)
137
138Downgrade prevention (avoid updating of images to an older version) can be enabled using the following configuration:
139
140```
141CONFIG_ESP_DOWNGRADE_PREVENTION=y
142```
143
144MCUboot will then verify and compare the new image version number with the current one before perform an update swap.
145
146Version number is added to the image when signing it with `imgtool` (`-v` parameter, e.g. `-v 1.0.0`).
147
148### [Downgrade prevention with security counter](#downgrade-prevention-with-security-counter)
149
150It 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:
151
152```
153CONFIG_ESP_DOWNGRADE_PREVENTION_SECURITY_COUNTER=y
154```
155
156E.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.
157
158# [Security Chain on Espressif port](#security-chain-on-espressif-port)
159
160[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.
161Espressif 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.
162
163## [MCUboot image signature verification](#mcuboot-image-signature-verification)
164
165The 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:
166
167---
168***Note***
169
170*It is strongly recommended to generate a new signing key using `imgtool` instead of use the existent samples.*
171
172---
173
174#### For EC256 algorithm use
175```
176CONFIG_ESP_SIGN_EC256=y
177
178# Use Tinycrypt lib for EC256 or ED25519 signing
179CONFIG_ESP_USE_TINYCRYPT=y
180
181CONFIG_ESP_SIGN_KEY_FILE=<YOUR_SIGNING_KEY.pem>
182```
183
184#### For ED25519 algorithm use
185```
186CONFIG_ESP_SIGN_ED25519=y
187
188# Use Tinycrypt lib for EC256 or ED25519 signing
189CONFIG_ESP_USE_TINYCRYPT=y
190
191CONFIG_ESP_SIGN_KEY_FILE=<YOUR_SIGNING_KEY.pem>
192```
193
194#### For RSA (2048 or 3072) algorithm use
195```
196CONFIG_ESP_SIGN_RSA=y
197# RSA_LEN is 2048 or 3072
198CONFIG_ESP_SIGN_RSA_LEN=<RSA_LEN>
199
200# Use Mbed TLS lib for RSA image signing
201CONFIG_ESP_USE_MBEDTLS=y
202
203CONFIG_ESP_SIGN_KEY_FILE=<YOUR_SIGNING_KEY.pem>
204```
205
206Notice that the public key will be embedded in the bootloader code, since the hardware key storage is not supported by Espressif port.
207
208### [Signing the image](#signing-the-image)
209
210Now you need to sign the **image binary**, use the `imgtool` with `-k` parameter:
211```bash
212imgtool.py sign -k <YOUR_SIGNING_KEY.pem> --pad --pad-sig --align 4 -v 0 -H 32 --pad-header -S 0x00100000 <BIN_IN> <BIN_OUT>
213```
214If signing a Zephyr image, the `--pad-header` is not needed, as it already have the padding for MCUboot header.
215
216
217## [Secure Boot](#secure-boot)
218
219The 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. \
220***Note***: ROM bootloader is the First Stage Bootloader, while the Espressif MCUboot port is the Second Stage Bootloader.
221
222### [Building bootloader with Secure Boot](#building-bootloader-with-secure-boot)
223
224In order to build the bootloader with the feature on, the following configurations must be enabled:
225```
226CONFIG_SECURE_BOOT=1
227CONFIG_SECURE_BOOT_V2_ENABLED=1
228CONFIG_SECURE_SIGNED_ON_BOOT=1
229CONFIG_SECURE_SIGNED_APPS_RSA_SCHEME=1
230CONFIG_SECURE_BOOT_SUPPORTS_RSA=1
231```
232
233---
234:warning: ***ATTENTION***
235
236*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:*
237```
238CONFIG_SECURE_BOOT_ALLOW_JTAG=1
239CONFIG_SECURE_FLASH_UART_BOOTLOADER_ALLOW_CACHE=1
240
241# Options for enabling eFuse emulation in Flash
242CONFIG_EFUSE_VIRTUAL=1
243CONFIG_EFUSE_VIRTUAL_KEEP_IN_FLASH=1
244```
245
246---
247
248---
249:warning: ***ATTENTION***
250
251*You can disable UART Download Mode by adding the following configuration:*
252```
253CONFIG_SECURE_DISABLE_ROM_DL_MODE=1
254```
255
256*This may be suitable for **production** builds. **After disabling UART Download Mode you will not be able to flash other images through UART.***
257
258*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.*
259```
260CONFIG_SECURE_ENABLE_SECURE_ROM_DL_MODE=1
261```
262
263*Once the device makes its first full boot, these configurations cannot be reverted*
264
265---
266
267Once the **bootloader image** is built, the resulting binary file is required to be signed with `espsecure.py` tool.
268
269First create a signing key:
270```bash
271espsecure.py generate_signing_key --version 2 <BOOTLOADER_SIGNING_KEY.pem>
272```
273
274Then sign the bootloader image:
275```bash
276espsecure.py sign_data --version 2 --keyfile <BOOTLOADER_SIGNING_KEY.pem> -o <BOOTLOADER_BIN_OUT> <BOOTLOADER_BIN_IN>
277```
278
279---
280:warning: ***ATTENTION***
281
282*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.*
283
284---
285
286Flash the bootloader as following, with `--after no_reset` flag, so you can reset the device only when assured:
287```bash
288esptool.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>
289```
290
291### [Secure Boot Process](#secure-boot-process)
292
293Secure 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.
294
295On 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:
296
2971. 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).
2982. Bootloader calculates the SHA-256 hash digest of the public key and writes the result to eFuse.
2993. Bootloader validates the application images and prepare the booting process (MCUboot phase).
3004. Bootloader burns eFuse to enable Secure Boot V2.
3015. Bootloader proceeds to load the Primary image.
302
303After that the Secure Boot feature is permanently enabled and on every next boot the ROM bootloader will verify the MCUboot bootloader image.
304The process of an usual boot:
305
3061. On startup, the ROM bootloader checks the Secure Boot enable bit in the eFuse. If it is enabled, the boot will proceed as following.
3072. ROM bootloader verifies the bootloader's signature block integrity (magic number and CRC). Interrupt boot if it fails.
3083. ROM bootloader verifies the bootloader image, interrupt boot if any step fails.: \
3093.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. \
3103.2. Generate the application image digest and match it with the image digest in the signature block. \
3113.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.
3124. ROM bootloader executes the bootloader image.
3135. Bootloader does the usual verification (MCUboot phase).
3146. Proceeds to boot the Primary image.
315
316## [Flash Encryption](#flash-encryption)
317
318The Espressif Flash Encryption is hardware-assisted, transparent to the MCUboot process and is an additional security measure beyond MCUboot existent features.
319The 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.
320
321When 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.
322
323### [Building bootloader with Flash Encryption](#building-bootloader-with-flash-encryption)
324
325In order to build the bootloader with the feature on, the following configurations must be enabled:
326
327For **release mode**:
328```
329CONFIG_SECURE_FLASH_ENC_ENABLED=1
330CONFIG_SECURE_FLASH_ENCRYPTION_MODE_RELEASE=1
331```
332
333For **development mode**:
334```
335CONFIG_SECURE_FLASH_ENC_ENABLED=1
336CONFIG_SECURE_FLASH_ENCRYPTION_MODE_DEVELOPMENT=1
337```
338
339---
340:warning: ***ATTENTION***
341
342*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:*
343```
344CONFIG_SECURE_FLASH_UART_BOOTLOADER_ALLOW_ENC=1
345CONFIG_SECURE_FLASH_UART_BOOTLOADER_ALLOW_DEC=1
346CONFIG_SECURE_FLASH_UART_BOOTLOADER_ALLOW_CACHE=1
347CONFIG_SECURE_BOOT_ALLOW_JTAG=1
348
349# Options for enabling eFuse emulation in Flash
350CONFIG_EFUSE_VIRTUAL=1
351CONFIG_EFUSE_VIRTUAL_KEEP_IN_FLASH=1
352```
353---
354
355---
356:warning: ***ATTENTION***
357
358*Unless the recommended flags for **DEVELOPMENT MODE** were enabled, the actions made by Flash Encryption process are **PERMANENT**.* \
359*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**.* \
360*When on **RELEASE MODE**, **ENSURE** that the application with an update agent is flashed before reset the device.*
361
362*In the same way as Secure Boot feature, you can disable UART Download Mode by adding the following configuration:*
363```
364CONFIG_SECURE_DISABLE_ROM_DL_MODE=1
365```
366
367*This may be suitable for **production** builds. **After disabling UART Download Mode you will not be able to flash other images through UART.***
368
369*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.*
370```
371CONFIG_SECURE_ENABLE_SECURE_ROM_DL_MODE=1
372```
373
374*These configurations cannot be reverted after the device's first boot*
375
376---
377
378### [Signing the image when working with Flash Encryption](#signing-the-image-when-working-with-flash-encryption)
379
380When enabling flash encryption, it is required to signed the image using 32-byte alignment: `--align 32 --max-align 32`.
381
382Command example:
383```bash
384imgtool.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>
385```
386
387### [Device generated key](#device-generated-key)
388
389First ensure that the application image is able to perform encrypted read and write operations to the SPI Flash.
390Flash the bootloader and application normally:
391```bash
392esptool.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>
393```
394```bash
395esptool.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>
396```
397
398On the **first boot**, the bootloader will:
3991. Generate Flash Encryption key and write to eFuse.
4002. Encrypt flash in-place including bootloader, image primary/secondary slot and scratch.
4013. Burn eFuse to enable Flash Encryption.
4024. Reset system to ensure Flash Encryption cache resets properly.
403
404### [Host generated key](#host-generated-key)
405
406First 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**.
407Before flashing, generate the encryption key using `espsecure.py` tool:
408```bash
409espsecure.py generate_flash_encryption_key <FLASH_ENCRYPTION_KEY.bin>
410```
411
412Burn the key into the device's eFuse (keep a copy on the host), this action can be done **only once**:
413
414---
415:warning: ***ATTENTION***
416
417*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.*
418
419---
420
421- ESP32
422```bash
423espefuse.py --port PORT burn_key flash_encryption <FLASH_ENCRYPTION_KEY.bin>
424```
425
426- ESP32S2, ESP32C3 and ESP32S3
427```bash
428espefuse.py --port PORT burn_key BLOCK <FLASH_ENCRYPTION_KEY.bin> <KEYPURPOSE>
429```
430
431BLOCK 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).
432
433Now, 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.
434
435Flashing the bootloader and application:
436```bash
437esptool.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>
438```
439```bash
440esptool.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>
441```
442
443On the **first boot**, the bootloader will:
4441. Encrypt flash in-place including bootloader, image primary/secondary slot and scratch using the written key.
4452. Burn eFuse to enable Flash Encryption.
4463. Reset system to ensure Flash Encryption cache resets properly.
447
448Encrypting data on the host:
449- ESP32
450```bash
451espsecure.py encrypt_flash_data --keyfile <FLASH_ENCRYPTION_KEY.bin> --address <FLASH_OFFSET> --output <OUTPUT_DATA> <INPUT_DATA>
452```
453
454- ESP32-S2, ESP32-C3 and ESP32-S3
455```bash
456espsecure.py encrypt_flash_data --aes_xts --keyfile <FLASH_ENCRYPTION_KEY.bin> --address <FLASH_OFFSET> --output <OUTPUT_DATA> <INPUT_DATA>
457```
458
459---
460***Note***
461
462OTA 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.
463
464For 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**.
465
466---
467
468## [Security Chain scheme](#security-chain-scheme)
469
470Using 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.
471
472The overall final process when all features are enabled:
4731. ROM bootloader validates the MCUboot bootloader using RSA signature verification.
4742. MCUboot bootloader validates the image using the chosen algorithm EC256/RSA/ED25519. It also validates an upcoming image when updating.
4753. Flash Encryption guarantees that code and data are not exposed.
476
477### [Size Limitation](#size-limitation)
478
479When 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.
480
481## [Multi image](#multi-image)
482
483The 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.
484
485The Espressif port bootloader handles the boot in two different approaches:
486
487### [Host OS boots second image](#host-os-boots-second-image)
488
489Host 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.
490
491Configuration example (`bootloader.conf`):
492```
493CONFIG_ESP_BOOTLOADER_SIZE=0xF000
494CONFIG_ESP_MCUBOOT_WDT_ENABLE=y
495
496# Enables multi image, if it is not defined, its assumed
497# only one updatable image
498CONFIG_ESP_IMAGE_NUMBER=2
499
500# Example of values to be used when multi image is enabled
501# Notice that the OS layer and update agent must be aware
502# of these regions
503CONFIG_ESP_APPLICATION_SIZE=0x50000
504CONFIG_ESP_IMAGE0_PRIMARY_START_ADDRESS=0x10000
505CONFIG_ESP_IMAGE0_SECONDARY_START_ADDRESS=0x60000
506CONFIG_ESP_IMAGE1_PRIMARY_START_ADDRESS=0xB0000
507CONFIG_ESP_IMAGE1_SECONDARY_START_ADDRESS=0x100000
508CONFIG_ESP_SCRATCH_OFFSET=0x150000
509CONFIG_ESP_SCRATCH_SIZE=0x40000
510```
511
512### [Multi boot](#multi-boot)
513
514In 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.
515
516---
517***Note***
518
519*The host OSes in each CPU must handle how the resources are divided/controlled between then.*
520
521---
522
523Configuration example:
524```
525CONFIG_ESP_BOOTLOADER_SIZE=0xF000
526CONFIG_ESP_MCUBOOT_WDT_ENABLE=y
527
528# Enables multi image, if it is not defined, its assumed
529# only one updatable image
530CONFIG_ESP_IMAGE_NUMBER=2
531
532# Enables multi image boot on independent processors
533# (main host OS is not responsible for booting the second image)
534# Use only with CONFIG_ESP_IMAGE_NUMBER=2
535CONFIG_ESP_MULTI_PROCESSOR_BOOT=y
536
537# Example of values to be used when multi image is enabled
538# Notice that the OS layer and update agent must be aware
539# of these regions
540CONFIG_ESP_APPLICATION_SIZE=0x50000
541CONFIG_ESP_IMAGE0_PRIMARY_START_ADDRESS=0x10000
542CONFIG_ESP_IMAGE0_SECONDARY_START_ADDRESS=0x60000
543CONFIG_ESP_IMAGE1_PRIMARY_START_ADDRESS=0xB0000
544CONFIG_ESP_IMAGE1_SECONDARY_START_ADDRESS=0x100000
545CONFIG_ESP_SCRATCH_OFFSET=0x150000
546CONFIG_ESP_SCRATCH_SIZE=0x40000
547```
548
549### [Image version dependency](#image-version-dependency)
550
551MCUboot 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:
552```bash
553imgtool.py sign --align 4 -v <VERSION> -d "(<IMAGE_INDEX>, <VERSION_DEPENDENCY>)" -H 32 --pad-header -S <SLOT_SIZE> <BIN_IN> <SIGNED_BIN>
554```
555
556- `<VERSION>` defines the version of the image being signed.
557- `"(<IMAGE_INDEX>, <VERSION_DEPENDENCY>)"` defines the minimum version and from which image is needed to satisfy the dependency.
558
559---
560Example:
561```bash
562imgtool.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
563```
564
565Supposing 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.
566
567---
568
569## [Serial recovery mode](#serial-recovery-mode)
570
571Serial 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.
572
573Configuration example:
574```
575# Enables the MCUboot Serial Recovery, that allows the use of
576# MCUMGR to upload a firmware through the serial port
577CONFIG_ESP_MCUBOOT_SERIAL=y
578# GPIO used to boot on Serial Recovery
579CONFIG_ESP_SERIAL_BOOT_GPIO_DETECT=32
580# GPIO input type (0 for Pull-down, 1 for Pull-up)
581CONFIG_ESP_SERIAL_BOOT_GPIO_INPUT_TYPE=0
582# GPIO signal value
583CONFIG_ESP_SERIAL_BOOT_GPIO_DETECT_VAL=1
584# Delay time for identify the GPIO signal
585CONFIG_ESP_SERIAL_BOOT_DETECT_DELAY_S=5
586# UART port used for serial communication
587CONFIG_ESP_SERIAL_BOOT_UART_NUM=1
588# GPIO for Serial RX signal
589CONFIG_ESP_SERIAL_BOOT_GPIO_RX=25
590# GPIO for Serial TX signal
591CONFIG_ESP_SERIAL_BOOT_GPIO_TX=26
592```
593
594When 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.
595
596Serial 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>`).
597
598### [Serial Recovery through USB JTAG Serial port](#serial-recovery-through-usb-jtag-serial-port)
599
600Some 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.
601More information about the USB pins and hardware configuration:
602- ESP32-C3: https://docs.espressif.com/projects/esp-idf/en/latest/esp32c3/api-guides/usb-serial-jtag-console.html
603- ESP32-S3: https://docs.espressif.com/projects/esp-idf/en/latest/esp32s3/api-guides/usb-serial-jtag-console.html.
604
605Configuration example:
606```
607# Use Serial through USB JTAG Serial port for Serial Recovery
608CONFIG_ESP_MCUBOOT_SERIAL_USB_SERIAL_JTAG=y
609# Use sector erasing (recommended) instead of entire image size
610# erasing when uploading through Serial Recovery
611CONFIG_ESP_MCUBOOT_ERASE_PROGRESSIVELY=y
612# GPIO used to boot on Serial Recovery
613CONFIG_ESP_SERIAL_BOOT_GPIO_DETECT=5
614# GPIO input type (0 for Pull-down, 1 for Pull-up)
615CONFIG_ESP_SERIAL_BOOT_GPIO_INPUT_TYPE=0
616# GPIO signal value
617CONFIG_ESP_SERIAL_BOOT_GPIO_DETECT_VAL=1
618# Delay time for identify the GPIO signal
619CONFIG_ESP_SERIAL_BOOT_DETECT_DELAY_S=5
620```
621
622---
623:warning: ***ATTENTION***
624
625*When working with Flash Encryption enabled, `CONFIG_ESP_MCUBOOT_ERASE_PROGRESSIVELY` must be ***disabled***, although it is recommended for common Serial Recovery usage*
626
627---
628
629### [MCUMGR image upload example](#mcumgr-image-upload-example)
630
631After entering the Serial recovery mode on the device, MCUMGR can be used as following:
632
633Configure the connection:
634```bash
635mcumgr conn add esp type="serial" connstring="dev=<PORT>,baud=115200,mtu=256"
636```
637
638Upload the image (the process may take some time):
639```bash
640mcumgr -c esp image upload <IMAGE_BIN>
641```
642
643Reset the device:
644```bash
645mcumgr -c esp reset
646```
647
648---
649:warning: ***ATTENTION***
650
651*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*
652
653---
654
readme-mbed.md
1# MCUboot port for Mbed OS
2
3This is an MCUboot port for Mbed OS.
4
5## Using MCUboot
6
7Note: The following is a general overview. It does not cover MCUboot or Mbed OS basics.
8
9See https://github.com/AGlass0fMilk/mbed-mcuboot-demo as a detailed example.
10
11### Basic configurations
12
13To use MCUboot, you need to create an Mbed OS project with the following configurations:
14* `"mcuboot.primary-slot-address"`: address of the primary slot in the internal flash
15* `"mcuboot.slot-size"`: size of an image slot (only one image, two slots are currently supported)
16* `"mcuboot.max-img-sectors"`: maximum number of sectors, should be at least the number of sectors in each slot
17* `"target.restrict_size"`: the maximum size of the bootloader, such that it does not overlap with the primary slot
18
19More configurations such as signing algorithm, slot swapping, etc. can be found in [mbed_lib.json](https://github.com/mcu-tools/mcuboot/tree/main/boot/mbed/mbed_lib.json). Please note that certain features are not currently supported.
20
21### Providing a secondary slot
22
23You need to provide an instance of `mbed::BlockDevice` as the secondary slot. It can be any types of internal or external storage provided that:
24* Its size equals the `"mcuboot.slot-size"` you have set
25* Its minimum supported read and write sizes (granularities) are _no larger than_ 16 byte, which MCUboot's read/write operations are aligned to. If the read size is larger than _one byte_, you need to set `"mcuboot.read-granularity"` to the read size of the storage - this buffers smaller read operations.
26
27In order for MCUboot to access your secondary slot, the interface to implement is
28```cpp
29mbed::BlockDevice* get_secondary_bd(void);
30```
31which should return an uninitialized instance of BlockDevice.
32
33### Building the bootloader
34
35To build a bootloader based on MCUboot, make sure `"mcuboot.bootloader-build"` is `true` (already the default) and you have provided configurations and a secondary slot BlockDevice as explained above.
36
37### Building a user application
38
39To build a user application, set `"mcuboot.bootloader-build"` to `false` so MCUboot is built as a _library only_ without a bootloader application. This is useful if your user application needs to confirm the current image with `boot_set_confirmed()` after an update, or set a new image in the secondary slot as pending with `boot_set_pending()` in order to trigger an update upon reboot.
40
41As your application starts in the primary slots (instead of the beginning of the whole flash), you need to set the start address (`"target.mbed_app_start"`) to be equal to `"mcuboot.primary-slot-address"` + `"mcuboot.header-size"` of your bootloader. And its size (`"target.mbed_app_size"`) must be no larger than `"mcuboot.slot-size"` - `"mcuboot.header-size"`, and some space must be left for the image trailer too (see [this](design.md#image-trailer)).
42
readme-mynewt.md
1# Running mynewt apps with MCUboot
2
3Due to small differences between Mynewt's bundled bootloader and MCUboot,
4when building an app that will be run with MCUboot as the bootloader and
5which at the same time requires to use `newtmgr` to manage images, MCUboot
6must be added as a new dependency for this app.
7
8First you need to add the repo to your `project.yml`:
9
10```
11 project.repositories:
12 - mcuboot
13
14 repository.mcuboot:
15 type: github
16 vers: 0-dev
17 user: mcu-tools
18 repo: mcuboot
19```
20
21Then update your app's `pkg.yml` adding the extra dependency:
22
23```
24 pkg.deps:
25 - "@mcuboot/boot/bootutil"
26```
27
28Also remove any dependency on `boot/bootutil` (mynewt's bundled bootloader)
29which might exist.
30
31To configure MCUboot check all the options available in
32`boot/mynewt/mcuboot_config/syscfg.yml`.
33
34Also, MCUboot uses a different image header struct as well as slightly
35different TLV structure, so images created by `newt` have to be generated
36in this new format. That is done by passing the extra parameter `-2` as in:
37
38`newt create-image <target> <version> <pubkey> -2`
39
40# Boot serial functionality with Mynewt
41
42Building with `BOOT_SERIAL: 1` enables some basic management functionality
43like listing images and uploading a new image to `slot0`. The serial bootloader
44requires that `mtu` is set to a value that is less than or equal to `256`.
45This can be done either by editing `~/.newtmgr.cp.json` and setting the `mtu`
46for the connection profile, or specifying you connection string manually as in:
47
48```
49newtmgr --conntype serial --connstring "dev=/dev/ttyUSB0,mtu=256" image upload -e blinky.img
50```
51
52where `/dev/ttyUSB0` is your serial port.
53
readme-nuttx.md
1# MCUboot port for NuttX
2
3## Description
4
5The NuttX port of MCUboot secure boot library expects that the platform provides a Flash storage with the following partitions:
6- `CONFIG_MCUBOOT_PRIMARY_SLOT_PATH`: MTD partition for the application firmware image PRIMARY slot;
7- `CONFIG_MCUBOOT_SECONDARY_SLOT_PATH`: MTD partition for the application firmware image SECONDARY slot;
8- `CONFIG_MCUBOOT_SCRATCH_PATH`: MTD partition for the Scratch area;
9
10Also, these are optional features that may be enabled:
11
12- `CONFIG_MCUBOOT_WATCHDOG`: If `CONFIG_WATCHDOG` is enabled, MCUboot shall reset the watchdog timer indicated by `CONFIG_MCUBOOT_WATCHDOG_DEVPATH` to the current timeout value, preventing any imminent watchdog timeouts.
13
14The porting layer of MCUboot library consists of the following interfaces:
15- `<flash_map_backend/flash_map_backend.h>`, for enabling MCUboot to manage the application firmware image slots in the device storage.
16- `<mcuboot_config/mcuboot_config.h>`, for configuration of MCUboot's features.
17- `<mcuboot_config/mcuboot_logging.h>`, for providing logging capabilities.
18- `<os/os_malloc.h>`, for providing MCUboot access to the OS memory management interfaces.
19- `<sysflash/sysflash.h>`, for configuration of the system's flash area organization.
20
21The NuttX port of MCUboot is implemented at application-level and requires minimal knowledge about characteristics of the underlying storage device. This is achieved by means of the `BCH` and `FTL` subsystems, which enable MCUboot to manage MTD partitions via character device drivers using standard POSIX filesystem operations (e.g. `open()` / `close()` / `read()` / `write()`).
22
23## Creating MCUboot-compatible application firmware images
24
25One common use case for MCUboot is to integrate it to a firmware update agent, which is an important component of a secure firmware update subsystem. Through MCUboot APIs an application is able to install a newly received application firmware image and, once this application firmware image is assured to be valid, the application may confirm it as a stable image. In case that application firmware image is deemed bogus, MCUboot provides an API for invalidating that update, which will induce a rollback procedure to the most recent stable application firmware image.
26
27The `CONFIG_MCUBOOT_UPDATE_AGENT_EXAMPLE` example demonstrates this workflow by downloading an application firmware image from a webserver, installing it and triggering the firmware update process for the next boot after a system reset. There is also the `CONFIG_MCUBOOT_SLOT_CONFIRM_EXAMPLE`, which is a fairly simple example that just calls an MCUboot API for confirming the executing application firmware image as stable.
28
29## Using MCUboot on NuttX as a secure boot solution
30
31NuttX port for MCUboot also enables the creation of a secure bootloader application requiring minimal platform-specific implementation. The logical implementation for the secure boot is performed at application-level by the MCUboot library. Once MCUboot validates the application firmware image, it delegates the loading and execution of the application firmware image to a platform-specific routine, which is accessed via `boardctl(BOARDIOC_BOOT_IMAGE)` call. Each platform must then provide an implementation for the `board_boot_image()` for executing the required actions in order to boot a new application firmware image (e.g. deinitialize peripherals, load the Program Counter register with the application firmware image entry point address).
32
33The MCUboot bootloader application may be enabled by selecting the `CONFIG_MCUBOOT_BOOTLOADER` option.
34
35## Assumptions
36
37### IOCTL MTD commands
38
39The implementation of `<flash_map_backend/flash_map_backend.h>` expects that the MTD driver for a given image partition handles the following `ioctl` commands:
40- `MTDIOC_GEOMETRY`, for retrieving information about the geometry of the MTD, required for the configuration of the size of each flash area.
41- `MTDIOC_ERASESTATE`, for retrieving the byte value of an erased cell of the MTD, required for the implementation of `flash_area_erased_val()` interface.
42
43### Write access alignment
44
45Through `flash_area_align()` interface MCUboot expects that the implementation provides the shortest data length that may be written via `flash_area_write()` interface. The NuttX implementation passes through the `BCH` and `FTL` layers, which appropriately handle the write alignment restrictions of the underlying MTD. So The NuttX implementation of `flash_area_align()` is able to return a fixed value of 1 byte, even if the MTD does not support byte operations.
46
47## Limitations
48
49### `<flash_map_backend/flash_map_backend.h>` functions are not multitasking-safe
50
51MCUboot's documentation imposes no restrictions regarding the usage of its public interfaces, which doesn't mean they are thread-safe.
52But, regarding NuttX implementation of the `<flash_map_backend/flash_map_backend.h>`, it is safe to state that they are **not** multitasking-safe. NuttX implementation manages the MTD partitions via character device drivers. As file-descriptors cannot be shared between different tasks, if one task calls `flash_area_open` and another task calls `flash_area_<read/write/close>` passing the same `struct flash_area` instance, it will result in failure.
53
readme-riot.md
1# Building and using MCUboot with RIOT
2
3MCUboot began its life as the bootloader for Mynewt. It has since
4acquired the ability to be used as a bootloader for RIOT as well.
5Currently the support is limited to the nrf52dk platform.
6
7## Building the bootloader itself
8
9In this first version, a prebuilt Mynewt binary is downloaded at
10compile time. This binary was compiled to do an integrity check, but
11not a signature check. In order to configure the bootloader for
12signature check it is necessary to re-compile it either with Mynewt
13or Zephyr, following the provided instructions.
14
15In the next version, it is planned to compile MCUboot using RIOT,
16which should be able to boot any of the supported OS images.
17
18## Building applications for the bootloader
19
20A compatible MCUboot image can be compiled by typing: `make mcuboot`.
21
22The only variable which needs to be set is `IMAGE_VERSION` loaded
23with a valid formatted value. The format is `major.minor.patch+other`
24(e.g. `export IMAGE_VERSION= 1.1.1+1`. This variable can be either
25exported in the Makefile or manually, prior to the compilation process.
26
27The goal is to produce an ELF file which is linked to be flashed at a
28`BOOTLOADER_OFFSET` offset rather than the beginning of ROM. MCUboot
29also expects an image padded with some specific headers containing the
30version information, and trailer type-length-value records (TLVs) with
31hash and signing information. This is done through the imgtool.py
32application, which is executed automatically by the RIOT build system.
33
34### Signing the application
35
36The application will be automatically signed with the provided key.
37If no key is provided, a new key will be automatically generated. The
38default key type is RSA-2048.
39
40In order to use your provided key, you need to recompile the bootloader
41using you public key, either in Zephyr or Mynewt by following the
42provided procedure for the selected OS.
43
44### Flashing the application
45
46The application can be flashed by typing: `make flash-mcuboot`.
47This will flash both the bootloader and the application.
48
readme-zephyr.md
1# Building and using MCUboot with Zephyr
2
3MCUboot began its life as the bootloader for Mynewt. It has since
4acquired the ability to be used as a bootloader for Zephyr as well.
5There are some pretty significant differences in how apps are built
6for Zephyr, and these are documented here.
7
8Please see the [design document](design.md) for documentation on the design
9and operation of the bootloader itself. This functionality should be the same
10on all supported RTOSs.
11
12The first step required for Zephyr is making sure your board has flash
13partitions defined in its device tree. These partitions are:
14
15- `boot_partition`: for MCUboot itself
16- `slot0_partition`: the primary slot of Image 0
17- `slot1_partition`: the secondary slot of Image 0
18
19It is not recommended to use the swap-using-scratch algorithm of MCUboot, but
20if this operating mode is desired then the following flash partition is also
21needed (see end of this help file for details on creating a scratch partition
22and how to use the swap-using-scratch algorithm):
23
24- `scratch_partition`: the scratch slot
25
26Currently, the two image slots must be contiguous. If you are running
27MCUboot as your stage 1 bootloader, `boot_partition` must be configured
28so your SoC runs it out of reset. If there are multiple updateable images
29then the corresponding primary and secondary partitions must be defined for
30the rest of the images too (for example, `slot2_partition` and
31`slot3_partition` for Image 1).
32
33The flash partitions are typically defined in the Zephyr boards folder, in a
34file named `boards/<arch>/<board>/<board>.dts`. An example `.dts` file with
35flash partitions defined is the frdm_k64f's in
36`boards/arm/frdm_k64f/frdm_k64f.dts`. Make sure the DT node labels in your board's
37`.dts` file match the ones used there.
38
39## Installing requirements and dependencies
40
41Install additional packages required for development with MCUboot:
42
43```
44 cd ~/mcuboot # or to your directory where MCUboot is cloned
45 pip3 install --user -r scripts/requirements.txt
46```
47
48## Building the bootloader itself
49
50The bootloader is an ordinary Zephyr application, at least from
51Zephyr's point of view. There is a bit of configuration that needs to
52be made before building it. Most of this can be done as documented in
53the `CMakeLists.txt` file in boot/zephyr. There are comments there for
54guidance. It is important to select a signature algorithm, and decide
55if the primary slot should be validated on every boot.
56
57To build MCUboot, create a build directory in boot/zephyr, and build
58it as usual:
59
60```
61 cd boot/zephyr
62 west build -b <board>
63```
64
65In addition to the partitions defined in DTS, some additional
66information about the flash layout is currently required to build
67MCUboot itself. All the needed configuration is collected in
68`boot/zephyr/include/target.h`. Depending on the board, this information
69may come from board-specific headers, Device Tree, or be configured by
70MCUboot on a per-SoC family basis.
71
72After building the bootloader, the binaries should reside in
73`build/zephyr/zephyr.{bin,hex,elf}`, where `build` is the build
74directory you chose when running `west build`. Use `west flash`
75to flash these binaries from the build directory. Depending
76on the target and flash tool used, this might erase the whole of the flash
77memory (mass erase) or only the sectors where the bootloader resides prior to
78programming the bootloader image itself.
79
80## Building applications for the bootloader
81
82In addition to flash partitions in DTS, some additional configuration
83is required to build applications for MCUboot.
84
85This is handled internally by the Zephyr configuration system and is wrapped
86in the `CONFIG_BOOTLOADER_MCUBOOT` Kconfig variable, which must be enabled in
87the application's `prj.conf` file.
88
89The directory `samples/zephyr/hello-world` in the MCUboot tree contains
90a simple application with everything you need. You can try it on your
91board and then just make a copy of it to get started on your own
92application; see samples/zephyr/README.md for a tutorial.
93
94The Zephyr `CONFIG_BOOTLOADER_MCUBOOT` configuration option
95[documentation](http://docs.zephyrproject.org/reference/kconfig/CONFIG_BOOTLOADER_MCUBOOT.html)
96provides additional details regarding the changes it makes to the image
97placement and generation in order for an application to be bootable by
98MCUboot.
99
100With this, build the application as your normally would.
101
102### Signing the application
103
104In order to upgrade to an image (or even boot it, if
105`MCUBOOT_VALIDATE_PRIMARY_SLOT` is enabled), the images must be signed.
106To make development easier, MCUboot is distributed with some example
107keys. It is important to stress that these should never be used for
108production, since the private key is publicly available in this
109repository. See below on how to make your own signatures.
110
111Images can be signed with the `scripts/imgtool.py` script. It is best
112to look at `samples/zephyr/Makefile` for examples on how to use this.
113
114### Flashing the application
115
116The application itself can flashed with regular flash tools, but will
117need to be programmed at the offset of the primary slot for this particular
118target. Depending on the platform and flash tool you might need to manually
119specify a flash offset corresponding to the primary slot starting address. This
120is usually not relevant for flash tools that use Intel Hex images (.hex) instead
121of raw binary images (.bin) since the former include destination address
122information. Additionally you will need to make sure that the flash tool does
123not perform a mass erase (erasing the whole of the flash) or else you would be
124deleting MCUboot.
125These images can also be marked for upgrade, and loaded into the secondary slot,
126at which point the bootloader should perform an upgrade. It is up to
127the image to mark the primary slot as "image ok" before the next reboot,
128otherwise the bootloader will revert the application.
129
130## Managing signing keys
131
132The signing keys used by MCUboot are represented in standard formats,
133and can be generated and processed using conventional tools. However,
134`scripts/imgtool.py` is able to generate key pairs in all of the
135supported formats. See [the docs](imgtool.md) for more details on
136this tool.
137
138### Generating a new keypair
139
140Generating a keypair with imgtool is a matter of running the keygen
141subcommand:
142
143```
144 $ ./scripts/imgtool.py keygen -k mykey.pem -t rsa-2048
145```
146
147The argument to `-t` should be the desired key type. See the
148[the docs](imgtool.md) for more details on the possible key types.
149
150### Extracting the public key
151
152The generated keypair above contains both the public and the private
153key. It is necessary to extract the public key and insert it into the
154bootloader. Use the ``CONFIG_BOOT_SIGNATURE_KEY_FILE`` Kconfig option to
155provide the path to the key file so the build system can extract
156the public key in a format usable by the C compiler.
157The generated public key is saved in `build/zephyr/autogen-pubkey.h`, which is included
158by the `boot/zephyr/keys.c`.
159
160Currently, the Zephyr RTOS port limits its support to one keypair at the time,
161although MCUboot's key management infrastructure supports multiple keypairs.
162
163Once MCUboot is built, this new keypair file (`mykey.pem` in this
164example) can be used to sign images.
165
166## Using swap-using-scratch flash algorithm
167
168To use the swap-using-scratch flash algorithm, a scratch partition needs to be
169present for the target board which is used for holding the data being swapped
170from both slots, this section must be at least as big as the largest sector
171size of the 2 partitions (e.g. if a device has a primary slot in main flash
172with a sector size of 512 bytes and secondar slot in external off-chip flash
173with a sector size of 4KB then the scratch area must be at least 4KB in size).
174The number of sectors must also be evenly divisable by this sector size, e.g.
1754KB, 8KB, 12KB, 16KB are allowed, 7KB, 7.5KB are not. This scratch partition
176needs adding to the .dts file for the board, e.g. for the nrf52dk_nrf52832
177board thus would involve updating
178`<zephyr>/boards/arm/nrf52dk_nrf52832/nrf52dk_nrf52832.dts` with:
179
180```
181 boot_partition: partition@0 {
182 label = "mcuboot";
183 reg = <0x00000000 0xc000>;
184 };
185 slot0_partition: partition@c000 {
186 label = "image-0";
187 reg = <0x0000C000 0x37000>;
188 };
189 slot1_partition: partition@43000 {
190 label = "image-1";
191 reg = <0x00043000 0x37000>;
192 };
193 storage_partition: partition@7a000 {
194 label = "storage";
195 reg = <0x0007a000 0x00006000>;
196 };
197```
198
199Which would make the application size 220KB and scratch size 24KB (the nRF52832
200has a 4KB sector size so the size of the scratch partition can be reduced at
201the cost of vastly reducing flash lifespan, e.g. for a 32KB firmware update
202with an 8KB scratch area, the scratch area would be erased and programmed 8
203times per image upgrade/revert). To configure MCUboot to work in
204swap-using-scratch mode, the Kconfig value must be set when building it:
205`CONFIG_BOOT_SWAP_USING_SCRATCH=y`.
206
207Note that it is possible for an application to get into a stuck state when
208swap-using-scratch is used whereby an application has loaded a firmware update
209and marked it as test/confirmed but MCUboot will not swap the images and
210erasing the secondary slot from the zephyr application returns an error
211because the slot is marked for upgrade.
212
213## Serial recovery
214
215### Interface selection
216
217A serial recovery protocol is available over either a hardware serial port or a USB CDC ACM virtual serial port.
218The SMP server implementation can be enabled by the ``CONFIG_MCUBOOT_SERIAL=y`` Kconfig option.
219To set a type of an interface, use the ``BOOT_SERIAL_DEVICE`` Kconfig choice, and select either the ``CONFIG_BOOT_SERIAL_UART`` or the ``CONFIG_BOOT_SERIAL_CDC_ACM`` value.
220Which interface belongs to the protocol shall be set by the devicetree-chosen node:
221- `zephyr,console` - If a hardware serial port is used.
222- `zephyr,cdc-acm-uart` - If a virtual serial port is used.
223
224### Entering the serial recovery mode
225
226To enter the serial recovery mode, the device has to initiate rebooting, and a triggering event has to occur (for example, pressing a button).
227
228By default, the serial recovery GPIO pin active state enters the serial recovery mode.
229Use the ``mcuboot_button0`` devicetree button alias to assign the GPIO pin to the MCUboot.
230
231Alternatively, MCUboot can wait for a limited time to check if DFU is invoked by receiving an MCUmgr command.
232Select ``CONFIG_BOOT_SERIAL_WAIT_FOR_DFU=y`` to use this mode. ``CONFIG_BOOT_SERIAL_WAIT_FOR_DFU_TIMEOUT`` option defines
233the amount of time in milliseconds the device will wait for the trigger.
234
235### Direct image upload
236
237By default, the SMP server implementation will only use the first slot.
238To change it, invoke the `image upload` MCUmgr command with a selected image number, and make sure the ``CONFIG_MCUBOOT_SERIAL_DIRECT_IMAGE_UPLOAD=y`` Kconfig option is enabled.
239Note that the ``CONFIG_UPDATEABLE_IMAGE_NUMBER`` Kconfig option adjusts the number of image-pairs supported by the MCUboot.
240
241The mapping of image number to partition is as follows:
242* 0 and 1 - image-0, the primary slot of the first image.
243* 2 - image-1, the secondary slot of the first image.
244* 3 - image-2.
245* 4 - image-3.
246
2470 is a default upload target when no explicit selection is done.
248
249### System-specific commands
250
251Use the ``CONFIG_ENABLE_MGMT_PERUSER=y`` Kconfig option to enable the following additional commands:
252* Storage erase - This command allows erasing the storage partition (enable with ``CONFIG_BOOT_MGMT_CUSTOM_STORAGE_ERASE=y``).
253* Custom image list - This command allows fetching version and installation status (custom properties) for all images (enable with ``CONFIG_BOOT_MGMT_CUSTOM_IMG_LIST=y``).
254
255### In-place image decryption
256
257Images uploaded by the serial recovery can be decrypted on the fly by using ECIES primitives described in the [ECIES encryption](encrypted_images.md#ecies-encryption) section.
258
259Enable support for this feature by using ``CONFIG_BOOT_SERIAL_ENCRYPT_EC256=y``.
260
261### More configuration
262
263For details on other available configuration options for the serial recovery protocol, check the Kconfig options (for example by using ``menuconfig``).
264