ESP32-S3 EFUSE pre-programming for production.

skiddd
Posts: 11
Joined: Sat May 28, 2022 8:58 am

ESP32-S3 EFUSE pre-programming for production.

Postby skiddd » Fri Dec 02, 2022 11:39 am

Greetings Dear Colleagues,

Is it an acceptable practice to pre-program EFUSES related to Secure Boot V2 and Flash Encryption without immediately flashing the bootloader and app afterwards?

I have always seen in the documentations that the boot and app are encrypted internally for the first time after flash encryption is enabled. What if I don't intend to flash the boot and app just yet? Will it still initially need an unencrypted binary or can I skip the plaintext and flash a fully signed and encrypted binary instead?

I am currently tasked to pre-program the full protection and keys of our first PCB run. It will be another person's job to program the bootloader and app next year. This said person is not allowed to handle unencrypted binaries of this project.

My goal right now is to prepare the PCB to just work signed and encrypted binaries. (Plaintext not allowed at all)

Flashing will be done via the UART bootloader initially, and the partition table has reserved areas for 2 OTA slots.

The reason I am asking for advice is because I don't want to mess up around 5K PCBs.

I am confused about the part that the first binary to be flashed should still be plaintext even after enabling SBV2 and encryption. Can I skip this part entirely?


Best Regards,

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

Re: ESP32-S3 EFUSE pre-programming for production.

Postby ESP_flying_raijin » Tue Dec 27, 2022 7:35 am

Hi Skidd,


> I am confused about the part that the first binary to be flashed should still be plaintext even after enabling SBV2 and encryption. Can I skip this part entirely?

Please note that the flash encryption key is present on the esp module. When you want to flash the firmware on a module that has Flash Encryption enabled, you need to use the --encrypt option. What it does is that it takes plaintext firmware from you and then the esp module encrypts the firmware before writing it to the flash. That is why it is mandatory to provide plaintext firmware every time ( irrespective of FE enabled or disabled)

I think we can divide your issue in two parts
1) Secure Boot -
In case of secure boot the digest of the public key whose corresponding private key is used to sign the bootloader is stored in the efuse.
Since we know the public key we also pre-program the efuse beforehand. Please note that internally the bootloader does this step and disabled burns some additional eFuses as well based on the secure boot configurations. If you are burning the secure boot key externally, you must also ensure that the additional eFuses are burned.

This part has one catch. When the SB is enabled through bootloader, bootloader also burns an eFuse that disables the ability for further read protection of any key blocks. This is to ensure that the key block in which the SB digest is stored is not read-protected. (Otherwise it cannot be read to verify Secure Boot afterwards). In order to disable the ability for further read protection of any key blocks, we need to be sure that no eFuse key blocks shall be used for purposes that require read protection. ( e.g. Digital Signature, Flash Encryption, HMAC)


2) Flash Encryption -
In order to generate firmware that is encrypted and can be flashed directly, we need the key outside of the device to encrypt the plaintext data. This puts a lot of responsibility for the key management (which now needs to be handled outside and trusted)
In case of flash encryption, It is recommended that the Flash Encryption key should be unique for each device. I think it would be very difficult to generate and manage these many flash encryption keys. In this case of unique keys, the firmware shall be unique to each device, so management would be problematic.

One solution for the flashing-in-steps problem would be the following but it doesn't resolve your problem related to unencrypted binaries.

1) Step 1 - Enable secure boot for the device. Enable Flash Encryption in development mode.
2) Step 2- Provide signed but unencrypted binaries to the factory. Ask them to flash the binaries using `--encrypt` option provided by esptool (https://github.com/espressif/esptool/bl ... __.py#L312).
3) Step 3- Ask them to enable flash encryption in release mode at the last step.


An alternate solution is to use the pre-encrypted OTA feature. In that case, the workflow would be something like the following:
1) Step 1 - Enable secure boot and flash encryption in the release mode. The firmware in this case shall contain the ability to perform pre-encrypted OTA. (https://docs.espressif.com/projects/esp ... d-firmware).
2) Step 2 - Provide encrypted firmware to the factory and ask them to initiate the execution of firmware flashed in STEP1. In this case, the encrypted firmware shall be downloaded on the esp module, first decrypted with the respective key and then written at the desired location. Since we have already enabled Flash Encryption in step 1, the downloaded firmware shall be written in an encrypted format on the flash. This encryption shall be done using the flash encryption key burned in the eFuse key block.

I hope I have answered your question, please feel free to ask if any additional information is required.
Thanks,
Aditya

skiddd
Posts: 11
Joined: Sat May 28, 2022 8:58 am

Re: ESP32-S3 EFUSE pre-programming for production.

Postby skiddd » Fri Jan 06, 2023 6:19 am

First of all, thank you for a very detailed answer to my query.

After analyzing bootloader.elf with SB and Encryption enabled, I was able to identify which of the eFuses the bootloader burns upon first and second boot. I came to the same conclusions you already described.

In the end, I was able to pre-program the entire eFuse blocks for SB 2.0, flash encryption as well as HMAC upstream. I used unique pre-generated 512-bit AES-XTS keys for flash encryption for each ESP32-S3 I program. A database takes note of matching the factory MAC with the unique encryption key. My block0 is already fully provisioned for final production with all the necessary key_purposes, securities, rd_dis and wr_dis bits burned. However, the built-in USB Serial CDC is left enabled but only in Secure Mode since it is much faster than UART0 when it comes to spi flash programming.

I also made a software that will sign and encrypt the bootloader, app, partition_table binaries that are going to be unique for each esp32-s3. These binary files will be given to workers with no security clearances whatsoever. They will be tasked to program the spi flash in the future. The built-in USB Serial CDC actually uses the factory MAC as it’s device serial number. This makes it possible to identify each esp32-s3 uniquely even if eFuse reading has already been disabled and the spi flash is still empty.

Best Regards

Who is online

Users browsing this forum: joglz8, markkuk and 126 guests