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.
Dependents: HTTPClient-SSL HTTPClient HTTPClient-SSL http_access ... more
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 Wed Jul 13 2022 02:18:39 by
 1.7.2
 1.7.2 
    