Skip to content

Commit a020a00

Browse files
Report FIPS module failures through wolfssl_prov_is_running()
1 parent ecdd878 commit a020a00

7 files changed

Lines changed: 358 additions & 9 deletions

File tree

.github/workflows/fips-ready.yml

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,10 @@ jobs:
6868
6969
- name: Build wolfProvider with FIPS Ready Bundle
7070
run: |
71-
./scripts/build-wolfprovider.sh --fips-bundle="$FIPS_BUNDLE_PATH" \
71+
# WOLFPROV_FORCE_FIPS_FAILURE is an internal, test-only knob (no CLI
72+
# flag) that enables HAVE_FORCE_FIPS_FAILURE for the fips_status test.
73+
WOLFPROV_FORCE_FIPS_FAILURE=1 ./scripts/build-wolfprovider.sh \
74+
--fips-bundle="$FIPS_BUNDLE_PATH" \
7275
--fips-check=ready --wolfssl-ver=v${{matrix.wolfssl_bundle_ref}}-stable
7376
7477
- name: Run FIPS Command Tests
@@ -82,3 +85,14 @@ jobs:
8285
8386
# --- force-fail mode ---
8487
WOLFPROV_FORCE_FAIL=1 ./scripts/cmd_test/do-cmd-tests.sh
88+
89+
- name: Run FIPS Status Test
90+
run: |
91+
# Exercises the FIPS-status gate in wolfssl_prov_is_running():
92+
export WOLFSSL_ISFIPS=1
93+
source scripts/env-setup
94+
set -o pipefail
95+
./test/standalone/tests/fips_status/run.sh 2>&1 | tee fips-status.log
96+
# The forced-failure branch must have actually run in this FIPS build;
97+
# fail if the test silently degraded to the healthy path only.
98+
grep -q "correctly rejected after FIPS failure" fips-status.log

scripts/utils-wolfssl.sh

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,14 @@ install_wolfssl() {
215215
printf "with FIPS ${fips_tag} ... "
216216
fi
217217
CONF_ARGS+=" --enable-fips=$fips_configure_arg"
218+
219+
# Internal test-only knob: expose wolfCrypt_SetStatus_fips for the
220+
# fips_status test. The define reaches the provider and test builds
221+
# automatically via the generated wolfssl options.h.
222+
if [ "${WOLFPROV_FORCE_FIPS_FAILURE:-}" = "1" ]; then
223+
WOLFSSL_FIPS_CONFIG_CFLAGS="${WOLFSSL_FIPS_CONFIG_CFLAGS} -DHAVE_FORCE_FIPS_FAILURE"
224+
fi
225+
218226
WOLFSSL_CONFIG_OPTS=$WOLFSSL_FIPS_CONFIG_OPTS
219227
WOLFSSL_CONFIG_CFLAGS=$WOLFSSL_FIPS_CONFIG_CFLAGS
220228
# Only run fips-check if not using a bundle

src/wp_wolfprov.c

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,10 @@
3636

3737
#include "wolfssl/wolfcrypt/logging.h"
3838

39+
#ifdef HAVE_FIPS
40+
#include <wolfssl/wolfcrypt/fips_test.h>
41+
#endif
42+
3943
const char* wolfprovider_id = "libwolfprov";
4044

4145
/* Core function that gets the table of parameters. */
@@ -72,10 +76,11 @@ static const OSSL_PARAM* wolfprov_gettable_params(void* provCtx)
7276
/*
7377
* Returns whether the provider is running/usable.
7478
*
75-
* In FIPS, if there is an issue with the integrity check, then this can return
76-
* 0 to indicate provider is unusable.
79+
* In FIPS builds the live wolfCrypt FIPS status is queried; a non-zero status
80+
* (integrity/POST or continuous-test failure) returns 0 so a status-polling
81+
* caller can observe the failure.
7782
*
78-
* @return 1 indicating provider is running.
83+
* @return 1 indicating provider is running, 0 otherwise.
7984
*/
8085
int wolfssl_prov_is_running(void)
8186
{
@@ -87,7 +92,12 @@ int wolfssl_prov_is_running(void)
8792
return 0;
8893
}
8994
#endif
90-
/* Always running. */
95+
#ifdef HAVE_FIPS
96+
if (wolfCrypt_GetStatus_fips() != 0) {
97+
WOLFPROV_LEAVE(WP_LOG_COMP_PROVIDER, __FILE__ ":" WOLFPROV_STRINGIZE(__LINE__), 0);
98+
return 0;
99+
}
100+
#endif
91101
WOLFPROV_LEAVE(WP_LOG_COMP_PROVIDER, __FILE__ ":" WOLFPROV_STRINGIZE(__LINE__), 1);
92102
return 1;
93103
}
@@ -1348,8 +1358,6 @@ static const OSSL_DISPATCH wolfprov_dispatch_table[] = {
13481358
};
13491359

13501360
#ifdef HAVE_FIPS
1351-
#include <wolfssl/wolfcrypt/fips_test.h>
1352-
13531361
static void wp_fipsCb(int ok, int err, const char* hash)
13541362
{
13551363
(void)ok;

test/standalone/include.am

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,8 @@ noinst_HEADERS += test/standalone/test_common.h \
1717
# Standalone test programs
1818
# Each test compiles to its own binary for isolated execution
1919
# Note: These are NOT in check_PROGRAMS because they must be run through scripts, not directly
20-
noinst_PROGRAMS += test/sha256_simple.test test/hardload.test test/fips_baseline.test test/pqc_interop.test
21-
DISTCLEANFILES += test/.libs/sha256_simple.test test/.libs/hardload.test test/.libs/fips_baseline.test test/.libs/pqc_interop.test
20+
noinst_PROGRAMS += test/sha256_simple.test test/hardload.test test/fips_baseline.test test/pqc_interop.test test/fips_status.test
21+
DISTCLEANFILES += test/.libs/sha256_simple.test test/.libs/hardload.test test/.libs/fips_baseline.test test/.libs/pqc_interop.test test/.libs/fips_status.test
2222

2323
# Common flags for all standalone tests
2424
STANDALONE_COMMON_CPPFLAGS = -DCERTS_DIR='"$(abs_top_srcdir)/certs"' \
@@ -60,6 +60,13 @@ test_pqc_interop_test_CPPFLAGS = $(STANDALONE_COMMON_CPPFLAGS)
6060
test_pqc_interop_test_SOURCES = test/standalone/tests/pqc_interop/test_pqc_interop.c
6161
test_pqc_interop_test_LDADD = $(STANDALONE_COMMON_LDADD)
6262

63+
test_fips_status_test_CPPFLAGS = $(STANDALONE_COMMON_CPPFLAGS)
64+
test_fips_status_test_SOURCES = test/standalone/tests/fips_status/test_fips_status.c
65+
test_fips_status_test_LDADD = $(STANDALONE_COMMON_LDADD)
66+
# Export the executable's dynamic symbols so libwolfprov resolves
67+
# wolfCrypt_GetStatus_fips to this binary on the interposition path.
68+
test_fips_status_test_LDFLAGS = -export-dynamic
69+
6370
# Common test utilities are built automatically by automake
6471

6572
# Standalone tests are available for manual execution but not part of make check

test/standalone/runners/run_standalone_tests.sh

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,19 @@ else
3838
fi
3939
set -e
4040

41+
# Run FIPS status test
42+
echo ""
43+
echo "Running FIPS status test..."
44+
set +e
45+
"$ROOT_DIR/test/standalone/tests/fips_status/run.sh"
46+
if [ $? -eq 0 ]; then
47+
echo "FIPS status test: PASSED"
48+
else
49+
echo "FIPS status test: FAILED"
50+
TOTAL_FAILURES=$((TOTAL_FAILURES + 1))
51+
fi
52+
set -e
53+
4154
echo ""
4255
echo "================================"
4356
if [ $TOTAL_FAILURES -eq 0 ]; then
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
#!/bin/bash
2+
# FIPS provider status test runner
3+
4+
set -e
5+
6+
# Get the directory of this script and find the root
7+
TEST_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
8+
ROOT_DIR="$(cd "$TEST_DIR/../../../.." && pwd)"
9+
10+
# Binary should be in the test/.libs/ directory
11+
BINARY="fips_status.test"
12+
BINARY_PATH="$ROOT_DIR/test/.libs/$BINARY"
13+
14+
# Make sure we can find the binary
15+
if [ ! -f "$BINARY_PATH" ]; then
16+
echo "Error: Cannot find binary $BINARY_PATH"
17+
echo "Make sure you've built the test with: make test/fips_status.test"
18+
exit 1
19+
fi
20+
21+
# Source env-setup
22+
if ! source "$ROOT_DIR/scripts/env-setup" >/dev/null; then
23+
echo "Error: env-setup failed"
24+
exit 1
25+
fi
26+
27+
# Source common test utilities
28+
source "$ROOT_DIR/test/standalone/test_common.sh"
29+
30+
# Check if this is a replace-default build
31+
WP_USING_REPLACE_DEFAULT="0"
32+
if detect_replace_default_build; then
33+
WP_USING_REPLACE_DEFAULT="1"
34+
unset OPENSSL_CONF
35+
fi
36+
37+
echo "Using environment:"
38+
echo "LD_LIBRARY_PATH: $LD_LIBRARY_PATH"
39+
echo "OPENSSL_CONF: $OPENSSL_CONF"
40+
echo "OPENSSL_BIN: $OPENSSL_BIN"
41+
42+
echo "Running FIPS status test: $BINARY_PATH"
43+
echo ""
44+
45+
# The healthy-path assertion runs on every build. The forced-failure path runs
46+
# in FIPS builds via wolfCrypt_SetStatus_fips (HAVE_FORCE_FIPS_FAILURE) or, on
47+
# Linux, symbol interposition; the binary self-reports which path it took.
48+
if "$BINARY_PATH"; then
49+
echo "FIPS status test: PASSED"
50+
exit 0
51+
else
52+
echo "FIPS status test: FAILED"
53+
exit 1
54+
fi

0 commit comments

Comments
 (0)