IDF v4.4 ESP32 secure boot and flash encryption step-by-step

ESP_Mahavir
Posts: 190
Joined: Wed Jan 24, 2018 6:51 am

Re: IDF v4.4 ESP32 secure boot and flash encryption step-by-step

Postby ESP_Mahavir » Wed Feb 14, 2024 9:30 am

1.- I imagine that this manual will be valid for any recent version of IDF, I am working with version 5.1.2.??? I ask because it is in the master branch and does not appear in the documentation of the version I use.
Yes, the host based security workflow document should apply to ESP-IDF 5.1.2 release as well.
2.- Both workflows end with the same option: C Disable UART ROM DL mode: But it doesn't say anything.
Thanks for noticing this. This is a problem with incorrect rendering of that section for ESP32 target. I have raised the internal fix to correct it, but the command to disable the UART DL mode ESP32 case looks like following:

Code: Select all

espefuse.py --port PORT burn_efuse UART_DOWNLOAD_DIS
Note: Please ensure that you run this command as the very last step to completely lock the UART download mode. After this step esptool would stop functioning and only way to update the firmware would be through OTA updates channel.
Uart Rom download mode is supposed to be permanently disabled when we enter the config menu to activate FE or SBv2. How and when exactly should it be done?
This will only be the case if you have enabled `CONFIG_SECURE_DISABLE_ROM_DL_MODE` in your sdkconfig. Please check and keep it disabled until you verify all settings at your end. UART ROM DL mode should be disabled as the very last step, either through esptool command specified above or through the API `esp_efuse_disable_rom_download_mode`.


Hope this helps!

Nespressif
Posts: 76
Joined: Tue Sep 12, 2017 11:25 am

Re: IDF v4.4 ESP32 secure boot and flash encryption step-by-step

Postby Nespressif » Wed Feb 14, 2024 10:20 am

ESP_Mahavir wrote:
Wed Feb 14, 2024 9:30 am
This will only be the case if you have enabled `CONFIG_SECURE_DISABLE_ROM_DL_MODE` in your sdkconfig. Please check and keep it disabled until you verify all settings at your end. UART ROM DL mode should be disabled as the very last step, either through esptool command specified above or through the API `esp_efuse_disable_rom_download_mode`.
Hi Mahavir, from what you say I think our mistake was to disable the UART ROM mode download prematurely. And I think the documentation is misleading. It should clearly state what you say, that disabling it is the last thing to do once FE and/or SBv2 is configured. However, in the workflow documentation, in step 5 of FE externally, it says to disable it and from what it says this is a mistake if you later want to enable SBv2.

Select UART ROM download mode (Permanently disabled (recommended)) (Note that this option is only available when CONFIG_ESP32_REV_MIN is set to 3 (ESP32 V3).) The default choice is to keep UART ROM download mode enabled, however it is recommended to permanently disable this mode to reduce the options available to an attacker.


In all the documentation about flash encryption it says to disable Uart Rom mode download while enabling FE in menuconfig security options. And I think this is the problem of the chips being locked.

Thank you,

ChrisAlfred
Posts: 19
Joined: Tue Mar 23, 2021 6:22 am

Re: IDF v4.4 ESP32 secure boot and flash encryption step-by-step

Postby ChrisAlfred » Fri Feb 16, 2024 1:58 am

I have thoroughly read through your suggested documentation you suggested at https://docs.espressif.com/projects/esp ... externally

We simply request a complete step-by-step with command lines.

It is obvious that the procedure in the documentation has not actually been performed or tested by Espressif because:


(1) In step "5. Encrypt and flash the binaries." there is the command line:

Code: Select all

espsecure.py encrypt_flash_data --keyfile my_flash_encryption_key.bin --address 0x8000 --output partition-table-enc.bin build/partition_table/partition-table.bin
This is INCORRECT AND WILL NOT WORK as your documentation states in https://docs.espressif.com/projects/esp ... oader-size section "Bootloader Size", the partition table must be moved when encryption is used:

Code: Select all

When Secure Boot V2 is enabled, there is also an absolute binary size limit of 48 KB (0xC000 bytes) (excluding the 4 KB signature), because the bootloader is first loaded into a fixed size buffer for verification.

(2) In "Enable Secure Boot V2 Externally" step "r. Sign and flash the binaries" you have the command line:

Code: Select all

espsecure.py sign_data --version 2 --keyfile secure_boot_signing_key.pem --output bootloader-signed.bin build/bootloader/bootloader.bin

espsecure.py sign_data --version 2 --keyfile secure_boot_signing_key.pem --output my-app-signed.bin build/my-app.bin
then you say, WITHOUT A REAL EXAMPLE COMMAND LINE,
The above files along with other binaries (e.g., partition table) can then be flashed to their respective offset using esptool.py
But these images have not been encrypted.

It is frustrating that:
(1) the procedure has obviously not actually be performed by the document author(s),
(2) the documentation is incomplete as it omits the most critical example flash commands line and leaves to for the user to work it out.

Nespressif
Posts: 76
Joined: Tue Sep 12, 2017 11:25 am

Re: IDF v4.4 ESP32 secure boot and flash encryption step-by-step

Postby Nespressif » Fri Feb 16, 2024 9:20 am

ChrisAlfred wrote:
Fri Feb 16, 2024 1:58 am
It is frustrating that:
(1) the procedure has obviously not actually be performed by the document author(s),
(2) the documentation is incomplete as it omits the most critical example flash commands line and leaves to for the user to work it out.
I totally agree, it is frustrating, the documentation is clearly confusing and/or erroneous. It is incredible to see how difficult it is to do something as important as security to protect your projects.

Before in idf 4.2 version I have done it several times without problems, just by enabling the security options in menuconfig, flashing, building the bootloader and flashing it with the build output, it worked. Now it has become such a cumbersome process, that I only consider enabling flash encription, to see if I can protect my code, but I rule out enabling SecureBoot, as I have already three ScO blocked.

And I wonder, aren't there more people suffering these problems?, what is the process to protect your ScO's when working with hundreds of devices? It can't be that you have to do this one by one.

Nespressif
Posts: 76
Joined: Tue Sep 12, 2017 11:25 am

Re: IDF v4.4 ESP32 secure boot and flash encryption step-by-step

Postby Nespressif » Fri Feb 16, 2024 9:41 am

Hello @ESP_Mahavir:
Yesterday I was testing with a chip on which I had already enabled FE in development mode, to test the FE and SBv2 workflow externally. And after a lot of testing I have a lot of doubts:

1.- In Enable Flash Encryption Externally:
- As I had already enabled it before, it didn't let me erase the flash, nor burn the encryption key. But I could change the value of the efuse FLASH_CRYPT_CNT to 127 indicating that the mode became release.
- After doing what it says in point 4, it says that FE is now enabled, and that it can be tested as indicated in step 5.
Note
At this point, the flash encryption on the device has been enabled. You may test the flash encryption process as given in step 5


So step 5 is optional???, I could skip going into the menuconfig, enable everything, encrypt the binaries and flash them? That is the most cumbersome step and go straight to burning the efuses as given in step 6????

Then I went on to try Enable Secure Boot V2 Externally:

-I ran the first four steps: generate the keys, burn them and burn the ABS_DONE_1 efuse.

Then I tried to continue with steps 5 and 6, but it wouldn't let me, as I burned ABS_DONE_1, the addresses below 0x8000 were protected and I couldn't flasher the signed bootloader, so another chip to hell. Since it doesn't let you change the value of the burned efuses either.

Also, as in FE, after point 4 it reads this:

At this stage V2 secure boot has been enabled for ESP32. The ROM boot loader will now verify the authenticity of the second stage boot loader at each boot. You can test the secure boot process by executing steps 5 and 6. Note that the security-related electronic fuses have not been blown at this point. For production use cases, all security-related eFuses must be burned as indicated in step 7.

So, it is understood that it is not necessary to perform steps 5 and 6, as it says they are for testing, but I think this is wrong, as already in 4 SBv2 has been activated by burning the key and efuse, but the signed binaries have not been flashed.

In short, a real mess and a nonsense.

Anyway, given all these problems, I have decided to just enable FE in release mode, and then when I get it enabled, I will burn the efuses that permanently disables the uart rom download mode. I think this way my code will be protected and I will try not to ruin more chip and with it more money.

Sorry for the long-windedness, greetings

Nespressif
Posts: 76
Joined: Tue Sep 12, 2017 11:25 am

Re: IDF v4.4 ESP32 secure boot and flash encryption step-by-step

Postby Nespressif » Fri Feb 16, 2024 9:59 am

ChrisAlfred wrote:
Fri Feb 16, 2024 1:58 am

(1) In step "5. Encrypt and flash the binaries." there is the command line:

Code: Select all

espsecure.py encrypt_flash_data --keyfile my_flash_encryption_key.bin --address 0x8000 --output partition-table-enc.bin build/partition_table/partition-table.bin
This is INCORRECT AND WILL NOT WORK as your documentation states in https://docs.espressif.com/projects/esp ... oader-size section "Bootloader Size", the partition table must be moved when encryption is used:

Code: Select all

When Secure Boot V2 is enabled, there is also an absolute binary size limit of 48 KB (0xC000 bytes) (excluding the 4 KB signature), because the bootloader is first loaded into a fixed size buffer for verification.
Hi ChrisAlfred, normally the bootloader size does not change to encrypt, if you do not increase the verbosity level. With the standard offset you can have a bootloader of 32768 bytes in size, you can check the size of yours inside the build directory. You can also check your partition table with idf.py partition-table or see the output of idf.py build, where the binary offsets are indicated. I think that's the case, anyway I agree with you that the workflow is wrong and leads us to waste time and money.

Furthermore, if you perform the last FE point, you would completely close the ScO and you would no longer be able to enable SBv2 and that is not clearly explained either.
ChrisAlfred wrote:
Fri Feb 16, 2024 1:58 am
(2) In "Enable Secure Boot V2 Externally" step "r. Sign and flash the binaries" you have the command line:

Code: Select all

espsecure.py sign_data --version 2 --keyfile secure_boot_signing_key.pem --output bootloader-signed.bin build/bootloader/bootloader.bin

espsecure.py sign_data --version 2 --keyfile secure_boot_signing_key.pem --output my-app-signed.bin build/my-app.bin
then you say, WITHOUT A REAL EXAMPLE COMMAND LINE,
The above files along with other binaries (e.g., partition table) can then be flashed to their respective offset using esptool.py
But these images have not been encrypted.
Regarding SBv2, I totally agree with you, the documentation is wrong, since it asks you to flash the binaries that are not encrypted and on top of that, by burning the efuse in point 4, it no longer lets you flash the bootloader... anyway. ...let's see if we're lucky and someone will explain to us how it's actually done, I imagine that many people will protect their projects and it won't be so complicated.

Regards

ESP_flying_raijin
Posts: 25
Joined: Tue Aug 13, 2019 2:03 pm

Re: IDF v4.4 ESP32 secure boot and flash encryption step-by-step

Postby ESP_flying_raijin » Sat Feb 17, 2024 5:23 am

Hi ChrisAlfred and Nespressif,
Please allow me to clear your doubts.
Here is my explanation for the questions raised above.

Question 1
(1) In step "5. Encrypt and flash the binaries." there is the command line:
CODE: SELECT ALL
espsecure.py encrypt_flash_data --keyfile my_flash_encryption_key.bin --address 0x8000 --output partition-table-enc.bin build/partition_table/partition-table.bin
This is INCORRECT AND WILL NOT WORK as your documentation states in https://docs.espressif.com/projects/esp ... oader-size section "Bootloader Size", the partition table must be moved when encryption is used:
CODE: SELECT ALL
When Secure Boot V2 is enabled, there is also an absolute binary size limit of 48 KB (0xC000 bytes) (excluding the 4 KB signature), because the bootloader is first loaded into a fixed size buffer for verification.
Answer
The same offsets would not work because the offset would totally depend on your own firmware. You can find the following text just below these commands.
In the above command the offsets are used for a sample firmware, the actual offset for your firmware can be obtained by checking the partition table entry or by running idf.py partition-table.
These commands were performed for a firmware which only had flash encryption enabled and no secure boot, hence the offsets are different. Please replace the offset numbers with the correct values for your firmware.

Question 2
In "Enable Secure Boot V2 Externally" step "r. Sign and flash the binaries" you have the command line
Answer
I understand what your confusion. In this case the steps are given for independent operations and it was assumed that the encryption and signing would be done in order as required by the firmware.
If only secure boot is enabled then only signing is done and if both are enabled then first signing is done and then the firmware is encrypted.
But I see we need to update the document to make it more obvious about the sequence. Thanks for your inputs, I will raise an internal code-change request that would update the workflow when both of them are enabled together.

@Nespressif

Question 3
1.- In Enable Flash Encryption Externally:
- As I had already enabled it before, it didn't let me erase the flash, nor burn the encryption key. But I could change the value of the efuse FLASH_CRYPT_CNT to 127 indicating that the mode became release.
- After doing what it says in point 4, it says that FE is now enabled, and that it can be tested as indicated in step 5.
Note
At this point, the flash encryption on the device has been enabled. You may test the flash encryption process as given in step 5
Answer
Please note that step 5 is the step in which you flash the encrypted firmware. This step is not necessary for enabling flash encryption feature. This step is only necessary if you want to actually flash a firmware and use it. You can skip this step and directly go to step 6 if you only want to enable flash encryption feature in the factory and then flash the firmware in the future ( when the device is ready to go into the field).


Question 4
I ran the first four steps: generate the keys, burn them and burn the ABS_DONE_1 efuse.

Then I tried to continue with steps 5 and 6, but it wouldn't let me, as I burned ABS_DONE_1, the addresses below 0x8000 were protected and I couldn't flasher the signed bootloader, so another chip to hell. Since it doesn't let you change the value of the burned efuses either.
Answer
Please note that it is still possible to burn the bootloader after enabling ABS_DONE_1 in step 5. ( assuming you have not disabled the ROM_DL mode which comes later in step 7)

Can you let me know which command you have used and the snapshot of the error that you have observed.

Question 5
So, it is understood that it is not necessary to perform steps 5 and 6, as it says they are for testing, but I think this is wrong, as already in 4 SBv2 has been activated by burning the key and efuse, but the signed binaries have not been flashed.

Answer
Please note that this document is designed for all generic users who have different use-cases. The document clearly mentions that it only enables Secure Boot feature. If you only want to enable it for the chip then step 5 and 6 are not necessary. This use-case is applicable in manufactures which enable flash encryption and secure boot feature first and then prepare the devices in the factory itself. At this point the firmware for the product might not ready. In future when the firmware is ready, they prepare the firmware and flash it on the device.


Note that the workflow that you mentioned about enabling Secure Boot and Flash encryption through IDF application is still available and not removed. You can still enable it by enabling the menuconfig option as mentioned here. This is a different workflow in which Flash Encryption and Secure Boot is enabled externally.


Based on the discussion above, I think the document clearly needs to be improved and simplified further.
I have considered following points for improvement based on your discussion
1) Add appropriate warning when disabling ROM DL mode.
2) Add more details when enabling FE and SB together. i) For e.g., Make it clear that the firmware is to be signed first using SB key and then it needs to be encrypted before flashing.
Please let me know what else might need improving.

Additionally,
We have added support of esp32 in the qemu emulator.
you can emulate the esp32 on your host machine and test the security features there itself without worrying about the loss of hardware.
You can find more details here https://github.com/espressif/esp-toolch ... qemu/esp32

ChrisAlfred
Posts: 19
Joined: Tue Mar 23, 2021 6:22 am

Re: IDF v4.4 ESP32 secure boot and flash encryption step-by-step

Postby ChrisAlfred » Mon Feb 19, 2024 2:50 am

Thanks for your answers.

Also note that you have to erase the flash (idf.py -p PORT erase_flash) before you start the procedure otherwise you can get ESP_ERR_NVS_CORRUPT_KEY_PART.

This also applies to ESP32's delivered from the factory as they are not always erased when received.

Who is online

Users browsing this forum: Accound, Bing [Bot] and 84 guests