cya_u
Fork of CyaSSL-forEncrypt by
Diff: random.c
- Revision:
- 0:5045d2638c29
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/random.c Sat Feb 05 01:09:17 2011 +0000 @@ -0,0 +1,184 @@ +/* random.c + * + * Copyright (C) 2006-2009 Sawtooth Consulting Ltd. + * + * This file is part of CyaSSL. + * + * CyaSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * CyaSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + + +/* on HPUX 11 you may need to install /dev/random see + http://h20293.www2.hp.com/portal/swdepot/displayProductInfo.do?productNumber=KRNG11I + +*/ + +#include "random.h" +#include "error.h" + + +#if defined(USE_WINDOWS_API) + #define _WIN32_WINNT 0x0400 + #include <windows.h> + #include <wincrypt.h> +#else + #ifndef NO_DEV_RANDOM + #include <fcntl.h> + #include <unistd.h> + #else + /* include headers that may be needed to get good seed */ + #endif +#endif /* USE_WINDOWS_API */ + + + +/* Get seed and key cipher */ +int InitRng(RNG* rng) +{ + byte key[32]; + byte junk[256]; + + int ret = GenerateSeed(&rng->seed, key, sizeof(key)); + + if (ret == 0) { + Arc4SetKey(&rng->cipher, key, sizeof(key)); + RNG_GenerateBlock(rng, junk, sizeof(junk)); /* rid initial state */ + } + + return ret; +} + + +/* place a generated block in output */ +void RNG_GenerateBlock(RNG* rng, byte* output, word32 sz) +{ + XMEMSET(output, 0, sz); + Arc4Process(&rng->cipher, output, output, sz); +} + + +byte RNG_GenerateByte(RNG* rng) +{ + byte b; + RNG_GenerateBlock(rng, &b, 1); + + return b; +} + + +#if defined(USE_WINDOWS_API) + + +int GenerateSeed(OS_Seed* os, byte* output, word32 sz) +{ + if(!CryptAcquireContext(&os->handle, 0, 0, PROV_RSA_FULL, + CRYPT_VERIFYCONTEXT)) + return WINCRYPT_E; + + if (!CryptGenRandom(os->handle, sz, output)) + return CRYPTGEN_E; + + CryptReleaseContext(os->handle, 0); + + return 0; +} + + +#elif defined(THREADX) + +#include "rtprand.h" /* rtp_rand () */ +#include "rtptime.h" /* rtp_get_system_msec() */ + + +int GenerateSeed(OS_Seed* os, byte* output, word32 sz) +{ + int i; + rtp_srand(rtp_get_system_msec()); + + for (i = 0; i < sz; i++ ) { + output[i] = rtp_rand() % 256; + if ( (i % 8) == 7) + rtp_srand(rtp_get_system_msec()); + } + + return 0; +} + + +#elif defined(MICRIUM) + +int GenerateSeed(OS_Seed* os, byte* output, word32 sz) +{ + #if (NET_SECURE_MGR_CFG_EN == DEF_ENABLED) + NetSecure_InitSeed(output, sz); + #endif + return 0; +} + + +#elif defined(MBED) + +int GenerateSeed(OS_Seed* os, byte* output, word32 sz) +{ + int i; + + for (i = 0; i < sz; i++) + output[i] = i; + + return 0; +} + + +#elif defined(NO_DEV_RANDOM) + +#error "you need to write an os specific GenerateSeed() here" + + +#else /* !USE_WINDOWS_API && !THREADX && !MICRIUM && !NO_DEV_RANDOM */ + + +/* may block */ +int GenerateSeed(OS_Seed* os, byte* output, word32 sz) +{ + os->fd = open("/dev/urandom",O_RDONLY); + if (os->fd == -1) { + /* may still have /dev/random */ + os->fd = open("/dev/random",O_RDONLY); + if (os->fd == -1) + return OPEN_RAN_E; + } + + while (sz) { + int len = read(os->fd, output, sz); + if (len == -1) + return READ_RAN_E; + + sz -= len; + output += len; + + if (sz) +#ifdef BLOCKING + sleep(0); /* context switch */ +#else + return RAN_BLOCK_E; +#endif + } + close(os->fd); + + return 0; +} + +#endif /* USE_WINDOWS_API */ +