MC/DC coverage for wolfCrypt modules - Part 3#10912
Open
danielinux wants to merge 12 commits into
Open
Conversation
Contributor
There was a problem hiding this comment.
Pull request overview
This PR extends the project’s ISO 26262 MC/DC test-coverage campaign by adding new DecisionCoverage/FeatureCoverage API tests and adding unit-mcdc white-box supplements for additional wolfCrypt primitives, then registering the new tests in the existing test harness.
Changes:
- Added new
tests/apiDecisionCoverage/FeatureCoverage test cases for multiple wolfCrypt modules (e.g., entropy, coding, error, encrypt, hash, random/DRBG, PQC/signature families). - Added new
tests/unit-mcdcwhite-box binaries that#includemodule.cfiles directly to exercise API-unreachable static decision paths. - Updated test registration/plumbing in
tests/api.candtests/api/include.am.
Reviewed changes
Copilot reviewed 46 out of 46 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| tests/unit-mcdc/test_wolfentropy_whitebox.c | White-box coverage for wolfentropy health-test statics |
| tests/unit-mcdc/test_wc_xmss_impl_whitebox.c | White-box XMSS/XMSS^MT impl roundtrip to hit static helpers |
| tests/unit-mcdc/test_wc_mlkem_poly_whitebox.c | White-box ML-KEM poly core statics (cmp/rej_uniform/ntt) |
| tests/unit-mcdc/test_wc_lms_impl_whitebox.c | White-box LMS/HSS impl roundtrip + targeted statics |
| tests/unit-mcdc/test_tfm_whitebox.c | White-box for tfm.c FASTMATH static decisions |
| tests/unit-mcdc/test_slhdsa_whitebox.c | White-box for SLH-DSA statics (param scan/base-2b/HA encode) |
| tests/unit-mcdc/test_random_whitebox.c | Extended random.c white-box leaves for MC/DC |
| tests/unit-mcdc/test_integer_whitebox.c | White-box for integer.c HEAPMATH static helpers |
| tests/unit-mcdc/test_ed448_whitebox.c | White-box for ed448_hash() guard operands |
| tests/api/test_wolfmath.h | Registers new wolfmath DecisionCoverage entry points |
| tests/api/test_wolfentropy.h | Adds wolfentropy API test declarations/registration macro |
| tests/api/test_wolfentropy.c | Adds wolfentropy API DecisionCoverage/FeatureCoverage tests |
| tests/api/test_wc_encrypt.h | Registers new wc_encrypt API tests |
| tests/api/test_wc_encrypt.c | Adds AES-CBC and BufferKeyEncrypt/Decrypt coverage tests |
| tests/api/test_slhdsa.h | Registers SLH-DSA Decision/Feature coverage tests |
| tests/api/test_slhdsa.c | Adds SLH-DSA API DecisionCoverage/FeatureCoverage tests |
| tests/api/test_signature.h | Registers signature wrapper Decision/Feature coverage tests |
| tests/api/test_signature.c | Adds signature wrapper DecisionCoverage/FeatureCoverage tests |
| tests/api/test_random.h | Registers DRBG Decision/Feature coverage tests |
| tests/api/test_random.c | Adds DRBG API DecisionCoverage/FeatureCoverage tests |
| tests/api/test_pwdbased.h | Registers PBKDF DecisionCoverage tests |
| tests/api/test_pwdbased.c | Adds PBKDF1/PBKDF2/PKCS12_PBKDF DecisionCoverage tests |
| tests/api/test_mlkem.h | Registers ML-KEM Decision/Feature coverage tests |
| tests/api/test_mlkem.c | Adds ML-KEM API DecisionCoverage/FeatureCoverage tests |
| tests/api/test_mldsa.h | Registers ML-DSA Decision/Feature coverage tests |
| tests/api/test_mldsa.c | Adds ML-DSA API coverage tests and adjusts PKCS12 guard |
| tests/api/test_lms_xmss.h | Registers LMS/XMSS Decision/Feature coverage tests |
| tests/api/test_kdf.h | Adds KDF test declarations/registration macro |
| tests/api/test_hash.h | Registers hash wrapper Decision/Feature coverage tests |
| tests/api/test_hash.c | Adds hash wrapper DecisionCoverage/FeatureCoverage tests |
| tests/api/test_error.h | Adds error-string coverage test declarations/registration |
| tests/api/test_error.c | Adds error.c switch-arm sweep coverage tests |
| tests/api/test_ed448.h | Registers ed448 Decision/Feature coverage tests |
| tests/api/test_ed448.c | Adds ed448 DecisionCoverage + streaming verify FeatureCoverage |
| tests/api/test_curve448.h | Registers new curve448 decision-coverage test functions |
| tests/api/test_curve448.c | Adds curve448 DecisionCoverage split tests |
| tests/api/test_coding.h | Adds coding.c coverage test declarations/registration |
| tests/api/test_coding.c | Adds Base64/Base16 DecisionCoverage + whitespace coverage |
| tests/api/test_chacha20_poly1305.h | Registers ChaCha20-Poly1305/XChaCha20-Poly1305 coverage tests |
| tests/api/test_chacha20_poly1305.c | Adds residual DecisionCoverage + large-buffer XChaCha test |
| tests/api/include.am | Adds new test sources/headers to automake lists |
| tests/api.c | Registers new test groups in the main API test runner |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
danielinux
added a commit
to danielinux/wolfssl
that referenced
this pull request
Jul 15, 2026
Copilot review (test_random.c:1238): test_wc_DrbgFeatureCoverage claimed a bounded burst of generate calls crosses WC_RESEED_INTERVAL, but the default interval is 1,000,000 so 40 generates never reach it and the DRBG_NEED_RESEED -> PollAndReSeed branch was not exercised in normal builds. Force the path instead: probe one generate to confirm the Hash_DRBG path is active (skipped under e.g. --enable-intelrand), then set the active DRBG's reseedCtr to WC_RESEED_INTERVAL - 1 and generate across it, asserting the reseed resets the counter (same idiom as test_wc_RNG_ReseedBoundary), for both SHA-256 and SHA-512 DRBG widths. Comment corrected to match.
danielinux
force-pushed
the
mcdc-test-coverage
branch
from
July 17, 2026 06:55
a27b11a to
3a47bfb
Compare
Adds/extends tests/api MC/DC DecisionCoverage + FeatureCoverage and tests/unit-mcdc white-box supplements for the remaining wolfCrypt primitives (first-pass per-module union; gap-closing to follow): - classic bigint: tfm.c, integer.c (extend test_wolfmath.c; tfm/integer whiteboxes) - coding.c, error.c, wc_encrypt.c, pwdbased.c - ed448.c + curve448.c (shared fe_448/ge_448 backends; ed448 whitebox) - random.c deepened + new wolfentropy.c (MemUse SP800-90B), whiteboxes - hash.c, kdf.c, signature.c, chacha20_poly1305.c - LMS/XMSS (wc_lms*.c, wc_xmss*.c) with impl whiteboxes - ML-KEM (wc_mlkem*.c), ML-DSA (wc_mldsa.c), SLH-DSA (wc_slhdsa.c) with whiteboxes New tests register in tests/api.c + tests/api/include.am. Frozen-module guards (!HAVE_SELFTEST && !HAVE_FIPS) applied to new random.c/pwdbased.c tests that call post-v4.1.0 symbols.
- CMakeLists.txt: register the new tests/api sources (test_kdf.c, test_coding.c, test_error.c, test_wolfentropy.c) with the unit_test target; fixes cmake link failure (undefined test_wc_GetErrorStringDecisionCoverage/test_wc_ErrorStringDecisionCoverage). - tests/api/test_mldsa.c: guard the wc_MlDsaKey_MakeKey NULL-arg checks in test_wc_MldsaDecisionCoverage with WOLFSSL_MLDSA_NO_MAKE_KEY; fixes link failure in verify-only builds (tinytls13-psk-mldsa, all-pq-verify-only-noasm). - tests/unit-mcdc/*: reword 'statics' to 'static helpers' in comments to satisfy codespell.
Copilot review (test_random.c:1238): test_wc_DrbgFeatureCoverage claimed a bounded burst of generate calls crosses WC_RESEED_INTERVAL, but the default interval is 1,000,000 so 40 generates never reach it and the DRBG_NEED_RESEED -> PollAndReSeed branch was not exercised in normal builds. Force the path instead: probe one generate to confirm the Hash_DRBG path is active (skipped under e.g. --enable-intelrand), then set the active DRBG's reseedCtr to WC_RESEED_INTERVAL - 1 and generate across it, asserting the reseed resets the counter (same idiom as test_wc_RNG_ReseedBoundary), for both SHA-256 and SHA-512 DRBG widths. Comment corrected to match.
Close API-reachable and file-static MC/DC gaps identified by the per-module GAPS.md reports (+291 conditions across the union): tfm.c 71->89, integer.c 49->92, ed448.c 62->92 (91%), wc_slhdsa.c 99->155 (88%), wc_mldsa.c 169->252, wc_mlkem.c 46->65 (96%), wc_lms_impl.c 60->82, wc_xmss_impl.c 38->57. Enriched DecisionCoverage in test_wolfmath.c (tfm/integer), test_ed448.c, test_slhdsa.c; new arg/state/length cases in test_mldsa.c/test_mlkem.c; and per-source *_gap white-box supplements under tests/unit-mcdc/ driving the static internals (WOTS/FORS/NTT/poly/Merkle/comba/Montgomery, etc.). Remaining uncovered conditions are justified residuals (AVX2/cpuid dispatch on an always-AVX2 host, deep alloc/crypto-failure err-chains, asm-only paths).
Reword "statics" -> "static functions" in test_ed448_whitebox_gap.c and test_wc_xmss_impl_whitebox_gap.c (codespell flags "statics").
Merge the _gap white-box drivers into their base file (tfm, integer, ed448, mldsa, mlkem_poly, slhdsa, xmss_impl) and delete the _gap copies; a single binary per source also satisfies more MC/DC independence pairs (tfm 89->91, integer 92->100, mlkem_poly 25->27, mldsa 252->256). LMS is kept as two files: its sign-side drivers reference internals absent under verify-only/small builds and use per-driver state that does not share one main() safely.
…quence test_wolfSSL_read_write_ex hard-coded the close-notify exchange as NOT_DONE/NOT_DONE/SUCCESS/SUCCESS, which is protocol-version/config dependent and fails under the cmake old-TLS build. Loop wolfSSL_shutdown on each side until WOLFSSL_SUCCESS (pre-existing flake, not from this PR's new tests).
Close API-reachable and file-static gaps in the smaller modules (+52 union conditions): kdf 75->91, coding 48->64, wolfentropy 9->13, curve448 54->58 (100%), chacha20_poly1305 43->46 (100%), hash 6->7 (100%), wc_encrypt 16->19, pwdbased 14->17, signature 30->32. Additive cases in the existing tests (one new test_wc_HashTypeConvert), plus wolfentropy/random white-box drivers. Remaining are justified residuals (WOLFSSL_LOCAL wc_CryptKey, dead defensive branches, alloc/crypto-failure err-chains, platform seed sources).
Under DEBUG_WOLFSSL, wc_HashUpdate/Final/Free first check (hash->type != type) and return BAD_FUNC_ARG before the switch, so the "unsupported type -> HASH_TYPE_E" arm is unreachable on an uninitialized hash (wc_HashInit refuses those types). Guard those Update/Final/Free assertions with #ifndef DEBUG_WOLFSSL; the arm's coverage comes from non-DEBUG variants in the union. Fixes the cmake (old-TLS/debug) build failure. wc_HashInit assertions keep running (Init has no such type check). This bug is fixed in PR wolfSSL#10927
kdf: wc_Tls13_HKDF_Extract_ex / wc_Tls13_HKDF_Expand_Label_ex postdate the frozen FIPS/selftest kdf.h and are undeclared there. Gate every _ex call site behind WOLFSSL_TEST_HKDF_EX (!HAVE_FIPS && !HAVE_SELFTEST); the thin non-_ex wrappers, which exist everywhere, keep their coverage. wolfmath: test_wc_TfmDecisionCoverage / test_wc_TfmExptModDecisionCoverage / test_wc_IntegerDecisionCoverage called library-internal fp_* and s_mp_* functions that carry no MP_API decoration, so under -fvisibility=hidden they are not exported from the shared library and unit.test failed to link them (undefined reference to fp_set / s_mp_mul_digs / ...) in the default shared CI build. Relocate those decision drivers into the tests/unit-mcdc white-boxes, which reach the internals legally by #including tfm.c / integer.c; tests/api now uses only the public mp_* interface. mp_rand_prime calls are gated by WOLFSSL_KEY_GEN (and, for integer, !NO_DH || !NO_DSA) to match where the library declares and defines it.
The FIPS build diverges from the OPEN build on KDF behavior these exhaustive MC/DC probes assert: wc_HmacSetKey enforces the 14-byte HMAC_FIPS_MIN_KEY, so wc_Tls13_HKDF_Extract with the short salt/ikm here returns HMAC_MIN_KEYLEN_E (-200) instead of 0 (test_kdf.c:766), and wc_PRF with resLen==0 returns 0 instead of BAD_FUNC_ARG (test_kdf.c:118). kdf.c coverage is measured only in non-FIPS campaign variants, so guard both test_wc_KdfDecisionCoverage and test_wc_KdfFeatureCoverage bodies with !HAVE_FIPS && !HAVE_SELFTEST; they run in full in OPEN builds and skip cleanly under FIPS/selftest. Verified against a --enable-fips=v5 build (both now skip, 0 failures).
check-source-text (rule I) flags error-code identifiers used as comparison operands even inside comments. Reword three comments so the code name is no longer written as "(ret == PUBLIC_KEY_E)" / "(ret != CRYPTOCB_UNAVAILABLE)" (test_kdf.c, test_ed448.c); the bare token on its own is fine. clang-tidy reported a possible 0-byte malloc in test_mlkem.c: the ML-KEM key/ciphertext sizes come from wc_MlKemKey_*Size() queries, which the analyzer cannot prove nonzero. Guard each XMALLOC with a >0 check so the allocation size is provably positive; the ExpectNotNull() checks still catch a 0-size query at runtime.
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
Adds/extends tests/api MC/DC DecisionCoverage + FeatureCoverage and tests/unit-mcdc white-box supplements for the remaining wolfCrypt primitives (first-pass per-module union; gap-closing to follow):
New tests register in tests/api.c + tests/api/include.am. Frozen-module guards (!HAVE_SELFTEST && !HAVE_FIPS) applied to new random.c/pwdbased.c tests that call post-v4.1.0 symbols.
Follow up to #10845 , #10876