1#line 2 "suites/host_test.function" 2 3/** 4 * \brief Verifies that string is in string parameter format i.e. "<str>" 5 * It also strips enclosing '"' from the input string. 6 * 7 * \param str String parameter. 8 * 9 * \return 0 if success else 1 10 */ 11int verify_string(char **str) 12{ 13 if ((*str)[0] != '"' || 14 (*str)[strlen(*str) - 1] != '"') { 15 mbedtls_fprintf(stderr, 16 "Expected string (with \"\") for parameter and got: %s\n", *str); 17 return -1; 18 } 19 20 (*str)++; 21 (*str)[strlen(*str) - 1] = '\0'; 22 23 return 0; 24} 25 26/** 27 * \brief Verifies that string is an integer. Also gives the converted 28 * integer value. 29 * 30 * \param str Input string. 31 * \param p_value Pointer to output value. 32 * 33 * \return 0 if success else 1 34 */ 35int verify_int(char *str, intmax_t *p_value) 36{ 37 char *end = NULL; 38 errno = 0; 39 /* Limit the range to long: for large integers, the test framework will 40 * use expressions anyway. */ 41 long value = strtol(str, &end, 0); 42 if (errno == EINVAL || *end != '\0') { 43 mbedtls_fprintf(stderr, 44 "Expected integer for parameter and got: %s\n", str); 45 return KEY_VALUE_MAPPING_NOT_FOUND; 46 } 47 if (errno == ERANGE) { 48 mbedtls_fprintf(stderr, "Integer out of range: %s\n", str); 49 return KEY_VALUE_MAPPING_NOT_FOUND; 50 } 51 *p_value = value; 52 return 0; 53} 54 55 56/** 57 * \brief Usage string. 58 * 59 */ 60#define USAGE \ 61 "Usage: %s [OPTIONS] files...\n\n" \ 62 " Command line arguments:\n" \ 63 " files... One or more test data files. If no file is\n" \ 64 " specified the following default test case\n" \ 65 " file is used:\n" \ 66 " %s\n\n" \ 67 " Options:\n" \ 68 " -v | --verbose Display full information about each test\n" \ 69 " -h | --help Display this information\n\n", \ 70 argv[0], \ 71 "TESTCASE_FILENAME" 72 73 74/** 75 * \brief Read a line from the passed file pointer. 76 * 77 * \param f FILE pointer 78 * \param buf Pointer to memory to hold read line. 79 * \param len Length of the buf. 80 * 81 * \return 0 if success else -1 82 */ 83int get_line(FILE *f, char *buf, size_t len) 84{ 85 char *ret; 86 int i = 0, str_len = 0, has_string = 0; 87 88 /* Read until we get a valid line */ 89 do { 90 ret = fgets(buf, len, f); 91 if (ret == NULL) { 92 return -1; 93 } 94 95 str_len = strlen(buf); 96 97 /* Skip empty line and comment */ 98 if (str_len == 0 || buf[0] == '#') { 99 continue; 100 } 101 has_string = 0; 102 for (i = 0; i < str_len; i++) { 103 char c = buf[i]; 104 if (c != ' ' && c != '\t' && c != '\n' && 105 c != '\v' && c != '\f' && c != '\r') { 106 has_string = 1; 107 break; 108 } 109 } 110 } while (!has_string); 111 112 /* Strip new line and carriage return */ 113 ret = buf + strlen(buf); 114 if (ret-- > buf && *ret == '\n') { 115 *ret = '\0'; 116 } 117 if (ret-- > buf && *ret == '\r') { 118 *ret = '\0'; 119 } 120 121 return 0; 122} 123 124/** 125 * \brief Splits string delimited by ':'. Ignores '\:'. 126 * 127 * \param buf Input string 128 * \param len Input string length 129 * \param params Out params found 130 * \param params_len Out params array len 131 * 132 * \return Count of strings found. 133 */ 134static int parse_arguments(char *buf, size_t len, char **params, 135 size_t params_len) 136{ 137 size_t cnt = 0, i; 138 char *cur = buf; 139 char *p = buf, *q; 140 141 params[cnt++] = cur; 142 143 while (*p != '\0' && p < (buf + len)) { 144 if (*p == '\\') { 145 p++; 146 p++; 147 continue; 148 } 149 if (*p == ':') { 150 if (p + 1 < buf + len) { 151 cur = p + 1; 152 TEST_HELPER_ASSERT(cnt < params_len); 153 params[cnt++] = cur; 154 } 155 *p = '\0'; 156 } 157 158 p++; 159 } 160 161 /* Replace backslash escapes in strings */ 162 for (i = 0; i < cnt; i++) { 163 p = params[i]; 164 q = params[i]; 165 166 while (*p != '\0') { 167 if (*p == '\\') { 168 ++p; 169 switch (*p) { 170 case 'n': 171 *p = '\n'; 172 break; 173 default: 174 // Fall through to copying *p 175 break; 176 } 177 } 178 *(q++) = *(p++); 179 } 180 *q = '\0'; 181 } 182 183 return cnt; 184} 185 186/** 187 * \brief Converts parameters into test function consumable parameters. 188 * Example: Input: {"int", "0", "char*", "Hello", 189 * "hex", "abef", "exp", "1"} 190 * Output: { 191 * 0, // Verified int 192 * "Hello", // Verified string 193 * 2, { 0xab, 0xef },// Converted len,hex pair 194 * 9600 // Evaluated expression 195 * } 196 * 197 * 198 * \param cnt Parameter array count. 199 * \param params Out array of found parameters. 200 * \param int_params_store Memory for storing processed integer parameters. 201 * 202 * \return 0 for success else 1 203 */ 204static int convert_params(size_t cnt, char **params, 205 mbedtls_test_argument_t *int_params_store) 206{ 207 char **cur = params; 208 char **out = params; 209 int ret = DISPATCH_TEST_SUCCESS; 210 211 while (cur < params + cnt) { 212 char *type = *cur++; 213 char *val = *cur++; 214 215 if (strcmp(type, "char*") == 0) { 216 if (verify_string(&val) == 0) { 217 *out++ = val; 218 } else { 219 ret = (DISPATCH_INVALID_TEST_DATA); 220 break; 221 } 222 } else if (strcmp(type, "int") == 0) { 223 if (verify_int(val, &int_params_store->sint) == 0) { 224 *out++ = (char *) int_params_store++; 225 } else { 226 ret = (DISPATCH_INVALID_TEST_DATA); 227 break; 228 } 229 } else if (strcmp(type, "hex") == 0) { 230 if (verify_string(&val) == 0) { 231 size_t len; 232 233 TEST_HELPER_ASSERT( 234 mbedtls_test_unhexify((unsigned char *) val, strlen(val), 235 val, &len) == 0); 236 237 int_params_store->len = len; 238 *out++ = val; 239 *out++ = (char *) (int_params_store++); 240 } else { 241 ret = (DISPATCH_INVALID_TEST_DATA); 242 break; 243 } 244 } else if (strcmp(type, "exp") == 0) { 245 int exp_id = strtol(val, NULL, 10); 246 if (get_expression(exp_id, &int_params_store->sint) == 0) { 247 *out++ = (char *) int_params_store++; 248 } else { 249 ret = (DISPATCH_INVALID_TEST_DATA); 250 break; 251 } 252 } else { 253 ret = (DISPATCH_INVALID_TEST_DATA); 254 break; 255 } 256 } 257 return ret; 258} 259 260/** 261 * \brief Tests snprintf implementation with test input. 262 * 263 * \note 264 * At high optimization levels (e.g. gcc -O3), this function may be 265 * inlined in run_test_snprintf. This can trigger a spurious warning about 266 * potential misuse of snprintf from gcc -Wformat-truncation (observed with 267 * gcc 7.2). This warning makes tests in run_test_snprintf redundant on gcc 268 * only. They are still valid for other compilers. Avoid this warning by 269 * forbidding inlining of this function by gcc. 270 * 271 * \param n Buffer test length. 272 * \param ref_buf Expected buffer. 273 * \param ref_ret Expected snprintf return value. 274 * 275 * \return 0 for success else 1 276 */ 277#if defined(__GNUC__) 278__attribute__((__noinline__)) 279#endif 280static int test_snprintf(size_t n, const char *ref_buf, int ref_ret) 281{ 282 int ret; 283 char buf[10] = "xxxxxxxxx"; 284 const char ref[10] = "xxxxxxxxx"; 285 286 if (n >= sizeof(buf)) { 287 return -1; 288 } 289 ret = mbedtls_snprintf(buf, n, "%s", "123"); 290 if (ret < 0 || (size_t) ret >= n) { 291 ret = -1; 292 } 293 294 if (strncmp(ref_buf, buf, sizeof(buf)) != 0 || 295 ref_ret != ret || 296 memcmp(buf + n, ref + n, sizeof(buf) - n) != 0) { 297 return 1; 298 } 299 300 return 0; 301} 302 303/** 304 * \brief Tests snprintf implementation. 305 * 306 * \return 0 for success else 1 307 */ 308static int run_test_snprintf(void) 309{ 310 return test_snprintf(0, "xxxxxxxxx", -1) != 0 || 311 test_snprintf(1, "", -1) != 0 || 312 test_snprintf(2, "1", -1) != 0 || 313 test_snprintf(3, "12", -1) != 0 || 314 test_snprintf(4, "123", 3) != 0 || 315 test_snprintf(5, "123", 3) != 0; 316} 317 318/** \brief Write the description of the test case to the outcome CSV file. 319 * 320 * \param outcome_file The file to write to. 321 * If this is \c NULL, this function does nothing. 322 * \param argv0 The test suite name. 323 * \param test_case The test case description. 324 */ 325static void write_outcome_entry(FILE *outcome_file, 326 const char *argv0, 327 const char *test_case) 328{ 329 /* The non-varying fields are initialized on first use. */ 330 static const char *platform = NULL; 331 static const char *configuration = NULL; 332 static const char *test_suite = NULL; 333 334 if (outcome_file == NULL) { 335 return; 336 } 337 338 if (platform == NULL) { 339 platform = getenv("MBEDTLS_TEST_PLATFORM"); 340 if (platform == NULL) { 341 platform = "unknown"; 342 } 343 } 344 if (configuration == NULL) { 345 configuration = getenv("MBEDTLS_TEST_CONFIGURATION"); 346 if (configuration == NULL) { 347 configuration = "unknown"; 348 } 349 } 350 if (test_suite == NULL) { 351 test_suite = strrchr(argv0, '/'); 352 if (test_suite != NULL) { 353 test_suite += 1; // skip the '/' 354 } else { 355 test_suite = argv0; 356 } 357 } 358 359 /* Write the beginning of the outcome line. 360 * Ignore errors: writing the outcome file is on a best-effort basis. */ 361 mbedtls_fprintf(outcome_file, "%s;%s;%s;%s;", 362 platform, configuration, test_suite, test_case); 363} 364 365/** \brief Write the result of the test case to the outcome CSV file. 366 * 367 * \param outcome_file The file to write to. 368 * If this is \c NULL, this function does nothing. 369 * \param unmet_dep_count The number of unmet dependencies. 370 * \param unmet_dependencies The array of unmet dependencies. 371 * \param missing_unmet_dependencies Non-zero if there was a problem tracking 372 * all unmet dependencies, 0 otherwise. 373 * \param ret The test dispatch status (DISPATCH_xxx). 374 * \param info A pointer to the test info structure. 375 */ 376static void write_outcome_result(FILE *outcome_file, 377 size_t unmet_dep_count, 378 int unmet_dependencies[], 379 int missing_unmet_dependencies, 380 int ret, 381 const mbedtls_test_info_t *info) 382{ 383 if (outcome_file == NULL) { 384 return; 385 } 386 387 /* Write the end of the outcome line. 388 * Ignore errors: writing the outcome file is on a best-effort basis. */ 389 switch (ret) { 390 case DISPATCH_TEST_SUCCESS: 391 if (unmet_dep_count > 0) { 392 size_t i; 393 mbedtls_fprintf(outcome_file, "SKIP"); 394 for (i = 0; i < unmet_dep_count; i++) { 395 mbedtls_fprintf(outcome_file, "%c%d", 396 i == 0 ? ';' : ':', 397 unmet_dependencies[i]); 398 } 399 if (missing_unmet_dependencies) { 400 mbedtls_fprintf(outcome_file, ":..."); 401 } 402 break; 403 } 404 switch (info->result) { 405 case MBEDTLS_TEST_RESULT_SUCCESS: 406 mbedtls_fprintf(outcome_file, "PASS;"); 407 break; 408 case MBEDTLS_TEST_RESULT_SKIPPED: 409 mbedtls_fprintf(outcome_file, "SKIP;Runtime skip"); 410 break; 411 default: 412 mbedtls_fprintf(outcome_file, "FAIL;%s:%d:%s", 413 info->filename, info->line_no, 414 info->test); 415 break; 416 } 417 break; 418 case DISPATCH_TEST_FN_NOT_FOUND: 419 mbedtls_fprintf(outcome_file, "FAIL;Test function not found"); 420 break; 421 case DISPATCH_INVALID_TEST_DATA: 422 mbedtls_fprintf(outcome_file, "FAIL;Invalid test data"); 423 break; 424 case DISPATCH_UNSUPPORTED_SUITE: 425 mbedtls_fprintf(outcome_file, "SKIP;Unsupported suite"); 426 break; 427 default: 428 mbedtls_fprintf(outcome_file, "FAIL;Unknown cause"); 429 break; 430 } 431 mbedtls_fprintf(outcome_file, "\n"); 432 fflush(outcome_file); 433} 434 435/** 436 * \brief Desktop implementation of execute_tests(). 437 * Parses command line and executes tests from 438 * supplied or default data file. 439 * 440 * \param argc Command line argument count. 441 * \param argv Argument array. 442 * 443 * \return Program exit status. 444 */ 445int execute_tests(int argc, const char **argv) 446{ 447 /* Local Configurations and options */ 448 const char *default_filename = "DATA_FILE"; 449 const char *test_filename = NULL; 450 const char **test_files = NULL; 451 size_t testfile_count = 0; 452 int option_verbose = 0; 453 size_t function_id = 0; 454 455 /* Other Local variables */ 456 int arg_index = 1; 457 const char *next_arg; 458 size_t testfile_index, i, cnt; 459 int ret; 460 unsigned total_errors = 0, total_tests = 0, total_skipped = 0; 461 FILE *file; 462 char buf[5000]; 463 char *params[50]; 464 /* Store for processed integer params. */ 465 mbedtls_test_argument_t int_params[50]; 466 void *pointer; 467#if defined(__unix__) || (defined(__APPLE__) && defined(__MACH__)) 468 int stdout_fd = -1; 469#endif /* __unix__ || __APPLE__ __MACH__ */ 470 const char *outcome_file_name = getenv("MBEDTLS_TEST_OUTCOME_FILE"); 471 FILE *outcome_file = NULL; 472 473#if defined(MBEDTLS_MEMORY_BUFFER_ALLOC_C) && \ 474 !defined(TEST_SUITE_MEMORY_BUFFER_ALLOC) 475 unsigned char alloc_buf[1000000]; 476 mbedtls_memory_buffer_alloc_init(alloc_buf, sizeof(alloc_buf)); 477#endif 478 479#if defined(MBEDTLS_TEST_MUTEX_USAGE) 480 mbedtls_test_mutex_usage_init(); 481#endif 482 483 /* 484 * The C standard doesn't guarantee that all-bits-0 is the representation 485 * of a NULL pointer. We do however use that in our code for initializing 486 * structures, which should work on every modern platform. Let's be sure. 487 */ 488 memset(&pointer, 0, sizeof(void *)); 489 if (pointer != NULL) { 490 mbedtls_fprintf(stderr, "all-bits-zero is not a NULL pointer\n"); 491 return 1; 492 } 493 494 /* 495 * Make sure we have a snprintf that correctly zero-terminates 496 */ 497 if (run_test_snprintf() != 0) { 498 mbedtls_fprintf(stderr, "the snprintf implementation is broken\n"); 499 return 1; 500 } 501 502 if (outcome_file_name != NULL && *outcome_file_name != '\0') { 503 outcome_file = fopen(outcome_file_name, "a"); 504 if (outcome_file == NULL) { 505 mbedtls_fprintf(stderr, "Unable to open outcome file. Continuing anyway.\n"); 506 } 507 } 508 509 while (arg_index < argc) { 510 next_arg = argv[arg_index]; 511 512 if (strcmp(next_arg, "--verbose") == 0 || 513 strcmp(next_arg, "-v") == 0) { 514 option_verbose = 1; 515 } else if (strcmp(next_arg, "--help") == 0 || 516 strcmp(next_arg, "-h") == 0) { 517 mbedtls_fprintf(stdout, USAGE); 518 mbedtls_exit(EXIT_SUCCESS); 519 } else { 520 /* Not an option, therefore treat all further arguments as the file 521 * list. 522 */ 523 test_files = &argv[arg_index]; 524 testfile_count = argc - arg_index; 525 break; 526 } 527 528 arg_index++; 529 } 530 531 /* If no files were specified, assume a default */ 532 if (test_files == NULL || testfile_count == 0) { 533 test_files = &default_filename; 534 testfile_count = 1; 535 } 536 537 /* Initialize the struct that holds information about the last test */ 538 mbedtls_test_info_reset(); 539 540 /* Now begin to execute the tests in the testfiles */ 541 for (testfile_index = 0; 542 testfile_index < testfile_count; 543 testfile_index++) { 544 size_t unmet_dep_count = 0; 545 int unmet_dependencies[20]; 546 int missing_unmet_dependencies = 0; 547 548 test_filename = test_files[testfile_index]; 549 550 file = fopen(test_filename, "r"); 551 if (file == NULL) { 552 mbedtls_fprintf(stderr, "Failed to open test file: %s\n", 553 test_filename); 554 if (outcome_file != NULL) { 555 fclose(outcome_file); 556 } 557 return 1; 558 } 559 560 while (!feof(file)) { 561 if (unmet_dep_count > 0) { 562 mbedtls_fprintf(stderr, 563 "FATAL: Dep count larger than zero at start of loop\n"); 564 mbedtls_exit(MBEDTLS_EXIT_FAILURE); 565 } 566 unmet_dep_count = 0; 567 missing_unmet_dependencies = 0; 568 569 if ((ret = get_line(file, buf, sizeof(buf))) != 0) { 570 break; 571 } 572 mbedtls_fprintf(stdout, "%s%.66s", 573 mbedtls_test_info.result == MBEDTLS_TEST_RESULT_FAILED ? 574 "\n" : "", buf); 575 mbedtls_fprintf(stdout, " "); 576 for (i = strlen(buf) + 1; i < 67; i++) { 577 mbedtls_fprintf(stdout, "."); 578 } 579 mbedtls_fprintf(stdout, " "); 580 fflush(stdout); 581 write_outcome_entry(outcome_file, argv[0], buf); 582 583 total_tests++; 584 585 if ((ret = get_line(file, buf, sizeof(buf))) != 0) { 586 break; 587 } 588 cnt = parse_arguments(buf, strlen(buf), params, 589 sizeof(params) / sizeof(params[0])); 590 591 if (strcmp(params[0], "depends_on") == 0) { 592 for (i = 1; i < cnt; i++) { 593 int dep_id = strtol(params[i], NULL, 10); 594 if (dep_check(dep_id) != DEPENDENCY_SUPPORTED) { 595 if (unmet_dep_count < 596 ARRAY_LENGTH(unmet_dependencies)) { 597 unmet_dependencies[unmet_dep_count] = dep_id; 598 unmet_dep_count++; 599 } else { 600 missing_unmet_dependencies = 1; 601 } 602 } 603 } 604 605 if ((ret = get_line(file, buf, sizeof(buf))) != 0) { 606 break; 607 } 608 cnt = parse_arguments(buf, strlen(buf), params, 609 sizeof(params) / sizeof(params[0])); 610 } 611 612 // If there are no unmet dependencies execute the test 613 if (unmet_dep_count == 0) { 614 mbedtls_test_info_reset(); 615 616#if defined(__unix__) || (defined(__APPLE__) && defined(__MACH__)) 617 /* Suppress all output from the library unless we're verbose 618 * mode 619 */ 620 if (!option_verbose) { 621 stdout_fd = redirect_output(stdout, "/dev/null"); 622 if (stdout_fd == -1) { 623 /* Redirection has failed with no stdout so exit */ 624 exit(1); 625 } 626 } 627#endif /* __unix__ || __APPLE__ __MACH__ */ 628 629 function_id = strtoul(params[0], NULL, 10); 630 if ((ret = check_test(function_id)) == DISPATCH_TEST_SUCCESS) { 631 ret = convert_params(cnt - 1, params + 1, int_params); 632 if (DISPATCH_TEST_SUCCESS == ret) { 633 ret = dispatch_test(function_id, (void **) (params + 1)); 634 } 635 } 636 637#if defined(__unix__) || (defined(__APPLE__) && defined(__MACH__)) 638 if (!option_verbose && restore_output(stdout, stdout_fd)) { 639 /* Redirection has failed with no stdout so exit */ 640 exit(1); 641 } 642#endif /* __unix__ || __APPLE__ __MACH__ */ 643 644 } 645 646 write_outcome_result(outcome_file, 647 unmet_dep_count, unmet_dependencies, 648 missing_unmet_dependencies, 649 ret, &mbedtls_test_info); 650 if (unmet_dep_count > 0 || ret == DISPATCH_UNSUPPORTED_SUITE) { 651 total_skipped++; 652 mbedtls_fprintf(stdout, "----"); 653 654 if (1 == option_verbose && ret == DISPATCH_UNSUPPORTED_SUITE) { 655 mbedtls_fprintf(stdout, "\n Test Suite not enabled"); 656 } 657 658 if (1 == option_verbose && unmet_dep_count > 0) { 659 mbedtls_fprintf(stdout, "\n Unmet dependencies: "); 660 for (i = 0; i < unmet_dep_count; i++) { 661 mbedtls_fprintf(stdout, "%d ", 662 unmet_dependencies[i]); 663 } 664 if (missing_unmet_dependencies) { 665 mbedtls_fprintf(stdout, "..."); 666 } 667 } 668 mbedtls_fprintf(stdout, "\n"); 669 fflush(stdout); 670 671 unmet_dep_count = 0; 672 missing_unmet_dependencies = 0; 673 } else if (ret == DISPATCH_TEST_SUCCESS) { 674 if (mbedtls_test_info.result == MBEDTLS_TEST_RESULT_SUCCESS) { 675 mbedtls_fprintf(stdout, "PASS\n"); 676 } else if (mbedtls_test_info.result == MBEDTLS_TEST_RESULT_SKIPPED) { 677 mbedtls_fprintf(stdout, "----\n"); 678 total_skipped++; 679 } else { 680 total_errors++; 681 mbedtls_fprintf(stdout, "FAILED\n"); 682 mbedtls_fprintf(stdout, " %s\n at ", 683 mbedtls_test_info.test); 684 if (mbedtls_test_info.step != (unsigned long) (-1)) { 685 mbedtls_fprintf(stdout, "step %lu, ", 686 mbedtls_test_info.step); 687 } 688 mbedtls_fprintf(stdout, "line %d, %s", 689 mbedtls_test_info.line_no, 690 mbedtls_test_info.filename); 691 if (mbedtls_test_info.line1[0] != 0) { 692 mbedtls_fprintf(stdout, "\n %s", 693 mbedtls_test_info.line1); 694 } 695 if (mbedtls_test_info.line2[0] != 0) { 696 mbedtls_fprintf(stdout, "\n %s", 697 mbedtls_test_info.line2); 698 } 699 } 700 fflush(stdout); 701 } else if (ret == DISPATCH_INVALID_TEST_DATA) { 702 mbedtls_fprintf(stderr, "FAILED: FATAL PARSE ERROR\n"); 703 fclose(file); 704 mbedtls_exit(2); 705 } else if (ret == DISPATCH_TEST_FN_NOT_FOUND) { 706 mbedtls_fprintf(stderr, "FAILED: FATAL TEST FUNCTION NOT FOUND\n"); 707 fclose(file); 708 mbedtls_exit(2); 709 } else { 710 total_errors++; 711 } 712 } 713 fclose(file); 714 } 715 716 if (outcome_file != NULL) { 717 fclose(outcome_file); 718 } 719 720 mbedtls_fprintf(stdout, 721 "\n----------------------------------------------------------------------------\n\n"); 722 if (total_errors == 0) { 723 mbedtls_fprintf(stdout, "PASSED"); 724 } else { 725 mbedtls_fprintf(stdout, "FAILED"); 726 } 727 728 mbedtls_fprintf(stdout, " (%u / %u tests (%u skipped))\n", 729 total_tests - total_errors, total_tests, total_skipped); 730 731#if defined(MBEDTLS_MEMORY_BUFFER_ALLOC_C) && \ 732 !defined(TEST_SUITE_MEMORY_BUFFER_ALLOC) 733#if defined(MBEDTLS_MEMORY_DEBUG) 734 mbedtls_memory_buffer_alloc_status(); 735#endif 736 mbedtls_memory_buffer_alloc_free(); 737#endif 738 739 return total_errors != 0; 740} 741