fdcavalcanti opened a new pull request, #17475:
URL: https://github.com/apache/nuttx/pull/17475
## Summary
- documentation: update flash encryption docs for Espressif devices
- espressif: automate build system for flash enc
- arch/xtensa: add critical section on e-fuse bringup
- arch/xtensa: change .bss clear location on start
- arch/xtensa: flash encryption support for ESP32|S2|S3
- arch/risc-v: flash encryption support for ESP32-C3|C6|H2
This PR adds flash encryption support to Espressif devices.
Flash encryption is intended for encrypting the contents of the ESP32's
off-chip flash memory. Once this feature is enabled, firmware is flashed as
plaintext, and then the data is encrypted in place on the first boot. As a
result, physical readout of flash will not be sufficient to recover most flash
contents.
The current state of flash encryption allows the use of Virtual E-Fuses and
development mode, which permit users to evaluate and test the firmware before
making definitive changes such as burning E-Fuses.
**Main changes:**
- Adds new documentation subsection under MCUBoot regarding use of flash
encryption.
- Modifies Kconfig and build tools to support flash encryption and E-Fuse
burning when flash encryption is enabled.
- Deprecates `ESP32_STORAGE_MTD_ENCRYPT` and `ESP32_OTA_PARTITION_ENCRYPT`
options. Add `ESPRESSIF_SECURE_FLASH_ENC_ENABLED` Kconfig option.
- Updates SPI Flash driver to handle encryption automatically.
- Add Kconfig option to enable flash encryption. Default E-Fuse state is now
VIRTUAL.
- Modifies SPI Flash driver for encrypted operation. Limitations:
- Requires MCUBoot
- Flash fully encrypted (no unencrypted MTD part. support)
## Impact
- Impact on user: Adds flash encryption feature.
- Impact on build: Building with Flash Encryption will give additional
warnings to the user. Also, if flashing a device with encryption, the user will
be prompted to confirm the e-fuse burning.
- Impact on hardware: Affects all Espressif devices: ESP32-S2-S3-C3-C6-H2
- Impact on documentation: Yes, adds documentation regarding flash
encryption for devices mentioned above.
- Impact on security: No.
- Impact on compatibility: No. The previous flash encryption was related to
legacy bootloader, which is not the case anymore.
## Testing
### Building
Build the `mcuboot_nsh` defconfig, then enable flash encryption. Virtual
E-Fuses are enabled by default but should be disabled when using QEMU.
- ./tools/configure.sh esp32-devkitc:mcuboot_nsh
- Enter: System Type → Bootloader and Image Configuration and enable
CONFIG_ESP32_SECURE_FLASH_ENC_ENABLED
- Enter: System Type → ESP32 Peripheral Selection and disable
CONFIG_ESPRESSIF_EFUSE_VIRTUAL (QEMU demonstration)
- Enter: System Type → ESP32 Peripheral Selection and enable ESP32_SPIFLASH
- Enter: Board Selection and enable CONFIG_ESP32_QEMU_IMAGE and
CONFIG_ESP32_SPIFLASH_FS
- make bootloader and make
Those settings will enable a QEMU build with flash encryption and SPI Flash.
Build log **should prompt the user to generate a encryption key**, and then
build is completed with:
```
...
Flash Encryption is enabled!
Applying encryption to user MTD partition on flash.
Encrypting user MTD partition offset: 0x260000, size: 0x100000 (1048576)
...
esptool.py -c esp32 merge_bin --output nuttx.merged.bin --fill-flash-size
4MB -fm dio -ff "40m" 0x1000 .//mcuboot-esp32.bin 0x10000 vefuse.bin 0x20000
nuttx.bin 0x260000 enc_mtd.bin
```
### Running
1- Create the virtual efuse binary required by QEMU so we can properly test
encryption:
```
python3 -c 'd=bytearray(124); d[0x0d]=0x80; d[0x16]=0x10;
open("qemu_efuse.bin","wb").write(d);'
```
2- Start QEMU:
```
qemu-system-xtensa -nographic -machine esp32 -m 4M \
-drive file=nuttx.merged.bin,if=mtd,format=raw \
-drive file=qemu_efuse.bin,if=none,format=raw,id=efuse \
-global driver=esp32.gpio,property=strap_mode,value=0x12 \
-global driver=nvram.esp32.efuse,property=drive,value=efuse
```
The bootloader will encrypt the binary on the first boot. Following QEMU
sessions will already be encrypted.
```
...
[esp32] [INF] [flash_encrypt] Encrypting bootloader...
[esp32] [INF] [flash_encrypt] Bootloader encrypted successfully
[esp32] [INF] [flash_encrypt] Encrypting primary slot...
[esp32] [INF] [flash_encrypt] Encrypting remaining flash...
[esp32] [INF] [flash_encrypt] Flash encryption completed
....
```
### Results
To test encryption works, we can simply write a test file to our user
partition and then attempt to read its location on the binary.
The file system is mounted automatically during boot. We write a small file
to it.
```
nsh> echo "nuttx PR test!" > /data/test.txt
nsh> ls /data
/data:
.
..
test.txt
```
Now with the assistance of a Python script or any hex dumping tool, we try
to read the user partition flash offset at 0x260000:
```
$ binary_reader.py nuttx.merged.bin 0x260000 1000
Reading 1000 bytes from offset 0x260000 in nuttx.merged.bin:
------------------------------------------------------------
[...]
3d d8 88 12 2c 86 4d fa 1d 69 3a bb 84 09 f3 14 8f 44 ed 8b 11 4d 61 1f 93
fc ef e4 b6 1e 6f 47 7c a1 cc e6 36 75 4a d8 b8 0a ab cc 14 14 3a e5 e4 3b d7
8f 59 47 d3 66 44 67 04 1d fc e1 04 01 9c 49 27 d7 13 1f fa e5 7f 19 88 03 e1
61 59 79 9c 49 27 d7 13 1f fa e5 7f 19 88 03 e1 61 59 79 9a 0b 36 62 1b bb e7
b7 23 87 0f 9b 30 d8 ca b2 9a 0b 36 62 1b bb e7 b7 23 87 0f 9b 30 d8 ca b2 d8
ce 68 82 b7 f6 b2 e0 72 e4 ee ee 13 [...]
```
The data is mostly garbage, which for us means it is encrypted. For
comparison, the output below is from a non-encrypted build:
```
$ binary_reader.py --format ascii nuttx.merged.bin 0x260000 10000
Reading 10000 bytes from offset 0x260000 in nuttx.merged.bin:
------------------------------------------------------------
[...]
............................................................................
............................................................................
....................................i.....nuttx PR test! ...................
...........................................................
..........................................................
```
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]