Replace liboqs SPHINCS+ with native SLH-DSA in certificate layer#5
Closed
Replace liboqs SPHINCS+ with native SLH-DSA in certificate layer#5
Conversation
Frauschi
commented
Apr 13, 2026
Frauschi
commented
Apr 13, 2026
| } | ||
| #endif /* HAVE_DILITHIUM */ | ||
| #if defined(WOLFSSL_HAVE_SLHDSA) | ||
| #if !defined(NO_RSA) || defined(HAVE_ECC) |
Frauschi
commented
Apr 14, 2026
Frauschi
pushed a commit
that referenced
this pull request
Apr 14, 2026
Add SLH-DSA as a TLS 1.3 signature algorithm for entity authentication in the handshake, per draft-reddy-tls-slhdsa-02. This builds on the certificate-layer SLH-DSA support (PR #5) and adds: TLS 1.3 SignatureScheme negotiation: - 6 SHAKE code points (0x0917-0x091C) with PQC_SA_MAJOR = 0x09 - EncodeSigAlg / DecodeTls13SigAlg / DecodeSigAlg - PickHashSigAlgo with SLH-DSA pkCurveOID matching - MatchSigAlgo for all 6 SHAKE variants - SIG_SLHDSA flag in SIG_ALL CertificateVerify signing and verification: - SendTls13CertificateVerify with SLH-DSA signing (empty context) - DoTls13CertificateVerify with SLH-DSA verification - Record fragmentation for signatures > MAX_RECORD_SIZE (16384 bytes) - Saves tail plaintext before in-place encryption - Loops through N fragments for arbitrarily large signatures - Tested with SHAKE-256f (49856-byte sig, 4 records) Peer key management: - peerSlhDsaKey / peerSlhDsaKeyPresent in WOLFSSL struct - AllocKey / FreeKey / ReuseKey for DYNAMIC_TYPE_SLHDSA - ProcessPeerCerts extracts SLH-DSA peer keys with param auto-detect Key loading: - ProcessBufferTryDecodeSlhDsa for SLH-DSA private key loading - ProcessBufferCertSetHave / ProcessBufferKeySet for haveSlhDsaSig Infrastructure: - haveSlhDsaSig, minSlhDsaKeySz in Options and CTX - MAX_X509_SIZE = 56*1024 for SLH-DSA (SHAKE-256f cert ~50KB) - WC_MAX_CERT_VERIFY_SZ = 49920 for SLH-DSA-SHAKE-256f - OpenSSL 3.5-generated SLH-DSA-SHAKE-128s cert chain for testing Interop tested with OQS provider (OpenSSL 3.4 + liboqs): - SHAKE-128s (7856-byte sig, 1 record) - bidirectional - SHAKE-128f (17088-byte sig, 2 records) - bidirectional - SHAKE-256f (49856-byte sig, 4 records) - bidirectional https://claude.ai/code/session_019gqvW3ZMKGGyi6zCRNPDYV
4 tasks
38b3c3e to
5f875ba
Compare
Replace the liboqs-based pre-standardization SPHINCS+ implementation with the native FIPS 205 SLH-DSA implementation across the certificate/ASN.1/X.509 layers. All liboqs SPHINCS+ code is removed. This PR enables SLH-DSA for certificate chain authentication (CA certificates signed with SLH-DSA, certificate verification). TLS 1.3 entity authentication via CertificateVerify with SLH-DSA will be added in a follow-up PR. Follows RFC 9909 (X.509 Algorithm Identifiers for SLH-DSA). Changes: - New DER codec for SLH-DSA (PrivateKeyDecode, PublicKeyDecode, KeyToDer, PrivateKeyToDer, PublicKeyToDer) with RFC 9909 compliant encoding (bare OCTET STRING, no nested wrapper) and OID auto- detection across all 6 SHAKE parameter sets - 12 standardized NIST OIDs (6 SHA2 + 6 SHAKE) per RFC 9909 - Complete ASN.1 layer replacement (~500 lines in asn.c) - X.509 public key handling in x509.c - OID collision mechanism cleaned up (NIST OIDs don't collide) - DER round-trip test for all compiled-in parameter sets - SLH-DSA test cert chain generated with OpenSSL 3.5 - All build system/IDE project files updated - SPHINCS+ source files, headers, and test data removed https://claude.ai/code/session_019gqvW3ZMKGGyi6zCRNPDYV
5f875ba to
1d23ad3
Compare
Frauschi
pushed a commit
that referenced
this pull request
May 3, 2026
Negative findings from review of 3b2d711: - Drop redundant `(word16)` inner cast in `wc_xmss_impl.c` (#1): `(word16)((word16)hs * n)` -> `(word16)(hs * n)`. The inner cast added nothing; word8 promotes to int regardless. - Normalize `(word32)1` to `(word32)1U` across the file (#5) so the pre-existing call sites match the style of the new shifts. - Defensive guard in `wc_xmss_hash_message` (#2): if `idx_len > params->n` ever holds, the explicit `(word32)(params->n - idx_len)` cast that silenced the warning would otherwise produce a ~4 GB XMEMSET. Set state->ret = WC_FAILURE and bail; the invariant is structural for valid parameter sets. - Defensive guard in `wc_idx_copy` (#3): if `dl < sl` is ever passed, the word32 subtraction wraps and the XMEMSET corrupts memory. Same structural invariant; early return rather than crash. - Extend `test_xmss_runtime` (#7, #8) from 2 to 4 configurations: 1. --enable-xmss (default) 2. --enable-xmss=yes,small 3. --enable-xmss=yes,verify-only (NEW: RFC 8391 test vectors) 4. --enable-xmss --enable-32bit -m32 (NEW: catches 32-bit width-dependent bugs in tree-index arithmetic; XmssIdx narrows to word32 there) The 32-bit row needs gcc-multilib so the job now installs it. Verified locally: - All 13 build_library matrix rows compile clean under the conversion flags. - testwolfcrypt's "XMSS Vfy" / "XMSS" pass for --enable-xmss, --enable-xmss=yes,small, --enable-xmss=yes,verify-only, and --enable-xmss --enable-32bit (4/4). - bench_xmss_xmssmt re-run with `-DBENCH_MIN_RUNTIME_SEC=5.0F` for longer averaging. Sign/verify deltas range -10% to +15% with no coherent regression pattern across parameter sets (the largest moves in either direction are on neighbouring rows of the same hash family), consistent with shared-system run-to-run noise rather than a real perf change. Single-sample keygens (1 op per measurement) carry expectedly high variance (-7% to +57%); sign/verify with hundreds to thousands of ops per measurement are the meaningful signal. https://claude.ai/code/session_01EJmy1bKDgHseTwZ5Qqpu1g
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
This PR replaces the liboqs-based pre-standardization SPHINCS+ implementation with the native FIPS 205 SLH-DSA implementation across the certificate/ASN.1/X.509 layers. All liboqs SPHINCS+ code is removed.
This enables SLH-DSA for certificate chain authentication (CA certificates signed with SLH-DSA, certificate verification). TLS 1.3 entity authentication via CertificateVerify with SLH-DSA will be added in the follow-up PR #6.
Follows RFC 9909 (X.509 Algorithm Identifiers for SLH-DSA).
Changes
New DER codec for SLH-DSA
wc_SlhDsaKey_PrivateKeyDecode,wc_SlhDsaKey_PublicKeyDecodewc_SlhDsaKey_KeyToDer,wc_SlhDsaKey_PrivateKeyToDer,wc_SlhDsaKey_PublicKeyToDerOIDs (RFC 9909)
12 standardized NIST OIDs under
2.16.840.1.101.3.4.3:AlgorithmIdentifier parameters are absent per RFC 9909. Context string is empty for X.509 certificate signing.
Certificate/ASN.1 layer
wolfcrypt/src/asn.cand ~70 inasn_orig.cwc_SlhDsaKey_Sign(key, NULL, 0, ...)wc_SlhDsaKey_Verify(key, NULL, 0, ...)X.509 layer
sphincs_keyhandling withSlhDsaKeyinsrc/x509.cBuild system
HAVE_SPHINCSremoved fromHAVE_LIBOQSblock insettings.hsphincs.cremoved fromBUILD_LIBOQSsourcesTest infrastructure
test_wc_slhdsa_der_roundtrip: DER encode/decode round-trip for all compiled-in SHAKE parameter sets with deliberate placeholder param mismatch to verify auto-detectioncerts/slhdsa/certs_test.handgencertbuf.plRemoved
wolfcrypt/src/sphincs.c,wolfssl/wolfcrypt/sphincs.hcerts/sphincs/directoryFollow-up
PR #6 adds SLH-DSA TLS 1.3 entity authentication (CertificateVerify signing/verification, SignatureScheme negotiation, record fragmentation for large signatures, OQS interop).
Test plan
./configure --enable-slhdsa && makeSLH-DSA test passed!including DER round-trip testDYNAMIC_TYPE_SPHINCS = 98ABI placeholder)https://claude.ai/code/session_019gqvW3ZMKGGyi6zCRNPDYV