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