Merge pull request #10050 from anhu/pbkdf_max

Add upper limit to PBKDF iteration count
This commit is contained in:
David Garske
2026-05-12 09:10:54 -07:00
committed by GitHub
6 changed files with 255 additions and 47 deletions
+4 -25
View File
@@ -30,8 +30,8 @@ ARDUINO_UNOR4_WIFI
ASN_DUMP_OID
ASN_TEMPLATE_SKIP_ISCA_CHECK
ATCAPRINTF
ATCA_HAL_I2C
ATCA_ENABLE_DEPRECATED
ATCA_HAL_I2C
ATCA_TFLEX_SUPPORT
ATECC_DEV_TYPE
AVR
@@ -471,7 +471,6 @@ NO_WOLFSSL_RENESAS_FSPSM_AES
NO_WOLFSSL_RENESAS_FSPSM_HASH
NO_WOLFSSL_RENESAS_TSIP_CRYPT_AES
NO_WOLFSSL_SHA256
NO_WOLFSSL_SHA256_INTERLEAVE
NO_WOLFSSL_SHA512_INTERLEAVE
NO_WOLFSSL_SKIP_TRAILING_PAD
NO_WOLFSSL_SMALL_STACK_STATIC
@@ -628,7 +627,6 @@ USS_API
WC_AESXTS_STREAM_NO_REQUEST_ACCOUNTING
WC_AES_BS_WORD_SIZE
WC_AES_GCM_DEC_AUTH_EARLY
WC_ALLOW_ECC_ZERO_HASH
WC_ASN_HASH_SHA256
WC_ASN_RUNTIME_DATE_CHECK_CONTROL
WC_ASYNC_ENABLE_ECC_KEYGEN
@@ -653,8 +651,6 @@ WC_ASYNC_NO_SHA512
WC_ASYNC_NO_X25519
WC_ASYNC_THREAD_BIND
WC_CACHE_RESISTANT_BASE64_TABLE
WC_DILITHIUM_CACHE_PRIV_VECTORS
WC_DILITHIUM_CACHE_PUB_VECTORS
WC_DILITHIUM_FIXED_ARRAY
WC_DISABLE_RADIX_ZERO_PAD
WC_FLAG_DONT_USE_AESNI
@@ -718,11 +714,9 @@ WOLFSSL_ASN_EXTRA
WOLFSSL_ASN_TEMPLATE_NEED_SET_INT32
WOLFSSL_ASN_TEMPLATE_TYPE_CHECK
WOLFSSL_ATECC508
WOLFSSL_ATECC508A_NOIDLE
WOLFSSL_ATECC508A_NOSOFTECC
WOLFSSL_ATECC508A_TLS
WOLFSSL_ATECC_ECDH_IOENC
WOLFSSL_ATECC_NO_ECDH_ENC
WOLFSSL_ATECC_RNG
WOLFSSL_ATECC_TFLXTLS
WOLFSSL_ATECC_TNGTLS
@@ -743,15 +737,11 @@ WOLFSSL_CLIENT_EXAMPLE
WOLFSSL_CONTIKI
WOLFSSL_CRL_ALLOW_MISSING_CDP
WOLFSSL_DILITHIUM_ASSIGN_KEY
WOLFSSL_DILITHIUM_NO_ASN1
WOLFSSL_DILITHIUM_NO_CHECK_KEY
WOLFSSL_DILITHIUM_NO_MAKE
WOLFSSL_DILITHIUM_REVERSE_HASH_OID
WOLFSSL_DILITHIUM_SIGN_CHECK_W0
WOLFSSL_DILITHIUM_SIGN_CHECK_Y
WOLFSSL_DILITHIUM_SIGN_SMALL_MEM_PRECALC
WOLFSSL_DILITHIUM_SIGN_SMALL_MEM_PRECALC_A
WOLFSSL_DILITHIUM_SMALL_MEM_POLY64
WOLFSSL_DISABLE_EARLY_SANITY_CHECKS
WOLFSSL_DRBG_SHA256
WOLFSSL_DTLS_DISALLOW_FUTURE
@@ -808,10 +798,8 @@ WOLFSSL_LINUXKM_USE_GET_RANDOM_USER_KRETPROBE
WOLFSSL_LINUXKM_USE_MUTEXES
WOLFSSL_LMS_CACHE_BITS
WOLFSSL_LMS_FULL_HASH
WOLFSSL_LMS_LARGE_CACHES
WOLFSSL_LMS_MAX_HEIGHT
WOLFSSL_LMS_MAX_LEVELS
WOLFSSL_LMS_NO_SIG_CACHE
WOLFSSL_LMS_ROOT_LEVELS
WOLFSSL_LPC43xx
WOLFSSL_MAKE_SYSTEM_NAME_LINUX
@@ -868,16 +856,10 @@ WOLFSSL_NO_TICKET_EXPIRE
WOLFSSL_NO_TRUSTED_CERTS_VERIFY
WOLFSSL_NO_WORD64_OPS
WOLFSSL_NO_XOR_OPS
WOLFSSL_NXP_LPC55S6X
WOLFSSL_NXP_CASPER
WOLFSSL_NXP_CASPER_ECC_MULMOD
WOLFSSL_NXP_CASPER_ECC_MUL2ADD
WOLFSSL_NXP_CASPER_RSA_PUB_EXPTMOD
WOLFSSL_NXP_HASHCRYPT
WOLFSSL_NXP_HASHCRYPT_AES
WOLFSSL_NXP_HASHCRYPT_SHA
WOLFSSL_NXP_RNG_1
WOLFSSL_NRF51_AES
WOLFSSL_NXP_CASPER_ECC_MUL2ADD
WOLFSSL_NXP_CASPER_ECC_MULMOD
WOLFSSL_NXP_LPC55S6X
WOLFSSL_OLDTLS_AEAD_CIPHERSUITES
WOLFSSL_OLD_SET_CURVES_LIST
WOLFSSL_OLD_TIMINGPADVERIFY
@@ -970,10 +952,8 @@ WOLFSSL_USE_FLASHMEM
WOLFSSL_USE_FORCE_ZERO
WOLFSSL_USE_OPTIONS_H
WOLFSSL_VALIDATE_DH_KEYGEN
WOLFSSL_WC_LMS_SERIALIZE_STATE
WOLFSSL_WC_SLHDSA_RECURSIVE
WOLFSSL_WC_XMSS_NO_SHA256
WOLFSSL_WC_XMSS_NO_SHAKE256
WOLFSSL_WICED_PSEUDO_UNIX_EPOCH_TIME
WOLFSSL_X509_STORE_ALLOW_NON_CA_INTERMEDIATE
WOLFSSL_X509_STORE_CERTS
@@ -982,7 +962,6 @@ WOLFSSL_XFREE_NO_NULLNESS_CHECK
WOLFSSL_XILINX_CRYPTO_OLD
WOLFSSL_XILINX_PATCH
WOLFSSL_XIL_MSG_NO_SLEEP
WOLFSSL_XMSS_LARGE_SECRET_KEY
WOLFSSL_ZEPHYR
WOLF_ALLOW_BUILTIN
WOLF_CRYPTO_CB_CMD
+53 -3
View File
@@ -174,7 +174,8 @@ int wc_PKCS12_PBKDF(byte* output, const byte* passwd, int passLen,
\brief Extended version of PBKDF1 with heap hint.
\return 0 on success
\return BAD_FUNC_ARG on invalid arguments
\return BAD_FUNC_ARG on invalid arguments or iterations is greater than
current_wc_pbkdf_max_iterations
\return MEMORY_E on memory allocation error
\param key Output key buffer
@@ -199,6 +200,8 @@ int wc_PKCS12_PBKDF(byte* output, const byte* passwd, int passLen,
\endcode
\sa wc_PBKDF1
\sa wc_PBKDF_max_iterations_set
\sa wc_PBKDF_max_iterations_get
*/
int wc_PBKDF1_ex(byte* key, int keyLen, byte* iv, int ivLen,
const byte* passwd, int passwdLen, const byte* salt, int saltLen,
@@ -209,7 +212,8 @@ int wc_PBKDF1_ex(byte* key, int keyLen, byte* iv, int ivLen,
\brief Extended version of PBKDF2 with heap hint and device ID.
\return 0 on success
\return BAD_FUNC_ARG on invalid arguments
\return BAD_FUNC_ARG on invalid arguments or iterations is greater than
current_wc_pbkdf_max_iterations
\return MEMORY_E on memory allocation error
\param output Output key buffer
@@ -234,6 +238,8 @@ int wc_PBKDF1_ex(byte* key, int keyLen, byte* iv, int ivLen,
\endcode
\sa wc_PBKDF2
\sa wc_PBKDF_max_iterations_set
\sa wc_PBKDF_max_iterations_get
*/
int wc_PBKDF2_ex(byte* output, const byte* passwd, int pLen,
const byte* salt, int sLen, int iterations, int kLen,
@@ -244,7 +250,8 @@ int wc_PBKDF2_ex(byte* output, const byte* passwd, int pLen,
\brief Extended version of PKCS12_PBKDF with heap hint.
\return 0 on success
\return BAD_FUNC_ARG on invalid arguments
\return BAD_FUNC_ARG on invalid arguments or iterations is greater than
current_wc_pbkdf_max_iterations
\return MEMORY_E on memory allocation error
\param output Output key buffer
@@ -268,6 +275,8 @@ int wc_PBKDF2_ex(byte* output, const byte* passwd, int pLen,
\endcode
\sa wc_PKCS12_PBKDF
\sa wc_PBKDF_max_iterations_set
\sa wc_PBKDF_max_iterations_get
*/
int wc_PKCS12_PBKDF_ex(byte* output, const byte* passwd,int passLen,
const byte* salt, int saltLen, int iterations, int kLen,
@@ -338,3 +347,44 @@ int wc_scrypt(byte* output, const byte* passwd, int passLen,
int wc_scrypt_ex(byte* output, const byte* passwd, int passLen,
const byte* salt, int saltLen, word32 iterations, int blockSize,
int parallel, int dkLen);
/*!
\ingroup Password
\brief Set the current iteration limit for PBKDF.
By default, the iteration limit is set to WC_PBKDF_DEFAULT_MAX_ITERATIONS,
which can be overridden at build time. This function allows runtime
override of the limit.
Note that `wc_PBKDF_max_iterations_set()` has no provisions for thread
synchronization. Users should arrange to call it at startup or idle times,
when there are no other PBKDF calls in progress.
\return Previous iteration limit on success
\return BAD_FUNC_ARG on invalid arguments
\param iters The new iteration limit.
_Example_
\code
int prev_iter_limit = wc_PBKDF_max_iterations_set(100000000);
\endcode
\sa wc_scrypt
*/
int wc_PBKDF_max_iterations_set(int iters);
/*!
\ingroup Password
\brief Get the current iteration limit for PBKDF.
\return Current iteration limit
_Example_
\code
int cur_iter_limit = wc_PBKDF_max_iterations_get();
\endcode
\sa wc_scrypt
*/
int wc_PBKDF_max_iterations_get(void);
+46 -16
View File
@@ -54,6 +54,24 @@
}
#endif
static int current_wc_pbkdf_max_iterations = WC_PBKDF_DEFAULT_MAX_ITERATIONS;
int wc_PBKDF_max_iterations_set(int iters)
{
if (iters <= 0)
return BAD_FUNC_ARG;
else {
int prev = current_wc_pbkdf_max_iterations;
current_wc_pbkdf_max_iterations = iters;
return prev;
}
}
int wc_PBKDF_max_iterations_get(void)
{
return current_wc_pbkdf_max_iterations;
}
#ifdef HAVE_PBKDF1
/* PKCS#5 v1.5 with non standard extension to optionally derive the extra data (IV) */
@@ -82,6 +100,11 @@ int wc_PBKDF1_ex(byte* key, int keyLen, byte* iv, int ivLen,
if (iterations <= 0)
iterations = 1;
if (iterations > current_wc_pbkdf_max_iterations) {
WOLFSSL_MSG("PBKDF1 iteration count exceeds current_wc_pbkdf_max_iterations");
return BAD_FUNC_ARG;
}
hashT = wc_HashTypeConvert(hashType);
err = wc_HashGetDigestSize(hashT);
if (err < 0)
@@ -218,6 +241,11 @@ int wc_PBKDF2_ex(byte* output, const byte* passwd, int pLen, const byte* salt,
if (iterations <= 0)
iterations = 1;
if (iterations > current_wc_pbkdf_max_iterations) {
WOLFSSL_MSG("PBKDF2 iteration count exceeds current_wc_pbkdf_max_iterations");
return BAD_FUNC_ARG;
}
hashT = wc_HashTypeConvert(hashType);
hLen = wc_HashGetDigestSize(hashT);
if (hLen < 0)
@@ -406,6 +434,12 @@ int wc_PKCS12_PBKDF_ex(byte* output, const byte* passwd, int passLen,
if (iterations <= 0)
iterations = 1;
if (iterations > current_wc_pbkdf_max_iterations) {
WOLFSSL_MSG("PKCS12 PBKDF iteration count exceeds "
"current_wc_pbkdf_max_iterations");
return BAD_FUNC_ARG;
}
hashT = wc_HashTypeConvert(hashType);
ret = wc_HashGetDigestSize(hashT);
if (ret < 0)
@@ -443,22 +477,17 @@ int wc_PKCS12_PBKDF_ex(byte* output, const byte* passwd, int passLen,
* must be 1 or greater here and is always 'true' */
pLen = v * (((word32)passLen + v - 1) / v);
/* Guard against overflow in iLen = sLen + pLen and totalLen = dLen + iLen.
* Individual sLen/pLen values fit in word32 (max 0x80000000 for INT_MAX
* inputs), but their sum can overflow. */
if (sLen > 0xFFFFFFFFU - pLen) {
if (! WC_SAFE_SUM_UNSIGNED(word32, sLen, pLen, iLen)) {
WC_FREE_VAR_EX(Ai, heap, DYNAMIC_TYPE_TMP_BUFFER);
WC_FREE_VAR_EX(B, heap, DYNAMIC_TYPE_TMP_BUFFER);
return BAD_FUNC_ARG;
}
iLen = sLen + pLen;
if (iLen > 0xFFFFFFFFU - dLen) {
if (! WC_SAFE_SUM_UNSIGNED(word32, dLen, sLen, totalLen)) {
WC_FREE_VAR_EX(Ai, heap, DYNAMIC_TYPE_TMP_BUFFER);
WC_FREE_VAR_EX(B, heap, DYNAMIC_TYPE_TMP_BUFFER);
return BAD_FUNC_ARG;
}
totalLen = dLen + sLen + pLen;
if (totalLen > sizeof(staticBuffer)) {
buffer = (byte*)XMALLOC(totalLen, heap, DYNAMIC_TYPE_KEY);
@@ -634,6 +663,12 @@ int wc_PKCS12_PBKDF_ex(byte* output, const byte* passwd, int passLen,
iterations = 1;
}
if (iterations > current_wc_pbkdf_max_iterations) {
WOLFSSL_MSG("PKCS12 PBKDF iteration count exceeds "
"current_wc_pbkdf_max_iterations");
return BAD_FUNC_ARG;
}
/* u = hash output size. */
hashT = wc_HashTypeConvert(hashType);
ret = wc_HashGetDigestSize(hashT);
@@ -656,19 +691,14 @@ int wc_PKCS12_PBKDF_ex(byte* output, const byte* passwd, int passLen,
/* RFC 7292 B.2 step 3: P = password repeated to ceil(passLen/v)*v bytes */
pLen = v * (((word32)passLen + v - 1) / v);
/* Guard against overflow in iLen = sLen + pLen and totalLen = v + iLen.
* Individual sLen/pLen values fit in word32 (max 0x80000000 for INT_MAX
* inputs), but their sum can overflow. */
if (sLen > 0xFFFFFFFFU - pLen) {
return BAD_FUNC_ARG;
}
/* RFC 7292 B.2 step 4: I = S || P */
iLen = sLen + pLen;
if (! WC_SAFE_SUM_UNSIGNED(word32, sLen, pLen, iLen)) {
return BAD_FUNC_ARG;
}
if (iLen > 0xFFFFFFFFU - v) {
if (! WC_SAFE_SUM_UNSIGNED(word32, v, iLen, totalLen)) {
return BAD_FUNC_ARG;
}
totalLen = v + iLen;
nwc = v / (word32)sizeof(PKCS12_WORD);
nBlocks = iLen / v;
+126 -3
View File
@@ -917,12 +917,18 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t openSSL_evpMD_test(void);
WOLFSSL_TEST_SUBROUTINE wc_test_ret_t openssl_evpSig_test(void);
#endif
#if defined(HAVE_PBKDF1) && !defined(NO_SHA)
WOLFSSL_TEST_SUBROUTINE wc_test_ret_t pbkdf1_test(void);
#endif
#if defined(HAVE_PKCS12) && !defined(NO_SHA256)
WOLFSSL_TEST_SUBROUTINE wc_test_ret_t pkcs12_pbkdf_test(void);
#endif
#if defined(HAVE_PBKDF2) && !defined(NO_SHA256) && !defined(NO_HMAC)
WOLFSSL_TEST_SUBROUTINE wc_test_ret_t pbkdf2_test(void);
#endif
#if !defined(NO_PWDBASED) && defined(HAVE_SCRYPT)
WOLFSSL_TEST_SUBROUTINE wc_test_ret_t scrypt_test(void);
#endif
#ifdef HAVE_ECC
WOLFSSL_TEST_SUBROUTINE wc_test_ret_t ecc_test(void);
#if defined(HAVE_ECC_ENCRYPT) && defined(HAVE_AES_CBC) && \
@@ -32207,7 +32213,31 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t pbkdf2_test(void)
if (XMEMCMP(derived, verify, sizeof(verify)) != 0)
return WC_TEST_RET_ENC_NC;
return 0;
{
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);
ret = wc_PBKDF2_ex(derived, (byte*)passwd, (int)XSTRLEN(passwd),
salt, (int)sizeof(salt), iterations,
kLen, WC_SHA256, HEAP_HINT, devId);
if (ret != WC_NO_ERR_TRACE(BAD_FUNC_ARG))
return WC_TEST_RET_ENC_EC(ret);
ret = wc_PBKDF_max_iterations_set(-1);
if (ret != WC_NO_ERR_TRACE(BAD_FUNC_ARG))
return WC_TEST_RET_ENC_EC(ret);
ret = wc_PBKDF_max_iterations_set(0);
if (ret != WC_NO_ERR_TRACE(BAD_FUNC_ARG))
return WC_TEST_RET_ENC_EC(ret);
ret = wc_PBKDF_max_iterations_get();
if (ret != iterations - 1)
return WC_TEST_RET_ENC_NC;
ret = wc_PBKDF_max_iterations_set(cur_pbkdf_limit);
if (ret != iterations - 1)
return WC_TEST_RET_ENC_EC(ret);
ret = 0;
}
return ret;
}
#endif /* HAVE_PBKDF2 && !NO_SHA256 && !NO_HMAC */
@@ -32262,10 +32292,58 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t pwdbased_test(void)
if (ret != 0)
return ret;
#endif
#if defined(HAVE_PKCS12) && !defined(NO_ASN) && !defined(NO_PWDBASED) && \
!defined(NO_HMAC) && !defined(NO_CERTS) && !defined(WOLFSSL_NO_MALLOC)
/* Test that a crafted PKCS#12 with INT_MAX MAC iterations is rejected
* immediately rather than hanging in DoPKCS12Hash(). */
{
static const byte evil_p12[] = {
0x30, 0x58, 0x02, 0x01, 0x03, 0x30, 0x1e, 0x06,
0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01,
0x07, 0x01, 0xa0, 0x11, 0x04, 0x0f, 0x30, 0x0d,
0x30, 0x0b, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
0xf7, 0x0d, 0x01, 0x07, 0x01, 0x30, 0x33, 0x30,
0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03,
0x02, 0x1a, 0x05, 0x00, 0x04, 0x14, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x04, 0x08, 0x41, 0x41, 0x41, 0x41,
0x41, 0x41, 0x41, 0x41, 0x02, 0x04, 0x7f, 0xff,
0xff, 0xff
};
WC_PKCS12* evilPkcs12 = wc_PKCS12_new_ex(HEAP_HINT);
if (evilPkcs12 == NULL)
return WC_TEST_RET_ENC_EC(MEMORY_E);
ret = wc_d2i_PKCS12(evil_p12, (word32)sizeof(evil_p12), evilPkcs12);
if (ret != 0)
ret = WC_TEST_RET_ENC_EC(ret);
else {
byte* evilKey = NULL;
byte* evilCert = NULL;
word32 evilKeySz = 0, evilCertSz = 0;
WC_DerCertList* evilCa = NULL;
ret = wc_PKCS12_parse(evilPkcs12, "test", &evilKey, &evilKeySz,
&evilCert, &evilCertSz, &evilCa);
/* Parse must fail (iteration cap), not succeed or hang */
if (ret == 0)
ret = WC_TEST_RET_ENC_NC;
else
ret = 0;
XFREE(evilKey, HEAP_HINT, DYNAMIC_TYPE_PKCS);
XFREE(evilCert, HEAP_HINT, DYNAMIC_TYPE_PKCS);
if (evilCa)
wc_FreeCertList(evilCa, HEAP_HINT);
}
wc_PKCS12_free(evilPkcs12);
if (ret != 0)
return ret;
}
#endif /* HAVE_PKCS12 && !NO_ASN && !NO_PWDBASED && !NO_HMAC && !NO_CERTS && */
/* !WOLFSSL_NO_MALLOC */
#ifdef HAVE_SCRYPT
ret = scrypt_test();
if (ret != 0)
return ret;
#endif
return ret;
}
@@ -32361,6 +32439,51 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t pkcs12_test(void)
goto out;
}
/* Test that a crafted PKCS#12 with INT_MAX MAC iterations is rejected
* immediately rather than hanging in DoPKCS12Hash(). This is a 90-byte
* minimal PKCS#12 with mac->itt = 0x7FFFFFFF (2,147,483,647). */
{
static const byte evil_p12[] = {
0x30, 0x58, 0x02, 0x01, 0x03, 0x30, 0x1e, 0x06,
0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01,
0x07, 0x01, 0xa0, 0x11, 0x04, 0x0f, 0x30, 0x0d,
0x30, 0x0b, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
0xf7, 0x0d, 0x01, 0x07, 0x01, 0x30, 0x33, 0x30,
0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03,
0x02, 0x1a, 0x05, 0x00, 0x04, 0x14, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x04, 0x08, 0x41, 0x41, 0x41, 0x41,
0x41, 0x41, 0x41, 0x41, 0x02, 0x04, 0x7f, 0xff,
0xff, 0xff
};
WC_PKCS12* evilPkcs12 = wc_PKCS12_new_ex(HEAP_HINT);
if (evilPkcs12 == NULL) {
ret = WC_TEST_RET_ENC_EC(MEMORY_E);
goto out;
}
ret = wc_d2i_PKCS12(evil_p12, (word32)sizeof(evil_p12), evilPkcs12);
if (ret == 0) {
byte* evilKey = NULL;
byte* evilCert = NULL;
word32 evilKeySz = 0, evilCertSz = 0;
WC_DerCertList* evilCa = NULL;
ret = wc_PKCS12_parse(evilPkcs12, "test", &evilKey, &evilKeySz,
&evilCert, &evilCertSz, &evilCa);
XFREE(evilKey, HEAP_HINT, DYNAMIC_TYPE_PKCS);
XFREE(evilCert, HEAP_HINT, DYNAMIC_TYPE_PKCS);
if (evilCa)
wc_FreeCertList(evilCa, HEAP_HINT);
wc_PKCS12_free(evilPkcs12);
/* Must have been rejected (not hung) */
if (ret == 0) {
ret = WC_TEST_RET_ENC_NC;
goto out;
}
ret = 0; /* rejection is the expected outcome */
}
}
out:
if (derCaListOut)
+6
View File
@@ -266,12 +266,18 @@ extern WOLFSSL_TEST_SUBROUTINE wc_test_ret_t openSSL_evpMD_test(void);
extern WOLFSSL_TEST_SUBROUTINE wc_test_ret_t openssl_evpSig_test(void);
#endif
#if defined(HAVE_PBKDF1) && !defined(NO_SHA)
extern WOLFSSL_TEST_SUBROUTINE wc_test_ret_t pbkdf1_test(void);
#endif
#if defined(HAVE_PKCS12) && !defined(NO_SHA256)
extern WOLFSSL_TEST_SUBROUTINE wc_test_ret_t pkcs12_pbkdf_test(void);
#endif
#if defined(HAVE_PBKDF2) && !defined(NO_SHA256) && !defined(NO_HMAC)
extern WOLFSSL_TEST_SUBROUTINE wc_test_ret_t pbkdf2_test(void);
#endif
#if !defined(NO_PWDBASED) && defined(HAVE_SCRYPT)
extern WOLFSSL_TEST_SUBROUTINE wc_test_ret_t scrypt_test(void);
#endif
#ifdef HAVE_ECC
extern WOLFSSL_TEST_SUBROUTINE wc_test_ret_t ecc_test(void);
#if defined(HAVE_ECC_ENCRYPT) && defined(HAVE_AES_CBC) && \
+20
View File
@@ -35,6 +35,26 @@
extern "C" {
#endif
/* Maximum allowed PBKDF iteration count to prevent CPU exhaustion DoS.
* Attacker-controlled PKCS#12 files can specify iterations up to INT_MAX
* (2,147,483,647) in the MAC data, causing hours of CPU time.
* Override by defining WC_PBKDF_DEFAULT_MAX_ITERATIONS before including
* this header, and override at runtime by calling
* wc_PBKDF_max_iterations_set() at application startup.
*
* Note that typical PKCS12 files use 1k to 10k iterations.
*/
#ifndef WC_PBKDF_DEFAULT_MAX_ITERATIONS
#define WC_PBKDF_DEFAULT_MAX_ITERATIONS 10000000
#endif
/* Note that wc_PBKDF_max_iterations_set() has no provisions for thread
* synchronization. Users should arrange to call it at startup or idle times,
* when there are no other PBKDF calls in progress.
*/
WOLFSSL_API int wc_PBKDF_max_iterations_set(int iters);
WOLFSSL_API int wc_PBKDF_max_iterations_get(void);
#if FIPS_VERSION3_GE(6,0,0)
extern const unsigned int wolfCrypt_FIPS_pbkdf_ro_sanity[2];
WOLFSSL_LOCAL int wolfCrypt_FIPS_PBKDF_sanity(void);