Saltar al contenido
ecdsa.com
C

wolfSSL (wolfCrypt)

wolfSSL, la biblioteca TLS para sistemas embebidos, y wolfCrypt: ECDSA en DER sobre un resumen que proporcionas tú, una llamada de verificación cuyo código de retorno y cuyo veredicto van por separado, y un conjunto de funciones que depende por completo de cómo se compiló.
Licencia
GPL-3.0-only
Versión comprobada
5.9.4 ·
Código fuente
github.com/wolfSSL/wolfssl
Documentación
www.wolfssl.com/documentation/manuals/wolfssl/

Compatibilidad de un vistazo

ECDSAEdDSACriptografía poscuántica

Curvas ECDSA
P-224P-256P-384P-521
EdDSA
Ed25519

wolfSSL está pensado para sistemas embebidos y despliegues FIPS, y casi todo es una opción de compilación: las curvas, las variantes de EdDSA, los nonces deterministas, los algoritmos poscuánticos y la compatibilidad con PEM aparecen y desaparecen con las opciones de ./configure. Los datos de esta página describen el paquete de Alpine 3.24.2 de wolfSSL 5.9.4, compilado con HAVE_ECC, HAVE_ED25519, HAVE_CURVE25519 y WOLFSSL_HAVE_MLKEM, pero sin HAVE_ED448, sin HAVE_DILITHIUM, sin curvas Koblitz ni Brainpool y sin WOLFSSL_ECDSA_DETERMINISTIC_K. Una compilación personalizada puede diferir en cada uno de esos puntos.

wc_ecc_sign_hash firma un resumen que calculas tú y devuelve DER; wc_ecc_verify_hash_ex recibe r y s como enteros para las firmas en bruto. La verificación tiene dos salidas: el código de retorno de la función indica si pudo ejecutarse, y el argumento int *res contiene el veredicto. Una firma en bruto de 64 bytes pasada a wc_ecc_verify_hash devolvió -171 (ECC ASN1 bad key data, invalid input) con el veredicto 0; el código que comprueba solo el código de retorno, o solo el veredicto, gestiona mal uno de los dos casos. El ejemplo imprime ambos.

En esta compilación, los nonces son aleatorios (la firma determinista RFC 6979 necesita WOLFSSL_ECDSA_DETERMINISTIC_K), s no se normaliza y las firmas high-S se verifican. Las curvas disponibles iban de P-224 a P-521; secp256k1 y Brainpool no están salvo que se activen. Ed25519 funciona, y ML-KEM-768 completó la encapsulación y la desencapsulación mediante wc_MlKemKey_*; ML-DSA (Dilithium) no está en esta compilación.

Las claves se intercambian en DER: wc_EccPublicKeyToDer escribe SPKI y wc_EccKeyToDer escribe un ECPrivateKey SEC1; la conversión a PEM (wc_DerToPem) está disponible porque el paquete activa WOLFSSL_DER_TO_PEM. El paquete de Alpine declara su licencia como GPL-3.0-only; wolfSSL Inc. vende licencias comerciales por separado. Compara las codificaciones con las de otras pilas en el conversor DER ⇄ en bruto.

Datos y las comprobaciones que los respaldan

Nada de lo que sigue está copiado de la documentación. La comprobación content/libraries/verify/wolfssl/run.sh ejecutó wolfSSL (wolfCrypt) 5.9.4 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

    der

    wc_ecc_sign_hash devuelve DER; wc_ecc_verify_hash_ex verifica r y s pasados como enteros.

    Registrado por la comprobación
    fact ecdsa-signature-encoding = der
    evidence ecdsa-signature-encoding: wc_ecc_verify_hash_ex with r and s as integers verifies: 1
  • Nonce de ECDSA

    random

    Nonce aleatorio en esta compilación, que no tiene WOLFSSL_ECDSA_DETERMINISTIC_K.

    Registrado por la comprobación
    fact ecdsa-nonce = random
    evidence ecdsa-nonce: this build lacks WOLFSSL_ECDSA_DETERMINISTIC_K, so RFC 6979 signing is not available
  • 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

    Una firma DER con s sustituido por n − s se verificó.

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

    takes-digest

    wc_ecc_sign_hash y wc_ecc_verify_hash trabajan sobre un resumen calculado por quien las llama.

    Registrado por la comprobación
    fact ecdsa-prehash = takes-digest
    evidence ecdsa-prehash: wc_ecc_sign_hash and wc_ecc_verify_hash take a digest the caller computed
  • Firma ECDSA mal formada

    returns-error

    Una firma r‖s en bruto hizo que wc_ecc_verify_hash devolviera -171 (ECC ASN1 bad key data, invalid input) con el veredicto 0.

    Registrado por la comprobación
    fact ecdsa-malformed-signature = returns-error
    evidence ecdsa-malformed-signature: wc_ecc_verify_hash on raw r||s: return code -171 (ECC ASN1 bad key data, invalid input), result 0
  • Curvas ECDSA

    P-224P-256P-384P-521

    P-224, P-256, P-384 y P-521 en esta compilación; la generación de claves secp256k1 y brainpoolP256r1 falló.

    Registrado por la comprobación
    fact ecdsa-curves = P-224, P-256, P-384, P-521
  • EdDSA

    Ed25519

    Ed25519; HAVE_ED448 no está definido en esta compilación.

    Registrado por la comprobación
    fact eddsa = Ed25519
    evidence eddsa: HAVE_ED448 is not set in this build
  • Algoritmos poscuánticos

    ML-KEM

    ML-KEM-768 completó el ciclo de encapsulación y desencapsulación mediante wc_MlKemKey_*; HAVE_DILITHIUM (ML-DSA) no está definido en esta compilación.

    Registrado por la comprobación
    fact pqc = ML-KEM
    evidence pqc: HAVE_DILITHIUM (ML-DSA) is not set in this build
  • Formatos de clave pública

    spki-der

    wc_EccPublicKeyToDer y wc_EccPublicKeyDecode manejan SPKI DER, y la clave decodificada verificó una firma.

    Registrado por la comprobación
    fact public-key-formats = spki-der
  • Formatos de clave privada

    sec1-der

    wc_EccKeyToDer escribe un ECPrivateKey SEC1 (121 bytes en P-256) que wc_EccPrivateKeyDecode vuelve a leer.

    Registrado por la comprobación
    fact private-key-formats = sec1-der
    evidence private-key-formats: wc_EccKeyToDer writes a SEC1 ECPrivateKey of 121 bytes
    evidence private-key-formats: WOLFSSL_DER_TO_PEM is set in this build

Uso

Calcula el hash, firma con P-256 y verifica, e imprime tanto el código de retorno como el veredicto de la verificación.
#include <wolfssl/options.h>
#include <wolfssl/wolfcrypt/ecc.h>
#include <wolfssl/wolfcrypt/random.h>
#include <wolfssl/wolfcrypt/sha256.h>
#include <stdio.h>

int main(void) {
    WC_RNG rng;
    ecc_key key;
    unsigned char digest[32], sig[ECC_MAX_SIG_SIZE];
    word32 sig_len = sizeof sig;
    int verified = 0;
    const unsigned char msg[] = "order #1042 approved";

    wc_InitRng(&rng);
    wc_ecc_init(&key);
    wc_ecc_make_key_ex(&rng, 32, &key, ECC_SECP256R1);

    /* wolfCrypt signs a digest you computed and returns DER. */
    wc_Sha256Hash(msg, sizeof msg - 1, digest);
    wc_ecc_sign_hash(digest, sizeof digest, sig, &sig_len, &rng, &key);
    /* The return code says whether verification ran; "verified" holds the verdict. */
    int rc = wc_ecc_verify_hash(sig, sig_len, digest, sizeof digest, &verified, &key);
    printf("rc: %d, verified: %d, DER starts with 0x%02x\n", rc, verified, sig[0]);

    wc_ecc_free(&key);
    wc_FreeRng(&rng);
    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 wolfssl-dev=5.9.4-r0 >/dev/null
Comando
cc -o usage usage.c -lwolfssl && ./usage
La salida debe coincidir (expresión regular)
rc: 0, verified: 1, DER starts with 0x30

Bibliotecas