diff --git a/wolfcrypt/src/pwdbased.c b/wolfcrypt/src/pwdbased.c index e5715fd5a..b2400a2a2 100644 --- a/wolfcrypt/src/pwdbased.c +++ b/wolfcrypt/src/pwdbased.c @@ -566,6 +566,11 @@ int wc_PKCS12_PBKDF_ex(byte* output, const byte* passwd, int passLen, */ #define R(a, b) rotlFixed(a, b) +/* (2^32 - 1) */ +#define SCRYPT_WORD32_MAX 4294967295U +/* (2^32 - 1) * 32, used in a couple of scrypt max calculations. */ +#define SCRYPT_MAX 137438953440UL + /* One round of Salsa20/8. * Code taken from RFC 7914: scrypt PBKDF. * @@ -755,7 +760,12 @@ int wc_scrypt(byte* output, const byte* passwd, int passLen, if (cost < 1 || cost >= 128 * blockSize / 8 || parallel < 1 || dkLen < 1) return BAD_FUNC_ARG; + if ((word32)parallel > (SCRYPT_MAX / (128 * blockSize))) + return BAD_FUNC_ARG; + bSz = 128 * blockSize; + if ((word32)parallel > (SCRYPT_WORD32_MAX / bSz)) + return BAD_FUNC_ARG; blocksSz = bSz * parallel; blocks = (byte*)XMALLOC(blocksSz, NULL, DYNAMIC_TYPE_TMP_BUFFER); if (blocks == NULL) { diff --git a/wolfcrypt/test/test.c b/wolfcrypt/test/test.c index c73c68952..e953e8ef5 100644 --- a/wolfcrypt/test/test.c +++ b/wolfcrypt/test/test.c @@ -20179,6 +20179,12 @@ WOLFSSL_TEST_SUBROUTINE int scrypt_test(void) if (XMEMCMP(derived, verify2, sizeof(verify2)) != 0) return -9203; + /* Test case with parallel overflowing */ + ret = wc_scrypt(derived, (byte*)"password", 16, (byte*)"NaCl", 16, 2, 4, 8388608, + sizeof(verify2)); + if (ret != BAD_FUNC_ARG) + return -9210; + /* Don't run these test on embedded, since they use large mallocs */ #if !defined(BENCH_EMBEDDED) && !defined(WOLFSSL_LINUXKM) && !defined(HAVE_INTEL_QA) ret = wc_scrypt(derived, (byte*)"pleaseletmein", 13,