Skip to content

Add SLH-DSA TLS 1.3 entity authentication (CertificateVerify)#6

Open
Frauschi wants to merge 2 commits intoclaude/sphincs-to-slhdsa-transition-VhszIfrom
claude/slhdsa-tls-handshake
Open

Add SLH-DSA TLS 1.3 entity authentication (CertificateVerify)#6
Frauschi wants to merge 2 commits intoclaude/sphincs-to-slhdsa-transition-VhszIfrom
claude/slhdsa-tls-handshake

Conversation

@Frauschi
Copy link
Copy Markdown
Owner

Summary

Adds SLH-DSA as a TLS 1.3 signature algorithm for entity authentication per draft-reddy-tls-slhdsa-02. This builds on the certificate-layer SLH-DSA support in PR #5.

Depends on: PR #5 (must be merged first)

Changes

TLS 1.3 SignatureScheme negotiation

  • 6 SHAKE code points (0x0917-0x091C) with PQC_SA_MAJOR = 0x09
  • EncodeSigAlg / DecodeTls13SigAlg / DecodeSigAlg for SLH-DSA
  • PickHashSigAlgo with SLH-DSA pkCurveOID matching
  • MatchSigAlgo for all 6 SHAKE variants
  • SIG_SLHDSA flag in SIG_ALL

CertificateVerify signing and verification

  • SendTls13CertificateVerify: SLH-DSA signing with empty context per spec
  • DoTls13CertificateVerify: SLH-DSA verification
  • Record fragmentation for signatures > 16384 bytes (MAX_RECORD_SIZE):
    • Saves tail plaintext before in-place encryption to avoid corruption
    • Loops through N fragments for arbitrarily large signatures
    • Tested with SHAKE-256f (49856-byte signature, 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

  • MAX_X509_SIZE = 56*1024 for SLH-DSA (SHAKE-256f cert ~50KB)
  • WC_MAX_CERT_VERIFY_SZ = 49920 for SLH-DSA-SHAKE-256f
  • MIN_SLHDSAKEY_SZ = 32 (smallest SLH-DSA public key)
  • OpenSSL 3.5-generated SLH-DSA-SHAKE-128s cert chain

Interop test results

Tested with OQS provider (OpenSSL 3.4 + liboqs) in both directions:

Variant Sig Size Records wolfssl-wolfssl wolfssl-OQS OQS-wolfssl
SHAKE-128s 7,856 1 PASS PASS PASS
SHAKE-128f 17,088 2 PASS PASS PASS
SHAKE-256f 49,856 4 PASS PASS PASS

Test plan

  • wolfcrypt tests pass (SLH-DSA test passed!)
  • wolfssl-to-wolfssl TLS 1.3 handshake with SLH-DSA certs (all 3 variants)
  • OQS interop in both directions (all 3 variants)
  • CertificateVerify record fragmentation works for signatures up to 50KB

https://claude.ai/code/session_019gqvW3ZMKGGyi6zCRNPDYV

claude added 2 commits April 14, 2026 08:25
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
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
@Frauschi Frauschi force-pushed the claude/sphincs-to-slhdsa-transition-VhszI branch 3 times, most recently from 5f875ba to 1d23ad3 Compare April 16, 2026 12:43
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.

2 participants