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.
random.c
00001 /* random.c 00002 * 00003 * Copyright (C) 2006-2013 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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 Sha256Update(&rng->sha, &ctr, sizeof(ctr)); 00109 Sha256Update(&rng->sha, (byte*)&bits, sizeof(bits)); 00110 /* churning V is the only string that doesn't have 00111 * the type added */ 00112 if (type != dbrgInitV) 00113 Sha256Update(&rng->sha, &type, sizeof(type)); 00114 Sha256Update(&rng->sha, inA, inASz); 00115 if (inB != NULL && inBSz > 0) 00116 Sha256Update(&rng->sha, inB, inBSz); 00117 if (inC != NULL && inCSz > 0) 00118 Sha256Update(&rng->sha, inC, inCSz); 00119 Sha256Final(&rng->sha, rng->digest); 00120 00121 if (outSz > SHA256_DIGEST_SIZE) { 00122 XMEMCPY(out, rng->digest, SHA256_DIGEST_SIZE); 00123 outSz -= SHA256_DIGEST_SIZE; 00124 out += SHA256_DIGEST_SIZE; 00125 } 00126 else { 00127 XMEMCPY(out, rng->digest, outSz); 00128 } 00129 } 00130 00131 return DBRG_SUCCESS; 00132 } 00133 00134 00135 static int Hash_DBRG_Reseed(RNG* rng, byte* entropy, word32 entropySz) 00136 { 00137 byte seed[DBRG_SEED_LEN]; 00138 00139 Hash_df(rng, seed, sizeof(seed), dbrgInitV, rng->V, sizeof(rng->V), 00140 entropy, entropySz, NULL, 0); 00141 XMEMCPY(rng->V, seed, sizeof(rng->V)); 00142 XMEMSET(seed, 0, sizeof(seed)); 00143 00144 Hash_df(rng, rng->C, sizeof(rng->C), dbrgInitC, rng->V, sizeof(rng->V), 00145 NULL, 0, NULL, 0); 00146 rng->reseed_ctr = 1; 00147 return 0; 00148 } 00149 00150 static INLINE void array_add_one(byte* data, word32 dataSz) 00151 { 00152 int i; 00153 00154 for (i = dataSz - 1; i >= 0; i--) 00155 { 00156 data[i]++; 00157 if (data[i] != 0) break; 00158 } 00159 } 00160 00161 static int Hash_gen(RNG* rng, byte* out, word32 outSz, byte* V) 00162 { 00163 byte data[DBRG_SEED_LEN]; 00164 int i, ret; 00165 int len = (outSz / SHA256_DIGEST_SIZE) 00166 + ((outSz % SHA256_DIGEST_SIZE) ? 1 : 0); 00167 00168 XMEMCPY(data, V, sizeof(data)); 00169 for (i = 0; i < len; i++) { 00170 ret = InitSha256(&rng->sha); 00171 if (ret != 0) return ret; 00172 Sha256Update(&rng->sha, data, sizeof(data)); 00173 Sha256Final(&rng->sha, rng->digest); 00174 if (outSz > SHA256_DIGEST_SIZE) { 00175 XMEMCPY(out, rng->digest, SHA256_DIGEST_SIZE); 00176 outSz -= SHA256_DIGEST_SIZE; 00177 out += SHA256_DIGEST_SIZE; 00178 array_add_one(data, DBRG_SEED_LEN); 00179 } 00180 else { 00181 XMEMCPY(out, rng->digest, outSz); 00182 } 00183 } 00184 XMEMSET(data, 0, sizeof(data)); 00185 00186 return 0; 00187 } 00188 00189 00190 static INLINE void array_add(byte* d, word32 dLen, byte* s, word32 sLen) 00191 { 00192 word16 carry = 0; 00193 00194 if (dLen > 0 && sLen > 0 && dLen >= sLen) { 00195 int sIdx, dIdx; 00196 00197 for (sIdx = sLen - 1, dIdx = dLen - 1; sIdx >= 0; dIdx--, sIdx--) 00198 { 00199 carry += d[dIdx] + s[sIdx]; 00200 d[dIdx] = carry; 00201 carry >>= 8; 00202 } 00203 if (dIdx > 0) 00204 d[dIdx] += carry; 00205 } 00206 } 00207 00208 00209 static int Hash_DBRG_Generate(RNG* rng, byte* out, word32 outSz) 00210 { 00211 int ret; 00212 00213 if (rng->reseed_ctr != RESEED_MAX) { 00214 byte type = dbrgGenerateH; 00215 00216 if (Hash_gen(rng, out, outSz, rng->V) != 0) 00217 return DBRG_ERROR; 00218 if (InitSha256(&rng->sha) != 0) 00219 return DBRG_ERROR; 00220 Sha256Update(&rng->sha, &type, sizeof(type)); 00221 Sha256Update(&rng->sha, rng->V, sizeof(rng->V)); 00222 Sha256Final(&rng->sha, rng->digest); 00223 array_add(rng->V, sizeof(rng->V), rng->digest, sizeof(rng->digest)); 00224 array_add(rng->V, sizeof(rng->V), rng->C, sizeof(rng->C)); 00225 array_add(rng->V, sizeof(rng->V), 00226 (byte*)&rng->reseed_ctr, sizeof(rng->reseed_ctr)); 00227 rng->reseed_ctr++; 00228 ret = DBRG_SUCCESS; 00229 } 00230 else { 00231 ret = DBRG_NEED_RESEED; 00232 } 00233 return ret; 00234 } 00235 00236 00237 static void Hash_DBRG_Instantiate(RNG* rng, byte* seed, word32 seedSz) 00238 { 00239 XMEMSET(rng, 0, sizeof(*rng)); 00240 Hash_df(rng, rng->V, sizeof(rng->V), dbrgInitV, seed, seedSz, NULL, 0, NULL, 0); 00241 Hash_df(rng, rng->C, sizeof(rng->C), dbrgInitC, rng->V, sizeof(rng->V), 00242 NULL, 0, NULL, 0); 00243 rng->reseed_ctr = 1; 00244 } 00245 00246 00247 static int Hash_DBRG_Uninstantiate(RNG* rng) 00248 { 00249 int result = DBRG_ERROR; 00250 00251 if (rng != NULL) { 00252 XMEMSET(rng, 0, sizeof(*rng)); 00253 result = DBRG_SUCCESS; 00254 } 00255 00256 return result; 00257 } 00258 00259 /* End NIST DRBG Code */ 00260 00261 00262 00263 /* Get seed and key cipher */ 00264 int InitRng(RNG* rng) 00265 { 00266 byte entropy[ENTROPY_SZ]; 00267 int ret = DBRG_ERROR; 00268 00269 if (GenerateSeed(&rng->seed, entropy, sizeof(entropy)) == 0) { 00270 Hash_DBRG_Instantiate(rng, entropy, sizeof(entropy)); 00271 ret = DBRG_SUCCESS; 00272 } 00273 XMEMSET(entropy, 0, sizeof(entropy)); 00274 return ret; 00275 } 00276 00277 00278 /* place a generated block in output */ 00279 void RNG_GenerateBlock(RNG* rng, byte* output, word32 sz) 00280 { 00281 int ret; 00282 00283 XMEMSET(output, 0, sz); 00284 ret = Hash_DBRG_Generate(rng, output, sz); 00285 if (ret == DBRG_NEED_RESEED) { 00286 byte entropy[ENTROPY_SZ]; 00287 ret = GenerateSeed(&rng->seed, entropy, sizeof(entropy)); 00288 if (ret == 0) { 00289 Hash_DBRG_Reseed(rng, entropy, sizeof(entropy)); 00290 ret = Hash_DBRG_Generate(rng, output, sz); 00291 } 00292 else 00293 ret = DBRG_ERROR; 00294 XMEMSET(entropy, 0, sizeof(entropy)); 00295 } 00296 } 00297 00298 00299 byte RNG_GenerateByte(RNG* rng) 00300 { 00301 byte b; 00302 RNG_GenerateBlock(rng, &b, 1); 00303 00304 return b; 00305 } 00306 00307 00308 void FreeRng(RNG* rng) 00309 { 00310 Hash_DBRG_Uninstantiate(rng); 00311 } 00312 00313 #else /* NO_RC4 */ 00314 00315 /* Get seed and key cipher */ 00316 int InitRng(RNG* rng) 00317 { 00318 byte key[32]; 00319 byte junk[256]; 00320 int ret; 00321 00322 #ifdef HAVE_CAVIUM 00323 if (rng->magic == CYASSL_RNG_CAVIUM_MAGIC) 00324 return 0; 00325 #endif 00326 ret = GenerateSeed(&rng->seed, key, sizeof(key)); 00327 00328 if (ret == 0) { 00329 Arc4SetKey(&rng->cipher, key, sizeof(key)); 00330 RNG_GenerateBlock(rng, junk, sizeof(junk)); /* rid initial state */ 00331 } 00332 00333 return ret; 00334 } 00335 00336 #ifdef HAVE_CAVIUM 00337 static void CaviumRNG_GenerateBlock(RNG* rng, byte* output, word32 sz); 00338 #endif 00339 00340 /* place a generated block in output */ 00341 void RNG_GenerateBlock(RNG* rng, byte* output, word32 sz) 00342 { 00343 #ifdef HAVE_CAVIUM 00344 if (rng->magic == CYASSL_RNG_CAVIUM_MAGIC) 00345 return CaviumRNG_GenerateBlock(rng, output, sz); 00346 #endif 00347 XMEMSET(output, 0, sz); 00348 Arc4Process(&rng->cipher, output, output, sz); 00349 } 00350 00351 00352 byte RNG_GenerateByte(RNG* rng) 00353 { 00354 byte b; 00355 RNG_GenerateBlock(rng, &b, 1); 00356 00357 return b; 00358 } 00359 00360 00361 #ifdef HAVE_CAVIUM 00362 00363 #include <cyassl/ctaocrypt/logging.h> 00364 #include "cavium_common.h" 00365 00366 /* Initiliaze RNG for use with Nitrox device */ 00367 int InitRngCavium(RNG* rng, int devId) 00368 { 00369 if (rng == NULL) 00370 return -1; 00371 00372 rng->devId = devId; 00373 rng->magic = CYASSL_RNG_CAVIUM_MAGIC; 00374 00375 return 0; 00376 } 00377 00378 00379 static void CaviumRNG_GenerateBlock(RNG* rng, byte* output, word32 sz) 00380 { 00381 word offset = 0; 00382 word32 requestId; 00383 00384 while (sz > CYASSL_MAX_16BIT) { 00385 word16 slen = (word16)CYASSL_MAX_16BIT; 00386 if (CspRandom(CAVIUM_BLOCKING, slen, output + offset, &requestId, 00387 rng->devId) != 0) { 00388 CYASSL_MSG("Cavium RNG failed"); 00389 } 00390 sz -= CYASSL_MAX_16BIT; 00391 offset += CYASSL_MAX_16BIT; 00392 } 00393 if (sz) { 00394 word16 slen = (word16)sz; 00395 if (CspRandom(CAVIUM_BLOCKING, slen, output + offset, &requestId, 00396 rng->devId) != 0) { 00397 CYASSL_MSG("Cavium RNG failed"); 00398 } 00399 } 00400 } 00401 00402 #endif /* HAVE_CAVIUM */ 00403 00404 #endif /* NO_RC4 */ 00405 00406 00407 #if defined(USE_WINDOWS_API) 00408 00409 00410 int GenerateSeed(OS_Seed* os, byte* output, word32 sz) 00411 { 00412 if(!CryptAcquireContext(&os->handle, 0, 0, PROV_RSA_FULL, 00413 CRYPT_VERIFYCONTEXT)) 00414 return WINCRYPT_E; 00415 00416 if (!CryptGenRandom(os->handle, sz, output)) 00417 return CRYPTGEN_E; 00418 00419 CryptReleaseContext(os->handle, 0); 00420 00421 return 0; 00422 } 00423 00424 00425 #elif defined(HAVE_RTP_SYS) || defined(EBSNET) 00426 00427 #include "rtprand.h" /* rtp_rand () */ 00428 #include "rtptime.h" /* rtp_get_system_msec() */ 00429 00430 00431 int GenerateSeed(OS_Seed* os, byte* output, word32 sz) 00432 { 00433 int i; 00434 rtp_srand(rtp_get_system_msec()); 00435 00436 for (i = 0; i < sz; i++ ) { 00437 output[i] = rtp_rand() % 256; 00438 if ( (i % 8) == 7) 00439 rtp_srand(rtp_get_system_msec()); 00440 } 00441 00442 return 0; 00443 } 00444 00445 00446 #elif defined(MICRIUM) 00447 00448 int GenerateSeed(OS_Seed* os, byte* output, word32 sz) 00449 { 00450 #if (NET_SECURE_MGR_CFG_EN == DEF_ENABLED) 00451 NetSecure_InitSeed(output, sz); 00452 #endif 00453 return 0; 00454 } 00455 00456 #elif defined(MBED) 00457 00458 /* write a real one !!!, just for testing board */ 00459 int GenerateSeed(OS_Seed* os, byte* output, word32 sz) 00460 { 00461 int i; 00462 for (i = 0; i < sz; i++ ) 00463 output[i] = i; 00464 00465 return 0; 00466 } 00467 00468 #elif defined(MICROCHIP_PIC32) 00469 00470 #ifdef MICROCHIP_MPLAB_HARMONY 00471 #define PIC32_SEED_COUNT _CP0_GET_COUNT 00472 #else 00473 #if !defined(CYASSL_MICROCHIP_PIC32MZ) 00474 #include <peripheral/timer.h> 00475 #endif 00476 #define PIC32_SEED_COUNT ReadCoreTimer 00477 #endif 00478 #ifdef CYASSL_MIC32MZ_RNG 00479 #include "xc.h" 00480 int GenerateSeed(OS_Seed* os, byte* output, word32 sz) 00481 { 00482 int i ; 00483 byte rnd[8] ; 00484 word32 *rnd32 = (word32 *)rnd ; 00485 word32 size = sz ; 00486 byte* op = output ; 00487 00488 /* This part has to be replaced with better random seed */ 00489 RNGNUMGEN1 = ReadCoreTimer(); 00490 RNGPOLY1 = ReadCoreTimer(); 00491 RNGPOLY2 = ReadCoreTimer(); 00492 RNGNUMGEN2 = ReadCoreTimer(); 00493 #ifdef DEBUG_CYASSL 00494 printf("GenerateSeed::Seed=%08x, %08x\n", RNGNUMGEN1, RNGNUMGEN2) ; 00495 #endif 00496 RNGCONbits.PLEN = 0x40; 00497 RNGCONbits.PRNGEN = 1; 00498 for(i=0; i<5; i++) { /* wait for RNGNUMGEN ready */ 00499 volatile int x ; 00500 x = RNGNUMGEN1 ; 00501 x = RNGNUMGEN2 ; 00502 } 00503 do { 00504 rnd32[0] = RNGNUMGEN1; 00505 rnd32[1] = RNGNUMGEN2; 00506 00507 for(i=0; i<8; i++, op++) { 00508 *op = rnd[i] ; 00509 size -- ; 00510 if(size==0)break ; 00511 } 00512 } while(size) ; 00513 return 0; 00514 } 00515 #else /* CYASSL_MIC32MZ_RNG */ 00516 /* uses the core timer, in nanoseconds to seed srand */ 00517 int GenerateSeed(OS_Seed* os, byte* output, word32 sz) 00518 { 00519 int i; 00520 srand(PIC32_SEED_COUNT() * 25); 00521 00522 for (i = 0; i < sz; i++ ) { 00523 output[i] = rand() % 256; 00524 if ( (i % 8) == 7) 00525 srand(PIC32_SEED_COUNT() * 25); 00526 } 00527 return 0; 00528 } 00529 #endif /* CYASSL_MIC32MZ_RNG */ 00530 00531 #elif defined(FREESCALE_MQX) 00532 00533 #ifdef FREESCALE_K70_RNGA 00534 /* 00535 * Generates a RNG seed using the Random Number Generator Accelerator 00536 * on the Kinetis K70. Documentation located in Chapter 37 of 00537 * K70 Sub-Family Reference Manual (see Note 3 in the README for link). 00538 */ 00539 int GenerateSeed(OS_Seed* os, byte* output, word32 sz) 00540 { 00541 int i; 00542 00543 /* turn on RNGA module */ 00544 SIM_SCGC3 |= SIM_SCGC3_RNGA_MASK; 00545 00546 /* set SLP bit to 0 - "RNGA is not in sleep mode" */ 00547 RNG_CR &= ~RNG_CR_SLP_MASK; 00548 00549 /* set HA bit to 1 - "security violations masked" */ 00550 RNG_CR |= RNG_CR_HA_MASK; 00551 00552 /* set GO bit to 1 - "output register loaded with data" */ 00553 RNG_CR |= RNG_CR_GO_MASK; 00554 00555 for (i = 0; i < sz; i++) { 00556 00557 /* wait for RNG FIFO to be full */ 00558 while((RNG_SR & RNG_SR_OREG_LVL(0xF)) == 0) {} 00559 00560 /* get value */ 00561 output[i] = RNG_OR; 00562 } 00563 00564 return 0; 00565 } 00566 00567 #elif defined(FREESCALE_K53_RNGB) 00568 /* 00569 * Generates a RNG seed using the Random Number Generator (RNGB) 00570 * on the Kinetis K53. Documentation located in Chapter 33 of 00571 * K53 Sub-Family Reference Manual (see note in the README for link). 00572 */ 00573 int GenerateSeed(OS_Seed* os, byte* output, word32 sz) 00574 { 00575 int i; 00576 00577 /* turn on RNGB module */ 00578 SIM_SCGC3 |= SIM_SCGC3_RNGB_MASK; 00579 00580 /* reset RNGB */ 00581 RNG_CMD |= RNG_CMD_SR_MASK; 00582 00583 /* FIFO generate interrupt, return all zeros on underflow, 00584 * set auto reseed */ 00585 RNG_CR |= (RNG_CR_FUFMOD_MASK | RNG_CR_AR_MASK); 00586 00587 /* gen seed, clear interrupts, clear errors */ 00588 RNG_CMD |= (RNG_CMD_GS_MASK | RNG_CMD_CI_MASK | RNG_CMD_CE_MASK); 00589 00590 /* wait for seeding to complete */ 00591 while ((RNG_SR & RNG_SR_SDN_MASK) == 0) {} 00592 00593 for (i = 0; i < sz; i++) { 00594 00595 /* wait for a word to be available from FIFO */ 00596 while((RNG_SR & RNG_SR_FIFO_LVL_MASK) == 0) {} 00597 00598 /* get value */ 00599 output[i] = RNG_OUT; 00600 } 00601 00602 return 0; 00603 } 00604 00605 #else 00606 #warning "write a real random seed!!!!, just for testing now" 00607 00608 int GenerateSeed(OS_Seed* os, byte* output, word32 sz) 00609 { 00610 int i; 00611 for (i = 0; i < sz; i++ ) 00612 output[i] = i; 00613 00614 return 0; 00615 } 00616 #endif /* FREESCALE_K70_RNGA */ 00617 00618 #elif defined(CYASSL_SAFERTOS) || defined(CYASSL_LEANPSK) \ 00619 || defined(CYASSL_IAR_ARM) 00620 00621 #warning "write a real random seed!!!!, just for testing now" 00622 00623 int GenerateSeed(OS_Seed* os, byte* output, word32 sz) 00624 { 00625 word32 i; 00626 for (i = 0; i < sz; i++ ) 00627 output[i] = i; 00628 00629 (void)os; 00630 00631 return 0; 00632 } 00633 00634 #elif defined(STM32F2_RNG) 00635 #undef RNG 00636 #include "stm32f2xx_rng.h" 00637 #include "stm32f2xx_rcc.h" 00638 /* 00639 * Generate a RNG seed using the hardware random number generator 00640 * on the STM32F2. Documentation located in STM32F2xx Standard Peripheral 00641 * Library document (See note in README). 00642 */ 00643 int GenerateSeed(OS_Seed* os, byte* output, word32 sz) 00644 { 00645 int i; 00646 00647 /* enable RNG clock source */ 00648 RCC_AHB2PeriphClockCmd(RCC_AHB2Periph_RNG, ENABLE); 00649 00650 /* enable RNG peripheral */ 00651 RNG_Cmd(ENABLE); 00652 00653 for (i = 0; i < sz; i++) { 00654 /* wait until RNG number is ready */ 00655 while(RNG_GetFlagStatus(RNG_FLAG_DRDY)== RESET) { } 00656 00657 /* get value */ 00658 output[i] = RNG_GetRandomNumber(); 00659 } 00660 00661 return 0; 00662 } 00663 #elif defined(CYASSL_LPC43xx) || defined(CYASSL_STM32F2xx) 00664 00665 #warning "write a real random seed!!!!, just for testing now" 00666 00667 int GenerateSeed(OS_Seed* os, byte* output, word32 sz) 00668 { 00669 int i; 00670 00671 for (i = 0; i < sz; i++ ) 00672 output[i] = i; 00673 00674 return 0; 00675 } 00676 00677 #elif defined(CUSTOM_RAND_GENERATE) 00678 00679 /* Implement your own random generation function 00680 * word32 rand_gen(void); 00681 * #define CUSTOM_RAND_GENERATE rand_gen */ 00682 00683 int GenerateSeed(OS_Seed* os, byte* output, word32 sz) 00684 { 00685 int i; 00686 00687 for (i = 0; i < sz; i++ ) 00688 output[i] = CUSTOM_RAND_GENERATE(); 00689 00690 return 0; 00691 } 00692 00693 #elif defined(NO_DEV_RANDOM) 00694 00695 #error "you need to write an os specific GenerateSeed() here" 00696 00697 /* 00698 int GenerateSeed(OS_Seed* os, byte* output, word32 sz) 00699 { 00700 return 0; 00701 } 00702 */ 00703 00704 00705 #else /* !USE_WINDOWS_API && !HAVE_RPT_SYS && !MICRIUM && !NO_DEV_RANDOM */ 00706 00707 00708 /* may block */ 00709 int GenerateSeed(OS_Seed* os, byte* output, word32 sz) 00710 { 00711 int ret = 0; 00712 00713 os->fd = open("/dev/urandom",O_RDONLY); 00714 if (os->fd == -1) { 00715 /* may still have /dev/random */ 00716 os->fd = open("/dev/random",O_RDONLY); 00717 if (os->fd == -1) 00718 return OPEN_RAN_E; 00719 } 00720 00721 while (sz) { 00722 int len = (int)read(os->fd, output, sz); 00723 if (len == -1) { 00724 ret = READ_RAN_E; 00725 break; 00726 } 00727 00728 sz -= len; 00729 output += len; 00730 00731 if (sz) { 00732 #ifdef BLOCKING 00733 sleep(0); /* context switch */ 00734 #else 00735 ret = RAN_BLOCK_E; 00736 break; 00737 #endif 00738 } 00739 } 00740 close(os->fd); 00741 00742 return ret; 00743 } 00744 00745 #endif /* USE_WINDOWS_API */ 00746
Generated on Tue Jul 12 2022 20:12:51 by
