summaryrefslogtreecommitdiff
path: root/src/lib/libcrypto/rand/rand_unix.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/libcrypto/rand/rand_unix.c')
-rw-r--r--src/lib/libcrypto/rand/rand_unix.c119
1 files changed, 84 insertions, 35 deletions
diff --git a/src/lib/libcrypto/rand/rand_unix.c b/src/lib/libcrypto/rand/rand_unix.c
index 9376554fae..6c2be5cb96 100644
--- a/src/lib/libcrypto/rand/rand_unix.c
+++ b/src/lib/libcrypto/rand/rand_unix.c
@@ -56,7 +56,7 @@
56 * [including the GNU Public Licence.] 56 * [including the GNU Public Licence.]
57 */ 57 */
58/* ==================================================================== 58/* ====================================================================
59 * Copyright (c) 1998-2000 The OpenSSL Project. All rights reserved. 59 * Copyright (c) 1998-2006 The OpenSSL Project. All rights reserved.
60 * 60 *
61 * Redistribution and use in source and binary forms, with or without 61 * Redistribution and use in source and binary forms, with or without
62 * modification, are permitted provided that the following conditions 62 * modification, are permitted provided that the following conditions
@@ -108,6 +108,7 @@
108 * Hudson (tjh@cryptsoft.com). 108 * Hudson (tjh@cryptsoft.com).
109 * 109 *
110 */ 110 */
111#include <stdio.h>
111 112
112#define USE_SOCKETS 113#define USE_SOCKETS
113#include "e_os.h" 114#include "e_os.h"
@@ -115,7 +116,7 @@
115#include <openssl/rand.h> 116#include <openssl/rand.h>
116#include "rand_lcl.h" 117#include "rand_lcl.h"
117 118
118#if !(defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_WIN32) || defined(OPENSSL_SYS_VMS) || defined(OPENSSL_SYS_OS2) || defined(OPENSSL_SYS_VXWORKS)) 119#if !(defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_WIN32) || defined(OPENSSL_SYS_VMS) || defined(OPENSSL_SYS_OS2) || defined(OPENSSL_SYS_VXWORKS) || defined(OPENSSL_SYS_NETWARE))
119 120
120#include <sys/types.h> 121#include <sys/types.h>
121#include <sys/time.h> 122#include <sys/time.h>
@@ -124,6 +125,13 @@
124#include <fcntl.h> 125#include <fcntl.h>
125#include <unistd.h> 126#include <unistd.h>
126#include <time.h> 127#include <time.h>
128#if defined(OPENSSL_SYS_LINUX) /* should actually be available virtually everywhere */
129# include <poll.h>
130#endif
131#include <limits.h>
132#ifndef FD_SETSIZE
133# define FD_SETSIZE (8*sizeof(fd_set))
134#endif
127 135
128#ifdef __OpenBSD__ 136#ifdef __OpenBSD__
129int RAND_poll(void) 137int RAND_poll(void)
@@ -142,7 +150,7 @@ int RAND_poll(void)
142 150
143 return 1; 151 return 1;
144} 152}
145#else 153#else /* !defined(__OpenBSD__) */
146int RAND_poll(void) 154int RAND_poll(void)
147{ 155{
148 unsigned long l; 156 unsigned long l;
@@ -154,7 +162,8 @@ int RAND_poll(void)
154#ifdef DEVRANDOM 162#ifdef DEVRANDOM
155 static const char *randomfiles[] = { DEVRANDOM }; 163 static const char *randomfiles[] = { DEVRANDOM };
156 struct stat randomstats[sizeof(randomfiles)/sizeof(randomfiles[0])]; 164 struct stat randomstats[sizeof(randomfiles)/sizeof(randomfiles[0])];
157 int fd,i; 165 int fd;
166 size_t i;
158#endif 167#endif
159#ifdef DEVRANDOM_EGD 168#ifdef DEVRANDOM_EGD
160 static const char *egdsockets[] = { DEVRANDOM_EGD, NULL }; 169 static const char *egdsockets[] = { DEVRANDOM_EGD, NULL };
@@ -182,10 +191,9 @@ int RAND_poll(void)
182#endif 191#endif
183 )) >= 0) 192 )) >= 0)
184 { 193 {
185 struct timeval t = { 0, 10*1000 }; /* Spend 10ms on 194 int usec = 10*1000; /* spend 10ms on each file */
186 each file. */ 195 int r;
187 int r,j; 196 size_t j;
188 fd_set fset;
189 struct stat *st=&randomstats[i]; 197 struct stat *st=&randomstats[i];
190 198
191 /* Avoid using same input... Used to be O_NOFOLLOW 199 /* Avoid using same input... Used to be O_NOFOLLOW
@@ -201,35 +209,75 @@ int RAND_poll(void)
201 209
202 do 210 do
203 { 211 {
204 FD_ZERO(&fset); 212 int try_read = 0;
205 FD_SET(fd, &fset);
206 r = -1;
207 213
208 if (select(fd+1,&fset,NULL,NULL,&t) < 0) 214#if defined(OPENSSL_SYS_LINUX)
209 t.tv_usec=0; 215 /* use poll() */
210 else if (FD_ISSET(fd, &fset)) 216 struct pollfd pset;
217
218 pset.fd = fd;
219 pset.events = POLLIN;
220 pset.revents = 0;
221
222 if (poll(&pset, 1, usec / 1000) < 0)
223 usec = 0;
224 else
225 try_read = (pset.revents & POLLIN) != 0;
226
227#else
228 /* use select() */
229 fd_set fset;
230 struct timeval t;
231
232 t.tv_sec = 0;
233 t.tv_usec = usec;
234
235 if (FD_SETSIZE > 0 && fd >= FD_SETSIZE)
236 {
237 /* can't use select, so just try to read once anyway */
238 try_read = 1;
239 }
240 else
241 {
242 FD_ZERO(&fset);
243 FD_SET(fd, &fset);
244
245 if (select(fd+1,&fset,NULL,NULL,&t) >= 0)
246 {
247 usec = t.tv_usec;
248 if (FD_ISSET(fd, &fset))
249 try_read = 1;
250 }
251 else
252 usec = 0;
253 }
254#endif
255
256 if (try_read)
211 { 257 {
212 r=read(fd,(unsigned char *)tmpbuf+n, 258 r = read(fd,(unsigned char *)tmpbuf+n, ENTROPY_NEEDED-n);
213 ENTROPY_NEEDED-n);
214 if (r > 0) 259 if (r > 0)
215 n += r; 260 n += r;
216 } 261 }
217 262 else
218 /* Some Unixen will update t, some 263 r = -1;
219 won't. For those who won't, give 264
220 up here, otherwise, we will do 265 /* Some Unixen will update t in select(), some
266 won't. For those who won't, or if we
267 didn't use select() in the first place,
268 give up here, otherwise, we will do
221 this once again for the remaining 269 this once again for the remaining
222 time. */ 270 time. */
223 if (t.tv_usec == 10*1000) 271 if (usec == 10*1000)
224 t.tv_usec=0; 272 usec = 0;
225 } 273 }
226 while ((r > 0 || (errno == EINTR || errno == EAGAIN)) 274 while ((r > 0 ||
227 && t.tv_usec != 0 && n < ENTROPY_NEEDED); 275 (errno == EINTR || errno == EAGAIN)) && usec != 0 && n < ENTROPY_NEEDED);
228 276
229 close(fd); 277 close(fd);
230 } 278 }
231 } 279 }
232#endif 280#endif /* defined(DEVRANDOM) */
233 281
234#ifdef DEVRANDOM_EGD 282#ifdef DEVRANDOM_EGD
235 /* Use an EGD socket to read entropy from an EGD or PRNGD entropy 283 /* Use an EGD socket to read entropy from an EGD or PRNGD entropy
@@ -244,24 +292,24 @@ int RAND_poll(void)
244 if (r > 0) 292 if (r > 0)
245 n += r; 293 n += r;
246 } 294 }
247#endif 295#endif /* defined(DEVRANDOM_EGD) */
248 296
249#if defined(DEVRANDOM) || defined(DEVRANDOM_EGD) 297#if defined(DEVRANDOM) || defined(DEVRANDOM_EGD)
250 if (n > 0) 298 if (n > 0)
251 { 299 {
252 RAND_add(tmpbuf,sizeof tmpbuf,n); 300 RAND_add(tmpbuf,sizeof tmpbuf,(double)n);
253 OPENSSL_cleanse(tmpbuf,n); 301 OPENSSL_cleanse(tmpbuf,n);
254 } 302 }
255#endif 303#endif
256 304
257 /* put in some default random data, we need more than just this */ 305 /* put in some default random data, we need more than just this */
258 l=curr_pid; 306 l=curr_pid;
259 RAND_add(&l,sizeof(l),0); 307 RAND_add(&l,sizeof(l),0.0);
260 l=getuid(); 308 l=getuid();
261 RAND_add(&l,sizeof(l),0); 309 RAND_add(&l,sizeof(l),0.0);
262 310
263 l=time(NULL); 311 l=time(NULL);
264 RAND_add(&l,sizeof(l),0); 312 RAND_add(&l,sizeof(l),0.0);
265 313
266#if defined(DEVRANDOM) || defined(DEVRANDOM_EGD) 314#if defined(DEVRANDOM) || defined(DEVRANDOM_EGD)
267 return 1; 315 return 1;
@@ -270,12 +318,13 @@ int RAND_poll(void)
270#endif 318#endif
271} 319}
272 320
273#endif 321#endif /* defined(__OpenBSD__) */
274#endif 322#endif /* !(defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_WIN32) || defined(OPENSSL_SYS_VMS) || defined(OPENSSL_SYS_OS2) || defined(OPENSSL_SYS_VXWORKS) || defined(OPENSSL_SYS_NETWARE)) */
323
275 324
276#if defined(OPENSSL_SYS_VXWORKS) 325#if defined(OPENSSL_SYS_VXWORKS)
277int RAND_poll(void) 326int RAND_poll(void)
278{ 327 {
279 return 0; 328 return 0;
280} 329 }
281#endif 330#endif