Skip to content

Add SLH-DSA Support - #455

Open
aidangarske wants to merge 29 commits into
wolfSSL:masterfrom
aidangarske:add-slhdsa
Open

Add SLH-DSA Support#455
aidangarske wants to merge 29 commits into
wolfSSL:masterfrom
aidangarske:add-slhdsa

Conversation

@aidangarske

@aidangarske aidangarske commented Jul 30, 2026

Copy link
Copy Markdown
Member

Copilot AI review requested due to automatic review settings July 30, 2026 18:04

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@aidangarske
aidangarske force-pushed the add-slhdsa branch 2 times, most recently from 0487400 to 02cbe8b Compare July 30, 2026 18:27
@aidangarske aidangarske added the ci:nginx-pqc PR OSP toggle: run nginx-pqc label Jul 30, 2026
@aidangarske aidangarske added ci:libacvp-pqc PR OSP toggle: run libacvp-pqc and removed ci:nginx-pqc PR OSP toggle: run nginx-pqc ci:libacvp-pqc PR OSP toggle: run libacvp-pqc labels Jul 30, 2026
@aidangarske aidangarske added ci:libacvp-pqc PR OSP toggle: run libacvp-pqc and removed ci:libacvp-pqc PR OSP toggle: run libacvp-pqc labels Jul 30, 2026
@aidangarske
aidangarske marked this pull request as ready for review July 30, 2026 23:26
@aidangarske
aidangarske force-pushed the add-slhdsa branch 2 times, most recently from 8bf2ba2 to ba88c76 Compare July 31, 2026 01:05
@aidangarske aidangarske added ci:libacvp-pqc PR OSP toggle: run libacvp-pqc and removed ci:libacvp-pqc PR OSP toggle: run libacvp-pqc labels Jul 31, 2026

@Frauschi Frauschi left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🐺 Skoll Code Review

Overall recommendation: REQUEST_CHANGES
Findings: 26 total — 15 posted, 11 skipped

Posted findings

  • [High] Examples are check_PROGRAMS so every build configuration runs them via make check, and CI's example steps silently depend on thatexamples/include.am:22-32
  • [High] pqc_openssl_example hard-codes SLH-DSA-SHA2-128f, which is absent whenever WOLFPROV_HAVE_SLHDSA is set but SHA2 sets are not builtexamples/pqc_openssl_example.c:210-218
  • [Medium] wp_encrypt_key_pkcs8: reports the output buffer size as the encrypted length, and ignores the RNG lock result its sibling now checkssrc/wp_internal.c:1110-1133
  • [Medium] Deterministic seed handling: seedLen survives gen_set_params failure paths, and validator and consumer compute the expected length differentlysrc/wp_slhdsa_kmgmt.c:1159-1174
  • [Medium] wp_slhdsa_import flag handling: asserts hasPub instead of verifying it, and wipes hasPub/hasPriv on failuresrc/wp_slhdsa_kmgmt.c:690-702
  • [Medium] Signature context state (context string, deterministic, entropy, encoding) persists across re-initsrc/wp_slhdsa_sig.c:284-291
  • [Medium] Uninitialized locals may break the build under the project's own -Werror hardeningsrc/wp_slhdsa_sig.c:338
  • [Medium] SLH-DSA key mutex covers only sign/verify and the refcount: keymgmt readers, import writers, and lock scope are all unguardedsrc/wp_slhdsa_kmgmt.c:432
  • [Medium] wp_dh_sync_priv_to_key mutates the shared inner DhKey unlocked, and wp_dh_encode_epki depends on the size function having run firstsrc/wp_dh_kmgmt.c:2789-2837
  • [Low] OSSL_SIGNATURE_PARAM_DETERMINISTIC is sent as unsigned int but advertised and read as inttest/test_slhdsa.c:1139
  • [Low] wp_slhdsa_free refcount handling: unsynchronized read, permanent leak when wc_LockMutex fails, and up_ref/free test the mutex result differentlysrc/wp_slhdsa_kmgmt.c:363-391
  • [Low] SLH-DSA export and get_params report the wrong outcome when a key component is absentsrc/wp_slhdsa_kmgmt.c:805-875
  • [Low] wp_slhdsa_gen_init_base calls wc_FreeRng on an RNG that wc_InitRng may never have initializedsrc/wp_slhdsa_kmgmt.c:1067-1091
  • [Low] Encoder dispatch binds OSSL_FUNC_ENCODER_IMPORT_OBJECT to a function with a mismatched signaturesrc/wp_slhdsa_kmgmt.c:1978
  • [Info] Preprocessor hygiene in the new SLH-DSA files: dead version guards, a redundant #ifndef, a dropped WP_HAVE_PKCS8_ENC guard, and a stale #endifsrc/wp_slhdsa_kmgmt.c:1985-1996
Skipped findings
  • [Medium] Encrypted-PKCS#8 PEM decode without WOLFSSL_ENCRYPTED_KEYS is unverified in the FIPS config it targets
  • [Medium] SLH-DSA test gating: verify-only builds, the decoder parameter-set mismatch, and the per-parameter-set macros are all untested
  • [Medium] New encrypted-PKCS#8 tests are guarded out of the exact configurations they were written for
  • [Medium] libacvp-pqc workflow pinned to a personal OSP fork branch
  • [Low] test_pki_cipher_encrypts stub comment contradicts the new fail-closed behaviour
  • [Low] test_slhdsa.c helper robustness: slhdsa_get_raw reads *out on its failure path, and pubonly_sign_fails passes silently on allocation failure
  • [Low] wp_cipher_from_params keeps a previously set cipher when the param has the wrong data type
  • [Low] wp_dh_fix_pki_len: doc block misattached and no bounds check
  • [Low] SLH-DSA key state is read from wolfSSL struct internals, with no has_private accessor of the kind ML-DSA exposes
  • [Info] PEM buffer is cleansed with the written length rather than the allocated length
  • [Info] openssl_example prints "self-test passed" although the provider registers no self-test callback

Review generated by Skoll via Claude/Codex

Comment thread examples/include.am Outdated
Comment thread examples/pqc_openssl_example.c Outdated
Comment thread src/wp_internal.c
Comment thread src/wp_slhdsa_kmgmt.c
Comment thread src/wp_slhdsa_kmgmt.c
Comment thread src/wp_slhdsa_kmgmt.c
Comment thread src/wp_slhdsa_kmgmt.c
Comment thread src/wp_slhdsa_kmgmt.c
Comment thread src/wp_slhdsa_kmgmt.c Outdated
Comment thread src/wp_slhdsa_kmgmt.c Outdated
@aidangarske aidangarske added ci:libacvp-pqc PR OSP toggle: run libacvp-pqc and removed ci:libacvp-pqc PR OSP toggle: run libacvp-pqc labels Jul 31, 2026
@aidangarske
aidangarske requested a review from Frauschi July 31, 2026 19:38
@aidangarske aidangarske added the ci:libacvp-pqc PR OSP toggle: run libacvp-pqc label Aug 4, 2026
@aidangarske aidangarske added ci:libacvp-pqc PR OSP toggle: run libacvp-pqc and removed ci:libacvp-pqc PR OSP toggle: run libacvp-pqc labels Aug 4, 2026

@Frauschi Frauschi left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🐺 Skoll Code Review

Overall recommendation: REQUEST_CHANGES
Findings: 26 total — 20 posted, 6 skipped

Posted findings

  • [High] wp_internal.c fails to compile when WP_HAVE_PKCS8_ENC is undefined: WP_CIPHER_NAMES_LEN is used outside the #ifdef that defines itsrc/wp_internal.c:891-967
  • [Medium] pem2der accepts ENCRYPTED PRIVATE KEY PEM in non-WOLFSSL_ENCRYPTED_KEYS builds and mislabels it as PrivateKeyInfosrc/wp_dec_pem2der.c:323-336
  • [Medium] Raw-message mode and the other signature params are now sticky across re-init, contradicting the ML-DSA siblingsrc/wp_slhdsa_sig.c:286-295
  • [Medium] PQC gating produces degenerate artifacts: the example runs keygen in verify-only builds, can compile to an empty body that exits 0, and the interop arrays can degenerate to empty initialisersexamples/pqc_openssl_example.c:151-152,262
  • [Medium] DH key data is guarded by two different mutexes: wp_dh_encode takes the new keyMutex while wp_dh_sync_priv_to_key still uses the reference-count mutexsrc/wp_dh_kmgmt.c:2648-2696
  • [Medium] Capacity checks on the PKCS#8 encrypt path run after the write, not beforesrc/wp_dh_kmgmt.c:3006-3008, src/wp_internal.c:1167
  • [Medium] DH key mutex is held across the application passphrase callback in the encrypted-PKCS#8 encode pathsrc/wp_dh_kmgmt.c:2913-3012
  • [Medium] SLH-DSA keyMutex discipline is inconsistent: sign/verify never re-validate hasPriv/hasPub under the lock, slhdsa->data and the decode/gen/dup writers skip it entirely, yet the lock is held across the whole signing operationsrc/wp_slhdsa_kmgmt.c:851-866
  • [Low] derAllocLen cleanse fix applied to DH only; ECC and RSA still cleanse the post-encode lengthsrc/wp_ecc_kmgmt.c:3100, src/wp_rsa_kmgmt.c:3693
  • [Low] DH type-specific encoder still accepts a cipher while ECC and RSA now refusesrc/wp_dh_kmgmt.c:2925-2930
  • [Low] Dead second wp_unlock(keyMutex) in wp_dh_encode gives a false cleanup guaranteesrc/wp_dh_kmgmt.c:3009-3012,3059-3061
  • [Low] Two defects in the new set_ctx_params staging block: validation silently degrades when no key is attached, and the staged context buffer retains the tail of the previous context stringsrc/wp_slhdsa_sig.c:796-807,844-855
  • [Low] wp_slhdsa_dup returns an empty key object when the selected components are absent, and its locked flag is never cleared so the early-return path unlocks by handsrc/wp_slhdsa_kmgmt.c:434-510
  • [Low] test_pkey_cipher returns success from all of its failure paths, so the new PKCS#8 CLI test can never failscripts/cmd_test/pkcs8-cmd-test.sh:18-73
  • [Low] CI and script hygiene: the new pkcs8 cmd test breaks four repo conventions, the libacvp force-fail row tests a narrower scope than the normal row, and the PQC/nginx changes left stale references behindscripts/cmd_test/pkcs8-cmd-test.sh:1,13, scripts/cmd_test/clean-cmd-test.sh:38, .gitignore:87
  • [Low] New tests assert the wrong thing: three robustness defects in the test_slhdsa.c helpers, and the cipher-rejection tests report the wrong cause while leaving the error queue dirtytest/test_slhdsa.c:123,239,950
  • [Low] wp_internal.c PKCS#8 helper hygiene: wp_encrypt_key_pkcs8_size missed the NULL-argument hardening, the RNG unlock is indented as if outside its enclosing block, and wp_cipher_from_params' doc comment omits the new clear-on-failure semanticssrc/wp_internal.c:997-1053
  • [Low] Message-API entry points omit WOLFPROV_ENTER/WOLFPROV_LEAVEsrc/wp_slhdsa_sig.c:623-643
  • [Low] wp_slhdsa_free still permanently leaks the key object, its private key material and both mutexes when wc_LockMutex(&refMutex) failssrc/wp_slhdsa_kmgmt.c:373-404
  • [Low] wp_slhdsa_export_object locks a borrowed key pointer from the decoder reference without holding a reference on itsrc/wp_slhdsa_kmgmt.c:1977-1994
Skipped findings
  • [Low] New ECX EPKI interop assertions are dead code in every CI configuration
  • [Low] SLH-DSA coverage gaps remain: signature negative paths, the keymgmt export and buffer-too-small branches, the AlgorithmIdentifier bytes and 7 of 12 OID arcs are all unexercised
  • [Low] SLH-DSA gating reaches past the provider abstraction: the OID arc table uses the raw wolfSSL macro and the decoder gating reads SlhDsaKey internals, instead of the WP_HAVE_SLH_DSA_* macros
  • [Low] Documentation and style nits: wp_dh_get_mutex has no doxygen block, wp_slhdsa_get_param takes a non-const pointer with two over-80-column comments, and the wp_slhdsa_key_types index arithmetic is opaque
  • [Info] Removal of the DH length fixup appears safe but is unverified against older wolfSSL
  • [Info] wp_slhdsa_up_ref and wp_lock disagree on the success predicate for wc_LockMutex

Review generated by Skoll via Claude/Codex

Comment thread src/wp_internal.c
Comment thread src/wp_dec_pem2der.c
Comment thread src/wp_slhdsa_sig.c
Comment thread examples/pqc_openssl_example.c
Comment thread src/wp_dh_kmgmt.c Outdated
Comment thread test/test_slhdsa.c
Comment thread src/wp_internal.c
Comment thread src/wp_slhdsa_sig.c
Comment thread src/wp_slhdsa_kmgmt.c
Comment thread src/wp_slhdsa_kmgmt.c
@aidangarske aidangarske added ci:libacvp-pqc PR OSP toggle: run libacvp-pqc and removed ci:libacvp-pqc PR OSP toggle: run libacvp-pqc labels Aug 5, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ci:libacvp-pqc PR OSP toggle: run libacvp-pqc

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants