diff options
Diffstat (limited to 'src/lib/libcrypto/rand/rand_unix.c')
-rw-r--r-- | src/lib/libcrypto/rand/rand_unix.c | 119 |
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__ |
129 | int RAND_poll(void) | 137 | int 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__) */ |
146 | int RAND_poll(void) | 154 | int 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) |
277 | int RAND_poll(void) | 326 | int RAND_poll(void) |
278 | { | 327 | { |
279 | return 0; | 328 | return 0; |
280 | } | 329 | } |
281 | #endif | 330 | #endif |