Hi,
Sorry, I somehow missed this follow-up questions the first time around.
user4_esp32 wrote: ↑Fri May 31, 2019 11:57 am
Thanks very much, ESP_Angus! To follow-on:
1.
If FLASH_CRYPT_CNT is write protected then no more serial flashes with plaintext are possible (if you keep a copy of the flash encryption key, you can still flash pre-encrypted images)
This only works if I pre-generate the flash encryption key (
https://docs.espressif.com/projects/esp ... yption-key), right?
Yes, without modifying the bootloader the only way to have a copy of the key is to have pre-generated and burned it first.
If you modify the bootloader code (by making a copy of the bootloader component in your project) then you could do something else if you wanted, like generate the key and also output a copy on the serial console or in some other place.
user4_esp32 wrote: ↑Fri May 31, 2019 11:57 am
2.
When you say "OTA a binary built with flash encryption enabled", you mean an app built with flash encryption enabled in the project configuration - yes? This answer is given on that assumption.
Yes to building an app with flash encryption enabled in the project configuration. My question stems from this situation: if I have a remote unit already deployed with a partition setup of:
Is it possible to OTA that unit in someway so that it will be "flash encrypted" in the future? I gather from your response that I would need to OTA a bootloader that was built with flash encryption enabled in the project configuration.
We don't have any supported workflow for this. The difficulty is that enabling flash encryption requires encrypting all partitions in-place first, and a failure during this process may require a serial reflash (due to the flash containing a mixture of ciphertext and plaintext).
It's assumed that on a first boot in a factory you can provide some reliable power source for this to happen (and you can also easily reflash a device from serial if something does go wrong). In an OTA situation where the device might be deployed in the field, if the initial encryption pass is interrupted in any way then there is no other recovery path.
For the same basic reason we don't support OTA updating the bootloader (if rewriting the bootloader is interrupted due to a power failure or a crash, there's no recovery mechanism apart from serial reflashing.)
If you know for sure that your devices will have stable power and a stable update environment, you could:
1. OTA update an app with flash encryption support enabled in sdkconfig (as there are some changes on the app side to support flash encryption). This OTA update happens 100% in plaintext.
2. Reset to running the new app.
3. A new, flash encryption enabled, bootloader image can be
embedded in the updated app as binary data. Have the app erase the bootloader region in flash and write out with the new bootloader. A power failure or crash at this point will require serial reflashing. Suggest doing this with minimal other code running, ie have the first check in app_main() be whether the bootloader is the old bootloader, with flash encryption disabled, and if these two conditions are true then it immediately writes the new bootloader without starting any other tasks which might interfere with the update process.
4. Reset again, and the new bootloader runs and will follow the "first boot" process to encrypt all the partitions and enable flash encryption. A power failure at this point will require serial reflashing.
5. Reset again and the same app will boot as step (2), but encrypted this time.
This is not supported or recommended though, for the reasons mentioned.
user4_esp32 wrote: ↑Fri May 31, 2019 11:57 am
3. For production devices deployed with a partition setup of:
- bootloader [ flash encryption enabled]
- factory [ flash encryption enabled]
When I build the binaries to be flashed via OTA into ota_0 or ota_1, do I need to build with flash encryption enabled in the sdkconfig, or can the binaries be plaintext (and will be encrypted by the bootloader on first boot into ota_0 or ota_1)?
Flash encryption should be enabled in the sdkconfig of both the app and the bootloader, if you want to use flash encryption. In the case of the app, it makes sure that support functions to work with encrypted flash are compiled in.
The app .bin files, both for initial serial flashing and for OTA should be plaintext. The factory app will be encrypted in-place by the bootloader on first boot. Any OTA updated binaries will be encrypted by the device when it writes them to flash.
(This raises the question of protecting the .bin files when transferring them from the server. The recommended way to do this is to apply some other encryption scheme to the files over the network, perhaps by using HTTPS and having the server authenticate the device when it requests the .bin file. We're planning a standard solution for this problem but we don't have an ETA for it to be available, yet.)