Add post-quantum (ML-DSA, SLH-DSA) signing support for CRLs#23
Open
Frauschi wants to merge 2 commits into
Open
Add post-quantum (ML-DSA, SLH-DSA) signing support for CRLs#23Frauschi wants to merge 2 commits into
Frauschi wants to merge 2 commits into
Conversation
CRL signature *verification* already supported post-quantum algorithms via the shared ConfirmSignature() path, but CRL *generation* did not: wc_SignCRL_ex rejected anything other than RSA/ECC keys and sized its signature buffer with MAX_ENCODED_CLASSIC_SIG_SZ, far too small for ML-DSA/SLH-DSA signatures. Extend wc_SignCRL_ex() to accept wc_MlDsaKey* and SlhDsaKey* signing keys and size the signature buffer from the key via GetSignatureBufferSz() (the same PQC-aware sizing the certificate-generation path uses). MakeSignature(), AddSignature() and CheckSigTypeForKey() already handle PQC keys, so they are reused unchanged. The existing RSA/ECC caller (wolfSSL_X509_CRL_sign) passes NULL for the new key parameters. Note: the OpenSSL-compat EVP_PKEY layer has no PQC private-key support (wolfSSL_d2i_PrivateKey has no ML-DSA case and WOLFSSL_EVP_PKEY has no PQC member), so PQC CRL signing is exposed through the wolfcrypt-level wc_SignCRL_ex API rather than the EVP wrapper. Add round-trip tests (build + sign + verify via the certificate manager, plus a tampered-signature negative case) covering ML-DSA-44/65/87 and SLH-DSA SHAKE-128s (SHA2-128s when built). A wolfSSL-signed ML-DSA-44 CRL was also verified with OpenSSL 3.5 (verify OK) to confirm DER interoperability.
- wc_SignCRL_ex: move the new ML-DSA/SLH-DSA key pointers to the end of the parameter list (after rng) so the original RSA/ECC parameter order is preserved instead of being split by the inserted PQC params. Update the prototype and all callers accordingly. - wc_SignCRL_ex: brace the single-statement key-count ifs to match file style. - Tests: size the CRL output buffer from the signing key's actual signature length (wc_MlDsaKey_GetSigLen / wc_SlhDsaKey_SigSize) plus wrapper headroom instead of a fixed 32768 magic number, so it scales to any parameter set. - Tests: add a post-quantum sigType/key mismatch negative case (a classic OID with a PQC key must return ALGO_ID_E). - Tests: assert the exact ASN_CRL_CONFIRM_E on the tampered-signature case rather than just "not success". - Tests: heap-allocate the issuer DER buffer instead of a 1 KB stack array.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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_exrejected anything other than RSA/ECC keys and sized its signature buffer withMAX_ENCODED_CLASSIC_SIG_SZ, far too small for PQC signatures.This PR closes that gap so wolfSSL can sign CRLs with ML-DSA (FIPS 204) and SLH-DSA (FIPS 205) keys.
Changes
wc_SignCRL_ex(wolfcrypt/src/asn.c) now acceptswc_MlDsaKey*andSlhDsaKey*signing keys and sizes the signature buffer from the key viaGetSignatureBufferSz()— the same PQC-aware sizing the certificate-generation path uses.MakeSignature(),AddSignature()andCheckSigTypeForKey()already handle PQC keys, so they are reused unchanged. The new key pointers are appended after the existing parameters so the RSA/ECC parameter order is preserved.wolfssl/wolfcrypt/asn_public.h) and the existing RSA/ECC caller (src/crl.c) updated to match.tests/api.c):test_wc_SignCRL_mldsaandtest_wc_SignCRL_slhdsa— build + sign + verify a CRL through the certificate manager against the issuing PQC CA, plus negative cases for a tampered signature (assertsASN_CRL_CONFIRM_E) and a sigType/key family mismatch (assertsALGO_ID_E). Coverage: ML-DSA-44/65/87 and SLH-DSA SHAKE-128s (SHA2-128s when built). Test vectors reuse the existingcerts/mldsa/andcerts/slhdsa/CA cert/key material.Scope note
wolfSSL's OpenSSL-compat
EVP_PKEYlayer has no PQC private-key support (wolfSSL_d2i_PrivateKeyhas no ML-DSA case andWOLFSSL_EVP_PKEYhas no PQC member), so PQC CRL signing is exposed through the wolfcrypt-levelwc_SignCRL_exAPI rather than thewolfSSL_X509_CRL_signEVP wrapper. Wiring the EVP layer for PQC is a separate, larger change and is intentionally out of scope here.Testing
openssl crl -verify→verify OK), confirming the emitted DER is standards-conformant.https://claude.ai/code/session_01AQerZ4diyqFynLJocio4CF
Generated by Claude Code