Commit Graph

6 Commits

Author SHA1 Message Date
Tobias Frauenschläger 28468b44f5 Support RFC 9802 LMS and XMSS in X.509 verification
Wire the stateful hash-based signature schemes HSS/LMS (RFC 8554) and
XMSS / XMSS^MT (RFC 8391) into the X.509 cert-verification path per
RFC 9802.

asn:
- Register id-alg-hss-lms-hashsig (1.2.840.113549.1.9.16.3.17),
  id-alg-xmss-hashsig (1.3.6.1.5.5.7.6.34) and id-alg-xmssmt-hashsig
  (1.3.6.1.5.5.7.6.35) in oid_sum.h, asn.c and asn1_oid_sum.pl.
- Plumb the new keyOIDs through GetCertKey, SigOidMatchesKeyOid,
  HashForSignature, FreeSignatureCtx and ConfirmSignature so leaf
  and CA certificates parse, load and verify end-to-end.
- Rename IsSigAlgoECC -> IsSigAlgoNoParams; the function has tested
  "AlgorithmIdentifier omits NULL parameters" since PQC algos were
  added, and HSS/LMS + XMSS only made the original name more
  misleading.

wc_lms / wc_xmss:
- Add wc_XmssKey_ImportPubRaw_ex which derives parameters from the
  4-byte OID prefix at the start of the raw public key, taking an
  is_xmssmt hint to disambiguate the overlapping XMSS / XMSS^MT OID
  spaces.
- Extend wc_LmsKey_ImportPubRaw with the same auto-derive from
  u32str(L) || lmsType || lmOtsType when key->params is NULL; this
  also fixes a latent NULL-deref when the legacy precondition was
  violated.
- Reject WC_*_STATE_OK in both ImportPubRaw paths so re-importing
  on a private-key-loaded handle can't desync priv/pub.
- Tighten wc_XmssKey_Verify's length check to strict equality,
  matching wc_LmsKey_Verify and the documented contract of using
  wc_XmssKey_GetSigLen for the buffer size.

tests / fixtures:
- Bouncy Castle 1.81 fixtures in certs/lms and certs/xmss covering
  every supported parameter set, plus CA->leaf chains per family
  and one BC-native LMS fixture as a cross-impl interop gate.
- New api tests verify each fixture end-to-end, tamper TBS and
  signature bytes, exercise the wolfCrypt-level negative paths
  (NOT_COMPILED_IN, BUFFER_E, BAD_FUNC_ARG, BAD_STATE_E, OID/family
  mismatch, partial-write invariants, lenient VERIFYONLY re-import,
  strict sigLen check) and confirm the outer signatureAlgorithm
  OID is rejected when it disagrees with the SPKI in both
  XMSS<->XMSS^MT directions.
2026-05-07 17:14:31 +02:00
Tobias Frauenschläger 9393d62591 Replace liboqs SPHINCS+ with SLH-DSA in certificate layer
Replace the liboqs-based pre-standardization SPHINCS+ implementation
with the native FIPS 205 SLH-DSA implementation across the
certificate / ASN.1 / X.509 layers, and add SLH-DSA-rooted test
certificates plus TLS 1.3 .conf scenarios that exercise the new
verification path. All liboqs SPHINCS+ code is removed.

This enables SLH-DSA for certificate chain authentication: CA
certificates signed with SLH-DSA, certificate signature verification
against an SLH-DSA root. 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) and
NIST FIPS 205. Supports both SHAKE and SHA-2 parameter families
across all twelve standardized variants.

DER codec:
- New PrivateKeyDecode, PublicKeyDecode, KeyToDer, PrivateKeyToDer,
  PublicKeyToDer with RFC 9909 encoding (bare OCTET STRING containing
  4*n raw bytes = SK.seed || SK.prf || PK.seed || PK.root, no nested
  wrapper). OID auto-detection across all twelve SHAKE / SHA-2 variants.
- PublicKeyDecode raw-bytes fast path mirrors wc_Falcon_PublicKeyDecode
  and wc_Dilithium_PublicKeyDecode so callers (notably
  wolfssl_x509_make_der and ConfirmSignature, which pass the raw
  BIT STRING contents stashed by StoreKey) decode correctly. Honours
  the caller's *inOutIdx start offset.
- Error paths in Private/PublicKeyDecode preserve params/flags/
  inOutIdx and only ForceZero the buffer half each helper actually
  writes; skip the wipe entirely on BAD_LENGTH_E (no bytes touched).
- ImportPublic uses |= on flags so a Private-then-Public import
  sequence retains FLAG_PRIVATE.

OID dispatch:
- 12 standardized NIST OIDs (6 SHAKE + 6 SHA-2) per RFC 9909. The
  pre-standardization OID-collision mechanism is removed since NIST
  OIDs do not collide.
- wc_SlhDsaOidToParam / wc_SlhDsaOidToCertType return NOT_COMPILED_IN
  (rather than -1) for recognised SLH-DSA OIDs whose parameter set
  isn't built; wc_IsSlhDsaOid recognises both. The x509 dispatch
  surfaces this as a precise diagnostic instead of the generic
  "No public key found".
- wc_GetKeyOID picks a placeholder parameter from whatever variant is
  compiled in and #errors at compile time if none is.
- asn_orig.c EncodeCert / EncodeCertReq accept SHA-2 SLH-DSA keyTypes
  alongside SHAKE.

Tests and fixtures:
- Test cert chain in certs/slhdsa/: SLH-DSA-SHAKE-128s and
  SLH-DSA-SHA2-128s self-signed roots that sign reused ML-DSA-44
  entity keys (server + client), plus the gen script
  (gen-slhdsa-mldsa-certs.sh, OpenSSL >= 3.5).
- New TLS 1.3 .conf scenarios under tests/suites.c dispatch:
  test-tls13-slhdsa-shake.conf, test-tls13-slhdsa-sha2.conf, and a
  wrong-CA negative test test-tls13-slhdsa-fail.conf.
- DER round-trip and on-disk decode tests; bench_slhdsa_*_key.der
  fixtures regenerated with wolfSSL's own encoder so the codec is
  pinned to RFC 9909.
- New unit test test_wc_slhdsa_x509_i2d_roundtrip exercises the raw
  PublicKeyDecode entry point that wolfssl_x509_make_der relies on.
- test_wc_slhdsa_check_key now tests both Public-then-Private and
  Private-then-Public import orderings.

Build / ABI:
- DYNAMIC_TYPE_SPHINCS = 98 kept as RESERVED with a tombstone comment
  for ABI stability; new code should use DYNAMIC_TYPE_SLHDSA (107).
- All build system / IDE project files updated; SPHINCS+ sources,
  headers, and test data removed.
- Dead bench_slhdsa_*_key arrays removed from gencertbuf.pl and
  certs_test.h; the .der files on disk drive the decode tests.
2026-04-30 18:32:07 +02:00
Tobias Frauenschläger 7a2cf5b655 Remove liboqs for ML-KEM and ML-DSA, update for Falcon 2026-04-30 11:03:06 +02:00
JacobBarthelmeh a156ed7bc7 update Copyright year 2026-02-18 09:52:21 -07:00
JacobBarthelmeh 629c5b4cf6 updating license from GPLv2 to GPLv3 2025-07-10 16:11:36 -06:00
Sean Parkinson 112351667a ASN.1 OIDs and sum: Change algorithm for sum
New sum algorithm has no clashes at this time.
Old algorithm enabled by defining: WOLFSSL_OLD_OID_SUM.
New oid_sum.h file generated with scripts/asn1_oid_sum.pl.

Added bunch of OID names into asn1 example.
2025-05-07 08:32:08 +10:00