Merge pull request #9829 from night1rider/tmpSha-fixes

Fix potential memory leak when copying into existing SHA contexts and zero init tmpSha
This commit is contained in:
Sean Parkinson
2026-03-02 21:18:55 +10:00
committed by GitHub
12 changed files with 397 additions and 5 deletions
+4
View File
@@ -12368,6 +12368,7 @@ static int BuildMD5(WOLFSSL* ssl, Hashes* hashes, const byte* sender)
#else
wc_Md5 md5[1];
#endif
XMEMSET(md5, 0, sizeof(wc_Md5));
/* make md5 inner */
ret = wc_Md5Copy(&ssl->hsHashes->hashMd5, md5);
@@ -12413,6 +12414,7 @@ static int BuildSHA(WOLFSSL* ssl, Hashes* hashes, const byte* sender)
#else
wc_Sha sha[1];
#endif
XMEMSET(sha, 0, sizeof(wc_Sha));
/* make sha inner */
ret = wc_ShaCopy(&ssl->hsHashes->hashSha, sha); /* Save current position */
if (ret == 0)
@@ -23919,6 +23921,7 @@ static int BuildMD5_CertVerify(const WOLFSSL* ssl, byte* digest)
#else
wc_Md5 md5[1];
#endif
XMEMSET(md5, 0, sizeof(wc_Md5));
/* make md5 inner */
ret = wc_Md5Copy(&ssl->hsHashes->hashMd5, md5); /* Save current position */
@@ -23962,6 +23965,7 @@ static int BuildSHA_CertVerify(const WOLFSSL* ssl, byte* digest)
#else
wc_Sha sha[1];
#endif
XMEMSET(sha, 0, sizeof(wc_Sha));
/* make sha inner */
ret = wc_ShaCopy(&ssl->hsHashes->hashSha, sha); /* Save current position */
+2
View File
@@ -11983,6 +11983,8 @@ static int ExpectedResumptionSecret(WOLFSSL* ssl)
Digest digest;
static byte header[] = { 0x14, 0x00, 0x00, 0x00 };
XMEMSET(&digest, 0, sizeof(Digest));
/* Copy the running hash so we can restore it after. */
switch (ssl->specs.mac_algorithm) {
#ifndef NO_SHA256
+3
View File
@@ -5846,6 +5846,9 @@ void wolfSSL_EVP_init(void)
if (out->pctx == NULL)
return WOLFSSL_FAILURE;
}
/* Zero hash context after shallow copy to prevent shared sub-pointers
* with src. The hash Copy function will perform the proper deep copy. */
XMEMSET(&out->hash, 0, sizeof(out->hash));
return wolfSSL_EVP_MD_Copy_Hasher(out, (WOLFSSL_EVP_MD_CTX*)in);
}
#ifndef NO_AES
+5
View File
@@ -331,6 +331,11 @@ int wc_HmacCopy(Hmac* src, Hmac* dst) {
XMEMCPY(dst, src, sizeof(*dst));
/* Zero hash context after shallow copy to prevent shared sub-pointers
* (e.g., msg, W buffers) with src. The hash Copy function will perform
* the proper deep copy. */
XMEMSET(&dst->hash, 0, sizeof(wc_HmacHash));
ret = HmacKeyCopyHash(src->macType, &src->hash, &dst->hash);
if (ret != 0)
+4
View File
@@ -522,6 +522,7 @@ int wc_Md5GetHash(wc_Md5* md5, byte* hash)
if (md5 == NULL || hash == NULL)
return BAD_FUNC_ARG;
XMEMSET(&tmpMd5, 0, sizeof(tmpMd5));
ret = wc_Md5Copy(md5, &tmpMd5);
if (ret == 0) {
ret = wc_Md5Final(&tmpMd5, hash);
@@ -537,6 +538,9 @@ int wc_Md5Copy(wc_Md5* src, wc_Md5* dst)
if (src == NULL || dst == NULL)
return BAD_FUNC_ARG;
/* Free dst resources before copy to prevent memory leaks (e.g.,
* hardware contexts). XMEMCPY overwrites dst. */
wc_Md5Free(dst);
XMEMCPY(dst, src, sizeof(wc_Md5));
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_MD5)
@@ -1031,6 +1031,7 @@ int wc_Sha256GetHash(wc_Sha256* sha256, byte* hash)
}
else {
wc_Sha256 tmpSha256;
XMEMSET(&tmpSha256, 0, sizeof(tmpSha256));
/* Create a copy of the hash to finalize. */
ret = wc_Sha256Copy(sha256, &tmpSha256);
if (ret == 0) {
@@ -1350,6 +1351,7 @@ int wc_Sha224GetHash(wc_Sha224* sha224, byte* hash)
}
else {
wc_Sha224 tmpSha224;
XMEMSET(&tmpSha224, 0, sizeof(tmpSha224));
/* Create a copy of the hash to finalize. */
ret = wc_Sha224Copy(sha224, &tmpSha224);
if (ret == 0) {
@@ -1140,6 +1140,7 @@ int wc_Sha512GetHash(wc_Sha512* sha512, byte* hash)
}
else {
wc_Sha512 tmpSha512;
XMEMSET(&tmpSha512, 0, sizeof(tmpSha512));
/* Create a copy of the hash to finalize. */
ret = wc_Sha512Copy(sha512, &tmpSha512);
if (ret == 0) {
@@ -1357,6 +1358,7 @@ int wc_Sha512_224GetHash(wc_Sha512* sha512, byte* hash)
}
else {
wc_Sha512 tmpSha512;
XMEMSET(&tmpSha512, 0, sizeof(tmpSha512));
/* Create a copy of the hash to finalize. */
ret = wc_Sha512Copy(sha512, &tmpSha512);
if (ret == 0) {
@@ -1456,6 +1458,7 @@ int wc_Sha512_256GetHash(wc_Sha512* sha512, byte* hash)
}
else {
wc_Sha512 tmpSha512;
XMEMSET(&tmpSha512, 0, sizeof(tmpSha512));
/* Create a copy of the hash to finalize. */
ret = wc_Sha512Copy(sha512, &tmpSha512);
if (ret == 0) {
@@ -1671,6 +1674,7 @@ int wc_Sha384GetHash(wc_Sha384* sha384, byte* hash)
}
else {
wc_Sha384 tmpSha384;
XMEMSET(&tmpSha384, 0, sizeof(tmpSha384));
/* Create a copy of the hash to finalize. */
ret = wc_Sha384Copy(sha384, &tmpSha384);
if (ret == 0) {
+4 -1
View File
@@ -1137,7 +1137,7 @@ int wc_ShaGetHash(wc_Sha* sha, byte* hash)
return BAD_FUNC_ARG;
}
WC_ALLOC_VAR_EX(tmpSha, wc_Sha, 1, NULL, DYNAMIC_TYPE_TMP_BUFFER,
WC_CALLOC_VAR_EX(tmpSha, wc_Sha, 1, NULL, DYNAMIC_TYPE_TMP_BUFFER,
return MEMORY_E);
ret = wc_ShaCopy(sha, tmpSha);
@@ -1172,6 +1172,9 @@ int wc_ShaCopy(wc_Sha* src, wc_Sha* dst)
ret = 0; /* Reset ret to 0 to avoid returning the callback error code */
#endif /* WOLF_CRYPTO_CB && WOLF_CRYPTO_CB_COPY */
/* Free dst resources before copy to prevent memory leaks (e.g., msg
* buffer, W cache, hardware contexts). XMEMCPY overwrites dst. */
wc_ShaFree(dst);
XMEMCPY(dst, src, sizeof(wc_Sha));
#if defined(WOLFSSL_SILABS_SE_ACCEL) && defined(WOLFSSL_SILABS_SE_ACCEL_3)
+8 -2
View File
@@ -2546,7 +2546,7 @@ int wc_Sha224_Grow(wc_Sha224* sha224, const byte* in, int inSz)
return BAD_FUNC_ARG;
}
WC_ALLOC_VAR_EX(tmpSha224, wc_Sha224, 1, NULL,
WC_CALLOC_VAR_EX(tmpSha224, wc_Sha224, 1, NULL,
DYNAMIC_TYPE_TMP_BUFFER, return MEMORY_E);
ret = wc_Sha224Copy(sha224, tmpSha224);
@@ -2582,6 +2582,9 @@ int wc_Sha224_Grow(wc_Sha224* sha224, const byte* in, int inSz)
ret = 0; /* Reset ret to 0 to avoid returning the callback error code */
#endif /* WOLF_CRYPTO_CB && WOLF_CRYPTO_CB_COPY */
/* Free dst resources before copy to prevent memory leaks (e.g., msg
* buffer, W cache, hardware contexts). XMEMCPY overwrites dst. */
wc_Sha224Free(dst);
XMEMCPY(dst, src, sizeof(wc_Sha224));
#ifdef WOLFSSL_SMALL_STACK_CACHE
@@ -2691,7 +2694,7 @@ int wc_Sha256GetHash(wc_Sha256* sha256, byte* hash)
return BAD_FUNC_ARG;
}
WC_ALLOC_VAR_EX(tmpSha256, wc_Sha256, 1, NULL, DYNAMIC_TYPE_TMP_BUFFER,
WC_CALLOC_VAR_EX(tmpSha256, wc_Sha256, 1, NULL, DYNAMIC_TYPE_TMP_BUFFER,
return MEMORY_E);
ret = wc_Sha256Copy(sha256, tmpSha256);
@@ -2728,6 +2731,9 @@ int wc_Sha256Copy(wc_Sha256* src, wc_Sha256* dst)
ret = 0; /* Reset ret to 0 to avoid returning the callback error code */
#endif /* WOLF_CRYPTO_CB && WOLF_CRYPTO_CB_COPY */
/* Free dst resources before copy to prevent memory leaks (e.g., msg
* buffer, W cache, hardware contexts). XMEMCPY overwrites dst. */
wc_Sha256Free(dst);
XMEMCPY(dst, src, sizeof(wc_Sha256));
#ifdef WOLFSSL_MAXQ10XX_CRYPTO
+4
View File
@@ -1306,6 +1306,9 @@ static int wc_Sha3Copy(wc_Sha3* src, wc_Sha3* dst)
ret = 0; /* Reset ret to 0 to avoid returning the callback error code */
#endif /* WOLF_CRYPTO_CB && WOLF_CRYPTO_CB_COPY */
/* Free dst resources before copy to prevent memory leaks (e.g.,
* hardware contexts). XMEMCPY overwrites dst. */
wc_Sha3Free(dst);
XMEMCPY(dst, src, sizeof(wc_Sha3));
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_SHA3)
@@ -1342,6 +1345,7 @@ static int wc_Sha3GetHash(wc_Sha3* sha3, byte* hash, byte p, byte len)
if (sha3 == NULL || hash == NULL)
return BAD_FUNC_ARG;
XMEMSET(&tmpSha3, 0, sizeof(tmpSha3));
ret = wc_Sha3Copy(sha3, &tmpSha3);
if (ret == 0) {
ret = wc_Sha3Final(&tmpSha3, hash, p, len);
+8 -2
View File
@@ -2206,7 +2206,7 @@ static int Sha512_Family_GetHash(wc_Sha512* sha512, byte* hash,
return BAD_FUNC_ARG;
}
WC_ALLOC_VAR_EX(tmpSha512, wc_Sha512, 1, NULL, DYNAMIC_TYPE_TMP_BUFFER,
WC_CALLOC_VAR_EX(tmpSha512, wc_Sha512, 1, NULL, DYNAMIC_TYPE_TMP_BUFFER,
return MEMORY_E);
/* copy this sha512 into tmpSha */
@@ -2249,6 +2249,9 @@ int wc_Sha512Copy(wc_Sha512* src, wc_Sha512* dst)
ret = 0; /* Reset ret to 0 to avoid returning the callback error code */
#endif /* WOLF_CRYPTO_CB && WOLF_CRYPTO_CB_COPY */
/* Free dst resources before copy to prevent memory leaks (e.g., msg
* buffer, W cache, hardware contexts). XMEMCPY overwrites dst. */
wc_Sha512Free(dst);
XMEMCPY(dst, src, sizeof(wc_Sha512));
#ifdef WOLFSSL_SMALL_STACK_CACHE
/* This allocation combines the customary W buffer used by
@@ -2649,7 +2652,7 @@ int wc_Sha384GetHash(wc_Sha384* sha384, byte* hash)
return BAD_FUNC_ARG;
}
WC_ALLOC_VAR_EX(tmpSha384, wc_Sha384, 1, NULL, DYNAMIC_TYPE_TMP_BUFFER,
WC_CALLOC_VAR_EX(tmpSha384, wc_Sha384, 1, NULL, DYNAMIC_TYPE_TMP_BUFFER,
return MEMORY_E);
/* copy this sha384 into tmpSha */
@@ -2687,6 +2690,9 @@ int wc_Sha384Copy(wc_Sha384* src, wc_Sha384* dst)
ret = 0; /* Reset ret to 0 to avoid returning the callback error code */
#endif /* WOLF_CRYPTO_CB && WOLF_CRYPTO_CB_COPY */
/* Free dst resources before copy to prevent memory leaks (e.g., msg
* buffer, W cache, hardware contexts). XMEMCPY overwrites dst. */
wc_Sha384Free(dst);
XMEMCPY(dst, src, sizeof(wc_Sha384));
#ifdef WOLFSSL_SMALL_STACK_CACHE
+349
View File
@@ -4329,6 +4329,30 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t md5_test(void)
} /* END LARGE HASH TEST */
#endif /* NO_LARGE_HASH_TEST */
/* Copy cleanup test: verify Copy into a previously-used dst does not leak
* resources (e.g., hardware contexts). Detectable by valgrind/ASAN. */
wc_Md5Free(&md5);
ret = wc_InitMd5_ex(&md5, HEAP_HINT, devId);
if (ret != 0)
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), exit);
ret = wc_InitMd5_ex(&md5Copy, HEAP_HINT, devId);
if (ret != 0)
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), exit);
ret = wc_Md5Update(&md5Copy, (byte*)b.input, (word32)b.inLen);
if (ret != 0)
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), exit);
ret = wc_Md5Update(&md5, (byte*)a.input, (word32)a.inLen);
if (ret != 0)
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), exit);
ret = wc_Md5Copy(&md5, &md5Copy);
if (ret != 0)
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), exit);
ret = wc_Md5Final(&md5Copy, hash);
if (ret != 0)
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), exit);
if (XMEMCMP(hash, a.output, WC_MD5_DIGEST_SIZE) != 0)
ERROR_OUT(WC_TEST_RET_ENC_NC, exit);
exit:
wc_Md5Free(&md5);
@@ -4540,6 +4564,30 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t sha_test(void)
} /* END LARGE HASH TEST */
#endif /* NO_LARGE_HASH_TEST */
/* Copy cleanup test: verify Copy into a previously-used dst does not leak
* resources (e.g., msg buffer, W cache). Detectable by valgrind/ASAN. */
wc_ShaFree(&sha);
ret = wc_InitSha_ex(&sha, HEAP_HINT, devId);
if (ret != 0)
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), exit);
ret = wc_InitSha_ex(&shaCopy, HEAP_HINT, devId);
if (ret != 0)
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), exit);
ret = wc_ShaUpdate(&shaCopy, (byte*)b.input, (word32)b.inLen);
if (ret != 0)
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), exit);
ret = wc_ShaUpdate(&sha, (byte*)a.input, (word32)a.inLen);
if (ret != 0)
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), exit);
ret = wc_ShaCopy(&sha, &shaCopy);
if (ret != 0)
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), exit);
ret = wc_ShaFinal(&shaCopy, hash);
if (ret != 0)
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), exit);
if (XMEMCMP(hash, a.output, WC_SHA_DIGEST_SIZE) != 0)
ERROR_OUT(WC_TEST_RET_ENC_NC, exit);
exit:
wc_ShaFree(&sha);
@@ -4979,6 +5027,30 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t sha224_test(void)
ERROR_OUT(WC_TEST_RET_ENC_I(i), exit);
}
/* Copy cleanup test: verify Copy into a previously-used dst does not leak
* resources (e.g., msg buffer, W cache). Detectable by valgrind/ASAN. */
wc_Sha224Free(&sha);
ret = wc_InitSha224_ex(&sha, HEAP_HINT, devId);
if (ret != 0)
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), exit);
ret = wc_InitSha224_ex(&shaCopy, HEAP_HINT, devId);
if (ret != 0)
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), exit);
ret = wc_Sha224Update(&shaCopy, (byte*)b.input, (word32)b.inLen);
if (ret != 0)
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), exit);
ret = wc_Sha224Update(&sha, (byte*)a.input, (word32)a.inLen);
if (ret != 0)
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), exit);
ret = wc_Sha224Copy(&sha, &shaCopy);
if (ret != 0)
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), exit);
ret = wc_Sha224Final(&shaCopy, hash);
if (ret != 0)
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), exit);
if (XMEMCMP(hash, a.output, WC_SHA224_DIGEST_SIZE) != 0)
ERROR_OUT(WC_TEST_RET_ENC_NC, exit);
exit:
wc_Sha224Free(&sha);
wc_Sha224Free(&shaCopy);
@@ -5203,6 +5275,30 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t sha256_test(void)
}
#endif
/* Copy cleanup test: verify Copy into a previously-used dst does not leak
* resources (e.g., msg buffer, W cache). Detectable by valgrind/ASAN. */
wc_Sha256Free(&sha);
ret = wc_InitSha256_ex(&sha, HEAP_HINT, devId);
if (ret != 0)
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), exit);
ret = wc_InitSha256_ex(&shaCopy, HEAP_HINT, devId);
if (ret != 0)
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), exit);
ret = wc_Sha256Update(&shaCopy, (byte*)b.input, (word32)b.inLen);
if (ret != 0)
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), exit);
ret = wc_Sha256Update(&sha, (byte*)a.input, (word32)a.inLen);
if (ret != 0)
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), exit);
ret = wc_Sha256Copy(&sha, &shaCopy);
if (ret != 0)
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), exit);
ret = wc_Sha256Final(&shaCopy, hash);
if (ret != 0)
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), exit);
if (XMEMCMP(hash, a.output, WC_SHA256_DIGEST_SIZE) != 0)
ERROR_OUT(WC_TEST_RET_ENC_NC, exit);
exit:
#if !defined(NO_LARGE_HASH_TEST) && defined(WOLFSSL_SMALL_STACK)
@@ -5412,12 +5508,38 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t sha512_test(void)
if (ret != 0)
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), exit);
ret = wc_Sha512Final(&sha, hash);
if (ret != 0)
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), exit);
}
#endif
} /* END LARGE HASH TEST */
#undef LARGE_HASH_TEST_INPUT_SZ
#endif /* NO_LARGE_HASH_TEST */
/* Copy cleanup test: verify Copy into a previously-used dst does not leak
* resources (e.g., msg buffer, W cache). Detectable by valgrind/ASAN. */
wc_Sha512Free(&sha);
ret = wc_InitSha512_ex(&sha, HEAP_HINT, devId);
if (ret != 0)
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), exit);
ret = wc_InitSha512_ex(&shaCopy, HEAP_HINT, devId);
if (ret != 0)
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), exit);
ret = wc_Sha512Update(&shaCopy, (byte*)b.input, (word32)b.inLen);
if (ret != 0)
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), exit);
ret = wc_Sha512Update(&sha, (byte*)a.input, (word32)a.inLen);
if (ret != 0)
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), exit);
ret = wc_Sha512Copy(&sha, &shaCopy);
if (ret != 0)
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), exit);
ret = wc_Sha512Final(&shaCopy, hash);
if (ret != 0)
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), exit);
if (XMEMCMP(hash, a.output, WC_SHA512_DIGEST_SIZE) != 0)
ERROR_OUT(WC_TEST_RET_ENC_NC, exit);
exit:
#if !defined(NO_LARGE_HASH_TEST) && defined(WOLFSSL_SMALL_STACK)
@@ -5839,6 +5961,30 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t sha384_test(void)
} /* END LARGE HASH TEST */
#endif /* NO_LARGE_HASH_TEST */
/* Copy cleanup test: verify Copy into a previously-used dst does not leak
* resources (e.g., msg buffer, W cache). Detectable by valgrind/ASAN. */
wc_Sha384Free(&sha);
ret = wc_InitSha384_ex(&sha, HEAP_HINT, devId);
if (ret != 0)
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), exit);
ret = wc_InitSha384_ex(&shaCopy, HEAP_HINT, devId);
if (ret != 0)
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), exit);
ret = wc_Sha384Update(&shaCopy, (byte*)b.input, (word32)b.inLen);
if (ret != 0)
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), exit);
ret = wc_Sha384Update(&sha, (byte*)a.input, (word32)a.inLen);
if (ret != 0)
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), exit);
ret = wc_Sha384Copy(&sha, &shaCopy);
if (ret != 0)
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), exit);
ret = wc_Sha384Final(&shaCopy, hash);
if (ret != 0)
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), exit);
if (XMEMCMP(hash, a.output, WC_SHA384_DIGEST_SIZE) != 0)
ERROR_OUT(WC_TEST_RET_ENC_NC, exit);
exit:
wc_Sha384Free(&sha);
@@ -5853,6 +5999,9 @@ exit:
static wc_test_ret_t sha3_224_test(void)
{
wc_Sha3 sha;
/* Heap-allocated when WOLFSSL_SMALL_STACK to avoid exceeding stack frame
* limit with two wc_Sha3 structs on the stack. */
WC_DECLARE_VAR(shaCopy, wc_Sha3, 1, HEAP_HINT);
byte hash[WC_SHA3_224_DIGEST_SIZE];
byte hashcopy[WC_SHA3_224_DIGEST_SIZE];
@@ -5861,6 +6010,10 @@ static wc_test_ret_t sha3_224_test(void)
wc_test_ret_t ret = 0;
int times = sizeof(test_sha) / sizeof(struct testVector), i;
WC_ALLOC_VAR(shaCopy, wc_Sha3, 1, HEAP_HINT);
if (!WC_VAR_OK(shaCopy))
return WC_TEST_RET_ENC_EC(MEMORY_E);
a.input = "";
a.output = "\x6b\x4e\x03\x42\x36\x67\xdb\xb7\x3b\x6e\x15\x45\x4f\x0e\xb1"
"\xab\xd4\x59\x7f\x9a\x1b\x07\x8e\x3f\x5b\x5a\x6b\xc7";
@@ -5930,8 +6083,34 @@ static wc_test_ret_t sha3_224_test(void)
} /* END LARGE HASH TEST */
#endif /* NO_LARGE_HASH_TEST */
/* Copy cleanup test: verify Copy into a previously-used dst does not leak
* resources (e.g., hardware contexts). Detectable by valgrind/ASAN. */
wc_Sha3_224_Free(&sha);
ret = wc_InitSha3_224(&sha, HEAP_HINT, devId);
if (ret != 0)
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), exit);
ret = wc_InitSha3_224(shaCopy, HEAP_HINT, devId);
if (ret != 0)
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), exit);
ret = wc_Sha3_224_Update(shaCopy, (byte*)b.input, (word32)b.inLen);
if (ret != 0)
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), exit);
ret = wc_Sha3_224_Update(&sha, (byte*)a.input, (word32)a.inLen);
if (ret != 0)
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), exit);
ret = wc_Sha3_224_Copy(&sha, shaCopy);
if (ret != 0)
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), exit);
ret = wc_Sha3_224_Final(shaCopy, hash);
if (ret != 0)
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), exit);
if (XMEMCMP(hash, a.output, WC_SHA3_224_DIGEST_SIZE) != 0)
ERROR_OUT(WC_TEST_RET_ENC_NC, exit);
exit:
wc_Sha3_224_Free(&sha);
wc_Sha3_224_Free(shaCopy);
WC_FREE_VAR(shaCopy, HEAP_HINT);
return ret;
}
@@ -5941,6 +6120,9 @@ exit:
static wc_test_ret_t sha3_256_test(void)
{
wc_Sha3 sha;
/* Heap-allocated when WOLFSSL_SMALL_STACK to avoid exceeding stack frame
* limit with two wc_Sha3 structs on the stack. */
WC_DECLARE_VAR(shaCopy, wc_Sha3, 1, HEAP_HINT);
byte hash[WC_SHA3_256_DIGEST_SIZE];
byte hashcopy[WC_SHA3_256_DIGEST_SIZE];
@@ -5961,6 +6143,10 @@ static wc_test_ret_t sha3_256_test(void)
"\xe5\x00\xb6\x53\xca\x82\x27\x3b\x7b\xfa\xd8\x04\x5d\x85\xa4\x70";
#endif
WC_ALLOC_VAR(shaCopy, wc_Sha3, 1, HEAP_HINT);
if (!WC_VAR_OK(shaCopy))
return WC_TEST_RET_ENC_EC(MEMORY_E);
/*
** https://csrc.nist.gov/CSRC/media/Projects/Cryptographic-Standards-and-Guidelines/documents/examples/SHA3-256_Msg0.pdf
*/
@@ -6051,8 +6237,34 @@ static wc_test_ret_t sha3_256_test(void)
}
#endif /* WOLFSSL_HASH_FLAGS && !WOLFSSL_ASYNC_CRYPT */
/* Copy cleanup test: verify Copy into a previously-used dst does not leak
* resources (e.g., hardware contexts). Detectable by valgrind/ASAN. */
wc_Sha3_256_Free(&sha);
ret = wc_InitSha3_256(&sha, HEAP_HINT, devId);
if (ret != 0)
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), exit);
ret = wc_InitSha3_256(shaCopy, HEAP_HINT, devId);
if (ret != 0)
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), exit);
ret = wc_Sha3_256_Update(shaCopy, (byte*)b.input, (word32)b.inLen);
if (ret != 0)
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), exit);
ret = wc_Sha3_256_Update(&sha, (byte*)a.input, (word32)a.inLen);
if (ret != 0)
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), exit);
ret = wc_Sha3_256_Copy(&sha, shaCopy);
if (ret != 0)
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), exit);
ret = wc_Sha3_256_Final(shaCopy, hash);
if (ret != 0)
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), exit);
if (XMEMCMP(hash, a.output, WC_SHA3_256_DIGEST_SIZE) != 0)
ERROR_OUT(WC_TEST_RET_ENC_NC, exit);
exit:
wc_Sha3_256_Free(&sha);
wc_Sha3_256_Free(shaCopy);
WC_FREE_VAR(shaCopy, HEAP_HINT);
return ret;
}
@@ -6062,6 +6274,9 @@ exit:
static wc_test_ret_t sha3_384_test(void)
{
wc_Sha3 sha;
/* Heap-allocated when WOLFSSL_SMALL_STACK to avoid exceeding stack frame
* limit with two wc_Sha3 structs on the stack. */
WC_DECLARE_VAR(shaCopy, wc_Sha3, 1, HEAP_HINT);
byte hash[WC_SHA3_384_DIGEST_SIZE];
byte buf[64];
#ifndef NO_INTM_HASH_TEST
@@ -6073,6 +6288,10 @@ static wc_test_ret_t sha3_384_test(void)
wc_test_ret_t ret;
int times = sizeof(test_sha) / sizeof(struct testVector), i;
WC_ALLOC_VAR(shaCopy, wc_Sha3, 1, HEAP_HINT);
if (!WC_VAR_OK(shaCopy))
return WC_TEST_RET_ENC_EC(MEMORY_E);
/*
** https://csrc.nist.gov/CSRC/media/Projects/Cryptographic-Standards-and-Guidelines/documents/examples/SHA3-384_Msg0.pdf
*/
@@ -6172,8 +6391,34 @@ static wc_test_ret_t sha3_384_test(void)
} /* END LARGE HASH TEST */
#endif /* NO_LARGE_HASH_TEST */
/* Copy cleanup test: verify Copy into a previously-used dst does not leak
* resources (e.g., hardware contexts). Detectable by valgrind/ASAN. */
wc_Sha3_384_Free(&sha);
ret = wc_InitSha3_384(&sha, HEAP_HINT, devId);
if (ret != 0)
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), exit);
ret = wc_InitSha3_384(shaCopy, HEAP_HINT, devId);
if (ret != 0)
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), exit);
ret = wc_Sha3_384_Update(shaCopy, (byte*)b.input, (word32)b.inLen);
if (ret != 0)
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), exit);
ret = wc_Sha3_384_Update(&sha, (byte*)a.input, (word32)a.inLen);
if (ret != 0)
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), exit);
ret = wc_Sha3_384_Copy(&sha, shaCopy);
if (ret != 0)
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), exit);
ret = wc_Sha3_384_Final(shaCopy, hash);
if (ret != 0)
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), exit);
if (XMEMCMP(hash, a.output, WC_SHA3_384_DIGEST_SIZE) != 0)
ERROR_OUT(WC_TEST_RET_ENC_NC, exit);
exit:
wc_Sha3_384_Free(&sha);
wc_Sha3_384_Free(shaCopy);
WC_FREE_VAR(shaCopy, HEAP_HINT);
return ret;
}
@@ -6183,6 +6428,9 @@ exit:
static wc_test_ret_t sha3_512_test(void)
{
wc_Sha3 sha;
/* Heap-allocated when WOLFSSL_SMALL_STACK to avoid exceeding stack frame
* limit with two wc_Sha3 structs on the stack. */
WC_DECLARE_VAR(shaCopy, wc_Sha3, 1, HEAP_HINT);
byte hash[WC_SHA3_512_DIGEST_SIZE];
byte hashcopy[WC_SHA3_512_DIGEST_SIZE];
@@ -6191,6 +6439,10 @@ static wc_test_ret_t sha3_512_test(void)
wc_test_ret_t ret;
int times = sizeof(test_sha) / sizeof(struct testVector), i;
WC_ALLOC_VAR(shaCopy, wc_Sha3, 1, HEAP_HINT);
if (!WC_VAR_OK(shaCopy))
return WC_TEST_RET_ENC_EC(MEMORY_E);
/*
** https://csrc.nist.gov/CSRC/media/Projects/Cryptographic-Standards-and-Guidelines/documents/examples/SHA3-512_Msg0.pdf
*/
@@ -6274,8 +6526,34 @@ static wc_test_ret_t sha3_512_test(void)
} /* END LARGE HASH TEST */
#endif /* NO_LARGE_HASH_TEST */
/* Copy cleanup test: verify Copy into a previously-used dst does not leak
* resources (e.g., hardware contexts). Detectable by valgrind/ASAN. */
wc_Sha3_512_Free(&sha);
ret = wc_InitSha3_512(&sha, HEAP_HINT, devId);
if (ret != 0)
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), exit);
ret = wc_InitSha3_512(shaCopy, HEAP_HINT, devId);
if (ret != 0)
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), exit);
ret = wc_Sha3_512_Update(shaCopy, (byte*)b.input, (word32)b.inLen);
if (ret != 0)
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), exit);
ret = wc_Sha3_512_Update(&sha, (byte*)a.input, (word32)a.inLen);
if (ret != 0)
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), exit);
ret = wc_Sha3_512_Copy(&sha, shaCopy);
if (ret != 0)
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), exit);
ret = wc_Sha3_512_Final(shaCopy, hash);
if (ret != 0)
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), exit);
if (XMEMCMP(hash, a.output, WC_SHA3_512_DIGEST_SIZE) != 0)
ERROR_OUT(WC_TEST_RET_ENC_NC, exit);
exit:
wc_Sha3_512_Free(&sha);
wc_Sha3_512_Free(shaCopy);
WC_FREE_VAR(shaCopy, HEAP_HINT);
return ret;
}
@@ -6498,6 +6776,9 @@ exit:
WOLFSSL_TEST_SUBROUTINE wc_test_ret_t shake128_test(void)
{
wc_Shake sha;
/* Heap-allocated when WOLFSSL_SMALL_STACK to avoid exceeding stack frame
* limit with two wc_Shake structs on the stack. */
WC_DECLARE_VAR(shaCopy, wc_Shake, 1, HEAP_HINT);
byte hash[250];
testVector a, b, c, d, e;
@@ -6522,6 +6803,9 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t shake128_test(void)
"\xfa\x1b";
WOLFSSL_ENTER("shake128_test");
WC_ALLOC_VAR(shaCopy, wc_Shake, 1, HEAP_HINT);
if (!WC_VAR_OK(shaCopy))
return WC_TEST_RET_ENC_EC(MEMORY_E);
/*
** https://csrc.nist.gov/CSRC/media/Projects/Cryptographic-Standards-and-Guidelines/documents/examples/SHAKE128_Msg0.pdf
@@ -6653,9 +6937,37 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t shake128_test(void)
#endif /* NO_LARGE_HASH_TEST */
ret = shake128_absorb_test(&sha, large_input, SHAKE128_LARGE_INPUT_BUFSIZ);
if (ret != 0)
ERROR_OUT(ret, exit);
/* Copy cleanup test: verify Copy into a previously-used dst does not leak
* resources (e.g., hardware contexts). Detectable by valgrind/ASAN. */
wc_Shake128_Free(&sha);
ret = wc_InitShake128(&sha, HEAP_HINT, devId);
if (ret != 0)
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), exit);
ret = wc_InitShake128(shaCopy, HEAP_HINT, devId);
if (ret != 0)
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), exit);
ret = wc_Shake128_Update(shaCopy, (byte*)b.input, (word32)b.inLen);
if (ret != 0)
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), exit);
ret = wc_Shake128_Update(&sha, (byte*)a.input, (word32)a.inLen);
if (ret != 0)
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), exit);
ret = wc_Shake128_Copy(&sha, shaCopy);
if (ret != 0)
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), exit);
ret = wc_Shake128_Final(shaCopy, hash, (word32)a.outLen);
if (ret != 0)
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), exit);
if (XMEMCMP(hash, a.output, a.outLen) != 0)
ERROR_OUT(WC_TEST_RET_ENC_NC, exit);
exit:
wc_Shake128_Free(&sha);
wc_Shake128_Free(shaCopy);
WC_FREE_VAR(shaCopy, HEAP_HINT);
#if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_NO_MALLOC)
XFREE(large_input, NULL, DYNAMIC_TYPE_TMP_BUFFER);
@@ -6838,6 +7150,9 @@ exit:
WOLFSSL_TEST_SUBROUTINE wc_test_ret_t shake256_test(void)
{
wc_Shake sha;
/* Heap-allocated when WOLFSSL_SMALL_STACK to avoid exceeding stack frame
* limit with two wc_Shake structs on the stack. */
WC_DECLARE_VAR(shaCopy, wc_Shake, 1, HEAP_HINT);
byte hash[250];
testVector a, b, c, d, e;
@@ -6862,6 +7177,11 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t shake256_test(void)
"\xea\x26";
WOLFSSL_ENTER("shake256_test");
WC_ALLOC_VAR(shaCopy, wc_Shake, 1, HEAP_HINT);
if (!WC_VAR_OK(shaCopy))
return WC_TEST_RET_ENC_EC(MEMORY_E);
/*
** https://csrc.nist.gov/CSRC/media/Projects/Cryptographic-Standards-and-Guidelines/documents/examples/SHAKE256_Msg0.pdf
*/
@@ -6992,8 +7312,37 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t shake256_test(void)
#endif /* NO_LARGE_HASH_TEST */
ret = shake256_absorb_test(&sha, large_input, SHAKE256_LARGE_INPUT_BUFSIZ);
if (ret != 0)
ERROR_OUT(ret, exit);
/* Copy cleanup test: verify Copy into a previously-used dst does not leak
* resources (e.g., hardware contexts). Detectable by valgrind/ASAN. */
wc_Shake256_Free(&sha);
ret = wc_InitShake256(&sha, HEAP_HINT, devId);
if (ret != 0)
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), exit);
ret = wc_InitShake256(shaCopy, HEAP_HINT, devId);
if (ret != 0)
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), exit);
ret = wc_Shake256_Update(shaCopy, (byte*)b.input, (word32)b.inLen);
if (ret != 0)
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), exit);
ret = wc_Shake256_Update(&sha, (byte*)a.input, (word32)a.inLen);
if (ret != 0)
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), exit);
ret = wc_Shake256_Copy(&sha, shaCopy);
if (ret != 0)
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), exit);
ret = wc_Shake256_Final(shaCopy, hash, (word32)a.outLen);
if (ret != 0)
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), exit);
if (XMEMCMP(hash, a.output, a.outLen) != 0)
ERROR_OUT(WC_TEST_RET_ENC_NC, exit);
exit:
wc_Shake256_Free(&sha);
wc_Shake256_Free(shaCopy);
WC_FREE_VAR(shaCopy, HEAP_HINT);
#if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_NO_MALLOC)
XFREE(large_input, NULL, DYNAMIC_TYPE_TMP_BUFFER);