- Timestamp:
- Feb 7, 2019, 8:36:33 AM (5 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
asp3_tinet_ecnl_rx/trunk/wolfssl-3.12.2/wolfcrypt/src/random.c
r337 r372 26 26 27 27 #include <wolfssl/wolfcrypt/settings.h> 28 #include <wolfssl/wolfcrypt/error-crypt.h> 28 29 29 30 /* on HPUX 11 you may need to install /dev/random see … … 32 33 */ 33 34 35 #if defined(HAVE_FIPS) && \ 36 defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 2) 37 38 /* set NO_WRAPPERS before headers, use direct internal f()s not wrappers */ 39 #define FIPS_NO_WRAPPERS 40 41 #ifdef USE_WINDOWS_API 42 #pragma code_seg(".fipsA$c") 43 #pragma const_seg(".fipsB$c") 44 #endif 45 #endif 46 47 34 48 #include <wolfssl/wolfcrypt/random.h> 35 49 #include <wolfssl/wolfcrypt/cpuid.h> 36 50 37 51 38 #ifdef HAVE_FIPS 52 /* If building for old FIPS. */ 53 #if defined(HAVE_FIPS) && \ 54 (!defined(HAVE_FIPS_VERSION) || (HAVE_FIPS_VERSION < 2)) 55 39 56 int wc_GenerateSeed(OS_Seed* os, byte* seed, word32 sz) 40 57 { … … 73 90 } 74 91 75 int wc_RNG_HealthTest(int reseed, 76 const byte* entropyA, word32 entropyASz, 77 const byte* entropyB, word32 entropyBSz, 92 int wc_RNG_HealthTest(int reseed, const byte* seedA, word32 seedASz, 93 const byte* seedB, word32 seedBSz, 78 94 byte* output, word32 outputSz) 79 95 { 80 return RNG_HealthTest_fips(reseed, entropyA, entropyASz,81 entropyB, entropyBSz, output, outputSz);96 return RNG_HealthTest_fips(reseed, seedA, seedASz, 97 seedB, seedBSz, output, outputSz); 82 98 } 83 99 #endif /* HAVE_HASHDRBG */ 84 100 85 #else /* else build without fips */101 #else /* else build without fips, or for new fips */ 86 102 87 103 #ifndef WC_NO_RNG /* if not FIPS and RNG is disabled then do not compile */ 88 104 89 #include <wolfssl/wolfcrypt/error-crypt.h>90 105 #include <wolfssl/wolfcrypt/sha256.h> 91 106 … … 127 142 #elif defined(WOLFSSL_EMBOS) 128 143 #elif defined(MICRIUM) 144 #elif defined(WOLFSSL_NUCLEUS) 145 #elif defined(WOLFSSL_PB) 129 146 #else 130 147 /* include headers that may be needed to get good seed */ … … 148 165 static int wc_GenerateRand_IntelRD(OS_Seed* os, byte* output, word32 sz); 149 166 #endif 167 168 #ifdef USE_WINDOWS_API 169 #include <immintrin.h> 170 #endif /* USE_WINDOWS_API */ 150 171 #endif 151 172 … … 156 177 #define MAX_REQUEST_LEN (0x10000) 157 178 #define RESEED_INTERVAL WC_RESEED_INTERVAL 158 #define SECURITY_STRENGTH (256) 159 #define ENTROPY_SZ (SECURITY_STRENGTH/8) 160 #define NONCE_SZ (ENTROPY_SZ/2) 161 #define ENTROPY_NONCE_SZ (ENTROPY_SZ+NONCE_SZ) 179 180 181 /* For FIPS builds, the user should not be adjusting the values. */ 182 #if defined(HAVE_FIPS) && \ 183 defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 2) 184 #if defined(RNG_SECURITY_STRENGTH) \ 185 || defined(ENTROPY_SCALE_FACTOR) \ 186 || defined(SEED_BLOCK_SZ) 187 188 #error "Do not change the RNG parameters for FIPS builds." 189 #endif 190 #endif 191 192 193 /* The security strength for the RNG is the target number of bits of 194 * entropy you are looking for in a seed. */ 195 #ifndef RNG_SECURITY_STRENGTH 196 #if defined(HAVE_FIPS) && \ 197 defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 2) 198 /* SHA-256 requires a minimum of 256-bits of entropy. The goal 199 * of 1024 will provide 4 times that. */ 200 #define RNG_SECURITY_STRENGTH (1024) 201 #else 202 /* If not using FIPS or using old FIPS, set the number down a bit. 203 * More is better, but more is also slower. */ 204 #define RNG_SECURITY_STRENGTH (256) 205 #endif 206 #endif 207 208 #ifndef ENTROPY_SCALE_FACTOR 209 /* The entropy scale factor should be the whole number inverse of the 210 * minimum bits of entropy per bit of NDRNG output. */ 211 #if defined(HAVE_INTEL_RDSEED) || defined(HAVE_INTEL_RDRAND) 212 /* The value of 2 applies to Intel's RDSEED which provides about 213 * 0.5 bits minimum of entropy per bit. */ 214 #define ENTROPY_SCALE_FACTOR 2 215 #else 216 /* Setting the default to 1. */ 217 #define ENTROPY_SCALE_FACTOR 1 218 #endif 219 #endif 220 221 #ifndef SEED_BLOCK_SZ 222 /* The seed block size, is the size of the output of the underlying NDRNG. 223 * This value is used for testing the output of the NDRNG. */ 224 #if defined(HAVE_INTEL_RDSEED) || defined(HAVE_INTEL_RDRAND) 225 /* RDSEED outputs in blocks of 64-bits. */ 226 #define SEED_BLOCK_SZ sizeof(word64) 227 #else 228 /* Setting the default to 4. */ 229 #define SEED_BLOCK_SZ 4 230 #endif 231 #endif 232 233 #define SEED_SZ (RNG_SECURITY_STRENGTH*ENTROPY_SCALE_FACTOR/8) 234 235 /* The maximum seed size will be the seed size plus a seed block for the 236 * test, and an additional half of the seed size. This additional half 237 * is in case the user does not supply a nonce. A nonce will be obtained 238 * from the NDRNG. */ 239 #define MAX_SEED_SZ (SEED_SZ + SEED_SZ/2 + SEED_BLOCK_SZ) 240 162 241 163 242 /* Internal return codes */ 164 243 #define DRBG_SUCCESS 0 165 #define DRBG_ERROR 1 166 #define DRBG_FAILURE 2 167 #define DRBG_NEED_RESEED 3 168 #define DRBG_CONT_FAILURE 4 244 #define DRBG_FAILURE 1 245 #define DRBG_NEED_RESEED 2 246 #define DRBG_CONT_FAILURE 3 169 247 170 248 /* RNG health states */ … … 200 278 #endif 201 279 byte matchCount; 280 #ifdef WOLFSSL_SMALL_STACK_CACHE 281 wc_Sha256 sha256; 282 #endif 202 283 } DRBG; 203 284 … … 216 297 int len; 217 298 word32 bits = (outSz * 8); /* reverse byte order */ 218 wc_Sha256 sha; 299 #ifdef WOLFSSL_SMALL_STACK_CACHE 300 wc_Sha256* sha = &drbg->sha256; 301 #else 302 wc_Sha256 sha[1]; 303 #endif 304 #ifdef WC_ASYNC_ENABLE_SHA256 219 305 DECLARE_VAR(digest, byte, WC_SHA256_DIGEST_SIZE, drbg->heap); 306 #else 307 byte digest[WC_SHA256_DIGEST_SIZE]; 308 #endif 220 309 221 310 (void)drbg; 222 #ifdef W OLFSSL_ASYNC_CRYPT311 #ifdef WC_ASYNC_ENABLE_SHA256 223 312 if (digest == NULL) 224 313 return DRBG_FAILURE; … … 232 321 233 322 for (i = 0, ctr = 1; i < len; i++, ctr++) { 323 #ifndef WOLFSSL_SMALL_STACK_CACHE 234 324 #ifdef WOLFSSL_ASYNC_CRYPT 235 ret = wc_InitSha256_ex( &sha, drbg->heap, drbg->devId);325 ret = wc_InitSha256_ex(sha, drbg->heap, drbg->devId); 236 326 #else 237 ret = wc_InitSha256( &sha);327 ret = wc_InitSha256(sha); 238 328 #endif 239 329 if (ret != 0) … … 241 331 242 332 if (ret == 0) 243 ret = wc_Sha256Update(&sha, &ctr, sizeof(ctr)); 333 #endif 334 ret = wc_Sha256Update(sha, &ctr, sizeof(ctr)); 244 335 if (ret == 0) 245 ret = wc_Sha256Update( &sha, (byte*)&bits, sizeof(bits));336 ret = wc_Sha256Update(sha, (byte*)&bits, sizeof(bits)); 246 337 247 338 if (ret == 0) { 248 339 /* churning V is the only string that doesn't have the type added */ 249 340 if (type != drbgInitV) 250 ret = wc_Sha256Update( &sha, &type, sizeof(type));341 ret = wc_Sha256Update(sha, &type, sizeof(type)); 251 342 } 252 343 if (ret == 0) 253 ret = wc_Sha256Update( &sha, inA, inASz);344 ret = wc_Sha256Update(sha, inA, inASz); 254 345 if (ret == 0) { 255 346 if (inB != NULL && inBSz > 0) 256 ret = wc_Sha256Update( &sha, inB, inBSz);347 ret = wc_Sha256Update(sha, inB, inBSz); 257 348 } 258 349 if (ret == 0) 259 ret = wc_Sha256Final(&sha, digest); 260 261 wc_Sha256Free(&sha); 350 ret = wc_Sha256Final(sha, digest); 351 352 #ifndef WOLFSSL_SMALL_STACK_CACHE 353 wc_Sha256Free(sha); 354 #endif 262 355 if (ret == 0) { 263 356 if (outSz > OUTPUT_BLOCK_LEN) { … … 274 367 ForceZero(digest, WC_SHA256_DIGEST_SIZE); 275 368 369 #ifdef WC_ASYNC_ENABLE_SHA256 276 370 FREE_VAR(digest, drbg->heap); 371 #endif 277 372 278 373 return (ret == 0) ? DRBG_SUCCESS : DRBG_FAILURE; … … 280 375 281 376 /* Returns: DRBG_SUCCESS or DRBG_FAILURE */ 282 static int Hash_DRBG_Reseed(DRBG* drbg, const byte* entropy, word32 entropySz) 283 { 284 byte seed[DRBG_SEED_LEN]; 285 286 if (Hash_df(drbg, seed, sizeof(seed), drbgReseed, drbg->V, sizeof(drbg->V), 287 entropy, entropySz) != DRBG_SUCCESS) { 377 static int Hash_DRBG_Reseed(DRBG* drbg, const byte* seed, word32 seedSz) 378 { 379 byte newV[DRBG_SEED_LEN]; 380 381 XMEMSET(newV, 0, DRBG_SEED_LEN); 382 383 if (Hash_df(drbg, newV, sizeof(newV), drbgReseed, 384 drbg->V, sizeof(drbg->V), seed, seedSz) != DRBG_SUCCESS) { 288 385 return DRBG_FAILURE; 289 386 } 290 387 291 XMEMCPY(drbg->V, seed, sizeof(drbg->V));292 ForceZero( seed, sizeof(seed));388 XMEMCPY(drbg->V, newV, sizeof(drbg->V)); 389 ForceZero(newV, sizeof(newV)); 293 390 294 391 if (Hash_df(drbg, drbg->C, sizeof(drbg->C), drbgInitC, drbg->V, … … 303 400 } 304 401 305 static INLINE void array_add_one(byte* data, word32 dataSz) 402 /* Returns: DRBG_SUCCESS and DRBG_FAILURE or BAD_FUNC_ARG on fail */ 403 int wc_RNG_DRBG_Reseed(WC_RNG* rng, const byte* seed, word32 seedSz) 404 { 405 if (rng == NULL || seed == NULL) { 406 return BAD_FUNC_ARG; 407 } 408 409 return Hash_DRBG_Reseed(rng->drbg, seed, seedSz); 410 } 411 412 static WC_INLINE void array_add_one(byte* data, word32 dataSz) 306 413 { 307 414 int i; … … 322 429 int len; 323 430 word32 checkBlock; 324 wc_Sha256 sha; 431 #ifdef WOLFSSL_SMALL_STACK_CACHE 432 wc_Sha256* sha = &drbg->sha256; 433 #else 434 wc_Sha256 sha[1]; 435 #endif 436 #ifdef WC_ASYNC_ENABLE_SHA256 325 437 DECLARE_VAR(digest, byte, WC_SHA256_DIGEST_SIZE, drbg->heap); 438 #else 439 byte digest[WC_SHA256_DIGEST_SIZE]; 440 #endif 326 441 327 442 /* Special case: outSz is 0 and out is NULL. wc_Generate a block to save for … … 334 449 XMEMCPY(data, V, sizeof(data)); 335 450 for (i = 0; i < len; i++) { 451 #ifndef WOLFSSL_SMALL_STACK_CACHE 336 452 #ifdef WOLFSSL_ASYNC_CRYPT 337 ret = wc_InitSha256_ex( &sha, drbg->heap, drbg->devId);453 ret = wc_InitSha256_ex(sha, drbg->heap, drbg->devId); 338 454 #else 339 ret = wc_InitSha256( &sha);455 ret = wc_InitSha256(sha); 340 456 #endif 341 457 if (ret == 0) 342 ret = wc_Sha256Update(&sha, data, sizeof(data)); 458 #endif 459 ret = wc_Sha256Update(sha, data, sizeof(data)); 343 460 if (ret == 0) 344 ret = wc_Sha256Final(&sha, digest); 345 wc_Sha256Free(&sha); 461 ret = wc_Sha256Final(sha, digest); 462 #ifndef WOLFSSL_SMALL_STACK_CACHE 463 wc_Sha256Free(sha); 464 #endif 346 465 347 466 if (ret == 0) { … … 379 498 ForceZero(data, sizeof(data)); 380 499 500 #ifdef WC_ASYNC_ENABLE_SHA256 381 501 FREE_VAR(digest, drbg->heap); 502 #endif 382 503 383 504 return (ret == 0) ? DRBG_SUCCESS : DRBG_FAILURE; 384 505 } 385 506 386 static INLINE void array_add(byte* d, word32 dLen, const byte* s, word32 sLen)507 static WC_INLINE void array_add(byte* d, word32 dLen, const byte* s, word32 sLen) 387 508 { 388 509 word16 carry = 0; … … 410 531 { 411 532 int ret; 412 wc_Sha256 sha; 533 #ifdef WOLFSSL_SMALL_STACK_CACHE 534 wc_Sha256* sha = &drbg->sha256; 535 #else 536 wc_Sha256 sha[1]; 537 #endif 413 538 byte type; 414 539 word32 reseedCtr; … … 417 542 return DRBG_NEED_RESEED; 418 543 } else { 544 #ifdef WC_ASYNC_ENABLE_SHA256 419 545 DECLARE_VAR(digest, byte, WC_SHA256_DIGEST_SIZE, drbg->heap); 546 #else 547 byte digest[WC_SHA256_DIGEST_SIZE]; 548 #endif 420 549 type = drbgGenerateH; 421 550 reseedCtr = drbg->reseedCtr; … … 423 552 ret = Hash_gen(drbg, out, outSz, drbg->V); 424 553 if (ret == DRBG_SUCCESS) { 554 #ifndef WOLFSSL_SMALL_STACK_CACHE 425 555 #ifdef WOLFSSL_ASYNC_CRYPT 426 ret = wc_InitSha256_ex( &sha, drbg->heap, drbg->devId);556 ret = wc_InitSha256_ex(sha, drbg->heap, drbg->devId); 427 557 #else 428 ret = wc_InitSha256( &sha);558 ret = wc_InitSha256(sha); 429 559 #endif 430 560 if (ret == 0) 431 ret = wc_Sha256Update(&sha, &type, sizeof(type)); 561 #endif 562 ret = wc_Sha256Update(sha, &type, sizeof(type)); 432 563 if (ret == 0) 433 ret = wc_Sha256Update( &sha, drbg->V, sizeof(drbg->V));564 ret = wc_Sha256Update(sha, drbg->V, sizeof(drbg->V)); 434 565 if (ret == 0) 435 ret = wc_Sha256Final(&sha, digest); 436 437 wc_Sha256Free(&sha); 566 ret = wc_Sha256Final(sha, digest); 567 568 #ifndef WOLFSSL_SMALL_STACK_CACHE 569 wc_Sha256Free(sha); 570 #endif 438 571 439 572 if (ret == 0) { … … 450 583 } 451 584 ForceZero(digest, WC_SHA256_DIGEST_SIZE); 585 #ifdef WC_ASYNC_ENABLE_SHA256 452 586 FREE_VAR(digest, drbg->heap); 587 #endif 453 588 } 454 589 … … 472 607 #endif 473 608 609 #ifdef WOLFSSL_SMALL_STACK_CACHE 610 #ifdef WOLFSSL_ASYNC_CRYPT 611 ret = wc_InitSha256_ex(&drbg->sha256, drbg->heap, drbg->devId); 612 #else 613 ret = wc_InitSha256(&drbg->sha256); 614 #endif 615 if (ret != 0) 616 return ret; 617 #endif 618 474 619 if (Hash_df(drbg, drbg->V, sizeof(drbg->V), drbgInitV, seed, seedSz, 475 620 nonce, nonceSz) == DRBG_SUCCESS && … … 493 638 byte* compareDrbg = (byte*)drbg; 494 639 640 #ifdef WOLFSSL_SMALL_STACK_CACHE 641 wc_Sha256Free(&drbg->sha256); 642 #endif 643 495 644 ForceZero(drbg, sizeof(DRBG)); 496 645 … … 500 649 return (compareSum == 0) ? DRBG_SUCCESS : DRBG_FAILURE; 501 650 } 651 652 653 int wc_RNG_TestSeed(const byte* seed, word32 seedSz) 654 { 655 int ret = DRBG_SUCCESS; 656 657 /* Check the seed for duplicate words. */ 658 word32 seedIdx = 0; 659 word32 scratchSz = min(SEED_BLOCK_SZ, seedSz - SEED_BLOCK_SZ); 660 661 while (seedIdx < seedSz - SEED_BLOCK_SZ) { 662 if (ConstantCompare(seed + seedIdx, 663 seed + seedIdx + scratchSz, 664 scratchSz) == 0) { 665 666 ret = DRBG_CONT_FAILURE; 667 } 668 seedIdx += SEED_BLOCK_SZ; 669 scratchSz = min(SEED_BLOCK_SZ, (seedSz - seedIdx)); 670 } 671 672 return ret; 673 } 502 674 #endif /* HAVE_HASHDRBG */ 503 675 /* End NIST DRBG Code */ 504 676 505 677 506 int wc_InitRng_ex(WC_RNG* rng, void* heap, int devId) 678 static int _InitRng(WC_RNG* rng, byte* nonce, word32 nonceSz, 679 void* heap, int devId) 507 680 { 508 681 int ret = RNG_FAILURE_E; 682 #ifdef HAVE_HASHDRBG 683 word32 seedSz = SEED_SZ + SEED_BLOCK_SZ; 684 #endif 685 686 (void)nonce; 687 (void)nonceSz; 509 688 510 689 if (rng == NULL) 690 return BAD_FUNC_ARG; 691 if (nonce == NULL && nonceSz != 0) 511 692 return BAD_FUNC_ARG; 512 693 … … 552 733 #else 553 734 #ifdef HAVE_HASHDRBG 735 if (nonceSz == 0) 736 seedSz = MAX_SEED_SZ; 737 554 738 if (wc_RNG_HealthTestLocal(0) == 0) { 555 DECLARE_VAR(entropy, byte, ENTROPY_NONCE_SZ, rng->heap); 739 #ifdef WC_ASYNC_ENABLE_SHA256 740 DECLARE_VAR(seed, byte, MAX_SEED_SZ, rng->heap); 741 #else 742 byte seed[MAX_SEED_SZ]; 743 #endif 556 744 557 745 rng->drbg = … … 561 749 ret = MEMORY_E; 562 750 } 563 /* This doesn't use a separate nonce. The entropy input will be 564 * the default size plus the size of the nonce making the seed 565 * size. */ 566 else if (wc_GenerateSeed(&rng->seed, entropy, ENTROPY_NONCE_SZ) == 0 && 567 Hash_DRBG_Instantiate(rng->drbg, entropy, ENTROPY_NONCE_SZ, 568 NULL, 0, rng->heap, devId) == DRBG_SUCCESS) { 751 else { 752 ret = wc_GenerateSeed(&rng->seed, seed, seedSz); 753 if (ret != 0) 754 ret = DRBG_FAILURE; 755 else 756 ret = wc_RNG_TestSeed(seed, seedSz); 757 758 if (ret == DRBG_SUCCESS) 759 ret = Hash_DRBG_Instantiate(rng->drbg, 760 seed + SEED_BLOCK_SZ, seedSz - SEED_BLOCK_SZ, 761 nonce, nonceSz, rng->heap, devId); 762 763 if (ret == DRBG_SUCCESS) 569 764 ret = Hash_DRBG_Generate(rng->drbg, NULL, 0); 570 765 } 571 else 572 ret = DRBG_FAILURE;573 574 F orceZero(entropy, ENTROPY_NONCE_SZ);575 FREE_VAR(entropy, rng->heap);766 767 ForceZero(seed, seedSz); 768 #ifdef WC_ASYNC_ENABLE_SHA256 769 FREE_VAR(seed, rng->heap); 770 #endif 576 771 } 577 772 else … … 599 794 } 600 795 796 601 797 int wc_InitRng(WC_RNG* rng) 602 798 { 603 return wc_InitRng_ex(rng, NULL, INVALID_DEVID); 799 return _InitRng(rng, NULL, 0, NULL, INVALID_DEVID); 800 } 801 802 803 int wc_InitRng_ex(WC_RNG* rng, void* heap, int devId) 804 { 805 return _InitRng(rng, NULL, 0, heap, devId); 806 } 807 808 809 int wc_InitRngNonce(WC_RNG* rng, byte* nonce, word32 nonceSz) 810 { 811 return _InitRng(rng, nonce, nonceSz, NULL, INVALID_DEVID); 812 } 813 814 815 int wc_InitRngNonce_ex(WC_RNG* rng, byte* nonce, word32 nonceSz, 816 void* heap, int devId) 817 { 818 return _InitRng(rng, nonce, nonceSz, heap, devId); 604 819 } 605 820 … … 623 838 #ifdef HAVE_CAVIUM 624 839 return NitroxRngGenerateBlock(rng, output, sz); 625 #elif defined(HAVE_INTEL_QA) 840 #elif defined(HAVE_INTEL_QA) && defined(QAT_ENABLE_RNG) 626 841 return IntelQaDrbg(&rng->asyncDev, output, sz); 627 842 #else … … 646 861 if (ret == DRBG_NEED_RESEED) { 647 862 if (wc_RNG_HealthTestLocal(1) == 0) { 648 byte entropy[ENTROPY_SZ]; 649 650 if (wc_GenerateSeed(&rng->seed, entropy, ENTROPY_SZ) == 0 && 651 Hash_DRBG_Reseed(rng->drbg, entropy, ENTROPY_SZ) 652 == DRBG_SUCCESS) { 653 863 byte newSeed[SEED_SZ + SEED_BLOCK_SZ]; 864 865 ret = wc_GenerateSeed(&rng->seed, newSeed, 866 SEED_SZ + SEED_BLOCK_SZ); 867 if (ret != 0) 868 ret = DRBG_FAILURE; 869 else 870 ret = wc_RNG_TestSeed(newSeed, SEED_SZ + SEED_BLOCK_SZ); 871 872 if (ret == DRBG_SUCCESS) 873 ret = Hash_DRBG_Reseed(rng->drbg, newSeed + SEED_BLOCK_SZ, 874 SEED_SZ); 875 if (ret == DRBG_SUCCESS) 654 876 ret = Hash_DRBG_Generate(rng->drbg, NULL, 0); 655 877 if (ret == DRBG_SUCCESS) 656 878 ret = Hash_DRBG_Generate(rng->drbg, output, sz); 657 } 658 else 659 ret = DRBG_FAILURE; 660 661 ForceZero(entropy, ENTROPY_SZ); 879 880 ForceZero(newSeed, sizeof(newSeed)); 662 881 } 663 882 else … … 721 940 722 941 #ifdef HAVE_HASHDRBG 723 int wc_RNG_HealthTest(int reseed, const byte* entropyA, word32 entropyASz,724 const byte* entropyB, word32 entropyBSz,942 int wc_RNG_HealthTest(int reseed, const byte* seedA, word32 seedASz, 943 const byte* seedB, word32 seedBSz, 725 944 byte* output, word32 outputSz) 945 { 946 return wc_RNG_HealthTest_ex(reseed, NULL, 0, 947 seedA, seedASz, seedB, seedBSz, 948 output, outputSz, 949 NULL, INVALID_DEVID); 950 } 951 952 953 int wc_RNG_HealthTest_ex(int reseed, const byte* nonce, word32 nonceSz, 954 const byte* seedA, word32 seedASz, 955 const byte* seedB, word32 seedBSz, 956 byte* output, word32 outputSz, 957 void* heap, int devId) 726 958 { 727 959 int ret = -1; … … 731 963 #endif 732 964 733 if ( entropyA == NULL || output == NULL) {965 if (seedA == NULL || output == NULL) { 734 966 return BAD_FUNC_ARG; 735 967 } 736 968 737 if (reseed != 0 && entropyB == NULL) {969 if (reseed != 0 && seedB == NULL) { 738 970 return BAD_FUNC_ARG; 739 971 } … … 744 976 745 977 #ifdef WOLFSSL_SMALL_STACK 746 drbg = ( structDRBG*)XMALLOC(sizeof(DRBG), NULL, DYNAMIC_TYPE_RNG);978 drbg = (DRBG*)XMALLOC(sizeof(DRBG), NULL, DYNAMIC_TYPE_RNG); 747 979 if (drbg == NULL) { 748 980 return MEMORY_E; … … 752 984 #endif 753 985 754 if (Hash_DRBG_Instantiate(drbg, entropyA, entropyASz, NULL, 0, NULL,755 INVALID_DEVID) != 0) {986 if (Hash_DRBG_Instantiate(drbg, seedA, seedASz, nonce, nonceSz, 987 heap, devId) != 0) { 756 988 goto exit_rng_ht; 757 989 } 758 990 759 991 if (reseed) { 760 if (Hash_DRBG_Reseed(drbg, entropyB, entropyBSz) != 0) {992 if (Hash_DRBG_Reseed(drbg, seedB, seedBSz) != 0) { 761 993 goto exit_rng_ht; 762 994 } … … 789 1021 790 1022 791 const byte entropyA[] = {1023 const byte seedA[] = { 792 1024 0x63, 0x36, 0x33, 0x77, 0xe4, 0x1e, 0x86, 0x46, 0x8d, 0xeb, 0x0a, 0xb4, 793 1025 0xa8, 0xed, 0x68, 0x3f, 0x6a, 0x13, 0x4e, 0x47, 0xe0, 0x14, 0xc7, 0x00, … … 796 1028 }; 797 1029 798 const byte reseed EntropyA[] = {1030 const byte reseedSeedA[] = { 799 1031 0xe6, 0x2b, 0x8a, 0x8e, 0xe8, 0xf1, 0x41, 0xb6, 0x98, 0x05, 0x66, 0xe3, 800 1032 0xbf, 0xe3, 0xc0, 0x49, 0x03, 0xda, 0xd4, 0xac, 0x2c, 0xdf, 0x9f, 0x22, … … 816 1048 }; 817 1049 818 const byte entropyB[] = {1050 const byte seedB[] = { 819 1051 0xa6, 0x5a, 0xd0, 0xf3, 0x45, 0xdb, 0x4e, 0x0e, 0xff, 0xe8, 0x75, 0xc3, 820 1052 0xa2, 0xe7, 0x1f, 0x42, 0xc7, 0x12, 0x9d, 0x62, 0x0f, 0xf5, 0xc1, 0x19, 821 0xa9, 0xef, 0x55, 0xf0, 0x51, 0x85, 0xe0, 0xfb, 0x85, 0x81, 0xf9, 0x31, 822 0x75, 0x17, 0x27, 0x6e, 0x06, 0xe9, 0x60, 0x7d, 0xdb, 0xcb, 0xcc, 0x2e 1053 0xa9, 0xef, 0x55, 0xf0, 0x51, 0x85, 0xe0, 0xfb, /* nonce next */ 1054 0x85, 0x81, 0xf9, 0x31, 0x75, 0x17, 0x27, 0x6e, 0x06, 0xe9, 0x60, 0x7d, 1055 0xdb, 0xcb, 0xcc, 0x2e 823 1056 }; 824 1057 … … 856 1089 857 1090 if (reseed) { 858 ret = wc_RNG_HealthTest(1, entropyA, sizeof(entropyA),859 reseed EntropyA, sizeof(reseedEntropyA),1091 ret = wc_RNG_HealthTest(1, seedA, sizeof(seedA), 1092 reseedSeedA, sizeof(reseedSeedA), 860 1093 check, RNG_HEALTH_TEST_CHECK_SIZE); 861 1094 if (ret == 0) { … … 866 1099 } 867 1100 else { 868 ret = wc_RNG_HealthTest(0, entropyB, sizeof(entropyB),1101 ret = wc_RNG_HealthTest(0, seedB, sizeof(seedB), 869 1102 NULL, 0, 870 1103 check, RNG_HEALTH_TEST_CHECK_SIZE); … … 873 1106 RNG_HEALTH_TEST_CHECK_SIZE) != 0) 874 1107 ret = -1; 1108 } 1109 1110 /* The previous test cases use a large seed instead of a seed and nonce. 1111 * seedB is actually from a test case with a seed and nonce, and 1112 * just concatenates them. The pivot point between seed and nonce is 1113 * byte 32, feed them into the health test separately. */ 1114 if (ret == 0) { 1115 ret = wc_RNG_HealthTest_ex(0, 1116 seedB + 32, sizeof(seedB) - 32, 1117 seedB, 32, 1118 NULL, 0, 1119 check, RNG_HEALTH_TEST_CHECK_SIZE, 1120 NULL, INVALID_DEVID); 1121 if (ret == 0) { 1122 if (ConstantCompare(check, outputB, sizeof(outputB)) != 0) 1123 ret = -1; 1124 } 875 1125 } 876 1126 } … … 995 1245 #ifdef HAVE_INTEL_RDSEED 996 1246 1247 #ifndef USE_WINDOWS_API 1248 997 1249 /* return 0 on success */ 998 staticINLINE int IntelRDseed64(word64* seed)1250 static WC_INLINE int IntelRDseed64(word64* seed) 999 1251 { 1000 1252 unsigned char ok; … … 1004 1256 } 1005 1257 1258 #else /* USE_WINDOWS_API */ 1259 /* The compiler Visual Studio uses does not allow inline assembly. 1260 * It does allow for Intel intrinsic functions. */ 1261 1006 1262 /* return 0 on success */ 1007 static INLINE int IntelRDseed64_r(word64* rnd) 1263 static WC_INLINE int IntelRDseed64(word64* seed) 1264 { 1265 int ok; 1266 1267 ok = _rdseed64_step(seed); 1268 return (ok) ? 0 : -1; 1269 } 1270 1271 #endif /* USE_WINDOWS_API */ 1272 1273 /* return 0 on success */ 1274 static WC_INLINE int IntelRDseed64_r(word64* rnd) 1008 1275 { 1009 1276 int i; … … 1041 1308 1042 1309 XMEMCPY(output, &rndTmp, sz); 1310 ForceZero(&rndTmp, sizeof(rndTmp)); 1043 1311 1044 1312 return 0; … … 1049 1317 #ifdef HAVE_INTEL_RDRAND 1050 1318 1319 #ifndef USE_WINDOWS_API 1320 1051 1321 /* return 0 on success */ 1052 static INLINE int IntelRDrand64(word64 *rnd)1322 static WC_INLINE int IntelRDrand64(word64 *rnd) 1053 1323 { 1054 1324 unsigned char ok; … … 1059 1329 } 1060 1330 1331 #else /* USE_WINDOWS_API */ 1332 /* The compiler Visual Studio uses does not allow inline assembly. 1333 * It does allow for Intel intrinsic functions. */ 1334 1061 1335 /* return 0 on success */ 1062 static INLINE int IntelRDrand64_r(word64 *rnd) 1336 static WC_INLINE int IntelRDrand64(word64 *rnd) 1337 { 1338 int ok; 1339 1340 ok = _rdrand64_step(rnd); 1341 1342 return (ok) ? 0 : -1; 1343 } 1344 1345 #endif /* USE_WINDOWS_API */ 1346 1347 /* return 0 on success */ 1348 static WC_INLINE int IntelRDrand64_r(word64 *rnd) 1063 1349 { 1064 1350 int i; … … 1182 1468 int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz) 1183 1469 { 1470 #ifdef HAVE_INTEL_RDSEED 1471 if (IS_INTEL_RDSEED(intel_flags)) { 1472 if (!wc_GenerateSeed_IntelRD(NULL, output, sz)) { 1473 /* success, we're done */ 1474 return 0; 1475 } 1476 #ifdef FORCE_FAILURE_RDSEED 1477 /* don't fall back to CryptoAPI */ 1478 return READ_RAN_E; 1479 #endif 1480 } 1481 #endif /* HAVE_INTEL_RDSEED */ 1482 1184 1483 if(!CryptAcquireContext(&os->handle, 0, 0, PROV_RSA_FULL, 1185 1484 CRYPT_VERIFYCONTEXT)) … … 1302 1601 int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz) 1303 1602 { 1304 inti;1603 word32 i; 1305 1604 1306 1605 /* turn on RNGA module */ … … 1418 1717 1419 1718 #elif defined(STM32_RNG) 1420 /* 1421 * wc_Generate a RNG seed using the hardware random number generator 1719 /* Generate a RNG seed using the hardware random number generator 1422 1720 * on the STM32F2/F4/F7. */ 1423 1721 … … 1443 1741 return 0; 1444 1742 } 1743 #elif defined(WOLFSSL_STM32F427_RNG) 1744 1745 /* Generate a RNG seed using the hardware RNG on the STM32F427 1746 * directly, following steps outlined in STM32F4 Reference 1747 * Manual (Chapter 24) for STM32F4xx family. */ 1748 int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz) 1749 { 1750 int i; 1751 (void)os; 1752 1753 /* enable RNG peripheral clock */ 1754 RCC->AHB2ENR |= RCC_AHB2ENR_RNGEN; 1755 1756 /* enable RNG interrupt, set IE bit in RNG->CR register */ 1757 RNG->CR |= RNG_CR_IE; 1758 1759 /* enable RNG, set RNGEN bit in RNG->CR. Activates RNG, 1760 * RNG_LFSR, and error detector */ 1761 RNG->CR |= RNG_CR_RNGEN; 1762 1763 /* verify no errors, make sure SEIS and CEIS bits are 0 1764 * in RNG->SR register */ 1765 if (RNG->SR & (RNG_SR_SECS | RNG_SR_CECS)) 1766 return RNG_FAILURE_E; 1767 1768 for (i = 0; i < (int)sz; i++) { 1769 /* wait until RNG number is ready */ 1770 while ((RNG->SR & RNG_SR_DRDY) == 0) { } 1771 1772 /* get value */ 1773 output[i] = RNG->DR; 1774 } 1775 1776 return 0; 1777 } 1778 1445 1779 #else 1780 1781 /* Generate a RNG seed using the STM32 Standard Peripheral Library */ 1446 1782 int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz) 1447 1783 { … … 1493 1829 } 1494 1830 1831 #elif defined(WOLFSSL_PB) 1832 1833 int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz) 1834 { 1835 word32 i; 1836 for (i = 0; i < sz; i++) 1837 output[i] = UTL_Rand(); 1838 1839 (void)os; 1840 1841 return 0; 1842 } 1843 1844 #elif defined(WOLFSSL_NUCLEUS) 1845 #include "nucleus.h" 1846 #include "kernel/plus_common.h" 1847 1848 #warning "potential for not enough entropy, currently being used for testing" 1849 int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz) 1850 { 1851 int i; 1852 srand(NU_Get_Time_Stamp()); 1853 1854 for (i = 0; i < sz; i++ ) { 1855 output[i] = rand() % 256; 1856 if ((i % 8) == 7) { 1857 srand(NU_Get_Time_Stamp()); 1858 } 1859 } 1860 1861 return 0; 1862 } 1495 1863 #elif defined(WOLFSSL_VXWORKS) 1496 1864 … … 1630 1998 } 1631 1999 2000 #elif (defined(WOLFSSL_IMX6_CAAM) || defined(WOLFSSL_IMX6_CAAM_RNG)) 2001 2002 #include <wolfssl/wolfcrypt/port/caam/wolfcaam.h> 2003 #include <wolfssl/wolfcrypt/port/caam/caam_driver.h> 2004 2005 int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz) 2006 { 2007 Buffer buf[1]; 2008 int ret = 0; 2009 int times = 1000, i; 2010 2011 (void)os; 2012 2013 if (output == NULL) { 2014 return BUFFER_E; 2015 } 2016 2017 buf[0].BufferType = DataBuffer | LastBuffer; 2018 buf[0].TheAddress = (Address)output; 2019 buf[0].Length = sz; 2020 2021 /* Check Waiting to make sure entropy is ready */ 2022 for (i = 0; i < times; i++) { 2023 ret = wc_caamAddAndWait(buf, NULL, CAAM_ENTROPY); 2024 if (ret == Success) { 2025 break; 2026 } 2027 2028 /* driver could be waiting for entropy */ 2029 if (ret != RAN_BLOCK_E) { 2030 return ret; 2031 } 2032 usleep(100); 2033 } 2034 2035 if (i == times && ret != Success) { 2036 return RNG_FAILURE_E; 2037 } 2038 else { /* Success case */ 2039 ret = 0; 2040 } 2041 2042 return ret; 2043 } 2044 2045 #elif defined(WOLFSSL_APACHE_MYNEWT) 2046 2047 #include <stdlib.h> 2048 #include "os/os_time.h" 2049 int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz) 2050 { 2051 int i; 2052 srand(os_time_get()); 2053 2054 for (i = 0; i < sz; i++ ) { 2055 output[i] = rand() % 256; 2056 if ((i % 8) == 7) { 2057 srand(os_time_get()); 2058 } 2059 } 2060 2061 return 0; 2062 } 2063 2064 #elif defined(WOLFSSL_ESPIDF) 2065 #if defined(WOLFSSL_ESPWROOM32) 2066 #include <esp_system.h> 2067 2068 int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz) 2069 { 2070 int i; 2071 2072 for (i = 0; i< sz; i++) { 2073 output[i] = esp_random( ); 2074 } 2075 2076 return 0; 2077 } 2078 #endif /* end WOLFSSL_ESPWROOM32 */ 2079 1632 2080 #elif defined(CUSTOM_RAND_GENERATE_BLOCK) 1633 2081 /* #define CUSTOM_RAND_GENERATE_BLOCK myRngFunc … … 1640 2088 defined(WOLFSSL_LPC43xx) || defined(WOLFSSL_STM32F2xx) || \ 1641 2089 defined(MBED) || defined(WOLFSSL_EMBOS) || \ 1642 defined(WOLFSSL_GENSEED_FORTEST) 2090 defined(WOLFSSL_GENSEED_FORTEST) || defined(WOLFSSL_CHIBIOS) || \ 2091 defined(WOLFSSL_CONTIKI) 1643 2092 1644 2093 /* these platforms do not have a default random seed and … … 1677 2126 return ret; 1678 2127 #else 1679 /* fallback to /dev/urandom attempt*/2128 /* reset error and fallback to using /dev/urandom */ 1680 2129 ret = 0; 1681 2130 #endif 1682 2131 } 1683 1684 2132 #endif /* HAVE_INTEL_RDSEED */ 1685 2133 2134 #ifndef NO_DEV_URANDOM /* way to disable use of /dev/urandom */ 1686 2135 os->fd = open("/dev/urandom",O_RDONLY); 1687 if (os->fd == -1) { 2136 if (os->fd == -1) 2137 #endif 2138 { 1688 2139 /* may still have /dev/random */ 1689 2140 os->fd = open("/dev/random",O_RDONLY); … … 1703 2154 1704 2155 if (sz) { 1705 #if def BLOCKING2156 #if defined(BLOCKING) || defined(WC_RNG_BLOCKING) 1706 2157 sleep(0); /* context switch */ 1707 2158 #else … … 1738 2189 1739 2190 /* End wc_GenerateSeed */ 1740 1741 2191 #endif /* WC_NO_RNG */ 1742 2192 #endif /* HAVE_FIPS */
Note:
See TracChangeset
for help on using the changeset viewer.