Skip to content

Add post-quantum and EdDSA CRL signing#10943

Open
Frauschi wants to merge 1 commit into
wolfSSL:masterfrom
Frauschi:crl_pqc
Open

Add post-quantum and EdDSA CRL signing#10943
Frauschi wants to merge 1 commit into
wolfSSL:masterfrom
Frauschi:crl_pqc

Conversation

@Frauschi

Copy link
Copy Markdown
Contributor

Summary

CRL signature verification already supported post-quantum algorithms: the CRL path reuses the shared ConfirmSignature() engine, which dispatches to ML-DSA / SLH-DSA / Falcon. CRL generation did not — wc_SignCRL_ex accepted only RSA and ECC keys and sized its signature buffer for a classic signature.

This PR adds wc_SignCRL_ex2, a new wolfcrypt API that signs a CRL with any supported key type, and sizes the signature buffer from the key so post-quantum signatures fit.

The new API

int wc_SignCRL_ex2(const byte* tbsBuf, int tbsSz, int sType,
                   byte* buf, word32 bufSz,
                   int keyType, void* key, WC_RNG* rng);
  • Takes an untyped key plus a keyType selector, the same scheme wc_MakeCert_ex and wc_SignCert_ex use, instead of one argument per key family.
  • Resolves the key and reuses the existing CheckSigTypeForKey, GetSignatureBufferSz, and MakeSignature helpers, so the signature buffer is sized from the key rather than assumed classic.
  • wc_SignCRL_ex is unchanged (its original RSA/ECC signature) and becomes a thin wrapper over wc_SignCRL_ex2, so the existing public API and ABI are preserved.

Supported algorithms

Key type CRL signing
RSA, ECC Yes (also via the classic wc_SignCRL_ex)
Ed25519, Ed448 Yes, newly available
Falcon Yes, newly available
ML-DSA (FIPS 204) Yes
SLH-DSA (FIPS 205) Yes
LMS, XMSS Rejected with ALGO_ID_E

LMS/XMSS are intentionally rejected. They are stateful hash-based schemes; a CRL is reissued periodically and would exhaust the key's one-time signature state, with catastrophic reuse risk if that state is mismanaged.

Buffer sizing

The signature buffer is sized from the key via GetSignatureBufferSz, so large post-quantum signatures (a few KB for ML-DSA up to tens of KB for SLH-DSA) get enough room. Under WOLFSSL_NO_MALLOC the signature must still fit the fixed CertSignCtx.sig buffer (tunable via WOLFSSL_MAX_SIG_SZ), consistent with the certificate signing path.

Scope and carve-outs

  • OpenSSL-compat EVP layer: wolfSSL_X509_CRL_sign (the EVP_PKEY wrapper) has no PQC private-key support, so PQC CRL signing is exposed at the wolfcrypt level through wc_SignCRL_ex2. Wiring the EVP layer for PQC is a separate, larger change and is out of scope here.
  • Async: wc_SignCRL_ex2 does not special-case WC_PENDING_E, mirroring the pre-existing wc_SignCRL_ex behavior. CRL signing is not async-safe; adding it would use the same guard wc_SignCert_ex already has.

Test coverage

New tests/api.c cases build a CRL, sign it with wc_SignCRL_ex2, and verify it through the certificate manager against the issuing CA:

  • ML-DSA 44 / 65 / 87
  • SLH-DSA SHAKE-128s (and SHA2-128s when built)
  • Ed25519 and Ed448
  • Negative cases:
    • tampered signature value verified as ASN_CRL_CONFIRM_E
    • sigType / key-family mismatch rejected with ALGO_ID_E
    • LMS / XMSS / XMSSMT key type rejected with ALGO_ID_E

The classic RSA/ECC path keeps its existing coverage through wc_SignCRL_ex.

@Frauschi Frauschi self-assigned this Jul 17, 2026
@github-actions

github-actions Bot commented Jul 17, 2026

Copy link
Copy Markdown

CRL signature verification already supported post-quantum algorithms
through the shared ConfirmSignature() engine, but CRL generation did not:
wc_SignCRL_ex accepted only RSA and ECC keys and sized its signature
buffer for a classic signature.

Add wc_SignCRL_ex2, which takes an untyped key plus a keyType selector,
the same scheme wc_MakeCert_ex and wc_SignCert_ex use. It resolves the key
and reuses the existing CheckSigTypeForKey, GetSignatureBufferSz and
MakeSignature helpers, so the signature buffer is sized from the key and
post-quantum signatures get enough room. wc_SignCRL_ex keeps its original
RSA/ECC signature and becomes a thin wrapper, preserving the public API.

This enables CRL signing with ML-DSA, SLH-DSA, Ed25519, Ed448 and Falcon.
Stateful hash-based schemes (LMS/XMSS) are rejected with ALGO_ID_E, since a
CRL is reissued periodically and would exhaust the key's one-time signature
state. Under WOLFSSL_NO_MALLOC the signature must still fit the fixed
CertSignCtx.sig buffer, consistent with the certificate signing path.

Tests cover CRL sign and verify through the certificate manager for ML-DSA
(44/65/87), SLH-DSA (SHAKE and SHA2 128s), Ed25519 and Ed448, plus negative
cases for a tampered signature, a sigType and key-family mismatch, and
rejection of LMS/XMSS.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant