本篇文档用来说明 ESP32 ECO3 芯片同时使能 Secure Boot V2 和 flash 加密的操作流程,其中,flash 加密使用发布模式(Release Mode),使用主机生成的密钥对数据进行加密。
IDF 版本:v4.4-rc1
测试设备:ESP32-WROOM-32E
测试例程:examples/system/ota/simple_ota_example
$ espefuse.py --chip esp32 summary
Connecting....
espefuse.py v3.2-dev
EFUSE_NAME (Block) Description = [Meaningful Value] [Readable/Writeable] (Hex Value)
----------------------------------------------------------------------------------------
Calibration fuses:
BLK3_PART_RESERVE (BLOCK0): BLOCK3 partially served for ADC calibration data = False R/W (0b0)
ADC_VREF (BLOCK0): Voltage reference calibration = 1072 R/W (0b10100)
Config fuses:
XPD_SDIO_FORCE (BLOCK0): Ignore MTDI pin (GPIO12) for VDD_SDIO on reset = False R/W (0b0)
XPD_SDIO_REG (BLOCK0): If XPD_SDIO_FORCE, enable VDD_SDIO reg on reset = False R/W (0b0)
XPD_SDIO_TIEH (BLOCK0): If XPD_SDIO_FORCE & XPD_SDIO_REG = 1.8V R/W (0b0)
CLK8M_FREQ (BLOCK0): 8MHz clock freq override = 53 R/W (0x35)
SPI_PAD_CONFIG_CLK (BLOCK0): Override SD_CLK pad (GPIO6/SPICLK) = 0 R/W (0b00000)
SPI_PAD_CONFIG_Q (BLOCK0): Override SD_DATA_0 pad (GPIO7/SPIQ) = 0 R/W (0b00000)
SPI_PAD_CONFIG_D (BLOCK0): Override SD_DATA_1 pad (GPIO8/SPID) = 0 R/W (0b00000)
SPI_PAD_CONFIG_HD (BLOCK0): Override SD_DATA_2 pad (GPIO9/SPIHD) = 0 R/W (0b00000)
SPI_PAD_CONFIG_CS0 (BLOCK0): Override SD_CMD pad (GPIO11/SPICS0) = 0 R/W (0b00000)
DISABLE_SDIO_HOST (BLOCK0): Disable SDIO host = False R/W (0b0)
Efuse fuses:
WR_DIS (BLOCK0): Efuse write disable mask = 0 R/W (0x0000)
RD_DIS (BLOCK0): Efuse read disable mask = 0 R/W (0x0)
CODING_SCHEME (BLOCK0): Efuse variable block length scheme
= NONE (BLK1-3 len=256 bits) R/W (0b00)
KEY_STATUS (BLOCK0): Usage of efuse block 3 (reserved) = False R/W (0b0)
Identity fuses:
MAC (BLOCK0): Factory MAC Address
= e8:9f:6d:d7:94:34 (CRC 0x19 OK) R/W
MAC_CRC (BLOCK0): CRC8 for factory MAC address = 25 R/W (0x19)
CHIP_VER_REV1 (BLOCK0): Silicon Revision 1 = True R/W (0b1)
CHIP_VER_REV2 (BLOCK0): Silicon Revision 2 = True R/W (0b1)
CHIP_VERSION (BLOCK0): Reserved for future chip versions = 2 R/W (0b10)
CHIP_PACKAGE (BLOCK0): Chip package identifier = 1 R/W (0b001)
MAC_VERSION (BLOCK3): Version of the MAC field = 0 R/W (0x00)
Security fuses:
FLASH_CRYPT_CNT (BLOCK0): Flash encryption mode counter = 0 R/W (0b0000000)
UART_DOWNLOAD_DIS (BLOCK0): Disable UART download mode (ESP32 rev3 only) = False R/W (0b0)
FLASH_CRYPT_CONFIG (BLOCK0): Flash encryption config (key tweak bits) = 0 R/W (0x0)
CONSOLE_DEBUG_DISABLE (BLOCK0): Disable ROM BASIC interpreter fallback = True R/W (0b1)
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 = False R/W (0b0)
JTAG_DISABLE (BLOCK0): Disable JTAG = False R/W (0b0)
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)
DISABLE_DL_CACHE (BLOCK0): Disable flash cache in UART bootloader = False R/W (0b0)
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): Secure boot 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
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
Flash voltage (VDD_SDIO) determined by GPIO12 on reset (High for 1.8V, Low/NC for 3.3V).
配置路径:(Top) -> Component config -> ESP32-specific -> Minimum Supported ESP32 Revision (Rev 3)
使能 flash 加密以及 Secure Boot V2 后,生成的 bootloader bin 会变大,可以通过调整分区表地址增大 bootloader 分区大小,本例中将分区表偏移量从默认的 0x8000 调整到 0xF000,这样 bootloader 分区的大小为 0xF000 - 0x1000 = 0xE000(0x1000 为 bootloader bin 烧录地址),可以参考引导加载程序大小。
配置路径:(Top) -> Partition Table -> (0xf000) Offset of partition table
本例中,Secure Boot 版本为 v2,flash 加密模式为 Release 模式。
相关配置路径如下:
secure boot v2:
(Top) -> Security features -> [*] Enable hardware Secure Boot in bootloader (READ DOCS FIRST)
(Top) -> Security features -> [*] Enable hardware Secure Boot in bootloader (READ DOCS FIRST) -> Select secure boot version (Enable Secure Boot version 2)
(Top) -> Security features -> [*] Sign binaries during build
flash 加密:
(Top) -> Security features -> [*] Enable flash encryption on boot (READ DOCS FIRST)
(Top) -> Security features -> Enable flash encryption on boot (READ DOCS FIRST) -> Enable usage mode (Release)
(Top) -> Security features -> UART ROM download mode (UART ROM download mode (Enabled (not recommended)))
补充说明:
如果使能
Sign binaries during build
, 将会在构建过程中对 app/partition bin 进行签名,Secure boot private signing key
中指定的文件将用于对 app/partition bin 进行签名。
如果该选项禁用,将会生成未签名的 app/partition bin,必须使用espsecure.py
手动签名。
可使用下面的命令手动签名:
espsecure.py sign_data --version 2 --keyfile ./my_signing_key.pem --output ./image_signed.bin image-unsigned.bin
可参考 Manual Commands
注意事项:
在量产过程中,建议将
UART ROM download mode
设置为Permanently disabled
(永久性禁用),以减少攻击者可用的选项。
参考官方文档说明:如果用户已经预先生成了 flash 加密密钥并存储了一个副本,并且 UART 下载模式没有通过 CONFIG_SECURE_UART_ROM_DL_MODE (ESP32 V3 only) 永久禁用,那么可以通过使用 espsecure.py encrypt_flash_data 预加密文件,从而在在本地更新 flash,然后烧录密文。
本例中为了以防操作不当从而导致损坏芯片,故选择使能。
测试过程中禁用 NVS 加密,配置路径:
(Top) -> Component config -> NVS -> [ ] Enable NVS encryption
,具体说明见常见问题。
可使用如下指令生成签名秘钥,参考 Generating Secure Boot Signing Key。
espsecure.py generate_signing_key --version 2 secure_boot_signing_key.pem
生成 secure-bootloader-key.bin,该 bin 文件为公钥的 SHA-256 摘要,参考 eFuse usage。
espsecure.py digest_rsa_public_key --keyfile secure_boot_signing_key.pem -o secure-bootloader-key.bin
烧录 secure-bootloader-key.bin:
espefuse.py burn_key secure_boot_v2 secure-bootloader-key.bin
烧录 ABS_DONE_1
,该 efuse 用于在启动时使能 secure boot v2 保护。
espefuse.py burn_efuse ABS_DONE_1
生成 flash 加密秘钥,该秘钥可用于对于明文数据进行加密:
espsecure.py generate_flash_encryption_key my_flash_encryption_key.bin
烧录 flash 加密秘钥:
python $IDF_PATH/components/esptool_py/esptool/espefuse.py burn_key flash_encryption my_flash_encryption_key.bin
flash 相关 efuse 烧录:
$ python $IDF_PATH/components/esptool_py/esptool/espefuse.py burn_efuse FLASH_CRYPT_CNT
$ python $IDF_PATH/components/esptool_py/esptool/espefuse.py burn_efuse FLASH_CRYPT_CONFIG 0xf
下面的 efuse 位说明可以参考启用 UART 引导加载程序加密/解密
$ python $IDF_PATH/components/esptool_py/esptool/espefuse.py burn_efuse DISABLE_DL_ENCRYPT
$ python $IDF_PATH/components/esptool_py/esptool/espefuse.py burn_efuse DISABLE_DL_DECRYPT
$ python $IDF_PATH/components/esptool_py/esptool/espefuse.py burn_efuse DISABLE_DL_CACHE
烧录完成后,查询 efuse 值如下:
$ espefuse.py --chip esp32 summary
Connecting....
espefuse.py v3.2-dev
EFUSE_NAME (Block) Description = [Meaningful Value] [Readable/Writeable] (Hex Value)
----------------------------------------------------------------------------------------
Calibration fuses:
BLK3_PART_RESERVE (BLOCK0): BLOCK3 partially served for ADC calibration data = False R/W (0b0)
ADC_VREF (BLOCK0): Voltage reference calibration = 1072 R/W (0b10100)
Config fuses:
XPD_SDIO_FORCE (BLOCK0): Ignore MTDI pin (GPIO12) for VDD_SDIO on reset = False R/W (0b0)
XPD_SDIO_REG (BLOCK0): If XPD_SDIO_FORCE, enable VDD_SDIO reg on reset = False R/W (0b0)
XPD_SDIO_TIEH (BLOCK0): If XPD_SDIO_FORCE & XPD_SDIO_REG = 1.8V R/W (0b0)
CLK8M_FREQ (BLOCK0): 8MHz clock freq override = 53 R/W (0x35)
SPI_PAD_CONFIG_CLK (BLOCK0): Override SD_CLK pad (GPIO6/SPICLK) = 0 R/W (0b00000)
SPI_PAD_CONFIG_Q (BLOCK0): Override SD_DATA_0 pad (GPIO7/SPIQ) = 0 R/W (0b00000)
SPI_PAD_CONFIG_D (BLOCK0): Override SD_DATA_1 pad (GPIO8/SPID) = 0 R/W (0b00000)
SPI_PAD_CONFIG_HD (BLOCK0): Override SD_DATA_2 pad (GPIO9/SPIHD) = 0 R/W (0b00000)
SPI_PAD_CONFIG_CS0 (BLOCK0): Override SD_CMD pad (GPIO11/SPICS0) = 0 R/W (0b00000)
DISABLE_SDIO_HOST (BLOCK0): Disable SDIO host = False R/W (0b0)
Efuse fuses:
WR_DIS (BLOCK0): Efuse write disable mask = 384 R/W (0x0180)
RD_DIS (BLOCK0): Efuse read disable mask = 1 R/W (0x1)
CODING_SCHEME (BLOCK0): Efuse variable block length scheme
= NONE (BLK1-3 len=256 bits) R/W (0b00)
KEY_STATUS (BLOCK0): Usage of efuse block 3 (reserved) = False R/W (0b0)
Identity fuses:
MAC (BLOCK0): Factory MAC Address
= e8:9f:6d:d7:94:34 (CRC 0x19 OK) R/W
MAC_CRC (BLOCK0): CRC8 for factory MAC address = 25 R/W (0x19)
CHIP_VER_REV1 (BLOCK0): Silicon Revision 1 = True R/W (0b1)
CHIP_VER_REV2 (BLOCK0): Silicon Revision 2 = True R/W (0b1)
CHIP_VERSION (BLOCK0): Reserved for future chip versions = 2 R/W (0b10)
CHIP_PACKAGE (BLOCK0): Chip package identifier = 1 R/W (0b001)
MAC_VERSION (BLOCK3): Version of the MAC field = 0 R/W (0x00)
Security fuses:
FLASH_CRYPT_CNT (BLOCK0): Flash encryption mode counter = 1 R/W (0b0000001)
UART_DOWNLOAD_DIS (BLOCK0): Disable UART download mode (ESP32 rev3 only) = False R/W (0b0)
FLASH_CRYPT_CONFIG (BLOCK0): Flash encryption config (key tweak bits) = 15 R/W (0xf)
CONSOLE_DEBUG_DISABLE (BLOCK0): Disable ROM BASIC interpreter fallback = True R/W (0b1)
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)
JTAG_DISABLE (BLOCK0): Disable JTAG = False R/W (0b0)
DISABLE_DL_ENCRYPT (BLOCK0): Disable flash encryption in UART bootloader = True R/W (0b1)
DISABLE_DL_DECRYPT (BLOCK0): Disable flash decryption in UART bootloader = True R/W (0b1)
DISABLE_DL_CACHE (BLOCK0): Disable flash cache in UART bootloader = True R/W (0b1)
BLOCK1 (BLOCK1): Flash encryption key
= ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? -/-
BLOCK2 (BLOCK2): Secure boot key
= ea b0 ba ca 3a 7f 44 99 03 e3 e8 7e 7c bc 17 a2 81 4c 3f 2b aa fd 23 00 ce 5f fc a3 8f df e2 1e 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
Flash voltage (VDD_SDIO) determined by GPIO12 on reset (High for 1.8V, Low/NC for 3.3V).
$ idf.py bootloader
对应的输出日志如下,生成签名后的 build/bootloader/bootloader.bin
。
==============================================================================
Bootloader built. Secure boot enabled, so bootloader not flashed automatically.
Secure boot enabled, so bootloader not flashed automatically.
/home/mali/.espressif/python_env/idf4.4_py3.8_env/bin/python /home/mali/esp/master-idf/components/esptool_py/esptool/esptool.py --chip esp32 --port=(PORT) --baud=(BAUD) --before=default_reset --after=no_reset write_flash --flash_mode dio --flash_freq 40m --flash_size 4MB 0x1000 /home/mali/esp/master-idf/examples/system/ota/simple_ota_example/build/bootloader/bootloader.bin
==============================================================================
[101/103] Generating binary image from built executable
esptool.py v3.2-dev
Merged 1 ELF section
Generated /home/mali/esp/master-idf/examples/system/ota/simple_ota_example/build/bootloader/bootloader.bin
[102/103] cd /home/mali/esp/master-idf/examples/system/ota/simple_ota_example/build/bootloader/esp-idf/esptool_py && /home/mali/.espressif/python_env/idf4.4_py3.8_env/bin/python /home/mali/esp/master-idf/components/partition_table/check_sizes.py --offset 0xf000 bootloader 0x1000 /home/mali/esp/master-idf/examples/system/ota/simple_ota_example/build/bootloader/bootloader.bin
Bootloader binary size 0xa230 bytes. 0x3dd0 bytes (28%) free.
[103/103] Generated the signed Bootloader
espsecure.py v3.2-dev
Padding data contents by 3536 bytes so signature sector aligns at sector boundary
1 signing key(s) found.
Signed 45056 bytes of data from /home/mali/esp/master-idf/examples/system/ota/simple_ota_example/build/bootloader/bootloader-unsigned.bin. Signature sector now has 1 signature blocks.
Generated signed binary image /home/mali/esp/master-idf/examples/system/ota/simple_ota_example/build/bootloader/bootloader.bin from /home/mali/esp/master-idf/examples/system/ota/simple_ota_example/build/bootloader/bootloader-unsigned.bin
[9/9] Completed 'bootloader'
Bootloader build complete.
$ idf.py build
对应的输出日志如下,生成 simple_ota.bin
(已签名)、partition-table.bin
和 ota_data_initial.bin
。
[1011/1013] Generating binary image from built executable
esptool.py v3.2-dev
Merged 25 ELF sections
Generated /home/mali/esp/master-idf/examples/system/ota/simple_ota_example/build/simple_ota-unsigned.bin
[1012/1013] Generating signed binary image
espsecure.py v3.2-dev
1 signing key(s) found.
Signed 851968 bytes of data from /home/mali/esp/master-idf/examples/system/ota/simple_ota_example/build/simple_ota-unsigned.bin. Signature sector now has 1 signature blocks.
Generated signed binary image /home/mali/esp/master-idf/examples/system/ota/simple_ota_example/build/simple_ota.bin from /home/mali/esp/master-idf/examples/system/ota/simple_ota_example/build/simple_ota-unsigned.bin
[1013/1013] cd /home/mali/esp/master-idf/examples/system/ota/simple_ota_example/build/esp-idf/esptool_...tition-table.bin /home/mali/esp/master-idf/examples/system/ota/simple_ota_example/build/simple_ota.bin
simple_ota.bin binary size 0xd1000 bytes. Smallest app partition is 0x100000 bytes. 0x2f000 bytes (18%) free.
Project build complete. To flash, run this command:
/home/mali/.espressif/python_env/idf4.4_py3.8_env/bin/python ../../../../components/esptool_py/esptool/esptool.py -p (PORT) -b 460800 --before default_reset --after no_reset --chip esp32 write_flash --flash_mode dio --flash_size keep --flash_freq 40m 0xf000 build/partition_table/partition-table.bin 0x14000 build/ota_data_initial.bin 0x20000 build/simple_ota.bin
or run 'idf.py -p (PORT) flash'
可以使用 idf.py partition-table
查询 app bin 文件的烧录地址:
本例中,输出如下:
Partition table binary generated. Contents:
*******************************************************************************
# ESP-IDF Partition Table
# Name, Type, SubType, Offset, Size, Flags
nvs,data,nvs,0x10000,16K,
otadata,data,ota,0x14000,8K,
phy_init,data,phy,0x16000,4K,
factory,app,factory,0x20000,1M,
ota_0,app,ota_0,0x120000,1M,
ota_1,app,ota_1,0x220000,1M,
*******************************************************************************
对 bootloader.bin 进行加密:
$ espsecure.py encrypt_flash_data --keyfile my_flash_encryption_key.bin --address 0x1000 -o build/bootloader/bootloader_encryped.bin build/bootloader/bootloader.bin
对 ota_data_initial.bin 进行加密:
$ espsecure.py encrypt_flash_data --keyfile my_flash_encryption_key.bin --address 0x14000 -o build/ota_data_initial_encrypted.bin build/ota_data_initial.bin
对 simple_ota.bin 进行加密:
$ espsecure.py encrypt_flash_data --keyfile my_flash_encryption_key.bin --address 0x20000 -o build/simple_ota_encrypted.bin build/simple_ota.bin
对 partition-table.bin 进行加密:
$ espsecure.py encrypt_flash_data --keyfile my_flash_encryption_key.bin --address 0xf000 -o build/partition_table/partition-table-encrypted.bin build/partition_table/partition-table.bin
$ esptool.py -b 921600 write_flash 0x1000 build/bootloader/bootloader_encryped.bin 0xf000 build/partition_table/partition-table-encrypted.bin 0x14000 build/ota_data_initial_encrypted.bin 0x20000 build/simple_ota_encrypted.bin
--- idf_monitor on /dev/ttyUSB0 115200 ---
--- Quit: Ctrl+] | Menu: Ctrl+T | Help: Ctrl+T followed by Ctrl+H ---
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:0x3fff0038 len:0x3664
load:0x40078000 len:0x5c34
load:0x40080400 len:0xed0
0x40080400: _init at ??:?
entry 0x40080694
I (57) boot: ESP-IDF v4.4-rc1-dirty 2nd stage bootloader
I (57) boot: compile time 19:20:31
I (57) boot: chip revision: 3
I (60) boot.esp32: SPI Speed : 40MHz
I (65) boot.esp32: SPI Mode : DIO
I (69) boot.esp32: SPI Flash Size : 4MB
I (74) boot: Enabling RNG early entropy source...
I (79) boot: Partition Table:
I (83) boot: ## Label Usage Type ST Offset Length
I (90) boot: 0 nvs WiFi data 01 02 00010000 00004000
I (98) boot: 1 otadata OTA data 01 00 00014000 00002000
I (105) boot: 2 phy_init RF data 01 01 00016000 00001000
I (113) boot: 3 factory factory app 00 00 00020000 00100000
I (120) boot: 4 ota_0 OTA app 00 10 00120000 00100000
I (128) boot: 5 ota_1 OTA app 00 11 00220000 00100000
I (135) boot: End of partition table
I (140) boot: Defaulting to factory image
I (144) esp_image: segment 0: paddr=00020020 vaddr=3f400020 size=1c128h (114984) map
I (196) esp_image: segment 1: paddr=0003c150 vaddr=3ffb0000 size=03780h ( 14208) load
I (202) esp_image: segment 2: paddr=0003f8d8 vaddr=40080000 size=00740h ( 1856) load
I (203) esp_image: segment 3: paddr=00040020 vaddr=400d0020 size=8f050h (585808) map
I (429) esp_image: segment 4: paddr=000cf078 vaddr=40080740 size=13a48h ( 80456) load
I (464) esp_image: segment 5: paddr=000e2ac8 vaddr=50000000 size=00010h ( 16) load
I (464) esp_image: segment 6: paddr=000e2ae0 vaddr=00000000 size=0d4f0h ( 54512)
I (489) esp_image: Verifying image signature...
I (490) secure_boot_v2: Verifying with RSA-PSS...
I (494) secure_boot_v2: Signature verified successfully!
I (505) boot: Loaded app from partition at offset 0x20000
I (505) secure_boot_v2: enabling secure boot v2...
I (506) secure_boot_v2: secure boot v2 is already enabled, continuing..
I (514) boot: Checking flash encryption...
I (518) flash_encrypt: flash encryption is enabled (0 plaintext flashes left)
I (526) boot: Disabling RNG early entropy source...
I (543) cpu_start: Pro cpu up.
I (543) cpu_start: Starting app cpu, entry point is 0x40081148
0x40081148: call_start_cpu1 at /home/mali/esp/master-idf/components/esp_system/port/cpu_start.c:156
I (0) cpu_start: App cpu up.
I (560) cpu_start: Pro cpu start user code
I (560) cpu_start: cpu freq: 160000000
I (560) cpu_start: Application information:
I (564) cpu_start: Project name: simple_ota
I (569) cpu_start: App version: v4.4-rc1-dirty
I (575) cpu_start: Compile time: Feb 1 2022 19:21:25
I (581) cpu_start: ELF file SHA256: 3558892d209a45c6...
I (587) cpu_start: ESP-IDF: v4.4-rc1-dirty
I (593) heap_init: Initializing. RAM available for dynamic allocation:
I (600) heap_init: At 3FFAE6E0 len 00001920 (6 KiB): DRAM
I (606) heap_init: At 3FFB7538 len 00028AC8 (162 KiB): DRAM
I (612) heap_init: At 3FFE0440 len 00003AE0 (14 KiB): D/IRAM
I (618) heap_init: At 3FFE4350 len 0001BCB0 (111 KiB): D/IRAM
I (625) heap_init: At 40094188 len 0000BE78 (47 KiB): IRAM
I (632) spi_flash: detected chip: generic
I (636) spi_flash: flash io: dio
I (640) flash_encrypt: Flash encryption mode is RELEASE
I (647) cpu_start: Starting scheduler on PRO CPU.
I (0) cpu_start: Starting scheduler on APP CPU.
I (757) simple_ota_example: SHA-256 for bootloader: e246cdf680a06d555681ad253fc7687812b3eca851fae5fdfd3746f01729b478
I (767) simple_ota_example: SHA-256 for current firmware: d205254da1034217040298677071cc0662d03d7d8be89f44d45c08ee33c6a715
I (787) wifi:wifi driver task: 3ffc02a0, prio:23, stack:6656, core=0
I (787) system_api: Base MAC address is not set
I (787) system_api: read default base MAC address from EFUSE
I (817) wifi:wifi firmware version: 7679c42
I (817) wifi:wifi certification version: v7.0
I (817) wifi:config NVS flash: enabled
I (817) wifi:config nano formating: disabled
I (817) wifi:Init data frame dynamic rx buffer num: 32
I (827) wifi:Init management frame dynamic rx buffer num: 32
I (827) wifi:Init management short buffer num: 32
I (837) wifi:Init dynamic tx buffer num: 32
I (837) wifi:Init static rx buffer size: 1600
I (837) wifi:Init static rx buffer num: 10
I (847) wifi:Init dynamic rx buffer num: 32
I (847) wifi_init: rx ba win: 6
I (847) wifi_init: tcpip mbox: 32
I (857) wifi_init: udp mbox: 6
I (857) wifi_init: tcp mbox: 6
I (867) wifi_init: tcp tx win: 5744
I (867) wifi_init: tcp rx win: 5744
I (867) wifi_init: tcp mss: 1440
I (877) wifi_init: WiFi IRAM OP enabled
I (877) wifi_init: WiFi RX IRAM OP enabled
设备第一次启动后,查询设备 efuse 值:
$ espefuse.py --chip esp32 summary
Connecting....
espefuse.py v3.2-dev
EFUSE_NAME (Block) Description = [Meaningful Value] [Readable/Writeable] (Hex Value)
----------------------------------------------------------------------------------------
Calibration fuses:
BLK3_PART_RESERVE (BLOCK0): BLOCK3 partially served for ADC calibration data = False R/W (0b0)
ADC_VREF (BLOCK0): Voltage reference calibration = 1072 R/W (0b10100)
Config fuses:
XPD_SDIO_FORCE (BLOCK0): Ignore MTDI pin (GPIO12) for VDD_SDIO on reset = False R/W (0b0)
XPD_SDIO_REG (BLOCK0): If XPD_SDIO_FORCE, enable VDD_SDIO reg on reset = False R/W (0b0)
XPD_SDIO_TIEH (BLOCK0): If XPD_SDIO_FORCE & XPD_SDIO_REG = 1.8V R/W (0b0)
CLK8M_FREQ (BLOCK0): 8MHz clock freq override = 53 R/W (0x35)
SPI_PAD_CONFIG_CLK (BLOCK0): Override SD_CLK pad (GPIO6/SPICLK) = 0 R/W (0b00000)
SPI_PAD_CONFIG_Q (BLOCK0): Override SD_DATA_0 pad (GPIO7/SPIQ) = 0 R/W (0b00000)
SPI_PAD_CONFIG_D (BLOCK0): Override SD_DATA_1 pad (GPIO8/SPID) = 0 R/W (0b00000)
SPI_PAD_CONFIG_HD (BLOCK0): Override SD_DATA_2 pad (GPIO9/SPIHD) = 0 R/W (0b00000)
SPI_PAD_CONFIG_CS0 (BLOCK0): Override SD_CMD pad (GPIO11/SPICS0) = 0 R/W (0b00000)
DISABLE_SDIO_HOST (BLOCK0): Disable SDIO host = False R/W (0b0)
Efuse fuses:
WR_DIS (BLOCK0): Efuse write disable mask = 388 R/W (0x0184)
RD_DIS (BLOCK0): Efuse read disable mask = 1 R/W (0x1)
CODING_SCHEME (BLOCK0): Efuse variable block length scheme
= NONE (BLK1-3 len=256 bits) R/W (0b00)
KEY_STATUS (BLOCK0): Usage of efuse block 3 (reserved) = False R/W (0b0)
Identity fuses:
MAC (BLOCK0): Factory MAC Address
= e8:9f:6d:d7:94:34 (CRC 0x19 OK) R/W
MAC_CRC (BLOCK0): CRC8 for factory MAC address = 25 R/W (0x19)
CHIP_VER_REV1 (BLOCK0): Silicon Revision 1 = True R/W (0b1)
CHIP_VER_REV2 (BLOCK0): Silicon Revision 2 = True R/W (0b1)
CHIP_VERSION (BLOCK0): Reserved for future chip versions = 2 R/W (0b10)
CHIP_PACKAGE (BLOCK0): Chip package identifier = 1 R/W (0b001)
MAC_VERSION (BLOCK3): Version of the MAC field = 0 R/W (0x00)
Security fuses:
FLASH_CRYPT_CNT (BLOCK0): Flash encryption mode counter = 1 R/- (0b0000001)
UART_DOWNLOAD_DIS (BLOCK0): Disable UART download mode (ESP32 rev3 only) = False R/- (0b0)
FLASH_CRYPT_CONFIG (BLOCK0): Flash encryption config (key tweak bits) = 15 R/W (0xf)
CONSOLE_DEBUG_DISABLE (BLOCK0): Disable ROM BASIC interpreter fallback = True R/W (0b1)
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)
JTAG_DISABLE (BLOCK0): Disable JTAG = False R/W (0b0)
DISABLE_DL_ENCRYPT (BLOCK0): Disable flash encryption in UART bootloader = True R/W (0b1)
DISABLE_DL_DECRYPT (BLOCK0): Disable flash decryption in UART bootloader = True R/W (0b1)
DISABLE_DL_CACHE (BLOCK0): Disable flash cache in UART bootloader = True R/W (0b1)
BLOCK1 (BLOCK1): Flash encryption key
= ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? -/-
BLOCK2 (BLOCK2): Secure boot key
= ea b0 ba ca 3a 7f 44 99 03 e3 e8 7e 7c bc 17 a2 81 4c 3f 2b aa fd 23 00 ce 5f fc a3 8f df e2 1e 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
Flash voltage (VDD_SDIO) determined by GPIO12 on reset (High for 1.8V, Low/NC for 3.3V).
发布模式会写保护 FLASH_CRYPT_CNT
eFuse 位,可以看到:FLASH_CRYPT_CNT
由 1 R/W (0b0000001)
变为 1 R/- (0b0000001)
。
1.设备启动后会出现如下报错,是什么原因?
I (638) flash_encrypt: Flash encryption mode is RELEASE
I (645) cpu_start: Starting scheduler on PRO CPU.
I (0) cpu_start: Starting scheduler on APP CPU.
E (655) nvs: CONFIG_NVS_ENCRYPTION is enabled, but no partition with subtype nvs_keys found in the partition table.
ESP_ERROR_CHECK failed: esp_err_t 0xffffffff (ESP_FAIL) at 0x40088204
0x40088204: _esp_error_check_failed at /home/mali/esp/master-idf/components/esp_system/esp_err.c:42
file: "../main/simple_ota_example.c" line 164
func: app_main
expression: err
abort() was called at PC 0x40088207 on core 0
0x40088207: _esp_error_check_failed at /home/mali/esp/master-idf/components/esp_system/esp_err.c:43
A:默认情况下,如果 flash 加密使能,NVS 加密会默认使能,配置路径如下:(Top) -> Component config -> NVS -> Enable NVS encryption
,
如果使用 NVS 加密,分区表必须包含类型为 data
,子类型为 nvs_keys
的 NVS 秘钥分区,参考 NVS 加密。
本例使用的是示例默认的分区表(Factory app, two OTA definitions),不包含 NVS 秘钥分区,为了避免出现上述错误,在测试中禁用 NVS 加密。
flash 加密
Secure Boot V2
ESP32-Secure Boot 安全方案