The PSS hook can hand back the recovered block through out/outSz/outLen.
A device that reports only a verdict leaves outLen at 0; wolfSSL then
zeroes the buffer and returns saltLen + hLen, and rejects a buffer
smaller than that with RSA_BUFFER_E. A reported length is clamped to the
buffer size, and any positive handler return maps to SIG_VERIFY_E.
Move the Ed448 sign WOLFSSL_CHECK_MEM_ZERO registration below the crypto
callback hook so the device path no longer returns past it, and guard the
RSA-PSS test callback against WOLF_CRYPTO_CB_ONLY_RSA.
Adds tests for the recovered-data, over-claimed-length and undersized
buffer paths, and an os-check config that builds the hooks under
WOLFSSL_CHECK_MEM_ZERO.
Add WOLF_CRYPTO_CB dispatch hooks so a device can service:
* Ed448 sign and verify, mirroring the existing Ed25519 hooks.
* CMAC context free on wc_CmacFree (WOLF_CRYPTO_CB_FREE), letting a device
release offload state.
* RSA-PSS verify with the digest (WOLF_CRYPTO_CB_RSA_PAD) so the device does
the full signature and padding check. On that path *out is set to NULL with a
positive return, documented in rsa.h.
Includes testwolfcrypt and API unit test coverage for each hook.
wolfcrypt/src/wc_mldsa.c: WC_C_DYNAMIC_FALLBACK fixes for AVX512.
tests/api/test_frodokem.c, wolfcrypt/test/test.c: fixes for WC_DEBUG_CIPHER_LIFECYCLE.
wolfcrypt/src/fe_x25519_asm.S, wolfcrypt/src/port/arm/armv8-32-aes-asm.S,
wolfcrypt/src/port/arm/armv8-aes-asm.S, wolfcrypt/src/port/arm/armv8-aes-asm_c.c,
wolfcrypt/src/port/arm/thumb2-aes-asm.S, wolfcrypt/src/sha3_asm.S,
wolfcrypt/src/wc_mldsa_asm.S: regenerate from scripts#647
.github/workflows/fips-dev-no-post.yml:
* update "minutes" for tests using empirical data;
* add --enable-experimental --enable-all-quantum-crypto to kernel-settings-all-asm scenario and rename it kernel-settings-all-pqc-asm; add all-pqc-asm-fallback-fuzzer scenario.
wolfcrypt/src/wolfentropy.c: remove WC_FIPS_LL_CRYPTO (it is not a FIPS file except in FIPS v5.2.4).
wolfcrypt/src/sha256.c: fix for rebase error (stray #endif).
.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().
* Use defined(WC_HAVE_RNG_BANKREF), not defined(WC_RNG_BANK_SUPPORT), as the feature sensor for RNG bankrefs.
* Add DRBG_KAT_FIPS_E and DRBG_CONT_FIPS_E to the list of immediate-failure errors in wc_rng_bank_init().
is_enabled, WC_DH_INITIAL_RUNTIME_ENABLEMENT, WC_DH_HAVE_RUNTIME_ENABLEMENT.
Place the enablement check AFTER key->heap/trustedGroup init in the five entry
points (wc_InitDhKey_ex, wc_DhGenerateKeyPair, wc_DhAgree, wc_DhAgree_ct,
_DhSetKey) so a disabled-DH early return never leaves a half-initialized key for
wc_FreeDhKey to mp_clear on garbage.
configure.ac: add --enable-dh=conditional; when DH is enabled (directly or via
all-crypto) set it initially usable under FIPS v7 with
-DWC_DH_INITIAL_RUNTIME_ENABLEMENT=1; remove the FIPS-v7 DH force-off (in FIPS
v7+, disable build by default, unless building in kernel mode with DH
registration enabled).
linuxkm/lkcapi_glue.c: bracket LKCAPI registration with
`need_dh_disable = (wc_dh_enable() == 0)` ... `if (need_dh_disable)
wc_dh_disable();`, so DH is disabled on every exit path, and only by the caller
that actually enabled it (wc_dh_enable returns ALREADY_E if DH was already on,
so this never disables a DH some other context legitimately enabled).
tests/unit.c, wolfcrypt/test/test.c: bracket the DH tests with enable/disable so
they succeed regardless of runtime initial default enablement.
and AM_CONDITIONAL BUILD_FIPS_NO_POST. Refactor FIPS dev/ready version setup:
hoist ENABLED_FIPS_DEV / ENABLED_FIPS_READY to set -DWOLFSSL_FIPS_DEV /
-DWOLFSSL_FIPS_READY centrally, and switch the FIPS AS_CASE arms from
`test "$FIPS_VERSION" != "dev"` to `test "$ENABLED_FIPS_DEV" != "yes"` so the
dev semantics extend to v5-dev/v6-dev/lean-aesgcm-dev.
src/include.am: under !BUILD_FIPS_NO_POST, drop fips.c / fips_test.c /
wolfcrypt_first.c / wolfcrypt_last.c from the build (dev-no-post uses no fips
repo content).
wolfssl/wolfcrypt/settings.h, wolfssl/wolfcrypt/wc_compat.h: under
WOLFSSL_FIPS_DEV_NO_POST, squat WOLF_CRYPT_FIPS_H to inhibit fips.h, and change
the FIPS_READY/DEV version block guard to `!defined(HAVE_FIPS_VERSION)`
(required so an externally supplied version is not clobbered).
wolfssl/wolfcrypt/fips_test.h: add WOLFSSL_FIPS_DEV_NO_POST stub block
(fipsCastStatus_get, the PRIVATE_KEY macros) so master builds without the fips
repo.
linuxkm/linuxkm_wc_port.h, linuxkm/module_hooks.c: accommodate
WOLFSSL_FIPS_DEV_NO_POST (guard verifyCore / CAST / fencepost paths that the
fips repo would otherwise provide; force WC_USE_PIE_FENCEPOSTS_FOR_FIPS).
wolfcrypt/test/test.c: in hmac_sha256_test(), don't expect HMAC_KAT_FIPS_E in
WOLFSSL_FIPS_DEV_NO_POST builds.
wolfssl/wolfcrypt/types.h: add stub macro for
wolfCrypt_SetPrivateKeyReadEnable_fips() when WOLFSSL_FIPS_DEV_NO_POST.
Second review follow-up on the async record layer series.
Stop the probe reselecting the cipher side. BuildMessage()'s BUILD_MSG_BEGIN
case can call SetKeysSide() for DTLS with secure renegotiation, which swaps
the active encryption state and clears recordSzOverhead. That is not part of a
size calculation, and after the previous commit the suspended build survives
to resume against whatever side the probe last chose, so a DTLS 1.2 record
suspended for PREV_ORDER could resume against the renegotiation keys. Skip it
when sizeOnly is set; the sizes are the same either way.
The probe itself has to keep running. Not re-entering BuildMessage at all
while a build is suspended looks tidier, but wolfssl_local_GetMaxPlaintextSize()
derives the DTLS fragment size from this result, so falling back to the upper
bound there shrinks fragments inconsistently between calls and the MTU
reproducer fails its buffer comparison. Saving and restoring the two fields is
what keeps the answer exact.
Resume inside the record when handshake content is left. The previous commit
declined to skip the padding for a fragmented or coalesced
certificate_request, which was right, but left processReply at doProcessInit
with the index inside the record, so the resume still started a fresh record
parse in the middle of one. Mirror both halves of the end of record block
instead: set runProcessingOneMessage when content remains, advance past the
padding only at the boundary.
Note the shared state at the source. BuildMessage() and BuildTls13Message()
write ssl->options.buildMsgState even for a sizeOnly probe with asyncOkay
clear, where everything else goes to the caller's own arguments. Nothing said
so at those sites, so the next sizeOnly caller would reintroduce this.
Record why only one of the three wc_ecc_make_key_ex() calls in eccsi.c needs
a wait: the other two are preceded by wc_ecc_free(), which clears the marker
their pending path is gated on. Moving either free would make them pend.
Test changes. Force the overhead cache cold before probing, otherwise an AEAD
suite answers from the cache without ever calling BuildMessage and the
assertions hold no matter what the probe did. Compare against BuildMessage's
own figure rather than only checking the size is positive, and run the whole
thing for TLS 1.3 as well as TLS 1.2, since BuildTls13Message() clobbers the
state by a different route: its sizeOnly return bypasses exit_buildmsg
entirely. Checked by stubbing the restore out again, which fails the test.
Also spell the new guard in cryptocb_test() as #if defined(WOLFSSL_ASYNC_CRYPT)
to match the rest of that file, which uses that form 170 times against 4.
cryptocb_test() generates a key with wc_ecc_make_key() and assigns the
result straight to ret. In an async build that call returns WC_PENDING_E,
which is not an encoded test result, so the raw -108 propagated out of
the test and printed as "error L=108" with no error code at all.
The key is reached through myCryptoDevCb, which services EC key
generation by calling wc_ecc_make_key_ex() on the same key after setting
key->devId = INVALID_DEVID. That comment says the intent is to force
software, and it does stop the crypto callback from dispatching again,
but the pending path in _ecc_make_key_ex() is gated on asyncDev.marker
rather than devId. The marker is untouched, so the inner call still goes
pending and the callback hands WC_PENDING_E back to its caller.
Wait at the call site rather than in the callback. Every other key
generation in this file already does exactly that, a callback returning
WC_PENDING_E is legitimate for a real asynchronous device, and the same
devId idiom appears 48 times in myCryptoDevCb against 48 different keys,
so there is no single place in the callback to fix.
With this, testwolfcrypt passes in full under --enable-all with
--enable-asynccrypt-sw, where it previously stopped here. Verified
against plain --enable-all as well, which is unaffected: the addition
compiles out entirely without WOLFSSL_ASYNC_CRYPT.
That configuration still cannot complete make check. unit.test fails in
the cipher suite runner on TLS 1.3 post-handshake authentication, which
is a record layer problem in the library rather than a test defect and
is not addressed here. All 2111 API tests pass.
ecc_encrypt_cryptocb_test() calls wc_ecc_make_key() twice and checks the
return code directly. Under WOLFSSL_ASYNC_CRYPT the software simulator
returns WC_PENDING_E from that call, so the test aborts with -108 before
it reaches a single ECIES operation. The sibling ecc_encrypt_test() right
below it already wraps the same two calls in wc_AsyncWait(); this one was
added later and never got the same treatment.
Mirror the sibling exactly: wc_AsyncWait() on each key's asyncDev with
WC_ASYNC_FLAG_NONE, guarded by WOLFSSL_ASYNC_CRYPT so non-async builds are
untouched by the preprocessor.
The failure needs --enable-all together with the software async simulator.
--enable-all turns on cryptocb, which suppresses the auto-enabled simulator
in configure.ac, so the simulator only appears if --enable-asynccrypt-sw is
passed explicitly. No configuration under .github/ combines the two, which
is why this was never seen in CI.
Verified with --enable-all --enable-asynccrypt-sw under the CFLAGS the
os-check workflow applies: "ECC Enc test failed! error code=-108" before,
"ECC Enc test passed!" after. Rebuilt the same tree as plain --enable-all
to confirm the non-async path is unaffected, where testwolfcrypt passes in
full.
Fixing this uncovers the next test to run, ECCSI, failing the same way.
That one is a library defect rather than a test defect and is fixed in the
following commit.
The encap and decap paths create a temporary RNG, install it into a key that
belongs to the caller so the shared secret computation can blind, and then
free it without taking it back out. Both wc_ecc_set_rng and
wc_curve25519_set_rng only record the pointer, and nothing else ever writes
that field, so the caller's key was left pointing at freed memory. Encap does
this to the ephemeral key and decap to the receiver key, including the
curve25519 branch. Repeated HPKE calls hide it because each one installs a
fresh RNG first, but any other use of the key that consults it, such as an
ECDH or a signature under timing resistance, reads the freed object. ECH
holds exactly such a long lived key.
Save whatever RNG the key already had and put it back before freeing the
temporary one, so the key is handed back to the caller unchanged. Clearing
the field instead would silently drop an RNG the caller had installed for
blinding of their own.
Extend the HPKE round trip test to give both keys an RNG of its own and to
require them to still have it once the seal and open have finished.
Fixes F-7083.
Add AES-GCM (128/256) as an ECIES DEM next to the AES-CBC/CTR+HMAC modes. Only the encryption key comes from the KDF; the mac salt is bound as GCM AAD and the 16-byte tag replaces the HMAC. The GCM DEM honors all three IV build modes, and default fixed-nonce GCM is gated behind the new WOLFSSL_ECIES_STATIC_GCM_NONCE opt-in. Adds ECIES CryptoCb encrypt/decrypt, the WOLF_CRYPTO_CB ctx getters, devId/heap threading into the DEM primitives, and test/benchmark/CI coverage.
Scrub the temporary "FN-DSA" name and the "FIPS 206" designation from all
in-tree comments, build text, and message strings, leaving the algorithm
named only as "Falcon". The eventual standardized name is not announced.
The differential known-answer test message ("wolfSSL FN-DSA differential
KAT") is a signed input, so the Falcon-512/1024 public keys and signatures
in wolfcrypt/test/test.c (and the mirrored Falcon-512 vector in
IDE/m33mu-falcon-verify/kat.h) were regenerated with liboqs over the new
message "wolfSSL Falcon differential KAT", preserving the differential
property (liboqs-produced signatures verified by the native verifier).
Verified: testwolfcrypt Falcon test passes; the m33mu verify-only harness
passes (BKPT 0x7f) with the regenerated vector.
Wire Falcon into the crypto callback framework like the other algorithms:
- wc_falcon_make_key now dispatches to wc_CryptoCb_MakePqcSignatureKey
(WC_PQC_SIG_TYPE_FALCON); wc_falcon_sign_msg / wc_falcon_verify_msg already
dispatched to wc_CryptoCb_PqcSign / PqcVerify. All three fall through to the
software implementation when the callback is unavailable.
- Add WOLF_CRYPTO_CB_ONLY_FALCON (mirrors WOLF_CRYPTO_CB_ONLY_RSA/ECC): the
callback becomes authoritative (no software fallback; returns NO_VALID_DEVID
when no device is registered) and the native core (wc_falcon*.c) is compiled
out entirely. WC_FALCON_HAVE_NATIVE_SIGN and the falcon_native_* prototypes
are gated off in that build.
Tests (test.c):
- myCryptoDevCb gains a Falcon branch for PQC keygen/sign/verify.
- falcon_test / falcon_verify_kat now use the global test devId, so
cryptocb_test drives every Falcon operation through the callback and asserts
(via the exampleVar hit counter) that the cb path was actually taken.
- Under WOLF_CRYPTO_CB_ONLY_FALCON, falcon_test instead confirms the API
returns NO_VALID_DEVID with no device registered, and the KAT data/verifier
(software-only) are compiled out.
Verified: default (no cryptocb), --enable-cryptocb, and
-DWOLF_CRYPTO_CB_ONLY_FALCON all build and pass testwolfcrypt (falcon_test +
crypto callback test); the CB_ONLY library contains no falcon_native_* symbols.
Add a complete native Falcon post-quantum lattice signature implementation to
wolfCrypt, replacing the liboqs wrapper. Full key generation, signing and
verification for Falcon-512 (level 1) and Falcon-1024 (level 5).
- Public API wc_falcon_* / falcon_key in falcon.c wraps the native core
(falcon_native_* in wc_falcon.c) plus wc_falcon_{fpr,fft,poly,sampler,
codec,keygen,sign,bigint}.c. No liboqs dependency.
- Portable, constant-time integer-emulated floating-point (fpr) backend is
the default; opt-in per-architecture acceleration:
--enable-falcon-double inline native double
--enable-falcon-asm x86-64 SSE2 out-of-line fpr asm
--enable-falcon-avx2 x86-64 AVX2 (4-wide) FFT
- Division-free (Barrett) integer NTT on the verify path, so no hardware
divide is required on Cortex-M / embedded targets.
- Verify uses a cached twiddle-factor NTT; signing uses the FFT / ffLDL tree
and discrete Gaussian sampler over the abstract fpr seam.
- test.c falcon_test (KAT verify + native keygen/sign/verify roundtrip);
scripts/falcon-interop.c and a CI workflow cross-check native<->liboqs in
both directions.
wolfssl/wolfcrypt/aes.h: if HAVE_FIPS && !WC_FIPS_AESGCM_ONE_SHOT_EXT_IV_ALLOWED, make wc_AesGcmEncrypt() a WOLFSSL_LOCAL, and if !_WC_BUILDING_AES_C, add a WC_DEPRECATED() attribute to it.
wolfssl/wolfcrypt/wc_compat.h, wolfssl/wolfcrypt/include.am, .wolfssl_known_macro_extras: add wc_compat.h: when HAVE_FIPS and !WC_FIPS_AESGCM_ONE_SHOT_EXT_IV_ALLOWED, shim wc_AesGcmEncrypt() to remap it to FIPS-allowed APIs.
wolfssl/wolfcrypt/types.h: at the end, #ifndef BUILDING_WOLFSSL, #include <wolfssl/wolfcrypt/wc_compat.h>, to assure transparent shimming of wc_AesGcmEncrypt() for all outside callers.
wolfcrypt/src/evp.c, wolfcrypt/src/hpke.c, wolfcrypt/src/pkcs7.c, wolfcrypt/benchmark/benchmark.c, wolfcrypt/test/test.c, wolfssl/ssl.h: #include <wolfssl/wolfcrypt/wc_compat.h> to shim in-library/in-module calls to wc_AesGcmEncrypt().
src/internal.c: in TicketEncDec(), add const attributes to constable input args, and fix swapped out/in in calls to wc_AesGcmEncrypt().
tests/api/test_aes.c: in test_wc_AesGcmEncryptDecrypt(), skip longIV test if WC_TEST_AES_GCM_ENCRYPT_NO_NONSTD_IV (defined by wc_compat.h when needed).
wolfssl/wolfcrypt/error-crypt.h, wolfssl/error-ssl.h, wolfcrypt/src/error.c, src/internal.c:
* add FIPS_WRONG_API_E;
* put several error codes back into sequence in wc_GetErrorString() switch().
* move wc_static_assert()s from headers to corresponding .c files, to eliminate dependency on wolfcrypt/types.h;
* remove unneeded #include <wolfssl/wolfcrypt/types.h> from error-crypt.h.