diff options
Diffstat (limited to 'crypto/rand/rand_lib.c')
-rw-r--r-- | crypto/rand/rand_lib.c | 64 |
1 files changed, 64 insertions, 0 deletions
diff --git a/crypto/rand/rand_lib.c b/crypto/rand/rand_lib.c index 3168d84b47..05aa45cd64 100644 --- a/crypto/rand/rand_lib.c +++ b/crypto/rand/rand_lib.c @@ -25,6 +25,70 @@ static CRYPTO_RWLOCK *rand_meth_lock; static const RAND_METHOD *default_RAND_meth; static CRYPTO_ONCE rand_init = CRYPTO_ONCE_STATIC_INIT; +#ifdef OPENSSL_RAND_SEED_RDTSC +/* + * IMPORTANT NOTE: It is not currently possible to use this code + * because we are not sure about the amount of randomness. Some + * SP900 tests have been run, but there is internal skepticism. + * So for now this code is not used. + */ +# error "RDTSC enabled? Should not be possible!" + +/* + * Since we get some randomness from the low-order bits of the + * high-speec clock, it can help. But don't return a status since + * it's not sufficient to indicate whether or not the seeding was + * done. + */ +void rand_rdtsc(void) +{ + unsigned char c; + int i; + + for (i = 0; i < 10; i++) { + c = (unsigned char)(OPENSSL_rdtsc() & 0xFF); + RAND_add(&c, 1, 0.5); + } +} +#endif + +#ifdef OPENSSL_RAND_SEED_RDCPU +size_t OPENSSL_ia32_rdseed(void); +size_t OPENSSL_ia32_rdrand(void); + +extern unsigned int OPENSSL_ia32cap_P[]; + +int rand_rdcpu(void) +{ + size_t i, s; + + /* If RDSEED is available, use that. */ + if ((OPENSSL_ia32cap_P[1] & (1 << 18)) != 0) { + for (i = 0; i < RANDOMNESS_NEEDED; i += sizeof(s)) { + s = OPENSSL_ia32_rdseed(); + if (s == 0) + break; + RAND_add(&s, (int)sizeof(s), sizeof(s)); + } + if (i >= RANDOMNESS_NEEDED) + return 1; + } + + /* Second choice is RDRAND. */ + if ((OPENSSL_ia32cap_P[1] & (1 << (62 - 32))) != 0) { + for (i = 0; i < RANDOMNESS_NEEDED; i += sizeof(s)) { + s = OPENSSL_ia32_rdrand(); + if (s == 0) + break; + RAND_add(&s, (int)sizeof(s), sizeof(s)); + } + if (i >= RANDOMNESS_NEEDED) + return 1; + } + + return 0; +} +#endif DEFINE_RUN_ONCE_STATIC(do_rand_init) { |