Skip to content

DRAFT: ESP32-XX hardware flash encryption issue when updating images - "bootutil layer" solution #2321

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 5 commits into
base: main
Choose a base branch
from

Conversation

almir-okato
Copy link
Collaborator

@almir-okato almir-okato commented May 24, 2025

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:
zephyrproject-rtos/zephyr#90442
Use hal_espressif branch from this PR:
zephyrproject-rtos/hal_espressif#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.

…sif Port

Signed-off-by: Almir Okato <almir.okato@espressif.com>
Signed-off-by: Almir Okato <almir.okato@espressif.com>
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.

Signed-off-by: Almir Okato <almir.okato@espressif.com>
…L BE DELETED

Signed-off-by: Almir Okato <almir.okato@espressif.com>
Signed-off-by: Almir Okato <almir.okato@espressif.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant