CyaSSL is an SSL library for devices like mbed.
Dependents: cyassl-client Sync
random.c
00001 /* random.c 00002 * 00003 * Copyright (C) 2006-2009 Sawtooth Consulting Ltd. 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 00023 /* on HPUX 11 you may need to install /dev/random see 00024 http://h20293.www2.hp.com/portal/swdepot/displayProductInfo.do?productNumber=KRNG11I 00025 00026 */ 00027 00028 #include "random.h" 00029 #include "error.h" 00030 00031 00032 #if defined(USE_WINDOWS_API) 00033 #define _WIN32_WINNT 0x0400 00034 #include <windows.h> 00035 #include <wincrypt.h> 00036 #else 00037 #ifndef NO_DEV_RANDOM 00038 #include <fcntl.h> 00039 #include <unistd.h> 00040 #else 00041 /* include headers that may be needed to get good seed */ 00042 #endif 00043 #endif /* USE_WINDOWS_API */ 00044 00045 00046 00047 /* Get seed and key cipher */ 00048 int InitRng(RNG* rng) 00049 { 00050 byte key[32]; 00051 byte junk[256]; 00052 00053 int ret = GenerateSeed(&rng->seed, key, sizeof(key)); 00054 00055 if (ret == 0) { 00056 Arc4SetKey(&rng->cipher, key, sizeof(key)); 00057 RNG_GenerateBlock(rng, junk, sizeof(junk)); /* rid initial state */ 00058 } 00059 00060 return ret; 00061 } 00062 00063 00064 /* place a generated block in output */ 00065 void RNG_GenerateBlock(RNG* rng, byte* output, word32 sz) 00066 { 00067 XMEMSET(output, 0, sz); 00068 Arc4Process(&rng->cipher, output, output, sz); 00069 } 00070 00071 00072 byte RNG_GenerateByte(RNG* rng) 00073 { 00074 byte b; 00075 RNG_GenerateBlock(rng, &b, 1); 00076 00077 return b; 00078 } 00079 00080 00081 #if defined(USE_WINDOWS_API) 00082 00083 00084 int GenerateSeed(OS_Seed* os, byte* output, word32 sz) 00085 { 00086 if(!CryptAcquireContext(&os->handle, 0, 0, PROV_RSA_FULL, 00087 CRYPT_VERIFYCONTEXT)) 00088 return WINCRYPT_E; 00089 00090 if (!CryptGenRandom(os->handle, sz, output)) 00091 return CRYPTGEN_E; 00092 00093 CryptReleaseContext(os->handle, 0); 00094 00095 return 0; 00096 } 00097 00098 00099 #elif defined(THREADX) 00100 00101 #include "rtprand.h" /* rtp_rand () */ 00102 #include "rtptime.h" /* rtp_get_system_msec() */ 00103 00104 00105 int GenerateSeed(OS_Seed* os, byte* output, word32 sz) 00106 { 00107 int i; 00108 rtp_srand(rtp_get_system_msec()); 00109 00110 for (i = 0; i < sz; i++ ) { 00111 output[i] = rtp_rand() % 256; 00112 if ( (i % 8) == 7) 00113 rtp_srand(rtp_get_system_msec()); 00114 } 00115 00116 return 0; 00117 } 00118 00119 00120 #elif defined(MICRIUM) 00121 00122 int GenerateSeed(OS_Seed* os, byte* output, word32 sz) 00123 { 00124 #if (NET_SECURE_MGR_CFG_EN == DEF_ENABLED) 00125 NetSecure_InitSeed(output, sz); 00126 #endif 00127 return 0; 00128 } 00129 00130 00131 #elif defined(MBED) 00132 00133 int GenerateSeed(OS_Seed* os, byte* output, word32 sz) 00134 { 00135 int i; 00136 00137 for (i = 0; i < sz; i++) 00138 output[i] = i; 00139 00140 return 0; 00141 } 00142 00143 00144 #elif defined(NO_DEV_RANDOM) 00145 00146 #error "you need to write an os specific GenerateSeed() here" 00147 00148 00149 #else /* !USE_WINDOWS_API && !THREADX && !MICRIUM && !NO_DEV_RANDOM */ 00150 00151 00152 /* may block */ 00153 int GenerateSeed(OS_Seed* os, byte* output, word32 sz) 00154 { 00155 os->fd = open("/dev/urandom",O_RDONLY); 00156 if (os->fd == -1) { 00157 /* may still have /dev/random */ 00158 os->fd = open("/dev/random",O_RDONLY); 00159 if (os->fd == -1) 00160 return OPEN_RAN_E; 00161 } 00162 00163 while (sz) { 00164 int len = read(os->fd, output, sz); 00165 if (len == -1) 00166 return READ_RAN_E; 00167 00168 sz -= len; 00169 output += len; 00170 00171 if (sz) 00172 #ifdef BLOCKING 00173 sleep(0); /* context switch */ 00174 #else 00175 return RAN_BLOCK_E; 00176 #endif 00177 } 00178 close(os->fd); 00179 00180 return 0; 00181 } 00182 00183 #endif /* USE_WINDOWS_API */ 00184
Generated on Tue Jul 12 2022 18:43:19 by 1.7.2