Problem enabling SecureBoot and FlashEncryption
Posted: Mon May 25, 2020 5:43 pm
Hello
I am working on a project that uses the ESP32 (wroom32) and I am doing an "auto config/build/flash" tool and i have some problems with the security options.
I am using ESP32 with the ESP-IDF environment for building. I am trying to enable SecureBoot (V1, as the chips seem too old for V2) and Flash encryption.
I have configured with idf.py menuconfig the following: SecureBoot one time flash and FlashEncryption in developer mode (I don't want the OTA updates). I am using for the secure boot a openssl generated key and for the flash a key generated with the espsecure.py generate_flash_encryption_key.
After having the keys generated and the config done I write the flash key (using espefuse.py burn_key flash_encryption); I do a full clean (noticed that otherwise the signing certificate is not updated or something was not working with the secure boot), build the bootloader (idf.py bootloader), build the rest of the images (idf.py build) and flash everything (in one command) not encrypted, in plain text, to the target (using esptool).
I expected that, as mentioned in https://docs.espressif.com/projects/esp ... ption.html (The image will include the firmware bootloader, partition table, application, and other partitions marked by the user as encrypted. These binaries will be written to flash memory unencrypted. Once the flashing is complete, your device will reset. On the next boot, the firmware bootloader encrypts the flash application partition and then resets. After that, the sample application is decrypted at runtime and executed.) the ESP32 will start the encryption process and this will in the end reset the device and after that it will work.
What actually happens is:
1) after the flash I get constant bootloader errors:
2) i can see with espfuse that the fuse config was done for the flashencrypt
To recover from this, the only solution I found was: to burn the FLASH_CRYPT_CNT (espefuse.py burn_efuse FLASH_CRYPT_CNT) and to make another flash after I have manually encrypted everything. Doing this the ESP32 works and it seems encrypted and with secure boot active but it seems that the process is not correct.
Questions:
1) Is this normal, did I misunderstand the auto encrypt with a self generated key process
2) Can the fullclean be easily avoided?
3) will idf.py build also build the bootloader if the SecureBoot is active; in the docs it says at least that idf.py flash will not write the bootloader (if secure boot is active), but for me it is not clear if it should be built, and if it will be signed like the images?
4) Is it normal that even with the secure boot enabled I can actually reflash the bootloader? If I for example flash it again with one encrypted with a different key the board stops working and sends errors like the one above until I flash again with one encrypted with the correct key. The docs say: "Remember this is a one time flash, you can’t change the bootloader after this!." so I thought the the flashing will just fail, not that it won't work afterwards.
5)What happens if I have a board with secure boot active and afterwards I try to enable flashencryption? From my personal exp it seems sw bricked, and the option is not working. If possible, what are the steps, if not may I suggest adding the info in the SecureBoot that if this is done flash encryption can't be activated anymore?
6) can someone pls write the required steps for this config: Secure boot one time only flash with flashencryption enabled in Dev mode.
I am working on a project that uses the ESP32 (wroom32) and I am doing an "auto config/build/flash" tool and i have some problems with the security options.
I am using ESP32 with the ESP-IDF environment for building. I am trying to enable SecureBoot (V1, as the chips seem too old for V2) and Flash encryption.
I have configured with idf.py menuconfig the following: SecureBoot one time flash and FlashEncryption in developer mode (I don't want the OTA updates). I am using for the secure boot a openssl generated key and for the flash a key generated with the espsecure.py generate_flash_encryption_key.
After having the keys generated and the config done I write the flash key (using espefuse.py burn_key flash_encryption); I do a full clean (noticed that otherwise the signing certificate is not updated or something was not working with the secure boot), build the bootloader (idf.py bootloader), build the rest of the images (idf.py build) and flash everything (in one command) not encrypted, in plain text, to the target (using esptool).
I expected that, as mentioned in https://docs.espressif.com/projects/esp ... ption.html (The image will include the firmware bootloader, partition table, application, and other partitions marked by the user as encrypted. These binaries will be written to flash memory unencrypted. Once the flashing is complete, your device will reset. On the next boot, the firmware bootloader encrypts the flash application partition and then resets. After that, the sample application is decrypted at runtime and executed.) the ESP32 will start the encryption process and this will in the end reset the device and after that it will work.
What actually happens is:
1) after the flash I get constant bootloader errors:
Code: Select all
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
Code: Select all
EFUSE_NAME Description = [Meaningful Value] [Readable/Writeable] (Hex Value)
----------------------------------------------------------------------------------------
Efuse fuses:
WR_DIS Efuse write disable mask = 128 R/W (0x80)
RD_DIS Efuse read disablemask = 1 R/W (0x1)
CODING_SCHEME Efuse variable block length scheme = 0 R/W (0x0)
KEY_STATUS Usage of efuse block 3 (reserved) = 0 R/W (0x0)
Security fuses:
FLASH_CRYPT_CNT Flash encryption mode counter = 0 R/W (0x0)
FLASH_CRYPT_CONFIG Flash encryption config (key tweak bits) = 15 R/W (0xf)
CONSOLE_DEBUG_DISABLE Disable ROM BASIC interpreter fallback = 1 R/W (0x1)
ABS_DONE_0 secure boot enabled for bootloader = 0 R/W (0x0)
ABS_DONE_1 secure boot abstract 1 locked = 0 R/W (0x0)
JTAG_DISABLE Disable JTAG = 1 R/W (0x1)
DISABLE_DL_ENCRYPT Disable flash encryption in UART bootloader = 0 R/W (0x0)
DISABLE_DL_DECRYPT Disable flash decryption in UART bootloader = 1 R/W (0x1)
DISABLE_DL_CACHE Disable flash cache in UART bootloader = 1 R/W (0x1)
BLK1 Flash encryption key
= ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? -/-
BLK2 Secure boot key
= 9e 44 2f ed 44 8c 91 05 0a 6a 94 02 09 77 30 17 44 3a 1b 0b 88 8f 19 aa 8f a8 89 92 2f 83 76 d7 R/W
BLK3 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
Calibration fuses:
BLK3_PART_RESERVE BLOCK3 partially served for ADC calibration data = 0 R/W (0x0)
ADC_VREF Voltage reference calibration = 1114 R/W (0x2)
Config fuses:
XPD_SDIO_FORCE Ignore MTDI pin (GPIO12) for VDD_SDIO on reset = 0 R/W (0x0)
XPD_SDIO_REG If XPD_SDIO_FORCE, enable VDD_SDIO reg on reset = 0 R/W (0x0)
XPD_SDIO_TIEH If XPD_SDIO_FORCE & XPD_SDIO_REG, 1=3.3V 0=1.8V = 0 R/W (0x0)
CLK8M_FREQ 8MHz clock freq override = 52 R/W (0x34)
SPI_PAD_CONFIG_CLK Override SD_CLK pad (GPIO6/SPICLK) = 0 R/W (0x0)
SPI_PAD_CONFIG_Q Override SD_DATA_0 pad (GPIO7/SPIQ) = 0 R/W (0x0)
SPI_PAD_CONFIG_D Override SD_DATA_1 pad (GPIO8/SPID) = 0 R/W (0x0)
SPI_PAD_CONFIG_HD Override SD_DATA_2 pad (GPIO9/SPIHD) = 0 R/W (0x0)
SPI_PAD_CONFIG_CS0 Override SD_CMD pad (GPIO11/SPICS0) = 0 R/W (0x0)
DISABLE_SDIO_HOST Disable SDIO host = 0 R/W (0x0)
Identity fuses:
MAC Factory MAC Address
= a4:cf:12:7c:a0:98 (CRC 0x9b OK) R/W
CHIP_VER_REV1 Silicon Revision 1 = 1 R/W (0x1)
CHIP_VER_REV2 Silicon Revision 2 = 0 R/W (0x0)
CHIP_VERSION Reserved for future chip versions = 2 R/W (0x2)
CHIP_PACKAGE Chip package identifier = 0 R/W (0x0)
Flash voltage (VDD_SDIO) determined by GPIO12 on reset (High for 1.8V, Low/NC for 3.3V).
Questions:
1) Is this normal, did I misunderstand the auto encrypt with a self generated key process
2) Can the fullclean be easily avoided?
3) will idf.py build also build the bootloader if the SecureBoot is active; in the docs it says at least that idf.py flash will not write the bootloader (if secure boot is active), but for me it is not clear if it should be built, and if it will be signed like the images?
4) Is it normal that even with the secure boot enabled I can actually reflash the bootloader? If I for example flash it again with one encrypted with a different key the board stops working and sends errors like the one above until I flash again with one encrypted with the correct key. The docs say: "Remember this is a one time flash, you can’t change the bootloader after this!." so I thought the the flashing will just fail, not that it won't work afterwards.
5)What happens if I have a board with secure boot active and afterwards I try to enable flashencryption? From my personal exp it seems sw bricked, and the option is not working. If possible, what are the steps, if not may I suggest adding the info in the SecureBoot that if this is done flash encryption can't be activated anymore?
6) can someone pls write the required steps for this config: Secure boot one time only flash with flashencryption enabled in Dev mode.