source: asp3_tinet_ecnl_arm/trunk/wolfssl-3.12.2/wolfcrypt/src/random.c@ 352

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

arm向けASP3版ECNLを追加

  • Property svn:eol-style set to native
  • Property svn:mime-type set to text/x-csrc;charset=UTF-8
File size: 45.6 KB
Line 
1/* random.c
2 *
3 * Copyright (C) 2006-2017 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
29/* on HPUX 11 you may need to install /dev/random see
30 http://h20293.www2.hp.com/portal/swdepot/displayProductInfo.do?productNumber=KRNG11I
31
32*/
33
34#include <wolfssl/wolfcrypt/random.h>
35#include <wolfssl/wolfcrypt/cpuid.h>
36
37
38#ifdef HAVE_FIPS
39int wc_GenerateSeed(OS_Seed* os, byte* seed, word32 sz)
40{
41 return GenerateSeed(os, seed, sz);
42}
43
44int wc_InitRng_ex(WC_RNG* rng, void* heap, int devId)
45{
46 (void)heap;
47 (void)devId;
48 return InitRng_fips(rng);
49}
50
51int wc_InitRng(WC_RNG* rng)
52{
53 return InitRng_fips(rng);
54}
55
56
57int wc_RNG_GenerateBlock(WC_RNG* rng, byte* b, word32 sz)
58{
59 return RNG_GenerateBlock_fips(rng, b, sz);
60}
61
62
63int wc_RNG_GenerateByte(WC_RNG* rng, byte* b)
64{
65 return RNG_GenerateByte(rng, b);
66}
67
68#ifdef HAVE_HASHDRBG
69
70 int wc_FreeRng(WC_RNG* rng)
71 {
72 return FreeRng_fips(rng);
73 }
74
75 int wc_RNG_HealthTest(int reseed,
76 const byte* entropyA, word32 entropyASz,
77 const byte* entropyB, word32 entropyBSz,
78 byte* output, word32 outputSz)
79 {
80 return RNG_HealthTest_fips(reseed, entropyA, entropyASz,
81 entropyB, entropyBSz, output, outputSz);
82 }
83#endif /* HAVE_HASHDRBG */
84
85#else /* else build without fips */
86
87#ifndef WC_NO_RNG /* if not FIPS and RNG is disabled then do not compile */
88
89#include <wolfssl/wolfcrypt/error-crypt.h>
90#include <wolfssl/wolfcrypt/sha256.h>
91
92#ifdef NO_INLINE
93 #include <wolfssl/wolfcrypt/misc.h>
94#else
95 #define WOLFSSL_MISC_INCLUDED
96 #include <wolfcrypt/src/misc.c>
97#endif
98
99#if defined(WOLFSSL_SGX)
100 #include <sgx_trts.h>
101#elif defined(USE_WINDOWS_API)
102 #ifndef _WIN32_WINNT
103 #define _WIN32_WINNT 0x0400
104 #endif
105 #include <windows.h>
106 #include <wincrypt.h>
107#elif defined(HAVE_WNR)
108 #include <wnr.h>
109 #include <wolfssl/wolfcrypt/logging.h>
110 wolfSSL_Mutex wnr_mutex; /* global netRandom mutex */
111 int wnr_timeout = 0; /* entropy timeout, mililseconds */
112 int wnr_mutex_init = 0; /* flag for mutex init */
113 wnr_context* wnr_ctx; /* global netRandom context */
114#elif defined(FREESCALE_KSDK_2_0_TRNG)
115 #include "fsl_trng.h"
116#elif defined(FREESCALE_KSDK_2_0_RNGA)
117 #include "fsl_rnga.h"
118
119#elif defined(NO_DEV_RANDOM)
120#elif defined(CUSTOM_RAND_GENERATE)
121#elif defined(CUSTOM_RAND_GENERATE_BLOCK)
122#elif defined(CUSTOM_RAND_GENERATE_SEED)
123#elif defined(WOLFSSL_GENSEED_FORTEST)
124#elif defined(WOLFSSL_MDK_ARM)
125#elif defined(WOLFSSL_IAR_ARM)
126#elif defined(WOLFSSL_ROWLEY_ARM)
127#elif defined(WOLFSSL_EMBOS)
128#elif defined(MICRIUM)
129#else
130 /* include headers that may be needed to get good seed */
131 #include <fcntl.h>
132 #ifndef EBSNET
133 #include <unistd.h>
134 #endif
135#endif
136
137
138#if defined(HAVE_INTEL_RDRAND) || defined(HAVE_INTEL_RDSEED)
139 static word32 intel_flags = 0;
140 static void wc_InitRng_IntelRD(void)
141 {
142 intel_flags = cpuid_get_flags();
143 }
144 #ifdef HAVE_INTEL_RDSEED
145 static int wc_GenerateSeed_IntelRD(OS_Seed* os, byte* output, word32 sz);
146 #endif
147 #ifdef HAVE_INTEL_RDRAND
148 static int wc_GenerateRand_IntelRD(OS_Seed* os, byte* output, word32 sz);
149 #endif
150#endif
151
152/* Start NIST DRBG code */
153#ifdef HAVE_HASHDRBG
154
155#define OUTPUT_BLOCK_LEN (WC_SHA256_DIGEST_SIZE)
156#define MAX_REQUEST_LEN (0x10000)
157#define RESEED_INTERVAL WC_RESEED_INTERVAL
158#define SECURITY_STRENGTH (256)
159#define ENTROPY_SZ (SECURITY_STRENGTH/8)
160#define NONCE_SZ (ENTROPY_SZ/2)
161#define ENTROPY_NONCE_SZ (ENTROPY_SZ+NONCE_SZ)
162
163/* Internal return codes */
164#define DRBG_SUCCESS 0
165#define DRBG_ERROR 1
166#define DRBG_FAILURE 2
167#define DRBG_NEED_RESEED 3
168#define DRBG_CONT_FAILURE 4
169
170/* RNG health states */
171#define DRBG_NOT_INIT 0
172#define DRBG_OK 1
173#define DRBG_FAILED 2
174#define DRBG_CONT_FAILED 3
175
176#define RNG_HEALTH_TEST_CHECK_SIZE (WC_SHA256_DIGEST_SIZE * 4)
177
178/* Verify max gen block len */
179#if RNG_MAX_BLOCK_LEN > MAX_REQUEST_LEN
180 #error RNG_MAX_BLOCK_LEN is larger than NIST DBRG max request length
181#endif
182
183enum {
184 drbgInitC = 0,
185 drbgReseed = 1,
186 drbgGenerateW = 2,
187 drbgGenerateH = 3,
188 drbgInitV
189};
190
191
192typedef struct DRBG {
193 word32 reseedCtr;
194 word32 lastBlock;
195 byte V[DRBG_SEED_LEN];
196 byte C[DRBG_SEED_LEN];
197#ifdef WOLFSSL_ASYNC_CRYPT
198 void* heap;
199 int devId;
200#endif
201 byte matchCount;
202} DRBG;
203
204
205static int wc_RNG_HealthTestLocal(int reseed);
206
207/* Hash Derivation Function */
208/* Returns: DRBG_SUCCESS or DRBG_FAILURE */
209static int Hash_df(DRBG* drbg, byte* out, word32 outSz, byte type,
210 const byte* inA, word32 inASz,
211 const byte* inB, word32 inBSz)
212{
213 int ret = DRBG_FAILURE;
214 byte ctr;
215 int i;
216 int len;
217 word32 bits = (outSz * 8); /* reverse byte order */
218 wc_Sha256 sha;
219 DECLARE_VAR(digest, byte, WC_SHA256_DIGEST_SIZE, drbg->heap);
220
221 (void)drbg;
222#ifdef WOLFSSL_ASYNC_CRYPT
223 if (digest == NULL)
224 return DRBG_FAILURE;
225#endif
226
227#ifdef LITTLE_ENDIAN_ORDER
228 bits = ByteReverseWord32(bits);
229#endif
230 len = (outSz / OUTPUT_BLOCK_LEN)
231 + ((outSz % OUTPUT_BLOCK_LEN) ? 1 : 0);
232
233 for (i = 0, ctr = 1; i < len; i++, ctr++) {
234 #ifdef WOLFSSL_ASYNC_CRYPT
235 ret = wc_InitSha256_ex(&sha, drbg->heap, drbg->devId);
236 #else
237 ret = wc_InitSha256(&sha);
238 #endif
239 if (ret != 0)
240 break;
241
242 if (ret == 0)
243 ret = wc_Sha256Update(&sha, &ctr, sizeof(ctr));
244 if (ret == 0)
245 ret = wc_Sha256Update(&sha, (byte*)&bits, sizeof(bits));
246
247 if (ret == 0) {
248 /* churning V is the only string that doesn't have the type added */
249 if (type != drbgInitV)
250 ret = wc_Sha256Update(&sha, &type, sizeof(type));
251 }
252 if (ret == 0)
253 ret = wc_Sha256Update(&sha, inA, inASz);
254 if (ret == 0) {
255 if (inB != NULL && inBSz > 0)
256 ret = wc_Sha256Update(&sha, inB, inBSz);
257 }
258 if (ret == 0)
259 ret = wc_Sha256Final(&sha, digest);
260
261 wc_Sha256Free(&sha);
262 if (ret == 0) {
263 if (outSz > OUTPUT_BLOCK_LEN) {
264 XMEMCPY(out, digest, OUTPUT_BLOCK_LEN);
265 outSz -= OUTPUT_BLOCK_LEN;
266 out += OUTPUT_BLOCK_LEN;
267 }
268 else {
269 XMEMCPY(out, digest, outSz);
270 }
271 }
272 }
273
274 ForceZero(digest, WC_SHA256_DIGEST_SIZE);
275
276 FREE_VAR(digest, drbg->heap);
277
278 return (ret == 0) ? DRBG_SUCCESS : DRBG_FAILURE;
279}
280
281/* Returns: DRBG_SUCCESS or DRBG_FAILURE */
282static int Hash_DRBG_Reseed(DRBG* drbg, const byte* entropy, word32 entropySz)
283{
284 byte seed[DRBG_SEED_LEN];
285
286 if (Hash_df(drbg, seed, sizeof(seed), drbgReseed, drbg->V, sizeof(drbg->V),
287 entropy, entropySz) != DRBG_SUCCESS) {
288 return DRBG_FAILURE;
289 }
290
291 XMEMCPY(drbg->V, seed, sizeof(drbg->V));
292 ForceZero(seed, sizeof(seed));
293
294 if (Hash_df(drbg, drbg->C, sizeof(drbg->C), drbgInitC, drbg->V,
295 sizeof(drbg->V), NULL, 0) != DRBG_SUCCESS) {
296 return DRBG_FAILURE;
297 }
298
299 drbg->reseedCtr = 1;
300 drbg->lastBlock = 0;
301 drbg->matchCount = 0;
302 return DRBG_SUCCESS;
303}
304
305static INLINE void array_add_one(byte* data, word32 dataSz)
306{
307 int i;
308
309 for (i = dataSz - 1; i >= 0; i--)
310 {
311 data[i]++;
312 if (data[i] != 0) break;
313 }
314}
315
316/* Returns: DRBG_SUCCESS or DRBG_FAILURE */
317static int Hash_gen(DRBG* drbg, byte* out, word32 outSz, const byte* V)
318{
319 int ret = DRBG_FAILURE;
320 byte data[DRBG_SEED_LEN];
321 int i;
322 int len;
323 word32 checkBlock;
324 wc_Sha256 sha;
325 DECLARE_VAR(digest, byte, WC_SHA256_DIGEST_SIZE, drbg->heap);
326
327 /* Special case: outSz is 0 and out is NULL. wc_Generate a block to save for
328 * the continuous test. */
329
330 if (outSz == 0) outSz = 1;
331
332 len = (outSz / OUTPUT_BLOCK_LEN) + ((outSz % OUTPUT_BLOCK_LEN) ? 1 : 0);
333
334 XMEMCPY(data, V, sizeof(data));
335 for (i = 0; i < len; i++) {
336 #ifdef WOLFSSL_ASYNC_CRYPT
337 ret = wc_InitSha256_ex(&sha, drbg->heap, drbg->devId);
338 #else
339 ret = wc_InitSha256(&sha);
340 #endif
341 if (ret == 0)
342 ret = wc_Sha256Update(&sha, data, sizeof(data));
343 if (ret == 0)
344 ret = wc_Sha256Final(&sha, digest);
345 wc_Sha256Free(&sha);
346
347 if (ret == 0) {
348 XMEMCPY(&checkBlock, digest, sizeof(word32));
349 if (drbg->reseedCtr > 1 && checkBlock == drbg->lastBlock) {
350 if (drbg->matchCount == 1) {
351 return DRBG_CONT_FAILURE;
352 }
353 else {
354 if (i == len) {
355 len++;
356 }
357 drbg->matchCount = 1;
358 }
359 }
360 else {
361 drbg->matchCount = 0;
362 drbg->lastBlock = checkBlock;
363 }
364
365 if (out != NULL && outSz != 0) {
366 if (outSz >= OUTPUT_BLOCK_LEN) {
367 XMEMCPY(out, digest, OUTPUT_BLOCK_LEN);
368 outSz -= OUTPUT_BLOCK_LEN;
369 out += OUTPUT_BLOCK_LEN;
370 array_add_one(data, DRBG_SEED_LEN);
371 }
372 else {
373 XMEMCPY(out, digest, outSz);
374 outSz = 0;
375 }
376 }
377 }
378 }
379 ForceZero(data, sizeof(data));
380
381 FREE_VAR(digest, drbg->heap);
382
383 return (ret == 0) ? DRBG_SUCCESS : DRBG_FAILURE;
384}
385
386static INLINE void array_add(byte* d, word32 dLen, const byte* s, word32 sLen)
387{
388 word16 carry = 0;
389
390 if (dLen > 0 && sLen > 0 && dLen >= sLen) {
391 int sIdx, dIdx;
392
393 for (sIdx = sLen - 1, dIdx = dLen - 1; sIdx >= 0; dIdx--, sIdx--)
394 {
395 carry += d[dIdx] + s[sIdx];
396 d[dIdx] = (byte)carry;
397 carry >>= 8;
398 }
399
400 for (; carry != 0 && dIdx >= 0; dIdx--) {
401 carry += d[dIdx];
402 d[dIdx] = (byte)carry;
403 carry >>= 8;
404 }
405 }
406}
407
408/* Returns: DRBG_SUCCESS, DRBG_NEED_RESEED, or DRBG_FAILURE */
409static int Hash_DRBG_Generate(DRBG* drbg, byte* out, word32 outSz)
410{
411 int ret;
412 wc_Sha256 sha;
413 byte type;
414 word32 reseedCtr;
415
416 if (drbg->reseedCtr == RESEED_INTERVAL) {
417 return DRBG_NEED_RESEED;
418 } else {
419 DECLARE_VAR(digest, byte, WC_SHA256_DIGEST_SIZE, drbg->heap);
420 type = drbgGenerateH;
421 reseedCtr = drbg->reseedCtr;
422
423 ret = Hash_gen(drbg, out, outSz, drbg->V);
424 if (ret == DRBG_SUCCESS) {
425 #ifdef WOLFSSL_ASYNC_CRYPT
426 ret = wc_InitSha256_ex(&sha, drbg->heap, drbg->devId);
427 #else
428 ret = wc_InitSha256(&sha);
429 #endif
430 if (ret == 0)
431 ret = wc_Sha256Update(&sha, &type, sizeof(type));
432 if (ret == 0)
433 ret = wc_Sha256Update(&sha, drbg->V, sizeof(drbg->V));
434 if (ret == 0)
435 ret = wc_Sha256Final(&sha, digest);
436
437 wc_Sha256Free(&sha);
438
439 if (ret == 0) {
440 array_add(drbg->V, sizeof(drbg->V), digest, WC_SHA256_DIGEST_SIZE);
441 array_add(drbg->V, sizeof(drbg->V), drbg->C, sizeof(drbg->C));
442 #ifdef LITTLE_ENDIAN_ORDER
443 reseedCtr = ByteReverseWord32(reseedCtr);
444 #endif
445 array_add(drbg->V, sizeof(drbg->V),
446 (byte*)&reseedCtr, sizeof(reseedCtr));
447 ret = DRBG_SUCCESS;
448 }
449 drbg->reseedCtr++;
450 }
451 ForceZero(digest, WC_SHA256_DIGEST_SIZE);
452 FREE_VAR(digest, drbg->heap);
453 }
454
455 return (ret == 0) ? DRBG_SUCCESS : DRBG_FAILURE;
456}
457
458/* Returns: DRBG_SUCCESS or DRBG_FAILURE */
459static int Hash_DRBG_Instantiate(DRBG* drbg, const byte* seed, word32 seedSz,
460 const byte* nonce, word32 nonceSz,
461 void* heap, int devId)
462{
463 int ret = DRBG_FAILURE;
464
465 XMEMSET(drbg, 0, sizeof(DRBG));
466#ifdef WOLFSSL_ASYNC_CRYPT
467 drbg->heap = heap;
468 drbg->devId = devId;
469#else
470 (void)heap;
471 (void)devId;
472#endif
473
474 if (Hash_df(drbg, drbg->V, sizeof(drbg->V), drbgInitV, seed, seedSz,
475 nonce, nonceSz) == DRBG_SUCCESS &&
476 Hash_df(drbg, drbg->C, sizeof(drbg->C), drbgInitC, drbg->V,
477 sizeof(drbg->V), NULL, 0) == DRBG_SUCCESS) {
478
479 drbg->reseedCtr = 1;
480 drbg->lastBlock = 0;
481 drbg->matchCount = 0;
482 ret = DRBG_SUCCESS;
483 }
484
485 return ret;
486}
487
488/* Returns: DRBG_SUCCESS or DRBG_FAILURE */
489static int Hash_DRBG_Uninstantiate(DRBG* drbg)
490{
491 word32 i;
492 int compareSum = 0;
493 byte* compareDrbg = (byte*)drbg;
494
495 ForceZero(drbg, sizeof(DRBG));
496
497 for (i = 0; i < sizeof(DRBG); i++)
498 compareSum |= compareDrbg[i] ^ 0;
499
500 return (compareSum == 0) ? DRBG_SUCCESS : DRBG_FAILURE;
501}
502#endif /* HAVE_HASHDRBG */
503/* End NIST DRBG Code */
504
505
506int wc_InitRng_ex(WC_RNG* rng, void* heap, int devId)
507{
508 int ret = RNG_FAILURE_E;
509
510 if (rng == NULL)
511 return BAD_FUNC_ARG;
512
513#ifdef WOLFSSL_HEAP_TEST
514 rng->heap = (void*)WOLFSSL_HEAP_TEST;
515 (void)heap;
516#else
517 rng->heap = heap;
518#endif
519#ifdef WOLFSSL_ASYNC_CRYPT
520 rng->devId = devId;
521#else
522 (void)devId;
523#endif
524
525#ifdef HAVE_HASHDRBG
526 /* init the DBRG to known values */
527 rng->drbg = NULL;
528 rng->status = DRBG_NOT_INIT;
529#endif
530
531#if defined(HAVE_INTEL_RDSEED) || defined(HAVE_INTEL_RDRAND)
532 /* init the intel RD seed and/or rand */
533 wc_InitRng_IntelRD();
534#endif
535
536 /* configure async RNG source if available */
537#ifdef WOLFSSL_ASYNC_CRYPT
538 ret = wolfAsync_DevCtxInit(&rng->asyncDev, WOLFSSL_ASYNC_MARKER_RNG,
539 rng->heap, rng->devId);
540 if (ret != 0)
541 return ret;
542#endif
543
544#ifdef HAVE_INTEL_RDRAND
545 /* if CPU supports RDRAND, use it directly and by-pass DRBG init */
546 if (IS_INTEL_RDRAND(intel_flags))
547 return 0;
548#endif
549
550#ifdef CUSTOM_RAND_GENERATE_BLOCK
551 ret = 0; /* success */
552#else
553#ifdef HAVE_HASHDRBG
554 if (wc_RNG_HealthTestLocal(0) == 0) {
555 DECLARE_VAR(entropy, byte, ENTROPY_NONCE_SZ, rng->heap);
556
557 rng->drbg =
558 (struct DRBG*)XMALLOC(sizeof(DRBG), rng->heap,
559 DYNAMIC_TYPE_RNG);
560 if (rng->drbg == NULL) {
561 ret = MEMORY_E;
562 }
563 /* This doesn't use a separate nonce. The entropy input will be
564 * the default size plus the size of the nonce making the seed
565 * size. */
566 else if (wc_GenerateSeed(&rng->seed, entropy, ENTROPY_NONCE_SZ) == 0 &&
567 Hash_DRBG_Instantiate(rng->drbg, entropy, ENTROPY_NONCE_SZ,
568 NULL, 0, rng->heap, devId) == DRBG_SUCCESS) {
569 ret = Hash_DRBG_Generate(rng->drbg, NULL, 0);
570 }
571 else
572 ret = DRBG_FAILURE;
573
574 ForceZero(entropy, ENTROPY_NONCE_SZ);
575 FREE_VAR(entropy, rng->heap);
576 }
577 else
578 ret = DRBG_CONT_FAILURE;
579
580 if (ret == DRBG_SUCCESS) {
581 rng->status = DRBG_OK;
582 ret = 0;
583 }
584 else if (ret == DRBG_CONT_FAILURE) {
585 rng->status = DRBG_CONT_FAILED;
586 ret = DRBG_CONT_FIPS_E;
587 }
588 else if (ret == DRBG_FAILURE) {
589 rng->status = DRBG_FAILED;
590 ret = RNG_FAILURE_E;
591 }
592 else {
593 rng->status = DRBG_FAILED;
594 }
595#endif /* HAVE_HASHDRBG */
596#endif /* CUSTOM_RAND_GENERATE_BLOCK */
597
598 return ret;
599}
600
601int wc_InitRng(WC_RNG* rng)
602{
603 return wc_InitRng_ex(rng, NULL, INVALID_DEVID);
604}
605
606
607/* place a generated block in output */
608int wc_RNG_GenerateBlock(WC_RNG* rng, byte* output, word32 sz)
609{
610 int ret;
611
612 if (rng == NULL || output == NULL)
613 return BAD_FUNC_ARG;
614
615#ifdef HAVE_INTEL_RDRAND
616 if (IS_INTEL_RDRAND(intel_flags))
617 return wc_GenerateRand_IntelRD(NULL, output, sz);
618#endif
619
620#if defined(WOLFSSL_ASYNC_CRYPT)
621 if (rng->asyncDev.marker == WOLFSSL_ASYNC_MARKER_RNG) {
622 /* these are blocking */
623 #ifdef HAVE_CAVIUM
624 return NitroxRngGenerateBlock(rng, output, sz);
625 #elif defined(HAVE_INTEL_QA)
626 return IntelQaDrbg(&rng->asyncDev, output, sz);
627 #else
628 /* simulator not supported */
629 #endif
630 }
631#endif
632
633#ifdef CUSTOM_RAND_GENERATE_BLOCK
634 XMEMSET(output, 0, sz);
635 ret = CUSTOM_RAND_GENERATE_BLOCK(output, sz);
636#else
637
638#ifdef HAVE_HASHDRBG
639 if (sz > RNG_MAX_BLOCK_LEN)
640 return BAD_FUNC_ARG;
641
642 if (rng->status != DRBG_OK)
643 return RNG_FAILURE_E;
644
645 ret = Hash_DRBG_Generate(rng->drbg, output, sz);
646 if (ret == DRBG_NEED_RESEED) {
647 if (wc_RNG_HealthTestLocal(1) == 0) {
648 byte entropy[ENTROPY_SZ];
649
650 if (wc_GenerateSeed(&rng->seed, entropy, ENTROPY_SZ) == 0 &&
651 Hash_DRBG_Reseed(rng->drbg, entropy, ENTROPY_SZ)
652 == DRBG_SUCCESS) {
653
654 ret = Hash_DRBG_Generate(rng->drbg, NULL, 0);
655 if (ret == DRBG_SUCCESS)
656 ret = Hash_DRBG_Generate(rng->drbg, output, sz);
657 }
658 else
659 ret = DRBG_FAILURE;
660
661 ForceZero(entropy, ENTROPY_SZ);
662 }
663 else
664 ret = DRBG_CONT_FAILURE;
665 }
666
667 if (ret == DRBG_SUCCESS) {
668 ret = 0;
669 }
670 else if (ret == DRBG_CONT_FAILURE) {
671 ret = DRBG_CONT_FIPS_E;
672 rng->status = DRBG_CONT_FAILED;
673 }
674 else {
675 ret = RNG_FAILURE_E;
676 rng->status = DRBG_FAILED;
677 }
678#else
679
680 /* if we get here then there is an RNG configuration error */
681 ret = RNG_FAILURE_E;
682
683#endif /* HAVE_HASHDRBG */
684#endif /* CUSTOM_RAND_GENERATE_BLOCK */
685
686 return ret;
687}
688
689
690int wc_RNG_GenerateByte(WC_RNG* rng, byte* b)
691{
692 return wc_RNG_GenerateBlock(rng, b, 1);
693}
694
695
696int wc_FreeRng(WC_RNG* rng)
697{
698 int ret = 0;
699
700 if (rng == NULL)
701 return BAD_FUNC_ARG;
702
703#if defined(WOLFSSL_ASYNC_CRYPT)
704 wolfAsync_DevCtxFree(&rng->asyncDev, WOLFSSL_ASYNC_MARKER_RNG);
705#endif
706
707#ifdef HAVE_HASHDRBG
708 if (rng->drbg != NULL) {
709 if (Hash_DRBG_Uninstantiate(rng->drbg) != DRBG_SUCCESS)
710 ret = RNG_FAILURE_E;
711
712 XFREE(rng->drbg, rng->heap, DYNAMIC_TYPE_RNG);
713 rng->drbg = NULL;
714 }
715
716 rng->status = DRBG_NOT_INIT;
717#endif /* HAVE_HASHDRBG */
718
719 return ret;
720}
721
722#ifdef HAVE_HASHDRBG
723int wc_RNG_HealthTest(int reseed, const byte* entropyA, word32 entropyASz,
724 const byte* entropyB, word32 entropyBSz,
725 byte* output, word32 outputSz)
726{
727 int ret = -1;
728 DRBG* drbg;
729#ifndef WOLFSSL_SMALL_STACK
730 DRBG drbg_var;
731#endif
732
733 if (entropyA == NULL || output == NULL) {
734 return BAD_FUNC_ARG;
735 }
736
737 if (reseed != 0 && entropyB == NULL) {
738 return BAD_FUNC_ARG;
739 }
740
741 if (outputSz != RNG_HEALTH_TEST_CHECK_SIZE) {
742 return ret;
743 }
744
745#ifdef WOLFSSL_SMALL_STACK
746 drbg = (struct DRBG*)XMALLOC(sizeof(DRBG), NULL, DYNAMIC_TYPE_RNG);
747 if (drbg == NULL) {
748 return MEMORY_E;
749 }
750#else
751 drbg = &drbg_var;
752#endif
753
754 if (Hash_DRBG_Instantiate(drbg, entropyA, entropyASz, NULL, 0, NULL,
755 INVALID_DEVID) != 0) {
756 goto exit_rng_ht;
757 }
758
759 if (reseed) {
760 if (Hash_DRBG_Reseed(drbg, entropyB, entropyBSz) != 0) {
761 goto exit_rng_ht;
762 }
763 }
764
765 if (Hash_DRBG_Generate(drbg, output, outputSz) != 0) {
766 goto exit_rng_ht;
767 }
768
769 if (Hash_DRBG_Generate(drbg, output, outputSz) != 0) {
770 goto exit_rng_ht;
771 }
772
773 /* Mark success */
774 ret = 0;
775
776exit_rng_ht:
777
778 /* This is safe to call even if Hash_DRBG_Instantiate fails */
779 if (Hash_DRBG_Uninstantiate(drbg) != 0) {
780 ret = -1;
781 }
782
783#ifdef WOLFSSL_SMALL_STACK
784 XFREE(drbg, NULL, DYNAMIC_TYPE_RNG);
785#endif
786
787 return ret;
788}
789
790
791const byte entropyA[] = {
792 0x63, 0x36, 0x33, 0x77, 0xe4, 0x1e, 0x86, 0x46, 0x8d, 0xeb, 0x0a, 0xb4,
793 0xa8, 0xed, 0x68, 0x3f, 0x6a, 0x13, 0x4e, 0x47, 0xe0, 0x14, 0xc7, 0x00,
794 0x45, 0x4e, 0x81, 0xe9, 0x53, 0x58, 0xa5, 0x69, 0x80, 0x8a, 0xa3, 0x8f,
795 0x2a, 0x72, 0xa6, 0x23, 0x59, 0x91, 0x5a, 0x9f, 0x8a, 0x04, 0xca, 0x68
796};
797
798const byte reseedEntropyA[] = {
799 0xe6, 0x2b, 0x8a, 0x8e, 0xe8, 0xf1, 0x41, 0xb6, 0x98, 0x05, 0x66, 0xe3,
800 0xbf, 0xe3, 0xc0, 0x49, 0x03, 0xda, 0xd4, 0xac, 0x2c, 0xdf, 0x9f, 0x22,
801 0x80, 0x01, 0x0a, 0x67, 0x39, 0xbc, 0x83, 0xd3
802};
803
804const byte outputA[] = {
805 0x04, 0xee, 0xc6, 0x3b, 0xb2, 0x31, 0xdf, 0x2c, 0x63, 0x0a, 0x1a, 0xfb,
806 0xe7, 0x24, 0x94, 0x9d, 0x00, 0x5a, 0x58, 0x78, 0x51, 0xe1, 0xaa, 0x79,
807 0x5e, 0x47, 0x73, 0x47, 0xc8, 0xb0, 0x56, 0x62, 0x1c, 0x18, 0xbd, 0xdc,
808 0xdd, 0x8d, 0x99, 0xfc, 0x5f, 0xc2, 0xb9, 0x20, 0x53, 0xd8, 0xcf, 0xac,
809 0xfb, 0x0b, 0xb8, 0x83, 0x12, 0x05, 0xfa, 0xd1, 0xdd, 0xd6, 0xc0, 0x71,
810 0x31, 0x8a, 0x60, 0x18, 0xf0, 0x3b, 0x73, 0xf5, 0xed, 0xe4, 0xd4, 0xd0,
811 0x71, 0xf9, 0xde, 0x03, 0xfd, 0x7a, 0xea, 0x10, 0x5d, 0x92, 0x99, 0xb8,
812 0xaf, 0x99, 0xaa, 0x07, 0x5b, 0xdb, 0x4d, 0xb9, 0xaa, 0x28, 0xc1, 0x8d,
813 0x17, 0x4b, 0x56, 0xee, 0x2a, 0x01, 0x4d, 0x09, 0x88, 0x96, 0xff, 0x22,
814 0x82, 0xc9, 0x55, 0xa8, 0x19, 0x69, 0xe0, 0x69, 0xfa, 0x8c, 0xe0, 0x07,
815 0xa1, 0x80, 0x18, 0x3a, 0x07, 0xdf, 0xae, 0x17
816};
817
818const byte entropyB[] = {
819 0xa6, 0x5a, 0xd0, 0xf3, 0x45, 0xdb, 0x4e, 0x0e, 0xff, 0xe8, 0x75, 0xc3,
820 0xa2, 0xe7, 0x1f, 0x42, 0xc7, 0x12, 0x9d, 0x62, 0x0f, 0xf5, 0xc1, 0x19,
821 0xa9, 0xef, 0x55, 0xf0, 0x51, 0x85, 0xe0, 0xfb, 0x85, 0x81, 0xf9, 0x31,
822 0x75, 0x17, 0x27, 0x6e, 0x06, 0xe9, 0x60, 0x7d, 0xdb, 0xcb, 0xcc, 0x2e
823};
824
825const byte outputB[] = {
826 0xd3, 0xe1, 0x60, 0xc3, 0x5b, 0x99, 0xf3, 0x40, 0xb2, 0x62, 0x82, 0x64,
827 0xd1, 0x75, 0x10, 0x60, 0xe0, 0x04, 0x5d, 0xa3, 0x83, 0xff, 0x57, 0xa5,
828 0x7d, 0x73, 0xa6, 0x73, 0xd2, 0xb8, 0xd8, 0x0d, 0xaa, 0xf6, 0xa6, 0xc3,
829 0x5a, 0x91, 0xbb, 0x45, 0x79, 0xd7, 0x3f, 0xd0, 0xc8, 0xfe, 0xd1, 0x11,
830 0xb0, 0x39, 0x13, 0x06, 0x82, 0x8a, 0xdf, 0xed, 0x52, 0x8f, 0x01, 0x81,
831 0x21, 0xb3, 0xfe, 0xbd, 0xc3, 0x43, 0xe7, 0x97, 0xb8, 0x7d, 0xbb, 0x63,
832 0xdb, 0x13, 0x33, 0xde, 0xd9, 0xd1, 0xec, 0xe1, 0x77, 0xcf, 0xa6, 0xb7,
833 0x1f, 0xe8, 0xab, 0x1d, 0xa4, 0x66, 0x24, 0xed, 0x64, 0x15, 0xe5, 0x1c,
834 0xcd, 0xe2, 0xc7, 0xca, 0x86, 0xe2, 0x83, 0x99, 0x0e, 0xea, 0xeb, 0x91,
835 0x12, 0x04, 0x15, 0x52, 0x8b, 0x22, 0x95, 0x91, 0x02, 0x81, 0xb0, 0x2d,
836 0xd4, 0x31, 0xf4, 0xc9, 0xf7, 0x04, 0x27, 0xdf
837};
838
839
840static int wc_RNG_HealthTestLocal(int reseed)
841{
842 int ret = 0;
843#ifdef WOLFSSL_SMALL_STACK
844 byte* check;
845#else
846 byte check[RNG_HEALTH_TEST_CHECK_SIZE];
847#endif
848
849#ifdef WOLFSSL_SMALL_STACK
850 check = (byte*)XMALLOC(RNG_HEALTH_TEST_CHECK_SIZE, NULL,
851 DYNAMIC_TYPE_TMP_BUFFER);
852 if (check == NULL) {
853 return MEMORY_E;
854 }
855#endif
856
857 if (reseed) {
858 ret = wc_RNG_HealthTest(1, entropyA, sizeof(entropyA),
859 reseedEntropyA, sizeof(reseedEntropyA),
860 check, RNG_HEALTH_TEST_CHECK_SIZE);
861 if (ret == 0) {
862 if (ConstantCompare(check, outputA,
863 RNG_HEALTH_TEST_CHECK_SIZE) != 0)
864 ret = -1;
865 }
866 }
867 else {
868 ret = wc_RNG_HealthTest(0, entropyB, sizeof(entropyB),
869 NULL, 0,
870 check, RNG_HEALTH_TEST_CHECK_SIZE);
871 if (ret == 0) {
872 if (ConstantCompare(check, outputB,
873 RNG_HEALTH_TEST_CHECK_SIZE) != 0)
874 ret = -1;
875 }
876 }
877
878#ifdef WOLFSSL_SMALL_STACK
879 XFREE(check, NULL, DYNAMIC_TYPE_TMP_BUFFER);
880#endif
881
882 return ret;
883}
884
885#endif /* HAVE_HASHDRBG */
886
887
888#ifdef HAVE_WNR
889
890/*
891 * Init global Whitewood netRandom context
892 * Returns 0 on success, negative on error
893 */
894int wc_InitNetRandom(const char* configFile, wnr_hmac_key hmac_cb, int timeout)
895{
896 if (configFile == NULL || timeout < 0)
897 return BAD_FUNC_ARG;
898
899 if (wnr_mutex_init > 0) {
900 WOLFSSL_MSG("netRandom context already created, skipping");
901 return 0;
902 }
903
904 if (wc_InitMutex(&wnr_mutex) != 0) {
905 WOLFSSL_MSG("Bad Init Mutex wnr_mutex");
906 return BAD_MUTEX_E;
907 }
908 wnr_mutex_init = 1;
909
910 if (wc_LockMutex(&wnr_mutex) != 0) {
911 WOLFSSL_MSG("Bad Lock Mutex wnr_mutex");
912 return BAD_MUTEX_E;
913 }
914
915 /* store entropy timeout */
916 wnr_timeout = timeout;
917
918 /* create global wnr_context struct */
919 if (wnr_create(&wnr_ctx) != WNR_ERROR_NONE) {
920 WOLFSSL_MSG("Error creating global netRandom context");
921 return RNG_FAILURE_E;
922 }
923
924 /* load config file */
925 if (wnr_config_loadf(wnr_ctx, (char*)configFile) != WNR_ERROR_NONE) {
926 WOLFSSL_MSG("Error loading config file into netRandom context");
927 wnr_destroy(wnr_ctx);
928 wnr_ctx = NULL;
929 return RNG_FAILURE_E;
930 }
931
932 /* create/init polling mechanism */
933 if (wnr_poll_create() != WNR_ERROR_NONE) {
934 printf("ERROR: wnr_poll_create() failed\n");
935 WOLFSSL_MSG("Error initializing netRandom polling mechanism");
936 wnr_destroy(wnr_ctx);
937 wnr_ctx = NULL;
938 return RNG_FAILURE_E;
939 }
940
941 /* validate config, set HMAC callback (optional) */
942 if (wnr_setup(wnr_ctx, hmac_cb) != WNR_ERROR_NONE) {
943 WOLFSSL_MSG("Error setting up netRandom context");
944 wnr_destroy(wnr_ctx);
945 wnr_ctx = NULL;
946 wnr_poll_destroy();
947 return RNG_FAILURE_E;
948 }
949
950 wc_UnLockMutex(&wnr_mutex);
951
952 return 0;
953}
954
955/*
956 * Free global Whitewood netRandom context
957 * Returns 0 on success, negative on error
958 */
959int wc_FreeNetRandom(void)
960{
961 if (wnr_mutex_init > 0) {
962
963 if (wc_LockMutex(&wnr_mutex) != 0) {
964 WOLFSSL_MSG("Bad Lock Mutex wnr_mutex");
965 return BAD_MUTEX_E;
966 }
967
968 if (wnr_ctx != NULL) {
969 wnr_destroy(wnr_ctx);
970 wnr_ctx = NULL;
971 }
972 wnr_poll_destroy();
973
974 wc_UnLockMutex(&wnr_mutex);
975
976 wc_FreeMutex(&wnr_mutex);
977 wnr_mutex_init = 0;
978 }
979
980 return 0;
981}
982
983#endif /* HAVE_WNR */
984
985
986#if defined(HAVE_INTEL_RDRAND) || defined(HAVE_INTEL_RDSEED)
987
988#ifdef WOLFSSL_ASYNC_CRYPT
989 /* need more retries if multiple cores */
990 #define INTELRD_RETRY (32 * 8)
991#else
992 #define INTELRD_RETRY 32
993#endif
994
995#ifdef HAVE_INTEL_RDSEED
996
997/* return 0 on success */
998static INLINE int IntelRDseed64(word64* seed)
999{
1000 unsigned char ok;
1001
1002 __asm__ volatile("rdseed %0; setc %1":"=r"(*seed), "=qm"(ok));
1003 return (ok) ? 0 : -1;
1004}
1005
1006/* return 0 on success */
1007static INLINE int IntelRDseed64_r(word64* rnd)
1008{
1009 int i;
1010 for (i = 0; i < INTELRD_RETRY; i++) {
1011 if (IntelRDseed64(rnd) == 0)
1012 return 0;
1013 }
1014 return -1;
1015}
1016
1017/* return 0 on success */
1018static int wc_GenerateSeed_IntelRD(OS_Seed* os, byte* output, word32 sz)
1019{
1020 int ret;
1021 word64 rndTmp;
1022
1023 (void)os;
1024
1025 if (!IS_INTEL_RDSEED(intel_flags))
1026 return -1;
1027
1028 for (; (sz / sizeof(word64)) > 0; sz -= sizeof(word64),
1029 output += sizeof(word64)) {
1030 ret = IntelRDseed64_r((word64*)output);
1031 if (ret != 0)
1032 return ret;
1033 }
1034 if (sz == 0)
1035 return 0;
1036
1037 /* handle unaligned remainder */
1038 ret = IntelRDseed64_r(&rndTmp);
1039 if (ret != 0)
1040 return ret;
1041
1042 XMEMCPY(output, &rndTmp, sz);
1043
1044 return 0;
1045}
1046
1047#endif /* HAVE_INTEL_RDSEED */
1048
1049#ifdef HAVE_INTEL_RDRAND
1050
1051/* return 0 on success */
1052static INLINE int IntelRDrand64(word64 *rnd)
1053{
1054 unsigned char ok;
1055
1056 __asm__ volatile("rdrand %0; setc %1":"=r"(*rnd), "=qm"(ok));
1057
1058 return (ok) ? 0 : -1;
1059}
1060
1061/* return 0 on success */
1062static INLINE int IntelRDrand64_r(word64 *rnd)
1063{
1064 int i;
1065 for (i = 0; i < INTELRD_RETRY; i++) {
1066 if (IntelRDrand64(rnd) == 0)
1067 return 0;
1068 }
1069 return -1;
1070}
1071
1072/* return 0 on success */
1073static int wc_GenerateRand_IntelRD(OS_Seed* os, byte* output, word32 sz)
1074{
1075 int ret;
1076 word64 rndTmp;
1077
1078 (void)os;
1079
1080 if (!IS_INTEL_RDRAND(intel_flags))
1081 return -1;
1082
1083 for (; (sz / sizeof(word64)) > 0; sz -= sizeof(word64),
1084 output += sizeof(word64)) {
1085 ret = IntelRDrand64_r((word64 *)output);
1086 if (ret != 0)
1087 return ret;
1088 }
1089 if (sz == 0)
1090 return 0;
1091
1092 /* handle unaligned remainder */
1093 ret = IntelRDrand64_r(&rndTmp);
1094 if (ret != 0)
1095 return ret;
1096
1097 XMEMCPY(output, &rndTmp, sz);
1098
1099 return 0;
1100}
1101
1102#endif /* HAVE_INTEL_RDRAND */
1103#endif /* HAVE_INTEL_RDRAND || HAVE_INTEL_RDSEED */
1104
1105
1106/* Begin wc_GenerateSeed Implementations */
1107#if defined(CUSTOM_RAND_GENERATE_SEED)
1108
1109 /* Implement your own random generation function
1110 * Return 0 to indicate success
1111 * int rand_gen_seed(byte* output, word32 sz);
1112 * #define CUSTOM_RAND_GENERATE_SEED rand_gen_seed */
1113
1114 int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
1115 {
1116 extern int CUSTOM_RAND_GENERATE_SEED(byte* output, word32 sz);
1117 (void)os; /* Suppress unused arg warning */
1118 return CUSTOM_RAND_GENERATE_SEED(output, sz);
1119 }
1120
1121#elif defined(CUSTOM_RAND_GENERATE_SEED_OS)
1122
1123 /* Implement your own random generation function,
1124 * which includes OS_Seed.
1125 * Return 0 to indicate success
1126 * int rand_gen_seed(OS_Seed* os, byte* output, word32 sz);
1127 * #define CUSTOM_RAND_GENERATE_SEED_OS rand_gen_seed */
1128
1129 int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
1130 {
1131 return CUSTOM_RAND_GENERATE_SEED_OS(os, output, sz);
1132 }
1133
1134#elif defined(CUSTOM_RAND_GENERATE)
1135
1136 /* Implement your own random generation function
1137 * word32 rand_gen(void);
1138 * #define CUSTOM_RAND_GENERATE rand_gen */
1139
1140 int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
1141 {
1142 word32 i = 0;
1143
1144 (void)os;
1145
1146 while (i < sz)
1147 {
1148 /* If not aligned or there is odd/remainder */
1149 if( (i + sizeof(CUSTOM_RAND_TYPE)) > sz ||
1150 ((wolfssl_word)&output[i] % sizeof(CUSTOM_RAND_TYPE)) != 0
1151 ) {
1152 /* Single byte at a time */
1153 output[i++] = (byte)CUSTOM_RAND_GENERATE();
1154 }
1155 else {
1156 /* Use native 8, 16, 32 or 64 copy instruction */
1157 *((CUSTOM_RAND_TYPE*)&output[i]) = CUSTOM_RAND_GENERATE();
1158 i += sizeof(CUSTOM_RAND_TYPE);
1159 }
1160 }
1161
1162 return 0;
1163 }
1164
1165#elif defined(WOLFSSL_SGX)
1166
1167int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
1168{
1169 int ret = !SGX_SUCCESS;
1170 int i, read_max = 10;
1171
1172 for (i = 0; i < read_max && ret != SGX_SUCCESS; i++) {
1173 ret = sgx_read_rand(output, sz);
1174 }
1175
1176 (void)os;
1177 return (ret == SGX_SUCCESS) ? 0 : 1;
1178}
1179
1180#elif defined(USE_WINDOWS_API)
1181
1182int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
1183{
1184 if(!CryptAcquireContext(&os->handle, 0, 0, PROV_RSA_FULL,
1185 CRYPT_VERIFYCONTEXT))
1186 return WINCRYPT_E;
1187
1188 if (!CryptGenRandom(os->handle, sz, output))
1189 return CRYPTGEN_E;
1190
1191 CryptReleaseContext(os->handle, 0);
1192
1193 return 0;
1194}
1195
1196
1197#elif defined(HAVE_RTP_SYS) || defined(EBSNET)
1198
1199#include "rtprand.h" /* rtp_rand () */
1200#include "rtptime.h" /* rtp_get_system_msec() */
1201
1202
1203int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
1204{
1205 int i;
1206 rtp_srand(rtp_get_system_msec());
1207
1208 for (i = 0; i < sz; i++ ) {
1209 output[i] = rtp_rand() % 256;
1210 if ( (i % 8) == 7)
1211 rtp_srand(rtp_get_system_msec());
1212 }
1213
1214 return 0;
1215}
1216
1217
1218#elif defined(MICROCHIP_PIC32)
1219
1220 #ifdef MICROCHIP_MPLAB_HARMONY
1221 #define PIC32_SEED_COUNT _CP0_GET_COUNT
1222 #else
1223 #if !defined(WOLFSSL_MICROCHIP_PIC32MZ)
1224 #include <peripheral/timer.h>
1225 #endif
1226 extern word32 ReadCoreTimer(void);
1227 #define PIC32_SEED_COUNT ReadCoreTimer
1228 #endif
1229
1230 #ifdef WOLFSSL_PIC32MZ_RNG
1231 #include "xc.h"
1232 int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
1233 {
1234 int i;
1235 byte rnd[8];
1236 word32 *rnd32 = (word32 *)rnd;
1237 word32 size = sz;
1238 byte* op = output;
1239
1240#if ((__PIC32_FEATURE_SET0 == 'E') && (__PIC32_FEATURE_SET1 == 'C'))
1241 RNGNUMGEN1 = _CP0_GET_COUNT();
1242 RNGPOLY1 = _CP0_GET_COUNT();
1243 RNGPOLY2 = _CP0_GET_COUNT();
1244 RNGNUMGEN2 = _CP0_GET_COUNT();
1245#else
1246 // All others can be seeded from the TRNG
1247 RNGCONbits.TRNGMODE = 1;
1248 RNGCONbits.TRNGEN = 1;
1249 while (RNGCNT < 64);
1250 RNGCONbits.LOAD = 1;
1251 while (RNGCONbits.LOAD == 1);
1252 while (RNGCNT < 64);
1253 RNGPOLY2 = RNGSEED2;
1254 RNGPOLY1 = RNGSEED1;
1255#endif
1256
1257 RNGCONbits.PLEN = 0x40;
1258 RNGCONbits.PRNGEN = 1;
1259 for (i=0; i<5; i++) { /* wait for RNGNUMGEN ready */
1260 volatile int x;
1261 x = RNGNUMGEN1;
1262 x = RNGNUMGEN2;
1263 (void)x;
1264 }
1265 do {
1266 rnd32[0] = RNGNUMGEN1;
1267 rnd32[1] = RNGNUMGEN2;
1268
1269 for(i=0; i<8; i++, op++) {
1270 *op = rnd[i];
1271 size --;
1272 if(size==0)break;
1273 }
1274 } while(size);
1275 return 0;
1276 }
1277 #else /* WOLFSSL_PIC32MZ_RNG */
1278 /* uses the core timer, in nanoseconds to seed srand */
1279 int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
1280 {
1281 int i;
1282 srand(PIC32_SEED_COUNT() * 25);
1283
1284 for (i = 0; i < sz; i++ ) {
1285 output[i] = rand() % 256;
1286 if ( (i % 8) == 7)
1287 srand(PIC32_SEED_COUNT() * 25);
1288 }
1289 return 0;
1290 }
1291 #endif /* WOLFSSL_PIC32MZ_RNG */
1292
1293#elif defined(FREESCALE_MQX) || defined(FREESCALE_KSDK_MQX) || \
1294 defined(FREESCALE_KSDK_BM) || defined(FREESCALE_FREE_RTOS)
1295
1296 #if defined(FREESCALE_K70_RNGA) || defined(FREESCALE_RNGA)
1297 /*
1298 * wc_Generates a RNG seed using the Random Number Generator Accelerator
1299 * on the Kinetis K70. Documentation located in Chapter 37 of
1300 * K70 Sub-Family Reference Manual (see Note 3 in the README for link).
1301 */
1302 int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
1303 {
1304 int i;
1305
1306 /* turn on RNGA module */
1307 #if defined(SIM_SCGC3_RNGA_MASK)
1308 SIM_SCGC3 |= SIM_SCGC3_RNGA_MASK;
1309 #endif
1310 #if defined(SIM_SCGC6_RNGA_MASK)
1311 /* additionally needed for at least K64F */
1312 SIM_SCGC6 |= SIM_SCGC6_RNGA_MASK;
1313 #endif
1314
1315 /* set SLP bit to 0 - "RNGA is not in sleep mode" */
1316 RNG_CR &= ~RNG_CR_SLP_MASK;
1317
1318 /* set HA bit to 1 - "security violations masked" */
1319 RNG_CR |= RNG_CR_HA_MASK;
1320
1321 /* set GO bit to 1 - "output register loaded with data" */
1322 RNG_CR |= RNG_CR_GO_MASK;
1323
1324 for (i = 0; i < sz; i++) {
1325
1326 /* wait for RNG FIFO to be full */
1327 while((RNG_SR & RNG_SR_OREG_LVL(0xF)) == 0) {}
1328
1329 /* get value */
1330 output[i] = RNG_OR;
1331 }
1332
1333 return 0;
1334 }
1335
1336 #elif defined(FREESCALE_K53_RNGB) || defined(FREESCALE_RNGB)
1337 /*
1338 * wc_Generates a RNG seed using the Random Number Generator (RNGB)
1339 * on the Kinetis K53. Documentation located in Chapter 33 of
1340 * K53 Sub-Family Reference Manual (see note in the README for link).
1341 */
1342 int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
1343 {
1344 int i;
1345
1346 /* turn on RNGB module */
1347 SIM_SCGC3 |= SIM_SCGC3_RNGB_MASK;
1348
1349 /* reset RNGB */
1350 RNG_CMD |= RNG_CMD_SR_MASK;
1351
1352 /* FIFO generate interrupt, return all zeros on underflow,
1353 * set auto reseed */
1354 RNG_CR |= (RNG_CR_FUFMOD_MASK | RNG_CR_AR_MASK);
1355
1356 /* gen seed, clear interrupts, clear errors */
1357 RNG_CMD |= (RNG_CMD_GS_MASK | RNG_CMD_CI_MASK | RNG_CMD_CE_MASK);
1358
1359 /* wait for seeding to complete */
1360 while ((RNG_SR & RNG_SR_SDN_MASK) == 0) {}
1361
1362 for (i = 0; i < sz; i++) {
1363
1364 /* wait for a word to be available from FIFO */
1365 while((RNG_SR & RNG_SR_FIFO_LVL_MASK) == 0) {}
1366
1367 /* get value */
1368 output[i] = RNG_OUT;
1369 }
1370
1371 return 0;
1372 }
1373
1374 #elif defined(FREESCALE_KSDK_2_0_TRNG)
1375
1376 int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
1377 {
1378 status_t status;
1379 status = TRNG_GetRandomData(TRNG0, output, sz);
1380 if (status == kStatus_Success)
1381 {
1382 return(0);
1383 }
1384 else
1385 {
1386 return RAN_BLOCK_E;
1387 }
1388 }
1389
1390 #elif defined(FREESCALE_KSDK_2_0_RNGA)
1391
1392 int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
1393 {
1394 status_t status;
1395 status = RNGA_GetRandomData(RNG, output, sz);
1396 if (status == kStatus_Success)
1397 {
1398 return(0);
1399 }
1400 else
1401 {
1402 return RAN_BLOCK_E;
1403 }
1404 }
1405
1406
1407 #elif defined(FREESCALE_RNGA)
1408
1409 int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
1410 {
1411 RNGA_DRV_GetRandomData(RNGA_INSTANCE, output, sz);
1412 return 0;
1413 }
1414
1415 #else
1416 #define USE_TEST_GENSEED
1417 #endif /* FREESCALE_K70_RNGA */
1418
1419#elif defined(STM32_RNG)
1420 /*
1421 * wc_Generate a RNG seed using the hardware random number generator
1422 * on the STM32F2/F4/F7. */
1423
1424 #ifdef WOLFSSL_STM32_CUBEMX
1425 int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
1426 {
1427 RNG_HandleTypeDef hrng;
1428 int i;
1429 (void)os;
1430
1431 /* enable RNG clock source */
1432 __HAL_RCC_RNG_CLK_ENABLE();
1433
1434 /* enable RNG peripheral */
1435 hrng.Instance = RNG;
1436 HAL_RNG_Init(&hrng);
1437
1438 for (i = 0; i < (int)sz; i++) {
1439 /* get value */
1440 output[i] = (byte)HAL_RNG_GetRandomNumber(&hrng);
1441 }
1442
1443 return 0;
1444 }
1445 #else
1446 int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
1447 {
1448 int i;
1449 (void)os;
1450
1451 /* enable RNG clock source */
1452 RCC_AHB2PeriphClockCmd(RCC_AHB2Periph_RNG, ENABLE);
1453
1454 /* reset RNG */
1455 RNG_DeInit();
1456
1457 /* enable RNG peripheral */
1458 RNG_Cmd(ENABLE);
1459
1460 /* verify no errors with RNG_CLK or Seed */
1461 if (RNG_GetFlagStatus(RNG_FLAG_SECS | RNG_FLAG_CECS) != RESET)
1462 return RNG_FAILURE_E;
1463
1464 for (i = 0; i < (int)sz; i++) {
1465 /* wait until RNG number is ready */
1466 while (RNG_GetFlagStatus(RNG_FLAG_DRDY) == RESET) { }
1467
1468 /* get value */
1469 output[i] = RNG_GetRandomNumber();
1470 }
1471
1472 return 0;
1473 }
1474 #endif /* WOLFSSL_STM32_CUBEMX */
1475
1476#elif defined(WOLFSSL_TIRTOS)
1477
1478 #include <xdc/runtime/Timestamp.h>
1479 #include <stdlib.h>
1480 int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
1481 {
1482 int i;
1483 srand(xdc_runtime_Timestamp_get32());
1484
1485 for (i = 0; i < sz; i++ ) {
1486 output[i] = rand() % 256;
1487 if ((i % 8) == 7) {
1488 srand(xdc_runtime_Timestamp_get32());
1489 }
1490 }
1491
1492 return 0;
1493 }
1494
1495#elif defined(WOLFSSL_VXWORKS)
1496
1497 #include <randomNumGen.h>
1498
1499 int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz) {
1500 STATUS status;
1501
1502 #ifdef VXWORKS_SIM
1503 /* cannot generate true entropy with VxWorks simulator */
1504 #warning "not enough entropy, simulator for testing only"
1505 int i = 0;
1506
1507 for (i = 0; i < 1000; i++) {
1508 randomAddTimeStamp();
1509 }
1510 #endif
1511
1512 status = randBytes (output, sz);
1513 if (status == ERROR) {
1514 return RNG_FAILURE_E;
1515 }
1516
1517 return 0;
1518 }
1519
1520#elif defined(WOLFSSL_NRF51)
1521 #include "app_error.h"
1522 #include "nrf_drv_rng.h"
1523 int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
1524 {
1525 int remaining = sz, length, pos = 0;
1526 uint8_t available;
1527 uint32_t err_code;
1528
1529 (void)os;
1530
1531 /* Make sure RNG is running */
1532 err_code = nrf_drv_rng_init(NULL);
1533 if (err_code != NRF_SUCCESS && err_code != NRF_ERROR_INVALID_STATE) {
1534 return -1;
1535 }
1536
1537 while (remaining > 0) {
1538 err_code = nrf_drv_rng_bytes_available(&available);
1539 if (err_code == NRF_SUCCESS) {
1540 length = (remaining < available) ? remaining : available;
1541 if (length > 0) {
1542 err_code = nrf_drv_rng_rand(&output[pos], length);
1543 remaining -= length;
1544 pos += length;
1545 }
1546 }
1547
1548 if (err_code != NRF_SUCCESS) {
1549 break;
1550 }
1551 }
1552
1553 return (err_code == NRF_SUCCESS) ? 0 : -1;
1554 }
1555
1556#elif defined(HAVE_WNR)
1557
1558 int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
1559 {
1560 if (os == NULL || output == NULL || wnr_ctx == NULL ||
1561 wnr_timeout < 0) {
1562 return BAD_FUNC_ARG;
1563 }
1564
1565 if (wnr_mutex_init == 0) {
1566 WOLFSSL_MSG("netRandom context must be created before use");
1567 return RNG_FAILURE_E;
1568 }
1569
1570 if (wc_LockMutex(&wnr_mutex) != 0) {
1571 WOLFSSL_MSG("Bad Lock Mutex wnr_mutex\n");
1572 return BAD_MUTEX_E;
1573 }
1574
1575 if (wnr_get_entropy(wnr_ctx, wnr_timeout, output, sz, sz) !=
1576 WNR_ERROR_NONE)
1577 return RNG_FAILURE_E;
1578
1579 wc_UnLockMutex(&wnr_mutex);
1580
1581 return 0;
1582 }
1583
1584#elif defined(WOLFSSL_ATMEL)
1585 #include <wolfssl/wolfcrypt/port/atmel/atmel.h>
1586
1587 int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
1588 {
1589 int ret = 0;
1590
1591 (void)os;
1592 if (output == NULL) {
1593 return BUFFER_E;
1594 }
1595
1596 ret = atmel_get_random_number(sz, output);
1597
1598 return ret;
1599 }
1600
1601#elif defined(INTIME_RTOS)
1602 int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
1603 {
1604 int ret = 0;
1605
1606 (void)os;
1607
1608 if (output == NULL) {
1609 return BUFFER_E;
1610 }
1611
1612 /* Note: Investigate better solution */
1613 /* no return to check */
1614 arc4random_buf(output, sz);
1615
1616 return ret;
1617 }
1618
1619#elif defined(IDIRECT_DEV_RANDOM)
1620
1621 extern int getRandom( int sz, unsigned char *output );
1622
1623 int GenerateSeed(OS_Seed* os, byte* output, word32 sz)
1624 {
1625 int num_bytes_returned = 0;
1626
1627 num_bytes_returned = getRandom( (int) sz, (unsigned char *) output );
1628
1629 return 0;
1630 }
1631
1632#elif defined(CUSTOM_RAND_GENERATE_BLOCK)
1633 /* #define CUSTOM_RAND_GENERATE_BLOCK myRngFunc
1634 * extern int myRngFunc(byte* output, word32 sz);
1635 */
1636
1637#elif defined(WOLFSSL_SAFERTOS) || defined(WOLFSSL_LEANPSK) || \
1638 defined(WOLFSSL_IAR_ARM) || defined(WOLFSSL_MDK_ARM) || \
1639 defined(WOLFSSL_uITRON4) || defined(WOLFSSL_uTKERNEL2) || \
1640 defined(WOLFSSL_LPC43xx) || defined(WOLFSSL_STM32F2xx) || \
1641 defined(MBED) || defined(WOLFSSL_EMBOS) || \
1642 defined(WOLFSSL_GENSEED_FORTEST)
1643
1644 /* these platforms do not have a default random seed and
1645 you'll need to implement your own wc_GenerateSeed or define via
1646 CUSTOM_RAND_GENERATE_BLOCK */
1647
1648 #define USE_TEST_GENSEED
1649
1650#elif defined(NO_DEV_RANDOM)
1651
1652 #error "you need to write an os specific wc_GenerateSeed() here"
1653
1654 /*
1655 int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
1656 {
1657 return 0;
1658 }
1659 */
1660
1661#else
1662
1663 /* may block */
1664 int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
1665 {
1666 int ret = 0;
1667
1668 #ifdef HAVE_INTEL_RDSEED
1669 if (IS_INTEL_RDSEED(intel_flags)) {
1670 ret = wc_GenerateSeed_IntelRD(NULL, output, sz);
1671 if (ret == 0) {
1672 /* success, we're done */
1673 return ret;
1674 }
1675 #ifdef FORCE_FAILURE_RDSEED
1676 /* don't fallback to /dev/urandom */
1677 return ret;
1678 #else
1679 /* fallback to /dev/urandom attempt */
1680 ret = 0;
1681 #endif
1682 }
1683
1684 #endif /* HAVE_INTEL_RDSEED */
1685
1686 os->fd = open("/dev/urandom",O_RDONLY);
1687 if (os->fd == -1) {
1688 /* may still have /dev/random */
1689 os->fd = open("/dev/random",O_RDONLY);
1690 if (os->fd == -1)
1691 return OPEN_RAN_E;
1692 }
1693
1694 while (sz) {
1695 int len = (int)read(os->fd, output, sz);
1696 if (len == -1) {
1697 ret = READ_RAN_E;
1698 break;
1699 }
1700
1701 sz -= len;
1702 output += len;
1703
1704 if (sz) {
1705 #ifdef BLOCKING
1706 sleep(0); /* context switch */
1707 #else
1708 ret = RAN_BLOCK_E;
1709 break;
1710 #endif
1711 }
1712 }
1713 close(os->fd);
1714
1715 return ret;
1716 }
1717
1718#endif
1719
1720#ifdef USE_TEST_GENSEED
1721 #ifndef _MSC_VER
1722 #warning "write a real random seed!!!!, just for testing now"
1723 #else
1724 #pragma message("Warning: write a real random seed!!!!, just for testing now")
1725 #endif
1726
1727 int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
1728 {
1729 word32 i;
1730 for (i = 0; i < sz; i++ )
1731 output[i] = i;
1732
1733 (void)os;
1734
1735 return 0;
1736 }
1737#endif
1738
1739/* End wc_GenerateSeed */
1740
1741#endif /* WC_NO_RNG */
1742#endif /* HAVE_FIPS */
Note: See TracBrowser for help on using the repository browser.