fixes and improvements from AI review:

.github/workflows/fips-dev-no-post.yml: add reporting of fuzzing seed.

wolfcrypt/src/aes.c, tests/api/test_aes.c, .wolfssl_known_macro_extras:

* change FIPS AES-GCM nonce size restrictions from from opt-out (WC_FIPS_AESGCM_ALLOW_SHORT_NONCES) to opt-in (WC_FIPS_AESGCM_NO_SHORT_NONCES).
* apply restrictions only on encryption operations, never on decryption.

configure.ac: fix HAVE_FIPS_VERSION of fips-ready; fix enable_dh setup in KERNEL_MODE_DEFAULTS setup; fix help message for --enable-dh.

linuxkm/x86_vector_register_glue.c: add dump_stack() on each BUG/WARNING message that didn't already have it.

src/tls.c: fix a couple leaks in TLSX_KeyShare_GenDhKey().

tests/swdev/swdev.c: gate src->sha_method access in swdev_sha256_copy_state() and swdev_sha512_copy_state() appropriately.

tests/unit.c: conditionally include dh.h, to assure wc_dh_enable() is available.

wolfcrypt/src/dh.c:
* in wc_InitDhKey_ex(), zero the key at entry unless null, remove duplicate key->trustedGroup = 0, and call wc_FreeDhKey() on error at end.
* add missing wc_dh_enabled checks in  wc_DhGeneratePublic() and wc_DhGenerateParams().

wolfcrypt/src/error.c: fix missing space in FIPS_UNAPPROVED_E string.

b/wolfssl/wolfcrypt/settings.h: sense __SIZEOF_INT128__ and if defined, but HAVE___INT128_T and/or HAVE___UINT128_T are undefined, define them.

wolfcrypt/src/falcon.c: tweak the gate on __uint128_t availability to lean solely on HAVE___UINT128_T.

wolfcrypt/src/random.c: fix a couple missed WC_NO_ERR_TRACE() wrappers.

wolfcrypt/src/rng_bank.c: properly tolerate WC_ACCEL_INHIBIT_E as a retval from bank->affinity_lock_cb().

wolfcrypt/src/sha256.c, wolfcrypt/src/sha512.c: move #undef WC_C_DYNAMIC_FALLBACK for WOLFSSL_AESNI without USE_INTEL_SPEEDUP to follow all includes, assuring no struct layout conflict.

wolfcrypt/src/sha512.c: fix wrong call in intelasm Transform_Sha512() !WC_C_DYNAMIC_FALLBACK SHA512_C path.

wolfcrypt/test/test.c: fix double-WC_TEST_RET_ENC_EC() in mldsa_param_*_vfy_test().
pull/11031/head
Daniel Pouzzner 2026-08-04 18:27:36 -05:00
parent ec04819695
commit 83b175ce95
18 changed files with 190 additions and 110 deletions

View File

@ -86,12 +86,16 @@ jobs:
# the pool builds with a bare "make" (no way to add variables to that
# command line); make picks them up from the environment, and they are
# inert for the non-linuxkm configs. Note the heredoc is unquoted so
# $(uname -r) expands -- there is no other $ or backtick in the JSON.
# $(uname -r) and $FUZZING_SEED expand -- there are no other $ or
# backticks in the JSON.
- name: Build all configs (parallel, out-of-tree)
env:
KERNEL_EXTRA_CFLAGS_REMOVE: -pg
FORCE_NO_MODULE_SIG: 1
run: |
FUZZING_SEED=$(( (RANDOM << 15) ^ RANDOM ))
echo "FUZZING_SEED=$FUZZING_SEED"
if [ -n "$GITHUB_STEP_SUMMARY" ]; then echo "FUZZING_SEED=$FUZZING_SEED" >> "$GITHUB_STEP_SUMMARY"; fi
cat > "$RUNNER_TEMP/fips-dev-no-post-configs.json" <<EOF
{"base": {"configure": ["--enable-fips=dev-no-post",
"--with-linux-source=/lib/modules/$(uname -r)/build",
@ -113,7 +117,7 @@ jobs:
{"name": "kernel-settings-all-asm", "minutes": 6,
"configure": ["--enable-kernel-settings", "--enable-all",
"--enable-all-asm", "--enable-sp",
"CPPFLAGS=-pedantic -DWC_C_DYNAMIC_FALLBACK -DDEBUG_VECTOR_REGISTER_ACCESS -DDEBUG_VECTOR_REGISTER_ACCESS_FUZZING -DWC_DEBUG_VECTOR_REGISTERS_FUZZING_SEED=$$"]}
"CPPFLAGS=-pedantic -DWC_C_DYNAMIC_FALLBACK -DDEBUG_VECTOR_REGISTER_ACCESS -DDEBUG_VECTOR_REGISTER_ACCESS_FUZZING -DWC_DEBUG_VECTOR_REGISTERS_FUZZING_SEED=$FUZZING_SEED"]}
]}
EOF
# out-of-tree kernel module builds not working yet:

View File

@ -749,7 +749,7 @@ WC_BLINDING_NO_RNG_ACKNOWLEDGE_WEAKNESS
WC_CACHE_RESISTANT_BASE64_TABLE
WC_DISABLE_RADIX_ZERO_PAD
WC_DRBG_BANKREF
WC_FIPS_AESGCM_ALLOW_SHORT_NONCES
WC_FIPS_AESGCM_NO_SHORT_NONCES
WC_FIPS_AESGCM_ONE_SHOT_EXT_IV_ALLOWED
WC_FLAG_DONT_USE_AESNI
WC_FORCE_LINUXKM_FORTIFY_SOURCE

View File

@ -660,6 +660,7 @@ AS_CASE([$ENABLED_FIPS],
HAVE_FIPS_VERSION_MINOR=3
HAVE_FIPS_VERSION_PATCH=0
ENABLED_FIPS="yes"
ENABLED_FIPS_DEV=yes
# for dev, DEF_SP_MATH_ALL and DEF_FAST_MATH follow non-FIPS defaults (currently sp-math-all)
],
[v6],[
@ -694,7 +695,7 @@ AS_CASE([$ENABLED_FIPS],
],
[ready|v7-ready],[
FIPS_VERSION="ready"
HAVE_FIPS_VERSION=8
HAVE_FIPS_VERSION=$FIPS_DEVREADY_MAJOR
HAVE_FIPS_VERSION_MAJOR=$FIPS_DEVREADY_MAJOR
HAVE_FIPS_VERSION_MINOR=$FIPS_DEVREADY_MINOR
HAVE_FIPS_VERSION_PATCH=$FIPS_DEVREADY_PATCH
@ -1877,18 +1878,22 @@ then
# "conditional" value leaves it disabled (unusable) after registration.
if test "$HAVE_FIPS_VERSION" -ge 7 && test "$enable_dh" = "" && test "$enable_linuxkm_lkcapi_register" != ""
then
lkcapi_dh=no
for lkcapi_alg in $(echo "$enable_linuxkm_lkcapi_register" | tr ',' ' ')
do
case "$lkcapi_alg" in
all | all-kconfig | dh) enable_dh=conditional ;;
all | all-kconfig | dh) lkcapi_dh=yes ;;
esac
done
for lkcapi_alg in $(echo "$enable_linuxkm_lkcapi_register" | tr ',' ' ')
do
case "$lkcapi_alg" in
-dh) enable_dh="" ;;
-dh) lkcapi_dh=no ;;
esac
done
if test "$lkcapi_dh" = yes; then
enable_dh=conditional
fi
fi
# Enable WOLFSSL_DH_EXTRA and DH const table speedups (eliminates `-lm` math lib dependency)
@ -6395,7 +6400,7 @@ else
# DH is outside the boundary in FIPS v7+, but if it's enabled directly or
# via --enable-all-crypto, then callers and the test suite will expect it to
# work.
if test "$enable_dh" = "yes"
if test "$enable_dh" != "no" && test "$enable_dh" != "conditional" && test "$enable_dh" != ""
then
AM_CFLAGS="$AM_CFLAGS -DWC_DH_INITIAL_RUNTIME_ENABLEMENT=1"
fi
@ -6409,7 +6414,7 @@ fi
# DH
AC_ARG_ENABLE([dh],
[AS_HELP_STRING([--enable-dh],[Enable DH (default: ${ENABLED_DH_DEFAULT}). Set to "nonblock" to enable non-blocking DH key agreement via SP small mod_exp_nb])],
[AS_HELP_STRING([--enable-dh],[Enable DH (default: on). Set to "nonblock" to enable non-blocking DH key agreement via SP small mod_exp_nb])],
[ ENABLED_DH=$enableval ],
[ ENABLED_DH=$ENABLED_DH_DEFAULT ]
)

View File

@ -136,6 +136,9 @@ static struct wc_thread_fpu_count_ent *wc_linuxkm_fpu_state_assoc_unlikely(int c
if (_warned_on_null == 0) {
pr_err("BUG: wc_linuxkm_fpu_state_assoc called by PID %d"
" before allocate_wolfcrypt_linuxkm_fpu_states.\n", my_pid);
#ifdef WOLFSSL_LINUXKM_VERBOSE_DEBUG
dump_stack();
#endif
_warned_on_null = 1;
}
return NULL;
@ -152,6 +155,9 @@ static struct wc_thread_fpu_count_ent *wc_linuxkm_fpu_state_assoc_unlikely(int c
pr_err("BUG: wc_linuxkm_fpu_state_assoc called with create_p=1 by"
" PID %d on CPU %d with CPU slot already reserved by"
" said PID.\n", my_pid, my_cpu);
#ifdef WOLFSSL_LINUXKM_VERBOSE_DEBUG
dump_stack();
#endif
++_warned_on_redundant_create_p;
}
}
@ -186,6 +192,9 @@ static struct wc_thread_fpu_count_ent *wc_linuxkm_fpu_state_assoc_unlikely(int c
pr_warn("WARNING: wc_linuxkm_fpu_state_assoc called by pid %d on CPU %d"
" but CPU slot already reserved by pid %d.\n",
my_pid, my_cpu, slot_pid);
#ifdef WOLFSSL_LINUXKM_VERBOSE_DEBUG
dump_stack();
#endif
++_warned_on_mismatched_pid;
}
}
@ -343,8 +352,12 @@ WARN_UNUSED_RESULT int wc_save_vector_registers_x86(enum wc_svr_flags flags)
* a second look at preempt_count().
*/
if (((preempt_count() & (NMI_MASK | HARDIRQ_MASK)) != 0) || (task_pid_nr(current) == 0)) {
if (! (flags & WC_SVR_FLAG_INHIBIT))
if (! (flags & WC_SVR_FLAG_INHIBIT)) {
VRG_PR_WARN_X("WARNING: wc_save_vector_registers_x86(0x%x) called with preempt_count 0x%x and pid %d on CPU %d.\n", (unsigned)flags, preempt_count(), task_pid_nr(current), raw_smp_processor_id());
#ifdef WOLFSSL_LINUXKM_VERBOSE_DEBUG
dump_stack();
#endif
}
return WC_ACCEL_INHIBIT_E;
}
@ -526,22 +539,33 @@ void wc_restore_vector_registers_x86(enum wc_svr_flags flags)
VRG_PR_WARN_X("BUG: wc_restore_vector_registers_x86() called by pid %d on CPU %d "
"with no saved state.\n", task_pid_nr(current),
raw_smp_processor_id());
#ifdef WOLFSSL_LINUXKM_VERBOSE_DEBUG
dump_stack();
#endif
return;
}
if ((--pstate->fpu_state & WC_FPU_COUNT_MASK) > 0U) {
if (flags & WC_SVR_FLAG_MAYBE_INHIBIT)
if (flags & WC_SVR_FLAG_MAYBE_INHIBIT) {
VRG_PR_WARN_X("BUG: wc_restore_vector_registers_x86() called by pid %d on CPU %d "
"with _MAYBE_INHIBIT flag at non-outermost depth %u.\n", task_pid_nr(current),
raw_smp_processor_id(),
(pstate->fpu_state & WC_FPU_COUNT_MASK) + 1U);
#ifdef WOLFSSL_LINUXKM_VERBOSE_DEBUG
dump_stack();
#endif
}
if (flags & WC_SVR_FLAG_INHIBIT) {
if (pstate->fpu_state & WC_FPU_INHIBITED_FLAG)
pstate->fpu_state &= ~WC_FPU_INHIBITED_FLAG;
else
else {
VRG_PR_WARN_X("BUG: wc_restore_vector_registers_x86() called by pid %d on CPU %d "
"with _INHIBIT flag but saved state isn't _INHIBITED_.\n", task_pid_nr(current),
raw_smp_processor_id());
#ifdef WOLFSSL_LINUXKM_VERBOSE_DEBUG
dump_stack();
#endif
}
}
return;
}
@ -554,10 +578,14 @@ void wc_restore_vector_registers_x86(enum wc_svr_flags flags)
#endif
local_bh_enable();
} else if (unlikely(pstate->fpu_state & WC_FPU_INHIBITED_FLAG)) {
if (unlikely(! (flags & (WC_SVR_FLAG_INHIBIT | WC_SVR_FLAG_MAYBE_INHIBIT))))
if (unlikely(! (flags & (WC_SVR_FLAG_INHIBIT | WC_SVR_FLAG_MAYBE_INHIBIT)))) {
VRG_PR_WARN_X("BUG: wc_restore_vector_registers_x86() called by pid %d on CPU %d "
"without _INHIBIT flag but saved state is _INHIBITED_.\n", task_pid_nr(current),
raw_smp_processor_id());
#ifdef WOLFSSL_LINUXKM_VERBOSE_DEBUG
dump_stack();
#endif
}
pstate->fpu_state = 0U;
wc_linuxkm_fpu_state_release(pstate);
local_bh_enable();

View File

@ -8217,6 +8217,13 @@ static int TLSX_KeyShare_GenDhKey(WOLFSSL *ssl, KeyShareEntry* kse)
/* Setup Key */
ret = wc_InitDhKey_ex((DhKey*)kse->key, ssl->heap, ssl->devId);
#if !defined(HAVE_FIPS) || FIPS_VERSION3_GE(7,0,0)
if (ret != 0) {
XFREE(kse->key, ssl->heap, DYNAMIC_TYPE_DH);
kse->key = NULL;
return ret;
}
#endif
if (ret == 0) {
dhKey = (DhKey*)kse->key;
#ifdef HAVE_PUBLIC_FFDHE
@ -9556,6 +9563,13 @@ static int TLSX_KeyShare_ProcessDh(WOLFSSL* ssl, KeyShareEntry* keyShareEntry)
/* Setup Key */
ret = wc_InitDhKey_ex((DhKey*)keyShareEntry->key, ssl->heap, ssl->devId);
#if !defined(HAVE_FIPS) || FIPS_VERSION3_GE(7,0,0)
if (ret != 0) {
XFREE(keyShareEntry->key, ssl->heap, DYNAMIC_TYPE_DH);
keyShareEntry->key = NULL;
return ret;
}
#endif
if (ret == 0) {
dhKey = (DhKey*)keyShareEntry->key;
/* Set key */

View File

@ -8391,16 +8391,13 @@ int test_wc_AesGcmDecisionCoverage(void)
/* Zero-length IV branch: should reject. */
ExpectIntEQ(wc_AesGcmSetExtIV(&aes, iv, 0),
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
#if FIPS_VERSION3_GE(7,0,0) && \
!defined(WC_FIPS_AESGCM_ALLOW_SHORT_NONCES)
ExpectIntEQ(wc_AesGcmSetExtIV(&aes, iv, GCM_NONCE_MIN_SZ),
WC_NO_ERR_TRACE(FIPS_BAD_VALUE_E));
#elif (FIPS_VERSION3_EQ(5,2,4) || FIPS_VERSION3_GE(7,0,0)) && \
#if (FIPS_VERSION3_EQ(5,2,4) || FIPS_VERSION3_GE(7,0,0)) && \
!defined(FIPS_NO_WRAPPERS)
ExpectIntEQ(wc_AesGcmSetExtIV(&aes, iv, GCM_NONCE_MIN_SZ),
WC_FIPS_NOT_APPROVED);
#else
ExpectIntEQ(wc_AesGcmSetExtIV(&aes, iv, GCM_NONCE_MIN_SZ), 0);
/* GCM_NONCE_MIN_SZ is missing from FIPS v2. */
ExpectIntEQ(wc_AesGcmSetExtIV(&aes, iv, 8 /* GCM_NONCE_MIN_SZ */), 0);
#endif
#endif /* !WC_NO_RNG && !HAVE_SELFTEST */
@ -9255,11 +9252,7 @@ int test_wc_AesGcmArgMcdc(void)
* self-contained demonstration). */
ExpectIntEQ(wc_AesGcmSetIV(&aes, 10, NULL, 0, &rng),
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
#if FIPS_VERSION3_GE(7,0,0) && \
!defined(WC_FIPS_AESGCM_ALLOW_SHORT_NONCES)
ExpectIntEQ(wc_AesGcmSetIV(&aes, GCM_NONCE_MIN_SZ, NULL, 0, &rng),
WC_NO_ERR_TRACE(FIPS_BAD_VALUE_E));
#elif (FIPS_VERSION3_EQ(5,2,4) || FIPS_VERSION3_GE(7,0,0)) && \
#if (FIPS_VERSION3_EQ(5,2,4) || FIPS_VERSION3_GE(7,0,0)) && \
!defined(FIPS_NO_WRAPPERS)
ExpectIntEQ(wc_AesGcmSetIV(&aes, GCM_NONCE_MIN_SZ, NULL, 0, &rng),
WC_FIPS_NOT_APPROVED);

View File

@ -366,7 +366,7 @@ static void swdev_sha256_copy_state(wc_Sha256* dst, const wc_Sha256* src)
dst->buffLen = src->buffLen;
dst->loLen = src->loLen;
dst->hiLen = src->hiLen;
#ifdef WC_C_DYNAMIC_FALLBACK
#if defined(WC_C_DYNAMIC_FALLBACK) && defined(HAVE_FIPS) && FIPS_VERSION_LT(7,0,0)
dst->sha_method = src->sha_method;
#endif
#ifdef WOLFSSL_HASH_FLAGS
@ -462,7 +462,7 @@ static void swdev_sha512_copy_state(wc_Sha512* dst, const wc_Sha512* src)
dst->buffLen = src->buffLen;
dst->loLen = src->loLen;
dst->hiLen = src->hiLen;
#ifdef WC_C_DYNAMIC_FALLBACK
#if defined(WC_C_DYNAMIC_FALLBACK) && defined(HAVE_FIPS) && FIPS_VERSION_LT(7,0,0)
dst->sha_method = src->sha_method;
#endif
#ifdef WOLFSSL_HASH_FLAGS

View File

@ -28,6 +28,9 @@
#ifdef HAVE_ECC
#include <wolfssl/wolfcrypt/ecc.h>
#endif
#ifndef NO_DH
#include <wolfssl/wolfcrypt/dh.h>
#endif
#include <stdio.h>
#include <wolfssl/wolfcrypt/fips_test.h>

View File

@ -11206,7 +11206,7 @@ int wc_AesGcmEncrypt(Aes* aes, byte* out, const byte* in, word32 sz,
if (ret != 0)
return ret;
#if defined(HAVE_FIPS) && !defined(WC_FIPS_AESGCM_ALLOW_SHORT_NONCES)
#if defined(HAVE_FIPS) && defined(WC_FIPS_AESGCM_NO_SHORT_NONCES)
if (ivSz < GCM_NONCE_MID_SZ)
return FIPS_BAD_VALUE_E;
#endif
@ -14256,8 +14256,8 @@ static WARN_UNUSED_RESULT int AesGcmDecryptFinal_RISCV64(
* is NULL, or the IV is NULL and no previous IV has been set.
* @return MEMORY_E when dynamic memory allocation fails. (WOLFSSL_SMALL_STACK)
*/
static int wc_AesGcmInit_local(Aes* aes, const byte* key, word32 len, const byte* iv,
word32 ivSz, int decrypt_p)
int wc_AesGcmInit(Aes* aes, const byte* key, word32 len, const byte* iv,
word32 ivSz)
{
int ret = 0;
@ -14268,20 +14268,6 @@ static int wc_AesGcmInit_local(Aes* aes, const byte* key, word32 len, const byte
ret = BAD_FUNC_ARG;
}
#if defined(HAVE_FIPS) && !defined(WC_FIPS_AESGCM_ALLOW_SHORT_NONCES)
/* Note iv is an optional arg to wc_AesGcmInit(), so we tolerate zero ivSz
* here.
*
* Additionally, there is no FIPS check on ivSz in decrypt mode -- SP
* 800-38D IV construction requirements bind encryption only; decryption
* must accept externally generated IVs of any supported length.
*/
if ((ret == 0) && (! decrypt_p) && (ivSz > 0) && (ivSz < GCM_NONCE_MID_SZ))
ret = FIPS_BAD_VALUE_E;
#else
(void)decrypt_p;
#endif
#if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_AESNI)
if ((ret == 0) && (aes->streamData == NULL)) {
/* Allocate buffers for streaming. */
@ -14324,16 +14310,26 @@ static int wc_AesGcmInit_local(Aes* aes, const byte* key, word32 len, const byte
#endif
if (ret == 0) {
/* Set the IV passed in if it is smaller than a block. */
if ((iv != NULL) && (ivSz <= WC_AES_BLOCK_SIZE)) {
XMEMMOVE((byte*)aes->reg, iv, ivSz);
aes->nonceSz = ivSz;
if (iv != NULL) {
if (ivSz <= WC_AES_BLOCK_SIZE) {
/* Set the IV passed in if it is smaller than a block. */
XMEMMOVE((byte*)aes->reg, iv, ivSz);
aes->nonceSz = ivSz;
}
else {
/* FIPS short-nonce detection depends on aes->nonceSz == 0
* signifying that supplied ivSz > WC_AES_BLOCK_SIZE.
*/
aes->nonceSz = 0;
}
}
/* No IV passed in, check for cached IV. */
if ((iv == NULL) && (aes->nonceSz != 0)) {
/* Use the cached copy. */
iv = (byte*)aes->reg;
ivSz = aes->nonceSz;
else {
/* No IV passed in, check for cached IV. */
if (aes->nonceSz != 0) {
/* Use the cached copy. */
iv = (byte*)aes->reg;
ivSz = aes->nonceSz;
}
}
if (iv != NULL) {
@ -14378,12 +14374,6 @@ static int wc_AesGcmInit_local(Aes* aes, const byte* key, word32 len, const byte
return ret;
}
int wc_AesGcmInit(Aes* aes, const byte* key, word32 len, const byte* iv,
word32 ivSz)
{
return wc_AesGcmInit_local(aes, key, len, iv, ivSz, 0 /* decrypt_p */);
}
/* Initialize an AES GCM cipher for encryption.
*
* Must call wc_AesInit() before calling this function.
@ -14400,7 +14390,15 @@ int wc_AesGcmInit(Aes* aes, const byte* key, word32 len, const byte* iv,
int wc_AesGcmEncryptInit(Aes* aes, const byte* key, word32 len, const byte* iv,
word32 ivSz)
{
return wc_AesGcmInit_local(aes, key, len, iv, ivSz, 0);
#if defined(HAVE_FIPS) && defined(WC_FIPS_AESGCM_NO_SHORT_NONCES)
/* Note iv is an optional arg to wc_AesGcmEncryptInit(), so we tolerate zero ivSz
* here.
*/
if ((ivSz > 0) && (ivSz < GCM_NONCE_MID_SZ))
return FIPS_BAD_VALUE_E;
#endif
return wc_AesGcmInit(aes, key, len, iv, ivSz);
}
/* Initialize an AES GCM cipher for encryption. Get IV.
@ -14430,11 +14428,16 @@ int wc_AesGcmEncryptInit_ex(Aes* aes, const byte* key, word32 len, byte* ivOut,
if ((aes == NULL) || (ivOut == NULL) || (ivOutSz != aes->nonceSz)) {
ret = BAD_FUNC_ARG;
}
#if defined(HAVE_FIPS) && defined(WC_FIPS_AESGCM_NO_SHORT_NONCES)
else if (ivOutSz < GCM_NONCE_MID_SZ) {
ret = FIPS_BAD_VALUE_E;
}
#endif
else {
/* Copy out the IV including generated part for decryption. */
XMEMCPY(ivOut, aes->reg, ivOutSz);
/* Initialize AES GCM cipher with key and cached Iv. */
ret = wc_AesGcmInit_local(aes, key, len, NULL, 0, 0);
ret = wc_AesGcmInit(aes, key, len, NULL, 0);
}
return ret;
@ -14461,6 +14464,11 @@ int wc_AesGcmEncryptUpdate(Aes* aes, byte* out, const byte* in, word32 sz,
ret = MISSING_IV;
}
#if defined(HAVE_FIPS) && defined(WC_FIPS_AESGCM_NO_SHORT_NONCES)
if ((ret == 0) && (aes->nonceSz != 0) && (aes->nonceSz < GCM_NONCE_MID_SZ))
ret = FIPS_BAD_VALUE_E;
#endif
/* Prevent overflow of aes->cSz and ->aSz. Per NIST SP 800-38D section
* 5.2.1.1, the maximum allowed ciphertext limit is 2^32 - 2 blocks, but we
* currently pass around the cumulative sizes in bytes as word32s, so we
@ -14548,6 +14556,11 @@ int wc_AesGcmEncryptFinal(Aes* aes, byte* authTag, word32 authTagSz)
ret = MISSING_IV;
}
#if defined(HAVE_FIPS) && defined(WC_FIPS_AESGCM_NO_SHORT_NONCES)
if ((ret == 0) && (aes->nonceSz != 0) && (aes->nonceSz < GCM_NONCE_MID_SZ))
ret = FIPS_BAD_VALUE_E;
#endif
if (ret == 0) {
/* Calculate authentication tag. */
#ifdef WOLFSSL_AESNI
@ -14599,7 +14612,12 @@ int wc_AesGcmEncryptFinal(Aes* aes, byte* authTag, word32 authTagSz)
int wc_AesGcmDecryptInit(Aes* aes, const byte* key, word32 len, const byte* iv,
word32 ivSz)
{
return wc_AesGcmInit_local(aes, key, len, iv, ivSz, 1);
/*
* There is no FIPS check on ivSz in decrypt mode -- SP
* 800-38D IV construction requirements bind encryption only; decryption
* must accept externally generated IVs of any supported length.
*/
return wc_AesGcmInit(aes, key, len, iv, ivSz);
}
/* Update the AES GCM for decryption with data and/or authentication data. */
@ -14757,11 +14775,6 @@ int wc_AesGcmSetExtIV(Aes* aes, const byte* iv, word32 ivSz)
ret = BAD_FUNC_ARG;
}
#if defined(HAVE_FIPS) && !defined(WC_FIPS_AESGCM_ALLOW_SHORT_NONCES)
if (ret == 0 && ivSz < GCM_NONCE_MID_SZ)
ret = FIPS_BAD_VALUE_E;
#endif
if (ret == 0) {
XMEMCPY((byte*)aes->reg, iv, ivSz);
@ -14793,11 +14806,6 @@ int wc_AesGcmSetIV(Aes* aes, word32 ivSz,
ret = BAD_FUNC_ARG;
}
#if defined(HAVE_FIPS) && !defined(WC_FIPS_AESGCM_ALLOW_SHORT_NONCES)
if (ret == 0 && ivSz < GCM_NONCE_MID_SZ)
ret = FIPS_BAD_VALUE_E;
#endif
if (ret == 0) {
byte* iv = (byte*)aes->reg;
@ -14837,6 +14845,11 @@ int wc_AesGcmEncrypt_ex(Aes* aes, byte* out, const byte* in, word32 sz,
ret = BAD_FUNC_ARG;
}
#if defined(HAVE_FIPS) && defined(WC_FIPS_AESGCM_NO_SHORT_NONCES)
if ((ret == 0) && (ivOutSz < GCM_NONCE_MID_SZ))
ret = FIPS_BAD_VALUE_E;
#endif
if (ret == 0) {
aes->invokeCtr[0]++;
if (aes->invokeCtr[0] == 0) {

View File

@ -58,6 +58,12 @@
#endif
#ifdef WC_DH_INITIAL_RUNTIME_ENABLEMENT
/* Note that the wc_dh_enabled runtime feature-switching facility is neither
* thread-synchronized nor thread-local, and is only allowed during global
* initialization or self-test sequences before application service begins.
*/
static volatile int wc_dh_enabled = WC_DH_INITIAL_RUNTIME_ENABLEMENT;
int wc_dh_enable(void) {
if (wc_dh_enabled)
@ -963,6 +969,8 @@ int wc_InitDhKey_ex(DhKey* key, void* heap, int devId)
if (key == NULL)
return BAD_FUNC_ARG;
XMEMSET(key, 0, sizeof(*key));
key->heap = heap; /* for XMALLOC/XFREE in future */
key->trustedGroup = 0;
@ -986,8 +994,6 @@ int wc_InitDhKey_ex(DhKey* key, void* heap, int devId)
(void)devId;
#endif
key->trustedGroup = 0;
#ifdef WOLFSSL_KCAPI_DH
key->handle = NULL;
#endif
@ -996,6 +1002,10 @@ int wc_InitDhKey_ex(DhKey* key, void* heap, int devId)
key->nb = NULL;
#endif
/* On failure, release MPI allocations, if any. */
if (ret != 0)
(void)wc_FreeDhKey(key);
return ret;
}
@ -1464,6 +1474,11 @@ int wc_DhGeneratePublic(DhKey* key, byte* priv, word32 privSz,
return BAD_FUNC_ARG;
}
#ifdef WC_DH_INITIAL_RUNTIME_ENABLEMENT
if (! wc_dh_enabled)
return FIPS_NOT_ALLOWED_E;
#endif
ret = GeneratePublicDh(key, priv, privSz, pub, pubSz);
#if FIPS_VERSION_GE(5,0) || defined(WOLFSSL_VALIDATE_DH_KEYGEN)
@ -3191,6 +3206,11 @@ int wc_DhGenerateParams(WC_RNG *rng, int modSz, DhKey *dh)
if (rng == NULL || dh == NULL)
ret = BAD_FUNC_ARG;
#ifdef WC_DH_INITIAL_RUNTIME_ENABLEMENT
if (! wc_dh_enabled)
return FIPS_NOT_ALLOWED_E;
#endif
/* set group size in bytes from modulus size
* FIPS 186-4 defines valid values (1024, 160) (2048, 256) (3072, 256)
*/

View File

@ -745,7 +745,7 @@ const char* wc_GetErrorString(int error)
return "Supplied value was rejected by FIPS policy";
case FIPS_UNAPPROVED_E:
return "Requested operation succeeded, but supplied"
return "Requested operation succeeded, but supplied "
"parameters are unapproved for FIPS";
case MAX_CODE_E:

View File

@ -1149,8 +1149,7 @@ int fpr_lt(fpr x, fpr y)
* targets it is a single multiply instruction; the portable 32x32 fallback
* (one MUL becomes four) is kept for platforms without a 128-bit integer type
* (e.g. Cortex-M). Both paths are constant-time and bit-identical. */
#if defined(HAVE___UINT128_T) && !defined(NO_INT128) && \
defined(__SIZEOF_INT128__)
#if defined(HAVE___UINT128_T) && !defined(NO_INT128)
#define FALCON_MULHI(z, y) \
((word64)(((__uint128_t)(word64)(z) * (__uint128_t)(word64)(y)) >> 64))
#else
@ -8311,7 +8310,7 @@ int falcon_native_sign_msg(const byte* in, word32 inLen, byte* out, word32* outL
* early-exit path is covered by the check. */
#ifdef WOLFSSL_CHECK_MEM_ZERO
XMEMSET(spc, 0, sizeof(*spc));
wc_MemZero_Add("falcon sign spc", spc, sizeof(spc));
wc_MemZero_Add("falcon sign spc", spc, sizeof(*spc));
#endif
/* One allocation backs every sign buffer (the working set is >100KB at

View File

@ -813,7 +813,7 @@ static int Hash_gen(DRBG_internal* drbg, byte* out, word32 outSz, const byte* V)
#endif
#ifdef WC_VERBOSE_RNG
if ((ret != DRBG_SUCCESS) && (ret != DRBG_FAILURE)) {
if ((ret != DRBG_SUCCESS) && (ret != WC_NO_ERR_TRACE(DRBG_FAILURE))) {
/* Note, if we're just going to return DRBG_FAILURE to the caller, then
* there's no point printing it out here because (1) the lower-level
* code that was remapped to DRBG_FAILURE already got printed before the
@ -1011,7 +1011,7 @@ static int Hash_DRBG_Generate(DRBG_internal* drbg, byte* out, word32 outSz,
}
#ifdef WC_VERBOSE_RNG
if ((ret != DRBG_SUCCESS) && (ret != DRBG_FAILURE)) {
if ((ret != DRBG_SUCCESS) && (ret != WC_NO_ERR_TRACE(DRBG_FAILURE))) {
/* see note above regarding log spam reduction */
WOLFSSL_DEBUG_PRINTF("ERROR: Hash_DRBG_Generate failed with err %d.",
ret);

View File

@ -545,7 +545,8 @@ WOLFSSL_API int wc_rng_bank_checkout(
ret = bank->affinity_lock_cb(bank->cb_arg);
if (ret == 0)
new_lock_value |= WC_RNG_BANK_INST_LOCK_AFFINITY_LOCKED;
else if (ret == WC_NO_ERR_TRACE(ALREADY_E))
else if ((ret == WC_NO_ERR_TRACE(ALREADY_E)) ||
(ret == WC_NO_ERR_TRACE(WC_ACCEL_INHIBIT_E)))
ret = 0;
else
break;

View File

@ -43,15 +43,6 @@ on the specific device platform.
#include <wolfssl/wolfcrypt/libwolfssl_sources.h>
#if defined(WC_C_DYNAMIC_FALLBACK) && \
defined(WOLFSSL_AESNI) && !defined(USE_INTEL_SPEEDUP)
/* AES-NI can be enabled with WC_C_DYNAMIC_FALLBACK, but without the rest of
* USE_INTEL_SPEEDUP, in which case we need to disable the dynamic
* fallback.
*/
#undef WC_C_DYNAMIC_FALLBACK
#endif
/*
* SHA256 Build Options:
* USE_SLOW_SHA256: Reduces code size by not partially unrolling
@ -189,6 +180,15 @@ on the specific device platform.
}
#endif
#if defined(WC_C_DYNAMIC_FALLBACK) && \
defined(WOLFSSL_AESNI) && !defined(USE_INTEL_SPEEDUP)
/* AES-NI can be enabled with WC_C_DYNAMIC_FALLBACK, but without the rest of
* USE_INTEL_SPEEDUP, in which case we need to disable the dynamic
* fallback.
*/
#undef WC_C_DYNAMIC_FALLBACK
#endif
#if defined(WOLFSSL_X86_64_BUILD) && defined(USE_INTEL_SPEEDUP)
#if defined(__GNUC__) && ((__GNUC__ < 4) || \
(__GNUC__ == 4 && __GNUC_MINOR__ <= 8))

View File

@ -65,15 +65,6 @@
" acceleration backends"
#endif
#if defined(WC_C_DYNAMIC_FALLBACK) && \
defined(WOLFSSL_AESNI) && !defined(USE_INTEL_SPEEDUP)
/* AES-NI can be enabled with WC_C_DYNAMIC_FALLBACK, but without the rest of
* USE_INTEL_SPEEDUP, in which case we need to disable the dynamic
* fallback.
*/
#undef WC_C_DYNAMIC_FALLBACK
#endif
#if (defined(WOLFSSL_SHA512) || defined(WOLFSSL_SHA384))
/* determine if we are using Espressif SHA hardware acceleration */
@ -145,6 +136,15 @@
#include <wolfssl/wolfcrypt/port/cypress/psoc6_crypto.h>
#endif
#if defined(WC_C_DYNAMIC_FALLBACK) && \
defined(WOLFSSL_AESNI) && !defined(USE_INTEL_SPEEDUP)
/* AES-NI can be enabled with WC_C_DYNAMIC_FALLBACK, but without the rest of
* USE_INTEL_SPEEDUP, in which case we need to disable the dynamic
* fallback.
*/
#undef WC_C_DYNAMIC_FALLBACK
#endif
#if defined(WOLFSSL_X86_64_BUILD) && defined(USE_INTEL_SPEEDUP)
#if defined(__GNUC__) && ((__GNUC__ < 4) || \
(__GNUC__ == 4 && __GNUC_MINOR__ <= 8))
@ -1285,7 +1285,7 @@ static int InitSha512_256(wc_Sha512* sha512)
}
#else
if (sha_method == SHA512_C)
return Transform_Sha512(sha512);
return _Transform_Sha512(sha512);
SAVE_VECTOR_REGISTERS(return _svr_ret;);
#endif
switch (sha_method) {

View File

@ -56465,15 +56465,11 @@ static wc_test_ret_t mldsa_param_44_vfy_test(void)
ret = mldsa_param_vfy_test(WC_ML_DSA_44, ml_dsa_44_pub_key,
(word32)sizeof(ml_dsa_44_pub_key), ml_dsa_44_sig,
(word32)sizeof(ml_dsa_44_sig));
if (ret != 0)
ret = WC_TEST_RET_ENC_EC(ret);
#ifdef WOLFSSL_MLDSA_FIPS204_DRAFT
if (ret == 0) {
ret = mldsa_param_vfy_test(WC_ML_DSA_44_DRAFT,
ml_dsa_44_draft_pub_key, (word32)sizeof(ml_dsa_44_draft_pub_key),
ml_dsa_44_draft_sig, (word32)sizeof(ml_dsa_44_draft_sig));
if (ret != 0)
ret = WC_TEST_RET_ENC_EC(ret);
}
#endif
@ -57467,15 +57463,11 @@ static wc_test_ret_t mldsa_param_65_vfy_test(void)
ret = mldsa_param_vfy_test(WC_ML_DSA_65, ml_dsa_65_pub_key,
(word32)sizeof(ml_dsa_65_pub_key), ml_dsa_65_sig,
(word32)sizeof(ml_dsa_65_sig));
if (ret != 0)
ret = WC_TEST_RET_ENC_EC(ret);
#ifdef WOLFSSL_MLDSA_FIPS204_DRAFT
if (ret == 0) {
ret = mldsa_param_vfy_test(WC_ML_DSA_65_DRAFT,
ml_dsa_65_draft_pub_key, (word32)sizeof(ml_dsa_65_draft_pub_key),
ml_dsa_65_draft_sig, (word32)sizeof(ml_dsa_65_draft_sig));
if (ret != 0)
ret = WC_TEST_RET_ENC_EC(ret);
}
#endif
@ -58828,15 +58820,11 @@ static wc_test_ret_t mldsa_param_87_vfy_test(void)
ret = mldsa_param_vfy_test(WC_ML_DSA_87, ml_dsa_87_pub_key,
(word32)sizeof(ml_dsa_87_pub_key), ml_dsa_87_sig,
(word32)sizeof(ml_dsa_87_sig));
if (ret != 0)
ret = WC_TEST_RET_ENC_EC(ret);
#ifdef WOLFSSL_MLDSA_FIPS204_DRAFT
if (ret == 0) {
ret = mldsa_param_vfy_test(WC_ML_DSA_87_DRAFT,
ml_dsa_87_draft_pub_key, (word32)sizeof(ml_dsa_87_draft_pub_key),
ml_dsa_87_draft_sig, (word32)sizeof(ml_dsa_87_draft_sig));
if (ret != 0)
ret = WC_TEST_RET_ENC_EC(ret);
}
#endif

View File

@ -663,6 +663,18 @@
#define AES_GCM_AESNI_NO_UNROLL
#endif
/* Leverage compiler built-ins to assure that __int128_t and __uint128_t are
* gated in regardless of autotools-dependent feature sensing.
*/
#if defined(__SIZEOF_INT128__) && !defined(NO_INT128)
#ifndef HAVE___INT128_T
#define HAVE___INT128_T 1
#endif
#ifndef HAVE___UINT128_T
#define HAVE___UINT128_T 1
#endif
#endif
#ifdef IPHONE
#define SIZEOF_LONG_LONG 8
#endif