source: azure_iot_hub_f767zi/trunk/wolfssl-4.4.0/wolfcrypt/src/random.c@ 457

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

ファイルを追加

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