Flash encryption on ESP32-C3 with OTA as Access Point

david10
Posts: 6
Joined: Wed Mar 15, 2023 6:16 am

Flash encryption on ESP32-C3 with OTA as Access Point

Postby david10 » Wed May 17, 2023 7:52 pm

Hello,
I want to configure the flash encryption on ESP32-C3 with OTA as Access Point, but I have problems with the encryption part.
Tehnically, I want to generate a pre-encrypted file of the firmware.
I have wrote the encryption key in the BLOCK_KEY0 (BLOCK4) with this command:

Code: Select all

espefuse.py -p COM35 burn_key BLOCK_KEY0 cryptkey.bin XTS_AES_128_KEY --no-write-protect --no-read-protect
I have tried to encrypt the flash file with this command:

Code: Select all

espsecure.py encrypt_flash_data --aes_xts --keyfile .\cryptkey.bin --output cryptedflash.bin .\build\throughput_client_demo.bin --address 0x20000 
Now if I try to upload the flash with the

Code: Select all

idf.py build | idf.py -p COM35 flash
or

Code: Select all

idf.py build | idf.py -p COM35 encrypted-app-flash 
or

Code: Select all

idf.py build | idf.py -p COM35 encrypted-flash 
commands, the device is not booting anymore, it is bootloping everytime with these errors:

Code: Select all

ESP-ROM:esp32c3-api1-20210207
Build:Feb  7 2021
rst:0x3 (RTC_SW_SYS_RST),boot:0x9 (SPI_FAST_FLASH_BOOT)
Saved PC:0x403cfa8a
SPIWP:0xee
mode:DIO, clock div:1
load:0x3fcd5988,len:0x2ae4
load:0x403cc710,len:0x948
load:0x403ce710,len:0x487c
entry 0x403cc710
I (25) boot: ESP-IDF v5.0.1-dirty 2nd stage bootloader
I (25) boot: compile time 15:05:24
I (25) boot: chip revision: v0.4
I (27) boot.esp32c3: SPI Speed      : 80MHz
I (32) boot.esp32c3: SPI Mode       : DIO
I (37) boot.esp32c3: SPI Flash Size : 4MB
I (42) boot: Enabling RNG early entropy source...
I (47) boot: Partition Table:
I (51) boot: ## Label            Usage          Type ST Offset   Length
I (58) boot:  0 nvs              WiFi data        01 02 00009000 00005000
I (65) boot:  1 otadata          OTA data         01 00 0000e000 00002000
I (73) boot:  2 phy_init         RF data          01 01 00011000 00001000
I (80) boot:  3 ota_0            OTA app          00 10 00020000 0015e000
I (88) boot:  4 ota_1            OTA app          00 11 00180000 0015e000
I (95) boot: End of partition table
I (99) esp_image: segment 0: paddr=00020020 vaddr=3c100020 size=3a578h (238968) map
I (144) esp_image: segment 1: paddr=0005a5a0 vaddr=3fc92e00 size=02c9ch ( 11420) load
I (146) esp_image: segment 2: paddr=0005d244 vaddr=40380000 size=02dd4h ( 11732) load
I (152) esp_image: segment 3: paddr=00060020 vaddr=42000020 size=fad18h (1027352) map
I (312) esp_image: segment 4: paddr=0015ad40 vaddr=40382dd4 size=0ffc8h ( 65480) load
I (330) boot: Loaded app from partition at offset 0x20000
I (330) boot: Checking flash encryption...
E (330) flash_encrypt: Flash Encryption cannot be enabled (CRYPT_CNT (0) is write protected)
E (339) boot: OTA app partition slot 0 is not bootable
E (345) esp_image: image at 0x180000 has invalid magic byte (nothing flashed here?)
E (353) boot: OTA app partition slot 1 is not bootable
E (359) boot: No bootable app partitions in the partition table
Here is the summary of the fuse bits:

Code: Select all

PS E:\Software\Espressif\frameworks\esp-idf-v5.0.1\examples\_projects\RGB_BLE_ESP32> espefuse.py -p COM35 summary
espefuse.py v4.5
Connecting...
Detecting chip type... ESP32-C3

=== Run "summary" command ===
EFUSE_NAME (Block) Description  = [Meaningful Value] [Readable/Writeable] (Hex Value)
----------------------------------------------------------------------------------------
Calibration fuses:
TEMP_SENSOR_CAL (BLOCK2)                           Temperature calibration                            = 16.1 R/W (0b010100001)
ADC1_MODE0_D2 (BLOCK2)                             ADC1 calibration 1                                 = 148 R/W (0x25)
ADC1_MODE1_D2 (BLOCK2)                             ADC1 calibration 2                                 = 360 R/W (0x5a)
ADC1_MODE2_D2 (BLOCK2)                             ADC1 calibration 3                                 = -48 R/W (0x8c)
ADC1_MODE3_D2 (BLOCK2)                             ADC1 calibration 4                                 = 288 R/W (0x48)
ADC2_MODE0_D2 (BLOCK2)                             ADC2 calibration 5                                 = -456 R/W (0xf2)
ADC2_MODE1_D2 (BLOCK2)                             ADC2 calibration 6                                 = 232 R/W (0x3a)
ADC2_MODE2_D2 (BLOCK2)                             ADC2 calibration 7                                 = 388 R/W (0x61)
ADC2_MODE3_D2 (BLOCK2)                             ADC2 calibration 8                                 = 40 R/W (0x0a)
ADC1_MODE0_D1 (BLOCK2)                             ADC1 calibration 9                                 = 20 R/W (0b000101)
ADC1_MODE1_D1 (BLOCK2)                             ADC1 calibration 10                                = -32 R/W (0b101000)
ADC1_MODE2_D1 (BLOCK2)                             ADC1 calibration 11                                = 48 R/W (0b001100)
ADC1_MODE3_D1 (BLOCK2)                             ADC1 calibration 12                                = 8 R/W (0b000010)
ADC2_MODE0_D1 (BLOCK2)                             ADC2 calibration 13                                = 0 R/W (0b000000)
ADC2_MODE1_D1 (BLOCK2)                             ADC2 calibration 14                                = 0 R/W (0b000000)
ADC2_MODE2_D1 (BLOCK2)                             ADC2 calibration 15                                = 0 R/W (0b000000)
ADC2_MODE3_D1 (BLOCK2)                             ADC2 calibration 16                                = 0 R/W (0b000000)

Config fuses:
DIS_ICACHE (BLOCK0)                                Disables ICache                                    = False R/W (0b0)
DIS_DOWNLOAD_ICACHE (BLOCK0)                       Disables Icache when SoC is in Download mode       = False R/W (0b0)
DIS_FORCE_DOWNLOAD (BLOCK0)                        Disables forcing chip into Download mode           = False R/W (0b0)
DIS_CAN (BLOCK0)                                   Disables the TWAI Controller hardware              = False R/W (0b0)
VDD_SPI_AS_GPIO (BLOCK0)                           Set this bit to vdd spi pin function as gpio       = False R/W (0b0)
BTLC_GPIO_ENABLE (BLOCK0)                          Enable btlc gpio                                   = 0 R/W (0b00)
POWERGLITCH_EN (BLOCK0)                            Set this bit to enable power glitch function       = False R/W (0b0)
POWER_GLITCH_DSENSE (BLOCK0)                       Sample delay configuration of power glitch         = 0 R/W (0b00)
DIS_DIRECT_BOOT (BLOCK0)                           Disables direct boot mode                          = False R/W (0b0)
DIS_USB_SERIAL_JTAG_ROM_PRINT (BLOCK0)             Disables USB-Serial-JTAG ROM printing              = False R/W (0b0)
UART_PRINT_CONTROL (BLOCK0)                        Sets the default UART boot message output mode     = Enabled R/W (0b00)
FORCE_SEND_RESUME (BLOCK0)                         Force ROM code to send a resume command during SPI = False R/W (0b0)
                                                    bootduring SPI boot
ERR_RST_ENABLE (BLOCK0)                            Use BLOCK0 to check error record registers         = with check R/W (0b1)
DISABLE_WAFER_VERSION_MAJOR (BLOCK0)               Disables check of wafer version major              = False R/W (0b0)
DISABLE_BLK_VERSION_MAJOR (BLOCK0)                 Disables check of blk version major                = False R/W (0b0)
BLOCK_USR_DATA (BLOCK3)                            User data
   = 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

Efuse fuses:
WR_DIS (BLOCK0)                                    Disables programming of individual eFuses          = 272 R/W (0x00000110)
RD_DIS (BLOCK0)                                    Disables software reading from BLOCK4-10           = 0 R/W (0b0000000)

Flash Config fuses:
FLASH_TPUW (BLOCK0)                                Configures flash startup delay after SoC power-up, = 0 R/W (0x0)
                                                    unit is (ms/2). When the value is 15, delay is 7.
                                                   5 ms

Identity fuses:
SECURE_VERSION (BLOCK0)                            Secure version (used by ESP-IDF anti-rollback feat = 0 R/W (0x0000)
                                                   ure)
MAC (BLOCK1)                                       Factory MAC Address
   = a0:76:4e:b2:31:20 (OK) R/W
WAFER_VERSION_MINOR_LO (BLOCK1)                    WAFER_VERSION_MINOR least significant bits         = 4 R/W (0b100)
PKG_VERSION (BLOCK1)                               Package version                                    = 0 R/W (0b000)
BLK_VERSION_MINOR (BLOCK1)                         BLOCK version minor                                = 2 R/W (0b010)
WAFER_VERSION_MINOR_HI (BLOCK1)                    WAFER_VERSION_MINOR most significant bits          = 0 R/W (0b0)
WAFER_VERSION_MAJOR (BLOCK1)                       WAFER_VERSION_MAJOR                                = 0 R/W (0b00)
OPTIONAL_UNIQUE_ID (BLOCK2)                        Optional unique 128-bit ID
   = ca 34 17 62 ab d3 75 3e 6c cc b6 78 99 6d 8d 8a R/W
BLK_VERSION_MAJOR (BLOCK2)                         BLOCK version major                                = With calibration R/W (0b01)
CUSTOM_MAC (BLOCK3)                                Custom MAC Address
   = 00:00:00:00:00:00 (OK) R/W
WAFER_VERSION_MINOR (BLOCK0)                       calc WAFER VERSION MINOR = WAFER_VERSION_MINOR_HI  = 4 R/W (0x4)
                                                   << 3 + WAFER_VERSION_MINOR_LO (read only)

Jtag Config fuses:
SOFT_DIS_JTAG (BLOCK0)                             Software disables JTAG. When software disabled, JT = 0 R/W (0b000)
                                                   AG can be activated temporarily by HMAC peripheral
DIS_PAD_JTAG (BLOCK0)                              Permanently disable JTAG access via pads. USB JTAG = False R/W (0b0)
                                                    is controlled separately.

Security fuses:
DIS_DOWNLOAD_MANUAL_ENCRYPT (BLOCK0)               Disables flash encryption when in download boot mo = False R/W (0b0)
                                                   des
SPI_BOOT_CRYPT_CNT (BLOCK0)                        Enables encryption and decryption, when an SPI boo = Disable R/- (0b000)
                                                   t mode is set. Enabled when 1 or 3 bits are set,di
                                                   sabled otherwise
SECURE_BOOT_KEY_REVOKE0 (BLOCK0)                   If set, revokes use of secure boot key digest 0    = False R/W (0b0)
SECURE_BOOT_KEY_REVOKE1 (BLOCK0)                   If set, revokes use of secure boot key digest 1    = False R/W (0b0)
SECURE_BOOT_KEY_REVOKE2 (BLOCK0)                   If set, revokes use of secure boot key digest 2    = False R/W (0b0)
KEY_PURPOSE_0 (BLOCK0)                             KEY0 purpose                                       = XTS_AES_128_KEY R/- (0x4)
KEY_PURPOSE_1 (BLOCK0)                             KEY1 purpose                                       = USER R/W (0x0)
KEY_PURPOSE_2 (BLOCK0)                             KEY2 purpose                                       = USER R/W (0x0)
KEY_PURPOSE_3 (BLOCK0)                             KEY3 purpose                                       = USER R/W (0x0)
KEY_PURPOSE_4 (BLOCK0)                             KEY4 purpose                                       = USER R/W (0x0)
KEY_PURPOSE_5 (BLOCK0)                             KEY5 purpose                                       = USER R/W (0x0)
SECURE_BOOT_EN (BLOCK0)                            Enables secure boot                                = False R/W (0b0)
SECURE_BOOT_AGGRESSIVE_REVOKE (BLOCK0)             Enables aggressive secure boot key revocation mode = False R/W (0b0)
DIS_DOWNLOAD_MODE (BLOCK0)                         Disables all Download boot modes                   = False R/W (0b0)
ENABLE_SECURITY_DOWNLOAD (BLOCK0)                  Enables secure UART download mode (read/write flas = False R/W (0b0)
                                                   h only)
BLOCK_KEY0 (BLOCK4)
  Purpose: XTS_AES_128_KEY
    Encryption key0 or user data
   = 65 3a b9 80 26 df 99 31 98 2a 30 4f 71 18 7c a7 64 0b 33 db c3 a3 61 1f 3d 9d 80 ef 56 cb 15 25 R/W
BLOCK_KEY1 (BLOCK5)
  Purpose: USER
               Encryption key1 or user data
   = 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
BLOCK_KEY2 (BLOCK6)
  Purpose: USER
               Encryption key2 or user data
   = 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
BLOCK_KEY3 (BLOCK7)
  Purpose: USER
               Encryption key3 or user data
   = 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
BLOCK_KEY4 (BLOCK8)
  Purpose: USER
               Encryption key4 or user data
   = 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
BLOCK_KEY5 (BLOCK9)
  Purpose: USER
               Encryption key5 or user data
   = 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
BLOCK_SYS_DATA2 (BLOCK10)                          System data (part 2)
   = 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

Spi_Pad_Config fuses:
SPI_PAD_CONFIG_CLK (BLOCK1)                        SPI CLK pad                                        = 0 R/W (0b000000)
SPI_PAD_CONFIG_Q (BLOCK1)                          SPI Q (D1) pad                                     = 0 R/W (0b000000)
SPI_PAD_CONFIG_D (BLOCK1)                          SPI D (D0) pad                                     = 0 R/W (0b000000)
SPI_PAD_CONFIG_CS (BLOCK1)                         SPI CS pad                                         = 0 R/W (0b000000)
SPI_PAD_CONFIG_HD (BLOCK1)                         SPI HD (D3) pad                                    = 0 R/W (0b000000)
SPI_PAD_CONFIG_WP (BLOCK1)                         SPI WP (D2) pad                                    = 0 R/W (0b000000)
SPI_PAD_CONFIG_DQS (BLOCK1)                        SPI DQS pad                                        = 0 R/W (0b000000)
SPI_PAD_CONFIG_D4 (BLOCK1)                         SPI D4 pad                                         = 0 R/W (0b000000)
SPI_PAD_CONFIG_D5 (BLOCK1)                         SPI D5 pad                                         = 0 R/W (0b000000)
SPI_PAD_CONFIG_D6 (BLOCK1)                         SPI D6 pad                                         = 0 R/W (0b000000)
SPI_PAD_CONFIG_D7 (BLOCK1)                         SPI D7 pad                                         = 0 R/W (0b000000)

Usb Config fuses:
DIS_USB_JTAG (BLOCK0)                              Disables USB JTAG. JTAG access via pads is control = False R/W (0b0)
                                                   led separately
DIS_USB_DEVICE (BLOCK0)                            Disables USB DEVICE                                = False R/W (0b0)
USB_EXCHG_PINS (BLOCK0)                            Exchanges USB D+ and D- pins                       = False R/W (0b0)
DIS_USB_SERIAL_JTAG_DOWNLOAD_MODE (BLOCK0)         Disables USB-Serial-JTAG download feature in UART  = False R/W (0b0)
                                                   download boot mode

Wdt Config fuses:
WDT_DELAY_SEL (BLOCK0)                             Selects RTC WDT timeout threshold at startup       = False R/W (0b0)
How can I fix the pre-encrypted flash uploading?
Thanks in advance.

ESP_WangYX
Posts: 97
Joined: Mon Jun 28, 2021 12:48 pm

Re: Flash encryption on ESP32-C3 with OTA as Access Point

Postby ESP_WangYX » Thu May 18, 2023 2:55 am

Hello,
From the information you provided regarding efuse, it can be seen that the device has not yet enabled flash encryption. Because `SPI_BOOT_CRYPT_CNT` is still 0b0000. For flash encryption and secure boot, I believe it is divided into two steps:
- how to enable this security feature
- how to operate it after successful enabled.
There are currently two main ways to enable flash encryption:
-The device automatically enables the encryption feature when running firmware(enable flash encryption) for the first time.
-Using scripts(espefuse.py、espsecure.py...) to burn the device's efuse and import encrypted firmware. This way has high requirements for the order of operations, which may be a bit difficult in practical operation.
Either way, you can generate a key in advance and burn it to the device.
Here are some explanations, please refer to: https://docs.espressif.com/projects/esp ... on-process
Additionally, here is an example: https://github.com/espressif/esp-idf/tr ... encryption

david10
Posts: 6
Joined: Wed Mar 15, 2023 6:16 am

Re: Flash encryption on ESP32-C3 with OTA as Access Point

Postby david10 » Thu May 25, 2023 12:18 pm

Thank you for the reply.
On this ESP32C3 it seems I have write protected the SPI_BOOT_CRYPT_CNT so I had to use another ESP32C3 module... on the other module I have enabled this bit, in the partition table I have marked the app partiton as "encrypted" but when I read out the memory content the firmware is still not encrypted, I can clearly see the strings inside the firmware.
What else can I check?

Who is online

Users browsing this forum: Google [Bot], Majestic-12 [Bot] and 85 guests