Signed App test in OTA Update passes with corrupted certificate

StevePeake
Posts: 8
Joined: Mon Nov 30, 2020 10:52 am

Signed App test in OTA Update passes with corrupted certificate

Postby StevePeake » Mon Nov 30, 2020 11:10 am

ESP-IDF v3.3.4

I am currently implementing an OTA Update mechanism. I have enabled:
Security Features->Require Signed app images
Security Features->Verify app signature on update
Security Features->Sign binaries during build

and generated a "Secure boot private signing key" as documented here: https://docs.espressif.com/projects/esp ... igning-key

I flashed FACTORY partition with my firmware v1.
I deliberated corrupted the boot sigining key by overwriting 20 characters - keeping the same length of key.
I built v2 of my firmware, and triggered an OTA update to download v2

v2 firmware is downloaded, and

Code: Select all

esp_https_ota_finish
returns

Code: Select all

ESP_OK
My ESP32 reboots, using v2 firmware.

Expected behaviour:
v2 firmware is downloaded, then

Code: Select all

esp_https_ota_finish
returns

Code: Select all

ESP_ERR_OTA_VALIDATE_FAILED
Am I missing something, or will any boot signing certificate allow an OTA update?

Regards
Steve

StevePeake
Posts: 8
Joined: Mon Nov 30, 2020 10:52 am

Re: Signed App test in OTA Update passes with corrupted certificate

Postby StevePeake » Tue Dec 01, 2020 9:24 am

A bit more experimentation proved I was missing something. Although I'd inserted the junk text into the middle of the key, I'd only overwritten padding characters. Anything after character 72 (and before the terminating == characters) can be overwritten without invalidating the key.

Overwriting earlier characters prevents the firmware from even compiling.

I generated a new boot signing key for firmware v2 and triggered the OTA update. The update was downloaded then

Code: Select all

esp_https_ota_finish
returns

Code: Select all

ESP_ERR_OTA_VALIDATE_FAILED
So all is behaving as expected.

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

Re: Signed App test in OTA Update passes with corrupted certificate

Postby ESP_Angus » Tue Dec 01, 2020 9:34 am

Hi Steve,

You posted just as I was coming to reply!

The reason that corrupting bytes at the end of the PEM key file doesn't invalidate the signature is that an ECDSA key generated by openssl (and possibly other tools) contains the private key bytes at the beginning and the public key bytes after that (the PEM format is a base64-encoded form of the DER format, which is a set of ASN.1 identifiers and values, so inside the blob of text are multiple fields.)

Corrupting the public key won't prevent a valid signature being generated, but if you'd rebuilt the original app using the corrupted key then it would have failed to verify any signatures (because the public key part is embedded into the app for signature verification).

To dump the actual key parameters you can use openssl:

Code: Select all

$ openssl ec -in secure_boot_signing_key.pem -noout -text
read EC key
Private-Key: (256 bit)
priv:
    1f:d6:52:99:d7:c5:60:8d:76:68:0f:f0:0f:8c:cd:
    69:55:00:10:36:37:17:1e:a2:1b:3c:91:67:f0:8c:
    8f:dc
pub:
    04:7b:f8:07:e3:5a:32:65:81:f7:7a:e2:d6:52:5b:
    78:56:2a:df:75:ab:33:c8:9f:d1:27:a8:77:ba:e2:
    71:9d:0b:2f:10:e8:03:fb:7f:12:8f:05:84:22:44:
    d8:95:b6:a5:de:48:17:38:0d:79:35:f2:6f:1f:14:
    55:01:d9:2b:9e
ASN1 OID: prime256v1
NIST CURVE: P-256

Code: Select all

$ openssl asn1parse -in secure_boot_signing_key.pem
    0:d=0  hl=2 l= 119 cons: SEQUENCE          
    2:d=1  hl=2 l=   1 prim: INTEGER           :01
    5:d=1  hl=2 l=  32 prim: OCTET STRING      [HEX DUMP]:1FD65299D7C5608D76680EF00F8CCD695500103637171EA21B3C9167F08C8FDC
   39:d=1  hl=2 l=  10 cons: cont [ 0 ]        
   41:d=2  hl=2 l=   8 prim: OBJECT            :prime256v1
   51:d=1  hl=2 l=  68 cons: cont [ 1 ]        
   53:d=2  hl=2 l=  66 prim: BIT STRING        
The offsets in the binary (base64-decoded DER) format are printed at the far left. To corrupt the private key you need to change the "OCTET STRING" bytes, not the longer "BIT STRING" at the end which is the public key.

I double checked that corrupting a byte of the private key causes the update to fail on v3.3.4 as well.

(Note: the above is from a key I generated for the purposes of this test, and have just deleted.)

StevePeake
Posts: 8
Joined: Mon Nov 30, 2020 10:52 am

Re: Signed App test in OTA Update passes with corrupted certificate

Postby StevePeake » Tue Dec 01, 2020 2:28 pm

Thanks for the info - I'm sure that will come in useful.

I caused my own problem by being lazy. I was documenting how the OTA Update system should work in a new project, and wanted to see what was reported if the wrong key was used. Rather than look-up the OpenSSL command to generate a new key, I thought I could just corrupt the existing key to force an error.

Time saved: 30s
Time cost: 90+ minutes, including registering for this forum :oops:

Who is online

Users browsing this forum: Majestic-12 [Bot] and 130 guests