Secure boot v2 and flash encryption failed in development mode with ESP-WROOM 32

dzungpv
Posts: 17
Joined: Thu Mar 26, 2020 4:52 am

Secure boot v2 and flash encryption failed in development mode with ESP-WROOM 32

Postby dzungpv » Sat Sep 23, 2023 4:31 am

Hi,
I try to enable Secure boot v2 with flash encryption for ESP-WROOM 32, V3.1 follow this guide https://docs.espressif.com/projects/esp ... ot-v2.html.
This is my custom config:

Code: Select all

#
# Serial flasher config
#
CONFIG_ESPTOOLPY_FLASHMODE_DIO=y
CONFIG_ESPTOOLPY_FLASHMODE="dio"
CONFIG_ESPTOOLPY_FLASHFREQ_40M=y
CONFIG_ESPTOOLPY_FLASHFREQ="40m"
CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y
CONFIG_ESPTOOLPY_FLASHSIZE="4MB"
#
# Partition Table
#
CONFIG_PARTITION_TABLE_CUSTOM=y
CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions.csv"
CONFIG_PARTITION_TABLE_FILENAME="partitions.csv"
CONFIG_PARTITION_TABLE_OFFSET=0xF000
CONFIG_PARTITION_TABLE_MD5=y

#
# Arduino Configuration
#
CONFIG_ARDUINO_VARIANT="esp32"
CONFIG_ENABLE_ARDUINO_DEPENDS=y
CONFIG_AUTOSTART_ARDUINO=y

#
# FreeRTOS
#
# 1000 require for Arduino
CONFIG_FREERTOS_HZ=1000

#
# TLS Key Exchange Methods
#
# 2 option require for arduino Arduino
CONFIG_MBEDTLS_PSK_MODES=y
CONFIG_MBEDTLS_KEY_EXCHANGE_PSK=y

#
# ESP32-specific
#
# anable secure boot v2 only working on Rev3 chip
CONFIG_ESP32_REV_MIN_3=y
CONFIG_ESP32_REV_MIN=3

#
# Security features
#
CONFIG_SECURE_SIGNED_ON_BOOT=y
CONFIG_SECURE_SIGNED_ON_UPDATE=y
CONFIG_SECURE_SIGNED_APPS=y
CONFIG_SECURE_ESP32_SUPPORTS_RSA=y
CONFIG_SECURE_BOOT_SUPPORTS_RSA=y
CONFIG_SECURE_SIGNED_APPS_RSA_SCHEME=y
CONFIG_SECURE_BOOT=y
# CONFIG_SECURE_BOOT_V1_ENABLED is not set
CONFIG_SECURE_BOOT_V2_ENABLED=y
CONFIG_SECURE_BOOT_BUILD_SIGNED_BINARIES=y
CONFIG_SECURE_BOOT_SIGNING_KEY="sbv2_private.pem"
# CONFIG_SECURE_BOOT_INSECURE is not set
CONFIG_SECURE_FLASH_ENC_ENABLED=y
# CONFIG_SECURE_FLASH_ENCRYPTION_MODE_DEVELOPMENT is not set
CONFIG_SECURE_FLASH_ENCRYPTION_MODE_RELEASE=y
CONFIG_SECURE_FLASH_CHECK_ENC_EN_IN_APP=y
# CONFIG_SECURE_DISABLE_ROM_DL_MODE is not set
CONFIG_SECURE_INSECURE_ALLOW_DL_MODE=y
# end of Security features

Partition table:

Code: Select all

# Name,   Type, SubType, Offset,  Size, Flags
nvs, data, nvs, 0x11000, 0xD000,
otadata, data, ota, 0x1E000, 0x2000,
app0, app, ota_0, 0x20000, 0x190000,
app1, app, ota_1, 0x1B0000, 0x190000,
spiffs, data, spiffs, 0x340000, 0x3C000,
coredump, data, coredump, 0x37C000, 0x41000,
nvs_key, data, nvs_keys, 0x3BD000, 0x1000, encrypted,
storage, data, fat, 0x3BE000, 0x42000,
On the first boot it successful and app working fine.
But the problem occur when I flash the app from the command line (I am not disable ROM for development). It failed to boot with logs:

Code: Select all

rst:0x10 (RTCWDT_RTC_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
invalid header: 0x76db9456
invalid header: 0x76db9456
invalid header: 0x76db9456
invalid header: 0x76db9456
invalid header: 0x76db9456
invalid header: 0x76db9456
invalid header: 0x76db9456
ets Jul 29 2019 12:21:46
espefuse.py summary content:

Code: Select all

espefuse.py v3.3.4-dev
Connecting....
Detecting chip type... Unsupported detection protocol, switching and trying again...
Connecting.....
Detecting chip type... ESP32

=== Run "summary" command ===
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                      = 1100 R/- (0b10000)

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                           = 385 R/W (0x0181)
RD_DIS (BLOCK0):                                   Efuse read disable mask                            = 1 R/- (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                               
   = a0:b7:65:58:72:fc (CRC 0xfd OK) R/W 
MAC_CRC (BLOCK0):                                  CRC8 for factory MAC address                       = 253 R/W (0xfd)
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)
CHIP_PACKAGE_4BIT (BLOCK0):                        Chip package identifier #4bit                      = False R/W (0b0)
MAC_VERSION (BLOCK3):                              Version of the MAC field                           = 0 R/W (0x00)

Security fuses:
FLASH_CRYPT_CNT (BLOCK0):                          Flash encryption mode counter                      = 127 R/W (0b1111111)
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        = 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                                   
   = xx 5c 3f 5a e5 a0 61 cd xx xx be f2 xx xx xx be xx xx af 1f eb xx 31 8f da eb 6d b3 b8 xx xx xx 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).
I try to re-flash boot loader and build app binary without any success.

dzungpv
Posts: 17
Joined: Thu Mar 26, 2020 4:52 am

Re: Secure boot v2 and flash encryption failed in development mode with ESP-WROOM 32

Postby dzungpv » Wed Sep 27, 2023 3:41 am

Still no answer. I have bricked 4 chips. Google all the web, problem still not fix.

ESP_Mahavir
Posts: 190
Joined: Wed Jan 24, 2018 6:51 am

Re: Secure boot v2 and flash encryption failed in development mode with ESP-WROOM 32

Postby ESP_Mahavir » Wed Sep 27, 2023 4:28 am

Hello,

Apologies for the delayed response here.

Looking at the efuse summary, device has both flash encryption and secure boot (v2) enabled. Hence, it is expecting encrypted artifacts (e.g. bootloader, partition-table etc.). Flashing plain-text bootloader won't help here and it will result in the error that you are getting.

May I ask, if you had generated and flashed the flash encryption key externally? In other words, do you have the backup of the flash encryption key? If yes, then it should be possible to manually encrypt the bootloader and flash it on the device. That should fix the problem. Please see documentation regarding this at:

https://docs.espressif.com/projects/esp ... pted-flash

Note: For the flash encryption development mode, it is possible to use commands like `idf.py encrypted-flash` to flash encrypted partitions over UART DL mode. But unfortunately since you have enabled the release mode, this command won't help here.

dzungpv
Posts: 17
Joined: Thu Mar 26, 2020 4:52 am

Re: Secure boot v2 and flash encryption failed in development mode with ESP-WROOM 32

Postby dzungpv » Wed Sep 27, 2023 5:45 am

ESP_Mahavir wrote:
Wed Sep 27, 2023 4:28 am
Hello,

Apologies for the delayed response here.

Looking at the efuse summary, device has both flash encryption and secure boot (v2) enabled. Hence, it is expecting encrypted artifacts (e.g. bootloader, partition-table etc.). Flashing plain-text bootloader won't help here and it will result in the error that you are getting.

May I ask, if you had generated and flashed the flash encryption key externally? In other words, do you have the backup of the flash encryption key? If yes, then it should be possible to manually encrypt the bootloader and flash it on the device. That should fix the problem. Please see documentation regarding this at:

https://docs.espressif.com/projects/esp ... pted-flash

Note: For the flash encryption development mode, it is possible to use commands like `idf.py encrypted-flash` to flash encrypted partitions over UART DL mode. But unfortunately since you have enabled the release mode, this command won't help here.
I have backup the key, I have devices that FLASH_CRYPT_CNT is 1 or 127. For the [FLASH_CRYPT_CNT b]1[/b] I try disable Flash encryption with espefuse.py burn_efuse FLASH_CRYPT_CNT and espefuse.py burn_efuse FLASH_CRYPT_CNT 2 with no luck it show the error:

Code: Select all

Detecting chip type... ESP32

=== Run "burn_efuse" command ===
The efuses to burn:
  from BLOCK0
     - FLASH_CRYPT_CNT

Burning efuses:

    - 'FLASH_CRYPT_CNT' (Flash encryption is enabled if this field has an odd number of bits set) 0b0000001 -> 0b0000010

A fatal error occurred: 	New value contains some bits that cannot be cleared (value will be 0b0000011)
For the secure boot I try mutiple --force write_flash command so it may break, Can I manual update the boot loader and the key? Bootloader require to encrypt before flash?
I try you hint and additional here https://esp32.com/viewtopic.php?t=30753 to re flash the bootloader with command: idf.py -p COM4 encrypted-bootloader-flash It can pass fist boot state but show error:

Code: Select all

rst:0x3 (SW_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:0x2d6c
load:0x40078000 len:0x5ea8
load:0x40080400 len:0x4
0x40080400: _init at ??:?

load:0x40080404 len:0xdb0
entry 0x400805e4
E (78) flash_parts: partition 0 invalid magic number 0xc2d9
E (79) boot: Failed to verify partition table
E (80) boot: load partition table error!
ets Jul 29 2019 12:21:46

ESP_Mahavir
Posts: 190
Joined: Wed Jan 24, 2018 6:51 am

Re: Secure boot v2 and flash encryption failed in development mode with ESP-WROOM 32

Postby ESP_Mahavir » Wed Sep 27, 2023 11:42 am

I have devices that FLASH_CRYPT_CNT is 1 or 127. For the [FLASH_CRYPT_CNT b]1[/b] I try disable Flash encryption with espefuse.py burn_efuse FLASH_CRYPT_CNT and espefuse.py burn_efuse FLASH_CRYPT_CNT 2 with no luck it show the error:

For flash encryption release mode, all possible bits in the crypt count field are exhausted. Hence, it is not possible to revert back to normal mode. In other words, flash encryption can not disabled once all bits in the flash crypt count field are exhausted or the field is write protected.
Can I manual update the boot loader and the key? Bootloader require to encrypt before flash?

Please note that the EFuse is one time programmable. Hence, reprogramming the key is not possible. Yes, bootloader (in-fact other partitions too) must be encrypted before flashing on the device.
E (78) flash_parts: partition 0 invalid magic number 0xc2d9
E (79) boot: Failed to verify partition table
E (80) boot: load partition table error!
ets Jul 29 2019 12:21:46

Bootup looks good. Could you try flashing the encrypted partition table image here?

dzungpv
Posts: 17
Joined: Thu Mar 26, 2020 4:52 am

Re: Secure boot v2 and flash encryption failed in development mode with ESP-WROOM 32

Postby dzungpv » Thu Sep 28, 2023 3:18 am

ESP_Mahavir wrote:
Wed Sep 27, 2023 11:42 am
I have devices that FLASH_CRYPT_CNT is 1 or 127. For the [FLASH_CRYPT_CNT b]1[/b] I try disable Flash encryption with espefuse.py burn_efuse FLASH_CRYPT_CNT and espefuse.py burn_efuse FLASH_CRYPT_CNT 2 with no luck it show the error:

For flash encryption release mode, all possible bits in the crypt count field are exhausted. Hence, it is not possible to revert back to normal mode. In other words, flash encryption can not disabled once all bits in the flash crypt count field are exhausted or the field is write protected.
Can I manual update the boot loader and the key? Bootloader require to encrypt before flash?

Please note that the EFuse is one time programmable. Hence, reprogramming the key is not possible. Yes, bootloader (in-fact other partitions too) must be encrypted before flashing on the device.
E (78) flash_parts: partition 0 invalid magic number 0xc2d9
E (79) boot: Failed to verify partition table
E (80) boot: load partition table error!
ets Jul 29 2019 12:21:46

Bootup looks good. Could you try flashing the encrypted partition table image here?
Docs not mention, what is the key to encrypt the flash along side with secure boot? Secureboot V2 I use a .pem 3072 RSA generate key with openssl (openssl genrsa -out sbv2_private_dev.pem 3072). Now want to manual encrypt the bin file before flash (some of my brick device only can flash via JTAG, use encrypt command with jtag prog not working) like the guide https://docs.espressif.com/projects/esp ... pted-flash but I dont know how to get the flash encryption file

ESP_Mahavir
Posts: 190
Joined: Wed Jan 24, 2018 6:51 am

Re: Secure boot v2 and flash encryption failed in development mode with ESP-WROOM 32

Postby ESP_Mahavir » Thu Sep 28, 2023 4:37 am

Docs not mention, what is the key to encrypt the flash along side with secure boot?
Please see here: https://docs.espressif.com/projects/esp ... erated-key

This is what I had asked in my earlier post too. If you did not program the flash encryption key externally then bootloader would generate one internally and read protect it. In that case, there is no way to retrieve the key and OTA update becomes only mechanism to update the firmware on the device.

Alternatively, you can also try different security workflows under emulator using this guide https://github.com/espressif/esp-toolch ... /README.md. Qemu release artifacts for ESP32 can be downloaded from here: https://github.com/espressif/qemu/releases

dzungpv
Posts: 17
Joined: Thu Mar 26, 2020 4:52 am

Re: Secure boot v2 and flash encryption failed in development mode with ESP-WROOM 32

Postby dzungpv » Thu Sep 28, 2023 7:19 am

ESP_Mahavir wrote:
Thu Sep 28, 2023 4:37 am
Docs not mention, what is the key to encrypt the flash along side with secure boot?
Please see here: https://docs.espressif.com/projects/esp ... erated-key

This is what I had asked in my earlier post too. If you did not program the flash encryption key externally then bootloader would generate one internally and read protect it. In that case, there is no way to retrieve the key and OTA update becomes only mechanism to update the firmware on the device.

Alternatively, you can also try different security workflows under emulator using this guide https://github.com/espressif/esp-toolch ... /README.md. Qemu release artifacts for ESP32 can be downloaded from here: https://github.com/espressif/qemu/releases
I use encrypt flash command and I can rewrite the firmware, now it running now so where is the flash encryption key?, I guest that with development mode the encryption key can be read back by the tool or by secret code. or it using the private key of the secure boot loader key, I don't known exactly how, docs not mention with V1 boot loader the flash key can be generate by the espsecure tool. I still confuse about the docs.
In this doc: https://docs.espressif.com/projects/esp ... ption.html

Code: Select all

Alternatively, if you’re using secure boot and have a secure boot signing key then you can generate a deterministic SHA-256 digest of the secure boot private signing key and use this as the flash encryption key:

espsecure.py digest_private_key --keyfile secure_boot_signing_key.pem --keylen 256 my_flash_encryption_key.bin

But it only work with ecdsa key, not 3072 RSA generate by openssl.

ESP_Mahavir
Posts: 190
Joined: Wed Jan 24, 2018 6:51 am

Re: Secure boot v2 and flash encryption failed in development mode with ESP-WROOM 32

Postby ESP_Mahavir » Thu Sep 28, 2023 8:57 am

Hello,

Good to hear that you have it working with development mode setup!

Few things:

1. Please don't refer to v3.3 docs. This release is already EOL. Please use and refer to latest stable release docs (e.g. 5.1.1)
2. Once the flash encryption key is read protected, it is not software accessible. However, the AES-XTS peripheral can still access the key and perform the encryption of the contents in UART DL mode (please note that, this works in development mode only). Alternately, for OTA update case also, the peripheral can help to encrypt the contents before writing them to flash on the device.
3. Please do not confuse secure boot and flash encryption features. They are different features. For ESP32 ECO3, it can support both secure boot v1 and v2 scheme. For secure boot v2 scheme, only the public key digest gets programmed in the efuse, private key stays outside of the device (RSA-3072 case).

I would recommend that your refer to technical reference manual for AES-XTS related details. That should help to clarify your doubts.

HTH!

Who is online

Users browsing this forum: Bing [Bot] and 95 guests