diff options
author | Pauli <paul.dale@oracle.com> | 2018-02-06 07:17:31 +1000 |
---|---|---|
committer | Pauli <paul.dale@oracle.com> | 2018-02-07 10:08:15 +1000 |
commit | 2b66fd5720c38c6e89f9cd00d36d2c828ed4cd4b (patch) | |
tree | 7b0c8f57515effbe3873bd5769b996376e350e6f /crypto | |
parent | 360fc9f412f1f60a4644228d9b6d386161aad406 (diff) |
Unify timer code
Remove the timer and TSC additional input code and instead provide a single
routine that attempts to use the "best" timer/counter available on the
system. It attempts to use TSC, then various OS dependent resources and
finally several tries to obtain the date. If any of these timer/counters
is successful, the rest are skipped.
No randomness is credited for this.
Reviewed-by: Richard Levitte <levitte@openssl.org>
Reviewed-by: Matthias St. Pierre <Matthias.St.Pierre@ncp-e.com>
(Merged from https://github.com/openssl/openssl/pull/5231)
Diffstat (limited to 'crypto')
-rw-r--r-- | crypto/rand/rand_lib.c | 92 |
1 files changed, 71 insertions, 21 deletions
diff --git a/crypto/rand/rand_lib.c b/crypto/rand/rand_lib.c index e82a63e599..810677b79b 100644 --- a/crypto/rand/rand_lib.c +++ b/crypto/rand/rand_lib.c @@ -22,6 +22,9 @@ #endif #include "e_os.h" +/* Macro to convert two thirty two bit values into a sixty four bit one */ +#define TWO32TO64(a, b) ((((uint64_t)(a)) << 32) + (b)) + #ifndef OPENSSL_NO_ENGINE /* non-NULL if default_RAND_meth is ENGINE-provided */ static ENGINE *funct_ref; @@ -194,6 +197,71 @@ size_t rand_drbg_get_entropy(RAND_DRBG *drbg, } /* + * Find a suitable system time. Start with the highest resolution source + * and work down to the slower ones. This is added as additional data and + * isn't counted as randomness, so any result is acceptable. + */ +static uint64_t get_timer_bits(void) +{ + uint64_t res = OPENSSL_rdtsc(); + + if (res != 0) + return res; +#if defined(_WIN32) + { + LARGE_INTEGER t; + FILETIME ft; + + if (QueryPerformanceCounter(&t) != 0) + return t.QuadPart; + GetSystemTimeAsFileTime(&ft); + return TWO32TO64(ft.dwHighDateTime, ft.dwLowDateTime); + } +#elif defined(__sun) || defined(__hpux) + return gethrtime(); +#elif defined(_AIX) + { + timebasestruct_t t; + + read_wall_time(&t, TIMEBASE_SZ); + return TWO32TO64(t.tb_high, t.tb_low); + } +#else + +# if defined(_POSIX_C_SOURCE) \ + && defined(_POSIX_TIMERS) \ + && _POSIX_C_SOURCE >= 199309L \ + && (!defined(__GLIBC__) || __GLIBC_PREREQ(2, 17)) + { + struct timespec ts; + clockid_t cid; + +# ifdef CLOCK_BOOTTIME + cid = CLOCK_BOOTTIME; +# elif defined(_POSIX_MONOTONIC_CLOCK) + cid = CLOCK_MONOTONIC; +# else + cid = CLOCK_REALTIME; +# endif + + if (clock_gettime(cid, &ts) == 0) + return TWO32TO64(ts.tv_sec, ts.tv_nsec); + } +# endif +# if defined(__unix__) \ + || (defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 200112L) + { + struct timeval tv; + + if (gettimeofday(&tv, NULL) == 0) + return TWO32TO64(tv.tv_sec, tv.tv_usec); + } +# endif + return time(NULL); +#endif +} + +/* * Generate additional data that can be used for the drbg. The data does * not need to contain entropy, but it's useful if it contains at least * some bits that are unpredictable. @@ -210,15 +278,10 @@ size_t rand_drbg_get_additional_data(unsigned char **pout, size_t max_len) size_t len; #ifdef OPENSSL_SYS_UNIX pid_t pid; - struct timeval tv; #elif defined(OPENSSL_SYS_WIN32) DWORD pid; - FILETIME ft; - LARGE_INTEGER pc; -#endif -#ifdef OPENSSL_CPUID_OBJ - uint32_t tsc = 0; #endif + uint64_t tbits; pool = RAND_POOL_new(0, 0, max_len); if (pool == NULL) @@ -236,21 +299,8 @@ size_t rand_drbg_get_additional_data(unsigned char **pout, size_t max_len) if (thread_id != 0) RAND_POOL_add(pool, (unsigned char *)&thread_id, sizeof(thread_id), 0); -#ifdef OPENSSL_CPUID_OBJ - tsc = OPENSSL_rdtsc(); - if (tsc != 0) - RAND_POOL_add(pool, (unsigned char *)&tsc, sizeof(tsc), 0); -#endif - -#ifdef OPENSSL_SYS_UNIX - if (gettimeofday(&tv, NULL) == 0) - RAND_POOL_add(pool, (unsigned char *)&tv, sizeof(tv), 0); -#elif defined(OPENSSL_SYS_WIN32) - if (QueryPerformanceCounter(&pc) != 0) - RAND_POOL_add(pool, (unsigned char *)&pc, sizeof(pc), 0); - GetSystemTimeAsFileTime(&ft); - RAND_POOL_add(pool, (unsigned char *)&ft, sizeof(ft), 0); -#endif + tbits = get_timer_bits(); + RAND_POOL_add(pool, (unsigned char *)&tbits, sizeof(tbits), 0); /* TODO: Use RDSEED? */ |