| 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 |