Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
8b5abe5
tests: add MC/DC decision/feature coverage tests
danielinux Jul 2, 2026
e7cd2b7
tests: AES MC/DC white-box supplement + api decision/feature coverage
danielinux Jul 6, 2026
e8cad24
tests: guard internal-symbol MC/DC tests with WOLFSSL_TEST_STATIC_BUILD
danielinux Jul 6, 2026
a3b3ee8
tests: fix config-dependent AES-CTR rounds-check coverage assertion
danielinux Jul 6, 2026
8324b67
tests: fix -Werror/config-gating failures in MC/DC coverage tests
danielinux Jul 6, 2026
09e4888
tests: replace non-ASCII chars in MC/DC test comments/docs
danielinux Jul 6, 2026
4880b27
tests: skip AES rounds-corruption checks under WOLF_CRYPTO_CB_FIND
danielinux Jul 6, 2026
9165eb0
tests: guard AES tests for cryptocb-only and no-AES-192/256 configs
danielinux Jul 6, 2026
bd87305
tests: fix X509V3_EXT leak, C++ build, and no-client link
danielinux Jul 6, 2026
ba3fd12
tests: skip AES rounds-corruption checks under WOLFSSL_ARMASM
danielinux Jul 6, 2026
a929973
tests: fix AesKeyExport lifecycle-tag leak and server-only session-ca…
danielinux Jul 6, 2026
a0dbe59
tests: guard AesSetKey/Cmac ArgMcdc tests for the older FIPS API
danielinux Jul 6, 2026
9d0c6cb
tests: guard AesModes/AesGcm ArgMcdc tests for the older FIPS API
danielinux Jul 6, 2026
ba2e52a
tests: zero-init ccmTag to satisfy clang-tidy
danielinux Jul 6, 2026
e3a6d4a
build: register HAVE_PQC in known-macro extras
danielinux Jul 6, 2026
27b1a40
tests: fix AUTHORITY_INFO_ACCESS leak under OPENSSL_EXTRA-only builds
danielinux Jul 6, 2026
e63555a
tests/unit-mcdc: white-box the AES-NI internal pointer guards
danielinux Jul 6, 2026
4755bb2
tests: skip AES rounds-corruption under FIPS/self-test (fixes CCM seg…
danielinux Jul 7, 2026
479659f
tests: guard Gmac/AesGcmSetExtIV tests for the self-test module
danielinux Jul 7, 2026
b680985
tests: skip whole AesCcmArgMcdc under FIPS/self-test (fixes v5 segfault)
danielinux Jul 7, 2026
b9925e7
tests: skip RsaDecisionCoverage under the self-test module
danielinux Jul 7, 2026
e14a3aa
tests: skip AesFeatureCoverage GCM/CCM under the self-test module
danielinux Jul 7, 2026
a178b6f
tests: also exclude old FIPS from AesFeatureCoverage CCM block
danielinux Jul 7, 2026
a79c704
tests: make RsaDecisionCoverage padding-mismatch check deterministic
danielinux Jul 7, 2026
2159b15
tests: keep test_wolfSSL_X509V3_EXT OPENSSL_ALL-only
danielinux Jul 7, 2026
53cad55
tests: address review findings (dead HAVE_PQC guard, guard/style clea…
danielinux Jul 8, 2026
7487366
tests: keep OQS_SIG_keypair() out of ExpectIntEQ
danielinux Jul 9, 2026
c1500f8
tests: import the falcon benchmark key instead of OQS keygen
danielinux Jul 9, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
548 changes: 546 additions & 2 deletions tests/api.c

Large diffs are not rendered by default.

2,492 changes: 2,355 additions & 137 deletions tests/api/test_aes.c

Large diffs are not rendered by default.

34 changes: 32 additions & 2 deletions tests/api/test_aes.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,21 @@ int test_wc_AesGcmStream(void);
int test_wc_AesGcmStream_MidStreamState(void);
int test_wc_AesGcmStream_ReinitAfterFinal(void);
int test_wc_AesGcmStream_BadAuthTag(void);
int test_wc_AesKeyWrapVectors(void);
int test_wc_AesKeyWrapDecisionCoverage(void);
int test_wc_AesGcmDecisionCoverage(void);
int test_wc_AesFeatureCoverage(void);
int test_wc_AesSetKeyArgMcdc(void);
int test_wc_AesModesArgMcdc(void);
int test_wc_AesGcmArgMcdc(void);
int test_wc_AesGmacArgMcdc(void);
int test_wc_AesCcmArgMcdc(void);
int test_wc_AesXtsArgMcdc(void);
int test_wc_AesCmacArgMcdc(void);
int test_wc_AesKeyExportArgMcdc(void);
#if defined(WOLFSSL_AES_SIV) && defined(WOLFSSL_AES_128)
int test_wc_AesSivArgMcdc(void);
#endif
int test_wc_AesCcmSetKey(void);
int test_wc_AesCcmEncryptDecrypt(void);
int test_wc_AesCcmEncryptDecrypt_InPlace(void);
Expand All @@ -76,6 +91,7 @@ int test_wc_AesEaxVectors(void);
int test_wc_AesEaxEncryptAuth(void);
int test_wc_AesEaxDecryptAuth(void);
int test_wc_AesEaxStream(void);
int test_wc_AesEaxArgMcdc(void);
#endif /* WOLFSSL_AES_EAX && WOLFSSL_AES_256*/
#if defined(WOLFSSL_AES_SIV) && defined(WOLFSSL_AES_128)
int test_wc_AesSivEncryptDecrypt(void);
Expand Down Expand Up @@ -179,6 +195,18 @@ int test_wc_CryptoCb_Tls13_Key_No_Zero_Without_Offload(void);
TEST_DECL_GROUP("aes", test_wc_AesGcmStream_MidStreamState), \
TEST_DECL_GROUP("aes", test_wc_AesGcmStream_ReinitAfterFinal), \
TEST_DECL_GROUP("aes", test_wc_AesGcmStream_BadAuthTag), \
TEST_DECL_GROUP("aes", test_wc_AesKeyWrapVectors), \
TEST_DECL_GROUP("aes", test_wc_AesKeyWrapDecisionCoverage), \
TEST_DECL_GROUP("aes", test_wc_AesGcmDecisionCoverage), \
TEST_DECL_GROUP("aes", test_wc_AesFeatureCoverage), \
TEST_DECL_GROUP("aes", test_wc_AesSetKeyArgMcdc), \
TEST_DECL_GROUP("aes", test_wc_AesModesArgMcdc), \
TEST_DECL_GROUP("aes", test_wc_AesGcmArgMcdc), \
TEST_DECL_GROUP("aes", test_wc_AesGmacArgMcdc), \
TEST_DECL_GROUP("aes", test_wc_AesCcmArgMcdc), \
TEST_DECL_GROUP("aes", test_wc_AesXtsArgMcdc), \
TEST_DECL_GROUP("aes", test_wc_AesCmacArgMcdc), \
TEST_DECL_GROUP("aes", test_wc_AesKeyExportArgMcdc), \
TEST_DECL_GROUP("aes", test_wc_AesCcmSetKey), \
TEST_DECL_GROUP("aes", test_wc_AesCcmEncryptDecrypt), \
TEST_DECL_GROUP("aes", test_wc_AesCcmEncryptDecrypt_InPlace), \
Expand Down Expand Up @@ -210,12 +238,14 @@ int test_wc_CryptoCb_Tls13_Key_No_Zero_Without_Offload(void);
TEST_DECL_GROUP("aes-eax", test_wc_AesEaxVectors), \
TEST_DECL_GROUP("aes-eax", test_wc_AesEaxEncryptAuth), \
TEST_DECL_GROUP("aes-eax", test_wc_AesEaxDecryptAuth), \
TEST_DECL_GROUP("aes-eax", test_wc_AesEaxStream)
TEST_DECL_GROUP("aes-eax", test_wc_AesEaxStream), \
TEST_DECL_GROUP("aes-eax", test_wc_AesEaxArgMcdc)
#endif /* WOLFSSL_AES_EAX */

#if defined(WOLFSSL_AES_SIV) && defined(WOLFSSL_AES_128)
#define TEST_AES_SIV_DECLS \
TEST_DECL_GROUP("aes-siv", test_wc_AesSivEncryptDecrypt)
TEST_DECL_GROUP("aes-siv", test_wc_AesSivEncryptDecrypt), \
TEST_DECL_GROUP("aes-siv", test_wc_AesSivArgMcdc)
#endif /* WOLFSSL_AES_SIV && WOLFSSL_AES_128 */

#define TEST_GMAC_DECLS \
Expand Down
267 changes: 267 additions & 0 deletions tests/api/test_asn.c
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,9 @@
#ifdef HAVE_ED448
#include <wolfssl/wolfcrypt/ed448.h>
#endif
#ifdef HAVE_ECC
#include <wolfssl/wolfcrypt/ecc.h>
#endif
#ifdef HAVE_DILITHIUM
#include <wolfssl/wolfcrypt/dilithium.h>
#endif
Expand Down Expand Up @@ -2214,3 +2217,267 @@ int test_ToTraditional_ex_mldsa_bad_params(void)
#endif
return EXPECT_RESULT();
}

/*
* MC/DC wave 2 - decision-targeted negative paths for PKCS#8 wrap/parse
* and RSA key decode. Targets argument-check, short-buffer, and
* truncated-DER decision branches in wolfcrypt/src/asn.c without touching
* the library source.
*/
int test_wc_AsnDecisionCoverage(void)
{
EXPECT_DECLS;

#if !defined(NO_ASN) && !defined(NO_RSA) && \
(defined(USE_CERT_BUFFERS_1024) || defined(USE_CERT_BUFFERS_2048)) && \
!defined(HAVE_FIPS)
/* ---- wc_RsaPublicKeyDecode: truncated / bad-arg decision branches ---- */
{
RsaKey key;
const byte* derKey;
word32 derKeySz;
word32 idx;

XMEMSET(&key, 0, sizeof(key));
ExpectIntEQ(wc_InitRsaKey(&key, HEAP_HINT), 0);

#ifdef USE_CERT_BUFFERS_2048
derKey = client_keypub_der_2048;
derKeySz = (word32)sizeof_client_keypub_der_2048;
#else
derKey = client_keypub_der_1024;
derKeySz = (word32)sizeof_client_keypub_der_1024;
#endif

/* Null arg branches. */
idx = 0;
ExpectIntEQ(wc_RsaPublicKeyDecode(NULL, &idx, &key, derKeySz),
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
ExpectIntEQ(wc_RsaPublicKeyDecode(derKey, NULL, &key, derKeySz),
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
ExpectIntEQ(wc_RsaPublicKeyDecode(derKey, &idx, NULL, derKeySz),
WC_NO_ERR_TRACE(BAD_FUNC_ARG));

/* Truncated input: header says more data than buffer length. */
idx = 0;
ExpectIntLT(wc_RsaPublicKeyDecode(derKey, &idx, &key, 4), 0);

/* wc_RsaPublicKeyDecodeRaw null-arg branches. */
{
static const byte nBuf[] = { 0xC0 };
static const byte eBuf[] = { 0x01, 0x00, 0x01 };
ExpectIntEQ(wc_RsaPublicKeyDecodeRaw(NULL, sizeof(nBuf),
eBuf, sizeof(eBuf), &key), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
ExpectIntEQ(wc_RsaPublicKeyDecodeRaw(nBuf, sizeof(nBuf),
NULL, sizeof(eBuf), &key), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
ExpectIntEQ(wc_RsaPublicKeyDecodeRaw(nBuf, sizeof(nBuf),
eBuf, sizeof(eBuf), NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
}

DoExpectIntEQ(wc_FreeRsaKey(&key), 0);
}

/* ---- wc_GetPkcs8TraditionalOffset: argument-check branches ---- */
{
byte buf[8] = { 0x30, 0x82, 0x00, 0x00, 0x02, 0x01, 0x00, 0x00 };
word32 idx;

idx = 0;
ExpectIntEQ(wc_GetPkcs8TraditionalOffset(NULL, &idx, sizeof(buf)),
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
ExpectIntEQ(wc_GetPkcs8TraditionalOffset(buf, NULL, sizeof(buf)),
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
/* idx >= sz decision branch - any negative return exercises the
* short-input guard (BUFFER_E in current code, but we do not pin
* the exact code here). */
idx = sizeof(buf);
ExpectIntLT(wc_GetPkcs8TraditionalOffset(buf, &idx, sizeof(buf)), 0);
/* Non-PKCS#8 blob: malformed DER decision branch. */
{
byte bogus[4] = { 0x00, 0x00, 0x00, 0x00 };
idx = 0;
ExpectIntLT(wc_GetPkcs8TraditionalOffset(bogus, &idx,
sizeof(bogus)), 0);
}
}

/* ---- wc_CreatePKCS8Key: size-query and bad-arg branches ----
* Uses the existing RSA private key DER from certs_test.h to avoid
* runtime key generation (which requires WOLFSSL_KEY_GEN and a usable
* RNG and is not available in every retained lane). */
{
#ifdef USE_CERT_BUFFERS_2048
const byte* rsaDer = client_key_der_2048;
word32 rsaDerSz = (word32)sizeof_client_key_der_2048;
#else
const byte* rsaDer = client_key_der_1024;
word32 rsaDerSz = (word32)sizeof_client_key_der_1024;
#endif
byte pkcs8[2048];
word32 pkcs8Sz;

/* Size-query: out == NULL should return LENGTH_ONLY_E and set
* outSz. */
pkcs8Sz = 0;
ExpectIntEQ(wc_CreatePKCS8Key(NULL, &pkcs8Sz, (byte*)rsaDer,
rsaDerSz, RSAk, NULL, 0),
WC_NO_ERR_TRACE(LENGTH_ONLY_E));
ExpectIntGT(pkcs8Sz, 0);

/* Null outSz branch. */
ExpectIntEQ(wc_CreatePKCS8Key(pkcs8, NULL, (byte*)rsaDer, rsaDerSz,
RSAk, NULL, 0), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
}
#endif /* !NO_ASN && !NO_RSA && cert-buffers && !HAVE_FIPS */

return EXPECT_RESULT();
}

/*
* MC/DC wave 2 - feature-oriented positive paths to lift asn.c MC/DC by
* exercising real cert parsing, PKCS#8 round trips, ECC key decoding, and
* PEM<->DER conversions on the static cert buffers (no new fixtures).
*/
int test_wc_AsnFeatureCoverage(void)
{
EXPECT_DECLS;
#if !defined(NO_ASN) && !defined(NO_RSA) && \
defined(USE_CERT_BUFFERS_2048) && !defined(HAVE_FIPS)
/* ---- DecodedCert: full client cert parse, with subject + pubkey ---- */
{
struct DecodedCert cert;
byte pubKey[512];
word32 pubKeySz = sizeof(pubKey);
char subject[256];
word32 subjectSz = sizeof(subject);

wc_InitDecodedCert(&cert, client_cert_der_2048,
sizeof_client_cert_der_2048, NULL);
ExpectIntEQ(wc_ParseCert(&cert, CERT_TYPE, NO_VERIFY, NULL), 0);
ExpectIntEQ(wc_GetPubKeyDerFromCert(&cert, pubKey, &pubKeySz), 0);
ExpectIntGT(pubKeySz, 0);
ExpectIntEQ(wc_GetDecodedCertSubject(&cert, subject, &subjectSz), 0);
wc_FreeDecodedCert(&cert);
}

/* ---- DecodedCert: server cert parse and SubjectPublicKeyInfo extract -- */
{
struct DecodedCert cert;
byte spki[1024];
word32 spkiSz = sizeof(spki);

wc_InitDecodedCert(&cert, server_cert_der_2048,
sizeof_server_cert_der_2048, NULL);
ExpectIntEQ(wc_ParseCert(&cert, CERT_TYPE, NO_VERIFY, NULL), 0);
wc_FreeDecodedCert(&cert);

/* Some retained builds return 0 on success and write spkiSz; others
* return spkiSz directly. Accept any non-negative result and require
* a non-zero output size. */
ExpectIntGE(wc_GetSubjectPubKeyInfoDerFromCert(server_cert_der_2048,
sizeof_server_cert_der_2048, spki, &spkiSz), 0);
ExpectIntGT(spkiSz, 0);
}

/* ---- PKCS#8: round trip wrap then offset extract ---- */
{
byte pkcs8[2048];
word32 pkcs8Sz = 0;
word32 idx;
int wrapSz;

/* Size query first. */
ExpectIntEQ(wc_CreatePKCS8Key(NULL, &pkcs8Sz,
(byte*)client_key_der_2048, sizeof_client_key_der_2048, RSAk,
NULL, 0), WC_NO_ERR_TRACE(LENGTH_ONLY_E));
ExpectIntGT(pkcs8Sz, 0);

wrapSz = wc_CreatePKCS8Key(pkcs8, &pkcs8Sz,
(byte*)client_key_der_2048, sizeof_client_key_der_2048, RSAk,
NULL, 0);
ExpectIntGT(wrapSz, 0);

if (wrapSz > 0) {
idx = 0;
ExpectIntGE(wc_GetPkcs8TraditionalOffset(pkcs8, &idx,
(word32)wrapSz), 0);
ExpectIntGT(idx, 0);
}
}

/* ---- CA cert parse: exercises CA-specific decision branches ---- */
{
struct DecodedCert caCert;
wc_InitDecodedCert(&caCert, ca_cert_der_2048, sizeof_ca_cert_der_2048,
NULL);
ExpectIntEQ(wc_ParseCert(&caCert, CA_TYPE, NO_VERIFY, NULL), 0);
wc_FreeDecodedCert(&caCert);
}

/* ---- Parse server cert a second time with CERT_TYPE + verify off ----
* to touch ParseCertRelative decision branches that the first pass skips.
*/
{
struct DecodedCert cert2;
wc_InitDecodedCert(&cert2, server_cert_der_2048,
sizeof_server_cert_der_2048, NULL);
ExpectIntEQ(wc_ParseCert(&cert2, CERT_TYPE, NO_VERIFY, NULL), 0);
wc_FreeDecodedCert(&cert2);
}

/* ---- PEM<->DER conversion round trip on the client cert ---- */
#ifdef WOLFSSL_DER_TO_PEM
{
byte pem[4096];
int pemSz;

pemSz = wc_DerToPem(client_cert_der_2048, sizeof_client_cert_der_2048,
pem, sizeof(pem), CERT_TYPE);
ExpectIntGT(pemSz, 0);

#ifdef WOLFSSL_PEM_TO_DER
if (pemSz > 0) {
byte der[2048];
int derSz;
derSz = wc_CertPemToDer(pem, pemSz, der, sizeof(der), CERT_TYPE);
ExpectIntGT(derSz, 0);
if (derSz > 0)
ExpectBufEQ(der, client_cert_der_2048,
sizeof_client_cert_der_2048);
}
#endif
}
#endif /* WOLFSSL_DER_TO_PEM */
#endif /* !NO_ASN && !NO_RSA && USE_CERT_BUFFERS_2048 && !HAVE_FIPS */

#if !defined(NO_ASN) && defined(HAVE_ECC) && \
defined(USE_CERT_BUFFERS_256) && !defined(HAVE_FIPS)
/* ---- ECC private + public key DER decode round trip ---- */
{
ecc_key ecKey;
word32 idx = 0;
byte pubKeyDer[256];
int derSz;

XMEMSET(&ecKey, 0, sizeof(ecKey));
ExpectIntEQ(wc_ecc_init(&ecKey), 0);
ExpectIntEQ(wc_EccPrivateKeyDecode(ecc_clikey_der_256, &idx, &ecKey,
sizeof_ecc_clikey_der_256), 0);

derSz = wc_EccPublicKeyToDer(&ecKey, pubKeyDer, sizeof(pubKeyDer), 1);
ExpectIntGT(derSz, 0);

if (derSz > 0) {
ecc_key pubOnly;
word32 idx2 = 0;
XMEMSET(&pubOnly, 0, sizeof(pubOnly));
ExpectIntEQ(wc_ecc_init(&pubOnly), 0);
ExpectIntEQ(wc_EccPublicKeyDecode(pubKeyDer, &idx2, &pubOnly,
(word32)derSz), 0);
wc_ecc_free(&pubOnly);
}
wc_ecc_free(&ecKey);
}
#endif /* !NO_ASN && HAVE_ECC && USE_CERT_BUFFERS_256 && !HAVE_FIPS */
return EXPECT_RESULT();
}
6 changes: 5 additions & 1 deletion tests/api/test_asn.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ int test_ToTraditional_ex_handcrafted(void);
int test_ToTraditional_ex_roundtrip(void);
int test_ToTraditional_ex_negative(void);
int test_ToTraditional_ex_mldsa_bad_params(void);
int test_wc_AsnDecisionCoverage(void);
int test_wc_AsnFeatureCoverage(void);

#define TEST_ASN_DECLS \
TEST_DECL_GROUP("asn", test_SetAsymKeyDer), \
Expand All @@ -61,6 +63,8 @@ int test_ToTraditional_ex_mldsa_bad_params(void);
TEST_DECL_GROUP("asn", test_ToTraditional_ex_handcrafted), \
TEST_DECL_GROUP("asn", test_ToTraditional_ex_roundtrip), \
TEST_DECL_GROUP("asn", test_ToTraditional_ex_negative), \
TEST_DECL_GROUP("asn", test_ToTraditional_ex_mldsa_bad_params)
TEST_DECL_GROUP("asn", test_ToTraditional_ex_mldsa_bad_params), \
TEST_DECL_GROUP("asn", test_wc_AsnDecisionCoverage), \
TEST_DECL_GROUP("asn", test_wc_AsnFeatureCoverage)

#endif /* WOLFCRYPT_TEST_ASN_H */
Loading
Loading