WiFive wrote:
The other option is to generate a high entropy random key off-device and program it into the efuse memory, but again the recommendation is to flash a plaintext firmware first.
This is primarily a security recommendation, because in other configuration it's tempting to share the same key across all devices. This means that disclosure of one key (via, for example, a factory leak or side channel power analysis) would potentially compromise all devices. Whereas with the on-device key generation, there is no predistributed key for a factory to leak and side channel analysis is only per-device.
If you're not worried about these kind of compromises then you can do whatever you think is wise.
WiFive wrote:
So the question becomes is it possible to flash a pre-encrypted firmware over uart or to have the stub loader encrypt on write or to write pre-encrypted directly to the flash chip using external spi interface and then manually set the FLASH_CRYPT_CNT to 1 so the flash is not reencrypted?
You can pre-encrypt data using the 'espsecure.py encrypt_flash_data` command (mentioned in the flash encryption documents) and then flash it. This is also a relative slow process if using per-device keys (the encryption algorithm is implemented unoptimised in Python so far) but it happens off-device so you have some flexibility about when/how you do it.
However the only supported way to write the pre-generated key to efuse and also burn FLASH_CRYPT_CNT is via the serial loader, or following the "encrypt all partitions on first boot" flow.
You could write a custom bootloader that does this on first boot, however. The existing "encrypt on first boot" logic will skip any app partition which doesn't hold an unencrypted app, so you should be able still make an initial unencrypted boot and have it only encrypt the bootloader and partiton table (which would need to be plaintext, but are much smaller so quicker to encrypt) and set FLASH_CRYPT_CNT before rebooting for a fully encrypted boot.
The additional first boot logic you'd need would involve reading the flash key from a preprogrammed flash sector or partition, writing it to efuse, then erasing that sector of flash (maybe write/erase several times if worried about forensic analysis - I'm not an expert on how secure NOR flash erasing is), and then following the default first boot encryption process for the rest. We don't support that workflow, but I can't think of a reason it wouldn't work.
WiFive wrote:
The goal being to save any precious seconds the device has to spend on the programming/testing jigs.
Understood. There may also be some optimisations we can do for on-device encryption as well, although the process will always take some amount of time.
Angus