/* test_digest.h * * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * * wolfSSL is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * wolfSSL is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA */ #define DIGEST_INIT_TEST(type, name) \ do { \ type dgst; \ \ /* Test bad arg. */ \ ExpectIntEQ(wc_Init##name(NULL, HEAP_HINT, INVALID_DEVID), \ WC_NO_ERR_TRACE(BAD_FUNC_ARG)); \ \ /* Test good arg. */ \ ExpectIntEQ(wc_Init##name(&dgst, HEAP_HINT, INVALID_DEVID), 0); \ wc_##name##_Free(&dgst); \ \ wc_##name##_Free(NULL); \ } while (0) #define DIGEST_INIT_AND_INIT_EX_TEST(type, name) \ type dgst; \ \ /* Test bad arg. */ \ ExpectIntEQ(wc_Init##name(NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG)); \ ExpectIntEQ(wc_Init##name##_ex(NULL, HEAP_HINT, INVALID_DEVID), \ WC_NO_ERR_TRACE(BAD_FUNC_ARG)); \ \ /* Test good arg. */ \ ExpectIntEQ(wc_Init##name(&dgst), 0); \ wc_##name##Free(&dgst); \ \ ExpectIntEQ(wc_Init##name##_ex(&dgst, HEAP_HINT, INVALID_DEVID), 0); \ wc_##name##Free(&dgst); \ \ wc_##name##Free(NULL) #define DIGEST_INIT_ONLY_TEST(type, name) \ do { \ type dgst; \ \ /* Test bad arg. */ \ wc_Init##name(NULL); \ \ /* Test good arg. */ \ wc_Init##name(&dgst); \ } while (0) #define DIGEST_UPDATE_TEST(type, name) \ type dgst; \ \ ExpectIntEQ(wc_Init##name(&dgst), 0); \ \ /* Pass in bad values. */ \ ExpectIntEQ(wc_##name##Update(NULL, NULL, 1), \ WC_NO_ERR_TRACE(BAD_FUNC_ARG)); \ ExpectIntEQ(wc_##name##Update(&dgst, NULL, 1), \ WC_NO_ERR_TRACE(BAD_FUNC_ARG)); \ ExpectIntEQ(wc_##name##Update(NULL, NULL, 0), \ WC_NO_ERR_TRACE(BAD_FUNC_ARG)); \ ExpectIntEQ(wc_##name##Update(NULL, (byte*)"a", 1), \ WC_NO_ERR_TRACE(BAD_FUNC_ARG)); \ \ ExpectIntEQ(wc_##name##Update(&dgst, NULL, 0), 0); \ ExpectIntEQ(wc_##name##Update(&dgst, (byte*)"a", 1), 0); \ \ wc_##name##Free(&dgst) #define DIGEST_ALT_UPDATE_TEST(type, name) \ do { \ type dgst; \ \ ExpectIntEQ(wc_Init##name(&dgst, HEAP_HINT, INVALID_DEVID), 0); \ \ /* Pass in bad values. */ \ ExpectIntEQ(wc_##name##_Update(NULL, NULL, 1), \ WC_NO_ERR_TRACE(BAD_FUNC_ARG)); \ ExpectIntEQ(wc_##name##_Update(&dgst, NULL, 1), \ WC_NO_ERR_TRACE(BAD_FUNC_ARG)); \ ExpectIntEQ(wc_##name##_Update(NULL, NULL, 0), \ WC_NO_ERR_TRACE(BAD_FUNC_ARG)); \ ExpectIntEQ(wc_##name##_Update(NULL, (byte*)"a", 1), \ WC_NO_ERR_TRACE(BAD_FUNC_ARG)); \ \ ExpectIntEQ(wc_##name##_Update(&dgst, NULL, 0), 0); \ ExpectIntEQ(wc_##name##_Update(&dgst, (byte*)"a", 1), 0); \ \ wc_##name##_Free(&dgst); \ } while (0) #define DIGEST_UPDATE_ONLY_TEST(type, name) \ type dgst; \ \ wc_Init##name(&dgst); \ \ /* Pass in bad values. */ \ wc_##name##Update(NULL, NULL, 1); \ wc_##name##Update(&dgst, NULL, 1); \ wc_##name##Update(NULL, NULL, 0); \ wc_##name##Update(NULL, (byte*)"a", 1); \ \ wc_##name##Update(&dgst, NULL, 0); \ wc_##name##Update(&dgst, (byte*)"a", 1) #define DIGEST_FINAL_TEST(type, name, upper) \ type dgst; \ byte hash[WC_##upper##_DIGEST_SIZE]; \ \ /* Initialize */ \ ExpectIntEQ(wc_Init##name(&dgst), 0); \ \ /* Test bad args. */ \ ExpectIntEQ(wc_##name##Final(NULL, NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG)); \ ExpectIntEQ(wc_##name##Final(&dgst, NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG)); \ ExpectIntEQ(wc_##name##Final(NULL, hash), WC_NO_ERR_TRACE(BAD_FUNC_ARG)); \ \ /* Test good args. */ \ ExpectIntEQ(wc_##name##Final(&dgst, hash), 0); \ \ wc_##name##Free(&dgst) #define DIGEST_ALT_FINAL_TEST(type, name, upper) \ do { \ type dgst; \ byte hash[WC_##upper##_DIGEST_SIZE]; \ \ /* Initialize */ \ ExpectIntEQ(wc_Init##name(&dgst, HEAP_HINT, INVALID_DEVID), 0); \ \ /* Test bad args. */ \ ExpectIntEQ(wc_##name##_Final(NULL, NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG)); \ ExpectIntEQ(wc_##name##_Final(&dgst, NULL), \ WC_NO_ERR_TRACE(BAD_FUNC_ARG)); \ ExpectIntEQ(wc_##name##_Final(NULL, hash), WC_NO_ERR_TRACE(BAD_FUNC_ARG)); \ \ /* Test good args. */ \ ExpectIntEQ(wc_##name##_Final(&dgst, hash), 0); \ \ wc_##name##_Free(&dgst); \ } while (0) #define DIGEST_COUNT_FINAL_TEST(type, name, upper) \ do { \ type dgst; \ byte hash[WC_##upper##_COUNT * 8]; \ \ /* Initialize */ \ ExpectIntEQ(wc_Init##name(&dgst, HEAP_HINT, INVALID_DEVID), 0); \ \ /* Test bad args. */ \ ExpectIntEQ(wc_##name##_Final(NULL, NULL, WC_##upper##_COUNT * 8), \ WC_NO_ERR_TRACE(BAD_FUNC_ARG)); \ ExpectIntEQ(wc_##name##_Final(&dgst, NULL, WC_##upper##_COUNT * 8), \ WC_NO_ERR_TRACE(BAD_FUNC_ARG)); \ ExpectIntEQ(wc_##name##_Final(NULL, hash, WC_##upper##_COUNT * 8), \ WC_NO_ERR_TRACE(BAD_FUNC_ARG)); \ \ /* Test good args. */ \ ExpectIntEQ(wc_##name##_Final(&dgst, hash, WC_##upper##_COUNT * 8), 0); \ \ wc_##name##_Free(&dgst); \ } while (0) #define DIGEST_FINAL_ONLY_TEST(type, name, upper) \ type dgst; \ byte hash[WC_##upper##_DIGEST_SIZE]; \ \ /* Initialize */ \ wc_Init##name(&dgst); \ \ /* Test bad args. */ \ wc_##name##Final(NULL, NULL); \ wc_##name##Final(&dgst, NULL); \ wc_##name##Final(NULL, hash); \ \ /* Test good args. */ \ wc_##name##Final(&dgst, hash); \ #define DIGEST_FINAL_RAW_TEST(type, name, upper, hashStr) \ type dgst; \ byte hash[WC_##upper##_DIGEST_SIZE]; \ const char* expHash = hashStr; \ \ /* Initialize */ \ ExpectIntEQ(wc_Init##name(&dgst), 0); \ \ /* Test bad args. */ \ ExpectIntEQ(wc_##name##FinalRaw(NULL, NULL), \ WC_NO_ERR_TRACE(BAD_FUNC_ARG)); \ ExpectIntEQ(wc_##name##FinalRaw(&dgst, NULL), \ WC_NO_ERR_TRACE(BAD_FUNC_ARG)); \ ExpectIntEQ(wc_##name##FinalRaw(NULL, hash), \ WC_NO_ERR_TRACE(BAD_FUNC_ARG)); \ \ /* Test good args. */ \ ExpectIntEQ(wc_##name##FinalRaw(&dgst, hash), 0); \ ExpectBufEQ(hash, expHash, WC_##upper##_DIGEST_SIZE); \ \ wc_##name##Free(&dgst) #define DIGEST_KATS_TEST_VARS(type, upper) \ type dgst; \ testVector dgst_kat[upper##_KAT_CNT]; \ byte hash[WC_##upper##_DIGEST_SIZE]; \ int i = 0 #define DIGEST_COUNT_KATS_TEST_VARS(type, upper, count) \ type dgst; \ testVector dgst_kat[upper##_KAT_CNT]; \ byte hash[WC_##count##_COUNT * 8]; \ int i = 0 #define DIGEST_KATS_ADD(in, len, out) \ dgst_kat[i].input = in; \ dgst_kat[i].inLen = len; \ dgst_kat[i].output = out; \ dgst_kat[i].outLen = 0; \ i++ #define DIGEST_KATS_TEST(name, upper) \ (void)i; \ \ /* Initialize */ \ ExpectIntEQ(wc_Init##name(&dgst), 0); \ \ for (i = 0; i < upper##_KAT_CNT; i++) { \ /* Do KAT. */ \ ExpectIntEQ(wc_##name##Update(&dgst, (byte*)dgst_kat[i].input, \ (word32)dgst_kat[i].inLen), 0); \ ExpectIntEQ(wc_##name##Final(&dgst, hash), 0); \ ExpectBufEQ(hash, (byte*)dgst_kat[i].output, \ WC_##upper##_DIGEST_SIZE); \ } \ \ wc_##name##Free(&dgst) #define DIGEST_COUNT_KATS_TEST(name, upper, count) \ (void)i; \ \ /* Initialize */ \ ExpectIntEQ(wc_Init##name(&dgst, HEAP_HINT, INVALID_DEVID), 0); \ \ for (i = 0; i < upper##_KAT_CNT; i++) { \ /* Do KAT. */ \ ExpectIntEQ(wc_##name##_Update(&dgst, (byte*)dgst_kat[i].input, \ (word32)dgst_kat[i].inLen), 0); \ ExpectIntEQ(wc_##name##_Final(&dgst, hash, WC_##count##_COUNT * 8), \ 0); \ ExpectBufEQ(hash, (byte*)dgst_kat[i].output, \ WC_##count##_COUNT * 8); \ } \ \ wc_##name##_Free(&dgst) #define DIGEST_KATS_ONLY_TEST(name, upper) \ do { \ (void)i; \ \ /* Initialize */ \ wc_Init##name(&dgst); \ \ for (i = 0; i < upper##_KAT_CNT; i++) { \ /* Do KAT. */ \ wc_##name##Update(&dgst, (byte*)dgst_kat[i].input, \ (word32)dgst_kat[i].inLen); \ wc_##name##Final(&dgst, hash); \ ExpectBufEQ(hash, (byte*)dgst_kat[i].output, \ WC_##upper##_DIGEST_SIZE); \ } \ } while (0) #define DIGEST_OTHER_TEST(type, name, upper, hashStr) \ type dgst; \ byte hash[WC_##upper##_DIGEST_SIZE + 1]; \ byte data[WC_##upper##_DIGEST_SIZE * 8 + 1]; \ int dataLen = WC_##upper##_DIGEST_SIZE * 8; \ const char* expHash = hashStr; \ int i; \ int j; \ \ XMEMSET(data, 0xa5, sizeof(data)); \ \ /* Initialize */ \ ExpectIntEQ(wc_Init##name(&dgst), 0); \ \ /* Unaligned input and output buffer. */ \ ExpectIntEQ(wc_##name##Update(&dgst, data + 1, dataLen), 0); \ ExpectIntEQ(wc_##name##Final(&dgst, hash + 1), 0); \ ExpectBufEQ(hash + 1, (byte*)expHash, WC_##upper##_DIGEST_SIZE); \ \ /* Test that empty updates work. */ \ ExpectIntEQ(wc_##name##Update(&dgst, NULL, 0), 0); \ ExpectIntEQ(wc_##name##Update(&dgst, (byte*)"", 0), 0); \ ExpectIntEQ(wc_##name##Update(&dgst, data, dataLen), 0); \ ExpectIntEQ(wc_##name##Final(&dgst, hash), 0); \ ExpectBufEQ(hash, (byte*)expHash, WC_##upper##_DIGEST_SIZE); \ \ /* Ensure chunking works. */ \ for (i = 1; i < dataLen; i++) { \ for (j = 0; j < dataLen; j += i) { \ int len = dataLen - j; \ if (i < len) \ len = i; \ ExpectIntEQ(wc_##name##Update(&dgst, data + j, len), 0); \ } \ ExpectIntEQ(wc_##name##Final(&dgst, hash), 0); \ ExpectBufEQ(hash, (byte*)expHash, WC_##upper##_DIGEST_SIZE); \ } \ \ wc_##name##Free(&dgst) #define DIGEST_ALT_OTHER_TEST(type, name, upper, hashStr) \ do { \ type dgst; \ byte hash[WC_##upper##_DIGEST_SIZE + 1]; \ byte data[WC_##upper##_DIGEST_SIZE * 8 + 1]; \ int dataLen = WC_##upper##_DIGEST_SIZE * 8; \ const char* expHash = hashStr; \ int i; \ int j; \ \ XMEMSET(data, 0xa5, sizeof(data)); \ \ /* Initialize */ \ ExpectIntEQ(wc_Init##name(&dgst, HEAP_HINT, INVALID_DEVID), 0); \ \ /* Unaligned input and output buffer. */ \ ExpectIntEQ(wc_##name##_Update(&dgst, data + 1, dataLen), 0); \ ExpectIntEQ(wc_##name##_Final(&dgst, hash + 1), 0); \ ExpectBufEQ(hash + 1, (byte*)expHash, WC_##upper##_DIGEST_SIZE); \ \ /* Test that empty updates work. */ \ ExpectIntEQ(wc_##name##_Update(&dgst, NULL, 0), 0); \ ExpectIntEQ(wc_##name##_Update(&dgst, (byte*)"", 0), 0); \ ExpectIntEQ(wc_##name##_Update(&dgst, data, dataLen), 0); \ ExpectIntEQ(wc_##name##_Final(&dgst, hash), 0); \ ExpectBufEQ(hash, (byte*)expHash, WC_##upper##_DIGEST_SIZE); \ \ /* Ensure chunking works. */ \ for (i = 1; i < dataLen; i++) { \ for (j = 0; j < dataLen; j += i) { \ int len = dataLen - j; \ if (i < len) \ len = i; \ ExpectIntEQ(wc_##name##_Update(&dgst, data + j, len), 0); \ } \ ExpectIntEQ(wc_##name##_Final(&dgst, hash), 0); \ ExpectBufEQ(hash, (byte*)expHash, WC_##upper##_DIGEST_SIZE); \ } \ \ wc_##name##_Free(&dgst); \ } while (0) #define DIGEST_COUNT_OTHER_TEST(type, name, upper, hashStr) \ do { \ type dgst; \ byte hash[WC_##upper##_COUNT * 8 + 1]; \ byte data[WC_##upper##_COUNT * 8 * 8 + 1]; \ int dataLen = WC_##upper##_COUNT * 8 * 8; \ const char* expHash = hashStr; \ int i; \ int j; \ \ XMEMSET(data, 0xa5, sizeof(data)); \ \ /* Initialize */ \ ExpectIntEQ(wc_Init##name(&dgst, HEAP_HINT, INVALID_DEVID), 0); \ \ /* Unaligned input and output buffer. */ \ ExpectIntEQ(wc_##name##_Update(&dgst, data + 1, dataLen), 0); \ ExpectIntEQ(wc_##name##_Final(&dgst, hash + 1, WC_##upper##_COUNT * 8), \ 0); \ ExpectBufEQ(hash + 1, (byte*)expHash, WC_##upper##_COUNT * 8); \ \ /* Test that empty updates work. */ \ ExpectIntEQ(wc_##name##_Update(&dgst, NULL, 0), 0); \ ExpectIntEQ(wc_##name##_Update(&dgst, (byte*)"", 0), 0); \ ExpectIntEQ(wc_##name##_Update(&dgst, data, dataLen), 0); \ ExpectIntEQ(wc_##name##_Final(&dgst, hash, WC_##upper##_COUNT * 8), 0); \ ExpectBufEQ(hash, (byte*)expHash, WC_##upper##_COUNT * 8); \ \ /* Ensure chunking works. */ \ for (i = 1; i < dataLen; i++) { \ for (j = 0; j < dataLen; j += i) { \ int len = dataLen - j; \ if (i < len) \ len = i; \ ExpectIntEQ(wc_##name##_Update(&dgst, data + j, len), 0); \ } \ ExpectIntEQ(wc_##name##_Final(&dgst, hash, WC_##upper##_COUNT * 8), \ 0); \ ExpectBufEQ(hash, (byte*)expHash, WC_##upper##_COUNT * 8); \ } \ \ wc_##name##_Free(&dgst); \ } while (0) #define DIGEST_OTHER_ONLY_TEST(type, name, upper, hashStr) \ do { \ type dgst; \ byte hash[WC_##upper##_DIGEST_SIZE + 1]; \ byte data[WC_##upper##_DIGEST_SIZE * 8 + 1]; \ int dataLen = WC_##upper##_DIGEST_SIZE * 8; \ const char* expHash = hashStr; \ int i; \ int j; \ \ XMEMSET(data, 0xa5, sizeof(data)); \ \ /* Initialize */ \ wc_Init##name(&dgst); \ \ /* Unaligned input and output buffer. */ \ wc_##name##Update(&dgst, data + 1, dataLen); \ wc_##name##Final(&dgst, hash + 1); \ ExpectBufEQ(hash + 1, (byte*)expHash, WC_##upper##_DIGEST_SIZE); \ \ /* Test that empty updates work. */ \ wc_##name##Update(&dgst, NULL, 0); \ wc_##name##Update(&dgst, (byte*)"", 0); \ wc_##name##Update(&dgst, data, dataLen); \ wc_##name##Final(&dgst, hash); \ ExpectBufEQ(hash, (byte*)expHash, WC_##upper##_DIGEST_SIZE); \ \ /* Ensure chunking works. */ \ for (i = 1; i < dataLen; i++) { \ for (j = 0; j < dataLen; j += i) { \ int len = dataLen - j; \ if (i < len) \ len = i; \ wc_##name##Update(&dgst, data + j, len); \ } \ wc_##name##Final(&dgst, hash); \ ExpectBufEQ(hash, (byte*)expHash, WC_##upper##_DIGEST_SIZE); \ } \ } while (0) #define DIGEST_COPY_TEST(type, name, upper, emptyHashStr, abcHashStr) \ type src; \ type dst; \ byte hashSrc[WC_##upper##_DIGEST_SIZE]; \ byte hashDst[WC_##upper##_DIGEST_SIZE]; \ const char* emptyHash = emptyHashStr; \ const char* abcHash = abcHashStr; \ byte data[WC_##upper##_BLOCK_SIZE]; \ \ XMEMSET(data, 0xa5, sizeof(data)); \ \ XMEMSET(&src, 0, sizeof(src)); \ XMEMSET(&dst, 0, sizeof(dst)); \ ExpectIntEQ(wc_Init##name(&src), 0); \ \ /* Tests bad params. */ \ ExpectIntEQ(wc_##name##Copy(NULL, NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG)); \ ExpectIntEQ(wc_##name##Copy(&src, NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG)); \ ExpectIntEQ(wc_##name##Copy(NULL, &dst), WC_NO_ERR_TRACE(BAD_FUNC_ARG)); \ \ /* Test copy works. */ \ ExpectIntEQ(wc_##name##Copy(&src, &dst), 0); \ ExpectIntEQ(wc_##name##Final(&src, hashSrc), 0); \ ExpectIntEQ(wc_##name##Final(&dst, hashDst), 0); \ ExpectBufEQ(hashSrc, emptyHash, WC_##upper##_DIGEST_SIZE); \ ExpectBufEQ(hashDst, emptyHash, WC_##upper##_DIGEST_SIZE); \ wc_##name##Free(&dst); \ \ /* Test buffered data is copied. */ \ ExpectIntEQ(wc_##name##Update(&src, (byte*)"abc", 3), 0); \ ExpectIntEQ(wc_##name##Copy(&src, &dst), 0); \ ExpectIntEQ(wc_##name##Final(&src, hashSrc), 0); \ ExpectIntEQ(wc_##name##Final(&dst, hashDst), 0); \ ExpectBufEQ(hashSrc, abcHash, WC_##upper##_DIGEST_SIZE); \ ExpectBufEQ(hashDst, abcHash, WC_##upper##_DIGEST_SIZE); \ wc_##name##Free(&dst); \ \ /* Test count of length is copied. */ \ ExpectIntEQ(wc_##name##Update(&src, data, sizeof(data)), 0); \ ExpectIntEQ(wc_##name##Copy(&src, &dst), 0); \ ExpectIntEQ(wc_##name##Final(&src, hashSrc), 0); \ ExpectIntEQ(wc_##name##Final(&dst, hashDst), 0); \ ExpectBufEQ(hashSrc, hashDst, WC_##upper##_DIGEST_SIZE); \ wc_##name##Free(&dst); \ \ wc_##name##Free(&src) #define DIGEST_ALT_COPY_TEST(type, name, upper, emptyHashStr, abcHashStr) \ do { \ type src; \ type dst; \ byte hashSrc[WC_##upper##_DIGEST_SIZE]; \ byte hashDst[WC_##upper##_DIGEST_SIZE]; \ const char* emptyHash = emptyHashStr; \ const char* abcHash = abcHashStr; \ byte data[WC_##upper##_BLOCK_SIZE]; \ \ XMEMSET(data, 0xa5, sizeof(data)); \ \ ExpectIntEQ(wc_Init##name(&src, HEAP_HINT, INVALID_DEVID), 0); \ XMEMSET(&dst, 0, sizeof(dst)); \ \ ExpectIntEQ(wc_##name##_Copy(NULL, NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG)); \ ExpectIntEQ(wc_##name##_Copy(&src, NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG)); \ ExpectIntEQ(wc_##name##_Copy(NULL, &dst), WC_NO_ERR_TRACE(BAD_FUNC_ARG)); \ \ /* Test copy works. */ \ ExpectIntEQ(wc_##name##_Copy(&src, &dst), 0); \ ExpectIntEQ(wc_##name##_Final(&src, hashSrc), 0); \ ExpectIntEQ(wc_##name##_Final(&dst, hashDst), 0); \ ExpectBufEQ(hashSrc, emptyHash, WC_##upper##_DIGEST_SIZE); \ ExpectBufEQ(hashDst, emptyHash, WC_##upper##_DIGEST_SIZE); \ wc_##name##_Free(&dst); \ \ /* Test buffered data is copied. */ \ ExpectIntEQ(wc_##name##_Update(&src, (byte*)"abc", 3), 0); \ ExpectIntEQ(wc_##name##_Copy(&src, &dst), 0); \ ExpectIntEQ(wc_##name##_Final(&src, hashSrc), 0); \ ExpectIntEQ(wc_##name##_Final(&dst, hashDst), 0); \ ExpectBufEQ(hashSrc, abcHash, WC_##upper##_DIGEST_SIZE); \ ExpectBufEQ(hashDst, abcHash, WC_##upper##_DIGEST_SIZE); \ wc_##name##_Free(&dst); \ \ /* Test count of length is copied. */ \ ExpectIntEQ(wc_##name##_Update(&src, data, sizeof(data)), 0); \ ExpectIntEQ(wc_##name##_Copy(&src, &dst), 0); \ ExpectIntEQ(wc_##name##_Final(&src, hashSrc), 0); \ ExpectIntEQ(wc_##name##_Final(&dst, hashDst), 0); \ ExpectBufEQ(hashSrc, hashDst, WC_##upper##_DIGEST_SIZE); \ wc_##name##_Free(&dst); \ \ wc_##name##_Free(&src); \ } while (0) #define DIGEST_COUNT_COPY_TEST(type, name, upper, emptyHashStr, abcHashStr) \ do { \ type src; \ type dst; \ byte hashSrc[WC_##upper##_COUNT * 8]; \ byte hashDst[WC_##upper##_COUNT * 8]; \ const char* emptyHash = emptyHashStr; \ const char* abcHash = abcHashStr; \ byte data[WC_##upper##_BLOCK_SIZE]; \ \ XMEMSET(data, 0xa5, sizeof(data)); \ \ ExpectIntEQ(wc_Init##name(&src, HEAP_HINT, INVALID_DEVID), 0); \ XMEMSET(&dst, 0, sizeof(dst)); \ \ ExpectIntEQ(wc_##name##_Copy(NULL, NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG)); \ ExpectIntEQ(wc_##name##_Copy(&src, NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG)); \ ExpectIntEQ(wc_##name##_Copy(NULL, &dst), WC_NO_ERR_TRACE(BAD_FUNC_ARG)); \ \ /* Test copy works. */ \ ExpectIntEQ(wc_##name##_Copy(&src, &dst), 0); \ ExpectIntEQ(wc_##name##_Final(&src, hashSrc, WC_##upper##_COUNT * 8), 0); \ ExpectIntEQ(wc_##name##_Final(&dst, hashDst, WC_##upper##_COUNT * 8), 0); \ ExpectBufEQ(hashSrc, emptyHash, WC_##upper##_COUNT * 8); \ ExpectBufEQ(hashDst, emptyHash, WC_##upper##_COUNT * 8); \ wc_##name##_Free(&src); \ \ /* Test buffered data is copied. */ \ ExpectIntEQ(wc_##name##_Update(&src, (byte*)"abc", 3), 0); \ ExpectIntEQ(wc_##name##_Copy(&src, &dst), 0); \ ExpectIntEQ(wc_##name##_Final(&src, hashSrc, WC_##upper##_COUNT * 8), 0); \ ExpectIntEQ(wc_##name##_Final(&dst, hashDst, WC_##upper##_COUNT * 8), 0); \ ExpectBufEQ(hashSrc, abcHash, WC_##upper##_COUNT * 8); \ ExpectBufEQ(hashDst, abcHash, WC_##upper##_COUNT * 8); \ wc_##name##_Free(&src); \ \ /* Test count of length is copied. */ \ ExpectIntEQ(wc_##name##_Update(&src, data, sizeof(data)), 0); \ ExpectIntEQ(wc_##name##_Copy(&src, &dst), 0); \ ExpectIntEQ(wc_##name##_Final(&src, hashSrc, WC_##upper##_COUNT * 8), 0); \ ExpectIntEQ(wc_##name##_Final(&dst, hashDst, WC_##upper##_COUNT * 8), 0); \ ExpectBufEQ(hashSrc, hashDst, WC_##upper##_COUNT * 8); \ wc_##name##_Free(&dst); \ \ wc_##name##_Free(&src); \ } while (0) #define DIGEST_GET_HASH_TEST(type, name, upper, emptyHashStr, abcHashStr) \ type dgst; \ byte hash[WC_##upper##_DIGEST_SIZE]; \ const char* emptyHash = emptyHashStr; \ const char* abcHash = abcHashStr; \ \ XMEMSET(&dgst, 0, sizeof(dgst)); \ ExpectIntEQ(wc_Init##name(&dgst), 0); \ \ ExpectIntEQ(wc_##name##GetHash(NULL, NULL), \ WC_NO_ERR_TRACE(BAD_FUNC_ARG)); \ ExpectIntEQ(wc_##name##GetHash(&dgst, NULL), \ WC_NO_ERR_TRACE(BAD_FUNC_ARG)); \ ExpectIntEQ(wc_##name##GetHash(NULL, hash), \ WC_NO_ERR_TRACE(BAD_FUNC_ARG)); \ \ ExpectIntEQ(wc_##name##GetHash(&dgst, hash), 0); \ ExpectBufEQ(hash, emptyHash, WC_##upper##_DIGEST_SIZE); \ /* Test that the hash state hasn't been modified. */ \ ExpectIntEQ(wc_##name##Update(&dgst, (byte*)"abc", 3), 0); \ ExpectIntEQ(wc_##name##GetHash(&dgst, hash), 0); \ ExpectBufEQ(hash, abcHash, WC_##upper##_DIGEST_SIZE); \ \ wc_##name##Free(&dgst) #ifdef LITTLE_ENDIAN_ORDER #define DIGEST_TRANSFORM_TEST(type, name, upper, abcBlockStr, abcHashStr) \ type dgst; \ const char* abc##name##Data = abcBlockStr; \ const char* abcHash = abcHashStr; \ \ ExpectIntEQ(wc_Init##name(&dgst), 0); \ \ /* Test bad args. */ \ ExpectIntEQ(wc_##name##Transform(NULL, NULL), \ WC_NO_ERR_TRACE(BAD_FUNC_ARG)); \ ExpectIntEQ(wc_##name##Transform(&dgst, NULL), \ WC_NO_ERR_TRACE(BAD_FUNC_ARG)); \ ExpectIntEQ(wc_##name##Transform(NULL, (byte*)abc##name##Data), \ WC_NO_ERR_TRACE(BAD_FUNC_ARG)); \ \ ExpectIntEQ(wc_##name##Transform(&dgst, (byte*)abc##name##Data), 0); \ ExpectBufEQ((byte*)dgst.digest, (byte*)abcHash, WC_##upper##_DIGEST_SIZE); \ \ wc_##name##Free(&dgst) #define DIGEST_TRANSFORM_FINAL_RAW_TEST(type, name, upper, abcBlockStr, \ abcHashStr) \ type dgst; \ const char* abc##name##Data = abcBlockStr; \ const char* abcHash = abcHashStr; \ byte abcData[WC_##upper##_BLOCK_SIZE]; \ byte hash[WC_##upper##_DIGEST_SIZE]; \ \ XMEMCPY(abcData, abc##name##Data, WC_##upper##_BLOCK_SIZE); \ \ ExpectIntEQ(wc_Init##name(&dgst), 0); \ \ /* Test bad args. */ \ ExpectIntEQ(wc_##name##Transform(NULL, NULL), \ WC_NO_ERR_TRACE(BAD_FUNC_ARG)); \ ExpectIntEQ(wc_##name##Transform(&dgst, NULL), \ WC_NO_ERR_TRACE(BAD_FUNC_ARG)); \ ExpectIntEQ(wc_##name##Transform(NULL, (byte*)abc##name##Data), \ WC_NO_ERR_TRACE(BAD_FUNC_ARG)); \ \ ExpectIntEQ(wc_##name##Transform(&dgst, (byte*)abcData), 0); \ ExpectIntEQ(wc_##name##FinalRaw(&dgst, hash), 0); \ ExpectBufEQ(hash, (byte*)abcHash, WC_##upper##_DIGEST_SIZE); \ \ wc_##name##Free(&dgst) #else #define DIGEST_TRANSFORM_TEST(type, name, upper, abcBlockStr, abcHashStr) \ type dgst; \ const char* abc##name##Data = abcBlockStr; \ const char* abcHash = abcHashStr; \ char abc##name##DataBE[WC_##upper##_BLOCK_SIZE]; \ char abcHashBE[WC_##upper##_DIGEST_SIZE]; \ \ ExpectIntEQ(wc_Init##name(&dgst), 0); \ \ /* Test bad args. */ \ ExpectIntEQ(wc_##name##Transform(NULL, NULL), \ WC_NO_ERR_TRACE(BAD_FUNC_ARG)); \ ExpectIntEQ(wc_##name##Transform(&dgst, NULL), \ WC_NO_ERR_TRACE(BAD_FUNC_ARG)); \ ExpectIntEQ(wc_##name##Transform(NULL, (byte*)abc##name##Data), \ WC_NO_ERR_TRACE(BAD_FUNC_ARG)); \ \ ByteReverseWords((word32*)abc##name##DataBE, (word32*)abc##name##Data, \ WC_##upper##_BLOCK_SIZE); \ ByteReverseWords((word32*)abcHashBE, (word32*)abcHash, \ WC_##upper##_DIGEST_SIZE); \ ExpectIntEQ(wc_##name##Transform(&dgst, (byte*)abc##name##DataBE), 0); \ ExpectBufEQ((byte*)dgst.digest, (byte*)abcHashBE, \ WC_##upper##_DIGEST_SIZE); \ \ wc_##name##Free(&dgst) #define DIGEST_TRANSFORM_FINAL_RAW_TEST(type, name, upper, abcBlockStr, \ abcHashStr) \ type dgst; \ const char* abc##name##Data = abcBlockStr; \ const char* abcHash = abcHashStr; \ char abc##name##DataBE[WC_##upper##_BLOCK_SIZE]; \ byte hash[WC_##upper##_DIGEST_SIZE]; \ \ ExpectIntEQ(wc_Init##name(&dgst), 0); \ \ /* Test bad args. */ \ ExpectIntEQ(wc_##name##Transform(NULL, NULL), \ WC_NO_ERR_TRACE(BAD_FUNC_ARG)); \ ExpectIntEQ(wc_##name##Transform(&dgst, NULL), \ WC_NO_ERR_TRACE(BAD_FUNC_ARG)); \ ExpectIntEQ(wc_##name##Transform(NULL, (byte*)abc##name##Data), \ WC_NO_ERR_TRACE(BAD_FUNC_ARG)); \ \ ByteReverseWords((word32*)abc##name##DataBE, (word32*)abc##name##Data, \ WC_##upper##_BLOCK_SIZE); \ ExpectIntEQ(wc_##name##Transform(&dgst, (byte*)abc##name##DataBE), 0); \ ExpectIntEQ(wc_##name##FinalRaw(&dgst, hash), 0); \ ExpectBufEQ(hash, (byte*)abcHash, WC_##upper##_DIGEST_SIZE); \ \ wc_##name##Free(&dgst) #endif #define DIGEST_TRANSFORM_FINAL_RAW_ALL_TEST(type, name, upper, abcBlockStr, \ abcHashStr) \ type dgst; \ const char* abc##name##Data = abcBlockStr; \ const char* abcHash = abcHashStr; \ byte abcData[WC_##upper##_BLOCK_SIZE]; \ byte hash[WC_##upper##_DIGEST_SIZE]; \ \ XMEMCPY(abcData, abc##name##Data, WC_##upper##_BLOCK_SIZE); \ \ ExpectIntEQ(wc_Init##name(&dgst), 0); \ \ /* Test bad args. */ \ ExpectIntEQ(wc_##name##Transform(NULL, NULL), \ WC_NO_ERR_TRACE(BAD_FUNC_ARG)); \ ExpectIntEQ(wc_##name##Transform(&dgst, NULL), \ WC_NO_ERR_TRACE(BAD_FUNC_ARG)); \ ExpectIntEQ(wc_##name##Transform(NULL, (byte*)abc##name##Data), \ WC_NO_ERR_TRACE(BAD_FUNC_ARG)); \ \ ExpectIntEQ(wc_##name##Transform(&dgst, (byte*)abcData), 0); \ ExpectIntEQ(wc_##name##FinalRaw(&dgst, hash), 0); \ ExpectBufEQ(hash, (byte*)abcHash, WC_##upper##_DIGEST_SIZE); \ \ wc_##name##Free(&dgst) #define DIGEST_FLAGS_TEST(type, name) \ type dgst; \ type dgst_copy; \ word32 flags; \ \ XMEMSET(&dgst, 0, sizeof(dgst)); \ XMEMSET(&dgst_copy, 0, sizeof(dgst_copy)); \ ExpectIntEQ(wc_Init##name(&dgst), 0); \ \ /* Do nothing. */ \ ExpectIntEQ(wc_##name##GetFlags(NULL, NULL), 0); \ ExpectIntEQ(wc_##name##GetFlags(&dgst, NULL), 0); \ ExpectIntEQ(wc_##name##GetFlags(NULL, &flags), 0); \ ExpectIntEQ(wc_##name##SetFlags(NULL, 1), 0); \ \ ExpectIntEQ(wc_##name##GetFlags(&dgst, &flags), 0); \ ExpectIntEQ(flags, 0); \ \ ExpectIntEQ(wc_##name##Copy(&dgst, &dgst_copy), 0); \ ExpectIntEQ(wc_##name##GetFlags(&dgst, &flags), 0); \ ExpectIntEQ(flags, 0); \ ExpectIntEQ(wc_##name##GetFlags(&dgst_copy, &flags), 0); \ ExpectIntEQ(flags, WC_HASH_FLAG_ISCOPY); \ \ ExpectIntEQ(wc_##name##SetFlags(&dgst, WC_HASH_FLAG_WILLCOPY), 0); \ ExpectIntEQ(wc_##name##GetFlags(&dgst, &flags), 0); \ ExpectIntEQ(flags, WC_HASH_FLAG_WILLCOPY); \ ExpectIntEQ(wc_##name##SetFlags(&dgst, 0), 0); \ \ wc_##name##Free(&dgst_copy); \ wc_##name##Free(&dgst) #define DIGEST_ALT_FLAGS_TEST(type, name, inst) \ type dgst; \ type dgst_copy; \ word32 flags; \ \ XMEMSET(&dgst_copy, 0, sizeof(dgst_copy)); \ ExpectIntEQ(wc_Init##inst(&dgst, HEAP_HINT, INVALID_DEVID), 0); \ \ /* Do nothing. */ \ ExpectIntEQ(wc_##name##_GetFlags(NULL, NULL), 0); \ ExpectIntEQ(wc_##name##_GetFlags(&dgst, NULL), 0); \ ExpectIntEQ(wc_##name##_GetFlags(NULL, &flags), 0); \ ExpectIntEQ(wc_##name##_SetFlags(NULL, 1), 0); \ \ ExpectIntEQ(wc_##name##_GetFlags(&dgst, &flags), 0); \ ExpectIntEQ(flags, 0); \ \ ExpectIntEQ(wc_##inst##_Copy(&dgst, &dgst_copy), 0); \ ExpectIntEQ(wc_##name##_GetFlags(&dgst, &flags), 0); \ ExpectIntEQ(flags, 0); \ ExpectIntEQ(wc_##name##_GetFlags(&dgst_copy, &flags), 0); \ ExpectIntEQ(flags, WC_HASH_FLAG_ISCOPY); \ \ ExpectIntEQ(wc_##name##_SetFlags(&dgst, 1), 0); \ ExpectIntEQ(wc_##name##_GetFlags(&dgst, &flags), 0); \ ExpectIntEQ(flags, 1); \ ExpectIntEQ(wc_##name##_SetFlags(&dgst, 0), 0); \ \ wc_##inst##_Free(&dgst_copy); \ wc_##inst##_Free(&dgst) #define DIGEST_HASH_TEST(name, upper) \ do { \ byte data[WC_##upper##_BLOCK_SIZE]; \ byte hash[WC_##upper##_DIGEST_SIZE]; \ \ XMEMSET(data, 0xa5, sizeof(data)); \ \ /* Invalid parameters. */ \ ExpectIntEQ(wc_##name##Hash(NULL, sizeof(data), hash), \ WC_NO_ERR_TRACE(BAD_FUNC_ARG)); \ ExpectIntEQ(wc_##name##Hash(data, sizeof(data), NULL), \ WC_NO_ERR_TRACE(BAD_FUNC_ARG)); \ ExpectIntEQ(wc_##name##Hash_ex(NULL, sizeof(data), hash, HEAP_HINT, \ INVALID_DEVID), WC_NO_ERR_TRACE(BAD_FUNC_ARG)); \ ExpectIntEQ(wc_##name##Hash_ex(data, sizeof(data), NULL, HEAP_HINT, \ INVALID_DEVID), WC_NO_ERR_TRACE(BAD_FUNC_ARG)); \ \ /* Valid parameters. */ \ ExpectIntEQ(wc_##name##Hash(data, sizeof(data), hash), 0); \ ExpectIntEQ(wc_##name##Hash_ex(data, sizeof(data), hash, HEAP_HINT, \ INVALID_DEVID), 0); \ } while (0) #define DIGEST_COUNT_HASH_TEST(name, upper) \ do { \ byte data[WC_##upper##_COUNT * 8]; \ byte hash[WC_##upper##_COUNT * 8]; \ \ XMEMSET(data, 0xa5, sizeof(data)); \ \ /* Invalid parameters. */ \ ExpectIntEQ(wc_##name##Hash(NULL, sizeof(data), hash), \ WC_NO_ERR_TRACE(BAD_FUNC_ARG)); \ ExpectIntEQ(wc_##name##Hash(data, sizeof(data), NULL), \ WC_NO_ERR_TRACE(BAD_FUNC_ARG)); \ ExpectIntEQ(wc_##name##Hash_ex(NULL, sizeof(data), hash, HEAP_HINT, \ INVALID_DEVID), WC_NO_ERR_TRACE(BAD_FUNC_ARG)); \ ExpectIntEQ(wc_##name##Hash_ex(data, sizeof(data), NULL, HEAP_HINT, \ INVALID_DEVID), WC_NO_ERR_TRACE(BAD_FUNC_ARG)); \ \ /* Valid parameters. */ \ ExpectIntEQ(wc_##name##Hash(data, sizeof(data), hash), 0); \ ExpectIntEQ(wc_##name##Hash_ex(data, sizeof(data), hash, HEAP_HINT, \ INVALID_DEVID), 0); \ } while (0) #define DIGEST_HASH_ONLY_TEST(name, upper) \ byte data[WC_##upper##_BLOCK_SIZE]; \ byte hash[WC_##upper##_DIGEST_SIZE]; \ \ XMEMSET(data, 0xa5, sizeof(data)); \ \ /* Invalid parameters. */ \ ExpectIntEQ(wc_##name##Hash(NULL, sizeof(data), hash), 0); \ ExpectIntEQ(wc_##name##Hash(data, sizeof(data), NULL), 0); \ \ /* Valid parameters. */ \ ExpectIntEQ(wc_##name##Hash(data, sizeof(data), hash), 0)