diff --git a/configure.ac b/configure.ac index 218b1659b2..24775bd1b3 100644 --- a/configure.ac +++ b/configure.ac @@ -397,8 +397,8 @@ AS_CASE([$ENABLED_WOLFENGINE], # v2 - FIPS 140-2 Cert 3389 # cert3389 - alias for v2 # rand - wolfRand -# v5-RC12 - FIPS 140-3, wolfCrypt/fips WCv5.0-RC12 -# v5 - currently, alias for v5-RC12 +# v5 - FIPS 140-3 Cert 4718 +# cert4718 - alias for v5 # ready - FIPS 140-3 settings with in-tree wolfcrypt sources, feature locked # dev - FIPS 140-3 settings with in-tree wolfcrypt sources, features freely adjustable # v5-ready - Alias for ready. @@ -414,6 +414,7 @@ AS_CASE([$ENABLED_WOLFENGINE], # HAVE_FIPS_VERSION = 5, HAVE_FIPS_VERSION_MINOR = 2. # v5-RC11 - historical FIPS 140-3, wolfCrypt/fips WCv5.0-RC11 # HAVE_FIPS_VERSION = 5, HAVE_FIPS_VERSION_MINOR = 2. +# v5-RC12 - historical FIPS 140-3, wolfCrypt/fips WCv5.0-RC12 AS_CASE([$ENABLED_FIPS], [no],[ FIPS_VERSION="none" @@ -445,10 +446,20 @@ AS_CASE([$ENABLED_FIPS], DEF_SP_MATH="no" DEF_FAST_MATH="no" ], - [v5|v5-RC12],[ + [v5|cert4718],[ + FIPS_VERSION="v5" + HAVE_FIPS_VERSION_MAJOR=5 + HAVE_FIPS_VERSION_MINOR=2 + HAVE_FIPS_VERSION_PATCH=1 + ENABLED_FIPS="yes" + DEF_SP_MATH="no" + DEF_FAST_MATH="yes" + ], + [v5-RC12],[ FIPS_VERSION="v5-RC12" HAVE_FIPS_VERSION_MAJOR=5 HAVE_FIPS_VERSION_MINOR=2 + HAVE_FIPS_VERSION_PATCH=0 ENABLED_FIPS="yes" DEF_SP_MATH="no" DEF_FAST_MATH="yes" @@ -689,6 +700,17 @@ fi # MATH LIBRARY SELECTION +# Assure consistency of defaults +if test "$DEF_FAST_MATH" = "yes" && ( (test "$enable_sp_math" != "no" && test "$enable_sp_math" != "") || test "$enable_heapmath" = "yes") +then + DEF_FAST_MATH=no +fi + +if test "$DEF_SP_MATH" = "yes" && (test "$enable_fastmath" = "yes" || test "$enable_fasthugemath" = "yes" || test "$enable_heapmath" = "yes") +then + DEF_SP_MATH=no +fi + # Single Precision maths implementation AC_ARG_ENABLE([sp], [AS_HELP_STRING([--enable-sp],[Enable Single Precision maths implementation (default: disabled)])], @@ -936,7 +958,7 @@ then AM_CFLAGS="$AM_CFLAGS -DHAVE_CRL_IO -DHAVE_IO_TIMEOUT" fi - if test "$ENABLED_SP_MATH" = "no" + if test "$ENABLED_SP_MATH" != "yes" then # linuxkm is incompatible with opensslextra and its dependents. if test "$ENABLED_LINUXKM_DEFAULTS" != "yes" @@ -987,7 +1009,7 @@ then test "$enable_webserver" = "" && enable_webserver=yes - if test "$ENABLED_SP_MATH" = "no" + if test "$ENABLED_SP_MATH" != "yes" then if test "$ENABLED_FIPS" = "no" then @@ -1183,7 +1205,7 @@ then fi # sp-math is incompatible with opensslextra, ECC custom curves, and DSA. - if test "$ENABLED_SP_MATH" = "no" + if test "$ENABLED_SP_MATH" != "yes" then test "$enable_dsa" = "" && test "$enable_sha" != "no" && enable_dsa=yes if test "$ENABLED_FIPS" = "no" || test "$HAVE_FIPS_VERSION" -le 5; then @@ -9848,7 +9870,7 @@ if test "x$ENABLED_LINUXKM" = "xyes"; then if test "$ENABLED_SMALL_STACK" != "yes"; then AC_MSG_ERROR([--enable-smallstack is required for --enable-linuxkm.]) fi - if test "$ENABLED_SP_MATH" = "no" && test "$ENABLED_SP_MATH_ALL" = "no" && test "$ENABLED_BIGNUM" != "no"; then + if test "$ENABLED_SP_MATH" != "yes" && test "$ENABLED_SP_MATH_ALL" = "no" && test "$ENABLED_BIGNUM" != "no"; then AC_MSG_ERROR([--enable-sp-math or --enable-sp-math-all is required for --enable-linuxkm.]) fi if test "$ENABLED_STACKSIZE" != "no"; then @@ -10320,7 +10342,7 @@ if test "$ENABLED_SP_MATH_ALL" != "no" then ENABLED_SP_MATH_DESC="all" else - if test "$ENABLED_SP_MATH" != "no" + if test "$ENABLED_SP_MATH" = "yes" then ENABLED_SP_MATH_DESC="restricted" else diff --git a/fips-check.sh b/fips-check.sh index 5ee63a7045..7d0e588998 100755 --- a/fips-check.sh +++ b/fips-check.sh @@ -18,7 +18,9 @@ FLAVOR="${FLAVOR:-linux}" KEEP="${KEEP:-no}" MAKECHECK=${MAKECHECK:-yes} DOCONFIGURE=${DOCONFIGURE:-yes} +DOAUTOGEN=${DOAUTOGEN:-yes} FIPS_REPO="${FIPS_REPO:-git@github.com:wolfssl/fips.git}" +WOLFSSL_REPO="${WOLFSSL_REPO:-origin}" Usage() { cat </dev/null +declare -A FIPS_TAGS_NEEDED WOLFCRYPT_TAGS_NEEDED +for file_entry in "${WOLFCRYPT_FILES[@]}"; do + WOLFCRYPT_TAGS_NEEDED["${file_entry#*:}"]=1 +done +for file_entry in "${FIPS_FILES[@]}"; do + FIPS_TAGS_NEEDED["${file_entry#*:}"]=1 +done + +echo "wolfCrypt tag$( [[ ${#WOLFCRYPT_TAGS_NEEDED[@]} != "1" ]] && echo -n 's'):" +for tag in "${!WOLFCRYPT_TAGS_NEEDED[@]}"; do + if $GIT describe --exact-match --long "$tag" 2>/dev/null; then + continue + fi + if ! $GIT fetch --depth 1 "$WOLFSSL_REPO" tag "$tag"; then + echo "Can't fetch wolfCrypt tag: $tag" + exit 1 + fi +done if ! $GIT clone . "$TEST_DIR"; then echo "fips-check: Couldn't duplicate current working directory." exit 1 fi -pushd "$TEST_DIR" || exit 2 +pushd "$TEST_DIR" 1>/dev/null || exit 2 if ! $GIT clone "$FIPS_REPO" fips; then echo "fips-check: Couldn't check out FIPS repository." exit 1 fi +pushd fips 1>/dev/null || exit 2 + +echo "FIPS tag$( [[ ${#FIPS_TAGS_NEEDED[@]} != "1" ]] && echo -n 's'):" +for tag in "${!FIPS_TAGS_NEEDED[@]}"; do + if $GIT describe "$tag" 2>/dev/null; then + continue + fi + if ! $GIT fetch --depth 1 "$FIPS_REPO" tag "$tag"; then + echo "Can't fetch FIPS tag: $tag" + exit 1 + fi +done + +popd 1>/dev/null || exit 2 + checkout_files "${WOLFCRYPT_FILES[@]}" || exit 3 -pushd fips || exit 2 +pushd fips 1>/dev/null || exit 2 copy_fips_files "${FIPS_FILES[@]}" || exit 3 -popd || exit 2 +popd 1>/dev/null || exit 2 # When checking out cert 3389 ready code, NIST will no longer perform # new certifications on 140-2 modules. If we were to use the latest files from @@ -461,7 +498,9 @@ if [ "$FLAVOR" = 'fipsv2-OE-ready' ] && [ -s wolfcrypt/src/fips.c ]; then fi # run the make test -./autogen.sh +if [ "$DOAUTOGEN" = "yes" ]; then + ./autogen.sh +fi if [ "$DOCONFIGURE" = "yes" ]; then case "$FIPS_OPTION" in @@ -499,7 +538,7 @@ if [ "$DOCONFIGURE" = "yes" ]; then fi # Clean up -popd || exit 2 +popd 1>/dev/null || exit 2 if [ "$KEEP" = 'no' ]; then rm -rf "$TEST_DIR" fi diff --git a/src/internal.c b/src/internal.c index 10e5867b6b..f8d014b30d 100644 --- a/src/internal.c +++ b/src/internal.c @@ -29851,11 +29851,9 @@ static int HashSkeData(WOLFSSL* ssl, enum wc_HashType hashType, ssl->buffers.digest.length = (unsigned int)digest_sz; /* buffer for hash */ - if (!ssl->buffers.digest.buffer) { - if (!ssl->options.dontFreeDigest) { - XFREE(ssl->buffers.digest.buffer, ssl->heap, - DYNAMIC_TYPE_DIGEST); - } + if (!ssl->options.dontFreeDigest) { + XFREE(ssl->buffers.digest.buffer, ssl->heap, + DYNAMIC_TYPE_DIGEST); } ssl->options.dontFreeDigest = 0; diff --git a/src/ssl_crypto.c b/src/ssl_crypto.c index 6907822a64..f2ff78193e 100644 --- a/src/ssl_crypto.c +++ b/src/ssl_crypto.c @@ -3041,7 +3041,7 @@ void wolfSSL_AES_decrypt(const unsigned char* input, unsigned char* output, } else #if !defined(HAVE_SELFTEST) && \ - (!defined(HAVE_FIPS) || (defined(FIPS_VERSION_GE) && FIPS_VERSION3_GE(5,2,1))) + (!defined(HAVE_FIPS) || (defined(FIPS_VERSION_GE) && FIPS_VERSION3_GE(5,3,0))) /* Decrypt a block with wolfCrypt AES. */ if (wc_AesDecryptDirect((Aes*)key, output, input) != 0) { WOLFSSL_MSG("wc_AesDecryptDirect failed"); diff --git a/wolfssl/wolfcrypt/cryptocb.h b/wolfssl/wolfcrypt/cryptocb.h index 93330f3596..a52742f49a 100644 --- a/wolfssl/wolfcrypt/cryptocb.h +++ b/wolfssl/wolfcrypt/cryptocb.h @@ -104,12 +104,12 @@ enum wc_CryptoCbCmdType { /* Crypto Information Structure for callbacks */ typedef struct wc_CryptoInfo { int algo_type; /* enum wc_AlgoType */ -#if HAVE_ANONYMOUS_INLINE_AGGREGATES +#ifdef HAVE_ANONYMOUS_INLINE_AGGREGATES union { #endif struct { int type; /* enum wc_PkType */ -#if HAVE_ANONYMOUS_INLINE_AGGREGATES +#ifdef HAVE_ANONYMOUS_INLINE_AGGREGATES union { #endif #ifndef NO_RSA @@ -279,7 +279,7 @@ typedef struct wc_CryptoInfo { int type; /* enum wc_PqcSignatureType */ } pqc_sig_check; #endif -#if HAVE_ANONYMOUS_INLINE_AGGREGATES +#ifdef HAVE_ANONYMOUS_INLINE_AGGREGATES }; #endif } pk; @@ -287,7 +287,7 @@ typedef struct wc_CryptoInfo { struct { int type; /* enum wc_CipherType */ int enc; -#if HAVE_ANONYMOUS_INLINE_AGGREGATES +#ifdef HAVE_ANONYMOUS_INLINE_AGGREGATES union { #endif #ifdef HAVE_AESGCM @@ -375,7 +375,7 @@ typedef struct wc_CryptoInfo { } des3; #endif void* ctx; -#if HAVE_ANONYMOUS_INLINE_AGGREGATES +#ifdef HAVE_ANONYMOUS_INLINE_AGGREGATES }; #endif } cipher; @@ -387,7 +387,7 @@ typedef struct wc_CryptoInfo { const byte* in; word32 inSz; byte* digest; -#if HAVE_ANONYMOUS_INLINE_AGGREGATES +#ifdef HAVE_ANONYMOUS_INLINE_AGGREGATES union { #endif #ifndef NO_SHA @@ -409,7 +409,7 @@ typedef struct wc_CryptoInfo { wc_Sha3* sha3; #endif void* ctx; -#if HAVE_ANONYMOUS_INLINE_AGGREGATES +#ifdef HAVE_ANONYMOUS_INLINE_AGGREGATES }; #endif } hash; @@ -454,7 +454,7 @@ typedef struct wc_CryptoInfo { void *ctx; } cmd; #endif -#if HAVE_ANONYMOUS_INLINE_AGGREGATES +#ifdef HAVE_ANONYMOUS_INLINE_AGGREGATES }; #endif } wc_CryptoInfo; diff --git a/wolfssl/wolfcrypt/hash.h b/wolfssl/wolfcrypt/hash.h index edbc949bcb..ee001a98b2 100644 --- a/wolfssl/wolfcrypt/hash.h +++ b/wolfssl/wolfcrypt/hash.h @@ -119,6 +119,7 @@ typedef union { #ifdef WOLFSSL_SM3 wc_Sm3 sm3; #endif + WOLF_AGG_DUMMY_MEMBER; } wc_Hashes; #ifndef NO_HASH_WRAPPER diff --git a/wolfssl/wolfcrypt/types.h b/wolfssl/wolfcrypt/types.h index d2a9dc44fb..5fb14b88a3 100644 --- a/wolfssl/wolfcrypt/types.h +++ b/wolfssl/wolfcrypt/types.h @@ -123,16 +123,67 @@ decouple library dependencies with standard string, memory and so on. #ifndef HAVE_ANONYMOUS_INLINE_AGGREGATES /* if a version is available, pivot on the version, otherwise guess it's - * allowed, subject to override. + * disallowed, subject to override. */ #if !defined(WOLF_C89) && (!defined(__STDC__) \ || (!defined(__STDC_VERSION__) && !defined(__cplusplus)) \ || (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201101L)) \ || (defined(__cplusplus) && (__cplusplus >= 201103L))) #define HAVE_ANONYMOUS_INLINE_AGGREGATES 1 - #else - #define HAVE_ANONYMOUS_INLINE_AGGREGATES 0 #endif + #elif ~(~HAVE_ANONYMOUS_INLINE_AGGREGATES + 1) == 1 + /* forced on with empty value -- remap to 1 */ + #undef HAVE_ANONYMOUS_INLINE_AGGREGATES + #define HAVE_ANONYMOUS_INLINE_AGGREGATES 1 + #elif HAVE_ANONYMOUS_INLINE_AGGREGATES + /* forced on with explicit nonzero value -- leave as-is. */ + #else + /* forced off with explicit zero value -- remap to undef. */ + #undef HAVE_ANONYMOUS_INLINE_AGGREGATES + #endif + + #ifndef HAVE_EMPTY_AGGREGATES + /* The C standards don't define empty aggregates, but gcc and clang do. + * We need to accommodate them for one of the same reasons C++ does -- + * conditionally empty aggregates, e.g. in hash.h. + */ + #if !defined(WOLF_C89) && defined(__GNUC__) && \ + !defined(__STRICT_ANSI__) && \ + defined(HAVE_ANONYMOUS_INLINE_AGGREGATES) + #define HAVE_EMPTY_AGGREGATES 1 + #endif + #elif ~(~HAVE_EMPTY_AGGREGATES + 1) == 1 + /* forced on with empty value -- remap to 1 */ + #undef HAVE_EMPTY_AGGREGATES + #define HAVE_EMPTY_AGGREGATES 1 + #elif HAVE_EMPTY_AGGREGATES + /* forced on with explicit nonzero value -- leave as-is. */ + #else + /* forced off with explicit zero value -- remap to undef. */ + #undef HAVE_EMPTY_AGGREGATES + #endif + + #define _WOLF_AGG_DUMMY_MEMBER_HELPER2(a, b, c) a ## b ## c + #define _WOLF_AGG_DUMMY_MEMBER_HELPER(a, b, c) _WOLF_AGG_DUMMY_MEMBER_HELPER2(a, b, c) + #ifdef HAVE_EMPTY_AGGREGATES + /* swallow the semicolon with a zero-sized array (language extension + * specific to gcc/clang). + */ + #define WOLF_AGG_DUMMY_MEMBER \ + struct { \ + PRAGMA_GCC_DIAG_PUSH \ + PRAGMA_GCC("GCC diagnostic ignored \"-Wpedantic\"") \ + PRAGMA_CLANG_DIAG_PUSH \ + PRAGMA_CLANG("clang diagnostic ignored \"-Wzero-length-array\"") \ + byte _WOLF_AGG_DUMMY_MEMBER_HELPER(_wolf_L, __LINE__, _agg_dummy_member)[0]; \ + PRAGMA_CLANG_DIAG_POP \ + PRAGMA_GCC_DIAG_POP \ + } + #else + /* Use a single byte with a constructed name as a dummy member -- these + * are the standard semantics of an empty structure in C++. + */ + #define WOLF_AGG_DUMMY_MEMBER char _WOLF_AGG_DUMMY_MEMBER_HELPER(_wolf_L, __LINE__, _agg_dummy_member) #endif /* helpers for stringifying the expanded value of a macro argument rather @@ -147,7 +198,6 @@ decouple library dependencies with standard string, memory and so on. * without disrupting clean flow/syntax when some enum values are * preprocessor-gated. */ - #define WC_VALUE_OF(x) x #if defined(WOLF_C89) || defined(WOLF_NO_TRAILING_ENUM_COMMAS) #define _WOLF_ENUM_DUMMY_LAST_ELEMENT_HELPER2(a, b, c, d, e) a ## b ## c ## d ## e #define _WOLF_ENUM_DUMMY_LAST_ELEMENT_HELPER(a, b, c, d, e) _WOLF_ENUM_DUMMY_LAST_ELEMENT_HELPER2(a, b, c, d, e)