DRAFT: ESP32-XX hardware flash encryption issue when updating images - "flash imp layer" solution
When hardware flash encryption is enabled, force expected erased value (0xFF) into flash when erasing a region, and also always do a real erase before writing data into flash.
This is handled on this implementation because MCUboot's state machine relies on erased valued data (0xFF) readed from a previously erased region that was not written yet, however when hardware flash encryption is enabled, the flash read always decrypts whats being read from flash, thus a region that was erased would not be read as what MCUboot expected (0xFF).
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/445
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.