From 871d0cb425e2e1713aa1e7fef8646e6182e93bdc Mon Sep 17 00:00:00 2001 From: kaleb-himes Date: Wed, 2 Sep 2026 15:53:35 -0600 Subject: [PATCH 01/10] tests/api: gate the seed-service indicator on the module capability --- tests/api/api.h | 53 ++++++++++++++++++++++++++++++++++++++++ tests/api/test_ed25519.c | 9 +++++++ tests/api/test_mldsa.c | 39 +++++++++++++++++++++++++++++ tests/api/test_mldsa.h | 2 ++ tests/api/test_mlkem.c | 42 +++++++++++++++++++++++++++++++ tests/api/test_mlkem.h | 2 ++ 6 files changed, 147 insertions(+) diff --git a/tests/api/api.h b/tests/api/api.h index 69b1f433e51..20db0847502 100644 --- a/tests/api/api.h +++ b/tests/api/api.h @@ -39,6 +39,59 @@ #include +/* PQC known-answer tests drive ML-KEM/ML-DSA/SLH-DSA keygen and signing from + * fixed NIST seeds. FIPS 203 sec 3.3, 204 sec 5.4 and 205 sec 10.2 require the + * module to generate that randomness itself, so the public seed-input service + * returns WC_FIPS_NOT_APPROVED in a FIPS build; these KATs run in non-FIPS + * builds only (module CASTs / optest / CAVP cover them otherwise). */ +#if !defined(HAVE_FIPS) + #define WOLFSSL_TEST_PQC_SEED_KAT +#endif + +/* Expected result for an argument-validation call to a *_with_seed / + * *_with_random seed-input wrapper: the public service is no longer gated, so + * it always reaches its normal argument validation and returns the given code + * (the WC_FIPS_NOT_APPROVED indicator applies only to a *successful* external + * call). */ +#define SEED_ARG_ERR(e) WC_NO_ERR_TRACE(e) + +/* Expected result for a SUCCESSFUL seed-input call. The counterpart to + * SEED_ARG_ERR: that macro asserts the ungated argument validation still runs, + * this one asserts the service-indicator behaviour that makes the seed APIs + * acceptable in an approved module at all (LAB-CONFIRMED 2026-07-24, the + * *_with_seed / *_with_random services stay public and in-module and report + * WC_FIPS_NOT_APPROVED rather than being hard-gated). + * + * Without an assertion on this value, SEED_ARG_ERR's premise, "the public + * service is no longer gated, so it always reaches its normal argument + * validation", is documented but untested: a wrapper changed to return the + * indicator BEFORE validating its arguments would keep every existing test + * green while silently changing the service contract. */ +/* A successful PQ seed-input call reports WC_FIPS_NOT_APPROVED from a module + * whose wrappers normalise the indicator, and a plain 0 from every other build. + * + * WC_HAVE_FIPS_INDICATOR is the CAPABILITY macro fips.h defines for exactly + * that, and gating on it rather than on the version alone is what lets this + * change merge BEFORE the FIPS-side PR: against a bundle without it the module + * returns 0 and so does SEED_OK; against one with it, both are the indicator. + * The test tracks the module actually present instead of assuming one. The + * same pattern is already used for Ed25519ctx below and in benchmark.c. + * + * FIPS_NO_WRAPPERS (settings.h, for WC_FIPS_LL_CRYPTO and + * WOLFSSL_FIPS_DEV_NO_POST) compiles no wrappers at all, so those expect 0. + * + * --enable-fips=dev is deliberately NOT excluded: it compiles the wrappers, so + * the module really does return the indicator under it and the test follows the + * module. Teaching fips.c about WOLFSSL_FIPS_DEV is not an option -- a + * development-only macro must never reach the module source. + */ +#if defined(HAVE_FIPS) && defined(WC_HAVE_FIPS_INDICATOR) && \ + FIPS_VERSION3_GE(7,0,0) && !defined(FIPS_NO_WRAPPERS) + #define SEED_OK WC_FIPS_NOT_APPROVED +#else + #define SEED_OK 0 +#endif + /* Old FIPS headers don't allow comparisons with WC_MIN_DIGEST_SIZE_FOR_SIGN by * the preprocessor, so we catch those builds with one of the first two * clauses. diff --git a/tests/api/test_ed25519.c b/tests/api/test_ed25519.c index 32eb91c958a..7526c009b31 100644 --- a/tests/api/test_ed25519.c +++ b/tests/api/test_ed25519.c @@ -1020,12 +1020,21 @@ int test_wc_ed25519_sign_verify_ctx_ph(void) /* Ed25519ctx round trip: type==Ed25519ctx true side, real context. */ sigLen = sizeof(sig); +#ifdef WC_FIPS_ED25519CTX_NOT_APPROVED + /* Ed25519ctx is not an Approved EdDSA instance in the FIPS module + * (FIPS 186-5 sec 7.6/7.8); the sign service must reject it. Gated on the + * module's capability macro (fips.h) rather than FIPS_VERSION3_GE(7,0,0): + * an earlier v7.0.0 module reports the same version but still signs. */ + ExpectIntEQ(wc_ed25519ctx_sign_msg(msg, sizeof(msg), sig, &sigLen, &key, + ctx, sizeof(ctx)), WC_NO_ERR_TRACE(SIG_TYPE_E)); +#else ExpectIntEQ(wc_ed25519ctx_sign_msg(msg, sizeof(msg), sig, &sigLen, &key, ctx, sizeof(ctx)), 0); verify_ok = 0; ExpectIntEQ(wc_ed25519ctx_verify_msg(sig, sigLen, msg, sizeof(msg), &verify_ok, &key, ctx, sizeof(ctx)), 0); ExpectIntEQ(verify_ok, 1); +#endif /* Ed25519ph round trip via hash and via full message, type==Ed25519ph * true side, WC_SHA512_DIGEST_SIZE length check false side (equal). */ diff --git a/tests/api/test_mldsa.c b/tests/api/test_mldsa.c index 35b2bd13ecf..acba3fb570d 100644 --- a/tests/api/test_mldsa.c +++ b/tests/api/test_mldsa.c @@ -31735,3 +31735,42 @@ int test_wc_MlDsaKey_SetPrecompA(void) #endif return EXPECT_RESULT(); } + +/* The seed-input service indicator, asserted on a SUCCESSFUL call. + * + * SEED_ARG_ERR() covers the argument-validation half of the contract: the + * *_with_seed / *_from_seed services are NOT hard-gated in a FIPS build, so + * they still reach their normal argument checks. Nothing asserted the other + * half, that a call which succeeds reports WC_FIPS_NOT_APPROVED, the + * positive service indicator that is what makes these services acceptable in + * an approved module at all (lab-confirmed 2026-07-24; FIPS 204 sec 5.4 says + * the module shall generate its own keygen randomness). + * + * Without this, a wrapper changed to return the indicator BEFORE validating + * its arguments would keep every existing SEED_ARG_ERR() assertion green while + * silently changing the service contract. SEED_OK is WC_FIPS_NOT_APPROVED in + * a FIPS v7+ build and 0 elsewhere, so the same assertion states the intended + * behavior for both. + */ +int test_wc_MlDsaKey_seed_service_indicator(void) +{ + EXPECT_DECLS; +#if defined(WOLFSSL_HAVE_MLDSA) && !defined(WOLFSSL_MLDSA_NO_MAKE_KEY) && \ + !defined(WOLFSSL_MLDSA_VERIFY_ONLY) + wc_MlDsaKey key; + byte seed[MLDSA_SEED_SZ]; + + XMEMSET(&key, 0, sizeof(key)); + XMEMSET(seed, 0x5a, sizeof(seed)); + + ExpectIntEQ(wc_MlDsaKey_Init(&key, NULL, INVALID_DEVID), 0); + ExpectIntEQ(wc_MlDsaKey_SetParams(&key, WC_ML_DSA_44), 0); + + /* Valid key, valid seed: the operation is performed, and in an approved + * build it is reported non-approved rather than refused. */ + ExpectIntEQ(wc_MlDsaKey_MakeKeyFromSeed(&key, seed), SEED_OK); + + wc_MlDsaKey_Free(&key); +#endif + return EXPECT_RESULT(); +} diff --git a/tests/api/test_mldsa.h b/tests/api/test_mldsa.h index d3cd09b78a7..265b9c76bd4 100644 --- a/tests/api/test_mldsa.h +++ b/tests/api/test_mldsa.h @@ -67,6 +67,7 @@ int test_wc_MldsaFeatureCoverage(void); * defined. */ int test_mldsa_legacy_shim(void); int test_wc_MldsaDecisionCoverage2(void); +int test_wc_MlDsaKey_seed_service_indicator(void); int test_wc_MldsaDerDecisionCoverage(void); int test_mldsa_cb_free(void); @@ -101,6 +102,7 @@ int test_wc_MlDsaKey_SetPrecompA(void); TEST_DECL_GROUP("mldsa", test_wc_MldsaFeatureCoverage), \ TEST_DECL_GROUP("mldsa", test_mldsa_legacy_shim), \ TEST_DECL_GROUP("mldsa", test_wc_MldsaDecisionCoverage2), \ + TEST_DECL_GROUP("mldsa", test_wc_MlDsaKey_seed_service_indicator), \ TEST_DECL_GROUP("mldsa", test_wc_MldsaDerDecisionCoverage), \ TEST_DECL_GROUP("mldsa", test_mldsa_cb_free), \ TEST_DECL_GROUP("mldsa", test_wc_MlDsaKey_SetPrecompA) diff --git a/tests/api/test_mlkem.c b/tests/api/test_mlkem.c index e909ee9953b..c0fe545656d 100644 --- a/tests/api/test_mlkem.c +++ b/tests/api/test_mlkem.c @@ -4650,6 +4650,48 @@ int test_wc_mlkem_encode_key_len_decision(void) return EXPECT_RESULT(); } /* END test_wc_mlkem_encode_key_len_decision */ +/* The seed-input service indicator, asserted on a SUCCESSFUL call. + * + * Counterpart to the SEED_ARG_ERR() invalid-argument assertions: those cover + * the "still reaches argument validation" half of the contract, this covers + * the half that makes the service acceptable in an approved module: a call + * that succeeds reports WC_FIPS_NOT_APPROVED (lab-confirmed 2026-07-24; + * FIPS 203 sec 6 says the module shall generate its own keygen randomness). + * + * The indicator is unambiguous here: wc_MlKemKey_MakeKeyWithRandom() returns + * 0 or a negative error and never a length or count, so a positive 1 cannot + * be confused for a result the way it could on an API like wc_RsaSSL_Verify() + * that returns a plaintext length. SEED_OK is WC_FIPS_NOT_APPROVED in a FIPS + * v7+ build and 0 elsewhere. + */ +int test_wc_MlKemKey_seed_service_indicator(void) +{ + EXPECT_DECLS; +#if defined(WOLFSSL_HAVE_MLKEM) && !defined(WOLFSSL_MLKEM_NO_MAKE_KEY) && \ + !defined(WOLFSSL_NO_ML_KEM) + MlKemKey key; + byte rand[WC_ML_KEM_MAKEKEY_RAND_SZ]; +#ifndef WOLFSSL_NO_ML_KEM_768 + const int mlkemType = WC_ML_KEM_768; +#elif !defined(WOLFSSL_NO_ML_KEM_512) + const int mlkemType = WC_ML_KEM_512; +#else + const int mlkemType = WC_ML_KEM_1024; +#endif + + XMEMSET(&key, 0, sizeof(key)); + XMEMSET(rand, 0x5a, sizeof(rand)); + + ExpectIntEQ(wc_MlKemKey_Init(&key, mlkemType, NULL, INVALID_DEVID), 0); + /* Valid key, valid randomness: performed, and reported non-approved. */ + ExpectIntEQ(wc_MlKemKey_MakeKeyWithRandom(&key, rand, (int)sizeof(rand)), + SEED_OK); + + wc_MlKemKey_Free(&key); +#endif + return EXPECT_RESULT(); +} + #if defined(WOLFSSL_HAVE_MLKEM) && !defined(WOLFSSL_NO_ML_KEM) && \ defined(WOLF_CRYPTO_CB) && defined(WOLF_CRYPTO_CB_FREE) #define TEST_MLKEM_CB_FREE diff --git a/tests/api/test_mlkem.h b/tests/api/test_mlkem.h index dda2b4fce4e..1e89e89c31f 100644 --- a/tests/api/test_mlkem.h +++ b/tests/api/test_mlkem.h @@ -25,6 +25,7 @@ #include int test_wc_mlkem_make_key_kats(void); +int test_wc_MlKemKey_seed_service_indicator(void); int test_wc_mlkem_encapsulate_kats(void); int test_wc_mlkem_decapsulate_kats(void); int test_wc_mlkem_decapsulate_pubonly_fails(void); @@ -41,6 +42,7 @@ int test_wc_mlkem_cb_pending_rejected(void); #define TEST_MLKEM_DECLS \ TEST_DECL_GROUP("mlkem", test_wc_mlkem_make_key_kats), \ + TEST_DECL_GROUP("mlkem", test_wc_MlKemKey_seed_service_indicator), \ TEST_DECL_GROUP("mlkem", test_wc_mlkem_encapsulate_kats), \ TEST_DECL_GROUP("mlkem", test_wc_mlkem_decapsulate_kats), \ TEST_DECL_GROUP("mlkem", test_wc_mlkem_decapsulate_pubonly_fails), \ From 2b638b4f7742361dd7b89f000f0951ed4f88013b Mon Sep 17 00:00:00 2001 From: kaleb-himes Date: Sun, 6 Sep 2026 10:33:18 -0600 Subject: [PATCH 02/10] tests/api: add the SLH-DSA seed-service indicator test --- tests/api/test_slhdsa.c | 39 +++++++++++++++++++++++++++++++++++++++ tests/api/test_slhdsa.h | 2 ++ 2 files changed, 41 insertions(+) diff --git a/tests/api/test_slhdsa.c b/tests/api/test_slhdsa.c index dbe8c105683..6f1c02916ac 100644 --- a/tests/api/test_slhdsa.c +++ b/tests/api/test_slhdsa.c @@ -4262,3 +4262,42 @@ int test_slhdsa_cb_free(void) #endif return EXPECT_RESULT(); } + +/* The seed-input service indicator, asserted on a SUCCESSFUL call. + * + * See test_wc_MlKemKey_seed_service_indicator() for the rationale. FIPS 205 + * sec 9.1 is the SLH-DSA equivalent: the module shall generate its own keygen + * randomness, so a caller-supplied one is performed but reported + * non-approved. wc_SlhDsaKey_MakeKeyWithRandom() returns 0 or a negative + * error and never a length, so the positive indicator is unambiguous. + */ +int test_wc_SlhDsaKey_seed_service_indicator(void) +{ + EXPECT_DECLS; +/* wc_SlhDsaKey_MakeKeyWithRandom() is declared inside + * "#ifndef WOLFSSL_SLHDSA_VERIFY_ONLY" in wc_slhdsa.h, and nothing else + * gates it, so that is the one guard this test needs. */ +#if defined(WOLFSSL_HAVE_SLHDSA) && !defined(WOLFSSL_SLHDSA_VERIFY_ONLY) + SlhDsaKey key; + /* n is 16/24/32 for the 128/192/256 parameter sets (FIPS 205 Table 2). + * The public key is PK.seed || PK.root, each n bytes (FIPS 205 sec 9.1), + * so n is half of PublicSize. Derived rather than tabulated so it covers + * every parameter set and cannot drift from the implementation. */ + byte seeds[3][WC_SLHDSA_N_256]; /* n is at most 32 */ + int n = 0; + + XMEMSET(&key, 0, sizeof(key)); + XMEMSET(seeds, 0x5a, sizeof(seeds)); + + ExpectIntEQ(wc_SlhDsaKey_Init(&key, WC_SLHDSA_DEFAULT_PARAM, NULL, + INVALID_DEVID), 0); + ExpectIntGT(n = wc_SlhDsaKey_PublicSize(&key), 0); + n /= 2; + /* Valid key, valid randomness: performed, and reported non-approved. */ + ExpectIntEQ(wc_SlhDsaKey_MakeKeyWithRandom(&key, seeds[0], (word32)n, + seeds[1], (word32)n, seeds[2], (word32)n), SEED_OK); + + wc_SlhDsaKey_Free(&key); +#endif + return EXPECT_RESULT(); +} diff --git a/tests/api/test_slhdsa.h b/tests/api/test_slhdsa.h index e364b57c80c..ae63879dfd2 100644 --- a/tests/api/test_slhdsa.h +++ b/tests/api/test_slhdsa.h @@ -25,6 +25,7 @@ #include int test_wc_slhdsa(void); +int test_wc_SlhDsaKey_seed_service_indicator(void); int test_wc_slhdsa_sizes(void); int test_wc_slhdsa_make_key(void); int test_wc_slhdsa_sign(void); @@ -55,6 +56,7 @@ int test_slhdsa_cb_free(void); #define TEST_SLHDSA_DECLS \ TEST_DECL_GROUP("slhdsa", test_wc_slhdsa), \ + TEST_DECL_GROUP("slhdsa", test_wc_SlhDsaKey_seed_service_indicator), \ TEST_DECL_GROUP("slhdsa", test_wc_slhdsa_sizes), \ TEST_DECL_GROUP("slhdsa", test_wc_slhdsa_make_key), \ TEST_DECL_GROUP("slhdsa", test_wc_slhdsa_sign), \ From f19692cd082e31aa65f694eac541a52c7af8e580 Mon Sep 17 00:00:00 2001 From: kaleb-himes Date: Sun, 6 Sep 2026 12:34:26 -0600 Subject: [PATCH 03/10] tests/api: gate RSA verify on the module 2048-bit minimum --- tests/api.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/tests/api.c b/tests/api.c index ccebd4fd8ce..2a7d69e79f3 100644 --- a/tests/api.c +++ b/tests/api.c @@ -30211,7 +30211,21 @@ static int test_wolfSSL_d2i_X509_REQ(void) /* * Verify the signature in the CSR */ +#ifdef WC_FIPS_RSA_VERIFY_MIN_2048 + /* certs/csr.ext.der carries a 1024-bit RSA key. CMVP IG C.F + * ("Signature verification"): "For the FIPS 186-5 signature + * verification, the modulus size shall be at least 2048." A 1024-bit + * modulus is only verifiable under a FIPS 186-4 legacy SigVer claim, + * which this module does not make, so the approved service rejects it + * and verification fails by design. + * Gated on the module's capability macro (fips.h) rather than + * FIPS_VERSION3_GE(7,0,0): an earlier module reports a version that + * satisfies that predicate but enforces the floor on key generation + * only, so it still verifies the 1024-bit signature. */ + ExpectIntEQ(X509_REQ_verify(req, pub_key), 0); +#else ExpectIntEQ(X509_REQ_verify(req, pub_key), 1); +#endif #ifdef OPENSSL_ALL ExpectNotNull(exts = (STACK_OF(X509_EXTENSION)*)X509_REQ_get_extensions( From 93aa6aa7fbeb2f8e446dc51fe84be0ef8834e5b0 Mon Sep 17 00:00:00 2001 From: kaleb-himes Date: Fri, 11 Sep 2026 14:12:12 -0600 Subject: [PATCH 04/10] tests/api: drop unused SEED_ARG_ERR and WOLFSSL_TEST_PQC_SEED_KAT --- tests/api/api.h | 28 ---------------------------- 1 file changed, 28 deletions(-) diff --git a/tests/api/api.h b/tests/api/api.h index 20db0847502..1ad2867e452 100644 --- a/tests/api/api.h +++ b/tests/api/api.h @@ -39,34 +39,6 @@ #include -/* PQC known-answer tests drive ML-KEM/ML-DSA/SLH-DSA keygen and signing from - * fixed NIST seeds. FIPS 203 sec 3.3, 204 sec 5.4 and 205 sec 10.2 require the - * module to generate that randomness itself, so the public seed-input service - * returns WC_FIPS_NOT_APPROVED in a FIPS build; these KATs run in non-FIPS - * builds only (module CASTs / optest / CAVP cover them otherwise). */ -#if !defined(HAVE_FIPS) - #define WOLFSSL_TEST_PQC_SEED_KAT -#endif - -/* Expected result for an argument-validation call to a *_with_seed / - * *_with_random seed-input wrapper: the public service is no longer gated, so - * it always reaches its normal argument validation and returns the given code - * (the WC_FIPS_NOT_APPROVED indicator applies only to a *successful* external - * call). */ -#define SEED_ARG_ERR(e) WC_NO_ERR_TRACE(e) - -/* Expected result for a SUCCESSFUL seed-input call. The counterpart to - * SEED_ARG_ERR: that macro asserts the ungated argument validation still runs, - * this one asserts the service-indicator behaviour that makes the seed APIs - * acceptable in an approved module at all (LAB-CONFIRMED 2026-07-24, the - * *_with_seed / *_with_random services stay public and in-module and report - * WC_FIPS_NOT_APPROVED rather than being hard-gated). - * - * Without an assertion on this value, SEED_ARG_ERR's premise, "the public - * service is no longer gated, so it always reaches its normal argument - * validation", is documented but untested: a wrapper changed to return the - * indicator BEFORE validating its arguments would keep every existing test - * green while silently changing the service contract. */ /* A successful PQ seed-input call reports WC_FIPS_NOT_APPROVED from a module * whose wrappers normalise the indicator, and a plain 0 from every other build. * From 71bcc3a5125d6b18e10245a8eb6851a00ce3af56 Mon Sep 17 00:00:00 2001 From: kaleb-himes Date: Fri, 11 Sep 2026 14:14:54 -0600 Subject: [PATCH 05/10] tests/api: drop seed indicator comment claims the tree does not back --- tests/api/api.h | 3 +-- tests/api/test_mldsa.c | 16 +++------------- tests/api/test_mlkem.c | 10 ++-------- 3 files changed, 6 insertions(+), 23 deletions(-) diff --git a/tests/api/api.h b/tests/api/api.h index 1ad2867e452..bf4f7205f6e 100644 --- a/tests/api/api.h +++ b/tests/api/api.h @@ -46,8 +46,7 @@ * that, and gating on it rather than on the version alone is what lets this * change merge BEFORE the FIPS-side PR: against a bundle without it the module * returns 0 and so does SEED_OK; against one with it, both are the indicator. - * The test tracks the module actually present instead of assuming one. The - * same pattern is already used for Ed25519ctx below and in benchmark.c. + * The test tracks the module actually present instead of assuming one. * * FIPS_NO_WRAPPERS (settings.h, for WC_FIPS_LL_CRYPTO and * WOLFSSL_FIPS_DEV_NO_POST) compiles no wrappers at all, so those expect 0. diff --git a/tests/api/test_mldsa.c b/tests/api/test_mldsa.c index acba3fb570d..349af104b2d 100644 --- a/tests/api/test_mldsa.c +++ b/tests/api/test_mldsa.c @@ -31738,19 +31738,9 @@ int test_wc_MlDsaKey_SetPrecompA(void) /* The seed-input service indicator, asserted on a SUCCESSFUL call. * - * SEED_ARG_ERR() covers the argument-validation half of the contract: the - * *_with_seed / *_from_seed services are NOT hard-gated in a FIPS build, so - * they still reach their normal argument checks. Nothing asserted the other - * half, that a call which succeeds reports WC_FIPS_NOT_APPROVED, the - * positive service indicator that is what makes these services acceptable in - * an approved module at all (lab-confirmed 2026-07-24; FIPS 204 sec 5.4 says - * the module shall generate its own keygen randomness). - * - * Without this, a wrapper changed to return the indicator BEFORE validating - * its arguments would keep every existing SEED_ARG_ERR() assertion green while - * silently changing the service contract. SEED_OK is WC_FIPS_NOT_APPROVED in - * a FIPS v7+ build and 0 elsewhere, so the same assertion states the intended - * behavior for both. + * SEED_OK is WC_FIPS_NOT_APPROVED when the module defines + * WC_HAVE_FIPS_INDICATOR and 0 otherwise, so the same assertion states the + * intended behavior for both. */ int test_wc_MlDsaKey_seed_service_indicator(void) { diff --git a/tests/api/test_mlkem.c b/tests/api/test_mlkem.c index c0fe545656d..067efc9eb1a 100644 --- a/tests/api/test_mlkem.c +++ b/tests/api/test_mlkem.c @@ -4651,18 +4651,12 @@ int test_wc_mlkem_encode_key_len_decision(void) } /* END test_wc_mlkem_encode_key_len_decision */ /* The seed-input service indicator, asserted on a SUCCESSFUL call. - * - * Counterpart to the SEED_ARG_ERR() invalid-argument assertions: those cover - * the "still reaches argument validation" half of the contract, this covers - * the half that makes the service acceptable in an approved module: a call - * that succeeds reports WC_FIPS_NOT_APPROVED (lab-confirmed 2026-07-24; - * FIPS 203 sec 6 says the module shall generate its own keygen randomness). * * The indicator is unambiguous here: wc_MlKemKey_MakeKeyWithRandom() returns * 0 or a negative error and never a length or count, so a positive 1 cannot * be confused for a result the way it could on an API like wc_RsaSSL_Verify() - * that returns a plaintext length. SEED_OK is WC_FIPS_NOT_APPROVED in a FIPS - * v7+ build and 0 elsewhere. + * that returns a plaintext length. SEED_OK is WC_FIPS_NOT_APPROVED when the + * module defines WC_HAVE_FIPS_INDICATOR and 0 otherwise. */ int test_wc_MlKemKey_seed_service_indicator(void) { From b43d79a526327c8f5424839c74065d808989b74c Mon Sep 17 00:00:00 2001 From: kaleb-himes Date: Fri, 11 Sep 2026 14:14:54 -0600 Subject: [PATCH 06/10] tests/api: replace a double hyphen dash in the SEED_OK comment --- tests/api/api.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/api/api.h b/tests/api/api.h index bf4f7205f6e..34e98cb5793 100644 --- a/tests/api/api.h +++ b/tests/api/api.h @@ -53,7 +53,7 @@ * * --enable-fips=dev is deliberately NOT excluded: it compiles the wrappers, so * the module really does return the indicator under it and the test follows the - * module. Teaching fips.c about WOLFSSL_FIPS_DEV is not an option -- a + * module. Teaching fips.c about WOLFSSL_FIPS_DEV is not an option: a * development-only macro must never reach the module source. */ #if defined(HAVE_FIPS) && defined(WC_HAVE_FIPS_INDICATOR) && \ From 5b8513d7c0fac33161899be9e7032612cf824910 Mon Sep 17 00:00:00 2001 From: kaleb-himes Date: Fri, 11 Sep 2026 14:16:29 -0600 Subject: [PATCH 07/10] tests/api: cut the capability gate comments to two lines --- tests/api.c | 12 ++---------- tests/api/api.h | 19 ++----------------- tests/api/test_ed25519.c | 6 ++---- tests/api/test_mldsa.c | 8 ++------ tests/api/test_mlkem.c | 10 ++-------- tests/api/test_slhdsa.c | 21 ++++++--------------- 6 files changed, 16 insertions(+), 60 deletions(-) diff --git a/tests/api.c b/tests/api.c index 2a7d69e79f3..c69ba272510 100644 --- a/tests/api.c +++ b/tests/api.c @@ -30212,16 +30212,8 @@ static int test_wolfSSL_d2i_X509_REQ(void) * Verify the signature in the CSR */ #ifdef WC_FIPS_RSA_VERIFY_MIN_2048 - /* certs/csr.ext.der carries a 1024-bit RSA key. CMVP IG C.F - * ("Signature verification"): "For the FIPS 186-5 signature - * verification, the modulus size shall be at least 2048." A 1024-bit - * modulus is only verifiable under a FIPS 186-4 legacy SigVer claim, - * which this module does not make, so the approved service rejects it - * and verification fails by design. - * Gated on the module's capability macro (fips.h) rather than - * FIPS_VERSION3_GE(7,0,0): an earlier module reports a version that - * satisfies that predicate but enforces the floor on key generation - * only, so it still verifies the 1024-bit signature. */ + /* certs/csr.ext.der has a 1024-bit RSA key; IG C.F requires at least + * 2048 bits for FIPS 186-5 signature verification. */ ExpectIntEQ(X509_REQ_verify(req, pub_key), 0); #else ExpectIntEQ(X509_REQ_verify(req, pub_key), 1); diff --git a/tests/api/api.h b/tests/api/api.h index 34e98cb5793..299a957b54f 100644 --- a/tests/api/api.h +++ b/tests/api/api.h @@ -39,23 +39,8 @@ #include -/* A successful PQ seed-input call reports WC_FIPS_NOT_APPROVED from a module - * whose wrappers normalise the indicator, and a plain 0 from every other build. - * - * WC_HAVE_FIPS_INDICATOR is the CAPABILITY macro fips.h defines for exactly - * that, and gating on it rather than on the version alone is what lets this - * change merge BEFORE the FIPS-side PR: against a bundle without it the module - * returns 0 and so does SEED_OK; against one with it, both are the indicator. - * The test tracks the module actually present instead of assuming one. - * - * FIPS_NO_WRAPPERS (settings.h, for WC_FIPS_LL_CRYPTO and - * WOLFSSL_FIPS_DEV_NO_POST) compiles no wrappers at all, so those expect 0. - * - * --enable-fips=dev is deliberately NOT excluded: it compiles the wrappers, so - * the module really does return the indicator under it and the test follows the - * module. Teaching fips.c about WOLFSSL_FIPS_DEV is not an option: a - * development-only macro must never reach the module source. - */ +/* A successful PQ seed-input call returns WC_FIPS_NOT_APPROVED from v7 module + * wrappers whose fips.h defines WC_HAVE_FIPS_INDICATOR, and 0 otherwise. */ #if defined(HAVE_FIPS) && defined(WC_HAVE_FIPS_INDICATOR) && \ FIPS_VERSION3_GE(7,0,0) && !defined(FIPS_NO_WRAPPERS) #define SEED_OK WC_FIPS_NOT_APPROVED diff --git a/tests/api/test_ed25519.c b/tests/api/test_ed25519.c index 7526c009b31..f9dd98e8e5e 100644 --- a/tests/api/test_ed25519.c +++ b/tests/api/test_ed25519.c @@ -1021,10 +1021,8 @@ int test_wc_ed25519_sign_verify_ctx_ph(void) /* Ed25519ctx round trip: type==Ed25519ctx true side, real context. */ sigLen = sizeof(sig); #ifdef WC_FIPS_ED25519CTX_NOT_APPROVED - /* Ed25519ctx is not an Approved EdDSA instance in the FIPS module - * (FIPS 186-5 sec 7.6/7.8); the sign service must reject it. Gated on the - * module's capability macro (fips.h) rather than FIPS_VERSION3_GE(7,0,0): - * an earlier v7.0.0 module reports the same version but still signs. */ + /* A module whose fips.h defines WC_FIPS_ED25519CTX_NOT_APPROVED rejects + * Ed25519ctx signing with SIG_TYPE_E. */ ExpectIntEQ(wc_ed25519ctx_sign_msg(msg, sizeof(msg), sig, &sigLen, &key, ctx, sizeof(ctx)), WC_NO_ERR_TRACE(SIG_TYPE_E)); #else diff --git a/tests/api/test_mldsa.c b/tests/api/test_mldsa.c index 349af104b2d..e6d3d34a645 100644 --- a/tests/api/test_mldsa.c +++ b/tests/api/test_mldsa.c @@ -31736,12 +31736,8 @@ int test_wc_MlDsaKey_SetPrecompA(void) return EXPECT_RESULT(); } -/* The seed-input service indicator, asserted on a SUCCESSFUL call. - * - * SEED_OK is WC_FIPS_NOT_APPROVED when the module defines - * WC_HAVE_FIPS_INDICATOR and 0 otherwise, so the same assertion states the - * intended behavior for both. - */ +/* ML-DSA keygen from a caller seed succeeds and returns SEED_OK, the service + * indicator for a seed-input call (api.h). */ int test_wc_MlDsaKey_seed_service_indicator(void) { EXPECT_DECLS; diff --git a/tests/api/test_mlkem.c b/tests/api/test_mlkem.c index 067efc9eb1a..b08f387805c 100644 --- a/tests/api/test_mlkem.c +++ b/tests/api/test_mlkem.c @@ -4650,14 +4650,8 @@ int test_wc_mlkem_encode_key_len_decision(void) return EXPECT_RESULT(); } /* END test_wc_mlkem_encode_key_len_decision */ -/* The seed-input service indicator, asserted on a SUCCESSFUL call. - * - * The indicator is unambiguous here: wc_MlKemKey_MakeKeyWithRandom() returns - * 0 or a negative error and never a length or count, so a positive 1 cannot - * be confused for a result the way it could on an API like wc_RsaSSL_Verify() - * that returns a plaintext length. SEED_OK is WC_FIPS_NOT_APPROVED when the - * module defines WC_HAVE_FIPS_INDICATOR and 0 otherwise. - */ +/* ML-KEM keygen from caller randomness succeeds and returns SEED_OK, the + * service indicator for a seed-input call (api.h). */ int test_wc_MlKemKey_seed_service_indicator(void) { EXPECT_DECLS; diff --git a/tests/api/test_slhdsa.c b/tests/api/test_slhdsa.c index 6f1c02916ac..1626be840cc 100644 --- a/tests/api/test_slhdsa.c +++ b/tests/api/test_slhdsa.c @@ -4263,26 +4263,17 @@ int test_slhdsa_cb_free(void) return EXPECT_RESULT(); } -/* The seed-input service indicator, asserted on a SUCCESSFUL call. - * - * See test_wc_MlKemKey_seed_service_indicator() for the rationale. FIPS 205 - * sec 9.1 is the SLH-DSA equivalent: the module shall generate its own keygen - * randomness, so a caller-supplied one is performed but reported - * non-approved. wc_SlhDsaKey_MakeKeyWithRandom() returns 0 or a negative - * error and never a length, so the positive indicator is unambiguous. - */ +/* SLH-DSA keygen from caller seeds succeeds and returns SEED_OK, the service + * indicator for a seed-input call (api.h). */ int test_wc_SlhDsaKey_seed_service_indicator(void) { EXPECT_DECLS; -/* wc_SlhDsaKey_MakeKeyWithRandom() is declared inside - * "#ifndef WOLFSSL_SLHDSA_VERIFY_ONLY" in wc_slhdsa.h, and nothing else - * gates it, so that is the one guard this test needs. */ +/* wc_slhdsa.h declares wc_SlhDsaKey_MakeKeyWithRandom() only under + * #ifndef WOLFSSL_SLHDSA_VERIFY_ONLY. */ #if defined(WOLFSSL_HAVE_SLHDSA) && !defined(WOLFSSL_SLHDSA_VERIFY_ONLY) SlhDsaKey key; - /* n is 16/24/32 for the 128/192/256 parameter sets (FIPS 205 Table 2). - * The public key is PK.seed || PK.root, each n bytes (FIPS 205 sec 9.1), - * so n is half of PublicSize. Derived rather than tabulated so it covers - * every parameter set and cannot drift from the implementation. */ + /* PK is PK.seed || PK.root, n bytes each (FIPS 205 sec 9.1), so n is half + * of PublicSize. */ byte seeds[3][WC_SLHDSA_N_256]; /* n is at most 32 */ int n = 0; From 7807582df7643b536bb06bd0029927dd7eb46dc8 Mon Sep 17 00:00:00 2001 From: kaleb-himes Date: Fri, 11 Sep 2026 16:01:37 -0600 Subject: [PATCH 08/10] tests/api: expect SEED_OK from the PQ seed-input services --- tests/api/test_mldsa.c | 48 +++++++++++++++++++++++++---------------- tests/api/test_mlkem.c | 12 +++++------ tests/api/test_slhdsa.c | 9 ++++---- 3 files changed, 41 insertions(+), 28 deletions(-) diff --git a/tests/api/test_mldsa.c b/tests/api/test_mldsa.c index e6d3d34a645..f40619c0dc8 100644 --- a/tests/api/test_mldsa.c +++ b/tests/api/test_mldsa.c @@ -7737,36 +7737,36 @@ int test_mldsa_make_key_from_seed(void) ExpectIntEQ(wc_MlDsaKey_Init(key, NULL, INVALID_DEVID), 0); #ifndef WOLFSSL_NO_ML_DSA_44 ExpectIntEQ(wc_MlDsaKey_SetParams(key, WC_ML_DSA_44), 0); - ExpectIntEQ(wc_MlDsaKey_MakeKeyFromSeed(key, seed_44), 0); + ExpectIntEQ(wc_MlDsaKey_MakeKeyFromSeed(key, seed_44), SEED_OK); ExpectIntEQ(XMEMCMP(key->p, pk_44, sizeof(pk_44)), 0); ExpectIntEQ(XMEMCMP(key->k, sk_44, sizeof(sk_44)), 0); #ifdef WOLFSSL_MLDSA_FIPS204_DRAFT ExpectIntEQ(wc_MlDsaKey_SetParams(key, WC_ML_DSA_44_DRAFT), 0); - ExpectIntEQ(wc_MlDsaKey_MakeKeyFromSeed(key, seed_44_draft), 0); + ExpectIntEQ(wc_MlDsaKey_MakeKeyFromSeed(key, seed_44_draft), SEED_OK); ExpectIntEQ(XMEMCMP(key->p, pk_44_draft, sizeof(pk_44_draft)), 0); ExpectIntEQ(XMEMCMP(key->k, sk_44_draft, sizeof(sk_44_draft)), 0); #endif #endif #ifndef WOLFSSL_NO_ML_DSA_65 ExpectIntEQ(wc_MlDsaKey_SetParams(key, WC_ML_DSA_65), 0); - ExpectIntEQ(wc_MlDsaKey_MakeKeyFromSeed(key, seed_65), 0); + ExpectIntEQ(wc_MlDsaKey_MakeKeyFromSeed(key, seed_65), SEED_OK); ExpectIntEQ(XMEMCMP(key->p, pk_65, sizeof(pk_65)), 0); ExpectIntEQ(XMEMCMP(key->k, sk_65, sizeof(sk_65)), 0); #ifdef WOLFSSL_MLDSA_FIPS204_DRAFT ExpectIntEQ(wc_MlDsaKey_SetParams(key, WC_ML_DSA_65_DRAFT), 0); - ExpectIntEQ(wc_MlDsaKey_MakeKeyFromSeed(key, seed_65_draft), 0); + ExpectIntEQ(wc_MlDsaKey_MakeKeyFromSeed(key, seed_65_draft), SEED_OK); ExpectIntEQ(XMEMCMP(key->p, pk_65_draft, sizeof(pk_65_draft)), 0); ExpectIntEQ(XMEMCMP(key->k, sk_65_draft, sizeof(sk_65_draft)), 0); #endif #endif #ifndef WOLFSSL_NO_ML_DSA_87 ExpectIntEQ(wc_MlDsaKey_SetParams(key, WC_ML_DSA_87), 0); - ExpectIntEQ(wc_MlDsaKey_MakeKeyFromSeed(key, seed_87), 0); + ExpectIntEQ(wc_MlDsaKey_MakeKeyFromSeed(key, seed_87), SEED_OK); ExpectIntEQ(XMEMCMP(key->p, pk_87, sizeof(pk_87)), 0); ExpectIntEQ(XMEMCMP(key->k, sk_87, sizeof(sk_87)), 0); #ifdef WOLFSSL_MLDSA_FIPS204_DRAFT ExpectIntEQ(wc_MlDsaKey_SetParams(key, WC_ML_DSA_87_DRAFT), 0); - ExpectIntEQ(wc_MlDsaKey_MakeKeyFromSeed(key, seed_87_draft), 0); + ExpectIntEQ(wc_MlDsaKey_MakeKeyFromSeed(key, seed_87_draft), SEED_OK); ExpectIntEQ(XMEMCMP(key->p, pk_87_draft, sizeof(pk_87_draft)), 0); ExpectIntEQ(XMEMCMP(key->k, sk_87_draft, sizeof(sk_87_draft)), 0); #endif @@ -12563,7 +12563,8 @@ int test_mldsa_sig_kats(void) ExpectIntEQ(wc_MlDsaKey_ImportPrivRaw(key, sk_44, (word32)sizeof(sk_44)), 0); sigLen = PARAMS_ML_DSA_44_SIG_SIZE; - ExpectIntEQ(wc_MlDsaKey_SignWithSeed(key, sig, &sigLen, msg_44, (word32)sizeof(msg_44), rnd_44), 0); + ExpectIntEQ(wc_MlDsaKey_SignWithSeed(key, sig, &sigLen, msg_44, (word32)sizeof(msg_44), rnd_44), + SEED_OK); ExpectIntEQ(sigLen, PARAMS_ML_DSA_44_SIG_SIZE); ExpectIntEQ(XMEMCMP(sig, sig_44, sizeof(sig_44)), 0); #endif @@ -12572,7 +12573,8 @@ int test_mldsa_sig_kats(void) ExpectIntEQ(wc_MlDsaKey_ImportPrivRaw(key, sk_65, (word32)sizeof(sk_65)), 0); sigLen = PARAMS_ML_DSA_65_SIG_SIZE; - ExpectIntEQ(wc_MlDsaKey_SignWithSeed(key, sig, &sigLen, msg_65, (word32)sizeof(msg_65), rnd_65), 0); + ExpectIntEQ(wc_MlDsaKey_SignWithSeed(key, sig, &sigLen, msg_65, (word32)sizeof(msg_65), rnd_65), + SEED_OK); ExpectIntEQ(sigLen, PARAMS_ML_DSA_65_SIG_SIZE); ExpectIntEQ(XMEMCMP(sig, sig_65, sizeof(sig_65)), 0); #endif @@ -12581,7 +12583,8 @@ int test_mldsa_sig_kats(void) ExpectIntEQ(wc_MlDsaKey_ImportPrivRaw(key, sk_87, (word32)sizeof(sk_87)), 0); sigLen = PARAMS_ML_DSA_87_SIG_SIZE; - ExpectIntEQ(wc_MlDsaKey_SignWithSeed(key, sig, &sigLen, msg_87, (word32)sizeof(msg_87), rnd_87), 0); + ExpectIntEQ(wc_MlDsaKey_SignWithSeed(key, sig, &sigLen, msg_87, (word32)sizeof(msg_87), rnd_87), + SEED_OK); ExpectIntEQ(sigLen, PARAMS_ML_DSA_87_SIG_SIZE); ExpectIntEQ(XMEMCMP(sig, sig_87, sizeof(sig_87)), 0); #endif @@ -16758,7 +16761,8 @@ int test_mldsa_sign_ctx_kats(void) ExpectIntEQ(wc_MlDsaKey_SetParams(key, WC_ML_DSA_44), 0); ExpectIntEQ(wc_MlDsaKey_ImportPrivRaw(key, sk_44, (word32)sizeof(sk_44)), 0); sigLen = MLDSA_MAX_SIG_SIZE; - ExpectIntEQ(wc_MlDsaKey_SignCtxWithSeed(key, NULL, 0, sig, &sigLen, msg_44, (word32)sizeof(msg_44), rnd_44), 0); + ExpectIntEQ(wc_MlDsaKey_SignCtxWithSeed(key, NULL, 0, sig, &sigLen, msg_44, (word32)sizeof(msg_44), rnd_44), + SEED_OK); ExpectIntEQ(sigLen, (word32)sizeof(sig_44_ctx0)); ExpectIntEQ(XMEMCMP(sig, sig_44_ctx0, sizeof(sig_44_ctx0)), 0); wc_MlDsaKey_Free(key); @@ -16768,7 +16772,8 @@ int test_mldsa_sign_ctx_kats(void) ExpectIntEQ(wc_MlDsaKey_SetParams(key, WC_ML_DSA_44), 0); ExpectIntEQ(wc_MlDsaKey_ImportPrivRaw(key, sk_44, (word32)sizeof(sk_44)), 0); sigLen = MLDSA_MAX_SIG_SIZE; - ExpectIntEQ(wc_MlDsaKey_SignCtxWithSeed(key, ctx_44, (byte)sizeof(ctx_44), sig, &sigLen, msg_44, (word32)sizeof(msg_44), rnd_44), 0); + ExpectIntEQ(wc_MlDsaKey_SignCtxWithSeed(key, ctx_44, (byte)sizeof(ctx_44), sig, &sigLen, msg_44, (word32)sizeof(msg_44), rnd_44), + SEED_OK); ExpectIntEQ(sigLen, (word32)sizeof(sig_44_ctx33)); ExpectIntEQ(XMEMCMP(sig, sig_44_ctx33, sizeof(sig_44_ctx33)), 0); wc_MlDsaKey_Free(key); @@ -16780,7 +16785,8 @@ int test_mldsa_sign_ctx_kats(void) ExpectIntEQ(wc_MlDsaKey_SetParams(key, WC_ML_DSA_65), 0); ExpectIntEQ(wc_MlDsaKey_ImportPrivRaw(key, sk_65, (word32)sizeof(sk_65)), 0); sigLen = MLDSA_MAX_SIG_SIZE; - ExpectIntEQ(wc_MlDsaKey_SignCtxWithSeed(key, NULL, 0, sig, &sigLen, msg_65, (word32)sizeof(msg_65), rnd_65), 0); + ExpectIntEQ(wc_MlDsaKey_SignCtxWithSeed(key, NULL, 0, sig, &sigLen, msg_65, (word32)sizeof(msg_65), rnd_65), + SEED_OK); ExpectIntEQ(sigLen, (word32)sizeof(sig_65_ctx0)); ExpectIntEQ(XMEMCMP(sig, sig_65_ctx0, sizeof(sig_65_ctx0)), 0); wc_MlDsaKey_Free(key); @@ -16790,7 +16796,8 @@ int test_mldsa_sign_ctx_kats(void) ExpectIntEQ(wc_MlDsaKey_SetParams(key, WC_ML_DSA_65), 0); ExpectIntEQ(wc_MlDsaKey_ImportPrivRaw(key, sk_65, (word32)sizeof(sk_65)), 0); sigLen = MLDSA_MAX_SIG_SIZE; - ExpectIntEQ(wc_MlDsaKey_SignCtxWithSeed(key, ctx_65, (byte)sizeof(ctx_65), sig, &sigLen, msg_65, (word32)sizeof(msg_65), rnd_65), 0); + ExpectIntEQ(wc_MlDsaKey_SignCtxWithSeed(key, ctx_65, (byte)sizeof(ctx_65), sig, &sigLen, msg_65, (word32)sizeof(msg_65), rnd_65), + SEED_OK); ExpectIntEQ(sigLen, (word32)sizeof(sig_65_ctx33)); ExpectIntEQ(XMEMCMP(sig, sig_65_ctx33, sizeof(sig_65_ctx33)), 0); wc_MlDsaKey_Free(key); @@ -16802,7 +16809,8 @@ int test_mldsa_sign_ctx_kats(void) ExpectIntEQ(wc_MlDsaKey_SetParams(key, WC_ML_DSA_87), 0); ExpectIntEQ(wc_MlDsaKey_ImportPrivRaw(key, sk_87, (word32)sizeof(sk_87)), 0); sigLen = MLDSA_MAX_SIG_SIZE; - ExpectIntEQ(wc_MlDsaKey_SignCtxWithSeed(key, NULL, 0, sig, &sigLen, msg_87, (word32)sizeof(msg_87), rnd_87), 0); + ExpectIntEQ(wc_MlDsaKey_SignCtxWithSeed(key, NULL, 0, sig, &sigLen, msg_87, (word32)sizeof(msg_87), rnd_87), + SEED_OK); ExpectIntEQ(sigLen, (word32)sizeof(sig_87_ctx0)); ExpectIntEQ(XMEMCMP(sig, sig_87_ctx0, sizeof(sig_87_ctx0)), 0); wc_MlDsaKey_Free(key); @@ -16812,7 +16820,8 @@ int test_mldsa_sign_ctx_kats(void) ExpectIntEQ(wc_MlDsaKey_SetParams(key, WC_ML_DSA_87), 0); ExpectIntEQ(wc_MlDsaKey_ImportPrivRaw(key, sk_87, (word32)sizeof(sk_87)), 0); sigLen = MLDSA_MAX_SIG_SIZE; - ExpectIntEQ(wc_MlDsaKey_SignCtxWithSeed(key, ctx_87, (byte)sizeof(ctx_87), sig, &sigLen, msg_87, (word32)sizeof(msg_87), rnd_87), 0); + ExpectIntEQ(wc_MlDsaKey_SignCtxWithSeed(key, ctx_87, (byte)sizeof(ctx_87), sig, &sigLen, msg_87, (word32)sizeof(msg_87), rnd_87), + SEED_OK); ExpectIntEQ(sigLen, (word32)sizeof(sig_87_ctx33)); ExpectIntEQ(XMEMCMP(sig, sig_87_ctx33, sizeof(sig_87_ctx33)), 0); wc_MlDsaKey_Free(key); @@ -27440,7 +27449,8 @@ int test_mldsa_sign_mu_kats(void) ExpectIntEQ(wc_MlDsaKey_SetParams(key, WC_ML_DSA_44), 0); ExpectIntEQ(wc_MlDsaKey_ImportPrivRaw(key, sk_44_mu, (word32)sizeof(sk_44_mu)), 0); sigLen = MLDSA_MAX_SIG_SIZE; - ExpectIntEQ(wc_MlDsaKey_SignMuWithSeed(key, sig, &sigLen, mu_44, (word32)sizeof(mu_44), zeroSeed), 0); + ExpectIntEQ(wc_MlDsaKey_SignMuWithSeed(key, sig, &sigLen, mu_44, (word32)sizeof(mu_44), zeroSeed), + SEED_OK); ExpectIntEQ(sigLen, (word32)sizeof(sig_44_mu)); ExpectIntEQ(XMEMCMP(sig, sig_44_mu, sizeof(sig_44_mu)), 0); wc_MlDsaKey_Free(key); @@ -27451,7 +27461,8 @@ int test_mldsa_sign_mu_kats(void) ExpectIntEQ(wc_MlDsaKey_SetParams(key, WC_ML_DSA_65), 0); ExpectIntEQ(wc_MlDsaKey_ImportPrivRaw(key, sk_65_mu, (word32)sizeof(sk_65_mu)), 0); sigLen = MLDSA_MAX_SIG_SIZE; - ExpectIntEQ(wc_MlDsaKey_SignMuWithSeed(key, sig, &sigLen, mu_65, (word32)sizeof(mu_65), zeroSeed), 0); + ExpectIntEQ(wc_MlDsaKey_SignMuWithSeed(key, sig, &sigLen, mu_65, (word32)sizeof(mu_65), zeroSeed), + SEED_OK); ExpectIntEQ(sigLen, (word32)sizeof(sig_65_mu)); ExpectIntEQ(XMEMCMP(sig, sig_65_mu, sizeof(sig_65_mu)), 0); wc_MlDsaKey_Free(key); @@ -27462,7 +27473,8 @@ int test_mldsa_sign_mu_kats(void) ExpectIntEQ(wc_MlDsaKey_SetParams(key, WC_ML_DSA_87), 0); ExpectIntEQ(wc_MlDsaKey_ImportPrivRaw(key, sk_87_mu, (word32)sizeof(sk_87_mu)), 0); sigLen = MLDSA_MAX_SIG_SIZE; - ExpectIntEQ(wc_MlDsaKey_SignMuWithSeed(key, sig, &sigLen, mu_87, (word32)sizeof(mu_87), zeroSeed), 0); + ExpectIntEQ(wc_MlDsaKey_SignMuWithSeed(key, sig, &sigLen, mu_87, (word32)sizeof(mu_87), zeroSeed), + SEED_OK); ExpectIntEQ(sigLen, (word32)sizeof(sig_87_mu)); ExpectIntEQ(XMEMCMP(sig, sig_87_mu, sizeof(sig_87_mu)), 0); wc_MlDsaKey_Free(key); diff --git a/tests/api/test_mlkem.c b/tests/api/test_mlkem.c index b08f387805c..8bee6213299 100644 --- a/tests/api/test_mlkem.c +++ b/tests/api/test_mlkem.c @@ -1454,7 +1454,7 @@ int test_wc_mlkem_make_key_kats(void) #ifndef WOLFSSL_NO_ML_KEM_512 ExpectIntEQ(wc_MlKemKey_Init(key, WC_ML_KEM_512, NULL, INVALID_DEVID), 0); ExpectIntEQ(wc_MlKemKey_MakeKeyWithRandom(key, seed_512, sizeof(seed_512)), - 0); + SEED_OK); ExpectIntEQ(wc_MlKemKey_EncodePublicKey(key, pubKey, WC_ML_KEM_512_PUBLIC_KEY_SIZE), 0); ExpectIntEQ(wc_MlKemKey_EncodePrivateKey(key, privKey, @@ -1466,7 +1466,7 @@ int test_wc_mlkem_make_key_kats(void) #ifndef WOLFSSL_NO_ML_KEM_768 ExpectIntEQ(wc_MlKemKey_Init(key, WC_ML_KEM_768, NULL, INVALID_DEVID), 0); ExpectIntEQ(wc_MlKemKey_MakeKeyWithRandom(key, seed_768, sizeof(seed_768)), - 0); + SEED_OK); ExpectIntEQ(wc_MlKemKey_EncodePublicKey(key, pubKey, WC_ML_KEM_768_PUBLIC_KEY_SIZE), 0); ExpectIntEQ(wc_MlKemKey_EncodePrivateKey(key, privKey, @@ -1478,7 +1478,7 @@ int test_wc_mlkem_make_key_kats(void) #ifndef WOLFSSL_NO_ML_KEM_1024 ExpectIntEQ(wc_MlKemKey_Init(key, WC_ML_KEM_1024, NULL, INVALID_DEVID), 0); ExpectIntEQ(wc_MlKemKey_MakeKeyWithRandom(key, seed_1024, - sizeof(seed_1024)), 0); + sizeof(seed_1024)), SEED_OK); ExpectIntEQ(wc_MlKemKey_EncodePublicKey(key, pubKey, WC_ML_KEM_1024_PUBLIC_KEY_SIZE), 0); ExpectIntEQ(wc_MlKemKey_EncodePrivateKey(key, privKey, @@ -2440,7 +2440,7 @@ int test_wc_mlkem_encapsulate_kats(void) ExpectIntEQ(wc_MlKemKey_Init(key, WC_ML_KEM_512, NULL, INVALID_DEVID), 0); ExpectIntEQ(wc_MlKemKey_DecodePublicKey(key, ek_512, sizeof(ek_512)), 0); ExpectIntEQ(wc_MlKemKey_EncapsulateWithRandom(key, ct, ss, seed_512, - sizeof(seed_512)), 0); + sizeof(seed_512)), SEED_OK); ExpectIntEQ(XMEMCMP(ct, c_512, WC_ML_KEM_512_CIPHER_TEXT_SIZE), 0); ExpectIntEQ(XMEMCMP(ss, k_512, WC_ML_KEM_SS_SZ), 0); wc_MlKemKey_Free(key); @@ -2449,7 +2449,7 @@ int test_wc_mlkem_encapsulate_kats(void) ExpectIntEQ(wc_MlKemKey_Init(key, WC_ML_KEM_768, NULL, INVALID_DEVID), 0); ExpectIntEQ(wc_MlKemKey_DecodePublicKey(key, ek_768, sizeof(ek_768)), 0); ExpectIntEQ(wc_MlKemKey_EncapsulateWithRandom(key, ct, ss, seed_768, - sizeof(seed_768)), 0); + sizeof(seed_768)), SEED_OK); ExpectIntEQ(XMEMCMP(ct, c_768, WC_ML_KEM_768_CIPHER_TEXT_SIZE), 0); ExpectIntEQ(XMEMCMP(ss, k_768, WC_ML_KEM_SS_SZ), 0); wc_MlKemKey_Free(key); @@ -2458,7 +2458,7 @@ int test_wc_mlkem_encapsulate_kats(void) ExpectIntEQ(wc_MlKemKey_Init(key, WC_ML_KEM_1024, NULL, INVALID_DEVID), 0); ExpectIntEQ(wc_MlKemKey_DecodePublicKey(key, ek_1024, sizeof(ek_1024)), 0); ExpectIntEQ(wc_MlKemKey_EncapsulateWithRandom(key, ct, ss, seed_1024, - sizeof(seed_1024)), 0); + sizeof(seed_1024)), SEED_OK); ExpectIntEQ(XMEMCMP(ct, c_1024, WC_ML_KEM_1024_CIPHER_TEXT_SIZE), 0); ExpectIntEQ(XMEMCMP(ss, k_1024, WC_ML_KEM_SS_SZ), 0); wc_MlKemKey_Free(key); diff --git a/tests/api/test_slhdsa.c b/tests/api/test_slhdsa.c index 1626be840cc..689eae45400 100644 --- a/tests/api/test_slhdsa.c +++ b/tests/api/test_slhdsa.c @@ -660,7 +660,7 @@ int test_wc_slhdsa_make_key(void) ExpectIntEQ(wc_SlhDsaKey_MakeKeyWithRandom(&key, sk_seed, sizeof(sk_seed), sk_prf, sizeof(sk_prf), pk_seed, sizeof(pk_seed)), - 0); + SEED_OK); wc_SlhDsaKey_Free(&key); } #endif @@ -763,7 +763,7 @@ int test_wc_slhdsa_sign(void) msg, sizeof(msg), sig, &sigLen, NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG)); ExpectIntEQ(wc_SlhDsaKey_SignWithRandom(&key, ctx, sizeof(ctx), - msg, sizeof(msg), sig, &sigLen, addRnd), 0); + msg, sizeof(msg), sig, &sigLen, addRnd), SEED_OK); ExpectIntEQ(sigLen, expSigLen); wc_SlhDsaKey_Free(&key); @@ -1174,7 +1174,8 @@ int test_wc_slhdsa_sign_hash(void) hash, TEST_SLHDSA_PH_SZ, TEST_SLHDSA_PH, sig, &sigLen, NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG)); ExpectIntEQ(wc_SlhDsaKey_SignHashWithRandom(&key, ctx, sizeof(ctx), - hash, TEST_SLHDSA_PH_SZ, TEST_SLHDSA_PH, sig, &sigLen, addRnd), 0); + hash, TEST_SLHDSA_PH_SZ, TEST_SLHDSA_PH, sig, &sigLen, addRnd), + SEED_OK); ExpectIntEQ(wc_SlhDsaKey_VerifyHash(&key, ctx, sizeof(ctx), hash, TEST_SLHDSA_PH_SZ, TEST_SLHDSA_PH, sig, sigLen), 0); } @@ -1302,7 +1303,7 @@ int test_wc_slhdsa_sign_msg(void) * silently rely on the previous call having set it to params->sigLen. */ sigLen = WC_SLHDSA_MAX_SIG_LEN; ExpectIntEQ(wc_SlhDsaKey_SignMsgWithRandom(&key, mprime, sizeof(mprime), - sig, &sigLen, addRnd), 0); + sig, &sigLen, addRnd), SEED_OK); ExpectIntEQ(wc_SlhDsaKey_VerifyMsg(&key, mprime, sizeof(mprime), sig, sigLen), 0); From 42025effbe6c6659598e4bccd745586f863b926e Mon Sep 17 00:00:00 2001 From: kaleb-himes Date: Fri, 11 Sep 2026 16:16:31 -0600 Subject: [PATCH 09/10] tests/api: expect SEED_OK from the newer SLH-DSA seed tests --- tests/api/test_slhdsa.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/tests/api/test_slhdsa.c b/tests/api/test_slhdsa.c index 689eae45400..590eb026188 100644 --- a/tests/api/test_slhdsa.c +++ b/tests/api/test_slhdsa.c @@ -1423,7 +1423,7 @@ int test_wc_slhdsa_sign_addrnd(void) ExpectIntEQ(wc_SlhDsaKey_Init(&key, TEST_SLHDSA_DEFAULT_PARAM, NULL, INVALID_DEVID), 0); ExpectIntEQ(wc_SlhDsaKey_MakeKeyWithRandom(&key, seed, n, seed + n, n, - seed + 2 * n, n), 0); + seed + 2 * n, n), SEED_OK); /* Deterministic: addRnd is PK.seed on both paths, so the two signatures * must be identical. */ @@ -1446,7 +1446,7 @@ int test_wc_slhdsa_sign_addrnd(void) * value is honoured rather than replaced with fresh randomness. */ sigIntLen = WC_SLHDSA_MAX_SIG_LEN; ExpectIntEQ(wc_SlhDsaKey_SignWithRandom(&key, ctx, (byte)sizeof(ctx), msg, - (word32)sizeof(msg) - 1, sigInt, &sigIntLen, addRnd), 0); + (word32)sizeof(msg) - 1, sigInt, &sigIntLen, addRnd), SEED_OK); ExpectIntEQ(sigIntLen, sigExtLen); ExpectIntNE(XMEMCMP(sigInt, sigExt, sigExtLen), 0); ExpectIntEQ(wc_SlhDsaKey_Verify(&key, ctx, (byte)sizeof(ctx), msg, @@ -1455,7 +1455,7 @@ int test_wc_slhdsa_sign_addrnd(void) /* The same explicit addRnd on the internal interface reproduces it. */ sigExtLen = WC_SLHDSA_MAX_SIG_LEN; ExpectIntEQ(wc_SlhDsaKey_SignMsgWithRandom(&key, mprime, idx, sigExt, - &sigExtLen, addRnd), 0); + &sigExtLen, addRnd), SEED_OK); ExpectIntEQ(sigExtLen, sigIntLen); ExpectBufEQ(sigExt, sigInt, sigIntLen); @@ -1559,12 +1559,12 @@ int test_wc_slhdsa_dev_only_key(void) sigLen = TEST_SLHDSA_DEFAULT_SIG_LEN; ExpectIntEQ(wc_SlhDsaKey_SignWithRandom(&key, ctx, (byte)sizeof(ctx), msg, - (word32)sizeof(msg) - 1, sig, &sigLen, addRnd), 0); + (word32)sizeof(msg) - 1, sig, &sigLen, addRnd), SEED_OK); ExpectIntEQ(calls, 2); sigLen = TEST_SLHDSA_DEFAULT_SIG_LEN; ExpectIntEQ(wc_SlhDsaKey_SignMsgWithRandom(&key, msg, - (word32)sizeof(msg) - 1, sig, &sigLen, addRnd), 0); + (word32)sizeof(msg) - 1, sig, &sigLen, addRnd), SEED_OK); ExpectIntEQ(calls, 3); /* MD5 is not an approved SLH-DSA pre-hash, so the host would reject it. @@ -1577,7 +1577,7 @@ int test_wc_slhdsa_dev_only_key(void) sigLen = TEST_SLHDSA_DEFAULT_SIG_LEN; ExpectIntEQ(wc_SlhDsaKey_SignHashWithRandom(&key, ctx, (byte)sizeof(ctx), hash, (word32)sizeof(hash), WC_HASH_TYPE_MD5, sig, &sigLen, addRnd), - 0); + SEED_OK); ExpectIntEQ(calls, 5); ExpectIntEQ(wc_SlhDsaKey_Verify(&key, ctx, (byte)sizeof(ctx), msg, From 9ae639b594cd3adfc912c7962c1a06fc51ccbbbd Mon Sep 17 00:00:00 2001 From: kaleb-himes Date: Tue, 15 Sep 2026 09:08:24 -0600 Subject: [PATCH 10/10] Add the FIPS capability macros to .wolfssl_known_macro_extras --- .wolfssl_known_macro_extras | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.wolfssl_known_macro_extras b/.wolfssl_known_macro_extras index 02f4e52f550..c93125d747f 100644 --- a/.wolfssl_known_macro_extras +++ b/.wolfssl_known_macro_extras @@ -773,11 +773,13 @@ WC_DRBG_BANKREF WC_FIPS_AESGCM_NO_SHORT_NONCES WC_FIPS_AESGCM_ONE_SHOT_EXT_IV_ALLOWED WC_FIPS_ED25519CTX_NOT_APPROVED +WC_FIPS_RSA_VERIFY_MIN_2048 WC_FLAG_DONT_USE_AESNI WC_FORCE_LINUXKM_FORTIFY_SOURCE WC_HASH_CUSTOM_MAX_BLOCK_SIZE WC_HASH_CUSTOM_MAX_DIGEST_SIZE WC_HASH_CUSTOM_MIN_DIGEST_SIZE +WC_HAVE_FIPS_INDICATOR WC_INIT_ERROR_WHEN_CONTENDED WC_LINUXKM_NO_USE_HEAP_WRAPPERS WC_LINUXKM_SVR_NO_BATCHING