1 /* 2 * Entropy accumulator implementation 3 * 4 * Copyright (C) 2006-2016, 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_ENTROPY_C) 31 32 #if defined(MBEDTLS_TEST_NULL_ENTROPY) 33 #warning "**** WARNING! MBEDTLS_TEST_NULL_ENTROPY defined! " 34 #warning "**** THIS BUILD HAS NO DEFINED ENTROPY SOURCES " 35 #warning "**** THIS BUILD IS *NOT* SUITABLE FOR PRODUCTION USE " 36 #endif 37 38 #include "mbedtls/entropy.h" 39 #include "mbedtls/entropy_poll.h" 40 41 #include <string.h> 42 43 #if defined(MBEDTLS_FS_IO) 44 #include <stdio.h> 45 #endif 46 47 #if defined(MBEDTLS_ENTROPY_NV_SEED) 48 #include "mbedtls/platform.h" 49 #endif 50 51 #if defined(MBEDTLS_SELF_TEST) 52 #if defined(MBEDTLS_PLATFORM_C) 53 #include "mbedtls/platform.h" 54 #else 55 #include <stdio.h> 56 #define mbedtls_printf printf 57 #endif /* MBEDTLS_PLATFORM_C */ 58 #endif /* MBEDTLS_SELF_TEST */ 59 60 #if defined(MBEDTLS_HAVEGE_C) 61 #include "mbedtls/havege.h" 62 #endif 63 64 /* Implementation that should never be optimized out by the compiler */ 65 static void mbedtls_zeroize( void *v, size_t n ) { 66 volatile unsigned char *p = v; while( n-- ) *p++ = 0; 67 } 68 69 #define ENTROPY_MAX_LOOP 256 /**< Maximum amount to loop before error */ 70 71 void mbedtls_entropy_init( mbedtls_entropy_context *ctx ) 72 { 73 memset( ctx, 0, sizeof(mbedtls_entropy_context) ); 74 75 #if defined(MBEDTLS_THREADING_C) 76 mbedtls_mutex_init( &ctx->mutex ); 77 #endif 78 79 #if defined(MBEDTLS_ENTROPY_SHA512_ACCUMULATOR) 80 mbedtls_sha512_starts( &ctx->accumulator, 0 ); 81 #else 82 mbedtls_sha256_starts( &ctx->accumulator, 0 ); 83 #endif 84 #if defined(MBEDTLS_HAVEGE_C) 85 mbedtls_havege_init( &ctx->havege_data ); 86 #endif 87 88 #if defined(MBEDTLS_TEST_NULL_ENTROPY) 89 mbedtls_entropy_add_source( ctx, mbedtls_null_entropy_poll, NULL, 90 1, MBEDTLS_ENTROPY_SOURCE_STRONG ); 91 #endif 92 93 #if !defined(MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES) 94 #if !defined(MBEDTLS_NO_PLATFORM_ENTROPY) 95 mbedtls_entropy_add_source( ctx, mbedtls_platform_entropy_poll, NULL, 96 MBEDTLS_ENTROPY_MIN_PLATFORM, 97 MBEDTLS_ENTROPY_SOURCE_STRONG ); 98 #endif 99 #if defined(MBEDTLS_TIMING_C) 100 mbedtls_entropy_add_source( ctx, mbedtls_hardclock_poll, NULL, 101 MBEDTLS_ENTROPY_MIN_HARDCLOCK, 102 MBEDTLS_ENTROPY_SOURCE_WEAK ); 103 #endif 104 #if defined(MBEDTLS_HAVEGE_C) 105 mbedtls_entropy_add_source( ctx, mbedtls_havege_poll, &ctx->havege_data, 106 MBEDTLS_ENTROPY_MIN_HAVEGE, 107 MBEDTLS_ENTROPY_SOURCE_STRONG ); 108 #endif 109 #if defined(MBEDTLS_ENTROPY_HARDWARE_ALT) 110 mbedtls_entropy_add_source( ctx, mbedtls_hardware_poll, NULL, 111 MBEDTLS_ENTROPY_MIN_HARDWARE, 112 MBEDTLS_ENTROPY_SOURCE_STRONG ); 113 #endif 114 #if defined(MBEDTLS_ENTROPY_NV_SEED) 115 mbedtls_entropy_add_source( ctx, mbedtls_nv_seed_poll, NULL, 116 MBEDTLS_ENTROPY_BLOCK_SIZE, 117 MBEDTLS_ENTROPY_SOURCE_STRONG ); 118 #endif 119 #endif /* MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES */ 120 } 121 122 void mbedtls_entropy_free( mbedtls_entropy_context *ctx ) 123 { 124 #if defined(MBEDTLS_HAVEGE_C) 125 mbedtls_havege_free( &ctx->havege_data ); 126 #endif 127 #if defined(MBEDTLS_THREADING_C) 128 mbedtls_mutex_free( &ctx->mutex ); 129 #endif 130 mbedtls_zeroize( ctx, sizeof( mbedtls_entropy_context ) ); 131 } 132 133 int mbedtls_entropy_add_source( mbedtls_entropy_context *ctx, 134 mbedtls_entropy_f_source_ptr f_source, void *p_source, 135 size_t threshold, int strong ) 136 { 137 int idx, ret = 0; 138 139 #if defined(MBEDTLS_THREADING_C) 140 if( ( ret = mbedtls_mutex_lock( &ctx->mutex ) ) != 0 ) 141 return( ret ); 142 #endif 143 144 idx = ctx->source_count; 145 if( idx >= MBEDTLS_ENTROPY_MAX_SOURCES ) 146 { 147 ret = MBEDTLS_ERR_ENTROPY_MAX_SOURCES; 148 goto exit; 149 } 150 151 ctx->source[idx].f_source = f_source; 152 ctx->source[idx].p_source = p_source; 153 ctx->source[idx].threshold = threshold; 154 ctx->source[idx].strong = strong; 155 156 ctx->source_count++; 157 158 exit: 159 #if defined(MBEDTLS_THREADING_C) 160 if( mbedtls_mutex_unlock( &ctx->mutex ) != 0 ) 161 return( MBEDTLS_ERR_THREADING_MUTEX_ERROR ); 162 #endif 163 164 return( ret ); 165 } 166 167 /* 168 * Entropy accumulator update 169 */ 170 static int entropy_update( mbedtls_entropy_context *ctx, unsigned char source_id, 171 const unsigned char *data, size_t len ) 172 { 173 unsigned char header[2]; 174 unsigned char tmp[MBEDTLS_ENTROPY_BLOCK_SIZE]; 175 size_t use_len = len; 176 const unsigned char *p = data; 177 178 if( use_len > MBEDTLS_ENTROPY_BLOCK_SIZE ) 179 { 180 #if defined(MBEDTLS_ENTROPY_SHA512_ACCUMULATOR) 181 mbedtls_sha512( data, len, tmp, 0 ); 182 #else 183 mbedtls_sha256( data, len, tmp, 0 ); 184 #endif 185 p = tmp; 186 use_len = MBEDTLS_ENTROPY_BLOCK_SIZE; 187 } 188 189 header[0] = source_id; 190 header[1] = use_len & 0xFF; 191 192 #if defined(MBEDTLS_ENTROPY_SHA512_ACCUMULATOR) 193 mbedtls_sha512_update( &ctx->accumulator, header, 2 ); 194 mbedtls_sha512_update( &ctx->accumulator, p, use_len ); 195 #else 196 mbedtls_sha256_update( &ctx->accumulator, header, 2 ); 197 mbedtls_sha256_update( &ctx->accumulator, p, use_len ); 198 #endif 199 200 return( 0 ); 201 } 202 203 int mbedtls_entropy_update_manual( mbedtls_entropy_context *ctx, 204 const unsigned char *data, size_t len ) 205 { 206 int ret; 207 208 #if defined(MBEDTLS_THREADING_C) 209 if( ( ret = mbedtls_mutex_lock( &ctx->mutex ) ) != 0 ) 210 return( ret ); 211 #endif 212 213 ret = entropy_update( ctx, MBEDTLS_ENTROPY_SOURCE_MANUAL, data, len ); 214 215 #if defined(MBEDTLS_THREADING_C) 216 if( mbedtls_mutex_unlock( &ctx->mutex ) != 0 ) 217 return( MBEDTLS_ERR_THREADING_MUTEX_ERROR ); 218 #endif 219 220 return( ret ); 221 } 222 223 /* 224 * Run through the different sources to add entropy to our accumulator 225 */ 226 static int entropy_gather_internal( mbedtls_entropy_context *ctx ) 227 { 228 int ret, i, have_one_strong = 0; 229 unsigned char buf[MBEDTLS_ENTROPY_MAX_GATHER]; 230 size_t olen; 231 232 if( ctx->source_count == 0 ) 233 return( MBEDTLS_ERR_ENTROPY_NO_SOURCES_DEFINED ); 234 235 /* 236 * Run through our entropy sources 237 */ 238 for( i = 0; i < ctx->source_count; i++ ) 239 { 240 if( ctx->source[i].strong == MBEDTLS_ENTROPY_SOURCE_STRONG ) 241 have_one_strong = 1; 242 243 olen = 0; 244 if( ( ret = ctx->source[i].f_source( ctx->source[i].p_source, 245 buf, MBEDTLS_ENTROPY_MAX_GATHER, &olen ) ) != 0 ) 246 { 247 return( ret ); 248 } 249 250 /* 251 * Add if we actually gathered something 252 */ 253 if( olen > 0 ) 254 { 255 entropy_update( ctx, (unsigned char) i, buf, olen ); 256 ctx->source[i].size += olen; 257 } 258 } 259 260 if( have_one_strong == 0 ) 261 return( MBEDTLS_ERR_ENTROPY_NO_STRONG_SOURCE ); 262 263 return( 0 ); 264 } 265 266 /* 267 * Thread-safe wrapper for entropy_gather_internal() 268 */ 269 int mbedtls_entropy_gather( mbedtls_entropy_context *ctx ) 270 { 271 int ret; 272 273 #if defined(MBEDTLS_THREADING_C) 274 if( ( ret = mbedtls_mutex_lock( &ctx->mutex ) ) != 0 ) 275 return( ret ); 276 #endif 277 278 ret = entropy_gather_internal( ctx ); 279 280 #if defined(MBEDTLS_THREADING_C) 281 if( mbedtls_mutex_unlock( &ctx->mutex ) != 0 ) 282 return( MBEDTLS_ERR_THREADING_MUTEX_ERROR ); 283 #endif 284 285 return( ret ); 286 } 287 288 int mbedtls_entropy_func( void *data, unsigned char *output, size_t len ) 289 { 290 int ret, count = 0, i, done; 291 mbedtls_entropy_context *ctx = (mbedtls_entropy_context *) data; 292 unsigned char buf[MBEDTLS_ENTROPY_BLOCK_SIZE]; 293 294 if( len > MBEDTLS_ENTROPY_BLOCK_SIZE ) 295 return( MBEDTLS_ERR_ENTROPY_SOURCE_FAILED ); 296 297 #if defined(MBEDTLS_ENTROPY_NV_SEED) 298 /* Update the NV entropy seed before generating any entropy for outside 299 * use. 300 */ 301 if( ctx->initial_entropy_run == 0 ) 302 { 303 ctx->initial_entropy_run = 1; 304 if( ( ret = mbedtls_entropy_update_nv_seed( ctx ) ) != 0 ) 305 return( ret ); 306 } 307 #endif 308 309 #if defined(MBEDTLS_THREADING_C) 310 if( ( ret = mbedtls_mutex_lock( &ctx->mutex ) ) != 0 ) 311 return( ret ); 312 #endif 313 314 /* 315 * Always gather extra entropy before a call 316 */ 317 do 318 { 319 if( count++ > ENTROPY_MAX_LOOP ) 320 { 321 ret = MBEDTLS_ERR_ENTROPY_SOURCE_FAILED; 322 goto exit; 323 } 324 325 if( ( ret = entropy_gather_internal( ctx ) ) != 0 ) 326 goto exit; 327 328 done = 1; 329 for( i = 0; i < ctx->source_count; i++ ) 330 if( ctx->source[i].size < ctx->source[i].threshold ) 331 done = 0; 332 } 333 while( ! done ); 334 335 memset( buf, 0, MBEDTLS_ENTROPY_BLOCK_SIZE ); 336 337 #if defined(MBEDTLS_ENTROPY_SHA512_ACCUMULATOR) 338 mbedtls_sha512_finish( &ctx->accumulator, buf ); 339 340 /* 341 * Reset accumulator and counters and recycle existing entropy 342 */ 343 memset( &ctx->accumulator, 0, sizeof( mbedtls_sha512_context ) ); 344 mbedtls_sha512_starts( &ctx->accumulator, 0 ); 345 mbedtls_sha512_update( &ctx->accumulator, buf, MBEDTLS_ENTROPY_BLOCK_SIZE ); 346 347 /* 348 * Perform second SHA-512 on entropy 349 */ 350 mbedtls_sha512( buf, MBEDTLS_ENTROPY_BLOCK_SIZE, buf, 0 ); 351 #else /* MBEDTLS_ENTROPY_SHA512_ACCUMULATOR */ 352 mbedtls_sha256_finish( &ctx->accumulator, buf ); 353 354 /* 355 * Reset accumulator and counters and recycle existing entropy 356 */ 357 memset( &ctx->accumulator, 0, sizeof( mbedtls_sha256_context ) ); 358 mbedtls_sha256_starts( &ctx->accumulator, 0 ); 359 mbedtls_sha256_update( &ctx->accumulator, buf, MBEDTLS_ENTROPY_BLOCK_SIZE ); 360 361 /* 362 * Perform second SHA-256 on entropy 363 */ 364 mbedtls_sha256( buf, MBEDTLS_ENTROPY_BLOCK_SIZE, buf, 0 ); 365 #endif /* MBEDTLS_ENTROPY_SHA512_ACCUMULATOR */ 366 367 for( i = 0; i < ctx->source_count; i++ ) 368 ctx->source[i].size = 0; 369 370 memcpy( output, buf, len ); 371 372 ret = 0; 373 374 exit: 375 #if defined(MBEDTLS_THREADING_C) 376 if( mbedtls_mutex_unlock( &ctx->mutex ) != 0 ) 377 return( MBEDTLS_ERR_THREADING_MUTEX_ERROR ); 378 #endif 379 380 return( ret ); 381 } 382 383 #if defined(MBEDTLS_ENTROPY_NV_SEED) 384 int mbedtls_entropy_update_nv_seed( mbedtls_entropy_context *ctx ) 385 { 386 int ret = MBEDTLS_ERR_ENTROPY_FILE_IO_ERROR; 387 unsigned char buf[ MBEDTLS_ENTROPY_MAX_SEED_SIZE ]; 388 389 /* Read new seed and write it to NV */ 390 if( ( ret = mbedtls_entropy_func( ctx, buf, MBEDTLS_ENTROPY_BLOCK_SIZE ) ) != 0 ) 391 return( ret ); 392 393 if( mbedtls_nv_seed_write( buf, MBEDTLS_ENTROPY_BLOCK_SIZE ) < 0 ) 394 return( MBEDTLS_ERR_ENTROPY_FILE_IO_ERROR ); 395 396 /* Manually update the remaining stream with a separator value to diverge */ 397 memset( buf, 0, MBEDTLS_ENTROPY_BLOCK_SIZE ); 398 mbedtls_entropy_update_manual( ctx, buf, MBEDTLS_ENTROPY_BLOCK_SIZE ); 399 400 return( 0 ); 401 } 402 #endif /* MBEDTLS_ENTROPY_NV_SEED */ 403 404 #if defined(MBEDTLS_FS_IO) 405 int mbedtls_entropy_write_seed_file( mbedtls_entropy_context *ctx, const char *path ) 406 { 407 int ret = MBEDTLS_ERR_ENTROPY_FILE_IO_ERROR; 408 FILE *f; 409 unsigned char buf[MBEDTLS_ENTROPY_BLOCK_SIZE]; 410 411 if( ( f = fopen( path, "wb" ) ) == NULL ) 412 return( MBEDTLS_ERR_ENTROPY_FILE_IO_ERROR ); 413 414 if( ( ret = mbedtls_entropy_func( ctx, buf, MBEDTLS_ENTROPY_BLOCK_SIZE ) ) != 0 ) 415 goto exit; 416 417 if( fwrite( buf, 1, MBEDTLS_ENTROPY_BLOCK_SIZE, f ) != MBEDTLS_ENTROPY_BLOCK_SIZE ) 418 { 419 ret = MBEDTLS_ERR_ENTROPY_FILE_IO_ERROR; 420 goto exit; 421 } 422 423 ret = 0; 424 425 exit: 426 fclose( f ); 427 return( ret ); 428 } 429 430 int mbedtls_entropy_update_seed_file( mbedtls_entropy_context *ctx, const char *path ) 431 { 432 FILE *f; 433 size_t n; 434 unsigned char buf[ MBEDTLS_ENTROPY_MAX_SEED_SIZE ]; 435 436 if( ( f = fopen( path, "rb" ) ) == NULL ) 437 return( MBEDTLS_ERR_ENTROPY_FILE_IO_ERROR ); 438 439 fseek( f, 0, SEEK_END ); 440 n = (size_t) ftell( f ); 441 fseek( f, 0, SEEK_SET ); 442 443 if( n > MBEDTLS_ENTROPY_MAX_SEED_SIZE ) 444 n = MBEDTLS_ENTROPY_MAX_SEED_SIZE; 445 446 if( fread( buf, 1, n, f ) != n ) 447 { 448 fclose( f ); 449 return( MBEDTLS_ERR_ENTROPY_FILE_IO_ERROR ); 450 } 451 452 fclose( f ); 453 454 mbedtls_entropy_update_manual( ctx, buf, n ); 455 456 return( mbedtls_entropy_write_seed_file( ctx, path ) ); 457 } 458 #endif /* MBEDTLS_FS_IO */ 459 460 #if defined(MBEDTLS_SELF_TEST) 461 #if !defined(MBEDTLS_TEST_NULL_ENTROPY) 462 /* 463 * Dummy source function 464 */ 465 static int entropy_dummy_source( void *data, unsigned char *output, 466 size_t len, size_t *olen ) 467 { 468 ((void) data); 469 470 memset( output, 0x2a, len ); 471 *olen = len; 472 473 return( 0 ); 474 } 475 #endif /* !MBEDTLS_TEST_NULL_ENTROPY */ 476 477 #if defined(MBEDTLS_ENTROPY_HARDWARE_ALT) 478 479 static int mbedtls_entropy_source_self_test_gather( unsigned char *buf, size_t buf_len ) 480 { 481 int ret = 0; 482 size_t entropy_len = 0; 483 size_t olen = 0; 484 size_t attempts = buf_len; 485 486 while( attempts > 0 && entropy_len < buf_len ) 487 { 488 if( ( ret = mbedtls_hardware_poll( NULL, buf + entropy_len, 489 buf_len - entropy_len, &olen ) ) != 0 ) 490 return( ret ); 491 492 entropy_len += olen; 493 attempts--; 494 } 495 496 if( entropy_len < buf_len ) 497 { 498 ret = 1; 499 } 500 501 return( ret ); 502 } 503 504 505 static int mbedtls_entropy_source_self_test_check_bits( const unsigned char *buf, 506 size_t buf_len ) 507 { 508 unsigned char set= 0xFF; 509 unsigned char unset = 0x00; 510 size_t i; 511 512 for( i = 0; i < buf_len; i++ ) 513 { 514 set &= buf[i]; 515 unset |= buf[i]; 516 } 517 518 return( set == 0xFF || unset == 0x00 ); 519 } 520 521 /* 522 * A test to ensure hat the entropy sources are functioning correctly 523 * and there is no obvious failure. The test performs the following checks: 524 * - The entropy source is not providing only 0s (all bits unset) or 1s (all 525 * bits set). 526 * - The entropy source is not providing values in a pattern. Because the 527 * hardware could be providing data in an arbitrary length, this check polls 528 * the hardware entropy source twice and compares the result to ensure they 529 * are not equal. 530 * - The error code returned by the entropy source is not an error. 531 */ 532 int mbedtls_entropy_source_self_test( int verbose ) 533 { 534 int ret = 0; 535 unsigned char buf0[2 * sizeof( unsigned long long int )]; 536 unsigned char buf1[2 * sizeof( unsigned long long int )]; 537 538 if( verbose != 0 ) 539 mbedtls_printf( " ENTROPY_BIAS test: " ); 540 541 memset( buf0, 0x00, sizeof( buf0 ) ); 542 memset( buf1, 0x00, sizeof( buf1 ) ); 543 544 if( ( ret = mbedtls_entropy_source_self_test_gather( buf0, sizeof( buf0 ) ) ) != 0 ) 545 goto cleanup; 546 if( ( ret = mbedtls_entropy_source_self_test_gather( buf1, sizeof( buf1 ) ) ) != 0 ) 547 goto cleanup; 548 549 /* Make sure that the returned values are not all 0 or 1 */ 550 if( ( ret = mbedtls_entropy_source_self_test_check_bits( buf0, sizeof( buf0 ) ) ) != 0 ) 551 goto cleanup; 552 if( ( ret = mbedtls_entropy_source_self_test_check_bits( buf1, sizeof( buf1 ) ) ) != 0 ) 553 goto cleanup; 554 555 /* Make sure that the entropy source is not returning values in a 556 * pattern */ 557 ret = memcmp( buf0, buf1, sizeof( buf0 ) ) == 0; 558 559 cleanup: 560 if( verbose != 0 ) 561 { 562 if( ret != 0 ) 563 mbedtls_printf( "failed\n" ); 564 else 565 mbedtls_printf( "passed\n" ); 566 567 mbedtls_printf( "\n" ); 568 } 569 570 return( ret != 0 ); 571 } 572 573 #endif /* MBEDTLS_ENTROPY_HARDWARE_ALT */ 574 575 /* 576 * The actual entropy quality is hard to test, but we can at least 577 * test that the functions don't cause errors and write the correct 578 * amount of data to buffers. 579 */ 580 int mbedtls_entropy_self_test( int verbose ) 581 { 582 int ret = 1; 583 #if !defined(MBEDTLS_TEST_NULL_ENTROPY) 584 mbedtls_entropy_context ctx; 585 unsigned char buf[MBEDTLS_ENTROPY_BLOCK_SIZE] = { 0 }; 586 unsigned char acc[MBEDTLS_ENTROPY_BLOCK_SIZE] = { 0 }; 587 size_t i, j; 588 #endif /* !MBEDTLS_TEST_NULL_ENTROPY */ 589 590 if( verbose != 0 ) 591 mbedtls_printf( " ENTROPY test: " ); 592 593 #if !defined(MBEDTLS_TEST_NULL_ENTROPY) 594 mbedtls_entropy_init( &ctx ); 595 596 /* First do a gather to make sure we have default sources */ 597 if( ( ret = mbedtls_entropy_gather( &ctx ) ) != 0 ) 598 goto cleanup; 599 600 ret = mbedtls_entropy_add_source( &ctx, entropy_dummy_source, NULL, 16, 601 MBEDTLS_ENTROPY_SOURCE_WEAK ); 602 if( ret != 0 ) 603 goto cleanup; 604 605 if( ( ret = mbedtls_entropy_update_manual( &ctx, buf, sizeof buf ) ) != 0 ) 606 goto cleanup; 607 608 /* 609 * To test that mbedtls_entropy_func writes correct number of bytes: 610 * - use the whole buffer and rely on ASan to detect overruns 611 * - collect entropy 8 times and OR the result in an accumulator: 612 * any byte should then be 0 with probably 2^(-64), so requiring 613 * each of the 32 or 64 bytes to be non-zero has a false failure rate 614 * of at most 2^(-58) which is acceptable. 615 */ 616 for( i = 0; i < 8; i++ ) 617 { 618 if( ( ret = mbedtls_entropy_func( &ctx, buf, sizeof( buf ) ) ) != 0 ) 619 goto cleanup; 620 621 for( j = 0; j < sizeof( buf ); j++ ) 622 acc[j] |= buf[j]; 623 } 624 625 for( j = 0; j < sizeof( buf ); j++ ) 626 { 627 if( acc[j] == 0 ) 628 { 629 ret = 1; 630 goto cleanup; 631 } 632 } 633 634 #if defined(MBEDTLS_ENTROPY_HARDWARE_ALT) 635 if( ( ret = mbedtls_entropy_source_self_test( 0 ) ) != 0 ) 636 goto cleanup; 637 #endif 638 639 cleanup: 640 mbedtls_entropy_free( &ctx ); 641 #endif /* !MBEDTLS_TEST_NULL_ENTROPY */ 642 643 if( verbose != 0 ) 644 { 645 if( ret != 0 ) 646 mbedtls_printf( "failed\n" ); 647 else 648 mbedtls_printf( "passed\n" ); 649 650 mbedtls_printf( "\n" ); 651 } 652 653 return( ret != 0 ); 654 } 655 #endif /* MBEDTLS_SELF_TEST */ 656 657 #endif /* MBEDTLS_ENTROPY_C */ 658