From 2168b154b6a7781f5f729c12d3a66e787ea93b35 Mon Sep 17 00:00:00 2001 From: John Safranek Date: Mon, 1 Apr 2024 11:35:45 -0700 Subject: [PATCH 1/8] Generic Memory Pools 1. Modify wolfSSL_CTX_load_static_memory() to use wc_LoadStaticMemory() instead of reimplementing it. 2. Initialize the pointers in wc_LoadStaticMemory() to null. 3. Whitespace changes. --- src/ssl.c | 60 +++++++++--------------------------------- wolfcrypt/src/memory.c | 6 ++--- 2 files changed, 16 insertions(+), 50 deletions(-) diff --git a/src/ssl.c b/src/ssl.c index 096f76953..5bc1a3eb3 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -2572,9 +2572,7 @@ int wolfSSL_CTX_load_static_memory(WOLFSSL_CTX** ctx, wolfSSL_method_func method, unsigned char* buf, unsigned int sz, int flag, int maxSz) { - WOLFSSL_HEAP* heap; - WOLFSSL_HEAP_HINT* hint; - word32 idx = 0; + WOLFSSL_HEAP_HINT* hint = NULL; if (ctx == NULL || buf == NULL) { return BAD_FUNC_ARG; @@ -2584,42 +2582,23 @@ int wolfSSL_CTX_load_static_memory(WOLFSSL_CTX** ctx, return BAD_FUNC_ARG; } - if (*ctx == NULL || (*ctx)->heap == NULL) { - if (sizeof(WOLFSSL_HEAP) + sizeof(WOLFSSL_HEAP_HINT) > sz - idx) { - return BUFFER_E; /* not enough memory for structures */ - } - heap = (WOLFSSL_HEAP*)buf; - idx += sizeof(WOLFSSL_HEAP); - if (wolfSSL_init_memory_heap(heap) != 0) { - return WOLFSSL_FAILURE; - } - hint = (WOLFSSL_HEAP_HINT*)(buf + idx); - idx += sizeof(WOLFSSL_HEAP_HINT); - XMEMSET(hint, 0, sizeof(WOLFSSL_HEAP_HINT)); - hint->memory = heap; + /* If there is a heap already, capture it in hint. */ + if (*ctx && (*ctx)->heap != NULL) { + hint = (*ctx)->heap; + } - if (*ctx && (*ctx)->heap == NULL) { + if (wc_LoadStaticMemory(&hint, buf, sz, flag, maxSz)) { + WOLFSSL_MSG("Error loading static memory"); + return WOLFSSL_FAILURE; + } + + if (*ctx) { + if ((*ctx)->heap == NULL) { (*ctx)->heap = (void*)hint; } } else { -#ifdef WOLFSSL_HEAP_TEST - /* do not load in memory if test has been set */ - if ((*ctx)->heap == (void*)WOLFSSL_HEAP_TEST) { - return WOLFSSL_SUCCESS; - } -#endif - hint = (WOLFSSL_HEAP_HINT*)((*ctx)->heap); - heap = hint->memory; - } - - if (wolfSSL_load_static_memory(buf + idx, sz - idx, flag, heap) != 1) { - WOLFSSL_MSG("Error partitioning memory"); - return WOLFSSL_FAILURE; - } - - /* create ctx if needed */ - if (*ctx == NULL) { + /* create ctx if needed */ *ctx = wolfSSL_CTX_new_ex(method(hint), hint); if (*ctx == NULL) { WOLFSSL_MSG("Error creating ctx"); @@ -2627,19 +2606,6 @@ int wolfSSL_CTX_load_static_memory(WOLFSSL_CTX** ctx, } } - /* determine what max applies too */ - if (flag & WOLFMEM_IO_POOL || flag & WOLFMEM_IO_POOL_FIXED) { - heap->maxIO = maxSz; - } - else { /* general memory used in handshakes */ - heap->maxHa = maxSz; - } - - heap->flag |= flag; - - (void)maxSz; - (void)method; - return WOLFSSL_SUCCESS; } diff --git a/wolfcrypt/src/memory.c b/wolfcrypt/src/memory.c index 4b068ce9c..94c9207a9 100644 --- a/wolfcrypt/src/memory.c +++ b/wolfcrypt/src/memory.c @@ -587,10 +587,10 @@ int wolfSSL_init_memory_heap(WOLFSSL_HEAP* heap) int wc_LoadStaticMemory(WOLFSSL_HEAP_HINT** pHint, unsigned char* buf, unsigned int sz, int flag, int maxSz) { - int ret; - WOLFSSL_HEAP* heap; - WOLFSSL_HEAP_HINT* hint; + WOLFSSL_HEAP* heap = NULL; + WOLFSSL_HEAP_HINT* hint = NULL; word32 idx = 0; + int ret; if (pHint == NULL || buf == NULL) { return BAD_FUNC_ARG; From 74816448420f40d665b38ef623ec7561ad045c40 Mon Sep 17 00:00:00 2001 From: John Safranek Date: Mon, 1 Apr 2024 15:12:08 -0700 Subject: [PATCH 2/8] Generic Memory Pools 1. Add the function wc_LoadStaticMemory_ex(), which is a generic version of wc_LoadStaticMemory(). 2. Modify wc_LoadStaticMemory() to call wc_LoadStaticMemory_ex() with the bucket lists. 3. Rename the function wolfSSL_load_static_memory() as wc_partition_static_memory(), make it static, move it higher in the file. --- wolfcrypt/src/memory.c | 164 ++++++++++++++++++++----------------- wolfssl/wolfcrypt/memory.h | 6 +- 2 files changed, 91 insertions(+), 79 deletions(-) diff --git a/wolfcrypt/src/memory.c b/wolfcrypt/src/memory.c index 94c9207a9..5e37f6db1 100644 --- a/wolfcrypt/src/memory.c +++ b/wolfcrypt/src/memory.c @@ -521,7 +521,7 @@ struct wc_Memory { /* returns amount of memory used on success. On error returns negative value wc_Memory** list is the list that new buckets are prepended to */ -static int create_memory_buckets(byte* buffer, word32 bufSz, +static int wc_create_memory_buckets(byte* buffer, word32 bufSz, word32 buckSz, word32 buckNum, wc_Memory** list) { word32 i; byte* pt = buffer; @@ -562,19 +562,87 @@ static int create_memory_buckets(byte* buffer, word32 bufSz, return ret; } -int wolfSSL_init_memory_heap(WOLFSSL_HEAP* heap) +static int wc_partition_static_memory(byte* buffer, word32 sz, int flag, + WOLFSSL_HEAP* heap) { - word32 wc_MemSz[WOLFMEM_DEF_BUCKETS] = { WOLFMEM_BUCKETS }; - word32 wc_Dist[WOLFMEM_DEF_BUCKETS] = { WOLFMEM_DIST }; + word32 ava = sz; + byte* pt = buffer; + int ret = 0; + word32 memSz = (word32)sizeof(wc_Memory); + word32 padSz = -(int)memSz & (WOLFSSL_STATIC_ALIGN - 1); - if (heap == NULL) { + WOLFSSL_ENTER("wc_partition_static_memory"); + + if (buffer == NULL) { + return BAD_FUNC_ARG; + } + + /* align pt */ + while ((wc_ptr_t)pt % WOLFSSL_STATIC_ALIGN && pt < (buffer + sz)) { + *pt = 0x00; + pt++; + ava--; + } + +#ifdef WOLFSSL_DEBUG_MEMORY + fprintf(stderr, "Allocated %d bytes for static memory @ %p\n", ava, pt); +#endif + + /* divide into chunks of memory and add them to available list */ + while (ava >= (heap->sizeList[0] + padSz + memSz)) { + /* creating only IO buffers from memory passed in, max TLS is 16k */ + if (flag & WOLFMEM_IO_POOL || flag & WOLFMEM_IO_POOL_FIXED) { + if ((ret = wc_create_memory_buckets(pt, ava, + WOLFMEM_IO_SZ, 1, &(heap->io))) < 0) { + WOLFSSL_LEAVE("wc_partition_static_memory", ret); + return ret; + } + + /* check if no more room left for creating IO buffers */ + if (ret == 0) { + break; + } + + /* advance pointer in buffer for next buckets and keep track + of how much memory is left available */ + pt += ret; + ava -= ret; + } + else { + int i; + /* start at largest and move to smaller buckets */ + for (i = (WOLFMEM_MAX_BUCKETS - 1); i >= 0; i--) { + if ((heap->sizeList[i] + padSz + memSz) <= ava) { + if ((ret = wc_create_memory_buckets(pt, ava, + heap->sizeList[i], heap->distList[i], + &(heap->ava[i]))) < 0) { + WOLFSSL_LEAVE("wc_partition_static_memory", ret); + return ret; + } + + /* advance pointer in buffer for next buckets and keep track + of how much memory is left available */ + pt += ret; + ava -= ret; + } + } + } + } + + return 1; +} + +static int wc_init_memory_heap(WOLFSSL_HEAP* heap, unsigned int listSz, + unsigned int* sizeList, unsigned int* distList) +{ + if (heap == NULL || listSz > WOLFMEM_MAX_BUCKETS) { return BAD_FUNC_ARG; } XMEMSET(heap, 0, sizeof(WOLFSSL_HEAP)); - XMEMCPY(heap->sizeList, wc_MemSz, sizeof(wc_MemSz)); - XMEMCPY(heap->distList, wc_Dist, sizeof(wc_Dist)); + XMEMCPY(heap->sizeList, sizeList, listSz * sizeof(sizeList[0])); + XMEMCPY(heap->distList, distList, listSz * sizeof(distList[0])); if (wc_InitMutex(&(heap->memory_mutex)) != 0) { WOLFSSL_MSG("Error creating heap memory mutex"); @@ -584,8 +652,10 @@ int wolfSSL_init_memory_heap(WOLFSSL_HEAP* heap) return 0; } -int wc_LoadStaticMemory(WOLFSSL_HEAP_HINT** pHint, - unsigned char* buf, unsigned int sz, int flag, int maxSz) +int wc_LoadStaticMemory_ex(WOLFSSL_HEAP_HINT** pHint, + unsigned int listSz, + unsigned int* memSzList, unsigned int* memDistList, + unsigned char* buf, unsigned int sz, int flag, int maxSz) { WOLFSSL_HEAP* heap = NULL; WOLFSSL_HEAP_HINT* hint = NULL; @@ -607,7 +677,7 @@ int wc_LoadStaticMemory(WOLFSSL_HEAP_HINT** pHint, hint = (WOLFSSL_HEAP_HINT*)(buf + idx); idx += sizeof(WOLFSSL_HEAP_HINT); - ret = wolfSSL_init_memory_heap(heap); + ret = wc_init_memory_heap(heap, listSz, memSzList, memDistList); if (ret != 0) { return ret; } @@ -627,7 +697,7 @@ int wc_LoadStaticMemory(WOLFSSL_HEAP_HINT** pHint, heap = hint->memory; } - ret = wolfSSL_load_static_memory(buf + idx, sz - idx, flag, heap); + ret = wc_partition_static_memory(buf + idx, sz - idx, flag, heap); if (ret != 1) { WOLFSSL_MSG("Error partitioning memory"); return -1; @@ -649,73 +719,15 @@ int wc_LoadStaticMemory(WOLFSSL_HEAP_HINT** pHint, return 0; } -int wolfSSL_load_static_memory(byte* buffer, word32 sz, int flag, - WOLFSSL_HEAP* heap) +int wc_LoadStaticMemory(WOLFSSL_HEAP_HINT** pHint, + unsigned char* buf, unsigned int sz, int flag, int maxSz) { - word32 ava = sz; - byte* pt = buffer; - int ret = 0; - word32 memSz = (word32)sizeof(wc_Memory); - word32 padSz = -(int)memSz & (WOLFSSL_STATIC_ALIGN - 1); + word32 sizeList[WOLFMEM_DEF_BUCKETS] = { WOLFMEM_BUCKETS }; + word32 distList[WOLFMEM_DEF_BUCKETS] = { WOLFMEM_DIST }; - WOLFSSL_ENTER("wolfSSL_load_static_memory"); - - if (buffer == NULL) { - return BAD_FUNC_ARG; - } - - /* align pt */ - while ((wc_ptr_t)pt % WOLFSSL_STATIC_ALIGN && pt < (buffer + sz)) { - *pt = 0x00; - pt++; - ava--; - } - -#ifdef WOLFSSL_DEBUG_MEMORY - fprintf(stderr, "Allocated %d bytes for static memory @ %p\n", ava, pt); -#endif - - /* divide into chunks of memory and add them to available list */ - while (ava >= (heap->sizeList[0] + padSz + memSz)) { - /* creating only IO buffers from memory passed in, max TLS is 16k */ - if (flag & WOLFMEM_IO_POOL || flag & WOLFMEM_IO_POOL_FIXED) { - if ((ret = create_memory_buckets(pt, ava, - WOLFMEM_IO_SZ, 1, &(heap->io))) < 0) { - WOLFSSL_LEAVE("wolfSSL_load_static_memory", ret); - return ret; - } - - /* check if no more room left for creating IO buffers */ - if (ret == 0) { - break; - } - - /* advance pointer in buffer for next buckets and keep track - of how much memory is left available */ - pt += ret; - ava -= ret; - } - else { - int i; - /* start at largest and move to smaller buckets */ - for (i = (WOLFMEM_MAX_BUCKETS - 1); i >= 0; i--) { - if ((heap->sizeList[i] + padSz + memSz) <= ava) { - if ((ret = create_memory_buckets(pt, ava, heap->sizeList[i], - heap->distList[i], &(heap->ava[i]))) < 0) { - WOLFSSL_LEAVE("wolfSSL_load_static_memory", ret); - return ret; - } - - /* advance pointer in buffer for next buckets and keep track - of how much memory is left available */ - pt += ret; - ava -= ret; - } - } - } - } - - return 1; + return wc_LoadStaticMemory_ex(pHint, + WOLFMEM_DEF_BUCKETS, sizeList, distList, + buf, sz, flag, maxSz); } diff --git a/wolfssl/wolfcrypt/memory.h b/wolfssl/wolfcrypt/memory.h index 9a1d7b06d..9e3aec05c 100644 --- a/wolfssl/wolfcrypt/memory.h +++ b/wolfssl/wolfcrypt/memory.h @@ -216,12 +216,12 @@ WOLFSSL_API int wolfSSL_GetAllocators(wolfSSL_Malloc_cb* mf, byte haFlag; /* flag used for checking handshake count */ } WOLFSSL_HEAP_HINT; + WOLFSSL_API int wc_LoadStaticMemory_ex(WOLFSSL_HEAP_HINT** pHint, + unsigned int listSz, unsigned int *sizeList, unsigned int *distList, + unsigned char* buf, unsigned int sz, int flag, int max); WOLFSSL_API int wc_LoadStaticMemory(WOLFSSL_HEAP_HINT** pHint, unsigned char* buf, unsigned int sz, int flag, int max); - WOLFSSL_LOCAL int wolfSSL_init_memory_heap(WOLFSSL_HEAP* heap); - WOLFSSL_LOCAL int wolfSSL_load_static_memory(byte* buffer, word32 sz, - int flag, WOLFSSL_HEAP* heap); WOLFSSL_LOCAL int wolfSSL_GetMemStats(WOLFSSL_HEAP* heap, WOLFSSL_MEM_STATS* stats); WOLFSSL_LOCAL int SetFixedIO(WOLFSSL_HEAP* heap, wc_Memory** io); From 15a0ae4244602f6fcc44c54a2ad4ed58c5b47178 Mon Sep 17 00:00:00 2001 From: John Safranek Date: Thu, 11 Apr 2024 13:59:28 -0700 Subject: [PATCH 3/8] Generic Memory Pools 1. Add generic function wolfSSL_StaticBufferSz_ex() where one specifies the memory bucket list sizes and distribution. 2. Rewrote wolfSSL_StaticBufferSz() in terms of the new function. 3. Changed the list pointers on wc_LoadStaticMemory_ex() and wc_init_memory_heap() to be pointers to const. --- wolfcrypt/src/memory.c | 40 +++++++++++++++++++++++++------------- wolfssl/wolfcrypt/memory.h | 8 ++++++-- 2 files changed, 32 insertions(+), 16 deletions(-) diff --git a/wolfcrypt/src/memory.c b/wolfcrypt/src/memory.c index 5e37f6db1..872d6512f 100644 --- a/wolfcrypt/src/memory.c +++ b/wolfcrypt/src/memory.c @@ -633,7 +633,7 @@ static int wc_partition_static_memory(byte* buffer, word32 sz, int flag, } static int wc_init_memory_heap(WOLFSSL_HEAP* heap, unsigned int listSz, - unsigned int* sizeList, unsigned int* distList) + const unsigned int* sizeList, const unsigned int* distList) { if (heap == NULL || listSz > WOLFMEM_MAX_BUCKETS) { return BAD_FUNC_ARG; @@ -653,9 +653,9 @@ static int wc_init_memory_heap(WOLFSSL_HEAP* heap, unsigned int listSz, } int wc_LoadStaticMemory_ex(WOLFSSL_HEAP_HINT** pHint, - unsigned int listSz, - unsigned int* memSzList, unsigned int* memDistList, - unsigned char* buf, unsigned int sz, int flag, int maxSz) + unsigned int listSz, const unsigned int* memSzList, + const unsigned int* memDistList, unsigned char* buf, + unsigned int sz, int flag, int maxSz) { WOLFSSL_HEAP* heap = NULL; WOLFSSL_HEAP_HINT* hint = NULL; @@ -743,17 +743,16 @@ int wolfSSL_MemoryPaddingSz(void) /* Used to calculate memory size for optimum use with buckets. returns the suggested size rounded down to the nearest bucket. */ -int wolfSSL_StaticBufferSz(byte* buffer, word32 sz, int flag) +int wolfSSL_StaticBufferSz_ex(unsigned int listSz, + const unsigned int *sizeList, const unsigned int *distList, + byte* buffer, word32 sz, int flag) { - word32 bucketSz[WOLFMEM_MAX_BUCKETS] = {WOLFMEM_BUCKETS}; - word32 distList[WOLFMEM_MAX_BUCKETS] = {WOLFMEM_DIST}; - word32 ava = sz; byte* pt = buffer; word32 memSz = (word32)sizeof(wc_Memory); word32 padSz = -(int)memSz & (WOLFSSL_STATIC_ALIGN - 1); - WOLFSSL_ENTER("wolfSSL_static_size"); + WOLFSSL_ENTER("wolfSSL_StaticBufferSz_ex"); if (buffer == NULL) { return BAD_FUNC_ARG; @@ -776,26 +775,39 @@ int wolfSSL_StaticBufferSz(byte* buffer, word32 sz, int flag) else { int i, k; - if (ava < (bucketSz[0] + padSz + memSz)) { + if (ava < (sizeList[0] + padSz + memSz)) { return 0; /* not enough room for even one bucket */ } - while ((ava >= (bucketSz[0] + padSz + memSz)) && (ava > 0)) { + while ((ava >= (sizeList[0] + padSz + memSz)) && (ava > 0)) { /* start at largest and move to smaller buckets */ - for (i = (WOLFMEM_MAX_BUCKETS - 1); i >= 0; i--) { + for (i = (listSz- 1); i >= 0; i--) { for (k = distList[i]; k > 0; k--) { - if ((bucketSz[i] + padSz + memSz) <= ava) { - ava -= bucketSz[i] + padSz + memSz; + if ((sizeList[i] + padSz + memSz) <= ava) { + ava -= sizeList[i] + padSz + memSz; } } } } } + WOLFSSL_LEAVE("wolfSSL_StaticBufferSz_ex", sz - ava); return sz - ava; /* round down */ } +/* Calls wolfSSL_StaticBufferSz_ex with the static memory pool config + * used by wolfSSL by default. */ +int wolfSSL_StaticBufferSz(byte* buffer, word32 sz, int flag) +{ + word32 bucketSz[WOLFMEM_MAX_BUCKETS] = {WOLFMEM_BUCKETS}; + word32 distList[WOLFMEM_MAX_BUCKETS] = {WOLFMEM_DIST}; + + return wolfSSL_StaticBufferSz_ex(WOLFMEM_MAX_BUCKETS, bucketSz, distList, + buffer, sz, flag); +} + + int FreeFixedIO(WOLFSSL_HEAP* heap, wc_Memory** io) { WOLFSSL_MSG("Freeing fixed IO buffer"); diff --git a/wolfssl/wolfcrypt/memory.h b/wolfssl/wolfcrypt/memory.h index 9e3aec05c..f4c8248c2 100644 --- a/wolfssl/wolfcrypt/memory.h +++ b/wolfssl/wolfcrypt/memory.h @@ -217,8 +217,9 @@ WOLFSSL_API int wolfSSL_GetAllocators(wolfSSL_Malloc_cb* mf, } WOLFSSL_HEAP_HINT; WOLFSSL_API int wc_LoadStaticMemory_ex(WOLFSSL_HEAP_HINT** pHint, - unsigned int listSz, unsigned int *sizeList, unsigned int *distList, - unsigned char* buf, unsigned int sz, int flag, int max); + unsigned int listSz, const unsigned int *sizeList, + const unsigned int *distList, unsigned char* buf, unsigned int sz, + int flag, int max); WOLFSSL_API int wc_LoadStaticMemory(WOLFSSL_HEAP_HINT** pHint, unsigned char* buf, unsigned int sz, int flag, int max); @@ -227,6 +228,9 @@ WOLFSSL_API int wolfSSL_GetAllocators(wolfSSL_Malloc_cb* mf, WOLFSSL_LOCAL int SetFixedIO(WOLFSSL_HEAP* heap, wc_Memory** io); WOLFSSL_LOCAL int FreeFixedIO(WOLFSSL_HEAP* heap, wc_Memory** io); + WOLFSSL_API int wolfSSL_StaticBufferSz_ex(unsigned int listSz, + const unsigned int *sizeList, const unsigned int *distList, + byte* buffer, word32 sz, int flag); WOLFSSL_API int wolfSSL_StaticBufferSz(byte* buffer, word32 sz, int flag); WOLFSSL_API int wolfSSL_MemoryPaddingSz(void); #endif /* WOLFSSL_STATIC_MEMORY */ From 7a0bcb05fb808bf72f7e00d24a40887d68c4bd38 Mon Sep 17 00:00:00 2001 From: John Safranek Date: Fri, 12 Apr 2024 09:31:40 -0700 Subject: [PATCH 4/8] Generic Memory Pools 1. Add checks for listSz against WOLFMEM_MAX_BUCKETS. 2. Use WOLFMEM_DEF_BUCKETS for the size when using the default memory descriptions. 3. Whitespace. --- wolfcrypt/src/memory.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/wolfcrypt/src/memory.c b/wolfcrypt/src/memory.c index 872d6512f..1d1405cf3 100644 --- a/wolfcrypt/src/memory.c +++ b/wolfcrypt/src/memory.c @@ -662,7 +662,7 @@ int wc_LoadStaticMemory_ex(WOLFSSL_HEAP_HINT** pHint, word32 idx = 0; int ret; - if (pHint == NULL || buf == NULL) { + if (pHint == NULL || buf == NULL || listSz > WOLFMEM_MAX_BUCKETS) { return BAD_FUNC_ARG; } @@ -754,7 +754,7 @@ int wolfSSL_StaticBufferSz_ex(unsigned int listSz, WOLFSSL_ENTER("wolfSSL_StaticBufferSz_ex"); - if (buffer == NULL) { + if (buffer == NULL || listSz > WOLFMEM_MAX_BUCKETS) { return BAD_FUNC_ARG; } @@ -781,7 +781,7 @@ int wolfSSL_StaticBufferSz_ex(unsigned int listSz, while ((ava >= (sizeList[0] + padSz + memSz)) && (ava > 0)) { /* start at largest and move to smaller buckets */ - for (i = (listSz- 1); i >= 0; i--) { + for (i = (listSz - 1); i >= 0; i--) { for (k = distList[i]; k > 0; k--) { if ((sizeList[i] + padSz + memSz) <= ava) { ava -= sizeList[i] + padSz + memSz; @@ -800,10 +800,10 @@ int wolfSSL_StaticBufferSz_ex(unsigned int listSz, * used by wolfSSL by default. */ int wolfSSL_StaticBufferSz(byte* buffer, word32 sz, int flag) { - word32 bucketSz[WOLFMEM_MAX_BUCKETS] = {WOLFMEM_BUCKETS}; - word32 distList[WOLFMEM_MAX_BUCKETS] = {WOLFMEM_DIST}; + word32 bucketSz[WOLFMEM_DEF_BUCKETS] = {WOLFMEM_BUCKETS}; + word32 distList[WOLFMEM_DEF_BUCKETS] = {WOLFMEM_DIST}; - return wolfSSL_StaticBufferSz_ex(WOLFMEM_MAX_BUCKETS, bucketSz, distList, + return wolfSSL_StaticBufferSz_ex(WOLFMEM_DEF_BUCKETS, bucketSz, distList, buffer, sz, flag); } From 0b5c83f589c71db7fdaff5251bb03dc4224890d4 Mon Sep 17 00:00:00 2001 From: John Safranek Date: Fri, 12 Apr 2024 14:10:19 -0700 Subject: [PATCH 5/8] Generic Memory Pools 1. Make the function wolfSSL_GetMemStats() public. --- wolfssl/wolfcrypt/memory.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wolfssl/wolfcrypt/memory.h b/wolfssl/wolfcrypt/memory.h index f4c8248c2..fe32e46a8 100644 --- a/wolfssl/wolfcrypt/memory.h +++ b/wolfssl/wolfcrypt/memory.h @@ -223,7 +223,7 @@ WOLFSSL_API int wolfSSL_GetAllocators(wolfSSL_Malloc_cb* mf, WOLFSSL_API int wc_LoadStaticMemory(WOLFSSL_HEAP_HINT** pHint, unsigned char* buf, unsigned int sz, int flag, int max); - WOLFSSL_LOCAL int wolfSSL_GetMemStats(WOLFSSL_HEAP* heap, + WOLFSSL_API int wolfSSL_GetMemStats(WOLFSSL_HEAP* heap, WOLFSSL_MEM_STATS* stats); WOLFSSL_LOCAL int SetFixedIO(WOLFSSL_HEAP* heap, wc_Memory** io); WOLFSSL_LOCAL int FreeFixedIO(WOLFSSL_HEAP* heap, wc_Memory** io); From d23994862ceaa4c6471532c667edc5b45cd6bdbf Mon Sep 17 00:00:00 2001 From: John Safranek Date: Fri, 26 Apr 2024 15:08:17 -0700 Subject: [PATCH 6/8] Generic Memory Pools 1. Added some extra parameter checking to wc_LoadStaticMemory_ex(). 2. Added some extra parameter checking to wc_StaticBufferSz_ex(). 3. Rename some parameters and add some logging prints. 4. Some static functions have some parameter checking and they are only calling in one spot, remove it. --- wolfcrypt/src/memory.c | 35 +++++++++++++++++------------------ 1 file changed, 17 insertions(+), 18 deletions(-) diff --git a/wolfcrypt/src/memory.c b/wolfcrypt/src/memory.c index 1d1405cf3..599da117b 100644 --- a/wolfcrypt/src/memory.c +++ b/wolfcrypt/src/memory.c @@ -573,10 +573,6 @@ static int wc_partition_static_memory(byte* buffer, word32 sz, int flag, WOLFSSL_ENTER("wc_partition_static_memory"); - if (buffer == NULL) { - return BAD_FUNC_ARG; - } - /* align pt */ while ((wc_ptr_t)pt % WOLFSSL_STATIC_ALIGN && pt < (buffer + sz)) { *pt = 0x00; @@ -593,7 +589,7 @@ static int wc_partition_static_memory(byte* buffer, word32 sz, int flag, /* creating only IO buffers from memory passed in, max TLS is 16k */ if (flag & WOLFMEM_IO_POOL || flag & WOLFMEM_IO_POOL_FIXED) { if ((ret = wc_create_memory_buckets(pt, ava, - WOLFMEM_IO_SZ, 1, &(heap->io))) < 0) { + WOLFMEM_IO_SZ, 1, &(heap->io))) < 0) { WOLFSSL_LEAVE("wc_partition_static_memory", ret); return ret; } @@ -635,10 +631,6 @@ static int wc_partition_static_memory(byte* buffer, word32 sz, int flag, static int wc_init_memory_heap(WOLFSSL_HEAP* heap, unsigned int listSz, const unsigned int* sizeList, const unsigned int* distList) { - if (heap == NULL || listSz > WOLFMEM_MAX_BUCKETS) { - return BAD_FUNC_ARG; - } - XMEMSET(heap, 0, sizeof(WOLFSSL_HEAP)); XMEMCPY(heap->sizeList, sizeList, listSz * sizeof(sizeList[0])); @@ -653,8 +645,8 @@ static int wc_init_memory_heap(WOLFSSL_HEAP* heap, unsigned int listSz, } int wc_LoadStaticMemory_ex(WOLFSSL_HEAP_HINT** pHint, - unsigned int listSz, const unsigned int* memSzList, - const unsigned int* memDistList, unsigned char* buf, + unsigned int listSz, const unsigned int* sizeList, + const unsigned int* distList, unsigned char* buf, unsigned int sz, int flag, int maxSz) { WOLFSSL_HEAP* heap = NULL; @@ -662,11 +654,15 @@ int wc_LoadStaticMemory_ex(WOLFSSL_HEAP_HINT** pHint, word32 idx = 0; int ret; - if (pHint == NULL || buf == NULL || listSz > WOLFMEM_MAX_BUCKETS) { + WOLFSSL_ENTER("wc_LoadStaticMemory_ex"); + + if (pHint == NULL || buf == NULL || listSz > WOLFMEM_MAX_BUCKETS + || sizeList == NULL || distList == NULL) { return BAD_FUNC_ARG; } if ((sizeof(WOLFSSL_HEAP) + sizeof(WOLFSSL_HEAP_HINT)) > sz - idx) { + WOLFSSL_MSG("Not enough memory for partition tracking"); return BUFFER_E; /* not enough memory for structures */ } @@ -677,7 +673,7 @@ int wc_LoadStaticMemory_ex(WOLFSSL_HEAP_HINT** pHint, hint = (WOLFSSL_HEAP_HINT*)(buf + idx); idx += sizeof(WOLFSSL_HEAP_HINT); - ret = wc_init_memory_heap(heap, listSz, memSzList, memDistList); + ret = wc_init_memory_heap(heap, listSz, sizeList, distList); if (ret != 0) { return ret; } @@ -700,7 +696,7 @@ int wc_LoadStaticMemory_ex(WOLFSSL_HEAP_HINT** pHint, ret = wc_partition_static_memory(buf + idx, sz - idx, flag, heap); if (ret != 1) { WOLFSSL_MSG("Error partitioning memory"); - return -1; + return MEMORY_E; } /* determine what max applies too */ @@ -714,8 +710,6 @@ int wc_LoadStaticMemory_ex(WOLFSSL_HEAP_HINT** pHint, heap->flag |= flag; *pHint = hint; - (void)maxSz; - return 0; } @@ -724,10 +718,14 @@ int wc_LoadStaticMemory(WOLFSSL_HEAP_HINT** pHint, { word32 sizeList[WOLFMEM_DEF_BUCKETS] = { WOLFMEM_BUCKETS }; word32 distList[WOLFMEM_DEF_BUCKETS] = { WOLFMEM_DIST }; + int ret = 0; - return wc_LoadStaticMemory_ex(pHint, + WOLFSSL_ENTER("wc_LoadStaticMemory"); + ret = wc_LoadStaticMemory_ex(pHint, WOLFMEM_DEF_BUCKETS, sizeList, distList, buf, sz, flag, maxSz); + WOLFSSL_LEAVE("wc_LoadStaticMemory", ret); + return ret; } @@ -754,7 +752,8 @@ int wolfSSL_StaticBufferSz_ex(unsigned int listSz, WOLFSSL_ENTER("wolfSSL_StaticBufferSz_ex"); - if (buffer == NULL || listSz > WOLFMEM_MAX_BUCKETS) { + if (buffer == NULL || listSz > WOLFMEM_MAX_BUCKETS + || sizeList == NULL || distList == NULL) { return BAD_FUNC_ARG; } From f6ae432be11e7f2b04d0aa9c578d61ec01ad4e37 Mon Sep 17 00:00:00 2001 From: John Safranek Date: Mon, 29 Apr 2024 22:22:08 -0700 Subject: [PATCH 7/8] Generic Memory Pools 1. Add API test for function `wc_LoadStaticMemory_ex()`. --- tests/api.c | 87 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 87 insertions(+) diff --git a/tests/api.c b/tests/api.c index ad07619f7..3c7ebbe32 100644 --- a/tests/api.c +++ b/tests/api.c @@ -672,6 +672,91 @@ static int test_wolfCrypt_Cleanup(void) return EXPECT_RESULT(); } +static int test_wc_LoadStaticMemory_ex(void) +{ + EXPECT_DECLS; +#ifdef WOLFSSL_STATIC_MEMORY + byte staticMemory[440000]; + word32 sizeList[WOLFMEM_DEF_BUCKETS] = { WOLFMEM_BUCKETS }; + word32 distList[WOLFMEM_DEF_BUCKETS] = { WOLFMEM_DIST }; + WOLFSSL_HEAP_HINT* heap; + + /* Pass in zero everything. */ + ExpectIntEQ(wc_LoadStaticMemory_ex(NULL, 0, NULL, NULL, NULL, 0, 0, 0), + BAD_FUNC_ARG); + + /* Set the heap pointer to NULL. */ + ExpectIntEQ(wc_LoadStaticMemory_ex(NULL, + WOLFMEM_DEF_BUCKETS, sizeList, distList, + staticMemory, (word32)sizeof(staticMemory), + 0, 1), + BAD_FUNC_ARG); + + /* Set other pointer values to NULL one at a time. */ + heap = NULL; + ExpectIntEQ(wc_LoadStaticMemory_ex(&heap, + WOLFMEM_DEF_BUCKETS, NULL, distList, + staticMemory, (word32)sizeof(staticMemory), + 0, 1), + BAD_FUNC_ARG); + heap = NULL; + ExpectIntEQ(wc_LoadStaticMemory_ex(&heap, + WOLFMEM_DEF_BUCKETS, sizeList, NULL, + staticMemory, (word32)sizeof(staticMemory), + 0, 1), + BAD_FUNC_ARG); + heap = NULL; + ExpectIntEQ(wc_LoadStaticMemory_ex(&heap, + WOLFMEM_DEF_BUCKETS, sizeList, distList, + NULL, (word32)sizeof(staticMemory), + 0, 1), + BAD_FUNC_ARG); + /* Set the size of the static buffer to 0. */ + heap = NULL; + ExpectIntEQ(wc_LoadStaticMemory_ex(&heap, + WOLFMEM_DEF_BUCKETS, sizeList, distList, + staticMemory, 0, + 0, 1), + BUFFER_E); + + /* Set the size of the static buffer to one less than minimum allowed. */ + heap = NULL; + ExpectIntEQ(wc_LoadStaticMemory_ex(&heap, + WOLFMEM_DEF_BUCKETS, sizeList, distList, + staticMemory, + (word32)(sizeof(WOLFSSL_HEAP) + sizeof(WOLFSSL_HEAP_HINT)) - 1, + 0, 1), + BUFFER_E); + + /* Set the number of buckets to 1 too many allowed. */ + heap = NULL; + ExpectIntEQ(wc_LoadStaticMemory_ex(&heap, + WOLFMEM_MAX_BUCKETS+1, sizeList, distList, + staticMemory, (word32)sizeof(staticMemory), + 0, 1), + BAD_FUNC_ARG); + + /* Set the size of the static buffer to exactly the minimum size. */ + heap = NULL; + ExpectIntEQ(wc_LoadStaticMemory_ex(&heap, + WOLFMEM_DEF_BUCKETS, sizeList, distList, + staticMemory, + (word32)(sizeof(WOLFSSL_HEAP) + sizeof(WOLFSSL_HEAP_HINT)), + 0, 1), + 0); + + /* Success case. */ + heap = NULL; + ExpectIntEQ(wc_LoadStaticMemory_ex(&heap, + WOLFMEM_DEF_BUCKETS, sizeList, distList, + staticMemory, (word32)sizeof(staticMemory), + 0, 1), + 0); +#endif /* WOLFSSL_STATIC_MEMORY */ + return EXPECT_RESULT(); +} + + /*----------------------------------------------------------------------------* | Platform dependent function test *----------------------------------------------------------------------------*/ @@ -71565,6 +71650,8 @@ TEST_CASE testCases[] = { TEST_DECL(test_wolfCrypt_Init), + TEST_DECL(test_wc_LoadStaticMemory_ex), + /* Locking with Compat Mutex */ TEST_DECL(test_wc_SetMutexCb), TEST_DECL(test_wc_LockMutex_ex), From 6be55269db0f19df83ebcce0d0b498694f61e4a4 Mon Sep 17 00:00:00 2001 From: John Safranek Date: Mon, 29 Apr 2024 22:22:08 -0700 Subject: [PATCH 8/8] Generic Memory Pools 1. Add API for function `wc_UnloadStaticMemory()` which frees the mutex used by the static memory pool. 2. Update the `wc_LoadStaticMemory_ex()` test to free the static memory pool's mutex on each successful test case. --- tests/api.c | 2 ++ wolfcrypt/src/memory.c | 9 +++++++++ wolfssl/wolfcrypt/memory.h | 1 + 3 files changed, 12 insertions(+) diff --git a/tests/api.c b/tests/api.c index 3c7ebbe32..68b1d0c50 100644 --- a/tests/api.c +++ b/tests/api.c @@ -744,6 +744,7 @@ static int test_wc_LoadStaticMemory_ex(void) (word32)(sizeof(WOLFSSL_HEAP) + sizeof(WOLFSSL_HEAP_HINT)), 0, 1), 0); + wc_UnloadStaticMemory(heap); /* Success case. */ heap = NULL; @@ -752,6 +753,7 @@ static int test_wc_LoadStaticMemory_ex(void) staticMemory, (word32)sizeof(staticMemory), 0, 1), 0); + wc_UnloadStaticMemory(heap); #endif /* WOLFSSL_STATIC_MEMORY */ return EXPECT_RESULT(); } diff --git a/wolfcrypt/src/memory.c b/wolfcrypt/src/memory.c index 599da117b..61fe735b6 100644 --- a/wolfcrypt/src/memory.c +++ b/wolfcrypt/src/memory.c @@ -729,6 +729,15 @@ int wc_LoadStaticMemory(WOLFSSL_HEAP_HINT** pHint, } +void wc_UnloadStaticMemory(WOLFSSL_HEAP_HINT* heap) +{ + WOLFSSL_ENTER("wc_UnloadStaticMemory"); + if (heap != NULL && heap->memory != NULL) { + wc_FreeMutex(&heap->memory->memory_mutex); + } +} + + /* returns the size of management memory needed for each bucket. * This is memory that is used to keep track of and align memory buckets. */ int wolfSSL_MemoryPaddingSz(void) diff --git a/wolfssl/wolfcrypt/memory.h b/wolfssl/wolfcrypt/memory.h index fe32e46a8..f0ce53ab1 100644 --- a/wolfssl/wolfcrypt/memory.h +++ b/wolfssl/wolfcrypt/memory.h @@ -222,6 +222,7 @@ WOLFSSL_API int wolfSSL_GetAllocators(wolfSSL_Malloc_cb* mf, int flag, int max); WOLFSSL_API int wc_LoadStaticMemory(WOLFSSL_HEAP_HINT** pHint, unsigned char* buf, unsigned int sz, int flag, int max); + WOLFSSL_API void wc_UnloadStaticMemory(WOLFSSL_HEAP_HINT* heap); WOLFSSL_API int wolfSSL_GetMemStats(WOLFSSL_HEAP* heap, WOLFSSL_MEM_STATS* stats);