Elliptic Curve Digital Signature Algorithm (ECDSA)

[中文]

The Elliptic Curve Digital Signature Algorithm (ECDSA) offers a variant of the Digital Signature Algorithm (DSA) which uses elliptic-curve cryptography.

ESP32-P4's ECDSA peripheral provides a secure and efficient environment for computing ECDSA signatures. It offers fast computations while ensuring the confidentiality of the signing process to prevent information leakage. ECDSA private key used in the signing process is accessible only to the hardware peripheral, and it is not readable by software.

ECDSA peripheral can help to establish Secure Device Identity for TLS mutual authentication and similar use-cases.

Supported Features

  • ECDSA digital signature generation and verification

  • Three different elliptic curves, namely P-192, P-256 and P-384 (FIPS 186-3 specification)

  • Three hash algorithms for message hash in the ECDSA operation, namely SHA-224, SHA-256 and SHA-384 (FIPS PUB 180-4 specification)

ECDSA on ESP32-P4

On ESP32-P4, the ECDSA module works with a secret key burnt into an eFuse block. This eFuse key is made completely inaccessible (default mode) for any resources outside the cryptographic modules, thus avoiding key leakage.

ECDSA Key Storage

ECDSA private keys are stored in eFuse key blocks. The number of key blocks required depends on the curve size:

  • P-256 curve: Require one eFuse key block (256 bits)

  • P-384 curve: Requires two eFuse key blocks (512 bits total)

For curves requiring two key blocks (like P-384), configure the following fields:

  • Set esp_tls_cfg_t::ecdsa_key_efuse_blk to the low block number

  • Set esp_tls_cfg_t::ecdsa_key_efuse_blk_high to the high block number

For single-block curves (like P-256), only set esp_tls_cfg_t::ecdsa_key_efuse_blk and leave esp_tls_cfg_t::ecdsa_key_efuse_blk_high as 0 or unassigned.

ECDSA key can be programmed externally through idf.py script. Here is an example of how to program the ECDSA key:

idf.py efuse-burn-key <BLOCK_NUM> </path/to/ecdsa_private_key.pem> ECDSA_KEY

Note

Six physical eFuse blocks can be used as keys for the ECDSA module: block 4 ~ block 9. E.g., for block 4 (which is the first key block) , the argument should be BLOCK_KEY0.

Alternatively the ECDSA key can also be programmed through the application running on the target.

Following code snippet uses esp_efuse_write_key() to set physical key block 0 in the eFuse with key purpose as esp_efuse_purpose_t::ESP_EFUSE_KEY_PURPOSE_ECDSA_KEY:

#include "esp_efuse.h"

const uint8_t key_data[32] = { ... };

esp_err_t status = esp_efuse_write_key(EFUSE_BLK_KEY0,
                    ESP_EFUSE_KEY_PURPOSE_ECDSA_KEY,
                    key_data, sizeof(key_data));

if (status == ESP_OK) {
    // written key
} else {
    // writing key failed, maybe written already
}

Deterministic Signature Generation

The ECDSA peripheral of ESP32-P4 also supports generation of deterministic signatures using deterministic derivation of the parameter K as specified in the RFC 6979 section 3.2.

Non-Determinisitic Signature Generation

Dependency on TRNG

ECDSA peripheral relies on the hardware True Random Number Generator (TRNG) for its internal entropy requirement for generating non-deterministic signatures. During ECDSA signature creation, the algorithm requires a random integer to be generated as specified in the RFC 6090 section 5.3.2.

Please ensure that hardware RNG is enabled before starting ECDSA computations (primarily signing) in the application.

Application Outline

Please refer to the ECDSA Peripheral with ESP-TLS guide for details on how-to use ECDSA peripheral for establishing a mutually authenticated TLS connection.

The ECDSA peripheral in Mbed TLS stack is integrated by overriding the ECDSA signing and verifying APIs. Please note that, the ECDSA peripheral does not support all curves or hash algorithms, and hence for cases where the hardware requirements are not met, the implementation falls back to the software.

For a particular TLS context, additional APIs have been supplied to populate certain fields (e.g., private key ctx) to differentiate routing to hardware. ESP-TLS layer integrates these APIs internally and hence no additional work is required at the application layer. However, for custom use-cases please refer to API details below.

API Reference

Header File

Structures

struct esp_ecdsa_opaque_key_t

Structure to store opaque key metadata.

Public Members

esp_ecdsa_curve_t curve

ECDSA curve

bool use_km_key

Use key deployed in the key manager

uint8_t efuse_block

eFuse block id for ECDSA private key

Macros

MAX_ECDSA_COMPONENT_LEN
MAX_ECDSA_SHA_LEN
ECDSA_SHA_LEN
ECDSA_SHA_LEN_P384

Enumerations

enum esp_ecdsa_curve_t

ECDSA curve options.

Values:

enumerator ESP_ECDSA_CURVE_SECP192R1
enumerator ESP_ECDSA_CURVE_SECP256R1
enumerator ESP_ECDSA_CURVE_SECP384R1
enumerator ESP_ECDSA_CURVE_MAX

Was this page helpful?