Closed
Conversation
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 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, 4*n bytes = SK.seed || SK.prf || PK.seed || PK.root, no nested wrapper) and OID auto-detection across all six SHAKE parameter sets. - 12 standardized NIST OIDs (6 SHA2 + 6 SHAKE) per RFC 9909. OID collision mechanism cleaned up since NIST OIDs don't collide. - Complete ASN.1 layer replacement (~500 lines in asn.c) and X.509 public-key handling in x509.c. - SHA2-SLH-DSA OIDs are recognized but the native backend is SHAKE-only; Private/PublicKeyDecode and ConfirmSignature return NOT_COMPILED_IN for SHA2 variants so callers get an informative error instead of a generic parse failure. - wc_GetKeyOID selects its placeholder parameter from whatever SHAKE variant is compiled in, so auto-detect works when specific variants (e.g. SHAKE128F) are disabled. - wc_SlhDsaKey_PublicKeyDecode saves and restores key->params and *inOutIdx on ImportPublic failure, matching PrivateKeyDecode. - DER round-trip and on-disk decode tests (bench_slhdsa_shake*_key.der fixtures regenerated with wolfSSL's own encoder, guaranteed RFC 9909 compliant) guard against future encoding drift. - SLH-DSA test cert chain generated with OpenSSL 3.5. - 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.
# Conflicts: # wolfcrypt/src/wc_slhdsa.c
Commit 9c22cf1 integrated SLH-DSA at the cert layer with all twelve RFC 9909 OIDs recognised but only the six SHAKE variants functional; SHA-2 OIDs were short-circuited to NOT_COMPILED_IN pending the native SHA-2 backend. Upstream PR wolfSSL#9843 (now merged at master via cf2db42) added that backend, so this commit drops the short-circuits and finishes the dispatch wiring. Changes: - wolfcrypt/src/wc_slhdsa.c: replace the SHA-2 NOT_COMPILED_IN cases in slhdsa_keytype_to_param() and slhdsa_param_to_keytype() with proper parameter mappings, gated by WOLFSSL_SLHDSA_SHA2 + WOLFSSL_SLHDSA_PARAM_NO_SHA2_* (PR wolfSSL#9843's macro names). Resolve merge conflict in wc_SlhDsaKey_ImportPublic() by keeping the |= flag preservation from the cert-layer integration and the SHA-2 midstate precomputation from PR wolfSSL#9843. - wolfcrypt/src/asn.c: extend ConfirmSignature() (SIG_STATE_KEY, SIG_STATE_DO, SIG_STATE_CHECK arms) and the keyType -> SLHDSA_* switches in EncodePublicKey(), MakeAnyCert(), wc_MakeCert_ex(), wc_SignCert_ex(), and the four other sites that dispatch on SLH_DSA_SHAKE_*_TYPE. Add SHA-2 PEM header/footer strings. - src/x509.c: extend the if-else chain that maps pubKeyOID to (type, SlhDsaParam) for SLH-DSA cert public-key load and the matching cleanup chain. - certs/slhdsa/bench_slhdsa_sha2_*_key.der: add six DER fixtures (one per SHA-2 parameter set) for the decode-files round-trip test. - tests/api/test_slhdsa.c: extend test_wc_slhdsa, _sizes, _der_roundtrip, _der_decode_files for SHA-2 variants. Add a new test_wc_slhdsa_cert_roundtrip that mints a self-signed cert with each of the twelve variants via wc_MakeCert_ex/wc_SignCert_ex and parses it back through ParseCert. - scripts/slhdsa-interop.test: new driver that runs the four-stage matrix (testwolfcrypt, cert-roundtrip, der-roundtrip, decode-files) for all twelve variants and optionally exercises OpenSSL+oqs-provider cross-stack when OQS_PROVIDER=1 is set. - scripts/include.am: wire the new test into BUILD_WC_SLHDSA. Verified: 48/48 PASS in scripts/slhdsa-interop.test; oqs-provider absent on this host so the cross-stack arm reports SKIPPED-EXTERNAL. https://claude.ai/code/session_01QV3GAEfzRSTiGsptuh8kdD
Fixes raised in self-review of 0030231: ConfirmSignature SLH-DSA arm fixes wc_SlhDsaKey_PublicKeyDecode (which expects an SPKI envelope) being called with cert->ca->publicKey -- which is the raw key bytes that StoreKey() copies out of the BIT STRING. The SHAKE side had this latent bug since 9c22cf1; it surfaced when the new test_wc_slhdsa_cert_roundtrip drove ConfirmSignature for the first time. Replaced with wc_SlhDsaKey_ImportPublic on the raw bytes. slhdsa_keytype_to_param() and slhdsa_param_to_keytype(): the SHA-2 arms now use the same axis macros as the SHAKE side (WOLFSSL_SLHDSA_PARAM_NO_SHA2_{128,192,256} and WOLFSSL_SLHDSA_PARAM_NO_SHA2_{SMALL,FAST}) instead of the per-variant WOLFSSL_SLHDSA_PARAM_NO_SHA2_*S/F. Setting WOLFSSL_SLHDSA_PARAM_NO_SHA2_128 now drops both 128S and 128F symmetrically with WOLFSSL_SLHDSA_NO_128. Restored the NOT_COMPILED_IN diagnostic when a SHA-2 SLH-DSA OID is parsed in a build that did not enable WOLFSSL_SLHDSA_SHA2: both slhdsa_keytype_to_param and the SIG_STATE_KEY arm of ConfirmSignature now report NOT_COMPILED_IN rather than the generic ASN_UNKNOWN_OID_E / BAD_FUNC_ARG. Documented the safety reasoning for the |= flag preservation in wc_SlhDsaKey_ImportPublic and removed the now-stale workaround comment in test_wc_slhdsa_check_key. Documented the underscore PEM label non-interop convention. Tests: extended test_wc_slhdsa_make_key and test_wc_slhdsa_sign_vfy to iterate all six SHA-2 variants (they previously only iterated SHAKE). test_wc_slhdsa_cert_roundtrip now drives ConfirmSignature directly with the parsed cert components (NO_VERIFY parse + manual ConfirmSignature), so the SHA-2 OID dispatch in ConfirmSignature is actually exercised end to end -- not just claimed to be. scripts/slhdsa-interop.test rewritten for genuine per-variant resolution: forks one process per variant via the new wolfcrypt/test/slhdsa_interop_one helper which mints a self-signed cert in that variant and runs ConfirmSignature against it. PASS/FAIL/SKIP-LOCAL status is now per-variant rather than a single test result fanned out. The OQS_PROVIDER stage is relabeled as a registration probe rather than "interop" since it doesn't run a TLS handshake. scripts/gen-slhdsa-fixtures.c: committed the previously-throwaway generator for the bench_slhdsa_*_key.der fixtures so reviewers and future maintainers can regenerate them. Run from the source root after build; not part of the default build (kept under scripts/). Verified: ./tests/unit.test reports test_wc_slhdsa_cert_roundtrip passing for all 12 variants; ./scripts/slhdsa-interop.test reports 12 PASS / 0 FAIL / 0 SKIP-LOCAL via 12 separate processes. https://claude.ai/code/session_01QV3GAEfzRSTiGsptuh8kdD
Addresses the second-round review of fac240d: ConfirmSignature SLH-DSA arm: deleted the orphaned word32 idx declaration and (void)idx cast. Tightened the comment to flag that this changes verify behaviour for ALL SLH-DSA variants (SHAKE + SHA-2), since the prior code path was never working in either case. Dispatch gating in slhdsa_keytype_to_param() and slhdsa_param_to_keytype() now uses per-variant macros (WOLFSSL_SLHDSA_PARAM_NO_SHA2_*S/F) matching the SlhDsaParams[] table, not the axis macros (_128/_192/_256/_SMALL/_FAST). A user_settings.h that disables a single SHA-2 variant via the per-variant macro alone no longer leaves the dispatch pointing at a parameter set that slhdsa_find_params() will not find. Added SLHDSA_SHA2_OID_CASE_LABELS to wolfssl/wolfcrypt/asn.h so the six SHA-2 OID case labels exist as a single definition. Used at the four sites that previously open-coded the list (NOT_COMPILED_IN tail in slhdsa_keytype_to_param; SIG_STATE_KEY / SIG_STATE_DO / SIG_STATE_CHECK arms in ConfirmSignature). scripts/gen-slhdsa-fixtures.c: deterministic. Switched from wc_SlhDsaKey_MakeKey(rng) to MakeKeyWithRandom() with fixed per-variant fill bytes for SK.seed, SK.prf, PK.seed. Re-running the generator now produces byte-identical .der files. Wired into autotools as a noinst_PROGRAMS target so it builds with `make` (no more bespoke gcc invocation in the header) under --enable-slhdsa --enable-keygen --enable-certgen. All twelve bench_slhdsa_*_key.der fixtures regenerated deterministically. scripts/slhdsa-interop.test: - Honours $(top_builddir) / $(top_srcdir) when run from automake so out-of-tree builds find the helper binary. - Counts PROBE-OK in the summary so totals balance to 24 (12 variants x 2 stages) when the OQS path runs successfully. - Aborts on rc=99 (framework error) from the helper rather than treating it as a regular FAIL. - Comment on the note_* helpers warns the next maintainer that the counters are shell-local and a subshell wrapper would zero them. wolfcrypt/test/slhdsa_interop_one: returns 99 (automake hard error) for unknown-variant or wrong-arg-count, so a typo in a future driver won't be misclassified as a per-variant test FAIL. Added a sister- function pointer to test_wc_slhdsa_cert_roundtrip so future API changes can find both copies. DISTCLEANFILES: added wolfcrypt/test/.libs/slhdsa_interop_one and scripts/.libs/gen-slhdsa-fixtures so `make distclean` sweeps them. tests/api/test_slhdsa.c: removed the leftover <wolfssl/ssl.h> include (the CertManager attempt was abandoned in the previous round but the include lingered). Verified: all 13 SLH-DSA unit tests pass; scripts/slhdsa-interop.test reports 12 PASS / 0 FAIL / 0 SKIP-LOCAL / 0 PROBE-OK / 12 SKIP-EXTERNAL with balanced totals; gen-slhdsa-fixtures produces byte-stable fixtures across re-runs. https://claude.ai/code/session_01QV3GAEfzRSTiGsptuh8kdD
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.
Description
Please describe the scope of the fix or feature addition.
Fixes zd#
Testing
How did you test?
Checklist