diff --git a/.wolfssl_known_macro_extras b/.wolfssl_known_macro_extras index fb302c4c8e1..2afca3f3940 100644 --- a/.wolfssl_known_macro_extras +++ b/.wolfssl_known_macro_extras @@ -574,8 +574,6 @@ NO_TLSX_PSKKEM_PLAIN_ANNOUNCE NO_VAES_SUPPORT NO_VERIFY_OID NO_WC_DHGENERATEPUBLIC -NO_WC_SHE_GETUID -NO_WC_SHE_IMPORT_M123 NO_WC_SHE_LOADKEY NO_WC_SSIZE_TYPE NO_WOLFSSL_ALLOC_ALIGN @@ -846,11 +844,11 @@ WC_HASH_CUSTOM_MAX_DIGEST_SIZE WC_HASH_CUSTOM_MIN_DIGEST_SIZE WC_HAVE_FIPS_INDICATOR WC_INIT_ERROR_WHEN_CONTENDED +WC_LINUXKM_FORCE_SVR_DYNAMIC_AUDITING WC_LINUXKM_NO_ENTROPY_DAEMON WC_LINUXKM_NO_SVR_DYNAMIC_AUDITING WC_LINUXKM_NO_USE_HEAP_WRAPPERS WC_LINUXKM_SPIN_IN_ATOMIC -WC_LINUXKM_FORCE_SVR_DYNAMIC_AUDITING WC_MLDSA_NO_ASM WC_MLKEM_KERNEL_ASM WC_MPFS_ATHENA_NO_BASE_ADDR @@ -861,8 +859,6 @@ WC_NO_RNG_SIMPLE WC_NO_STATIC_ASSERT WC_NO_VERBOSE_RNG WC_PKCS11_FIND_WITH_ID_ONLY -WC_PKCS12_PBKDF_USING_MP_API -WC_PUF_HELPER_COMPACT WC_PUF_SHA3 WC_RNG_BANK_NO_DAEMON_SUPPORT WC_RNG_BANK_NO_DEFAULT_SUPPORT @@ -889,7 +885,6 @@ WC_RSA_NO_FERMAT_CHECK WC_RTL8735B_NO_DERIVE_CACHE WC_RWLOCK_OPS_INLINE WC_SHA2_SMALL_STACK -WC_SHE_SW_DEFAULT WC_SKIP_INCLUDED_C_FILES WC_SLHDSA_KERNEL_ASM WC_SLHDSA_NO_ASM @@ -934,12 +929,8 @@ WOLFSSL_ALTERA_FCS_RAW_RNG WOLFSSL_ALTERNATIVE_DOWNGRADE WOLFSSL_ALT_NAMES_NO_REV WOLFSSL_ARM32_BUILD -WOLFSSL_ARM32_PRIVILEGE_MODE WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP -WOLFSSL_ARMASM_SHA3_NO_NEON -WOLFSSL_ARMASM_SHA512_NO_NEON WOLFSSL_ARM_ARCH_NEON_64BIT -WOLFSSL_ASCON_UNROLL WOLFSSL_ASN_EXTRA WOLFSSL_ATECC508 WOLFSSL_ATECC508A_NOSOFTECC @@ -980,18 +971,13 @@ WOLFSSL_CRL_ALLOW_MISSING_CDP WOLFSSL_CRYPTOCELL WOLFSSL_CRYPTOCELL_AES WOLFSSL_DEBUG_TRACE_ERROR_CODES_SUPPORT -WOLFSSL_DILITHIUM_VERIFY_SMALLEST_MEM WOLFSSL_DISABLE_EARLY_SANITY_CHECKS WOLFSSL_DRBG_SHA256 -WOLFSSL_DTLS13_ECHO_LEGACY_SESSION_ID -WOLFSSL_DTLS13_NO_HRR_ON_RESUME WOLFSSL_DTLS_DISALLOW_FUTURE -WOLFSSL_DTLS_RECORDS_CAN_SPAN_DATAGRAMS WOLFSSL_DTLS_RESEND_ONLY_TIMEOUT WOLFSSL_DUMP_MEMIO_STREAM WOLFSSL_DUP_CERTPOL WOLFSSL_EARLY_DATA_NO_ANTI_REPLAY -WOLFSSL_ECC_BLIND_K WOLFSSL_ECC_GEN_REJECT_SAMPLING WOLFSSL_ECC_NO_SMALL_STACK WOLFSSL_ECC_SIGALG_PARAMS_NULL_ALLOWED @@ -1006,7 +992,6 @@ WOLFSSL_ESPWROOM32 WOLFSSL_EVP_PRINT WOLFSSL_EXPORT_INT WOLFSSL_EXPORT_SPC_SZ -WOLFSSL_EXTRA WOLFSSL_FALCON_NO_NTT_DSP WOLFSSL_FALCON_SIGN_STATS WOLFSSL_FORCE_OCSP_NONCE_CHECK @@ -1057,17 +1042,12 @@ WOLFSSL_MANUALLY_SELECT_DEVICE_CONFIG WOLFSSL_MCDC_ALLOC_SWEEP WOLFSSL_MDK5 WOLFSSL_MICROCHIP_AESGCM -WOLFSSL_MLDSA_ALLOW_WEAK_PREHASH -WOLFSSL_MLDSA_CHECK_INVNTT_BOUND -WOLFSSL_MLDSA_SIGN_SMALLEST_MEM -WOLFSSL_MLDSA_TEST_REJ_NTT_FAIL WOLFSSL_MLDSA_VERIFY_ALLOW_MALLOC WOLFSSL_MLDSA_VERIFY_PRECOMP_A WOLFSSL_MLKEM_ASM_TEST WOLFSSL_MLKEM_INVNTT_UNROLL WOLFSSL_MLKEM_NO_MALLOC WOLFSSL_MLKEM_NTT_UNROLL -WOLFSSL_ML_KEM_USE_OLD_IDS WOLFSSL_MONT_RED_CT WOLFSSL_MP_COND_COPY WOLFSSL_MP_INVMOD_CONSTANT_TIME @@ -1075,18 +1055,15 @@ WOLFSSL_MULTICIRCULATE_ALTNAMELIST WOLFSSL_MX2_CONF_INCLUDE WOLFSSL_NETX_DUO WOLFSSL_NEW_PRIME_CHECK -WOLFSSL_NONBLOCK_OCSP WOLFSSL_NOSHA3_384 WOLFSSL_NOT_WINDOWS_API WOLFSSL_NO_AES_KEY_SET_CHECK WOLFSSL_NO_BIO_ADDR_IN -WOLFSSL_NO_CA_NAMES WOLFSSL_NO_CHACHA20_POLY1305_FUSED WOLFSSL_NO_CHACHA20_POLY1305_FUSED_IFMA WOLFSSL_NO_CHACHA20_POLY1305_SHORT WOLFSSL_NO_CHACHA20_POLY1305_SMALL_ASM WOLFSSL_NO_CLIENT_CERT_ERROR -WOLFSSL_NO_COPY_CERT WOLFSSL_NO_COPY_KEY WOLFSSL_NO_CRL_DATE_CHECK WOLFSSL_NO_CRL_NEXT_DATE @@ -1096,10 +1073,7 @@ WOLFSSL_NO_DECODE_EXTRA WOLFSSL_NO_DEL_HANDLE WOLFSSL_NO_DER_TO_PEM WOLFSSL_NO_DH186 -WOLFSSL_NO_DILITHIUM_LEGACY_GATES WOLFSSL_NO_DILITHIUM_LEGACY_NAMES -WOLFSSL_NO_DTLS_SIZE_CHECK -WOLFSSL_NO_ECC_SW WOLFSSL_NO_ECDHX_SHARED_ZERO_CHECK WOLFSSL_NO_ETM_ALERT WOLFSSL_NO_FCHMOD @@ -1117,7 +1091,6 @@ WOLFSSL_NO_LMS_SHAKE256_256 WOLFSSL_NO_OCSP_DATE_CHECK WOLFSSL_NO_OCSP_OPTIONAL_CERTS WOLFSSL_NO_RSA_KEY_CHECK -WOLFSSL_NO_RSA_SW WOLFSSL_NO_SERVER_GROUPS_EXT WOLFSSL_NO_SESSION_STATS WOLFSSL_NO_SHA256_N_WAY @@ -1128,7 +1101,6 @@ WOLFSSL_NO_SIGALG WOLFSSL_NO_SIGNER_DER_CERT WOLFSSL_NO_SOCKADDR_UN WOLFSSL_NO_STRICT_CIPHER_SUITE -WOLFSSL_NO_TICKET_EXPIRE WOLFSSL_NO_TRUSTED_CERTS_VERIFY WOLFSSL_NO_WORD64_OPS WOLFSSL_NO_XOR_OPS @@ -1145,7 +1117,6 @@ WOLFSSL_NXP_ELE_NO_TRNG_CHECK WOLFSSL_NXP_ELE_USE_DEVID WOLFSSL_NXP_HWPUF WOLFSSL_NXP_LPC55S6X -WOLFSSL_OCSP_SCREEN_RESPONDER WOLFSSL_OLDTLS_AEAD_CIPHERSUITES WOLFSSL_OLD_SET_CURVES_LIST WOLFSSL_OLD_TIMINGPADVERIFY @@ -1208,7 +1179,6 @@ WOLFSSL_SEC_QORIQ_NO_PKHA WOLFSSL_SEC_QORIQ_NO_RSA WOLFSSL_SEC_QORIQ_SWAP_REGS WOLFSSL_SERVER_EXAMPLE -WOLFSSL_SESSION_CACHE_REF_WARNED WOLFSSL_SETTINGS_FILE WOLFSSL_SGX_CPUID_AVX512_VAES WOLFSSL_SHA256_ALT_CH_MAJ @@ -1237,10 +1207,6 @@ WOLFSSL_STSAFE_TAKES_SLOT WOLFSSL_TELIT_M2MB WOLFSSL_TEMPLATE_EXAMPLE WOLFSSL_THREADED_CRYPT -WOLFSSL_TI_AM64X_R5 -WOLFSSL_TI_AM64X_RNG_CTR_DRBG -WOLFSSL_TI_AM64X_NO_AES -WOLFSSL_TI_AM64X_NO_SHA WOLFSSL_TICKET_DECRYPT_NO_CREATE WOLFSSL_TICKET_ENC_AES128_GCM WOLFSSL_TICKET_ENC_AES256_CBC @@ -1250,11 +1216,13 @@ WOLFSSL_TICKET_ENC_CHACHA20_POLY1305 WOLFSSL_TICKET_ENC_HMAC_SHA384 WOLFSSL_TICKET_ENC_HMAC_SHA512 WOLFSSL_TINY_TLS13_NO_DEFAULT_CURVE +WOLFSSL_TI_AM64X_NO_AES +WOLFSSL_TI_AM64X_NO_SHA +WOLFSSL_TI_AM64X_R5 +WOLFSSL_TI_AM64X_RNG_CTR_DRBG WOLFSSL_TI_CURRTIME WOLFSSL_TLS13_DRAFT WOLFSSL_TLS13_IGNORE_AEAD_LIMITS -WOLFSSL_TLS13_IGNORE_PT_ALERT_ON_ENC -WOLFSSL_TLS13_NULL_CIPHER_IN_DEFAULT WOLFSSL_TLS13_TICKET_BEFORE_FINISHED WOLFSSL_TLS13_TICKET_CHECK_PSK_MODES WOLFSSL_TLSX_PQC_MLKEM_STORE_PRIV_KEY @@ -1275,7 +1243,6 @@ WOLFSSL_VALIDATE_MLDSA_KEYGEN WOLFSSL_VALIDATE_MLKEM_KEYGEN WOLFSSL_VALIDATE_SLHDSA_KEYGEN WOLFSSL_VAULTIC_DEBUG -WOLFSSL_VERBOSE_LOGGING WOLFSSL_VERSAL_GEN2_ASU_CCM_ALIGN_DECLINE WOLFSSL_VERSAL_GEN2_ASU_CTR_WRAP_HW_FIXED WOLFSSL_VERSAL_GEN2_ASU_DEBUG @@ -1300,7 +1267,6 @@ WOLFSSL_X509_KEY_GEN WOLFSSL_X509_PEM WOLFSSL_X509_STORE_ALLOW_NON_CA_INTERMEDIATE WOLFSSL_X509_STORE_CERTS -WOLFSSL_X509_TINY WOLFSSL_X509_TRUSTED_CERTIFICATE_CALLBACK WOLFSSL_X509_VERIFY_ONLY WOLFSSL_XFREE_NO_NULLNESS_CHECK @@ -1312,10 +1278,7 @@ WOLFSSL_ZEPHYR_MAIN_ARGS WOLFSSL_nRF5x_SDK_15_2 WOLF_ALLOW_BUILTIN WOLF_CONF_ASN_TIME -WOLF_CRYPTO_CB_ASYNC_POLL -WOLF_CRYPTO_CB_KEYGEN_SW_FALLBACK WOLF_CRYPTO_CB_ONLY_SHA -WOLF_CRYPTO_CB_SHAKE_XOF WOLF_CRYPTO_DEV WOLF_NO_TRAILING_ENUM_COMMAS WindowsCE diff --git a/linuxkm/Kbuild b/linuxkm/Kbuild index ff73672e8a7..a6acbfb784a 100644 --- a/linuxkm/Kbuild +++ b/linuxkm/Kbuild @@ -147,7 +147,18 @@ endif ccflags-y = $(WOLFSSL_CFLAGS) $(WOLFSSL_CFLAGS_NO_VECTOR_INSNS) +# Retpoline mitigation for Spectre v2 was added in 4.15, but under knob +# CONFIG_RETPOLINE, and return thunk mitigation for retbleed was added +# in 5.19, but under knob CONFIG_RETHUNK. The current knob names were +# merged in 6.9; alias to current names so one set of conditionals +# serves both. +CONFIG_MITIGATION_RETPOLINE ?= $(CONFIG_RETPOLINE) +CONFIG_MITIGATION_RETHUNK ?= $(CONFIG_RETHUNK) + ifeq "$(ENABLED_LINUXKM_PIE)" "yes" + ifdef CONFIG_CFI_CLANG + $(error CONFIG_CFI_CLANG is not compatible with ENABLED_LINUXKM_PIE.) + endif # note, we need -fno-stack-protector to avoid references to # "__stack_chk_fail" from the wolfCrypt container. PIE_FLAGS := -DWC_CONTAINERIZE_THIS -fno-stack-protector -fno-toplevel-reorder @@ -206,44 +217,86 @@ ifeq "$(ENABLED_LINUXKM_PIE)" "yes" ifeq "$(KERNEL_ARCH_X86)" "yes" PIE_FLAGS += -mcmodel=small - # eliminate external references to __x86_return_thunk and - # __x86_indirect_thunk_foo implementations. _all_ references must be - # eliminated, not just those in PIE objects, otherwise some kernels will + # eliminate external references to __x86_return_thunk (via + # -mfunction-return=thunk-inline) and __x86_indirect_thunk_foo (via + # -mindirect-branch=thunk-inline). _all_ references must be eliminated, + # not just those in PIE objects, otherwise some kernels will # false-positively complain about unpatched thunks. - ifeq "$(CONFIG_MITIGATION_RETPOLINE)" "y" - PIE_SUPPORT_FLAGS += -mfunction-return=thunk-inline - else - PIE_SUPPORT_FLAGS += -mfunction-return=keep - endif - ifeq "$(CONFIG_MITIGATION_RETHUNK)" "y" - PIE_SUPPORT_FLAGS += -mindirect-branch=thunk-inline - else - PIE_SUPPORT_FLAGS += -mindirect-branch=keep - endif + + NO_EXTERNAL_THUNKS := y OBJECT_FILES_NON_STANDARD := y endif ifeq "$(KERNEL_ARCH)" "arm" - PIE_FLAGS += -fno-unwind-tables + PIE_FLAGS += -fno-unwind-tables endif ifeq "$(KERNEL_ARCH)" "mips" - PIE_FLAGS += -mabicalls + PIE_FLAGS += -mabicalls endif - ccflags-y += $(PIE_SUPPORT_FLAGS) $(WOLFCRYPT_PIE_FILES): ccflags-y += $(PIE_FLAGS) $(WOLFCRYPT_PIE_FILES): ccflags-remove-y += -pg \ - $(call cc-option,-ftrivial-auto-var-init=zero) + $(call cc-option,-ftrivial-auto-var-init=zero) +endif + +# An explicit FORCE_GLOBAL_OBJTOOL_OFF is refused outright with clang -- the +# thunk repair below is gcc-only. +ifdef CONFIG_CC_IS_CLANG + ifdef FORCE_GLOBAL_OBJTOOL_OFF + $(error FORCE_GLOBAL_OBJTOOL_OFF is not supported with clang.) + endif endif -# On some kernels/configs, objtool runs and warns on the linked libwolfssl.o, -# ignoring the below "OBJECT_FILES_NON_STANDARD := y" annotations. This -# mechanism, activated with "make KBUILD_EXTRA_FLAGS=FORCE_GLOBAL_OBJTOOL_OFF=1", -# inhibits objtool completely. This may be necessary on modules compiled with -# assembly accelerations and/or ENABLED_LINUXKM_PIE. +# Similar to scripts/Makefile.lib delay-objtool: disable objtool on the kernels +# that run it on the linked object, ignoring OBJECT_FILES_NON_STANDARD. (Parse +# order prevents testing delay-objtool itself here: Makefile.build includes this +# file before Makefile.lib.) Auto-disablement is a gcc-only remedy, unavailable +# on clang, and objtool is mandatory to CONFIG_LTO_CLANG in any case. +ifndef CONFIG_CC_IS_CLANG + ifneq ($(or $(CONFIG_X86_KERNEL_IBT),$(CONFIG_KLP_BUILD)),) + ifeq "$(ENABLED_LINUXKM_PIE)" "yes" + FORCE_GLOBAL_OBJTOOL_OFF := y + else ifeq "$(ENABLED_ASM)" "yes" + FORCE_GLOBAL_OBJTOOL_OFF := y + endif + endif +endif + +# objtool disablement can be manually activated with "make +# KBUILD_EXTRA_FLAGS=FORCE_GLOBAL_OBJTOOL_OFF=1" ifdef FORCE_GLOBAL_OBJTOOL_OFF undefine CONFIG_OBJTOOL + # On <5.19, the knob is named CONFIG_STACK_VALIDATION. + undefine CONFIG_STACK_VALIDATION + NO_EXTERNAL_THUNKS := y endif +ifdef NO_EXTERNAL_THUNKS + ifeq "$(KERNEL_ARCH_X86)" "yes" + ifdef CONFIG_CC_IS_CLANG + # clang has no inline-thunk codegen (-mfunction-return accepts + # only keep/thunk-extern, and -mindirect-branch is a gcc-only + # spelling), so external thunk references are ineliminable when + # the mitigations are configured. + ifneq "$(CONFIG_MITIGATION_RETHUNK)$(CONFIG_MITIGATION_RETPOLINE)" "" + $(error NO_EXTERNAL_THUNKS requires gcc when retpoline/rethunk is configured.) + endif + else + ifeq "$(CONFIG_MITIGATION_RETHUNK)" "y" + PIE_SUPPORT_FLAGS += -mfunction-return=thunk-inline + else + PIE_SUPPORT_FLAGS += -mfunction-return=keep + endif + ifeq "$(CONFIG_MITIGATION_RETPOLINE)" "y" + PIE_SUPPORT_FLAGS += -mindirect-branch=thunk-inline -mindirect-branch-register + else + PIE_SUPPORT_FLAGS += -mindirect-branch=keep + endif + endif + endif +endif + +ccflags-y += $(PIE_SUPPORT_FLAGS) + ifdef KERNEL_EXTRA_CFLAGS_REMOVE ccflags-remove-y += $(KERNEL_EXTRA_CFLAGS_REMOVE) endif @@ -354,9 +407,9 @@ RENAME_PIE_TEXT_AND_DATA_SECTIONS := \ cd "$(obj)" || exit $$?; \ for file in $(WOLFCRYPT_PIE_FILES); do \ $(OBJCOPY) $$($(READELF) --sections --wide "$$file" | \ - $(AWK) ' \ + $(AWK) ' \ { \ - if (match($$0, "^ *\\[ *[0-9]+\\] +\\.(text|rodata|data|bss)(\\.[^ ]+)? ", a)) \ + if (match($$0, "^ *\\[ *[0-9]+\\] +\\.(text|rodata|data|bss)(\\.[^ ]+)? ", a)) \ { \ printf("--rename-section .%s%s=.%s_wolfcrypt ", \ a[1], a[2], a[1]); \ @@ -366,7 +419,7 @@ RENAME_PIE_TEXT_AND_DATA_SECTIONS := \ printf("--rename-section .%s.%s=.%s_wolfcrypt ", a[1], a[2], a[2]); \ } \ }') "$$file" || exit $$?; \ - done; \ + done; \ { $(READELF) --sections --syms --wide $(WOLFCRYPT_PIE_FILES) | \ $(AWK) -v obj="$(obj)" ' \ /^File:/ { \ diff --git a/src/pk.c b/src/pk.c index 8b91ff04268..19f1ca89179 100644 --- a/src/pk.c +++ b/src/pk.c @@ -1605,7 +1605,7 @@ WOLFSSL_DSA_SIG* wolfSSL_d2i_DSA_SIG(WOLFSSL_DSA_SIG **sig, #endif /* !HAVE_SELFTEST */ -int wolfssl_dsa_do_sign(const unsigned char* d, int dLen, +int wolfssl_local_dsa_do_sign(const unsigned char* d, int dLen, unsigned char* sigRet, WOLFSSL_DSA* dsa) { int ret = WC_NO_ERR_TRACE(WOLFSSL_FATAL_ERROR); @@ -1686,7 +1686,7 @@ int wolfSSL_DSA_do_sign(const unsigned char* d, unsigned char* sigRet, { WOLFSSL_ENTER("wolfSSL_DSA_do_sign"); - return wolfssl_dsa_do_sign(d, WC_SHA_DIGEST_SIZE, sigRet, dsa); + return wolfssl_local_dsa_do_sign(d, WC_SHA_DIGEST_SIZE, sigRet, dsa); } #ifndef HAVE_SELFTEST @@ -1704,7 +1704,7 @@ WOLFSSL_DSA_SIG* wolfSSL_DSA_do_sign_ex(const unsigned char* digest, return NULL; } - if (wolfssl_dsa_do_sign(digest, inLen, sigBin, dsa) != 1) { + if (wolfssl_local_dsa_do_sign(digest, inLen, sigBin, dsa) != 1) { WOLFSSL_MSG("wolfSSL_DSA_do_sign error"); return NULL; } @@ -1725,7 +1725,7 @@ WOLFSSL_DSA_SIG* wolfSSL_DSA_do_sign_ex(const unsigned char* digest, } #endif -int wolfssl_dsa_do_verify(const unsigned char* d, int dLen, unsigned char* sig, +int wolfssl_local_dsa_do_verify(const unsigned char* d, int dLen, unsigned char* sig, WOLFSSL_DSA* dsa, int *dsacheck) { int ret; @@ -1777,7 +1777,7 @@ int wolfSSL_DSA_do_verify(const unsigned char* d, unsigned char* sig, { WOLFSSL_ENTER("wolfSSL_DSA_do_verify"); - return wolfssl_dsa_do_verify(d, WC_SHA_DIGEST_SIZE, sig, dsa, dsacheck); + return wolfssl_local_dsa_do_verify(d, WC_SHA_DIGEST_SIZE, sig, dsa, dsacheck); } @@ -1854,7 +1854,7 @@ int wolfSSL_DSA_do_verify_ex(const unsigned char* digest, int digest_len, if (wolfSSL_BN_bn2bin(sig->s, sigBinPtr) == -1) return 0; - if ((wolfssl_dsa_do_verify(digest, digest_len, sigBin, dsa, &dsacheck) + if ((wolfssl_local_dsa_do_verify(digest, digest_len, sigBin, dsa, &dsacheck) != 1) || dsacheck != 1) { return 0; } diff --git a/tests/api/test_aes.c b/tests/api/test_aes.c index 7aeeceb83b4..c99de66a0c7 100644 --- a/tests/api/test_aes.c +++ b/tests/api/test_aes.c @@ -14683,10 +14683,6 @@ int test_wc_AesGcm_PrimitiveFailureCleanup(void) const byte zeros[5 * WC_AES_BLOCK_SIZE] = {0}; byte tag[WC_AES_BLOCK_SIZE]; int ret; -#ifdef WOLFSSL_AESGCM_STREAM - byte in[17] = {0}; - byte out[17]; -#endif XMEMSET(&aes, 0, sizeof(aes)); ExpectIntEQ(wc_AesInit(&aes, NULL, INVALID_DEVID), 0); @@ -14701,21 +14697,26 @@ int test_wc_AesGcm_PrimitiveFailureCleanup(void) return TEST_SKIPPED; /* backend does not use the portable primitive */ } ExpectBufEQ(tag, zeros, sizeof(tag)); -#ifdef WOLFSSL_AESGCM_STREAM - ExpectIntEQ(wc_AesGcmEncryptInit(&aes, key, sizeof(key), iv, sizeof(iv)), 0); - /* Retain fifteen bytes of keystream, then fail generating the next block. */ - ExpectIntEQ(wc_AesGcmEncryptUpdate(&aes, out, in, 1, NULL, 0), 0); - aes.rounds = 0; - ExpectIntEQ(wc_AesGcmEncryptUpdate(&aes, out, in, sizeof(in), NULL, 0), - WC_NO_ERR_TRACE(KEYUSAGE_E)); - ExpectBufEQ(aes.streamData, zeros, sizeof(zeros)); - ExpectIntEQ(aes.nonceSet, 0); - ExpectIntEQ(aes.over, 0); - /* A failed stream must require reinitialization. */ - ExpectIntLT(wc_AesGcmEncryptUpdate(&aes, out, in, 1, NULL, 0), 0); - ExpectIntEQ(wc_AesGcmEncryptInit(&aes, key, sizeof(key), iv, sizeof(iv)), 0); - ExpectIntEQ(wc_AesGcmEncryptUpdate(&aes, out, in, sizeof(in), NULL, 0), 0); - ExpectIntEQ(wc_AesGcmEncryptFinal(&aes, tag, sizeof(tag)), 0); +#if defined(WOLFSSL_AESGCM_STREAM) && \ + (!defined(HAVE_FIPS) || FIPS_VERSION3_GE(7,0,0)) + { + byte in[17] = {0}; + byte out[17]; + ExpectIntEQ(wc_AesGcmEncryptInit(&aes, key, sizeof(key), iv, sizeof(iv)), 0); + /* Retain fifteen bytes of keystream, then fail generating the next block. */ + ExpectIntEQ(wc_AesGcmEncryptUpdate(&aes, out, in, 1, NULL, 0), 0); + aes.rounds = 0; + ExpectIntEQ(wc_AesGcmEncryptUpdate(&aes, out, in, sizeof(in), NULL, 0), + WC_NO_ERR_TRACE(KEYUSAGE_E)); + ExpectBufEQ(aes.streamData, zeros, sizeof(zeros)); + ExpectIntEQ(aes.nonceSet, 0); + ExpectIntEQ(aes.over, 0); + /* A failed stream must require reinitialization. */ + ExpectIntLT(wc_AesGcmEncryptUpdate(&aes, out, in, 1, NULL, 0), 0); + ExpectIntEQ(wc_AesGcmEncryptInit(&aes, key, sizeof(key), iv, sizeof(iv)), 0); + ExpectIntEQ(wc_AesGcmEncryptUpdate(&aes, out, in, sizeof(in), NULL, 0), 0); + ExpectIntEQ(wc_AesGcmEncryptFinal(&aes, tag, sizeof(tag)), 0); + } #endif wc_AesFree(&aes); #else diff --git a/tests/api/test_kdf.c b/tests/api/test_kdf.c index 86ce87f6d36..4ba02505107 100644 --- a/tests/api/test_kdf.c +++ b/tests/api/test_kdf.c @@ -64,7 +64,7 @@ * dispatch-taken-and-succeeds), both within this one registered devId. */ static int test_kdf_cryptocb_force_fail = 0; -static int test_kdf_cryptocb(int cbDevId, wc_CryptoInfo* info, void* ctx) +static WC_MAYBE_UNUSED int test_kdf_cryptocb(int cbDevId, wc_CryptoInfo* info, void* ctx) { (void)ctx; if (cbDevId != TEST_KDF_CRYPTOCB_DEVID) @@ -939,7 +939,13 @@ int test_wc_KdfFeatureCoverage(void) int test_wc_SshKdfReuse(void) { EXPECT_DECLS; -#if defined(WOLFSSL_WOLFSSH) && !defined(NO_HMAC) + /* Note, must skip on old FIPS with _SMALL_STACK_CACHE, due to leak in + * wc_SSH_KDF() via _HashInit() over already-initialized hash, fixed by + * 827807d2efd. */ +#if defined(WOLFSSL_WOLFSSH) && !defined(NO_HMAC) && \ + (!defined(HAVE_FIPS) || \ + FIPS_VERSION3_GE(7,0,0) || \ + !defined(WOLFSSL_SMALL_STACK_CACHE)) static const struct { byte hashId; const char* expected; diff --git a/tests/api/test_ossl_rand.c b/tests/api/test_ossl_rand.c index 6152bf0965a..fcca4a146ff 100644 --- a/tests/api/test_ossl_rand.c +++ b/tests/api/test_ossl_rand.c @@ -231,7 +231,9 @@ int test_wolfSSL_RAND_bytes(void) ok = (RAND_bytes(randbuf, sizeof(randbuf)) == 1); n_written = write(pipefds[1], randbuf, sizeof(randbuf)); close(pipefds[1]); - exit((ok && n_written == sizeof(randbuf)) ? 0 : 1); + /* Must terminate via _exit() to avoid provoking LSAN via the atexit + * handlers. */ + _exit((ok && n_written == sizeof(randbuf)) ? 0 : 1); } else if (pid > 0) { /* Parent process. */ diff --git a/tests/api/test_ossl_x509_str.c b/tests/api/test_ossl_x509_str.c index 41b67bbbf0d..367f39a76f9 100644 --- a/tests/api/test_ossl_x509_str.c +++ b/tests/api/test_ossl_x509_str.c @@ -391,14 +391,18 @@ int test_wolfSSL_X509_verify_cert_crl_date_override(void) static int test_crl_date_cb_waive[2]; static int test_crl_date_cb_seen[4]; static int test_crl_date_cb_calls; +#ifdef OPENSSL_ALL static int test_crl_date_cb_ok_calls; +#endif static int test_crl_date_verify_cb(int ok, X509_STORE_CTX* ctx) { int err = X509_STORE_CTX_get_error(ctx); if (ok) { +#ifdef OPENSSL_ALL test_crl_date_cb_ok_calls++; +#endif return ok; } if (test_crl_date_cb_calls < 4) @@ -417,7 +421,9 @@ static int test_crl_date_verify(X509_STORE* store, X509* cert, int waive0, test_crl_date_cb_waive[0] = waive0; test_crl_date_cb_waive[1] = waive1; test_crl_date_cb_calls = 0; +#ifdef OPENSSL_ALL test_crl_date_cb_ok_calls = 0; +#endif XMEMSET(test_crl_date_cb_seen, 0, sizeof(test_crl_date_cb_seen)); if ((storeCtx != NULL) && (X509_STORE_CTX_init(storeCtx, store, cert, NULL) == diff --git a/tests/api/test_sha512.c b/tests/api/test_sha512.c index 7e09fdc6d7c..e44aac331d9 100644 --- a/tests/api/test_sha512.c +++ b/tests/api/test_sha512.c @@ -909,7 +909,7 @@ typedef struct { * SHA-512 callback; that callback fills a recognisable digest and deliberately * leaves the SHA-512 IV in the caller's state, forcing the dispatcher to reset * the state back to the variant IV. */ -static int sha512_dev_cb(int devIdArg, wc_CryptoInfo* info, void* ctx) +static WC_MAYBE_UNUSED int sha512_dev_cb(int devIdArg, wc_CryptoInfo* info, void* ctx) { Sha512DevCbCtx* cbCtx = (Sha512DevCbCtx*)ctx; int i; diff --git a/wolfcrypt/benchmark/benchmark.c b/wolfcrypt/benchmark/benchmark.c index 5e5c347a49e..08cca2c40d6 100644 --- a/wolfcrypt/benchmark/benchmark.c +++ b/wolfcrypt/benchmark/benchmark.c @@ -12849,12 +12849,11 @@ static void bench_frodokem_keygen(int type, const char* name, int keySize, do { /* while free pending slots in queue, submit ops */ for (times = 0; times < agreeTimes || pending > 0; times++) { - wc_FrodoKemKey_Free(key); ret = wc_FrodoKemKey_Init(key, type, HEAP_HINT, INVALID_DEVID); if (ret != 0) goto exit; - ret = wc_FrodoKemKey_MakeKey(key, &gRng); + wc_FrodoKemKey_Free(key); if (ret != 0) goto exit; RECORD_MULTI_VALUE_STATS(); @@ -12884,6 +12883,7 @@ static void bench_frodokem_keygen(int type, const char* name, int keySize, static void bench_frodokem_encap(int type, const char* name, int keySize, FrodoKemKey* key1, FrodoKemKey* key2) { +#ifndef WOLFSSL_FRODOKEM_NO_MAKE_KEY int ret = 0, times, count, pending = 0; double start; const char**desc = bench_desc_words[lng_index]; @@ -12900,6 +12900,14 @@ static void bench_frodokem_encap(int type, const char* name, int keySize, WC_ALLOC_VAR(ss, byte, FRODOKEM_MAX_LENSEC, HEAP_HINT); WC_ALLOC_VAR(pub, byte, FRODOKEM_MAX_PUBLIC_KEY_SIZE, HEAP_HINT); + ret = wc_FrodoKemKey_Init(key1, type, HEAP_HINT, INVALID_DEVID); + if (ret != 0) + goto exit; + + ret = wc_FrodoKemKey_MakeKey(key1, &gRng); + if (ret != 0) + goto exit; + ret = wc_FrodoKemKey_PublicKeySize(key1, &pubLen); if (ret != 0) { goto exit; @@ -12979,6 +12987,9 @@ static void bench_frodokem_encap(int type, const char* name, int keySize, exit: + wc_FrodoKemKey_Free(key2); + wc_FrodoKemKey_Free(key1); + WC_FREE_VAR(ct, HEAP_HINT); WC_FREE_VAR(ss, HEAP_HINT); WC_FREE_VAR(pub, HEAP_HINT); @@ -12987,6 +12998,13 @@ static void bench_frodokem_encap(int type, const char* name, int keySize, printf("error: bench_frodokem_encap() failed with code %d.\n", ret); return; +#else + (void)type; + (void)name; + (void)keySize; + (void)key1; + (void)key2; +#endif /* !WOLFSSL_FRODOKEM_NO_MAKE_KEY */ } #endif @@ -13057,10 +13075,14 @@ void bench_frodokem(int type) } #endif - /* Zero the key objects so the wc_FrodoKemKey_Free calls below are safe even - * if a benchmark helper returns before initializing its key. */ + /* Zero the key objects so wc_FrodoKemKey_Free calls are safe even + * if a benchmark helper cleans up before initializing its key. */ XMEMSET(key1, 0, sizeof(*key1)); XMEMSET(key2, 0, sizeof(*key2)); +#ifdef WOLF_CRYPTO_CB + key1->devId = INVALID_DEVID; + key2->devId = INVALID_DEVID; +#endif for (v = 0; v < sizeof(mods) / sizeof(mods[0]); v++) { int mod = mods[v]; @@ -13080,9 +13102,6 @@ void bench_frodokem(int type) #endif } - wc_FrodoKemKey_Free(key2); - wc_FrodoKemKey_Free(key1); - WC_FREE_VAR_EX(key1, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); WC_FREE_VAR_EX(key2, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); } diff --git a/wolfcrypt/src/evp.c b/wolfcrypt/src/evp.c index 1828f4d94b6..952e4d785e5 100644 --- a/wolfcrypt/src/evp.c +++ b/wolfcrypt/src/evp.c @@ -3510,12 +3510,12 @@ int wolfSSL_EVP_PKEY_sign(WOLFSSL_EVP_PKEY_CTX *ctx, unsigned char *sig, } if ((int)*siglen < bytes) return WOLFSSL_FAILURE; - /* wolfssl_dsa_do_sign() takes the length as an int, and wolfCrypt + /* wolfssl_local_dsa_do_sign() takes the length as an int, and wolfCrypt * rejects anything longer than this anyway. */ if (tbslen > WC_MAX_DIGEST_SIZE) return WOLFSSL_FAILURE; - ret = wolfssl_dsa_do_sign(tbs, (int)tbslen, sig, ctx->pkey->dsa); - /* wolfssl_dsa_do_sign() can return WOLFSSL_FATAL_ERROR */ + ret = wolfssl_local_dsa_do_sign(tbs, (int)tbslen, sig, ctx->pkey->dsa); + /* wolfssl_local_dsa_do_sign() can return WOLFSSL_FATAL_ERROR */ if (ret != WOLFSSL_SUCCESS) return ret; if (bytes == WC_NO_ERR_TRACE(WOLFSSL_FAILURE)) @@ -3645,11 +3645,11 @@ int wolfSSL_EVP_PKEY_verify(WOLFSSL_EVP_PKEY_CTX *ctx, const unsigned char *sig, bytes = wolfSSL_BN_num_bytes(ctx->pkey->dsa->q); if (bytes <= 0 || siglen < (size_t)bytes * 2) return WOLFSSL_FAILURE; - /* wolfssl_dsa_do_verify() takes the length as an int, and wolfCrypt + /* wolfssl_local_dsa_do_verify() takes the length as an int, and wolfCrypt * rejects anything longer than this anyway. */ if (tbslen > WC_MAX_DIGEST_SIZE) return WOLFSSL_FAILURE; - if (wolfssl_dsa_do_verify(tbs, (int)tbslen, (unsigned char *)sig, + if (wolfssl_local_dsa_do_verify(tbs, (int)tbslen, (unsigned char *)sig, ctx->pkey->dsa, &dsacheck) != WOLFSSL_SUCCESS || dsacheck != 1) return WOLFSSL_FAILURE; return WOLFSSL_SUCCESS; @@ -4668,8 +4668,8 @@ int wolfSSL_EVP_SignFinal(WOLFSSL_EVP_MD_CTX *ctx, unsigned char *sigret, { return WOLFSSL_FAILURE; } - ret = wolfssl_dsa_do_sign(md, (int)mdsize, sigret, pkey->dsa); - /* wolfssl_dsa_do_sign() can return WOLFSSL_FATAL_ERROR */ + ret = wolfssl_local_dsa_do_sign(md, (int)mdsize, sigret, pkey->dsa); + /* wolfssl_local_dsa_do_sign() can return WOLFSSL_FATAL_ERROR */ if (ret != WOLFSSL_SUCCESS) return ret; *siglen = (unsigned int)(bytes * 2); diff --git a/wolfcrypt/src/hpke.c b/wolfcrypt/src/hpke.c index 759e37a6d2a..8bbc06c9819 100644 --- a/wolfcrypt/src/hpke.c +++ b/wolfcrypt/src/hpke.c @@ -961,6 +961,8 @@ static int wc_HpkeSetupBaseSender(Hpke* hpke, HpkeBaseContext* context, int wc_HpkeInitSealContext(Hpke* hpke, HpkeBaseContext* context, void* ephemeralKey, void* receiverKey, byte* info, word32 infoSz) { + int ret; + if (hpke == NULL || context == NULL || ephemeralKey == NULL || receiverKey == NULL || (info == NULL && infoSz != 0)) { return BAD_FUNC_ARG; @@ -969,8 +971,14 @@ int wc_HpkeInitSealContext(Hpke* hpke, HpkeBaseContext* context, /* zero out all fields */ XMEMSET(context, 0, sizeof(HpkeBaseContext)); - return wc_HpkeSetupBaseSender(hpke, context, ephemeralKey, receiverKey, + /* the derived secrets are consumed internally -- do the FIPS + * private-key unlock for the caller, as wc_HpkeSealBase() does. */ + PRIVATE_KEY_UNLOCK(); + ret = wc_HpkeSetupBaseSender(hpke, context, ephemeralKey, receiverKey, info, infoSz); + PRIVATE_KEY_LOCK(); + + return ret; } /* encrypt a message using an hpke base context, return 0 or error. @@ -1403,13 +1411,21 @@ int wc_HpkeInitOpenContext(Hpke* hpke, HpkeBaseContext* context, void* receiverKey, const byte* pubKey, word16 pubKeySz, byte* info, word32 infoSz) { + int ret; + if (hpke == NULL || context == NULL || receiverKey == NULL || pubKey == NULL || (info == NULL && infoSz != 0)) { return BAD_FUNC_ARG; } - return wc_HpkeSetupBaseReceiver(hpke, context, receiverKey, pubKey, + /* the derived secrets are consumed internally -- do the FIPS + * private-key unlock for the caller, as wc_HpkeOpenBase() does. */ + PRIVATE_KEY_UNLOCK(); + ret = wc_HpkeSetupBaseReceiver(hpke, context, receiverKey, pubKey, pubKeySz, info, infoSz); + PRIVATE_KEY_LOCK(); + + return ret; } /* decrypt a message using a setup hpke context, return 0 or error */ diff --git a/wolfcrypt/src/pkcs7.c b/wolfcrypt/src/pkcs7.c index c917fd8ab84..ced0ee4e6d6 100644 --- a/wolfcrypt/src/pkcs7.c +++ b/wolfcrypt/src/pkcs7.c @@ -10930,8 +10930,12 @@ static int wc_PKCS7_GenerateKEK_PWRI(wc_PKCS7* pkcs7, byte* passwd, word32 pLen, case PBKDF2_OID: + /* The KEK is consumed internally to wrap/unwrap the CEK -- do + * the FIPS private-key unlock for the caller. */ + PRIVATE_KEY_UNLOCK(); ret = wc_PBKDF2(out, passwd, (int)pLen, salt, (int)saltSz, iterations, (int)outSz, prfOID); + PRIVATE_KEY_LOCK(); if (ret != 0) { return ret; } diff --git a/wolfcrypt/src/rng_bank.c b/wolfcrypt/src/rng_bank.c index 4901857162b..790640955a4 100644 --- a/wolfcrypt/src/rng_bank.c +++ b/wolfcrypt/src/rng_bank.c @@ -309,8 +309,19 @@ WOLFSSL_API int wc_rng_bank_init_nonce( wc_RNG_lock_put(&ctx->root_rng, 0); #endif - if (ret != 0) + if (ret != 0) { +#if defined(WC_RNG_HAVE_LOCK) && defined(WC_RNG_BANK_HAVE_ROOT_RNG) + /* A root init that failed under WC_RNG_INIT_FLAG_LOCK_INITIALLY (e.g. + * instantiation refused in FIPS error state) dies holding the root's + * lock with no owner to release it -- root_rng_locked is only set on + * success. Release it unconditionally, or the fini below refuses + * with BUSY_E at its root-lock check and ctx->rngs is leaked, with + * every subsequent fini refused the same way. */ + if (! root_rng_locked) + wc_RNG_lock_put_unconditional(&ctx->root_rng); +#endif (void)wc_rng_bank_fini(ctx); + } return ret; } @@ -3112,8 +3123,12 @@ static int wc_InitRng_BankRef_local(struct wc_rng_bank *bank, WC_RNG **rng) { XMEMSET(*rng, 0, sizeof(**rng)); (*rng)->heap = bank->heap; - (*rng)->flags |= WC_RNG_FLAG_BANKREF; (*rng)->bankref = bank; +#if defined(HAVE_FIPS) && FIPS_VERSION3_LT(7,0,0) + (*rng)->status = WC_DRBG_BANKREF; +#else + (*rng)->flags |= WC_RNG_FLAG_BANKREF; +#endif ret = 0; @@ -3144,8 +3159,13 @@ WOLFSSL_API int wc_BankRef_Release(WC_RNG *rng) int ret = 0; if (rng == NULL) return BAD_FUNC_ARG; +#if defined(HAVE_FIPS) && FIPS_VERSION3_LT(7,0,0) + if (rng->status != WC_DRBG_BANKREF) + return WRONG_TYPE_OBJECT_E; +#else if (! (rng->flags & WC_RNG_FLAG_BANKREF)) return WRONG_TYPE_OBJECT_E; +#endif if (rng->bankref == NULL) return BAD_FUNC_ARG; wolfSSL_RefDec(&rng->bankref->refcount, &isZero, &ret); @@ -3157,7 +3177,11 @@ WOLFSSL_API int wc_BankRef_Release(WC_RNG *rng) (void)isZero; #endif rng->heap = NULL; +#if defined(HAVE_FIPS) && FIPS_VERSION3_LT(7,0,0) + rng->status = WC_DRBG_NOT_INIT; +#else rng->flags &= ~WC_RNG_FLAG_BANKREF; +#endif rng->bankref = NULL; return ret; } diff --git a/wolfcrypt/test/test.c b/wolfcrypt/test/test.c index ff02ebaa7a2..68746a3eaa1 100644 --- a/wolfcrypt/test/test.c +++ b/wolfcrypt/test/test.c @@ -3047,9 +3047,7 @@ options: [-s max_relative_stack_bytes] [-m max_relative_heap_memory_bytes]\n\ #endif #if defined(HAVE_HKDF) && !defined(NO_HMAC) - PRIVATE_KEY_UNLOCK(); ret = hkdf_test(); - PRIVATE_KEY_LOCK(); if (ret != 0) TEST_FAIL("HMAC-KDF test failed!\n", ret); else @@ -3058,9 +3056,7 @@ options: [-s max_relative_stack_bytes] [-m max_relative_heap_memory_bytes]\n\ #endif /* !NO_HMAC */ #ifdef WOLFSSL_WOLFSSH - PRIVATE_KEY_UNLOCK(); ret = sshkdf_test(); - PRIVATE_KEY_LOCK(); if (ret != 0) TEST_FAIL("SSH-KDF test failed!\n", ret); else @@ -3069,9 +3065,7 @@ options: [-s max_relative_stack_bytes] [-m max_relative_heap_memory_bytes]\n\ #if defined(WOLFSSL_HAVE_PRF) && !defined(NO_HMAC) && \ defined(WOLFSSL_SHA384) && !defined(WOLFSSL_NO_TLS12) - PRIVATE_KEY_UNLOCK(); ret = prf_test(); - PRIVATE_KEY_LOCK(); if (ret != 0) TEST_FAIL("PRF test failed!\n", ret); else @@ -3080,9 +3074,7 @@ options: [-s max_relative_stack_bytes] [-m max_relative_heap_memory_bytes]\n\ #if defined(WOLFSSL_HAVE_PRF) && defined(HAVE_HKDF) && !defined(NO_HMAC) && \ defined(WOLFSSL_BASE16) && !defined(WOLFSSL_NO_TLS12) - PRIVATE_KEY_UNLOCK(); ret = tls12_kdf_test(); - PRIVATE_KEY_LOCK(); if (ret != 0) TEST_FAIL("TLSv1.2 KDF test failed!\n", ret); else @@ -3091,9 +3083,7 @@ options: [-s max_relative_stack_bytes] [-m max_relative_heap_memory_bytes]\n\ /* WOLFSSL_BASE16 && !WOLFSSL_NO_TLS12 */ #if defined(WOLFSSL_TLS13) && !defined(NO_HMAC) - PRIVATE_KEY_UNLOCK(); ret = tls13_kdf_test(); - PRIVATE_KEY_LOCK(); if (ret != 0) TEST_FAIL("TLSv1.3 KDF test failed!\n", ret); else @@ -3111,9 +3101,7 @@ options: [-s max_relative_stack_bytes] [-m max_relative_heap_memory_bytes]\n\ (defined(HAVE_ECC) || defined(HAVE_CURVE25519) || \ defined(HAVE_CURVE448)) && \ defined(HAVE_AESGCM) - PRIVATE_KEY_UNLOCK(); ret = hpke_test(); - PRIVATE_KEY_LOCK(); if (ret != 0) TEST_FAIL("HPKE test failed!\n", ret); else @@ -3121,9 +3109,7 @@ options: [-s max_relative_stack_bytes] [-m max_relative_heap_memory_bytes]\n\ #endif #if defined(WC_SRTP_KDF) - PRIVATE_KEY_UNLOCK(); ret = srtpkdf_test(); - PRIVATE_KEY_LOCK(); if (ret != 0) TEST_FAIL("SRTP KDF test failed!\n", ret); else @@ -3407,9 +3393,7 @@ options: [-s max_relative_stack_bytes] [-m max_relative_heap_memory_bytes]\n\ #endif #ifndef NO_DH - PRIVATE_KEY_UNLOCK(); ret = dh_test(); - PRIVATE_KEY_LOCK(); if (ret != 0) TEST_FAIL("DH test failed!\n", ret); @@ -3432,9 +3416,7 @@ options: [-s max_relative_stack_bytes] [-m max_relative_heap_memory_bytes]\n\ #endif #ifndef NO_PWDBASED - PRIVATE_KEY_UNLOCK(); ret = pwdbased_test(); - PRIVATE_KEY_LOCK(); if (ret != 0) TEST_FAIL("PWDBASED test failed!\n", ret); else @@ -3489,9 +3471,7 @@ options: [-s max_relative_stack_bytes] [-m max_relative_heap_memory_bytes]\n\ #endif #if defined(HAVE_ECC) - PRIVATE_KEY_UNLOCK(); ret = ecc_test(); - PRIVATE_KEY_LOCK(); if (ret != 0) TEST_FAIL("ECC test failed!\n", ret); else @@ -3614,9 +3594,7 @@ options: [-s max_relative_stack_bytes] [-m max_relative_heap_memory_bytes]\n\ #if defined(HAVE_ED25519) && \ (!defined(WOLF_CRYPTO_CB_ONLY_ED25519) || defined(WOLFSSL_SWDEV)) - PRIVATE_KEY_UNLOCK(); ret = ed25519_test(); - PRIVATE_KEY_LOCK(); if (ret != 0) TEST_FAIL("ED25519 test failed!\n", ret); else @@ -3632,9 +3610,7 @@ options: [-s max_relative_stack_bytes] [-m max_relative_heap_memory_bytes]\n\ #endif #ifdef HAVE_ED448 - PRIVATE_KEY_UNLOCK(); ret = ed448_test(); - PRIVATE_KEY_LOCK(); if (ret != 0) TEST_FAIL("ED448 test failed!\n", ret); else @@ -3642,9 +3618,7 @@ options: [-s max_relative_stack_bytes] [-m max_relative_heap_memory_bytes]\n\ #endif #ifdef WOLFSSL_HAVE_MLKEM - PRIVATE_KEY_UNLOCK(); ret = mlkem_test(); - PRIVATE_KEY_LOCK(); if (ret != 0) TEST_FAIL("MLKEM test failed!\n", ret); else @@ -3659,9 +3633,7 @@ options: [-s max_relative_stack_bytes] [-m max_relative_heap_memory_bytes]\n\ #endif #ifdef WOLFSSL_HAVE_MLDSA - PRIVATE_KEY_UNLOCK(); ret = mldsa_test(); - PRIVATE_KEY_LOCK(); if (ret != 0) TEST_FAIL("ML-DSA test failed!\n", ret); else @@ -3669,9 +3641,7 @@ options: [-s max_relative_stack_bytes] [-m max_relative_heap_memory_bytes]\n\ #endif #ifdef HAVE_FALCON - PRIVATE_KEY_UNLOCK(); ret = falcon_test(); - PRIVATE_KEY_LOCK(); if (ret != 0) TEST_FAIL("Falcon test failed!\n", ret); else @@ -3789,18 +3759,14 @@ options: [-s max_relative_stack_bytes] [-m max_relative_heap_memory_bytes]\n\ else TEST_PASS("PKCS7signed test passed!\n"); - PRIVATE_KEY_UNLOCK(); ret = pkcs7enveloped_test(); - PRIVATE_KEY_LOCK(); if (ret != 0) TEST_FAIL("PKCS7enveloped test failed!\n", ret); else TEST_PASS("PKCS7enveloped test passed!\n"); #if defined(HAVE_AESGCM) || defined(HAVE_AESCCM) - PRIVATE_KEY_UNLOCK(); ret = pkcs7authenveloped_test(); - PRIVATE_KEY_LOCK(); if (ret != 0) TEST_FAIL("PKCS7authenveloped test failed!\n", ret); else @@ -29632,11 +29598,19 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t XChaCha20Poly1305_test(void) #define RNG_STATS_EXPECT_SAME_DELTA(rng, f1, f2, fail_action) WC_DO_NOTHING #endif /* WC_RNG_DEBUG_STATS */ -#if !defined(HAVE_SELFTEST) && \ - (!defined(HAVE_FIPS) || FIPS_VERSION3_GE(7,0,0)) - #define RESEED_CTR(rng) (((rng) != NULL) ? (rng)->reseedCtr : \ - ~((wc_drbg_reseed_ctr_t)0)) - #define RESEED_CTR_LVAL(rng) ((rng)->reseedCtr) +#ifdef WC_DRBG_RESEED_CTR_TYPE_DEFINED + #if !defined(HAVE_SELFTEST) && \ + (!defined(HAVE_FIPS) || FIPS_VERSION3_GE(7,0,0)) + static WC_INLINE wc_drbg_reseed_ctr_t RESEED_CTR(WC_RNG *rng) { + return ((rng) != NULL) ? (rng)->reseedCtr : ~((wc_drbg_reseed_ctr_t)0); + } + #define RESEED_CTR_LVAL(rng) ((rng)->reseedCtr) + #else + static WC_INLINE wc_drbg_reseed_ctr_t RESEED_CTR(WC_RNG *rng) { + return ((rng) != NULL) ? ((struct DRBG_internal *)(rng)->drbg)->reseedCtr : ~((wc_drbg_reseed_ctr_t)0); + } + #define RESEED_CTR_LVAL(rng) (((struct DRBG_internal *)(rng)->drbg)->reseedCtr) + #endif #else #define RESEED_CTR(rng) (((rng) != NULL) ? \ ((struct DRBG_internal *)(rng)->drbg)->reseedCtr : ~0U) @@ -32727,7 +32701,8 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t random_bank_test(void) defined(HAVE_FIPS) && \ FIPS_VERSION3_LT(7,0,0) && \ !defined(DEBUG_VECTOR_REGISTER_ACCESS_ALWAYS_ON) && \ - defined(WC_SVR_HAVE_FLAGS) + defined(WC_SVR_HAVE_FLAGS) && \ + !defined(WC_SVR_USE_NATIVE_REG_BUFS) #ifdef WOLFSSL_DRBG_SHA512 if (rng_inst->rng.drbgType == WC_DRBG_SHA512) { @@ -32740,7 +32715,7 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t random_bank_test(void) if (((struct DRBG_internal *)rng_inst->rng.drbg)->sha256.sha_method != 7 /* SHA256_C */) ERROR_OUT(WC_TEST_RET_ENC_I(((struct DRBG_internal *)rng_inst->rng.drbg)->sha256.sha_method), out); } -#endif /* USE_INTEL_SPEEDUP && ... && !DEBUG_VECTOR_REGISTER_ACCESS_ALWAYS_ON */ +#endif /* USE_INTEL_SPEEDUP && ... && !WC_SVR_USE_NATIVE_REG_BUFS */ ret = wc_RNG_GenerateBlock(WC_RNG_BANK_INST_TO_RNG(rng_inst), outbuf1, sizeof(outbuf1)); if (ret != 0) @@ -44231,22 +44206,34 @@ static wc_test_ret_t dh_fips_generate_test(WC_RNG *rng) #endif /* Parameter Validation testing. */ + PRIVATE_KEY_UNLOCK(); ret = wc_DhGenerateKeyPair(NULL, rng, priv, &privSz, pub, &pubSz); + PRIVATE_KEY_LOCK(); if (ret != WC_NO_ERR_TRACE(BAD_FUNC_ARG)) ERROR_OUT(WC_TEST_RET_ENC_EC(ret), exit_gen_test); + PRIVATE_KEY_UNLOCK(); ret = wc_DhGenerateKeyPair(key, NULL, priv, &privSz, pub, &pubSz); + PRIVATE_KEY_LOCK(); if (ret != WC_NO_ERR_TRACE(BAD_FUNC_ARG)) ERROR_OUT(WC_TEST_RET_ENC_EC(ret), exit_gen_test); + PRIVATE_KEY_UNLOCK(); ret = wc_DhGenerateKeyPair(key, rng, NULL, &privSz, pub, &pubSz); + PRIVATE_KEY_LOCK(); if (ret != WC_NO_ERR_TRACE(BAD_FUNC_ARG)) ERROR_OUT(WC_TEST_RET_ENC_EC(ret), exit_gen_test); + PRIVATE_KEY_UNLOCK(); ret = wc_DhGenerateKeyPair(key, rng, priv, NULL, pub, &pubSz); + PRIVATE_KEY_LOCK(); if (ret != WC_NO_ERR_TRACE(BAD_FUNC_ARG)) ERROR_OUT(WC_TEST_RET_ENC_EC(ret), exit_gen_test); + PRIVATE_KEY_UNLOCK(); ret = wc_DhGenerateKeyPair(key, rng, priv, &privSz, NULL, &pubSz); + PRIVATE_KEY_LOCK(); if (ret != WC_NO_ERR_TRACE(BAD_FUNC_ARG)) ERROR_OUT(WC_TEST_RET_ENC_EC(ret), exit_gen_test); + PRIVATE_KEY_UNLOCK(); ret = wc_DhGenerateKeyPair(key, rng, priv, &privSz, pub, NULL); + PRIVATE_KEY_LOCK(); if (ret != WC_NO_ERR_TRACE(BAD_FUNC_ARG)) ERROR_OUT(WC_TEST_RET_ENC_EC(ret), exit_gen_test); @@ -44269,7 +44256,9 @@ static wc_test_ret_t dh_fips_generate_test(WC_RNG *rng) ERROR_OUT(WC_TEST_RET_ENC_EC(ret), exit_gen_test); /* Use API. */ + PRIVATE_KEY_UNLOCK(); ret = wc_DhGenerateKeyPair(key, rng, priv, &privSz, pub, &pubSz); + PRIVATE_KEY_LOCK(); #if defined(WOLFSSL_ASYNC_CRYPT) ret = wc_AsyncWait(ret, &key->asyncDev, WC_ASYNC_FLAG_NONE); #endif @@ -44339,7 +44328,9 @@ static wc_test_ret_t dh_fips_generate_test(WC_RNG *rng) privSz = sizeof(priv); pubSz = sizeof(pub); + PRIVATE_KEY_UNLOCK(); ret = wc_DhGenerateKeyPair(key, rng, priv, &privSz, pub, &pubSz); + PRIVATE_KEY_LOCK(); #if defined(WOLFSSL_ASYNC_CRYPT) ret = wc_AsyncWait(ret, &key->asyncDev, WC_ASYNC_FLAG_NONE); #endif @@ -44450,7 +44441,9 @@ static wc_test_ret_t dh_generate_test(WC_RNG *rng) privSz = sizeof(priv); pubSz = sizeof(pub); + PRIVATE_KEY_UNLOCK(); ret = wc_DhGenerateKeyPair(smallKey, rng, priv, &privSz, pub, &pubSz); + PRIVATE_KEY_LOCK(); #if defined(WOLFSSL_ASYNC_CRYPT) ret = wc_AsyncWait(ret, &smallKey->asyncDev, WC_ASYNC_FLAG_NONE); #endif @@ -44650,28 +44643,36 @@ static wc_test_ret_t dh_ffdhe_test(WC_RNG *rng, int name) if (ret != 0) ERROR_OUT(WC_TEST_RET_ENC_EC(ret), done); + PRIVATE_KEY_UNLOCK(); ret = wc_DhGenerateKeyPair(key, rng, priv, &privSz, pub, &pubSz); + PRIVATE_KEY_LOCK(); #if defined(WOLFSSL_ASYNC_CRYPT) ret = wc_AsyncWait(ret, &key->asyncDev, WC_ASYNC_FLAG_NONE); #endif if (ret != 0) ERROR_OUT(WC_TEST_RET_ENC_EC(ret), done); + PRIVATE_KEY_UNLOCK(); ret = wc_DhGenerateKeyPair(key2, rng, priv2, &privSz2, pub2, &pubSz2); + PRIVATE_KEY_LOCK(); #if defined(WOLFSSL_ASYNC_CRYPT) ret = wc_AsyncWait(ret, &key2->asyncDev, WC_ASYNC_FLAG_NONE); #endif if (ret != 0) ERROR_OUT(WC_TEST_RET_ENC_EC(ret), done); + PRIVATE_KEY_UNLOCK(); ret = wc_DhAgree(key, agree, &agreeSz, priv, privSz, pub2, pubSz2); + PRIVATE_KEY_LOCK(); #if defined(WOLFSSL_ASYNC_CRYPT) ret = wc_AsyncWait(ret, &key->asyncDev, WC_ASYNC_FLAG_NONE); #endif if (ret != 0) ERROR_OUT(WC_TEST_RET_ENC_EC(ret), done); + PRIVATE_KEY_UNLOCK(); ret = wc_DhAgree(key2, agree2, &agreeSz2, priv2, privSz2, pub, pubSz); + PRIVATE_KEY_LOCK(); #if defined(WOLFSSL_ASYNC_CRYPT) ret = wc_AsyncWait(ret, &key2->asyncDev, WC_ASYNC_FLAG_NONE); #endif @@ -44693,6 +44694,7 @@ static wc_test_ret_t dh_ffdhe_test(WC_RNG *rng, int name) if (nb_ret != 0) ERROR_OUT(WC_TEST_RET_ENC_EC(nb_ret), done); + PRIVATE_KEY_UNLOCK(); do { nb_ret = wc_DhAgree(key, agree2, &nbAgreeSz, priv, privSz, pub2, pubSz2); @@ -44711,6 +44713,7 @@ static wc_test_ret_t dh_ffdhe_test(WC_RNG *rng, int name) #endif } while (nb_ret == WC_NO_ERR_TRACE(MP_WOULDBLOCK) || nb_ret == WC_NO_ERR_TRACE(WC_PENDING_E)); + PRIVATE_KEY_LOCK(); if (nb_ret != 0) ERROR_OUT(WC_TEST_RET_ENC_EC(nb_ret), done); @@ -44777,7 +44780,9 @@ static wc_test_ret_t dh_ffdhe_test(WC_RNG *rng, int name) if (ret != 0) ERROR_OUT(WC_TEST_RET_ENC_EC(ret), done); + PRIVATE_KEY_UNLOCK(); ret = wc_DhGenerateKeyPair(key, rng, priv, &privSz, pub, &pubSz); + PRIVATE_KEY_LOCK(); #if defined(WOLFSSL_ASYNC_CRYPT) ret = wc_AsyncWait(ret, &key->asyncDev, WC_ASYNC_FLAG_NONE); #endif @@ -44787,7 +44792,9 @@ static wc_test_ret_t dh_ffdhe_test(WC_RNG *rng, int name) ERROR_OUT(WC_TEST_RET_ENC_EC(ret), done); } + PRIVATE_KEY_UNLOCK(); ret = wc_DhAgree(key, agree, &agreeSz, priv, privSz, pub2, pubSz2); + PRIVATE_KEY_LOCK(); #if defined(WOLFSSL_ASYNC_CRYPT) ret = wc_AsyncWait(ret, &key->asyncDev, WC_ASYNC_FLAG_NONE); #endif @@ -44859,28 +44866,36 @@ static wc_test_ret_t dh_keyagree_test(DhKey* key, DhKey* key2, WC_RNG* rng, word32 agreeSz = agreeBufSz; word32 agreeSz2 = agreeBufSz2; + PRIVATE_KEY_UNLOCK(); ret = wc_DhGenerateKeyPair(key, rng, priv, privSz, pub, pubSz); + PRIVATE_KEY_LOCK(); #if defined(WOLFSSL_ASYNC_CRYPT) ret = wc_AsyncWait(ret, &key->asyncDev, WC_ASYNC_FLAG_NONE); #endif if (ret != 0) ERROR_OUT(WC_TEST_RET_ENC_EC(ret), exit_dh_keyagree); + PRIVATE_KEY_UNLOCK(); ret = wc_DhGenerateKeyPair(key2, rng, priv2, privSz2, pub2, pubSz2); + PRIVATE_KEY_LOCK(); #if defined(WOLFSSL_ASYNC_CRYPT) ret = wc_AsyncWait(ret, &key2->asyncDev, WC_ASYNC_FLAG_NONE); #endif if (ret != 0) ERROR_OUT(WC_TEST_RET_ENC_EC(ret), exit_dh_keyagree); + PRIVATE_KEY_UNLOCK(); ret = wc_DhAgree(key, agree, &agreeSz, priv, *privSz, pub2, *pubSz2); + PRIVATE_KEY_LOCK(); #if defined(WOLFSSL_ASYNC_CRYPT) ret = wc_AsyncWait(ret, &key->asyncDev, WC_ASYNC_FLAG_NONE); #endif if (ret != 0) ERROR_OUT(WC_TEST_RET_ENC_EC(ret), exit_dh_keyagree); + PRIVATE_KEY_UNLOCK(); ret = wc_DhAgree(key2, agree2, &agreeSz2, priv2, *privSz2, pub, *pubSz); + PRIVATE_KEY_LOCK(); #if defined(WOLFSSL_ASYNC_CRYPT) ret = wc_AsyncWait(ret, &key2->asyncDev, WC_ASYNC_FLAG_NONE); #endif @@ -49117,8 +49132,10 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t pkcs12_pbkdf_test(void) wc_test_ret_t ret; WOLFSSL_ENTER("pkcs12_pbkdf_test"); + PRIVATE_KEY_UNLOCK(); ret = wc_PKCS12_PBKDF(derived, passwd, sizeof(passwd), salt, 8, iterations, kLen, WC_SHA256, id); + PRIVATE_KEY_LOCK(); if (ret < 0) return WC_TEST_RET_ENC_EC(ret); @@ -49126,13 +49143,17 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t pkcs12_pbkdf_test(void) return WC_TEST_RET_ENC_NC; iterations = 1000; + PRIVATE_KEY_UNLOCK(); ret = wc_PKCS12_PBKDF(derived, passwd2, sizeof(passwd2), salt2, 8, iterations, kLen, WC_SHA256, id); + PRIVATE_KEY_LOCK(); if (ret < 0) return WC_TEST_RET_ENC_EC(ret); + PRIVATE_KEY_UNLOCK(); ret = wc_PKCS12_PBKDF_ex(derived, passwd2, sizeof(passwd2), salt2, 8, iterations, kLen, WC_SHA256, id, HEAP_HINT); + PRIVATE_KEY_LOCK(); if (ret < 0) return WC_TEST_RET_ENC_EC(ret); @@ -49161,9 +49182,11 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t pbkdf2_test(void) wc_test_ret_t ret; WOLFSSL_ENTER("pbkdf2_test"); + PRIVATE_KEY_UNLOCK(); ret = wc_PBKDF2_ex(derived, (byte*)passwd, (int)XSTRLEN(passwd), salt, (int)sizeof(salt), iterations, kLen, WC_SHA256, HEAP_HINT, devId); + PRIVATE_KEY_LOCK(); if (ret != 0) return WC_TEST_RET_ENC_EC(ret); @@ -49176,9 +49199,11 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t pbkdf2_test(void) int cur_pbkdf_limit = wc_PBKDF_max_iterations_set(iterations - 1); if (cur_pbkdf_limit <= 0) return WC_TEST_RET_ENC_EC(cur_pbkdf_limit); + PRIVATE_KEY_UNLOCK(); ret = wc_PBKDF2_ex(derived, (byte*)passwd, (int)XSTRLEN(passwd), salt, (int)sizeof(salt), iterations, kLen, WC_SHA256, HEAP_HINT, devId); + PRIVATE_KEY_LOCK(); if (ret != WC_NO_ERR_TRACE(BAD_FUNC_ARG)) return WC_TEST_RET_ENC_EC(ret); ret = wc_PBKDF_max_iterations_set(-1); @@ -49525,6 +49550,7 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t hkdf_test(void) L = (int)sizeof(okm1); #ifndef NO_SHA + PRIVATE_KEY_UNLOCK(); #if !defined(HAVE_SELFTEST) && (!defined(HAVE_FIPS) || FIPS_VERSION_GE(7,0)) ret = wc_HKDF_ex(WC_SHA, ikm1, (word32)sizeof(ikm1), NULL, 0, NULL, 0, okm1, (word32)L, HEAP_HINT, devId); @@ -49532,6 +49558,7 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t hkdf_test(void) ret = wc_HKDF(WC_SHA, ikm1, (word32)sizeof(ikm1), NULL, 0, NULL, 0, okm1, (word32)L); #endif + PRIVATE_KEY_LOCK(); if (ret != 0) return WC_TEST_RET_ENC_EC(ret); @@ -49541,6 +49568,7 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t hkdf_test(void) #ifndef HAVE_FIPS /* fips can't have key size under 14 bytes, salt is key too */ L = (int)sizeof(okm1); + PRIVATE_KEY_UNLOCK(); #if !defined(HAVE_SELFTEST) ret = wc_HKDF_ex(WC_SHA, ikm1, 11, salt1, (word32)sizeof(salt1), info1, (word32)sizeof(info1), okm1, (word32)L, HEAP_HINT, devId); @@ -49548,6 +49576,7 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t hkdf_test(void) ret = wc_HKDF(WC_SHA, ikm1, 11, salt1, (word32)sizeof(salt1), info1, (word32)sizeof(info1), okm1, (word32)L); #endif + PRIVATE_KEY_LOCK(); if (ret != 0) return WC_TEST_RET_ENC_EC(ret); @@ -49557,6 +49586,7 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t hkdf_test(void) #endif /* !NO_SHA */ #ifndef NO_SHA256 + PRIVATE_KEY_UNLOCK(); #if !defined(HAVE_SELFTEST) && (!defined(HAVE_FIPS) || FIPS_VERSION_GE(7,0)) ret = wc_HKDF_ex(WC_SHA256, ikm1, (word32)sizeof(ikm1), NULL, 0, NULL, 0, okm1, (word32)L, HEAP_HINT, devId); @@ -49564,6 +49594,7 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t hkdf_test(void) ret = wc_HKDF(WC_SHA256, ikm1, (word32)sizeof(ikm1), NULL, 0, NULL, 0, okm1, (word32)L); #endif + PRIVATE_KEY_LOCK(); if (ret != 0) return WC_TEST_RET_ENC_EC(ret); @@ -49572,6 +49603,7 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t hkdf_test(void) #ifndef HAVE_FIPS /* fips can't have key size under 14 bytes, salt is key too */ + PRIVATE_KEY_UNLOCK(); #if !defined(HAVE_SELFTEST) ret = wc_HKDF_ex(WC_SHA256, ikm1, (word32)sizeof(ikm1), salt1, (word32)sizeof(salt1), info1, (word32)sizeof(info1), okm1, @@ -49581,6 +49613,7 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t hkdf_test(void) (word32)sizeof(salt1), info1, (word32)sizeof(info1), okm1, (word32)L); #endif + PRIVATE_KEY_LOCK(); if (ret != 0) return WC_TEST_RET_ENC_EC(ret); @@ -49590,15 +49623,18 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t hkdf_test(void) #endif /* !NO_SHA256 */ #ifndef NO_SHA + PRIVATE_KEY_UNLOCK(); #if !defined(HAVE_SELFTEST) && (!defined(HAVE_FIPS) || FIPS_VERSION_GE(7,0)) ret = wc_HKDF_Extract_ex(WC_SHA, NULL, 0, ikm1, (word32)sizeof(ikm1), prk, HEAP_HINT, devId); #else ret = wc_HKDF_Extract(WC_SHA, NULL, 0, ikm1, (word32)sizeof(ikm1), prk); #endif + PRIVATE_KEY_LOCK(); if (ret != 0) return WC_TEST_RET_ENC_EC(ret); + PRIVATE_KEY_UNLOCK(); #if !defined(HAVE_SELFTEST) && (!defined(HAVE_FIPS) || FIPS_VERSION_GE(7,0)) ret = wc_HKDF_Expand_ex(WC_SHA, prk, WC_SHA_DIGEST_SIZE, NULL, 0, okm1, (word32)L, HEAP_HINT, devId); @@ -49606,6 +49642,7 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t hkdf_test(void) ret = wc_HKDF_Expand(WC_SHA, prk, WC_SHA_DIGEST_SIZE, NULL, 0, okm1, (word32)L); #endif + PRIVATE_KEY_LOCK(); if (ret != 0) return WC_TEST_RET_ENC_EC(ret); @@ -49614,15 +49651,18 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t hkdf_test(void) #ifndef HAVE_FIPS /* fips can't have key size under 14 bytes, salt is key too */ + PRIVATE_KEY_UNLOCK(); #if !defined(HAVE_SELFTEST) ret = wc_HKDF_Extract_ex(WC_SHA, salt1, (word32)sizeof(salt1), ikm1, 11, prk, HEAP_HINT, devId); #else ret = wc_HKDF_Extract(WC_SHA, salt1, (word32)sizeof(salt1), ikm1, 11, prk); #endif + PRIVATE_KEY_LOCK(); if (ret != 0) return WC_TEST_RET_ENC_EC(ret); + PRIVATE_KEY_UNLOCK(); #if !defined(HAVE_SELFTEST) ret = wc_HKDF_Expand_ex(WC_SHA, prk, WC_SHA_DIGEST_SIZE, info1, (word32)sizeof(info1), okm1, (word32)L, HEAP_HINT, devId); @@ -49630,6 +49670,7 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t hkdf_test(void) ret = wc_HKDF_Expand(WC_SHA, prk, WC_SHA_DIGEST_SIZE, info1, (word32)sizeof(info1), okm1, (word32)L); #endif + PRIVATE_KEY_LOCK(); if (ret != 0) return WC_TEST_RET_ENC_EC(ret); @@ -49639,15 +49680,18 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t hkdf_test(void) #endif /* !NO_SHA */ #ifndef NO_SHA256 + PRIVATE_KEY_UNLOCK(); #if !defined(HAVE_SELFTEST) && (!defined(HAVE_FIPS) || FIPS_VERSION_GE(7,0)) ret = wc_HKDF_Extract_ex(WC_SHA256, NULL, 0, ikm1, (word32)sizeof(ikm1), prk, HEAP_HINT, devId); #else ret = wc_HKDF_Extract(WC_SHA256, NULL, 0, ikm1, (word32)sizeof(ikm1), prk); #endif + PRIVATE_KEY_LOCK(); if (ret != 0) return WC_TEST_RET_ENC_EC(ret); + PRIVATE_KEY_UNLOCK(); #if !defined(HAVE_SELFTEST) && (!defined(HAVE_FIPS) || FIPS_VERSION_GE(7,0)) ret = wc_HKDF_Expand_ex(WC_SHA256, prk, WC_SHA256_DIGEST_SIZE, NULL, 0, okm1, (word32)L, HEAP_HINT, devId); @@ -49655,6 +49699,7 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t hkdf_test(void) ret = wc_HKDF_Expand(WC_SHA256, prk, WC_SHA256_DIGEST_SIZE, NULL, 0, okm1, (word32)L); #endif + PRIVATE_KEY_LOCK(); if (ret != 0) return WC_TEST_RET_ENC_EC(ret); @@ -49663,6 +49708,7 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t hkdf_test(void) #ifndef HAVE_FIPS /* fips can't have key size under 14 bytes, salt is key too */ + PRIVATE_KEY_UNLOCK(); #if !defined(HAVE_SELFTEST) ret = wc_HKDF_Extract_ex(WC_SHA256, salt1, (word32)sizeof(salt1), ikm1, (word32)sizeof(ikm1), prk, HEAP_HINT, devId); @@ -49670,9 +49716,11 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t hkdf_test(void) ret = wc_HKDF_Extract(WC_SHA256, salt1, (word32)sizeof(salt1), ikm1, (word32)sizeof(ikm1), prk); #endif + PRIVATE_KEY_LOCK(); if (ret != 0) return WC_TEST_RET_ENC_EC(ret); + PRIVATE_KEY_UNLOCK(); #if !defined(HAVE_SELFTEST) ret = wc_HKDF_Expand_ex(WC_SHA256, prk, WC_SHA256_DIGEST_SIZE, info1, (word32)sizeof(info1), okm1, (word32)L, HEAP_HINT, devId); @@ -49680,6 +49728,7 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t hkdf_test(void) ret = wc_HKDF_Expand(WC_SHA256, prk, WC_SHA256_DIGEST_SIZE, info1, (word32)sizeof(info1), okm1, (word32)L); #endif + PRIVATE_KEY_LOCK(); if (ret != 0) return WC_TEST_RET_ENC_EC(ret); @@ -49692,21 +49741,29 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t hkdf_test(void) #if !defined(NO_SHA256) && !defined(HAVE_SELFTEST) && \ (!defined(HAVE_FIPS) || FIPS_VERSION3_GE(7,0,0)) /* wc_HKDF_Extract bad arg: NULL out */ + PRIVATE_KEY_UNLOCK(); ret = wc_HKDF_Extract(WC_SHA256, NULL, 0, ikm1, (word32)sizeof(ikm1), NULL); + PRIVATE_KEY_LOCK(); if (ret != WC_NO_ERR_TRACE(BAD_FUNC_ARG)) return WC_TEST_RET_ENC_EC(ret); /* wc_HKDF_Extract bad arg: NULL inKey with non-zero inKeySz */ + PRIVATE_KEY_UNLOCK(); ret = wc_HKDF_Extract(WC_SHA256, NULL, 0, NULL, 5, okm1); + PRIVATE_KEY_LOCK(); if (ret != WC_NO_ERR_TRACE(BAD_FUNC_ARG)) return WC_TEST_RET_ENC_EC(ret); /* wc_HKDF_Expand bad arg: NULL out */ + PRIVATE_KEY_UNLOCK(); ret = wc_HKDF_Expand(WC_SHA256, prk, WC_SHA256_DIGEST_SIZE, NULL, 0, NULL, (word32)L); + PRIVATE_KEY_LOCK(); if (ret != WC_NO_ERR_TRACE(BAD_FUNC_ARG)) return WC_TEST_RET_ENC_EC(ret); /* wc_HKDF_Expand bad arg: NULL inKey with non-zero inKeySz */ + PRIVATE_KEY_UNLOCK(); ret = wc_HKDF_Expand(WC_SHA256, NULL, WC_SHA256_DIGEST_SIZE, NULL, 0, okm1, (word32)L); + PRIVATE_KEY_LOCK(); if (ret != WC_NO_ERR_TRACE(BAD_FUNC_ARG)) return WC_TEST_RET_ENC_EC(ret); #endif /* !NO_SHA256 && !HAVE_SELFTEST */ @@ -49855,10 +49912,12 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t sshkdf_test(void) /* sId - Session ID, eKey - Expected Key, cKey - Calculated Key */ for (i = 0, tv = sshKdfTestVectors; i < tc; i++, tv++) { + PRIVATE_KEY_UNLOCK(); result = wc_SSH_KDF(tv->hashId, tv->keyId, cKey, tv->expectedKeySz, tv->k, tv->kSz, tv->h, tv->hSz, tv->sessionId, tv->sessionIdSz); + PRIVATE_KEY_LOCK(); if (result != 0) { printf("KDF: Could not derive key.\n"); @@ -49914,9 +49973,11 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t prf_test(void) int lblsdL = LBSL; int hash_type = sha384_mac; + PRIVATE_KEY_UNLOCK(); ret = wc_PRF(dig, (word32)digL, secret, (word32)secL, lablSd, (word32)lblsdL, hash_type, HEAP_HINT, devId); + PRIVATE_KEY_LOCK(); if (ret != 0) { printf("Failed w/ code: %d\n", ret); return WC_TEST_RET_ENC_EC(ret); @@ -49970,9 +50031,11 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t tls12_kdf_test(void) if (ret != 0) return ret; + PRIVATE_KEY_UNLOCK(); ret = wc_PRF_TLS(result, msSz, pms, pmsSz, (const byte*)label, (word32)XSTRLEN(label), seed, seedSz, 1, sha256_mac, NULL, devId); + PRIVATE_KEY_LOCK(); if (ret != 0) { if (ret == WC_NO_ERR_TRACE(FIPS_PRIVATE_KEY_LOCKED_E)) { printf(" wc_PRF_TLSv12: Private key locked.\n"); @@ -50549,6 +50612,7 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t tls13_kdf_test(void) const Tls13KdfTestVector* tv = NULL; WOLFSSL_ENTER("tls13_kdf_test"); + PRIVATE_KEY_UNLOCK(); for (i = 0, tv = tls13KdfTestVectors; i < tc; i++, tv++) { byte output[WC_MAX_DIGEST_SIZE]; byte secret[WC_MAX_DIGEST_SIZE]; @@ -50679,6 +50743,7 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t tls13_kdf_test(void) (unsigned long)hashAlgSz); if (ret != 0) break; } + PRIVATE_KEY_LOCK(); return ret; } @@ -52133,6 +52198,8 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t srtpkdf_test(void) WOLFSSL_ENTER("srtpkdf_test"); + PRIVATE_KEY_UNLOCK(); + for (i = 0; (ret == 0) && (i < SRTP_TV_CNT); i++) { #ifndef WOLFSSL_AES_128 if (tv[i].keySz == AES_128_KEY_SIZE) { @@ -52423,6 +52490,8 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t srtpkdf_test(void) out: + PRIVATE_KEY_LOCK(); + #ifdef SRTP_KDF_LONG_KEY WC_FREE_VAR(keyELong, HEAP_HINT); WC_FREE_VAR(keyALong, HEAP_HINT); @@ -53631,6 +53700,7 @@ static wc_test_ret_t ecc_test_cdh_vectors(WC_RNG* rng) /* compute ECC Cofactor shared secret */ x = sizeof(sharedA); + PRIVATE_KEY_UNLOCK(); do { #if defined(WOLFSSL_ASYNC_CRYPT) ret = wc_AsyncWait(ret, &priv_key->asyncDev, WC_ASYNC_FLAG_CALL_AGAIN); @@ -53638,6 +53708,7 @@ static wc_test_ret_t ecc_test_cdh_vectors(WC_RNG* rng) if (ret == 0) ret = wc_ecc_shared_secret(priv_key, pub_key, sharedA, &x); } while (ret == WC_NO_ERR_TRACE(WC_PENDING_E)); + PRIVATE_KEY_LOCK(); if (ret != 0) ERROR_OUT(WC_TEST_RET_ENC_EC(ret), done); TEST_SLEEP(); @@ -53775,7 +53846,9 @@ static wc_test_ret_t ecc_test_make_pub(WC_RNG* rng) #ifdef HAVE_ECC_KEY_EXPORT x = ECC_BUFSIZE; + PRIVATE_KEY_UNLOCK(); ret = wc_ecc_export_private_only(key, exportBuf, &x); + PRIVATE_KEY_LOCK(); if (ret != 0) ERROR_OUT(WC_TEST_RET_ENC_EC(ret), done); @@ -53887,7 +53960,9 @@ static wc_test_ret_t ecc_test_make_pub(WC_RNG* rng) #if defined(HAVE_ECC_DHE) && defined(HAVE_ECC_KEY_EXPORT) && !defined(WC_NO_RNG) /* now test private only key with creating a shared secret */ x = ECC_BUFSIZE; + PRIVATE_KEY_UNLOCK(); ret = wc_ecc_export_private_only(key, exportBuf, &x); + PRIVATE_KEY_LOCK(); if (ret != 0) ERROR_OUT(WC_TEST_RET_ENC_EC(ret), done); @@ -53930,6 +54005,7 @@ static wc_test_ret_t ecc_test_make_pub(WC_RNG* rng) #endif x = ECC_BUFSIZE; + PRIVATE_KEY_UNLOCK(); do { #if defined(WOLFSSL_ASYNC_CRYPT) ret = wc_AsyncWait(ret, &key->asyncDev, WC_ASYNC_FLAG_CALL_AGAIN); @@ -53937,6 +54013,7 @@ static wc_test_ret_t ecc_test_make_pub(WC_RNG* rng) if (ret == 0) ret = wc_ecc_shared_secret(key, pub, exportBuf, &x); } while (ret == WC_NO_ERR_TRACE(WC_PENDING_E)); + PRIVATE_KEY_LOCK(); wc_ecc_free(pub); if (ret != 0) ERROR_OUT(WC_TEST_RET_ENC_EC(ret), done); @@ -54337,6 +54414,7 @@ static wc_test_ret_t ecc_test_curve_size(WC_RNG* rng, int keySize, int testVerif #endif x = ECC_SHARED_SIZE; + PRIVATE_KEY_UNLOCK(); do { #if defined(WOLFSSL_ASYNC_CRYPT) ret = wc_AsyncWait(ret, &userA->asyncDev, WC_ASYNC_FLAG_CALL_AGAIN); @@ -54344,11 +54422,13 @@ static wc_test_ret_t ecc_test_curve_size(WC_RNG* rng, int keySize, int testVerif if (ret == 0) ret = wc_ecc_shared_secret(userA, userB, sharedA, &x); } while (ret == WC_NO_ERR_TRACE(WC_PENDING_E)); + PRIVATE_KEY_LOCK(); if (ret != 0) ERROR_OUT(WC_TEST_RET_ENC_EC(ret), done); TEST_SLEEP(); y = ECC_SHARED_SIZE; + PRIVATE_KEY_UNLOCK(); do { #if defined(WOLFSSL_ASYNC_CRYPT) ret = wc_AsyncWait(ret, &userB->asyncDev, WC_ASYNC_FLAG_CALL_AGAIN); @@ -54356,6 +54436,7 @@ static wc_test_ret_t ecc_test_curve_size(WC_RNG* rng, int keySize, int testVerif if (ret == 0) ret = wc_ecc_shared_secret(userB, userA, sharedB, &y); } while (ret == WC_NO_ERR_TRACE(WC_PENDING_E)); + PRIVATE_KEY_LOCK(); if (ret != 0) ERROR_OUT(WC_TEST_RET_ENC_EC(ret), done); @@ -54372,6 +54453,7 @@ static wc_test_ret_t ecc_test_curve_size(WC_RNG* rng, int keySize, int testVerif wc_ecc_set_flags(userB, WC_ECC_FLAG_COFACTOR); x = ECC_SHARED_SIZE; + PRIVATE_KEY_UNLOCK(); do { #if defined(WOLFSSL_ASYNC_CRYPT) ret = wc_AsyncWait(ret, &userA->asyncDev, WC_ASYNC_FLAG_CALL_AGAIN); @@ -54379,11 +54461,13 @@ static wc_test_ret_t ecc_test_curve_size(WC_RNG* rng, int keySize, int testVerif if (ret == 0) ret = wc_ecc_shared_secret(userA, userB, sharedA, &x); } while (ret == WC_NO_ERR_TRACE(WC_PENDING_E)); + PRIVATE_KEY_LOCK(); if (ret != 0) ERROR_OUT(WC_TEST_RET_ENC_EC(ret), done); TEST_SLEEP(); y = ECC_SHARED_SIZE; + PRIVATE_KEY_UNLOCK(); do { #if defined(WOLFSSL_ASYNC_CRYPT) ret = wc_AsyncWait(ret, &userB->asyncDev, WC_ASYNC_FLAG_CALL_AGAIN); @@ -54391,6 +54475,7 @@ static wc_test_ret_t ecc_test_curve_size(WC_RNG* rng, int keySize, int testVerif if (ret == 0) ret = wc_ecc_shared_secret(userB, userA, sharedB, &y); } while (ret == WC_NO_ERR_TRACE(WC_PENDING_E)); + PRIVATE_KEY_LOCK(); if (ret != 0) ERROR_OUT(WC_TEST_RET_ENC_EC(ret), done); @@ -54430,6 +54515,7 @@ static wc_test_ret_t ecc_test_curve_size(WC_RNG* rng, int keySize, int testVerif !defined(WOLFSSL_MICROCHIP_TA100) #ifdef HAVE_ECC_DHE y = ECC_SHARED_SIZE; + PRIVATE_KEY_UNLOCK(); do { #if defined(WOLFSSL_ASYNC_CRYPT) ret = wc_AsyncWait(ret, &userB->asyncDev, WC_ASYNC_FLAG_CALL_AGAIN); @@ -54437,6 +54523,7 @@ static wc_test_ret_t ecc_test_curve_size(WC_RNG* rng, int keySize, int testVerif if (ret == 0) ret = wc_ecc_shared_secret(userB, pubKey, sharedB, &y); } while (ret == WC_NO_ERR_TRACE(WC_PENDING_E)); + PRIVATE_KEY_LOCK(); if (ret != 0) ERROR_OUT(WC_TEST_RET_ENC_EC(ret), done); @@ -54469,6 +54556,7 @@ static wc_test_ret_t ecc_test_curve_size(WC_RNG* rng, int keySize, int testVerif #ifdef HAVE_ECC_DHE y = ECC_SHARED_SIZE; + PRIVATE_KEY_UNLOCK(); do { #if defined(WOLFSSL_ASYNC_CRYPT) ret = wc_AsyncWait(ret, &userB->asyncDev, WC_ASYNC_FLAG_CALL_AGAIN); @@ -54476,6 +54564,7 @@ static wc_test_ret_t ecc_test_curve_size(WC_RNG* rng, int keySize, int testVerif if (ret == 0) ret = wc_ecc_shared_secret(userB, pubKey, sharedB, &y); } while (ret == WC_NO_ERR_TRACE(WC_PENDING_E)); + PRIVATE_KEY_LOCK(); if (ret != 0) ERROR_OUT(WC_TEST_RET_ENC_EC(ret), done); @@ -54600,7 +54689,9 @@ static wc_test_ret_t ecc_test_curve_size(WC_RNG* rng, int keySize, int testVerif !defined(WC_TEST_SKIP_ECC_PRIVATE_EXPORT) && \ !defined(WOLFSSL_MICROCHIP_TA100) x = ECC_KEY_EXPORT_BUF_SIZE; + PRIVATE_KEY_UNLOCK(); ret = wc_ecc_export_private_only(userA, exportBuf, &x); + PRIVATE_KEY_LOCK(); if (ret != 0) ERROR_OUT(WC_TEST_RET_ENC_EC(ret), done); #elif defined(HAVE_ECC_KEY_EXPORT) @@ -55084,7 +55175,9 @@ static wc_test_ret_t ecc_exp_imp_test(ecc_key* key) wc_ecc_init_ex(keyImp, HEAP_HINT, devId); privLen = sizeof(priv); + PRIVATE_KEY_UNLOCK(); ret = wc_ecc_export_private_only(key, priv, &privLen); + PRIVATE_KEY_LOCK(); if (ret != 0) ERROR_OUT(WC_TEST_RET_ENC_EC(ret), done); pubLen = sizeof(pub); @@ -55139,8 +55232,10 @@ static wc_test_ret_t ecc_exp_imp_test(ecc_key* key) /* test export private and public raw */ pubLenX = pubLenY = privLen = 32; + PRIVATE_KEY_UNLOCK(); ret = wc_ecc_export_private_raw(key, pub, &pubLenX, &pub[32], &pubLenY, priv, &privLen); + PRIVATE_KEY_LOCK(); if (ret != 0) ERROR_OUT(WC_TEST_RET_ENC_EC(ret), done); @@ -55286,16 +55381,24 @@ static wc_test_ret_t ecc_ssh_test(ecc_key* key, WC_RNG* rng) word32 outLen = sizeof(out); /* Parameter Validation testing. */ + PRIVATE_KEY_UNLOCK(); ret = wc_ecc_shared_secret_ssh(NULL, &key->pubkey, out, &outLen); + PRIVATE_KEY_LOCK(); if (ret != WC_NO_ERR_TRACE(BAD_FUNC_ARG)) return WC_TEST_RET_ENC_EC(ret); + PRIVATE_KEY_UNLOCK(); ret = wc_ecc_shared_secret_ssh(key, NULL, out, &outLen); + PRIVATE_KEY_LOCK(); if (ret != WC_NO_ERR_TRACE(BAD_FUNC_ARG)) return WC_TEST_RET_ENC_EC(ret); + PRIVATE_KEY_UNLOCK(); ret = wc_ecc_shared_secret_ssh(key, &key->pubkey, NULL, &outLen); + PRIVATE_KEY_LOCK(); if (ret != WC_NO_ERR_TRACE(BAD_FUNC_ARG)) return WC_TEST_RET_ENC_EC(ret); + PRIVATE_KEY_UNLOCK(); ret = wc_ecc_shared_secret_ssh(key, &key->pubkey, out, NULL); + PRIVATE_KEY_LOCK(); if (ret != WC_NO_ERR_TRACE(BAD_FUNC_ARG)) return WC_TEST_RET_ENC_EC(ret); @@ -55311,6 +55414,7 @@ static wc_test_ret_t ecc_ssh_test(ecc_key* key, WC_RNG* rng) /* Use API. */ ret = 0; + PRIVATE_KEY_UNLOCK(); do { #if defined(WOLFSSL_ASYNC_CRYPT) ret = wc_AsyncWait(ret, &key->asyncDev, WC_ASYNC_FLAG_CALL_AGAIN); @@ -55318,6 +55422,7 @@ static wc_test_ret_t ecc_ssh_test(ecc_key* key, WC_RNG* rng) if (ret == 0) ret = wc_ecc_shared_secret_ssh(key, &key->pubkey, out, &outLen); } while (ret == WC_NO_ERR_TRACE(WC_PENDING_E)); + PRIVATE_KEY_LOCK(); if (ret != 0) return WC_TEST_RET_ENC_EC(ret); @@ -56273,7 +56378,9 @@ static int ecc_sm2_test_curve(WC_RNG* rng, int testVerifyCount) #if defined(HAVE_ECC_KEY_EXPORT) && !defined(WC_NO_RNG) x = ECC_KEY_EXPORT_BUF_SIZE; + PRIVATE_KEY_UNLOCK(); ret = wc_ecc_export_private_only(userA, exportBuf, &x); + PRIVATE_KEY_LOCK(); if (ret != 0) ERROR_OUT(WC_TEST_RET_ENC_EC(ret), done); #elif defined(HAVE_ECC_KEY_EXPORT) @@ -57116,10 +57223,12 @@ static wc_test_ret_t ecc_test_nonblock_dhe(int curveId, word32 curveSz, } count = 0; if (ret == 0) { + PRIVATE_KEY_UNLOCK(); do { ret = wc_ecc_shared_secret(&keyA, &keyB, secretA, &secretSzA); count++; } while (ret == FP_WOULDBLOCK); + PRIVATE_KEY_LOCK(); if (ret < 0) ret = WC_TEST_RET_ENC_EC(ret); } @@ -57127,9 +57236,11 @@ static wc_test_ret_t ecc_test_nonblock_dhe(int curveId, word32 curveSz, fprintf(stderr, "ECC non-block shared secret: %d times\n", count); #endif if (ret == 0) { + PRIVATE_KEY_UNLOCK(); do { ret = wc_ecc_shared_secret(&keyB, &keyA, secretB, &secretSzB); } while (ret == FP_WOULDBLOCK); + PRIVATE_KEY_LOCK(); if (ret < 0) ret = WC_TEST_RET_ENC_EC(ret); } @@ -57602,10 +57713,14 @@ static wc_test_ret_t ecc_se050_onlykeyid_test(WC_RNG* rng) ret = wc_ecc_set_rng(&swKey, rng); if (ret != 0) { ret = WC_TEST_RET_ENC_EC(ret); goto ecdh_done; } + PRIVATE_KEY_UNLOCK(); ret = wc_ecc_shared_secret(&swKey, &peer, secretSw, &secretSwSz); + PRIVATE_KEY_LOCK(); if (ret != 0) { ret = WC_TEST_RET_ENC_EC(ret); goto ecdh_done; } + PRIVATE_KEY_UNLOCK(); ret = wc_ecc_shared_secret(&hwKey, &peer, secretHw, &secretHwSz); + PRIVATE_KEY_LOCK(); if (ret != 0) { ret = WC_TEST_RET_ENC_EC(ret); goto ecdh_done; } /* The peer was and must remain a software key (keyIdSet == 0) */ @@ -57699,7 +57814,9 @@ static wc_test_ret_t ecc_no_sw_test(void) if (ret != 0) ERROR_OUT(WC_TEST_RET_ENC_EC(ret), done); + PRIVATE_KEY_UNLOCK(); ret = (wc_test_ret_t)wc_ecc_shared_secret(privKey, pubKey, out, &outLen); + PRIVATE_KEY_LOCK(); if (ret != WC_NO_ERR_TRACE(NOT_COMPILED_IN)) ERROR_OUT(WC_TEST_RET_ENC_EC(ret), done); @@ -61451,7 +61568,9 @@ static wc_test_ret_t ed25519_export_key_no_pub_test(void) /* wc_ed25519_export_key() must propagate the missing-public-key error. */ if (res == 0) { + PRIVATE_KEY_UNLOCK(); ret = wc_ed25519_export_key(&key, priv, &privSz, pub, &pubSz); + PRIVATE_KEY_LOCK(); if (ret != WC_NO_ERR_TRACE(PUBLIC_KEY_E)) { res = WC_TEST_RET_ENC_NC; } @@ -62165,7 +62284,10 @@ static wc_test_ret_t ed25519_kat_test(ed25519_key* key, ed25519_key* key2) if (wc_ed25519_import_public_ex(exportPKey, exportPSz, key2, 1) != 0) ERROR_OUT(WC_TEST_RET_ENC_I(i), exit_ed25519_kat); - if (wc_ed25519_export_private_only(key, exportSKey, &exportSSz) != 0) + PRIVATE_KEY_UNLOCK(); + ret = wc_ed25519_export_private_only(key, exportSKey, &exportSSz); + PRIVATE_KEY_LOCK(); + if (ret != 0) ERROR_OUT(WC_TEST_RET_ENC_I(i), exit_ed25519_kat); if (wc_ed25519_import_private_key(exportSKey, exportSSz, @@ -63765,7 +63887,9 @@ static wc_test_ret_t ed448_export_key_no_pub_test(void) /* wc_ed448_export_key() must propagate the missing-public-key error. */ if (res == 0) { + PRIVATE_KEY_UNLOCK(); ret = wc_ed448_export_key(&key, priv, &privSz, pub, &pubSz); + PRIVATE_KEY_LOCK(); if (ret != WC_NO_ERR_TRACE(PUBLIC_KEY_E)) { res = WC_TEST_RET_ENC_NC; } @@ -64538,7 +64662,11 @@ static wc_test_ret_t ed448_kat_test(ed448_key* key, ed448_key* key2) break; } - if (wc_ed448_export_private_only(key, exportSKey, &exportSSz) != 0) { + PRIVATE_KEY_UNLOCK(); + ret = wc_ed448_export_private_only(key, exportSKey, + &exportSSz); + PRIVATE_KEY_LOCK(); + if (ret != 0) { ret = WC_TEST_RET_ENC_I(i); break; } @@ -69363,11 +69491,15 @@ static wc_test_ret_t mlkem_seed_consistency_test(void) goto out_seed; } ret = wc_MlKemKey_MakeKeyWithRandom(key, seed, (int)sizeof(seed)); - if (ret == SEED_OK) + if (ret == SEED_OK) { ret = wc_MlKemKey_PrivateKeySize(key, &expandedSz); + if (ret != 0) + ret = WC_TEST_RET_ENC_EC(ret); + } + else + ret = WC_TEST_RET_ENC_EC(ret); if (ret != 0) { wc_MlKemKey_Free(key); - ret = WC_TEST_RET_ENC_EC(ret); goto out_seed; } expanded = (byte*)XMALLOC(expandedSz, HEAP_HINT, @@ -69377,7 +69509,9 @@ static wc_test_ret_t mlkem_seed_consistency_test(void) ret = WC_TEST_RET_ENC_ERRNO; goto out_seed; } + PRIVATE_KEY_UNLOCK(); ret = wc_MlKemKey_EncodePrivateKey(key, expanded, expandedSz); + PRIVATE_KEY_LOCK(); wc_MlKemKey_Free(key); if (ret != 0) { ret = WC_TEST_RET_ENC_EC(ret); @@ -69451,17 +69585,23 @@ static wc_test_ret_t mlkem_seed_consistency_test(void) goto out_seed; } idx = 0; + PRIVATE_KEY_UNLOCK(); ret = wc_MlKemKey_PrivateKeyDecode(key, der, n, &idx); - - if (((j == 0) || (j == 2)) && (ret != 0)) { - wc_MlKemKey_Free(key); - ret = WC_TEST_RET_ENC_EC(ret); /* valid, must decode */ - goto out_seed; + PRIVATE_KEY_LOCK(); + if ((j == 0) || (j == 2)) { + if (ret != 0) { + ret = WC_TEST_RET_ENC_EC(ret); + wc_MlKemKey_Free(key); + goto out_seed; + } } - if (((j == 1) || (j == 3)) && (ret == 0)) { - wc_MlKemKey_Free(key); - ret = WC_TEST_RET_ENC_NC; /* invalid, must not decode */ - goto out_seed; + else { + if (ret == 0) { + wc_MlKemKey_Free(key); + ret = WC_TEST_RET_ENC_NC; /* invalid, must not decode */ + goto out_seed; + } + ret = 0; /* refusal was the pass condition */ } if (j == 2) { /* the seed alone must reproduce the expanded key exactly */ @@ -69472,7 +69612,11 @@ static wc_test_ret_t mlkem_seed_consistency_test(void) ret = WC_TEST_RET_ENC_ERRNO; goto out_seed; } + PRIVATE_KEY_UNLOCK(); ret = wc_MlKemKey_EncodePrivateKey(key, again, expandedSz); + PRIVATE_KEY_LOCK(); + if (ret != 0) + ret = WC_TEST_RET_ENC_EC(ret); if (ret == 0 && XMEMCMP(again, expanded, expandedSz) != 0) ret = WC_TEST_RET_ENC_NC; XMEMSET(again, 0, expandedSz); @@ -69483,7 +69627,6 @@ static wc_test_ret_t mlkem_seed_consistency_test(void) } } wc_MlKemKey_Free(key); - ret = 0; XFREE(der, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); der = NULL; @@ -69511,6 +69654,7 @@ static wc_test_ret_t mlkem_asn1_test(void) WC_RNG rng; int rngInit = 0; int i; + int nlevels; static const int levels[] = { #if defined(WOLFSSL_WC_ML_KEM_512) && !defined(WOLFSSL_NO_ML_KEM) WC_ML_KEM_512, @@ -69524,6 +69668,9 @@ static wc_test_ret_t mlkem_asn1_test(void) -1 }; + /* count the number of valid levels compiled in: */ + for (nlevels = 0; levels[nlevels] != -1; ++nlevels); + ret = wc_InitRng_ex(&rng, HEAP_HINT, devId); if (ret != 0) return WC_TEST_RET_ENC_EC(ret); @@ -69542,8 +69689,10 @@ static wc_test_ret_t mlkem_asn1_test(void) word32 ctLen = 0; int pubLen = 0; int privLen = 0; - int wrongLevel = (levels[i] == WC_ML_KEM_512) ? WC_ML_KEM_1024 : - WC_ML_KEM_512; + /* Always a compiled-in set, so wc_MlKemKey_Init(wrongLevel) below is + * expected to succeed. In a single-set build it aliases levels[i] and + * the cross-set refusal check is skipped. */ + int wrongLevel = levels[(i + 1) % nlevels]; int keyInit = 0; key = (MlKemKey*)XMALLOC(sizeof(MlKemKey), HEAP_HINT, @@ -69561,15 +69710,24 @@ static wc_test_ret_t mlkem_asn1_test(void) if (ret == 0) { keyInit = 1; ret = wc_MlKemKey_MakeKey(key, &rng); + if (ret != 0) + ret = WC_TEST_RET_ENC_EC(ret); } + else + ret = WC_TEST_RET_ENC_EC(ret); /* The generated key produces the ciphertext every decode is measured * against. */ - if (ret == 0) + if (ret == 0) { ret = wc_MlKemKey_CipherTextSize(key, &ctLen); - if (ret == 0) + if (ret != 0) + ret = WC_TEST_RET_ENC_EC(ret); + } + if (ret == 0) { ret = wc_MlKemKey_Encapsulate(key, ct, ss, &rng); - + if (ret != 0) + ret = WC_TEST_RET_ENC_EC(ret); + } if (ret == 0) { pubLen = wc_MlKemKey_PublicKeyToDer(key, NULL, 0, 1); if (pubLen <= 0) @@ -69608,9 +69766,11 @@ static wc_test_ret_t mlkem_asn1_test(void) keyInit = 0; } - /* A DER naming a different parameter set must be refused. */ - if (ret == 0) { - if (wc_MlKemKey_Init(key, wrongLevel, HEAP_HINT, devId) == 0) { + /* A DER naming a different parameter set must be refused. Needs a + * second compiled-in set to name -- single-set builds have none. */ + if ((ret == 0) && (nlevels > 1)) { + ret = wc_MlKemKey_Init(key, wrongLevel, HEAP_HINT, devId); + if (ret == 0) { idx = 0; if (wc_MlKemKey_PublicKeyDecode(key, pubDer, (word32)pubLen, &idx) == 0) { @@ -69618,6 +69778,8 @@ static wc_test_ret_t mlkem_asn1_test(void) } wc_MlKemKey_Free(key); } + else + ret = WC_TEST_RET_ENC_EC(ret); } /* Initialised without a parameter set, each decode names it. */ if (ret == 0) { @@ -69627,10 +69789,14 @@ static wc_test_ret_t mlkem_asn1_test(void) idx = 0; ret = wc_MlKemKey_PublicKeyDecode(key, pubDer, (word32)pubLen, &idx); + if (ret != 0) + ret = WC_TEST_RET_ENC_EC(ret); if ((ret == 0) && (key->type != levels[i])) ret = WC_TEST_RET_ENC_NC; wc_MlKemKey_Free(key); } + else + ret = WC_TEST_RET_ENC_EC(ret); } if (ret == 0) { ret = wc_MlKemKey_Init(key, WC_ML_KEM_TYPE_UNSET, HEAP_HINT, @@ -69639,10 +69805,14 @@ static wc_test_ret_t mlkem_asn1_test(void) idx = 0; ret = wc_MlKemKey_PrivateKeyDecode(key, privDer, (word32)privLen, &idx); + if (ret != 0) + ret = WC_TEST_RET_ENC_EC(ret); if ((ret == 0) && (key->type != levels[i])) ret = WC_TEST_RET_ENC_NC; wc_MlKemKey_Free(key); } + else + ret = WC_TEST_RET_ENC_EC(ret); } /* The PKCS#8 round trip must recover the original decapsulation key. */ @@ -69650,15 +69820,23 @@ static wc_test_ret_t mlkem_asn1_test(void) ret = wc_MlKemKey_Init(key, levels[i], HEAP_HINT, devId); if (ret == 0) keyInit = 1; + else + ret = WC_TEST_RET_ENC_EC(ret); } if (ret == 0) { idx = 0; ret = wc_MlKemKey_PrivateKeyDecode(key, privDer, (word32)privLen, &idx); + if (ret != 0) + ret = WC_TEST_RET_ENC_EC(ret); } if (ret == 0) { XMEMSET(ssDec, 0, sizeof(ssDec)); + PRIVATE_KEY_UNLOCK(); ret = wc_MlKemKey_Decapsulate(key, ssDec, ct, ctLen); + PRIVATE_KEY_LOCK(); + if (ret != 0) + ret = WC_TEST_RET_ENC_EC(ret); } if (ret == 0) { if (XMEMCMP(ss, ssDec, WC_ML_KEM_SS_SZ) != 0) @@ -69675,14 +69853,21 @@ static wc_test_ret_t mlkem_asn1_test(void) ret = wc_MlKemKey_Init(key, levels[i], HEAP_HINT, devId); if (ret == 0) keyInit = 1; + else + ret = WC_TEST_RET_ENC_EC(ret); } if (ret == 0) { idx = 0; ret = wc_MlKemKey_PublicKeyDecode(key, pubDer, (word32)pubLen, &idx); + if (ret != 0) + ret = WC_TEST_RET_ENC_EC(ret); } - if (ret == 0) + if (ret == 0) { ret = wc_MlKemKey_Encapsulate(key, ct, ss, &rng); + if (ret != 0) + ret = WC_TEST_RET_ENC_EC(ret); + } if (keyInit) { wc_MlKemKey_Free(key); keyInit = 0; @@ -69691,15 +69876,23 @@ static wc_test_ret_t mlkem_asn1_test(void) ret = wc_MlKemKey_Init(key, levels[i], HEAP_HINT, devId); if (ret == 0) keyInit = 1; + else + ret = WC_TEST_RET_ENC_EC(ret); } if (ret == 0) { idx = 0; ret = wc_MlKemKey_PrivateKeyDecode(key, privDer, (word32)privLen, &idx); + if (ret != 0) + ret = WC_TEST_RET_ENC_EC(ret); } if (ret == 0) { XMEMSET(ssDec, 0, sizeof(ssDec)); + PRIVATE_KEY_UNLOCK(); ret = wc_MlKemKey_Decapsulate(key, ssDec, ct, ctLen); + PRIVATE_KEY_LOCK(); + if (ret != 0) + ret = WC_TEST_RET_ENC_EC(ret); } if (ret == 0) { if (XMEMCMP(ss, ssDec, WC_ML_KEM_SS_SZ) != 0) @@ -69793,77 +69986,71 @@ static wc_test_ret_t mlkem_cert_test(WC_RNG* rng) key = (MlKemKey*)XMALLOC(sizeof(MlKemKey), HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); spki = (byte*)XMALLOC(spkiSz, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - if (key == NULL || spki == NULL) { - ret = WC_TEST_RET_ENC_ERRNO; - goto free_vector; - } + if (key == NULL || spki == NULL) + ERROR_OUT(WC_TEST_RET_ENC_ERRNO, free_vector); /* Pull the SubjectPublicKeyInfo straight out of the certificate. */ ret = wc_GetSubjectPubKeyInfoDerFromCert(vectors[i].cert, vectors[i].certSz, spki, &spkiSz); - if (ret == 0) { - ret = wc_MlKemKey_Init(key, vectors[i].level, HEAP_HINT, devId); - if (ret == 0) - keyInit = 1; - } + if (ret != 0) + ERROR_OUT(WC_TEST_RET_ENC_EC(ret), free_vector); + ret = wc_MlKemKey_Init(key, vectors[i].level, HEAP_HINT, devId); + if (ret != 0) + ERROR_OUT(WC_TEST_RET_ENC_EC(ret), free_vector); + keyInit = 1; /* Decoding only succeeds when the SPKI names this parameter set. */ - if (ret == 0) { - idx = 0; - ret = wc_MlKemKey_PublicKeyDecode(key, spki, spkiSz, &idx); - } - if (ret == 0) - ret = wc_MlKemKey_PublicKeySize(key, &pubSz); - if (ret == 0) { - pubA = (byte*)XMALLOC(pubSz, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - pubB = (byte*)XMALLOC(pubSz, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - if (pubA == NULL || pubB == NULL) { - ret = WC_TEST_RET_ENC_ERRNO; - goto free_vector; - } - } - if (ret == 0) - ret = wc_MlKemKey_EncodePublicKey(key, pubA, pubSz); + idx = 0; + ret = wc_MlKemKey_PublicKeyDecode(key, spki, spkiSz, &idx); + if (ret != 0) + ERROR_OUT(WC_TEST_RET_ENC_EC(ret), free_vector); + ret = wc_MlKemKey_PublicKeySize(key, &pubSz); + if (ret != 0) + ERROR_OUT(WC_TEST_RET_ENC_EC(ret), free_vector); + pubA = (byte*)XMALLOC(pubSz, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + pubB = (byte*)XMALLOC(pubSz, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + if (pubA == NULL || pubB == NULL) + ERROR_OUT(WC_TEST_RET_ENC_ERRNO, free_vector); + ret = wc_MlKemKey_EncodePublicKey(key, pubA, pubSz); + if (ret != 0) + ERROR_OUT(WC_TEST_RET_ENC_EC(ret), free_vector); #ifdef MLKEM_CERT_TEST_KEM /* Encapsulate to the certificate key, decapsulate below. */ - if (ret == 0) - ret = wc_MlKemKey_CipherTextSize(key, &ctSz); - if (ret == 0) { - ct = (byte*)XMALLOC(ctSz, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - if (ct == NULL) - ret = WC_TEST_RET_ENC_ERRNO; - } - if (ret == 0) - ret = wc_MlKemKey_Encapsulate(key, ct, ssA, rng); -#endif - if (keyInit) { - wc_MlKemKey_Free(key); - keyInit = 0; - } + ret = wc_MlKemKey_CipherTextSize(key, &ctSz); if (ret != 0) - goto free_vector; + ERROR_OUT(WC_TEST_RET_ENC_EC(ret), free_vector); + ct = (byte*)XMALLOC(ctSz, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + if (ct == NULL) + ERROR_OUT(WC_TEST_RET_ENC_ERRNO, free_vector); + ret = wc_MlKemKey_Encapsulate(key, ct, ssA, rng); + if (ret != 0) + ERROR_OUT(WC_TEST_RET_ENC_EC(ret), free_vector); +#endif + wc_MlKemKey_Free(key); + keyInit = 0; ret = wc_MlKemKey_Init(key, vectors[i].level, HEAP_HINT, devId); - if (ret == 0) - keyInit = 1; - if (ret == 0) { - idx = 0; - ret = wc_MlKemKey_PrivateKeyDecode(key, vectors[i].key, - vectors[i].keySz, &idx); - } + if (ret != 0) + ERROR_OUT(WC_TEST_RET_ENC_EC(ret), free_vector); + keyInit = 1; + idx = 0; + ret = wc_MlKemKey_PrivateKeyDecode(key, vectors[i].key, + vectors[i].keySz, &idx); + if (ret != 0) + ERROR_OUT(WC_TEST_RET_ENC_EC(ret), free_vector); /* The private key must reproduce the certificate's public key. */ - if (ret == 0) - ret = wc_MlKemKey_EncodePublicKey(key, pubB, pubSz); - if (ret == 0) { - if (XMEMCMP(pubA, pubB, pubSz) != 0) - ret = WC_TEST_RET_ENC_NC; - } + ret = wc_MlKemKey_EncodePublicKey(key, pubB, pubSz); + if (ret != 0) + ERROR_OUT(WC_TEST_RET_ENC_EC(ret), free_vector); + if (XMEMCMP(pubA, pubB, pubSz) != 0) + ERROR_OUT(WC_TEST_RET_ENC_NC, free_vector); #ifdef MLKEM_CERT_TEST_KEM - if (ret == 0) - ret = wc_MlKemKey_Decapsulate(key, ssB, ct, ctSz); - if (ret == 0) { - if (XMEMCMP(ssA, ssB, sizeof(ssA)) != 0) - ret = WC_TEST_RET_ENC_NC; - } + PRIVATE_KEY_UNLOCK(); + ret = wc_MlKemKey_Decapsulate(key, ssB, ct, ctSz); + PRIVATE_KEY_LOCK(); + if (ret != 0) + ERROR_OUT(WC_TEST_RET_ENC_EC(ret), free_vector); + if (XMEMCMP(ssA, ssB, sizeof(ssA)) != 0) + ERROR_OUT(WC_TEST_RET_ENC_NC, free_vector); #endif free_vector: @@ -70180,48 +70367,67 @@ static wc_test_ret_t mlkem_decode_pub_test(void) ret = wc_MlKemKey_Init(a, WC_ML_KEM_768, HEAP_HINT, INVALID_DEVID); a_inited = (ret == 0); - if (ret == 0) { - ret = wc_MlKemKey_Init(b, WC_ML_KEM_768, HEAP_HINT, INVALID_DEVID); - b_inited = (ret == 0); - } - if (ret == 0) - ret = wc_RNG_GenerateBlock(&rng, rnd, sizeof(rnd)); + if (ret != 0) + ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); + ret = wc_MlKemKey_Init(b, WC_ML_KEM_768, HEAP_HINT, INVALID_DEVID); + b_inited = (ret == 0); + if (ret != 0) + ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); + ret = wc_RNG_GenerateBlock(&rng, rnd, sizeof(rnd)); + if (ret != 0) + ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); /* Same key twice; a's public key hash is not computed yet. */ - if (ret == 0) - ret = wc_MlKemKey_MakeKeyWithRandom(a, rnd, sizeof(rnd)); - if (ret == SEED_OK) - ret = wc_MlKemKey_MakeKeyWithRandom(b, rnd, sizeof(rnd)); - if (ret == SEED_OK) - ret = wc_MlKemKey_PublicKeySize(b, &pubSz); - if (ret == 0) - ret = wc_MlKemKey_CipherTextSize(b, &ctSz); - if (ret == 0) - ret = wc_MlKemKey_EncodePublicKey(b, pub, pubSz); - if (ret == 0) - ret = wc_MlKemKey_Encapsulate(b, ct, ss, &rng); - if (ret == 0) - ret = wc_MlKemKey_DecodePublicKey(a, pub, pubSz); - if (ret == 0) - ret = wc_MlKemKey_Decapsulate(a, ssA, ct, ctSz); + ret = wc_MlKemKey_MakeKeyWithRandom(a, rnd, sizeof(rnd)); + if (ret != SEED_OK) + ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); + ret = wc_MlKemKey_MakeKeyWithRandom(b, rnd, sizeof(rnd)); + if (ret != SEED_OK) + ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); + ret = wc_MlKemKey_PublicKeySize(b, &pubSz); + if (ret != 0) + ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); + ret = wc_MlKemKey_CipherTextSize(b, &ctSz); + if (ret != 0) + ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); + ret = wc_MlKemKey_EncodePublicKey(b, pub, pubSz); + if (ret != 0) + ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); + ret = wc_MlKemKey_Encapsulate(b, ct, ss, &rng); + if (ret != 0) + ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); + ret = wc_MlKemKey_DecodePublicKey(a, pub, pubSz); + if (ret != 0) + ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); + PRIVATE_KEY_UNLOCK(); + ret = wc_MlKemKey_Decapsulate(a, ssA, ct, ctSz); + PRIVATE_KEY_LOCK(); if (ret != 0) ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); if (XMEMCMP(ss, ssA, sizeof(ss)) != 0) ERROR_OUT(WC_TEST_RET_ENC_NC, out); ret = wc_MlKemKey_MakeKey(b, &rng); - if (ret == 0) - ret = wc_MlKemKey_EncodePublicKey(b, pub, pubSz); - if (ret == 0) - ret = wc_MlKemKey_Encapsulate(b, ct, ss, &rng); - if (ret == 0) - ret = wc_MlKemKey_DecodePublicKey(a, pub, pubSz); + if (ret != 0) + ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); + ret = wc_MlKemKey_EncodePublicKey(b, pub, pubSz); + if (ret != 0) + ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); + ret = wc_MlKemKey_Encapsulate(b, ct, ss, &rng); + if (ret != 0) + ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); + ret = wc_MlKemKey_DecodePublicKey(a, pub, pubSz); if (ret != 0) ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); + /* a now holds only a decoded public key: decapsulation must be refused + * by the library proper. Unlock so the FIPS wrapper's private-key gate + * doesn't preempt the BAD_STATE_E this probe exists to observe. */ + PRIVATE_KEY_UNLOCK(); ret = wc_MlKemKey_Decapsulate(a, ssA, ct, ctSz); + PRIVATE_KEY_LOCK(); if (ret != WC_NO_ERR_TRACE(BAD_STATE_E)) - ERROR_OUT(WC_TEST_RET_ENC_NC, out); - ret = 0; + ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); + ret = 0; /* refusal was the pass condition */ out: if (a_inited) @@ -70412,9 +70618,11 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t mlkem_test(void) if (ret != 0) ERROR_OUT(WC_TEST_RET_ENC_I(i), out); + PRIVATE_KEY_UNLOCK(); ret = wc_MlKemKey_EncodePrivateKey(key, priv, testData[i][1]); + PRIVATE_KEY_LOCK(); if (ret != 0) - ERROR_OUT(WC_TEST_RET_ENC_I(i), out); + ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); wc_MlKemKey_Free(key); ret = wc_MlKemKey_Init(key, testData[i][0], HEAP_HINT, devId); @@ -70454,7 +70662,9 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t mlkem_test(void) #if !defined(WOLFSSL_MLKEM_NO_ENCAPSULATE) && \ !defined(WOLFSSL_MLKEM_NO_DECAPSULATE) + PRIVATE_KEY_UNLOCK(); ret = wc_MlKemKey_Decapsulate(key, ss_dec, ct, testData[i][3]); + PRIVATE_KEY_LOCK(); if (ret != 0) ERROR_OUT(WC_TEST_RET_ENC_I(i), out); @@ -70462,7 +70672,9 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t mlkem_test(void) ERROR_OUT(WC_TEST_RET_ENC_I(i), out); #endif + PRIVATE_KEY_UNLOCK(); ret = wc_MlKemKey_EncodePrivateKey(key, priv2, testData[i][1]); + PRIVATE_KEY_LOCK(); if (ret != 0) ERROR_OUT(WC_TEST_RET_ENC_I(i), out); @@ -75029,8 +75241,10 @@ static wc_test_ret_t test_mldsa_decode_level(const byte* rawKey, #endif #ifdef WOLFSSL_MLDSA_PRIVATE_KEY if (!isPublicOnlyKey) { + PRIVATE_KEY_UNLOCK(); ret = wc_MlDsaKey_PrivateKeyToDer(key, der, MLDSA_MAX_PRV_KEY_DER_SIZE); + PRIVATE_KEY_LOCK(); if (ret < 0) ret = WC_TEST_RET_ENC_EC(ret); } @@ -78579,6 +78793,7 @@ static wc_test_ret_t slhdsa_init_fail_free_test(void) #define SLHDSA_TEST_CERT_SHA2_128S #endif #if !defined(NO_ASN) && !defined(NO_CERTS) && \ + !defined(WOLFSSL_NO_MALLOC) && \ (defined(SLHDSA_TEST_CERT_SHAKE128S) || \ defined(SLHDSA_TEST_CERT_SHA2_128S)) #define SLHDSA_TEST_CERT @@ -104147,10 +104362,8 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t cryptocb_test(void) ret = random_test(); #endif /* WC_NO_RNG */ #if !defined(NO_RSA) - PRIVATE_KEY_UNLOCK(); if (ret == 0) ret = rsa_test(); - PRIVATE_KEY_LOCK(); #endif #if defined(WOLF_CRYPTO_CB_ONLY_RSA) && !defined(WOLFSSL_SWDEV) PRIVATE_KEY_UNLOCK(); @@ -104504,10 +104717,8 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t cryptocb_test(void) ret = dh_cryptocb_test(devId, &myCtx); #endif /* !NO_DH && HAVE_FFDHE_2048 && !WC_NO_RNG */ #if defined(HAVE_ECC) - PRIVATE_KEY_UNLOCK(); if (ret == 0) ret = ecc_test(); - PRIVATE_KEY_LOCK(); /* Confirm the new ECC pubkey callbacks were routed through the device and * not silently handled in software. The check-pubkey callback is only * exercised when wc_ecc_check_key is built (HAVE_ECC_CHECK_KEY) and the @@ -104539,7 +104750,6 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t cryptocb_test(void) int haveZeroKey = 0; WC_ALLOC_VAR(zeroKey, ecc_key, 1, HEAP_HINT); - PRIVATE_KEY_UNLOCK(); if (!WC_VAR_OK(zeroKey)) ret = MEMORY_E; else @@ -104569,7 +104779,6 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t cryptocb_test(void) if (haveZeroKey) wc_ecc_free(zeroKey); WC_FREE_VAR(zeroKey, HEAP_HINT); - PRIVATE_KEY_LOCK(); } #endif /* WOLFSSL_NO_ECC_SW is excluded: wc_CryptoCb_EccMakePub() is called from @@ -104614,7 +104823,6 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t cryptocb_test(void) WC_ALLOC_VAR(srcKey, ecc_key, 1, HEAP_HINT); WC_ALLOC_VAR(resKey, ecc_key, 1, HEAP_HINT); WC_ALLOC_VAR(eccRng, WC_RNG, 1, HEAP_HINT); - PRIVATE_KEY_UNLOCK(); if (!WC_VAR_OK(srcKey) || !WC_VAR_OK(resKey) || !WC_VAR_OK(eccRng)) ret = MEMORY_E; else @@ -104723,7 +104931,6 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t cryptocb_test(void) WC_FREE_VAR(srcKey, HEAP_HINT); WC_FREE_VAR(resKey, HEAP_HINT); WC_FREE_VAR(eccRng, HEAP_HINT); - PRIVATE_KEY_LOCK(); } #endif #endif @@ -105370,10 +105577,8 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t cryptocb_test(void) #endif #if defined(HAVE_ED25519) && \ (!defined(WOLF_CRYPTO_CB_ONLY_ED25519) || defined(WOLFSSL_SWDEV)) - PRIVATE_KEY_UNLOCK(); if (ret == 0) ret = ed25519_test(); - PRIVATE_KEY_LOCK(); #endif #if defined(WOLF_CRYPTO_CB_ONLY_ED25519) && !defined(WOLFSSL_SWDEV) PRIVATE_KEY_UNLOCK(); @@ -105558,8 +105763,11 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t cryptocb_test(void) #endif #endif #if defined(HAVE_HKDF) && !defined(NO_HMAC) - if (ret == 0) + if (ret == 0) { + PRIVATE_KEY_UNLOCK(); ret = hkdf_test(); + PRIVATE_KEY_LOCK(); + } #if !defined(NO_SHA256) && !defined(HAVE_SELFTEST) && \ !defined(HAVE_FIPS) if (ret == 0) diff --git a/wolfssl/internal.h b/wolfssl/internal.h index c3b447df35c..398ccd4617f 100644 --- a/wolfssl/internal.h +++ b/wolfssl/internal.h @@ -8216,9 +8216,9 @@ WOLFSSL_LOCAL int SetKeysSide(WOLFSSL* ssl, enum encrypt_side side); WOLFSSL_LOCAL int SetDsaInternal(WOLFSSL_DSA* dsa); WOLFSSL_LOCAL int SetDsaExternal(WOLFSSL_DSA* dsa); #ifndef NO_DSA -WOLFSSL_LOCAL int wolfssl_dsa_do_sign(const unsigned char* d, int dLen, +WOLFSSL_LOCAL int wolfssl_local_dsa_do_sign(const unsigned char* d, int dLen, unsigned char* sigRet, WOLFSSL_DSA* dsa); -WOLFSSL_LOCAL int wolfssl_dsa_do_verify(const unsigned char* d, int dLen, +WOLFSSL_LOCAL int wolfssl_local_dsa_do_verify(const unsigned char* d, int dLen, unsigned char* sig, WOLFSSL_DSA* dsa, int* dsacheck); #endif WOLFSSL_LOCAL int SetRsaExternal(WOLFSSL_RSA* rsa); diff --git a/wolfssl/wolfcrypt/error-crypt.h b/wolfssl/wolfcrypt/error-crypt.h index df07b63fdc0..547e1c512d2 100644 --- a/wolfssl/wolfcrypt/error-crypt.h +++ b/wolfssl/wolfcrypt/error-crypt.h @@ -398,7 +398,8 @@ WOLFSSL_ABI WOLFSSL_API const char* wc_GetErrorString(int error); (defined(BUILDING_WOLFSSL) || \ defined(WOLFSSL_DEBUG_TRACE_ERROR_CODES_ALWAYS)) && \ (!defined(WOLFSSL_DEBUG_TRACE_ERROR_CODES_PER_FILE) || \ - defined(WOLFSSL_DEBUG_TRACE_ERROR_CODES_THIS_FILE)) + defined(WOLFSSL_DEBUG_TRACE_ERROR_CODES_THIS_FILE)) && \ + !defined(WOLFSSL_DEBUG_NO_TRACE_ERROR_CODES_THIS_FILE) #include #define WC_NO_ERR_TRACE(label) (CONST_NUM_ERR_ ## label) diff --git a/wolfssl/wolfcrypt/memory.h b/wolfssl/wolfcrypt/memory.h index 91200566acb..d7a35203478 100644 --- a/wolfssl/wolfcrypt/memory.h +++ b/wolfssl/wolfcrypt/memory.h @@ -331,8 +331,10 @@ WOLFSSL_LOCAL void wc_MemZero_Add(const char* name, const void* addr, WOLFSSL_LOCAL void wc_MemZero_Check(void* addr, size_t len); #endif -#ifndef WOLFSSL_NO_FORCE_ZERO -WOLFSSL_API void wc_ForceZero(void *mem, size_t len); +#ifdef WOLFSSL_NO_FORCE_ZERO + #define wc_ForceZero ForceZero +#else + WOLFSSL_API void wc_ForceZero(void *mem, size_t len); #endif #ifndef WOLFSSL_NO_CONST_CMP diff --git a/wolfssl/wolfcrypt/types.h b/wolfssl/wolfcrypt/types.h index 0a33992fc4b..bcae15817a9 100644 --- a/wolfssl/wolfcrypt/types.h +++ b/wolfssl/wolfcrypt/types.h @@ -346,6 +346,9 @@ typedef const char wcchar[]; * octets per cell, low octet first. Convert at the boundary with * wc_UnpackOctets()/wc_PackOctets(), declared only where a cell is wider than * an octet - elsewhere the two layouts coincide and there is nothing to do. */ +#if (CHAR_BIT <= 0) || (CHAR_BIT % 8 != 0) + #error CHAR_BIT must be a positive multiple of 8. +#endif #define WC_OCTETS_PER_BYTE ((word32)(CHAR_BIT / 8)) /* Cells needed to hold octetSz octets packed. Divides before adding the * round-up so a near-WORD32_MAX octetSz cannot wrap. octetSz is evaluated diff --git a/wolfssl/wolfcrypt/wc_compat.h b/wolfssl/wolfcrypt/wc_compat.h index 2bfa5de687d..4a0ec45b796 100644 --- a/wolfssl/wolfcrypt/wc_compat.h +++ b/wolfssl/wolfcrypt/wc_compat.h @@ -69,6 +69,23 @@ #define wc_AesGcmEncrypt wc_AesGcmEncrypt_compat_shim + /* Reachable (via types.h) before memory.h's body when an application + * includes memory.h first: its include guard defers the body, so declare + * the exported zeroizer here for the inline shims below. Redeclaration + * with identical tokens is harmless. */ + #ifdef WOLFSSL_NO_FORCE_ZERO + /* The application-supplied zeroizer -- same tokens as misc.h, which + * no include path can have parsed yet (misc.h includes types.h, + * which reaches this header first). */ + /* NOLINTNEXTLINE(readability-redundant-declaration) */ + void ForceZero(void* mem, size_t len); + #undef wc_ForceZero + #define wc_ForceZero ForceZero + #else + /* NOLINTNEXTLINE(readability-redundant-declaration) */ + WOLFSSL_API void wc_ForceZero(void *mem, size_t len); + #endif + #ifdef WOLFSSL_AESGCM_STREAM static WC_INLINE int wc_AesGcmEncrypt_compat_shim(Aes* aes, byte* out, const byte* in, word32 sz, @@ -84,12 +101,24 @@ return BAD_FUNC_ARG; #endif ret = wc_AesGcmInit(aes, NULL /* key */, 0 /* len */, iv, ivSz); - if (ret) - return ret; - ret = wc_AesGcmEncryptUpdate(aes, out, in, sz, authIn, authInSz); - if (ret) - return ret; - return wc_AesGcmEncryptFinal(aes, authTag, authTagSz); + if (ret == 0) + ret = wc_AesGcmEncryptUpdate(aes, out, in, sz, authIn, authInSz); + if (ret == 0) + ret = wc_AesGcmEncryptFinal(aes, authTag, authTagSz); + if (ret != 0) { + /* Match the native one-shot's failure contract: no ciphertext and no + * tag escape a failed operation, whichever stage failed. On the + * Init/Update failure paths authTag was never written, so there this + * is contract uniformity rather than leak repair. */ + if (out != NULL) + wc_ForceZero(out, sz); + if (authTag != NULL) + wc_ForceZero(authTag, + authTagSz > WC_AES_BLOCK_SIZE + ? WC_AES_BLOCK_SIZE + : authTagSz); + } + return ret; } #else /* ! WOLFSSL_AESGCM_STREAM */ @@ -109,13 +138,22 @@ return BAD_LENGTH_E; ret = wc_AesGcmSetExtIV(aes, iv, ivSz); - if (ret != 0) - return ret; - ret = wc_AesGcmEncrypt_ex(aes, out, in, sz, scratch, ivSz, authTag, - authTagSz, authIn, authInSz); - if (ret != 0) - return ret; - return wc_AesGcmSetExtIV(aes, iv, ivSz); + if (ret == 0) + ret = wc_AesGcmEncrypt_ex(aes, out, in, sz, scratch, ivSz, authTag, + authTagSz, authIn, authInSz); + if (ret == 0) + ret = wc_AesGcmSetExtIV(aes, iv, ivSz); + if (ret != 0) { + /* Match above ISO-19790 wipe--this arm airdropped into old-FIPS. */ + if (out != NULL) + wc_ForceZero(out, sz); + if (authTag != NULL) + wc_ForceZero(authTag, + authTagSz > WC_AES_BLOCK_SIZE + ? WC_AES_BLOCK_SIZE + : authTagSz); + } + return ret; } #endif /* ! WOLFSSL_AESGCM_STREAM */ #endif /* HAVE_FIPS && HAVE_AESGCM && */