wolfSSL SSL/TLS library, support up to TLS1.3
Dependents: CyaSSL-Twitter-OAuth4Tw Example-client-tls-cert TwitterReader TweetTest ... more
memory.c
00001 /* memory.c 00002 * 00003 * Copyright (C) 2006-2020 wolfSSL Inc. 00004 * 00005 * This file is part of wolfSSL. 00006 * 00007 * wolfSSL is free software; you can redistribute it and/or modify 00008 * it under the terms of the GNU General Public License as published by 00009 * the Free Software Foundation; either version 2 of the License, or 00010 * (at your option) any later version. 00011 * 00012 * wolfSSL is distributed in the hope that it will be useful, 00013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00015 * GNU General Public License for more details. 00016 * 00017 * You should have received a copy of the GNU General Public License 00018 * along with this program; if not, write to the Free Software 00019 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA 00020 */ 00021 00022 00023 #ifdef HAVE_CONFIG_H 00024 #include <config.h> 00025 #endif 00026 00027 #include <wolfssl/wolfcrypt/settings.h> 00028 00029 /* check old macros @wc_fips */ 00030 #if defined(USE_CYASSL_MEMORY) && !defined(USE_WOLFSSL_MEMORY) 00031 #define USE_WOLFSSL_MEMORY 00032 #endif 00033 #if defined(CYASSL_MALLOC_CHECK) && !defined(WOLFSSL_MALLOC_CHECK) 00034 #define WOLFSSL_MALLOC_CHECK 00035 #endif 00036 00037 00038 /* 00039 Possible memory options: 00040 * NO_WOLFSSL_MEMORY: Disables wolf memory callback support. When not defined settings.h defines USE_WOLFSSL_MEMORY. 00041 * WOLFSSL_STATIC_MEMORY: Turns on the use of static memory buffers and functions. 00042 This allows for using static memory instead of dynamic. 00043 * WOLFSSL_STATIC_ALIGN: Define defaults to 16 to indicate static memory alignment. 00044 * HAVE_IO_POOL: Enables use of static thread safe memory pool for input/output buffers. 00045 * XMALLOC_OVERRIDE: Allows override of the XMALLOC, XFREE and XREALLOC macros. 00046 * XMALLOC_USER: Allows custom XMALLOC, XFREE and XREALLOC functions to be defined. 00047 * WOLFSSL_NO_MALLOC: Disables the fall-back case to use STDIO malloc/free when no callbacks are set. 00048 * WOLFSSL_TRACK_MEMORY: Enables memory tracking for total stats and list of allocated memory. 00049 * WOLFSSL_DEBUG_MEMORY: Enables extra function and line number args for memory callbacks. 00050 * WOLFSSL_DEBUG_MEMORY_PRINT: Enables printing of each malloc/free. 00051 * WOLFSSL_MALLOC_CHECK: Reports malloc or alignment failure using WOLFSSL_STATIC_ALIGN 00052 * WOLFSSL_FORCE_MALLOC_FAIL_TEST: Used for internal testing to induce random malloc failures. 00053 * WOLFSSL_HEAP_TEST: Used for internal testing of heap hint 00054 */ 00055 00056 #ifdef WOLFSSL_ZEPHYR 00057 #undef realloc 00058 void *z_realloc(void *ptr, size_t size) 00059 { 00060 if (ptr == NULL) 00061 ptr = malloc(size); 00062 else 00063 ptr = realloc(ptr, size); 00064 00065 return ptr; 00066 } 00067 #define realloc z_realloc 00068 #endif 00069 00070 #ifdef USE_WOLFSSL_MEMORY 00071 00072 #include <wolfssl/wolfcrypt/memory.h > 00073 #include <wolfssl/wolfcrypt/error-crypt.h > 00074 #include <wolfssl/wolfcrypt/logging.h > 00075 00076 #if defined(WOLFSSL_DEBUG_MEMORY) && defined(WOLFSSL_DEBUG_MEMORY_PRINT) 00077 #include <stdio.h> 00078 #endif 00079 00080 #ifdef WOLFSSL_FORCE_MALLOC_FAIL_TEST 00081 static int gMemFailCountSeed; 00082 static int gMemFailCount; 00083 void wolfSSL_SetMemFailCount(int memFailCount) 00084 { 00085 if (gMemFailCountSeed == 0) { 00086 gMemFailCountSeed = memFailCount; 00087 gMemFailCount = memFailCount; 00088 } 00089 } 00090 #endif 00091 #if defined(WOLFSSL_MALLOC_CHECK) || defined(WOLFSSL_TRACK_MEMORY_FULL) || \ 00092 defined(WOLFSSL_MEMORY_LOG) 00093 #include <stdio.h> 00094 #endif 00095 00096 00097 /* Set these to default values initially. */ 00098 static wolfSSL_Malloc_cb malloc_function = NULL; 00099 static wolfSSL_Free_cb free_function = NULL; 00100 static wolfSSL_Realloc_cb realloc_function = NULL; 00101 00102 int wolfSSL_SetAllocators(wolfSSL_Malloc_cb mf, 00103 wolfSSL_Free_cb ff, 00104 wolfSSL_Realloc_cb rf) 00105 { 00106 malloc_function = mf; 00107 free_function = ff; 00108 realloc_function = rf; 00109 return 0; 00110 } 00111 00112 int wolfSSL_GetAllocators(wolfSSL_Malloc_cb* mf, 00113 wolfSSL_Free_cb* ff, 00114 wolfSSL_Realloc_cb* rf) 00115 { 00116 if (mf) *mf = malloc_function; 00117 if (ff) *ff = free_function; 00118 if (rf) *rf = realloc_function; 00119 return 0; 00120 } 00121 00122 #ifndef WOLFSSL_STATIC_MEMORY 00123 #ifdef WOLFSSL_DEBUG_MEMORY 00124 void* wolfSSL_Malloc(size_t size, const char* func, unsigned int line) 00125 #else 00126 void* wolfSSL_Malloc(size_t size) 00127 #endif 00128 { 00129 void* res = 0; 00130 00131 if (malloc_function) { 00132 #ifdef WOLFSSL_DEBUG_MEMORY 00133 res = malloc_function(size, func, line); 00134 #else 00135 res = malloc_function(size); 00136 #endif 00137 } 00138 else { 00139 #ifndef WOLFSSL_NO_MALLOC 00140 res = malloc(size); 00141 #else 00142 WOLFSSL_MSG("No malloc available"); 00143 #endif 00144 } 00145 00146 #ifdef WOLFSSL_DEBUG_MEMORY 00147 #if defined(WOLFSSL_DEBUG_MEMORY_PRINT) && !defined(WOLFSSL_TRACK_MEMORY) 00148 printf("Alloc: %p -> %u at %s:%d\n", res, (word32)size, func, line); 00149 #else 00150 (void)func; 00151 (void)line; 00152 #endif 00153 #endif 00154 00155 #ifdef WOLFSSL_MALLOC_CHECK 00156 if (res == NULL) 00157 WOLFSSL_MSG("wolfSSL_malloc failed"); 00158 #endif 00159 00160 #ifdef WOLFSSL_FORCE_MALLOC_FAIL_TEST 00161 if (res && --gMemFailCount == 0) { 00162 printf("\n---FORCED MEM FAIL TEST---\n"); 00163 if (free_function) { 00164 #ifdef WOLFSSL_DEBUG_MEMORY 00165 free_function(res, func, line); 00166 #else 00167 free_function(res); 00168 #endif 00169 } 00170 else { 00171 free(res); /* clear */ 00172 } 00173 gMemFailCount = gMemFailCountSeed; /* reset */ 00174 return NULL; 00175 } 00176 #endif 00177 00178 return res; 00179 } 00180 00181 #ifdef WOLFSSL_DEBUG_MEMORY 00182 void wolfSSL_Free(void *ptr, const char* func, unsigned int line) 00183 #else 00184 void wolfSSL_Free(void *ptr) 00185 #endif 00186 { 00187 #ifdef WOLFSSL_DEBUG_MEMORY 00188 #if defined(WOLFSSL_DEBUG_MEMORY_PRINT) && !defined(WOLFSSL_TRACK_MEMORY) 00189 printf("Free: %p at %s:%d\n", ptr, func, line); 00190 #else 00191 (void)func; 00192 (void)line; 00193 #endif 00194 #endif 00195 00196 if (free_function) { 00197 #ifdef WOLFSSL_DEBUG_MEMORY 00198 free_function(ptr, func, line); 00199 #else 00200 free_function(ptr); 00201 #endif 00202 } 00203 else { 00204 #ifndef WOLFSSL_NO_MALLOC 00205 free(ptr); 00206 #else 00207 WOLFSSL_MSG("No free available"); 00208 #endif 00209 } 00210 } 00211 00212 #ifdef WOLFSSL_DEBUG_MEMORY 00213 void* wolfSSL_Realloc(void *ptr, size_t size, const char* func, unsigned int line) 00214 #else 00215 void* wolfSSL_Realloc(void *ptr, size_t size) 00216 #endif 00217 { 00218 void* res = 0; 00219 00220 if (realloc_function) { 00221 #ifdef WOLFSSL_DEBUG_MEMORY 00222 res = realloc_function(ptr, size, func, line); 00223 #else 00224 res = realloc_function(ptr, size); 00225 #endif 00226 } 00227 else { 00228 #ifndef WOLFSSL_NO_MALLOC 00229 res = realloc(ptr, size); 00230 #else 00231 WOLFSSL_MSG("No realloc available"); 00232 #endif 00233 } 00234 00235 return res; 00236 } 00237 #endif /* WOLFSSL_STATIC_MEMORY */ 00238 00239 #ifdef WOLFSSL_STATIC_MEMORY 00240 00241 struct wc_Memory { 00242 byte* buffer; 00243 struct wc_Memory* next; 00244 word32 sz; 00245 }; 00246 00247 00248 /* returns amount of memory used on success. On error returns negative value 00249 wc_Memory** list is the list that new buckets are prepended to 00250 */ 00251 static int create_memory_buckets(byte* buffer, word32 bufSz, 00252 word32 buckSz, word32 buckNum, wc_Memory** list) { 00253 word32 i; 00254 byte* pt = buffer; 00255 int ret = 0; 00256 word32 memSz = (word32)sizeof(wc_Memory); 00257 word32 padSz = -(int)memSz & (WOLFSSL_STATIC_ALIGN - 1); 00258 00259 /* if not enough space available for bucket size then do not try */ 00260 if (buckSz + memSz + padSz > bufSz) { 00261 return ret; 00262 } 00263 00264 for (i = 0; i < buckNum; i++) { 00265 if ((buckSz + memSz + padSz) <= (bufSz - ret)) { 00266 /* create a new struct and set its values */ 00267 wc_Memory* mem = (struct wc_Memory*)(pt); 00268 mem->sz = buckSz; 00269 mem->buffer = (byte*)pt + padSz + memSz; 00270 mem->next = NULL; 00271 00272 /* add the newly created struct to front of list */ 00273 if (*list == NULL) { 00274 *list = mem; 00275 } else { 00276 mem->next = *list; 00277 *list = mem; 00278 } 00279 00280 /* advance pointer and keep track of memory used */ 00281 ret += buckSz + padSz + memSz; 00282 pt += buckSz + padSz + memSz; 00283 } 00284 else { 00285 break; /* not enough space left for more buckets of this size */ 00286 } 00287 } 00288 00289 return ret; 00290 } 00291 00292 int wolfSSL_init_memory_heap(WOLFSSL_HEAP* heap) 00293 { 00294 word32 wc_MemSz[WOLFMEM_DEF_BUCKETS] = { WOLFMEM_BUCKETS }; 00295 word32 wc_Dist[WOLFMEM_DEF_BUCKETS] = { WOLFMEM_DIST }; 00296 00297 if (heap == NULL) { 00298 return BAD_FUNC_ARG; 00299 } 00300 00301 XMEMSET(heap, 0, sizeof(WOLFSSL_HEAP)); 00302 00303 XMEMCPY(heap->sizeList, wc_MemSz, sizeof(wc_MemSz)); 00304 XMEMCPY(heap->distList, wc_Dist, sizeof(wc_Dist)); 00305 00306 if (wc_InitMutex(&(heap->memory_mutex)) != 0) { 00307 WOLFSSL_MSG("Error creating heap memory mutex"); 00308 return BAD_MUTEX_E; 00309 } 00310 00311 return 0; 00312 } 00313 00314 int wc_LoadStaticMemory(WOLFSSL_HEAP_HINT** pHint, 00315 unsigned char* buf, unsigned int sz, int flag, int max) 00316 { 00317 int ret; 00318 WOLFSSL_HEAP* heap; 00319 WOLFSSL_HEAP_HINT* hint; 00320 word32 idx = 0; 00321 00322 if (pHint == NULL || buf == NULL) { 00323 return BAD_FUNC_ARG; 00324 } 00325 00326 if ((sizeof(WOLFSSL_HEAP) + sizeof(WOLFSSL_HEAP_HINT)) > sz - idx) { 00327 return BUFFER_E; /* not enough memory for structures */ 00328 } 00329 00330 /* check if hint has already been assigned */ 00331 if (*pHint == NULL) { 00332 heap = (WOLFSSL_HEAP*)buf; 00333 idx += sizeof(WOLFSSL_HEAP); 00334 hint = (WOLFSSL_HEAP_HINT*)(buf + idx); 00335 idx += sizeof(WOLFSSL_HEAP_HINT); 00336 00337 ret = wolfSSL_init_memory_heap(heap); 00338 if (ret != 0) { 00339 return ret; 00340 } 00341 00342 XMEMSET(hint, 0, sizeof(WOLFSSL_HEAP_HINT)); 00343 hint->memory = heap; 00344 } 00345 else { 00346 #ifdef WOLFSSL_HEAP_TEST 00347 /* do not load in memory if test has been set */ 00348 if (heap == (void*)WOLFSSL_HEAP_TEST) { 00349 return 0; 00350 } 00351 #endif 00352 00353 hint = (WOLFSSL_HEAP_HINT*)(*pHint); 00354 heap = hint->memory; 00355 } 00356 00357 ret = wolfSSL_load_static_memory(buf + idx, sz - idx, flag, heap); 00358 if (ret != 1) { 00359 WOLFSSL_MSG("Error partitioning memory"); 00360 return -1; 00361 } 00362 00363 /* determine what max applies too */ 00364 if ((flag & WOLFMEM_IO_POOL) || (flag & WOLFMEM_IO_POOL_FIXED)) { 00365 heap->maxIO = max; 00366 } 00367 else { /* general memory used in handshakes */ 00368 heap->maxHa = max; 00369 } 00370 00371 heap->flag |= flag; 00372 *pHint = hint; 00373 00374 (void)max; 00375 00376 return 0; 00377 } 00378 00379 int wolfSSL_load_static_memory(byte* buffer, word32 sz, int flag, 00380 WOLFSSL_HEAP* heap) 00381 { 00382 word32 ava = sz; 00383 byte* pt = buffer; 00384 int ret = 0; 00385 word32 memSz = (word32)sizeof(wc_Memory); 00386 word32 padSz = -(int)memSz & (WOLFSSL_STATIC_ALIGN - 1); 00387 00388 WOLFSSL_ENTER("wolfSSL_load_static_memory"); 00389 00390 if (buffer == NULL) { 00391 return BAD_FUNC_ARG; 00392 } 00393 00394 /* align pt */ 00395 while ((wolfssl_word)pt % WOLFSSL_STATIC_ALIGN && pt < (buffer + sz)) { 00396 *pt = 0x00; 00397 pt++; 00398 ava--; 00399 } 00400 00401 #ifdef WOLFSSL_DEBUG_MEMORY 00402 printf("Allocated %d bytes for static memory @ %p\n", ava, pt); 00403 #endif 00404 00405 /* divide into chunks of memory and add them to available list */ 00406 while (ava >= (heap->sizeList[0] + padSz + memSz)) { 00407 int i; 00408 /* creating only IO buffers from memory passed in, max TLS is 16k */ 00409 if (flag & WOLFMEM_IO_POOL || flag & WOLFMEM_IO_POOL_FIXED) { 00410 if ((ret = create_memory_buckets(pt, ava, 00411 WOLFMEM_IO_SZ, 1, &(heap->io))) < 0) { 00412 WOLFSSL_LEAVE("wolfSSL_load_static_memory", ret); 00413 return ret; 00414 } 00415 00416 /* check if no more room left for creating IO buffers */ 00417 if (ret == 0) { 00418 break; 00419 } 00420 00421 /* advance pointer in buffer for next buckets and keep track 00422 of how much memory is left available */ 00423 pt += ret; 00424 ava -= ret; 00425 } 00426 else { 00427 /* start at largest and move to smaller buckets */ 00428 for (i = (WOLFMEM_MAX_BUCKETS - 1); i >= 0; i--) { 00429 if ((heap->sizeList[i] + padSz + memSz) <= ava) { 00430 if ((ret = create_memory_buckets(pt, ava, heap->sizeList[i], 00431 heap->distList[i], &(heap->ava[i]))) < 0) { 00432 WOLFSSL_LEAVE("wolfSSL_load_static_memory", ret); 00433 return ret; 00434 } 00435 00436 /* advance pointer in buffer for next buckets and keep track 00437 of how much memory is left available */ 00438 pt += ret; 00439 ava -= ret; 00440 } 00441 } 00442 } 00443 } 00444 00445 return 1; 00446 } 00447 00448 00449 /* returns the size of management memory needed for each bucket. 00450 * This is memory that is used to keep track of and align memory buckets. */ 00451 int wolfSSL_MemoryPaddingSz(void) 00452 { 00453 word32 memSz = (word32)sizeof(wc_Memory); 00454 word32 padSz = -(int)memSz & (WOLFSSL_STATIC_ALIGN - 1); 00455 return memSz + padSz; 00456 } 00457 00458 00459 /* Used to calculate memory size for optimum use with buckets. 00460 returns the suggested size rounded down to the nearest bucket. */ 00461 int wolfSSL_StaticBufferSz(byte* buffer, word32 sz, int flag) 00462 { 00463 word32 bucketSz[WOLFMEM_MAX_BUCKETS] = {WOLFMEM_BUCKETS}; 00464 word32 distList[WOLFMEM_MAX_BUCKETS] = {WOLFMEM_DIST}; 00465 00466 word32 ava = sz; 00467 byte* pt = buffer; 00468 word32 memSz = (word32)sizeof(wc_Memory); 00469 word32 padSz = -(int)memSz & (WOLFSSL_STATIC_ALIGN - 1); 00470 00471 WOLFSSL_ENTER("wolfSSL_static_size"); 00472 00473 if (buffer == NULL) { 00474 return BAD_FUNC_ARG; 00475 } 00476 00477 /* align pt */ 00478 while ((wolfssl_word)pt % WOLFSSL_STATIC_ALIGN && pt < (buffer + sz)) { 00479 pt++; 00480 ava--; 00481 } 00482 00483 /* creating only IO buffers from memory passed in, max TLS is 16k */ 00484 if (flag & WOLFMEM_IO_POOL || flag & WOLFMEM_IO_POOL_FIXED) { 00485 if (ava < (memSz + padSz + WOLFMEM_IO_SZ)) { 00486 return 0; /* not enough room for even one bucket */ 00487 } 00488 00489 ava = ava % (memSz + padSz + WOLFMEM_IO_SZ); 00490 } 00491 else { 00492 int i, k; 00493 00494 if (ava < (bucketSz[0] + padSz + memSz)) { 00495 return 0; /* not enough room for even one bucket */ 00496 } 00497 00498 while ((ava >= (bucketSz[0] + padSz + memSz)) && (ava > 0)) { 00499 /* start at largest and move to smaller buckets */ 00500 for (i = (WOLFMEM_MAX_BUCKETS - 1); i >= 0; i--) { 00501 for (k = distList[i]; k > 0; k--) { 00502 if ((bucketSz[i] + padSz + memSz) <= ava) { 00503 ava -= bucketSz[i] + padSz + memSz; 00504 } 00505 } 00506 } 00507 } 00508 } 00509 00510 return sz - ava; /* round down */ 00511 } 00512 00513 00514 int FreeFixedIO(WOLFSSL_HEAP* heap, wc_Memory** io) 00515 { 00516 WOLFSSL_MSG("Freeing fixed IO buffer"); 00517 00518 /* check if fixed buffer was set */ 00519 if (*io == NULL) { 00520 return 1; 00521 } 00522 00523 if (heap == NULL) { 00524 WOLFSSL_MSG("No heap to return fixed IO too"); 00525 } 00526 else { 00527 /* put IO buffer back into IO pool */ 00528 (*io)->next = heap->io; 00529 heap->io = *io; 00530 *io = NULL; 00531 } 00532 00533 return 1; 00534 } 00535 00536 00537 int SetFixedIO(WOLFSSL_HEAP* heap, wc_Memory** io) 00538 { 00539 WOLFSSL_MSG("Setting fixed IO for SSL"); 00540 if (heap == NULL) { 00541 return MEMORY_E; 00542 } 00543 00544 *io = heap->io; 00545 00546 if (*io != NULL) { 00547 heap->io = (*io)->next; 00548 (*io)->next = NULL; 00549 } 00550 else { /* failed to grab an IO buffer */ 00551 return 0; 00552 } 00553 00554 return 1; 00555 } 00556 00557 00558 int wolfSSL_GetMemStats(WOLFSSL_HEAP* heap, WOLFSSL_MEM_STATS* stats) 00559 { 00560 word32 i; 00561 wc_Memory* pt; 00562 00563 XMEMSET(stats, 0, sizeof(WOLFSSL_MEM_STATS)); 00564 00565 stats->totalAlloc = heap->alloc; 00566 stats->totalFr = heap->frAlc; 00567 stats->curAlloc = stats->totalAlloc - stats->totalFr; 00568 stats->maxHa = heap->maxHa; 00569 stats->maxIO = heap->maxIO; 00570 for (i = 0; i < WOLFMEM_MAX_BUCKETS; i++) { 00571 stats->blockSz[i] = heap->sizeList[i]; 00572 for (pt = heap->ava[i]; pt != NULL; pt = pt->next) { 00573 stats->avaBlock[i] += 1; 00574 } 00575 } 00576 00577 for (pt = heap->io; pt != NULL; pt = pt->next) { 00578 stats->avaIO++; 00579 } 00580 00581 stats->flag = heap->flag; /* flag used */ 00582 00583 return 1; 00584 } 00585 00586 00587 #ifdef WOLFSSL_DEBUG_MEMORY 00588 void* wolfSSL_Malloc(size_t size, void* heap, int type, const char* func, unsigned int line) 00589 #else 00590 void* wolfSSL_Malloc(size_t size, void* heap, int type) 00591 #endif 00592 { 00593 void* res = 0; 00594 wc_Memory* pt = NULL; 00595 int i; 00596 00597 /* check for testing heap hint was set */ 00598 #ifdef WOLFSSL_HEAP_TEST 00599 if (heap == (void*)WOLFSSL_HEAP_TEST) { 00600 return malloc(size); 00601 } 00602 #endif 00603 00604 /* if no heap hint then use dynamic memory*/ 00605 if (heap == NULL) { 00606 #ifdef WOLFSSL_HEAP_TEST 00607 /* allow using malloc for creating ctx and method */ 00608 if (type == DYNAMIC_TYPE_CTX || type == DYNAMIC_TYPE_METHOD || 00609 type == DYNAMIC_TYPE_CERT_MANAGER) { 00610 WOLFSSL_MSG("ERROR allowing null heap hint for ctx/method\n"); 00611 res = malloc(size); 00612 } 00613 else { 00614 WOLFSSL_MSG("ERROR null heap hint passed into XMALLOC\n"); 00615 res = NULL; 00616 } 00617 #else 00618 #ifndef WOLFSSL_NO_MALLOC 00619 #ifdef FREERTOS 00620 res = pvPortMalloc(size); 00621 #else 00622 res = malloc(size); 00623 #endif 00624 #else 00625 WOLFSSL_MSG("No heap hint found to use and no malloc"); 00626 #ifdef WOLFSSL_DEBUG_MEMORY 00627 printf("ERROR: at %s:%d\n", func, line); 00628 #endif 00629 #endif /* WOLFSSL_NO_MALLOC */ 00630 #endif /* WOLFSSL_HEAP_TEST */ 00631 } 00632 else { 00633 WOLFSSL_HEAP_HINT* hint = (WOLFSSL_HEAP_HINT*)heap; 00634 WOLFSSL_HEAP* mem = hint->memory; 00635 00636 if (wc_LockMutex(&(mem->memory_mutex)) != 0) { 00637 WOLFSSL_MSG("Bad memory_mutex lock"); 00638 return NULL; 00639 } 00640 00641 /* case of using fixed IO buffers */ 00642 if (mem->flag & WOLFMEM_IO_POOL_FIXED && 00643 (type == DYNAMIC_TYPE_OUT_BUFFER || 00644 type == DYNAMIC_TYPE_IN_BUFFER)) { 00645 if (type == DYNAMIC_TYPE_OUT_BUFFER) { 00646 pt = hint->outBuf; 00647 } 00648 if (type == DYNAMIC_TYPE_IN_BUFFER) { 00649 pt = hint->inBuf; 00650 } 00651 } 00652 else { 00653 /* check if using IO pool flag */ 00654 if (mem->flag & WOLFMEM_IO_POOL && 00655 (type == DYNAMIC_TYPE_OUT_BUFFER || 00656 type == DYNAMIC_TYPE_IN_BUFFER)) { 00657 if (mem->io != NULL) { 00658 pt = mem->io; 00659 mem->io = pt->next; 00660 } 00661 } 00662 00663 /* general static memory */ 00664 if (pt == NULL) { 00665 for (i = 0; i < WOLFMEM_MAX_BUCKETS; i++) { 00666 if ((word32)size < mem->sizeList[i]) { 00667 if (mem->ava[i] != NULL) { 00668 pt = mem->ava[i]; 00669 mem->ava[i] = pt->next; 00670 break; 00671 } 00672 #ifdef WOLFSSL_DEBUG_STATIC_MEMORY 00673 else { 00674 printf("Size: %ld, Empty: %d\n", size, 00675 mem->sizeList[i]); 00676 } 00677 #endif 00678 } 00679 } 00680 } 00681 } 00682 00683 if (pt != NULL) { 00684 mem->inUse += pt->sz; 00685 mem->alloc += 1; 00686 res = pt->buffer; 00687 00688 #ifdef WOLFSSL_DEBUG_MEMORY 00689 printf("Alloc: %p -> %u at %s:%d\n", pt->buffer, pt->sz, func, line); 00690 #endif 00691 00692 /* keep track of connection statistics if flag is set */ 00693 if (mem->flag & WOLFMEM_TRACK_STATS) { 00694 WOLFSSL_MEM_CONN_STATS* stats = hint->stats; 00695 if (stats != NULL) { 00696 stats->curMem += pt->sz; 00697 if (stats->peakMem < stats->curMem) { 00698 stats->peakMem = stats->curMem; 00699 } 00700 stats->curAlloc++; 00701 if (stats->peakAlloc < stats->curAlloc) { 00702 stats->peakAlloc = stats->curAlloc; 00703 } 00704 stats->totalAlloc++; 00705 } 00706 } 00707 } 00708 else { 00709 WOLFSSL_MSG("ERROR ran out of static memory"); 00710 #ifdef WOLFSSL_DEBUG_MEMORY 00711 printf("Looking for %lu bytes at %s:%d\n", size, func, line); 00712 #endif 00713 } 00714 00715 wc_UnLockMutex(&(mem->memory_mutex)); 00716 } 00717 00718 #ifdef WOLFSSL_MALLOC_CHECK 00719 if ((wolfssl_word)res % WOLFSSL_STATIC_ALIGN) { 00720 WOLFSSL_MSG("ERROR memory is not aligned"); 00721 res = NULL; 00722 } 00723 #endif 00724 00725 00726 (void)i; 00727 (void)pt; 00728 (void)type; 00729 00730 return res; 00731 } 00732 00733 00734 #ifdef WOLFSSL_DEBUG_MEMORY 00735 void wolfSSL_Free(void *ptr, void* heap, int type, const char* func, unsigned int line) 00736 #else 00737 void wolfSSL_Free(void *ptr, void* heap, int type) 00738 #endif 00739 { 00740 int i; 00741 wc_Memory* pt; 00742 00743 if (ptr) { 00744 /* check for testing heap hint was set */ 00745 #ifdef WOLFSSL_HEAP_TEST 00746 if (heap == (void*)WOLFSSL_HEAP_TEST) { 00747 return free(ptr); 00748 } 00749 #endif 00750 00751 if (heap == NULL) { 00752 #ifdef WOLFSSL_HEAP_TEST 00753 /* allow using malloc for creating ctx and method */ 00754 if (type == DYNAMIC_TYPE_CTX || type == DYNAMIC_TYPE_METHOD || 00755 type == DYNAMIC_TYPE_CERT_MANAGER) { 00756 WOLFSSL_MSG("ERROR allowing null heap hint for ctx/method\n"); 00757 } 00758 else { 00759 WOLFSSL_MSG("ERROR null heap hint passed into XFREE\n"); 00760 } 00761 #endif 00762 #ifndef WOLFSSL_NO_MALLOC 00763 #ifdef FREERTOS 00764 vPortFree(ptr); 00765 #else 00766 free(ptr); 00767 #endif 00768 #else 00769 WOLFSSL_MSG("Error trying to call free when turned off"); 00770 #endif /* WOLFSSL_NO_MALLOC */ 00771 } 00772 else { 00773 WOLFSSL_HEAP_HINT* hint = (WOLFSSL_HEAP_HINT*)heap; 00774 WOLFSSL_HEAP* mem = hint->memory; 00775 word32 padSz = -(int)sizeof(wc_Memory) & (WOLFSSL_STATIC_ALIGN - 1); 00776 00777 /* get memory struct and add it to available list */ 00778 pt = (wc_Memory*)((byte*)ptr - sizeof(wc_Memory) - padSz); 00779 if (wc_LockMutex(&(mem->memory_mutex)) != 0) { 00780 WOLFSSL_MSG("Bad memory_mutex lock"); 00781 return; 00782 } 00783 00784 /* case of using fixed IO buffers */ 00785 if (mem->flag & WOLFMEM_IO_POOL_FIXED && 00786 (type == DYNAMIC_TYPE_OUT_BUFFER || 00787 type == DYNAMIC_TYPE_IN_BUFFER)) { 00788 /* fixed IO pools are free'd at the end of SSL lifetime 00789 using FreeFixedIO(WOLFSSL_HEAP* heap, wc_Memory** io) */ 00790 } 00791 else if (mem->flag & WOLFMEM_IO_POOL && pt->sz == WOLFMEM_IO_SZ && 00792 (type == DYNAMIC_TYPE_OUT_BUFFER || 00793 type == DYNAMIC_TYPE_IN_BUFFER)) { 00794 pt->next = mem->io; 00795 mem->io = pt; 00796 } 00797 else { /* general memory free */ 00798 for (i = 0; i < WOLFMEM_MAX_BUCKETS; i++) { 00799 if (pt->sz == mem->sizeList[i]) { 00800 pt->next = mem->ava[i]; 00801 mem->ava[i] = pt; 00802 break; 00803 } 00804 } 00805 } 00806 mem->inUse -= pt->sz; 00807 mem->frAlc += 1; 00808 00809 #ifdef WOLFSSL_DEBUG_MEMORY 00810 printf("Free: %p -> %u at %s:%d\n", pt->buffer, pt->sz, func, line); 00811 #endif 00812 00813 /* keep track of connection statistics if flag is set */ 00814 if (mem->flag & WOLFMEM_TRACK_STATS) { 00815 WOLFSSL_MEM_CONN_STATS* stats = hint->stats; 00816 if (stats != NULL) { 00817 /* avoid under flow */ 00818 if (stats->curMem > pt->sz) { 00819 stats->curMem -= pt->sz; 00820 } 00821 else { 00822 stats->curMem = 0; 00823 } 00824 00825 if (stats->curAlloc > 0) { 00826 stats->curAlloc--; 00827 } 00828 stats->totalFr++; 00829 } 00830 } 00831 wc_UnLockMutex(&(mem->memory_mutex)); 00832 } 00833 } 00834 00835 (void)i; 00836 (void)pt; 00837 (void)type; 00838 } 00839 00840 #ifdef WOLFSSL_DEBUG_MEMORY 00841 void* wolfSSL_Realloc(void *ptr, size_t size, void* heap, int type, const char* func, unsigned int line) 00842 #else 00843 void* wolfSSL_Realloc(void *ptr, size_t size, void* heap, int type) 00844 #endif 00845 { 00846 void* res = 0; 00847 wc_Memory* pt = NULL; 00848 word32 prvSz; 00849 int i; 00850 00851 /* check for testing heap hint was set */ 00852 #ifdef WOLFSSL_HEAP_TEST 00853 if (heap == (void*)WOLFSSL_HEAP_TEST) { 00854 return realloc(ptr, size); 00855 } 00856 #endif 00857 00858 if (heap == NULL) { 00859 #ifdef WOLFSSL_HEAP_TEST 00860 WOLFSSL_MSG("ERROR null heap hint passed in to XREALLOC\n"); 00861 #endif 00862 #ifndef WOLFSSL_NO_MALLOC 00863 res = realloc(ptr, size); 00864 #else 00865 WOLFSSL_MSG("NO heap found to use for realloc"); 00866 #endif /* WOLFSSL_NO_MALLOC */ 00867 } 00868 else { 00869 WOLFSSL_HEAP_HINT* hint = (WOLFSSL_HEAP_HINT*)heap; 00870 WOLFSSL_HEAP* mem = hint->memory; 00871 word32 padSz = -(int)sizeof(wc_Memory) & (WOLFSSL_STATIC_ALIGN - 1); 00872 00873 if (ptr == NULL) { 00874 #ifdef WOLFSSL_DEBUG_MEMORY 00875 return wolfSSL_Malloc(size, heap, type, func, line); 00876 #else 00877 return wolfSSL_Malloc(size, heap, type); 00878 #endif 00879 } 00880 00881 if (wc_LockMutex(&(mem->memory_mutex)) != 0) { 00882 WOLFSSL_MSG("Bad memory_mutex lock"); 00883 return NULL; 00884 } 00885 00886 /* case of using fixed IO buffers or IO pool */ 00887 if (((mem->flag & WOLFMEM_IO_POOL)||(mem->flag & WOLFMEM_IO_POOL_FIXED)) 00888 && (type == DYNAMIC_TYPE_OUT_BUFFER || 00889 type == DYNAMIC_TYPE_IN_BUFFER)) { 00890 /* no realloc, is fixed size */ 00891 pt = (wc_Memory*)((byte*)ptr - padSz - sizeof(wc_Memory)); 00892 if (pt->sz < size) { 00893 WOLFSSL_MSG("Error IO memory was not large enough"); 00894 res = NULL; /* return NULL in error case */ 00895 } 00896 res = pt->buffer; 00897 } 00898 else { 00899 /* general memory */ 00900 for (i = 0; i < WOLFMEM_MAX_BUCKETS; i++) { 00901 if ((word32)size < mem->sizeList[i]) { 00902 if (mem->ava[i] != NULL) { 00903 pt = mem->ava[i]; 00904 mem->ava[i] = pt->next; 00905 break; 00906 } 00907 } 00908 } 00909 00910 if (pt != NULL && res == NULL) { 00911 res = pt->buffer; 00912 00913 /* copy over original information and free ptr */ 00914 prvSz = ((wc_Memory*)((byte*)ptr - padSz - 00915 sizeof(wc_Memory)))->sz; 00916 prvSz = (prvSz > pt->sz)? pt->sz: prvSz; 00917 XMEMCPY(pt->buffer, ptr, prvSz); 00918 mem->inUse += pt->sz; 00919 mem->alloc += 1; 00920 00921 /* free memory that was previously being used */ 00922 wc_UnLockMutex(&(mem->memory_mutex)); 00923 wolfSSL_Free(ptr, heap, type 00924 #ifdef WOLFSSL_DEBUG_MEMORY 00925 , func, line 00926 #endif 00927 ); 00928 if (wc_LockMutex(&(mem->memory_mutex)) != 0) { 00929 WOLFSSL_MSG("Bad memory_mutex lock"); 00930 return NULL; 00931 } 00932 } 00933 } 00934 wc_UnLockMutex(&(mem->memory_mutex)); 00935 } 00936 00937 #ifdef WOLFSSL_MALLOC_CHECK 00938 if ((wolfssl_word)res % WOLFSSL_STATIC_ALIGN) { 00939 WOLFSSL_MSG("ERROR memory is not aligned"); 00940 res = NULL; 00941 } 00942 #endif 00943 00944 (void)i; 00945 (void)pt; 00946 (void)type; 00947 00948 return res; 00949 } 00950 #endif /* WOLFSSL_STATIC_MEMORY */ 00951 00952 #endif /* USE_WOLFSSL_MEMORY */ 00953 00954 00955 #ifdef HAVE_IO_POOL 00956 00957 /* Example for user io pool, shared build may need definitions in lib proper */ 00958 00959 #include <wolfssl/wolfcrypt/types.h > 00960 #include <stdlib.h> 00961 00962 #ifndef HAVE_THREAD_LS 00963 #error "Oops, simple I/O pool example needs thread local storage" 00964 #endif 00965 00966 00967 /* allow simple per thread in and out pools */ 00968 /* use 17k size since max record size is 16k plus overhead */ 00969 static THREAD_LS_T byte pool_in[17*1024]; 00970 static THREAD_LS_T byte pool_out[17*1024]; 00971 00972 00973 void* XMALLOC(size_t n, void* heap, int type) 00974 { 00975 (void)heap; 00976 00977 if (type == DYNAMIC_TYPE_IN_BUFFER) { 00978 if (n < sizeof(pool_in)) 00979 return pool_in; 00980 else 00981 return NULL; 00982 } 00983 00984 if (type == DYNAMIC_TYPE_OUT_BUFFER) { 00985 if (n < sizeof(pool_out)) 00986 return pool_out; 00987 else 00988 return NULL; 00989 } 00990 00991 return malloc(n); 00992 } 00993 00994 void* XREALLOC(void *p, size_t n, void* heap, int type) 00995 { 00996 (void)heap; 00997 00998 if (type == DYNAMIC_TYPE_IN_BUFFER) { 00999 if (n < sizeof(pool_in)) 01000 return pool_in; 01001 else 01002 return NULL; 01003 } 01004 01005 if (type == DYNAMIC_TYPE_OUT_BUFFER) { 01006 if (n < sizeof(pool_out)) 01007 return pool_out; 01008 else 01009 return NULL; 01010 } 01011 01012 return realloc(p, n); 01013 } 01014 01015 void XFREE(void *p, void* heap, int type) 01016 { 01017 (void)heap; 01018 01019 if (type == DYNAMIC_TYPE_IN_BUFFER) 01020 return; /* do nothing, static pool */ 01021 01022 if (type == DYNAMIC_TYPE_OUT_BUFFER) 01023 return; /* do nothing, static pool */ 01024 01025 free(p); 01026 } 01027 01028 #endif /* HAVE_IO_POOL */ 01029 01030 #ifdef WOLFSSL_MEMORY_LOG 01031 void *xmalloc(size_t n, void* heap, int type, const char* func, 01032 const char* file, unsigned int line) 01033 { 01034 void* p; 01035 word32* p32; 01036 01037 if (malloc_function) 01038 p32 = malloc_function(n + sizeof(word32) * 4); 01039 else 01040 p32 = malloc(n + sizeof(word32) * 4); 01041 01042 p32[0] = (word32)n; 01043 p = (void*)(p32 + 4); 01044 01045 fprintf(stderr, "Alloc: %p -> %u (%d) at %s:%s:%u\n", p, (word32)n, type, 01046 func, file, line); 01047 01048 (void)heap; 01049 01050 return p; 01051 } 01052 void *xrealloc(void *p, size_t n, void* heap, int type, const char* func, 01053 const char* file, unsigned int line) 01054 { 01055 void* newp = NULL; 01056 word32* p32; 01057 word32* oldp32 = NULL; 01058 word32 oldLen; 01059 01060 if (p != NULL) { 01061 oldp32 = (word32*)p; 01062 oldp32 -= 4; 01063 oldLen = oldp32[0]; 01064 } 01065 01066 if (realloc_function) 01067 p32 = realloc_function(oldp32, n + sizeof(word32) * 4); 01068 else 01069 p32 = realloc(oldp32, n + sizeof(word32) * 4); 01070 01071 if (p32 != NULL) { 01072 p32[0] = (word32)n; 01073 newp = (void*)(p32 + 4); 01074 01075 fprintf(stderr, "Alloc: %p -> %u (%d) at %s:%s:%u\n", newp, (word32)n, 01076 type, func, file, line); 01077 if (p != NULL) { 01078 fprintf(stderr, "Free: %p -> %u (%d) at %s:%s:%u\n", p, oldLen, 01079 type, func, file, line); 01080 } 01081 } 01082 01083 (void)heap; 01084 01085 return newp; 01086 } 01087 void xfree(void *p, void* heap, int type, const char* func, const char* file, 01088 unsigned int line) 01089 { 01090 word32* p32 = (word32*)p; 01091 01092 if (p != NULL) { 01093 p32 -= 4; 01094 01095 fprintf(stderr, "Free: %p -> %u (%d) at %s:%s:%u\n", p, p32[0], type, 01096 func, file, line); 01097 01098 if (free_function) 01099 free_function(p32); 01100 else 01101 free(p32); 01102 } 01103 01104 (void)heap; 01105 } 01106 #endif /* WOLFSSL_MEMORY_LOG */ 01107 01108 #ifdef WOLFSSL_STACK_LOG 01109 /* Note: this code only works with GCC using -finstrument-functions. */ 01110 void __attribute__((no_instrument_function)) 01111 __cyg_profile_func_enter(void *func, void *caller) 01112 { 01113 register void* sp asm("sp"); 01114 fprintf(stderr, "ENTER: %016lx %p\n", (unsigned long)(size_t)func, sp); 01115 (void)caller; 01116 } 01117 01118 void __attribute__((no_instrument_function)) 01119 __cyg_profile_func_exit(void *func, void *caller) 01120 { 01121 register void* sp asm("sp"); 01122 fprintf(stderr, "EXIT: %016lx %p\n", (unsigned long)(size_t)func, sp); 01123 (void)caller; 01124 } 01125 #endif 01126 01127
Generated on Tue Jul 12 2022 20:58:40 by 1.7.2