Page 1 of 1

ESP32 Flash Encryption Error

Posted: Tue Feb 28, 2023 4:47 am
by helpwithesp32
Hello,
I just tried enabling flash encryption for my esp32, and I'm seeing the following error on bootup:

E (435) flash_encrypt: Flash encryption key has to be either unset or both read and write protected


When I run espefuse.py summary, I can see the full encryption key in Block1 (I redacted it below for privacy):

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 = 1079 R/- (0b10011)

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 = 385 R/W (0x0181)
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
= 44:17:93:7b:c9:b8 (CRC 0x35 OK) R/W
MAC_CRC (BLOCK0): CRC8 for factory MAC address = 53 R/W (0x35)
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) = 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 = True R/W (0b1)
DISABLE_DL_CACHE (BLOCK0): Disable flash cache in UART bootloader = True R/W (0b1)
BLOCK1 (BLOCK1): Flash encryption key
= 256 bit number redacted
BLOCK2 (BLOCK2): Secure boot key
= 256 bit number redacted
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



Since I can see the full flash encryption key, I thought I need to disable reading of the flash encryption key:

python espefuse.py -p /dev/ttyUSB1 read_protect_efuse BLOCK1


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


Do I need to to enable write first, or is there some other issue? Also, why would I need to manually change reading and writing, shouldn't my menuconfig take care of all of this?


Here is the full log I see on bootup after enabling flash encryption:

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:0x3fff0030 len:0x2824
load:0x40078000 len:0x5218
load:0x40080400 len:0x1254
0x40080400: _init at ??:?

entry 0x40080694
E (435) flash_encrypt: Flash encryption key has to be either unset or both read and write protected
E (435) boot: Flash encryption check failed (259).
E (439) boot: Factory app partition is not bootable
E (444) esp_image: image at 0x160000 has invalid magic byte (nothing flashed here?)
E (453) boot: OTA app partition slot 0 is not bootable
E (458) esp_image: image at 0x2a0000 has invalid magic byte (nothing flashed here?)
E (467) boot: OTA app partition slot 1 is not bootable
E (473) boot: No bootable app partitions in the partition table



Thanks in advanced for the help.

Re: ESP32 Flash Encryption Error

Posted: Sat Mar 04, 2023 12:50 am
by helpwithesp32
Does anyone have any ideas? I'm essentially just seeing this fault, the rest of the post is background information:
E (435) flash_encrypt: Flash encryption key has to be either unset or both read and write protected

Re: ESP32 Flash Encryption Error

Posted: Mon Mar 06, 2023 3:36 am
by ESP_Mahavir
Hello,
FLASH_CRYPT_CNT (BLOCK0): Flash encryption mode counter = 0 R/W (0b0000000)
It appears like your device has flash encryption key programmed but flash encryption itself not enabled (based on the count value above).

Ideally, this situation should not occur, unless the first boot workflow where security features get enabled was somehow interrupted (e.g. device was power cycled)

Since, additional read protection is now disabled (part of the secure boot workflow), it won't be possible to read protect the flash encryption key now.

For this particular device, you may disable this check in the bootloader where flash encryption key block is checked for read/write protection fuses. This should allow for the flash encryption workflow to proceed further and encrypt the contents of the bootloader, partition table and application on the flash. Please note that, this device still exposes a risk of flash encryption key being software readable and hence should not be used for production scenarios.

Re: ESP32 Flash Encryption Error

Posted: Mon Sep 25, 2023 5:03 pm
by steveglennon
I ended up repeatably in this situation.
I enabled secure boot V2, but not flash encryption (on a Rev 3 chip).

This is the flash summary following secure boot:
[Codebox]
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                      = 1142 R/- (0b00110)
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                           = 51 R/W (0x33)
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                              
   = <redacted> (CRC 0xa2 OK) R/W
MAC_CRC (BLOCK0):                                  CRC8 for factory MAC address                       = 162 R/W (0xa2)
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                           = Custom MAC in BLOCK3 R/W (0x01)
CUSTOM_MAC (BLOCK3):                               Custom MAC                                       
   = <redacted> (CRC 0xe1 OK) R/W
CUSTOM_MAC_CRC (BLOCK3):                           CRC of custom MAC                                  = 225 R/W (0xe1)
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                                  
   = <redacted> R/-
BLOCK3 (BLOCK3):                                   Variable Block 3                                 
   = <redacted> 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 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).
[/Codebox]

Following that it was in secure boot mode successfully - I had to sign images to update them.

I then take this one step further, to enable encrypted flash using:
[Codebox]espefuse --port /dev/cu.usbserial-1430 burn_key flash_encryption key_file.bin[/Codebox]

And I then get the following:
[Codebox]<information about keyfile/key>
A fatal error occurred: This efuse cannot be read-disabled due the to RD_DIS field is already write-disabled[/Codebox]

It appears that the act of enabling secure boot (without flash encryption) causes the RD_DIS to be write protected, which prevents the burning of encryption keys.

If I burn the encryption key first, and then flash a bootloader/app image built with flash encryption and secure boot enabled (and I sign the image), all is well.

This looks like a hole in the process/tools that can result in devices that can no longer have flash encryption enabled.

Re: ESP32 Flash Encryption Error

Posted: Tue Sep 26, 2023 4:59 am
by ESP_Mahavir
Hello,

Relevant discussion pointer:
https://github.com/espressif/esp-idf/is ... 1637872304

This is a known limitation and it has been highlighted in the docs at following locations:

https://docs.espressif.com/projects/esp ... is-enabled
https://docs.espressif.com/projects/esp ... externally

Thanks.