OLD | NEW |
1 /* crypto/rand/rand_unix.c */ | 1 /* crypto/rand/rand_unix.c */ |
2 /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) | 2 /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) |
3 * All rights reserved. | 3 * All rights reserved. |
4 * | 4 * |
5 * This package is an SSL implementation written | 5 * This package is an SSL implementation written |
6 * by Eric Young (eay@cryptsoft.com). | 6 * by Eric Young (eay@cryptsoft.com). |
7 * The implementation was written so as to conform with Netscapes SSL. | 7 * The implementation was written so as to conform with Netscapes SSL. |
8 * | 8 * |
9 * This library is free for commercial and non-commercial use as long as | 9 * This library is free for commercial and non-commercial use as long as |
10 * the following conditions are aheared to. The following conditions | 10 * the following conditions are aheared to. The following conditions |
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
126 #include <unistd.h> | 126 #include <unistd.h> |
127 #include <time.h> | 127 #include <time.h> |
128 #if defined(OPENSSL_SYS_LINUX) /* should actually be available virtually everywh
ere */ | 128 #if defined(OPENSSL_SYS_LINUX) /* should actually be available virtually everywh
ere */ |
129 # include <poll.h> | 129 # include <poll.h> |
130 #endif | 130 #endif |
131 #include <limits.h> | 131 #include <limits.h> |
132 #ifndef FD_SETSIZE | 132 #ifndef FD_SETSIZE |
133 # define FD_SETSIZE (8*sizeof(fd_set)) | 133 # define FD_SETSIZE (8*sizeof(fd_set)) |
134 #endif | 134 #endif |
135 | 135 |
136 #ifdef __OpenBSD__ | 136 #if defined(OPENSSL_SYS_VOS) |
| 137 |
| 138 /* The following algorithm repeatedly samples the real-time clock |
| 139 (RTC) to generate a sequence of unpredictable data. The algorithm |
| 140 relies upon the uneven execution speed of the code (due to factors |
| 141 such as cache misses, interrupts, bus activity, and scheduling) and |
| 142 upon the rather large relative difference between the speed of the |
| 143 clock and the rate at which it can be read. |
| 144 |
| 145 If this code is ported to an environment where execution speed is |
| 146 more constant or where the RTC ticks at a much slower rate, or the |
| 147 clock can be read with fewer instructions, it is likely that the |
| 148 results would be far more predictable. |
| 149 |
| 150 As a precaution, we generate 4 times the minimum required amount of |
| 151 seed data. */ |
| 152 |
| 153 int RAND_poll(void) |
| 154 { |
| 155 » short int code; |
| 156 » gid_t curr_gid; |
| 157 » pid_t curr_pid; |
| 158 » uid_t curr_uid; |
| 159 » int i, k; |
| 160 » struct timespec ts; |
| 161 » unsigned char v; |
| 162 |
| 163 #ifdef OPENSSL_SYS_VOS_HPPA |
| 164 » long duration; |
| 165 » extern void s$sleep (long *_duration, short int *_code); |
| 166 #else |
| 167 #ifdef OPENSSL_SYS_VOS_IA32 |
| 168 » long long duration; |
| 169 » extern void s$sleep2 (long long *_duration, short int *_code); |
| 170 #else |
| 171 #error "Unsupported Platform." |
| 172 #endif /* OPENSSL_SYS_VOS_IA32 */ |
| 173 #endif /* OPENSSL_SYS_VOS_HPPA */ |
| 174 |
| 175 » /* Seed with the gid, pid, and uid, to ensure *some* |
| 176 » variation between different processes. */ |
| 177 |
| 178 » curr_gid = getgid(); |
| 179 » RAND_add (&curr_gid, sizeof curr_gid, 1); |
| 180 » curr_gid = 0; |
| 181 |
| 182 » curr_pid = getpid(); |
| 183 » RAND_add (&curr_pid, sizeof curr_pid, 1); |
| 184 » curr_pid = 0; |
| 185 |
| 186 » curr_uid = getuid(); |
| 187 » RAND_add (&curr_uid, sizeof curr_uid, 1); |
| 188 » curr_uid = 0; |
| 189 |
| 190 » for (i=0; i<(ENTROPY_NEEDED*4); i++) |
| 191 » { |
| 192 » » /* burn some cpu; hope for interrupts, cache |
| 193 » » collisions, bus interference, etc. */ |
| 194 » » for (k=0; k<99; k++) |
| 195 » » » ts.tv_nsec = random (); |
| 196 |
| 197 #ifdef OPENSSL_SYS_VOS_HPPA |
| 198 » » /* sleep for 1/1024 of a second (976 us). */ |
| 199 » » duration = 1; |
| 200 » » s$sleep (&duration, &code); |
| 201 #else |
| 202 #ifdef OPENSSL_SYS_VOS_IA32 |
| 203 » » /* sleep for 1/65536 of a second (15 us). */ |
| 204 » » duration = 1; |
| 205 » » s$sleep2 (&duration, &code); |
| 206 #endif /* OPENSSL_SYS_VOS_IA32 */ |
| 207 #endif /* OPENSSL_SYS_VOS_HPPA */ |
| 208 |
| 209 » » /* get wall clock time. */ |
| 210 » » clock_gettime (CLOCK_REALTIME, &ts); |
| 211 |
| 212 » » /* take 8 bits */ |
| 213 » » v = (unsigned char) (ts.tv_nsec % 256); |
| 214 » » RAND_add (&v, sizeof v, 1); |
| 215 » » v = 0; |
| 216 » } |
| 217 » return 1; |
| 218 } |
| 219 #elif defined __OpenBSD__ |
137 int RAND_poll(void) | 220 int RAND_poll(void) |
138 { | 221 { |
139 u_int32_t rnd = 0, i; | 222 u_int32_t rnd = 0, i; |
140 unsigned char buf[ENTROPY_NEEDED]; | 223 unsigned char buf[ENTROPY_NEEDED]; |
141 | 224 |
142 for (i = 0; i < sizeof(buf); i++) { | 225 for (i = 0; i < sizeof(buf); i++) { |
143 if (i % 4 == 0) | 226 if (i % 4 == 0) |
144 rnd = arc4random(); | 227 rnd = arc4random(); |
145 buf[i] = rnd; | 228 buf[i] = rnd; |
146 rnd >>= 8; | 229 rnd >>= 8; |
147 } | 230 } |
148 RAND_add(buf, sizeof(buf), ENTROPY_NEEDED); | 231 RAND_add(buf, sizeof(buf), ENTROPY_NEEDED); |
149 memset(buf, 0, sizeof(buf)); | 232 memset(buf, 0, sizeof(buf)); |
150 | 233 |
151 return 1; | 234 return 1; |
152 } | 235 } |
153 #else /* !defined(__OpenBSD__) */ | 236 #else /* !defined(__OpenBSD__) */ |
154 int RAND_poll(void) | 237 int RAND_poll(void) |
155 { | 238 { |
156 unsigned long l; | 239 unsigned long l; |
157 pid_t curr_pid = getpid(); | 240 pid_t curr_pid = getpid(); |
158 #if defined(DEVRANDOM) || defined(DEVRANDOM_EGD) | 241 #if defined(DEVRANDOM) || defined(DEVRANDOM_EGD) |
159 unsigned char tmpbuf[ENTROPY_NEEDED]; | 242 unsigned char tmpbuf[ENTROPY_NEEDED]; |
160 int n = 0; | 243 int n = 0; |
161 #endif | 244 #endif |
162 #ifdef DEVRANDOM | 245 #ifdef DEVRANDOM |
163 static const char *randomfiles[] = { DEVRANDOM }; | 246 static const char *randomfiles[] = { DEVRANDOM }; |
164 struct stat randomstats[sizeof(randomfiles)/sizeof(randomfiles[0])]; | 247 struct stat randomstats[sizeof(randomfiles)/sizeof(randomfiles[0])]; |
165 int fd; | 248 int fd; |
166 » size_t i; | 249 » unsigned int i; |
167 #endif | 250 #endif |
168 #ifdef DEVRANDOM_EGD | 251 #ifdef DEVRANDOM_EGD |
169 static const char *egdsockets[] = { DEVRANDOM_EGD, NULL }; | 252 static const char *egdsockets[] = { DEVRANDOM_EGD, NULL }; |
170 const char **egdsocket = NULL; | 253 const char **egdsocket = NULL; |
171 #endif | 254 #endif |
172 | 255 |
173 #ifdef DEVRANDOM | 256 #ifdef DEVRANDOM |
174 memset(randomstats,0,sizeof(randomstats)); | 257 memset(randomstats,0,sizeof(randomstats)); |
175 /* Use a random entropy pool device. Linux, FreeBSD and OpenBSD | 258 /* Use a random entropy pool device. Linux, FreeBSD and OpenBSD |
176 * have this. Use /dev/urandom if you can as /dev/random may block | 259 * have this. Use /dev/urandom if you can as /dev/random may block |
177 * if it runs out of random entries. */ | 260 * if it runs out of random entries. */ |
178 | 261 |
179 » for (i=0; i<sizeof(randomfiles)/sizeof(randomfiles[0]) && n < ENTROPY_NE
EDED; i++) | 262 » for (i = 0; (i < sizeof(randomfiles)/sizeof(randomfiles[0])) && |
| 263 » » » (n < ENTROPY_NEEDED); i++) |
180 { | 264 { |
181 if ((fd = open(randomfiles[i], O_RDONLY | 265 if ((fd = open(randomfiles[i], O_RDONLY |
182 #ifdef O_NONBLOCK | 266 #ifdef O_NONBLOCK |
183 |O_NONBLOCK | 267 |O_NONBLOCK |
184 #endif | 268 #endif |
185 #ifdef O_BINARY | 269 #ifdef O_BINARY |
186 |O_BINARY | 270 |O_BINARY |
187 #endif | 271 #endif |
188 #ifdef O_NOCTTY /* If it happens to be a TTY (god forbid), do not make it | 272 #ifdef O_NOCTTY /* If it happens to be a TTY (god forbid), do not make it |
189 our controlling tty */ | 273 our controlling tty */ |
190 |O_NOCTTY | 274 |O_NOCTTY |
191 #endif | 275 #endif |
192 )) >= 0) | 276 )) >= 0) |
193 { | 277 { |
194 int usec = 10*1000; /* spend 10ms on each file */ | 278 int usec = 10*1000; /* spend 10ms on each file */ |
195 int r; | 279 int r; |
196 » » » size_t j; | 280 » » » unsigned int j; |
197 struct stat *st=&randomstats[i]; | 281 struct stat *st=&randomstats[i]; |
198 | 282 |
199 /* Avoid using same input... Used to be O_NOFOLLOW | 283 /* Avoid using same input... Used to be O_NOFOLLOW |
200 * above, but it's not universally appropriate... */ | 284 * above, but it's not universally appropriate... */ |
201 if (fstat(fd,st) != 0) { close(fd); continue; } | 285 if (fstat(fd,st) != 0) { close(fd); continue; } |
202 for (j=0;j<i;j++) | 286 for (j=0;j<i;j++) |
203 { | 287 { |
204 if (randomstats[j].st_ino==st->st_ino && | 288 if (randomstats[j].st_ino==st->st_ino && |
205 randomstats[j].st_dev==st->st_dev) | 289 randomstats[j].st_dev==st->st_dev) |
206 break; | 290 break; |
207 } | 291 } |
208 if (j<i) { close(fd); continue; } | 292 if (j<i) { close(fd); continue; } |
209 | 293 |
210 do | 294 do |
211 { | 295 { |
212 int try_read = 0; | 296 int try_read = 0; |
213 | 297 |
214 #if defined(OPENSSL_SYS_LINUX) | 298 #if defined(OPENSSL_SYS_BEOS_R5) |
| 299 » » » » /* select() is broken in BeOS R5, so we simply |
| 300 » » » » * try to read something and snooze if we could
n't */ |
| 301 » » » » try_read = 1; |
| 302 |
| 303 #elif defined(OPENSSL_SYS_LINUX) |
215 /* use poll() */ | 304 /* use poll() */ |
216 struct pollfd pset; | 305 struct pollfd pset; |
217 | 306 |
218 pset.fd = fd; | 307 pset.fd = fd; |
219 pset.events = POLLIN; | 308 pset.events = POLLIN; |
220 pset.revents = 0; | 309 pset.revents = 0; |
221 | 310 |
222 if (poll(&pset, 1, usec / 1000) < 0) | 311 if (poll(&pset, 1, usec / 1000) < 0) |
223 usec = 0; | 312 usec = 0; |
224 else | 313 else |
(...skipping 26 matching lines...) Expand all Loading... |
251 else | 340 else |
252 usec = 0; | 341 usec = 0; |
253 } | 342 } |
254 #endif | 343 #endif |
255 | 344 |
256 if (try_read) | 345 if (try_read) |
257 { | 346 { |
258 r = read(fd,(unsigned char *)tmpbuf+n, E
NTROPY_NEEDED-n); | 347 r = read(fd,(unsigned char *)tmpbuf+n, E
NTROPY_NEEDED-n); |
259 if (r > 0) | 348 if (r > 0) |
260 n += r; | 349 n += r; |
| 350 #if defined(OPENSSL_SYS_BEOS_R5) |
| 351 if (r == 0) |
| 352 snooze(t.tv_usec); |
| 353 #endif |
261 } | 354 } |
262 else | 355 else |
263 r = -1; | 356 r = -1; |
264 | 357 |
265 /* Some Unixen will update t in select(), some | 358 /* Some Unixen will update t in select(), some |
266 won't. For those who won't, or if we | 359 won't. For those who won't, or if we |
267 didn't use select() in the first place, | 360 didn't use select() in the first place, |
268 give up here, otherwise, we will do | 361 give up here, otherwise, we will do |
269 this once again for the remaining | 362 this once again for the remaining |
270 time. */ | 363 time. */ |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
304 | 397 |
305 /* put in some default random data, we need more than just this */ | 398 /* put in some default random data, we need more than just this */ |
306 l=curr_pid; | 399 l=curr_pid; |
307 RAND_add(&l,sizeof(l),0.0); | 400 RAND_add(&l,sizeof(l),0.0); |
308 l=getuid(); | 401 l=getuid(); |
309 RAND_add(&l,sizeof(l),0.0); | 402 RAND_add(&l,sizeof(l),0.0); |
310 | 403 |
311 l=time(NULL); | 404 l=time(NULL); |
312 RAND_add(&l,sizeof(l),0.0); | 405 RAND_add(&l,sizeof(l),0.0); |
313 | 406 |
| 407 #if defined(OPENSSL_SYS_BEOS) |
| 408 { |
| 409 system_info sysInfo; |
| 410 get_system_info(&sysInfo); |
| 411 RAND_add(&sysInfo,sizeof(sysInfo),0); |
| 412 } |
| 413 #endif |
| 414 |
314 #if defined(DEVRANDOM) || defined(DEVRANDOM_EGD) | 415 #if defined(DEVRANDOM) || defined(DEVRANDOM_EGD) |
315 return 1; | 416 return 1; |
316 #else | 417 #else |
317 return 0; | 418 return 0; |
318 #endif | 419 #endif |
319 } | 420 } |
320 | 421 |
321 #endif /* defined(__OpenBSD__) */ | 422 #endif /* defined(__OpenBSD__) */ |
322 #endif /* !(defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_WIN32) || define
d(OPENSSL_SYS_VMS) || defined(OPENSSL_SYS_OS2) || defined(OPENSSL_SYS_VXWORKS) |
| defined(OPENSSL_SYS_NETWARE)) */ | 423 #endif /* !(defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_WIN32) || define
d(OPENSSL_SYS_VMS) || defined(OPENSSL_SYS_OS2) || defined(OPENSSL_SYS_VXWORKS) |
| defined(OPENSSL_SYS_NETWARE)) */ |
323 | 424 |
324 | 425 |
325 #if defined(OPENSSL_SYS_VXWORKS) | 426 #if defined(OPENSSL_SYS_VXWORKS) |
326 int RAND_poll(void) | 427 int RAND_poll(void) |
327 { | 428 { |
328 return 0; | 429 return 0; |
329 } | 430 } |
330 #endif | 431 #endif |
OLD | NEW |