The flash encryption key is stored in
BLOCK_KEY. There are two methods to write the key into eFuse:
espsecure.py to manually generate a key and write it into eFuse. This method can only be used before enabling flash encryption for the first time.
After flash encryption is enabled in
menuconfig, the device will automatically generate a key in the bootloader when it starts up for the first time, and automatically save the key in eFuse.
To manually write the flash encryption key into eFuse, first run the following command to generate the key:
$ espsecure.py generate_flash_encryption_key my_flash_encryption_key.bin
Then, run the following command to write the key into eFuse:
$ espefuse.py --port PORT burn_key BLOCK my_flash_encryption_key.bin XTS_AES_128_KEY
Since writing eFuse is irreversible, manual writing of the key into eFuse can only be performed once.
Flash encryption can be enabled through
menuconfig → Security features → Enable flash encryption on boot. If flash encryption is enabled in
building stage and the key has not been manually written into eFuse in
advance, then after the firmware is flashed, the device will enable
flash encryption, automatically generate a key, and write it into eFuse.
The main difference between the manual method and automatic method is
that with the manual method, you can know the content of the key and use
a script tool to encrypt the data before flashing it into the device.
With the automatic method, if the read protection of
enabled in the eFuse (which is enabled by default), the key is generated
inside the device and stored directly in the read-protected eFuse,
making it impossible for external developers to obtain the key or
manually encrypt/decrypt the data.
In manual mode, use the following command to encrypt the app firmware, and flash it to the device:
$ espsecure.py encrypt_flash_data --aes_xts --keyfile /path/to/key.bin --address 0x10000 --output my-app-ciphertext.bin build/my-app
It is important to note that when using the aforementioned command for
data encryption, you must specify the storage address of the data in the
partition table. In the command provided, the data being encrypted is
my-app, with its address set to 0x10000. As emphasised in Section
13.3.2, flash encryption relies on the tweakable block cipher AES-XTS,
and therefore, the accurate data address must be specified. Failure to
specify or incorrectly specifying the address will result in device
failure after flashing the encrypted firmware.
Furthermore, it is worth mentioning that if the encryption key is known,
the script tool
espsecure.py can also be used to decrypt the data.
Running the command
espsecure.py-h will provide helpful information regarding the usage of the script tool.
During the mass production of devices, it is highly recommended to utilise the automatic method for key writing. This ensures that each device is assigned a unique key that remains inaccessible from external sources, thus maximising the overall security of the device.