Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Generic Memory Pools #7418

Merged
merged 8 commits into from
Apr 30, 2024
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 13 additions & 47 deletions src/ssl.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -2584,62 +2582,30 @@ 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 (*ctx && (*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 there is a heap already, capture it in hint. */
if (*ctx && (*ctx)->heap != NULL) {
hint = (*ctx)->heap;
}

if (wolfSSL_load_static_memory(buf + idx, sz - idx, flag, heap) != 1) {
WOLFSSL_MSG("Error partitioning memory");
if (wc_LoadStaticMemory(&hint, buf, sz, flag, maxSz)) {
WOLFSSL_MSG("Error loading static memory");
return WOLFSSL_FAILURE;
}

/* create ctx if needed */
if (*ctx == NULL) {
if (*ctx) {
if ((*ctx)->heap == NULL) {
(*ctx)->heap = (void*)hint;
}
}
else {
/* create ctx if needed */
*ctx = wolfSSL_CTX_new_ex(method(hint), hint);
if (*ctx == NULL) {
WOLFSSL_MSG("Error creating ctx");
return WOLFSSL_FAILURE;
}
}

/* 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;
}

Expand Down
206 changes: 115 additions & 91 deletions wolfcrypt/src/memory.c
Original file line number Diff line number Diff line change
Expand Up @@ -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,
billphipps marked this conversation as resolved.
Show resolved Hide resolved
word32 buckSz, word32 buckNum, wc_Memory** list) {
word32 i;
byte* pt = buffer;
Expand Down Expand Up @@ -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,
const unsigned int* sizeList, const unsigned int* distList)
{
if (heap == NULL || listSz > WOLFMEM_MAX_BUCKETS) {
billphipps marked this conversation as resolved.
Show resolved Hide resolved
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");
Expand All @@ -584,15 +652,17 @@ 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, const unsigned int* memSzList,
const unsigned int* memDistList, 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) {
if (pHint == NULL || buf == NULL || listSz > WOLFMEM_MAX_BUCKETS) {
return BAD_FUNC_ARG;
}

Expand All @@ -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;
}
Expand All @@ -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;
Expand All @@ -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);

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;
}
}
}
}
word32 sizeList[WOLFMEM_DEF_BUCKETS] = { WOLFMEM_BUCKETS };
word32 distList[WOLFMEM_DEF_BUCKETS] = { WOLFMEM_DIST };

billphipps marked this conversation as resolved.
Show resolved Hide resolved
return 1;
return wc_LoadStaticMemory_ex(pHint,
WOLFMEM_DEF_BUCKETS, sizeList, distList,
buf, sz, flag, maxSz);
}


Expand All @@ -731,19 +743,18 @@ 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) {
if (buffer == NULL || listSz > WOLFMEM_MAX_BUCKETS) {
billphipps marked this conversation as resolved.
Show resolved Hide resolved
return BAD_FUNC_ARG;
}

Expand All @@ -764,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_DEF_BUCKETS] = {WOLFMEM_BUCKETS};
word32 distList[WOLFMEM_DEF_BUCKETS] = {WOLFMEM_DIST};

return wolfSSL_StaticBufferSz_ex(WOLFMEM_DEF_BUCKETS, bucketSz, distList,
buffer, sz, flag);
}


int FreeFixedIO(WOLFSSL_HEAP* heap, wc_Memory** io)
{
WOLFSSL_MSG("Freeing fixed IO buffer");
Expand Down
Loading