ESP32 ECO3 and later versions
of the chip support Secure Boot V1 and Secure Boot V2. It is recommended to use Secure Boot V2 when working with the ESP32 ECO3
version chip. This document records the implementation of enabling Secure Boot V2 on the ESP32 ECO3 chip using the Flash Download Tool.
Products that Support Secure Boot V2
Product | Secure Boot Version |
---|---|
ESP32 ECO V3 and above versions | Secure Boot V1 & Secure Boot V2 ( RSA-PSS) |
ESP32-S2 All versions | Secure Boot V2 ( RSA-PSS) |
ESP32-S3 All versions | Secure Boot V2 ( RSA-PSS) |
ESP32-C2 All versions | Secure Boot V2 ( ECDSA) |
ESP32-C3 ECO V3 and above versions | Secure Boot V2 ( RSA-PSS) |
ESP32-C6 All versions | Secure Boot V2 (RSA-PSS or ECDSA) |
ESP32-H2 All versions | Secure Boot V2 (RSA-PSS or ECDSA) |
Overview of Secure Boot V2
Enabling Secure Boot V2 on the ESP32 ECO V3 chip requires users to add a private key
for Secure Boot V2 signatures. Secure Boot V2 on ESP32 requires the use of a private key
of the rsa3072 type.
How to Generate a private key
for Secure Boot V2 Signature
- Generate the Secure Boot V2 signature private key using the esptool with the following command:
espsecure.py generate_signing_key secure_boot_signing_key.pem --version 2 --scheme rsa3072
secure_boot_signing_key.pem
is the generatedkey file
which can custom name.--version 2
selects theSecure Boot V2
version.--scheme rsa3072
select the type of key.
- Alternatively, you can also install the OpenSSL environment and generate an RSA 3072 type private key for Secure Boot signing with the following command:
openssl genrsa -out my_secure_boot_signing_key.pem 3072
When signing firmware with the Secure Boot V2 private key
, a public key
and a digest of the public key
will be generated based on the Secure Boot V2 private key
.
-
The
public key
anda digest of the public key
will be saved in thesignature block
, which is written at the end of thebootloader.bin
andapp.bin
firmware, i.e., Secure Boot V2 only signs thebootloader.bin
andapp.bin
firmware. -
After enabling the Secure Boot V2 feature, upon firmware startup, it will check if the second-stage-bootloader (
bootloader.bin
) is signed. Then, the signed second-stage-bootloader (bootloader.bin
) will be used to verify the signedapp.bin
. If the verification passes, the firmware will start normally.
If you are using the ESP32 ECO3
version chip and wish to enable the Secure Boot V2 feature, from the perspective of mass production environment, we recommend using the Flash Download Tool (version V3.9.6 or above) to complete the Flash Download Tool process.
The implementation process for completing the Secure Boot V2 feature using the Flash Download Tool are as follows:
- Import the
digest of the public key
based on the Flash Download Tool . - Directly write the
digest of the public key
into the chip’seFuse BLOCK2
during the firmware download process. - Simultaneously write the eFuse control bit (
ABS_DONE_1
) to enable theSecure Boot V2
feature. - Flash the
signed firmware
that enables the Secure Boot V2 feature.
Utilizing the Flash Download Tool to complete the Secure Boot V2 feature offers the following advantages on the operational steps :
- Once the firmware download is completed, the entire Secure Boot V2 process is also finished.
- It mitigates the risks associated with
power outages
orunstable power supply
during the Secure Boot V2 process.
The implementation process for completing Secure Boot V2 using the Flash Download Tool are as follows:
1. Software Configuration
-
Generate the Secure Boot V2
private key
in the esp-idf SDK build environment with the following command, see: Enable Secure Boot V2 Externallyespsecure.py generate_signing_key secure_boot_signing_key.pem --version 2 --scheme rsa3072
-
Generate a digest of the
private key
for Secure Boot V2 , see: Enable Secure Boot V2 Externallyespsecure.py digest_rsa_public_key --keyfile secure_boot_signing_key.pem --output public_key_digest.bin
-
In software configuration, set the chip version to ECO3 version . As follows:
→ Component config → Hardware Settings → Chip revision → Minimum Supported ESP32 Revision
-
You need to enable
Secure Boot V2
on the software configuration and specify the path to theprivate key
file.
-
At the same time, please pay attention to the setting of
UART ROM download mode
. If you do not want to disable the download mode, it is recommended to selectUART ROM download mode (Enabled (not recommended))
mode.→ Security features → UART ROM download mode
-
Since the Secure Boot V2 feature will increase the size of the bootloader firmware, you need to increase the partition table offset setting. As follows:
Default is
0x8000
, which can be increased to0xF000
.idf.py menuconfig —> Partition Table
2. Compile the Project to Obtain Firmware
-
Compile the current project using the following command:
idf.py build
-
After compilation, the following firmware will be generated:
- Unsigned
bootloader-unsigned.bin
- Unsigned
blink-unsinged.bin
- Unsigned
partition-table.bin
- Signed
bootloader.bin
- Signed
blink.bin
As follows:
- The firmware files can be found in the local path:
- Unsigned
-
Through the compilation completion log, you can see the firmware download address . As follows:
0x1000
: bootloader.bin
0xf000
: partition-table.bin
0x20000
: blink.binYou need to download the signed
bootloader.bin
andblink.bin
.
3. Flash Download Tool Configuration
-
In the
configure\esp32\security.conf
configuration file of the Flash Download Tool , enable theSecure Boot V2
configuration option . As follows:[SECURE BOOT] secure_boot_en = True secure_boot_version = 2 public_key_digest_path = .\bin\public_key_digest.bin
public_key_digest_path = .\bin\public_key_digest.bin
is specifies the digest of the Secure Boot V2 public key.Note: This path (
.\bin\public_key_digest.bin
) is based on the current path of the Flash Download Tool . -
Place the
digest of public key
in thebin
folder of the Flash Download Tool .
4. Restart the Flash Download Tool
After re-starting the Flash Download Tool, it will read the information from the configure\esp32\security.conf
configuration file. As follows:
5. Import Firmware to Be Downloaded
According to different partitions, add the firmware to be downloaded and set the corresponding download address . As follows:
Do not support directly importing the
combined firmware
bootloader.bin
andblink.bin
are signed firmware.
6. Flash Firmware
During the download process, the digest of the public key
will be written to the chip’s eFuse BLOCK2
, and the corresponding Secure Boot V2
eFuse control bit (ABS_DONE_1
) will be enabled. As follows:
test offset : 61440 0xf000
case ok
test offset : 131072 0x20000
case ok
..
Uploading stub...
Running stub...
Stub running...
Changing baud rate to 115200
Changed.
NO XMC flash detected!
FLASH_CRYPT_CNT 0
ABS_DONE_0 False
ESP32 secure boot v2 skip generate key
burn secure key ...
Burn keys to blocks:
- BLOCK2 -> [bf f7 73 1f b7 3c 4c 38 bc f7 68 f1 c6 8f 8e 2a d5 14 7d b6 78 b4 7d b9 9f 37 e8 5d 4f 86 68 78]
Disabling write to key block
Burn keys in efuse blocks.
The key block will be read and write protected
Check all blocks for burn...
idx, BLOCK_NAME, Conclusion
[00] BLOCK0 is not empty
(written ): 0x0000000400100000000004310000a20000af94e68629432c00000000
(to write): 0x00000000000000000000000000000000000000000000000000000100
(coding scheme = NONE)
[02] BLOCK2 is empty, will burn the new value
.
This is an irreversible operation!
BURN BLOCK2 - OK (write block == read block)
BURN BLOCK0 - OK (all write block bits are set)
Reading updated efuses...
Successful
The efuses to burn:
from BLOCK0
- ABS_DONE_1
Burning efuses:
- 'ABS_DONE_1' (Secure boot V2 is enabled for bootloader image) 0b0 -> 0b1
Check all blocks for burn...
idx, BLOCK_NAME, Conclusion
[00] BLOCK0 is not empty
(written ): 0x0000000400100000000004310000a20000af94e68629432c00000100
(to write): 0x00000020000000000000000000000000000000000000000000000000
(coding scheme = NONE)
.
This is an irreversible operation!
BURN BLOCK0 - OK (all write block bits are set)
Reading updated efuses...
Checking efuses...
Successful
Compressed 45056 bytes to 25294...
Compressed 3072 bytes to 104...
Compressed 200704 bytes to 104344...
is stub and send flash finish
After the firmware is downloaded, the entire Secure Boot V2 process is completed.
7. Running the Firmware
Upon the first power-up startup, the firmware will:
- Check if the Secure Boot V2 feature is enabled
- Then, verify the signed firmware
- If the verification succeeds, the firmware will run normally
The running log as follows:
ets Jul 29 2019 12:21:46
rst:0x1 (POWERON_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:2, clock div:2
secure boot v2 enabled
secure boot verification succeeded
load:0x3fff00b8 len:0x32ac
load:0x40078000 len:0x5afc
load:0x40080400 len:0x4
0x40080400: _init at ??:?
load:0x40080404 len:0xf24
entry 0x4008064c
I (56) boot: ESP-IDF v5.1.2-dirty 2nd stage bootloader
I (56) boot: compile time Mar 27 2024 16:41:29
I (56) boot: Multicore bootloader
I (60) boot: chip revision: v3.0
I (64) boot.esp32: SPI Speed : 40MHz
I (69) boot.esp32: SPI Mode : DIO
I (73) boot.esp32: SPI Flash Size : 2MB
I (78) boot: Enabling RNG early entropy source...
I (83) boot: Partition Table:
I (87) boot: ## Label Usage Type ST Offset Length
I (94) boot: 0 nvs WiFi data 01 02 00010000 00006000
I (102) boot: 1 phy_init RF data 01 01 00016000 00001000
I (109) boot: 2 factory factory app 00 00 00020000 00100000
I (117) boot: End of partition table
I (121) esp_image: segment 0: paddr=00020020 vaddr=3f400020 size=09d90h ( 40336) map
I (144) esp_image: segment 1: paddr=00029db8 vaddr=3ffb0000 size=02070h ( 8304) load
I (148) esp_image: segment 2: paddr=0002be30 vaddr=40080000 size=041e8h ( 16872) load
I (157) esp_image: segment 3: paddr=00030020 vaddr=400d0020 size=15910h ( 88336) map
I (190) esp_image: segment 4: paddr=00045938 vaddr=400841e8 size=07bach ( 31660) load
I (204) esp_image: segment 5: paddr=0004d4ec vaddr=00000000 size=02ae4h ( 10980)
I (208) esp_image: Verifying image signature...
I (208) secure_boot_v2: Verifying with RSA-PSS...
I (215) secure_boot_v2: Signature verified successfully!
I (223) boot: Loaded app from partition at offset 0x20000
I (223) secure_boot_v2: enabling secure boot v2...
I (229) secure_boot_v2: secure boot v2 is already enabled, continuing..
I (236) boot: Disabling RNG early entropy source...
I (253) cpu_start: Multicore app
I (253) cpu_start: Pro cpu up.
I (253) cpu_start: Starting app cpu, entry point is 0x400810b8
0x400810b8: call_start_cpu1 at E:/esp/Espressif/frameworks/esp-idf-v5.1.2/components/esp_system/port/cpu_start.c:157
I (0) cpu_start: App cpu up.
I (271) cpu_start: Pro cpu start user code
I (271) cpu_start: cpu freq: 160000000 Hz
I (271) cpu_start: Application information:
I (276) cpu_start: Project name: blink
I (280) cpu_start: App version: v5.1.2-dirty
I (286) cpu_start: Compile time: Mar 27 2024 16:41:11
I (292) cpu_start: ELF file SHA256: 51a4c7d0b141e070...
I (298) cpu_start: ESP-IDF: v5.1.2-dirty
I (303) cpu_start: Min chip rev: v3.0
I (308) cpu_start: Max chip rev: v3.99
I (313) cpu_start: Chip rev: v3.0
I (318) heap_init: Initializing. RAM available for dynamic allocation:
I (325) heap_init: At 3FFAE6E0 len 00001920 (6 KiB): DRAM
I (331) heap_init: At 3FFB2968 len 0002D698 (181 KiB): DRAM
I (337) heap_init: At 3FFE0440 len 00003AE0 (14 KiB): D/IRAM
I (343) heap_init: At 3FFE4350 len 0001BCB0 (111 KiB): D/IRAM
I (350) heap_init: At 4008BD94 len 0001426C (80 KiB): IRAM
I (357) spi_flash: detected chip: generic
I (361) spi_flash: flash io: dio
W (365) spi_flash: Detected size(4096k) larger than the size in the binary image header(2048k). Using the size in the binary image header.
I (379) app_start: Starting scheduler on CPU0
I (383) app_start: Starting scheduler on CPU1
I (383) main_task: Started on CPU0
I (393) main_task: Calling app_main()
I (393) example: Example configured to blink GPIO LED!
I (393) gpio: GPIO[5]| InputEn: 0| OutputEn: 0| OpenDrain: 0| Pullup: 1| Pulldown: 0| Intr:0
I (403) example: Turning the LED OFF!
I (1413) example: Turning the LED ON!
I (2413) example: Turning the LED OFF!
I (3413) example: Turning the LED ON!
8. Check the chip’s eFuse informations
Use the esptool to run the following command to get the eFuse informations of the chip
espefuse.py -p COM4 summary
- The chip‘s security informations are as follows:
Security fuses:
UART_DOWNLOAD_DIS (BLOCK0) Disable UART download mode. Valid for ESP32 V3 and = False R/W (0b0)
newer; only
ABS_DONE_0 (BLOCK0) Secure boot V1 is enabled for bootloader image = False R/W (0b0)
ABS_DONE_1 (BLOCK0) Secure boot V2 is enabled for bootloader image = True R/W (0b1)
DISABLE_DL_ENCRYPT (BLOCK0) Disable flash encryption in UART bootloader = False R/W (0b0)
DISABLE_DL_DECRYPT (BLOCK0) Disable flash decryption in UART bootloader = False R/W (0b0)
KEY_STATUS (BLOCK0) Usage of efuse block 3 (reserved) = False R/W (0b0)
SECURE_VERSION (BLOCK3) Secure version for anti-rollback = 0 R/W (0x00000000)
BLOCK1 (BLOCK1) Flash encryption key
= 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 R/W
BLOCK2 (BLOCK2) Security boot key
= bf f7 73 1f b7 3c 4c 38 bc f7 68 f1 c6 8f 8e 2a d5 14 7d b6 78 b4 7d b9 9f 37 e8 5d 4f 86 68 78 R/-
BLOCK3 (BLOCK3) Variable Block 3
= 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 R/W
Instructions
- After enabling the Secure Boot V2 feature, the chip’s eFuse informations can be read.
- As long as the download mode is not disabled in the software configuration, it is also possible to re-flash the firmware.
- The re-downloaded firmware must be signed with the same private key for Secure Boot V2 .
- When implementing OTA (Over The Air Updates) applications, the OTA firmware must be signed with the same private key for Secure Boot V2 .