mcuboot icon indicating copy to clipboard operation
mcuboot copied to clipboard

DRAFT: ESP32-XX hardware flash encryption issue when updating images - "flash imp layer" solution

Open almir-okato opened this issue 6 months ago • 0 comments

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.

almir-okato avatar May 24 '25 18:05 almir-okato