X-Git-Url: https://git.openssl.org/gitweb/?p=openssl.git;a=blobdiff_plain;f=crypto%2Frand%2Frand_lib.c;h=05aa45cd640a153f16e43f5796794e43dc39228e;hp=3168d84b4796bcc20bd70136e16d432b39004e13;hb=8389ec4b4950b9474e72a959eb0b0a6ce77ac1e8;hpb=0d7903f83f84bba1d29225efd999c633a0c5ba01;ds=sidebyside 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) {