diff --git a/crypto/fipsmodule/bcm.c b/crypto/fipsmodule/bcm.c index 119e2cad6d..577a9b5751 100644 --- a/crypto/fipsmodule/bcm.c +++ b/crypto/fipsmodule/bcm.c @@ -270,13 +270,6 @@ static void BORINGSSL_bcm_power_on_self_test(void) __attribute__ ((constructor)) #endif static void BORINGSSL_bcm_power_on_self_test(void) { -#if defined(AWSLC_FIPS_FAILURE_CALLBACK) - if (AWS_LC_fips_failure_callback == NULL) { - fprintf(stderr, "AWS_LC_fips_failure_callback not defined but AWS-LC built with AWSLC_FIPS_FAILURE_CALLBACK\n"); - fflush(stderr); - abort(); - } -#endif // TODO: remove !defined(OPENSSL_PPC64BE) from the check below when starting to support // PPC64BE that has VCRYPTO capability. In that case, add `|| defined(OPENSSL_PPC64BE)` // to `#if defined(OPENSSL_PPC64LE)` wherever it occurs. @@ -408,21 +401,18 @@ int BORINGSSL_integrity_test(void) { void AWS_LC_FIPS_failure(const char* message) { #if defined(AWSLC_FIPS_FAILURE_CALLBACK) - if (AWS_LC_fips_failure_callback == NULL) { - fprintf(stderr, "AWS_LC_fips_failure_callback not defined but AWS-LC built with AWSLC_FIPS_FAILURE_CALLBACK. FIPS failure:\n%s", message); - fflush(stderr); - abort(); - } else { + if (AWS_LC_fips_failure_callback != NULL) { AWS_LC_fips_failure_callback(message); + return; } -#else + // Fallback to the default behavior if the callback is not defined +#endif fprintf(stderr, "AWS-LC FIPS failure caused by:\n%s\n", message); fflush(stderr); for (;;) { abort(); exit(1); } -#endif } #else // BORINGSSL_FIPS void AWS_LC_FIPS_failure(const char* message) { diff --git a/crypto/internal.h b/crypto/internal.h index 2e8cf3785c..080f866c8b 100644 --- a/crypto/internal.h +++ b/crypto/internal.h @@ -1270,8 +1270,16 @@ static inline uint64_t CRYPTO_subc_u64(uint64_t x, uint64_t y, uint64_t borrow, #if defined(BORINGSSL_FIPS) // AWS_LC_FIPS_failure is called when a FIPS power-on or continuous test -// fails. If the library is built in FIPS mode it prevents any further -// cryptographic operations by the current process. +// fails. The behavior depends on how AWS-LC is built: +// - When AWS-LC is not in FIPS mode it prints |message| to |stderr|. +// - If AWS-LC is built with FIPS it prints |message| to |stderr| and prevents +// any further cryptographic operations by the current process. +// - If AWS-LC is built with FIPS, AWSLC_FIPS_FAILURE_CALLBACK, and the +// application does not define the AWS_LC_fips_failure_callback function +// the normal behavior FIPS behavior is used. +// - If AWS-LC is built with FIPS, AWSLC_FIPS_FAILURE_CALLBACK, and the +// application defines the AWS_LC_fips_failure_callback function that +// function is called with |message|. #if defined(AWSLC_FIPS_FAILURE_CALLBACK) void AWS_LC_FIPS_failure(const char* message); #else diff --git a/tests/ci/cdk/cdk/codebuild/github_ci_linux_x86_omnibus.yaml b/tests/ci/cdk/cdk/codebuild/github_ci_linux_x86_omnibus.yaml index 3f4e0cad5d..53fd692ca7 100644 --- a/tests/ci/cdk/cdk/codebuild/github_ci_linux_x86_omnibus.yaml +++ b/tests/ci/cdk/cdk/codebuild/github_ci_linux_x86_omnibus.yaml @@ -627,3 +627,14 @@ batch: image: 620771051181.dkr.ecr.us-west-2.amazonaws.com/aws-lc-docker-images-linux-x86:ubuntu-10.04_gcc-4.1x_latest variables: AWS_LC_CI_TARGET: "tests/ci/run_legacy_build.sh" + + - identifier: amazonlinux2_gcc7x_x86_64_fips_callback + buildspec: ./tests/ci/codebuild/common/run_simple_target.yml + env: + type: LINUX_CONTAINER + privileged-mode: true + compute-type: BUILD_GENERAL1_LARGE + image: 620771051181.dkr.ecr.us-west-2.amazonaws.com/aws-lc-docker-images-linux-x86:amazonlinux-2_gcc-7x_latest + variables: + AWS_LC_CI_TARGET: "tests/ci/run_fips_callback_tests.sh" + diff --git a/tests/ci/run_fips_callback_tests.sh b/tests/ci/run_fips_callback_tests.sh index b788a68c76..58846e1789 100755 --- a/tests/ci/run_fips_callback_tests.sh +++ b/tests/ci/run_fips_callback_tests.sh @@ -4,26 +4,86 @@ set -ex # SPDX-License-Identifier: Apache-2.0 OR ISC source tests/ci/common_posix_setup.sh -original_test="${BUILD_ROOT}/crypto/crypto_test" -broken_test="${BUILD_ROOT}/crypto/crypto_test_broken" - -# By default the test should pass -$original_test --gtest_filter=FIPSCallback.PowerOnSelfTests -$original_test --gtest_filter=FIPSCallback.PWCT - -# Break the tests -KATS=$(go run "${SRC_ROOT}/util/fipstools/break-kat.go" --list-tests) -for kat in $KATS; do - go run "${SRC_ROOT}/util/fipstools/break-kat.go" "$original_test" "$kat" > "$broken_test" - chmod +x "$broken_test" - export FIPS_CALLBACK_TEST_EXPECTED_FAILURE="$kat" - # When a callback is defined AWS-LC will not abort and the test should exit successfully - $broken_test --gtest_filter=FIPSCallback.PowerOnSelfTests - unset FIPS_CALLBACK_TEST_EXPECTED_FAILURE -done - -for TEST in RSA_PWCT ECDSA_PWCT EDDSA_PWCT MLKEM_PWCT MLDSA_PWCT; do - export FIPS_CALLBACK_TEST_EXPECTED_FAILURE="${TEST}" - export BORINGSSL_FIPS_BREAK_TEST="${TEST}" - $original_test --gtest_filter=FIPSCallback.PWCT -done +# This test file is designed to replicate the internal FIPS callback build defined in the build-glue package + +# This should follow AWS-LC-Build-GLue/bin/fips_tests.sh maybe_run_fips_tests +function maybe_run_fips_tests() { + expect_fips_mode=1 + module_status=$("${BUILD_ROOT}/tool/bssl" isfips) + [[ "${expect_fips_mode}" == "${module_status}" ]] || { + echo >&2 "FIPS Mode validation failed." + exit 1 + } + # Mainline AWS-LC does not have the CAVP tests anymore so only run the test_fips branch + "${BUILD_ROOT}/util/fipstools/test_fips" +} + +# This should follow AWS-LC-Build-GLue/bin/fips_tests.sh maybe_run_fips_break_tests +function maybe_run_fips_break_tests() { + break_kat_executable="${BUILD_ROOT}/break-kat" + pushd "${SRC_ROOT}" + go build -o "$break_kat_executable" "./util/fipstools/break-kat.go" + "$break_kat_executable" -list-tests + + working_bssl="${BUILD_ROOT}/tool/bssl" + broken_bssl="${BUILD_ROOT}/tool/brokenbssl" + "$working_bssl" isfips + + # This breaks a local copy of bssl that will not be included in the build artifacts + "$break_kat_executable" "$working_bssl" DRBG >"$broken_bssl" + chmod +x "$broken_bssl" + if ! ("$broken_bssl" isfips 2>&1 >/dev/null || true) | + grep -q "DRBG"; then + echo "Broken bssl did not mention DRBG failure in startup" + exit 1 + fi + popd +} + +function run_all_break_tests() { + original_test="${BUILD_ROOT}/crypto/crypto_test" + broken_test="${BUILD_ROOT}/crypto/crypto_test_broken" + + # By default the test should pass + $original_test --gtest_filter=FIPSCallback.PowerOnSelfTests + $original_test --gtest_filter=FIPSCallback.PWCT + + # Break the tests + KATS=$(go run "${SRC_ROOT}/util/fipstools/break-kat.go" --list-tests) + for kat in $KATS; do + go run "${SRC_ROOT}/util/fipstools/break-kat.go" "$original_test" "$kat" > "$broken_test" + chmod +x "$broken_test" + export FIPS_CALLBACK_TEST_EXPECTED_FAILURE="$kat" + # When a callback is defined AWS-LC will not abort and the test should exit successfully + $broken_test --gtest_filter=FIPSCallback.PowerOnSelfTests + unset FIPS_CALLBACK_TEST_EXPECTED_FAILURE + done + + for TEST in RSA_PWCT ECDSA_PWCT EDDSA_PWCT MLKEM_PWCT MLDSA_PWCT; do + export FIPS_CALLBACK_TEST_EXPECTED_FAILURE="${TEST}" + export BORINGSSL_FIPS_BREAK_TEST="${TEST}" + $original_test --gtest_filter=FIPSCallback.PWCT + unset FIPS_CALLBACK_TEST_EXPECTED_FAILURE + unset BORINGSSL_FIPS_BREAK_TEST + done + +} + +echo "Testing AWS-LC static breakable build with custom callback and Jitter enabled" +build_and_test -DFIPS=1 \ + -DCMAKE_C_FLAGS="-DBORINGSSL_FIPS_BREAK_TESTS -DAWSLC_FIPS_FAILURE_CALLBACK" \ + -DCMAKE_CXX_FLAGS="-DAWSLC_FIPS_FAILURE_CALLBACK" \ + -DENABLE_FIPS_ENTROPY_CPU_JITTER=1 + +maybe_run_fips_tests +maybe_run_fips_break_tests +run_all_break_tests + +echo "Testing AWS-LC static build with custom callback and Jitter enabled" +build_and_test -DFIPS=1 \ + -DCMAKE_C_FLAGS="-DAWSLC_FIPS_FAILURE_CALLBACK" \ + -DCMAKE_CXX_FLAGS="-DAWSLC_FIPS_FAILURE_CALLBACK" \ + -DENABLE_FIPS_ENTROPY_CPU_JITTER=1 + +maybe_run_fips_tests +# Can't run maybe_run_fips_break_tests or run_all_break_tests since they require BORINGSSL_FIPS_BREAK_TESTS diff --git a/tests/ci/run_fips_tests.sh b/tests/ci/run_fips_tests.sh index f27b3e0a2e..a76bda8d08 100755 --- a/tests/ci/run_fips_tests.sh +++ b/tests/ci/run_fips_tests.sh @@ -32,13 +32,6 @@ if static_linux_supported || static_openbsd_supported; then echo "Testing AWS-LC static library in FIPS Release mode." fips_build_and_test -DCMAKE_BUILD_TYPE=Release - echo "Testing AWS-LC static breakable build with custom callback enabled" - run_build -DFIPS=1 \ - -DCMAKE_C_FLAGS="-DBORINGSSL_FIPS_BREAK_TESTS -DAWSLC_FIPS_FAILURE_CALLBACK" \ - -DCMAKE_CXX_FLAGS="-DAWSLC_FIPS_FAILURE_CALLBACK" - shard_gtest ./test_build_dir/crypto/crypto_test - ./tests/ci/run_fips_callback_tests.sh - echo "Testing AWS-LC static breakable release build" run_build -DFIPS=1 -DCMAKE_C_FLAGS="-DBORINGSSL_FIPS_BREAK_TESTS" ./util/fipstools/test-break-kat.sh diff --git a/tool/tool.cc b/tool/tool.cc index 41c2847526..36e5a9a99e 100644 --- a/tool/tool.cc +++ b/tool/tool.cc @@ -30,16 +30,6 @@ #include "internal.h" -#if defined(AWSLC_FIPS_FAILURE_CALLBACK) -extern "C" { - void AWS_LC_fips_failure_callback(const char* message); -} - -void AWS_LC_fips_failure_callback(const char* message) { - fprintf(stderr, "FIPS failure:\n%s", message); -} -#endif - static bool version(const std::vector &args) { printf("%s\n", AWSLC_VERSION_NUMBER_STRING); return true;