Flash encryption without secure boot

user4_esp32
Posts: 21
Joined: Sun Nov 26, 2017 4:48 pm

Flash encryption without secure boot

Postby user4_esp32 » Fri May 31, 2019 12:20 am

Hello All--a few questions about using flash encryption without secure boot:

If I serial flash a binary with flash encryption enabled (i.e. "in make menuconfig, navigate to “Security Features” and select “Yes” for “Enable flash encryption on boot”."), and then write-protect the FLASH_CRYPT_CNT efuse via:

Code: Select all

espefuse.py --port PORT write_protect_efuse FLASH_CRYPT_CNT
(https://docs.espressif.com/projects/esp ... encryption)

1. Is it then impossible to disable flash encryption per the steps at https://docs.espressif.com/projects/esp ... encryption?

2. Will I still have three more serial flashes available? (https://docs.espressif.com/projects/esp ... l-flashing)

3. Assuming a partition setup of factory [plaintext], ota_0 [empty], and ota_1 [empty], if I OTA a binary built with flash encryption enabled to the ota_0 partition, and then set the device to boot from the ota_0 partition, will the device be able to execute the binary at ota_0?

ESP_Angus
Posts: 1786
Joined: Sun May 08, 2016 4:11 am

Re: Flash encryption without secure boot

Postby ESP_Angus » Fri May 31, 2019 12:27 am

Hi user4,
user4_esp32 wrote:
Fri May 31, 2019 12:20 am
1. Is it then impossible to disable flash encryption per the steps at https://docs.espressif.com/projects/esp ... encryption?
Yes, if FLASH_CRYPT_CNT is write protected then this is impossible.
user4_esp32 wrote:
Fri May 31, 2019 12:20 am
2. Will I still have three more serial flashes available? (https://docs.espressif.com/projects/esp ... l-flashing)
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).

The reason for the recommendation to write-protected FLASH_CRYPT_CNT is that, without secure boot enabled, an attacker can disable flash encryption and then flash their own small bootloader which re-enables flash encryption itself and then dumps out the real firmware.

If you're still in development phase and you don't need the device to be secure than you can keep FLASH_CRYPT_CNT writable until you need to deploy.
user4_esp32 wrote:
Fri May 31, 2019 12:20 am
3. Assuming a partition setup of factory [plaintext], ota_0 [empty], and ota_1 [empty], if I OTA a binary built with flash encryption enabled to the ota_0 partition, and then set the device to boot from the ota_0 partition, will the device be able to execute the binary at ota_0?
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.

The bootloader also needs to also have flash encryption enabled in the project configuration. Initially, it's flashed in plaintext as well (same as the factory app partition).

Then, on first boot the device encrypts itself (bootloader, partition table, app) and enables flash encryption by burning the FLASH_CRYPT_CNT efuse. Now the factory app partition is encrypted and the device will boot from this after the next reset.

If the factory partition OTA updates with a new app binary then it will transparently encrypt that binary as it's written to flash in the ota_0 partition. This makes it eligible to boot from, if the OTA API is used to change the boot partition.

user4_esp32
Posts: 21
Joined: Sun Nov 26, 2017 4:48 pm

Re: Flash encryption without secure boot

Postby user4_esp32 » 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?

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:
  • bootloader [ plaintext]
  • factory [ plaintext]
  • ota_0 [empty]
  • ota_1 [empty]
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.

3. For production devices deployed with a partition setup of:
  • bootloader [ flash encryption enabled]
  • factory [ flash encryption enabled]
  • ota_0 [empty]
  • ota_1 [empty]
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)?

user4_esp32
Posts: 21
Joined: Sun Nov 26, 2017 4:48 pm

Re: Flash encryption without secure boot

Postby user4_esp32 » Wed Aug 07, 2019 6:49 pm

Hello,

Could someone please answer #3 from above? Perhaps @ESP_Angus?

3. For production devices deployed with a partition setup of:
bootloader [ flash encryption enabled]
factory [ flash encryption enabled]
ota_0 [empty]
ota_1 [empty]
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)?

ESP_Angus
Posts: 1786
Joined: Sun May 08, 2016 4:11 am

Re: Flash encryption without secure boot

Postby ESP_Angus » Wed Aug 07, 2019 11:49 pm

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:
  • bootloader [ plaintext]
  • factory [ plaintext]
  • ota_0 [empty]
  • ota_1 [empty]
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]
  • ota_0 [empty]
  • ota_1 [empty]
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.)

user4_esp32
Posts: 21
Joined: Sun Nov 26, 2017 4:48 pm

Re: Flash encryption without secure boot

Postby user4_esp32 » Sat Aug 10, 2019 1:13 pm

Thanks very much for the thorough reply, @ESP_Angus, and for clarifying.

It would be helpful to add a note to the Docs to mention that for binaries meant for OTA to a device with encryption-enabled-in-the-bootloader, one should build the binary with flash encryption support enabled in sdkconfig--perhaps here: https://docs.espressif.com/projects/esp ... ta-updates

Who is online

Users browsing this forum: Google [Bot] and 10 guests