Problems Flashing Firmware With Secure Boot and Flash Encryption
Posted: Thu Nov 24, 2022 8:18 pm
Hi, I am trying to get flash encryption and secure boot working in "development" mode so that we can run and test all our code with these options on, but still be able to erase the flash and re-program (e.g. with "idf.py erase-flash") during development.
I have generated an RSA key for code signing and secure boot.
Here are the config options I turned on:
The first time I installed this build, I saw log messages about encrypting the flash partitions, and querying the efuses etc. showed that secure boot and flash encryption had been enabled in "developer" mode. Everything worked well.
HOWEVER, I then erased the flash:
And tried to flash the firmware again, but it no longer boots.
According to my understanding, with these options, it should be possible to re-write the firmware even with encryption enabled because UART bootloader encryption and decryption are enabled, and the bootloader can access the encrypted flash transparently.
I have tried various options, e.g. this sequence:
But I typically get this when I use "monitor":
There are instructions here which say "idf.py bootloader will produce a pre-digested bootloader and secure boot digest file for flashing at offset 0x0. When following the plaintext serial re-flashing steps it is necessary to re-flash this file before flashing other plaintext data." I think this is supposed to generate "bootloader-reflash-digest.bin" ???, but my build doesn't create this file and I am not sure why it is needed. The instructions also talk about a "Reflashable" option ("SECURE_BOOTLOADER_REFLASHABLE") but I don't see this option in the security configuration.
Is there any way to recover my board? What is the process to re-flash the firmware (including 2nd stage bootloader and partition table) with these options? Or have I got the options wrong?
I have generated an RSA key for code signing and secure boot.
Here are the config options I turned on:
Code: Select all
(Top) → Component config → ESP32-specific
Minimum Supported ESP32 Revision (Rev 3) --->
(Top) → Security features
App Signing Scheme (RSA) --->
[*] Enable hardware Secure Boot in bootloader (READ DOCS FIRST)
Select secure boot version (Enable Secure Boot version 2) --->
[*] Sign binaries during build
(signing_key/secure_boot_v2_signing_key.pem) Secure boot private signing key
[*] Allow potentially insecure options
[*] Enable flash encryption on boot (READ DOCS FIRST)
Enable usage mode (Development (NOT SECURE)) --->
Potentially insecure options --->
[ ] Leave ROM BASIC Interpreter available on reset (NEW)
[ ] Allow JTAG Debugging (NEW)
[ ] Allow app partition length not 64KB aligned (NEW)
[*] Allow additional read protecting of efuses
-*- Leave UART bootloader encryption enabled (NEW)
[*] Leave UART bootloader decryption enabled
[*] Leave UART bootloader flash cache enabled
[ ] Require flash encryption to be already enabled
[ ] Check Flash Encryption enabled on app startup (NEW)
UART ROM download mode (UART ROM download mode (Enabled (not recommended))) --->
HOWEVER, I then erased the flash:
Code: Select all
idf.py -p COM4 erase-flash
According to my understanding, with these options, it should be possible to re-write the firmware even with encryption enabled because UART bootloader encryption and decryption are enabled, and the bootloader can access the encrypted flash transparently.
I have tried various options, e.g. this sequence:
Code: Select all
idf.py -p COM4 erase-flash
idf.py -p COM4 bootloader
idf.py -p COM4 bootloader-flash
idf.py -p COM4 encrypted-flash
Code: Select all
ets Jul 29 2019 12:21:46
rst:0x1 (POWERON_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
invalid header: 0xa239a46e
invalid header: 0xa239a46e
invalid header: 0xa239a46e
invalid header: 0xa239a46e
invalid header: 0xa239a46e
invalid header: 0xa239a46e
invalid header: 0xa239a46e
ets Jul 29 2019 12:21:46
Is there any way to recover my board? What is the process to re-flash the firmware (including 2nd stage bootloader and partition table) with these options? Or have I got the options wrong?
Code: Select all
ESP32 (ESP32-D0WD-V3, revision 3)
ESP-IDF 4.4
PS C:\Users\Jeremycb\esp\wireless-controller> espefuse -p COM4 summary
Connecting....
Detecting chip type... Unsupported detection protocol, switching and trying again...
Connecting.....
Detecting chip type... ESP32
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 = 1093 R/W (0b10001)
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 = 55 R/W (0x37)
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
= 34:ab:95:49:47:dc (CRC 0xac OK) R/W
MAC_CRC (BLOCK0): CRC8 for factory MAC address = 172 R/W (0xac)
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 = 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)
DISABLE_DL_CACHE (BLOCK0): Disable flash cache in UART bootloader = False R/W (0b0)
BLOCK1 (BLOCK1): Flash encryption key
= ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? -/-
BLOCK2 (BLOCK2): Secure boot key
= 84 d7 c4 4d 6b 57 85 e3 1b bf 88 65 89 61 88 16 07 78 7a 22 66 c1 a5 b2 75 42 53 43 28 d9 2d 7c 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).