Saltar al contenido
ecdsa.com
C

Mbed TLS (TF-PSA-Crypto)

Mbed TLS 4.x, la pila TLS para sistemas embebidos cuya criptografía es ahora la API PSA Crypto: firmas ECDSA r‖s en bruto, ECDSA determinista como algoritmo aparte y políticas de clave que fijan el algoritmo de cada clave.
Licencia
Apache-2.0 OR GPL-2.0-or-later
Versión comprobada
4.1.1 ·
Código fuente
github.com/Mbed-TLS/mbedtls
Documentación
mbed-tls.readthedocs.io/

Compatibilidad de un vistazo

ECDSACriptografía poscuántica

Curvas ECDSA
P-256P-384P-521secp256k1brainpoolP256r1brainpoolP384r1brainpoolP512r1
EdDSA
none
Formatos de clave pública
spki-dersec1-uncompressed

Mbed TLS 4 trasladó su criptografía a TF-PSA-Crypto y a la API PSA Crypto (psa_sign_message, psa_verify_message, psa_generate_key), la misma API que usa Trusted Firmware de Arm. Los datos de esta página se comprobaron con el paquete de Alpine 3.24.2, Mbed TLS 4.1.1 (la última versión del proyecto ya era la 4.2.0); las funciones disponibles dependen de la configuración de compilación, como en cualquier biblioteca para sistemas embebidos.

La codificación de la firma es lo que difiere del código derivado de OpenSSL: PSA devuelve la forma r‖s en bruto, 64 bytes en P-256, no DER. Las firmas destinadas a X.509, CMS o un verificador de OpenSSL deben envolverse en DER, y las firmas DER que llegan de esos interlocutores deben desenvolverse antes de psa_verify_message, que de lo contrario devuelve PSA_ERROR_INVALID_SIGNATURE, el mismo estado que con una firma falsificada o un blob de 3 bytes. Convierte las firmas con el conversor DER ⇄ en bruto.

Cada clave lleva una política con un único algoritmo permitido, así que la elección entre PSA_ALG_ECDSA (nonce aleatorio) y PSA_ALG_DETERMINISTIC_ECDSA (RFC 6979; el vector de prueba del RFC se reprodujo) se hace al crear la clave, como muestra el ejemplo. s no se normaliza y la verificación acepta high-S. psa_sign_hash firma un resumen calculado de antemano.

Esta compilación firmó y verificó con P-256, P-384, P-521, secp256k1 y las curvas Brainpool r1; P-224 no estaba disponible y se rechazó la generación de claves Ed25519 (PSA_ERROR_NOT_SUPPORTED). La compatibilidad poscuántica se limita a la verificación de LMS, un esquema de firma basada en hash (MBEDTLS_LMS_C); no hay tipo de clave ML-KEM ni ML-DSA, y el controlador experimental de ML-DSA de mldsa-native (TF_PSA_CRYPTO_PQCP_MLDSA_ENABLED) está comentado en la configuración de esta compilación. Las claves públicas se exportan como puntos SEC1 en formato sin comprimir mediante PSA y como DER SPKI mediante la capa pk.

Datos y las comprobaciones que los respaldan

Nada de lo que sigue está copiado de la documentación. La comprobación content/libraries/verify/mbedtls/run.sh ejecutó Mbed TLS (TF-PSA-Crypto) 4.1.1 en la imagen de contenedor alpine:3.24.2 el 20 de octubre de 2026; la página debe coincidir con lo que imprimió, y cada dato cita esas líneas.

  • Codificación de la firma ECDSA

    raw

    psa_sign_message devolvió 64 bytes de r‖s en bruto en P-256.

    Registrado por la comprobación
    fact ecdsa-signature-encoding = raw
    evidence ecdsa-signature-encoding: psa_sign_message returned 64 bytes
  • Nonce de ECDSA

    rfc6979-opt-in

    PSA_ALG_ECDSA usa un nonce aleatorio; PSA_ALG_DETERMINISTIC_ECDSA reprodujo el apéndice A.2.5 del RFC 6979.

    Registrado por la comprobación
    fact ecdsa-nonce = rfc6979-opt-in
    evidence ecdsa-nonce: PSA_ALG_ECDSA repeats: no; PSA_ALG_DETERMINISTIC_ECDSA reproduces the RFC 6979 A.2.5 r: yes (status 0)
  • Low-S al firmar

    either

    s no se normaliza: aparecieron valores high-S entre 64 firmas.

    Registrado por la comprobación
    fact ecdsa-low-s-sign = either
  • High-S al verificar

    accepts-high-s

    Se verificó una firma con s sustituido por n − s.

    Registrado por la comprobación
    fact ecdsa-low-s-verify = accepts-high-s
  • De qué calcula el hash la llamada de firma

    hashes-message-or-digest

    psa_sign_message calcula el hash; psa_sign_hash firma un resumen, y esa firma se verificó con psa_verify_message.

    Registrado por la comprobación
    fact ecdsa-prehash = hashes-message-or-digest
  • Firma ECDSA mal formada

    returns-false

    Una firma DER, un blob de 3 bytes y una firma válida sobre otros datos devolvieron todos PSA_ERROR_INVALID_SIGNATURE (-149).

    Registrado por la comprobación
    fact ecdsa-malformed-signature = returns-false
    evidence ecdsa-malformed-signature: psa_verify_message status: DER -149, 3 bytes -149, wrong message -149 (PSA_ERROR_INVALID_SIGNATURE = -149)
  • Curvas ECDSA

    P-256P-384P-521secp256k1brainpoolP256r1brainpoolP384r1brainpoolP512r1

    Con P-256, P-384, P-521, secp256k1 y brainpoolP256r1/P384r1/P512r1 se firmó y se verificó; la generación de claves P-224 falló en esta compilación.

    Registrado por la comprobación
    fact ecdsa-curves = P-256, P-384, P-521, secp256k1, brainpoolP256r1, brainpoolP384r1, brainpoolP512r1
  • EdDSA

    none

    La generación de claves Ed25519 devolvió PSA_ERROR_NOT_SUPPORTED (-134).

    Registrado por la comprobación
    fact eddsa = none
    evidence eddsa: psa_generate_key for an Ed25519 key: status -134
  • Algoritmos poscuánticos

    LMS

    MBEDTLS_LMS_C está activado (verificación de firmas LMS); no hay definido ningún tipo de clave PSA para ML-KEM ni ML-DSA, y el controlador experimental mldsa-native no se compila.

    Registrado por la comprobación
    fact pqc = LMS
    evidence pqc: MBEDTLS_LMS_C is enabled (LMS hash-based signature verification, <mbedtls/lms.h>)
    evidence pqc: no ML-DSA or ML-KEM PSA key type is defined in these headers
    evidence pqc: psa/crypto_config.h of this build: //#define TF_PSA_CRYPTO_PQCP_MLDSA_ENABLED;//#define TF_PSA_CRYPTO_PQCP_MLDSA_87_ENABLED (commented out = the experimental mldsa-native driver is not built)
  • Formatos de clave pública

    spki-dersec1-uncompressed

    psa_export_public_key devuelve el punto SEC1 de 65 bytes en formato sin comprimir; DER SPKI se escribe y se analiza mediante la capa pk.

    Registrado por la comprobación
    fact public-key-formats = spki-der, sec1-uncompressed
    evidence public-key-formats: psa_export_public_key returns 65 bytes starting 0x04 (an uncompressed SEC1 point)

Uso

Crea una clave P-256 cuya política permite ECDSA determinista, firma un mensaje y verifica la firma en bruto de 64 bytes.
#include <psa/crypto.h>
#include <stdio.h>

int main(void) {
    if (psa_crypto_init() != PSA_SUCCESS) return 1;
    /* The algorithm is part of the key policy: here deterministic ECDSA (RFC 6979) with SHA-256. */
    psa_algorithm_t alg = PSA_ALG_DETERMINISTIC_ECDSA(PSA_ALG_SHA_256);
    psa_key_attributes_t attr = PSA_KEY_ATTRIBUTES_INIT;
    psa_set_key_type(&attr, PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1));
    psa_set_key_bits(&attr, 256);
    psa_set_key_usage_flags(&attr, PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE);
    psa_set_key_algorithm(&attr, alg);
    psa_key_id_t key;
    if (psa_generate_key(&attr, &key) != PSA_SUCCESS) return 1;

    const uint8_t msg[] = "order #1042 approved";
    uint8_t sig[PSA_SIGNATURE_MAX_SIZE];
    size_t sig_len;
    psa_sign_message(key, alg, msg, sizeof msg - 1, sig, sizeof sig, &sig_len);

    /* PSA signatures are raw r||s (64 bytes on P-256): wrap them in DER for X.509 or OpenSSL peers. */
    psa_status_t status = psa_verify_message(key, alg, msg, sizeof msg - 1, sig, sig_len);
    printf("signature bytes: %zu, verified: %d\n", sig_len, status == PSA_SUCCESS);
    psa_destroy_key(key);
    return 0;
}

El arnés de pruebas de fragmentos de código ejecuta cada ejemplo tal cual en la imagen de contenedor alpine:3.24.2, y la ejecución falla si la salida no coincide.

Configuración
apk add --no-cache -q build-base mbedtls-dev=4.1.1-r0 >/dev/null
Comando
cc -o usage usage.c -lmbedcrypto -ltfpsacrypto && ./usage
La salida debe coincidir (expresión regular)
signature bytes: 64, verified: 1

Bibliotecas