Dependents:   cobaLCDJoyMotor_Thread odometry_omni_3roda_v3 odometry_omni_3roda_v1 odometry_omni_3roda_v2 ... more

Committer:
be_bryan
Date:
Mon Dec 11 17:54:04 2017 +0000
Revision:
0:b74591d5ab33
motor ++

Who changed what in which revision?

UserRevisionLine numberNew contents of line
be_bryan 0:b74591d5ab33 1 /*
be_bryan 0:b74591d5ab33 2 * Buffer-based memory allocator
be_bryan 0:b74591d5ab33 3 *
be_bryan 0:b74591d5ab33 4 * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
be_bryan 0:b74591d5ab33 5 * SPDX-License-Identifier: Apache-2.0
be_bryan 0:b74591d5ab33 6 *
be_bryan 0:b74591d5ab33 7 * Licensed under the Apache License, Version 2.0 (the "License"); you may
be_bryan 0:b74591d5ab33 8 * not use this file except in compliance with the License.
be_bryan 0:b74591d5ab33 9 * You may obtain a copy of the License at
be_bryan 0:b74591d5ab33 10 *
be_bryan 0:b74591d5ab33 11 * http://www.apache.org/licenses/LICENSE-2.0
be_bryan 0:b74591d5ab33 12 *
be_bryan 0:b74591d5ab33 13 * Unless required by applicable law or agreed to in writing, software
be_bryan 0:b74591d5ab33 14 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
be_bryan 0:b74591d5ab33 15 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
be_bryan 0:b74591d5ab33 16 * See the License for the specific language governing permissions and
be_bryan 0:b74591d5ab33 17 * limitations under the License.
be_bryan 0:b74591d5ab33 18 *
be_bryan 0:b74591d5ab33 19 * This file is part of mbed TLS (https://tls.mbed.org)
be_bryan 0:b74591d5ab33 20 */
be_bryan 0:b74591d5ab33 21
be_bryan 0:b74591d5ab33 22 #if !defined(MBEDTLS_CONFIG_FILE)
be_bryan 0:b74591d5ab33 23 #include "mbedtls/config.h"
be_bryan 0:b74591d5ab33 24 #else
be_bryan 0:b74591d5ab33 25 #include MBEDTLS_CONFIG_FILE
be_bryan 0:b74591d5ab33 26 #endif
be_bryan 0:b74591d5ab33 27
be_bryan 0:b74591d5ab33 28 #if defined(MBEDTLS_MEMORY_BUFFER_ALLOC_C)
be_bryan 0:b74591d5ab33 29 #include "mbedtls/memory_buffer_alloc.h"
be_bryan 0:b74591d5ab33 30
be_bryan 0:b74591d5ab33 31 /* No need for the header guard as MBEDTLS_MEMORY_BUFFER_ALLOC_C
be_bryan 0:b74591d5ab33 32 is dependent upon MBEDTLS_PLATFORM_C */
be_bryan 0:b74591d5ab33 33 #include "mbedtls/platform.h"
be_bryan 0:b74591d5ab33 34
be_bryan 0:b74591d5ab33 35 #include <string.h>
be_bryan 0:b74591d5ab33 36
be_bryan 0:b74591d5ab33 37 #if defined(MBEDTLS_MEMORY_BACKTRACE)
be_bryan 0:b74591d5ab33 38 #include <execinfo.h>
be_bryan 0:b74591d5ab33 39 #endif
be_bryan 0:b74591d5ab33 40
be_bryan 0:b74591d5ab33 41 #if defined(MBEDTLS_THREADING_C)
be_bryan 0:b74591d5ab33 42 #include "mbedtls/threading.h"
be_bryan 0:b74591d5ab33 43 #endif
be_bryan 0:b74591d5ab33 44
be_bryan 0:b74591d5ab33 45 /* Implementation that should never be optimized out by the compiler */
be_bryan 0:b74591d5ab33 46 static void mbedtls_zeroize( void *v, size_t n ) {
be_bryan 0:b74591d5ab33 47 volatile unsigned char *p = v; while( n-- ) *p++ = 0;
be_bryan 0:b74591d5ab33 48 }
be_bryan 0:b74591d5ab33 49
be_bryan 0:b74591d5ab33 50 #define MAGIC1 0xFF00AA55
be_bryan 0:b74591d5ab33 51 #define MAGIC2 0xEE119966
be_bryan 0:b74591d5ab33 52 #define MAX_BT 20
be_bryan 0:b74591d5ab33 53
be_bryan 0:b74591d5ab33 54 typedef struct _memory_header memory_header;
be_bryan 0:b74591d5ab33 55 struct _memory_header
be_bryan 0:b74591d5ab33 56 {
be_bryan 0:b74591d5ab33 57 size_t magic1;
be_bryan 0:b74591d5ab33 58 size_t size;
be_bryan 0:b74591d5ab33 59 size_t alloc;
be_bryan 0:b74591d5ab33 60 memory_header *prev;
be_bryan 0:b74591d5ab33 61 memory_header *next;
be_bryan 0:b74591d5ab33 62 memory_header *prev_free;
be_bryan 0:b74591d5ab33 63 memory_header *next_free;
be_bryan 0:b74591d5ab33 64 #if defined(MBEDTLS_MEMORY_BACKTRACE)
be_bryan 0:b74591d5ab33 65 char **trace;
be_bryan 0:b74591d5ab33 66 size_t trace_count;
be_bryan 0:b74591d5ab33 67 #endif
be_bryan 0:b74591d5ab33 68 size_t magic2;
be_bryan 0:b74591d5ab33 69 };
be_bryan 0:b74591d5ab33 70
be_bryan 0:b74591d5ab33 71 typedef struct
be_bryan 0:b74591d5ab33 72 {
be_bryan 0:b74591d5ab33 73 unsigned char *buf;
be_bryan 0:b74591d5ab33 74 size_t len;
be_bryan 0:b74591d5ab33 75 memory_header *first;
be_bryan 0:b74591d5ab33 76 memory_header *first_free;
be_bryan 0:b74591d5ab33 77 int verify;
be_bryan 0:b74591d5ab33 78 #if defined(MBEDTLS_MEMORY_DEBUG)
be_bryan 0:b74591d5ab33 79 size_t alloc_count;
be_bryan 0:b74591d5ab33 80 size_t free_count;
be_bryan 0:b74591d5ab33 81 size_t total_used;
be_bryan 0:b74591d5ab33 82 size_t maximum_used;
be_bryan 0:b74591d5ab33 83 size_t header_count;
be_bryan 0:b74591d5ab33 84 size_t maximum_header_count;
be_bryan 0:b74591d5ab33 85 #endif
be_bryan 0:b74591d5ab33 86 #if defined(MBEDTLS_THREADING_C)
be_bryan 0:b74591d5ab33 87 mbedtls_threading_mutex_t mutex;
be_bryan 0:b74591d5ab33 88 #endif
be_bryan 0:b74591d5ab33 89 }
be_bryan 0:b74591d5ab33 90 buffer_alloc_ctx;
be_bryan 0:b74591d5ab33 91
be_bryan 0:b74591d5ab33 92 static buffer_alloc_ctx heap;
be_bryan 0:b74591d5ab33 93
be_bryan 0:b74591d5ab33 94 #if defined(MBEDTLS_MEMORY_DEBUG)
be_bryan 0:b74591d5ab33 95 static void debug_header( memory_header *hdr )
be_bryan 0:b74591d5ab33 96 {
be_bryan 0:b74591d5ab33 97 #if defined(MBEDTLS_MEMORY_BACKTRACE)
be_bryan 0:b74591d5ab33 98 size_t i;
be_bryan 0:b74591d5ab33 99 #endif
be_bryan 0:b74591d5ab33 100
be_bryan 0:b74591d5ab33 101 mbedtls_fprintf( stderr, "HDR: PTR(%10zu), PREV(%10zu), NEXT(%10zu), "
be_bryan 0:b74591d5ab33 102 "ALLOC(%zu), SIZE(%10zu)\n",
be_bryan 0:b74591d5ab33 103 (size_t) hdr, (size_t) hdr->prev, (size_t) hdr->next,
be_bryan 0:b74591d5ab33 104 hdr->alloc, hdr->size );
be_bryan 0:b74591d5ab33 105 mbedtls_fprintf( stderr, " FPREV(%10zu), FNEXT(%10zu)\n",
be_bryan 0:b74591d5ab33 106 (size_t) hdr->prev_free, (size_t) hdr->next_free );
be_bryan 0:b74591d5ab33 107
be_bryan 0:b74591d5ab33 108 #if defined(MBEDTLS_MEMORY_BACKTRACE)
be_bryan 0:b74591d5ab33 109 mbedtls_fprintf( stderr, "TRACE: \n" );
be_bryan 0:b74591d5ab33 110 for( i = 0; i < hdr->trace_count; i++ )
be_bryan 0:b74591d5ab33 111 mbedtls_fprintf( stderr, "%s\n", hdr->trace[i] );
be_bryan 0:b74591d5ab33 112 mbedtls_fprintf( stderr, "\n" );
be_bryan 0:b74591d5ab33 113 #endif
be_bryan 0:b74591d5ab33 114 }
be_bryan 0:b74591d5ab33 115
be_bryan 0:b74591d5ab33 116 static void debug_chain()
be_bryan 0:b74591d5ab33 117 {
be_bryan 0:b74591d5ab33 118 memory_header *cur = heap.first;
be_bryan 0:b74591d5ab33 119
be_bryan 0:b74591d5ab33 120 mbedtls_fprintf( stderr, "\nBlock list\n" );
be_bryan 0:b74591d5ab33 121 while( cur != NULL )
be_bryan 0:b74591d5ab33 122 {
be_bryan 0:b74591d5ab33 123 debug_header( cur );
be_bryan 0:b74591d5ab33 124 cur = cur->next;
be_bryan 0:b74591d5ab33 125 }
be_bryan 0:b74591d5ab33 126
be_bryan 0:b74591d5ab33 127 mbedtls_fprintf( stderr, "Free list\n" );
be_bryan 0:b74591d5ab33 128 cur = heap.first_free;
be_bryan 0:b74591d5ab33 129
be_bryan 0:b74591d5ab33 130 while( cur != NULL )
be_bryan 0:b74591d5ab33 131 {
be_bryan 0:b74591d5ab33 132 debug_header( cur );
be_bryan 0:b74591d5ab33 133 cur = cur->next_free;
be_bryan 0:b74591d5ab33 134 }
be_bryan 0:b74591d5ab33 135 }
be_bryan 0:b74591d5ab33 136 #endif /* MBEDTLS_MEMORY_DEBUG */
be_bryan 0:b74591d5ab33 137
be_bryan 0:b74591d5ab33 138 static int verify_header( memory_header *hdr )
be_bryan 0:b74591d5ab33 139 {
be_bryan 0:b74591d5ab33 140 if( hdr->magic1 != MAGIC1 )
be_bryan 0:b74591d5ab33 141 {
be_bryan 0:b74591d5ab33 142 #if defined(MBEDTLS_MEMORY_DEBUG)
be_bryan 0:b74591d5ab33 143 mbedtls_fprintf( stderr, "FATAL: MAGIC1 mismatch\n" );
be_bryan 0:b74591d5ab33 144 #endif
be_bryan 0:b74591d5ab33 145 return( 1 );
be_bryan 0:b74591d5ab33 146 }
be_bryan 0:b74591d5ab33 147
be_bryan 0:b74591d5ab33 148 if( hdr->magic2 != MAGIC2 )
be_bryan 0:b74591d5ab33 149 {
be_bryan 0:b74591d5ab33 150 #if defined(MBEDTLS_MEMORY_DEBUG)
be_bryan 0:b74591d5ab33 151 mbedtls_fprintf( stderr, "FATAL: MAGIC2 mismatch\n" );
be_bryan 0:b74591d5ab33 152 #endif
be_bryan 0:b74591d5ab33 153 return( 1 );
be_bryan 0:b74591d5ab33 154 }
be_bryan 0:b74591d5ab33 155
be_bryan 0:b74591d5ab33 156 if( hdr->alloc > 1 )
be_bryan 0:b74591d5ab33 157 {
be_bryan 0:b74591d5ab33 158 #if defined(MBEDTLS_MEMORY_DEBUG)
be_bryan 0:b74591d5ab33 159 mbedtls_fprintf( stderr, "FATAL: alloc has illegal value\n" );
be_bryan 0:b74591d5ab33 160 #endif
be_bryan 0:b74591d5ab33 161 return( 1 );
be_bryan 0:b74591d5ab33 162 }
be_bryan 0:b74591d5ab33 163
be_bryan 0:b74591d5ab33 164 if( hdr->prev != NULL && hdr->prev == hdr->next )
be_bryan 0:b74591d5ab33 165 {
be_bryan 0:b74591d5ab33 166 #if defined(MBEDTLS_MEMORY_DEBUG)
be_bryan 0:b74591d5ab33 167 mbedtls_fprintf( stderr, "FATAL: prev == next\n" );
be_bryan 0:b74591d5ab33 168 #endif
be_bryan 0:b74591d5ab33 169 return( 1 );
be_bryan 0:b74591d5ab33 170 }
be_bryan 0:b74591d5ab33 171
be_bryan 0:b74591d5ab33 172 if( hdr->prev_free != NULL && hdr->prev_free == hdr->next_free )
be_bryan 0:b74591d5ab33 173 {
be_bryan 0:b74591d5ab33 174 #if defined(MBEDTLS_MEMORY_DEBUG)
be_bryan 0:b74591d5ab33 175 mbedtls_fprintf( stderr, "FATAL: prev_free == next_free\n" );
be_bryan 0:b74591d5ab33 176 #endif
be_bryan 0:b74591d5ab33 177 return( 1 );
be_bryan 0:b74591d5ab33 178 }
be_bryan 0:b74591d5ab33 179
be_bryan 0:b74591d5ab33 180 return( 0 );
be_bryan 0:b74591d5ab33 181 }
be_bryan 0:b74591d5ab33 182
be_bryan 0:b74591d5ab33 183 static int verify_chain()
be_bryan 0:b74591d5ab33 184 {
be_bryan 0:b74591d5ab33 185 memory_header *prv = heap.first, *cur = heap.first->next;
be_bryan 0:b74591d5ab33 186
be_bryan 0:b74591d5ab33 187 if( verify_header( heap.first ) != 0 )
be_bryan 0:b74591d5ab33 188 {
be_bryan 0:b74591d5ab33 189 #if defined(MBEDTLS_MEMORY_DEBUG)
be_bryan 0:b74591d5ab33 190 mbedtls_fprintf( stderr, "FATAL: verification of first header "
be_bryan 0:b74591d5ab33 191 "failed\n" );
be_bryan 0:b74591d5ab33 192 #endif
be_bryan 0:b74591d5ab33 193 return( 1 );
be_bryan 0:b74591d5ab33 194 }
be_bryan 0:b74591d5ab33 195
be_bryan 0:b74591d5ab33 196 if( heap.first->prev != NULL )
be_bryan 0:b74591d5ab33 197 {
be_bryan 0:b74591d5ab33 198 #if defined(MBEDTLS_MEMORY_DEBUG)
be_bryan 0:b74591d5ab33 199 mbedtls_fprintf( stderr, "FATAL: verification failed: "
be_bryan 0:b74591d5ab33 200 "first->prev != NULL\n" );
be_bryan 0:b74591d5ab33 201 #endif
be_bryan 0:b74591d5ab33 202 return( 1 );
be_bryan 0:b74591d5ab33 203 }
be_bryan 0:b74591d5ab33 204
be_bryan 0:b74591d5ab33 205 while( cur != NULL )
be_bryan 0:b74591d5ab33 206 {
be_bryan 0:b74591d5ab33 207 if( verify_header( cur ) != 0 )
be_bryan 0:b74591d5ab33 208 {
be_bryan 0:b74591d5ab33 209 #if defined(MBEDTLS_MEMORY_DEBUG)
be_bryan 0:b74591d5ab33 210 mbedtls_fprintf( stderr, "FATAL: verification of header "
be_bryan 0:b74591d5ab33 211 "failed\n" );
be_bryan 0:b74591d5ab33 212 #endif
be_bryan 0:b74591d5ab33 213 return( 1 );
be_bryan 0:b74591d5ab33 214 }
be_bryan 0:b74591d5ab33 215
be_bryan 0:b74591d5ab33 216 if( cur->prev != prv )
be_bryan 0:b74591d5ab33 217 {
be_bryan 0:b74591d5ab33 218 #if defined(MBEDTLS_MEMORY_DEBUG)
be_bryan 0:b74591d5ab33 219 mbedtls_fprintf( stderr, "FATAL: verification failed: "
be_bryan 0:b74591d5ab33 220 "cur->prev != prv\n" );
be_bryan 0:b74591d5ab33 221 #endif
be_bryan 0:b74591d5ab33 222 return( 1 );
be_bryan 0:b74591d5ab33 223 }
be_bryan 0:b74591d5ab33 224
be_bryan 0:b74591d5ab33 225 prv = cur;
be_bryan 0:b74591d5ab33 226 cur = cur->next;
be_bryan 0:b74591d5ab33 227 }
be_bryan 0:b74591d5ab33 228
be_bryan 0:b74591d5ab33 229 return( 0 );
be_bryan 0:b74591d5ab33 230 }
be_bryan 0:b74591d5ab33 231
be_bryan 0:b74591d5ab33 232 static void *buffer_alloc_calloc( size_t n, size_t size )
be_bryan 0:b74591d5ab33 233 {
be_bryan 0:b74591d5ab33 234 memory_header *new, *cur = heap.first_free;
be_bryan 0:b74591d5ab33 235 unsigned char *p;
be_bryan 0:b74591d5ab33 236 void *ret;
be_bryan 0:b74591d5ab33 237 size_t original_len, len;
be_bryan 0:b74591d5ab33 238 #if defined(MBEDTLS_MEMORY_BACKTRACE)
be_bryan 0:b74591d5ab33 239 void *trace_buffer[MAX_BT];
be_bryan 0:b74591d5ab33 240 size_t trace_cnt;
be_bryan 0:b74591d5ab33 241 #endif
be_bryan 0:b74591d5ab33 242
be_bryan 0:b74591d5ab33 243 if( heap.buf == NULL || heap.first == NULL )
be_bryan 0:b74591d5ab33 244 return( NULL );
be_bryan 0:b74591d5ab33 245
be_bryan 0:b74591d5ab33 246 original_len = len = n * size;
be_bryan 0:b74591d5ab33 247
be_bryan 0:b74591d5ab33 248 if( n != 0 && len / n != size )
be_bryan 0:b74591d5ab33 249 return( NULL );
be_bryan 0:b74591d5ab33 250
be_bryan 0:b74591d5ab33 251 if( len % MBEDTLS_MEMORY_ALIGN_MULTIPLE )
be_bryan 0:b74591d5ab33 252 {
be_bryan 0:b74591d5ab33 253 len -= len % MBEDTLS_MEMORY_ALIGN_MULTIPLE;
be_bryan 0:b74591d5ab33 254 len += MBEDTLS_MEMORY_ALIGN_MULTIPLE;
be_bryan 0:b74591d5ab33 255 }
be_bryan 0:b74591d5ab33 256
be_bryan 0:b74591d5ab33 257 // Find block that fits
be_bryan 0:b74591d5ab33 258 //
be_bryan 0:b74591d5ab33 259 while( cur != NULL )
be_bryan 0:b74591d5ab33 260 {
be_bryan 0:b74591d5ab33 261 if( cur->size >= len )
be_bryan 0:b74591d5ab33 262 break;
be_bryan 0:b74591d5ab33 263
be_bryan 0:b74591d5ab33 264 cur = cur->next_free;
be_bryan 0:b74591d5ab33 265 }
be_bryan 0:b74591d5ab33 266
be_bryan 0:b74591d5ab33 267 if( cur == NULL )
be_bryan 0:b74591d5ab33 268 return( NULL );
be_bryan 0:b74591d5ab33 269
be_bryan 0:b74591d5ab33 270 if( cur->alloc != 0 )
be_bryan 0:b74591d5ab33 271 {
be_bryan 0:b74591d5ab33 272 #if defined(MBEDTLS_MEMORY_DEBUG)
be_bryan 0:b74591d5ab33 273 mbedtls_fprintf( stderr, "FATAL: block in free_list but allocated "
be_bryan 0:b74591d5ab33 274 "data\n" );
be_bryan 0:b74591d5ab33 275 #endif
be_bryan 0:b74591d5ab33 276 mbedtls_exit( 1 );
be_bryan 0:b74591d5ab33 277 }
be_bryan 0:b74591d5ab33 278
be_bryan 0:b74591d5ab33 279 #if defined(MBEDTLS_MEMORY_DEBUG)
be_bryan 0:b74591d5ab33 280 heap.alloc_count++;
be_bryan 0:b74591d5ab33 281 #endif
be_bryan 0:b74591d5ab33 282
be_bryan 0:b74591d5ab33 283 // Found location, split block if > memory_header + 4 room left
be_bryan 0:b74591d5ab33 284 //
be_bryan 0:b74591d5ab33 285 if( cur->size - len < sizeof(memory_header) +
be_bryan 0:b74591d5ab33 286 MBEDTLS_MEMORY_ALIGN_MULTIPLE )
be_bryan 0:b74591d5ab33 287 {
be_bryan 0:b74591d5ab33 288 cur->alloc = 1;
be_bryan 0:b74591d5ab33 289
be_bryan 0:b74591d5ab33 290 // Remove from free_list
be_bryan 0:b74591d5ab33 291 //
be_bryan 0:b74591d5ab33 292 if( cur->prev_free != NULL )
be_bryan 0:b74591d5ab33 293 cur->prev_free->next_free = cur->next_free;
be_bryan 0:b74591d5ab33 294 else
be_bryan 0:b74591d5ab33 295 heap.first_free = cur->next_free;
be_bryan 0:b74591d5ab33 296
be_bryan 0:b74591d5ab33 297 if( cur->next_free != NULL )
be_bryan 0:b74591d5ab33 298 cur->next_free->prev_free = cur->prev_free;
be_bryan 0:b74591d5ab33 299
be_bryan 0:b74591d5ab33 300 cur->prev_free = NULL;
be_bryan 0:b74591d5ab33 301 cur->next_free = NULL;
be_bryan 0:b74591d5ab33 302
be_bryan 0:b74591d5ab33 303 #if defined(MBEDTLS_MEMORY_DEBUG)
be_bryan 0:b74591d5ab33 304 heap.total_used += cur->size;
be_bryan 0:b74591d5ab33 305 if( heap.total_used > heap.maximum_used )
be_bryan 0:b74591d5ab33 306 heap.maximum_used = heap.total_used;
be_bryan 0:b74591d5ab33 307 #endif
be_bryan 0:b74591d5ab33 308 #if defined(MBEDTLS_MEMORY_BACKTRACE)
be_bryan 0:b74591d5ab33 309 trace_cnt = backtrace( trace_buffer, MAX_BT );
be_bryan 0:b74591d5ab33 310 cur->trace = backtrace_symbols( trace_buffer, trace_cnt );
be_bryan 0:b74591d5ab33 311 cur->trace_count = trace_cnt;
be_bryan 0:b74591d5ab33 312 #endif
be_bryan 0:b74591d5ab33 313
be_bryan 0:b74591d5ab33 314 if( ( heap.verify & MBEDTLS_MEMORY_VERIFY_ALLOC ) && verify_chain() != 0 )
be_bryan 0:b74591d5ab33 315 mbedtls_exit( 1 );
be_bryan 0:b74591d5ab33 316
be_bryan 0:b74591d5ab33 317 ret = (unsigned char *) cur + sizeof( memory_header );
be_bryan 0:b74591d5ab33 318 memset( ret, 0, original_len );
be_bryan 0:b74591d5ab33 319
be_bryan 0:b74591d5ab33 320 return( ret );
be_bryan 0:b74591d5ab33 321 }
be_bryan 0:b74591d5ab33 322
be_bryan 0:b74591d5ab33 323 p = ( (unsigned char *) cur ) + sizeof(memory_header) + len;
be_bryan 0:b74591d5ab33 324 new = (memory_header *) p;
be_bryan 0:b74591d5ab33 325
be_bryan 0:b74591d5ab33 326 new->size = cur->size - len - sizeof(memory_header);
be_bryan 0:b74591d5ab33 327 new->alloc = 0;
be_bryan 0:b74591d5ab33 328 new->prev = cur;
be_bryan 0:b74591d5ab33 329 new->next = cur->next;
be_bryan 0:b74591d5ab33 330 #if defined(MBEDTLS_MEMORY_BACKTRACE)
be_bryan 0:b74591d5ab33 331 new->trace = NULL;
be_bryan 0:b74591d5ab33 332 new->trace_count = 0;
be_bryan 0:b74591d5ab33 333 #endif
be_bryan 0:b74591d5ab33 334 new->magic1 = MAGIC1;
be_bryan 0:b74591d5ab33 335 new->magic2 = MAGIC2;
be_bryan 0:b74591d5ab33 336
be_bryan 0:b74591d5ab33 337 if( new->next != NULL )
be_bryan 0:b74591d5ab33 338 new->next->prev = new;
be_bryan 0:b74591d5ab33 339
be_bryan 0:b74591d5ab33 340 // Replace cur with new in free_list
be_bryan 0:b74591d5ab33 341 //
be_bryan 0:b74591d5ab33 342 new->prev_free = cur->prev_free;
be_bryan 0:b74591d5ab33 343 new->next_free = cur->next_free;
be_bryan 0:b74591d5ab33 344 if( new->prev_free != NULL )
be_bryan 0:b74591d5ab33 345 new->prev_free->next_free = new;
be_bryan 0:b74591d5ab33 346 else
be_bryan 0:b74591d5ab33 347 heap.first_free = new;
be_bryan 0:b74591d5ab33 348
be_bryan 0:b74591d5ab33 349 if( new->next_free != NULL )
be_bryan 0:b74591d5ab33 350 new->next_free->prev_free = new;
be_bryan 0:b74591d5ab33 351
be_bryan 0:b74591d5ab33 352 cur->alloc = 1;
be_bryan 0:b74591d5ab33 353 cur->size = len;
be_bryan 0:b74591d5ab33 354 cur->next = new;
be_bryan 0:b74591d5ab33 355 cur->prev_free = NULL;
be_bryan 0:b74591d5ab33 356 cur->next_free = NULL;
be_bryan 0:b74591d5ab33 357
be_bryan 0:b74591d5ab33 358 #if defined(MBEDTLS_MEMORY_DEBUG)
be_bryan 0:b74591d5ab33 359 heap.header_count++;
be_bryan 0:b74591d5ab33 360 if( heap.header_count > heap.maximum_header_count )
be_bryan 0:b74591d5ab33 361 heap.maximum_header_count = heap.header_count;
be_bryan 0:b74591d5ab33 362 heap.total_used += cur->size;
be_bryan 0:b74591d5ab33 363 if( heap.total_used > heap.maximum_used )
be_bryan 0:b74591d5ab33 364 heap.maximum_used = heap.total_used;
be_bryan 0:b74591d5ab33 365 #endif
be_bryan 0:b74591d5ab33 366 #if defined(MBEDTLS_MEMORY_BACKTRACE)
be_bryan 0:b74591d5ab33 367 trace_cnt = backtrace( trace_buffer, MAX_BT );
be_bryan 0:b74591d5ab33 368 cur->trace = backtrace_symbols( trace_buffer, trace_cnt );
be_bryan 0:b74591d5ab33 369 cur->trace_count = trace_cnt;
be_bryan 0:b74591d5ab33 370 #endif
be_bryan 0:b74591d5ab33 371
be_bryan 0:b74591d5ab33 372 if( ( heap.verify & MBEDTLS_MEMORY_VERIFY_ALLOC ) && verify_chain() != 0 )
be_bryan 0:b74591d5ab33 373 mbedtls_exit( 1 );
be_bryan 0:b74591d5ab33 374
be_bryan 0:b74591d5ab33 375 ret = (unsigned char *) cur + sizeof( memory_header );
be_bryan 0:b74591d5ab33 376 memset( ret, 0, original_len );
be_bryan 0:b74591d5ab33 377
be_bryan 0:b74591d5ab33 378 return( ret );
be_bryan 0:b74591d5ab33 379 }
be_bryan 0:b74591d5ab33 380
be_bryan 0:b74591d5ab33 381 static void buffer_alloc_free( void *ptr )
be_bryan 0:b74591d5ab33 382 {
be_bryan 0:b74591d5ab33 383 memory_header *hdr, *old = NULL;
be_bryan 0:b74591d5ab33 384 unsigned char *p = (unsigned char *) ptr;
be_bryan 0:b74591d5ab33 385
be_bryan 0:b74591d5ab33 386 if( ptr == NULL || heap.buf == NULL || heap.first == NULL )
be_bryan 0:b74591d5ab33 387 return;
be_bryan 0:b74591d5ab33 388
be_bryan 0:b74591d5ab33 389 if( p < heap.buf || p > heap.buf + heap.len )
be_bryan 0:b74591d5ab33 390 {
be_bryan 0:b74591d5ab33 391 #if defined(MBEDTLS_MEMORY_DEBUG)
be_bryan 0:b74591d5ab33 392 mbedtls_fprintf( stderr, "FATAL: mbedtls_free() outside of managed "
be_bryan 0:b74591d5ab33 393 "space\n" );
be_bryan 0:b74591d5ab33 394 #endif
be_bryan 0:b74591d5ab33 395 mbedtls_exit( 1 );
be_bryan 0:b74591d5ab33 396 }
be_bryan 0:b74591d5ab33 397
be_bryan 0:b74591d5ab33 398 p -= sizeof(memory_header);
be_bryan 0:b74591d5ab33 399 hdr = (memory_header *) p;
be_bryan 0:b74591d5ab33 400
be_bryan 0:b74591d5ab33 401 if( verify_header( hdr ) != 0 )
be_bryan 0:b74591d5ab33 402 mbedtls_exit( 1 );
be_bryan 0:b74591d5ab33 403
be_bryan 0:b74591d5ab33 404 if( hdr->alloc != 1 )
be_bryan 0:b74591d5ab33 405 {
be_bryan 0:b74591d5ab33 406 #if defined(MBEDTLS_MEMORY_DEBUG)
be_bryan 0:b74591d5ab33 407 mbedtls_fprintf( stderr, "FATAL: mbedtls_free() on unallocated "
be_bryan 0:b74591d5ab33 408 "data\n" );
be_bryan 0:b74591d5ab33 409 #endif
be_bryan 0:b74591d5ab33 410 mbedtls_exit( 1 );
be_bryan 0:b74591d5ab33 411 }
be_bryan 0:b74591d5ab33 412
be_bryan 0:b74591d5ab33 413 hdr->alloc = 0;
be_bryan 0:b74591d5ab33 414
be_bryan 0:b74591d5ab33 415 #if defined(MBEDTLS_MEMORY_DEBUG)
be_bryan 0:b74591d5ab33 416 heap.free_count++;
be_bryan 0:b74591d5ab33 417 heap.total_used -= hdr->size;
be_bryan 0:b74591d5ab33 418 #endif
be_bryan 0:b74591d5ab33 419
be_bryan 0:b74591d5ab33 420 #if defined(MBEDTLS_MEMORY_BACKTRACE)
be_bryan 0:b74591d5ab33 421 free( hdr->trace );
be_bryan 0:b74591d5ab33 422 hdr->trace = NULL;
be_bryan 0:b74591d5ab33 423 hdr->trace_count = 0;
be_bryan 0:b74591d5ab33 424 #endif
be_bryan 0:b74591d5ab33 425
be_bryan 0:b74591d5ab33 426 // Regroup with block before
be_bryan 0:b74591d5ab33 427 //
be_bryan 0:b74591d5ab33 428 if( hdr->prev != NULL && hdr->prev->alloc == 0 )
be_bryan 0:b74591d5ab33 429 {
be_bryan 0:b74591d5ab33 430 #if defined(MBEDTLS_MEMORY_DEBUG)
be_bryan 0:b74591d5ab33 431 heap.header_count--;
be_bryan 0:b74591d5ab33 432 #endif
be_bryan 0:b74591d5ab33 433 hdr->prev->size += sizeof(memory_header) + hdr->size;
be_bryan 0:b74591d5ab33 434 hdr->prev->next = hdr->next;
be_bryan 0:b74591d5ab33 435 old = hdr;
be_bryan 0:b74591d5ab33 436 hdr = hdr->prev;
be_bryan 0:b74591d5ab33 437
be_bryan 0:b74591d5ab33 438 if( hdr->next != NULL )
be_bryan 0:b74591d5ab33 439 hdr->next->prev = hdr;
be_bryan 0:b74591d5ab33 440
be_bryan 0:b74591d5ab33 441 memset( old, 0, sizeof(memory_header) );
be_bryan 0:b74591d5ab33 442 }
be_bryan 0:b74591d5ab33 443
be_bryan 0:b74591d5ab33 444 // Regroup with block after
be_bryan 0:b74591d5ab33 445 //
be_bryan 0:b74591d5ab33 446 if( hdr->next != NULL && hdr->next->alloc == 0 )
be_bryan 0:b74591d5ab33 447 {
be_bryan 0:b74591d5ab33 448 #if defined(MBEDTLS_MEMORY_DEBUG)
be_bryan 0:b74591d5ab33 449 heap.header_count--;
be_bryan 0:b74591d5ab33 450 #endif
be_bryan 0:b74591d5ab33 451 hdr->size += sizeof(memory_header) + hdr->next->size;
be_bryan 0:b74591d5ab33 452 old = hdr->next;
be_bryan 0:b74591d5ab33 453 hdr->next = hdr->next->next;
be_bryan 0:b74591d5ab33 454
be_bryan 0:b74591d5ab33 455 if( hdr->prev_free != NULL || hdr->next_free != NULL )
be_bryan 0:b74591d5ab33 456 {
be_bryan 0:b74591d5ab33 457 if( hdr->prev_free != NULL )
be_bryan 0:b74591d5ab33 458 hdr->prev_free->next_free = hdr->next_free;
be_bryan 0:b74591d5ab33 459 else
be_bryan 0:b74591d5ab33 460 heap.first_free = hdr->next_free;
be_bryan 0:b74591d5ab33 461
be_bryan 0:b74591d5ab33 462 if( hdr->next_free != NULL )
be_bryan 0:b74591d5ab33 463 hdr->next_free->prev_free = hdr->prev_free;
be_bryan 0:b74591d5ab33 464 }
be_bryan 0:b74591d5ab33 465
be_bryan 0:b74591d5ab33 466 hdr->prev_free = old->prev_free;
be_bryan 0:b74591d5ab33 467 hdr->next_free = old->next_free;
be_bryan 0:b74591d5ab33 468
be_bryan 0:b74591d5ab33 469 if( hdr->prev_free != NULL )
be_bryan 0:b74591d5ab33 470 hdr->prev_free->next_free = hdr;
be_bryan 0:b74591d5ab33 471 else
be_bryan 0:b74591d5ab33 472 heap.first_free = hdr;
be_bryan 0:b74591d5ab33 473
be_bryan 0:b74591d5ab33 474 if( hdr->next_free != NULL )
be_bryan 0:b74591d5ab33 475 hdr->next_free->prev_free = hdr;
be_bryan 0:b74591d5ab33 476
be_bryan 0:b74591d5ab33 477 if( hdr->next != NULL )
be_bryan 0:b74591d5ab33 478 hdr->next->prev = hdr;
be_bryan 0:b74591d5ab33 479
be_bryan 0:b74591d5ab33 480 memset( old, 0, sizeof(memory_header) );
be_bryan 0:b74591d5ab33 481 }
be_bryan 0:b74591d5ab33 482
be_bryan 0:b74591d5ab33 483 // Prepend to free_list if we have not merged
be_bryan 0:b74591d5ab33 484 // (Does not have to stay in same order as prev / next list)
be_bryan 0:b74591d5ab33 485 //
be_bryan 0:b74591d5ab33 486 if( old == NULL )
be_bryan 0:b74591d5ab33 487 {
be_bryan 0:b74591d5ab33 488 hdr->next_free = heap.first_free;
be_bryan 0:b74591d5ab33 489 if( heap.first_free != NULL )
be_bryan 0:b74591d5ab33 490 heap.first_free->prev_free = hdr;
be_bryan 0:b74591d5ab33 491 heap.first_free = hdr;
be_bryan 0:b74591d5ab33 492 }
be_bryan 0:b74591d5ab33 493
be_bryan 0:b74591d5ab33 494 if( ( heap.verify & MBEDTLS_MEMORY_VERIFY_FREE ) && verify_chain() != 0 )
be_bryan 0:b74591d5ab33 495 mbedtls_exit( 1 );
be_bryan 0:b74591d5ab33 496 }
be_bryan 0:b74591d5ab33 497
be_bryan 0:b74591d5ab33 498 void mbedtls_memory_buffer_set_verify( int verify )
be_bryan 0:b74591d5ab33 499 {
be_bryan 0:b74591d5ab33 500 heap.verify = verify;
be_bryan 0:b74591d5ab33 501 }
be_bryan 0:b74591d5ab33 502
be_bryan 0:b74591d5ab33 503 int mbedtls_memory_buffer_alloc_verify()
be_bryan 0:b74591d5ab33 504 {
be_bryan 0:b74591d5ab33 505 return verify_chain();
be_bryan 0:b74591d5ab33 506 }
be_bryan 0:b74591d5ab33 507
be_bryan 0:b74591d5ab33 508 #if defined(MBEDTLS_MEMORY_DEBUG)
be_bryan 0:b74591d5ab33 509 void mbedtls_memory_buffer_alloc_status()
be_bryan 0:b74591d5ab33 510 {
be_bryan 0:b74591d5ab33 511 mbedtls_fprintf( stderr,
be_bryan 0:b74591d5ab33 512 "Current use: %zu blocks / %zu bytes, max: %zu blocks / "
be_bryan 0:b74591d5ab33 513 "%zu bytes (total %zu bytes), alloc / free: %zu / %zu\n",
be_bryan 0:b74591d5ab33 514 heap.header_count, heap.total_used,
be_bryan 0:b74591d5ab33 515 heap.maximum_header_count, heap.maximum_used,
be_bryan 0:b74591d5ab33 516 heap.maximum_header_count * sizeof( memory_header )
be_bryan 0:b74591d5ab33 517 + heap.maximum_used,
be_bryan 0:b74591d5ab33 518 heap.alloc_count, heap.free_count );
be_bryan 0:b74591d5ab33 519
be_bryan 0:b74591d5ab33 520 if( heap.first->next == NULL )
be_bryan 0:b74591d5ab33 521 mbedtls_fprintf( stderr, "All memory de-allocated in stack buffer\n" );
be_bryan 0:b74591d5ab33 522 else
be_bryan 0:b74591d5ab33 523 {
be_bryan 0:b74591d5ab33 524 mbedtls_fprintf( stderr, "Memory currently allocated:\n" );
be_bryan 0:b74591d5ab33 525 debug_chain();
be_bryan 0:b74591d5ab33 526 }
be_bryan 0:b74591d5ab33 527 }
be_bryan 0:b74591d5ab33 528
be_bryan 0:b74591d5ab33 529 void mbedtls_memory_buffer_alloc_max_get( size_t *max_used, size_t *max_blocks )
be_bryan 0:b74591d5ab33 530 {
be_bryan 0:b74591d5ab33 531 *max_used = heap.maximum_used;
be_bryan 0:b74591d5ab33 532 *max_blocks = heap.maximum_header_count;
be_bryan 0:b74591d5ab33 533 }
be_bryan 0:b74591d5ab33 534
be_bryan 0:b74591d5ab33 535 void mbedtls_memory_buffer_alloc_max_reset( void )
be_bryan 0:b74591d5ab33 536 {
be_bryan 0:b74591d5ab33 537 heap.maximum_used = 0;
be_bryan 0:b74591d5ab33 538 heap.maximum_header_count = 0;
be_bryan 0:b74591d5ab33 539 }
be_bryan 0:b74591d5ab33 540
be_bryan 0:b74591d5ab33 541 void mbedtls_memory_buffer_alloc_cur_get( size_t *cur_used, size_t *cur_blocks )
be_bryan 0:b74591d5ab33 542 {
be_bryan 0:b74591d5ab33 543 *cur_used = heap.total_used;
be_bryan 0:b74591d5ab33 544 *cur_blocks = heap.header_count;
be_bryan 0:b74591d5ab33 545 }
be_bryan 0:b74591d5ab33 546 #endif /* MBEDTLS_MEMORY_DEBUG */
be_bryan 0:b74591d5ab33 547
be_bryan 0:b74591d5ab33 548 #if defined(MBEDTLS_THREADING_C)
be_bryan 0:b74591d5ab33 549 static void *buffer_alloc_calloc_mutexed( size_t n, size_t size )
be_bryan 0:b74591d5ab33 550 {
be_bryan 0:b74591d5ab33 551 void *buf;
be_bryan 0:b74591d5ab33 552 if( mbedtls_mutex_lock( &heap.mutex ) != 0 )
be_bryan 0:b74591d5ab33 553 return( NULL );
be_bryan 0:b74591d5ab33 554 buf = buffer_alloc_calloc( n, size );
be_bryan 0:b74591d5ab33 555 if( mbedtls_mutex_unlock( &heap.mutex ) )
be_bryan 0:b74591d5ab33 556 return( NULL );
be_bryan 0:b74591d5ab33 557 return( buf );
be_bryan 0:b74591d5ab33 558 }
be_bryan 0:b74591d5ab33 559
be_bryan 0:b74591d5ab33 560 static void buffer_alloc_free_mutexed( void *ptr )
be_bryan 0:b74591d5ab33 561 {
be_bryan 0:b74591d5ab33 562 /* We have to good option here, but corrupting the heap seems
be_bryan 0:b74591d5ab33 563 * worse than loosing memory. */
be_bryan 0:b74591d5ab33 564 if( mbedtls_mutex_lock( &heap.mutex ) )
be_bryan 0:b74591d5ab33 565 return;
be_bryan 0:b74591d5ab33 566 buffer_alloc_free( ptr );
be_bryan 0:b74591d5ab33 567 (void) mbedtls_mutex_unlock( &heap.mutex );
be_bryan 0:b74591d5ab33 568 }
be_bryan 0:b74591d5ab33 569 #endif /* MBEDTLS_THREADING_C */
be_bryan 0:b74591d5ab33 570
be_bryan 0:b74591d5ab33 571 void mbedtls_memory_buffer_alloc_init( unsigned char *buf, size_t len )
be_bryan 0:b74591d5ab33 572 {
be_bryan 0:b74591d5ab33 573 memset( &heap, 0, sizeof(buffer_alloc_ctx) );
be_bryan 0:b74591d5ab33 574 memset( buf, 0, len );
be_bryan 0:b74591d5ab33 575
be_bryan 0:b74591d5ab33 576 #if defined(MBEDTLS_THREADING_C)
be_bryan 0:b74591d5ab33 577 mbedtls_mutex_init( &heap.mutex );
be_bryan 0:b74591d5ab33 578 mbedtls_platform_set_calloc_free( buffer_alloc_calloc_mutexed,
be_bryan 0:b74591d5ab33 579 buffer_alloc_free_mutexed );
be_bryan 0:b74591d5ab33 580 #else
be_bryan 0:b74591d5ab33 581 mbedtls_platform_set_calloc_free( buffer_alloc_calloc, buffer_alloc_free );
be_bryan 0:b74591d5ab33 582 #endif
be_bryan 0:b74591d5ab33 583
be_bryan 0:b74591d5ab33 584 if( (size_t) buf % MBEDTLS_MEMORY_ALIGN_MULTIPLE )
be_bryan 0:b74591d5ab33 585 {
be_bryan 0:b74591d5ab33 586 /* Adjust len first since buf is used in the computation */
be_bryan 0:b74591d5ab33 587 len -= MBEDTLS_MEMORY_ALIGN_MULTIPLE
be_bryan 0:b74591d5ab33 588 - (size_t) buf % MBEDTLS_MEMORY_ALIGN_MULTIPLE;
be_bryan 0:b74591d5ab33 589 buf += MBEDTLS_MEMORY_ALIGN_MULTIPLE
be_bryan 0:b74591d5ab33 590 - (size_t) buf % MBEDTLS_MEMORY_ALIGN_MULTIPLE;
be_bryan 0:b74591d5ab33 591 }
be_bryan 0:b74591d5ab33 592
be_bryan 0:b74591d5ab33 593 heap.buf = buf;
be_bryan 0:b74591d5ab33 594 heap.len = len;
be_bryan 0:b74591d5ab33 595
be_bryan 0:b74591d5ab33 596 heap.first = (memory_header *) buf;
be_bryan 0:b74591d5ab33 597 heap.first->size = len - sizeof(memory_header);
be_bryan 0:b74591d5ab33 598 heap.first->magic1 = MAGIC1;
be_bryan 0:b74591d5ab33 599 heap.first->magic2 = MAGIC2;
be_bryan 0:b74591d5ab33 600 heap.first_free = heap.first;
be_bryan 0:b74591d5ab33 601 }
be_bryan 0:b74591d5ab33 602
be_bryan 0:b74591d5ab33 603 void mbedtls_memory_buffer_alloc_free()
be_bryan 0:b74591d5ab33 604 {
be_bryan 0:b74591d5ab33 605 #if defined(MBEDTLS_THREADING_C)
be_bryan 0:b74591d5ab33 606 mbedtls_mutex_free( &heap.mutex );
be_bryan 0:b74591d5ab33 607 #endif
be_bryan 0:b74591d5ab33 608 mbedtls_zeroize( &heap, sizeof(buffer_alloc_ctx) );
be_bryan 0:b74591d5ab33 609 }
be_bryan 0:b74591d5ab33 610
be_bryan 0:b74591d5ab33 611 #if defined(MBEDTLS_SELF_TEST)
be_bryan 0:b74591d5ab33 612 static int check_pointer( void *p )
be_bryan 0:b74591d5ab33 613 {
be_bryan 0:b74591d5ab33 614 if( p == NULL )
be_bryan 0:b74591d5ab33 615 return( -1 );
be_bryan 0:b74591d5ab33 616
be_bryan 0:b74591d5ab33 617 if( (size_t) p % MBEDTLS_MEMORY_ALIGN_MULTIPLE != 0 )
be_bryan 0:b74591d5ab33 618 return( -1 );
be_bryan 0:b74591d5ab33 619
be_bryan 0:b74591d5ab33 620 return( 0 );
be_bryan 0:b74591d5ab33 621 }
be_bryan 0:b74591d5ab33 622
be_bryan 0:b74591d5ab33 623 static int check_all_free( )
be_bryan 0:b74591d5ab33 624 {
be_bryan 0:b74591d5ab33 625 if(
be_bryan 0:b74591d5ab33 626 #if defined(MBEDTLS_MEMORY_DEBUG)
be_bryan 0:b74591d5ab33 627 heap.total_used != 0 ||
be_bryan 0:b74591d5ab33 628 #endif
be_bryan 0:b74591d5ab33 629 heap.first != heap.first_free ||
be_bryan 0:b74591d5ab33 630 (void *) heap.first != (void *) heap.buf )
be_bryan 0:b74591d5ab33 631 {
be_bryan 0:b74591d5ab33 632 return( -1 );
be_bryan 0:b74591d5ab33 633 }
be_bryan 0:b74591d5ab33 634
be_bryan 0:b74591d5ab33 635 return( 0 );
be_bryan 0:b74591d5ab33 636 }
be_bryan 0:b74591d5ab33 637
be_bryan 0:b74591d5ab33 638 #define TEST_ASSERT( condition ) \
be_bryan 0:b74591d5ab33 639 if( ! (condition) ) \
be_bryan 0:b74591d5ab33 640 { \
be_bryan 0:b74591d5ab33 641 if( verbose != 0 ) \
be_bryan 0:b74591d5ab33 642 mbedtls_printf( "failed\n" ); \
be_bryan 0:b74591d5ab33 643 \
be_bryan 0:b74591d5ab33 644 ret = 1; \
be_bryan 0:b74591d5ab33 645 goto cleanup; \
be_bryan 0:b74591d5ab33 646 }
be_bryan 0:b74591d5ab33 647
be_bryan 0:b74591d5ab33 648 int mbedtls_memory_buffer_alloc_self_test( int verbose )
be_bryan 0:b74591d5ab33 649 {
be_bryan 0:b74591d5ab33 650 unsigned char buf[1024];
be_bryan 0:b74591d5ab33 651 unsigned char *p, *q, *r, *end;
be_bryan 0:b74591d5ab33 652 int ret = 0;
be_bryan 0:b74591d5ab33 653
be_bryan 0:b74591d5ab33 654 if( verbose != 0 )
be_bryan 0:b74591d5ab33 655 mbedtls_printf( " MBA test #1 (basic alloc-free cycle): " );
be_bryan 0:b74591d5ab33 656
be_bryan 0:b74591d5ab33 657 mbedtls_memory_buffer_alloc_init( buf, sizeof( buf ) );
be_bryan 0:b74591d5ab33 658
be_bryan 0:b74591d5ab33 659 p = mbedtls_calloc( 1, 1 );
be_bryan 0:b74591d5ab33 660 q = mbedtls_calloc( 1, 128 );
be_bryan 0:b74591d5ab33 661 r = mbedtls_calloc( 1, 16 );
be_bryan 0:b74591d5ab33 662
be_bryan 0:b74591d5ab33 663 TEST_ASSERT( check_pointer( p ) == 0 &&
be_bryan 0:b74591d5ab33 664 check_pointer( q ) == 0 &&
be_bryan 0:b74591d5ab33 665 check_pointer( r ) == 0 );
be_bryan 0:b74591d5ab33 666
be_bryan 0:b74591d5ab33 667 mbedtls_free( r );
be_bryan 0:b74591d5ab33 668 mbedtls_free( q );
be_bryan 0:b74591d5ab33 669 mbedtls_free( p );
be_bryan 0:b74591d5ab33 670
be_bryan 0:b74591d5ab33 671 TEST_ASSERT( check_all_free( ) == 0 );
be_bryan 0:b74591d5ab33 672
be_bryan 0:b74591d5ab33 673 /* Memorize end to compare with the next test */
be_bryan 0:b74591d5ab33 674 end = heap.buf + heap.len;
be_bryan 0:b74591d5ab33 675
be_bryan 0:b74591d5ab33 676 mbedtls_memory_buffer_alloc_free( );
be_bryan 0:b74591d5ab33 677
be_bryan 0:b74591d5ab33 678 if( verbose != 0 )
be_bryan 0:b74591d5ab33 679 mbedtls_printf( "passed\n" );
be_bryan 0:b74591d5ab33 680
be_bryan 0:b74591d5ab33 681 if( verbose != 0 )
be_bryan 0:b74591d5ab33 682 mbedtls_printf( " MBA test #2 (buf not aligned): " );
be_bryan 0:b74591d5ab33 683
be_bryan 0:b74591d5ab33 684 mbedtls_memory_buffer_alloc_init( buf + 1, sizeof( buf ) - 1 );
be_bryan 0:b74591d5ab33 685
be_bryan 0:b74591d5ab33 686 TEST_ASSERT( heap.buf + heap.len == end );
be_bryan 0:b74591d5ab33 687
be_bryan 0:b74591d5ab33 688 p = mbedtls_calloc( 1, 1 );
be_bryan 0:b74591d5ab33 689 q = mbedtls_calloc( 1, 128 );
be_bryan 0:b74591d5ab33 690 r = mbedtls_calloc( 1, 16 );
be_bryan 0:b74591d5ab33 691
be_bryan 0:b74591d5ab33 692 TEST_ASSERT( check_pointer( p ) == 0 &&
be_bryan 0:b74591d5ab33 693 check_pointer( q ) == 0 &&
be_bryan 0:b74591d5ab33 694 check_pointer( r ) == 0 );
be_bryan 0:b74591d5ab33 695
be_bryan 0:b74591d5ab33 696 mbedtls_free( r );
be_bryan 0:b74591d5ab33 697 mbedtls_free( q );
be_bryan 0:b74591d5ab33 698 mbedtls_free( p );
be_bryan 0:b74591d5ab33 699
be_bryan 0:b74591d5ab33 700 TEST_ASSERT( check_all_free( ) == 0 );
be_bryan 0:b74591d5ab33 701
be_bryan 0:b74591d5ab33 702 mbedtls_memory_buffer_alloc_free( );
be_bryan 0:b74591d5ab33 703
be_bryan 0:b74591d5ab33 704 if( verbose != 0 )
be_bryan 0:b74591d5ab33 705 mbedtls_printf( "passed\n" );
be_bryan 0:b74591d5ab33 706
be_bryan 0:b74591d5ab33 707 if( verbose != 0 )
be_bryan 0:b74591d5ab33 708 mbedtls_printf( " MBA test #3 (full): " );
be_bryan 0:b74591d5ab33 709
be_bryan 0:b74591d5ab33 710 mbedtls_memory_buffer_alloc_init( buf, sizeof( buf ) );
be_bryan 0:b74591d5ab33 711
be_bryan 0:b74591d5ab33 712 p = mbedtls_calloc( 1, sizeof( buf ) - sizeof( memory_header ) );
be_bryan 0:b74591d5ab33 713
be_bryan 0:b74591d5ab33 714 TEST_ASSERT( check_pointer( p ) == 0 );
be_bryan 0:b74591d5ab33 715 TEST_ASSERT( mbedtls_calloc( 1, 1 ) == NULL );
be_bryan 0:b74591d5ab33 716
be_bryan 0:b74591d5ab33 717 mbedtls_free( p );
be_bryan 0:b74591d5ab33 718
be_bryan 0:b74591d5ab33 719 p = mbedtls_calloc( 1, sizeof( buf ) - 2 * sizeof( memory_header ) - 16 );
be_bryan 0:b74591d5ab33 720 q = mbedtls_calloc( 1, 16 );
be_bryan 0:b74591d5ab33 721
be_bryan 0:b74591d5ab33 722 TEST_ASSERT( check_pointer( p ) == 0 && check_pointer( q ) == 0 );
be_bryan 0:b74591d5ab33 723 TEST_ASSERT( mbedtls_calloc( 1, 1 ) == NULL );
be_bryan 0:b74591d5ab33 724
be_bryan 0:b74591d5ab33 725 mbedtls_free( q );
be_bryan 0:b74591d5ab33 726
be_bryan 0:b74591d5ab33 727 TEST_ASSERT( mbedtls_calloc( 1, 17 ) == NULL );
be_bryan 0:b74591d5ab33 728
be_bryan 0:b74591d5ab33 729 mbedtls_free( p );
be_bryan 0:b74591d5ab33 730
be_bryan 0:b74591d5ab33 731 TEST_ASSERT( check_all_free( ) == 0 );
be_bryan 0:b74591d5ab33 732
be_bryan 0:b74591d5ab33 733 mbedtls_memory_buffer_alloc_free( );
be_bryan 0:b74591d5ab33 734
be_bryan 0:b74591d5ab33 735 if( verbose != 0 )
be_bryan 0:b74591d5ab33 736 mbedtls_printf( "passed\n" );
be_bryan 0:b74591d5ab33 737
be_bryan 0:b74591d5ab33 738 cleanup:
be_bryan 0:b74591d5ab33 739 mbedtls_memory_buffer_alloc_free( );
be_bryan 0:b74591d5ab33 740
be_bryan 0:b74591d5ab33 741 return( ret );
be_bryan 0:b74591d5ab33 742 }
be_bryan 0:b74591d5ab33 743 #endif /* MBEDTLS_SELF_TEST */
be_bryan 0:b74591d5ab33 744
be_bryan 0:b74591d5ab33 745 #endif /* MBEDTLS_MEMORY_BUFFER_ALLOC_C */