Skip to content

Update library does not support signatures created from bin_signing.py #12427

@codingandmore

Description

@codingandmore

Board

ESP32Dev board

Device Description

DevKit plain module

Hardware Configuration

no attachments, plan board with WiFi

Version

v3.3.7

Type

Bug

IDE Name

VSCode

Operating System

Windows 11

Flash frequency

40MHz

PSRAM enabled

yes

Upload speed

921600

Description

After applying fix from #12422 signed binaries created with the signing helper tool bin_signing.py can not be verified. The verification fails even with a correct signature and public key for RSA keys. It seems that the code for sigining uses:

        signature = private_key.sign(
            binary_data, padding.PSS(mgf=padding.MGF1(hash_obj), salt_length=padding.PSS.MAX_LENGTH), hash_obj
        )
        key_typ

Apparently the PSS algorithm with this salt length is not accepted by the mbed-tls library. It works after changing line 127 in Updater_Signing.cpp
from

 int ret = mbedtls_pk_verify((mbedtls_pk_context *)_ctx, md_type, hashBytes, hash->getHashSize(), (const unsigned char *)signature, signatureLen);

to

  // set mode and padding length according to python script for signing:
  size_t max_salt_bytes = 0;
  size_t hash_size = hash->getHashSize();
  mbedtls_rsa_context* rsa_ctx = mbedtls_pk_rsa(*(mbedtls_pk_context *)_ctx);
  if (rsa_ctx) {
    size_t key_size = mbedtls_rsa_get_len(rsa_ctx);
    max_salt_bytes = key_size - hash_size - 2;
    log_i("key size: %d, hash size: %d, salt-len: %d", key_size, hash_size, max_salt_bytes);
    if (max_salt_bytes <= 0) {
      log_e("Invalid length for salt: %d", max_salt_bytes);
      max_salt_bytes = 0;
    }
  }

  int ret;
  if (max_salt_bytes) {
    mbedtls_pk_rsassa_pss_options  options = { md_type, (int) max_salt_bytes};
    log_d("using verify ext to verify signature");
    ret = mbedtls_pk_verify_ext(MBEDTLS_PK_RSASSA_PSS, &options, (mbedtls_pk_context *) _ctx ,md_type, hashBytes, hash_size,
            (const unsigned char *)signature, signatureLen);
  } else {
    ret = mbedtls_pk_verify((mbedtls_pk_context *)_ctx, md_type, hashBytes, hash_size, (const unsigned char *)signature, signatureLen);
  }

The calculation of max_salt_bytes should be reviewed by an expert.

Another option would be to change the signing script to use parameters compatible with mbed-tls, But I could not figure out what mbded-tls uses as defaults (might also be a configuration of the library). And it seems that the current settings are the recommended ones w.r.t. security.

I could also not verify signatures generated with ECDSA keys but I did not investigate this.

Sketch

https://github.com/espressif/arduino-esp32/blob/master/libraries/Update/examples/Signed_OTA_Update/Signed_OTA_Update.ino

Debug Message

[ 52322][I][Updater.cpp:734] end(): Verifying signature: hash: 3ffd25ec, _sign: 3ffc3b1c, size: 512
[ 52331][I][Updater.cpp:736] end(): Verifying signature...
[ 52835][E][Updater_Signing.cpp:74] verify(): RSA signature verification failed: -0x4380
[ 52843][E][Updater.cpp:762] end(): Signature verification failed

Other Steps to Reproduce

The ESP32 Arduino Update Library is excellent to have. Signing OTA updates is really important and this library makes it so much easier! Thank You for making this available in the Espressif Arduino SDK.

I have checked existing issues, online documentation and the Troubleshooting Guide

  • I confirm I have checked existing issues, online documentation and Troubleshooting guide.

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions