esp-idf: Cannot enable flash encryption after secure-boot v2 (IDFGH-10657)

Answers checklist.

  • I have read the documentation ESP-IDF Programming Guide and the issue is not addressed there.
  • I have updated my IDF branch (master or release) to the latest version and checked that the issue is present there.
  • I have searched the issue tracker for a similar issue and not found a similar issue.

IDF version.

v4.4.4-dirty

Operating System used.

Windows

How did you build your project?

Command line with idf.py

If you are using Windows, please specify command line type.

None

Development Kit.

ESP32 Rev.3 - Custom Board

Power Supply used.

External 3.3V

What is the expected behavior?

I enabled secure boot v2 and it worked well. Now I would like to enable flash encryption with an external key so that FW are already encrypted when they’re distributed to the devices.

What is the actual behavior?

The “espefuse.py” tool does not let me burn the flash encryption key. It says :

espefuse.py v4.5.1
Connecting...
Device PID identification is only supported on COM and /dev/ serial ports.

Detecting chip type... Unsupported detection protocol, switching and trying again...
Connecting...
Device PID identification is only supported on COM and /dev/ serial ports.

Detecting chip type... ESP32

=== Run "burn_key" command ===
Burn keys to blocks:
 - BLOCK1 -> [Key bytes]
        Reversing the byte order
        Disabling read to key block

A fatal error occurred: This efuse cannot be read-disabled due the to RD_DIS field is already write-disabled

However when running the summary command, nothing is written to the BLOCK1 used for the flash encryption key :

espefuse.py v4.5.1
Connecting...
Device PID identification is only supported on COM and /dev/ serial ports.
.
Detecting chip type... Unsupported detection protocol, switching and trying again...
Connecting...
Device PID identification is only supported on COM and /dev/ serial ports.

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                      = 1107 R/- (0b00001)

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                           = 56 R/W (0x38)
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                           = 257 R/W (0x0101)
RD_DIS (BLOCK0):                                   Efuse read disable mask                            = 0 R/- (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                               
   = 78:21:84:a5:c4:78 (CRC 0xad OK) R/W 
MAC_CRC (BLOCK0):                                  CRC8 for factory MAC address                       = 173 R/W (0xad)
CHIP_VER_REV1 (BLOCK0):                            Silicon Revision 1                                 = True R/W (0b1)
CHIP_VER_REV2 (BLOCK0):                            Silicon Revision 2                                 = True R/W (0b1)
WAFER_VERSION_MINOR (BLOCK0):                      WAFER VERSION MINOR                                = 0 R/W (0b00)
CHIP_PACKAGE (BLOCK0):                             Chip package identifier                            = 0 R/W (0b000)
CHIP_PACKAGE_4BIT (BLOCK0):                        Chip package identifier #4bit                      = 0 R/W (0b0)
MAC_VERSION (BLOCK3):                              Version of the MAC field                           = 0 R/W (0x00)
WAFER_VERSION_MAJOR (BLOCK0):                      calc WAFER VERSION MAJOR from CHIP_VER_REV1 and CH = 3 R/W (0b011)
                                                   IP_VER_REV2 and apb_ctl_date (read only)          
PKG_VERSION (BLOCK0):                              calc Chip package = CHIP_PACKAGE_4BIT << 3 + CHIP_ = 0 R/W (0x0)
                                                   PACKAGE (read only)                               

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     = 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                              
   = 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                                   
   = Secure boot key bytes 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

Steps to reproduce.

  1. Generate a secure boot key : espsecure.py generate_signing_key --version 2 sb_private_key.pem
  2. Export the public key : openssl rsa -in sb_private_key.pem -pubout > sb_public_key.pem
  3. Burn the digest in efuse : espefuse.py burn_key_digest sb_public_key.pem
  4. Generate a flash encryption key digest : espsecure.py generate_flash_encryption_key --keylen 256 flash_enc_key.bin
  5. Flash the digest : espefuse.py --port rfc2217://host.docker.internal:4005?ign_set_control burn_key flash_encryption flash_enc_key.bin

I get the error at step number 5 :

espefuse.py v4.5.1
Connecting...
Device PID identification is only supported on COM and /dev/ serial ports.

Detecting chip type... Unsupported detection protocol, switching and trying again...
Connecting...
Device PID identification is only supported on COM and /dev/ serial ports.

Detecting chip type... ESP32

=== Run "burn_key" command ===
Burn keys to blocks:
 - BLOCK1 -> [Key bytes]
        Reversing the byte order
        Disabling read to key block

A fatal error occurred: This efuse cannot be read-disabled due the to RD_DIS field is already write-disabled

Debug Logs.

No response

More Information.

Do I make something wrong ? Is there another way to generate keys and flash ? I found the documentation about secure boot v2 and flash encryption a bit lacking because I did not find any information about espefuse.py burn_key_digest sb_public_key.pem which seems to be the command to be used for flashing the secure_boot v2 key digest.

About this issue

  • Original URL
  • State: closed
  • Created a year ago
  • Comments: 17

Most upvoted comments

Hi @FnxQT If there’s nothing else then can you close the issue? Thanks, Aditya

It depends on multiple options

  • UART ROM Download mode: If it is kept enabled( not recommended for security reasons) then you can flash a new firmware, if it is disabled then the only way to update the firmware is through OTA.
  • Secure Boot: If you have the secure boot key then you can sign the bootloader/firmware and update it.
  • Flash Encryption: If you have the flash encryption key on host or you have enabled it in development mode then you can flash the firmware again. (Both ways are not recommended for security reasons). If you have enabled flash encryption in release mode then the only option to update the firmware is through OTA.

In case of OTA, it would only work if the updated firmware is able to receive the next OTA. if it crashes in loop then the next OTA would not be possible. Also in case of OTA, bootloader cannot be updated.

I think you can ignore that error. It happens because as you have already observed, when bootloader tries to load the image and it doesn’t find it, hence it gives out an error.

You need to write the encrypted binaries on the flash of the esp32. Please follow step 5 of the same document