| OLD | NEW |
| (Empty) |
| 1 /* crypto/rand/rand_unix.c */ | |
| 2 /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) | |
| 3 * All rights reserved. | |
| 4 * | |
| 5 * This package is an SSL implementation written | |
| 6 * by Eric Young (eay@cryptsoft.com). | |
| 7 * The implementation was written so as to conform with Netscapes SSL. | |
| 8 * | |
| 9 * This library is free for commercial and non-commercial use as long as | |
| 10 * the following conditions are aheared to. The following conditions | |
| 11 * apply to all code found in this distribution, be it the RC4, RSA, | |
| 12 * lhash, DES, etc., code; not just the SSL code. The SSL documentation | |
| 13 * included with this distribution is covered by the same copyright terms | |
| 14 * except that the holder is Tim Hudson (tjh@cryptsoft.com). | |
| 15 * | |
| 16 * Copyright remains Eric Young's, and as such any Copyright notices in | |
| 17 * the code are not to be removed. | |
| 18 * If this package is used in a product, Eric Young should be given attribution | |
| 19 * as the author of the parts of the library used. | |
| 20 * This can be in the form of a textual message at program startup or | |
| 21 * in documentation (online or textual) provided with the package. | |
| 22 * | |
| 23 * Redistribution and use in source and binary forms, with or without | |
| 24 * modification, are permitted provided that the following conditions | |
| 25 * are met: | |
| 26 * 1. Redistributions of source code must retain the copyright | |
| 27 * notice, this list of conditions and the following disclaimer. | |
| 28 * 2. Redistributions in binary form must reproduce the above copyright | |
| 29 * notice, this list of conditions and the following disclaimer in the | |
| 30 * documentation and/or other materials provided with the distribution. | |
| 31 * 3. All advertising materials mentioning features or use of this software | |
| 32 * must display the following acknowledgement: | |
| 33 * "This product includes cryptographic software written by | |
| 34 * Eric Young (eay@cryptsoft.com)" | |
| 35 * The word 'cryptographic' can be left out if the rouines from the library | |
| 36 * being used are not cryptographic related :-). | |
| 37 * 4. If you include any Windows specific code (or a derivative thereof) from | |
| 38 * the apps directory (application code) you must include an acknowledgement: | |
| 39 * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" | |
| 40 * | |
| 41 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND | |
| 42 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |
| 43 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |
| 44 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE | |
| 45 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | |
| 46 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | |
| 47 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |
| 48 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | |
| 49 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | |
| 50 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |
| 51 * SUCH DAMAGE. | |
| 52 * | |
| 53 * The licence and distribution terms for any publically available version or | |
| 54 * derivative of this code cannot be changed. i.e. this code cannot simply be | |
| 55 * copied and put under another distribution licence | |
| 56 * [including the GNU Public Licence.] | |
| 57 */ | |
| 58 /* ==================================================================== | |
| 59 * Copyright (c) 1998-2006 The OpenSSL Project. All rights reserved. | |
| 60 * | |
| 61 * Redistribution and use in source and binary forms, with or without | |
| 62 * modification, are permitted provided that the following conditions | |
| 63 * are met: | |
| 64 * | |
| 65 * 1. Redistributions of source code must retain the above copyright | |
| 66 * notice, this list of conditions and the following disclaimer. | |
| 67 * | |
| 68 * 2. Redistributions in binary form must reproduce the above copyright | |
| 69 * notice, this list of conditions and the following disclaimer in | |
| 70 * the documentation and/or other materials provided with the | |
| 71 * distribution. | |
| 72 * | |
| 73 * 3. All advertising materials mentioning features or use of this | |
| 74 * software must display the following acknowledgment: | |
| 75 * "This product includes software developed by the OpenSSL Project | |
| 76 * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" | |
| 77 * | |
| 78 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to | |
| 79 * endorse or promote products derived from this software without | |
| 80 * prior written permission. For written permission, please contact | |
| 81 * openssl-core@openssl.org. | |
| 82 * | |
| 83 * 5. Products derived from this software may not be called "OpenSSL" | |
| 84 * nor may "OpenSSL" appear in their names without prior written | |
| 85 * permission of the OpenSSL Project. | |
| 86 * | |
| 87 * 6. Redistributions of any form whatsoever must retain the following | |
| 88 * acknowledgment: | |
| 89 * "This product includes software developed by the OpenSSL Project | |
| 90 * for use in the OpenSSL Toolkit (http://www.openssl.org/)" | |
| 91 * | |
| 92 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY | |
| 93 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |
| 94 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | |
| 95 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR | |
| 96 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |
| 97 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | |
| 98 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | |
| 99 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |
| 100 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | |
| 101 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | |
| 102 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED | |
| 103 * OF THE POSSIBILITY OF SUCH DAMAGE. | |
| 104 * ==================================================================== | |
| 105 * | |
| 106 * This product includes cryptographic software written by Eric Young | |
| 107 * (eay@cryptsoft.com). This product includes software written by Tim | |
| 108 * Hudson (tjh@cryptsoft.com). | |
| 109 * | |
| 110 */ | |
| 111 #include <stdio.h> | |
| 112 | |
| 113 #define USE_SOCKETS | |
| 114 #include "e_os.h" | |
| 115 #include "cryptlib.h" | |
| 116 #include <openssl/rand.h> | |
| 117 #include "rand_lcl.h" | |
| 118 | |
| 119 #if !(defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_WIN32) || defined(OPEN
SSL_SYS_VMS) || defined(OPENSSL_SYS_OS2) || defined(OPENSSL_SYS_VXWORKS) || defi
ned(OPENSSL_SYS_NETWARE)) | |
| 120 | |
| 121 #include <sys/types.h> | |
| 122 #include <sys/time.h> | |
| 123 #include <sys/times.h> | |
| 124 #include <sys/stat.h> | |
| 125 #include <fcntl.h> | |
| 126 #include <unistd.h> | |
| 127 #include <time.h> | |
| 128 #if defined(OPENSSL_SYS_LINUX) /* should actually be available virtually everywh
ere */ | |
| 129 # include <poll.h> | |
| 130 #endif | |
| 131 #include <limits.h> | |
| 132 #ifndef FD_SETSIZE | |
| 133 # define FD_SETSIZE (8*sizeof(fd_set)) | |
| 134 #endif | |
| 135 | |
| 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__ | |
| 220 int RAND_poll(void) | |
| 221 { | |
| 222 u_int32_t rnd = 0, i; | |
| 223 unsigned char buf[ENTROPY_NEEDED]; | |
| 224 | |
| 225 for (i = 0; i < sizeof(buf); i++) { | |
| 226 if (i % 4 == 0) | |
| 227 rnd = arc4random(); | |
| 228 buf[i] = rnd; | |
| 229 rnd >>= 8; | |
| 230 } | |
| 231 RAND_add(buf, sizeof(buf), ENTROPY_NEEDED); | |
| 232 memset(buf, 0, sizeof(buf)); | |
| 233 | |
| 234 return 1; | |
| 235 } | |
| 236 #else /* !defined(__OpenBSD__) */ | |
| 237 int RAND_poll(void) | |
| 238 { | |
| 239 unsigned long l; | |
| 240 pid_t curr_pid = getpid(); | |
| 241 #if defined(DEVRANDOM) || defined(DEVRANDOM_EGD) | |
| 242 unsigned char tmpbuf[ENTROPY_NEEDED]; | |
| 243 int n = 0; | |
| 244 #endif | |
| 245 #ifdef DEVRANDOM | |
| 246 static const char *randomfiles[] = { DEVRANDOM }; | |
| 247 struct stat randomstats[sizeof(randomfiles)/sizeof(randomfiles[0])]; | |
| 248 int fd; | |
| 249 unsigned int i; | |
| 250 #endif | |
| 251 #ifdef DEVRANDOM_EGD | |
| 252 static const char *egdsockets[] = { DEVRANDOM_EGD, NULL }; | |
| 253 const char **egdsocket = NULL; | |
| 254 #endif | |
| 255 | |
| 256 #ifdef DEVRANDOM | |
| 257 memset(randomstats,0,sizeof(randomstats)); | |
| 258 /* Use a random entropy pool device. Linux, FreeBSD and OpenBSD | |
| 259 * have this. Use /dev/urandom if you can as /dev/random may block | |
| 260 * if it runs out of random entries. */ | |
| 261 | |
| 262 for (i = 0; (i < sizeof(randomfiles)/sizeof(randomfiles[0])) && | |
| 263 (n < ENTROPY_NEEDED); i++) | |
| 264 { | |
| 265 if ((fd = open(randomfiles[i], O_RDONLY | |
| 266 #ifdef O_NONBLOCK | |
| 267 |O_NONBLOCK | |
| 268 #endif | |
| 269 #ifdef O_BINARY | |
| 270 |O_BINARY | |
| 271 #endif | |
| 272 #ifdef O_NOCTTY /* If it happens to be a TTY (god forbid), do not make it | |
| 273 our controlling tty */ | |
| 274 |O_NOCTTY | |
| 275 #endif | |
| 276 )) >= 0) | |
| 277 { | |
| 278 int usec = 10*1000; /* spend 10ms on each file */ | |
| 279 int r; | |
| 280 unsigned int j; | |
| 281 struct stat *st=&randomstats[i]; | |
| 282 | |
| 283 /* Avoid using same input... Used to be O_NOFOLLOW | |
| 284 * above, but it's not universally appropriate... */ | |
| 285 if (fstat(fd,st) != 0) { close(fd); continue; } | |
| 286 for (j=0;j<i;j++) | |
| 287 { | |
| 288 if (randomstats[j].st_ino==st->st_ino && | |
| 289 randomstats[j].st_dev==st->st_dev) | |
| 290 break; | |
| 291 } | |
| 292 if (j<i) { close(fd); continue; } | |
| 293 | |
| 294 do | |
| 295 { | |
| 296 int try_read = 0; | |
| 297 | |
| 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) | |
| 304 /* use poll() */ | |
| 305 struct pollfd pset; | |
| 306 | |
| 307 pset.fd = fd; | |
| 308 pset.events = POLLIN; | |
| 309 pset.revents = 0; | |
| 310 | |
| 311 if (poll(&pset, 1, usec / 1000) < 0) | |
| 312 usec = 0; | |
| 313 else | |
| 314 try_read = (pset.revents & POLLIN) != 0; | |
| 315 | |
| 316 #else | |
| 317 /* use select() */ | |
| 318 fd_set fset; | |
| 319 struct timeval t; | |
| 320 | |
| 321 t.tv_sec = 0; | |
| 322 t.tv_usec = usec; | |
| 323 | |
| 324 if (FD_SETSIZE > 0 && (unsigned)fd >= FD_SETSIZE
) | |
| 325 { | |
| 326 /* can't use select, so just try to read
once anyway */ | |
| 327 try_read = 1; | |
| 328 } | |
| 329 else | |
| 330 { | |
| 331 FD_ZERO(&fset); | |
| 332 FD_SET(fd, &fset); | |
| 333 | |
| 334 if (select(fd+1,&fset,NULL,NULL,&t) >= 0
) | |
| 335 { | |
| 336 usec = t.tv_usec; | |
| 337 if (FD_ISSET(fd, &fset)) | |
| 338 try_read = 1; | |
| 339 } | |
| 340 else | |
| 341 usec = 0; | |
| 342 } | |
| 343 #endif | |
| 344 | |
| 345 if (try_read) | |
| 346 { | |
| 347 r = read(fd,(unsigned char *)tmpbuf+n, E
NTROPY_NEEDED-n); | |
| 348 if (r > 0) | |
| 349 n += r; | |
| 350 #if defined(OPENSSL_SYS_BEOS_R5) | |
| 351 if (r == 0) | |
| 352 snooze(t.tv_usec); | |
| 353 #endif | |
| 354 } | |
| 355 else | |
| 356 r = -1; | |
| 357 | |
| 358 /* Some Unixen will update t in select(), some | |
| 359 won't. For those who won't, or if we | |
| 360 didn't use select() in the first place, | |
| 361 give up here, otherwise, we will do | |
| 362 this once again for the remaining | |
| 363 time. */ | |
| 364 if (usec == 10*1000) | |
| 365 usec = 0; | |
| 366 } | |
| 367 while ((r > 0 || | |
| 368 (errno == EINTR || errno == EAGAIN)) && usec != 0
&& n < ENTROPY_NEEDED); | |
| 369 | |
| 370 close(fd); | |
| 371 } | |
| 372 } | |
| 373 #endif /* defined(DEVRANDOM) */ | |
| 374 | |
| 375 #ifdef DEVRANDOM_EGD | |
| 376 /* Use an EGD socket to read entropy from an EGD or PRNGD entropy | |
| 377 * collecting daemon. */ | |
| 378 | |
| 379 for (egdsocket = egdsockets; *egdsocket && n < ENTROPY_NEEDED; egdsocket
++) | |
| 380 { | |
| 381 int r; | |
| 382 | |
| 383 r = RAND_query_egd_bytes(*egdsocket, (unsigned char *)tmpbuf+n, | |
| 384 ENTROPY_NEEDED-n); | |
| 385 if (r > 0) | |
| 386 n += r; | |
| 387 } | |
| 388 #endif /* defined(DEVRANDOM_EGD) */ | |
| 389 | |
| 390 #if defined(DEVRANDOM) || defined(DEVRANDOM_EGD) | |
| 391 if (n > 0) | |
| 392 { | |
| 393 RAND_add(tmpbuf,sizeof tmpbuf,(double)n); | |
| 394 OPENSSL_cleanse(tmpbuf,n); | |
| 395 } | |
| 396 #endif | |
| 397 | |
| 398 /* put in some default random data, we need more than just this */ | |
| 399 l=curr_pid; | |
| 400 RAND_add(&l,sizeof(l),0.0); | |
| 401 l=getuid(); | |
| 402 RAND_add(&l,sizeof(l),0.0); | |
| 403 | |
| 404 l=time(NULL); | |
| 405 RAND_add(&l,sizeof(l),0.0); | |
| 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 | |
| 415 #if defined(DEVRANDOM) || defined(DEVRANDOM_EGD) | |
| 416 return 1; | |
| 417 #else | |
| 418 return 0; | |
| 419 #endif | |
| 420 } | |
| 421 | |
| 422 #endif /* defined(__OpenBSD__) */ | |
| 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)) */ | |
| 424 | |
| 425 | |
| 426 #if defined(OPENSSL_SYS_VXWORKS) | |
| 427 int RAND_poll(void) | |
| 428 { | |
| 429 return 0; | |
| 430 } | |
| 431 #endif | |
| OLD | NEW |