| Index: openssl/crypto/rand/rand_unix.c
|
| ===================================================================
|
| --- openssl/crypto/rand/rand_unix.c (revision 105093)
|
| +++ openssl/crypto/rand/rand_unix.c (working copy)
|
| @@ -133,9 +133,92 @@
|
| # define FD_SETSIZE (8*sizeof(fd_set))
|
| #endif
|
|
|
| -#ifdef __OpenBSD__
|
| +#if defined(OPENSSL_SYS_VOS)
|
| +
|
| +/* The following algorithm repeatedly samples the real-time clock
|
| + (RTC) to generate a sequence of unpredictable data. The algorithm
|
| + relies upon the uneven execution speed of the code (due to factors
|
| + such as cache misses, interrupts, bus activity, and scheduling) and
|
| + upon the rather large relative difference between the speed of the
|
| + clock and the rate at which it can be read.
|
| +
|
| + If this code is ported to an environment where execution speed is
|
| + more constant or where the RTC ticks at a much slower rate, or the
|
| + clock can be read with fewer instructions, it is likely that the
|
| + results would be far more predictable.
|
| +
|
| + As a precaution, we generate 4 times the minimum required amount of
|
| + seed data. */
|
| +
|
| int RAND_poll(void)
|
| {
|
| + short int code;
|
| + gid_t curr_gid;
|
| + pid_t curr_pid;
|
| + uid_t curr_uid;
|
| + int i, k;
|
| + struct timespec ts;
|
| + unsigned char v;
|
| +
|
| +#ifdef OPENSSL_SYS_VOS_HPPA
|
| + long duration;
|
| + extern void s$sleep (long *_duration, short int *_code);
|
| +#else
|
| +#ifdef OPENSSL_SYS_VOS_IA32
|
| + long long duration;
|
| + extern void s$sleep2 (long long *_duration, short int *_code);
|
| +#else
|
| +#error "Unsupported Platform."
|
| +#endif /* OPENSSL_SYS_VOS_IA32 */
|
| +#endif /* OPENSSL_SYS_VOS_HPPA */
|
| +
|
| + /* Seed with the gid, pid, and uid, to ensure *some*
|
| + variation between different processes. */
|
| +
|
| + curr_gid = getgid();
|
| + RAND_add (&curr_gid, sizeof curr_gid, 1);
|
| + curr_gid = 0;
|
| +
|
| + curr_pid = getpid();
|
| + RAND_add (&curr_pid, sizeof curr_pid, 1);
|
| + curr_pid = 0;
|
| +
|
| + curr_uid = getuid();
|
| + RAND_add (&curr_uid, sizeof curr_uid, 1);
|
| + curr_uid = 0;
|
| +
|
| + for (i=0; i<(ENTROPY_NEEDED*4); i++)
|
| + {
|
| + /* burn some cpu; hope for interrupts, cache
|
| + collisions, bus interference, etc. */
|
| + for (k=0; k<99; k++)
|
| + ts.tv_nsec = random ();
|
| +
|
| +#ifdef OPENSSL_SYS_VOS_HPPA
|
| + /* sleep for 1/1024 of a second (976 us). */
|
| + duration = 1;
|
| + s$sleep (&duration, &code);
|
| +#else
|
| +#ifdef OPENSSL_SYS_VOS_IA32
|
| + /* sleep for 1/65536 of a second (15 us). */
|
| + duration = 1;
|
| + s$sleep2 (&duration, &code);
|
| +#endif /* OPENSSL_SYS_VOS_IA32 */
|
| +#endif /* OPENSSL_SYS_VOS_HPPA */
|
| +
|
| + /* get wall clock time. */
|
| + clock_gettime (CLOCK_REALTIME, &ts);
|
| +
|
| + /* take 8 bits */
|
| + v = (unsigned char) (ts.tv_nsec % 256);
|
| + RAND_add (&v, sizeof v, 1);
|
| + v = 0;
|
| + }
|
| + return 1;
|
| +}
|
| +#elif defined __OpenBSD__
|
| +int RAND_poll(void)
|
| +{
|
| u_int32_t rnd = 0, i;
|
| unsigned char buf[ENTROPY_NEEDED];
|
|
|
| @@ -163,7 +246,7 @@
|
| static const char *randomfiles[] = { DEVRANDOM };
|
| struct stat randomstats[sizeof(randomfiles)/sizeof(randomfiles[0])];
|
| int fd;
|
| - size_t i;
|
| + unsigned int i;
|
| #endif
|
| #ifdef DEVRANDOM_EGD
|
| static const char *egdsockets[] = { DEVRANDOM_EGD, NULL };
|
| @@ -176,7 +259,8 @@
|
| * have this. Use /dev/urandom if you can as /dev/random may block
|
| * if it runs out of random entries. */
|
|
|
| - for (i=0; i<sizeof(randomfiles)/sizeof(randomfiles[0]) && n < ENTROPY_NEEDED; i++)
|
| + for (i = 0; (i < sizeof(randomfiles)/sizeof(randomfiles[0])) &&
|
| + (n < ENTROPY_NEEDED); i++)
|
| {
|
| if ((fd = open(randomfiles[i], O_RDONLY
|
| #ifdef O_NONBLOCK
|
| @@ -193,7 +277,7 @@
|
| {
|
| int usec = 10*1000; /* spend 10ms on each file */
|
| int r;
|
| - size_t j;
|
| + unsigned int j;
|
| struct stat *st=&randomstats[i];
|
|
|
| /* Avoid using same input... Used to be O_NOFOLLOW
|
| @@ -211,7 +295,12 @@
|
| {
|
| int try_read = 0;
|
|
|
| -#if defined(OPENSSL_SYS_LINUX)
|
| +#if defined(OPENSSL_SYS_BEOS_R5)
|
| + /* select() is broken in BeOS R5, so we simply
|
| + * try to read something and snooze if we couldn't */
|
| + try_read = 1;
|
| +
|
| +#elif defined(OPENSSL_SYS_LINUX)
|
| /* use poll() */
|
| struct pollfd pset;
|
|
|
| @@ -258,6 +347,10 @@
|
| r = read(fd,(unsigned char *)tmpbuf+n, ENTROPY_NEEDED-n);
|
| if (r > 0)
|
| n += r;
|
| +#if defined(OPENSSL_SYS_BEOS_R5)
|
| + if (r == 0)
|
| + snooze(t.tv_usec);
|
| +#endif
|
| }
|
| else
|
| r = -1;
|
| @@ -311,6 +404,14 @@
|
| l=time(NULL);
|
| RAND_add(&l,sizeof(l),0.0);
|
|
|
| +#if defined(OPENSSL_SYS_BEOS)
|
| + {
|
| + system_info sysInfo;
|
| + get_system_info(&sysInfo);
|
| + RAND_add(&sysInfo,sizeof(sysInfo),0);
|
| + }
|
| +#endif
|
| +
|
| #if defined(DEVRANDOM) || defined(DEVRANDOM_EGD)
|
| return 1;
|
| #else
|
|
|