diff --git a/tests/unit-mcdc/test_aes_whitebox.c b/tests/unit-mcdc/test_aes_whitebox.c index b84cbee4aec..59c9a69e4a1 100644 --- a/tests/unit-mcdc/test_aes_whitebox.c +++ b/tests/unit-mcdc/test_aes_whitebox.c @@ -218,10 +218,8 @@ static void wb_ghash_update(void) { WB_NOTE("AESGCM stream off; GHASH_UPDATE ski * ------------------------------------------------------------------------- */ static void wb_release(Aes* aes) { - if (aes != NULL) { - wc_AesFree(aes); - XFREE(aes, NULL, DYNAMIC_TYPE_AES); - } + if (aes != NULL) + (void)wc_AesDelete(aes, NULL); } static void wb_aesnew_common(void) diff --git a/wolfcrypt/src/aes.c b/wolfcrypt/src/aes.c index d3daf08842b..85c772cdd2e 100644 --- a/wolfcrypt/src/aes.c +++ b/wolfcrypt/src/aes.c @@ -392,6 +392,40 @@ int wc_local_AesGcmCheckTagSz(word32 authTagSz) { } #endif /* HAVE_AESGCM */ +/* Aes contains 16-byte-aligned members, but malloc on 32-bit Arm may only + * return an 8-byte-aligned pointer. Keep the original allocation for XFREE. + * The TI backend uses its existing plain allocation path. */ +static WC_MAYBE_UNUSED Aes* AesAlloc(void* heap) +{ +#if defined(WOLFSSL_USE_ALIGN) && defined(WC_ALIGNOF) && \ + !defined(WOLFSSL_TI_CRYPT) + const size_t align = WC_ALIGNOF(Aes); + byte* raw = (byte*)XMALLOC(sizeof(Aes) + align - 1 + sizeof(void*), heap, + DYNAMIC_TYPE_AES); + wc_ptr_t p; + + if (raw == NULL) + return NULL; + p = ((wc_ptr_t)(raw + sizeof(void*)) + align - 1) & + ~((wc_ptr_t)align - 1); + ((void**)p)[-1] = raw; + return (Aes*)p; +#else + return (Aes*)XMALLOC(sizeof(Aes), heap, DYNAMIC_TYPE_AES); +#endif +} + +static WC_MAYBE_UNUSED void AesAllocFree(Aes* aes, void* heap) +{ +#if defined(WOLFSSL_USE_ALIGN) && defined(WC_ALIGNOF) && \ + !defined(WOLFSSL_TI_CRYPT) + if (aes != NULL) + XFREE(((void**)aes)[-1], heap, DYNAMIC_TYPE_AES); +#else + XFREE(aes, heap, DYNAMIC_TYPE_AES); +#endif +} + #if defined(WOLFSSL_TI_CRYPT) #include @@ -17006,7 +17040,7 @@ static Aes* _AesNew_common(void* heap, int devId, int *result_code, int idLen, const char* label) { int ret; - Aes* aes = (Aes*)XMALLOC(sizeof(Aes), heap, DYNAMIC_TYPE_AES); + Aes* aes = AesAlloc(heap); if (aes == NULL) { ret = MEMORY_E; } @@ -17040,7 +17074,7 @@ static Aes* _AesNew_common(void* heap, int devId, int *result_code, break; } if (ret != 0) { - XFREE(aes, heap, DYNAMIC_TYPE_AES); + AesAllocFree(aes, heap); aes = NULL; } } @@ -17085,7 +17119,7 @@ int wc_AesDelete(Aes *aes, Aes** aes_p) return BAD_FUNC_ARG; heap = aes->heap; wc_AesFree(aes); - XFREE(aes, heap, DYNAMIC_TYPE_AES); + AesAllocFree(aes, heap); if (aes_p != NULL) *aes_p = NULL; return 0; @@ -18673,8 +18707,7 @@ int wc_AesKeyWrap(const byte* key, word32 keySz, const byte* in, word32 inSz, return BAD_FUNC_ARG; #ifdef WOLFSSL_SMALL_STACK - if ((aes = (Aes *)XMALLOC(sizeof *aes, NULL, - DYNAMIC_TYPE_AES)) == NULL) + if ((aes = AesAlloc(NULL)) == NULL) return MEMORY_E; #endif @@ -18693,7 +18726,9 @@ int wc_AesKeyWrap(const byte* key, word32 keySz, const byte* in, word32 inSz, wc_AesFree(aes); out: - WC_FREE_VAR_EX(aes, NULL, DYNAMIC_TYPE_AES); +#ifdef WOLFSSL_SMALL_STACK + AesAllocFree(aes, NULL); +#endif return ret; } @@ -18868,8 +18903,7 @@ int wc_AesKeyUnWrap(const byte* key, word32 keySz, const byte* in, word32 inSz, return BAD_FUNC_ARG; #ifdef WOLFSSL_SMALL_STACK - if ((aes = (Aes *)XMALLOC(sizeof *aes, NULL, - DYNAMIC_TYPE_AES)) == NULL) + if ((aes = AesAlloc(NULL)) == NULL) return MEMORY_E; #endif @@ -18889,7 +18923,9 @@ int wc_AesKeyUnWrap(const byte* key, word32 keySz, const byte* in, word32 inSz, wc_AesFree(aes); out: - WC_FREE_VAR_EX(aes, NULL, DYNAMIC_TYPE_AES); +#ifdef WOLFSSL_SMALL_STACK + AesAllocFree(aes, NULL); +#endif return ret; } @@ -19000,7 +19036,10 @@ int wc_AesKeyWrap_Pad(const byte* key, word32 keySz, const byte* in, return BAD_FUNC_ARG; } - WC_ALLOC_VAR_EX(aes, Aes, 1, NULL, DYNAMIC_TYPE_AES, return MEMORY_E); +#ifdef WOLFSSL_SMALL_STACK + if ((aes = AesAlloc(NULL)) == NULL) + return MEMORY_E; +#endif ret = wc_AesInit(aes, NULL, INVALID_DEVID); if (ret != 0) { @@ -19018,7 +19057,9 @@ int wc_AesKeyWrap_Pad(const byte* key, word32 keySz, const byte* in, wc_AesFree(aes); out: - WC_FREE_VAR_EX(aes, NULL, DYNAMIC_TYPE_AES); +#ifdef WOLFSSL_SMALL_STACK + AesAllocFree(aes, NULL); +#endif return ret; } @@ -19173,7 +19214,10 @@ int wc_AesKeyUnWrap_Pad(const byte* key, word32 keySz, const byte* in, return BAD_FUNC_ARG; } - WC_ALLOC_VAR_EX(aes, Aes, 1, NULL, DYNAMIC_TYPE_AES, return MEMORY_E); +#ifdef WOLFSSL_SMALL_STACK + if ((aes = AesAlloc(NULL)) == NULL) + return MEMORY_E; +#endif ret = wc_AesInit(aes, NULL, INVALID_DEVID); if (ret != 0) { @@ -19191,7 +19235,9 @@ int wc_AesKeyUnWrap_Pad(const byte* key, word32 keySz, const byte* in, wc_AesFree(aes); out: - WC_FREE_VAR_EX(aes, NULL, DYNAMIC_TYPE_AES); +#ifdef WOLFSSL_SMALL_STACK + AesAllocFree(aes, NULL); +#endif return ret; } diff --git a/wolfcrypt/test/test.c b/wolfcrypt/test/test.c index 74d42b0a6d6..2a2a7b35996 100644 --- a/wolfcrypt/test/test.c +++ b/wolfcrypt/test/test.c @@ -17698,6 +17698,11 @@ static wc_test_ret_t aes_key_size_test(void) aes = wc_AesNew(HEAP_HINT, devId, &ret); if (aes == NULL) return WC_TEST_RET_ENC_EC(ret); +#if defined(WC_ALIGNOF) && !defined(HAVE_FIPS) && \ + !defined(HAVE_SELFTEST) + if (!WC_IS_ALIGNED(aes, WC_ALIGNOF(Aes))) + ERROR_OUT(WC_TEST_RET_ENC_NC, out); +#endif #else ret = wc_AesInit(aes, HEAP_HINT, devId); /* 0 check OK for FIPSv1 */ @@ -26904,9 +26909,8 @@ typedef struct keywrapVector { * byte alignment through its ALIGN16 members, which XMALLOC does not guarantee * on 32-bit targets, where malloc only promises 8 -- and wc_AesSetIV() lowers * to an alignment-qualified NEON store when building for armv8-a+crypto, which - * faults on an under-aligned object. Neither a plain local nor a plain XMALLOC - * (wc_AesNew() included) satisfies both, so allocate with headroom, align by - * hand, and keep the base pointer for XFREE. */ + * faults on an under-aligned object. Allocate with headroom, align by hand, + * and keep the base pointer for XFREE. */ #define AESKEYWRAP_AES_ALIGN 16 static wc_test_ret_t aeskeywrap_caller_aes_test(const keywrapVector* v, byte* output, word32 outputSz,