Examples of Flash Encryption and NVS Encryption

In the esp-idf/examples/security/flash_encryption directory, we've uploaded an example of flash encryption and NVS encryption. By running this example, you can observe the logs that demonstrate the results of flash encryption and NVS encryption.

As mentioned earlier, when flash encryption is enabled in development mode, the firmware can be flashed repeatedly. To flash the firmware into the device, we have used the following three commands:

Command 1:

$ idf.py -p PORT flash monitor

Command 2:

$ idf.py -p PORT encrypted-flash monitor

Command 3:

$ idf.py -p PORT encrypted-app-flash monitor

The results of running the above three commands are:

  • Command 1: the data stored in flash remains plaintext, resulting in a loading error;

  • Command 2: only the encrypted bootloader, app firmware, and partition table are flashed, and can be loaded and run on the device without any issues;

  • Command 3: only the encrypted app firmware is flashed; if the bootloader is also encrypted, the firmware can be loaded and run on the device.

The above three commands actually call esptool.py internally. The corresponding settings of esptool.py are:

$ esptool.py --chip esp32c3 -p /dev/ttyUSB0 -b 460800 --before=default_reset --after= no_reset write_flash --flash_mode dio --flash_freq 40m --flash_size 2MB 0x1000 bootloader/bootloader 0x20000 flash_encryption.bin 0xa000 partition_table/partition-table.bin

$ esptool.py --chip esp32c3 -p /dev/ttyUSB0 -b 460800 --before=default_reset --after= no_reset write_flash --flash_mode dio --flash_freq 40m --flash_size 2MB --encrypt 0x1000 bootloader/bootloader 0x20000 flash_encryption.bin 0xa000 partition_table/partition-table.bin

$ esptool.py --chip esp32c3 -p /dev/ttyUSB0 -b 460800 --before=default_reset --after= no_reset write_flash --flash_mode dio --flash_freq 40m --flash_size 2MB --encrypt 0x20000 flash_encryption.bin

By examining the settings of the commands, we can conclude that when using esptool.py for flashing, adding the option --encrypt will enable automatic flash encryption and write the encrypted data into flash.

Below are several typical failure cases when enabling flash encryption:

  • If the bootloader is plaintext, the following failure may occur when starting the device:

    rst:0x3 (SW_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
    invalid header: 0xb414f76b
    invalid header: 0xb414f76b
    invalid header: 0xb414f76b
    invalid header: 0xb414f76b
    invalid header: 0xb414f76b
    invalid header: 0xb414f76b
    invalid header: 0xb414f76b
    
  • If the partition is plaintext, the following failure may occur when starting the device:

    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:DIO, clock div:2
    load:0x3fff0018,len:4
    load:0x3fff001c,len:10464
    ho 0 tail 12 room 4
    load:0x40078000,len:19168
    load:0x40080400,len:6664
    entry 0x40080764
    I (60) boot: ESP-IDF v4.0-dev-763-g2c55fae6c-dirty 2nd stage bootloader
    I (60) boot: compile time 19:15:54
    I (62) boot: Enabling RNG early entropy source...
    I (67) boot: SPI Speed       : 40MHz
    I (72) boot: SPI Mode        : DIO
    I (76) boot: SPI Flash Size : 4MB
    E (80) flash_parts: partition 0 invalid magic number 0x94f6
    E (86) boot: Failed to verify partition table
    E (91) boot: load partition table error!
    
  • If the app firmware is plaintext, the following failure may occur when starting the device:

    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:DIO, clock div:2
    load:0x3fff0018,len:4
    load:0x3fff001c,len:8452
    load:0x40078000,len:13616
    load:0x40080400,len:6664
    entry 0x40080764
    I (56) boot: ESP-IDF v4.0-dev-850-gc4447462d-dirty 2nd stage bootloader
    I (56) boot: compile time 15:37:14
    I (58) boot: Enabling RNG early entropy source...
    I (64) boot: SPI Speed          : 40MHz
    I (68) boot: SPI Mode           : DIO
    I (72) boot: SPI Flash Size : 4MB
    I (76) boot: Partition Table:
    I (79) boot: ## Label           Usage          Type ST Offset   Length
    I (87) boot:  0 nvs             Wi-Fi data      01 02 0000a000 00006000
    I (94) boot:  1 phy_init        RF data         01 01 00010000 00001000
    I (102) boot:  2 factory        factory app     00 00 00020000 00100000
    I (109) boot: End of partition table
    E (113) esp_image: image at 0x20000 has invalid magic byte
    W (120) esp_image: image at 0x20000 has invalid SPI mode 108
    W (126) esp_image: image at 0x20000 has invalid SPI size 11
    E (132) boot: Factory app partition is not bootable
    E (138) boot: No bootable app partitions in the partition table