ESP ENCRYPTED OTA HMAC PROBLEM

Baldhead
Posts: 515
Joined: Sun Mar 31, 2019 5:16 am
Location: Brazil

ESP ENCRYPTED OTA HMAC PROBLEM

Postby Baldhead » Sat May 09, 2026 3:14 am

Hi,

I am trying to implement ENCRYPTED OTA using this doc:
https://github.com/espressif/idf-extra- ... rypted_img

I am using ECIES-P256.
I wanted to read the esp_secure_cert.bin file from the esp_secure_cert partition of the flash memory, without needing to burn an Efuse, but it seems that's not possible with the ECIES-P256. I think it can only be done using RSA-3072.

I am with problems here:

Code: Select all

#define HMAC_UP_KEY_ID 2

esp_decrypt_cfg_t cfg = {0};
cfg.hmac_key_id = HMAC_UP_KEY_ID;  // the lib returns hmac not found in efuse(Obviously I didn't burn anything in the efuse).
or
cfg.hmac_key_id = -1;  // the lib returns invalid argument. 
or   
cfg.hmac_key_id = 0;  // not works too
esp_decrypt_handle_t decrypt_handle = esp_encrypted_img_decrypt_start(&cfg);
if (decrypt_handle == NULL)
{        
    ota_task_error("decrypt_handle = NULL.");
}    
The function esp_encrypted_img_decrypt_start() returns NULL.

Is there a way to bypass the HMAC peripheral dependency in esp_encrypted_img to use a raw private key stored in a flash partition (e.g., via esp_secure_cert) instead of deriving it from an eFuse key?
Or is the ECIES implementation hardcoded to hardware-only derivation ?

Note:
If I'm not wrong:
The current implementation of esp_encrypted_img is inconsistent. For RSA-3072, the documentation states the private key can be retrieved via esp_secure_cert. However, for ECIES-P256, the library hardcodes the requirement for an HMAC eFuse Key, preventing the use of a private key stored in a flash partition. This limitation makes no sense when Flash Encryption is enabled, as the flash partition would be just as secure as the eFuse-derived key, but with much more flexibility for development and provisioning.

Environment:
ESP-IDF 6.0.1
ESP32-S3
esp_encrypted_img:
https://github.com/espressif/idf-extra- ... rypted_img
version: 2.7.1
esp_secure_cert_mgr:
https://github.com/espressif/esp_secure_cert_mgr
version: 2.9.2

Thank's.
Last edited by Baldhead on Mon May 11, 2026 5:08 am, edited 6 times in total.

Baldhead
Posts: 515
Joined: Sun Mar 31, 2019 5:16 am
Location: Brazil

Re: ESP ENCRYPTED OTA HMAC PROBLEM

Postby Baldhead » Sat May 09, 2026 9:17 pm

I think I was following the rsa-3072 scheme which could use the esp_secure_cert.bin file in the esp_secure_cert partition.
However, I want to use the ECIES-P256 scheme.
From what I understand, it's not possible to use this logic in the ECIES-P256 scheme only in RSA-3072 scheme, so:

Subject: Clarification on ECIES-P256 workflow using Hardware HMAC Key (ESP32-S3)

I am implementing pre-encrypted OTA updates on an ESP32-S3 using the ECIES-P256 scheme. I want to use the hardware-based approach, since flash partition doesn't work, where the private key is derived from an HMAC key stored in eFuses.

I would like to verify if my understanding of the execution order and the tools involved is correct:

1. Generate the Device HMAC Key and public key:
Generate a 32-byte random binary file to serve as the HMAC key (this is used as the base key for hardware derivation) and generate the public key in a single command.
Command: python managed_components/espressif__esp_encrypted_img/tools/esp_enc_img_gen.py --generate_ecc_key

2. Burn the HMAC Key to eFuse:
Burn this key into an eFuse block on the ESP32-S3 (e.g., BLOCK_KEY2) and set the purpose to HMAC_UP.
Command: espefuse.py burn_key BLOCK_KEY2 device_hmac_key.bin HMAC_UP

3. Encrypt the Firmware:
Use the derived device_pub_key.pem to encrypt the binary. This script will also generate the ephemeral public key and include it in the image header.
Command: python esp_enc_img_gen.py encrypt --pub_key device_pub_key.pem --bin_path firmware.bin --out_path firmware_enc.bin

4. Firmware Decryption (On Device ESP32S3):
In the C code, using the esp_encrypted_img component, I only need to provide the hmac_key_id in the esp_decrypt_cfg_t structure.

Code: Select all

esp_decrypt_cfg_t cfg = 
{    
    .hmac_key_id = 2,  // ID corresponding to BLOCK_KEY2
};
Is this workflow correct ?

Thanks in advance.
Last edited by Baldhead on Mon May 11, 2026 3:51 am, edited 12 times in total.

lbernstone
Posts: 1131
Joined: Mon Jul 22, 2019 3:20 pm

Re: ESP ENCRYPTED OTA HMAC PROBLEM

Postby lbernstone » Sun May 10, 2026 2:37 am

Header says you need to set CONFIG_PRE_ENCRYPTED_OTA_USE_RSA.
Then, read your file containing a 3072 bit RSA private key in PEM format, and set the rsa_priv_key (and len) in cfg. You could also embed the key in your firmware as a literal string.

Baldhead
Posts: 515
Joined: Sun Mar 31, 2019 5:16 am
Location: Brazil

Re: ESP ENCRYPTED OTA HMAC PROBLEM

Postby Baldhead » Sun May 10, 2026 3:02 am

Header says you need to set CONFIG_PRE_ENCRYPTED_OTA_USE_RSA.
Then, read your file containing a 3072 bit RSA private key in PEM format, and set the rsa_priv_key (and len) in cfg. You could also embed the key in your firmware as a literal string.
But I want to use the ECIES-P256 scheme.

Baldhead
Posts: 515
Joined: Sun Mar 31, 2019 5:16 am
Location: Brazil

Re: ESP ENCRYPTED OTA HMAC PROBLEM

Postby Baldhead » Mon May 11, 2026 4:55 pm

Is there no espressif expert to shed some light on this ?

Baldhead
Posts: 515
Joined: Sun Mar 31, 2019 5:16 am
Location: Brazil

Re: ESP ENCRYPTED OTA HMAC PROBLEM

Postby Baldhead » Mon May 11, 2026 9:01 pm

I think I was following the rsa-3072 scheme which could use the esp_secure_cert.bin file in the esp_secure_cert partition.
However, I want to use the ECIES-P256 scheme.
From what I understand, it's not possible to use this logic in the ECIES-P256 scheme only in RSA-3072 scheme, so:

Subject: Clarification on ECIES-P256 workflow using Hardware HMAC Key (ESP32-S3)

I am implementing pre-encrypted OTA updates on an ESP32-S3 using the ECIES-P256 scheme. I want to use the hardware-based approach, since flash partition doesn't work, where the private key is derived from an HMAC key stored in eFuses.

I would like to verify if my understanding of the execution order and the tools involved is correct:

1. Generate the Device HMAC Key and public key:
Generate a 32-byte random binary file to serve as the HMAC key (this is used as the base key for hardware derivation) and generate the public key in a single command.
Command: python managed_components/espressif__esp_encrypted_img/tools/esp_enc_img_gen.py --generate_ecc_key

2. Burn the HMAC Key to eFuse:
Burn this key into an eFuse block on the ESP32-S3 (e.g., BLOCK_KEY2) and set the purpose to HMAC_UP.
Command: espefuse.py burn_key BLOCK_KEY2 device_hmac_key.bin HMAC_UP

3. Encrypt the Firmware:
Use the derived device_pub_key.pem to encrypt the binary. This script will also generate the ephemeral public key and include it in the image header.
Command: python esp_enc_img_gen.py encrypt --pub_key device_pub_key.pem --bin_path firmware.bin --out_path firmware_enc.bin

4. Firmware Decryption (On Device ESP32S3):
In the C code, using the esp_encrypted_img component, I only need to provide the hmac_key_id in the esp_decrypt_cfg_t structure.

Code: Select all

esp_decrypt_cfg_t cfg = 
{    
    .hmac_key_id = 2,  // ID corresponding to BLOCK_KEY2
};
Is this workflow correct ?

Thanks in advance.
It apparently worked, but after an OTA reset (software reset), my LCD driver or LCD controller no longer works (even after resetting the LCD controller driver ili_xxxx).
After I performed a power-up reset, the LCD reappeared with semi-transparent rectangular stripes that disappeared after a while.
And everything works normally after power-up, this is very strange.

I think it might be my GDMA driver(or just the GDMA channel returned by the system) and/or my LCD_CAM driver.

Any suggestions on how to reset them on startup or do something before calling esp_restart() ?

Or could it be something else ?

Any suggestions are welcome.

Baldhead
Posts: 515
Joined: Sun Mar 31, 2019 5:16 am
Location: Brazil

Re: ESP ENCRYPTED OTA HMAC PROBLEM

Postby Baldhead » Tue May 12, 2026 2:21 am

I replaced esp_restart() with below command, which solved the lcd issue.

SET_PERI_REG_MASK(RTC_CNTL_OPTIONS0_REG, RTC_CNTL_SW_SYS_RST); // Reboot (software reset like hardware reset).

Are there any drawbacks ?

Who is online

Users browsing this forum: Applebot, Bing [Bot] and 13 guests