From b1edb08119c78acd4deb58007c7be83418a7a6e2 Mon Sep 17 00:00:00 2001 From: Daniel Pouzzner Date: Fri, 1 Mar 2024 14:55:37 -0600 Subject: [PATCH] linuxkm/linuxkm_wc_port.h: * fix WC_LINUXKM_ROUND_UP_P_OF_2() to not round up values that are already powers of 2, nor values larger than 8192. linuxkm/lkcapi_glue.c: * fix gating on km_AesSetKeyCommon(). * small stack refactors of Aes objects in self-test routines. * change kmalloc/free to malloc/free in self-test routines. * fix error-path "return"s to "goto exit"s in self-test routines. * fix memory leak around large_input in aes_xts_128_test(). wolfcrypt/benchmark/benchmark.c: * smallstack refactors in bench_chacha() and bench_chacha20_poly1305_aead(). * add error handling in bench_chacha(). wolfcrypt/src/chacha20_poly1305.c: smallstack refactor for wc_ChaCha20Poly1305_Encrypt() and wc_ChaCha20Poly1305_Decrypt(). --- linuxkm/linuxkm_wc_port.h | 12 +- linuxkm/lkcapi_glue.c | 224 +++++++++++++++++------------- wolfcrypt/benchmark/benchmark.c | 36 +++-- wolfcrypt/src/chacha20_poly1305.c | 52 +++++-- 4 files changed, 207 insertions(+), 117 deletions(-) diff --git a/linuxkm/linuxkm_wc_port.h b/linuxkm/linuxkm_wc_port.h index b94957fcf..b847cbabb 100644 --- a/linuxkm/linuxkm_wc_port.h +++ b/linuxkm/linuxkm_wc_port.h @@ -809,11 +809,13 @@ /* fun fact: since linux commit 59bb47985c, kmalloc with power-of-2 size is * aligned to the size. */ - #define WC_LINUXKM_ROUND_UP_P_OF_2(x) ( \ - { \ - size_t _alloc_sz = (x); \ - _alloc_sz = 1UL << ((sizeof(_alloc_sz) * 8UL) - __builtin_clzl(_alloc_sz)); \ - _alloc_sz; \ + #define WC_LINUXKM_ROUND_UP_P_OF_2(x) ( \ + { \ + size_t _alloc_sz = (x); \ + if (_alloc_sz < 8192) \ + _alloc_sz = 1UL << \ + ((sizeof(_alloc_sz) * 8UL) - __builtin_clzl(_alloc_sz - 1)); \ + _alloc_sz; \ }) #ifdef HAVE_KVMALLOC #define malloc(size) kvmalloc_node(WC_LINUXKM_ROUND_UP_P_OF_2(size), GFP_KERNEL, NUMA_NO_NODE) diff --git a/linuxkm/lkcapi_glue.c b/linuxkm/lkcapi_glue.c index c780a1784..7fe91afee 100644 --- a/linuxkm/lkcapi_glue.c +++ b/linuxkm/lkcapi_glue.c @@ -175,6 +175,10 @@ static void km_AesExitCommon(struct km_AesCtx * ctx) } } +#if defined(LINUXKM_LKCAPI_REGISTER_ALL) || \ + defined(LINUXKM_LKCAPI_REGISTER_AESCBC) || \ + defined(LINUXKM_LKCAPI_REGISTER_AESCFB) + static int km_AesSetKeyCommon(struct km_AesCtx * ctx, const u8 *in_key, unsigned int key_len, const char * name) { @@ -201,10 +205,6 @@ static int km_AesSetKeyCommon(struct km_AesCtx * ctx, const u8 *in_key, return 0; } -#if defined(LINUXKM_LKCAPI_REGISTER_ALL) || \ - defined(LINUXKM_LKCAPI_REGISTER_AESCBC) || \ - defined(LINUXKM_LKCAPI_REGISTER_AESCFB) - static void km_AesExit(struct crypto_skcipher *tfm) { struct km_AesCtx * ctx = crypto_skcipher_ctx(tfm); @@ -964,11 +964,12 @@ static int xtsAesAlg_loaded = 0; static int linuxkm_test_aescbc(void) { - int ret = 0; + int ret = 0; struct crypto_skcipher * tfm = NULL; struct skcipher_request * req = NULL; struct scatterlist src, dst; - Aes aes; + Aes *aes; + int aes_inited = 0; static const byte key32[] = { 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, @@ -1000,25 +1001,30 @@ static int linuxkm_test_aescbc(void) u8 * enc2 = NULL; u8 * dec2 = NULL; + aes = (Aes *)malloc(sizeof(*aes)); + if (aes == NULL) + return -ENOMEM; + XMEMSET(enc, 0, sizeof(enc)); XMEMSET(dec, 0, sizeof(enc)); - ret = wc_AesInit(&aes, NULL, INVALID_DEVID); + ret = wc_AesInit(aes, NULL, INVALID_DEVID); if (ret) { pr_err("wolfcrypt wc_AesInit failed with return code %d.\n", ret); - return ret; + goto test_cbc_end; } + aes_inited = 1; - ret = wc_AesSetKey(&aes, key32, AES_BLOCK_SIZE * 2, iv, AES_ENCRYPTION); + ret = wc_AesSetKey(aes, key32, AES_BLOCK_SIZE * 2, iv, AES_ENCRYPTION); if (ret) { pr_err("wolfcrypt wc_AesSetKey failed with return code %d\n", ret); - return ret; + goto test_cbc_end; } - ret = wc_AesCbcEncrypt(&aes, enc, p_vector, sizeof(p_vector)); + ret = wc_AesCbcEncrypt(aes, enc, p_vector, sizeof(p_vector)); if (ret) { pr_err("wolfcrypt wc_AesCbcEncrypt failed with return code %d\n", ret); - return ret; + goto test_cbc_end; } if (XMEMCMP(enc, c_vector, sizeof(c_vector)) != 0) { @@ -1027,42 +1033,44 @@ static int linuxkm_test_aescbc(void) } /* Re init for decrypt and set flag. */ - wc_AesFree(&aes); + wc_AesFree(aes); + aes_inited = 0; - ret = wc_AesInit(&aes, NULL, INVALID_DEVID); + ret = wc_AesInit(aes, NULL, INVALID_DEVID); if (ret) { pr_err("wolfcrypt wc_AesInit failed with return code %d.\n", ret); - return ret; + goto test_cbc_end; } + aes_inited = 1; - ret = wc_AesSetKey(&aes, key32, AES_BLOCK_SIZE * 2, iv, AES_DECRYPTION); + ret = wc_AesSetKey(aes, key32, AES_BLOCK_SIZE * 2, iv, AES_DECRYPTION); if (ret) { pr_err("wolfcrypt wc_AesSetKey failed with return code %d.\n", ret); - return ret; + goto test_cbc_end; } - ret = wc_AesCbcDecrypt(&aes, dec, enc, sizeof(p_vector)); + ret = wc_AesCbcDecrypt(aes, dec, enc, sizeof(p_vector)); if (ret) { pr_err("wolfcrypt wc_AesCbcDecrypt failed with return code %d\n", ret); - return ret; + goto test_cbc_end; } ret = XMEMCMP(p_vector, dec, sizeof(p_vector)); if (ret) { pr_err("error: p_vector and dec do not match: %d\n", ret); - return ret; - } - - /* now the kernel crypto part */ - enc2 = kmalloc(sizeof(p_vector), GFP_KERNEL); - if (!enc2) { - pr_err("error: kmalloc failed\n"); goto test_cbc_end; } - dec2 = kmalloc(sizeof(p_vector), GFP_KERNEL); + /* now the kernel crypto part */ + enc2 = malloc(sizeof(p_vector)); + if (!enc2) { + pr_err("error: malloc failed\n"); + goto test_cbc_end; + } + + dec2 = malloc(sizeof(p_vector)); if (!dec2) { - pr_err("error: kmalloc failed\n"); + pr_err("error: malloc failed\n"); goto test_cbc_end; } @@ -1142,10 +1150,14 @@ static int linuxkm_test_aescbc(void) test_cbc_end: - if (enc2) { kfree(enc2); enc2 = NULL; } - if (dec2) { kfree(dec2); dec2 = NULL; } - if (req) { skcipher_request_free(req); req = NULL; } - if (tfm) { crypto_free_skcipher(tfm); tfm = NULL; } + if (enc2) { free(enc2); } + if (dec2) { free(dec2); } + if (req) { skcipher_request_free(req); } + if (tfm) { crypto_free_skcipher(tfm); } + + if (aes_inited) + wc_AesFree(aes); + free(aes); return ret; } @@ -1160,11 +1172,12 @@ test_cbc_end: static int linuxkm_test_aescfb(void) { - int ret = 0; + int ret = 0; struct crypto_skcipher * tfm = NULL; struct skcipher_request * req = NULL; struct scatterlist src, dst; - Aes aes; + Aes *aes; + int aes_inited = 0; static const byte key32[] = { 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, @@ -1194,25 +1207,30 @@ static int linuxkm_test_aescfb(void) u8 * enc2 = NULL; u8 * dec2 = NULL; + aes = (Aes *)malloc(sizeof(*aes)); + if (aes == NULL) + return -ENOMEM; + XMEMSET(enc, 0, sizeof(enc)); XMEMSET(dec, 0, sizeof(enc)); - ret = wc_AesInit(&aes, NULL, INVALID_DEVID); + ret = wc_AesInit(aes, NULL, INVALID_DEVID); if (ret) { pr_err("wolfcrypt wc_AesInit failed with return code %d.\n", ret); - return ret; + goto test_cfb_end; } + aes_inited = 1; - ret = wc_AesSetKey(&aes, key32, AES_BLOCK_SIZE * 2, iv, AES_ENCRYPTION); + ret = wc_AesSetKey(aes, key32, AES_BLOCK_SIZE * 2, iv, AES_ENCRYPTION); if (ret) { pr_err("wolfcrypt wc_AesSetKey failed with return code %d\n", ret); - return ret; + goto test_cfb_end; } - ret = wc_AesCfbEncrypt(&aes, enc, p_vector, sizeof(p_vector)); + ret = wc_AesCfbEncrypt(aes, enc, p_vector, sizeof(p_vector)); if (ret) { pr_err("wolfcrypt wc_AesCfbEncrypt failed with return code %d\n", ret); - return ret; + goto test_cfb_end; } if (XMEMCMP(enc, c_vector, sizeof(c_vector)) != 0) { @@ -1221,42 +1239,44 @@ static int linuxkm_test_aescfb(void) } /* Re init for decrypt and set flag. */ - wc_AesFree(&aes); + wc_AesFree(aes); + aes_inited = 0; - ret = wc_AesInit(&aes, NULL, INVALID_DEVID); + ret = wc_AesInit(aes, NULL, INVALID_DEVID); if (ret) { pr_err("wolfcrypt wc_AesInit failed with return code %d.\n", ret); - return ret; + goto test_cfb_end; } + aes_inited = 1; - ret = wc_AesSetKey(&aes, key32, AES_BLOCK_SIZE * 2, iv, AES_ENCRYPTION); + ret = wc_AesSetKey(aes, key32, AES_BLOCK_SIZE * 2, iv, AES_ENCRYPTION); if (ret) { pr_err("wolfcrypt wc_AesSetKey failed with return code %d.\n", ret); - return ret; + goto test_cfb_end; } - ret = wc_AesCfbDecrypt(&aes, dec, enc, sizeof(p_vector)); + ret = wc_AesCfbDecrypt(aes, dec, enc, sizeof(p_vector)); if (ret) { pr_err("wolfcrypt wc_AesCfbDecrypt failed with return code %d\n", ret); - return ret; + goto test_cfb_end; } ret = XMEMCMP(p_vector, dec, sizeof(p_vector)); if (ret) { pr_err("error: p_vector and dec do not match: %d\n", ret); - return ret; - } - - /* now the kernel crypto part */ - enc2 = kmalloc(sizeof(p_vector), GFP_KERNEL); - if (!enc2) { - pr_err("error: kmalloc failed\n"); goto test_cfb_end; } - dec2 = kmalloc(sizeof(p_vector), GFP_KERNEL); + /* now the kernel crypto part */ + enc2 = malloc(sizeof(p_vector)); + if (!enc2) { + pr_err("error: malloc failed\n"); + goto test_cfb_end; + } + + dec2 = malloc(sizeof(p_vector)); if (!dec2) { - pr_err("error: kmalloc failed\n"); + pr_err("error: malloc failed\n"); goto test_cfb_end; } @@ -1336,10 +1356,14 @@ static int linuxkm_test_aescfb(void) test_cfb_end: - if (enc2) { kfree(enc2); enc2 = NULL; } - if (dec2) { kfree(dec2); dec2 = NULL; } - if (req) { skcipher_request_free(req); req = NULL; } - if (tfm) { crypto_free_skcipher(tfm); tfm = NULL; } + if (enc2) { free(enc2); } + if (dec2) { free(dec2); } + if (req) { skcipher_request_free(req); } + if (tfm) { crypto_free_skcipher(tfm); } + + if (aes_inited) + wc_AesFree(aes); + free(aes); return ret; } @@ -1359,7 +1383,8 @@ static int linuxkm_test_aesgcm(void) struct aead_request * req = NULL; struct scatterlist * src = NULL; struct scatterlist * dst = NULL; - Aes aes; + Aes *aes; + int aes_inited = 0; static const byte key32[] = { 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, @@ -1407,27 +1432,32 @@ static int linuxkm_test_aesgcm(void) XMEMSET(dec, 0, sizeof(p_vector)); XMEMSET(authTag, 0, AES_BLOCK_SIZE); - ret = wc_AesInit(&aes, NULL, INVALID_DEVID); + aes = (Aes *)malloc(sizeof(*aes)); + if (aes == NULL) + return -ENOMEM; + + ret = wc_AesInit(aes, NULL, INVALID_DEVID); if (ret) { pr_err("error: wc_AesInit failed with return code %d.\n", ret); goto test_gcm_end; } + aes_inited = 1; - ret = wc_AesGcmInit(&aes, key32, sizeof(key32)/sizeof(byte), ivstr, + ret = wc_AesGcmInit(aes, key32, sizeof(key32)/sizeof(byte), ivstr, AES_BLOCK_SIZE); if (ret) { pr_err("error: wc_AesGcmInit failed with return code %d.\n", ret); goto test_gcm_end; } - ret = wc_AesGcmEncryptUpdate(&aes, NULL, NULL, 0, assoc, sizeof(assoc)); + ret = wc_AesGcmEncryptUpdate(aes, NULL, NULL, 0, assoc, sizeof(assoc)); if (ret) { pr_err("error: wc_AesGcmEncryptUpdate failed with return code %d\n", ret); goto test_gcm_end; } - ret = wc_AesGcmEncryptUpdate(&aes, enc, p_vector, sizeof(p_vector), NULL, 0); + ret = wc_AesGcmEncryptUpdate(aes, enc, p_vector, sizeof(p_vector), NULL, 0); if (ret) { pr_err("error: wc_AesGcmEncryptUpdate failed with return code %d\n", ret); @@ -1440,7 +1470,7 @@ static int linuxkm_test_aesgcm(void) goto test_gcm_end; } - ret = wc_AesGcmEncryptFinal(&aes, authTag, AES_BLOCK_SIZE); + ret = wc_AesGcmEncryptFinal(aes, authTag, AES_BLOCK_SIZE); if (ret) { pr_err("error: wc_AesGcmEncryptFinal failed with return code %d\n", ret); @@ -1453,14 +1483,14 @@ static int linuxkm_test_aesgcm(void) goto test_gcm_end; } - ret = wc_AesGcmInit(&aes, key32, sizeof(key32)/sizeof(byte), ivstr, + ret = wc_AesGcmInit(aes, key32, sizeof(key32)/sizeof(byte), ivstr, AES_BLOCK_SIZE); if (ret) { pr_err("error: wc_AesGcmInit failed with return code %d.\n", ret); goto test_gcm_end; } - ret = wc_AesGcmDecryptUpdate(&aes, dec, enc, sizeof(p_vector), + ret = wc_AesGcmDecryptUpdate(aes, dec, enc, sizeof(p_vector), assoc, sizeof(assoc)); if (ret) { pr_err("error: wc_AesGcmDecryptUpdate failed with return code %d\n", @@ -1468,7 +1498,7 @@ static int linuxkm_test_aesgcm(void) goto test_gcm_end; } - ret = wc_AesGcmDecryptFinal(&aes, authTag, AES_BLOCK_SIZE); + ret = wc_AesGcmDecryptFinal(aes, authTag, AES_BLOCK_SIZE); if (ret) { pr_err("error: wc_AesGcmEncryptFinal failed with return code %d\n", ret); @@ -1482,31 +1512,31 @@ static int linuxkm_test_aesgcm(void) } /* now the kernel crypto part */ - assoc2 = kmalloc(sizeof(assoc), GFP_KERNEL); + assoc2 = malloc(sizeof(assoc)); if (IS_ERR(assoc2)) { - pr_err("error: kmalloc failed\n"); + pr_err("error: malloc failed\n"); goto test_gcm_end; } memset(assoc2, 0, sizeof(assoc)); memcpy(assoc2, assoc, sizeof(assoc)); - iv = kmalloc(AES_BLOCK_SIZE, GFP_KERNEL); + iv = malloc(AES_BLOCK_SIZE); if (IS_ERR(iv)) { - pr_err("error: kmalloc failed\n"); + pr_err("error: malloc failed\n"); goto test_gcm_end; } memset(iv, 0, AES_BLOCK_SIZE); memcpy(iv, ivstr, AES_BLOCK_SIZE); - enc2 = kmalloc(decryptLen, GFP_KERNEL); + enc2 = malloc(decryptLen); if (IS_ERR(enc2)) { - pr_err("error: kmalloc failed\n"); + pr_err("error: malloc failed\n"); goto test_gcm_end; } - dec2 = kmalloc(decryptLen, GFP_KERNEL); + dec2 = malloc(decryptLen); if (IS_ERR(dec2)) { - pr_err("error: kmalloc failed\n"); + pr_err("error: malloc failed\n"); goto test_gcm_end; } @@ -1552,11 +1582,11 @@ static int linuxkm_test_aesgcm(void) goto test_gcm_end; } - src = kmalloc(sizeof(struct scatterlist) * 2, GFP_KERNEL); - dst = kmalloc(sizeof(struct scatterlist) * 2, GFP_KERNEL); + src = malloc(sizeof(struct scatterlist) * 2); + dst = malloc(sizeof(struct scatterlist) * 2); if (IS_ERR(src) || IS_ERR(dst)) { - pr_err("error: kmalloc src or dst failed: %ld, %ld\n", + pr_err("error: malloc src or dst failed: %ld, %ld\n", PTR_ERR(src), PTR_ERR(dst)); goto test_gcm_end; } @@ -1614,14 +1644,18 @@ test_gcm_end: if (req) { aead_request_free(req); req = NULL; } if (tfm) { crypto_free_aead(tfm); tfm = NULL; } - if (src) { kfree(src); src = NULL; } - if (dst) { kfree(dst); dst = NULL; } + if (src) { free(src); src = NULL; } + if (dst) { free(dst); dst = NULL; } - if (dec2) { kfree(dec2); dec2 = NULL; } - if (enc2) { kfree(enc2); enc2 = NULL; } + if (dec2) { free(dec2); dec2 = NULL; } + if (enc2) { free(enc2); enc2 = NULL; } - if (assoc2) { kfree(assoc2); assoc2 = NULL; } - if (iv) { kfree(iv); iv = NULL; } + if (assoc2) { free(assoc2); assoc2 = NULL; } + if (iv) { free(iv); iv = NULL; } + + if (aes_inited) + wc_AesFree(aes); + free(aes); return ret; } @@ -1653,6 +1687,7 @@ static int aes_xts_128_test(void) struct crypto_skcipher *tfm = NULL; struct skcipher_request *req = NULL; u8 iv[AES_BLOCK_SIZE]; + byte* large_input = NULL; /* 128 key tests */ static const unsigned char k1[] = { @@ -1946,14 +1981,15 @@ static int aes_xts_128_test(void) { #define LARGE_XTS_SZ 1024 - byte* large_input = (byte *)XMALLOC(LARGE_XTS_SZ, NULL, - DYNAMIC_TYPE_TMP_BUFFER); int i; int j; - if (large_input == NULL) + large_input = (byte *)XMALLOC(LARGE_XTS_SZ, NULL, + DYNAMIC_TYPE_TMP_BUFFER); + if (large_input == NULL) { ret = MEMORY_E; - goto out; + goto out; + } for (i = 0; i < (int)LARGE_XTS_SZ; i++) large_input[i] = (byte)i; @@ -1981,19 +2017,18 @@ static int aes_xts_128_test(void) } } } - XFREE(large_input, NULL, DYNAMIC_TYPE_TMP_BUFFER); } /* now the kernel crypto part */ - enc2 = XMALLOC(sizeof(p1), NULL, DYNAMIC_TYPE_AES); + enc2 = XMALLOC(sizeof(pp), NULL, DYNAMIC_TYPE_AES); if (!enc2) { pr_err("error: malloc failed\n"); ret = -ENOMEM; goto test_xts_end; } - dec2 = XMALLOC(sizeof(p1), NULL, DYNAMIC_TYPE_AES); + dec2 = XMALLOC(sizeof(pp), NULL, DYNAMIC_TYPE_AES); if (!dec2) { pr_err("error: malloc failed\n"); ret = -ENOMEM; @@ -2164,6 +2199,9 @@ static int aes_xts_128_test(void) out: + if (large_input) + XFREE(large_input, NULL, DYNAMIC_TYPE_TMP_BUFFER); + if (aes_inited) wc_AesXtsFree(aes); diff --git a/wolfcrypt/benchmark/benchmark.c b/wolfcrypt/benchmark/benchmark.c index e8ebccfe9..6f6dcd257 100644 --- a/wolfcrypt/benchmark/benchmark.c +++ b/wolfcrypt/benchmark/benchmark.c @@ -5755,19 +5755,29 @@ exit: #ifdef HAVE_CHACHA void bench_chacha(void) { - ChaCha enc; + WC_DECLARE_VAR(enc, ChaCha, 1, HEAP_HINT); double start; - int i, count; + int ret, i, count; DECLARE_MULTI_VALUE_STATS_VARS() - XMEMSET(&enc, 0, sizeof(enc)); - wc_Chacha_SetKey(&enc, bench_key, 16); + WC_ALLOC_VAR(enc, ChaCha, 1, HEAP_HINT); + + XMEMSET(enc, 0, sizeof(ChaCha)); + wc_Chacha_SetKey(enc, bench_key, 16); bench_stats_start(&count, &start); do { for (i = 0; i < numBlocks; i++) { - wc_Chacha_SetIV(&enc, bench_iv, 0); - wc_Chacha_Process(&enc, bench_cipher, bench_plain, bench_size); + ret = wc_Chacha_SetIV(enc, bench_iv, 0); + if (ret < 0) { + printf("wc_Chacha_SetIV error: %d\n", ret); + goto exit; + } + ret = wc_Chacha_Process(enc, bench_cipher, bench_plain, bench_size); + if (ret < 0) { + printf("wc_Chacha_Process error: %d\n", ret); + goto exit; + } RECORD_MULTI_VALUE_STATS(); } count += i; @@ -5781,6 +5791,9 @@ void bench_chacha(void) #ifdef MULTI_VALUE_STATISTICS bench_multi_value_stats(max, min, sum, squareSum, runs); #endif + +exit: + WC_FREE_VAR(enc, HEAP_HINT); } #endif /* HAVE_CHACHA*/ @@ -5791,8 +5804,9 @@ void bench_chacha20_poly1305_aead(void) int ret = 0, i, count; DECLARE_MULTI_VALUE_STATS_VARS() - byte authTag[CHACHA20_POLY1305_AEAD_AUTHTAG_SIZE]; - XMEMSET(authTag, 0, sizeof(authTag)); + WC_DECLARE_VAR(authTag, byte, CHACHA20_POLY1305_AEAD_AUTHTAG_SIZE, HEAP_HINT); + WC_ALLOC_VAR(authTag, byte, CHACHA20_POLY1305_AEAD_AUTHTAG_SIZE, HEAP_HINT); + XMEMSET(authTag, 0, CHACHA20_POLY1305_AEAD_AUTHTAG_SIZE); bench_stats_start(&count, &start); do { @@ -5801,7 +5815,7 @@ void bench_chacha20_poly1305_aead(void) bench_plain, bench_size, bench_cipher, authTag); if (ret < 0) { printf("wc_ChaCha20Poly1305_Encrypt error: %d\n", ret); - break; + goto exit; } RECORD_MULTI_VALUE_STATS(); } @@ -5816,6 +5830,10 @@ void bench_chacha20_poly1305_aead(void) #ifdef MULTI_VALUE_STATISTICS bench_multi_value_stats(max, min, sum, squareSum, runs); #endif + +exit: + + WC_FREE_VAR(authTag, HEAP_HINT); } #endif /* HAVE_CHACHA && HAVE_POLY1305 */ diff --git a/wolfcrypt/src/chacha20_poly1305.c b/wolfcrypt/src/chacha20_poly1305.c index 0c37de747..df4147c87 100644 --- a/wolfcrypt/src/chacha20_poly1305.c +++ b/wolfcrypt/src/chacha20_poly1305.c @@ -57,7 +57,11 @@ int wc_ChaCha20Poly1305_Encrypt( byte outAuthTag[CHACHA20_POLY1305_AEAD_AUTHTAG_SIZE]) { int ret; - ChaChaPoly_Aead aead; +#ifdef WOLFSSL_SMALL_STACK + ChaChaPoly_Aead *aead = NULL; +#else + ChaChaPoly_Aead aead[1]; +#endif /* Validate function arguments */ if (!inKey || !inIV || @@ -68,15 +72,27 @@ int wc_ChaCha20Poly1305_Encrypt( return BAD_FUNC_ARG; } - ret = wc_ChaCha20Poly1305_Init(&aead, inKey, inIV, +#ifdef WOLFSSL_SMALL_STACK + aead = (ChaChaPoly_Aead *)XMALLOC(sizeof(*aead), NULL, + DYNAMIC_TYPE_TMP_BUFFER); + if (aead == NULL) + return MEMORY_E; +#endif + + ret = wc_ChaCha20Poly1305_Init(aead, inKey, inIV, CHACHA20_POLY1305_AEAD_ENCRYPT); if (ret == 0) - ret = wc_ChaCha20Poly1305_UpdateAad(&aead, inAAD, inAADLen); + ret = wc_ChaCha20Poly1305_UpdateAad(aead, inAAD, inAADLen); if (ret == 0) - ret = wc_ChaCha20Poly1305_UpdateData(&aead, inPlaintext, outCiphertext, + ret = wc_ChaCha20Poly1305_UpdateData(aead, inPlaintext, outCiphertext, inPlaintextLen); if (ret == 0) - ret = wc_ChaCha20Poly1305_Final(&aead, outAuthTag); + ret = wc_ChaCha20Poly1305_Final(aead, outAuthTag); + +#ifdef WOLFSSL_SMALL_STACK + XFREE(aead, NULL, DYNAMIC_TYPE_TMP_BUFFER); +#endif + return ret; } @@ -90,7 +106,11 @@ int wc_ChaCha20Poly1305_Decrypt( byte* outPlaintext) { int ret; - ChaChaPoly_Aead aead; +#ifdef WOLFSSL_SMALL_STACK + ChaChaPoly_Aead *aead = NULL; +#else + ChaChaPoly_Aead aead[1]; +#endif byte calculatedAuthTag[CHACHA20_POLY1305_AEAD_AUTHTAG_SIZE]; /* Validate function arguments */ @@ -102,19 +122,31 @@ int wc_ChaCha20Poly1305_Decrypt( return BAD_FUNC_ARG; } +#ifdef WOLFSSL_SMALL_STACK + aead = (ChaChaPoly_Aead *)XMALLOC(sizeof(*aead), NULL, + DYNAMIC_TYPE_TMP_BUFFER); + if (aead == NULL) + return MEMORY_E; +#endif + XMEMSET(calculatedAuthTag, 0, sizeof(calculatedAuthTag)); - ret = wc_ChaCha20Poly1305_Init(&aead, inKey, inIV, + ret = wc_ChaCha20Poly1305_Init(aead, inKey, inIV, CHACHA20_POLY1305_AEAD_DECRYPT); if (ret == 0) - ret = wc_ChaCha20Poly1305_UpdateAad(&aead, inAAD, inAADLen); + ret = wc_ChaCha20Poly1305_UpdateAad(aead, inAAD, inAADLen); if (ret == 0) - ret = wc_ChaCha20Poly1305_UpdateData(&aead, inCiphertext, outPlaintext, + ret = wc_ChaCha20Poly1305_UpdateData(aead, inCiphertext, outPlaintext, inCiphertextLen); if (ret == 0) - ret = wc_ChaCha20Poly1305_Final(&aead, calculatedAuthTag); + ret = wc_ChaCha20Poly1305_Final(aead, calculatedAuthTag); if (ret == 0) ret = wc_ChaCha20Poly1305_CheckTag(inAuthTag, calculatedAuthTag); + +#ifdef WOLFSSL_SMALL_STACK + XFREE(aead, NULL, DYNAMIC_TYPE_TMP_BUFFER); +#endif + return ret; }