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 |