wolfSSL SSL/TLS library, support up to TLS1.3

Dependents:   CyaSSL-Twitter-OAuth4Tw Example-client-tls-cert TwitterReader TweetTest ... more

Committer:
wolfSSL
Date:
Tue May 02 08:44:47 2017 +0000
Revision:
7:481bce714567
wolfSSL3.10.2

Who changed what in which revision?

UserRevisionLine numberNew contents of line
wolfSSL 7:481bce714567 1 /* memory.c
wolfSSL 7:481bce714567 2 *
wolfSSL 7:481bce714567 3 * Copyright (C) 2006-2016 wolfSSL Inc.
wolfSSL 7:481bce714567 4 *
wolfSSL 7:481bce714567 5 * This file is part of wolfSSL.
wolfSSL 7:481bce714567 6 *
wolfSSL 7:481bce714567 7 * wolfSSL is free software; you can redistribute it and/or modify
wolfSSL 7:481bce714567 8 * it under the terms of the GNU General Public License as published by
wolfSSL 7:481bce714567 9 * the Free Software Foundation; either version 2 of the License, or
wolfSSL 7:481bce714567 10 * (at your option) any later version.
wolfSSL 7:481bce714567 11 *
wolfSSL 7:481bce714567 12 * wolfSSL is distributed in the hope that it will be useful,
wolfSSL 7:481bce714567 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
wolfSSL 7:481bce714567 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
wolfSSL 7:481bce714567 15 * GNU General Public License for more details.
wolfSSL 7:481bce714567 16 *
wolfSSL 7:481bce714567 17 * You should have received a copy of the GNU General Public License
wolfSSL 7:481bce714567 18 * along with this program; if not, write to the Free Software
wolfSSL 7:481bce714567 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
wolfSSL 7:481bce714567 20 */
wolfSSL 7:481bce714567 21
wolfSSL 7:481bce714567 22
wolfSSL 7:481bce714567 23 #ifdef HAVE_CONFIG_H
wolfSSL 7:481bce714567 24 #include <config.h>
wolfSSL 7:481bce714567 25 #endif
wolfSSL 7:481bce714567 26
wolfSSL 7:481bce714567 27 #include <wolfssl/wolfcrypt/settings.h>
wolfSSL 7:481bce714567 28
wolfSSL 7:481bce714567 29 /* check old macros @wc_fips */
wolfSSL 7:481bce714567 30 #if defined(USE_CYASSL_MEMORY) && !defined(USE_WOLFSSL_MEMORY)
wolfSSL 7:481bce714567 31 #define USE_WOLFSSL_MEMORY
wolfSSL 7:481bce714567 32 #endif
wolfSSL 7:481bce714567 33 #if defined(CYASSL_MALLOC_CHECK) && !defined(WOLFSSL_MALLOC_CHECK)
wolfSSL 7:481bce714567 34 #define WOLFSSL_MALLOC_CHECK
wolfSSL 7:481bce714567 35 #endif
wolfSSL 7:481bce714567 36
wolfSSL 7:481bce714567 37 #ifdef USE_WOLFSSL_MEMORY
wolfSSL 7:481bce714567 38
wolfSSL 7:481bce714567 39 #include <wolfssl/wolfcrypt/memory.h>
wolfSSL 7:481bce714567 40 #include <wolfssl/wolfcrypt/error-crypt.h>
wolfSSL 7:481bce714567 41 #include <wolfssl/wolfcrypt/logging.h>
wolfSSL 7:481bce714567 42
wolfSSL 7:481bce714567 43 #if defined(WOLFSSL_MALLOC_CHECK) || defined(WOLFSSL_TRACK_MEMORY_FULL)
wolfSSL 7:481bce714567 44 #include <stdio.h>
wolfSSL 7:481bce714567 45 #endif
wolfSSL 7:481bce714567 46
wolfSSL 7:481bce714567 47
wolfSSL 7:481bce714567 48 /* Set these to default values initially. */
wolfSSL 7:481bce714567 49 static wolfSSL_Malloc_cb malloc_function = 0;
wolfSSL 7:481bce714567 50 static wolfSSL_Free_cb free_function = 0;
wolfSSL 7:481bce714567 51 static wolfSSL_Realloc_cb realloc_function = 0;
wolfSSL 7:481bce714567 52
wolfSSL 7:481bce714567 53 int wolfSSL_SetAllocators(wolfSSL_Malloc_cb mf,
wolfSSL 7:481bce714567 54 wolfSSL_Free_cb ff,
wolfSSL 7:481bce714567 55 wolfSSL_Realloc_cb rf)
wolfSSL 7:481bce714567 56 {
wolfSSL 7:481bce714567 57 int res = 0;
wolfSSL 7:481bce714567 58
wolfSSL 7:481bce714567 59 if (mf)
wolfSSL 7:481bce714567 60 malloc_function = mf;
wolfSSL 7:481bce714567 61 else
wolfSSL 7:481bce714567 62 res = BAD_FUNC_ARG;
wolfSSL 7:481bce714567 63
wolfSSL 7:481bce714567 64 if (ff)
wolfSSL 7:481bce714567 65 free_function = ff;
wolfSSL 7:481bce714567 66 else
wolfSSL 7:481bce714567 67 res = BAD_FUNC_ARG;
wolfSSL 7:481bce714567 68
wolfSSL 7:481bce714567 69 if (rf)
wolfSSL 7:481bce714567 70 realloc_function = rf;
wolfSSL 7:481bce714567 71 else
wolfSSL 7:481bce714567 72 res = BAD_FUNC_ARG;
wolfSSL 7:481bce714567 73
wolfSSL 7:481bce714567 74 return res;
wolfSSL 7:481bce714567 75 }
wolfSSL 7:481bce714567 76
wolfSSL 7:481bce714567 77 #ifndef WOLFSSL_STATIC_MEMORY
wolfSSL 7:481bce714567 78 #ifdef WOLFSSL_DEBUG_MEMORY
wolfSSL 7:481bce714567 79 void* wolfSSL_Malloc(size_t size, const char* func, unsigned int line)
wolfSSL 7:481bce714567 80 #else
wolfSSL 7:481bce714567 81 void* wolfSSL_Malloc(size_t size)
wolfSSL 7:481bce714567 82 #endif
wolfSSL 7:481bce714567 83 {
wolfSSL 7:481bce714567 84 void* res = 0;
wolfSSL 7:481bce714567 85
wolfSSL 7:481bce714567 86 if (malloc_function) {
wolfSSL 7:481bce714567 87 #ifdef WOLFSSL_DEBUG_MEMORY
wolfSSL 7:481bce714567 88 res = malloc_function(size, func, line);
wolfSSL 7:481bce714567 89 #else
wolfSSL 7:481bce714567 90 res = malloc_function(size);
wolfSSL 7:481bce714567 91 #endif
wolfSSL 7:481bce714567 92 }
wolfSSL 7:481bce714567 93 else {
wolfSSL 7:481bce714567 94 res = malloc(size);
wolfSSL 7:481bce714567 95 }
wolfSSL 7:481bce714567 96
wolfSSL 7:481bce714567 97 #ifdef WOLFSSL_MALLOC_CHECK
wolfSSL 7:481bce714567 98 if (res == NULL)
wolfSSL 7:481bce714567 99 puts("wolfSSL_malloc failed");
wolfSSL 7:481bce714567 100 #endif
wolfSSL 7:481bce714567 101
wolfSSL 7:481bce714567 102 return res;
wolfSSL 7:481bce714567 103 }
wolfSSL 7:481bce714567 104
wolfSSL 7:481bce714567 105 #ifdef WOLFSSL_DEBUG_MEMORY
wolfSSL 7:481bce714567 106 void wolfSSL_Free(void *ptr, const char* func, unsigned int line)
wolfSSL 7:481bce714567 107 #else
wolfSSL 7:481bce714567 108 void wolfSSL_Free(void *ptr)
wolfSSL 7:481bce714567 109 #endif
wolfSSL 7:481bce714567 110 {
wolfSSL 7:481bce714567 111 if (free_function) {
wolfSSL 7:481bce714567 112 #ifdef WOLFSSL_DEBUG_MEMORY
wolfSSL 7:481bce714567 113 free_function(ptr, func, line);
wolfSSL 7:481bce714567 114 #else
wolfSSL 7:481bce714567 115 free_function(ptr);
wolfSSL 7:481bce714567 116 #endif
wolfSSL 7:481bce714567 117 }
wolfSSL 7:481bce714567 118 else {
wolfSSL 7:481bce714567 119 free(ptr);
wolfSSL 7:481bce714567 120 }
wolfSSL 7:481bce714567 121 }
wolfSSL 7:481bce714567 122
wolfSSL 7:481bce714567 123 #ifdef WOLFSSL_DEBUG_MEMORY
wolfSSL 7:481bce714567 124 void* wolfSSL_Realloc(void *ptr, size_t size, const char* func, unsigned int line)
wolfSSL 7:481bce714567 125 #else
wolfSSL 7:481bce714567 126 void* wolfSSL_Realloc(void *ptr, size_t size)
wolfSSL 7:481bce714567 127 #endif
wolfSSL 7:481bce714567 128 {
wolfSSL 7:481bce714567 129 void* res = 0;
wolfSSL 7:481bce714567 130
wolfSSL 7:481bce714567 131 if (realloc_function) {
wolfSSL 7:481bce714567 132 #ifdef WOLFSSL_DEBUG_MEMORY
wolfSSL 7:481bce714567 133 res = realloc_function(ptr, size, func, line);
wolfSSL 7:481bce714567 134 #else
wolfSSL 7:481bce714567 135 res = realloc_function(ptr, size);
wolfSSL 7:481bce714567 136 #endif
wolfSSL 7:481bce714567 137 }
wolfSSL 7:481bce714567 138 else {
wolfSSL 7:481bce714567 139 res = realloc(ptr, size);
wolfSSL 7:481bce714567 140 }
wolfSSL 7:481bce714567 141
wolfSSL 7:481bce714567 142 return res;
wolfSSL 7:481bce714567 143 }
wolfSSL 7:481bce714567 144 #endif /* WOLFSSL_STATIC_MEMORY */
wolfSSL 7:481bce714567 145
wolfSSL 7:481bce714567 146 #ifdef WOLFSSL_STATIC_MEMORY
wolfSSL 7:481bce714567 147
wolfSSL 7:481bce714567 148 struct wc_Memory {
wolfSSL 7:481bce714567 149 byte* buffer;
wolfSSL 7:481bce714567 150 struct wc_Memory* next;
wolfSSL 7:481bce714567 151 word32 sz;
wolfSSL 7:481bce714567 152 };
wolfSSL 7:481bce714567 153
wolfSSL 7:481bce714567 154
wolfSSL 7:481bce714567 155 /* returns amount of memory used on success. On error returns negative value
wolfSSL 7:481bce714567 156 wc_Memory** list is the list that new buckets are prepended to
wolfSSL 7:481bce714567 157 */
wolfSSL 7:481bce714567 158 static int create_memory_buckets(byte* buffer, word32 bufSz,
wolfSSL 7:481bce714567 159 word32 buckSz, word32 buckNum, wc_Memory** list) {
wolfSSL 7:481bce714567 160 word32 i;
wolfSSL 7:481bce714567 161 byte* pt = buffer;
wolfSSL 7:481bce714567 162 int ret = 0;
wolfSSL 7:481bce714567 163 word32 memSz = (word32)sizeof(wc_Memory);
wolfSSL 7:481bce714567 164 word32 padSz = -(int)memSz & (WOLFSSL_STATIC_ALIGN - 1);
wolfSSL 7:481bce714567 165
wolfSSL 7:481bce714567 166 /* if not enough space available for bucket size then do not try */
wolfSSL 7:481bce714567 167 if (buckSz + memSz + padSz > bufSz) {
wolfSSL 7:481bce714567 168 return ret;
wolfSSL 7:481bce714567 169 }
wolfSSL 7:481bce714567 170
wolfSSL 7:481bce714567 171 for (i = 0; i < buckNum; i++) {
wolfSSL 7:481bce714567 172 if ((buckSz + memSz + padSz) <= (bufSz - ret)) {
wolfSSL 7:481bce714567 173 /* create a new struct and set its values */
wolfSSL 7:481bce714567 174 wc_Memory* mem = (struct wc_Memory*)(pt);
wolfSSL 7:481bce714567 175 mem->sz = buckSz;
wolfSSL 7:481bce714567 176 mem->buffer = (byte*)pt + padSz + memSz;
wolfSSL 7:481bce714567 177 mem->next = NULL;
wolfSSL 7:481bce714567 178
wolfSSL 7:481bce714567 179 /* add the newly created struct to front of list */
wolfSSL 7:481bce714567 180 if (*list == NULL) {
wolfSSL 7:481bce714567 181 *list = mem;
wolfSSL 7:481bce714567 182 } else {
wolfSSL 7:481bce714567 183 mem->next = *list;
wolfSSL 7:481bce714567 184 *list = mem;
wolfSSL 7:481bce714567 185 }
wolfSSL 7:481bce714567 186
wolfSSL 7:481bce714567 187 /* advance pointer and keep track of memory used */
wolfSSL 7:481bce714567 188 ret += buckSz + padSz + memSz;
wolfSSL 7:481bce714567 189 pt += buckSz + padSz + memSz;
wolfSSL 7:481bce714567 190 }
wolfSSL 7:481bce714567 191 else {
wolfSSL 7:481bce714567 192 break; /* not enough space left for more buckets of this size */
wolfSSL 7:481bce714567 193 }
wolfSSL 7:481bce714567 194 }
wolfSSL 7:481bce714567 195
wolfSSL 7:481bce714567 196 return ret;
wolfSSL 7:481bce714567 197 }
wolfSSL 7:481bce714567 198
wolfSSL 7:481bce714567 199 int wolfSSL_init_memory_heap(WOLFSSL_HEAP* heap)
wolfSSL 7:481bce714567 200 {
wolfSSL 7:481bce714567 201 word32 wc_MemSz[WOLFMEM_DEF_BUCKETS] = { WOLFMEM_BUCKETS };
wolfSSL 7:481bce714567 202 word32 wc_Dist[WOLFMEM_DEF_BUCKETS] = { WOLFMEM_DIST };
wolfSSL 7:481bce714567 203
wolfSSL 7:481bce714567 204 if (heap == NULL) {
wolfSSL 7:481bce714567 205 return BAD_FUNC_ARG;
wolfSSL 7:481bce714567 206 }
wolfSSL 7:481bce714567 207
wolfSSL 7:481bce714567 208 XMEMSET(heap, 0, sizeof(WOLFSSL_HEAP));
wolfSSL 7:481bce714567 209
wolfSSL 7:481bce714567 210 XMEMCPY(heap->sizeList, wc_MemSz, sizeof(wc_MemSz));
wolfSSL 7:481bce714567 211 XMEMCPY(heap->distList, wc_Dist, sizeof(wc_Dist));
wolfSSL 7:481bce714567 212
wolfSSL 7:481bce714567 213 if (wc_InitMutex(&(heap->memory_mutex)) != 0) {
wolfSSL 7:481bce714567 214 WOLFSSL_MSG("Error creating heap memory mutex");
wolfSSL 7:481bce714567 215 return BAD_MUTEX_E;
wolfSSL 7:481bce714567 216 }
wolfSSL 7:481bce714567 217
wolfSSL 7:481bce714567 218 return 0;
wolfSSL 7:481bce714567 219 }
wolfSSL 7:481bce714567 220
wolfSSL 7:481bce714567 221 int wc_LoadStaticMemory(WOLFSSL_HEAP_HINT** pHint,
wolfSSL 7:481bce714567 222 unsigned char* buf, unsigned int sz, int flag, int max)
wolfSSL 7:481bce714567 223 {
wolfSSL 7:481bce714567 224 int ret;
wolfSSL 7:481bce714567 225 WOLFSSL_HEAP* heap;
wolfSSL 7:481bce714567 226 WOLFSSL_HEAP_HINT* hint;
wolfSSL 7:481bce714567 227 word32 idx = 0;
wolfSSL 7:481bce714567 228
wolfSSL 7:481bce714567 229 if (pHint == NULL || buf == NULL) {
wolfSSL 7:481bce714567 230 return BAD_FUNC_ARG;
wolfSSL 7:481bce714567 231 }
wolfSSL 7:481bce714567 232
wolfSSL 7:481bce714567 233 if ((sizeof(WOLFSSL_HEAP) + sizeof(WOLFSSL_HEAP_HINT)) > sz - idx) {
wolfSSL 7:481bce714567 234 return BUFFER_E; /* not enough memory for structures */
wolfSSL 7:481bce714567 235 }
wolfSSL 7:481bce714567 236
wolfSSL 7:481bce714567 237 /* check if hint has already been assigned */
wolfSSL 7:481bce714567 238 if (*pHint == NULL) {
wolfSSL 7:481bce714567 239 heap = (WOLFSSL_HEAP*)buf;
wolfSSL 7:481bce714567 240 idx += sizeof(WOLFSSL_HEAP);
wolfSSL 7:481bce714567 241 hint = (WOLFSSL_HEAP_HINT*)(buf + idx);
wolfSSL 7:481bce714567 242 idx += sizeof(WOLFSSL_HEAP_HINT);
wolfSSL 7:481bce714567 243
wolfSSL 7:481bce714567 244 ret = wolfSSL_init_memory_heap(heap);
wolfSSL 7:481bce714567 245 if (ret != 0) {
wolfSSL 7:481bce714567 246 return ret;
wolfSSL 7:481bce714567 247 }
wolfSSL 7:481bce714567 248
wolfSSL 7:481bce714567 249 XMEMSET(hint, 0, sizeof(WOLFSSL_HEAP_HINT));
wolfSSL 7:481bce714567 250 hint->memory = heap;
wolfSSL 7:481bce714567 251 }
wolfSSL 7:481bce714567 252 else {
wolfSSL 7:481bce714567 253 #ifdef WOLFSSL_HEAP_TEST
wolfSSL 7:481bce714567 254 /* do not load in memory if test has been set */
wolfSSL 7:481bce714567 255 if (heap == (void*)WOLFSSL_HEAP_TEST) {
wolfSSL 7:481bce714567 256 return 0;
wolfSSL 7:481bce714567 257 }
wolfSSL 7:481bce714567 258 #endif
wolfSSL 7:481bce714567 259
wolfSSL 7:481bce714567 260 hint = (WOLFSSL_HEAP_HINT*)(*pHint);
wolfSSL 7:481bce714567 261 heap = hint->memory;
wolfSSL 7:481bce714567 262 }
wolfSSL 7:481bce714567 263
wolfSSL 7:481bce714567 264 ret = wolfSSL_load_static_memory(buf + idx, sz - idx, flag, heap);
wolfSSL 7:481bce714567 265 if (ret != 1) {
wolfSSL 7:481bce714567 266 WOLFSSL_MSG("Error partitioning memory");
wolfSSL 7:481bce714567 267 return -1;
wolfSSL 7:481bce714567 268 }
wolfSSL 7:481bce714567 269
wolfSSL 7:481bce714567 270 /* determine what max applies too */
wolfSSL 7:481bce714567 271 if ((flag & WOLFMEM_IO_POOL) || (flag & WOLFMEM_IO_POOL_FIXED)) {
wolfSSL 7:481bce714567 272 heap->maxIO = max;
wolfSSL 7:481bce714567 273 }
wolfSSL 7:481bce714567 274 else { /* general memory used in handshakes */
wolfSSL 7:481bce714567 275 heap->maxHa = max;
wolfSSL 7:481bce714567 276 }
wolfSSL 7:481bce714567 277
wolfSSL 7:481bce714567 278 heap->flag |= flag;
wolfSSL 7:481bce714567 279 *pHint = hint;
wolfSSL 7:481bce714567 280
wolfSSL 7:481bce714567 281 (void)max;
wolfSSL 7:481bce714567 282
wolfSSL 7:481bce714567 283 return 0;
wolfSSL 7:481bce714567 284 }
wolfSSL 7:481bce714567 285
wolfSSL 7:481bce714567 286 int wolfSSL_load_static_memory(byte* buffer, word32 sz, int flag,
wolfSSL 7:481bce714567 287 WOLFSSL_HEAP* heap)
wolfSSL 7:481bce714567 288 {
wolfSSL 7:481bce714567 289 word32 ava = sz;
wolfSSL 7:481bce714567 290 byte* pt = buffer;
wolfSSL 7:481bce714567 291 int ret = 0;
wolfSSL 7:481bce714567 292 word32 memSz = (word32)sizeof(wc_Memory);
wolfSSL 7:481bce714567 293 word32 padSz = -(int)memSz & (WOLFSSL_STATIC_ALIGN - 1);
wolfSSL 7:481bce714567 294
wolfSSL 7:481bce714567 295 WOLFSSL_ENTER("wolfSSL_load_static_memory");
wolfSSL 7:481bce714567 296
wolfSSL 7:481bce714567 297 if (buffer == NULL) {
wolfSSL 7:481bce714567 298 return BAD_FUNC_ARG;
wolfSSL 7:481bce714567 299 }
wolfSSL 7:481bce714567 300
wolfSSL 7:481bce714567 301 /* align pt */
wolfSSL 7:481bce714567 302 while ((wolfssl_word)pt % WOLFSSL_STATIC_ALIGN && pt < (buffer + sz)) {
wolfSSL 7:481bce714567 303 *pt = 0x00;
wolfSSL 7:481bce714567 304 pt++;
wolfSSL 7:481bce714567 305 ava--;
wolfSSL 7:481bce714567 306 }
wolfSSL 7:481bce714567 307
wolfSSL 7:481bce714567 308 #ifdef WOLFSSL_DEBUG_MEMORY
wolfSSL 7:481bce714567 309 printf("Allocated %d bytes for static memory @ %p\n", ava, pt);
wolfSSL 7:481bce714567 310 #endif
wolfSSL 7:481bce714567 311
wolfSSL 7:481bce714567 312 /* devide into chunks of memory and add them to available list */
wolfSSL 7:481bce714567 313 while (ava >= (heap->sizeList[0] + padSz + memSz)) {
wolfSSL 7:481bce714567 314 int i;
wolfSSL 7:481bce714567 315 /* creating only IO buffers from memory passed in, max TLS is 16k */
wolfSSL 7:481bce714567 316 if (flag & WOLFMEM_IO_POOL || flag & WOLFMEM_IO_POOL_FIXED) {
wolfSSL 7:481bce714567 317 if ((ret = create_memory_buckets(pt, ava,
wolfSSL 7:481bce714567 318 WOLFMEM_IO_SZ, 1, &(heap->io))) < 0) {
wolfSSL 7:481bce714567 319 WOLFSSL_LEAVE("wolfSSL_load_static_memory", ret);
wolfSSL 7:481bce714567 320 return ret;
wolfSSL 7:481bce714567 321 }
wolfSSL 7:481bce714567 322
wolfSSL 7:481bce714567 323 /* check if no more room left for creating IO buffers */
wolfSSL 7:481bce714567 324 if (ret == 0) {
wolfSSL 7:481bce714567 325 break;
wolfSSL 7:481bce714567 326 }
wolfSSL 7:481bce714567 327
wolfSSL 7:481bce714567 328 /* advance pointer in buffer for next buckets and keep track
wolfSSL 7:481bce714567 329 of how much memory is left available */
wolfSSL 7:481bce714567 330 pt += ret;
wolfSSL 7:481bce714567 331 ava -= ret;
wolfSSL 7:481bce714567 332 }
wolfSSL 7:481bce714567 333 else {
wolfSSL 7:481bce714567 334 /* start at largest and move to smaller buckets */
wolfSSL 7:481bce714567 335 for (i = (WOLFMEM_MAX_BUCKETS - 1); i >= 0; i--) {
wolfSSL 7:481bce714567 336 if ((heap->sizeList[i] + padSz + memSz) <= ava) {
wolfSSL 7:481bce714567 337 if ((ret = create_memory_buckets(pt, ava, heap->sizeList[i],
wolfSSL 7:481bce714567 338 heap->distList[i], &(heap->ava[i]))) < 0) {
wolfSSL 7:481bce714567 339 WOLFSSL_LEAVE("wolfSSL_load_static_memory", ret);
wolfSSL 7:481bce714567 340 return ret;
wolfSSL 7:481bce714567 341 }
wolfSSL 7:481bce714567 342
wolfSSL 7:481bce714567 343 /* advance pointer in buffer for next buckets and keep track
wolfSSL 7:481bce714567 344 of how much memory is left available */
wolfSSL 7:481bce714567 345 pt += ret;
wolfSSL 7:481bce714567 346 ava -= ret;
wolfSSL 7:481bce714567 347 }
wolfSSL 7:481bce714567 348 }
wolfSSL 7:481bce714567 349 }
wolfSSL 7:481bce714567 350 }
wolfSSL 7:481bce714567 351
wolfSSL 7:481bce714567 352 return 1;
wolfSSL 7:481bce714567 353 }
wolfSSL 7:481bce714567 354
wolfSSL 7:481bce714567 355
wolfSSL 7:481bce714567 356 /* returns the size of management memory needed for each bucket.
wolfSSL 7:481bce714567 357 * This is memory that is used to keep track of and align memory buckets. */
wolfSSL 7:481bce714567 358 int wolfSSL_MemoryPaddingSz(void)
wolfSSL 7:481bce714567 359 {
wolfSSL 7:481bce714567 360 word32 memSz = (word32)sizeof(wc_Memory);
wolfSSL 7:481bce714567 361 word32 padSz = -(int)memSz & (WOLFSSL_STATIC_ALIGN - 1);
wolfSSL 7:481bce714567 362 return memSz + padSz;
wolfSSL 7:481bce714567 363 }
wolfSSL 7:481bce714567 364
wolfSSL 7:481bce714567 365
wolfSSL 7:481bce714567 366 /* Used to calculate memory size for optimum use with buckets.
wolfSSL 7:481bce714567 367 returns the suggested size rounded down to the nearest bucket. */
wolfSSL 7:481bce714567 368 int wolfSSL_StaticBufferSz(byte* buffer, word32 sz, int flag)
wolfSSL 7:481bce714567 369 {
wolfSSL 7:481bce714567 370 word32 bucketSz[WOLFMEM_MAX_BUCKETS] = {WOLFMEM_BUCKETS};
wolfSSL 7:481bce714567 371 word32 distList[WOLFMEM_MAX_BUCKETS] = {WOLFMEM_DIST};
wolfSSL 7:481bce714567 372
wolfSSL 7:481bce714567 373 word32 ava = sz;
wolfSSL 7:481bce714567 374 byte* pt = buffer;
wolfSSL 7:481bce714567 375 word32 memSz = (word32)sizeof(wc_Memory);
wolfSSL 7:481bce714567 376 word32 padSz = -(int)memSz & (WOLFSSL_STATIC_ALIGN - 1);
wolfSSL 7:481bce714567 377
wolfSSL 7:481bce714567 378 WOLFSSL_ENTER("wolfSSL_static_size");
wolfSSL 7:481bce714567 379
wolfSSL 7:481bce714567 380 if (buffer == NULL) {
wolfSSL 7:481bce714567 381 return BAD_FUNC_ARG;
wolfSSL 7:481bce714567 382 }
wolfSSL 7:481bce714567 383
wolfSSL 7:481bce714567 384 /* align pt */
wolfSSL 7:481bce714567 385 while ((wolfssl_word)pt % WOLFSSL_STATIC_ALIGN && pt < (buffer + sz)) {
wolfSSL 7:481bce714567 386 pt++;
wolfSSL 7:481bce714567 387 ava--;
wolfSSL 7:481bce714567 388 }
wolfSSL 7:481bce714567 389
wolfSSL 7:481bce714567 390 /* creating only IO buffers from memory passed in, max TLS is 16k */
wolfSSL 7:481bce714567 391 if (flag & WOLFMEM_IO_POOL || flag & WOLFMEM_IO_POOL_FIXED) {
wolfSSL 7:481bce714567 392 if (ava < (memSz + padSz + WOLFMEM_IO_SZ)) {
wolfSSL 7:481bce714567 393 return 0; /* not enough room for even one bucket */
wolfSSL 7:481bce714567 394 }
wolfSSL 7:481bce714567 395
wolfSSL 7:481bce714567 396 ava = ava % (memSz + padSz + WOLFMEM_IO_SZ);
wolfSSL 7:481bce714567 397 }
wolfSSL 7:481bce714567 398 else {
wolfSSL 7:481bce714567 399 int i, k;
wolfSSL 7:481bce714567 400
wolfSSL 7:481bce714567 401 if (ava < (bucketSz[0] + padSz + memSz)) {
wolfSSL 7:481bce714567 402 return 0; /* not enough room for even one bucket */
wolfSSL 7:481bce714567 403 }
wolfSSL 7:481bce714567 404
wolfSSL 7:481bce714567 405 while ((ava >= (bucketSz[0] + padSz + memSz)) && (ava > 0)) {
wolfSSL 7:481bce714567 406 /* start at largest and move to smaller buckets */
wolfSSL 7:481bce714567 407 for (i = (WOLFMEM_MAX_BUCKETS - 1); i >= 0; i--) {
wolfSSL 7:481bce714567 408 for (k = distList[i]; k > 0; k--) {
wolfSSL 7:481bce714567 409 if ((bucketSz[i] + padSz + memSz) <= ava) {
wolfSSL 7:481bce714567 410 ava -= bucketSz[i] + padSz + memSz;
wolfSSL 7:481bce714567 411 }
wolfSSL 7:481bce714567 412 }
wolfSSL 7:481bce714567 413 }
wolfSSL 7:481bce714567 414 }
wolfSSL 7:481bce714567 415 }
wolfSSL 7:481bce714567 416
wolfSSL 7:481bce714567 417 return sz - ava; /* round down */
wolfSSL 7:481bce714567 418 }
wolfSSL 7:481bce714567 419
wolfSSL 7:481bce714567 420
wolfSSL 7:481bce714567 421 int FreeFixedIO(WOLFSSL_HEAP* heap, wc_Memory** io)
wolfSSL 7:481bce714567 422 {
wolfSSL 7:481bce714567 423 WOLFSSL_MSG("Freeing fixed IO buffer");
wolfSSL 7:481bce714567 424
wolfSSL 7:481bce714567 425 /* check if fixed buffer was set */
wolfSSL 7:481bce714567 426 if (*io == NULL) {
wolfSSL 7:481bce714567 427 return 1;
wolfSSL 7:481bce714567 428 }
wolfSSL 7:481bce714567 429
wolfSSL 7:481bce714567 430 if (heap == NULL) {
wolfSSL 7:481bce714567 431 WOLFSSL_MSG("No heap to return fixed IO too");
wolfSSL 7:481bce714567 432 }
wolfSSL 7:481bce714567 433 else {
wolfSSL 7:481bce714567 434 /* put IO buffer back into IO pool */
wolfSSL 7:481bce714567 435 (*io)->next = heap->io;
wolfSSL 7:481bce714567 436 heap->io = *io;
wolfSSL 7:481bce714567 437 *io = NULL;
wolfSSL 7:481bce714567 438 }
wolfSSL 7:481bce714567 439
wolfSSL 7:481bce714567 440 return 1;
wolfSSL 7:481bce714567 441 }
wolfSSL 7:481bce714567 442
wolfSSL 7:481bce714567 443
wolfSSL 7:481bce714567 444 int SetFixedIO(WOLFSSL_HEAP* heap, wc_Memory** io)
wolfSSL 7:481bce714567 445 {
wolfSSL 7:481bce714567 446 WOLFSSL_MSG("Setting fixed IO for SSL");
wolfSSL 7:481bce714567 447 if (heap == NULL) {
wolfSSL 7:481bce714567 448 return MEMORY_E;
wolfSSL 7:481bce714567 449 }
wolfSSL 7:481bce714567 450
wolfSSL 7:481bce714567 451 *io = heap->io;
wolfSSL 7:481bce714567 452
wolfSSL 7:481bce714567 453 if (*io != NULL) {
wolfSSL 7:481bce714567 454 heap->io = (*io)->next;
wolfSSL 7:481bce714567 455 (*io)->next = NULL;
wolfSSL 7:481bce714567 456 }
wolfSSL 7:481bce714567 457 else { /* failed to grab an IO buffer */
wolfSSL 7:481bce714567 458 return 0;
wolfSSL 7:481bce714567 459 }
wolfSSL 7:481bce714567 460
wolfSSL 7:481bce714567 461 return 1;
wolfSSL 7:481bce714567 462 }
wolfSSL 7:481bce714567 463
wolfSSL 7:481bce714567 464
wolfSSL 7:481bce714567 465 int wolfSSL_GetMemStats(WOLFSSL_HEAP* heap, WOLFSSL_MEM_STATS* stats)
wolfSSL 7:481bce714567 466 {
wolfSSL 7:481bce714567 467 word32 i;
wolfSSL 7:481bce714567 468 wc_Memory* pt;
wolfSSL 7:481bce714567 469
wolfSSL 7:481bce714567 470 XMEMSET(stats, 0, sizeof(WOLFSSL_MEM_STATS));
wolfSSL 7:481bce714567 471
wolfSSL 7:481bce714567 472 stats->totalAlloc = heap->alloc;
wolfSSL 7:481bce714567 473 stats->totalFr = heap->frAlc;
wolfSSL 7:481bce714567 474 stats->curAlloc = stats->totalAlloc - stats->totalFr;
wolfSSL 7:481bce714567 475 stats->maxHa = heap->maxHa;
wolfSSL 7:481bce714567 476 stats->maxIO = heap->maxIO;
wolfSSL 7:481bce714567 477 for (i = 0; i < WOLFMEM_MAX_BUCKETS; i++) {
wolfSSL 7:481bce714567 478 stats->blockSz[i] = heap->sizeList[i];
wolfSSL 7:481bce714567 479 for (pt = heap->ava[i]; pt != NULL; pt = pt->next) {
wolfSSL 7:481bce714567 480 stats->avaBlock[i] += 1;
wolfSSL 7:481bce714567 481 }
wolfSSL 7:481bce714567 482 }
wolfSSL 7:481bce714567 483
wolfSSL 7:481bce714567 484 for (pt = heap->io; pt != NULL; pt = pt->next) {
wolfSSL 7:481bce714567 485 stats->avaIO++;
wolfSSL 7:481bce714567 486 }
wolfSSL 7:481bce714567 487
wolfSSL 7:481bce714567 488 stats->flag = heap->flag; /* flag used */
wolfSSL 7:481bce714567 489
wolfSSL 7:481bce714567 490 return 1;
wolfSSL 7:481bce714567 491 }
wolfSSL 7:481bce714567 492
wolfSSL 7:481bce714567 493
wolfSSL 7:481bce714567 494 #ifdef WOLFSSL_DEBUG_MEMORY
wolfSSL 7:481bce714567 495 void* wolfSSL_Malloc(size_t size, void* heap, int type, const char* func, unsigned int line)
wolfSSL 7:481bce714567 496 #else
wolfSSL 7:481bce714567 497 void* wolfSSL_Malloc(size_t size, void* heap, int type)
wolfSSL 7:481bce714567 498 #endif
wolfSSL 7:481bce714567 499 {
wolfSSL 7:481bce714567 500 void* res = 0;
wolfSSL 7:481bce714567 501 wc_Memory* pt = NULL;
wolfSSL 7:481bce714567 502 int i;
wolfSSL 7:481bce714567 503
wolfSSL 7:481bce714567 504 /* check for testing heap hint was set */
wolfSSL 7:481bce714567 505 #ifdef WOLFSSL_HEAP_TEST
wolfSSL 7:481bce714567 506 if (heap == (void*)WOLFSSL_HEAP_TEST) {
wolfSSL 7:481bce714567 507 return malloc(size);
wolfSSL 7:481bce714567 508 }
wolfSSL 7:481bce714567 509 #endif
wolfSSL 7:481bce714567 510
wolfSSL 7:481bce714567 511 /* if no heap hint then use dynamic memory*/
wolfSSL 7:481bce714567 512 if (heap == NULL) {
wolfSSL 7:481bce714567 513 #ifdef WOLFSSL_HEAP_TEST
wolfSSL 7:481bce714567 514 /* allow using malloc for creating ctx and method */
wolfSSL 7:481bce714567 515 if (type == DYNAMIC_TYPE_CTX || type == DYNAMIC_TYPE_METHOD ||
wolfSSL 7:481bce714567 516 type == DYNAMIC_TYPE_CERT_MANAGER) {
wolfSSL 7:481bce714567 517 WOLFSSL_MSG("ERROR allowing null heap hint for ctx/method\n");
wolfSSL 7:481bce714567 518 res = malloc(size);
wolfSSL 7:481bce714567 519 }
wolfSSL 7:481bce714567 520 else {
wolfSSL 7:481bce714567 521 WOLFSSL_MSG("ERROR null heap hint passed into XMALLOC\n");
wolfSSL 7:481bce714567 522 res = NULL;
wolfSSL 7:481bce714567 523 }
wolfSSL 7:481bce714567 524 #else
wolfSSL 7:481bce714567 525 #ifndef WOLFSSL_NO_MALLOC
wolfSSL 7:481bce714567 526 res = malloc(size);
wolfSSL 7:481bce714567 527 #else
wolfSSL 7:481bce714567 528 WOLFSSL_MSG("No heap hint found to use and no malloc");
wolfSSL 7:481bce714567 529 #endif /* WOLFSSL_NO_MALLOC */
wolfSSL 7:481bce714567 530 #endif /* WOLFSSL_HEAP_TEST */
wolfSSL 7:481bce714567 531 }
wolfSSL 7:481bce714567 532 else {
wolfSSL 7:481bce714567 533 WOLFSSL_HEAP_HINT* hint = (WOLFSSL_HEAP_HINT*)heap;
wolfSSL 7:481bce714567 534 WOLFSSL_HEAP* mem = hint->memory;
wolfSSL 7:481bce714567 535
wolfSSL 7:481bce714567 536 if (wc_LockMutex(&(mem->memory_mutex)) != 0) {
wolfSSL 7:481bce714567 537 WOLFSSL_MSG("Bad memory_mutex lock");
wolfSSL 7:481bce714567 538 return NULL;
wolfSSL 7:481bce714567 539 }
wolfSSL 7:481bce714567 540
wolfSSL 7:481bce714567 541 /* case of using fixed IO buffers */
wolfSSL 7:481bce714567 542 if (mem->flag & WOLFMEM_IO_POOL_FIXED &&
wolfSSL 7:481bce714567 543 (type == DYNAMIC_TYPE_OUT_BUFFER ||
wolfSSL 7:481bce714567 544 type == DYNAMIC_TYPE_IN_BUFFER)) {
wolfSSL 7:481bce714567 545 if (type == DYNAMIC_TYPE_OUT_BUFFER) {
wolfSSL 7:481bce714567 546 pt = hint->outBuf;
wolfSSL 7:481bce714567 547 }
wolfSSL 7:481bce714567 548 if (type == DYNAMIC_TYPE_IN_BUFFER) {
wolfSSL 7:481bce714567 549 pt = hint->inBuf;
wolfSSL 7:481bce714567 550 }
wolfSSL 7:481bce714567 551 }
wolfSSL 7:481bce714567 552 else {
wolfSSL 7:481bce714567 553 /* check if using IO pool flag */
wolfSSL 7:481bce714567 554 if (mem->flag & WOLFMEM_IO_POOL &&
wolfSSL 7:481bce714567 555 (type == DYNAMIC_TYPE_OUT_BUFFER ||
wolfSSL 7:481bce714567 556 type == DYNAMIC_TYPE_IN_BUFFER)) {
wolfSSL 7:481bce714567 557 if (mem->io != NULL) {
wolfSSL 7:481bce714567 558 pt = mem->io;
wolfSSL 7:481bce714567 559 mem->io = pt->next;
wolfSSL 7:481bce714567 560 }
wolfSSL 7:481bce714567 561 }
wolfSSL 7:481bce714567 562
wolfSSL 7:481bce714567 563 /* general static memory */
wolfSSL 7:481bce714567 564 if (pt == NULL) {
wolfSSL 7:481bce714567 565 for (i = 0; i < WOLFMEM_MAX_BUCKETS; i++) {
wolfSSL 7:481bce714567 566 if ((word32)size < mem->sizeList[i]) {
wolfSSL 7:481bce714567 567 if (mem->ava[i] != NULL) {
wolfSSL 7:481bce714567 568 pt = mem->ava[i];
wolfSSL 7:481bce714567 569 mem->ava[i] = pt->next;
wolfSSL 7:481bce714567 570 break;
wolfSSL 7:481bce714567 571 }
wolfSSL 7:481bce714567 572 }
wolfSSL 7:481bce714567 573 }
wolfSSL 7:481bce714567 574 }
wolfSSL 7:481bce714567 575 }
wolfSSL 7:481bce714567 576
wolfSSL 7:481bce714567 577 if (pt != NULL) {
wolfSSL 7:481bce714567 578 mem->inUse += pt->sz;
wolfSSL 7:481bce714567 579 mem->alloc += 1;
wolfSSL 7:481bce714567 580 res = pt->buffer;
wolfSSL 7:481bce714567 581
wolfSSL 7:481bce714567 582 #ifdef WOLFSSL_DEBUG_MEMORY
wolfSSL 7:481bce714567 583 printf("Alloc: %p -> %u at %s:%d\n", pt->buffer, pt->sz, func, line);
wolfSSL 7:481bce714567 584 #endif
wolfSSL 7:481bce714567 585
wolfSSL 7:481bce714567 586 /* keep track of connection statistics if flag is set */
wolfSSL 7:481bce714567 587 if (mem->flag & WOLFMEM_TRACK_STATS) {
wolfSSL 7:481bce714567 588 WOLFSSL_MEM_CONN_STATS* stats = hint->stats;
wolfSSL 7:481bce714567 589 if (stats != NULL) {
wolfSSL 7:481bce714567 590 stats->curMem += pt->sz;
wolfSSL 7:481bce714567 591 if (stats->peakMem < stats->curMem) {
wolfSSL 7:481bce714567 592 stats->peakMem = stats->curMem;
wolfSSL 7:481bce714567 593 }
wolfSSL 7:481bce714567 594 stats->curAlloc++;
wolfSSL 7:481bce714567 595 if (stats->peakAlloc < stats->curAlloc) {
wolfSSL 7:481bce714567 596 stats->peakAlloc = stats->curAlloc;
wolfSSL 7:481bce714567 597 }
wolfSSL 7:481bce714567 598 stats->totalAlloc++;
wolfSSL 7:481bce714567 599 }
wolfSSL 7:481bce714567 600 }
wolfSSL 7:481bce714567 601 }
wolfSSL 7:481bce714567 602 else {
wolfSSL 7:481bce714567 603 WOLFSSL_MSG("ERROR ran out of static memory");
wolfSSL 7:481bce714567 604 }
wolfSSL 7:481bce714567 605
wolfSSL 7:481bce714567 606 wc_UnLockMutex(&(mem->memory_mutex));
wolfSSL 7:481bce714567 607 }
wolfSSL 7:481bce714567 608
wolfSSL 7:481bce714567 609 #ifdef WOLFSSL_MALLOC_CHECK
wolfSSL 7:481bce714567 610 if ((wolfssl_word)res % WOLFSSL_STATIC_ALIGN) {
wolfSSL 7:481bce714567 611 WOLFSSL_MSG("ERROR memory is not alligned");
wolfSSL 7:481bce714567 612 res = NULL;
wolfSSL 7:481bce714567 613 }
wolfSSL 7:481bce714567 614 #endif
wolfSSL 7:481bce714567 615
wolfSSL 7:481bce714567 616
wolfSSL 7:481bce714567 617 (void)i;
wolfSSL 7:481bce714567 618 (void)pt;
wolfSSL 7:481bce714567 619 (void)type;
wolfSSL 7:481bce714567 620
wolfSSL 7:481bce714567 621 return res;
wolfSSL 7:481bce714567 622 }
wolfSSL 7:481bce714567 623
wolfSSL 7:481bce714567 624
wolfSSL 7:481bce714567 625 #ifdef WOLFSSL_DEBUG_MEMORY
wolfSSL 7:481bce714567 626 void wolfSSL_Free(void *ptr, void* heap, int type, const char* func, unsigned int line)
wolfSSL 7:481bce714567 627 #else
wolfSSL 7:481bce714567 628 void wolfSSL_Free(void *ptr, void* heap, int type)
wolfSSL 7:481bce714567 629 #endif
wolfSSL 7:481bce714567 630 {
wolfSSL 7:481bce714567 631 int i;
wolfSSL 7:481bce714567 632 wc_Memory* pt;
wolfSSL 7:481bce714567 633
wolfSSL 7:481bce714567 634 if (ptr) {
wolfSSL 7:481bce714567 635 /* check for testing heap hint was set */
wolfSSL 7:481bce714567 636 #ifdef WOLFSSL_HEAP_TEST
wolfSSL 7:481bce714567 637 if (heap == (void*)WOLFSSL_HEAP_TEST) {
wolfSSL 7:481bce714567 638 return free(ptr);
wolfSSL 7:481bce714567 639 }
wolfSSL 7:481bce714567 640 #endif
wolfSSL 7:481bce714567 641
wolfSSL 7:481bce714567 642 if (heap == NULL) {
wolfSSL 7:481bce714567 643 #ifdef WOLFSSL_HEAP_TEST
wolfSSL 7:481bce714567 644 /* allow using malloc for creating ctx and method */
wolfSSL 7:481bce714567 645 if (type == DYNAMIC_TYPE_CTX || type == DYNAMIC_TYPE_METHOD ||
wolfSSL 7:481bce714567 646 type == DYNAMIC_TYPE_CERT_MANAGER) {
wolfSSL 7:481bce714567 647 WOLFSSL_MSG("ERROR allowing null heap hint for ctx/method\n");
wolfSSL 7:481bce714567 648 }
wolfSSL 7:481bce714567 649 else {
wolfSSL 7:481bce714567 650 WOLFSSL_MSG("ERROR null heap hint passed into XFREE\n");
wolfSSL 7:481bce714567 651 }
wolfSSL 7:481bce714567 652 #endif
wolfSSL 7:481bce714567 653 #ifndef WOLFSSL_NO_MALLOC
wolfSSL 7:481bce714567 654 free(ptr);
wolfSSL 7:481bce714567 655 #else
wolfSSL 7:481bce714567 656 WOLFSSL_MSG("Error trying to call free when turned off");
wolfSSL 7:481bce714567 657 #endif /* WOLFSSL_NO_MALLOC */
wolfSSL 7:481bce714567 658 }
wolfSSL 7:481bce714567 659 else {
wolfSSL 7:481bce714567 660 WOLFSSL_HEAP_HINT* hint = (WOLFSSL_HEAP_HINT*)heap;
wolfSSL 7:481bce714567 661 WOLFSSL_HEAP* mem = hint->memory;
wolfSSL 7:481bce714567 662 word32 padSz = -(int)sizeof(wc_Memory) & (WOLFSSL_STATIC_ALIGN - 1);
wolfSSL 7:481bce714567 663
wolfSSL 7:481bce714567 664 /* get memory struct and add it to available list */
wolfSSL 7:481bce714567 665 pt = (wc_Memory*)((byte*)ptr - sizeof(wc_Memory) - padSz);
wolfSSL 7:481bce714567 666 if (wc_LockMutex(&(mem->memory_mutex)) != 0) {
wolfSSL 7:481bce714567 667 WOLFSSL_MSG("Bad memory_mutex lock");
wolfSSL 7:481bce714567 668 return;
wolfSSL 7:481bce714567 669 }
wolfSSL 7:481bce714567 670
wolfSSL 7:481bce714567 671 /* case of using fixed IO buffers */
wolfSSL 7:481bce714567 672 if (mem->flag & WOLFMEM_IO_POOL_FIXED &&
wolfSSL 7:481bce714567 673 (type == DYNAMIC_TYPE_OUT_BUFFER ||
wolfSSL 7:481bce714567 674 type == DYNAMIC_TYPE_IN_BUFFER)) {
wolfSSL 7:481bce714567 675 /* fixed IO pools are free'd at the end of SSL lifetime
wolfSSL 7:481bce714567 676 using FreeFixedIO(WOLFSSL_HEAP* heap, wc_Memory** io) */
wolfSSL 7:481bce714567 677 }
wolfSSL 7:481bce714567 678 else if (mem->flag & WOLFMEM_IO_POOL && pt->sz == WOLFMEM_IO_SZ &&
wolfSSL 7:481bce714567 679 (type == DYNAMIC_TYPE_OUT_BUFFER ||
wolfSSL 7:481bce714567 680 type == DYNAMIC_TYPE_IN_BUFFER)) {
wolfSSL 7:481bce714567 681 pt->next = mem->io;
wolfSSL 7:481bce714567 682 mem->io = pt;
wolfSSL 7:481bce714567 683 }
wolfSSL 7:481bce714567 684 else { /* general memory free */
wolfSSL 7:481bce714567 685 for (i = 0; i < WOLFMEM_MAX_BUCKETS; i++) {
wolfSSL 7:481bce714567 686 if (pt->sz == mem->sizeList[i]) {
wolfSSL 7:481bce714567 687 pt->next = mem->ava[i];
wolfSSL 7:481bce714567 688 mem->ava[i] = pt;
wolfSSL 7:481bce714567 689 break;
wolfSSL 7:481bce714567 690 }
wolfSSL 7:481bce714567 691 }
wolfSSL 7:481bce714567 692 }
wolfSSL 7:481bce714567 693 mem->inUse -= pt->sz;
wolfSSL 7:481bce714567 694 mem->frAlc += 1;
wolfSSL 7:481bce714567 695
wolfSSL 7:481bce714567 696 #ifdef WOLFSSL_DEBUG_MEMORY
wolfSSL 7:481bce714567 697 printf("Free: %p -> %u at %s:%d\n", pt->buffer, pt->sz, func, line);
wolfSSL 7:481bce714567 698 #endif
wolfSSL 7:481bce714567 699
wolfSSL 7:481bce714567 700 /* keep track of connection statistics if flag is set */
wolfSSL 7:481bce714567 701 if (mem->flag & WOLFMEM_TRACK_STATS) {
wolfSSL 7:481bce714567 702 WOLFSSL_MEM_CONN_STATS* stats = hint->stats;
wolfSSL 7:481bce714567 703 if (stats != NULL) {
wolfSSL 7:481bce714567 704 /* avoid under flow */
wolfSSL 7:481bce714567 705 if (stats->curMem > pt->sz) {
wolfSSL 7:481bce714567 706 stats->curMem -= pt->sz;
wolfSSL 7:481bce714567 707 }
wolfSSL 7:481bce714567 708 else {
wolfSSL 7:481bce714567 709 stats->curMem = 0;
wolfSSL 7:481bce714567 710 }
wolfSSL 7:481bce714567 711
wolfSSL 7:481bce714567 712 if (stats->curAlloc > 0) {
wolfSSL 7:481bce714567 713 stats->curAlloc--;
wolfSSL 7:481bce714567 714 }
wolfSSL 7:481bce714567 715 stats->totalFr++;
wolfSSL 7:481bce714567 716 }
wolfSSL 7:481bce714567 717 }
wolfSSL 7:481bce714567 718 wc_UnLockMutex(&(mem->memory_mutex));
wolfSSL 7:481bce714567 719 }
wolfSSL 7:481bce714567 720 }
wolfSSL 7:481bce714567 721
wolfSSL 7:481bce714567 722 (void)i;
wolfSSL 7:481bce714567 723 (void)pt;
wolfSSL 7:481bce714567 724 (void)type;
wolfSSL 7:481bce714567 725 }
wolfSSL 7:481bce714567 726
wolfSSL 7:481bce714567 727 #ifdef WOLFSSL_DEBUG_MEMORY
wolfSSL 7:481bce714567 728 void* wolfSSL_Realloc(void *ptr, size_t size, void* heap, int type, const char* func, unsigned int line)
wolfSSL 7:481bce714567 729 #else
wolfSSL 7:481bce714567 730 void* wolfSSL_Realloc(void *ptr, size_t size, void* heap, int type)
wolfSSL 7:481bce714567 731 #endif
wolfSSL 7:481bce714567 732 {
wolfSSL 7:481bce714567 733 void* res = 0;
wolfSSL 7:481bce714567 734 wc_Memory* pt = NULL;
wolfSSL 7:481bce714567 735 word32 prvSz;
wolfSSL 7:481bce714567 736 int i;
wolfSSL 7:481bce714567 737
wolfSSL 7:481bce714567 738 /* check for testing heap hint was set */
wolfSSL 7:481bce714567 739 #ifdef WOLFSSL_HEAP_TEST
wolfSSL 7:481bce714567 740 if (heap == (void*)WOLFSSL_HEAP_TEST) {
wolfSSL 7:481bce714567 741 return realloc(ptr, size);
wolfSSL 7:481bce714567 742 }
wolfSSL 7:481bce714567 743 #endif
wolfSSL 7:481bce714567 744
wolfSSL 7:481bce714567 745 if (heap == NULL) {
wolfSSL 7:481bce714567 746 #ifdef WOLFSSL_HEAP_TEST
wolfSSL 7:481bce714567 747 WOLFSSL_MSG("ERROR null heap hint passed in to XREALLOC\n");
wolfSSL 7:481bce714567 748 #endif
wolfSSL 7:481bce714567 749 #ifndef WOLFSSL_NO_MALLOC
wolfSSL 7:481bce714567 750 res = realloc(ptr, size);
wolfSSL 7:481bce714567 751 #else
wolfSSL 7:481bce714567 752 WOLFSSL_MSG("NO heap found to use for realloc");
wolfSSL 7:481bce714567 753 #endif /* WOLFSSL_NO_MALLOC */
wolfSSL 7:481bce714567 754 }
wolfSSL 7:481bce714567 755 else {
wolfSSL 7:481bce714567 756 WOLFSSL_HEAP_HINT* hint = (WOLFSSL_HEAP_HINT*)heap;
wolfSSL 7:481bce714567 757 WOLFSSL_HEAP* mem = hint->memory;
wolfSSL 7:481bce714567 758 word32 padSz = -(int)sizeof(wc_Memory) & (WOLFSSL_STATIC_ALIGN - 1);
wolfSSL 7:481bce714567 759
wolfSSL 7:481bce714567 760 if (wc_LockMutex(&(mem->memory_mutex)) != 0) {
wolfSSL 7:481bce714567 761 WOLFSSL_MSG("Bad memory_mutex lock");
wolfSSL 7:481bce714567 762 return NULL;
wolfSSL 7:481bce714567 763 }
wolfSSL 7:481bce714567 764
wolfSSL 7:481bce714567 765 /* case of using fixed IO buffers or IO pool */
wolfSSL 7:481bce714567 766 if (((mem->flag & WOLFMEM_IO_POOL)||(mem->flag & WOLFMEM_IO_POOL_FIXED))
wolfSSL 7:481bce714567 767 && (type == DYNAMIC_TYPE_OUT_BUFFER ||
wolfSSL 7:481bce714567 768 type == DYNAMIC_TYPE_IN_BUFFER)) {
wolfSSL 7:481bce714567 769 /* no realloc, is fixed size */
wolfSSL 7:481bce714567 770 pt = (wc_Memory*)((byte*)ptr - padSz - sizeof(wc_Memory));
wolfSSL 7:481bce714567 771 if (pt->sz < size) {
wolfSSL 7:481bce714567 772 WOLFSSL_MSG("Error IO memory was not large enough");
wolfSSL 7:481bce714567 773 res = NULL; /* return NULL in error case */
wolfSSL 7:481bce714567 774 }
wolfSSL 7:481bce714567 775 res = pt->buffer;
wolfSSL 7:481bce714567 776 }
wolfSSL 7:481bce714567 777 else {
wolfSSL 7:481bce714567 778 /* general memory */
wolfSSL 7:481bce714567 779 for (i = 0; i < WOLFMEM_MAX_BUCKETS; i++) {
wolfSSL 7:481bce714567 780 if ((word32)size < mem->sizeList[i]) {
wolfSSL 7:481bce714567 781 if (mem->ava[i] != NULL) {
wolfSSL 7:481bce714567 782 pt = mem->ava[i];
wolfSSL 7:481bce714567 783 mem->ava[i] = pt->next;
wolfSSL 7:481bce714567 784 break;
wolfSSL 7:481bce714567 785 }
wolfSSL 7:481bce714567 786 }
wolfSSL 7:481bce714567 787 }
wolfSSL 7:481bce714567 788
wolfSSL 7:481bce714567 789 if (pt != NULL && res == NULL) {
wolfSSL 7:481bce714567 790 res = pt->buffer;
wolfSSL 7:481bce714567 791
wolfSSL 7:481bce714567 792 /* copy over original information and free ptr */
wolfSSL 7:481bce714567 793 prvSz = ((wc_Memory*)((byte*)ptr - padSz -
wolfSSL 7:481bce714567 794 sizeof(wc_Memory)))->sz;
wolfSSL 7:481bce714567 795 prvSz = (prvSz > pt->sz)? pt->sz: prvSz;
wolfSSL 7:481bce714567 796 XMEMCPY(pt->buffer, ptr, prvSz);
wolfSSL 7:481bce714567 797 mem->inUse += pt->sz;
wolfSSL 7:481bce714567 798 mem->alloc += 1;
wolfSSL 7:481bce714567 799
wolfSSL 7:481bce714567 800 /* free memory that was previously being used */
wolfSSL 7:481bce714567 801 wc_UnLockMutex(&(mem->memory_mutex));
wolfSSL 7:481bce714567 802 wolfSSL_Free(ptr, heap, type
wolfSSL 7:481bce714567 803 #ifdef WOLFSSL_DEBUG_MEMORY
wolfSSL 7:481bce714567 804 , func, line
wolfSSL 7:481bce714567 805 #endif
wolfSSL 7:481bce714567 806 );
wolfSSL 7:481bce714567 807 if (wc_LockMutex(&(mem->memory_mutex)) != 0) {
wolfSSL 7:481bce714567 808 WOLFSSL_MSG("Bad memory_mutex lock");
wolfSSL 7:481bce714567 809 return NULL;
wolfSSL 7:481bce714567 810 }
wolfSSL 7:481bce714567 811 }
wolfSSL 7:481bce714567 812 }
wolfSSL 7:481bce714567 813 wc_UnLockMutex(&(mem->memory_mutex));
wolfSSL 7:481bce714567 814 }
wolfSSL 7:481bce714567 815
wolfSSL 7:481bce714567 816 #ifdef WOLFSSL_MALLOC_CHECK
wolfSSL 7:481bce714567 817 if ((wolfssl_word)res % WOLFSSL_STATIC_ALIGN) {
wolfSSL 7:481bce714567 818 WOLFSSL_MSG("ERROR memory is not alligned");
wolfSSL 7:481bce714567 819 res = NULL;
wolfSSL 7:481bce714567 820 }
wolfSSL 7:481bce714567 821 #endif
wolfSSL 7:481bce714567 822
wolfSSL 7:481bce714567 823 (void)i;
wolfSSL 7:481bce714567 824 (void)pt;
wolfSSL 7:481bce714567 825 (void)type;
wolfSSL 7:481bce714567 826
wolfSSL 7:481bce714567 827 return res;
wolfSSL 7:481bce714567 828 }
wolfSSL 7:481bce714567 829 #endif /* WOLFSSL_STATIC_MEMORY */
wolfSSL 7:481bce714567 830
wolfSSL 7:481bce714567 831 #endif /* USE_WOLFSSL_MEMORY */
wolfSSL 7:481bce714567 832
wolfSSL 7:481bce714567 833
wolfSSL 7:481bce714567 834 #ifdef HAVE_IO_POOL
wolfSSL 7:481bce714567 835
wolfSSL 7:481bce714567 836 /* Example for user io pool, shared build may need definitions in lib proper */
wolfSSL 7:481bce714567 837
wolfSSL 7:481bce714567 838 #include <wolfssl/wolfcrypt/types.h>
wolfSSL 7:481bce714567 839 #include <stdlib.h>
wolfSSL 7:481bce714567 840
wolfSSL 7:481bce714567 841 #ifndef HAVE_THREAD_LS
wolfSSL 7:481bce714567 842 #error "Oops, simple I/O pool example needs thread local storage"
wolfSSL 7:481bce714567 843 #endif
wolfSSL 7:481bce714567 844
wolfSSL 7:481bce714567 845
wolfSSL 7:481bce714567 846 /* allow simple per thread in and out pools */
wolfSSL 7:481bce714567 847 /* use 17k size since max record size is 16k plus overhead */
wolfSSL 7:481bce714567 848 static THREAD_LS_T byte pool_in[17*1024];
wolfSSL 7:481bce714567 849 static THREAD_LS_T byte pool_out[17*1024];
wolfSSL 7:481bce714567 850
wolfSSL 7:481bce714567 851
wolfSSL 7:481bce714567 852 void* XMALLOC(size_t n, void* heap, int type)
wolfSSL 7:481bce714567 853 {
wolfSSL 7:481bce714567 854 (void)heap;
wolfSSL 7:481bce714567 855
wolfSSL 7:481bce714567 856 if (type == DYNAMIC_TYPE_IN_BUFFER) {
wolfSSL 7:481bce714567 857 if (n < sizeof(pool_in))
wolfSSL 7:481bce714567 858 return pool_in;
wolfSSL 7:481bce714567 859 else
wolfSSL 7:481bce714567 860 return NULL;
wolfSSL 7:481bce714567 861 }
wolfSSL 7:481bce714567 862
wolfSSL 7:481bce714567 863 if (type == DYNAMIC_TYPE_OUT_BUFFER) {
wolfSSL 7:481bce714567 864 if (n < sizeof(pool_out))
wolfSSL 7:481bce714567 865 return pool_out;
wolfSSL 7:481bce714567 866 else
wolfSSL 7:481bce714567 867 return NULL;
wolfSSL 7:481bce714567 868 }
wolfSSL 7:481bce714567 869
wolfSSL 7:481bce714567 870 return malloc(n);
wolfSSL 7:481bce714567 871 }
wolfSSL 7:481bce714567 872
wolfSSL 7:481bce714567 873 void* XREALLOC(void *p, size_t n, void* heap, int type)
wolfSSL 7:481bce714567 874 {
wolfSSL 7:481bce714567 875 (void)heap;
wolfSSL 7:481bce714567 876
wolfSSL 7:481bce714567 877 if (type == DYNAMIC_TYPE_IN_BUFFER) {
wolfSSL 7:481bce714567 878 if (n < sizeof(pool_in))
wolfSSL 7:481bce714567 879 return pool_in;
wolfSSL 7:481bce714567 880 else
wolfSSL 7:481bce714567 881 return NULL;
wolfSSL 7:481bce714567 882 }
wolfSSL 7:481bce714567 883
wolfSSL 7:481bce714567 884 if (type == DYNAMIC_TYPE_OUT_BUFFER) {
wolfSSL 7:481bce714567 885 if (n < sizeof(pool_out))
wolfSSL 7:481bce714567 886 return pool_out;
wolfSSL 7:481bce714567 887 else
wolfSSL 7:481bce714567 888 return NULL;
wolfSSL 7:481bce714567 889 }
wolfSSL 7:481bce714567 890
wolfSSL 7:481bce714567 891 return realloc(p, n);
wolfSSL 7:481bce714567 892 }
wolfSSL 7:481bce714567 893
wolfSSL 7:481bce714567 894 void XFREE(void *p, void* heap, int type)
wolfSSL 7:481bce714567 895 {
wolfSSL 7:481bce714567 896 (void)heap;
wolfSSL 7:481bce714567 897
wolfSSL 7:481bce714567 898 if (type == DYNAMIC_TYPE_IN_BUFFER)
wolfSSL 7:481bce714567 899 return; /* do nothing, static pool */
wolfSSL 7:481bce714567 900
wolfSSL 7:481bce714567 901 if (type == DYNAMIC_TYPE_OUT_BUFFER)
wolfSSL 7:481bce714567 902 return; /* do nothing, static pool */
wolfSSL 7:481bce714567 903
wolfSSL 7:481bce714567 904 free(p);
wolfSSL 7:481bce714567 905 }
wolfSSL 7:481bce714567 906
wolfSSL 7:481bce714567 907 #endif /* HAVE_IO_POOL */
wolfSSL 7:481bce714567 908
wolfSSL 7:481bce714567 909