diff --git a/wolfcrypt/src/dh.c b/wolfcrypt/src/dh.c index 55d82c0e23..b57ce7d8e1 100644 --- a/wolfcrypt/src/dh.c +++ b/wolfcrypt/src/dh.c @@ -1713,6 +1713,9 @@ int wc_DhCheckPubValue(const byte* prime, word32 primeSz, const byte* pub, int ret = 0; word32 i; + if (prime == NULL || pub == NULL) + return BAD_FUNC_ARG; + for (i = 0; i < pubSz && pub[i] == 0; i++) { } pubSz -= i; diff --git a/wolfcrypt/src/ecc.c b/wolfcrypt/src/ecc.c index a3e708e989..2453f4445d 100644 --- a/wolfcrypt/src/ecc.c +++ b/wolfcrypt/src/ecc.c @@ -10982,16 +10982,24 @@ static int _ecc_import_x963_ex2(const byte* in, word32 inLen, ecc_key* key, if (err == MP_OKAY) { #ifdef HAVE_COMP_KEY /* adjust inLen if compressed */ - if (compressed) - inLen = inLen*2 + 1; /* used uncompressed len */ + if (compressed) { + /* a compressed coordinate cannot exceed MAX_ECC_BYTES; bound it + * before doubling so inLen*2 + 1 cannot overflow word32. */ + if (inLen > MAX_ECC_BYTES) + err = BAD_FUNC_ARG; + else + inLen = inLen*2 + 1; /* used uncompressed len */ + } #endif /* determine key size */ - keysize = (int)(inLen>>1); - /* NOTE: FIPS v6.0.0 or greater, no restriction on imported keys, only - * on created keys or signatures */ - err = wc_ecc_set_curve(key, keysize, curve_id); - key->type = ECC_PUBLICKEY; + if (err == MP_OKAY) { + keysize = (int)(inLen>>1); + /* NOTE: FIPS v6.0.0 or greater, no restriction on imported keys, + * only on created keys or signatures */ + err = wc_ecc_set_curve(key, keysize, curve_id); + key->type = ECC_PUBLICKEY; + } } /* read data */ diff --git a/wolfcrypt/src/kdf.c b/wolfcrypt/src/kdf.c index 4ae7d584f9..90ef96a4bf 100644 --- a/wolfcrypt/src/kdf.c +++ b/wolfcrypt/src/kdf.c @@ -89,6 +89,10 @@ int wc_PRF(byte* result, word32 resLen, const byte* secret, Hmac hmac[1]; #endif + if ((result == NULL && resLen != 0) || (secret == NULL && secLen != 0) || + (seed == NULL && seedLen != 0)) + return BAD_FUNC_ARG; + switch (hash) { #ifndef NO_MD5 case md5_mac: @@ -234,8 +238,18 @@ int wc_PRF_TLSv1(byte* digest, word32 digLen, const byte* secret, WC_DECLARE_VAR(sha_result, byte, MAX_PRF_DIG, heap); /* digLen is real size */ WC_DECLARE_VAR(labelSeed, byte, MAX_PRF_LABSEED, heap); + if ((digest == NULL && digLen != 0) || + (secret == NULL && secLen != 0) || + (label == NULL && labLen != 0) || + (seed == NULL && seedLen != 0)) { + return BAD_FUNC_ARG; + } + + /* labLen + seedLen is checked with subtraction to avoid word32 wraparound + * (the labLen bound first ensures MAX_PRF_LABSEED - labLen cannot + * underflow). */ if (half > MAX_PRF_HALF || - labLen + seedLen > MAX_PRF_LABSEED || + labLen > MAX_PRF_LABSEED || seedLen > (MAX_PRF_LABSEED - labLen) || digLen > MAX_PRF_DIG) { return BUFFER_E; @@ -251,8 +265,10 @@ int wc_PRF_TLSv1(byte* digest, word32 digLen, const byte* secret, sha_half = secret + half - secLen % 2; md5_result = digest; - XMEMCPY(labelSeed, label, labLen); - XMEMCPY(labelSeed + labLen, seed, seedLen); + if (labLen != 0) + XMEMCPY(labelSeed, label, labLen); + if (seedLen != 0) + XMEMCPY(labelSeed + labLen, seed, seedLen); if ((ret = wc_PRF(md5_result, digLen, md5_half, half, labelSeed, labLen + seedLen, md5_mac, heap, devId)) == 0) { @@ -286,6 +302,13 @@ int wc_PRF_TLS(byte* digest, word32 digLen, const byte* secret, word32 secLen, { int ret = 0; + if ((digest == NULL && digLen != 0) || + (secret == NULL && secLen != 0) || + (label == NULL && labLen != 0) || + (seed == NULL && seedLen != 0)) { + return BAD_FUNC_ARG; + } + #ifdef WOLFSSL_DEBUG_TLS WOLFSSL_MSG(" secret"); WOLFSSL_BUFFER(secret, secLen); @@ -298,15 +321,19 @@ int wc_PRF_TLS(byte* digest, word32 digLen, const byte* secret, word32 secLen, if (useAtLeastSha256) { WC_DECLARE_VAR(labelSeed, byte, MAX_PRF_LABSEED, 0); - if (labLen + seedLen > MAX_PRF_LABSEED) { + /* Checked with subtraction to avoid word32 wraparound of + * labLen + seedLen. */ + if (labLen > MAX_PRF_LABSEED || seedLen > (MAX_PRF_LABSEED - labLen)) { return BUFFER_E; } WC_ALLOC_VAR_EX(labelSeed, byte, MAX_PRF_LABSEED, heap, DYNAMIC_TYPE_DIGEST, return MEMORY_E); - XMEMCPY(labelSeed, label, labLen); - XMEMCPY(labelSeed + labLen, seed, seedLen); + if (labLen != 0) + XMEMCPY(labelSeed, label, labLen); + if (seedLen != 0) + XMEMCPY(labelSeed + labLen, seed, seedLen); /* If a cipher suite wants an algorithm better than sha256, it * should use better. */ diff --git a/wolfcrypt/src/rsa.c b/wolfcrypt/src/rsa.c index cd66eab2ef..8e900932e4 100644 --- a/wolfcrypt/src/rsa.c +++ b/wolfcrypt/src/rsa.c @@ -1825,7 +1825,7 @@ static int RsaUnPad_OAEP(byte *pkcsBlock, unsigned int pkcsBlockLen, if (ret != 0) { ForceZero(tmp, hLen); #ifdef WOLFSSL_SMALL_STACK - XFREE(tmp, NULL, DYNAMIC_TYPE_RSA_BUFFER); + XFREE(tmp, heap, DYNAMIC_TYPE_RSA_BUFFER); #elif defined(WOLFSSL_CHECK_MEM_ZERO) wc_MemZero_Check(tmp, hLen); #endif @@ -5412,7 +5412,11 @@ int wc_MakeRsaKey(RsaKey* key, int size, long e, WC_RNG* rng) goto out; } +#if defined(HAVE_FIPS) + if (e < WC_RSA_EXPONENT || (e & 1) == 0) { +#else if (e < 3 || (e & 1) == 0) { +#endif err = BAD_FUNC_ARG; goto out; }