source: azure_iot_hub_f767zi/trunk/wolfssl-4.7.0/wolfcrypt/src/random.c@ 464

Last change on this file since 464 was 464, checked in by coas-nagasima, 3 years ago

WolfSSLとAzure IoT SDKを更新

  • Property svn:eol-style set to native
  • Property svn:mime-type set to text/x-csrc;charset=UTF-8
File size: 71.7 KB
Line 
1/* random.c
2 *
3 * Copyright (C) 2006-2020 wolfSSL Inc.
4 *
5 * This file is part of wolfSSL.
6 *
7 * wolfSSL 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 * wolfSSL 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
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
20 */
21
22/*
23
24DESCRIPTION
25This library contains implementation for the random number generator.
26
27*/
28#ifdef HAVE_CONFIG_H
29 #include <config.h>
30#endif
31
32#include <wolfssl/wolfcrypt/settings.h>
33#include <wolfssl/wolfcrypt/error-crypt.h>
34
35/* on HPUX 11 you may need to install /dev/random see
36 http://h20293.www2.hp.com/portal/swdepot/displayProductInfo.do?productNumber=KRNG11I
37
38*/
39
40#if defined(HAVE_FIPS) && \
41 defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 2)
42
43 /* set NO_WRAPPERS before headers, use direct internal f()s not wrappers */
44 #define FIPS_NO_WRAPPERS
45
46 #ifdef USE_WINDOWS_API
47 #pragma code_seg(".fipsA$c")
48 #pragma const_seg(".fipsB$c")
49 #endif
50#endif
51
52
53#include <wolfssl/wolfcrypt/random.h>
54#include <wolfssl/wolfcrypt/cpuid.h>
55
56
57/* If building for old FIPS. */
58#if defined(HAVE_FIPS) && \
59 (!defined(HAVE_FIPS_VERSION) || (HAVE_FIPS_VERSION < 2))
60
61int wc_GenerateSeed(OS_Seed* os, byte* seed, word32 sz)
62{
63 return GenerateSeed(os, seed, sz);
64}
65
66int wc_InitRng_ex(WC_RNG* rng, void* heap, int devId)
67{
68 (void)heap;
69 (void)devId;
70 return InitRng_fips(rng);
71}
72
73int wc_InitRng(WC_RNG* rng)
74{
75 return InitRng_fips(rng);
76}
77
78
79int wc_RNG_GenerateBlock(WC_RNG* rng, byte* b, word32 sz)
80{
81 return RNG_GenerateBlock_fips(rng, b, sz);
82}
83
84
85int wc_RNG_GenerateByte(WC_RNG* rng, byte* b)
86{
87 return RNG_GenerateByte(rng, b);
88}
89
90#ifdef HAVE_HASHDRBG
91
92 int wc_FreeRng(WC_RNG* rng)
93 {
94 return FreeRng_fips(rng);
95 }
96
97 int wc_RNG_HealthTest(int reseed, const byte* seedA, word32 seedASz,
98 const byte* seedB, word32 seedBSz,
99 byte* output, word32 outputSz)
100 {
101 return RNG_HealthTest_fips(reseed, seedA, seedASz,
102 seedB, seedBSz, output, outputSz);
103 }
104#endif /* HAVE_HASHDRBG */
105
106#else /* else build without fips, or for new fips */
107
108#ifndef WC_NO_RNG /* if not FIPS and RNG is disabled then do not compile */
109
110#include <wolfssl/wolfcrypt/sha256.h>
111
112#ifdef WOLF_CRYPTO_CB
113 #include <wolfssl/wolfcrypt/cryptocb.h>
114#endif
115
116#ifdef NO_INLINE
117 #include <wolfssl/wolfcrypt/misc.h>
118#else
119 #define WOLFSSL_MISC_INCLUDED
120 #include <wolfcrypt/src/misc.c>
121#endif
122
123#if defined(WOLFSSL_SGX)
124 #include <sgx_trts.h>
125#elif defined(USE_WINDOWS_API)
126 #ifndef _WIN32_WINNT
127 #define _WIN32_WINNT 0x0400
128 #endif
129 #include <windows.h>
130 #include <wincrypt.h>
131#elif defined(HAVE_WNR)
132 #include <wnr.h>
133 #include <wolfssl/wolfcrypt/logging.h>
134 wolfSSL_Mutex wnr_mutex; /* global netRandom mutex */
135 int wnr_timeout = 0; /* entropy timeout, mililseconds */
136 int wnr_mutex_init = 0; /* flag for mutex init */
137 wnr_context* wnr_ctx; /* global netRandom context */
138#elif defined(FREESCALE_KSDK_2_0_TRNG)
139 #include "fsl_trng.h"
140#elif defined(FREESCALE_KSDK_2_0_RNGA)
141 #include "fsl_rnga.h"
142#elif defined(WOLFSSL_WICED)
143 #include "wiced_crypto.h"
144#elif defined(WOLFSSL_NETBURNER)
145 #include <predef.h>
146 #include <basictypes.h>
147 #include <random.h>
148#elif defined(NO_DEV_RANDOM)
149#elif defined(CUSTOM_RAND_GENERATE)
150#elif defined(CUSTOM_RAND_GENERATE_BLOCK)
151#elif defined(CUSTOM_RAND_GENERATE_SEED)
152#elif defined(WOLFSSL_GENSEED_FORTEST)
153#elif defined(WOLFSSL_MDK_ARM)
154#elif defined(WOLFSSL_IAR_ARM)
155#elif defined(WOLFSSL_ROWLEY_ARM)
156#elif defined(WOLFSSL_EMBOS)
157#elif defined(WOLFSSL_DEOS)
158#elif defined(MICRIUM)
159#elif defined(WOLFSSL_NUCLEUS)
160#elif defined(WOLFSSL_PB)
161#elif defined(WOLFSSL_ZEPHYR)
162#elif defined(WOLFSSL_TELIT_M2MB)
163#elif defined(WOLFSSL_SCE) && !defined(WOLFSSL_SCE_NO_TRNG)
164#else
165 /* include headers that may be needed to get good seed */
166 #include <fcntl.h>
167 #ifndef EBSNET
168 #include <unistd.h>
169 #endif
170#endif
171
172#if defined(WOLFSSL_SILABS_SE_ACCEL)
173#include <wolfssl/wolfcrypt/port/silabs/silabs_random.h>
174#endif
175
176
177#if defined(HAVE_INTEL_RDRAND) || defined(HAVE_INTEL_RDSEED)
178 static word32 intel_flags = 0;
179 static void wc_InitRng_IntelRD(void)
180 {
181 intel_flags = cpuid_get_flags();
182 }
183 #if defined(HAVE_INTEL_RDSEED) && !defined(WOLFSSL_LINUXKM)
184 static int wc_GenerateSeed_IntelRD(OS_Seed* os, byte* output, word32 sz);
185 #endif
186 #ifdef HAVE_INTEL_RDRAND
187 static int wc_GenerateRand_IntelRD(OS_Seed* os, byte* output, word32 sz);
188 #endif
189
190#ifdef USE_WINDOWS_API
191 #define USE_INTEL_INTRINSICS
192#elif !defined __GNUC__ || defined __clang__ || __GNUC__ > 4
193 #define USE_INTEL_INTRINSICS
194#else
195 #undef USE_INTEL_INTRINSICS
196#endif
197
198#ifdef USE_INTEL_INTRINSICS
199 #include <immintrin.h>
200 /* Before clang 7 or GCC 9, immintrin.h did not define _rdseed64_step() */
201 #ifndef HAVE_INTEL_RDSEED
202 #elif defined __clang__ && __clang_major__ > 6
203 #elif !defined __GNUC__
204 #elif __GNUC__ > 8
205 #else
206 #ifndef __clang__
207 #pragma GCC push_options
208 #pragma GCC target("rdseed")
209 #else
210 #define __RDSEED__
211 #endif
212 #include <x86intrin.h>
213 #ifndef __clang__
214 #pragma GCC pop_options
215 #endif
216 #endif
217#endif /* USE_WINDOWS_API */
218#endif
219
220/* Start NIST DRBG code */
221#ifdef HAVE_HASHDRBG
222
223#define OUTPUT_BLOCK_LEN (WC_SHA256_DIGEST_SIZE)
224#define MAX_REQUEST_LEN (0x10000)
225#define RESEED_INTERVAL WC_RESEED_INTERVAL
226
227
228/* For FIPS builds, the user should not be adjusting the values. */
229#if defined(HAVE_FIPS) && \
230 defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 2)
231 #if defined(RNG_SECURITY_STRENGTH) \
232 || defined(ENTROPY_SCALE_FACTOR) \
233 || defined(SEED_BLOCK_SZ)
234
235 #error "Do not change the RNG parameters for FIPS builds."
236 #endif
237#endif
238
239
240/* The security strength for the RNG is the target number of bits of
241 * entropy you are looking for in a seed. */
242#ifndef RNG_SECURITY_STRENGTH
243 #if defined(HAVE_FIPS) && \
244 defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 2)
245 /* SHA-256 requires a minimum of 256-bits of entropy. The goal
246 * of 1024 will provide 4 times that. */
247 #define RNG_SECURITY_STRENGTH (1024)
248 #else
249 /* If not using FIPS or using old FIPS, set the number down a bit.
250 * More is better, but more is also slower. */
251 #define RNG_SECURITY_STRENGTH (256)
252 #endif
253#endif
254
255#ifndef ENTROPY_SCALE_FACTOR
256 /* The entropy scale factor should be the whole number inverse of the
257 * minimum bits of entropy per bit of NDRNG output. */
258 #if defined(HAVE_INTEL_RDSEED) || defined(HAVE_INTEL_RDRAND)
259 /* The value of 2 applies to Intel's RDSEED which provides about
260 * 0.5 bits minimum of entropy per bit. */
261 #define ENTROPY_SCALE_FACTOR 2
262 #else
263 /* Setting the default to 1. */
264 #define ENTROPY_SCALE_FACTOR 1
265 #endif
266#endif
267
268#ifndef SEED_BLOCK_SZ
269 /* The seed block size, is the size of the output of the underlying NDRNG.
270 * This value is used for testing the output of the NDRNG. */
271 #if defined(HAVE_INTEL_RDSEED) || defined(HAVE_INTEL_RDRAND)
272 /* RDSEED outputs in blocks of 64-bits. */
273 #define SEED_BLOCK_SZ sizeof(word64)
274 #else
275 /* Setting the default to 4. */
276 #define SEED_BLOCK_SZ 4
277 #endif
278#endif
279
280#define SEED_SZ (RNG_SECURITY_STRENGTH*ENTROPY_SCALE_FACTOR/8)
281
282/* The maximum seed size will be the seed size plus a seed block for the
283 * test, and an additional half of the seed size. This additional half
284 * is in case the user does not supply a nonce. A nonce will be obtained
285 * from the NDRNG. */
286#define MAX_SEED_SZ (SEED_SZ + SEED_SZ/2 + SEED_BLOCK_SZ)
287
288
289/* Internal return codes */
290#define DRBG_SUCCESS 0
291#define DRBG_FAILURE 1
292#define DRBG_NEED_RESEED 2
293#define DRBG_CONT_FAILURE 3
294
295/* RNG health states */
296#define DRBG_NOT_INIT 0
297#define DRBG_OK 1
298#define DRBG_FAILED 2
299#define DRBG_CONT_FAILED 3
300
301#define RNG_HEALTH_TEST_CHECK_SIZE (WC_SHA256_DIGEST_SIZE * 4)
302
303/* Verify max gen block len */
304#if RNG_MAX_BLOCK_LEN > MAX_REQUEST_LEN
305 #error RNG_MAX_BLOCK_LEN is larger than NIST DBRG max request length
306#endif
307
308enum {
309 drbgInitC = 0,
310 drbgReseed = 1,
311 drbgGenerateW = 2,
312 drbgGenerateH = 3,
313 drbgInitV
314};
315
316typedef struct DRBG_internal DRBG_internal;
317
318static int wc_RNG_HealthTestLocal(int reseed);
319
320/* Hash Derivation Function */
321/* Returns: DRBG_SUCCESS or DRBG_FAILURE */
322static int Hash_df(DRBG_internal* drbg, byte* out, word32 outSz, byte type,
323 const byte* inA, word32 inASz,
324 const byte* inB, word32 inBSz)
325{
326 int ret = DRBG_FAILURE;
327 byte ctr;
328 int i;
329 int len;
330 word32 bits = (outSz * 8); /* reverse byte order */
331#ifdef WOLFSSL_SMALL_STACK_CACHE
332 wc_Sha256* sha = &drbg->sha256;
333#else
334 wc_Sha256 sha[1];
335#endif
336#ifdef WC_ASYNC_ENABLE_SHA256
337 DECLARE_VAR(digest, byte, WC_SHA256_DIGEST_SIZE, drbg->heap);
338 if (digest == NULL)
339 return MEMORY_E;
340#else
341 byte digest[WC_SHA256_DIGEST_SIZE];
342#endif
343
344 (void)drbg;
345#ifdef WC_ASYNC_ENABLE_SHA256
346 if (digest == NULL)
347 return DRBG_FAILURE;
348#endif
349
350#ifdef LITTLE_ENDIAN_ORDER
351 bits = ByteReverseWord32(bits);
352#endif
353 len = (outSz / OUTPUT_BLOCK_LEN)
354 + ((outSz % OUTPUT_BLOCK_LEN) ? 1 : 0);
355
356 for (i = 0, ctr = 1; i < len; i++, ctr++) {
357#ifndef WOLFSSL_SMALL_STACK_CACHE
358 #if defined(WOLFSSL_ASYNC_CRYPT) || defined(WOLF_CRYPTO_CB)
359 ret = wc_InitSha256_ex(sha, drbg->heap, drbg->devId);
360 #else
361 ret = wc_InitSha256(sha);
362 #endif
363 if (ret != 0)
364 break;
365
366 if (ret == 0)
367#endif
368 ret = wc_Sha256Update(sha, &ctr, sizeof(ctr));
369 if (ret == 0)
370 ret = wc_Sha256Update(sha, (byte*)&bits, sizeof(bits));
371
372 if (ret == 0) {
373 /* churning V is the only string that doesn't have the type added */
374 if (type != drbgInitV)
375 ret = wc_Sha256Update(sha, &type, sizeof(type));
376 }
377 if (ret == 0)
378 ret = wc_Sha256Update(sha, inA, inASz);
379 if (ret == 0) {
380 if (inB != NULL && inBSz > 0)
381 ret = wc_Sha256Update(sha, inB, inBSz);
382 }
383 if (ret == 0)
384 ret = wc_Sha256Final(sha, digest);
385
386#ifndef WOLFSSL_SMALL_STACK_CACHE
387 wc_Sha256Free(sha);
388#endif
389 if (ret == 0) {
390 if (outSz > OUTPUT_BLOCK_LEN) {
391 XMEMCPY(out, digest, OUTPUT_BLOCK_LEN);
392 outSz -= OUTPUT_BLOCK_LEN;
393 out += OUTPUT_BLOCK_LEN;
394 }
395 else {
396 XMEMCPY(out, digest, outSz);
397 }
398 }
399 }
400
401 ForceZero(digest, WC_SHA256_DIGEST_SIZE);
402
403#ifdef WC_ASYNC_ENABLE_SHA256
404 FREE_VAR(digest, drbg->heap);
405#endif
406
407 return (ret == 0) ? DRBG_SUCCESS : DRBG_FAILURE;
408}
409
410/* Returns: DRBG_SUCCESS or DRBG_FAILURE */
411static int Hash_DRBG_Reseed(DRBG_internal* drbg, const byte* seed, word32 seedSz)
412{
413 byte newV[DRBG_SEED_LEN];
414
415 XMEMSET(newV, 0, DRBG_SEED_LEN);
416
417 if (Hash_df(drbg, newV, sizeof(newV), drbgReseed,
418 drbg->V, sizeof(drbg->V), seed, seedSz) != DRBG_SUCCESS) {
419 return DRBG_FAILURE;
420 }
421
422 XMEMCPY(drbg->V, newV, sizeof(drbg->V));
423 ForceZero(newV, sizeof(newV));
424
425 if (Hash_df(drbg, drbg->C, sizeof(drbg->C), drbgInitC, drbg->V,
426 sizeof(drbg->V), NULL, 0) != DRBG_SUCCESS) {
427 return DRBG_FAILURE;
428 }
429
430 drbg->reseedCtr = 1;
431 drbg->lastBlock = 0;
432 drbg->matchCount = 0;
433 return DRBG_SUCCESS;
434}
435
436/* Returns: DRBG_SUCCESS and DRBG_FAILURE or BAD_FUNC_ARG on fail */
437int wc_RNG_DRBG_Reseed(WC_RNG* rng, const byte* seed, word32 seedSz)
438{
439 if (rng == NULL || seed == NULL) {
440 return BAD_FUNC_ARG;
441 }
442
443 return Hash_DRBG_Reseed((DRBG_internal *)rng->drbg, seed, seedSz);
444}
445
446static WC_INLINE void array_add_one(byte* data, word32 dataSz)
447{
448 int i;
449
450 for (i = dataSz - 1; i >= 0; i--)
451 {
452 data[i]++;
453 if (data[i] != 0) break;
454 }
455}
456
457/* Returns: DRBG_SUCCESS or DRBG_FAILURE */
458static int Hash_gen(DRBG_internal* drbg, byte* out, word32 outSz, const byte* V)
459{
460 int ret = DRBG_FAILURE;
461 byte data[DRBG_SEED_LEN];
462 int i;
463 int len;
464 word32 checkBlock;
465#ifdef WOLFSSL_SMALL_STACK_CACHE
466 wc_Sha256* sha = &drbg->sha256;
467#else
468 wc_Sha256 sha[1];
469#endif
470#ifdef WC_ASYNC_ENABLE_SHA256
471 DECLARE_VAR(digest, byte, WC_SHA256_DIGEST_SIZE, drbg->heap);
472 if (digest == NULL)
473 return MEMORY_E;
474#else
475 byte digest[WC_SHA256_DIGEST_SIZE];
476#endif
477
478 /* Special case: outSz is 0 and out is NULL. wc_Generate a block to save for
479 * the continuous test. */
480
481 if (outSz == 0) outSz = 1;
482
483 len = (outSz / OUTPUT_BLOCK_LEN) + ((outSz % OUTPUT_BLOCK_LEN) ? 1 : 0);
484
485 XMEMCPY(data, V, sizeof(data));
486 for (i = 0; i < len; i++) {
487#ifndef WOLFSSL_SMALL_STACK_CACHE
488 #if defined(WOLFSSL_ASYNC_CRYPT) || defined(WOLF_CRYPTO_CB)
489 ret = wc_InitSha256_ex(sha, drbg->heap, drbg->devId);
490 #else
491 ret = wc_InitSha256(sha);
492 #endif
493 if (ret == 0)
494#endif
495 ret = wc_Sha256Update(sha, data, sizeof(data));
496 if (ret == 0)
497 ret = wc_Sha256Final(sha, digest);
498#ifndef WOLFSSL_SMALL_STACK_CACHE
499 wc_Sha256Free(sha);
500#endif
501
502 if (ret == 0) {
503 XMEMCPY(&checkBlock, digest, sizeof(word32));
504 if (drbg->reseedCtr > 1 && checkBlock == drbg->lastBlock) {
505 if (drbg->matchCount == 1) {
506 return DRBG_CONT_FAILURE;
507 }
508 else {
509 if (i == (len-1)) {
510 len++;
511 }
512 drbg->matchCount = 1;
513 }
514 }
515 else {
516 drbg->matchCount = 0;
517 drbg->lastBlock = checkBlock;
518 }
519
520 if (out != NULL && outSz != 0) {
521 if (outSz >= OUTPUT_BLOCK_LEN) {
522 XMEMCPY(out, digest, OUTPUT_BLOCK_LEN);
523 outSz -= OUTPUT_BLOCK_LEN;
524 out += OUTPUT_BLOCK_LEN;
525 array_add_one(data, DRBG_SEED_LEN);
526 }
527 else {
528 XMEMCPY(out, digest, outSz);
529 outSz = 0;
530 }
531 }
532 }
533 else {
534 /* wc_Sha256Update or wc_Sha256Final returned error */
535 break;
536 }
537 }
538 ForceZero(data, sizeof(data));
539
540#ifdef WC_ASYNC_ENABLE_SHA256
541 FREE_VAR(digest, drbg->heap);
542#endif
543
544 return (ret == 0) ? DRBG_SUCCESS : DRBG_FAILURE;
545}
546
547static WC_INLINE void array_add(byte* d, word32 dLen, const byte* s, word32 sLen)
548{
549 word16 carry = 0;
550
551 if (dLen > 0 && sLen > 0 && dLen >= sLen) {
552 int sIdx, dIdx;
553
554 for (sIdx = sLen - 1, dIdx = dLen - 1; sIdx >= 0; dIdx--, sIdx--) {
555 carry += (word16)d[dIdx] + (word16)s[sIdx];
556 d[dIdx] = (byte)carry;
557 carry >>= 8;
558 }
559
560 for (; carry != 0 && dIdx >= 0; dIdx--) {
561 carry += (word16)d[dIdx];
562 d[dIdx] = (byte)carry;
563 carry >>= 8;
564 }
565 }
566}
567
568/* Returns: DRBG_SUCCESS, DRBG_NEED_RESEED, or DRBG_FAILURE */
569static int Hash_DRBG_Generate(DRBG_internal* drbg, byte* out, word32 outSz)
570{
571 int ret;
572#ifdef WOLFSSL_SMALL_STACK_CACHE
573 wc_Sha256* sha = &drbg->sha256;
574#else
575 wc_Sha256 sha[1];
576#endif
577 byte type;
578 word32 reseedCtr;
579
580 if (drbg->reseedCtr == RESEED_INTERVAL) {
581 return DRBG_NEED_RESEED;
582 } else {
583 #ifdef WC_ASYNC_ENABLE_SHA256
584 DECLARE_VAR(digest, byte, WC_SHA256_DIGEST_SIZE, drbg->heap);
585 if (digest == NULL)
586 return MEMORY_E;
587 #else
588 byte digest[WC_SHA256_DIGEST_SIZE];
589 #endif
590 type = drbgGenerateH;
591 reseedCtr = drbg->reseedCtr;
592
593 ret = Hash_gen(drbg, out, outSz, drbg->V);
594 if (ret == DRBG_SUCCESS) {
595#ifndef WOLFSSL_SMALL_STACK_CACHE
596 #if defined(WOLFSSL_ASYNC_CRYPT) || defined(WOLF_CRYPTO_CB)
597 ret = wc_InitSha256_ex(sha, drbg->heap, drbg->devId);
598 #else
599 ret = wc_InitSha256(sha);
600 #endif
601 if (ret == 0)
602#endif
603 ret = wc_Sha256Update(sha, &type, sizeof(type));
604 if (ret == 0)
605 ret = wc_Sha256Update(sha, drbg->V, sizeof(drbg->V));
606 if (ret == 0)
607 ret = wc_Sha256Final(sha, digest);
608
609#ifndef WOLFSSL_SMALL_STACK_CACHE
610 wc_Sha256Free(sha);
611#endif
612
613 if (ret == 0) {
614 array_add(drbg->V, sizeof(drbg->V), digest, WC_SHA256_DIGEST_SIZE);
615 array_add(drbg->V, sizeof(drbg->V), drbg->C, sizeof(drbg->C));
616 #ifdef LITTLE_ENDIAN_ORDER
617 reseedCtr = ByteReverseWord32(reseedCtr);
618 #endif
619 array_add(drbg->V, sizeof(drbg->V),
620 (byte*)&reseedCtr, sizeof(reseedCtr));
621 ret = DRBG_SUCCESS;
622 }
623 drbg->reseedCtr++;
624 }
625 ForceZero(digest, WC_SHA256_DIGEST_SIZE);
626 #ifdef WC_ASYNC_ENABLE_SHA256
627 FREE_VAR(digest, drbg->heap);
628 #endif
629 }
630
631 return (ret == 0) ? DRBG_SUCCESS : DRBG_FAILURE;
632}
633
634/* Returns: DRBG_SUCCESS or DRBG_FAILURE */
635static int Hash_DRBG_Instantiate(DRBG_internal* drbg, const byte* seed, word32 seedSz,
636 const byte* nonce, word32 nonceSz,
637 void* heap, int devId)
638{
639 int ret = DRBG_FAILURE;
640
641 XMEMSET(drbg, 0, sizeof(DRBG_internal));
642#if defined(WOLFSSL_ASYNC_CRYPT) || defined(WOLF_CRYPTO_CB)
643 drbg->heap = heap;
644 drbg->devId = devId;
645#else
646 (void)heap;
647 (void)devId;
648#endif
649
650#ifdef WOLFSSL_SMALL_STACK_CACHE
651 #if defined(WOLFSSL_ASYNC_CRYPT) || defined(WOLF_CRYPTO_CB)
652 ret = wc_InitSha256_ex(&drbg->sha256, drbg->heap, drbg->devId);
653 #else
654 ret = wc_InitSha256(&drbg->sha256);
655 #endif
656 if (ret != 0)
657 return ret;
658#endif
659
660 if (Hash_df(drbg, drbg->V, sizeof(drbg->V), drbgInitV, seed, seedSz,
661 nonce, nonceSz) == DRBG_SUCCESS &&
662 Hash_df(drbg, drbg->C, sizeof(drbg->C), drbgInitC, drbg->V,
663 sizeof(drbg->V), NULL, 0) == DRBG_SUCCESS) {
664
665 drbg->reseedCtr = 1;
666 drbg->lastBlock = 0;
667 drbg->matchCount = 0;
668 ret = DRBG_SUCCESS;
669 }
670
671 return ret;
672}
673
674/* Returns: DRBG_SUCCESS or DRBG_FAILURE */
675static int Hash_DRBG_Uninstantiate(DRBG_internal* drbg)
676{
677 word32 i;
678 int compareSum = 0;
679 byte* compareDrbg = (byte*)drbg;
680
681#ifdef WOLFSSL_SMALL_STACK_CACHE
682 wc_Sha256Free(&drbg->sha256);
683#endif
684
685 ForceZero(drbg, sizeof(DRBG_internal));
686
687 for (i = 0; i < sizeof(DRBG_internal); i++)
688 compareSum |= compareDrbg[i] ^ 0;
689
690 return (compareSum == 0) ? DRBG_SUCCESS : DRBG_FAILURE;
691}
692
693
694int wc_RNG_TestSeed(const byte* seed, word32 seedSz)
695{
696 int ret = 0;
697
698 /* Check the seed for duplicate words. */
699 word32 seedIdx = 0;
700 word32 scratchSz = min(SEED_BLOCK_SZ, seedSz - SEED_BLOCK_SZ);
701
702 while (seedIdx < seedSz - SEED_BLOCK_SZ) {
703 if (ConstantCompare(seed + seedIdx,
704 seed + seedIdx + scratchSz,
705 scratchSz) == 0) {
706
707 ret = DRBG_CONT_FAILURE;
708 }
709 seedIdx += SEED_BLOCK_SZ;
710 scratchSz = min(SEED_BLOCK_SZ, (seedSz - seedIdx));
711 }
712
713 return ret;
714}
715#endif /* HAVE_HASHDRBG */
716/* End NIST DRBG Code */
717
718
719static int _InitRng(WC_RNG* rng, byte* nonce, word32 nonceSz,
720 void* heap, int devId)
721{
722 int ret = 0;
723#ifdef HAVE_HASHDRBG
724 word32 seedSz = SEED_SZ + SEED_BLOCK_SZ;
725#endif
726
727 (void)nonce;
728 (void)nonceSz;
729
730 if (rng == NULL)
731 return BAD_FUNC_ARG;
732 if (nonce == NULL && nonceSz != 0)
733 return BAD_FUNC_ARG;
734
735#ifdef WOLFSSL_HEAP_TEST
736 rng->heap = (void*)WOLFSSL_HEAP_TEST;
737 (void)heap;
738#else
739 rng->heap = heap;
740#endif
741#if defined(WOLFSSL_ASYNC_CRYPT) || defined(WOLF_CRYPTO_CB)
742 rng->devId = devId;
743 #if defined(WOLF_CRYPTO_CB)
744 rng->seed.devId = devId;
745 #endif
746#else
747 (void)devId;
748#endif
749
750#ifdef HAVE_HASHDRBG
751 /* init the DBRG to known values */
752 rng->drbg = NULL;
753 rng->status = DRBG_NOT_INIT;
754#endif
755
756#if defined(HAVE_INTEL_RDSEED) || defined(HAVE_INTEL_RDRAND)
757 /* init the intel RD seed and/or rand */
758 wc_InitRng_IntelRD();
759#endif
760
761 /* configure async RNG source if available */
762#ifdef WOLFSSL_ASYNC_CRYPT
763 ret = wolfAsync_DevCtxInit(&rng->asyncDev, WOLFSSL_ASYNC_MARKER_RNG,
764 rng->heap, rng->devId);
765 if (ret != 0)
766 return ret;
767#endif
768
769#ifdef HAVE_INTEL_RDRAND
770 /* if CPU supports RDRAND, use it directly and by-pass DRBG init */
771 if (IS_INTEL_RDRAND(intel_flags))
772 return 0;
773#endif
774
775#ifdef CUSTOM_RAND_GENERATE_BLOCK
776 ret = 0; /* success */
777#else
778#ifdef HAVE_HASHDRBG
779 if (nonceSz == 0)
780 seedSz = MAX_SEED_SZ;
781
782 if (wc_RNG_HealthTestLocal(0) == 0) {
783 #ifdef WC_ASYNC_ENABLE_SHA256
784 DECLARE_VAR(seed, byte, MAX_SEED_SZ, rng->heap);
785 if (seed == NULL)
786 return MEMORY_E;
787 #else
788 byte seed[MAX_SEED_SZ];
789 #endif
790
791#if !defined(WOLFSSL_NO_MALLOC) || defined(WOLFSSL_STATIC_MEMORY)
792 rng->drbg =
793 (struct DRBG*)XMALLOC(sizeof(DRBG_internal), rng->heap,
794 DYNAMIC_TYPE_RNG);
795 if (rng->drbg == NULL) {
796 ret = MEMORY_E;
797 rng->status = DRBG_FAILED;
798 }
799#else
800 rng->drbg = (struct DRBG*)&rng->drbg_data;
801#endif
802 if (ret == 0) {
803 ret = wc_GenerateSeed(&rng->seed, seed, seedSz);
804 if (ret == 0)
805 ret = wc_RNG_TestSeed(seed, seedSz);
806 else {
807 ret = DRBG_FAILURE;
808 rng->status = DRBG_FAILED;
809 }
810
811 if (ret == DRBG_SUCCESS)
812 ret = Hash_DRBG_Instantiate((DRBG_internal *)rng->drbg,
813 seed + SEED_BLOCK_SZ, seedSz - SEED_BLOCK_SZ,
814 nonce, nonceSz, rng->heap, devId);
815
816 if (ret != DRBG_SUCCESS) {
817 #if !defined(WOLFSSL_NO_MALLOC) || defined(WOLFSSL_STATIC_MEMORY)
818 XFREE(rng->drbg, rng->heap, DYNAMIC_TYPE_RNG);
819 #endif
820 rng->drbg = NULL;
821 }
822 }
823
824 ForceZero(seed, seedSz);
825 #ifdef WC_ASYNC_ENABLE_SHA256
826 FREE_VAR(seed, rng->heap);
827 #endif
828 }
829 else
830 ret = DRBG_CONT_FAILURE;
831
832 if (ret == DRBG_SUCCESS) {
833 rng->status = DRBG_OK;
834 ret = 0;
835 }
836 else if (ret == DRBG_CONT_FAILURE) {
837 rng->status = DRBG_CONT_FAILED;
838 ret = DRBG_CONT_FIPS_E;
839 }
840 else if (ret == DRBG_FAILURE) {
841 rng->status = DRBG_FAILED;
842 ret = RNG_FAILURE_E;
843 }
844 else {
845 rng->status = DRBG_FAILED;
846 }
847#endif /* HAVE_HASHDRBG */
848#endif /* CUSTOM_RAND_GENERATE_BLOCK */
849
850 return ret;
851}
852
853
854WOLFSSL_ABI
855WC_RNG* wc_rng_new(byte* nonce, word32 nonceSz, void* heap)
856{
857 WC_RNG* rng;
858
859 rng = (WC_RNG*)XMALLOC(sizeof(WC_RNG), heap, DYNAMIC_TYPE_RNG);
860 if (rng) {
861 int error = _InitRng(rng, nonce, nonceSz, heap, INVALID_DEVID) != 0;
862 if (error) {
863 XFREE(rng, heap, DYNAMIC_TYPE_RNG);
864 rng = NULL;
865 }
866 }
867
868 return rng;
869}
870
871
872WOLFSSL_ABI
873void wc_rng_free(WC_RNG* rng)
874{
875 if (rng) {
876 void* heap = rng->heap;
877
878 wc_FreeRng(rng);
879 ForceZero(rng, sizeof(WC_RNG));
880 XFREE(rng, heap, DYNAMIC_TYPE_RNG);
881 (void)heap;
882 }
883}
884
885
886int wc_InitRng(WC_RNG* rng)
887{
888 return _InitRng(rng, NULL, 0, NULL, INVALID_DEVID);
889}
890
891
892int wc_InitRng_ex(WC_RNG* rng, void* heap, int devId)
893{
894 return _InitRng(rng, NULL, 0, heap, devId);
895}
896
897
898int wc_InitRngNonce(WC_RNG* rng, byte* nonce, word32 nonceSz)
899{
900 return _InitRng(rng, nonce, nonceSz, NULL, INVALID_DEVID);
901}
902
903
904int wc_InitRngNonce_ex(WC_RNG* rng, byte* nonce, word32 nonceSz,
905 void* heap, int devId)
906{
907 return _InitRng(rng, nonce, nonceSz, heap, devId);
908}
909
910
911/* place a generated block in output */
912WOLFSSL_ABI
913int wc_RNG_GenerateBlock(WC_RNG* rng, byte* output, word32 sz)
914{
915 int ret;
916
917 if (rng == NULL || output == NULL)
918 return BAD_FUNC_ARG;
919
920 if (sz == 0)
921 return 0;
922
923#ifdef WOLF_CRYPTO_CB
924 if (rng->devId != INVALID_DEVID) {
925 ret = wc_CryptoCb_RandomBlock(rng, output, sz);
926 if (ret != CRYPTOCB_UNAVAILABLE)
927 return ret;
928 /* fall-through when unavailable */
929 }
930#endif
931
932#ifdef HAVE_INTEL_RDRAND
933 if (IS_INTEL_RDRAND(intel_flags))
934 return wc_GenerateRand_IntelRD(NULL, output, sz);
935#endif
936
937#if defined(WOLFSSL_SILABS_SE_ACCEL) && defined(WOLFSSL_SILABS_TRNG)
938 return silabs_GenerateRand(output, sz);
939#endif
940
941#if defined(WOLFSSL_ASYNC_CRYPT)
942 if (rng->asyncDev.marker == WOLFSSL_ASYNC_MARKER_RNG) {
943 /* these are blocking */
944 #ifdef HAVE_CAVIUM
945 return NitroxRngGenerateBlock(rng, output, sz);
946 #elif defined(HAVE_INTEL_QA) && defined(QAT_ENABLE_RNG)
947 return IntelQaDrbg(&rng->asyncDev, output, sz);
948 #else
949 /* simulator not supported */
950 #endif
951 }
952#endif
953
954#ifdef CUSTOM_RAND_GENERATE_BLOCK
955 XMEMSET(output, 0, sz);
956 ret = CUSTOM_RAND_GENERATE_BLOCK(output, sz);
957#else
958
959#ifdef HAVE_HASHDRBG
960 if (sz > RNG_MAX_BLOCK_LEN)
961 return BAD_FUNC_ARG;
962
963 if (rng->status != DRBG_OK)
964 return RNG_FAILURE_E;
965
966 ret = Hash_DRBG_Generate((DRBG_internal *)rng->drbg, output, sz);
967 if (ret == DRBG_NEED_RESEED) {
968 if (wc_RNG_HealthTestLocal(1) == 0) {
969 byte newSeed[SEED_SZ + SEED_BLOCK_SZ];
970
971 ret = wc_GenerateSeed(&rng->seed, newSeed,
972 SEED_SZ + SEED_BLOCK_SZ);
973 if (ret != 0)
974 ret = DRBG_FAILURE;
975 else
976 ret = wc_RNG_TestSeed(newSeed, SEED_SZ + SEED_BLOCK_SZ);
977
978 if (ret == DRBG_SUCCESS)
979 ret = Hash_DRBG_Reseed((DRBG_internal *)rng->drbg, newSeed + SEED_BLOCK_SZ,
980 SEED_SZ);
981 if (ret == DRBG_SUCCESS)
982 ret = Hash_DRBG_Generate((DRBG_internal *)rng->drbg, output, sz);
983
984 ForceZero(newSeed, sizeof(newSeed));
985 }
986 else
987 ret = DRBG_CONT_FAILURE;
988 }
989
990 if (ret == DRBG_SUCCESS) {
991 ret = 0;
992 }
993 else if (ret == DRBG_CONT_FAILURE) {
994 ret = DRBG_CONT_FIPS_E;
995 rng->status = DRBG_CONT_FAILED;
996 }
997 else {
998 ret = RNG_FAILURE_E;
999 rng->status = DRBG_FAILED;
1000 }
1001#else
1002
1003 /* if we get here then there is an RNG configuration error */
1004 ret = RNG_FAILURE_E;
1005
1006#endif /* HAVE_HASHDRBG */
1007#endif /* CUSTOM_RAND_GENERATE_BLOCK */
1008
1009 return ret;
1010}
1011
1012
1013int wc_RNG_GenerateByte(WC_RNG* rng, byte* b)
1014{
1015 return wc_RNG_GenerateBlock(rng, b, 1);
1016}
1017
1018
1019int wc_FreeRng(WC_RNG* rng)
1020{
1021 int ret = 0;
1022
1023 if (rng == NULL)
1024 return BAD_FUNC_ARG;
1025
1026#if defined(WOLFSSL_ASYNC_CRYPT)
1027 wolfAsync_DevCtxFree(&rng->asyncDev, WOLFSSL_ASYNC_MARKER_RNG);
1028#endif
1029
1030#ifdef HAVE_HASHDRBG
1031 if (rng->drbg != NULL) {
1032 if (Hash_DRBG_Uninstantiate((DRBG_internal *)rng->drbg) != DRBG_SUCCESS)
1033 ret = RNG_FAILURE_E;
1034
1035 #if !defined(WOLFSSL_NO_MALLOC) || defined(WOLFSSL_STATIC_MEMORY)
1036 XFREE(rng->drbg, rng->heap, DYNAMIC_TYPE_RNG);
1037 #endif
1038 rng->drbg = NULL;
1039 }
1040
1041 rng->status = DRBG_NOT_INIT;
1042#endif /* HAVE_HASHDRBG */
1043
1044 return ret;
1045}
1046
1047#ifdef HAVE_HASHDRBG
1048int wc_RNG_HealthTest(int reseed, const byte* seedA, word32 seedASz,
1049 const byte* seedB, word32 seedBSz,
1050 byte* output, word32 outputSz)
1051{
1052 return wc_RNG_HealthTest_ex(reseed, NULL, 0,
1053 seedA, seedASz, seedB, seedBSz,
1054 output, outputSz,
1055 NULL, INVALID_DEVID);
1056}
1057
1058
1059int wc_RNG_HealthTest_ex(int reseed, const byte* nonce, word32 nonceSz,
1060 const byte* seedA, word32 seedASz,
1061 const byte* seedB, word32 seedBSz,
1062 byte* output, word32 outputSz,
1063 void* heap, int devId)
1064{
1065 int ret = -1;
1066 DRBG_internal* drbg;
1067#ifndef WOLFSSL_SMALL_STACK
1068 DRBG_internal drbg_var;
1069#endif
1070
1071 if (seedA == NULL || output == NULL) {
1072 return BAD_FUNC_ARG;
1073 }
1074
1075 if (reseed != 0 && seedB == NULL) {
1076 return BAD_FUNC_ARG;
1077 }
1078
1079 if (outputSz != RNG_HEALTH_TEST_CHECK_SIZE) {
1080 return ret;
1081 }
1082
1083#ifdef WOLFSSL_SMALL_STACK
1084 drbg = (DRBG_internal*)XMALLOC(sizeof(DRBG_internal), NULL, DYNAMIC_TYPE_RNG);
1085 if (drbg == NULL) {
1086 return MEMORY_E;
1087 }
1088#else
1089 drbg = &drbg_var;
1090#endif
1091
1092 if (Hash_DRBG_Instantiate(drbg, seedA, seedASz, nonce, nonceSz,
1093 heap, devId) != 0) {
1094 goto exit_rng_ht;
1095 }
1096
1097 if (reseed) {
1098 if (Hash_DRBG_Reseed(drbg, seedB, seedBSz) != 0) {
1099 goto exit_rng_ht;
1100 }
1101 }
1102
1103 /* This call to generate is prescribed by the NIST DRBGVS
1104 * procedure. The results are thrown away. The known
1105 * answer test checks the second block of DRBG out of
1106 * the generator to ensure the internal state is updated
1107 * as expected. */
1108 if (Hash_DRBG_Generate(drbg, output, outputSz) != 0) {
1109 goto exit_rng_ht;
1110 }
1111
1112 if (Hash_DRBG_Generate(drbg, output, outputSz) != 0) {
1113 goto exit_rng_ht;
1114 }
1115
1116 /* Mark success */
1117 ret = 0;
1118
1119exit_rng_ht:
1120
1121 /* This is safe to call even if Hash_DRBG_Instantiate fails */
1122 if (Hash_DRBG_Uninstantiate(drbg) != 0) {
1123 ret = -1;
1124 }
1125
1126#ifdef WOLFSSL_SMALL_STACK
1127 XFREE(drbg, NULL, DYNAMIC_TYPE_RNG);
1128#endif
1129
1130 return ret;
1131}
1132
1133
1134const FLASH_QUALIFIER byte seedA_data[] = {
1135 0x63, 0x36, 0x33, 0x77, 0xe4, 0x1e, 0x86, 0x46, 0x8d, 0xeb, 0x0a, 0xb4,
1136 0xa8, 0xed, 0x68, 0x3f, 0x6a, 0x13, 0x4e, 0x47, 0xe0, 0x14, 0xc7, 0x00,
1137 0x45, 0x4e, 0x81, 0xe9, 0x53, 0x58, 0xa5, 0x69, 0x80, 0x8a, 0xa3, 0x8f,
1138 0x2a, 0x72, 0xa6, 0x23, 0x59, 0x91, 0x5a, 0x9f, 0x8a, 0x04, 0xca, 0x68
1139};
1140
1141const FLASH_QUALIFIER byte reseedSeedA_data[] = {
1142 0xe6, 0x2b, 0x8a, 0x8e, 0xe8, 0xf1, 0x41, 0xb6, 0x98, 0x05, 0x66, 0xe3,
1143 0xbf, 0xe3, 0xc0, 0x49, 0x03, 0xda, 0xd4, 0xac, 0x2c, 0xdf, 0x9f, 0x22,
1144 0x80, 0x01, 0x0a, 0x67, 0x39, 0xbc, 0x83, 0xd3
1145};
1146
1147const FLASH_QUALIFIER byte outputA_data[] = {
1148 0x04, 0xee, 0xc6, 0x3b, 0xb2, 0x31, 0xdf, 0x2c, 0x63, 0x0a, 0x1a, 0xfb,
1149 0xe7, 0x24, 0x94, 0x9d, 0x00, 0x5a, 0x58, 0x78, 0x51, 0xe1, 0xaa, 0x79,
1150 0x5e, 0x47, 0x73, 0x47, 0xc8, 0xb0, 0x56, 0x62, 0x1c, 0x18, 0xbd, 0xdc,
1151 0xdd, 0x8d, 0x99, 0xfc, 0x5f, 0xc2, 0xb9, 0x20, 0x53, 0xd8, 0xcf, 0xac,
1152 0xfb, 0x0b, 0xb8, 0x83, 0x12, 0x05, 0xfa, 0xd1, 0xdd, 0xd6, 0xc0, 0x71,
1153 0x31, 0x8a, 0x60, 0x18, 0xf0, 0x3b, 0x73, 0xf5, 0xed, 0xe4, 0xd4, 0xd0,
1154 0x71, 0xf9, 0xde, 0x03, 0xfd, 0x7a, 0xea, 0x10, 0x5d, 0x92, 0x99, 0xb8,
1155 0xaf, 0x99, 0xaa, 0x07, 0x5b, 0xdb, 0x4d, 0xb9, 0xaa, 0x28, 0xc1, 0x8d,
1156 0x17, 0x4b, 0x56, 0xee, 0x2a, 0x01, 0x4d, 0x09, 0x88, 0x96, 0xff, 0x22,
1157 0x82, 0xc9, 0x55, 0xa8, 0x19, 0x69, 0xe0, 0x69, 0xfa, 0x8c, 0xe0, 0x07,
1158 0xa1, 0x80, 0x18, 0x3a, 0x07, 0xdf, 0xae, 0x17
1159};
1160
1161const FLASH_QUALIFIER byte seedB_data[] = {
1162 0xa6, 0x5a, 0xd0, 0xf3, 0x45, 0xdb, 0x4e, 0x0e, 0xff, 0xe8, 0x75, 0xc3,
1163 0xa2, 0xe7, 0x1f, 0x42, 0xc7, 0x12, 0x9d, 0x62, 0x0f, 0xf5, 0xc1, 0x19,
1164 0xa9, 0xef, 0x55, 0xf0, 0x51, 0x85, 0xe0, 0xfb, /* nonce next */
1165 0x85, 0x81, 0xf9, 0x31, 0x75, 0x17, 0x27, 0x6e, 0x06, 0xe9, 0x60, 0x7d,
1166 0xdb, 0xcb, 0xcc, 0x2e
1167};
1168
1169const FLASH_QUALIFIER byte outputB_data[] = {
1170 0xd3, 0xe1, 0x60, 0xc3, 0x5b, 0x99, 0xf3, 0x40, 0xb2, 0x62, 0x82, 0x64,
1171 0xd1, 0x75, 0x10, 0x60, 0xe0, 0x04, 0x5d, 0xa3, 0x83, 0xff, 0x57, 0xa5,
1172 0x7d, 0x73, 0xa6, 0x73, 0xd2, 0xb8, 0xd8, 0x0d, 0xaa, 0xf6, 0xa6, 0xc3,
1173 0x5a, 0x91, 0xbb, 0x45, 0x79, 0xd7, 0x3f, 0xd0, 0xc8, 0xfe, 0xd1, 0x11,
1174 0xb0, 0x39, 0x13, 0x06, 0x82, 0x8a, 0xdf, 0xed, 0x52, 0x8f, 0x01, 0x81,
1175 0x21, 0xb3, 0xfe, 0xbd, 0xc3, 0x43, 0xe7, 0x97, 0xb8, 0x7d, 0xbb, 0x63,
1176 0xdb, 0x13, 0x33, 0xde, 0xd9, 0xd1, 0xec, 0xe1, 0x77, 0xcf, 0xa6, 0xb7,
1177 0x1f, 0xe8, 0xab, 0x1d, 0xa4, 0x66, 0x24, 0xed, 0x64, 0x15, 0xe5, 0x1c,
1178 0xcd, 0xe2, 0xc7, 0xca, 0x86, 0xe2, 0x83, 0x99, 0x0e, 0xea, 0xeb, 0x91,
1179 0x12, 0x04, 0x15, 0x52, 0x8b, 0x22, 0x95, 0x91, 0x02, 0x81, 0xb0, 0x2d,
1180 0xd4, 0x31, 0xf4, 0xc9, 0xf7, 0x04, 0x27, 0xdf
1181};
1182
1183
1184static int wc_RNG_HealthTestLocal(int reseed)
1185{
1186 int ret = 0;
1187#ifdef WOLFSSL_SMALL_STACK
1188 byte* check;
1189#else
1190 byte check[RNG_HEALTH_TEST_CHECK_SIZE];
1191#endif
1192
1193#ifdef WOLFSSL_SMALL_STACK
1194 check = (byte*)XMALLOC(RNG_HEALTH_TEST_CHECK_SIZE, NULL,
1195 DYNAMIC_TYPE_TMP_BUFFER);
1196 if (check == NULL) {
1197 return MEMORY_E;
1198 }
1199#endif
1200
1201 if (reseed) {
1202#ifdef WOLFSSL_USE_FLASHMEM
1203 byte* seedA = (byte*)XMALLOC(sizeof(seedA_data), NULL,
1204 DYNAMIC_TYPE_TMP_BUFFER);
1205 byte* reseedSeedA = (byte*)XMALLOC(sizeof(reseedSeedA_data), NULL,
1206 DYNAMIC_TYPE_TMP_BUFFER);
1207 byte* outputA = (byte*)XMALLOC(sizeof(outputA_data), NULL,
1208 DYNAMIC_TYPE_TMP_BUFFER);
1209
1210 if (!seedA || !reseedSeedA || !outputA) {
1211 XFREE(seedA, NULL, DYNAMIC_TYPE_TMP_BUFFER);
1212 XFREE(reseedSeedA, NULL, DYNAMIC_TYPE_TMP_BUFFER);
1213 XFREE(outputA, NULL, DYNAMIC_TYPE_TMP_BUFFER);
1214 ret = MEMORY_E;
1215 }
1216 else {
1217 XMEMCPY_P(seedA, seedA_data, sizeof(seedA_data));
1218 XMEMCPY_P(reseedSeedA, reseedSeedA_data, sizeof(reseedSeedA_data));
1219 XMEMCPY_P(outputA, outputA_data, sizeof(outputA_data));
1220#else
1221 const byte* seedA = seedA_data;
1222 const byte* reseedSeedA = reseedSeedA_data;
1223 const byte* outputA = outputA_data;
1224#endif
1225 ret = wc_RNG_HealthTest(1, seedA, sizeof(seedA_data),
1226 reseedSeedA, sizeof(reseedSeedA_data),
1227 check, RNG_HEALTH_TEST_CHECK_SIZE);
1228 if (ret == 0) {
1229 if (ConstantCompare(check, outputA,
1230 RNG_HEALTH_TEST_CHECK_SIZE) != 0)
1231 ret = -1;
1232 }
1233
1234#ifdef WOLFSSL_USE_FLASHMEM
1235 XFREE(seedA, NULL, DYNAMIC_TYPE_TMP_BUFFER);
1236 XFREE(reseedSeedA, NULL, DYNAMIC_TYPE_TMP_BUFFER);
1237 XFREE(outputA, NULL, DYNAMIC_TYPE_TMP_BUFFER);
1238 }
1239#endif
1240 }
1241 else {
1242#ifdef WOLFSSL_USE_FLASHMEM
1243 byte* seedB = (byte*)XMALLOC(sizeof(seedB_data), NULL,
1244 DYNAMIC_TYPE_TMP_BUFFER);
1245 byte* outputB = (byte*)XMALLOC(sizeof(outputB_data), NULL,
1246 DYNAMIC_TYPE_TMP_BUFFER);
1247
1248 if (!seedB || !outputB) {
1249 XFREE(seedB, NULL, DYNAMIC_TYPE_TMP_BUFFER);
1250 XFREE(outputB, NULL, DYNAMIC_TYPE_TMP_BUFFER);
1251 ret = MEMORY_E;
1252 }
1253 else {
1254 XMEMCPY_P(seedB, seedB_data, sizeof(seedB_data));
1255 XMEMCPY_P(outputB, outputB_data, sizeof(outputB_data));
1256#else
1257 const byte* seedB = seedB_data;
1258 const byte* outputB = outputB_data;
1259#endif
1260 ret = wc_RNG_HealthTest(0, seedB, sizeof(seedB_data),
1261 NULL, 0,
1262 check, RNG_HEALTH_TEST_CHECK_SIZE);
1263 if (ret == 0) {
1264 if (ConstantCompare(check, outputB,
1265 RNG_HEALTH_TEST_CHECK_SIZE) != 0)
1266 ret = -1;
1267 }
1268
1269 /* The previous test cases use a large seed instead of a seed and nonce.
1270 * seedB is actually from a test case with a seed and nonce, and
1271 * just concatenates them. The pivot point between seed and nonce is
1272 * byte 32, feed them into the health test separately. */
1273 if (ret == 0) {
1274 ret = wc_RNG_HealthTest_ex(0,
1275 seedB + 32, sizeof(seedB_data) - 32,
1276 seedB, 32,
1277 NULL, 0,
1278 check, RNG_HEALTH_TEST_CHECK_SIZE,
1279 NULL, INVALID_DEVID);
1280 if (ret == 0) {
1281 if (ConstantCompare(check, outputB, sizeof(outputB_data)) != 0)
1282 ret = -1;
1283 }
1284 }
1285
1286#ifdef WOLFSSL_USE_FLASHMEM
1287 XFREE(seedB, NULL, DYNAMIC_TYPE_TMP_BUFFER);
1288 XFREE(outputB, NULL, DYNAMIC_TYPE_TMP_BUFFER);
1289 }
1290#endif
1291 }
1292
1293#ifdef WOLFSSL_SMALL_STACK
1294 XFREE(check, NULL, DYNAMIC_TYPE_TMP_BUFFER);
1295#endif
1296
1297 return ret;
1298}
1299
1300#endif /* HAVE_HASHDRBG */
1301
1302
1303#ifdef HAVE_WNR
1304
1305/*
1306 * Init global Whitewood netRandom context
1307 * Returns 0 on success, negative on error
1308 */
1309int wc_InitNetRandom(const char* configFile, wnr_hmac_key hmac_cb, int timeout)
1310{
1311 if (configFile == NULL || timeout < 0)
1312 return BAD_FUNC_ARG;
1313
1314 if (wnr_mutex_init > 0) {
1315 WOLFSSL_MSG("netRandom context already created, skipping");
1316 return 0;
1317 }
1318
1319 if (wc_InitMutex(&wnr_mutex) != 0) {
1320 WOLFSSL_MSG("Bad Init Mutex wnr_mutex");
1321 return BAD_MUTEX_E;
1322 }
1323 wnr_mutex_init = 1;
1324
1325 if (wc_LockMutex(&wnr_mutex) != 0) {
1326 WOLFSSL_MSG("Bad Lock Mutex wnr_mutex");
1327 return BAD_MUTEX_E;
1328 }
1329
1330 /* store entropy timeout */
1331 wnr_timeout = timeout;
1332
1333 /* create global wnr_context struct */
1334 if (wnr_create(&wnr_ctx) != WNR_ERROR_NONE) {
1335 WOLFSSL_MSG("Error creating global netRandom context");
1336 return RNG_FAILURE_E;
1337 }
1338
1339 /* load config file */
1340 if (wnr_config_loadf(wnr_ctx, (char*)configFile) != WNR_ERROR_NONE) {
1341 WOLFSSL_MSG("Error loading config file into netRandom context");
1342 wnr_destroy(wnr_ctx);
1343 wnr_ctx = NULL;
1344 return RNG_FAILURE_E;
1345 }
1346
1347 /* create/init polling mechanism */
1348 if (wnr_poll_create() != WNR_ERROR_NONE) {
1349 printf("ERROR: wnr_poll_create() failed\n");
1350 WOLFSSL_MSG("Error initializing netRandom polling mechanism");
1351 wnr_destroy(wnr_ctx);
1352 wnr_ctx = NULL;
1353 return RNG_FAILURE_E;
1354 }
1355
1356 /* validate config, set HMAC callback (optional) */
1357 if (wnr_setup(wnr_ctx, hmac_cb) != WNR_ERROR_NONE) {
1358 WOLFSSL_MSG("Error setting up netRandom context");
1359 wnr_destroy(wnr_ctx);
1360 wnr_ctx = NULL;
1361 wnr_poll_destroy();
1362 return RNG_FAILURE_E;
1363 }
1364
1365 wc_UnLockMutex(&wnr_mutex);
1366
1367 return 0;
1368}
1369
1370/*
1371 * Free global Whitewood netRandom context
1372 * Returns 0 on success, negative on error
1373 */
1374int wc_FreeNetRandom(void)
1375{
1376 if (wnr_mutex_init > 0) {
1377
1378 if (wc_LockMutex(&wnr_mutex) != 0) {
1379 WOLFSSL_MSG("Bad Lock Mutex wnr_mutex");
1380 return BAD_MUTEX_E;
1381 }
1382
1383 if (wnr_ctx != NULL) {
1384 wnr_destroy(wnr_ctx);
1385 wnr_ctx = NULL;
1386 }
1387 wnr_poll_destroy();
1388
1389 wc_UnLockMutex(&wnr_mutex);
1390
1391 wc_FreeMutex(&wnr_mutex);
1392 wnr_mutex_init = 0;
1393 }
1394
1395 return 0;
1396}
1397
1398#endif /* HAVE_WNR */
1399
1400
1401#if defined(HAVE_INTEL_RDRAND) || defined(HAVE_INTEL_RDSEED)
1402
1403#ifdef WOLFSSL_ASYNC_CRYPT
1404 /* need more retries if multiple cores */
1405 #define INTELRD_RETRY (32 * 8)
1406#else
1407 #define INTELRD_RETRY 32
1408#endif
1409
1410#ifdef HAVE_INTEL_RDSEED
1411
1412#ifndef USE_INTEL_INTRINSICS
1413
1414 /* return 0 on success */
1415 static WC_INLINE int IntelRDseed64(word64* seed)
1416 {
1417 unsigned char ok;
1418
1419 __asm__ volatile("rdseed %0; setc %1":"=r"(*seed), "=qm"(ok));
1420 return (ok) ? 0 : -1;
1421 }
1422
1423#else /* USE_INTEL_INTRINSICS */
1424 /* The compiler Visual Studio uses does not allow inline assembly.
1425 * It does allow for Intel intrinsic functions. */
1426
1427 /* return 0 on success */
1428# ifdef __GNUC__
1429 __attribute__((target("rdseed")))
1430# endif
1431 static WC_INLINE int IntelRDseed64(word64* seed)
1432 {
1433 int ok;
1434
1435 ok = _rdseed64_step((unsigned long long*) seed);
1436 return (ok) ? 0 : -1;
1437 }
1438
1439#endif /* USE_INTEL_INTRINSICS */
1440
1441/* return 0 on success */
1442static WC_INLINE int IntelRDseed64_r(word64* rnd)
1443{
1444 int i;
1445 for (i = 0; i < INTELRD_RETRY; i++) {
1446 if (IntelRDseed64(rnd) == 0)
1447 return 0;
1448 }
1449 return -1;
1450}
1451
1452#ifndef WOLFSSL_LINUXKM
1453/* return 0 on success */
1454static int wc_GenerateSeed_IntelRD(OS_Seed* os, byte* output, word32 sz)
1455{
1456 int ret;
1457 word64 rndTmp;
1458
1459 (void)os;
1460
1461 if (!IS_INTEL_RDSEED(intel_flags))
1462 return -1;
1463
1464 for (; (sz / sizeof(word64)) > 0; sz -= sizeof(word64),
1465 output += sizeof(word64)) {
1466 ret = IntelRDseed64_r((word64*)output);
1467 if (ret != 0)
1468 return ret;
1469 }
1470 if (sz == 0)
1471 return 0;
1472
1473 /* handle unaligned remainder */
1474 ret = IntelRDseed64_r(&rndTmp);
1475 if (ret != 0)
1476 return ret;
1477
1478 XMEMCPY(output, &rndTmp, sz);
1479 ForceZero(&rndTmp, sizeof(rndTmp));
1480
1481 return 0;
1482}
1483#endif
1484
1485#endif /* HAVE_INTEL_RDSEED */
1486
1487#ifdef HAVE_INTEL_RDRAND
1488
1489#ifndef USE_INTEL_INTRINSICS
1490
1491/* return 0 on success */
1492static WC_INLINE int IntelRDrand64(word64 *rnd)
1493{
1494 unsigned char ok;
1495
1496 __asm__ volatile("rdrand %0; setc %1":"=r"(*rnd), "=qm"(ok));
1497
1498 return (ok) ? 0 : -1;
1499}
1500
1501#else /* USE_INTEL_INTRINSICS */
1502 /* The compiler Visual Studio uses does not allow inline assembly.
1503 * It does allow for Intel intrinsic functions. */
1504
1505/* return 0 on success */
1506# ifdef __GNUC__
1507__attribute__((target("rdrnd")))
1508# endif
1509static WC_INLINE int IntelRDrand64(word64 *rnd)
1510{
1511 int ok;
1512
1513 ok = _rdrand64_step((unsigned long long*) rnd);
1514
1515 return (ok) ? 0 : -1;
1516}
1517
1518#endif /* USE_INTEL_INTRINSICS */
1519
1520/* return 0 on success */
1521static WC_INLINE int IntelRDrand64_r(word64 *rnd)
1522{
1523 int i;
1524 for (i = 0; i < INTELRD_RETRY; i++) {
1525 if (IntelRDrand64(rnd) == 0)
1526 return 0;
1527 }
1528 return -1;
1529}
1530
1531/* return 0 on success */
1532static int wc_GenerateRand_IntelRD(OS_Seed* os, byte* output, word32 sz)
1533{
1534 int ret;
1535 word64 rndTmp;
1536
1537 (void)os;
1538
1539 if (!IS_INTEL_RDRAND(intel_flags))
1540 return -1;
1541
1542 for (; (sz / sizeof(word64)) > 0; sz -= sizeof(word64),
1543 output += sizeof(word64)) {
1544 ret = IntelRDrand64_r((word64 *)output);
1545 if (ret != 0)
1546 return ret;
1547 }
1548 if (sz == 0)
1549 return 0;
1550
1551 /* handle unaligned remainder */
1552 ret = IntelRDrand64_r(&rndTmp);
1553 if (ret != 0)
1554 return ret;
1555
1556 XMEMCPY(output, &rndTmp, sz);
1557
1558 return 0;
1559}
1560
1561#endif /* HAVE_INTEL_RDRAND */
1562#endif /* HAVE_INTEL_RDRAND || HAVE_INTEL_RDSEED */
1563
1564
1565/* Begin wc_GenerateSeed Implementations */
1566#if defined(CUSTOM_RAND_GENERATE_SEED)
1567
1568 /* Implement your own random generation function
1569 * Return 0 to indicate success
1570 * int rand_gen_seed(byte* output, word32 sz);
1571 * #define CUSTOM_RAND_GENERATE_SEED rand_gen_seed */
1572
1573 int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
1574 {
1575 (void)os; /* Suppress unused arg warning */
1576 return CUSTOM_RAND_GENERATE_SEED(output, sz);
1577 }
1578
1579#elif defined(CUSTOM_RAND_GENERATE_SEED_OS)
1580
1581 /* Implement your own random generation function,
1582 * which includes OS_Seed.
1583 * Return 0 to indicate success
1584 * int rand_gen_seed(OS_Seed* os, byte* output, word32 sz);
1585 * #define CUSTOM_RAND_GENERATE_SEED_OS rand_gen_seed */
1586
1587 int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
1588 {
1589 return CUSTOM_RAND_GENERATE_SEED_OS(os, output, sz);
1590 }
1591
1592#elif defined(CUSTOM_RAND_GENERATE)
1593
1594 /* Implement your own random generation function
1595 * word32 rand_gen(void);
1596 * #define CUSTOM_RAND_GENERATE rand_gen */
1597
1598 int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
1599 {
1600 word32 i = 0;
1601
1602 (void)os;
1603
1604 while (i < sz)
1605 {
1606 /* If not aligned or there is odd/remainder */
1607 if( (i + sizeof(CUSTOM_RAND_TYPE)) > sz ||
1608 ((wolfssl_word)&output[i] % sizeof(CUSTOM_RAND_TYPE)) != 0
1609 ) {
1610 /* Single byte at a time */
1611 output[i++] = (byte)CUSTOM_RAND_GENERATE();
1612 }
1613 else {
1614 /* Use native 8, 16, 32 or 64 copy instruction */
1615 *((CUSTOM_RAND_TYPE*)&output[i]) = CUSTOM_RAND_GENERATE();
1616 i += sizeof(CUSTOM_RAND_TYPE);
1617 }
1618 }
1619
1620 return 0;
1621 }
1622
1623#elif defined(WOLFSSL_SGX)
1624
1625int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
1626{
1627 int ret = !SGX_SUCCESS;
1628 int i, read_max = 10;
1629
1630 for (i = 0; i < read_max && ret != SGX_SUCCESS; i++) {
1631 ret = sgx_read_rand(output, sz);
1632 }
1633
1634 (void)os;
1635 return (ret == SGX_SUCCESS) ? 0 : 1;
1636}
1637
1638#elif defined(USE_WINDOWS_API)
1639
1640int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
1641{
1642#ifdef WOLF_CRYPTO_CB
1643 int ret;
1644
1645 if (os != NULL && os->devId != INVALID_DEVID) {
1646 ret = wc_CryptoCb_RandomSeed(os, output, sz);
1647 if (ret != CRYPTOCB_UNAVAILABLE)
1648 return ret;
1649 /* fall-through when unavailable */
1650 }
1651#endif
1652
1653 #ifdef HAVE_INTEL_RDSEED
1654 if (IS_INTEL_RDSEED(intel_flags)) {
1655 if (!wc_GenerateSeed_IntelRD(NULL, output, sz)) {
1656 /* success, we're done */
1657 return 0;
1658 }
1659 #ifdef FORCE_FAILURE_RDSEED
1660 /* don't fall back to CryptoAPI */
1661 return READ_RAN_E;
1662 #endif
1663 }
1664 #endif /* HAVE_INTEL_RDSEED */
1665
1666 if(!CryptAcquireContext(&os->handle, 0, 0, PROV_RSA_FULL,
1667 CRYPT_VERIFYCONTEXT))
1668 return WINCRYPT_E;
1669
1670 if (!CryptGenRandom(os->handle, sz, output))
1671 return CRYPTGEN_E;
1672
1673 CryptReleaseContext(os->handle, 0);
1674
1675 return 0;
1676}
1677
1678
1679#elif defined(HAVE_RTP_SYS) || defined(EBSNET)
1680
1681#include "rtprand.h" /* rtp_rand () */
1682#include "rtptime.h" /* rtp_get_system_msec() */
1683
1684int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
1685{
1686 word32 i;
1687
1688 rtp_srand(rtp_get_system_msec());
1689 for (i = 0; i < sz; i++ ) {
1690 output[i] = rtp_rand() % 256;
1691 }
1692
1693 return 0;
1694}
1695
1696#elif (defined(WOLFSSL_ATMEL) || defined(WOLFSSL_ATECC_RNG)) && \
1697 !defined(WOLFSSL_PIC32MZ_RNG)
1698 /* enable ATECC RNG unless using PIC32MZ one instead */
1699 #include <wolfssl/wolfcrypt/port/atmel/atmel.h>
1700
1701 int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
1702 {
1703 int ret = 0;
1704
1705 (void)os;
1706 if (output == NULL) {
1707 return BUFFER_E;
1708 }
1709
1710 ret = atmel_get_random_number(sz, output);
1711
1712 return ret;
1713 }
1714
1715#elif defined(MICROCHIP_PIC32)
1716
1717 #ifdef MICROCHIP_MPLAB_HARMONY
1718 #ifdef MICROCHIP_MPLAB_HARMONY_3
1719 #include "system/time/sys_time.h"
1720 #define PIC32_SEED_COUNT SYS_TIME_CounterGet
1721 #else
1722 #define PIC32_SEED_COUNT _CP0_GET_COUNT
1723 #endif
1724 #else
1725 #if !defined(WOLFSSL_MICROCHIP_PIC32MZ)
1726 #include <peripheral/timer.h>
1727 #endif
1728 extern word32 ReadCoreTimer(void);
1729 #define PIC32_SEED_COUNT ReadCoreTimer
1730 #endif
1731
1732 #ifdef WOLFSSL_PIC32MZ_RNG
1733 #include "xc.h"
1734 int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
1735 {
1736 int i;
1737 byte rnd[8];
1738 word32 *rnd32 = (word32 *)rnd;
1739 word32 size = sz;
1740 byte* op = output;
1741
1742#if ((__PIC32_FEATURE_SET0 == 'E') && (__PIC32_FEATURE_SET1 == 'C'))
1743 RNGNUMGEN1 = _CP0_GET_COUNT();
1744 RNGPOLY1 = _CP0_GET_COUNT();
1745 RNGPOLY2 = _CP0_GET_COUNT();
1746 RNGNUMGEN2 = _CP0_GET_COUNT();
1747#else
1748 // All others can be seeded from the TRNG
1749 RNGCONbits.TRNGMODE = 1;
1750 RNGCONbits.TRNGEN = 1;
1751 while (RNGCNT < 64);
1752 RNGCONbits.LOAD = 1;
1753 while (RNGCONbits.LOAD == 1);
1754 while (RNGCNT < 64);
1755 RNGPOLY2 = RNGSEED2;
1756 RNGPOLY1 = RNGSEED1;
1757#endif
1758
1759 RNGCONbits.PLEN = 0x40;
1760 RNGCONbits.PRNGEN = 1;
1761 for (i=0; i<5; i++) { /* wait for RNGNUMGEN ready */
1762 volatile int x, y;
1763 x = RNGNUMGEN1;
1764 y = RNGNUMGEN2;
1765 (void)x;
1766 (void)y;
1767 }
1768 do {
1769 rnd32[0] = RNGNUMGEN1;
1770 rnd32[1] = RNGNUMGEN2;
1771
1772 for(i=0; i<8; i++, op++) {
1773 *op = rnd[i];
1774 size --;
1775 if(size==0)break;
1776 }
1777 } while(size);
1778 return 0;
1779 }
1780 #else /* WOLFSSL_PIC32MZ_RNG */
1781 /* uses the core timer, in nanoseconds to seed srand */
1782 int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
1783 {
1784 int i;
1785 srand(PIC32_SEED_COUNT() * 25);
1786
1787 for (i = 0; i < sz; i++ ) {
1788 output[i] = rand() % 256;
1789 if ( (i % 8) == 7)
1790 srand(PIC32_SEED_COUNT() * 25);
1791 }
1792 return 0;
1793 }
1794 #endif /* WOLFSSL_PIC32MZ_RNG */
1795
1796#elif defined(FREESCALE_MQX) || defined(FREESCALE_KSDK_MQX) || \
1797 defined(FREESCALE_KSDK_BM) || defined(FREESCALE_FREE_RTOS)
1798
1799 #if defined(FREESCALE_K70_RNGA) || defined(FREESCALE_RNGA)
1800 /*
1801 * wc_Generates a RNG seed using the Random Number Generator Accelerator
1802 * on the Kinetis K70. Documentation located in Chapter 37 of
1803 * K70 Sub-Family Reference Manual (see Note 3 in the README for link).
1804 */
1805 int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
1806 {
1807 word32 i;
1808
1809 /* turn on RNGA module */
1810 #if defined(SIM_SCGC3_RNGA_MASK)
1811 SIM_SCGC3 |= SIM_SCGC3_RNGA_MASK;
1812 #endif
1813 #if defined(SIM_SCGC6_RNGA_MASK)
1814 /* additionally needed for at least K64F */
1815 SIM_SCGC6 |= SIM_SCGC6_RNGA_MASK;
1816 #endif
1817
1818 /* set SLP bit to 0 - "RNGA is not in sleep mode" */
1819 RNG_CR &= ~RNG_CR_SLP_MASK;
1820
1821 /* set HA bit to 1 - "security violations masked" */
1822 RNG_CR |= RNG_CR_HA_MASK;
1823
1824 /* set GO bit to 1 - "output register loaded with data" */
1825 RNG_CR |= RNG_CR_GO_MASK;
1826
1827 for (i = 0; i < sz; i++) {
1828
1829 /* wait for RNG FIFO to be full */
1830 while((RNG_SR & RNG_SR_OREG_LVL(0xF)) == 0) {}
1831
1832 /* get value */
1833 output[i] = RNG_OR;
1834 }
1835
1836 return 0;
1837 }
1838
1839 #elif defined(FREESCALE_K53_RNGB) || defined(FREESCALE_RNGB)
1840 /*
1841 * wc_Generates a RNG seed using the Random Number Generator (RNGB)
1842 * on the Kinetis K53. Documentation located in Chapter 33 of
1843 * K53 Sub-Family Reference Manual (see note in the README for link).
1844 */
1845 int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
1846 {
1847 int i;
1848
1849 /* turn on RNGB module */
1850 SIM_SCGC3 |= SIM_SCGC3_RNGB_MASK;
1851
1852 /* reset RNGB */
1853 RNG_CMD |= RNG_CMD_SR_MASK;
1854
1855 /* FIFO generate interrupt, return all zeros on underflow,
1856 * set auto reseed */
1857 RNG_CR |= (RNG_CR_FUFMOD_MASK | RNG_CR_AR_MASK);
1858
1859 /* gen seed, clear interrupts, clear errors */
1860 RNG_CMD |= (RNG_CMD_GS_MASK | RNG_CMD_CI_MASK | RNG_CMD_CE_MASK);
1861
1862 /* wait for seeding to complete */
1863 while ((RNG_SR & RNG_SR_SDN_MASK) == 0) {}
1864
1865 for (i = 0; i < sz; i++) {
1866
1867 /* wait for a word to be available from FIFO */
1868 while((RNG_SR & RNG_SR_FIFO_LVL_MASK) == 0) {}
1869
1870 /* get value */
1871 output[i] = RNG_OUT;
1872 }
1873
1874 return 0;
1875 }
1876
1877 #elif defined(FREESCALE_KSDK_2_0_TRNG)
1878
1879 int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
1880 {
1881 status_t status;
1882 status = TRNG_GetRandomData(TRNG0, output, sz);
1883 if (status == kStatus_Success)
1884 {
1885 return(0);
1886 }
1887 else
1888 {
1889 return RAN_BLOCK_E;
1890 }
1891 }
1892
1893 #elif defined(FREESCALE_KSDK_2_0_RNGA)
1894
1895 int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
1896 {
1897 status_t status;
1898 status = RNGA_GetRandomData(RNG, output, sz);
1899 if (status == kStatus_Success)
1900 {
1901 return(0);
1902 }
1903 else
1904 {
1905 return RAN_BLOCK_E;
1906 }
1907 }
1908
1909
1910 #elif defined(FREESCALE_RNGA)
1911
1912 int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
1913 {
1914 RNGA_DRV_GetRandomData(RNGA_INSTANCE, output, sz);
1915 return 0;
1916 }
1917
1918 #else
1919 #define USE_TEST_GENSEED
1920 #endif /* FREESCALE_K70_RNGA */
1921
1922#elif defined(WOLFSSL_SILABS_SE_ACCEL)
1923 int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
1924 {
1925 (void)os;
1926 return silabs_GenerateRand(output, sz);
1927 }
1928
1929#elif defined(STM32_RNG)
1930 /* Generate a RNG seed using the hardware random number generator
1931 * on the STM32F2/F4/F7/L4. */
1932
1933 #ifdef WOLFSSL_STM32_CUBEMX
1934 int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
1935 {
1936 int ret;
1937 RNG_HandleTypeDef hrng;
1938 word32 i = 0;
1939 (void)os;
1940
1941 ret = wolfSSL_CryptHwMutexLock();
1942 if (ret != 0) {
1943 return ret;
1944 }
1945
1946 /* enable RNG clock source */
1947 __HAL_RCC_RNG_CLK_ENABLE();
1948
1949 /* enable RNG peripheral */
1950 XMEMSET(&hrng, 0, sizeof(hrng));
1951 hrng.Instance = RNG;
1952 HAL_RNG_Init(&hrng);
1953
1954 while (i < sz) {
1955 /* If not aligned or there is odd/remainder */
1956 if( (i + sizeof(word32)) > sz ||
1957 ((wolfssl_word)&output[i] % sizeof(word32)) != 0
1958 ) {
1959 /* Single byte at a time */
1960 word32 tmpRng = 0;
1961 if (HAL_RNG_GenerateRandomNumber(&hrng, &tmpRng) != HAL_OK) {
1962 wolfSSL_CryptHwMutexUnLock();
1963 return RAN_BLOCK_E;
1964 }
1965 output[i++] = (byte)tmpRng;
1966 }
1967 else {
1968 /* Use native 32 instruction */
1969 if (HAL_RNG_GenerateRandomNumber(&hrng, (word32*)&output[i]) != HAL_OK) {
1970 wolfSSL_CryptHwMutexUnLock();
1971 return RAN_BLOCK_E;
1972 }
1973 i += sizeof(word32);
1974 }
1975 }
1976
1977 wolfSSL_CryptHwMutexUnLock();
1978
1979 return 0;
1980 }
1981 #elif defined(WOLFSSL_STM32F427_RNG) || defined(WOLFSSL_STM32_RNG_NOLIB)
1982
1983 /* Generate a RNG seed using the hardware RNG on the STM32F427
1984 * directly, following steps outlined in STM32F4 Reference
1985 * Manual (Chapter 24) for STM32F4xx family. */
1986 int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
1987 {
1988 int ret;
1989 word32 i;
1990 (void)os;
1991
1992 ret = wolfSSL_CryptHwMutexLock();
1993 if (ret != 0) {
1994 return ret;
1995 }
1996
1997 /* enable RNG peripheral clock */
1998 RCC->AHB2ENR |= RCC_AHB2ENR_RNGEN;
1999
2000 /* enable RNG interrupt, set IE bit in RNG->CR register */
2001 RNG->CR |= RNG_CR_IE;
2002
2003 /* enable RNG, set RNGEN bit in RNG->CR. Activates RNG,
2004 * RNG_LFSR, and error detector */
2005 RNG->CR |= RNG_CR_RNGEN;
2006
2007 /* verify no errors, make sure SEIS and CEIS bits are 0
2008 * in RNG->SR register */
2009 if (RNG->SR & (RNG_SR_SECS | RNG_SR_CECS)) {
2010 wolfSSL_CryptHwMutexUnLock();
2011 return RNG_FAILURE_E;
2012 }
2013
2014 for (i = 0; i < sz; i++) {
2015 /* wait until RNG number is ready */
2016 while ((RNG->SR & RNG_SR_DRDY) == 0) { }
2017
2018 /* get value */
2019 output[i] = RNG->DR;
2020 }
2021
2022 wolfSSL_CryptHwMutexUnLock();
2023
2024 return 0;
2025 }
2026
2027 #else
2028
2029 /* Generate a RNG seed using the STM32 Standard Peripheral Library */
2030 int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
2031 {
2032 int ret;
2033 word32 i;
2034 (void)os;
2035
2036 ret = wolfSSL_CryptHwMutexLock();
2037 if (ret != 0) {
2038 return ret;
2039 }
2040
2041 /* enable RNG clock source */
2042 RCC_AHB2PeriphClockCmd(RCC_AHB2Periph_RNG, ENABLE);
2043
2044 /* reset RNG */
2045 RNG_DeInit();
2046
2047 /* enable RNG peripheral */
2048 RNG_Cmd(ENABLE);
2049
2050 /* verify no errors with RNG_CLK or Seed */
2051 if (RNG_GetFlagStatus(RNG_FLAG_SECS | RNG_FLAG_CECS) != RESET) {
2052 wolfSSL_CryptHwMutexUnLock();
2053 return RNG_FAILURE_E;
2054 }
2055
2056 for (i = 0; i < sz; i++) {
2057 /* wait until RNG number is ready */
2058 while (RNG_GetFlagStatus(RNG_FLAG_DRDY) == RESET) { }
2059
2060 /* get value */
2061 output[i] = RNG_GetRandomNumber();
2062 }
2063
2064 wolfSSL_CryptHwMutexUnLock();
2065
2066 return 0;
2067 }
2068 #endif /* WOLFSSL_STM32_CUBEMX */
2069
2070#elif defined(WOLFSSL_TIRTOS)
2071
2072 #include <xdc/runtime/Timestamp.h>
2073 #include <stdlib.h>
2074 int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
2075 {
2076 int i;
2077 srand(xdc_runtime_Timestamp_get32());
2078
2079 for (i = 0; i < sz; i++ ) {
2080 output[i] = rand() % 256;
2081 if ((i % 8) == 7) {
2082 srand(xdc_runtime_Timestamp_get32());
2083 }
2084 }
2085
2086 return 0;
2087 }
2088
2089#elif defined(WOLFSSL_PB)
2090
2091 int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
2092 {
2093 word32 i;
2094 for (i = 0; i < sz; i++)
2095 output[i] = UTL_Rand();
2096
2097 (void)os;
2098
2099 return 0;
2100 }
2101
2102#elif defined(WOLFSSL_NUCLEUS)
2103#include "nucleus.h"
2104#include "kernel/plus_common.h"
2105
2106#warning "potential for not enough entropy, currently being used for testing"
2107int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
2108{
2109 int i;
2110 srand(NU_Get_Time_Stamp());
2111
2112 for (i = 0; i < sz; i++ ) {
2113 output[i] = rand() % 256;
2114 if ((i % 8) == 7) {
2115 srand(NU_Get_Time_Stamp());
2116 }
2117 }
2118
2119 return 0;
2120}
2121#elif defined(WOLFSSL_DEOS) && !defined(CUSTOM_RAND_GENERATE)
2122 #include "stdlib.h"
2123
2124 #warning "potential for not enough entropy, currently being used for testing Deos"
2125 int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
2126 {
2127 int i;
2128 int seed = XTIME(0);
2129 (void)os;
2130
2131 for (i = 0; i < sz; i++ ) {
2132 output[i] = rand_r(&seed) % 256;
2133 if ((i % 8) == 7) {
2134 seed = XTIME(0);
2135 rand_r(&seed);
2136 }
2137 }
2138
2139 return 0;
2140 }
2141#elif defined(WOLFSSL_VXWORKS)
2142
2143 #include <randomNumGen.h>
2144
2145 int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz) {
2146 STATUS status;
2147
2148 #ifdef VXWORKS_SIM
2149 /* cannot generate true entropy with VxWorks simulator */
2150 #warning "not enough entropy, simulator for testing only"
2151 int i = 0;
2152
2153 for (i = 0; i < 1000; i++) {
2154 randomAddTimeStamp();
2155 }
2156 #endif
2157
2158 status = randBytes (output, sz);
2159 if (status == ERROR) {
2160 return RNG_FAILURE_E;
2161 }
2162
2163 return 0;
2164 }
2165
2166#elif defined(WOLFSSL_NRF51) || defined(WOLFSSL_NRF5x)
2167 #include "app_error.h"
2168 #include "nrf_drv_rng.h"
2169 int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
2170 {
2171 int remaining = sz, length, pos = 0;
2172 word32 err_code;
2173 byte available;
2174 static byte initialized = 0;
2175
2176 (void)os;
2177
2178 /* Make sure RNG is running */
2179 if (!initialized) {
2180 err_code = nrf_drv_rng_init(NULL);
2181 if (err_code != NRF_SUCCESS && err_code != NRF_ERROR_INVALID_STATE
2182 #ifdef NRF_ERROR_MODULE_ALREADY_INITIALIZED
2183 && err_code != NRF_ERROR_MODULE_ALREADY_INITIALIZED
2184 #endif
2185 ) {
2186 return -1;
2187 }
2188 initialized = 1;
2189 }
2190
2191 while (remaining > 0) {
2192 available = 0;
2193 nrf_drv_rng_bytes_available(&available); /* void func */
2194 length = (remaining < available) ? remaining : available;
2195 if (length > 0) {
2196 err_code = nrf_drv_rng_rand(&output[pos], length);
2197 if (err_code != NRF_SUCCESS) {
2198 break;
2199 }
2200 remaining -= length;
2201 pos += length;
2202 }
2203 }
2204
2205 return (err_code == NRF_SUCCESS) ? 0 : -1;
2206 }
2207
2208#elif defined(HAVE_WNR)
2209
2210 int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
2211 {
2212 if (os == NULL || output == NULL || wnr_ctx == NULL ||
2213 wnr_timeout < 0) {
2214 return BAD_FUNC_ARG;
2215 }
2216
2217 if (wnr_mutex_init == 0) {
2218 WOLFSSL_MSG("netRandom context must be created before use");
2219 return RNG_FAILURE_E;
2220 }
2221
2222 if (wc_LockMutex(&wnr_mutex) != 0) {
2223 WOLFSSL_MSG("Bad Lock Mutex wnr_mutex\n");
2224 return BAD_MUTEX_E;
2225 }
2226
2227 if (wnr_get_entropy(wnr_ctx, wnr_timeout, output, sz, sz) !=
2228 WNR_ERROR_NONE)
2229 return RNG_FAILURE_E;
2230
2231 wc_UnLockMutex(&wnr_mutex);
2232
2233 return 0;
2234 }
2235
2236#elif defined(INTIME_RTOS)
2237 int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
2238 {
2239 int ret = 0;
2240
2241 (void)os;
2242
2243 if (output == NULL) {
2244 return BUFFER_E;
2245 }
2246
2247 /* Note: Investigate better solution */
2248 /* no return to check */
2249 arc4random_buf(output, sz);
2250
2251 return ret;
2252 }
2253
2254#elif defined(WOLFSSL_WICED)
2255 int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
2256 {
2257 int ret;
2258 (void)os;
2259
2260 if (output == NULL || UINT16_MAX < sz) {
2261 return BUFFER_E;
2262 }
2263
2264 if ((ret = wiced_crypto_get_random((void*) output, sz) )
2265 != WICED_SUCCESS) {
2266 return ret;
2267 }
2268
2269 return ret;
2270 }
2271
2272#elif defined(WOLFSSL_NETBURNER)
2273 #warning using NetBurner pseudo random GetRandomByte for seed
2274 int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
2275 {
2276 word32 i;
2277 (void)os;
2278
2279 if (output == NULL) {
2280 return BUFFER_E;
2281 }
2282
2283 for (i = 0; i < sz; i++) {
2284 output[i] = GetRandomByte();
2285
2286 /* check if was a valid random number */
2287 if (!RandomValid())
2288 return RNG_FAILURE_E;
2289 }
2290
2291 return 0;
2292 }
2293#elif defined(IDIRECT_DEV_RANDOM)
2294
2295 extern int getRandom( int sz, unsigned char *output );
2296
2297 int GenerateSeed(OS_Seed* os, byte* output, word32 sz)
2298 {
2299 int num_bytes_returned = 0;
2300
2301 num_bytes_returned = getRandom( (int) sz, (unsigned char *) output );
2302
2303 return 0;
2304 }
2305
2306#elif (defined(WOLFSSL_IMX6_CAAM) || defined(WOLFSSL_IMX6_CAAM_RNG))
2307
2308 #include <wolfssl/wolfcrypt/port/caam/wolfcaam.h>
2309 #include <wolfssl/wolfcrypt/port/caam/caam_driver.h>
2310
2311 int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
2312 {
2313 Buffer buf[1];
2314 int ret = 0;
2315 int times = 1000, i;
2316
2317 (void)os;
2318
2319 if (output == NULL) {
2320 return BUFFER_E;
2321 }
2322
2323 buf[0].BufferType = DataBuffer | LastBuffer;
2324 buf[0].TheAddress = (Address)output;
2325 buf[0].Length = sz;
2326
2327 /* Check Waiting to make sure entropy is ready */
2328 for (i = 0; i < times; i++) {
2329 ret = wc_caamAddAndWait(buf, NULL, CAAM_ENTROPY);
2330 if (ret == Success) {
2331 break;
2332 }
2333
2334 /* driver could be waiting for entropy */
2335 if (ret != RAN_BLOCK_E) {
2336 return ret;
2337 }
2338 usleep(100);
2339 }
2340
2341 if (i == times && ret != Success) {
2342 return RNG_FAILURE_E;
2343 }
2344 else { /* Success case */
2345 ret = 0;
2346 }
2347
2348 return ret;
2349 }
2350
2351#elif defined(WOLFSSL_APACHE_MYNEWT)
2352
2353 #include <stdlib.h>
2354 #include "os/os_time.h"
2355 int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
2356 {
2357 int i;
2358 srand(os_time_get());
2359
2360 for (i = 0; i < sz; i++ ) {
2361 output[i] = rand() % 256;
2362 if ((i % 8) == 7) {
2363 srand(os_time_get());
2364 }
2365 }
2366
2367 return 0;
2368 }
2369
2370#elif defined(WOLFSSL_ESPIDF)
2371 #if defined(WOLFSSL_ESPWROOM32) || defined(WOLFSSL_ESPWROOM32SE)
2372 #include <esp_system.h>
2373
2374 int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
2375 {
2376 word32 rand;
2377 while (sz > 0) {
2378 word32 len = sizeof(rand);
2379 if (sz < len)
2380 len = sz;
2381 /* Get one random 32-bit word from hw RNG */
2382 rand = esp_random( );
2383 XMEMCPY(output, &rand, len);
2384 output += len;
2385 sz -= len;
2386 }
2387
2388 return 0;
2389 }
2390 #endif /* end WOLFSSL_ESPWROOM32 */
2391
2392#elif defined(WOLFSSL_LINUXKM)
2393 #include <linux/random.h>
2394 int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
2395 {
2396 (void)os;
2397
2398 get_random_bytes(output, sz);
2399
2400 return 0;
2401 }
2402
2403#elif defined(WOLFSSL_RENESAS_TSIP)
2404#if defined(WOLFSSL_RENESA_TSIP_IAREWRX)
2405 #include "r_bsp/mcu/all/r_rx_compiler.h"
2406#endif
2407 #include "r_bsp/platform.h"
2408 #include "r_tsip_rx_if.h"
2409
2410 int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
2411 {
2412 int ret;
2413 word32 buffer[4];
2414
2415 while (sz > 0) {
2416 word32 len = sizeof(buffer);
2417
2418 if (sz < len) {
2419 len = sz;
2420 }
2421 /* return 4 words random number*/
2422 ret = R_TSIP_GenerateRandomNumber(buffer);
2423 if(ret == TSIP_SUCCESS) {
2424 XMEMCPY(output, &buffer, len);
2425 output += len;
2426 sz -= len;
2427 } else
2428 return ret;
2429 }
2430 return ret;
2431 }
2432
2433#elif defined(WOLFSSL_SCE) && !defined(WOLFSSL_SCE_NO_TRNG)
2434 #include "hal_data.h"
2435
2436 #ifndef WOLFSSL_SCE_TRNG_HANDLE
2437 #define WOLFSSL_SCE_TRNG_HANDLE g_sce_trng
2438 #endif
2439
2440 int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
2441 {
2442 word32 ret;
2443 word32 blocks;
2444 word32 len = sz;
2445
2446 ret = WOLFSSL_SCE_TRNG_HANDLE.p_api->open(WOLFSSL_SCE_TRNG_HANDLE.p_ctrl,
2447 WOLFSSL_SCE_TRNG_HANDLE.p_cfg);
2448 if (ret != SSP_SUCCESS && ret != SSP_ERR_CRYPTO_ALREADY_OPEN) {
2449 /* error opening TRNG driver */
2450 return -1;
2451 }
2452
2453 blocks = sz / sizeof(word32);
2454 if (blocks > 0) {
2455 ret = WOLFSSL_SCE_TRNG_HANDLE.p_api->read(WOLFSSL_SCE_TRNG_HANDLE.p_ctrl,
2456 (word32*)output, blocks);
2457 if (ret != SSP_SUCCESS) {
2458 return -1;
2459 }
2460 }
2461
2462 len = len - (blocks * sizeof(word32));
2463 if (len > 0) {
2464 word32 tmp;
2465
2466 if (len > sizeof(word32)) {
2467 return -1;
2468 }
2469 ret = WOLFSSL_SCE_TRNG_HANDLE.p_api->read(WOLFSSL_SCE_TRNG_HANDLE.p_ctrl,
2470 (word32*)tmp, 1);
2471 if (ret != SSP_SUCCESS) {
2472 return -1;
2473 }
2474 XMEMCPY(output + (blocks * sizeof(word32)), (byte*)&tmp, len);
2475 }
2476
2477 ret = WOLFSSL_SCE_TRNG_HANDLE.p_api->close(WOLFSSL_SCE_TRNG_HANDLE.p_ctrl);
2478 if (ret != SSP_SUCCESS) {
2479 /* error opening TRNG driver */
2480 return -1;
2481 }
2482 return 0;
2483 }
2484#elif defined(CUSTOM_RAND_GENERATE_BLOCK)
2485 /* #define CUSTOM_RAND_GENERATE_BLOCK myRngFunc
2486 * extern int myRngFunc(byte* output, word32 sz);
2487 */
2488
2489#elif defined(WOLFSSL_SAFERTOS) || defined(WOLFSSL_LEANPSK) || \
2490 defined(WOLFSSL_IAR_ARM) || defined(WOLFSSL_MDK_ARM) || \
2491 defined(WOLFSSL_uITRON4) || defined(WOLFSSL_uTKERNEL2) || \
2492 defined(WOLFSSL_LPC43xx) || defined(WOLFSSL_STM32F2xx) || \
2493 defined(MBED) || defined(WOLFSSL_EMBOS) || \
2494 defined(WOLFSSL_GENSEED_FORTEST) || defined(WOLFSSL_CHIBIOS) || \
2495 defined(WOLFSSL_CONTIKI) || defined(WOLFSSL_AZSPHERE)
2496
2497 /* these platforms do not have a default random seed and
2498 you'll need to implement your own wc_GenerateSeed or define via
2499 CUSTOM_RAND_GENERATE_BLOCK */
2500
2501 #define USE_TEST_GENSEED
2502
2503#elif defined(WOLFSSL_ZEPHYR)
2504
2505 #include <entropy.h>
2506 #ifndef _POSIX_C_SOURCE
2507 #include <posix/time.h>
2508 #else
2509 #include <sys/time.h>
2510 #endif
2511
2512 int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
2513 {
2514 int ret = 0;
2515 word32 rand;
2516 while (sz > 0) {
2517 word32 len = sizeof(rand);
2518 if (sz < len)
2519 len = sz;
2520 rand = sys_rand32_get();
2521 XMEMCPY(output, &rand, len);
2522 output += len;
2523 sz -= len;
2524 }
2525
2526 return ret;
2527 }
2528
2529#elif defined(WOLFSSL_TELIT_M2MB)
2530
2531 #include "stdlib.h"
2532 static long get_timestamp(void) {
2533 long myTime = 0;
2534 INT32 fd = m2mb_rtc_open("/dev/rtc0", 0);
2535 if (fd >= 0) {
2536 M2MB_RTC_TIMEVAL_T timeval;
2537 m2mb_rtc_ioctl(fd, M2MB_RTC_IOCTL_GET_TIMEVAL, &timeval);
2538 myTime = timeval.msec;
2539 m2mb_rtc_close(fd);
2540 }
2541 return myTime;
2542 }
2543 int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
2544 {
2545 int i;
2546 srand(get_timestamp());
2547 for (i = 0; i < sz; i++ ) {
2548 output[i] = rand() % 256;
2549 if ((i % 8) == 7) {
2550 srand(get_timestamp());
2551 }
2552 }
2553 return 0;
2554 }
2555
2556#elif defined(NO_DEV_RANDOM)
2557
2558 #error "you need to write an os specific wc_GenerateSeed() here"
2559
2560 /*
2561 int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
2562 {
2563 return 0;
2564 }
2565 */
2566
2567#else
2568
2569 /* may block */
2570 int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
2571 {
2572 int ret = 0;
2573
2574 if (os == NULL) {
2575 return BAD_FUNC_ARG;
2576 }
2577
2578 #ifdef WOLF_CRYPTO_CB
2579 if (os->devId != INVALID_DEVID) {
2580 ret = wc_CryptoCb_RandomSeed(os, output, sz);
2581 if (ret != CRYPTOCB_UNAVAILABLE)
2582 return ret;
2583 /* fall-through when unavailable */
2584 ret = 0; /* reset error code */
2585 }
2586 #endif
2587
2588 #ifdef HAVE_INTEL_RDSEED
2589 if (IS_INTEL_RDSEED(intel_flags)) {
2590 ret = wc_GenerateSeed_IntelRD(NULL, output, sz);
2591 if (ret == 0) {
2592 /* success, we're done */
2593 return ret;
2594 }
2595 #ifdef FORCE_FAILURE_RDSEED
2596 /* don't fallback to /dev/urandom */
2597 return ret;
2598 #else
2599 /* reset error and fallback to using /dev/urandom */
2600 ret = 0;
2601 #endif
2602 }
2603 #endif /* HAVE_INTEL_RDSEED */
2604
2605 #ifndef NO_DEV_URANDOM /* way to disable use of /dev/urandom */
2606 os->fd = open("/dev/urandom", O_RDONLY);
2607 if (os->fd == -1)
2608 #endif
2609 {
2610 /* may still have /dev/random */
2611 os->fd = open("/dev/random", O_RDONLY);
2612 if (os->fd == -1)
2613 return OPEN_RAN_E;
2614 }
2615
2616 while (sz) {
2617 int len = (int)read(os->fd, output, sz);
2618 if (len == -1) {
2619 ret = READ_RAN_E;
2620 break;
2621 }
2622
2623 sz -= len;
2624 output += len;
2625
2626 if (sz) {
2627 #if defined(BLOCKING) || defined(WC_RNG_BLOCKING)
2628 sleep(0); /* context switch */
2629 #else
2630 ret = RAN_BLOCK_E;
2631 break;
2632 #endif
2633 }
2634 }
2635 close(os->fd);
2636
2637 return ret;
2638 }
2639
2640#endif
2641
2642#ifdef USE_TEST_GENSEED
2643 #ifndef _MSC_VER
2644 #warning "write a real random seed!!!!, just for testing now"
2645 #else
2646 #pragma message("Warning: write a real random seed!!!!, just for testing now")
2647 #endif
2648 int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
2649 {
2650 word32 i;
2651 for (i = 0; i < sz; i++ )
2652 output[i] = i;
2653
2654 (void)os;
2655
2656 return 0;
2657 }
2658#endif
2659
2660
2661/* End wc_GenerateSeed */
2662#endif /* WC_NO_RNG */
2663#endif /* HAVE_FIPS */
Note: See TracBrowser for help on using the repository browser.