esp-idf: Unable to boot with Secure Boot and Encrypted Flash (IDFGH-2359)

Environment

  • Development Kit: [ESP32-DEVKIT]

  • Kit version (for WroverKit/PicoKit/): [v1|v2|v3|v4]

  • IDF version : ESP-IDF v4.1-dev-1086-g93a8603c5-dirty

  • Build System: Make

  • Compiler version (run xtensa-esp32-elf-gcc --version to find it): xtensa-esp32-elf-gcc (crosstool-NG esp-2019r2) 8.2.0 Copyright © 2018 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

  • Operating System: Linux(Fedora 30)

  • Power Supply: USB

Problem Description

The problem is that on the terminal the ESP32 dev kit is continuously printing the following message after enabling secure boot and flash encryption and I do follow all the steps from #3548 still facing the issue as below

rst:0x10 (RTCWDT_RTC_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT) flash read err, 1000 ets_main.c 371 ets Jun 8 2016 00:22:57

//Detailed problem description goes here.

Expected Behavior

It should run blink example successfully with secure bootloader and encrypted flash

Actual Behavior

error_cm

Steps to repropduce

Below are the screenshots of menuconfig and commands to reproduce this issue //Detailed problem description goes here. I took blink example from IDF/examples Step1: On menuconfig>securtity options I have set as below

menu_config_security menu_config_Bootloader_verbosity menu_config_partition_table

Step 2: creating .pem file openssl ecparam -name prime256v1 -genkey -noout -out my_secure_boot_signing_key.pem

Step 3: Digesting private key to bin file to flash to efuse and I have used below commands to produce bin files(Both produces same bin file with different names because the fact I’ve used to digest based on same pem file) espsecure.py digest_private_key --keyfile secure_boot_signing_key.pem --keylen 256 my_flash_encryption_key.bin espsecure.py digest_private_key --keyfile secure_boot_signing_key.pem --keylen 256 secure-bootloader-key.bin

Step 4: Burning keys to efuse espefuse.py --port /dev/ttyUSB0 burn_key flash_encryption my_flash_encryption_key.bin espefuse.py --port /dev/ttyUSB0 burn_key secure_boot secure-bootloader-key.bin

Step 5: After 4th step espefuse summary looks like below efuse

Step 6: make bootloader && make partition_table && make -j4 (After this step bootloader.bin size:32.7kb and bootloader-reflash-digest.bin 36.9kb)

Step 7: Encrypting all bins with the my_flash_encryption_key.bin which was produced in step3 esptool.py --chip esp32 --port /dev/ttyUSB0 --baud 921600 --before default_reset --after hard_reset write_flash -z --flash_mode dio --flash_freq 40m --flash_size detect 0x1000 /build/bootloader/bootloader-encrypted.bin

(In menuconfig i have setted parttion offset to 10,000,Inorder to prevent bootloader overirite the partition table which is by default 0x8000) esptool.py --port /dev/ttyUSB0 --baud 921000 write_flash 0x10000 build/partitions_singleapp-encrypted.bin

espsecure.py encrypt_flash_data --keyfile my_flash_encryption_key.bin --address 0x20000 -o build/blink-encrypted.bin build/blink.bin

Step 8: Now flashing each encrypted bin files to the esp flash.

esptool.py --chip esp32 --port /dev/ttyUSB0 --baud 921600 --before default_reset --after hard_reset write_flash -z --flash_mode dio --flash_freq 40m --flash_size detect 0x1000 /build/bootloader/bootloader-encrypted.bin

esptool.py --port /dev/ttyUSB0 --baud 921000 write_flash 0x10000 build/partitions_singleapp-encrypted.bin

esptool.py --port /dev/ttyUSB0 --baud 921000 write_flash 0x20000 build/app-encrypted.bin

Code to reproduce this issue

#include <stdio.h> #include “freertos/FreeRTOS.h” #include “freertos/task.h” #include “driver/gpio.h” #include “sdkconfig.h”

#define BLINK_GPIO CONFIG_BLINK_GPIO

void app_main(void) {

gpio_pad_select_gpio(BLINK_GPIO);
/* Set the GPIO as a push/pull output */
gpio_set_direction(BLINK_GPIO, GPIO_MODE_OUTPUT);
while(1) {
    /* Blink off (output low) */
printf("Turning off the LED\n");
    gpio_set_level(BLINK_GPIO, 0);
    vTaskDelay(1000 / portTICK_PERIOD_MS);
    /* Blink on (output high) */
printf("Turning on the LED\n");
    gpio_set_level(BLINK_GPIO, 1);
    vTaskDelay(1000 / portTICK_PERIOD_MS);
}

}

// If your code is longer than 30 lines, [GIST](https://gist.github.com) is preferred.

## Debug Logs
(https://user-images.githubusercontent.com/3605941/70848008-92c9a080-1e91-11ea-9781-85528d4d7223.png)

## Other items if possible
- [*] sdkconfig file (attach the sdkconfig file from your project folder)
- [*] elf file in the ``build`` folder (**note this may contain all the code details and symbols of your project.**)
- [ ] coredump (This provides stacks of tasks.) 
[blink_elf_and_sdkconfig.zip](https://github.com/espressif/esp-idf/files/3963747/blink_elf_and_sdkconfig.zip)

About this issue

  • Original URL
  • State: closed
  • Created 5 years ago
  • Comments: 18 (7 by maintainers)

Most upvoted comments

  1. Use https with client/server certificates
  2. Encrypt the bin yourself and modify ota to decrypt it before writing to flash
  3. Use a fixed flash encryption key (not recommended)

There is a lot of discussion about this already https://www.google.com/search?q=site%3Aesp32.com+ota+encryption

Hi @kanakamedalasumanth,

Thanks for the updates.

Note: After @projectgus suggested I have tested and flashed plaintext bins, After that I have observed that FLASH_CRYPT_CONFIG has changed to 15

This efuse is not what enables flash encryption. The efuse which enables flash encryption is FLASH_CRYPT_CNT, and this is still zero.

Rather than flashing individual binaries one at a time, please follow exactly the steps I sent you in my previous reply.

Here’s the same link, but for ESP-IDF v3.3.1: https://docs.espressif.com/projects/esp-idf/en/v3.3.1/security/secure-boot.html#how-to-enable-secure-boot

Pay particular attention to steps 5 through 8.

Hi @kanakamedalasumanth ,

Your existing chips are probably still fine and can be recovered.

Your steps 1-6 have set up the device with Secure Boot & Flash Encryption keys burned into the efuse key blocks (BLK1 & BLK2), and you’ve configured the project for Secure Boot & Flash Encryption but these features are not enabled in the hardware yet. You can double check this by running espefuse.py summary again and checking that ABS_DONE_0==0 (set to 1 when secure boot is enabled), and that FLASH_CRYPT_CNT==0 (set to 1 when Flash Encryption is enabled).

Your Steps 7 & 8 prepared pre-encrypted images and flashed them, but because flash encryption is not actually enabled yet the ESP32 sees random bytes in the flash and can’t boot.

The recommended process for enabling Flash Encryption & Secure Boot is to allow the device to enable these features itself on first boot. Because you’ve pre-burned keys in efuse, these keys will be used. But you need to flash plaintext binaries, not encrypted ones. The device will encrypt itself on first boot and enable all the efuses required for Flash Encryption & Secure Boot.

To do the initial flash of plaintext, you can follow these steps from the Secure Boot docs: https://docs.espressif.com/projects/esp-idf/en/latest/security/secure-boot.html#how-to-enable-secure-boot

After the first boot is done and you want to update, you will need to flash pre-encrypted files like what you’ve shown in your Steps 7 & 8.


Because you seem to be in the development phase and using ESP-IDF v4.1-dev, you may also be interested in the new Flash Encryption “development” mode which was added in ESP-IDF v4.x: https://docs.espressif.com/projects/esp-idf/en/latest/security/flash-encryption.html#flash-enc-development-mode

Configuring a project in Development mode allows you to re-flash the encrypted ESP32 without needing to pre-encrypt the binaries on the host, or even keep a copy of the flash encryption key.

In general, you may also want to read or re-read the rest of the documentation pages on Secure Boot & Flash Encryption (linked above).

Angus

Thanks for the update @kanakamedalasumanth , good to hear everything is working now.