How to validate flash encryption in Development mode?

sidwarkd
Posts: 9
Joined: Mon Aug 02, 2021 9:34 pm

How to validate flash encryption in Development mode?

Postby sidwarkd » Sat Feb 11, 2023 11:47 pm

I am trying to learn more about flash encryption and have read the docs multiple times but am still confused as to why I can dump encrypted flash in development mode with esptool.py and see plain strings. I followed the instructions in the documentation by enabling flash encryption and allowing the first boot to happen. I saw the bootloader output saying it was encrypting the partitions and all booted fine. When I use idf.py flash I get the error as expected that the firmware isn't valid. If I use idf.py encrypted-flash everything works fine. However, when I use esptool.py to dump the contents of flash it is not encrypted at all as I can see all strings in plaintext.

In the ESP32 technical reference it says that the decrypt block is disabled in Download mode when DISABLE_DL_DECRYPT is set, which the first flash does after enabling flash encryption.

So I have a couple of questions:
1. What steps/settings can I follow with a brand new device to enable flash encryption and then see on a run of esptool.py that the contents are, indeed, encrypted?
2. What is idf.py encrypted-flash doing different than idf.py flash? I thought the flash was updated with plaintext and then encrypted by the device on boot.

Here is the dump of my efuses for validation. The count is higher because I disabled and reenabled encryption but the results are the same. I can still see everything in plaintext in the dumped binary.

Code: Select all

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                      = 1058 R/W (0b10110)

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                           = 32896 R/W (0x8080)
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                               
   = 24:0a:c4:c1:2e:88 (CRC 0x4b OK) R/W 
MAC_CRC (BLOCK0):                                  CRC8 for factory MAC address                       = 75 R/W (0x4b)
CHIP_VER_REV1 (BLOCK0):                            Silicon Revision 1                                 = True R/W (0b1)
CHIP_VER_REV2 (BLOCK0):                            Silicon Revision 2                                 = False R/W (0b0)
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                      = 7 R/W (0b0000111)
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/- (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     = False R/W (0b0)
JTAG_DISABLE (BLOCK0):                             Disable JTAG                                       = True R/W (0b1)
DISABLE_DL_ENCRYPT (BLOCK0):                       Disable flash encryption in UART bootloader        = False R/- (0b0)
DISABLE_DL_DECRYPT (BLOCK0):                       Disable flash decryption in UART bootloader        = True R/- (0b1)
DISABLE_DL_CACHE (BLOCK0):                         Disable flash cache in UART bootloader             = True R/- (0b1)
BLOCK1 (BLOCK1):                                   Flash encryption key                              
   = ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? -/- 
BLOCK2 (BLOCK2):                                   Secure boot 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 
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 
Thanks so much for any assistance in helping me understand this better.

ESP_Sprite
Posts: 9709
Joined: Thu Nov 26, 2015 4:08 am

Re: How to validate flash encryption in Development mode?

Postby ESP_Sprite » Sun Feb 12, 2023 1:34 am

Are you sure you're not seeing remnants of older, unencrypted programming sessions?

sidwarkd
Posts: 9
Joined: Mon Aug 02, 2021 9:34 pm

Re: How to validate flash encryption in Development mode?

Postby sidwarkd » Sun Feb 12, 2023 5:55 am

:roll: Wow, don't I feel foolish. As part of enabling flash encryption I left bootloader logging on and, therefore, had to move the app partition after making more room for the bootloader. This is exactly what was going on. I did an idf.py erase_flash followed by an idf.py encrypted-flash. Everything ran fine and then I used esptool.py to dump the flash contents and confirmed it is fully encrypted.

This probably would have been obvious if I used a tool like dd to extract the actual partition from the full dump. Thanks @ESP_Sprite for the quick reply and pointing me in the right direction.

Who is online

Users browsing this forum: MicroController and 190 guests