DRAFT: ESP32-XX hardware flash encryption issue when updating images - "bootutil layer" solution
bootutil: add MCUBOOT_FLASH_HAS_HW_ENCRYPTION config-condition MCUboot's state machine relies on erased valued data (e.g. 0xFF) readed from this erased region that could be not written before, however if the flash device has hardware flash encryption and its flash read operation always decrypts what is being read from flash, thus a region that was erased would not be read as what MCUboot expected (after erasing, the region physically contains 0xFF, but once reading it, flash controller decrypts 0xFF to something else).
So this configuration force the erased value into the region after the erasing the trailer regions, and also make an erase operation before writing trailers.
NOTE that for other ports, this configuration needs to be added, and flash implementation of flash_area_erase must be able to erase unaligned regions (could be through software algorithm).
Use Zephyr branch from this PR: https://github.com/zephyrproject-rtos/zephyr/pull/90442 Use hal_espressif branch from this PR: https://github.com/zephyrproject-rtos/hal_espressif/pull/446
Prepare and enable Flash Encryption on ESP32-S3 (the conf files are already modified on the used branches):
- Create a "zeroed" key (TEST ONLY, so the device will not be bricked):
dd if=/dev/zero of=zero_key.bin bs=1 count=32
- Burn the key into the eFuses:
espefuse.py -p /dev/ttyUSB0 burn_key BLOCK_KEY4 zero_key.bin XTS_AES_128_KEY
- Burn the eFuse that enabled Flash Encryption
espefuse.py burn_efuse SPI_BOOT_CRYPT_CNT
Building the sample application on Zephyr:
cd <ZEPHYRPROJECT_DIR>/zephyr/samples/subsys/mgmt/mcumgr/smp_svr/
west build -b esp32s3_devkitm/esp32s3/procpu -p -- -DEXTRA_CONF_FILE="overlay-bt.conf"
- Flash the image (will be force encrypted, since the encryption is already enabled on the device and we are using the DEVELOPMENT configs):
esptool.py -p /dev/ttyUSB0 -b 2000000 --no-stub --after no_reset write_flash --flash_mode dio --flash_freq 40m --encrypt 0x0020000 build/zephyr/zephyr.signed.bin --force
- For the update image, flash it on the second slot
esptool.py -p /dev/ttyUSB0 -b 2000000 --no-stub --after no_reset write_flash --flash_mode dio --flash_freq 40m --encrypt 0x00170000 build/zephyr/zephyr.signed.bin --force
- Also, the confirmed image (
build/zephyr/zephyr.signed.confirmed.bin) can be used for testing the scenario in which an image is already confirmed
Building and flashing MCUboot:
cd <MCUBOOT_DIR>/boot/espressif
(MCUBOOT_DIR should be the directory from Zephyr environment: <ZEPHYRPROJECT_DIR>/bootloader/mcuboot)
- Build:
rm -rf build/ && cmake -DCMAKE_TOOLCHAIN_FILE=tools/toolchain-esp32s3.cmake -DMCUBOOT_TARGET=esp32s3 -DMCUBOOT_FLASH_PORT=/dev/ttyUSB0 -DESP_HAL_PATH=<ZEPHYRPROJECT_DIR>/modules/hal/espressif -B build -GNinja && ninja -C build
- Flash:
esptool.py -p /dev/ttyUSB0 -b 2000000 --no-stub --after no_reset write_flash --flash_mode dio --flash_freq 40m --encrypt 0x0000 build/mcuboot_esp32s3.bin --force
- Now open the serial monitor and press the devkit's reset button.