From 689a82a622c07bfa5fc3330d7caa98ebf8c6ea6a Mon Sep 17 00:00:00 2001 From: Daniel Pouzzner Date: Tue, 5 Dec 2023 15:49:32 -0600 Subject: [PATCH 1/5] fix AES-related code, in both crypto and TLS layers, for various uninitialized data and resource leak defects around wc_AesInit() and wc_AesFree(): * followup to https://github.com/wolfSSL/wolfssl/pull/7009 "20231128-misc-fixes" and https://github.com/wolfSSL/wolfssl/pull/7011 "Add missing wc_AesInit calls." * adds WC_DEBUG_CIPHER_LIFECYCLE, which embeds asserts in low-level AES implementations for proper usage of wc_AesInit() and wc_AesFree(). * fixes native CMAC, AES-EAX, and AES-XTS implementations to assure resource release. * adds missing wc_AesXtsInit() API, and adds a new wc_AesXtsSetKey_NoInit(). * fixes misspellings in EVP that unconditionally gated out AES-OFB and AES-XTS. * fixes misspellings in EVP that unconditionally gated out AES-CBC and AES-CFB code in wolfSSL_EVP_CIPHER_CTX_cleanup_cipher(). * openssl compat AES low level cipher API has no counterpart to wc_AesFree(), so these compat APIs will now be gated out in configurations where they would otherwise leak memory or file descriptors (WOLFSSL_AFALG, WOLFSSL_DEVCRYPTO, WOLF_CRYPTO_CB, etc.). A new macro, WC_AESFREE_IS_MANDATORY, is defined in wolfcrypt/aes.h to streamline this dependency. * fixes 40 missing EVP_CIPHER_CTX_cleanup()s and 11 wc_AesFree()s in src/ssl.c, src/ssl_crypto.c, tests/api.c, and wolfcrypt/test/test.c. --- src/quic.c | 1 + src/ssl.c | 2 + src/ssl_crypto.c | 38 ++- tests/api.c | 82 ++++++- wolfcrypt/src/aes.c | 324 ++++++++++++++++++++++++-- wolfcrypt/src/cmac.c | 17 +- wolfcrypt/src/evp.c | 277 +++++++++++++++------- wolfcrypt/src/memory.c | 64 +++++ wolfcrypt/src/port/af_alg/afalg_aes.c | 8 + wolfcrypt/test/test.c | 228 +++++++++++------- wolfssl/openssl/aes.h | 10 + wolfssl/openssl/evp.h | 1 + wolfssl/test.h | 20 ++ wolfssl/wolfcrypt/aes.h | 31 +++ wolfssl/wolfcrypt/memory.h | 16 ++ wolfssl/wolfcrypt/types.h | 1 + 16 files changed, 900 insertions(+), 220 deletions(-) diff --git a/src/quic.c b/src/quic.c index a3b3755aa..0a60f5767 100644 --- a/src/quic.c +++ b/src/quic.c @@ -1055,6 +1055,7 @@ size_t wolfSSL_quic_get_aead_tag_len(const WOLFSSL_EVP_CIPHER* aead_cipher) ret = 0; } + (void)wolfSSL_EVP_CIPHER_CTX_cleanup(ctx); #ifdef WOLFSSL_SMALL_STACK XFREE(ctx, NULL, DYNAMIC_TYPE_TMP_BUFFER); #endif diff --git a/src/ssl.c b/src/ssl.c index 32d81e7aa..d3aa318ed 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -29665,6 +29665,8 @@ static int wolfSSL_TicketKeyCb(WOLFSSL* ssl, end: (void)wc_HmacFree(&hmacCtx.hmac); + (void)wolfSSL_EVP_CIPHER_CTX_cleanup(evpCtx); + #ifdef WOLFSSL_SMALL_STACK XFREE(evpCtx, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER); #endif diff --git a/src/ssl_crypto.c b/src/ssl_crypto.c index f44fb0fab..7b8c0360a 100644 --- a/src/ssl_crypto.c +++ b/src/ssl_crypto.c @@ -2079,14 +2079,10 @@ WOLFSSL_CMAC_CTX* wolfSSL_CMAC_CTX_new(void) ctx = (WOLFSSL_CMAC_CTX*)XMALLOC(sizeof(WOLFSSL_CMAC_CTX), NULL, DYNAMIC_TYPE_OPENSSL); if (ctx != NULL) { - /* Allocate memory for wolfSSL CMAC object. */ - ctx->internal = (Cmac*)XMALLOC(sizeof(Cmac), NULL, DYNAMIC_TYPE_CMAC); - if (ctx->internal == NULL) { - XFREE(ctx, NULL, DYNAMIC_TYPE_OPENSSL); - ctx = NULL; - } - } - if (ctx != NULL) { + /* Memory for wolfSSL CMAC object is allocated in + * wolfSSL_CMAC_Init(). + */ + ctx->internal = NULL; /* Allocate memory for EVP cipher context object. */ ctx->cctx = wolfSSL_EVP_CIPHER_CTX_new(); if (ctx->cctx == NULL) { @@ -2110,9 +2106,11 @@ void wolfSSL_CMAC_CTX_free(WOLFSSL_CMAC_CTX *ctx) if (ctx != NULL) { /* Deallocate dynamically allocated fields. */ if (ctx->internal != NULL) { + wc_CmacFinal((Cmac*)ctx->internal, NULL, NULL); XFREE(ctx->internal, NULL, DYNAMIC_TYPE_CMAC); } if (ctx->cctx != NULL) { + wolfSSL_EVP_CIPHER_CTX_cleanup(ctx->cctx); wolfSSL_EVP_CIPHER_CTX_free(ctx->cctx); } /* Deallocate CMAC context object. */ @@ -2167,22 +2165,37 @@ int wolfSSL_CMAC_Init(WOLFSSL_CMAC_CTX* ctx, const void *key, size_t keySz, /* Only AES-CBC ciphers are supported. */ if ((ret == 1) && (cipher != EVP_AES_128_CBC) && (cipher != EVP_AES_192_CBC) && (cipher != EVP_AES_256_CBC)) { + WOLFSSL_MSG("wolfSSL_CMAC_Init: requested cipher is unsupported"); ret = 0; } /* Key length must match cipher. */ if ((ret == 1) && ((int)keySz != wolfSSL_EVP_Cipher_key_length(cipher))) { + WOLFSSL_MSG("wolfSSL_CMAC_Init: " + "supplied key size doesn't match requested cipher"); ret = 0; } + if ((ret == 1) && (ctx->internal == NULL)) { + /* Allocate memory for wolfSSL CMAC object. */ + ctx->internal = (Cmac*)XMALLOC(sizeof(Cmac), NULL, DYNAMIC_TYPE_CMAC); + if (ctx->internal == NULL) + ret = 0; + } + /* Initialize the wolfCrypt CMAC object. */ if ((ret == 1) && (wc_InitCmac((Cmac*)ctx->internal, (const byte*)key, (word32)keySz, WC_CMAC_AES, NULL) != 0)) { + WOLFSSL_MSG("wolfSSL_CMAC_Init: wc_InitCmac() failed"); + XFREE(ctx->internal, NULL, DYNAMIC_TYPE_CMAC); + ctx->internal = NULL; ret = 0; } if (ret == 1) { /* Initialize the EVP cipher context object for encryption. */ ret = wolfSSL_EVP_CipherInit(ctx->cctx, cipher, (const byte*)key, NULL, 1); + if (ret != WOLFSSL_SUCCESS) + WOLFSSL_MSG("wolfSSL_CMAC_Init: wolfSSL_EVP_CipherInit() failed"); } WOLFSSL_LEAVE("wolfSSL_CMAC_Init", ret); @@ -2237,7 +2250,7 @@ int wolfSSL_CMAC_Final(WOLFSSL_CMAC_CTX* ctx, unsigned char* out, size_t* len) WOLFSSL_ENTER("wolfSSL_CMAC_Final"); - /* Valiudate parameters. */ + /* Validate parameters. */ if (ctx == NULL) { ret = 0; } @@ -2268,6 +2281,9 @@ int wolfSSL_CMAC_Final(WOLFSSL_CMAC_CTX* ctx, unsigned char* out, size_t* len) else if (len != NULL) { *len = (size_t)len32; } + + XFREE(ctx->internal, NULL, DYNAMIC_TYPE_CMAC); + ctx->internal = NULL; } WOLFSSL_LEAVE("wolfSSL_CMAC_Final", ret); @@ -2899,7 +2915,7 @@ void wolfSSL_DES_ecb_encrypt(WOLFSSL_DES_cblock* in, WOLFSSL_DES_cblock* out, #ifdef OPENSSL_EXTRA -#ifndef NO_AES +#if !defined(NO_AES) && !defined(WOLFSSL_NO_OPENSSL_AES_LOW_LEVEL_API) /* Sets the key into the AES key object for encryption or decryption. * @@ -3408,7 +3424,7 @@ size_t wolfSSL_CRYPTO_cts128_decrypt(const unsigned char *in, return len; } #endif /* HAVE_CTS */ -#endif /* NO_AES */ +#endif /* !NO_AES && !WOLFSSL_NO_OPENSSL_AES_LOW_LEVEL_API */ #endif /* OPENSSL_EXTRA */ /******************************************************************************* diff --git a/tests/api.c b/tests/api.c index b0d141a66..f065ea4af 100644 --- a/tests/api.c +++ b/tests/api.c @@ -5680,7 +5680,7 @@ static int test_wolfSSL_EVP_CIPHER_CTX(void) return 0; } - static WC_INLINE int myTicketEncCbOpenSSL(WOLFSSL* ssl, + static int myTicketEncCbOpenSSL(WOLFSSL* ssl, byte name[WOLFSSL_TICKET_NAME_SZ], byte iv[WOLFSSL_TICKET_IV_SZ], WOLFSSL_EVP_CIPHER_CTX *ectx, @@ -15994,6 +15994,10 @@ static int test_wc_AesGcmStream(void) ExpectIntEQ(wc_AesGcmDecryptFinal(aesDec, tag, AES_BLOCK_SIZE), 0); /* Set key and IV through streaming init API. */ + wc_AesFree(aesEnc); + wc_AesFree(aesDec); + ExpectIntEQ(wc_AesInit(aesEnc, NULL, INVALID_DEVID), 0); + ExpectIntEQ(wc_AesInit(aesDec, NULL, INVALID_DEVID), 0); ExpectIntEQ(wc_AesGcmInit(aesEnc, key, sizeof(key), iv, AES_IV_SIZE), 0); ExpectIntEQ(wc_AesGcmInit(aesDec, key, sizeof(key), iv, AES_IV_SIZE), 0); /* Encrypt/decrypt one block and AAD of one block. */ @@ -16007,6 +16011,10 @@ static int test_wc_AesGcmStream(void) ExpectIntEQ(wc_AesGcmDecryptFinal(aesDec, tag, AES_BLOCK_SIZE), 0); /* Set key and IV through streaming init API. */ + wc_AesFree(aesEnc); + wc_AesFree(aesDec); + ExpectIntEQ(wc_AesInit(aesEnc, NULL, INVALID_DEVID), 0); + ExpectIntEQ(wc_AesInit(aesDec, NULL, INVALID_DEVID), 0); ExpectIntEQ(wc_AesGcmInit(aesEnc, key, sizeof(key), iv, AES_IV_SIZE), 0); ExpectIntEQ(wc_AesGcmInit(aesDec, key, sizeof(key), iv, AES_IV_SIZE), 0); /* No data to encrypt/decrypt one byte of AAD. */ @@ -16018,6 +16026,10 @@ static int test_wc_AesGcmStream(void) ExpectIntEQ(wc_AesGcmDecryptFinal(aesDec, tag, AES_BLOCK_SIZE), 0); /* Set key and IV through streaming init API. */ + wc_AesFree(aesEnc); + wc_AesFree(aesDec); + ExpectIntEQ(wc_AesInit(aesEnc, NULL, INVALID_DEVID), 0); + ExpectIntEQ(wc_AesInit(aesDec, NULL, INVALID_DEVID), 0); ExpectIntEQ(wc_AesGcmInit(aesEnc, key, sizeof(key), iv, AES_IV_SIZE), 0); ExpectIntEQ(wc_AesGcmInit(aesDec, key, sizeof(key), iv, AES_IV_SIZE), 0); /* Encrypt/decrypt one byte and no AAD. */ @@ -16030,6 +16042,10 @@ static int test_wc_AesGcmStream(void) ExpectIntEQ(wc_AesGcmDecryptFinal(aesDec, tag, AES_BLOCK_SIZE), 0); /* Set key and IV through streaming init API. */ + wc_AesFree(aesEnc); + wc_AesFree(aesDec); + ExpectIntEQ(wc_AesInit(aesEnc, NULL, INVALID_DEVID), 0); + ExpectIntEQ(wc_AesInit(aesDec, NULL, INVALID_DEVID), 0); ExpectIntEQ(wc_AesGcmInit(aesEnc, key, sizeof(key), iv, AES_IV_SIZE), 0); ExpectIntEQ(wc_AesGcmInit(aesDec, key, sizeof(key), iv, AES_IV_SIZE), 0); /* Encryption AES is one byte at a time */ @@ -16057,6 +16073,9 @@ static int test_wc_AesGcmStream(void) ExpectIntEQ(wc_AesGcmDecryptFinal(aesDec, tag, AES_BLOCK_SIZE), 0); /* Check streaming encryption can be decrypted with one shot. */ + wc_AesFree(aesDec); + ExpectIntEQ(wc_AesInit(aesDec, NULL, INVALID_DEVID), 0); + ExpectIntEQ(wc_AesGcmInit(aesDec, key, sizeof(key), iv, AES_IV_SIZE), 0); ExpectIntEQ(wc_AesGcmSetKey(aesDec, key, sizeof(key)), 0); ExpectIntEQ(wc_AesGcmDecrypt(aesDec, plain, out, sizeof(in), iv, AES_IV_SIZE, tag, AES_BLOCK_SIZE, aad, sizeof(aad)), 0); @@ -17612,7 +17631,6 @@ static int test_wc_AesCbcEncryptDecrypt(void) ExpectIntEQ(wc_AesSetKey(&aes, key32, AES_BLOCK_SIZE * 2, iv, AES_ENCRYPTION), 0); ExpectIntEQ(wc_AesCbcEncrypt(&aes, enc, vector, sizeof(vector)), 0); - wc_AesFree(&aes); /* Re init for decrypt and set flag. */ ExpectIntEQ(wc_AesSetKey(&aes, key32, AES_BLOCK_SIZE * 2, iv, @@ -18154,13 +18172,13 @@ static int test_wc_GmacUpdate(void) XMEMSET(tagOut2, 0, sizeof(tagOut2)); XMEMSET(tagOut3, 0, sizeof(tagOut3)); - ExpectIntEQ(wc_AesInit(&gmac.aes, NULL, INVALID_DEVID), 0); - #ifdef WOLFSSL_AES_128 + ExpectIntEQ(wc_AesInit(&gmac.aes, NULL, INVALID_DEVID), 0); ExpectIntEQ(wc_GmacSetKey(&gmac, key16, sizeof(key16)), 0); ExpectIntEQ(wc_GmacUpdate(&gmac, iv, sizeof(iv), authIn, sizeof(authIn), tagOut, sizeof(tag1)), 0); ExpectIntEQ(XMEMCMP(tag1, tagOut, sizeof(tag1)), 0); + wc_AesFree(&gmac.aes); #endif #ifdef WOLFSSL_AES_192 @@ -18170,6 +18188,7 @@ static int test_wc_GmacUpdate(void) ExpectIntEQ(wc_GmacUpdate(&gmac, iv2, sizeof(iv2), authIn2, sizeof(authIn2), tagOut2, sizeof(tag2)), 0); ExpectIntEQ(XMEMCMP(tagOut2, tag2, sizeof(tag2)), 0); + wc_AesFree(&gmac.aes); #endif #ifdef WOLFSSL_AES_256 @@ -18179,17 +18198,19 @@ static int test_wc_GmacUpdate(void) ExpectIntEQ(wc_GmacUpdate(&gmac, iv3, sizeof(iv3), authIn3, sizeof(authIn3), tagOut3, sizeof(tag3)), 0); ExpectIntEQ(XMEMCMP(tag3, tagOut3, sizeof(tag3)), 0); + wc_AesFree(&gmac.aes); #endif /* Pass bad args. */ + ExpectIntEQ(wc_AesInit(&gmac.aes, NULL, INVALID_DEVID), 0); ExpectIntEQ(wc_GmacUpdate(NULL, iv3, sizeof(iv3), authIn3, sizeof(authIn3), tagOut3, sizeof(tag3)), BAD_FUNC_ARG); ExpectIntEQ(wc_GmacUpdate(&gmac, iv3, sizeof(iv3), authIn3, sizeof(authIn3), tagOut3, sizeof(tag3) - 5), BAD_FUNC_ARG); ExpectIntEQ(wc_GmacUpdate(&gmac, iv3, sizeof(iv3), authIn3, sizeof(authIn3), tagOut3, sizeof(tag3) + 1), BAD_FUNC_ARG); - wc_AesFree(&gmac.aes); + #endif return EXPECT_RESULT(); } /* END test_wc_GmacUpdate */ @@ -42239,7 +42260,8 @@ static int test_wolfSSL_DES_ede3_cbc_encrypt(void) static int test_wolfSSL_AES_encrypt(void) { EXPECT_DECLS; -#if defined(OPENSSL_EXTRA) && !defined(NO_AES) && defined(HAVE_AES_ECB) +#if defined(OPENSSL_EXTRA) && !defined(NO_AES) && defined(HAVE_AES_ECB) \ + && !defined(WOLFSSL_NO_OPENSSL_AES_LOW_LEVEL_API) AES_KEY enc; AES_KEY dec; const byte msg[] = { @@ -42289,7 +42311,8 @@ static int test_wolfSSL_AES_encrypt(void) static int test_wolfSSL_AES_ecb_encrypt(void) { EXPECT_DECLS; -#if defined(OPENSSL_EXTRA) && !defined(NO_AES) && defined(HAVE_AES_ECB) +#if defined(OPENSSL_EXTRA) && !defined(NO_AES) && defined(HAVE_AES_ECB) \ + && !defined(WOLFSSL_NO_OPENSSL_AES_LOW_LEVEL_API) AES_KEY aes; const byte msg[] = { @@ -42337,7 +42360,8 @@ static int test_wolfSSL_AES_ecb_encrypt(void) static int test_wolfSSL_AES_cbc_encrypt(void) { EXPECT_DECLS; -#if !defined(NO_AES) && defined(HAVE_AES_CBC) && defined(OPENSSL_EXTRA) +#if !defined(NO_AES) && defined(HAVE_AES_CBC) && defined(OPENSSL_EXTRA) && \ + !defined(WOLFSSL_NO_OPENSSL_AES_LOW_LEVEL_API) AES_KEY aes; AES_KEY* aesN = NULL; size_t len = 0; @@ -42592,7 +42616,8 @@ static int test_wolfSSL_AES_cbc_encrypt(void) static int test_wolfSSL_AES_cfb128_encrypt(void) { EXPECT_DECLS; -#if defined(OPENSSL_EXTRA) && !defined(NO_AES) && defined(WOLFSSL_AES_CFB) +#if defined(OPENSSL_EXTRA) && !defined(NO_AES) && defined(WOLFSSL_AES_CFB) && \ + !defined(WOLFSSL_NO_OPENSSL_AES_LOW_LEVEL_API) AES_KEY aesEnc; AES_KEY aesDec; const byte msg[] = { @@ -42684,7 +42709,7 @@ static int test_wolfSSL_CRYPTO_cts128(void) { EXPECT_DECLS; #if !defined(NO_AES) && defined(HAVE_AES_CBC) && defined(OPENSSL_EXTRA) && \ - defined(HAVE_CTS) + defined(HAVE_CTS) && !defined(WOLFSSL_NO_OPENSSL_AES_LOW_LEVEL_API) byte tmp[64]; /* Largest vector size */ /* Test vectors taken form RFC3962 Appendix B */ const testVector vects[] = { @@ -46276,7 +46301,8 @@ static int test_wolfSSL_EVP_Cipher_extra(void) for (i = 0; test_drive[i]; i++) { - ExpectIntNE((ret = EVP_CipherInit(evp, NULL, key, iv, 1)), 0); + ExpectIntNE((ret = EVP_CipherInit(evp, NULL, key, iv, 1)), 0); + init_offset(); test_drive_len[i] = 0; @@ -46319,6 +46345,7 @@ static int test_wolfSSL_EVP_Cipher_extra(void) } ret = EVP_CipherFinal(evp, outb, &outl); + binary_dump(outb, outl); ret = (((test_drive_len[i] % 16) != 0) && (ret == 0)) || @@ -46326,6 +46353,7 @@ static int test_wolfSSL_EVP_Cipher_extra(void) ExpectTrue(ret); } + ExpectIntEQ(wolfSSL_EVP_CIPHER_CTX_cleanup(evp), WOLFSSL_SUCCESS); EVP_CIPHER_CTX_free(evp); evp = NULL; @@ -47818,6 +47846,7 @@ static int test_wolfSSL_EVP_CIPHER_CTX_key_length(void) ExpectIntEQ(EVP_CipherInit(ctx, init, key, iv, 1), WOLFSSL_SUCCESS); ExpectIntEQ(wolfSSL_EVP_CIPHER_CTX_key_length(ctx), key_lengths[i]); + ExpectIntEQ(wolfSSL_EVP_CIPHER_CTX_set_key_length(ctx, key_lengths[i]), WOLFSSL_SUCCESS); @@ -54689,6 +54718,36 @@ static int test_wolfssl_EVP_aes_gcm(void) ExpectIntEQ(0, XMEMCMP(plaintxt, decryptedtxt, decryptedtxtSz)); /* modify tag*/ + if (i == 0) { + /* Default uses 96-bits IV length */ +#ifdef WOLFSSL_AES_128 + ExpectIntEQ(1, EVP_DecryptInit_ex(&de[i], EVP_aes_128_gcm(), NULL, + key, iv)); +#elif defined(WOLFSSL_AES_192) + ExpectIntEQ(1, EVP_DecryptInit_ex(&de[i], EVP_aes_192_gcm(), NULL, + key, iv)); +#elif defined(WOLFSSL_AES_256) + ExpectIntEQ(1, EVP_DecryptInit_ex(&de[i], EVP_aes_256_gcm(), NULL, + key, iv)); +#endif + } + else { +#ifdef WOLFSSL_AES_128 + ExpectIntEQ(1, EVP_DecryptInit_ex(&de[i], EVP_aes_128_gcm(), NULL, + NULL, NULL)); +#elif defined(WOLFSSL_AES_192) + ExpectIntEQ(1, EVP_DecryptInit_ex(&de[i], EVP_aes_192_gcm(), NULL, + NULL, NULL)); +#elif defined(WOLFSSL_AES_256) + ExpectIntEQ(1, EVP_DecryptInit_ex(&de[i], EVP_aes_256_gcm(), NULL, + NULL, NULL)); +#endif + /* non-default must to set the IV length first */ + ExpectIntEQ(1, EVP_CIPHER_CTX_ctrl(&de[i], EVP_CTRL_GCM_SET_IVLEN, + ivSz, NULL)); + ExpectIntEQ(1, EVP_DecryptInit_ex(&de[i], NULL, NULL, key, iv)); + + } tag[AES_BLOCK_SIZE-1]+=0xBB; ExpectIntEQ(1, EVP_DecryptUpdate(&de[i], NULL, &len, aad, aadSz)); ExpectIntEQ(1, EVP_CIPHER_CTX_ctrl(&de[i], EVP_CTRL_GCM_SET_TAG, @@ -54698,6 +54757,7 @@ static int test_wolfssl_EVP_aes_gcm(void) ciphertxtSz)); ExpectIntEQ(0, EVP_DecryptFinal_ex(&de[i], decryptedtxt, &len)); ExpectIntEQ(0, len); + ExpectIntEQ(wolfSSL_EVP_CIPHER_CTX_cleanup(&de[i]), 1); } #endif /* OPENSSL_EXTRA && !NO_AES && HAVE_AESGCM */ diff --git a/wolfcrypt/src/aes.c b/wolfcrypt/src/aes.c index c5fc0c3c4..b677804fb 100644 --- a/wolfcrypt/src/aes.c +++ b/wolfcrypt/src/aes.c @@ -114,7 +114,6 @@ block cipher mechanism that uses n-bit binary string parameter key with 128-bits #pragma warning(disable: 4127) #endif - /* Define AES implementation includes and functions */ #if defined(STM32_CRYPTO) /* STM32F2/F4/F7/L4/L5/H7/WB55 hardware AES support for ECB, CBC, CTR and GCM modes */ @@ -132,6 +131,12 @@ block cipher mechanism that uses n-bit binary string parameter key with 128-bits CRYP_KeyInitTypeDef keyInit; #endif +#ifdef WC_DEBUG_CIPHER_LIFECYCLE + ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0); + if (ret < 0) + return ret; +#endif + #ifdef WOLFSSL_STM32_CUBEMX ret = wc_Stm32_Aes_Init(aes, &hcryp); if (ret != 0) @@ -227,6 +232,12 @@ block cipher mechanism that uses n-bit binary string parameter key with 128-bits CRYP_KeyInitTypeDef keyInit; #endif +#ifdef WC_DEBUG_CIPHER_LIFECYCLE + ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0); + if (ret < 0) + return ret; +#endif + #ifdef WOLFSSL_STM32_CUBEMX ret = wc_Stm32_Aes_Init(aes, &hcryp); if (ret != 0) @@ -343,6 +354,12 @@ block cipher mechanism that uses n-bit binary string parameter key with 128-bits if (ret != 0) return ret; +#ifdef WC_DEBUG_CIPHER_LIFECYCLE + ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0); + if (ret < 0) + return ret; +#endif + if (wolfSSL_CryptHwMutexLock() == 0) { LTC_AES_EncryptEcb(LTC_BASE, inBlock, outBlock, AES_BLOCK_SIZE, key, keySize); @@ -360,6 +377,12 @@ block cipher mechanism that uses n-bit binary string parameter key with 128-bits if (ret != 0) return ret; +#ifdef WC_DEBUG_CIPHER_LIFECYCLE + ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0); + if (ret < 0) + return ret; +#endif + if (wolfSSL_CryptHwMutexLock() == 0) { LTC_AES_DecryptEcb(LTC_BASE, inBlock, outBlock, AES_BLOCK_SIZE, key, keySize, kLTC_EncryptKey); @@ -384,6 +407,14 @@ block cipher mechanism that uses n-bit binary string parameter key with 128-bits static WARN_UNUSED_RESULT int wc_AesEncrypt( Aes* aes, const byte* inBlock, byte* outBlock) { +#ifdef WC_DEBUG_CIPHER_LIFECYCLE + { + int ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0); + if (ret < 0) + return ret; + } +#endif + if (wolfSSL_CryptHwMutexLock() == 0) { #ifdef FREESCALE_MMCAU_CLASSIC if ((wc_ptr_t)outBlock % WOLFSSL_MMCAU_ALIGNMENT) { @@ -403,6 +434,13 @@ block cipher mechanism that uses n-bit binary string parameter key with 128-bits static WARN_UNUSED_RESULT int wc_AesDecrypt( Aes* aes, const byte* inBlock, byte* outBlock) { +#ifdef WC_DEBUG_CIPHER_LIFECYCLE + { + int ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0); + if (ret < 0) + return ret; + } +#endif if (wolfSSL_CryptHwMutexLock() == 0) { #ifdef FREESCALE_MMCAU_CLASSIC if ((wc_ptr_t)outBlock % WOLFSSL_MMCAU_ALIGNMENT) { @@ -428,6 +466,13 @@ block cipher mechanism that uses n-bit binary string parameter key with 128-bits static WARN_UNUSED_RESULT int wc_AesEncrypt( Aes* aes, const byte* inBlock, byte* outBlock) { +#ifdef WC_DEBUG_CIPHER_LIFECYCLE + { + int ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0); + if (ret < 0) + return ret; + } +#endif /* Thread mutex protection handled in Pic32Crypto */ return wc_Pic32AesCrypt(aes->key, aes->keylen, NULL, 0, outBlock, inBlock, AES_BLOCK_SIZE, @@ -439,6 +484,13 @@ block cipher mechanism that uses n-bit binary string parameter key with 128-bits static WARN_UNUSED_RESULT int wc_AesDecrypt( Aes* aes, const byte* inBlock, byte* outBlock) { +#ifdef WC_DEBUG_CIPHER_LIFECYCLE + { + int ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0); + if (ret < 0) + return ret; + } +#endif /* Thread mutex protection handled in Pic32Crypto */ return wc_Pic32AesCrypt(aes->key, aes->keylen, NULL, 0, outBlock, inBlock, AES_BLOCK_SIZE, @@ -454,6 +506,13 @@ block cipher mechanism that uses n-bit binary string parameter key with 128-bits Aes* aes, const byte* inBlock, byte* outBlock) { int ret; + +#ifdef WC_DEBUG_CIPHER_LIFECYCLE + ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0); + if (ret < 0) + return ret; +#endif + ret = wolfSSL_CryptHwMutexLock(); if (ret == 0) { ret = nrf51_aes_encrypt(inBlock, (byte*)aes->key, aes->rounds, @@ -489,6 +548,13 @@ block cipher mechanism that uses n-bit binary string parameter key with 128-bits Aes* aes, const byte* inBlock, byte* outBlock) { int ret; + +#ifdef WC_DEBUG_CIPHER_LIFECYCLE + ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0); + if (ret < 0) + return ret; +#endif + /* Thread mutex protection handled in esp_aes_hw_InUse */ #ifdef NEED_AES_HW_FALLBACK if (wc_esp32AesSupportedKeyLen(aes)) { @@ -507,6 +573,11 @@ block cipher mechanism that uses n-bit binary string parameter key with 128-bits Aes* aes, const byte* inBlock, byte* outBlock) { int ret = 0; +#ifdef WC_DEBUG_CIPHER_LIFECYCLE + ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0); + if (ret < 0) + return ret; +#endif /* Thread mutex protection handled in esp_aes_hw_InUse */ #ifdef NEED_AES_HW_FALLBACK if (wc_esp32AesSupportedKeyLen(aes)) { @@ -700,6 +771,14 @@ block cipher mechanism that uses n-bit binary string parameter key with 128-bits static WARN_UNUSED_RESULT int wc_AesEncrypt( Aes* aes, const byte* inBlock, byte* outBlock) { +#ifdef WC_DEBUG_CIPHER_LIFECYCLE + { + int ret = + wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0); + if (ret < 0) + return ret; + } +#endif return wc_AesEncryptDirect(aes, outBlock, inBlock); } @@ -842,6 +921,13 @@ block cipher mechanism that uses n-bit binary string parameter key with 128-bits static WARN_UNUSED_RESULT int wc_AesEncrypt( Aes* aes, const byte* inBlock, byte* outBlock) { +#ifdef WC_DEBUG_CIPHER_LIFECYCLE + { + int ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0); + if (ret < 0) + return ret; + } +#endif return AES_ECB_encrypt(aes, inBlock, outBlock, AES_BLOCK_SIZE); } #endif @@ -850,6 +936,13 @@ block cipher mechanism that uses n-bit binary string parameter key with 128-bits static WARN_UNUSED_RESULT int wc_AesDecrypt( Aes* aes, const byte* inBlock, byte* outBlock) { +#ifdef WC_DEBUG_CIPHER_LIFECYCLE + { + int ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0); + if (ret < 0) + return ret; + } +#endif return AES_ECB_decrypt(aes, inBlock, outBlock, AES_BLOCK_SIZE); } #endif @@ -2671,6 +2764,14 @@ static WARN_UNUSED_RESULT int wc_AesEncrypt( return BAD_FUNC_ARG; } +#ifdef WC_DEBUG_CIPHER_LIFECYCLE + { + int ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0); + if (ret < 0) + return ret; + } +#endif + r = aes->rounds >> 1; if (r > 7 || r == 0) { @@ -3413,6 +3514,14 @@ static WARN_UNUSED_RESULT int wc_AesDecrypt( return BAD_FUNC_ARG; } +#ifdef WC_DEBUG_CIPHER_LIFECYCLE + { + int ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0); + if (ret < 0) + return ret; + } +#endif + r = aes->rounds >> 1; if (r > 7 || r == 0) { @@ -3505,6 +3614,14 @@ static WARN_UNUSED_RESULT int wc_AesDecrypt( return BAD_FUNC_ARG; } +#ifdef WC_DEBUG_CIPHER_LIFECYCLE + { + int ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0); + if (ret < 0) + return ret; + } +#endif + rk = aes->key; aes->keylen = keylen; aes->rounds = keylen/4 + 6; @@ -3578,6 +3695,14 @@ static WARN_UNUSED_RESULT int wc_AesDecrypt( if (aes == NULL) return BAD_FUNC_ARG; +#ifdef WC_DEBUG_CIPHER_LIFECYCLE + { + int ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0); + if (ret < 0) + return ret; + } +#endif + aes->keylen = keylen; aes->rounds = keylen/4 + 6; XMEMCPY(aes->key, userKey, keylen); @@ -3599,6 +3724,14 @@ static WARN_UNUSED_RESULT int wc_AesDecrypt( if (aes == NULL) return BAD_FUNC_ARG; +#ifdef WC_DEBUG_CIPHER_LIFECYCLE + { + int ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0); + if (ret < 0) + return ret; + } +#endif + if (checkKeyLen) { if (!((keylen == 16) || (keylen == 24) || (keylen == 32))) return BAD_FUNC_ARG; @@ -3643,6 +3776,14 @@ static WARN_UNUSED_RESULT int wc_AesDecrypt( if (aes == NULL) return BAD_FUNC_ARG; +#ifdef WC_DEBUG_CIPHER_LIFECYCLE + { + int ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0); + if (ret < 0) + return ret; + } +#endif + if (checkKeyLen) { if (!((keylen == 16) || (keylen == 24) || (keylen == 32))) return BAD_FUNC_ARG; @@ -3722,6 +3863,12 @@ static WARN_UNUSED_RESULT int wc_AesDecrypt( if (aes == NULL || keylen != 16) return BAD_FUNC_ARG; +#ifdef WC_DEBUG_CIPHER_LIFECYCLE + ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0); + if (ret < 0) + return ret; +#endif + aes->keylen = keylen; aes->rounds = keylen/4 + 6; XMEMCPY(aes->key, userKey, keylen); @@ -3754,6 +3901,14 @@ static WARN_UNUSED_RESULT int wc_AesDecrypt( return BAD_FUNC_ARG; } +#ifdef WC_DEBUG_CIPHER_LIFECYCLE + { + int ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0); + if (ret < 0) + return ret; + } +#endif + #if !defined(WOLFSSL_AES_128) if (keylen == 16) { return BAD_FUNC_ARG; @@ -3797,6 +3952,16 @@ static WARN_UNUSED_RESULT int wc_AesDecrypt( keylen != AES_256_KEY_SIZE)) { return BAD_FUNC_ARG; } + +#ifdef WC_DEBUG_CIPHER_LIFECYCLE + { + int ret2 = + wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0); + if (ret2 < 0) + return ret2; + } +#endif + #if defined(AES_MAX_KEY_SIZE) if (keylen > (AES_MAX_KEY_SIZE/8)) { return BAD_FUNC_ARG; @@ -4140,6 +4305,14 @@ static void AesSetKey_C(Aes* aes, const byte* key, word32 keySz, int dir) word32 localSz = 32; #endif + if (aes == NULL) + return BAD_FUNC_ARG; +#ifdef WC_DEBUG_CIPHER_LIFECYCLE + ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0); + if (ret < 0) + return ret; +#endif + switch (keylen) { #if defined(AES_MAX_KEY_SIZE) && AES_MAX_KEY_SIZE >= 128 && \ defined(WOLFSSL_AES_128) @@ -4460,6 +4633,14 @@ int wc_AesSetIV(Aes* aes, const byte* iv) if (aes == NULL) return BAD_FUNC_ARG; +#ifdef WC_DEBUG_CIPHER_LIFECYCLE + { + int ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0); + if (ret < 0) + return ret; + } +#endif + if (iv) XMEMCPY(aes->reg, iv, AES_BLOCK_SIZE); else @@ -10018,10 +10199,6 @@ int wc_AesGcmDecryptFinal(Aes* aes, const byte* authTag, word32 authTagSz) VECTOR_REGISTERS_POP; } - /* reset the state */ - if (ret == 0) - wc_AesFree(aes); - return ret; } #endif /* HAVE_AES_DECRYPT || HAVE_AESGCM_DECRYPT */ @@ -10986,6 +11163,12 @@ int wc_AesInit(Aes* aes, void* heap, int devId) #if defined(WOLFSSL_RENESAS_FSPSM) XMEMSET(&aes->ctx, 0, sizeof(aes->ctx)); #endif + +#ifdef WC_DEBUG_CIPHER_LIFECYCLE + if (ret == 0) + ret = wc_debug_CipherLifecycleInit(&aes->CipherLifecycleTag, aes->heap); +#endif + return ret; } @@ -11041,6 +11224,10 @@ void wc_AesFree(Aes* aes) if (aes == NULL) return; +#ifdef WC_DEBUG_CIPHER_LIFECYCLE + (void)wc_debug_CipherLifecycleFree(&aes->CipherLifecycleTag, aes->heap, 1); +#endif + #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_AES) wolfAsync_DevCtxFree(&aes->asyncDev, WOLFSSL_ASYNC_MARKER_AES); #endif /* WOLFSSL_ASYNC_CRYPT */ @@ -11096,17 +11283,16 @@ void wc_AesFree(Aes* aes) wc_MAXQ10XX_AesFree(aes); #endif -#ifdef WOLFSSL_CHECK_MEM_ZERO - wc_MemZero_Check(aes, sizeof(Aes)); -#endif - #if ((defined(WOLFSSL_RENESAS_FSPSM_TLS) || \ defined(WOLFSSL_RENESAS_FSPSM_CRYPTONLY)) && \ !defined(NO_WOLFSSL_RENESAS_FSPSM_AES)) wc_fspsm_Aesfree(aes); #endif -} +#ifdef WOLFSSL_CHECK_MEM_ZERO + wc_MemZero_Check(aes, sizeof(Aes)); +#endif +} int wc_AesGetKeySize(Aes* aes, word32* keySize) { @@ -12066,6 +12252,24 @@ int wc_AesKeyUnWrap(const byte* key, word32 keySz, const byte* in, word32 inSz, /* Galios Field to use */ #define GF_XTS 0x87 +int wc_AesXtsInit(XtsAes* aes, void* heap, int devId) +{ + int ret = 0; + + if (aes == NULL) { + return BAD_FUNC_ARG; + } + + if ((ret = wc_AesInit(&aes->tweak, heap, devId)) != 0) { + return ret; + } + if ((ret = wc_AesInit(&aes->aes, heap, devId)) != 0) { + return ret; + } + + return 0; +} + /* This is to help with setting keys to correct encrypt or decrypt type. * * tweak AES key for tweak in XTS @@ -12077,7 +12281,45 @@ int wc_AesKeyUnWrap(const byte* key, word32 keySz, const byte* in, word32 inSz, * heap heap hint to use for memory. Can be NULL * devId id to use with async crypto. Can be 0 * - * Note: is up to user to call wc_AesFree on tweak and aes key when done. + * return 0 on success + */ +int wc_AesXtsSetKey_NoInit(XtsAes* aes, const byte* key, word32 len, int dir) +{ + word32 keySz; + int ret = 0; + + if (aes == NULL || key == NULL) { + return BAD_FUNC_ARG; + } + + keySz = len/2; + if (keySz != 16 && keySz != 32) { + WOLFSSL_MSG("Unsupported key size"); + return WC_KEY_SIZE_E; + } + + if ((ret = wc_AesSetKey(&aes->aes, key, keySz, NULL, dir)) == 0) { + ret = wc_AesSetKey(&aes->tweak, key + keySz, keySz, NULL, + AES_ENCRYPTION); + if (ret != 0) { + wc_AesFree(&aes->aes); + } +#ifdef WOLFSSL_AESNI + if (aes->aes.use_aesni != aes->tweak.use_aesni) { + if (aes->aes.use_aesni) + aes->aes.use_aesni = 0; + else + aes->tweak.use_aesni = 0; + } +#endif + } + + return ret; +} + +/* Combined call to wc_AesXtsInit() and wc_AesXtsSetKey_NoInit(). + * + * Note: is up to user to call wc_AesXtsFree when done. * * return 0 on success */ @@ -12091,12 +12333,9 @@ int wc_AesXtsSetKey(XtsAes* aes, const byte* key, word32 len, int dir, return BAD_FUNC_ARG; } - if ((ret = wc_AesInit(&aes->tweak, heap, devId)) != 0) { + ret = wc_AesXtsInit(aes, heap, devId); + if (ret != 0) return ret; - } - if ((ret = wc_AesInit(&aes->aes, heap, devId)) != 0) { - return ret; - } keySz = len/2; if (keySz != 16 && keySz != 32) { @@ -13360,25 +13599,34 @@ int wc_AesEaxEncryptFinal(AesEax* eax, byte* authTag, word32 authTagSz) word32 cmacSize; int ret; word32 i; + int ciphertextCmac_finalized = 0; + int aadCmac_finalized = 0; - if (eax == NULL || authTag == NULL || authTagSz > AES_BLOCK_SIZE) { + if (eax == NULL) { return BAD_FUNC_ARG; } + if (authTag == NULL || authTagSz > AES_BLOCK_SIZE) { + ret = BAD_FUNC_ARG; + goto out; + } + /* Complete the OMAC for the ciphertext */ cmacSize = AES_BLOCK_SIZE; + ciphertextCmac_finalized = 1; if ((ret = wc_CmacFinal(&eax->ciphertextCmac, eax->ciphertextCmacFinal, &cmacSize)) != 0) { - return ret; + goto out; } /* Complete the OMAC for auth data */ cmacSize = AES_BLOCK_SIZE; + aadCmac_finalized = 1; if ((ret = wc_CmacFinal(&eax->aadCmac, eax->aadCmacFinal, &cmacSize)) != 0) { - return ret; + goto out; } /* @@ -13392,7 +13640,16 @@ int wc_AesEaxEncryptFinal(AesEax* eax, byte* authTag, word32 authTagSz) ^ eax->ciphertextCmacFinal[i]; } - return 0; + ret = 0; + +out: + + if (! ciphertextCmac_finalized) + (void)wc_CmacFinal(&eax->ciphertextCmac, NULL, NULL); + if (! aadCmac_finalized) + (void)wc_CmacFinal(&eax->aadCmac, NULL, NULL); + + return ret; } @@ -13411,37 +13668,47 @@ int wc_AesEaxDecryptFinal(AesEax* eax, int ret; word32 i; word32 cmacSize; + int ciphertextCmac_finalized = 0; + int aadCmac_finalized = 0; #if defined(WOLFSSL_SMALL_STACK) - byte *authTag; + byte *authTag = NULL; #else byte authTag[AES_BLOCK_SIZE]; #endif - if (eax == NULL || authIn == NULL || authInSz > AES_BLOCK_SIZE) { + if (eax == NULL) { return BAD_FUNC_ARG; } + if (authIn == NULL || authInSz > AES_BLOCK_SIZE) { + ret = BAD_FUNC_ARG; + goto out; + } + /* Complete the OMAC for the ciphertext */ cmacSize = AES_BLOCK_SIZE; + ciphertextCmac_finalized = 1; if ((ret = wc_CmacFinal(&eax->ciphertextCmac, eax->ciphertextCmacFinal, &cmacSize)) != 0) { - return ret; + goto out; } /* Complete the OMAC for auth data */ cmacSize = AES_BLOCK_SIZE; + aadCmac_finalized = 1; if ((ret = wc_CmacFinal(&eax->aadCmac, eax->aadCmacFinal, &cmacSize)) != 0) { - return ret; + goto out; } #if defined(WOLFSSL_SMALL_STACK) authTag = (byte*)XMALLOC(AES_BLOCK_SIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER); if (authTag == NULL) { - return MEMORY_E; + ret = MEMORY_E; + goto out; } #endif @@ -13463,6 +13730,13 @@ int wc_AesEaxDecryptFinal(AesEax* eax, ret = 0; } +out: + + if (! ciphertextCmac_finalized) + (void)wc_CmacFinal(&eax->ciphertextCmac, NULL, NULL); + if (! aadCmac_finalized) + (void)wc_CmacFinal(&eax->aadCmac, NULL, NULL); + #if defined(WOLFSSL_SMALL_STACK) XFREE(authTag, NULL, DYNAMIC_TYPE_TMP_BUFFER); #endif diff --git a/wolfcrypt/src/cmac.c b/wolfcrypt/src/cmac.c index 0461a7b55..de16dc2eb 100644 --- a/wolfcrypt/src/cmac.c +++ b/wolfcrypt/src/cmac.c @@ -230,9 +230,16 @@ int wc_CmacFinal(Cmac* cmac, byte* out, word32* outSz) const byte* subKey; word32 remainder; - if (cmac == NULL || out == NULL || outSz == NULL) { + if (cmac == NULL) return BAD_FUNC_ARG; + + if (out == NULL || outSz == NULL) { + if ((out == NULL) ^ (outSz == NULL)) + return BAD_FUNC_ARG; + ret = 0; + goto out; } + if (*outSz < WC_CMAC_TAG_MIN_SZ || *outSz > WC_CMAC_TAG_MAX_SZ) { return BUFFER_E; } @@ -244,7 +251,7 @@ int wc_CmacFinal(Cmac* cmac, byte* out, word32* outSz) { ret = wc_CryptoCb_Cmac(cmac, NULL, 0, NULL, 0, out, outSz, 0, NULL); if (ret != CRYPTOCB_UNAVAILABLE) - return ret; + goto out; /* fall-through when unavailable */ } #endif @@ -255,7 +262,8 @@ int wc_CmacFinal(Cmac* cmac, byte* out, word32* outSz) else { /* ensure we will have a valid remainder value */ if (cmac->bufferSz > AES_BLOCK_SIZE) { - return BAD_STATE_E; + ret = BAD_STATE_E; + goto out; } remainder = AES_BLOCK_SIZE - cmac->bufferSz; @@ -285,6 +293,9 @@ int wc_CmacFinal(Cmac* cmac, byte* out, word32* outSz) cmac->msg = NULL; } #endif + +out: + wc_AesFree(&cmac->aes); ForceZero(cmac, sizeof(Cmac)); diff --git a/wolfcrypt/src/evp.c b/wolfcrypt/src/evp.c index 56cbdfde9..173fe75fc 100644 --- a/wolfcrypt/src/evp.c +++ b/wolfcrypt/src/evp.c @@ -1225,20 +1225,20 @@ int wolfSSL_EVP_CipherFinal(WOLFSSL_EVP_CIPHER_CTX *ctx, unsigned char *out, IncCtr((byte*)ctx->cipher.aes.reg, ctx->cipher.aes.nonceSz); } } - if (ret == 0) { - /* Reinitialize for subsequent wolfSSL_EVP_Cipher calls. */ - if (wc_AesGcmInit(&ctx->cipher.aes, NULL, 0, - (byte*)ctx->cipher.aes.reg, - (word32)ctx->ivSz) != 0) { - WOLFSSL_MSG("wc_AesGcmInit failed"); - ret = WOLFSSL_FAILURE; - } - else { - ret = WOLFSSL_SUCCESS; - } + + /* Reinitialize for subsequent wolfSSL_EVP_Cipher calls. */ + if (wc_AesGcmInit(&ctx->cipher.aes, NULL, 0, + (byte*)ctx->cipher.aes.reg, + (word32)ctx->ivSz) != 0) + { + WOLFSSL_MSG("wc_AesGcmInit failed"); + ret = WOLFSSL_FAILURE; } else { - ret = WOLFSSL_FAILURE; + if (ret == 0) + ret = WOLFSSL_SUCCESS; + else + ret = WOLFSSL_FAILURE; } #endif /* WOLFSSL_AESGCM_STREAM */ if (ret == WOLFSSL_SUCCESS) { @@ -4841,7 +4841,7 @@ static const struct cipher{ #endif #endif - #ifdef HAVE_AES_OFB + #ifdef WOLFSSL_AES_OFB #ifdef WOLFSSL_AES_128 {AES_128_OFB_TYPE, EVP_AES_128_OFB, NID_aes_128_ofb}, #endif @@ -4853,7 +4853,7 @@ static const struct cipher{ #endif #endif - #ifdef HAVE_AES_XTS + #ifdef WOLFSSL_AES_XTS #ifdef WOLFSSL_AES_128 {AES_128_XTS_TYPE, EVP_AES_128_XTS, NID_aes_128_xts}, #endif @@ -6075,34 +6075,34 @@ void wolfSSL_EVP_init(void) } /* WOLFSSL_SUCCESS on ok */ - int wolfSSL_EVP_CIPHER_CTX_cleanup(WOLFSSL_EVP_CIPHER_CTX* ctx) + static int wolfSSL_EVP_CIPHER_CTX_cleanup_cipher( + WOLFSSL_EVP_CIPHER_CTX* ctx) { int ret = WOLFSSL_SUCCESS; - WOLFSSL_ENTER("wolfSSL_EVP_CIPHER_CTX_cleanup"); if (ctx) { #if (!defined(HAVE_FIPS) && !defined(HAVE_SELFTEST)) || \ (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 2)) switch (ctx->cipherType) { #if (defined(HAVE_AESGCM) && defined(WOLFSSL_AESGCM_STREAM)) || \ defined(HAVE_AESCCM) || \ - defined(HAVE_AESCBC) || \ + defined(HAVE_AES_CBC) || \ defined(WOLFSSL_AES_COUNTER) || \ defined(HAVE_AES_ECB) || \ - defined(HAVE_AES_CFB) || \ - defined(HAVE_AES_OFB) || \ + defined(WOLFSSL_AES_CFB) || \ + defined(WOLFSSL_AES_OFB) || \ defined(WOLFSSL_AES_XTS) - #if defined(HAVE_AESGCM) && defined(WOLFSSL_AESGCM_STREAM) + #if defined(HAVE_AESGCM) case AES_128_GCM_TYPE: case AES_192_GCM_TYPE: case AES_256_GCM_TYPE: - #endif /* HAVE_AESGCM && WOLFSSL_AESGCM_STREAM */ + #endif /* HAVE_AESGCM */ #if defined(HAVE_AESCCM) case AES_128_CCM_TYPE: case AES_192_CCM_TYPE: case AES_256_CCM_TYPE: #endif /* HAVE_AESCCM */ - #ifdef HAVE_AESCBC + #ifdef HAVE_AES_CBC case AES_128_CBC_TYPE: case AES_192_CBC_TYPE: case AES_256_CBC_TYPE: @@ -6117,7 +6117,7 @@ void wolfSSL_EVP_init(void) case AES_192_ECB_TYPE: case AES_256_ECB_TYPE: #endif - #ifdef HAVE_AES_CFB + #ifdef WOLFSSL_AES_CFB case AES_128_CFB1_TYPE: case AES_192_CFB1_TYPE: case AES_256_CFB1_TYPE: @@ -6128,17 +6128,21 @@ void wolfSSL_EVP_init(void) case AES_192_CFB128_TYPE: case AES_256_CFB128_TYPE: #endif - #ifdef HAVE_AES_OFB + #ifdef WOLFSSL_AES_OFB case AES_128_OFB_TYPE: case AES_192_OFB_TYPE: case AES_256_OFB_TYPE: #endif + wc_AesFree(&ctx->cipher.aes); + ctx->flags &= ~WOLFSSL_EVP_CIPH_LOW_LEVEL_INITED; + break; #ifdef WOLFSSL_AES_XTS case AES_128_XTS_TYPE: case AES_256_XTS_TYPE: - #endif - wc_AesFree(&ctx->cipher.aes); + wc_AesXtsFree(&ctx->cipher.xts); + ctx->flags &= ~WOLFSSL_EVP_CIPH_LOW_LEVEL_INITED; break; + #endif #endif /* AES */ #ifdef HAVE_ARIA case ARIA_128_GCM_TYPE: @@ -6177,7 +6181,16 @@ void wolfSSL_EVP_init(void) wc_Sm4Free(&ctx->cipher.sm4); } #endif + } + return ret; + } + int wolfSSL_EVP_CIPHER_CTX_cleanup(WOLFSSL_EVP_CIPHER_CTX* ctx) + { + int ret = WOLFSSL_SUCCESS; + WOLFSSL_ENTER("wolfSSL_EVP_CIPHER_CTX_cleanup"); + if (ctx) { + wolfSSL_EVP_CIPHER_CTX_cleanup_cipher(ctx); ctx->cipherType = WOLFSSL_EVP_CIPH_TYPE_INIT; /* not yet initialized */ #if defined(HAVE_CHACHA) && defined(HAVE_POLY1305) if (ctx->key) { @@ -6362,6 +6375,13 @@ void wolfSSL_EVP_init(void) } #endif + if (! (ctx->flags & WOLFSSL_EVP_CIPH_LOW_LEVEL_INITED)) { + if (wc_AesInit(&ctx->cipher.aes, NULL, INVALID_DEVID) != 0) + ret = WOLFSSL_FAILURE; + else + ctx->flags |= WOLFSSL_EVP_CIPH_LOW_LEVEL_INITED; + } + #ifndef WOLFSSL_AESGCM_STREAM if (ret == WOLFSSL_SUCCESS && key && wc_AesGcmSetKey(&ctx->cipher.aes, key, ctx->keyLen)) { @@ -6486,7 +6506,7 @@ void wolfSSL_EVP_init(void) (byte*)ctx->cipher.aes.reg, (word32)ctx->ivSz) != 0) { WOLFSSL_MSG("wc_AesGcmInit failed"); - return WOLFSSL_FATAL_ERROR; + return WOLFSSL_FAILURE; } ctx->authIncIv = 0; } @@ -6562,6 +6582,16 @@ void wolfSSL_EVP_init(void) } #endif + if (ret == WOLFSSL_SUCCESS) { + if (! (ctx->flags & WOLFSSL_EVP_CIPH_LOW_LEVEL_INITED)) { + if (wc_AesInit(&ctx->cipher.aes, NULL, INVALID_DEVID) != 0) { + WOLFSSL_MSG("wc_AesInit() failed"); + ret = WOLFSSL_FAILURE; + } else + ctx->flags |= WOLFSSL_EVP_CIPH_LOW_LEVEL_INITED; + } + } + if (ret == WOLFSSL_SUCCESS && key && wc_AesCcmSetKey(&ctx->cipher.aes, key, (word32)ctx->keyLen)) { WOLFSSL_MSG("wc_AesCcmSetKey() failed"); @@ -6737,6 +6767,7 @@ void wolfSSL_EVP_init(void) XMEMSET(&ctx->cipher, 0, sizeof(ctx->cipher)); ctx->flags = 0; } + /* always clear buffer state */ ctx->bufUsed = 0; ctx->lastUsed = 0; @@ -6761,11 +6792,12 @@ void wolfSSL_EVP_init(void) ctx->ivSz = AES_BLOCK_SIZE; if (enc == 0 || enc == 1) ctx->enc = enc ? 1 : 0; - if (key) { - ret = wc_AesInit(&ctx->cipher.aes, NULL, INVALID_DEVID); - if (ret != 0) + if (! (ctx->flags & WOLFSSL_EVP_CIPH_LOW_LEVEL_INITED)) { + if (wc_AesInit(&ctx->cipher.aes, NULL, INVALID_DEVID) != 0) return WOLFSSL_FAILURE; - + ctx->flags |= WOLFSSL_EVP_CIPH_LOW_LEVEL_INITED; + } + if (key) { ret = AesSetKey_ex(&ctx->cipher.aes, key, (word32)ctx->keyLen, iv, ctx->enc ? AES_ENCRYPTION : AES_DECRYPTION, 0); if (ret != 0) @@ -6790,6 +6822,11 @@ void wolfSSL_EVP_init(void) ctx->ivSz = AES_BLOCK_SIZE; if (enc == 0 || enc == 1) ctx->enc = enc ? 1 : 0; + if (! (ctx->flags & WOLFSSL_EVP_CIPH_LOW_LEVEL_INITED)) { + if (wc_AesInit(&ctx->cipher.aes, NULL, INVALID_DEVID) != 0) + return WOLFSSL_FAILURE; + ctx->flags |= WOLFSSL_EVP_CIPH_LOW_LEVEL_INITED; + } if (key) { ret = AesSetKey_ex(&ctx->cipher.aes, key, (word32)ctx->keyLen, iv, ctx->enc ? AES_ENCRYPTION : AES_DECRYPTION, 0); @@ -6815,6 +6852,11 @@ void wolfSSL_EVP_init(void) ctx->ivSz = AES_BLOCK_SIZE; if (enc == 0 || enc == 1) ctx->enc = enc ? 1 : 0; + if (! (ctx->flags & WOLFSSL_EVP_CIPH_LOW_LEVEL_INITED)) { + if (wc_AesInit(&ctx->cipher.aes, NULL, INVALID_DEVID) != 0) + return WOLFSSL_FAILURE; + ctx->flags |= WOLFSSL_EVP_CIPH_LOW_LEVEL_INITED; + } if (key) { ret = AesSetKey_ex(&ctx->cipher.aes, key, (word32)ctx->keyLen, iv, ctx->enc ? AES_ENCRYPTION : AES_DECRYPTION, 0); @@ -6872,7 +6914,8 @@ void wolfSSL_EVP_init(void) || ctx->cipherType == AES_256_CCM_TYPE || (type && EVP_CIPHER_TYPE_MATCHES(type, EVP_AES_256_CCM)) #endif - ) { + ) + { if (EvpCipherInitAesCCM(ctx, type, key, iv, enc) != WOLFSSL_SUCCESS) { return WOLFSSL_FAILURE; @@ -6896,6 +6939,11 @@ void wolfSSL_EVP_init(void) #endif if (enc == 0 || enc == 1) ctx->enc = enc ? 1 : 0; + if (! (ctx->flags & WOLFSSL_EVP_CIPH_LOW_LEVEL_INITED)) { + if (wc_AesInit(&ctx->cipher.aes, NULL, INVALID_DEVID) != 0) + return WOLFSSL_FAILURE; + ctx->flags |= WOLFSSL_EVP_CIPH_LOW_LEVEL_INITED; + } if (key) { ret = AesSetKey_ex(&ctx->cipher.aes, key, (word32)ctx->keyLen, iv, AES_ENCRYPTION, 1); @@ -6924,6 +6972,11 @@ void wolfSSL_EVP_init(void) #endif if (enc == 0 || enc == 1) ctx->enc = enc ? 1 : 0; + if (! (ctx->flags & WOLFSSL_EVP_CIPH_LOW_LEVEL_INITED)) { + if (wc_AesInit(&ctx->cipher.aes, NULL, INVALID_DEVID) != 0) + return WOLFSSL_FAILURE; + ctx->flags |= WOLFSSL_EVP_CIPH_LOW_LEVEL_INITED; + } if (key) { ret = AesSetKey_ex(&ctx->cipher.aes, key, (word32)ctx->keyLen, iv, AES_ENCRYPTION, 1); @@ -6952,6 +7005,11 @@ void wolfSSL_EVP_init(void) #endif if (enc == 0 || enc == 1) ctx->enc = enc ? 1 : 0; + if (! (ctx->flags & WOLFSSL_EVP_CIPH_LOW_LEVEL_INITED)) { + if (wc_AesInit(&ctx->cipher.aes, NULL, INVALID_DEVID) != 0) + return WOLFSSL_FAILURE; + ctx->flags |= WOLFSSL_EVP_CIPH_LOW_LEVEL_INITED; + } if (key) { ret = AesSetKey_ex(&ctx->cipher.aes, key, (word32)ctx->keyLen, iv, AES_ENCRYPTION, 1); @@ -6978,6 +7036,11 @@ void wolfSSL_EVP_init(void) ctx->block_size = AES_BLOCK_SIZE; if (enc == 0 || enc == 1) ctx->enc = enc ? 1 : 0; + if (! (ctx->flags & WOLFSSL_EVP_CIPH_LOW_LEVEL_INITED)) { + if (wc_AesInit(&ctx->cipher.aes, NULL, INVALID_DEVID) != 0) + return WOLFSSL_FAILURE; + ctx->flags |= WOLFSSL_EVP_CIPH_LOW_LEVEL_INITED; + } if (key) { ret = AesSetKey_ex(&ctx->cipher.aes, key, (word32)ctx->keyLen, NULL, ctx->enc ? AES_ENCRYPTION : AES_DECRYPTION, 1); @@ -6997,6 +7060,11 @@ void wolfSSL_EVP_init(void) ctx->block_size = AES_BLOCK_SIZE; if (enc == 0 || enc == 1) ctx->enc = enc ? 1 : 0; + if (! (ctx->flags & WOLFSSL_EVP_CIPH_LOW_LEVEL_INITED)) { + if (wc_AesInit(&ctx->cipher.aes, NULL, INVALID_DEVID) != 0) + return WOLFSSL_FAILURE; + ctx->flags |= WOLFSSL_EVP_CIPH_LOW_LEVEL_INITED; + } if (key) { ret = AesSetKey_ex(&ctx->cipher.aes, key, (word32)ctx->keyLen, NULL, ctx->enc ? AES_ENCRYPTION : AES_DECRYPTION, 1); @@ -7016,6 +7084,11 @@ void wolfSSL_EVP_init(void) ctx->block_size = AES_BLOCK_SIZE; if (enc == 0 || enc == 1) ctx->enc = enc ? 1 : 0; + if (! (ctx->flags & WOLFSSL_EVP_CIPH_LOW_LEVEL_INITED)) { + if (wc_AesInit(&ctx->cipher.aes, NULL, INVALID_DEVID) != 0) + return WOLFSSL_FAILURE; + ctx->flags |= WOLFSSL_EVP_CIPH_LOW_LEVEL_INITED; + } if (key) { ret = AesSetKey_ex(&ctx->cipher.aes, key, (word32)ctx->keyLen, NULL, ctx->enc ? AES_ENCRYPTION : AES_DECRYPTION, 1); @@ -7037,11 +7110,12 @@ void wolfSSL_EVP_init(void) ctx->block_size = 1; if (enc == 0 || enc == 1) ctx->enc = enc ? 1 : 0; - if (key) { - ret = wc_AesInit(&ctx->cipher.aes, NULL, INVALID_DEVID); - if (ret != 0) + if (! (ctx->flags & WOLFSSL_EVP_CIPH_LOW_LEVEL_INITED)) { + if (wc_AesInit(&ctx->cipher.aes, NULL, INVALID_DEVID) != 0) return WOLFSSL_FAILURE; - + ctx->flags |= WOLFSSL_EVP_CIPH_LOW_LEVEL_INITED; + } + if (key) { ret = AesSetKey_ex(&ctx->cipher.aes, key, (word32)ctx->keyLen, iv, AES_ENCRYPTION, 0); if (ret != 0) @@ -7065,11 +7139,12 @@ void wolfSSL_EVP_init(void) ctx->block_size = 1; if (enc == 0 || enc == 1) ctx->enc = enc ? 1 : 0; - if (key) { - ret = wc_AesInit(&ctx->cipher.aes, NULL, INVALID_DEVID); - if (ret != 0) + if (! (ctx->flags & WOLFSSL_EVP_CIPH_LOW_LEVEL_INITED)) { + if (wc_AesInit(&ctx->cipher.aes, NULL, INVALID_DEVID) != 0) return WOLFSSL_FAILURE; - + ctx->flags |= WOLFSSL_EVP_CIPH_LOW_LEVEL_INITED; + } + if (key) { ret = AesSetKey_ex(&ctx->cipher.aes, key, (word32)ctx->keyLen, iv, AES_ENCRYPTION, 0); if (ret != 0) @@ -7093,11 +7168,12 @@ void wolfSSL_EVP_init(void) ctx->block_size = 1; if (enc == 0 || enc == 1) ctx->enc = enc ? 1 : 0; - if (key) { - ret = wc_AesInit(&ctx->cipher.aes, NULL, INVALID_DEVID); - if (ret != 0) + if (! (ctx->flags & WOLFSSL_EVP_CIPH_LOW_LEVEL_INITED)) { + if (wc_AesInit(&ctx->cipher.aes, NULL, INVALID_DEVID) != 0) return WOLFSSL_FAILURE; - + ctx->flags |= WOLFSSL_EVP_CIPH_LOW_LEVEL_INITED; + } + if (key) { ret = AesSetKey_ex(&ctx->cipher.aes, key, (word32)ctx->keyLen, iv, AES_ENCRYPTION, 0); if (ret != 0){ @@ -7125,11 +7201,12 @@ void wolfSSL_EVP_init(void) ctx->block_size = 1; if (enc == 0 || enc == 1) ctx->enc = enc ? 1 : 0; - if (key) { - ret = wc_AesInit(&ctx->cipher.aes, NULL, INVALID_DEVID); - if (ret != 0) + if (! (ctx->flags & WOLFSSL_EVP_CIPH_LOW_LEVEL_INITED)) { + if (wc_AesInit(&ctx->cipher.aes, NULL, INVALID_DEVID) != 0) return WOLFSSL_FAILURE; - + ctx->flags |= WOLFSSL_EVP_CIPH_LOW_LEVEL_INITED; + } + if (key) { ret = AesSetKey_ex(&ctx->cipher.aes, key, (word32)ctx->keyLen, iv, AES_ENCRYPTION, 0); if (ret != 0) @@ -7153,11 +7230,12 @@ void wolfSSL_EVP_init(void) ctx->block_size = 1; if (enc == 0 || enc == 1) ctx->enc = enc ? 1 : 0; - if (key) { - ret = wc_AesInit(&ctx->cipher.aes, NULL, INVALID_DEVID); - if (ret != 0) + if (! (ctx->flags & WOLFSSL_EVP_CIPH_LOW_LEVEL_INITED)) { + if (wc_AesInit(&ctx->cipher.aes, NULL, INVALID_DEVID) != 0) return WOLFSSL_FAILURE; - + ctx->flags |= WOLFSSL_EVP_CIPH_LOW_LEVEL_INITED; + } + if (key) { ret = AesSetKey_ex(&ctx->cipher.aes, key, (word32)ctx->keyLen, iv, AES_ENCRYPTION, 0); if (ret != 0) @@ -7181,11 +7259,12 @@ void wolfSSL_EVP_init(void) ctx->block_size = 1; if (enc == 0 || enc == 1) ctx->enc = enc ? 1 : 0; - if (key) { - ret = wc_AesInit(&ctx->cipher.aes, NULL, INVALID_DEVID); - if (ret != 0) + if (! (ctx->flags & WOLFSSL_EVP_CIPH_LOW_LEVEL_INITED)) { + if (wc_AesInit(&ctx->cipher.aes, NULL, INVALID_DEVID) != 0) return WOLFSSL_FAILURE; - + ctx->flags |= WOLFSSL_EVP_CIPH_LOW_LEVEL_INITED; + } + if (key) { ret = AesSetKey_ex(&ctx->cipher.aes, key, (word32)ctx->keyLen, iv, AES_ENCRYPTION, 0); if (ret != 0){ @@ -7213,11 +7292,12 @@ void wolfSSL_EVP_init(void) ctx->block_size = 1; if (enc == 0 || enc == 1) ctx->enc = enc ? 1 : 0; - if (key) { - ret = wc_AesInit(&ctx->cipher.aes, NULL, INVALID_DEVID); - if (ret != 0) + if (! (ctx->flags & WOLFSSL_EVP_CIPH_LOW_LEVEL_INITED)) { + if (wc_AesInit(&ctx->cipher.aes, NULL, INVALID_DEVID) != 0) return WOLFSSL_FAILURE; - + ctx->flags |= WOLFSSL_EVP_CIPH_LOW_LEVEL_INITED; + } + if (key) { ret = AesSetKey_ex(&ctx->cipher.aes, key, (word32)ctx->keyLen, iv, AES_ENCRYPTION, 0); if (ret != 0) @@ -7241,11 +7321,12 @@ void wolfSSL_EVP_init(void) ctx->block_size = 1; if (enc == 0 || enc == 1) ctx->enc = enc ? 1 : 0; - if (key) { - ret = wc_AesInit(&ctx->cipher.aes, NULL, INVALID_DEVID); - if (ret != 0) + if (! (ctx->flags & WOLFSSL_EVP_CIPH_LOW_LEVEL_INITED)) { + if (wc_AesInit(&ctx->cipher.aes, NULL, INVALID_DEVID) != 0) return WOLFSSL_FAILURE; - + ctx->flags |= WOLFSSL_EVP_CIPH_LOW_LEVEL_INITED; + } + if (key) { ret = AesSetKey_ex(&ctx->cipher.aes, key, (word32)ctx->keyLen, iv, AES_ENCRYPTION, 0); if (ret != 0) @@ -7269,11 +7350,12 @@ void wolfSSL_EVP_init(void) ctx->block_size = 1; if (enc == 0 || enc == 1) ctx->enc = enc ? 1 : 0; - if (key) { - ret = wc_AesInit(&ctx->cipher.aes, NULL, INVALID_DEVID); - if (ret != 0) + if (! (ctx->flags & WOLFSSL_EVP_CIPH_LOW_LEVEL_INITED)) { + if (wc_AesInit(&ctx->cipher.aes, NULL, INVALID_DEVID) != 0) return WOLFSSL_FAILURE; - + ctx->flags |= WOLFSSL_EVP_CIPH_LOW_LEVEL_INITED; + } + if (key) { ret = AesSetKey_ex(&ctx->cipher.aes, key, (word32)ctx->keyLen, iv, AES_ENCRYPTION, 0); if (ret != 0){ @@ -7303,11 +7385,12 @@ void wolfSSL_EVP_init(void) ctx->block_size = 1; if (enc == 0 || enc == 1) ctx->enc = enc ? 1 : 0; - if (key) { - ret = wc_AesInit(&ctx->cipher.aes, NULL, INVALID_DEVID); - if (ret != 0) + if (! (ctx->flags & WOLFSSL_EVP_CIPH_LOW_LEVEL_INITED)) { + if (wc_AesInit(&ctx->cipher.aes, NULL, INVALID_DEVID) != 0) return WOLFSSL_FAILURE; - + ctx->flags |= WOLFSSL_EVP_CIPH_LOW_LEVEL_INITED; + } + if (key) { ret = AesSetKey_ex(&ctx->cipher.aes, key, (word32)ctx->keyLen, iv, AES_ENCRYPTION, 0); if (ret != 0) @@ -7331,11 +7414,12 @@ void wolfSSL_EVP_init(void) ctx->block_size = 1; if (enc == 0 || enc == 1) ctx->enc = enc ? 1 : 0; - if (key) { - ret = wc_AesInit(&ctx->cipher.aes, NULL, INVALID_DEVID); - if (ret != 0) + if (! (ctx->flags & WOLFSSL_EVP_CIPH_LOW_LEVEL_INITED)) { + if (wc_AesInit(&ctx->cipher.aes, NULL, INVALID_DEVID) != 0) return WOLFSSL_FAILURE; - + ctx->flags |= WOLFSSL_EVP_CIPH_LOW_LEVEL_INITED; + } + if (key) { ret = AesSetKey_ex(&ctx->cipher.aes, key, (word32)ctx->keyLen, iv, AES_ENCRYPTION, 0); if (ret != 0) @@ -7359,11 +7443,12 @@ void wolfSSL_EVP_init(void) ctx->block_size = 1; if (enc == 0 || enc == 1) ctx->enc = enc ? 1 : 0; - if (key) { - ret = wc_AesInit(&ctx->cipher.aes, NULL, INVALID_DEVID); - if (ret != 0) + if (! (ctx->flags & WOLFSSL_EVP_CIPH_LOW_LEVEL_INITED)) { + if (wc_AesInit(&ctx->cipher.aes, NULL, INVALID_DEVID) != 0) return WOLFSSL_FAILURE; - + ctx->flags |= WOLFSSL_EVP_CIPH_LOW_LEVEL_INITED; + } + if (key) { ret = AesSetKey_ex(&ctx->cipher.aes, key, (word32)ctx->keyLen, iv, AES_ENCRYPTION, 0); if (ret != 0){ @@ -7380,7 +7465,7 @@ void wolfSSL_EVP_init(void) } } #endif /* WOLFSSL_AES_256 */ - #endif /* HAVE_AES_OFB */ + #endif /* WOLFSSL_AES_OFB */ #ifdef WOLFSSL_AES_XTS #ifdef WOLFSSL_AES_128 if (ctx->cipherType == AES_128_XTS_TYPE || @@ -7402,10 +7487,20 @@ void wolfSSL_EVP_init(void) if (enc == 0 || enc == 1) ctx->enc = enc ? 1 : 0; + + if (! (ctx->flags & WOLFSSL_EVP_CIPH_LOW_LEVEL_INITED)) { + ret = wc_AesXtsInit(&ctx->cipher.xts, NULL, 0); + if (ret != 0) { + WOLFSSL_MSG("wc_AesXtsInit() failed"); + return WOLFSSL_FAILURE; + } + ctx->flags |= WOLFSSL_EVP_CIPH_LOW_LEVEL_INITED; + } + if (key) { - ret = wc_AesXtsSetKey(&ctx->cipher.xts, key, + ret = wc_AesXtsSetKey_NoInit(&ctx->cipher.xts, key, (word32)ctx->keyLen, - ctx->enc ? AES_ENCRYPTION : AES_DECRYPTION, NULL, 0); + ctx->enc ? AES_ENCRYPTION : AES_DECRYPTION); if (ret != 0) { WOLFSSL_MSG("wc_AesXtsSetKey() failed"); return WOLFSSL_FAILURE; @@ -7433,10 +7528,20 @@ void wolfSSL_EVP_init(void) if (enc == 0 || enc == 1) ctx->enc = enc ? 1 : 0; + + if (! (ctx->flags & WOLFSSL_EVP_CIPH_LOW_LEVEL_INITED)) { + ret = wc_AesXtsInit(&ctx->cipher.xts, NULL, 0); + if (ret != 0) { + WOLFSSL_MSG("wc_AesXtsInit() failed"); + return WOLFSSL_FAILURE; + } + ctx->flags |= WOLFSSL_EVP_CIPH_LOW_LEVEL_INITED; + } + if (key) { - ret = wc_AesXtsSetKey(&ctx->cipher.xts, key, + ret = wc_AesXtsSetKey_NoInit(&ctx->cipher.xts, key, (word32)ctx->keyLen, - ctx->enc ? AES_ENCRYPTION : AES_DECRYPTION, NULL, 0); + ctx->enc ? AES_ENCRYPTION : AES_DECRYPTION); if (ret != 0) { WOLFSSL_MSG("wc_AesXtsSetKey() failed"); return WOLFSSL_FAILURE; @@ -7444,7 +7549,7 @@ void wolfSSL_EVP_init(void) } } #endif /* WOLFSSL_AES_256 */ - #endif /* HAVE_AES_XTS */ + #endif /* WOLFSSL_AES_XTS */ #endif /* NO_AES */ #if defined(HAVE_ARIA) if (ctx->cipherType == ARIA_128_GCM_TYPE || diff --git a/wolfcrypt/src/memory.c b/wolfcrypt/src/memory.c index 3c265c0cf..565d91075 100644 --- a/wolfcrypt/src/memory.c +++ b/wolfcrypt/src/memory.c @@ -1438,6 +1438,70 @@ void __attribute__((no_instrument_function)) } #endif +#ifdef WC_DEBUG_CIPHER_LIFECYCLE +static const byte wc_debug_cipher_lifecycle_tag_value[] = + { 'W', 'o', 'l', 'f' }; + +WOLFSSL_LOCAL int wc_debug_CipherLifecycleInit( + void **CipherLifecycleTag, + void *heap) +{ + if (CipherLifecycleTag == NULL) + return BAD_FUNC_ARG; + *CipherLifecycleTag = (void *)XMALLOC( + sizeof(wc_debug_cipher_lifecycle_tag_value), + heap, + DYNAMIC_TYPE_DEBUG_TAG); + if (*CipherLifecycleTag == NULL) + return MEMORY_E; + XMEMCPY(*CipherLifecycleTag, + wc_debug_cipher_lifecycle_tag_value, + sizeof(wc_debug_cipher_lifecycle_tag_value)); + return 0; +} + +WOLFSSL_LOCAL int wc_debug_CipherLifecycleCheck( + void *CipherLifecycleTag, + int abort_p) +{ + int ret; + if (CipherLifecycleTag == NULL) { + ret = BAD_STATE_E; + goto out; + } + if (XMEMCMP(CipherLifecycleTag, + wc_debug_cipher_lifecycle_tag_value, + sizeof(wc_debug_cipher_lifecycle_tag_value)) != 0) + { + ret = BAD_STATE_E; + goto out; + } + ret = 0; + +out: + if ((ret < 0) && abort_p) + abort(); + + return ret; +} + +WOLFSSL_LOCAL int wc_debug_CipherLifecycleFree( + void **CipherLifecycleTag, + void *heap, + int abort_p) +{ + int ret; + if (CipherLifecycleTag == NULL) + return BAD_FUNC_ARG; + ret = wc_debug_CipherLifecycleCheck(*CipherLifecycleTag, abort_p); + if (ret != 0) + return ret; + XFREE(*CipherLifecycleTag, heap, DYNAMIC_TYPE_DEBUG_TAG); + *CipherLifecycleTag = NULL; + return 0; +} +#endif /* WC_DEBUG_CIPHER_LIFECYCLE */ + #ifdef DEBUG_VECTOR_REGISTER_ACCESS THREAD_LS_T int wc_svr_count = 0; THREAD_LS_T const char *wc_svr_last_file = NULL; diff --git a/wolfcrypt/src/port/af_alg/afalg_aes.c b/wolfcrypt/src/port/af_alg/afalg_aes.c index 39a9ee6e6..27ee88f61 100644 --- a/wolfcrypt/src/port/af_alg/afalg_aes.c +++ b/wolfcrypt/src/port/af_alg/afalg_aes.c @@ -58,6 +58,14 @@ static int wc_AesSetup(Aes* aes, const char* type, const char* name, int ivSz, i byte* key = (byte*)aes->key; #endif + if (aes->alFd <= 0) { + aes->alFd = wc_Afalg_Socket(); + if (aes->alFd < 0) { + WOLFSSL_MSG("Unable to open an AF_ALG socket"); + return WC_AFALG_SOCK_E; + } + } + aes->rdFd = wc_Afalg_CreateRead(aes->alFd, type, name); if (aes->rdFd < 0) { WOLFSSL_MSG("Unable to accept and get AF_ALG read socket"); diff --git a/wolfcrypt/test/test.c b/wolfcrypt/test/test.c index 534dedc43..09cd9db29 100644 --- a/wolfcrypt/test/test.c +++ b/wolfcrypt/test/test.c @@ -7961,6 +7961,7 @@ static wc_test_ret_t EVP_test(const WOLFSSL_EVP_CIPHER* type, const byte* key, #else EVP_CIPHER_CTX ctx[1]; #endif + int ctx_inited = 0; int idx, cipherSz; wc_test_ret_t ret = 0; byte* cipher; @@ -7978,6 +7979,7 @@ static wc_test_ret_t EVP_test(const WOLFSSL_EVP_CIPHER* type, const byte* key, /* test encrypt */ EVP_CIPHER_CTX_init(ctx); + ctx_inited = 1; if (EVP_CipherInit(ctx, type, key, iv, 1) == 0) { ret = WC_TEST_RET_ENC_NC; goto EVP_TEST_END; @@ -8000,8 +8002,18 @@ static wc_test_ret_t EVP_test(const WOLFSSL_EVP_CIPHER* type, const byte* key, goto EVP_TEST_END; } + ret = wolfSSL_EVP_CIPHER_CTX_cleanup(ctx); + ctx_inited = 0; + if (ret == WOLFSSL_SUCCESS) + ret = 0; + else { + ret = WC_TEST_RET_ENC_NC; + goto EVP_TEST_END; + } + /* test decrypt */ EVP_CIPHER_CTX_init(ctx); + ctx_inited = 1; if (EVP_CipherInit(ctx, type, key, iv, 0) == 0) { ret = WC_TEST_RET_ENC_NC; goto EVP_TEST_END; @@ -8028,6 +8040,13 @@ EVP_TEST_END: if (cipher) XFREE(cipher, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); (void)cipherSz; + + if (ctx_inited) { + int cleanup_ret = wolfSSL_EVP_CIPHER_CTX_cleanup(ctx); + if (cleanup_ret != WOLFSSL_SUCCESS) + ret = WC_TEST_RET_ENC_NC; + } + #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_NO_MALLOC) wolfSSL_EVP_CIPHER_CTX_free(ctx); #endif @@ -9460,13 +9479,16 @@ static wc_test_ret_t aes_xts_128_test(void) #endif XMEMSET(buf, 0, sizeof(buf)); - ret = wc_AesXtsSetKey(aes, k2, sizeof(k2), AES_ENCRYPTION, - HEAP_HINT, devId); + ret = wc_AesXtsInit(aes, HEAP_HINT, devId); if (ret != 0) ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); else aes_inited = 1; + ret = wc_AesXtsSetKey_NoInit(aes, k2, sizeof(k2), AES_ENCRYPTION); + if (ret != 0) + ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); + ret = wc_AesXtsEncrypt(aes, buf, p2, sizeof(p2), i2, sizeof(i2)); #if defined(WOLFSSL_ASYNC_CRYPT) ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE); @@ -9490,10 +9512,8 @@ static wc_test_ret_t aes_xts_128_test(void) #endif XMEMSET(buf, 0, sizeof(buf)); - wc_AesXtsFree(aes); - ret = wc_AesXtsSetKey(aes, k1, sizeof(k1), AES_ENCRYPTION, - HEAP_HINT, devId); + ret = wc_AesXtsSetKey_NoInit(aes, k1, sizeof(k1), AES_ENCRYPTION); if (ret != 0) ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); ret = wc_AesXtsEncrypt(aes, buf, p1, sizeof(p1), i1, sizeof(i1)); @@ -9543,12 +9563,9 @@ static wc_test_ret_t aes_xts_128_test(void) ERROR_OUT(WC_TEST_RET_ENC_NC, out); #endif - wc_AesXtsFree(aes); - /* partial block decrypt test */ XMEMSET(buf, 0, sizeof(buf)); - ret = wc_AesXtsSetKey(aes, k1, sizeof(k1), AES_DECRYPTION, - HEAP_HINT, devId); + ret = wc_AesXtsSetKey_NoInit(aes, k1, sizeof(k1), AES_DECRYPTION); if (ret != 0) ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); ret = wc_AesXtsDecrypt(aes, buf, cipher, sizeof(pp), i1, sizeof(i1)); @@ -9610,12 +9627,9 @@ static wc_test_ret_t aes_xts_128_test(void) if (XMEMCMP(p2, buf, sizeof(p2)) == 0) /* fail case with wrong key */ ERROR_OUT(WC_TEST_RET_ENC_NC, out); - wc_AesXtsFree(aes); - /* set correct key and retest */ XMEMSET(buf, 0, sizeof(buf)); - ret = wc_AesXtsSetKey(aes, k2, sizeof(k2), AES_DECRYPTION, - HEAP_HINT, devId); + ret = wc_AesXtsSetKey_NoInit(aes, k2, sizeof(k2), AES_DECRYPTION); if (ret != 0) ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); ret = wc_AesXtsDecrypt(aes, buf, c2, sizeof(c2), i2, sizeof(i2)); @@ -9627,18 +9641,13 @@ static wc_test_ret_t aes_xts_128_test(void) if (XMEMCMP(p2, buf, sizeof(p2))) ERROR_OUT(WC_TEST_RET_ENC_NC, out); - wc_AesXtsFree(aes); - #if !defined(HAVE_FIPS) || FIPS_VERSION_GE(5,3) /* Test ciphertext stealing in-place. */ XMEMCPY(buf, p3, sizeof(p3)); - ret = wc_AesXtsSetKey(aes, k3, sizeof(k3), AES_ENCRYPTION, - HEAP_HINT, devId); + ret = wc_AesXtsSetKey_NoInit(aes, k3, sizeof(k3), AES_ENCRYPTION); if (ret != 0) ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); - else - aes_inited = 1; ret = wc_AesXtsEncrypt(aes, buf, buf, sizeof(p3), i3, sizeof(i3)); #if defined(WOLFSSL_ASYNC_CRYPT) @@ -9649,10 +9658,7 @@ static wc_test_ret_t aes_xts_128_test(void) if (XMEMCMP(c3, buf, sizeof(c3))) ERROR_OUT(WC_TEST_RET_ENC_NC, out); - wc_AesXtsFree(aes); - - ret = wc_AesXtsSetKey(aes, k3, sizeof(k3), AES_DECRYPTION, - HEAP_HINT, devId); + ret = wc_AesXtsSetKey_NoInit(aes, k3, sizeof(k3), AES_DECRYPTION); if (ret != 0) ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); ret = wc_AesXtsDecrypt(aes, buf, buf, sizeof(c3), i3, sizeof(i3)); @@ -9688,8 +9694,7 @@ static wc_test_ret_t aes_xts_128_test(void) large_input[i] = (byte)i; for (j = 16; j < (int)LARGE_XTS_SZ; j++) { - ret = wc_AesXtsSetKey(aes, k1, sizeof(k1), AES_ENCRYPTION, - HEAP_HINT, devId); + ret = wc_AesXtsSetKey_NoInit(aes, k1, sizeof(k1), AES_ENCRYPTION); if (ret != 0) ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); ret = wc_AesXtsEncrypt(aes, large_input, large_input, j, i1, @@ -9700,8 +9705,7 @@ static wc_test_ret_t aes_xts_128_test(void) if (ret != 0) ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); - ret = wc_AesXtsSetKey(aes, k1, sizeof(k1), AES_DECRYPTION, - HEAP_HINT, devId); + ret = wc_AesXtsSetKey_NoInit(aes, k1, sizeof(k1), AES_DECRYPTION); if (ret != 0) ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); ret = wc_AesXtsDecrypt(aes, large_input, large_input, j, i1, @@ -9840,13 +9844,17 @@ static wc_test_ret_t aes_xts_256_test(void) } #endif - XMEMSET(buf, 0, sizeof(buf)); - ret = wc_AesXtsSetKey(aes, k2, sizeof(k2), AES_ENCRYPTION, - HEAP_HINT, devId); + ret = wc_AesXtsInit(aes, HEAP_HINT, devId); if (ret != 0) ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); else aes_inited = 1; + + XMEMSET(buf, 0, sizeof(buf)); + ret = wc_AesXtsSetKey_NoInit(aes, k2, sizeof(k2), AES_ENCRYPTION); + if (ret != 0) + ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); + ret = wc_AesXtsEncrypt(aes, buf, p2, sizeof(p2), i2, sizeof(i2)); #if defined(WOLFSSL_ASYNC_CRYPT) ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE); @@ -9855,11 +9863,9 @@ static wc_test_ret_t aes_xts_256_test(void) ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); if (XMEMCMP(c2, buf, sizeof(c2))) ERROR_OUT(WC_TEST_RET_ENC_NC, out); - wc_AesXtsFree(aes); XMEMSET(buf, 0, sizeof(buf)); - ret = wc_AesXtsSetKey(aes, k1, sizeof(k1), AES_ENCRYPTION, - HEAP_HINT, devId); + ret = wc_AesXtsSetKey_NoInit(aes, k1, sizeof(k1), AES_ENCRYPTION); if (ret != 0) ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); ret = wc_AesXtsEncrypt(aes, buf, p1, sizeof(p1), i1, sizeof(i1)); @@ -9879,12 +9885,10 @@ static wc_test_ret_t aes_xts_256_test(void) #endif if (ret != 0) ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); - wc_AesXtsFree(aes); /* partial block decrypt test */ XMEMSET(buf, 0, sizeof(buf)); - ret = wc_AesXtsSetKey(aes, k1, sizeof(k1), AES_DECRYPTION, - HEAP_HINT, devId); + ret = wc_AesXtsSetKey_NoInit(aes, k1, sizeof(k1), AES_DECRYPTION); if (ret != 0) ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); ret = wc_AesXtsDecrypt(aes, buf, cipher, sizeof(pp), i1, sizeof(i1)); @@ -9906,11 +9910,9 @@ static wc_test_ret_t aes_xts_256_test(void) ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); if (XMEMCMP(p1, buf, AES_BLOCK_SIZE)) ERROR_OUT(WC_TEST_RET_ENC_NC, out); - wc_AesXtsFree(aes); XMEMSET(buf, 0, sizeof(buf)); - ret = wc_AesXtsSetKey(aes, k2, sizeof(k2), AES_DECRYPTION, - HEAP_HINT, devId); + ret = wc_AesXtsSetKey_NoInit(aes, k2, sizeof(k2), AES_DECRYPTION); if (ret != 0) ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); ret = wc_AesXtsDecrypt(aes, buf, c2, sizeof(c2), i2, sizeof(i2)); @@ -10119,13 +10121,17 @@ static wc_test_ret_t aes_xts_sector_test(void) ERROR_OUT(WC_TEST_RET_ENC_ERRNO, out); #endif - XMEMSET(buf, 0, sizeof(buf)); - ret = wc_AesXtsSetKey(aes, k1, sizeof(k1), AES_ENCRYPTION, - HEAP_HINT, devId); + ret = wc_AesXtsInit(aes, HEAP_HINT, devId); if (ret != 0) ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); else aes_inited = 1; + + XMEMSET(buf, 0, sizeof(buf)); + ret = wc_AesXtsSetKey_NoInit(aes, k1, sizeof(k1), AES_ENCRYPTION); + if (ret != 0) + ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); + ret = wc_AesXtsEncryptSector(aes, buf, p1, sizeof(p1), s1); #if defined(WOLFSSL_ASYNC_CRYPT) ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE); @@ -10134,12 +10140,10 @@ static wc_test_ret_t aes_xts_sector_test(void) ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); if (XMEMCMP(c1, buf, AES_BLOCK_SIZE)) ERROR_OUT(WC_TEST_RET_ENC_NC, out); - wc_AesXtsFree(aes); /* decrypt test */ XMEMSET(buf, 0, sizeof(buf)); - ret = wc_AesXtsSetKey(aes, k1, sizeof(k1), AES_DECRYPTION, - HEAP_HINT, devId); + ret = wc_AesXtsSetKey_NoInit(aes, k1, sizeof(k1), AES_DECRYPTION); if (ret != 0) ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); ret = wc_AesXtsDecryptSector(aes, buf, c1, sizeof(c1), s1); @@ -10150,12 +10154,10 @@ static wc_test_ret_t aes_xts_sector_test(void) ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); if (XMEMCMP(p1, buf, AES_BLOCK_SIZE)) ERROR_OUT(WC_TEST_RET_ENC_NC, out); - wc_AesXtsFree(aes); /* 256 bit key tests */ XMEMSET(buf, 0, sizeof(buf)); - ret = wc_AesXtsSetKey(aes, k2, sizeof(k2), AES_ENCRYPTION, - HEAP_HINT, devId); + ret = wc_AesXtsSetKey_NoInit(aes, k2, sizeof(k2), AES_ENCRYPTION); if (ret != 0) ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); ret = wc_AesXtsEncryptSector(aes, buf, p2, sizeof(p2), s2); @@ -10166,12 +10168,10 @@ static wc_test_ret_t aes_xts_sector_test(void) ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); if (XMEMCMP(c2, buf, sizeof(c2))) ERROR_OUT(WC_TEST_RET_ENC_NC, out); - wc_AesXtsFree(aes); /* decrypt test */ XMEMSET(buf, 0, sizeof(buf)); - ret = wc_AesXtsSetKey(aes, k2, sizeof(k2), AES_DECRYPTION, - HEAP_HINT, devId); + ret = wc_AesXtsSetKey_NoInit(aes, k2, sizeof(k2), AES_DECRYPTION); if (ret != 0) ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); ret = wc_AesXtsDecryptSector(aes, buf, c2, sizeof(c2), s2); @@ -10182,14 +10182,12 @@ static wc_test_ret_t aes_xts_sector_test(void) ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); if (XMEMCMP(p2, buf, sizeof(p2))) ERROR_OUT(WC_TEST_RET_ENC_NC, out); - wc_AesXtsFree(aes); #if !defined(BENCH_EMBEDDED) && \ (!defined(HAVE_FIPS) || FIPS_VERSION_GE(5, 3)) && !defined(HAVE_SELFTEST) /* encrypt consecutive sectors test */ XMEMSET(data, 0, sizeof(buf)); - ret = wc_AesXtsSetKey(aes, k3, sizeof(k3), AES_ENCRYPTION, - HEAP_HINT, devId); + ret = wc_AesXtsSetKey_NoInit(aes, k3, sizeof(k3), AES_ENCRYPTION); if (ret != 0) ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); ret = wc_AesXtsEncryptConsecutiveSectors(aes, data, p3, @@ -10201,12 +10199,10 @@ static wc_test_ret_t aes_xts_sector_test(void) ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); if (XMEMCMP(c3, data, sizeof(c3))) ERROR_OUT(WC_TEST_RET_ENC_NC, out); - wc_AesXtsFree(aes); /* decrypt consecutive sectors test */ XMEMSET(data, 0, sizeof(buf)); - ret = wc_AesXtsSetKey(aes, k3, sizeof(k3), AES_DECRYPTION, - HEAP_HINT, devId); + ret = wc_AesXtsSetKey_NoInit(aes, k3, sizeof(k3), AES_DECRYPTION); if (ret != 0) ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); ret = wc_AesXtsDecryptConsecutiveSectors(aes, data, c3, @@ -10218,7 +10214,6 @@ static wc_test_ret_t aes_xts_sector_test(void) ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); if (XMEMCMP(p3, data, sizeof(p3))) ERROR_OUT(WC_TEST_RET_ENC_NC, out); - wc_AesXtsFree(aes); #endif /* !BENCH_EMBEDDED && (!HAVE_FIPS || FIPS_VERSION_GE(5, 3)) */ @@ -10274,20 +10269,22 @@ static wc_test_ret_t aes_xts_args_test(void) ERROR_OUT(WC_TEST_RET_ENC_ERRNO, out); #endif - if (wc_AesXtsSetKey(NULL, k1, sizeof(k1), AES_ENCRYPTION, - HEAP_HINT, devId) == 0) - ERROR_OUT(WC_TEST_RET_ENC_NC, out); - if (wc_AesXtsSetKey(aes, NULL, sizeof(k1), AES_ENCRYPTION, - HEAP_HINT, devId) == 0) - ERROR_OUT(WC_TEST_RET_ENC_NC, out); - - /* encryption operations */ - ret = wc_AesXtsSetKey(aes, k1, sizeof(k1), AES_ENCRYPTION, - HEAP_HINT, devId); + ret = wc_AesXtsInit(aes, HEAP_HINT, devId); if (ret != 0) ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); else aes_inited = 1; + + if (wc_AesXtsSetKey_NoInit(NULL, k1, sizeof(k1), AES_ENCRYPTION) == 0) + ERROR_OUT(WC_TEST_RET_ENC_NC, out); + if (wc_AesXtsSetKey_NoInit(aes, NULL, sizeof(k1), AES_ENCRYPTION) == 0) + ERROR_OUT(WC_TEST_RET_ENC_NC, out); + + /* encryption operations */ + ret = wc_AesXtsSetKey_NoInit(aes, k1, sizeof(k1), AES_ENCRYPTION); + if (ret != 0) + ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); + ret = wc_AesXtsEncryptSector(NULL, buf, p1, sizeof(p1), s1); #if defined(WOLFSSL_ASYNC_CRYPT) ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE); @@ -10301,11 +10298,9 @@ static wc_test_ret_t aes_xts_args_test(void) #endif if (ret == 0) ERROR_OUT(WC_TEST_RET_ENC_NC, out); - wc_AesXtsFree(aes); /* decryption operations */ - ret = wc_AesXtsSetKey(aes, k1, sizeof(k1), AES_DECRYPTION, - HEAP_HINT, devId); + ret = wc_AesXtsSetKey_NoInit(aes, k1, sizeof(k1), AES_DECRYPTION); if (ret != 0) ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); ret = wc_AesXtsDecryptSector(NULL, buf, c1, sizeof(c1), s1); @@ -20605,10 +20600,7 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t dsa_test(void) wc_Sha sha; byte hash[WC_SHA_DIGEST_SIZE]; byte signature[40]; -#if (defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_NO_MALLOC)) || \ - defined(WOLFSSL_KEY_GEN) int key_inited = 0; -#endif #ifdef WOLFSSL_KEY_GEN byte* der = 0; int derIn_inited = 0; @@ -20671,10 +20663,7 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t dsa_test(void) ret = wc_InitDsaKey(key); if (ret != 0) ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); -#if (defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_NO_MALLOC)) || \ - defined(WOLFSSL_KEY_GEN) key_inited = 1; -#endif ret = wc_DsaPrivateKeyDecode(tmp, &idx, key, bytes); if (ret != 0) @@ -20700,18 +20689,12 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t dsa_test(void) ERROR_OUT(WC_TEST_RET_ENC_NC, out); wc_FreeDsaKey(key); -#if (defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_NO_MALLOC)) || \ - defined(WOLFSSL_KEY_GEN) key_inited = 0; -#endif ret = wc_InitDsaKey_h(key, NULL); if (ret != 0) ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); -#if (defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_NO_MALLOC)) || \ - defined(WOLFSSL_KEY_GEN) key_inited = 1; -#endif #ifdef WOLFSSL_KEY_GEN { @@ -20785,9 +20768,9 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t dsa_test(void) #else /* !WOLFSSL_SMALL_STACK || WOLFSSL_NO_MALLOC */ -#ifdef WOLFSSL_KEY_GEN if (key_inited) wc_FreeDsaKey(key); +#ifdef WOLFSSL_KEY_GEN if (derIn_inited) wc_FreeDsaKey(derIn); if (genKey_inited) @@ -21068,6 +21051,8 @@ static wc_test_ret_t openssl_aes_test(void) if (total != 32) return 3408; + EVP_CIPHER_CTX_cleanup(en); + total = 0; EVP_CIPHER_CTX_init(de); if (EVP_CipherInit(de, EVP_aes_128_cbc(), @@ -21105,6 +21090,8 @@ static wc_test_ret_t openssl_aes_test(void) if (XMEMCMP(plain, cbcPlain, 18)) return WC_TEST_RET_ENC_NC; + EVP_CIPHER_CTX_cleanup(de); + /* test with encrypting/decrypting more than 16 bytes at once */ total = 0; EVP_CIPHER_CTX_init(en); @@ -21133,6 +21120,8 @@ static wc_test_ret_t openssl_aes_test(void) if (total != 32) return WC_TEST_RET_ENC_NC; + EVP_CIPHER_CTX_cleanup(en); + total = 0; EVP_CIPHER_CTX_init(de); if (EVP_CipherInit(de, EVP_aes_128_cbc(), @@ -21179,6 +21168,8 @@ static wc_test_ret_t openssl_aes_test(void) plain[i] = i; } + EVP_CIPHER_CTX_cleanup(de); + total = 0; EVP_CIPHER_CTX_init(en); if (EVP_CipherInit(en, EVP_aes_128_cbc(), @@ -21199,6 +21190,8 @@ static wc_test_ret_t openssl_aes_test(void) if (total != sizeof(plain)) return WC_TEST_RET_ENC_NC; + EVP_CIPHER_CTX_cleanup(en); + total = 0; EVP_CIPHER_CTX_init(de); if (EVP_CipherInit(de, EVP_aes_128_cbc(), @@ -21234,6 +21227,8 @@ static wc_test_ret_t openssl_aes_test(void) } } + EVP_CIPHER_CTX_cleanup(de); + #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_NO_MALLOC) wolfSSL_EVP_CIPHER_CTX_free(en); wolfSSL_EVP_CIPHER_CTX_free(de); @@ -21297,6 +21292,8 @@ static wc_test_ret_t openssl_aes_test(void) if (EVP_CipherFinal(en, (byte*)&cipher[total], &outlen) != 0) return WC_TEST_RET_ENC_NC; + EVP_CIPHER_CTX_cleanup(en); + /* turn padding back on and do successful encrypt */ total = 0; EVP_CIPHER_CTX_init(en); @@ -21319,6 +21316,8 @@ static wc_test_ret_t openssl_aes_test(void) return WC_TEST_RET_ENC_NC; XMEMCPY(cipher, padded, EVP_TEST_BUF_SZ); + EVP_CIPHER_CTX_cleanup(en); + /* test out of bounds read on buffers w/o padding during decryption */ total = 0; EVP_CIPHER_CTX_init(de); @@ -21339,6 +21338,8 @@ static wc_test_ret_t openssl_aes_test(void) if (EVP_CipherFinal(de, (byte*)&plain[total], &outlen) != 0) return WC_TEST_RET_ENC_NC; + EVP_CIPHER_CTX_cleanup(de); + total = 0; EVP_CIPHER_CTX_init(de); if (EVP_CipherInit(de, EVP_aes_128_cbc(), @@ -21358,6 +21359,8 @@ static wc_test_ret_t openssl_aes_test(void) if (XMEMCMP(padded, cbcPlain, EVP_TEST_BUF_SZ)) return WC_TEST_RET_ENC_NC; + EVP_CIPHER_CTX_cleanup(de); + #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_NO_MALLOC) wolfSSL_EVP_CIPHER_CTX_free(en); wolfSSL_EVP_CIPHER_CTX_free(de); @@ -21406,6 +21409,8 @@ static wc_test_ret_t openssl_aes_test(void) if (XMEMCMP(cipher, verify, AES_BLOCK_SIZE)) return WC_TEST_RET_ENC_NC; + EVP_CIPHER_CTX_cleanup(ctx); + EVP_CIPHER_CTX_init(ctx); if (EVP_CipherInit(ctx, EVP_aes_128_cbc(), key, iv, 0) == 0) return WC_TEST_RET_ENC_NC; @@ -21416,6 +21421,8 @@ static wc_test_ret_t openssl_aes_test(void) if (XMEMCMP(plain, msg, AES_BLOCK_SIZE)) return WC_TEST_RET_ENC_NC; + EVP_CIPHER_CTX_cleanup(ctx); + #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_NO_MALLOC) wolfSSL_EVP_CIPHER_CTX_free(ctx); #endif @@ -21423,6 +21430,8 @@ static wc_test_ret_t openssl_aes_test(void) #endif /* WOLFSSL_AES_128 */ #endif /* HAVE_AES_CBC */ +#ifndef WOLFSSL_NO_OPENSSL_AES_LOW_LEVEL_API + #if defined(HAVE_AES_ECB) && defined(WOLFSSL_AES_256) { /* evp_cipher test: EVP_aes_256_ecb*/ #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_NO_MALLOC) @@ -21556,6 +21565,8 @@ static wc_test_ret_t openssl_aes_test(void) } #endif /* WOLFSSL_AES_DIRECT && WOLFSSL_AES_256 */ +#endif /* !WOLFSSL_NO_OPENSSL_AES_LOW_LEVEL_API */ + /* EVP_Cipher with EVP_aes_xxx_ctr() */ #ifdef WOLFSSL_AES_COUNTER { @@ -21703,6 +21714,11 @@ static wc_test_ret_t openssl_aes_test(void) AES_BLOCK_SIZE*4) != AES_BLOCK_SIZE*4) return WC_TEST_RET_ENC_NC; + if (wolfSSL_EVP_CIPHER_CTX_cleanup(en) != WOLFSSL_SUCCESS) + return WC_TEST_RET_ENC_NC; + if (wolfSSL_EVP_CIPHER_CTX_cleanup(de) != WOLFSSL_SUCCESS) + return WC_TEST_RET_ENC_NC; + if (XMEMCMP(cipherBuff, ctrCipher, AES_BLOCK_SIZE*4)) return WC_TEST_RET_ENC_NC; if (XMEMCMP(plainBuff, ctrPlain, AES_BLOCK_SIZE*4)) @@ -21730,6 +21746,11 @@ static wc_test_ret_t openssl_aes_test(void) AES_BLOCK_SIZE*4) != AES_BLOCK_SIZE*4) return WC_TEST_RET_ENC_NC; + if (wolfSSL_EVP_CIPHER_CTX_cleanup(en) != WOLFSSL_SUCCESS) + return WC_TEST_RET_ENC_NC; + if (wolfSSL_EVP_CIPHER_CTX_cleanup(de) != WOLFSSL_SUCCESS) + return WC_TEST_RET_ENC_NC; + wolfSSL_EVP_CIPHER_CTX_free(p_en); wolfSSL_EVP_CIPHER_CTX_free(p_de); #endif /* WOLFSSL_SMALL_STACK && !WOLFSSL_NO_MALLOC */ @@ -21768,6 +21789,11 @@ static wc_test_ret_t openssl_aes_test(void) return WC_TEST_RET_ENC_NC; if (XMEMCMP(cipherBuff, oddCipher, 9)) return WC_TEST_RET_ENC_NC; + + if (wolfSSL_EVP_CIPHER_CTX_cleanup(en) != WOLFSSL_SUCCESS) + return WC_TEST_RET_ENC_NC; + if (wolfSSL_EVP_CIPHER_CTX_cleanup(de) != WOLFSSL_SUCCESS) + return WC_TEST_RET_ENC_NC; #endif /* WOLFSSL_AES_128 */ #ifdef WOLFSSL_AES_192 @@ -21792,6 +21818,11 @@ static wc_test_ret_t openssl_aes_test(void) return WC_TEST_RET_ENC_NC; if (XMEMCMP(ctr192Cipher, cipherBuff, sizeof(ctr192Cipher))) return WC_TEST_RET_ENC_NC; + + if (wolfSSL_EVP_CIPHER_CTX_cleanup(en) != WOLFSSL_SUCCESS) + return WC_TEST_RET_ENC_NC; + if (wolfSSL_EVP_CIPHER_CTX_cleanup(de) != WOLFSSL_SUCCESS) + return WC_TEST_RET_ENC_NC; #endif /* WOLFSSL_AES_192 */ #ifdef WOLFSSL_AES_256 @@ -21817,6 +21848,11 @@ static wc_test_ret_t openssl_aes_test(void) if (XMEMCMP(ctr256Cipher, cipherBuff, sizeof(ctr256Cipher))) return WC_TEST_RET_ENC_NC; + if (wolfSSL_EVP_CIPHER_CTX_cleanup(en) != WOLFSSL_SUCCESS) + return WC_TEST_RET_ENC_NC; + if (wolfSSL_EVP_CIPHER_CTX_cleanup(de) != WOLFSSL_SUCCESS) + return WC_TEST_RET_ENC_NC; + #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_NO_MALLOC) wolfSSL_EVP_CIPHER_CTX_free(en); wolfSSL_EVP_CIPHER_CTX_free(de); @@ -21826,6 +21862,8 @@ static wc_test_ret_t openssl_aes_test(void) } #endif /* HAVE_AES_COUNTER */ +#ifndef WOLFSSL_NO_OPENSSL_AES_LOW_LEVEL_API + #if defined(WOLFSSL_AES_CFB) && defined(WOLFSSL_AES_128) { #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_NO_MALLOC) @@ -21901,6 +21939,9 @@ static wc_test_ret_t openssl_aes_test(void) #endif } #endif /* WOLFSSL_AES_CFB && WOLFSSL_AES_128 */ + +#endif /* !WOLFSSL_NO_OPENSSL_AES_LOW_LEVEL_API */ + return 0; } @@ -22460,6 +22501,8 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t openssl_test(void) } /* end evp_cipher test */ #endif /* HAVE_AES_ECB && WOLFSSL_AES_128 */ +#ifndef WOLFSSL_NO_OPENSSL_AES_LOW_LEVEL_API + #if defined(WOLFSSL_AES_DIRECT) && defined(WOLFSSL_AES_256) /* enable HAVE_AES_DECRYPT for AES_encrypt/decrypt */ { @@ -22535,6 +22578,8 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t openssl_test(void) #endif /* WOLFSSL_AES_DIRECT && WOLFSSL_AES_256 */ +#endif /* !WOLFSSL_NO_OPENSSL_AES_LOW_LEVEL_API */ + /* EVP_Cipher with EVP_aes_xxx_ctr() */ #ifdef WOLFSSL_AES_COUNTER { @@ -22685,6 +22730,9 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t openssl_test(void) if (XMEMCMP(plainBuff, ctrPlain, AES_BLOCK_SIZE*4)) return WC_TEST_RET_ENC_NC; + EVP_CIPHER_CTX_cleanup(en); + EVP_CIPHER_CTX_cleanup(de); + #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_NO_MALLOC) p_en = wolfSSL_EVP_CIPHER_CTX_new(); if (p_en == NULL) @@ -22707,6 +22755,9 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t openssl_test(void) AES_BLOCK_SIZE*4) != AES_BLOCK_SIZE*4) return WC_TEST_RET_ENC_NC; + EVP_CIPHER_CTX_cleanup(p_en); + EVP_CIPHER_CTX_cleanup(p_de); + wolfSSL_EVP_CIPHER_CTX_free(p_en); wolfSSL_EVP_CIPHER_CTX_free(p_de); #endif /* WOLFSSL_SMALL_STACK && !WOLFSSL_NO_MALLOC */ @@ -22745,6 +22796,9 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t openssl_test(void) return WC_TEST_RET_ENC_NC; if (XMEMCMP(cipherBuff, oddCipher, 9)) return WC_TEST_RET_ENC_NC; + + EVP_CIPHER_CTX_cleanup(en); + EVP_CIPHER_CTX_cleanup(de); #endif /* WOLFSSL_AES_128 */ #ifdef WOLFSSL_AES_192 @@ -22769,6 +22823,9 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t openssl_test(void) return WC_TEST_RET_ENC_NC; if (XMEMCMP(ctr192Cipher, cipherBuff, sizeof(ctr192Cipher))) return WC_TEST_RET_ENC_NC; + + EVP_CIPHER_CTX_cleanup(en); + EVP_CIPHER_CTX_cleanup(de); #endif /* WOLFSSL_AES_192 */ #ifdef WOLFSSL_AES_256 @@ -22793,6 +22850,9 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t openssl_test(void) return WC_TEST_RET_ENC_NC; if (XMEMCMP(ctr256Cipher, cipherBuff, sizeof(ctr256Cipher))) return WC_TEST_RET_ENC_NC; + + EVP_CIPHER_CTX_cleanup(en); + EVP_CIPHER_CTX_cleanup(de); #endif /* WOLFSSL_AES_256 */ #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_NO_MALLOC) diff --git a/wolfssl/openssl/aes.h b/wolfssl/openssl/aes.h index caecd8be5..38e71ae5b 100644 --- a/wolfssl/openssl/aes.h +++ b/wolfssl/openssl/aes.h @@ -33,6 +33,14 @@ #ifndef NO_AES #include + +#if !defined(WOLFSSL_NO_OPENSSL_AES_LOW_LEVEL_API) && \ + defined(WC_AESFREE_IS_MANDATORY) +#define WOLFSSL_NO_OPENSSL_AES_LOW_LEVEL_API +#endif + +#ifndef WOLFSSL_NO_OPENSSL_AES_LOW_LEVEL_API + #include /* for size_t */ #ifdef __cplusplus @@ -95,6 +103,8 @@ WOLFSSL_API void wolfSSL_AES_decrypt( } /* extern "C" */ #endif +#endif /* !WOLFSSL_NO_OPENSSL_AES_LOW_LEVEL_API */ + #endif /* NO_AES */ #endif /* WOLFSSL_AES_H_ */ diff --git a/wolfssl/openssl/evp.h b/wolfssl/openssl/evp.h index c047d4095..bdeabf255 100644 --- a/wolfssl/openssl/evp.h +++ b/wolfssl/openssl/evp.h @@ -854,6 +854,7 @@ WOLFSSL_API int wolfSSL_EVP_PKEY_CTX_hkdf_mode(WOLFSSL_EVP_PKEY_CTX* ctx, #define WOLFSSL_EVP_CIPH_FLAG_AEAD_CIPHER 0x20 #define WOLFSSL_EVP_CIPH_NO_PADDING 0x100 #define WOLFSSL_EVP_CIPH_VARIABLE_LENGTH 0x200 +#define WOLFSSL_EVP_CIPH_LOW_LEVEL_INITED 0x400 #define WOLFSSL_EVP_CIPH_TYPE_INIT 0xff diff --git a/wolfssl/test.h b/wolfssl/test.h index 6882cc0b9..5265e87fb 100644 --- a/wolfssl/test.h +++ b/wolfssl/test.h @@ -2669,6 +2669,11 @@ static WC_INLINE int myMacEncryptCb(WOLFSSL* ssl, unsigned char* macOut, iv = wolfSSL_GetServerWriteIV(ssl); } + ret = wc_AesInit(&encCtx->aes, NULL, INVALID_DEVID); + if (ret != 0) { + fprintf(stderr, "AesInit failed in myMacEncryptCb\n"); + return ret; + } ret = wc_AesSetKey(&encCtx->aes, key, keyLen, iv, AES_ENCRYPTION); if (ret != 0) { fprintf(stderr, "AesSetKey failed in myMacEncryptCb\n"); @@ -2725,6 +2730,11 @@ static WC_INLINE int myDecryptVerifyCb(WOLFSSL* ssl, iv = wolfSSL_GetServerWriteIV(ssl); } + ret = wc_AesInit(&decCtx->aes, NULL, INVALID_DEVID); + if (ret != 0) { + fprintf(stderr, "AesInit failed in myDecryptVerifyCb\n"); + return ret; + } ret = wc_AesSetKey(&decCtx->aes, key, keyLen, iv, AES_DECRYPTION); if (ret != 0) { fprintf(stderr, "AesSetKey failed in myDecryptVerifyCb\n"); @@ -2819,6 +2829,11 @@ static WC_INLINE int myEncryptMacCb(WOLFSSL* ssl, unsigned char* macOut, iv = wolfSSL_GetServerWriteIV(ssl); } + ret = wc_AesInit(&encCtx->aes, NULL, INVALID_DEVID); + if (ret != 0) { + fprintf(stderr, "AesInit failed in myMacEncryptCb\n"); + return ret; + } ret = wc_AesSetKey(&encCtx->aes, key, keyLen, iv, AES_ENCRYPTION); if (ret != 0) { fprintf(stderr, "AesSetKey failed in myMacEncryptCb\n"); @@ -2917,6 +2932,11 @@ static WC_INLINE int myVerifyDecryptCb(WOLFSSL* ssl, iv = wolfSSL_GetServerWriteIV(ssl); } + ret = wc_AesInit(&decCtx->aes, NULL, INVALID_DEVID); + if (ret != 0) { + fprintf(stderr, "AesInit failed in myDecryptVerifyCb\n"); + return ret; + } ret = wc_AesSetKey(&decCtx->aes, key, keyLen, iv, AES_DECRYPTION); if (ret != 0) { fprintf(stderr, "AesSetKey failed in myDecryptVerifyCb\n"); diff --git a/wolfssl/wolfcrypt/aes.h b/wolfssl/wolfcrypt/aes.h index 4c5e35865..5e6e6b395 100644 --- a/wolfssl/wolfcrypt/aes.h +++ b/wolfssl/wolfcrypt/aes.h @@ -380,6 +380,11 @@ struct Aes { byte nonceSet:1; byte ctrSet:1; #endif +#ifdef WC_DEBUG_CIPHER_LIFECYCLE + void *CipherLifecycleTag; /* used for dummy allocation and initialization, + * trackable by sanitizers. + */ +#endif }; #ifndef WC_AES_TYPE_DEFINED @@ -394,6 +399,27 @@ typedef struct XtsAes { } XtsAes; #endif +#if (!defined(WC_AESFREE_IS_MANDATORY)) && \ + (defined(WC_DEBUG_CIPHER_LIFECYCLE) || \ + (defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_AES)) || \ + defined(WOLFSSL_AFALG) || defined(WOLFSSL_AFALG_XILINX_AES) || \ + defined(WOLFSSL_KCAPI_AES) || \ + (defined(WOLFSSL_DEVCRYPTO) && \ + (defined(WOLFSSL_DEVCRYPTO_AES) || \ + defined(WOLFSSL_DEVCRYPTO_CBC))) || \ + defined(WOLF_CRYPTO_CB) || \ + defined(WOLFSSL_IMXRT_DCP) || \ + (defined(WOLFSSL_AESGCM_STREAM) && defined(WOLFSSL_SMALL_STACK) && \ + !defined(WOLFSSL_AESNI)) || \ + (defined(WOLFSSL_SE050) && defined(WOLFSSL_SE050_CRYPT)) || \ + (defined(WOLFSSL_HAVE_PSA) && !defined(WOLFSSL_PSA_NO_AES)) || \ + defined(WOLFSSL_MAXQ10XX_CRYPTO) || \ + ((defined(WOLFSSL_RENESAS_FSPSM_TLS) || \ + defined(WOLFSSL_RENESAS_FSPSM_CRYPTONLY)) && \ + !defined(NO_WOLFSSL_RENESAS_FSPSM_AES))) +#define WC_AESFREE_IS_MANDATORY +#endif + #ifdef HAVE_AESGCM typedef struct Gmac { Aes aes; @@ -595,6 +621,11 @@ WOLFSSL_API int wc_AesGcmDecryptFinal(Aes* aes, const byte* authTag, #ifdef WOLFSSL_AES_XTS +WOLFSSL_API int wc_AesXtsInit(XtsAes* aes, void* heap, int devId); + +WOLFSSL_API int wc_AesXtsSetKey_NoInit(XtsAes* aes, const byte* key, + word32 len, int dir); + WOLFSSL_API int wc_AesXtsSetKey(XtsAes* aes, const byte* key, word32 len, int dir, void* heap, int devId); diff --git a/wolfssl/wolfcrypt/memory.h b/wolfssl/wolfcrypt/memory.h index bd72ccb66..cf8327316 100644 --- a/wolfssl/wolfcrypt/memory.h +++ b/wolfssl/wolfcrypt/memory.h @@ -251,6 +251,22 @@ WOLFSSL_LOCAL void wc_MemZero_Add(const char* name, const void* addr, WOLFSSL_LOCAL void wc_MemZero_Check(void* addr, size_t len); #endif +#ifdef WC_DEBUG_CIPHER_LIFECYCLE +WOLFSSL_LOCAL int wc_debug_CipherLifecycleInit(void **CipherLifecycleTag, + void *heap); +WOLFSSL_LOCAL int wc_debug_CipherLifecycleCheck(void *CipherLifecycleTag, + int abort_p); +WOLFSSL_LOCAL int wc_debug_CipherLifecycleFree(void **CipherLifecycleTag, + void *heap, int abort_p); +#else +#define wc_debug_CipherLifecycleInit(CipherLifecycleTag, heap) \ + ((void)(CipherLifecycleTag), (void)(heap), 0) +#define wc_debug_CipherLifecycleCheck(CipherLifecycleTag, abort_p) \ + ((void)(CipherLifecycleTag), (void)(abort_p), 0) +#define wc_debug_CipherLifecycleFree(CipherLifecycleTag, heap, abort_p) \ + ((void)(CipherLifecycleTag), (void)(heap), (void)(abort_p), 0) +#endif + #ifdef DEBUG_VECTOR_REGISTER_ACCESS WOLFSSL_API extern THREAD_LS_T int wc_svr_count; WOLFSSL_API extern THREAD_LS_T const char *wc_svr_last_file; diff --git a/wolfssl/wolfcrypt/types.h b/wolfssl/wolfcrypt/types.h index bc1f63012..0d41354ea 100644 --- a/wolfssl/wolfcrypt/types.h +++ b/wolfssl/wolfcrypt/types.h @@ -1014,6 +1014,7 @@ typedef struct w64wrapper { DYNAMIC_TYPE_DILITHIUM = 97, DYNAMIC_TYPE_SPHINCS = 98, DYNAMIC_TYPE_SM4_BUFFER = 99, + DYNAMIC_TYPE_DEBUG_TAG = 100, DYNAMIC_TYPE_SNIFFER_SERVER = 1000, DYNAMIC_TYPE_SNIFFER_SESSION = 1001, DYNAMIC_TYPE_SNIFFER_PB = 1002, From b14aba48afa2ba813157b92bd77cff7997587968 Mon Sep 17 00:00:00 2001 From: Daniel Pouzzner Date: Wed, 6 Dec 2023 16:55:57 -0600 Subject: [PATCH 2/5] wolfcrypt/src/cmac.c: add wc_CmacFree(), revert wc_CmacFinal(), rename wc_CmacFinal() as wc_CmacFinalNoFree() removing its deallocation clauses, and add new wc_CmacFinal() that calls wc_CmacFinalNoFree() then calls wc_CmacFree() unconditionally, for compatibility with legacy client code (some of which may have previously leaked). tests/api.c: modify test_wc_CmacFinal() to use wc_CmacFinalNoFree() except for the final call. wolfcrypt/src/aes.c: * fix wc_AesEaxEncryptAuth() and wc_AesEaxDecryptAuth() to call wc_AesEaxFree() only if wc_AesEaxInit() succeeded. * fix wc_AesEaxInit() to free all resources on failure. * revert wc_AesEaxEncryptFinal() and wc_AesEaxDecryptFinal() changes, then change wc_CmacFinal() calls in them to wc_CmacFinalNoFree() calls. * wc_AesEaxFree(): add wc_CmacFree() calls. --- src/ssl_crypto.c | 2 +- tests/api.c | 8 ++- wolfcrypt/src/aes.c | 133 ++++++++++++++++++--------------------- wolfcrypt/src/cmac.c | 58 ++++++++--------- wolfssl/wolfcrypt/cmac.h | 6 ++ 5 files changed, 104 insertions(+), 103 deletions(-) diff --git a/src/ssl_crypto.c b/src/ssl_crypto.c index 7b8c0360a..0523ad952 100644 --- a/src/ssl_crypto.c +++ b/src/ssl_crypto.c @@ -2106,7 +2106,7 @@ void wolfSSL_CMAC_CTX_free(WOLFSSL_CMAC_CTX *ctx) if (ctx != NULL) { /* Deallocate dynamically allocated fields. */ if (ctx->internal != NULL) { - wc_CmacFinal((Cmac*)ctx->internal, NULL, NULL); + wc_CmacFree((Cmac*)ctx->internal); XFREE(ctx->internal, NULL, DYNAMIC_TYPE_CMAC); } if (ctx->cctx != NULL) { diff --git a/tests/api.c b/tests/api.c index f065ea4af..6af145a80 100644 --- a/tests/api.c +++ b/tests/api.c @@ -15795,12 +15795,14 @@ static int test_wc_CmacFinal(void) ExpectIntEQ(wc_InitCmac(&cmac, key, keySz, type, NULL), 0); ExpectIntEQ(wc_CmacUpdate(&cmac, msg, msgSz), 0); - ExpectIntEQ(wc_CmacFinal(&cmac, mac, &macSz), 0); + ExpectIntEQ(wc_CmacFinalNoFree(&cmac, mac, &macSz), 0); ExpectIntEQ(XMEMCMP(mac, expMac, expMacSz), 0); /* Pass in bad args. */ - ExpectIntEQ(wc_CmacFinal(NULL, mac, &macSz), BAD_FUNC_ARG); - ExpectIntEQ(wc_CmacFinal(&cmac, NULL, &macSz), BAD_FUNC_ARG); + ExpectIntEQ(wc_CmacFinalNoFree(NULL, mac, &macSz), BAD_FUNC_ARG); + ExpectIntEQ(wc_CmacFinalNoFree(&cmac, NULL, &macSz), BAD_FUNC_ARG); + + /* For the last call, use the API with implicit wc_CmacFree(). */ ExpectIntEQ(wc_CmacFinal(&cmac, mac, &badMacSz), BUFFER_E); #endif return EXPECT_RESULT(); diff --git a/wolfcrypt/src/aes.c b/wolfcrypt/src/aes.c index b677804fb..64497dc1c 100644 --- a/wolfcrypt/src/aes.c +++ b/wolfcrypt/src/aes.c @@ -13266,6 +13266,7 @@ int wc_AesEaxEncryptAuth(const byte* key, word32 keySz, byte* out, AesEax *eax = &eax_mem; #endif int ret; + int eaxInited = 0; if (key == NULL || out == NULL || in == NULL || nonce == NULL || authTag == NULL || authIn == NULL) { @@ -13286,6 +13287,7 @@ int wc_AesEaxEncryptAuth(const byte* key, word32 keySz, byte* out, authIn, authInSz)) != 0) { goto cleanup; } + eaxInited = 1; if ((ret = wc_AesEaxEncryptUpdate(eax, out, in, inSz, NULL, 0)) != 0) { goto cleanup; @@ -13296,7 +13298,8 @@ int wc_AesEaxEncryptAuth(const byte* key, word32 keySz, byte* out, } cleanup: - wc_AesEaxFree(eax); + if (eaxInited) + wc_AesEaxFree(eax); #if defined(WOLFSSL_SMALL_STACK) XFREE(eax, NULL, DYNAMIC_TYPE_AES_EAX); #endif @@ -13326,6 +13329,7 @@ int wc_AesEaxDecryptAuth(const byte* key, word32 keySz, byte* out, AesEax *eax = &eax_mem; #endif int ret; + int eaxInited = 0; if (key == NULL || out == NULL || in == NULL || nonce == NULL || authTag == NULL || authIn == NULL) { @@ -13347,6 +13351,7 @@ int wc_AesEaxDecryptAuth(const byte* key, word32 keySz, byte* out, goto cleanup; } + eaxInited = 1; if ((ret = wc_AesEaxDecryptUpdate(eax, out, in, inSz, NULL, 0)) != 0) { goto cleanup; @@ -13357,7 +13362,8 @@ int wc_AesEaxDecryptAuth(const byte* key, word32 keySz, byte* out, } cleanup: - wc_AesEaxFree(eax); + if (eaxInited) + wc_AesEaxFree(eax); #if defined(WOLFSSL_SMALL_STACK) XFREE(eax, NULL, DYNAMIC_TYPE_AES_EAX); #endif @@ -13380,6 +13386,9 @@ int wc_AesEaxInit(AesEax* eax, { int ret = 0; word32 cmacSize; + int aesInited = 0; + int nonceCmacInited = 0; + int aadCmacInited = 0; if (eax == NULL || key == NULL || nonce == NULL) { return BAD_FUNC_ARG; @@ -13388,14 +13397,16 @@ int wc_AesEaxInit(AesEax* eax, XMEMSET(eax->prefixBuf, 0, sizeof(eax->prefixBuf)); if ((ret = wc_AesInit(&eax->aes, NULL, INVALID_DEVID)) != 0) { - return ret; + goto out; } + aesInited = 1; + if ((ret = wc_AesSetKey(&eax->aes, key, keySz, NULL, AES_ENCRYPTION)) != 0) { - return ret; + goto out; } /* @@ -13409,26 +13420,27 @@ int wc_AesEaxInit(AesEax* eax, NULL)) != 0) { return ret; } + nonceCmacInited = 1; if ((ret = wc_CmacUpdate(&eax->nonceCmac, eax->prefixBuf, sizeof(eax->prefixBuf))) != 0) { - return ret; + goto out; } if ((ret = wc_CmacUpdate(&eax->nonceCmac, nonce, nonceSz)) != 0) { - return ret; + goto out; } cmacSize = AES_BLOCK_SIZE; if ((ret = wc_CmacFinal(&eax->nonceCmac, eax->nonceCmacFinal, &cmacSize)) != 0) { - return ret; + goto out; } if ((ret = wc_AesSetIV(&eax->aes, eax->nonceCmacFinal)) != 0) { - return ret; + goto out; } /* @@ -13443,18 +13455,19 @@ int wc_AesEaxInit(AesEax* eax, keySz, WC_CMAC_AES, NULL)) != 0) { - return ret; + goto out; } + aadCmacInited = 1; if ((ret = wc_CmacUpdate(&eax->aadCmac, eax->prefixBuf, sizeof(eax->prefixBuf))) != 0) { - return ret; + goto out; } if (authIn != NULL) { if ((ret = wc_CmacUpdate(&eax->aadCmac, authIn, authInSz)) != 0) { - return ret; + goto out; } } @@ -13469,13 +13482,24 @@ int wc_AesEaxInit(AesEax* eax, keySz, WC_CMAC_AES, NULL)) != 0) { - return ret; + goto out; } if ((ret = wc_CmacUpdate(&eax->ciphertextCmac, eax->prefixBuf, sizeof(eax->prefixBuf))) != 0) { - return ret; + goto out; + } + +out: + + if (ret != 0) { + if (aesInited) + wc_AesFree(&eax->aes); + if (nonceCmacInited) + wc_CmacFree(&eax->nonceCmac); + if (aadCmacInited) + wc_CmacFree(&eax->aadCmac); } return ret; @@ -13599,34 +13623,25 @@ int wc_AesEaxEncryptFinal(AesEax* eax, byte* authTag, word32 authTagSz) word32 cmacSize; int ret; word32 i; - int ciphertextCmac_finalized = 0; - int aadCmac_finalized = 0; - if (eax == NULL) { + if (eax == NULL || authTag == NULL || authTagSz > AES_BLOCK_SIZE) { return BAD_FUNC_ARG; } - if (authTag == NULL || authTagSz > AES_BLOCK_SIZE) { - ret = BAD_FUNC_ARG; - goto out; - } - /* Complete the OMAC for the ciphertext */ cmacSize = AES_BLOCK_SIZE; - ciphertextCmac_finalized = 1; - if ((ret = wc_CmacFinal(&eax->ciphertextCmac, - eax->ciphertextCmacFinal, - &cmacSize)) != 0) { - goto out; + if ((ret = wc_CmacFinalNoFree(&eax->ciphertextCmac, + eax->ciphertextCmacFinal, + &cmacSize)) != 0) { + return ret; } /* Complete the OMAC for auth data */ cmacSize = AES_BLOCK_SIZE; - aadCmac_finalized = 1; - if ((ret = wc_CmacFinal(&eax->aadCmac, - eax->aadCmacFinal, - &cmacSize)) != 0) { - goto out; + if ((ret = wc_CmacFinalNoFree(&eax->aadCmac, + eax->aadCmacFinal, + &cmacSize)) != 0) { + return ret; } /* @@ -13640,16 +13655,7 @@ int wc_AesEaxEncryptFinal(AesEax* eax, byte* authTag, word32 authTagSz) ^ eax->ciphertextCmacFinal[i]; } - ret = 0; - -out: - - if (! ciphertextCmac_finalized) - (void)wc_CmacFinal(&eax->ciphertextCmac, NULL, NULL); - if (! aadCmac_finalized) - (void)wc_CmacFinal(&eax->aadCmac, NULL, NULL); - - return ret; + return 0; } @@ -13668,47 +13674,37 @@ int wc_AesEaxDecryptFinal(AesEax* eax, int ret; word32 i; word32 cmacSize; - int ciphertextCmac_finalized = 0; - int aadCmac_finalized = 0; #if defined(WOLFSSL_SMALL_STACK) - byte *authTag = NULL; + byte *authTag; #else byte authTag[AES_BLOCK_SIZE]; #endif - if (eax == NULL) { + if (eax == NULL || authIn == NULL || authInSz > AES_BLOCK_SIZE) { return BAD_FUNC_ARG; } - if (authIn == NULL || authInSz > AES_BLOCK_SIZE) { - ret = BAD_FUNC_ARG; - goto out; - } - /* Complete the OMAC for the ciphertext */ cmacSize = AES_BLOCK_SIZE; - ciphertextCmac_finalized = 1; - if ((ret = wc_CmacFinal(&eax->ciphertextCmac, - eax->ciphertextCmacFinal, - &cmacSize)) != 0) { - goto out; + if ((ret = wc_CmacFinalNoFree(&eax->ciphertextCmac, + eax->ciphertextCmacFinal, + &cmacSize)) != 0) { + return ret; } /* Complete the OMAC for auth data */ cmacSize = AES_BLOCK_SIZE; - aadCmac_finalized = 1; - if ((ret = wc_CmacFinal(&eax->aadCmac, - eax->aadCmacFinal, - &cmacSize)) != 0) { - goto out; + if ((ret = wc_CmacFinalNoFree(&eax->aadCmac, + eax->aadCmacFinal, + &cmacSize)) != 0) { + return ret; } #if defined(WOLFSSL_SMALL_STACK) authTag = (byte*)XMALLOC(AES_BLOCK_SIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER); if (authTag == NULL) { - ret = MEMORY_E; - goto out; + return MEMORY_E; } #endif @@ -13730,13 +13726,6 @@ int wc_AesEaxDecryptFinal(AesEax* eax, ret = 0; } -out: - - if (! ciphertextCmac_finalized) - (void)wc_CmacFinal(&eax->ciphertextCmac, NULL, NULL); - if (! aadCmac_finalized) - (void)wc_CmacFinal(&eax->aadCmac, NULL, NULL); - #if defined(WOLFSSL_SMALL_STACK) XFREE(authTag, NULL, DYNAMIC_TYPE_TMP_BUFFER); #endif @@ -13745,8 +13734,8 @@ out: } /* - * Frees the underlying AES context. Must be called when done using the AES EAX - * context structure + * Frees the underlying CMAC and AES contexts. Must be called when done using + * the AES EAX context structure. * * Returns 0 on success * Returns error code on failure @@ -13757,6 +13746,8 @@ int wc_AesEaxFree(AesEax* eax) return BAD_FUNC_ARG; } + (void)wc_CmacFree(&eax->ciphertextCmac); + (void)wc_CmacFree(&eax->aadCmac); wc_AesFree(&eax->aes); return 0; diff --git a/wolfcrypt/src/cmac.c b/wolfcrypt/src/cmac.c index de16dc2eb..7cade1903 100644 --- a/wolfcrypt/src/cmac.c +++ b/wolfcrypt/src/cmac.c @@ -223,23 +223,32 @@ int wc_CmacUpdate(Cmac* cmac, const byte* in, word32 inSz) return ret; } +int wc_CmacFree(Cmac* cmac) +{ + if (cmac == NULL) + return BAD_FUNC_ARG; +#if defined(WOLFSSL_HASH_KEEP) + /* TODO: msg is leaked if wc_CmacFinal() is not called + * e.g. when multiple calls to wc_CmacUpdate() and one fails but + * wc_CmacFinal() not called. */ + if (cmac->msg != NULL) { + XFREE(cmac->msg, cmac->heap, DYNAMIC_TYPE_TMP_BUFFER); + } +#endif + wc_AesFree(&cmac->aes); + ForceZero(cmac, sizeof(Cmac)); + return 0; +} -int wc_CmacFinal(Cmac* cmac, byte* out, word32* outSz) +int wc_CmacFinalNoFree(Cmac* cmac, byte* out, word32* outSz) { int ret; const byte* subKey; word32 remainder; - if (cmac == NULL) + if (cmac == NULL || out == NULL || outSz == NULL) { return BAD_FUNC_ARG; - - if (out == NULL || outSz == NULL) { - if ((out == NULL) ^ (outSz == NULL)) - return BAD_FUNC_ARG; - ret = 0; - goto out; } - if (*outSz < WC_CMAC_TAG_MIN_SZ || *outSz > WC_CMAC_TAG_MAX_SZ) { return BUFFER_E; } @@ -251,7 +260,7 @@ int wc_CmacFinal(Cmac* cmac, byte* out, word32* outSz) { ret = wc_CryptoCb_Cmac(cmac, NULL, 0, NULL, 0, out, outSz, 0, NULL); if (ret != CRYPTOCB_UNAVAILABLE) - goto out; + return ret; /* fall-through when unavailable */ } #endif @@ -262,8 +271,7 @@ int wc_CmacFinal(Cmac* cmac, byte* out, word32* outSz) else { /* ensure we will have a valid remainder value */ if (cmac->bufferSz > AES_BLOCK_SIZE) { - ret = BAD_STATE_E; - goto out; + return BAD_STATE_E; } remainder = AES_BLOCK_SIZE - cmac->bufferSz; @@ -284,24 +292,18 @@ int wc_CmacFinal(Cmac* cmac, byte* out, word32* outSz) XMEMCPY(out, cmac->digest, *outSz); } -#if defined(WOLFSSL_HASH_KEEP) - /* TODO: msg is leaked if wc_CmacFinal() is not called - * e.g. when multiple calls to wc_CmacUpdate() and one fails but - * wc_CmacFinal() not called. */ - if (cmac->msg != NULL) { - XFREE(cmac->msg, cmac->heap, DYNAMIC_TYPE_TMP_BUFFER); - cmac->msg = NULL; - } -#endif - -out: - - wc_AesFree(&cmac->aes); - ForceZero(cmac, sizeof(Cmac)); - - return ret; + return 0; } +int wc_CmacFinal(Cmac* cmac, byte* out, word32* outSz) { + int ret; + + if (cmac == NULL) + return BAD_FUNC_ARG; + ret = wc_CmacFinalNoFree(cmac, out, outSz); + (void)wc_CmacFree(cmac); + return ret; +} int wc_AesCmacGenerate(byte* out, word32* outSz, const byte* in, word32 inSz, diff --git a/wolfssl/wolfcrypt/cmac.h b/wolfssl/wolfcrypt/cmac.h index 679952bab..5fbda43cd 100644 --- a/wolfssl/wolfcrypt/cmac.h +++ b/wolfssl/wolfcrypt/cmac.h @@ -98,9 +98,15 @@ WOLFSSL_API int wc_CmacUpdate(Cmac* cmac, const byte* in, word32 inSz); WOLFSSL_API +int wc_CmacFinalNoFree(Cmac* cmac, + byte* out, word32* outSz); +WOLFSSL_API int wc_CmacFinal(Cmac* cmac, byte* out, word32* outSz); +WOLFSSL_API +int wc_CmacFree(Cmac* cmac); + WOLFSSL_API int wc_AesCmacGenerate(byte* out, word32* outSz, const byte* in, word32 inSz, From 931ac4e5686b8981d1440a32d195b5bcb67569f6 Mon Sep 17 00:00:00 2001 From: Daniel Pouzzner Date: Wed, 6 Dec 2023 19:26:46 -0600 Subject: [PATCH 3/5] add documentation for wc_AesXtsInit(), wc_AesXtsSetKeyNoInit(), wc_CmacFinalNoFree(), and wc_CmacFree(); rename wc_AesXtsSetKey_NoInit() to wc_AesXtsSetKeyNoInit() for morphological consistency; refactor wc_AesXtsSetKey() to call wc_AesXtsSetKeyNoInit() and clean up on failure; readability tweak in wolfSSL_EVP_CipherFinal(). --- doc/dox_comments/header_files/aes.h | 88 ++++++++++++++++++++++++++++ doc/dox_comments/header_files/cmac.h | 57 ++++++++++++++++-- wolfcrypt/src/aes.c | 28 ++------- wolfcrypt/src/evp.c | 15 +++-- wolfcrypt/test/test.c | 44 +++++++------- wolfssl/wolfcrypt/aes.h | 2 +- 6 files changed, 176 insertions(+), 58 deletions(-) diff --git a/doc/dox_comments/header_files/aes.h b/doc/dox_comments/header_files/aes.h index 4110a1f92..997bc58c0 100644 --- a/doc/dox_comments/header_files/aes.h +++ b/doc/dox_comments/header_files/aes.h @@ -658,6 +658,82 @@ int wc_AesCcmDecrypt(Aes* aes, byte* out, const byte* authTag, word32 authTagSz, const byte* authIn, word32 authInSz); +/*! + \ingroup AES + + \brief This is to initialize an AES-XTS context. It is up to user to call + wc_AesXtsFree on aes key when done. + + \return 0 Success + + \param aes AES keys for encrypt/decrypt process + \param heap heap hint to use for memory. Can be NULL + \param devId id to use with async crypto. Can be 0 + + _Example_ + \code + XtsAes aes; + + if(wc_AesXtsInit(&aes, NULL, 0) != 0) + { + // Handle error + } + if(wc_AesXtsSetKeyNoInit(&aes, key, sizeof(key), AES_ENCRYPTION) != 0) + { + // Handle error + } + wc_AesXtsFree(&aes); + \endcode + + \sa wc_AesXtsSetKey + \sa wc_AesXtsSetKeyNoInit + \sa wc_AesXtsEncrypt + \sa wc_AesXtsDecrypt + \sa wc_AesXtsFree +*/ +int wc_AesXtsInit(XtsAes* aes, void* heap, int devId); + + +/*! + \ingroup AES + + \brief This is to help with setting keys to correct encrypt or decrypt type, + after first calling wc_AesXtsInit(). It is up to user to call wc_AesXtsFree + on aes key when done. + + \return 0 Success + + \param aes AES keys for encrypt/decrypt process + \param key buffer holding aes key | tweak key + \param len length of key buffer in bytes. Should be twice that of + key size. + i.e. 32 for a 16 byte key. + \param dir direction, either AES_ENCRYPTION or AES_DECRYPTION + + _Example_ + \code + XtsAes aes; + + if(wc_AesXtsInit(&aes, NULL, 0) != 0) + { + // Handle error + } + if(wc_AesXtsSetKeyNoInit(&aes, key, sizeof(key), AES_ENCRYPTION, NULL, 0) + != 0) + { + // Handle error + } + wc_AesXtsFree(&aes); + \endcode + + \sa wc_AesXtsEncrypt + \sa wc_AesXtsDecrypt + \sa wc_AesXtsFree +*/ +int wc_AesXtsSetKeyNoInit(XtsAes* aes, const byte* key, + word32 len, int dir); + + /*! \ingroup AES @@ -686,6 +762,8 @@ int wc_AesCcmDecrypt(Aes* aes, byte* out, wc_AesXtsFree(&aes); \endcode + \sa wc_AesXtsInit + \sa wc_AesXtsSetKeyNoInit \sa wc_AesXtsEncrypt \sa wc_AesXtsDecrypt \sa wc_AesXtsFree @@ -726,6 +804,8 @@ int wc_AesXtsSetKey(XtsAes* aes, const byte* key, \sa wc_AesXtsEncrypt \sa wc_AesXtsDecrypt + \sa wc_AesXtsInit + \sa wc_AesXtsSetKeyNoInit \sa wc_AesXtsSetKey \sa wc_AesXtsFree */ @@ -765,6 +845,8 @@ int wc_AesXtsEncryptSector(XtsAes* aes, byte* out, \sa wc_AesXtsEncrypt \sa wc_AesXtsDecrypt + \sa wc_AesXtsInit + \sa wc_AesXtsSetKeyNoInit \sa wc_AesXtsSetKey \sa wc_AesXtsFree */ @@ -805,6 +887,8 @@ int wc_AesXtsDecryptSector(XtsAes* aes, byte* out, \endcode \sa wc_AesXtsDecrypt + \sa wc_AesXtsInit + \sa wc_AesXtsSetKeyNoInit \sa wc_AesXtsSetKey \sa wc_AesXtsFree */ @@ -844,6 +928,8 @@ int wc_AesXtsEncrypt(XtsAes* aes, byte* out, \endcode \sa wc_AesXtsEncrypt + \sa wc_AesXtsInit + \sa wc_AesXtsSetKeyNoInit \sa wc_AesXtsSetKey \sa wc_AesXtsFree */ @@ -872,6 +958,8 @@ int wc_AesXtsDecrypt(XtsAes* aes, byte* out, \sa wc_AesXtsEncrypt \sa wc_AesXtsDecrypt + \sa wc_AesXtsInit + \sa wc_AesXtsSetKeyNoInit \sa wc_AesXtsSetKey */ int wc_AesXtsFree(XtsAes* aes); diff --git a/doc/dox_comments/header_files/cmac.h b/doc/dox_comments/header_files/cmac.h index 230231345..96d5bc8cc 100644 --- a/doc/dox_comments/header_files/cmac.h +++ b/doc/dox_comments/header_files/cmac.h @@ -23,6 +23,8 @@ \sa wc_InitCmac_ex \sa wc_CmacUpdate \sa wc_CmacFinal + \sa wc_CmacFinalNoFree + \sa wc_CmacFree */ int wc_InitCmac(Cmac* cmac, const byte* key, word32 keySz, @@ -55,6 +57,8 @@ int wc_InitCmac(Cmac* cmac, \sa wc_InitCmac_ex \sa wc_CmacUpdate \sa wc_CmacFinal + \sa wc_CmacFinalNoFree + \sa wc_CmacFree */ int wc_InitCmac_ex(Cmac* cmac, const byte* key, word32 keySz, @@ -75,13 +79,38 @@ int wc_InitCmac_ex(Cmac* cmac, \sa wc_InitCmac \sa wc_CmacFinal + \sa wc_CmacFinalNoFree + \sa wc_CmacFree */ int wc_CmacUpdate(Cmac* cmac, const byte* in, word32 inSz); + /*! \ingroup CMAC - \brief Generate the final result using Cipher-based Message Authentication Code + \brief Generate the final result using Cipher-based Message Authentication Code, deferring context cleanup. + \return 0 on success + \param cmac pointer to the Cmac structure + \param out pointer to return the result + \param outSz pointer size of output (in/out) + + _Example_ + \code + ret = wc_CmacFinalNoFree(cmac, out, &outSz); + (void)wc_CmacFree(cmac); + \endcode + + \sa wc_InitCmac + \sa wc_CmacFinal + \sa wc_CmacFinalNoFree + \sa wc_CmacFree +*/ +int wc_CmacFinalNoFree(Cmac* cmac, + byte* out, word32* outSz); + +/*! + \ingroup CMAC + \brief Generate the final result using Cipher-based Message Authentication Code, and clean up the context with wc_CmacFree(). \return 0 on success \param cmac pointer to the Cmac structure \param out pointer to return the result @@ -93,10 +122,30 @@ int wc_CmacUpdate(Cmac* cmac, \endcode \sa wc_InitCmac - \sa wc_CmacFinal + \sa wc_CmacFinalNoFree + \sa wc_CmacFinalNoFree + \sa wc_CmacFree */ -int wc_CmacFinal(Cmac* cmac, - byte* out, word32* outSz); +int wc_CmacFinalNoFree(Cmac* cmac); + +/*! + \ingroup CMAC + \brief Clean up allocations in a CMAC context. + \return 0 on success + \param cmac pointer to the Cmac structure + + _Example_ + \code + ret = wc_CmacFinalNoFree(cmac, out, &outSz); + (void)wc_CmacFree(cmac); + \endcode + + \sa wc_InitCmac + \sa wc_CmacFinalNoFree + \sa wc_CmacFinal + \sa wc_CmacFree +*/ +int wc_CmacFree(Cmac* cmac); /*! \ingroup CMAC diff --git a/wolfcrypt/src/aes.c b/wolfcrypt/src/aes.c index 64497dc1c..d4e44d735 100644 --- a/wolfcrypt/src/aes.c +++ b/wolfcrypt/src/aes.c @@ -12283,7 +12283,7 @@ int wc_AesXtsInit(XtsAes* aes, void* heap, int devId) * * return 0 on success */ -int wc_AesXtsSetKey_NoInit(XtsAes* aes, const byte* key, word32 len, int dir) +int wc_AesXtsSetKeyNoInit(XtsAes* aes, const byte* key, word32 len, int dir) { word32 keySz; int ret = 0; @@ -12317,7 +12317,7 @@ int wc_AesXtsSetKey_NoInit(XtsAes* aes, const byte* key, word32 len, int dir) return ret; } -/* Combined call to wc_AesXtsInit() and wc_AesXtsSetKey_NoInit(). +/* Combined call to wc_AesXtsInit() and wc_AesXtsSetKeyNoInit(). * * Note: is up to user to call wc_AesXtsFree when done. * @@ -12326,7 +12326,6 @@ int wc_AesXtsSetKey_NoInit(XtsAes* aes, const byte* key, word32 len, int dir) int wc_AesXtsSetKey(XtsAes* aes, const byte* key, word32 len, int dir, void* heap, int devId) { - word32 keySz; int ret = 0; if (aes == NULL || key == NULL) { @@ -12337,27 +12336,10 @@ int wc_AesXtsSetKey(XtsAes* aes, const byte* key, word32 len, int dir, if (ret != 0) return ret; - keySz = len/2; - if (keySz != 16 && keySz != 32) { - WOLFSSL_MSG("Unsupported key size"); - return WC_KEY_SIZE_E; - } + ret = wc_AesXtsSetKeyNoInit(aes, key, len, dir); - if ((ret = wc_AesSetKey(&aes->aes, key, keySz, NULL, dir)) == 0) { - ret = wc_AesSetKey(&aes->tweak, key + keySz, keySz, NULL, - AES_ENCRYPTION); - if (ret != 0) { - wc_AesFree(&aes->aes); - } -#ifdef WOLFSSL_AESNI - if (aes->aes.use_aesni != aes->tweak.use_aesni) { - if (aes->aes.use_aesni) - aes->aes.use_aesni = 0; - else - aes->tweak.use_aesni = 0; - } -#endif - } + if (ret != 0) + wc_AesXtsFree(aes); return ret; } diff --git a/wolfcrypt/src/evp.c b/wolfcrypt/src/evp.c index 173fe75fc..f59cc2e10 100644 --- a/wolfcrypt/src/evp.c +++ b/wolfcrypt/src/evp.c @@ -1226,6 +1226,11 @@ int wolfSSL_EVP_CipherFinal(WOLFSSL_EVP_CIPHER_CTX *ctx, unsigned char *out, } } + if (ret == 0) + ret = WOLFSSL_SUCCESS; + else + ret = WOLFSSL_FAILURE; + /* Reinitialize for subsequent wolfSSL_EVP_Cipher calls. */ if (wc_AesGcmInit(&ctx->cipher.aes, NULL, 0, (byte*)ctx->cipher.aes.reg, @@ -1234,12 +1239,6 @@ int wolfSSL_EVP_CipherFinal(WOLFSSL_EVP_CIPHER_CTX *ctx, unsigned char *out, WOLFSSL_MSG("wc_AesGcmInit failed"); ret = WOLFSSL_FAILURE; } - else { - if (ret == 0) - ret = WOLFSSL_SUCCESS; - else - ret = WOLFSSL_FAILURE; - } #endif /* WOLFSSL_AESGCM_STREAM */ if (ret == WOLFSSL_SUCCESS) { if (ctx->authIncIv) { @@ -7498,7 +7497,7 @@ void wolfSSL_EVP_init(void) } if (key) { - ret = wc_AesXtsSetKey_NoInit(&ctx->cipher.xts, key, + ret = wc_AesXtsSetKeyNoInit(&ctx->cipher.xts, key, (word32)ctx->keyLen, ctx->enc ? AES_ENCRYPTION : AES_DECRYPTION); if (ret != 0) { @@ -7539,7 +7538,7 @@ void wolfSSL_EVP_init(void) } if (key) { - ret = wc_AesXtsSetKey_NoInit(&ctx->cipher.xts, key, + ret = wc_AesXtsSetKeyNoInit(&ctx->cipher.xts, key, (word32)ctx->keyLen, ctx->enc ? AES_ENCRYPTION : AES_DECRYPTION); if (ret != 0) { diff --git a/wolfcrypt/test/test.c b/wolfcrypt/test/test.c index 09cd9db29..0667aee8d 100644 --- a/wolfcrypt/test/test.c +++ b/wolfcrypt/test/test.c @@ -9485,7 +9485,7 @@ static wc_test_ret_t aes_xts_128_test(void) else aes_inited = 1; - ret = wc_AesXtsSetKey_NoInit(aes, k2, sizeof(k2), AES_ENCRYPTION); + ret = wc_AesXtsSetKeyNoInit(aes, k2, sizeof(k2), AES_ENCRYPTION); if (ret != 0) ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); @@ -9513,7 +9513,7 @@ static wc_test_ret_t aes_xts_128_test(void) XMEMSET(buf, 0, sizeof(buf)); - ret = wc_AesXtsSetKey_NoInit(aes, k1, sizeof(k1), AES_ENCRYPTION); + ret = wc_AesXtsSetKeyNoInit(aes, k1, sizeof(k1), AES_ENCRYPTION); if (ret != 0) ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); ret = wc_AesXtsEncrypt(aes, buf, p1, sizeof(p1), i1, sizeof(i1)); @@ -9565,7 +9565,7 @@ static wc_test_ret_t aes_xts_128_test(void) /* partial block decrypt test */ XMEMSET(buf, 0, sizeof(buf)); - ret = wc_AesXtsSetKey_NoInit(aes, k1, sizeof(k1), AES_DECRYPTION); + ret = wc_AesXtsSetKeyNoInit(aes, k1, sizeof(k1), AES_DECRYPTION); if (ret != 0) ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); ret = wc_AesXtsDecrypt(aes, buf, cipher, sizeof(pp), i1, sizeof(i1)); @@ -9629,7 +9629,7 @@ static wc_test_ret_t aes_xts_128_test(void) /* set correct key and retest */ XMEMSET(buf, 0, sizeof(buf)); - ret = wc_AesXtsSetKey_NoInit(aes, k2, sizeof(k2), AES_DECRYPTION); + ret = wc_AesXtsSetKeyNoInit(aes, k2, sizeof(k2), AES_DECRYPTION); if (ret != 0) ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); ret = wc_AesXtsDecrypt(aes, buf, c2, sizeof(c2), i2, sizeof(i2)); @@ -9645,7 +9645,7 @@ static wc_test_ret_t aes_xts_128_test(void) /* Test ciphertext stealing in-place. */ XMEMCPY(buf, p3, sizeof(p3)); - ret = wc_AesXtsSetKey_NoInit(aes, k3, sizeof(k3), AES_ENCRYPTION); + ret = wc_AesXtsSetKeyNoInit(aes, k3, sizeof(k3), AES_ENCRYPTION); if (ret != 0) ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); @@ -9658,7 +9658,7 @@ static wc_test_ret_t aes_xts_128_test(void) if (XMEMCMP(c3, buf, sizeof(c3))) ERROR_OUT(WC_TEST_RET_ENC_NC, out); - ret = wc_AesXtsSetKey_NoInit(aes, k3, sizeof(k3), AES_DECRYPTION); + ret = wc_AesXtsSetKeyNoInit(aes, k3, sizeof(k3), AES_DECRYPTION); if (ret != 0) ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); ret = wc_AesXtsDecrypt(aes, buf, buf, sizeof(c3), i3, sizeof(i3)); @@ -9694,7 +9694,7 @@ static wc_test_ret_t aes_xts_128_test(void) large_input[i] = (byte)i; for (j = 16; j < (int)LARGE_XTS_SZ; j++) { - ret = wc_AesXtsSetKey_NoInit(aes, k1, sizeof(k1), AES_ENCRYPTION); + ret = wc_AesXtsSetKeyNoInit(aes, k1, sizeof(k1), AES_ENCRYPTION); if (ret != 0) ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); ret = wc_AesXtsEncrypt(aes, large_input, large_input, j, i1, @@ -9705,7 +9705,7 @@ static wc_test_ret_t aes_xts_128_test(void) if (ret != 0) ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); - ret = wc_AesXtsSetKey_NoInit(aes, k1, sizeof(k1), AES_DECRYPTION); + ret = wc_AesXtsSetKeyNoInit(aes, k1, sizeof(k1), AES_DECRYPTION); if (ret != 0) ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); ret = wc_AesXtsDecrypt(aes, large_input, large_input, j, i1, @@ -9851,7 +9851,7 @@ static wc_test_ret_t aes_xts_256_test(void) aes_inited = 1; XMEMSET(buf, 0, sizeof(buf)); - ret = wc_AesXtsSetKey_NoInit(aes, k2, sizeof(k2), AES_ENCRYPTION); + ret = wc_AesXtsSetKeyNoInit(aes, k2, sizeof(k2), AES_ENCRYPTION); if (ret != 0) ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); @@ -9865,7 +9865,7 @@ static wc_test_ret_t aes_xts_256_test(void) ERROR_OUT(WC_TEST_RET_ENC_NC, out); XMEMSET(buf, 0, sizeof(buf)); - ret = wc_AesXtsSetKey_NoInit(aes, k1, sizeof(k1), AES_ENCRYPTION); + ret = wc_AesXtsSetKeyNoInit(aes, k1, sizeof(k1), AES_ENCRYPTION); if (ret != 0) ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); ret = wc_AesXtsEncrypt(aes, buf, p1, sizeof(p1), i1, sizeof(i1)); @@ -9888,7 +9888,7 @@ static wc_test_ret_t aes_xts_256_test(void) /* partial block decrypt test */ XMEMSET(buf, 0, sizeof(buf)); - ret = wc_AesXtsSetKey_NoInit(aes, k1, sizeof(k1), AES_DECRYPTION); + ret = wc_AesXtsSetKeyNoInit(aes, k1, sizeof(k1), AES_DECRYPTION); if (ret != 0) ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); ret = wc_AesXtsDecrypt(aes, buf, cipher, sizeof(pp), i1, sizeof(i1)); @@ -9912,7 +9912,7 @@ static wc_test_ret_t aes_xts_256_test(void) ERROR_OUT(WC_TEST_RET_ENC_NC, out); XMEMSET(buf, 0, sizeof(buf)); - ret = wc_AesXtsSetKey_NoInit(aes, k2, sizeof(k2), AES_DECRYPTION); + ret = wc_AesXtsSetKeyNoInit(aes, k2, sizeof(k2), AES_DECRYPTION); if (ret != 0) ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); ret = wc_AesXtsDecrypt(aes, buf, c2, sizeof(c2), i2, sizeof(i2)); @@ -10128,7 +10128,7 @@ static wc_test_ret_t aes_xts_sector_test(void) aes_inited = 1; XMEMSET(buf, 0, sizeof(buf)); - ret = wc_AesXtsSetKey_NoInit(aes, k1, sizeof(k1), AES_ENCRYPTION); + ret = wc_AesXtsSetKeyNoInit(aes, k1, sizeof(k1), AES_ENCRYPTION); if (ret != 0) ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); @@ -10143,7 +10143,7 @@ static wc_test_ret_t aes_xts_sector_test(void) /* decrypt test */ XMEMSET(buf, 0, sizeof(buf)); - ret = wc_AesXtsSetKey_NoInit(aes, k1, sizeof(k1), AES_DECRYPTION); + ret = wc_AesXtsSetKeyNoInit(aes, k1, sizeof(k1), AES_DECRYPTION); if (ret != 0) ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); ret = wc_AesXtsDecryptSector(aes, buf, c1, sizeof(c1), s1); @@ -10157,7 +10157,7 @@ static wc_test_ret_t aes_xts_sector_test(void) /* 256 bit key tests */ XMEMSET(buf, 0, sizeof(buf)); - ret = wc_AesXtsSetKey_NoInit(aes, k2, sizeof(k2), AES_ENCRYPTION); + ret = wc_AesXtsSetKeyNoInit(aes, k2, sizeof(k2), AES_ENCRYPTION); if (ret != 0) ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); ret = wc_AesXtsEncryptSector(aes, buf, p2, sizeof(p2), s2); @@ -10171,7 +10171,7 @@ static wc_test_ret_t aes_xts_sector_test(void) /* decrypt test */ XMEMSET(buf, 0, sizeof(buf)); - ret = wc_AesXtsSetKey_NoInit(aes, k2, sizeof(k2), AES_DECRYPTION); + ret = wc_AesXtsSetKeyNoInit(aes, k2, sizeof(k2), AES_DECRYPTION); if (ret != 0) ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); ret = wc_AesXtsDecryptSector(aes, buf, c2, sizeof(c2), s2); @@ -10187,7 +10187,7 @@ static wc_test_ret_t aes_xts_sector_test(void) (!defined(HAVE_FIPS) || FIPS_VERSION_GE(5, 3)) && !defined(HAVE_SELFTEST) /* encrypt consecutive sectors test */ XMEMSET(data, 0, sizeof(buf)); - ret = wc_AesXtsSetKey_NoInit(aes, k3, sizeof(k3), AES_ENCRYPTION); + ret = wc_AesXtsSetKeyNoInit(aes, k3, sizeof(k3), AES_ENCRYPTION); if (ret != 0) ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); ret = wc_AesXtsEncryptConsecutiveSectors(aes, data, p3, @@ -10202,7 +10202,7 @@ static wc_test_ret_t aes_xts_sector_test(void) /* decrypt consecutive sectors test */ XMEMSET(data, 0, sizeof(buf)); - ret = wc_AesXtsSetKey_NoInit(aes, k3, sizeof(k3), AES_DECRYPTION); + ret = wc_AesXtsSetKeyNoInit(aes, k3, sizeof(k3), AES_DECRYPTION); if (ret != 0) ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); ret = wc_AesXtsDecryptConsecutiveSectors(aes, data, c3, @@ -10275,13 +10275,13 @@ static wc_test_ret_t aes_xts_args_test(void) else aes_inited = 1; - if (wc_AesXtsSetKey_NoInit(NULL, k1, sizeof(k1), AES_ENCRYPTION) == 0) + if (wc_AesXtsSetKeyNoInit(NULL, k1, sizeof(k1), AES_ENCRYPTION) == 0) ERROR_OUT(WC_TEST_RET_ENC_NC, out); - if (wc_AesXtsSetKey_NoInit(aes, NULL, sizeof(k1), AES_ENCRYPTION) == 0) + if (wc_AesXtsSetKeyNoInit(aes, NULL, sizeof(k1), AES_ENCRYPTION) == 0) ERROR_OUT(WC_TEST_RET_ENC_NC, out); /* encryption operations */ - ret = wc_AesXtsSetKey_NoInit(aes, k1, sizeof(k1), AES_ENCRYPTION); + ret = wc_AesXtsSetKeyNoInit(aes, k1, sizeof(k1), AES_ENCRYPTION); if (ret != 0) ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); @@ -10300,7 +10300,7 @@ static wc_test_ret_t aes_xts_args_test(void) ERROR_OUT(WC_TEST_RET_ENC_NC, out); /* decryption operations */ - ret = wc_AesXtsSetKey_NoInit(aes, k1, sizeof(k1), AES_DECRYPTION); + ret = wc_AesXtsSetKeyNoInit(aes, k1, sizeof(k1), AES_DECRYPTION); if (ret != 0) ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); ret = wc_AesXtsDecryptSector(NULL, buf, c1, sizeof(c1), s1); diff --git a/wolfssl/wolfcrypt/aes.h b/wolfssl/wolfcrypt/aes.h index 5e6e6b395..7b2cb918f 100644 --- a/wolfssl/wolfcrypt/aes.h +++ b/wolfssl/wolfcrypt/aes.h @@ -623,7 +623,7 @@ WOLFSSL_API int wc_AesGcmDecryptFinal(Aes* aes, const byte* authTag, WOLFSSL_API int wc_AesXtsInit(XtsAes* aes, void* heap, int devId); -WOLFSSL_API int wc_AesXtsSetKey_NoInit(XtsAes* aes, const byte* key, +WOLFSSL_API int wc_AesXtsSetKeyNoInit(XtsAes* aes, const byte* key, word32 len, int dir); WOLFSSL_API int wc_AesXtsSetKey(XtsAes* aes, const byte* key, From 106e39bd7638bef71718c541a3579b5027fc761b Mon Sep 17 00:00:00 2001 From: Daniel Pouzzner Date: Wed, 6 Dec 2023 21:58:55 -0600 Subject: [PATCH 4/5] tests/api.c: in test_wc_CmacFinal(), don't use wc_CmacFinalNoFree() if FIPS <5.3. --- tests/api.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/tests/api.c b/tests/api.c index 6af145a80..12d46ec93 100644 --- a/tests/api.c +++ b/tests/api.c @@ -15795,15 +15795,24 @@ static int test_wc_CmacFinal(void) ExpectIntEQ(wc_InitCmac(&cmac, key, keySz, type, NULL), 0); ExpectIntEQ(wc_CmacUpdate(&cmac, msg, msgSz), 0); - ExpectIntEQ(wc_CmacFinalNoFree(&cmac, mac, &macSz), 0); - ExpectIntEQ(XMEMCMP(mac, expMac, expMacSz), 0); - +#if (!defined(HAVE_FIPS) || FIPS_VERSION_GE(5, 3)) && !defined(HAVE_SELFTEST) /* Pass in bad args. */ ExpectIntEQ(wc_CmacFinalNoFree(NULL, mac, &macSz), BAD_FUNC_ARG); ExpectIntEQ(wc_CmacFinalNoFree(&cmac, NULL, &macSz), BAD_FUNC_ARG); + ExpectIntEQ(wc_CmacFinalNoFree(&cmac, mac, &badMacSz), BUFFER_E); /* For the last call, use the API with implicit wc_CmacFree(). */ + ExpectIntEQ(wc_CmacFinal(&cmac, mac, &macSz), 0); + ExpectIntEQ(XMEMCMP(mac, expMac, expMacSz), 0); +#else /* !HAVE_FIPS || FIPS>=5.3 */ + ExpectIntEQ(wc_CmacFinal(&cmac, mac, &macSz), 0); + ExpectIntEQ(XMEMCMP(mac, expMac, expMacSz), 0); + + /* Pass in bad args. */ + ExpectIntEQ(wc_CmacFinal(NULL, mac, &macSz), BAD_FUNC_ARG); + ExpectIntEQ(wc_CmacFinal(&cmac, NULL, &macSz), BAD_FUNC_ARG); ExpectIntEQ(wc_CmacFinal(&cmac, mac, &badMacSz), BUFFER_E); +#endif /* !HAVE_FIPS || FIPS>=5.3 */ #endif return EXPECT_RESULT(); } /* END test_wc_CmacFinal */ From 803b17a8b3d004c0500bf40daba0f87efe5b1467 Mon Sep 17 00:00:00 2001 From: Daniel Pouzzner Date: Wed, 6 Dec 2023 23:04:52 -0600 Subject: [PATCH 5/5] src/ssl_crypto.c: in wolfSSL_CMAC_CTX_free(), gate wc_CmacFree() on !FIPS || FIPS>=5.3. --- src/ssl_crypto.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/ssl_crypto.c b/src/ssl_crypto.c index 0523ad952..3c73b88f5 100644 --- a/src/ssl_crypto.c +++ b/src/ssl_crypto.c @@ -2106,7 +2106,9 @@ void wolfSSL_CMAC_CTX_free(WOLFSSL_CMAC_CTX *ctx) if (ctx != NULL) { /* Deallocate dynamically allocated fields. */ if (ctx->internal != NULL) { +#if (!defined(HAVE_FIPS) || FIPS_VERSION_GE(5, 3)) && !defined(HAVE_SELFTEST) wc_CmacFree((Cmac*)ctx->internal); +#endif XFREE(ctx->internal, NULL, DYNAMIC_TYPE_CMAC); } if (ctx->cctx != NULL) {