Infrastructure for Mc/Dc test coverage + AES coverage campaign#10845
Open
danielinux wants to merge 7 commits into
Open
Infrastructure for Mc/Dc test coverage + AES coverage campaign#10845danielinux wants to merge 7 commits into
danielinux wants to merge 7 commits into
Conversation
Add MC/DC-targeted unit tests exercising decision and feature coverage across AES (key wrap, GCM, feature), ASN.1, RSA, signature (falcon), and CryptoCb registry surfaces.
Add tests/unit-mcdc/, a standalone white-box program that compiles
wolfcrypt/src/aes.c directly to reach static/WOLFSSL_LOCAL helpers
(GHASH/GHASH_UPDATE ptr guards, _AesNew_common cross-arg checks) that
are structurally unreachable through the public API, closing 19 of the
AES MC/DC residuals. Extend tests/api/test_aes.{c,h} with the
decision/feature coverage cases these build on.
These are for the external ISO 26262 per-module MC/DC campaign; they do
not change library behaviour and are not part of the wolfSSL build.
Contributor
There was a problem hiding this comment.
Pull request overview
This PR adds test-only infrastructure and new/expanded unit tests to increase structural MC/DC coverage (notably for AES), including a standalone “white-box” harness for exercising API-unreachable decision conditions.
Changes:
- Added
tests/unit-mcdc/white-box harness infrastructure and the first AES-focused harness binary. - Expanded
tests/apicoverage across AES, ASN.1, RSA, PKCS#7, PKCS#12, OCSP wolfIO helpers, Falcon (via liboqs), and OpenSSL-compat X.509 verification paths. - Registered new tests in existing groups so they run in normal CI when features are enabled.
Reviewed changes
Copilot reviewed 20 out of 21 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| tests/api.c | Adds additional API-level coverage tests (incl. negative/guard paths) and related helper coverage. |
| tests/api/test_aes.c | Adds extensive AES decision/feature/argument coverage tests (incl. MC/DC-targeted branches). |
| tests/api/test_aes.h | Registers new AES test entry points. |
| tests/api/test_asn.c | Adds ASN.1 decision/feature coverage tests for PKCS#8 and key/cert parsing paths. |
| tests/api/test_asn.h | Registers new ASN.1 coverage test entry points. |
| tests/api/test_certman.c | Adds/extends CertManager/X.509 constraint-related tests (coverage for name constraints/verification paths). |
| tests/api/test_ocsp.c | Adds OCSP-related tests including wolfIO URL/HTTP helper coverage. |
| tests/api/test_ossl_x509.c | Extends OpenSSL-compat X.509 coverage in the primary test module. |
| tests/api/test_ossl_x509_ext.c | Adds coverage for X.509 extension handling paths (incl. name constraints-related logic). |
| tests/api/test_ossl_x509_ext.h | Header updates for the X.509 extension coverage additions. |
| tests/api/test_ossl_x509_vp.c | Adds coverage for X509_VERIFY_PARAM / verification parameter paths. |
| tests/api/test_pkcs12.c | Adds PKCS#12 create/parse guardrail coverage tests. |
| tests/api/test_pkcs12.h | Registers new PKCS#12 guardrail test entry points. |
| tests/api/test_pkcs7.c | Adds PKCS#7 InitWithCert guardrail coverage tests. |
| tests/api/test_pkcs7.h | Registers new PKCS#7 guardrail test entry points. |
| tests/api/test_rsa.c | Adds RSA decision and feature coverage tests (OAEP/PSS/PKCS#1 v1.5 and negative branches). |
| tests/api/test_rsa.h | Registers new RSA coverage test entry points. |
| tests/api/test_signature.c | Adds Falcon sign/verify coverage test (guarded on HAVE_PQC/HAVE_FALCON/HAVE_LIBOQS). |
| tests/api/test_signature.h | Registers the new Falcon signature coverage test. |
| tests/unit-mcdc/README.md | Documents the white-box MC/DC supplement mechanism and build contract. |
| tests/unit-mcdc/test_aes_whitebox.c | Implements AES white-box MC/DC supplement by including wolfcrypt/src/aes.c and calling internal helpers. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Several MC/DC coverage tests called WOLFSSL_LOCAL (hidden-visibility) library functions directly from the in-tree unit.test: - wc_AesCcmCheckTagSize() (test_aes.c) - wc_CryptoCb_Init/Cleanup/GetDevIdAtIndex() (api.c) These only link when the library is built with test-static visibility, so normal (shared) builds failed at link with "undefined reference", breaking essentially every CI build job. Gate the affected assertions on WOLFSSL_TEST_STATIC_BUILD (in addition to the existing feature guards) so they compile out where the symbols are hidden, matching the existing wolfSSL convention for internal-symbol tests. Verified: ./configure --enable-all (no WOLFSSL_TEST_STATIC_BUILD) now builds tests/unit.test cleanly and the full suite passes.
test_wc_AesModesArgMcdc asserted that wc_AesCtrEncrypt() with corrupted aes.rounds returns KEYUSAGE_E, but used sz = 32 (an exact block multiple). When in != out, the full blocks are consumed by a batch path that does not surface the per-block rounds error - the AES-NI batch, or the HAVE_AES_ECB fast path which ignores wc_AesEcbEncrypt()'s return - leaving no trailing partial block, so the function returns 0 and the assertion fails. This was latent (the whole test binary failed to link before the visibility fix) and reproduces in --disable-aesni --enable-aesecb builds. Use a non-block-multiple size (WC_AES_BLOCK_SIZE + 4) so the "(ret == 0) && sz" leftover-handling call runs and fails on the corrupted rounds via wc_AesEncrypt() in every backend. Reported by Copilot review on PR wolfSSL#10845. Verified: test_wc_AesModesArgMcdc now passes under --disable-aesni --enable-aesecb (previously failed) and under --enable-aesni --enable-aesecb.
The new MC/DC coverage tests broke many CI configs under -Werror (which is auto-enabled for in-git-tree builds). Fixes, each verified with a real -Werror build of the relevant config: - test_aes.c: wrap the whole test_wc_AesSivArgMcdc definition in WOLFSSL_AES_SIV && WOLFSSL_AES_128 (was body-only guarded while its prototype is guarded) -> fixes -Wmissing-prototypes when SIV is off. - test_aes.c: mark key/in/out (void) in test_wc_AesModesArgMcdc; they are used only by the per-mode (CTR/CFB/OFB) blocks -> fixes -Wunused-variable when no such mode is enabled. - api.c: guard the test_CryptoCb_* callback helpers with WOLF_CRYPTO_CB && WOLFSSL_TEST_STATIC_BUILD to match their only caller -> fixes -Wunused-function in cryptocb non-static builds. - api.c: register test_wc_CryptoCb_registry under its actual definition condition (WOLF_CRYPTO_CB && HAVE_IO_TESTS_DEPENDENCIES && !ONLY_*) and keep test_wc_CryptoCb registered unconditionally (as on master) -> fixes undeclared / defined-but-unused across cryptocb configs. - api.c: declare session-cache 'mode' under OPENSSL_EXTRA (its only uses) -> fixes -Wunused-variable without opensslextra. - api.c: guard the Enable/DisableOCSPStapling calls in test_wolfSSL_crl_ocsp_object_api with HAVE_CERTIFICATE_STATUS_REQUEST[_V2] -> fixes undefined references with OCSP but no stapling. Verified clean under: --enable-ocsp --enable-ocspstapling, --enable-ocsp (no stapling), and --enable-all; unit.test runs pass.
The check-source-text CI job flags non-ASCII (8-bit) bytes in source. The new MC/DC tests and README used UTF-8 punctuation in comments/prose (em-dash, ellipsis, left-right arrow). Replace with ASCII equivalents (-, ..., <->). Verified: ./.github/scripts/check-source-text.sh on the changed files reports clean.
Several AES ArgMcdc tests corrupt aes.rounds (or cmac.aes.rounds) and expect the subsequent op to fail with KEYUSAGE_E from the in-process software AES path. Under WOLF_CRYPTO_CB_FIND (e.g. --enable-swdev), the "devId != INVALID_DEVID" guard is removed, so CTR/CCM/CMAC ops are offloaded to the registered crypto callback even for INVALID_DEVID; the callback re-derives the key and ignores the corrupted struct, returning 0 instead of KEYUSAGE_E and failing the assertion. Guard those internal-failure checks with #ifndef WOLF_CRYPTO_CB_FIND (wc_AesCtrEncrypt, wc_AesCfb/OfbEncrypt/Decrypt, wc_AesCcmEncrypt/Decrypt, wc_CmacUpdate); the raw-block wc_AesEncryptDirect path in SetKey does not route through cryptocb, so it stays. (void)-cast the locals only used by the guarded checks to keep -Werror clean. MC/DC is unioned across configs, so no union coverage is lost. Verified: --enable-swdev ... (WOLF_CRYPTO_CB_FIND) now passes, and a non-CB_FIND build with all these modes still runs and passes the checks.
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
This PR is test-only, additive infrastructure for structural (MC/DC) test coverage — no library source or behaviour changes.
Two parts:
Reusable MC/DC white-box harness — tests/unit-mcdc/ (new).
A standalone pattern for exercising decision conditions that are structurally unreachable through the public API: static / WOLFSSL_LOCAL helpers whose "impossible" operand combinations every wc_* entry point rejects first (e.g. a size != 0 argument paired with a NULL pointer). The program #includes the module .c directly so those helpers are in scope, and calls them with both halves of each MC/DC independence pair in one binary. It is not part of the wolfSSL build and not registered in tests/api — it's an opt-in supplement for coverage campaigns. The first instance, test_aes_whitebox.c, reaches the AES GHASH / GHASH_UPDATE pointer guards and _AesNew_common cross-argument checks; README.md documents the mechanism and how to add modules.
AES coverage campaign + seed coverage for adjacent modules.
A large batch of decision-, feature-, and argument-check tests, registered in the existing test groups so they run in normal CI:
All new tests/api tests are guarded by the same #if as the code under test, so they auto-report TEST_SKIPPED when the feature is compiled out.
Testing
Checklist