Skip to content

Mcdc test coverage: part 5 - #11039

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

Mcdc test coverage: part 5#11039
danielinux wants to merge 15 commits into
wolfSSL:masterfrom
danielinux:mcdc-test-coverage

Conversation

@danielinux

Copy link
Copy Markdown
Member

MC/DC coverage: ASN.1/PKCS layer, wolfCrypt completeness (Part 5)

Test-only. Extends the ISO 26262 (ASIL-D) MC/DC campaign to the last large
untouched block of wolfCrypt — the ASN.1/PKCS layer — and closes the
accounting for every top-level wolfcrypt/src/*.c.

No library behaviour is changed. The only non-test file touched is
CMakeLists.txt, which registers the two new test sources.

Coverage

Aggregate 6872 / 10486 MC/DC conditions (65.5%) across 62 modules.

file before after
asn.c 267/1510 936/1510
pkcs7.c 245/1058 463/1058
pkcs12.c 6/65 58/65
tsp.c 148/185 154/185
asn_tsp.c 89/110
wc_port.c 3/25 19/25
wc_she.c 31/34
compress.c 8/8

ecc.c (394/603) and rsa.c (182/283) were advanced and are frozen here;
remaining gaps are deferred to Part 6.

What's added

  • New tests/api groups: port, compress, plus SHE and PKCS#12 decision
    cases, and a deterministic ocsp group (its tests previously registered as
    bare TEST_DECL, reachable only via --api).
  • New tests/unit-mcdc/ white-box supplements for asn.c, pkcs7.c,
    pkcs12.c, tsp.c and wc_port.c. These #include the source directly to
    reach file-statics that no public entry point can drive — the densest
    decision clusters in the layer are static.
  • Existing ECC/RSA white-boxes expanded; a new ECC allocation-fault driver.

Notes for review

  • White-box programs are EXTRA_DIST only. Each defines its own main() and
    includes a .c, so they cannot join unit.test; the out-of-tree coverage
    campaign compiles them standalone.
  • Test corpus is reused from certs/ rather than newly authored.
  • ~50 HAVE_FIPS/HAVE_SELFTEST sites in this layer are structurally
    uncoverable in an open build and are recorded as justified residuals, not
    gaps.

Covers the argument guards of wc_FileLoad, wc_ReadDirFirst/Next,
wc_strtok, wc_strsep, wc_strlcpy's truncation arm and wolfSSL_NewThread.
wc_port.c had no test group of its own.

Builds clean under --enable-all, default and --enable-singlethreaded.
Argument guards of wc_Compress_ex, wc_DeCompress_ex and
wc_DeCompressDynamic, plus the inSz overflow cap. Takes compress.c to
8/8 with the existing compress_test() KAT.
The pkcs12 group was almost entirely wc_PKCS12_PBKDF_ex, which lives in
pwdbased.c, leaving pkcs12.c's container entry points to the KAT alone.
Drives the argument guards of wc_d2i_PKCS12, wc_i2d_PKCS12,
wc_PKCS12_parse and wc_PKCS12_free.
wc_SHE_GenerateM1M2M3 and wc_SHE_GenerateM4M5 have a 12-operand and an
8-operand argument OR that account for 20 of wc_she.c's 23 uncovered
conditions; the group's other tests only pass valid arguments. One call
per operand.
ecc: test_ecc_whitebox.c 336 -> 1591 lines, 4 -> 21 driver classes
(curve-id lookup AND-chains, projective add/dbl NULL and range guards,
point-at-infinity and collision special cases, FP_ECC cache internals,
export_point_der paths). New test_ecc_fault_whitebox.c drives the
SMALL_STACK allocation guards via mcdc_fault_alloc.h.

rsa: three more drivers (wc_RsaCleanup data/type pairs,
wc_CheckProbablePrime_ex qRaw cross-check, wc_RsaFunctionNonBlock).
First white-box coverage for the ASN.1/PKCS layer. asn: 24 drivers over
the template engine, the ASN.1 primitives and the OID/signature
matching. pkcs12: 14 drivers over the container statics the API group
never reaches.
The 7 parse/verify tests become TEST_DECL_GROUP("ocsp") so the MC/DC
campaign can drive asn.c's OCSP paths without --api. The TLS-coupled
ocsp tests stay bare: they need live connections.
wolfSSL_strnstr is not in any public wolfcrypt header, so the port group
cannot reach it. Drives both operands of its "n >= s2_len && s1[0]" loop
guard.
Four asn white-boxes, one per functional area, so they can be worked in
parallel: keys/PKCS8, extensions and name constraints, OCSP/CRL, cert
generation and aux. Plus a pkcs7 white-box covering the streaming state
machine, signer-info parsing and the recipient helpers.

Takes asn.c to 745/1510 and pkcs7.c to 329/1058.
Both were left mid-edit when their authoring sessions were cut off.

ext: a comment reading "takes only DNS_entry*/Base_entry*" closed itself
early on the embedded */, so the rest became code.

revocation: DecodedCert.serial is an array not a pointer; SlhDsaKey is
an incomplete type unless SLH-DSA is on, so the opaque key argument is
now a plain buffer; and InitOcspResponse needs real OcspEntry and
CertStatus storage or the decoder dereferences a NULL single.
asn: the DecodedCert/names/time area -- AltNameDup, SetCurve,
SetEccPublicKey, the DNS-entry builders, the GetRDN/GetCertName OID
dispatch, and the date/time helpers driven with hand-built UTCTime and
GeneralizedTime strings.

pkcs7: the ASN.1-walk chains in PKCS7_VerifySignedData and the
Enveloped/AuthEnveloped/EncryptedData decoders, reached by sweeping
truncated and single-byte-corrupted copies of real messages.

Both verified to run, not just compile.
tsp: first white-box for the RFC 3161 timestamp protocol.
pkcs12: the deep DER-walk conditions in the parse path, reached with
truncated and byte-corrupted copies of the in-tree .p12 blobs.
The public wc_ed25519_verify_msg_init/update/final reject a NULL key
before delegating, so the identical checks inside the static
ed25519_verify_msg_*_with_sha helpers are unreachable through the API.
Drive the three statics directly, issuing both the key==NULL vector and
its all-false partner in this binary.
It contributed nothing in all six variants.

WOLFSSL_WC_LMS_SMALL reshapes LmsParams and LmsState and
WOLFSSL_LMS_VERIFY_ONLY drops keygen and signing, so every driver built
on wb_make_params() failed to compile there; guard them on WB_GAP_SIGN.

The rest overran the 600s test timeout in a 3-level height-5 keygen that
could only fail anyway, since the module config pins
WOLFSSL_LMS_MAX_LEVELS to 2 and HssPrivKey holds state[LMS_MAX_LEVELS].
Guard that driver on LMS_MAX_LEVELS >= 3 and shrink the full-cycle tree
to height 2, which still crosses one subtree boundary.

Unbuffer stdout so a timeout kill keeps the log that says where it
stopped.
Copilot AI review requested due to automatic review settings August 3, 2026 19:16

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

Note

Copilot couldn't run its full agentic review because it didn't start before the timeout. Make sure your repository has a runner available, or add a copilot-code-review.yml file specifying one with the runs-on attribute. See the docs for more details.

Test-only PR extending the ISO 26262 (ASIL-D) MC/DC campaign to cover remaining large decision clusters in wolfCrypt’s ASN.1/PKCS layer and related modules, primarily via new tests/api groups and unit-mcdc white-box supplements.

Changes:

  • Added multiple tests/unit-mcdc/ white-box supplements that #include source files to drive static/internal decision paths.
  • Added new tests/api groups (port, compress, plus new SHE/PKCS#12 decision-coverage cases) and registered them in the test harness/build.
  • Adjusted test registration (including grouping OCSP tests) and build files to compile the new test sources.

Reviewed changes

Copilot reviewed 28 out of 28 changed files in this pull request and generated 8 comments.

Show a summary per file
File Description
tests/unit-mcdc/test_wc_port_whitebox.c White-box driver to exercise internal wolfSSL_strnstr loop-guard operand pairs.
tests/unit-mcdc/test_wc_lms_impl_whitebox_gap.c Reduces LMS keygen runtime for instrumented runs; adds conditional compilation stubs and unbuffered stdout.
tests/unit-mcdc/test_tsp_whitebox.c White-box supplement for TSP / ASN TSP failure-half and static-helper coverage.
tests/unit-mcdc/test_rsa_whitebox.c Adds coverage drivers for additional RSA guards (cleanup, probable-prime cross-check, nonblock guard).
tests/unit-mcdc/test_pkcs7_decode_whitebox.c Adds decode-path ASN.1 walk truncation/corruption sweeps for PKCS#7 decoders.
tests/unit-mcdc/test_pkcs12_whitebox.c Adds PKCS#12 white-box drivers for guards, alloc-failures, DER walks, and LENGTH_ONLY_E pass-throughs.
tests/unit-mcdc/test_pkcs12_parse_whitebox.c Adds PKCS#12 deep-parse DER/BER-walk coverage and synthetic indefinite/EOC cases.
tests/unit-mcdc/test_ed25519_whitebox.c Adds coverage for file-static streaming-verify helper key == NULL operand.
tests/unit-mcdc/test_ecc_whitebox.c Expands ECC white-box coverage across many internal guards and special cases.
tests/unit-mcdc/test_ecc_fault_whitebox.c Adds fault-injection sweep for ECC SMALL_STACK allocation-failure guards.
tests/unit-mcdc/test_asn_whitebox.c New ASN.1 template-engine and primitive white-box driver covering many internal decisions.
tests/api/test_she.h / tests/api/test_she.c Registers and implements a new SHE decision-coverage test.
tests/api/test_port.h / tests/api/test_port.c New portability-layer decision-coverage tests and group registration.
tests/api/test_pkcs12.h / tests/api/test_pkcs12.c Registers and implements a new PKCS#12 container API decision-coverage test.
tests/api/test_compress.h / tests/api/test_compress.c New zlib-wrapper decision-coverage tests and group registration.
tests/api/include.am Adds new api test sources and headers to build and distribution lists.
tests/api.c Includes and registers new port/compress groups; groups OCSP tests under ocsp.
CMakeLists.txt Adds the two new tests/api sources to the CMake test build.

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

Comment on lines +119 to +122
byte data[] = { 0x04, 0x04, 0x02, 0xAA, 0xBB };
idx = 0; curIdx = 0;
ret = PKCS12_CoalesceOctetStrings(&p, data, sizeof(data), &idx, &curIdx);
if (ret != 0) { wb_fail = 1; }
Comment on lines +139 to +142
byte data[] = { 0x02, 0x02, 0x00 };
idx = 0; curIdx = 0;
ret = PKCS12_CoalesceOctetStrings(&p, data, sizeof(data), &idx, &curIdx);
if (ret != WC_NO_ERR_TRACE(ASN_PARSE_E)) { wb_fail = 1; }
Comment on lines +150 to +153
byte data[] = { 0x02, 0x04, 0x00 };
idx = 0; curIdx = 0;
ret = PKCS12_CoalesceOctetStrings(&p, data, sizeof(data), &idx, &curIdx);
if (ret != WC_NO_ERR_TRACE(ASN_PARSE_E)) { wb_fail = 1; }
Comment thread tests/api/test_compress.c
Comment on lines +22 to +29
#include <tests/unit.h>

#ifdef HAVE_LIBZ
#include <wolfssl/wolfcrypt/compress.h>
#endif
#include <wolfssl/wolfcrypt/error-crypt.h>
#include <tests/api/api.h>
#include <tests/api/test_compress.h>
Comment thread tests/api/test_compress.c
Comment on lines +91 to +93
ExpectIntEQ(wc_DeCompressDynamic(&dynOut, 1, DYNAMIC_TYPE_TMP_BUFFER,
packed, (word32)(INT_MAX / 2) + 1, 0, NULL),
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
Comment thread tests/api/test_port.c
Comment on lines +162 to +167
/* "i < (dstSize - 1) && *src != '\0'": a source longer than the
* destination ends the loop on the size operand rather than on the
* terminator, which is that operand's uncovered half. */
XMEMSET(lcpyDst, 0, sizeof(lcpyDst));
ExpectIntEQ((int)wc_strlcpy(lcpyDst, "abcdef", 3), 2);
ExpectIntEQ(XSTRNCMP(lcpyDst, "ab", 3), 0);
Comment thread tests/api/test_pkcs12.c
Comment on lines +1129 to +1133
ExpectIntLT(wc_PKCS12_parse(pkcs12, "pw", &pkey, &pkeySz, &cert,
&certSz, &ca), 0);
if (pkey != NULL) XFREE(pkey, NULL, DYNAMIC_TYPE_PUBLIC_KEY);
if (cert != NULL) XFREE(cert, NULL, DYNAMIC_TYPE_PKCS);
if (ca != NULL) wc_FreeCertList(ca, NULL);
Comment thread tests/api/test_she.c
Comment on lines +795 to +801
ExpectIntEQ(wc_SHE_Init(&she, NULL, INVALID_DEVID), 0);
if (EXPECT_SUCCESS()) inited = 1;

/* wc_SHE_GenerateM1M2M3: 12 operands, one invalid per call. */
ExpectIntEQ(wc_SHE_GenerateM1M2M3(&she, NULL, WC_SHE_UID_SZ, 1, key,
WC_SHE_KEY_SZ, 2, key, WC_SHE_KEY_SZ, 1, 0, m1, sizeof(m1), m2,
sizeof(m2), m3, sizeof(m3)), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
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.

2 participants