Skip to content

MC/DC decision coverage part 4: remaining wolfCrypt primitives - #10967

Open
danielinux wants to merge 15 commits into
wolfSSL:masterfrom
danielinux:mcdc-test-coverage
Open

MC/DC decision coverage part 4: remaining wolfCrypt primitives#10967
danielinux wants to merge 15 commits into
wolfSSL:masterfrom
danielinux:mcdc-test-coverage

Conversation

@danielinux

Copy link
Copy Markdown
Member

Add DecisionCoverage/FeatureCoverage tests and tests/unit-mcdc white-box supplements for the remaining reachable wolfCrypt primitive sources in the ISO 26262 per-module MC/DC campaign (excluding asn* and the EVP/OpenSSL compat layer, which are mot yet covered).

tests/api:

  • legacy ciphers / digests: des3, camellia, ascon, blake2, siphash
  • niche PK: srp, eccsi, sakke, hpke
  • native PQC KEM: frodokem
  • math: wolfmath

tests/unit-mcdc white-box drivers (#include the .c to reach file-static helpers and impl-selected paths, standalone main()/WB_NOTE harness):

  • blake2b, blake2s
  • eccsi, sakke, hpke
  • SP host backends: sp_x86_64, sp_c64, sp_c32
  • infra: cryptocb (dev && dev->cb dispatch three-vector, 127/127), logging (per-thread + global error-queue impls, 19/19), memory (static-pool allocator, 46/48)

Registrations in tests/api.c, tests/api/include.am and CMakeLists.txt.

Copilot AI review requested due to automatic review settings July 22, 2026 04:35

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

This PR extends the ISO 26262 per-module MC/DC campaign by adding API-level DecisionCoverage/FeatureCoverage tests and standalone tests/unit-mcdc white-box supplements (via #include of the target .c) for additional wolfCrypt primitives and infrastructure modules, and wires the new API tests into the autotools and CMake test builds.

Changes:

  • Add multiple tests/unit-mcdc/*_whitebox.c standalone drivers to reach file-static helpers and implementation-selected paths for SP math, SAKKE/ECCSI/HPKE, logging, and memory.
  • Add/extend tests/api DecisionCoverage/FeatureCoverage tests for algorithms including SipHash, HPKE, Ascon, BLAKE2, DES (single), FrodoKEM, and wolfmath guards.
  • Register new API tests in tests/api.c, tests/api/include.am, and CMakeLists.txt.

Reviewed changes

Copilot reviewed 34 out of 34 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
tests/unit-mcdc/test_sp_c64_whitebox.c New white-box supplement to drive sp_c64.c SP math decisions via ECC/RSA/DH entry points.
tests/unit-mcdc/test_sakke_whitebox.c New white-box supplement targeting otherwise-unreachable decisions and file-static helpers in sakke.c.
tests/unit-mcdc/test_memory_whitebox.c New white-box supplement for memory.c static-pool allocator decision coverage.
tests/unit-mcdc/test_logging_whitebox.c New white-box supplement for core logging.c decisions using the per-thread error-queue implementation.
tests/unit-mcdc/test_logging_globalq_whitebox.c New white-box supplement for the global (mutex + list) logging.c error-queue implementation decisions.
tests/unit-mcdc/test_hpke_whitebox.c New white-box supplement to reach inner/static helper NULL-guard decisions in hpke.c.
tests/unit-mcdc/test_eccsi_whitebox.c New white-box supplement to drive static-helper decisions in eccsi.c not reachable via public API alone.
tests/unit-mcdc/test_blake2s_whitebox.c New white-box supplement to exercise internal BLAKE2s init guards unreachable from public wrappers.
tests/unit-mcdc/test_blake2b_whitebox.c New white-box supplement to exercise internal BLAKE2b init guards unreachable from public wrappers.
tests/api/test_wolfmath.c Adds additional decision vectors for mp_rand() and wc_export_int() argument validation.
tests/api/test_srp.h Adds declarations/registration macro for SRP Decision/Feature coverage tests.
tests/api/test_siphash.h Adds declarations/registration macro for SipHash Decision/Feature coverage tests.
tests/api/test_siphash.c New API tests for SipHash DecisionCoverage and FeatureCoverage.
tests/api/test_sakke.h Adds declarations/registration macro for SAKKE Decision/Feature coverage tests.
tests/api/test_hpke.h Adds declarations/registration macro for HPKE Decision/Feature coverage tests.
tests/api/test_hpke.c New API tests for HPKE DecisionCoverage and FeatureCoverage.
tests/api/test_frodokem.c Expands FrodoKEM test comments and adds additional bad-arg vectors for guard operand coverage.
tests/api/test_eccsi.h Adds declarations/registration macro for ECCSI Decision/Feature coverage tests.
tests/api/test_des3.h Registers a new single-DES CBC encrypt/decrypt API test.
tests/api/test_des3.c Adds a new test covering single-DES guard decisions and a basic round-trip.
tests/api/test_camellia.c Adds missing bad-arg operand coverage for wc_CamelliaSetKey() guard.
tests/api/test_blake2.h Registers new decision-coverage tests for BLAKE2b/BLAKE2s wrappers.
tests/api/test_blake2.c Adds DecisionCoverage tests for wrapper-level bound checks (internal guards remain in white-box tests).
tests/api/test_ascon.h Registers a new Ascon decision-coverage test.
tests/api/test_ascon.c Adds Ascon DecisionCoverage tests covering argument/state guard decisions across hash and AEAD APIs.
tests/api/include.am Adds new API test sources/headers to autotools test build lists.
tests/api.c Includes and registers the new API test groups in the master test case list.
CMakeLists.txt Adds new API test sources to the CMake tests target sources list.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread tests/api/test_wolfmath.c
Comment thread tests/unit-mcdc/test_sakke_whitebox.c Outdated
Comment thread tests/unit-mcdc/test_memory_whitebox.c
@danielinux

Copy link
Copy Markdown
Member Author

jenkins retest this please

@danielinux danielinux assigned wolfSSL-Bot and unassigned danielinux Jul 29, 2026
Add DecisionCoverage/FeatureCoverage tests and tests/unit-mcdc white-box
supplements for the remaining reachable wolfCrypt primitive sources in the
ISO 26262 per-module MC/DC campaign (excluding asn* and the EVP/OpenSSL
compat layer, which are out of the MC/DC boundary).

tests/api:
- legacy ciphers / digests: des3, camellia, ascon, blake2, siphash
- niche PK: srp, eccsi, sakke, hpke
- native PQC KEM: frodokem
- math: wolfmath

tests/unit-mcdc white-box drivers (#include the .c to reach file-static
helpers and impl-selected paths, standalone main()/WB_NOTE harness):
- blake2b, blake2s
- eccsi, sakke, hpke
- SP host backends: sp_x86_64, sp_c64, sp_c32
- infra: cryptocb (dev && dev->cb dispatch three-vector, 127/127),
  logging (per-thread + global error-queue impls, 19/19),
  memory (static-pool allocator, 46/48)

Registrations in tests/api.c, tests/api/include.am and CMakeLists.txt.
- test_hpke.c: guard both test bodies on HAVE_HPKE. They were gated only on
  HAVE_CURVE25519 && !NO_SHA256 && WOLFSSL_AES_128, so configs with those but
  without HPKE (e.g. pk-mlkem) compiled the body against absent HPKE symbols
  and failed to build under -Werror.

- test_sakke.c: make the wc_GenerateSakkeRskTable / wc_GenerateSakkePointITable
  / wc_SetSakkePointITable checks SP-backend agnostic. The required table size
  is 0 on the small-stack SP path but non-zero on the full precomputation path
  (sizeof(sp_table_entry_1024) * 1167 / * 256), so the previous fixed
  "len == 0" and success-with-tiny-buffer assertions failed (and could write a
  full-size table into the small stack buffer) under --enable-all. Capture the
  queried length and branch: the Rsk table builds into a correctly-sized heap
  buffer; the PointI table's full-path build/store is left to the sakke_test
  KAT (it stores the pointer in the key).

- codespell: rename addRes -> addResult in test_sakke_whitebox.c and reword a
  comment in test_hpke.c ("statics").
- test_wolfmath.c: limit the "digits > capacity" mp_rand rejection vector to
  the fixed-size backends. USE_INTEGER_HEAP_MATH grows the mp_int via
  mp_set_bit instead of rejecting, so the call would legally succeed (and
  force a large allocation), failing ExpectIntNE.

- test_memory_whitebox.c: guard the WOLFSSL_STATIC_MEMORY / WOLFSSL_MEM_FAIL_COUNT
  defines with #ifndef so a build that already provides them (user_settings.h /
  CFLAGS) does not hit a redefinition warning treated as error.

- test_sakke_whitebox.c: skip the sakke_mulmod_base_add() calls when
  wc_ecc_new_point() returns NULL. That function does not validate its result
  pointer and would dereference a NULL addResult under allocation pressure.
wc_ValidateEccsiPair() reports an off-curve PVT via wc_ecc_is_point(), whose
error code is backend-dependent: the mp-based check (classic / SP_MATH_ALL /
fast-math) returns IS_POINT_E, but the minimal WOLFSSL_SP_MATH backend routes
through sp_ecc_is_point_*(), which returns MP_VAL for a point not on the curve
(and eccsi.c only remaps -1 -> IS_POINT_E, not MP_VAL). Select the expected
code per backend so the all-pq-sp-math CI config (--enable-sp-math) passes.

Verified: full unit.test --api under --enable-all --enable-sp-math --enable-sp-asm
reports 0 failures.
The tests/unit-mcdc/*.c MC/DC white-box supplements this branch adds each
#include a wolfCrypt .c and carry their own main(); they are built standalone
by the per-module coverage campaign and are NOT compiled into libwolfssl or
unit.test (that would duplicate main()/symbols). They are test-only.

The source-completeness check (per-PR diff) requires every file a PR adds to
appear in an include.am. Since these cannot be tests_unit_test_SOURCES, list
them in EXTRA_DIST -- the same bucket tests/api/include.am uses for its
non-compiled files -- so they ship in the dist tarball without being built.
Scope: only the white-boxes this branch introduces.
Add the tests/unit-mcdc white-box drivers produced by the coverage campaign's
fault-injection and SP-ARM emulator-lane passes, and extend the EXTRA_DIST
listing to cover them (test-only; standalone main() + #include the target .c;
never built into libwolfssl or unit.test -- see the comment in tests/include.am).

Fault-injection (mcdc_fault_alloc.h: a fail-after-N wolfSSL_SetAllocators mock,
swept across allocation sites to drive the FALSE half of (err==MP_OKAY)&&step
success-chain guards): dsa, eccsi, sakke, hpke, mlkem, mldsa, integer, rsa,
frodokem (+ a shared frodokem fault header).

SP-ARM emulator lanes (drive the C-level decisions in the cross-only asm SP
backends under qemu-user / m33mu): sp_arm64, sp_arm32, sp_armthumb, sp_cortexm.
Add test_wc_FalconDecisionCoverage to the falcon API group, covering the
public wc_falcon_* wrapper decisions (level checks, import/export and
sign/verify argument guards, init_id/init_label) with per-condition MC/DC
independence cases.

Add tests/unit-mcdc/test_falcon_whitebox.c, a standalone binary that
#includes falcon.c and drives its file-static encode/decode/zint/modp/
sampler/keygen-solver/sign guards -- including the small-mem
falcon_do_sign_dyn twin -- with both halves of each independence pair, plus
a real Falcon-512 make/sign/verify round-trip for the proceed halves.

Register the whitebox in EXTRA_DIST (test-only; it is not part of the
library build).
check-source-text (check E) rejects C++-style // comments in C files, and
its regex fires on the // used as inline annotations inside the /* */ doc
blocks of mcdc_fault_alloc.h (sweep-pattern pseudo-code) and
test_integer_fault_whitebox.c (the mp_div alloc-chain line:col:cond refs).
Nested /* */ can't be used inside a block comment, so switch those inline
markers to '--'. No code change.
stm32h563_OTP.bin is a generated one-time-programmable flashing artifact,
not source. Remove it from the tree and add it to the directory .gitignore
alongside the other generated outputs (app-falcon.*) so a local build can
no longer re-add it.
codespell reads "statics" as a misspelling of "statistics" and fails the
Codespell CI lane. Reword the whitebox doc comments/notes to "static
helpers" (falcon/frodokem/rsa fault white-boxes). Comment/string only.
test_wc_Des_CbcEncryptDecrypt drove the per-operand NULL guards of
wc_Des_CbcEncrypt/CbcDecrypt/EcbEncrypt/SetIV. The frozen FIPS/selftest
single-DES module predates those open-build NULL checks and dereferences a
NULL des/out/in directly, so the probes segfault (exit 139) in a FIPS build.
Gate the whole test on !HAVE_FIPS && !HAVE_SELFTEST -- this single-DES MC/DC
coverage is gathered in the open build; the frozen module is out of its scope.
Two check-source-text / clang-tidy fixes on the MC/DC test files:

* Wrap error-code comparison operands in WC_NO_ERR_TRACE() (check-source-text
  check I). Code comparisons (blake2b/blake2s/hpke white-boxes and the
  logging global-queue pull check) are wrapped; the pseudo-code in doc
  comments and the WB_CHECK message strings (mcdc_fault_alloc.h, dsa/mlkem
  fault white-boxes, logging white-box) are reworded so an error code is no
  longer adjacent to == / != .

* Uppercase the integer-literal suffixes in test_sakke.c (384u -> 384U, etc.)
  for clang-tidy readability-uppercase-literal-suffix.

No behavioral change.
test_sp_cortexm_whitebox.c gated on defined(WOLFSSL_SP_256), which is not a
real wolfSSL macro (256-bit SP is the default, disabled via WOLFSSL_SP_NO_256;
the sized macros are WOLFSSL_SP_384/521/1024). check-source-text flags it as
an unrecognized macro and the guard was always false (dead code). Use
!defined(WOLFSSL_SP_NO_256) so the P-256 Cortex-M SP path is actually built.
Remove whitelist entries the check-source-text macro check (check K) no
longer needs because the macros are recognised independently: the falcon
backend macros set by configure.ac (WOLFSSL_FALCON_FPR_DOUBLE /
SIGN_SMALL_MEM / FFT_AVX2 / FFT_NEON / FPR_ASM), WOLFSSL_FALCON_NTT_DSP
(#defined in falcon.c), WOLFSSL_FALCON_VERIFY_ONLY (#defined in
IDE/m33mu-falcon-verify/user_settings.h), and WOLFSSL_CHECK_MEM_ZERO.

WOLFSSL_FALCON_SIGN_STATS and WOLFSSL_FALCON_NO_NTT_DSP are kept: they are
pure user-opt macros (used in #if, defined nowhere) that still require
whitelisting.
Add test_wc_WolfEventDecisionCoverage (group "wolfevent") driving the
wolfEvent / wolfEventQueue_* doubly-linked FIFO from the public API:
the queue==NULL || event==NULL guards (Push/Pop/Add/Remove, each operand
plus the all-false half), the Add first-element branch, the Remove
head/tail/sole cascade including the (event==head && event==tail) AND and
the defensive (next==NULL || prev==NULL) corruption guard, and the Poll
context-filter OR.

Guarded by HAVE_WOLF_EVENT (compiled empty otherwise). The queue core is
async-independent; it builds standalone (no WOLFSSL_ASYNC_CRYPT) now that
BUILD_WOLFEVENT is true under --enable-usersettings and wolfEvent_Poll no
longer warns on unused params in non-async builds.
@danielinux
danielinux force-pushed the mcdc-test-coverage branch from c24910d to 9de9de3 Compare July 29, 2026 19:28
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.

3 participants