source: UsbWattMeter/trunk/wolfssl-3.7.0/wolfcrypt/src/random.c@ 167

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

MIMEにSJISを設定

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
  • Property svn:mime-type set to text/x-csrc; charset=SHIFT_JIS
File size: 35.2 KB
RevLine 
[164]1/* random.c
2 *
3 * Copyright (C) 2006-2015 wolfSSL Inc.
4 *
5 * This file is part of wolfSSL. (formerly known as CyaSSL)
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-1301, USA
20 */
21
22#ifdef HAVE_CONFIG_H
23 #include <config.h>
24#endif
25
26#include <wolfssl/wolfcrypt/settings.h>
27
28/* on HPUX 11 you may need to install /dev/random see
29 http://h20293.www2.hp.com/portal/swdepot/displayProductInfo.do?productNumber=KRNG11I
30
31*/
32
33#include <wolfssl/wolfcrypt/random.h>
34
35#ifdef HAVE_FIPS
36int wc_GenerateSeed(OS_Seed* os, byte* seed, word32 sz)
37{
38 return GenerateSeed(os, seed, sz);
39}
40
41#ifdef HAVE_CAVIUM
42 int wc_InitRngCavium(WC_RNG* rng, int i)
43 {
44 return InitRngCavium(rng, i);
45 }
46#endif
47
48
49int wc_InitRng(WC_RNG* rng)
50{
51 return InitRng_fips(rng);
52}
53
54
55int wc_RNG_GenerateBlock(WC_RNG* rng, byte* b, word32 sz)
56{
57 return RNG_GenerateBlock_fips(rng, b, sz);
58}
59
60
61int wc_RNG_GenerateByte(WC_RNG* rng, byte* b)
62{
63 return RNG_GenerateByte(rng, b);
64}
65
66#if defined(HAVE_HASHDRBG) || defined(NO_RC4)
67
68 int wc_FreeRng(WC_RNG* rng)
69 {
70 return FreeRng_fips(rng);
71 }
72
73
74 int wc_RNG_HealthTest(int reseed,
75 const byte* entropyA, word32 entropyASz,
76 const byte* entropyB, word32 entropyBSz,
77 byte* output, word32 outputSz)
78 {
79 return RNG_HealthTest_fips(reseed, entropyA, entropyASz,
80 entropyB, entropyBSz, output, outputSz);
81 }
82#endif /* HAVE_HASHDRBG || NO_RC4 */
83#else /* else build without fips */
84#include <wolfssl/wolfcrypt/error-crypt.h>
85
86#if defined(HAVE_HASHDRBG) || defined(NO_RC4)
87
88 #include <wolfssl/wolfcrypt/sha256.h>
89
90 #ifdef NO_INLINE
91 #include <wolfssl/wolfcrypt/misc.h>
92 #else
93 #include <wolfcrypt/src/misc.c>
94 #endif
95#endif /* HAVE_HASHDRBG || NO_RC4 */
96
97#if defined(USE_WINDOWS_API)
98 #ifndef _WIN32_WINNT
99 #define _WIN32_WINNT 0x0400
100 #endif
101 #include <windows.h>
102 #include <wincrypt.h>
103#else
104 #if !defined(NO_DEV_RANDOM) && !defined(CUSTOM_RAND_GENERATE) && \
105 !defined(WOLFSSL_GENSEED_FORTEST) && !defined(WOLFSSL_MDK_ARM) && \
106 !defined(WOLFSSL_IAR_ARM) && !defined(WOLFSSL_ROWLEY_ARM)
107 //#include <fcntl.h>
108 #ifndef EBSNET
109 //#include <unistd.h>
110 #endif
111 #elif defined(FREESCALE_TRNG)
112 #define TRNG_INSTANCE (0)
113 #include "fsl_device_registers.h"
114 #include "fsl_trng_driver.h"
115 #else
116 /* include headers that may be needed to get good seed */
117 #endif
118#endif /* USE_WINDOWS_API */
119
120#ifdef HAVE_INTEL_RDGEN
121 static int wc_InitRng_IntelRD(void) ;
122 #if defined(HAVE_HASHDRBG) || defined(NO_RC4)
123 static int wc_GenerateSeed_IntelRD(OS_Seed* os, byte* output, word32 sz) ;
124 #else
125 static int wc_GenerateRand_IntelRD(OS_Seed* os, byte* output, word32 sz) ;
126 #endif
127 static word32 cpuid_check = 0 ;
128 static word32 cpuid_flags = 0 ;
129 #define CPUID_RDRAND 0x4
130 #define CPUID_RDSEED 0x8
131 #define IS_INTEL_RDRAND (cpuid_flags&CPUID_RDRAND)
132 #define IS_INTEL_RDSEED (cpuid_flags&CPUID_RDSEED)
133#endif
134
135#if defined(HAVE_HASHDRBG) || defined(NO_RC4)
136
137/* Start NIST DRBG code */
138
139#define OUTPUT_BLOCK_LEN (SHA256_DIGEST_SIZE)
140#define MAX_REQUEST_LEN (0x10000)
141#define RESEED_INTERVAL (1000000)
142#define SECURITY_STRENGTH (256)
143#define ENTROPY_SZ (SECURITY_STRENGTH/8)
144#define NONCE_SZ (ENTROPY_SZ/2)
145#define ENTROPY_NONCE_SZ (ENTROPY_SZ+NONCE_SZ)
146
147/* Internal return codes */
148#define DRBG_SUCCESS 0
149#define DRBG_ERROR 1
150#define DRBG_FAILURE 2
151#define DRBG_NEED_RESEED 3
152#define DRBG_CONT_FAILURE 4
153
154/* RNG health states */
155#define DRBG_NOT_INIT 0
156#define DRBG_OK 1
157#define DRBG_FAILED 2
158#define DRBG_CONT_FAILED 3
159
160
161enum {
162 drbgInitC = 0,
163 drbgReseed = 1,
164 drbgGenerateW = 2,
165 drbgGenerateH = 3,
166 drbgInitV
167};
168
169
170typedef struct DRBG {
171 word32 reseedCtr;
172 word32 lastBlock;
173 byte V[DRBG_SEED_LEN];
174 byte C[DRBG_SEED_LEN];
175 byte matchCount;
176} DRBG;
177
178
179static int wc_RNG_HealthTestLocal(int reseed);
180
181/* Hash Derivation Function */
182/* Returns: DRBG_SUCCESS or DRBG_FAILURE */
183static int Hash_df(DRBG* drbg, byte* out, word32 outSz, byte type,
184 const byte* inA, word32 inASz,
185 const byte* inB, word32 inBSz)
186{
187 byte ctr;
188 int i;
189 int len;
190 word32 bits = (outSz * 8); /* reverse byte order */
191 Sha256 sha;
192 byte digest[SHA256_DIGEST_SIZE];
193
194 (void)drbg;
195 #ifdef LITTLE_ENDIAN_ORDER
196 bits = ByteReverseWord32(bits);
197 #endif
198 len = (outSz / OUTPUT_BLOCK_LEN)
199 + ((outSz % OUTPUT_BLOCK_LEN) ? 1 : 0);
200
201 for (i = 0, ctr = 1; i < len; i++, ctr++)
202 {
203 if (wc_InitSha256(&sha) != 0)
204 return DRBG_FAILURE;
205
206 if (wc_Sha256Update(&sha, &ctr, sizeof(ctr)) != 0)
207 return DRBG_FAILURE;
208
209 if (wc_Sha256Update(&sha, (byte*)&bits, sizeof(bits)) != 0)
210 return DRBG_FAILURE;
211
212 /* churning V is the only string that doesn't have the type added */
213 if (type != drbgInitV)
214 if (wc_Sha256Update(&sha, &type, sizeof(type)) != 0)
215 return DRBG_FAILURE;
216
217 if (wc_Sha256Update(&sha, inA, inASz) != 0)
218 return DRBG_FAILURE;
219
220 if (inB != NULL && inBSz > 0)
221 if (wc_Sha256Update(&sha, inB, inBSz) != 0)
222 return DRBG_FAILURE;
223
224 if (wc_Sha256Final(&sha, digest) != 0)
225 return DRBG_FAILURE;
226
227 if (outSz > OUTPUT_BLOCK_LEN) {
228 XMEMCPY(out, digest, OUTPUT_BLOCK_LEN);
229 outSz -= OUTPUT_BLOCK_LEN;
230 out += OUTPUT_BLOCK_LEN;
231 }
232 else {
233 XMEMCPY(out, digest, outSz);
234 }
235 }
236 ForceZero(digest, sizeof(digest));
237
238 return DRBG_SUCCESS;
239}
240
241
242/* Returns: DRBG_SUCCESS or DRBG_FAILURE */
243static int Hash_DRBG_Reseed(DRBG* drbg, const byte* entropy, word32 entropySz)
244{
245 byte seed[DRBG_SEED_LEN];
246
247 if (Hash_df(drbg, seed, sizeof(seed), drbgReseed, drbg->V, sizeof(drbg->V),
248 entropy, entropySz) != DRBG_SUCCESS) {
249 return DRBG_FAILURE;
250 }
251
252 XMEMCPY(drbg->V, seed, sizeof(drbg->V));
253 ForceZero(seed, sizeof(seed));
254
255 if (Hash_df(drbg, drbg->C, sizeof(drbg->C), drbgInitC, drbg->V,
256 sizeof(drbg->V), NULL, 0) != DRBG_SUCCESS) {
257 return DRBG_FAILURE;
258 }
259
260 drbg->reseedCtr = 1;
261 drbg->lastBlock = 0;
262 drbg->matchCount = 0;
263 return DRBG_SUCCESS;
264}
265
266static INLINE void array_add_one(byte* data, word32 dataSz)
267{
268 int i;
269
270 for (i = dataSz - 1; i >= 0; i--)
271 {
272 data[i]++;
273 if (data[i] != 0) break;
274 }
275}
276
277
278/* Returns: DRBG_SUCCESS or DRBG_FAILURE */
279static int Hash_gen(DRBG* drbg, byte* out, word32 outSz, const byte* V)
280{
281 byte data[DRBG_SEED_LEN];
282 int i;
283 int len;
284 word32 checkBlock;
285 Sha256 sha;
286 byte digest[SHA256_DIGEST_SIZE];
287
288 /* Special case: outSz is 0 and out is NULL. wc_Generate a block to save for
289 * the continuous test. */
290
291 if (outSz == 0) outSz = 1;
292
293 len = (outSz / OUTPUT_BLOCK_LEN) + ((outSz % OUTPUT_BLOCK_LEN) ? 1 : 0);
294
295 XMEMCPY(data, V, sizeof(data));
296 for (i = 0; i < len; i++) {
297 if (wc_InitSha256(&sha) != 0 ||
298 wc_Sha256Update(&sha, data, sizeof(data)) != 0 ||
299 wc_Sha256Final(&sha, digest) != 0) {
300
301 return DRBG_FAILURE;
302 }
303
304 XMEMCPY(&checkBlock, digest, sizeof(word32));
305 if (drbg->reseedCtr > 1 && checkBlock == drbg->lastBlock) {
306 if (drbg->matchCount == 1) {
307 return DRBG_CONT_FAILURE;
308 }
309 else {
310 if (i == len) {
311 len++;
312 }
313 drbg->matchCount = 1;
314 }
315 }
316 else {
317 drbg->matchCount = 0;
318 drbg->lastBlock = checkBlock;
319 }
320
321 if (outSz >= OUTPUT_BLOCK_LEN) {
322 XMEMCPY(out, digest, OUTPUT_BLOCK_LEN);
323 outSz -= OUTPUT_BLOCK_LEN;
324 out += OUTPUT_BLOCK_LEN;
325 array_add_one(data, DRBG_SEED_LEN);
326 }
327 else if (out != NULL && outSz != 0) {
328 XMEMCPY(out, digest, outSz);
329 outSz = 0;
330 }
331 }
332 ForceZero(data, sizeof(data));
333
334 return DRBG_SUCCESS;
335}
336
337
338static INLINE void array_add(byte* d, word32 dLen, const byte* s, word32 sLen)
339{
340 word16 carry = 0;
341
342 if (dLen > 0 && sLen > 0 && dLen >= sLen) {
343 int sIdx, dIdx;
344
345 for (sIdx = sLen - 1, dIdx = dLen - 1; sIdx >= 0; dIdx--, sIdx--)
346 {
347 carry += d[dIdx] + s[sIdx];
348 d[dIdx] = (byte)carry;
349 carry >>= 8;
350 }
351
352 for (; carry != 0 && dIdx >= 0; dIdx--) {
353 carry += d[dIdx];
354 d[dIdx] = (byte)carry;
355 carry >>= 8;
356 }
357 }
358}
359
360
361/* Returns: DRBG_SUCCESS, DRBG_NEED_RESEED, or DRBG_FAILURE */
362static int Hash_DRBG_Generate(DRBG* drbg, byte* out, word32 outSz)
363{
364 int ret = DRBG_NEED_RESEED;
365 Sha256 sha;
366 byte digest[SHA256_DIGEST_SIZE];
367
368 if (drbg->reseedCtr != RESEED_INTERVAL) {
369 byte type = drbgGenerateH;
370 word32 reseedCtr = drbg->reseedCtr;
371
372 ret = Hash_gen(drbg, out, outSz, drbg->V);
373 if (ret == DRBG_SUCCESS) {
374 if (wc_InitSha256(&sha) != 0 ||
375 wc_Sha256Update(&sha, &type, sizeof(type)) != 0 ||
376 wc_Sha256Update(&sha, drbg->V, sizeof(drbg->V)) != 0 ||
377 wc_Sha256Final(&sha, digest) != 0) {
378
379 ret = DRBG_FAILURE;
380 }
381 else {
382 array_add(drbg->V, sizeof(drbg->V), digest, sizeof(digest));
383 array_add(drbg->V, sizeof(drbg->V), drbg->C, sizeof(drbg->C));
384 #ifdef LITTLE_ENDIAN_ORDER
385 reseedCtr = ByteReverseWord32(reseedCtr);
386 #endif
387 array_add(drbg->V, sizeof(drbg->V),
388 (byte*)&reseedCtr, sizeof(reseedCtr));
389 ret = DRBG_SUCCESS;
390 }
391 drbg->reseedCtr++;
392 }
393 }
394 ForceZero(digest, sizeof(digest));
395
396 return ret;
397}
398
399
400/* Returns: DRBG_SUCCESS or DRBG_FAILURE */
401static int Hash_DRBG_Instantiate(DRBG* drbg, const byte* seed, word32 seedSz,
402 const byte* nonce, word32 nonceSz)
403{
404 int ret = DRBG_FAILURE;
405
406 XMEMSET(drbg, 0, sizeof(DRBG));
407
408 if (Hash_df(drbg, drbg->V, sizeof(drbg->V), drbgInitV, seed, seedSz,
409 nonce, nonceSz) == DRBG_SUCCESS &&
410 Hash_df(drbg, drbg->C, sizeof(drbg->C), drbgInitC, drbg->V,
411 sizeof(drbg->V), NULL, 0) == DRBG_SUCCESS) {
412
413 drbg->reseedCtr = 1;
414 drbg->lastBlock = 0;
415 drbg->matchCount = 0;
416 ret = DRBG_SUCCESS;
417 }
418
419 return ret;
420}
421
422
423/* Returns: DRBG_SUCCESS or DRBG_FAILURE */
424static int Hash_DRBG_Uninstantiate(DRBG* drbg)
425{
426 word32 i;
427 int compareSum = 0;
428 byte* compareDrbg = (byte*)drbg;
429
430 ForceZero(drbg, sizeof(DRBG));
431
432 for (i = 0; i < sizeof(DRBG); i++)
433 compareSum |= compareDrbg[i] ^ 0;
434
435 return (compareSum == 0) ? DRBG_SUCCESS : DRBG_FAILURE;
436}
437
438/* End NIST DRBG Code */
439
440
441/* Get seed and key cipher */
442int wc_InitRng(WC_RNG* rng)
443{
444 int ret = BAD_FUNC_ARG;
445
446 if (rng != NULL) {
447 if (wc_RNG_HealthTestLocal(0) == 0) {
448 byte entropy[ENTROPY_NONCE_SZ];
449
450 rng->drbg =
451 (struct DRBG*)XMALLOC(sizeof(DRBG), NULL, DYNAMIC_TYPE_RNG);
452 if (rng->drbg == NULL) {
453 ret = MEMORY_E;
454 }
455 /* This doesn't use a separate nonce. The entropy input will be
456 * the default size plus the size of the nonce making the seed
457 * size. */
458 else if (wc_GenerateSeed(&rng->seed,
459 entropy, ENTROPY_NONCE_SZ) == 0 &&
460 Hash_DRBG_Instantiate(rng->drbg,
461 entropy, ENTROPY_NONCE_SZ, NULL, 0) == DRBG_SUCCESS) {
462
463 ret = Hash_DRBG_Generate(rng->drbg, NULL, 0);
464 }
465 else
466 ret = DRBG_FAILURE;
467
468 ForceZero(entropy, ENTROPY_NONCE_SZ);
469 }
470 else
471 ret = DRBG_CONT_FAILURE;
472
473 if (ret == DRBG_SUCCESS) {
474 rng->status = DRBG_OK;
475 ret = 0;
476 }
477 else if (ret == DRBG_CONT_FAILURE) {
478 rng->status = DRBG_CONT_FAILED;
479 ret = DRBG_CONT_FIPS_E;
480 }
481 else if (ret == DRBG_FAILURE) {
482 rng->status = DRBG_FAILED;
483 ret = RNG_FAILURE_E;
484 }
485 else {
486 rng->status = DRBG_FAILED;
487 }
488 }
489
490 return ret;
491}
492
493
494/* place a generated block in output */
495int wc_RNG_GenerateBlock(WC_RNG* rng, byte* output, word32 sz)
496{
497 int ret;
498
499 if (rng == NULL || output == NULL || sz > MAX_REQUEST_LEN)
500 return BAD_FUNC_ARG;
501
502 if (rng->status != DRBG_OK)
503 return RNG_FAILURE_E;
504
505 ret = Hash_DRBG_Generate(rng->drbg, output, sz);
506
507 if (ret == DRBG_NEED_RESEED) {
508 if (wc_RNG_HealthTestLocal(1) == 0) {
509 byte entropy[ENTROPY_SZ];
510
511 if (wc_GenerateSeed(&rng->seed, entropy, ENTROPY_SZ) == 0 &&
512 Hash_DRBG_Reseed(rng->drbg, entropy, ENTROPY_SZ)
513 == DRBG_SUCCESS) {
514
515 ret = Hash_DRBG_Generate(rng->drbg, NULL, 0);
516 if (ret == DRBG_SUCCESS)
517 ret = Hash_DRBG_Generate(rng->drbg, output, sz);
518 }
519 else
520 ret = DRBG_FAILURE;
521
522 ForceZero(entropy, ENTROPY_SZ);
523 }
524 else
525 ret = DRBG_CONT_FAILURE;
526 }
527
528 if (ret == DRBG_SUCCESS) {
529 ret = 0;
530 }
531 else if (ret == DRBG_CONT_FAILURE) {
532 ret = DRBG_CONT_FIPS_E;
533 rng->status = DRBG_CONT_FAILED;
534 }
535 else {
536 ret = RNG_FAILURE_E;
537 rng->status = DRBG_FAILED;
538 }
539
540 return ret;
541}
542
543
544int wc_RNG_GenerateByte(WC_RNG* rng, byte* b)
545{
546 return wc_RNG_GenerateBlock(rng, b, 1);
547}
548
549
550int wc_FreeRng(WC_RNG* rng)
551{
552 int ret = BAD_FUNC_ARG;
553
554 if (rng != NULL) {
555 if (rng->drbg != NULL) {
556 if (Hash_DRBG_Uninstantiate(rng->drbg) == DRBG_SUCCESS)
557 ret = 0;
558 else
559 ret = RNG_FAILURE_E;
560
561 XFREE(rng->drbg, NULL, DYNAMIC_TYPE_RNG);
562 rng->drbg = NULL;
563 }
564
565 rng->status = DRBG_NOT_INIT;
566 }
567
568 return ret;
569}
570
571
572int wc_RNG_HealthTest(int reseed, const byte* entropyA, word32 entropyASz,
573 const byte* entropyB, word32 entropyBSz,
574 byte* output, word32 outputSz)
575{
576 DRBG drbg;
577
578 if (entropyA == NULL || output == NULL)
579 return BAD_FUNC_ARG;
580
581 if (reseed != 0 && entropyB == NULL)
582 return BAD_FUNC_ARG;
583
584 if (outputSz != (SHA256_DIGEST_SIZE * 4))
585 return -1;
586
587 if (Hash_DRBG_Instantiate(&drbg, entropyA, entropyASz, NULL, 0) != 0)
588 return -1;
589
590 if (reseed) {
591 if (Hash_DRBG_Reseed(&drbg, entropyB, entropyBSz) != 0) {
592 Hash_DRBG_Uninstantiate(&drbg);
593 return -1;
594 }
595 }
596
597 if (Hash_DRBG_Generate(&drbg, output, outputSz) != 0) {
598 Hash_DRBG_Uninstantiate(&drbg);
599 return -1;
600 }
601
602 if (Hash_DRBG_Generate(&drbg, output, outputSz) != 0) {
603 Hash_DRBG_Uninstantiate(&drbg);
604 return -1;
605 }
606
607 if (Hash_DRBG_Uninstantiate(&drbg) != 0) {
608 return -1;
609 }
610
611 return 0;
612}
613
614
615const byte entropyA[] = {
616 0x63, 0x36, 0x33, 0x77, 0xe4, 0x1e, 0x86, 0x46, 0x8d, 0xeb, 0x0a, 0xb4,
617 0xa8, 0xed, 0x68, 0x3f, 0x6a, 0x13, 0x4e, 0x47, 0xe0, 0x14, 0xc7, 0x00,
618 0x45, 0x4e, 0x81, 0xe9, 0x53, 0x58, 0xa5, 0x69, 0x80, 0x8a, 0xa3, 0x8f,
619 0x2a, 0x72, 0xa6, 0x23, 0x59, 0x91, 0x5a, 0x9f, 0x8a, 0x04, 0xca, 0x68
620};
621
622const byte reseedEntropyA[] = {
623 0xe6, 0x2b, 0x8a, 0x8e, 0xe8, 0xf1, 0x41, 0xb6, 0x98, 0x05, 0x66, 0xe3,
624 0xbf, 0xe3, 0xc0, 0x49, 0x03, 0xda, 0xd4, 0xac, 0x2c, 0xdf, 0x9f, 0x22,
625 0x80, 0x01, 0x0a, 0x67, 0x39, 0xbc, 0x83, 0xd3
626};
627
628const byte outputA[] = {
629 0x04, 0xee, 0xc6, 0x3b, 0xb2, 0x31, 0xdf, 0x2c, 0x63, 0x0a, 0x1a, 0xfb,
630 0xe7, 0x24, 0x94, 0x9d, 0x00, 0x5a, 0x58, 0x78, 0x51, 0xe1, 0xaa, 0x79,
631 0x5e, 0x47, 0x73, 0x47, 0xc8, 0xb0, 0x56, 0x62, 0x1c, 0x18, 0xbd, 0xdc,
632 0xdd, 0x8d, 0x99, 0xfc, 0x5f, 0xc2, 0xb9, 0x20, 0x53, 0xd8, 0xcf, 0xac,
633 0xfb, 0x0b, 0xb8, 0x83, 0x12, 0x05, 0xfa, 0xd1, 0xdd, 0xd6, 0xc0, 0x71,
634 0x31, 0x8a, 0x60, 0x18, 0xf0, 0x3b, 0x73, 0xf5, 0xed, 0xe4, 0xd4, 0xd0,
635 0x71, 0xf9, 0xde, 0x03, 0xfd, 0x7a, 0xea, 0x10, 0x5d, 0x92, 0x99, 0xb8,
636 0xaf, 0x99, 0xaa, 0x07, 0x5b, 0xdb, 0x4d, 0xb9, 0xaa, 0x28, 0xc1, 0x8d,
637 0x17, 0x4b, 0x56, 0xee, 0x2a, 0x01, 0x4d, 0x09, 0x88, 0x96, 0xff, 0x22,
638 0x82, 0xc9, 0x55, 0xa8, 0x19, 0x69, 0xe0, 0x69, 0xfa, 0x8c, 0xe0, 0x07,
639 0xa1, 0x80, 0x18, 0x3a, 0x07, 0xdf, 0xae, 0x17
640};
641
642const byte entropyB[] = {
643 0xa6, 0x5a, 0xd0, 0xf3, 0x45, 0xdb, 0x4e, 0x0e, 0xff, 0xe8, 0x75, 0xc3,
644 0xa2, 0xe7, 0x1f, 0x42, 0xc7, 0x12, 0x9d, 0x62, 0x0f, 0xf5, 0xc1, 0x19,
645 0xa9, 0xef, 0x55, 0xf0, 0x51, 0x85, 0xe0, 0xfb, 0x85, 0x81, 0xf9, 0x31,
646 0x75, 0x17, 0x27, 0x6e, 0x06, 0xe9, 0x60, 0x7d, 0xdb, 0xcb, 0xcc, 0x2e
647};
648
649const byte outputB[] = {
650 0xd3, 0xe1, 0x60, 0xc3, 0x5b, 0x99, 0xf3, 0x40, 0xb2, 0x62, 0x82, 0x64,
651 0xd1, 0x75, 0x10, 0x60, 0xe0, 0x04, 0x5d, 0xa3, 0x83, 0xff, 0x57, 0xa5,
652 0x7d, 0x73, 0xa6, 0x73, 0xd2, 0xb8, 0xd8, 0x0d, 0xaa, 0xf6, 0xa6, 0xc3,
653 0x5a, 0x91, 0xbb, 0x45, 0x79, 0xd7, 0x3f, 0xd0, 0xc8, 0xfe, 0xd1, 0x11,
654 0xb0, 0x39, 0x13, 0x06, 0x82, 0x8a, 0xdf, 0xed, 0x52, 0x8f, 0x01, 0x81,
655 0x21, 0xb3, 0xfe, 0xbd, 0xc3, 0x43, 0xe7, 0x97, 0xb8, 0x7d, 0xbb, 0x63,
656 0xdb, 0x13, 0x33, 0xde, 0xd9, 0xd1, 0xec, 0xe1, 0x77, 0xcf, 0xa6, 0xb7,
657 0x1f, 0xe8, 0xab, 0x1d, 0xa4, 0x66, 0x24, 0xed, 0x64, 0x15, 0xe5, 0x1c,
658 0xcd, 0xe2, 0xc7, 0xca, 0x86, 0xe2, 0x83, 0x99, 0x0e, 0xea, 0xeb, 0x91,
659 0x12, 0x04, 0x15, 0x52, 0x8b, 0x22, 0x95, 0x91, 0x02, 0x81, 0xb0, 0x2d,
660 0xd4, 0x31, 0xf4, 0xc9, 0xf7, 0x04, 0x27, 0xdf
661};
662
663
664static int wc_RNG_HealthTestLocal(int reseed)
665{
666 int ret = 0;
667 byte check[SHA256_DIGEST_SIZE * 4];
668
669 if (reseed) {
670 ret = wc_RNG_HealthTest(1, entropyA, sizeof(entropyA),
671 reseedEntropyA, sizeof(reseedEntropyA),
672 check, sizeof(check));
673 if (ret == 0) {
674 if (ConstantCompare(check, outputA, sizeof(check)) != 0)
675 ret = -1;
676 }
677 }
678 else {
679 ret = wc_RNG_HealthTest(0, entropyB, sizeof(entropyB),
680 NULL, 0,
681 check, sizeof(check));
682 if (ret == 0) {
683 if (ConstantCompare(check, outputB, sizeof(check)) != 0)
684 ret = -1;
685 }
686 }
687
688 return ret;
689}
690
691
692#else /* HAVE_HASHDRBG || NO_RC4 */
693
694/* Get seed and key cipher */
695int wc_InitRng(WC_RNG* rng)
696{
697 int ret;
698#ifdef WOLFSSL_SMALL_STACK
699 byte* key;
700 byte* junk;
701#else
702 byte key[32];
703 byte junk[256];
704#endif
705
706#ifdef HAVE_INTEL_RDGEN
707 wc_InitRng_IntelRD() ;
708 if(IS_INTEL_RDRAND)return 0 ;
709#endif
710#ifdef HAVE_CAVIUM
711 if (rng->magic == WOLFSSL_RNG_CAVIUM_MAGIC)
712 return 0;
713#endif
714
715#ifdef WOLFSSL_SMALL_STACK
716 key = (byte*)XMALLOC(32, NULL, DYNAMIC_TYPE_TMP_BUFFER);
717 if (key == NULL)
718 return MEMORY_E;
719
720 junk = (byte*)XMALLOC(256, NULL, DYNAMIC_TYPE_TMP_BUFFER);
721 if (junk == NULL) {
722 XFREE(key, NULL, DYNAMIC_TYPE_TMP_BUFFER);
723 return MEMORY_E;
724 }
725#endif
726
727 ret = wc_GenerateSeed(&rng->seed, key, 32);
728
729 if (ret == 0) {
730 wc_Arc4SetKey(&rng->cipher, key, sizeof(key));
731
732 ret = wc_RNG_GenerateBlock(rng, junk, 256); /*rid initial state*/
733 }
734
735#ifdef WOLFSSL_SMALL_STACK
736 XFREE(key, NULL, DYNAMIC_TYPE_TMP_BUFFER);
737 XFREE(junk, NULL, DYNAMIC_TYPE_TMP_BUFFER);
738#endif
739
740 return ret;
741}
742
743#ifdef HAVE_CAVIUM
744 static void CaviumRNG_GenerateBlock(WC_RNG* rng, byte* output, word32 sz);
745#endif
746
747/* place a generated block in output */
748int wc_RNG_GenerateBlock(WC_RNG* rng, byte* output, word32 sz)
749{
750#ifdef HAVE_INTEL_RDGEN
751 if(IS_INTEL_RDRAND)
752 return wc_GenerateRand_IntelRD(NULL, output, sz) ;
753#endif
754#ifdef HAVE_CAVIUM
755 if (rng->magic == WOLFSSL_RNG_CAVIUM_MAGIC)
756 return CaviumRNG_GenerateBlock(rng, output, sz);
757#endif
758 XMEMSET(output, 0, sz);
759 wc_Arc4Process(&rng->cipher, output, output, sz);
760
761 return 0;
762}
763
764
765int wc_RNG_GenerateByte(WC_RNG* rng, byte* b)
766{
767 return wc_RNG_GenerateBlock(rng, b, 1);
768}
769
770
771int wc_FreeRng(WC_RNG* rng)
772{
773 (void)rng;
774 return 0;
775}
776
777
778#ifdef HAVE_CAVIUM
779
780#include <wolfssl/ctaocrypt/logging.h>
781#include "cavium_common.h"
782
783/* Initiliaze RNG for use with Nitrox device */
784int wc_InitRngCavium(WC_RNG* rng, int devId)
785{
786 if (rng == NULL)
787 return -1;
788
789 rng->devId = devId;
790 rng->magic = WOLFSSL_RNG_CAVIUM_MAGIC;
791
792 return 0;
793}
794
795
796static void CaviumRNG_GenerateBlock(WC_RNG* rng, byte* output, word32 sz)
797{
798 wolfssl_word offset = 0;
799 word32 requestId;
800
801 while (sz > WOLFSSL_MAX_16BIT) {
802 word16 slen = (word16)WOLFSSL_MAX_16BIT;
803 if (CspRandom(CAVIUM_BLOCKING, slen, output + offset, &requestId,
804 rng->devId) != 0) {
805 WOLFSSL_MSG("Cavium RNG failed");
806 }
807 sz -= WOLFSSL_MAX_16BIT;
808 offset += WOLFSSL_MAX_16BIT;
809 }
810 if (sz) {
811 word16 slen = (word16)sz;
812 if (CspRandom(CAVIUM_BLOCKING, slen, output + offset, &requestId,
813 rng->devId) != 0) {
814 WOLFSSL_MSG("Cavium RNG failed");
815 }
816 }
817}
818
819#endif /* HAVE_CAVIUM */
820
821#endif /* HAVE_HASHDRBG || NO_RC4 */
822
823
824#if defined(HAVE_INTEL_RDGEN)
825
826#ifndef _MSC_VER
827 #define cpuid(reg, leaf, sub)\
828 __asm__ __volatile__ ("cpuid":\
829 "=a" (reg[0]), "=b" (reg[1]), "=c" (reg[2]), "=d" (reg[3]) :\
830 "a" (leaf), "c"(sub));
831
832 #define XASM_LINK(f) asm(f)
833#else
834
835 #include <intrin.h>
836 #define cpuid(a,b) __cpuid((int*)a,b)
837
838 #define XASM_LINK(f)
839
840#endif /* _MSC_VER */
841
842#define EAX 0
843#define EBX 1
844#define ECX 2
845#define EDX 3
846
847static word32 cpuid_flag(word32 leaf, word32 sub, word32 num, word32 bit) {
848 int got_intel_cpu=0;
849 unsigned int reg[5];
850
851 reg[4] = '\0' ;
852 cpuid(reg, 0, 0);
853 if(memcmp((char *)&(reg[EBX]), "Genu", 4) == 0 &&
854 memcmp((char *)&(reg[EDX]), "ineI", 4) == 0 &&
855 memcmp((char *)&(reg[ECX]), "ntel", 4) == 0) {
856 got_intel_cpu = 1;
857 }
858 if (got_intel_cpu) {
859 cpuid(reg, leaf, sub);
860 return((reg[num]>>bit)&0x1) ;
861 }
862 return 0 ;
863}
864
865static int wc_InitRng_IntelRD()
866{
867 if(cpuid_check==0) {
868 if(cpuid_flag(1, 0, ECX, 30)){ cpuid_flags |= CPUID_RDRAND ;}
869 if(cpuid_flag(7, 0, EBX, 18)){ cpuid_flags |= CPUID_RDSEED ;}
870 cpuid_check = 1 ;
871 }
872 return 1 ;
873}
874
875#define INTELRD_RETRY 10
876
877#if defined(HAVE_HASHDRBG) || defined(NO_RC4)
878
879/* return 0 on success */
880static INLINE int IntelRDseed32(unsigned int *seed)
881{
882 int rdseed; unsigned char ok ;
883
884 __asm__ volatile("rdseed %0; setc %1":"=r"(rdseed), "=qm"(ok));
885 if(ok){
886 *seed = rdseed ;
887 return 0 ;
888 } else
889 return 1;
890}
891
892/* return 0 on success */
893static INLINE int IntelRDseed32_r(unsigned int *rnd)
894{
895 int i ;
896 for(i=0; i<INTELRD_RETRY;i++) {
897 if(IntelRDseed32(rnd) == 0) return 0 ;
898 }
899 return 1 ;
900}
901
902/* return 0 on success */
903static int wc_GenerateSeed_IntelRD(OS_Seed* os, byte* output, word32 sz)
904{
905 (void) os ;
906 int ret ;
907 unsigned int rndTmp ;
908
909 for( ; sz/4 > 0; sz-=4, output+=4) {
910 if(IS_INTEL_RDSEED)ret = IntelRDseed32_r((word32 *)output) ;
911 else return 1 ;
912 if(ret)
913 return 1 ;
914 }
915 if(sz == 0)return 0 ;
916
917 if(IS_INTEL_RDSEED)ret = IntelRDseed32_r(&rndTmp) ;
918 else return 1 ;
919 if(ret)
920 return 1 ;
921 XMEMCPY(output, &rndTmp, sz) ;
922 return 0;
923}
924
925#else
926
927/* return 0 on success */
928static INLINE int IntelRDrand32(unsigned int *rnd)
929{
930 int rdrand; unsigned char ok ;
931 __asm__ volatile("rdrand %0; setc %1":"=r"(rdrand), "=qm"(ok));
932 if(ok){
933 *rnd = rdrand;
934 return 0 ;
935 } else
936 return 1;
937}
938
939/* return 0 on success */
940static INLINE int IntelRDrand32_r(unsigned int *rnd)
941{
942 int i ;
943 for(i=0; i<INTELRD_RETRY;i++) {
944 if(IntelRDrand32(rnd) == 0) return 0 ;
945 }
946 return 1 ;
947}
948
949/* return 0 on success */
950static int wc_GenerateRand_IntelRD(OS_Seed* os, byte* output, word32 sz)
951{
952 (void) os ;
953 int ret ;
954 unsigned int rndTmp;
955
956 for( ; sz/4 > 0; sz-=4, output+=4) {
957 if(IS_INTEL_RDRAND)ret = IntelRDrand32_r((word32 *)output);
958 else return 1 ;
959 if(ret)
960 return 1 ;
961 }
962 if(sz == 0)return 0 ;
963
964 if(IS_INTEL_RDRAND)ret = IntelRDrand32_r(&rndTmp);
965 else return 1 ;
966 if(ret)
967 return 1 ;
968 XMEMCPY(output, &rndTmp, sz) ;
969 return 0;
970}
971#endif /* defined(HAVE_HASHDRBG) || defined(NO_RC4) */
972
973#endif /* HAVE_INTEL_RDGEN */
974
975
976#if defined(USE_WINDOWS_API)
977
978
979int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
980{
981 if(!CryptAcquireContext(&os->handle, 0, 0, PROV_RSA_FULL,
982 CRYPT_VERIFYCONTEXT))
983 return WINCRYPT_E;
984
985 if (!CryptGenRandom(os->handle, sz, output))
986 return CRYPTGEN_E;
987
988 CryptReleaseContext(os->handle, 0);
989
990 return 0;
991}
992
993
994#elif defined(HAVE_RTP_SYS) || defined(EBSNET)
995
996#include "rtprand.h" /* rtp_rand () */
997#include "rtptime.h" /* rtp_get_system_msec() */
998
999
1000int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
1001{
1002 int i;
1003 rtp_srand(rtp_get_system_msec());
1004
1005 for (i = 0; i < sz; i++ ) {
1006 output[i] = rtp_rand() % 256;
1007 if ( (i % 8) == 7)
1008 rtp_srand(rtp_get_system_msec());
1009 }
1010
1011 return 0;
1012}
1013
1014
1015#elif defined(MICRIUM)
1016
1017int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
1018{
1019 #if (NET_SECURE_MGR_CFG_EN == DEF_ENABLED)
1020 NetSecure_InitSeed(output, sz);
1021 #endif
1022 return 0;
1023}
1024
1025#elif defined(MICROCHIP_PIC32)
1026
1027#ifdef MICROCHIP_MPLAB_HARMONY
1028 #define PIC32_SEED_COUNT _CP0_GET_COUNT
1029#else
1030 #if !defined(WOLFSSL_MICROCHIP_PIC32MZ)
1031 #include <peripheral/timer.h>
1032 #endif
1033 #define PIC32_SEED_COUNT ReadCoreTimer
1034#endif
1035 #ifdef WOLFSSL_MIC32MZ_RNG
1036 #include "xc.h"
1037 int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
1038 {
1039 int i ;
1040 byte rnd[8] ;
1041 word32 *rnd32 = (word32 *)rnd ;
1042 word32 size = sz ;
1043 byte* op = output ;
1044
1045 /* This part has to be replaced with better random seed */
1046 RNGNUMGEN1 = ReadCoreTimer();
1047 RNGPOLY1 = ReadCoreTimer();
1048 RNGPOLY2 = ReadCoreTimer();
1049 RNGNUMGEN2 = ReadCoreTimer();
1050#ifdef DEBUG_WOLFSSL
1051 printf("GenerateSeed::Seed=%08x, %08x\n", RNGNUMGEN1, RNGNUMGEN2) ;
1052#endif
1053 RNGCONbits.PLEN = 0x40;
1054 RNGCONbits.PRNGEN = 1;
1055 for(i=0; i<5; i++) { /* wait for RNGNUMGEN ready */
1056 volatile int x ;
1057 x = RNGNUMGEN1 ;
1058 x = RNGNUMGEN2 ;
1059 }
1060 do {
1061 rnd32[0] = RNGNUMGEN1;
1062 rnd32[1] = RNGNUMGEN2;
1063
1064 for(i=0; i<8; i++, op++) {
1065 *op = rnd[i] ;
1066 size -- ;
1067 if(size==0)break ;
1068 }
1069 } while(size) ;
1070 return 0;
1071 }
1072 #else /* WOLFSSL_MIC32MZ_RNG */
1073 /* uses the core timer, in nanoseconds to seed srand */
1074 int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
1075 {
1076 int i;
1077 srand(PIC32_SEED_COUNT() * 25);
1078
1079 for (i = 0; i < sz; i++ ) {
1080 output[i] = rand() % 256;
1081 if ( (i % 8) == 7)
1082 srand(PIC32_SEED_COUNT() * 25);
1083 }
1084 return 0;
1085 }
1086 #endif /* WOLFSSL_MIC32MZ_RNG */
1087
1088#elif defined(FREESCALE_MQX) || defined(FREESCALE_KSDK_MQX) || \
1089 defined(FREESCALE_KSDK_BM) || defined(FREESCALE_FREE_RTOS)
1090
1091 #ifdef FREESCALE_K70_RNGA
1092 /*
1093 * wc_Generates a RNG seed using the Random Number Generator Accelerator
1094 * on the Kinetis K70. Documentation located in Chapter 37 of
1095 * K70 Sub-Family Reference Manual (see Note 3 in the README for link).
1096 */
1097 int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
1098 {
1099 int i;
1100
1101 /* turn on RNGA module */
1102 SIM_SCGC3 |= SIM_SCGC3_RNGA_MASK;
1103
1104 /* set SLP bit to 0 - "RNGA is not in sleep mode" */
1105 RNG_CR &= ~RNG_CR_SLP_MASK;
1106
1107 /* set HA bit to 1 - "security violations masked" */
1108 RNG_CR |= RNG_CR_HA_MASK;
1109
1110 /* set GO bit to 1 - "output register loaded with data" */
1111 RNG_CR |= RNG_CR_GO_MASK;
1112
1113 for (i = 0; i < sz; i++) {
1114
1115 /* wait for RNG FIFO to be full */
1116 while((RNG_SR & RNG_SR_OREG_LVL(0xF)) == 0) {}
1117
1118 /* get value */
1119 output[i] = RNG_OR;
1120 }
1121
1122 return 0;
1123 }
1124
1125 #elif defined(FREESCALE_K53_RNGB)
1126 /*
1127 * wc_Generates a RNG seed using the Random Number Generator (RNGB)
1128 * on the Kinetis K53. Documentation located in Chapter 33 of
1129 * K53 Sub-Family Reference Manual (see note in the README for link).
1130 */
1131 int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
1132 {
1133 int i;
1134
1135 /* turn on RNGB module */
1136 SIM_SCGC3 |= SIM_SCGC3_RNGB_MASK;
1137
1138 /* reset RNGB */
1139 RNG_CMD |= RNG_CMD_SR_MASK;
1140
1141 /* FIFO generate interrupt, return all zeros on underflow,
1142 * set auto reseed */
1143 RNG_CR |= (RNG_CR_FUFMOD_MASK | RNG_CR_AR_MASK);
1144
1145 /* gen seed, clear interrupts, clear errors */
1146 RNG_CMD |= (RNG_CMD_GS_MASK | RNG_CMD_CI_MASK | RNG_CMD_CE_MASK);
1147
1148 /* wait for seeding to complete */
1149 while ((RNG_SR & RNG_SR_SDN_MASK) == 0) {}
1150
1151 for (i = 0; i < sz; i++) {
1152
1153 /* wait for a word to be available from FIFO */
1154 while((RNG_SR & RNG_SR_FIFO_LVL_MASK) == 0) {}
1155
1156 /* get value */
1157 output[i] = RNG_OUT;
1158 }
1159
1160 return 0;
1161 }
1162
1163 #elif defined(FREESCALE_TRNG)
1164
1165 int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
1166 {
1167 TRNG_DRV_GetRandomData(TRNG_INSTANCE, output, sz);
1168 return(0);
1169 }
1170
1171 #else
1172 #warning "write a real random seed!!!!, just for testing now"
1173
1174 int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
1175 {
1176 int i;
1177 for (i = 0; i < sz; i++ )
1178 output[i] = i;
1179
1180 return 0;
1181 }
1182 #endif /* FREESCALE_K70_RNGA */
1183
1184#elif defined(WOLFSSL_SAFERTOS) || defined(WOLFSSL_LEANPSK) \
1185 || defined(WOLFSSL_IAR_ARM) || defined(WOLFSSL_MDK_ARM) \
1186 || defined(WOLFSSL_uITRON4) || defined(WOLFSSL_uTKERNEL2)\
1187 || defined(WOLFSSL_GENSEED_FORTEST)
1188
1189#if 0 //ndef _MSC_VER
1190#warning "write a real random seed!!!!, just for testing now"
1191//#else
1192#pragma message("Warning: write a real random seed!!!!, just for testing now")
1193
1194int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
1195{
1196 word32 i;
1197 for (i = 0; i < sz; i++ )
1198 output[i] = i;
1199
1200 (void)os;
1201
1202 return 0;
1203}
1204#endif
1205
1206#elif defined(STM32F2_RNG)
1207 #undef RNG
1208 #include "stm32f2xx_rng.h"
1209 #include "stm32f2xx_rcc.h"
1210 /*
1211 * wc_Generate a RNG seed using the hardware random number generator
1212 * on the STM32F2. Documentation located in STM32F2xx Standard Peripheral
1213 * Library document (See note in README).
1214 */
1215 int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
1216 {
1217 int i;
1218
1219 /* enable RNG clock source */
1220 RCC_AHB2PeriphClockCmd(RCC_AHB2Periph_RNG, ENABLE);
1221
1222 /* enable RNG peripheral */
1223 RNG_Cmd(ENABLE);
1224
1225 for (i = 0; i < sz; i++) {
1226 /* wait until RNG number is ready */
1227 while(RNG_GetFlagStatus(RNG_FLAG_DRDY)== RESET) { }
1228
1229 /* get value */
1230 output[i] = RNG_GetRandomNumber();
1231 }
1232
1233 return 0;
1234 }
1235#elif defined(WOLFSSL_LPC43xx) || defined(WOLFSSL_STM32F2xx) || defined(MBED)
1236
1237 #warning "write a real random seed!!!!, just for testing now"
1238
1239 int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
1240 {
1241 int i;
1242
1243 for (i = 0; i < sz; i++ )
1244 output[i] = i;
1245
1246 return 0;
1247 }
1248
1249#elif defined(WOLFSSL_TIRTOS)
1250
1251 #include <xdc/runtime/Timestamp.h>
1252 #include <stdlib.h>
1253 int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
1254 {
1255 int i;
1256 srand(xdc_runtime_Timestamp_get32());
1257
1258 for (i = 0; i < sz; i++ ) {
1259 output[i] = rand() % 256;
1260 if ((i % 8) == 7) {
1261 srand(xdc_runtime_Timestamp_get32());
1262 }
1263 }
1264
1265 return 0;
1266 }
1267
1268#elif defined(CUSTOM_RAND_GENERATE)
1269
1270 /* Implement your own random generation function
1271 * word32 rand_gen(void);
1272 * #define CUSTOM_RAND_GENERATE rand_gen */
1273
1274 int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
1275 {
1276 word32 i;
1277
1278 (void)os;
1279
1280 for (i = 0; i < sz; i++ )
1281 output[i] = CUSTOM_RAND_GENERATE();
1282
1283 return 0;
1284 }
1285
1286#elif defined(NO_DEV_RANDOM)
1287
1288#error "you need to write an os specific wc_GenerateSeed() here"
1289
1290/*
1291int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
1292{
1293 return 0;
1294}
1295*/
1296
1297
1298#elif defined(IDIRECT_DEV_RANDOM)
1299
1300extern int getRandom( int sz, unsigned char *output );
1301
1302int GenerateSeed(OS_Seed* os, byte* output, word32 sz)
1303{
1304 int num_bytes_returned = 0;
1305
1306 num_bytes_returned = getRandom( (int) sz, (unsigned char *) output );
1307
1308 return 0;
1309}
1310
1311
1312#else /* !USE_WINDOWS_API && !HAVE_RPT_SYS && !MICRIUM && !NO_DEV_RANDOM */
1313
1314/* may block */
1315int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
1316{
1317 int ret = 0;
1318
1319
1320#if defined(HAVE_INTEL_RDGEN) && (defined(HAVE_HASHDRBG) || defined(NO_RC4))
1321 wc_InitRng_IntelRD() ; /* set cpuid_flags if not yet */
1322 if(IS_INTEL_RDSEED)
1323 return wc_GenerateSeed_IntelRD(NULL, output, sz) ;
1324#endif
1325
1326 os->fd = open("/dev/urandom",O_RDONLY);
1327 if (os->fd == -1) {
1328 /* may still have /dev/random */
1329 os->fd = open("/dev/random",O_RDONLY);
1330 if (os->fd == -1)
1331 return OPEN_RAN_E;
1332 }
1333
1334 while (sz) {
1335 int len = (int)read(os->fd, output, sz);
1336 if (len == -1) {
1337 ret = READ_RAN_E;
1338 break;
1339 }
1340
1341 sz -= len;
1342 output += len;
1343
1344 if (sz) {
1345#ifdef BLOCKING
1346 sleep(0); /* context switch */
1347#else
1348 ret = RAN_BLOCK_E;
1349 break;
1350#endif
1351 }
1352 }
1353 close(os->fd);
1354
1355 return ret;
1356}
1357
1358#endif /* USE_WINDOWS_API */
1359#endif /* HAVE_FIPS */
1360
Note: See TracBrowser for help on using the repository browser.