diff options
author | jkim <jkim@FreeBSD.org> | 2012-07-12 19:30:53 +0000 |
---|---|---|
committer | jkim <jkim@FreeBSD.org> | 2012-07-12 19:30:53 +0000 |
commit | e393e47b1e23744a7d0ed999afb5d137070f5f8f (patch) | |
tree | 9739a803477c4610ec6628d914bdcc55fbb3602a /crypto/openssl/crypto/rand/rand_unix.c | |
parent | a8b00dea2cde4c3d96e6ed1de530ddff21012266 (diff) | |
parent | 532b4084cb8cac5e6d91d42aa6a497dd4ba4a4f5 (diff) | |
download | FreeBSD-src-e393e47b1e23744a7d0ed999afb5d137070f5f8f.zip FreeBSD-src-e393e47b1e23744a7d0ed999afb5d137070f5f8f.tar.gz |
Merge OpenSSL 1.0.1c.
Approved by: benl (maintainer)
Diffstat (limited to 'crypto/openssl/crypto/rand/rand_unix.c')
-rw-r--r-- | crypto/openssl/crypto/rand/rand_unix.c | 111 |
1 files changed, 106 insertions, 5 deletions
diff --git a/crypto/openssl/crypto/rand/rand_unix.c b/crypto/openssl/crypto/rand/rand_unix.c index 71b98ec..e3a6557 100644 --- a/crypto/openssl/crypto/rand/rand_unix.c +++ b/crypto/openssl/crypto/rand/rand_unix.c @@ -133,7 +133,90 @@ # 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; @@ -163,7 +246,7 @@ int RAND_poll(void) 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 @@ int RAND_poll(void) * 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 RAND_poll(void) { 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 RAND_poll(void) { 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 @@ int RAND_poll(void) 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 @@ int RAND_poll(void) 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 |