#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.
+ * because we are not sure about the amount of randomness it provides.
+ * 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!"
unsigned char c;
int i;
- for (i = 0; i < 10; i++) {
- c = (unsigned char)(OPENSSL_rdtsc() & 0xFF);
- cb(arg, &c, 1, 0.5);
+ if ((OPENSSL_ia32cap_P[0] & (1 << 4)) != 0) {
+ for (i = 0; i < TSC_READ_COUNT; i++) {
+ c = (unsigned char)(OPENSSL_rdtsc() & 0xFF);
+ cb(arg, &c, 1, 0.5);
+ }
}
}
#endif
#ifdef OPENSSL_RAND_SEED_RDCPU
-size_t OPENSSL_ia32_rdseed(void);
-size_t OPENSSL_ia32_rdrand(void);
+size_t OPENSSL_ia32_rdseed_bytes(char *buf, size_t len);
+size_t OPENSSL_ia32_rdrand_bytes(char *buf, size_t len);
extern unsigned int OPENSSL_ia32cap_P[];
int rand_read_cpu(RAND_poll_fn cb, void *arg)
{
- size_t i, s;
+ char buff[RANDOMNESS_NEEDED];
/* 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;
- cb(arg, &s, (int)sizeof(s), sizeof(s));
- }
- if (i >= RANDOMNESS_NEEDED)
+ if ((OPENSSL_ia32cap_P[2] & (1 << 18)) != 0) {
+ if (OPENSSL_ia32_rdseed_bytes(buff, sizeof(buff)) == sizeof(buff)) {
+ cb(arg, buff, (int)sizeof(buff), sizeof(buff));
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;
- cb(arg, &s, (int)sizeof(s), sizeof(s));
- }
- if (i >= RANDOMNESS_NEEDED)
+ if (OPENSSL_ia32_rdrand_bytes(buff, sizeof(buff)) == sizeof(buff)) {
+ cb(arg, buff, (int)sizeof(buff), sizeof(buff));
return 1;
+ }
}
return 0;
drbg->lock = CRYPTO_THREAD_lock_new();
ret &= drbg->lock != NULL;
drbg->size = RANDOMNESS_NEEDED;
- drbg->randomness = OPENSSL_malloc(drbg->size);
+ drbg->secure = CRYPTO_secure_malloc_initialized();
+ drbg->randomness = drbg->secure
+ ? OPENSSL_secure_malloc(drbg->size)
+ : OPENSSL_malloc(drbg->size);
ret &= drbg->randomness != NULL;
/* If you change these parameters, see RANDOMNESS_NEEDED */
ret &= RAND_DRBG_set(drbg,
static void free_drbg(RAND_DRBG *drbg)
{
CRYPTO_THREAD_lock_free(drbg->lock);
- OPENSSL_clear_free(drbg->randomness, drbg->size);
+ if (drbg->secure)
+ OPENSSL_secure_clear_free(drbg->randomness, drbg->size);
+ else
+ OPENSSL_clear_free(drbg->randomness, drbg->size);
RAND_DRBG_uninstantiate(drbg);
}
ret &= rand_bytes.lock != NULL;
rand_bytes.curr = 0;
rand_bytes.size = MAX_RANDOMNESS_HELD;
- /* TODO: Should this be secure malloc? */
- rand_bytes.buff = malloc(rand_bytes.size);
-
+ rand_bytes.secure = CRYPTO_secure_malloc_initialized();
+ rand_bytes.buff = rand_bytes.secure
+ ? OPENSSL_secure_malloc(rand_bytes.size)
+ : OPENSSL_malloc(rand_bytes.size);
ret &= rand_bytes.buff != NULL;
ret &= setup_drbg(&rand_drbg);
ret &= setup_drbg(&priv_drbg);
#endif
CRYPTO_THREAD_lock_free(rand_meth_lock);
CRYPTO_THREAD_lock_free(rand_bytes.lock);
- OPENSSL_clear_free(rand_bytes.buff, rand_bytes.size);
+ if (rand_bytes.secure)
+ OPENSSL_secure_clear_free(rand_bytes.buff, rand_bytes.size);
+ else
+ OPENSSL_clear_free(rand_bytes.buff, rand_bytes.size);
free_drbg(&rand_drbg);
free_drbg(&priv_drbg);
}
{
# ifndef USE_BCRYPTGENRANDOM
HCRYPTPROV hProvider;
+ int ok = 0;
# endif
- DWORD w;
BYTE buf[RANDOMNESS_NEEDED];
- int ok = 0;
# ifdef OPENSSL_RAND_SEED_RDTSC
rand_read_tsc(cb, arg);
# endif
# ifdef OPENSSL_RAND_SEED_RDCPU
if (rand_read_cpu(cb, arg))
- ok++;
+ return 1;
# endif
# ifdef USE_BCRYPTGENRANDOM
if (BCryptGenRandom(NULL, buf, (ULONG)sizeof(buf),
- BCRYPT_USE_SYSTEM_PREFERRED_RNG) != STATUS_SUCCESS)
- return 0;
- cb(arg, buf, sizeof(buf), sizeof(buf));
- return 1;
+ BCRYPT_USE_SYSTEM_PREFERRED_RNG) == STATUS_SUCCESS) {
+ cb(arg, buf, sizeof(buf), sizeof(buf));
+ return 1;
+ }
# else
/* poll the CryptoAPI PRNG */
if (CryptAcquireContextW(&hProvider, NULL, NULL, PROV_RSA_FULL,
CRYPT_VERIFYCONTEXT | CRYPT_SILENT) != 0) {
if (CryptGenRandom(hProvider, (DWORD)sizeof(buf), buf) != 0) {
cb(arg, buf, sizeof(buf), sizeof(buf));
- ok++;
+ ok = 1;
}
CryptReleaseContext(hProvider, 0);
+ if (ok)
+ return 1;
}
/* poll the Pentium PRG with CryptoAPI */
CRYPT_VERIFYCONTEXT | CRYPT_SILENT) != 0) {
if (CryptGenRandom(hProvider, (DWORD)sizeof(buf), buf) != 0) {
cb(arg, buf, sizeof(buf), sizeof(buf));
- ok++;
+ ok = 1;
}
CryptReleaseContext(hProvider, 0);
+ if (ok)
+ return 1;
}
# endif
- return ok ? 1 : 0;
+ return 0;
}
-#if OPENSSL_API_COMPAT < 0x10100000L
+# if OPENSSL_API_COMPAT < 0x10100000L
int RAND_event(UINT iMsg, WPARAM wParam, LPARAM lParam)
{
RAND_poll();
{
RAND_poll();
}
-#endif
+# endif
#endif