Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of CyaSSL by
random.c
00001 /* random.c 00002 * 00003 * Copyright (C) 2006-2014 wolfSSL Inc. 00004 * 00005 * This file is part of CyaSSL. 00006 * 00007 * CyaSSL is free software; you can redistribute it and/or modify 00008 * it under the terms of the GNU General Public License as published by 00009 * the Free Software Foundation; either version 2 of the License, or 00010 * (at your option) any later version. 00011 * 00012 * CyaSSL is distributed in the hope that it will be useful, 00013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00015 * GNU General Public License for more details. 00016 * 00017 * You should have received a copy of the GNU General Public License 00018 * along with this program; if not, write to the Free Software 00019 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA 00020 */ 00021 00022 #ifdef HAVE_CONFIG_H 00023 #include <config.h> 00024 #endif 00025 00026 #include <cyassl/ctaocrypt/settings.h> 00027 00028 /* on HPUX 11 you may need to install /dev/random see 00029 http://h20293.www2.hp.com/portal/swdepot/displayProductInfo.do?productNumber=KRNG11I 00030 00031 */ 00032 00033 #include <cyassl/ctaocrypt/random.h> 00034 #include <cyassl/ctaocrypt/error-crypt.h> 00035 00036 #ifdef NO_RC4 00037 #include <cyassl/ctaocrypt/sha256.h> 00038 00039 #ifdef NO_INLINE 00040 #include <cyassl/ctaocrypt/misc.h> 00041 #else 00042 #define MISC_DUMM_FUNC misc_dummy_random 00043 #include <ctaocrypt/src/misc.c> 00044 #endif 00045 #endif 00046 00047 #if defined(USE_WINDOWS_API) 00048 #ifndef _WIN32_WINNT 00049 #define _WIN32_WINNT 0x0400 00050 #endif 00051 #include <windows.h> 00052 #include <wincrypt.h> 00053 #else 00054 #if !defined(NO_DEV_RANDOM) && !defined(CYASSL_MDK_ARM) \ 00055 && !defined(CYASSL_IAR_ARM) 00056 #include <fcntl.h> 00057 #ifndef EBSNET 00058 #include <unistd.h> 00059 #endif 00060 #else 00061 /* include headers that may be needed to get good seed */ 00062 #endif 00063 #endif /* USE_WINDOWS_API */ 00064 00065 00066 #ifdef NO_RC4 00067 00068 /* Start NIST DRBG code */ 00069 00070 #define OUTPUT_BLOCK_LEN (256/8) 00071 #define MAX_REQUEST_LEN (0x1000) 00072 #define MAX_STRING_LEN (0x100000000) 00073 #define RESEED_MAX (0x100000000000LL) 00074 #define ENTROPY_SZ 256 00075 00076 #define DBRG_SUCCESS 0 00077 #define DBRG_ERROR 1 00078 #define DBRG_NEED_RESEED 2 00079 00080 00081 enum { 00082 dbrgInitC = 0, 00083 dbrgReseed = 1, 00084 dbrgGenerateW = 2, 00085 dbrgGenerateH = 3, 00086 dbrgInitV 00087 }; 00088 00089 00090 static int Hash_df(RNG* rng, byte* out, word32 outSz, byte type, byte* inA, word32 inASz, 00091 byte* inB, word32 inBSz, byte* inC, word32 inCSz) 00092 { 00093 byte ctr; 00094 int i; 00095 int len; 00096 word32 bits = (outSz * 8); /* reverse byte order */ 00097 00098 #ifdef LITTLE_ENDIAN_ORDER 00099 bits = ByteReverseWord32(bits); 00100 #endif 00101 len = (outSz / SHA256_DIGEST_SIZE) 00102 + ((outSz % SHA256_DIGEST_SIZE) ? 1 : 0); 00103 00104 for (i = 0, ctr = 1; i < len; i++, ctr++) 00105 { 00106 if (InitSha256(&rng->sha) != 0) 00107 return DBRG_ERROR; 00108 00109 if (Sha256Update(&rng->sha, &ctr, sizeof(ctr)) != 0) 00110 return DBRG_ERROR; 00111 00112 if (Sha256Update(&rng->sha, (byte*)&bits, sizeof(bits)) != 0) 00113 return DBRG_ERROR; 00114 00115 /* churning V is the only string that doesn't have 00116 * the type added */ 00117 if (type != dbrgInitV) 00118 if (Sha256Update(&rng->sha, &type, sizeof(type)) != 0) 00119 return DBRG_ERROR; 00120 00121 if (Sha256Update(&rng->sha, inA, inASz) != 0) 00122 return DBRG_ERROR; 00123 00124 if (inB != NULL && inBSz > 0) 00125 if (Sha256Update(&rng->sha, inB, inBSz) != 0) 00126 return DBRG_ERROR; 00127 00128 if (inC != NULL && inCSz > 0) 00129 if (Sha256Update(&rng->sha, inC, inCSz) != 0) 00130 return DBRG_ERROR; 00131 00132 if (Sha256Final(&rng->sha, rng->digest) != 0) 00133 return DBRG_ERROR; 00134 00135 if (outSz > SHA256_DIGEST_SIZE) { 00136 XMEMCPY(out, rng->digest, SHA256_DIGEST_SIZE); 00137 outSz -= SHA256_DIGEST_SIZE; 00138 out += SHA256_DIGEST_SIZE; 00139 } 00140 else { 00141 XMEMCPY(out, rng->digest, outSz); 00142 } 00143 } 00144 00145 return DBRG_SUCCESS; 00146 } 00147 00148 00149 static int Hash_DBRG_Reseed(RNG* rng, byte* entropy, word32 entropySz) 00150 { 00151 int ret; 00152 byte seed[DBRG_SEED_LEN]; 00153 00154 ret = Hash_df(rng, seed, sizeof(seed), dbrgInitV, rng->V, sizeof(rng->V), 00155 entropy, entropySz, NULL, 0); 00156 if (ret != 0) 00157 return ret; 00158 00159 XMEMCPY(rng->V, seed, sizeof(rng->V)); 00160 XMEMSET(seed, 0, sizeof(seed)); 00161 00162 ret = Hash_df(rng, rng->C, sizeof(rng->C), dbrgInitC, rng->V, 00163 sizeof(rng->V), NULL, 0, NULL, 0); 00164 if (ret != 0) 00165 return ret; 00166 00167 rng->reseed_ctr = 1; 00168 return 0; 00169 } 00170 00171 static INLINE void array_add_one(byte* data, word32 dataSz) 00172 { 00173 int i; 00174 00175 for (i = dataSz - 1; i >= 0; i--) 00176 { 00177 data[i]++; 00178 if (data[i] != 0) break; 00179 } 00180 } 00181 00182 static int Hash_gen(RNG* rng, byte* out, word32 outSz, byte* V) 00183 { 00184 byte data[DBRG_SEED_LEN]; 00185 int i, ret; 00186 int len = (outSz / SHA256_DIGEST_SIZE) 00187 + ((outSz % SHA256_DIGEST_SIZE) ? 1 : 0); 00188 00189 XMEMCPY(data, V, sizeof(data)); 00190 for (i = 0; i < len; i++) { 00191 ret = InitSha256(&rng->sha); 00192 if (ret != 0) 00193 return ret; 00194 00195 ret = Sha256Update(&rng->sha, data, sizeof(data)); 00196 if (ret != 0) 00197 return ret; 00198 00199 ret = Sha256Final(&rng->sha, rng->digest); 00200 if (ret != 0) 00201 return ret; 00202 00203 if (outSz > SHA256_DIGEST_SIZE) { 00204 XMEMCPY(out, rng->digest, SHA256_DIGEST_SIZE); 00205 outSz -= SHA256_DIGEST_SIZE; 00206 out += SHA256_DIGEST_SIZE; 00207 array_add_one(data, DBRG_SEED_LEN); 00208 } 00209 else { 00210 XMEMCPY(out, rng->digest, outSz); 00211 } 00212 } 00213 XMEMSET(data, 0, sizeof(data)); 00214 00215 return 0; 00216 } 00217 00218 00219 static INLINE void array_add(byte* d, word32 dLen, byte* s, word32 sLen) 00220 { 00221 word16 carry = 0; 00222 00223 if (dLen > 0 && sLen > 0 && dLen >= sLen) { 00224 int sIdx, dIdx; 00225 00226 for (sIdx = sLen - 1, dIdx = dLen - 1; sIdx >= 0; dIdx--, sIdx--) 00227 { 00228 carry += d[dIdx] + s[sIdx]; 00229 d[dIdx] = carry; 00230 carry >>= 8; 00231 } 00232 if (dIdx > 0) 00233 d[dIdx] += carry; 00234 } 00235 } 00236 00237 00238 static int Hash_DBRG_Generate(RNG* rng, byte* out, word32 outSz) 00239 { 00240 int ret; 00241 00242 if (rng->reseed_ctr != RESEED_MAX) { 00243 byte type = dbrgGenerateH; 00244 00245 if (Hash_gen(rng, out, outSz, rng->V) != 0) 00246 return DBRG_ERROR; 00247 if (InitSha256(&rng->sha) != 0) 00248 return DBRG_ERROR; 00249 if (Sha256Update(&rng->sha, &type, sizeof(type)) != 0) 00250 return DBRG_ERROR; 00251 if (Sha256Update(&rng->sha, rng->V, sizeof(rng->V)) != 0) 00252 return DBRG_ERROR; 00253 if (Sha256Final(&rng->sha, rng->digest) != 0) 00254 return DBRG_ERROR; 00255 00256 array_add(rng->V, sizeof(rng->V), rng->digest, sizeof(rng->digest)); 00257 array_add(rng->V, sizeof(rng->V), rng->C, sizeof(rng->C)); 00258 array_add(rng->V, sizeof(rng->V), 00259 (byte*)&rng->reseed_ctr, sizeof(rng->reseed_ctr)); 00260 rng->reseed_ctr++; 00261 ret = DBRG_SUCCESS; 00262 } 00263 else { 00264 ret = DBRG_NEED_RESEED; 00265 } 00266 return ret; 00267 } 00268 00269 00270 static int Hash_DBRG_Instantiate(RNG* rng, byte* seed, word32 seedSz) 00271 { 00272 int ret; 00273 00274 XMEMSET(rng, 0, sizeof(*rng)); 00275 ret = Hash_df(rng, rng->V, sizeof(rng->V), dbrgInitV, seed, seedSz, NULL, 0, 00276 NULL, 0); 00277 if (ret != 0) 00278 return ret; 00279 00280 ret = Hash_df(rng, rng->C, sizeof(rng->C), dbrgInitC, rng->V, 00281 sizeof(rng->V), NULL, 0, NULL, 0); 00282 if (ret != 0) 00283 return ret; 00284 00285 rng->reseed_ctr = 1; 00286 00287 return 0; 00288 } 00289 00290 00291 static int Hash_DBRG_Uninstantiate(RNG* rng) 00292 { 00293 int result = DBRG_ERROR; 00294 00295 if (rng != NULL) { 00296 XMEMSET(rng, 0, sizeof(*rng)); 00297 result = DBRG_SUCCESS; 00298 } 00299 00300 return result; 00301 } 00302 00303 /* End NIST DRBG Code */ 00304 00305 00306 00307 /* Get seed and key cipher */ 00308 int InitRng(RNG* rng) 00309 { 00310 #ifdef CYASSL_SMALL_STACK 00311 byte* entropy; 00312 #else 00313 byte entropy[ENTROPY_SZ]; 00314 #endif 00315 int ret = DBRG_ERROR; 00316 00317 #ifdef CYASSL_SMALL_STACK 00318 entropy = (byte*)XMALLOC(ENTROPY_SZ, NULL, DYNAMIC_TYPE_TMP_BUFFER); 00319 if (entropy == NULL) 00320 return MEMORY_E; 00321 #endif 00322 00323 if (GenerateSeed(&rng->seed, entropy, ENTROPY_SZ) == 0) 00324 ret = Hash_DBRG_Instantiate(rng, entropy, ENTROPY_SZ); 00325 00326 XMEMSET(entropy, 0, ENTROPY_SZ); 00327 00328 #ifdef CYASSL_SMALL_STACK 00329 XFREE(entropy, NULL, DYNAMIC_TYPE_TMP_BUFFER); 00330 #endif 00331 00332 return ret; 00333 } 00334 00335 00336 /* place a generated block in output */ 00337 int RNG_GenerateBlock(RNG* rng, byte* output, word32 sz) 00338 { 00339 int ret; 00340 00341 XMEMSET(output, 0, sz); 00342 ret = Hash_DBRG_Generate(rng, output, sz); 00343 00344 if (ret == DBRG_NEED_RESEED) { 00345 #ifdef CYASSL_SMALL_STACK 00346 byte* entropy; 00347 #else 00348 byte entropy[ENTROPY_SZ]; 00349 #endif 00350 00351 #ifdef CYASSL_SMALL_STACK 00352 entropy = (byte*)XMALLOC(ENTROPY_SZ, NULL, DYNAMIC_TYPE_TMP_BUFFER); 00353 if (entropy == NULL) 00354 return MEMORY_E; 00355 #endif 00356 00357 ret = GenerateSeed(&rng->seed, entropy, ENTROPY_SZ); 00358 if (ret == 0) { 00359 ret = Hash_DBRG_Reseed(rng, entropy, ENTROPY_SZ); 00360 00361 if (ret == 0) 00362 ret = Hash_DBRG_Generate(rng, output, sz); 00363 } 00364 else 00365 ret = DBRG_ERROR; 00366 00367 XMEMSET(entropy, 0, ENTROPY_SZ); 00368 00369 #ifdef CYASSL_SMALL_STACK 00370 XFREE(entropy, NULL, DYNAMIC_TYPE_TMP_BUFFER); 00371 #endif 00372 } 00373 00374 return ret; 00375 } 00376 00377 00378 int RNG_GenerateByte(RNG* rng, byte* b) 00379 { 00380 return RNG_GenerateBlock(rng, b, 1); 00381 } 00382 00383 00384 void FreeRng(RNG* rng) 00385 { 00386 Hash_DBRG_Uninstantiate(rng); 00387 } 00388 00389 #else /* NO_RC4 */ 00390 00391 /* Get seed and key cipher */ 00392 int InitRng(RNG* rng) 00393 { 00394 int ret; 00395 #ifdef CYASSL_SMALL_STACK 00396 byte* key; 00397 byte* junk; 00398 #else 00399 byte key[32]; 00400 byte junk[256]; 00401 #endif 00402 00403 #ifdef HAVE_CAVIUM 00404 if (rng->magic == CYASSL_RNG_CAVIUM_MAGIC) 00405 return 0; 00406 #endif 00407 00408 #ifdef CYASSL_SMALL_STACK 00409 key = (byte*)XMALLOC(32, NULL, DYNAMIC_TYPE_TMP_BUFFER); 00410 if (key == NULL) 00411 return MEMORY_E; 00412 00413 junk = (byte*)XMALLOC(256, NULL, DYNAMIC_TYPE_TMP_BUFFER); 00414 if (junk == NULL) { 00415 XFREE(key, NULL, DYNAMIC_TYPE_TMP_BUFFER); 00416 return MEMORY_E; 00417 } 00418 #endif 00419 00420 ret = GenerateSeed(&rng->seed, key, 32); 00421 00422 if (ret == 0) { 00423 Arc4SetKey(&rng->cipher, key, sizeof(key)); 00424 00425 ret = RNG_GenerateBlock(rng, junk, 256); /*rid initial state*/ 00426 } 00427 00428 #ifdef CYASSL_SMALL_STACK 00429 XFREE(key, NULL, DYNAMIC_TYPE_TMP_BUFFER); 00430 XFREE(junk, NULL, DYNAMIC_TYPE_TMP_BUFFER); 00431 #endif 00432 00433 return ret; 00434 } 00435 00436 #ifdef HAVE_CAVIUM 00437 static void CaviumRNG_GenerateBlock(RNG* rng, byte* output, word32 sz); 00438 #endif 00439 00440 /* place a generated block in output */ 00441 int RNG_GenerateBlock(RNG* rng, byte* output, word32 sz) 00442 { 00443 #ifdef HAVE_CAVIUM 00444 if (rng->magic == CYASSL_RNG_CAVIUM_MAGIC) 00445 return CaviumRNG_GenerateBlock(rng, output, sz); 00446 #endif 00447 XMEMSET(output, 0, sz); 00448 Arc4Process(&rng->cipher, output, output, sz); 00449 00450 return 0; 00451 } 00452 00453 00454 int RNG_GenerateByte(RNG* rng, byte* b) 00455 { 00456 return RNG_GenerateBlock(rng, b, 1); 00457 } 00458 00459 00460 #ifdef HAVE_CAVIUM 00461 00462 #include <cyassl/ctaocrypt/logging.h> 00463 #include "cavium_common.h" 00464 00465 /* Initiliaze RNG for use with Nitrox device */ 00466 int InitRngCavium(RNG* rng, int devId) 00467 { 00468 if (rng == NULL) 00469 return -1; 00470 00471 rng->devId = devId; 00472 rng->magic = CYASSL_RNG_CAVIUM_MAGIC; 00473 00474 return 0; 00475 } 00476 00477 00478 static void CaviumRNG_GenerateBlock(RNG* rng, byte* output, word32 sz) 00479 { 00480 word offset = 0; 00481 word32 requestId; 00482 00483 while (sz > CYASSL_MAX_16BIT) { 00484 word16 slen = (word16)CYASSL_MAX_16BIT; 00485 if (CspRandom(CAVIUM_BLOCKING, slen, output + offset, &requestId, 00486 rng->devId) != 0) { 00487 CYASSL_MSG("Cavium RNG failed"); 00488 } 00489 sz -= CYASSL_MAX_16BIT; 00490 offset += CYASSL_MAX_16BIT; 00491 } 00492 if (sz) { 00493 word16 slen = (word16)sz; 00494 if (CspRandom(CAVIUM_BLOCKING, slen, output + offset, &requestId, 00495 rng->devId) != 0) { 00496 CYASSL_MSG("Cavium RNG failed"); 00497 } 00498 } 00499 } 00500 00501 #endif /* HAVE_CAVIUM */ 00502 00503 #endif /* NO_RC4 */ 00504 00505 00506 #if defined(USE_WINDOWS_API) 00507 00508 00509 int GenerateSeed(OS_Seed* os, byte* output, word32 sz) 00510 { 00511 if(!CryptAcquireContext(&os->handle, 0, 0, PROV_RSA_FULL, 00512 CRYPT_VERIFYCONTEXT)) 00513 return WINCRYPT_E; 00514 00515 if (!CryptGenRandom(os->handle, sz, output)) 00516 return CRYPTGEN_E; 00517 00518 CryptReleaseContext(os->handle, 0); 00519 00520 return 0; 00521 } 00522 00523 00524 #elif defined(HAVE_RTP_SYS) || defined(EBSNET) 00525 00526 #include "rtprand.h" /* rtp_rand () */ 00527 #include "rtptime.h" /* rtp_get_system_msec() */ 00528 00529 00530 int GenerateSeed(OS_Seed* os, byte* output, word32 sz) 00531 { 00532 int i; 00533 rtp_srand(rtp_get_system_msec()); 00534 00535 for (i = 0; i < sz; i++ ) { 00536 output[i] = rtp_rand() % 256; 00537 if ( (i % 8) == 7) 00538 rtp_srand(rtp_get_system_msec()); 00539 } 00540 00541 return 0; 00542 } 00543 00544 00545 #elif defined(MICRIUM) 00546 00547 int GenerateSeed(OS_Seed* os, byte* output, word32 sz) 00548 { 00549 #if (NET_SECURE_MGR_CFG_EN == DEF_ENABLED) 00550 NetSecure_InitSeed(output, sz); 00551 #endif 00552 return 0; 00553 } 00554 00555 #elif defined(MBED) 00556 00557 /* write a real one !!!, just for testing board */ 00558 int GenerateSeed(OS_Seed* os, byte* output, word32 sz) 00559 { 00560 int i; 00561 for (i = 0; i < sz; i++ ) 00562 output[i] = i; 00563 00564 return 0; 00565 } 00566 00567 #elif defined(MICROCHIP_PIC32) 00568 00569 #ifdef MICROCHIP_MPLAB_HARMONY 00570 #define PIC32_SEED_COUNT _CP0_GET_COUNT 00571 #else 00572 #if !defined(CYASSL_MICROCHIP_PIC32MZ) 00573 #include <peripheral/timer.h> 00574 #endif 00575 #define PIC32_SEED_COUNT ReadCoreTimer 00576 #endif 00577 #ifdef CYASSL_MIC32MZ_RNG 00578 #include "xc.h" 00579 int GenerateSeed(OS_Seed* os, byte* output, word32 sz) 00580 { 00581 int i ; 00582 byte rnd[8] ; 00583 word32 *rnd32 = (word32 *)rnd ; 00584 word32 size = sz ; 00585 byte* op = output ; 00586 00587 /* This part has to be replaced with better random seed */ 00588 RNGNUMGEN1 = ReadCoreTimer(); 00589 RNGPOLY1 = ReadCoreTimer(); 00590 RNGPOLY2 = ReadCoreTimer(); 00591 RNGNUMGEN2 = ReadCoreTimer(); 00592 #ifdef DEBUG_CYASSL 00593 printf("GenerateSeed::Seed=%08x, %08x\n", RNGNUMGEN1, RNGNUMGEN2) ; 00594 #endif 00595 RNGCONbits.PLEN = 0x40; 00596 RNGCONbits.PRNGEN = 1; 00597 for(i=0; i<5; i++) { /* wait for RNGNUMGEN ready */ 00598 volatile int x ; 00599 x = RNGNUMGEN1 ; 00600 x = RNGNUMGEN2 ; 00601 } 00602 do { 00603 rnd32[0] = RNGNUMGEN1; 00604 rnd32[1] = RNGNUMGEN2; 00605 00606 for(i=0; i<8; i++, op++) { 00607 *op = rnd[i] ; 00608 size -- ; 00609 if(size==0)break ; 00610 } 00611 } while(size) ; 00612 return 0; 00613 } 00614 #else /* CYASSL_MIC32MZ_RNG */ 00615 /* uses the core timer, in nanoseconds to seed srand */ 00616 int GenerateSeed(OS_Seed* os, byte* output, word32 sz) 00617 { 00618 int i; 00619 srand(PIC32_SEED_COUNT() * 25); 00620 00621 for (i = 0; i < sz; i++ ) { 00622 output[i] = rand() % 256; 00623 if ( (i % 8) == 7) 00624 srand(PIC32_SEED_COUNT() * 25); 00625 } 00626 return 0; 00627 } 00628 #endif /* CYASSL_MIC32MZ_RNG */ 00629 00630 #elif defined(FREESCALE_MQX) 00631 00632 #ifdef FREESCALE_K70_RNGA 00633 /* 00634 * Generates a RNG seed using the Random Number Generator Accelerator 00635 * on the Kinetis K70. Documentation located in Chapter 37 of 00636 * K70 Sub-Family Reference Manual (see Note 3 in the README for link). 00637 */ 00638 int GenerateSeed(OS_Seed* os, byte* output, word32 sz) 00639 { 00640 int i; 00641 00642 /* turn on RNGA module */ 00643 SIM_SCGC3 |= SIM_SCGC3_RNGA_MASK; 00644 00645 /* set SLP bit to 0 - "RNGA is not in sleep mode" */ 00646 RNG_CR &= ~RNG_CR_SLP_MASK; 00647 00648 /* set HA bit to 1 - "security violations masked" */ 00649 RNG_CR |= RNG_CR_HA_MASK; 00650 00651 /* set GO bit to 1 - "output register loaded with data" */ 00652 RNG_CR |= RNG_CR_GO_MASK; 00653 00654 for (i = 0; i < sz; i++) { 00655 00656 /* wait for RNG FIFO to be full */ 00657 while((RNG_SR & RNG_SR_OREG_LVL(0xF)) == 0) {} 00658 00659 /* get value */ 00660 output[i] = RNG_OR; 00661 } 00662 00663 return 0; 00664 } 00665 00666 #elif defined(FREESCALE_K53_RNGB) 00667 /* 00668 * Generates a RNG seed using the Random Number Generator (RNGB) 00669 * on the Kinetis K53. Documentation located in Chapter 33 of 00670 * K53 Sub-Family Reference Manual (see note in the README for link). 00671 */ 00672 int GenerateSeed(OS_Seed* os, byte* output, word32 sz) 00673 { 00674 int i; 00675 00676 /* turn on RNGB module */ 00677 SIM_SCGC3 |= SIM_SCGC3_RNGB_MASK; 00678 00679 /* reset RNGB */ 00680 RNG_CMD |= RNG_CMD_SR_MASK; 00681 00682 /* FIFO generate interrupt, return all zeros on underflow, 00683 * set auto reseed */ 00684 RNG_CR |= (RNG_CR_FUFMOD_MASK | RNG_CR_AR_MASK); 00685 00686 /* gen seed, clear interrupts, clear errors */ 00687 RNG_CMD |= (RNG_CMD_GS_MASK | RNG_CMD_CI_MASK | RNG_CMD_CE_MASK); 00688 00689 /* wait for seeding to complete */ 00690 while ((RNG_SR & RNG_SR_SDN_MASK) == 0) {} 00691 00692 for (i = 0; i < sz; i++) { 00693 00694 /* wait for a word to be available from FIFO */ 00695 while((RNG_SR & RNG_SR_FIFO_LVL_MASK) == 0) {} 00696 00697 /* get value */ 00698 output[i] = RNG_OUT; 00699 } 00700 00701 return 0; 00702 } 00703 00704 #else 00705 #warning "write a real random seed!!!!, just for testing now" 00706 00707 int GenerateSeed(OS_Seed* os, byte* output, word32 sz) 00708 { 00709 int i; 00710 for (i = 0; i < sz; i++ ) 00711 output[i] = i; 00712 00713 return 0; 00714 } 00715 #endif /* FREESCALE_K70_RNGA */ 00716 00717 #elif defined(CYASSL_SAFERTOS) || defined(CYASSL_LEANPSK) \ 00718 || defined(CYASSL_IAR_ARM) 00719 00720 #warning "write a real random seed!!!!, just for testing now" 00721 00722 int GenerateSeed(OS_Seed* os, byte* output, word32 sz) 00723 { 00724 word32 i; 00725 for (i = 0; i < sz; i++ ) 00726 output[i] = i; 00727 00728 (void)os; 00729 00730 return 0; 00731 } 00732 00733 #elif defined(STM32F2_RNG) 00734 #undef RNG 00735 #include "stm32f2xx_rng.h" 00736 #include "stm32f2xx_rcc.h" 00737 /* 00738 * Generate a RNG seed using the hardware random number generator 00739 * on the STM32F2. Documentation located in STM32F2xx Standard Peripheral 00740 * Library document (See note in README). 00741 */ 00742 int GenerateSeed(OS_Seed* os, byte* output, word32 sz) 00743 { 00744 int i; 00745 00746 /* enable RNG clock source */ 00747 RCC_AHB2PeriphClockCmd(RCC_AHB2Periph_RNG, ENABLE); 00748 00749 /* enable RNG peripheral */ 00750 RNG_Cmd(ENABLE); 00751 00752 for (i = 0; i < sz; i++) { 00753 /* wait until RNG number is ready */ 00754 while(RNG_GetFlagStatus(RNG_FLAG_DRDY)== RESET) { } 00755 00756 /* get value */ 00757 output[i] = RNG_GetRandomNumber(); 00758 } 00759 00760 return 0; 00761 } 00762 #elif defined(CYASSL_LPC43xx) || defined(CYASSL_STM32F2xx) 00763 00764 #warning "write a real random seed!!!!, just for testing now" 00765 00766 int GenerateSeed(OS_Seed* os, byte* output, word32 sz) 00767 { 00768 int i; 00769 00770 for (i = 0; i < sz; i++ ) 00771 output[i] = i; 00772 00773 return 0; 00774 } 00775 00776 #elif defined(CUSTOM_RAND_GENERATE) 00777 00778 /* Implement your own random generation function 00779 * word32 rand_gen(void); 00780 * #define CUSTOM_RAND_GENERATE rand_gen */ 00781 00782 int GenerateSeed(OS_Seed* os, byte* output, word32 sz) 00783 { 00784 int i; 00785 00786 for (i = 0; i < sz; i++ ) 00787 output[i] = CUSTOM_RAND_GENERATE(); 00788 00789 return 0; 00790 } 00791 00792 #elif defined(NO_DEV_RANDOM) 00793 00794 #error "you need to write an os specific GenerateSeed() here" 00795 00796 /* 00797 int GenerateSeed(OS_Seed* os, byte* output, word32 sz) 00798 { 00799 return 0; 00800 } 00801 */ 00802 00803 00804 #else /* !USE_WINDOWS_API && !HAVE_RPT_SYS && !MICRIUM && !NO_DEV_RANDOM */ 00805 00806 00807 /* may block */ 00808 int GenerateSeed(OS_Seed* os, byte* output, word32 sz) 00809 { 00810 int ret = 0; 00811 00812 os->fd = open("/dev/urandom",O_RDONLY); 00813 if (os->fd == -1) { 00814 /* may still have /dev/random */ 00815 os->fd = open("/dev/random",O_RDONLY); 00816 if (os->fd == -1) 00817 return OPEN_RAN_E; 00818 } 00819 00820 while (sz) { 00821 int len = (int)read(os->fd, output, sz); 00822 if (len == -1) { 00823 ret = READ_RAN_E; 00824 break; 00825 } 00826 00827 sz -= len; 00828 output += len; 00829 00830 if (sz) { 00831 #ifdef BLOCKING 00832 sleep(0); /* context switch */ 00833 #else 00834 ret = RAN_BLOCK_E; 00835 break; 00836 #endif 00837 } 00838 } 00839 close(os->fd); 00840 00841 return ret; 00842 } 00843 00844 #endif /* USE_WINDOWS_API */ 00845 00846
Generated on Tue Jul 12 2022 21:40:05 by
1.7.2
