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