add helper functions for choosing static buffer size

This commit is contained in:
Jacob Barthelmeh
2016-07-21 12:11:15 -06:00
parent b81e687bf3
commit e8f7d78fc4
5 changed files with 198 additions and 17 deletions

View File

@ -632,6 +632,18 @@ THREAD_RETURN CYASSL_THREAD server_test(void* args)
err_sys("unable to get method");
#ifdef WOLFSSL_STATIC_MEMORY
#ifdef DEBUG_WOLFSSL
/* print off helper buffer sizes for use with static memory
* printing to stderr incase of debug mode turned on */
fprintf(stderr, "static memory management size = %d\n",
wolfSSL_MemoryPaddingSz());
fprintf(stderr, "calculated optimum general buffer size = %d\n",
wolfSSL_StaticBufferSz(memory, sizeof(memory), 0));
fprintf(stderr, "calculated optimum IO buffer size = %d\n",
wolfSSL_StaticBufferSz(memoryIO, sizeof(memoryIO),
WOLFMEM_IO_POOL_FIXED));
#endif /* DEBUG_WOLFSSL */
if (wolfSSL_CTX_load_static_memory(&ctx, method, memory, sizeof(memory),0,1)
!= SSL_SUCCESS)
err_sys("unable to load static memory and create ctx");

View File

@ -643,16 +643,8 @@ int wolfSSL_GetObjectSize(void)
int wolfSSL_init_memory_heap(WOLFSSL_HEAP* heap)
{
/* default size of chunks of memory to seperate into
* having session certs enabled makes a 21k SSL struct */
#ifndef SESSION_CERTS
word32 wc_defaultMemSz[WOLFMEM_DEF_BUCKETS] =
{ 64, 128, 256, 512, 1024, 2432, 3456, 4544, 16128 };
#else
word32 wc_defaultMemSz[WOLFMEM_DEF_BUCKETS] =
{ 64, 128, 256, 512, 1024, 2432, 3456, 4544, 21056 };
#endif
word32 wc_defaultDist[WOLFMEM_DEF_BUCKETS] = { 8, 4, 4, 12, 4, 5, 2, 1, 1 };
word32 wc_MemSz[WOLFMEM_DEF_BUCKETS] = { WOLFMEM_BUCKETS };
word32 wc_Dist[WOLFMEM_DEF_BUCKETS] = { WOLFMEM_DIST };
if (heap == NULL) {
return BAD_FUNC_ARG;
@ -660,11 +652,8 @@ int wolfSSL_init_memory_heap(WOLFSSL_HEAP* heap)
XMEMSET(heap, 0, sizeof(WOLFSSL_HEAP));
/* default pool sizes and distribution, else leave a 0's for now */
#if WOLFMEM_DEF_BUCKETS == WOLFMEM_MAX_BUCKETS
XMEMCPY(heap->sizeList, wc_defaultMemSz, sizeof(wc_defaultMemSz));
XMEMCPY(heap->distList, wc_defaultDist, sizeof(wc_defaultMemSz));
#endif
XMEMCPY(heap->sizeList, wc_MemSz, sizeof(wc_MemSz));
XMEMCPY(heap->distList, wc_Dist, sizeof(wc_Dist));
if (InitMutex(&(heap->memory_mutex)) != 0) {
WOLFSSL_MSG("Error creating heap memory mutex");

View File

@ -263,6 +263,62 @@ int wolfSSL_load_static_memory(byte* buffer, word32 sz, int flag,
}
/* 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)
{
word32 memSz = (word32)sizeof(wc_Memory);
word32 padSz = -(int)memSz & (WOLFSSL_STATIC_ALIGN - 1);
return memSz + padSz;
}
/* 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)
{
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");
if (buffer == NULL) {
return BAD_FUNC_ARG;
}
/* align pt */
while ((wolfssl_word)pt % WOLFSSL_STATIC_ALIGN && pt < (buffer + sz)) {
pt++;
ava--;
}
/* creating only IO buffers from memory passed in, max TLS is 16k */
if (flag & WOLFMEM_IO_POOL || flag & WOLFMEM_IO_POOL_FIXED) {
ava = sz % (memSz + padSz + WOLFMEM_IO_SZ);
}
else {
int i, k;
while ((ava >= (bucketSz[0] + padSz + memSz)) && (ava > 0)) {
/* start at largest and move to smaller buckets */
for (i = (WOLFMEM_MAX_BUCKETS - 1); i >= 0; i--) {
for (k = distList[i]; k > 0; k--) {
if ((bucketSz[i] + padSz + memSz) <= ava) {
ava -= bucketSz[i] + padSz + memSz;
}
}
}
}
}
return sz - ava; /* round down */
}
int FreeFixedIO(WOLFSSL_HEAP* heap, wc_Memory** io)
{
WOLFSSL_MSG("Freeing fixed IO buffer");

View File

@ -248,6 +248,9 @@ int certext_test(void);
#ifdef HAVE_IDEA
int idea_test(void);
#endif
#ifdef WOLFSSL_STATIC_MEMORY
int memory_test(void);
#endif
/* General big buffer size for many tests. */
#define FOURK_BUF 4096
@ -532,6 +535,13 @@ int wolfcrypt_test(void* args)
else
printf( "RANDOM test passed!\n");
#ifdef WOLFSSL_STATIC_MEMORY
if ( (ret = memory_test()) != 0)
return err_sys("MEMORY test failed!\n", ret);
else
printf( "MEMORY test passed!\n");
#endif
#ifndef NO_RSA
if ( (ret = rsa_test()) != 0)
return err_sys("RSA test failed!\n", ret);
@ -3857,6 +3867,101 @@ int random_test(void)
#endif /* (HAVE_HASHDRBG || NO_RC4) && !CUSTOM_RAND_GENERATE_BLOCK */
#ifdef WOLFSSL_STATIC_MEMORY
int memory_test(void)
{
int ret = 0;
unsigned int i;
word32 size[] = { WOLFMEM_BUCKETS };
word32 dist[] = { WOLFMEM_DIST };
byte buffer[30000]; /* make large enough to involve many bucket sizes */
/* check macro settings */
if (sizeof(size)/sizeof(word32) != WOLFMEM_MAX_BUCKETS) {
return -97;
}
if (sizeof(dist)/sizeof(word32) != WOLFMEM_MAX_BUCKETS) {
return -98;
}
for (i = 0; i < WOLFMEM_MAX_BUCKETS; i++) {
if ((size[i] % WOLFSSL_STATIC_ALIGN) != 0) {
/* each element in array should be divisable by alignment size */
return -99;
}
}
for (i = 1; i < WOLFMEM_MAX_BUCKETS; i++) {
if (size[i - 1] >= size[i]) {
return -100; /* sizes should be in increasing order */
}
}
/* check that padding size returned is possible */
if (wolfSSL_MemoryPaddingSz() <= WOLFSSL_STATIC_ALIGN) {
return -101; /* no room for wc_Memory struct */
}
if (wolfSSL_MemoryPaddingSz() < 0) {
return -102;
}
if (wolfSSL_MemoryPaddingSz() % WOLFSSL_STATIC_ALIGN != 0) {
return -103; /* not aligned! */
}
/* check function to return optimum buffer size (rounded down) */
if ((ret = wolfSSL_StaticBufferSz(buffer, sizeof(buffer), WOLFMEM_GENERAL))
% WOLFSSL_STATIC_ALIGN != 0) {
return -104; /* not aligned! */
}
if (ret < 0) {
return -105;
}
if ((unsigned int)ret > sizeof(buffer)) {
return -106; /* did not round down as expected */
}
if (ret != wolfSSL_StaticBufferSz(buffer, ret, WOLFMEM_GENERAL)) {
return -107; /* retrun value changed when using suggested value */
}
ret = wolfSSL_MemoryPaddingSz();
if (wolfSSL_StaticBufferSz(buffer, size[0] + ret + 1, WOLFMEM_GENERAL) !=
(ret + (int)size[0])) {
return -108; /* did not round down to nearest bucket value */
}
ret = wolfSSL_StaticBufferSz(buffer, sizeof(buffer), WOLFMEM_IO_POOL);
if (ret < 0) {
return -109;
}
if ((ret % (WOLFMEM_IO_SZ + wolfSSL_MemoryPaddingSz())) != 0) {
return -110; /* not even chunks of memory for IO size */
}
if ((ret % WOLFSSL_STATIC_ALIGN) != 0) {
return -111; /* memory not aligned */
}
/* check for passing bad or unknown argments to functions */
if (wolfSSL_StaticBufferSz(NULL, 1, WOLFMEM_GENERAL) > 0) {
return -112;
}
if (wolfSSL_StaticBufferSz(buffer, 1, WOLFMEM_GENERAL) != 0) {
return -113; /* should round to 0 since struct + bucket will not fit */
}
return 0;
}
#endif /* WOLFSSL_STATIC_MEMORY */
#ifdef HAVE_NTRU
byte GetEntropy(ENTROPY_CMD cmd, byte* out);

View File

@ -71,10 +71,26 @@ WOLFSSL_API int wolfSSL_SetAllocators(wolfSSL_Malloc_cb malloc_function,
#ifdef WOLFSSL_STATIC_MEMORY
#define WOLFSSL_STATIC_TIMEOUT 1
#define WOLFSSL_STATIC_ALIGN 16
#define WOLFMEM_MAX_BUCKETS 9
#ifndef WOLFSSL_STATIC_ALIGN
#define WOLFSSL_STATIC_ALIGN 16
#endif
#ifndef WOLFMEM_MAX_BUCKETS
#define WOLFMEM_MAX_BUCKETS 9
#endif
#define WOLFMEM_DEF_BUCKETS 9 /* number of default memory blocks */
#define WOLFMEM_IO_SZ 16992 /* 16 byte aligned */
#ifndef WOLFMEM_BUCKETS
/* default size of chunks of memory to seperate into
* having session certs enabled makes a 21k SSL struct */
#ifndef SESSION_CERTS
#define WOLFMEM_BUCKETS 64,128,256,512,1024,2432,3456,4544,16128
#else
#define WOLFMEM_BUCKETS 64,128,256,512,1024,2432,3456,4544,21056
#endif
#endif
#ifndef WOLFMEM_DIST
#define WOLFMEM_DIST 8,4,4,12,4,5,2,1,1
#endif
/* flags for loading static memory (one hot bit) */
#define WOLFMEM_GENERAL 0x01
@ -147,6 +163,9 @@ WOLFSSL_API int wolfSSL_SetAllocators(wolfSSL_Malloc_cb malloc_function,
WOLFSSL_MEM_STATS* stats);
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(byte* buffer, word32 sz, int flag);
WOLFSSL_API int wolfSSL_MemoryPaddingSz(void);
#endif /* WOLFSSL_STATIC_MEMORY */
#ifdef __cplusplus