Skip to content

Instantly share code, notes, and snippets.

@jessebraham
Last active June 9, 2024 08:00
Show Gist options
  • Save jessebraham/0c7d86f9866614dc602e5d8e0e97c37a to your computer and use it in GitHub Desktop.
Save jessebraham/0c7d86f9866614dc602e5d8e0e97c37a to your computer and use it in GitHub Desktop.

Flash Encryption Instructions

For more details instructions please see the official ESP-IDF documentation:

https://docs.espressif.com/projects/esp-idf/en/latest/esp32c3/security/flash-encryption.html

std

TODO

no_std

We require esp-idf in order to build the bootloader:

$ mkdir -p ~/esp
$ cd ~/esp
$ git clone --recursive https://github.com/espressif/esp-idf

We can use any project to build the bootloader. Set the correct target and then configure the bootloader for flash encryption:

$ cd ~/esp/esp-idf/examples/get-started/hello_world/
$ idf.py set-target $CHIP
$ idf.py menuconfig

Enable the Security Features -> Enable flash encryption on boot setting. Usage mode is set to Development by default, can also be set to Production if desired. Remember to check the minimum chip revision is compatible with your chip as well. Exit menuconfig and save.

Build the bootloader and move it to your project:

$ idf.py build bootloader
$ cp build/bootloader/bootloader.bin $PROJECT_DIR

For example, we can test using the esp32c3-hal package's examples from esp-hal:

$ cargo espflash --release --monitor --bootloader=bootloader.bin --example=hello_world

Upon first boot the device will generate a key and self-encrypt. The second-stage bootloader logs the process to the serial monitor (this can take some time):

I (51) boot: ESP-IDF v5.0-dev-3290-g01d014c42d-dirty 2nd stage bootloader
I (52) boot: compile time 09:50:23
I (52) boot: chip revision: 2
I (56) boot.esp32c3: SPI Speed      : 80MHz
I (60) boot.esp32c3: SPI Mode       : DIO
I (65) boot.esp32c3: SPI Flash Size : 4MB
I (70) boot: Enabling RNG early entropy source...
I (75) boot: Partition Table:
I (79) boot: ## Label            Usage          Type ST Offset   Length
I (86) boot:  0 nvs              WiFi data        01 02 00009000 00006000
I (93) boot:  1 phy_init         RF data          01 01 0000f000 00001000
I (101) boot:  2 factory          factory app      00 00 00010000 003f0000
I (108) boot: End of partition table
I (113) boot_comm: chip revision: 2, min. application chip revision: 0
I (120) esp_image: segment 0: paddr=00010020 vaddr=3c010020 size=00508h (  1288) map
I (129) esp_image: segment 1: paddr=00010530 vaddr=00000000 size=0fae8h ( 64232)
I (147) esp_image: segment 2: paddr=00020020 vaddr=42000020 size=01ca8h (  7336) map
I (148) boot: Loaded app from partition at offset 0x10000
I (151) boot: Checking flash encryption...
I (156) esp_image: segment 0: paddr=00000020 vaddr=3fcd6270 size=02c88h ( 11400)
I (165) esp_image: segment 1: paddr=00002cb0 vaddr=403ce000 size=00904h (  2308)
I (172) esp_image: segment 2: paddr=000035bc vaddr=403cf600 size=048b4h ( 18612)
I (579) flash_encrypt: bootloader encrypted successfully
I (626) flash_encrypt: partition table encrypted and loaded successfully
I (626) boot_comm: chip revision: 2, min. application chip revision: 0
I (629) esp_image: segment 0: paddr=00010020 vaddr=3c010020 size=00508h (  1288) map
I (638) esp_image: segment 1: paddr=00010530 vaddr=00000000 size=0fae8h ( 64232)
I (656) esp_image: segment 2: paddr=00020020 vaddr=42000020 size=01ca8h (  7336) map
I (657) flash_encrypt: Encrypting partition 2 at offset 0x10000 (length 0x3f0000)...
I (50652) flash_encrypt: Done encrypting
I (50653) efuse: BURN BLOCK0
I (50655) efuse: BURN BLOCK0 - OK (all write block bits are set)
I (50656) flash_encrypt: Flash encryption completed
I (50661) boot: Resetting with flash encryption enabled...

Upon completing the encryption process the device will reset itself and run the application:

I (57) boot: ESP-IDF v5.0-dev-3290-g01d014c42d-dirty 2nd stage bootloader
I (57) boot: compile time 09:50:23
I (57) boot: chip revision: 2
I (61) boot.esp32c3: SPI Speed      : 80MHz
I (66) boot.esp32c3: SPI Mode       : DIO
I (71) boot.esp32c3: SPI Flash Size : 4MB
I (75) boot: Enabling RNG early entropy source...
I (81) boot: Partition Table:
I (84) boot: ## Label            Usage          Type ST Offset   Length
I (92) boot:  0 nvs              WiFi data        01 02 00009000 00006000
I (99) boot:  1 phy_init         RF data          01 01 0000f000 00001000
I (107) boot:  2 factory          factory app      00 00 00010000 003f0000
I (114) boot: End of partition table
I (118) boot_comm: chip revision: 2, min. application chip revision: 0
I (126) esp_image: segment 0: paddr=00010020 vaddr=3c010020 size=00508h (  1288) map
I (134) esp_image: segment 1: paddr=00010530 vaddr=00000000 size=0fae8h ( 64232)
I (153) esp_image: segment 2: paddr=00020020 vaddr=42000020 size=01ca8h (  7336) map
I (155) boot: Loaded app from partition at offset 0x10000
I (157) boot: Checking flash encryption...
I (161) flash_encrypt: flash encryption is enabled (0 plaintext flashes left)
I (169) boot: Disabling RNG early entropy source...
Hello world!
Hello world!
Hello world!

To disable flash encryption once enabled, you must burn the correct eFuse.

For ESP32:

$ espefuse.py burn_efuse FLASH_CRYPT_CNT

For ESP32-C2, ESP32-C3, ESP32-S2, and ESP32-S3:

$ espefuse.py burn_efuse SPI_BOOT_CRYPT_CNT
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment