summaryrefslogtreecommitdiffstats
path: root/crypto/rand
diff options
context:
space:
mode:
authorRich Salz <rsalz@openssl.org>2017-07-18 09:39:21 -0400
committerRich Salz <rsalz@openssl.org>2017-07-22 14:00:07 -0400
commit8389ec4b4950b9474e72a959eb0b0a6ce77ac1e8 (patch)
tree433fb30336963d2bd5a8cd7bb87a4dba32313f92 /crypto/rand
parent0d7903f83f84bba1d29225efd999c633a0c5ba01 (diff)
Add --with-rand-seed
Add a new config param to specify how the CSPRNG should be seeded. Illegal values or nonsensical combinations (e.g., anything other than "os" on VMS or HP VOS etc) result in build failures. Add RDSEED support. Add RDTSC but leave it disabled for now pending more investigation. Refactor and reorganization all seeding files (rand_unix/win/vms) so that they are simpler. Only require 128 bits of seeding material. Many document improvements, including why to not use RAND_add() and the limitations around using load_file/write_file. Document RAND_poll(). Cleanup Windows RAND_poll and return correct status More completely initialize the default DRBG. Reviewed-by: Paul Dale <paul.dale@oracle.com> (Merged from https://github.com/openssl/openssl/pull/3965)
Diffstat (limited to 'crypto/rand')
-rw-r--r--crypto/rand/drbg_rand.c6
-rw-r--r--crypto/rand/rand_lcl.h28
-rw-r--r--crypto/rand/rand_lib.c64
-rw-r--r--crypto/rand/rand_unix.c292
-rw-r--r--crypto/rand/rand_vms.c6
-rw-r--r--crypto/rand/rand_win.c98
6 files changed, 220 insertions, 274 deletions
diff --git a/crypto/rand/drbg_rand.c b/crypto/rand/drbg_rand.c
index 77d59ec813..8b30cd8a0d 100644
--- a/crypto/rand/drbg_rand.c
+++ b/crypto/rand/drbg_rand.c
@@ -29,8 +29,12 @@ static CRYPTO_ONCE ossl_drbg_init = CRYPTO_ONCE_STATIC_INIT;
DEFINE_RUN_ONCE_STATIC(do_ossl_drbg_init)
{
+ int st = 1;
+
ossl_drbg.lock = CRYPTO_THREAD_lock_new();
- return ossl_drbg.lock != NULL;
+ st &= ossl_drbg.lock != NULL;
+ st &= RAND_DRBG_set(&ossl_drbg, NID_aes_128_ctr, 0) == 1;
+ return st;
}
void rand_drbg_cleanup(void)
diff --git a/crypto/rand/rand_lcl.h b/crypto/rand/rand_lcl.h
index de1f2cd4e6..b9df5d18e2 100644
--- a/crypto/rand/rand_lcl.h
+++ b/crypto/rand/rand_lcl.h
@@ -17,21 +17,24 @@
# include <openssl/ec.h>
# include "internal/rand.h"
-/* we require 256 bits of randomness */
-# define RANDOMNESS_NEEDED (256 / 8)
+/* Amount of randomness (in bytes) we want for initial seeding. */
+# define RANDOMNESS_NEEDED (128 / 8)
/* Maximum count allowed in reseeding */
#define MAX_RESEED (1 << 24)
/* DRBG status values */
-#define DRBG_STATUS_UNINITIALISED 0
-#define DRBG_STATUS_READY 1
-#define DRBG_STATUS_RESEED 2
-#define DRBG_STATUS_ERROR 3
+# define DRBG_STATUS_UNINITIALISED 0
+# define DRBG_STATUS_READY 1
+# define DRBG_STATUS_RESEED 2
+# define DRBG_STATUS_ERROR 3
/* A default maximum length: larger than any reasonable value used in pratice */
-#define DRBG_MAX_LENGTH 0x7ffffff0
+# define DRBG_MAX_LENGTH 0x7ffffff0
+/*
+ * The context for DRBG AES-CTR
+ */
typedef struct drbg_ctr_ctx_st {
AES_KEY ks;
size_t keylen;
@@ -46,6 +49,10 @@ typedef struct drbg_ctr_ctx_st {
unsigned char KX[48];
} DRBG_CTR_CTX;
+
+/*
+ * The context for all DRBG's
+ */
struct drbg_ctx_st {
CRYPTO_RWLOCK *lock;
DRBG_CTX *parent;
@@ -84,9 +91,12 @@ struct drbg_ctx_st {
extern RAND_METHOD openssl_rand_meth;
void rand_drbg_cleanup(void);
+/* Hardware-based seeding functions. */
+void rand_rdtsc(void);
+int rand_rdcpu(void);
+
+/* DRBG functions implementing AES-CTR */
int ctr_init(DRBG_CTX *dctx);
-int drbg_hash_init(DRBG_CTX *dctx);
-int drbg_hmac_init(DRBG_CTX *dctx);
int ctr_uninstantiate(DRBG_CTX *dctx);
int ctr_instantiate(DRBG_CTX *dctx,
const unsigned char *ent, size_t entlen,
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)
{
diff --git a/crypto/rand/rand_unix.c b/crypto/rand/rand_unix.c
index bfdd3e6efa..2cfd20dd50 100644
--- a/crypto/rand/rand_unix.c
+++ b/crypto/rand/rand_unix.c
@@ -1,5 +1,5 @@
/*
- * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2017 The OpenSSL Project Authors. All Rights Reserved.
*
* Licensed under the OpenSSL license (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
@@ -9,32 +9,32 @@
#include <stdio.h>
-#define USE_SOCKETS
#include "e_os.h"
#include "internal/cryptlib.h"
#include <openssl/rand.h>
#include "rand_lcl.h"
+#include <stdio.h>
#if !(defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_WIN32) || defined(OPENSSL_SYS_VMS) || defined(OPENSSL_SYS_VXWORKS) || defined(OPENSSL_SYS_UEFI))
-# include <sys/types.h>
-# include <sys/time.h>
-# include <sys/times.h>
-# include <sys/stat.h>
-# include <fcntl.h>
-# include <unistd.h>
-# include <time.h>
-# if defined(OPENSSL_SYS_LINUX) /* should actually be available virtually
- * everywhere */
-# include <poll.h>
-# endif
-# include <limits.h>
-# ifndef FD_SETSIZE
-# define FD_SETSIZE (8*sizeof(fd_set))
+# if (defined(OPENSSL_SYS_VXWORKS) || defined(OPENSSL_SYS_UEFI)) && \
+ !defined(OPENSSL_RAND_SEED_NONE)
+# error "UEFI and VXWorks only support seeding NONE"
# endif
# if defined(OPENSSL_SYS_VOS)
+# ifndef OPENSSL_RAND_SEED_OS
+# error "Unsupported seeding method configured; must be os"
+# endif
+
+# if defined(OPENSSL_SYS_VOS_HPPA) && defined(OPENSSL_SYS_VOS_IA32)
+# error "Unsupported HP-PA and IA32 at the same time."
+# endif
+# if !defined(OPENSSL_SYS_VOS_HPPA) && !defined(OPENSSL_SYS_VOS_IA32)
+# error "Must have one of HP-PA or IA32"
+# endif
+
/*
* The following algorithm repeatedly samples the real-time clock (RTC) to
* generate a sequence of unpredictable data. The algorithm relies upon the
@@ -51,7 +51,6 @@
* As a precaution, we generate 4 times the minimum required amount of seed
* data.
*/
-
int RAND_poll(void)
{
short int code;
@@ -61,35 +60,24 @@ int RAND_poll(void)
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 */
+# endif
/*
* 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;
-
+ RAND_add(&curr_gid, sizeof curr_gid, 0);
curr_pid = getpid();
- RAND_add(&curr_pid, sizeof curr_pid, 1);
- curr_pid = 0;
-
+ RAND_add(&curr_pid, sizeof curr_pid, 0);
curr_uid = getuid();
- RAND_add(&curr_uid, sizeof curr_uid, 1);
- curr_uid = 0;
+ RAND_add(&curr_uid, sizeof curr_uid, 0);
for (i = 0; i < (RANDOMNESS_NEEDED * 4); i++) {
/*
@@ -104,203 +92,111 @@ int RAND_poll(void)
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 */
+# endif
- /* get wall clock time. */
+ /* Get wall clock time, take 8 bits. */
clock_gettime(CLOCK_REALTIME, &ts);
-
- /* take 8 bits */
- v = (unsigned char)(ts.tv_nsec % 256);
+ v = (unsigned char)(ts.tv_nsec & 0xFF);
RAND_add(&v, sizeof v, 1);
- v = 0;
}
return 1;
}
+
# else
-int RAND_poll(void)
-{
- unsigned long l;
- pid_t curr_pid = getpid();
-# if defined(DEVRANDOM) || (!defined(OPENSS_NO_EGD) && defined(DEVRANDOM_EGD))
- unsigned char tmpbuf[RANDOMNESS_NEEDED];
- int n = 0;
-# endif
-# ifdef DEVRANDOM
- static const char *randomfiles[] = { DEVRANDOM };
- struct stat randomstats[OSSL_NELEM(randomfiles)];
- int fd;
- unsigned int i;
-# endif
-# if !defined(OPENSSL_NO_EGD) && defined(DEVRANDOM_EGD)
- static const char *egdsockets[] = { DEVRANDOM_EGD, NULL };
- const char **egdsocket = NULL;
+
+# if defined(OPENSSL_RAND_SEED_EGD) && \
+ (defined(OPENSSL_NO_EGD) || !defined(DEVRANDOM_EGD))
+# error "Seeding uses EGD but EGD is turned off or no device given"
# endif
-# ifdef DEVRANDOM
- memset(randomstats, 0, sizeof(randomstats));
- /*
- * Use a randomness device. Linux, FreeBSD and OpenBSD have
- * this. Use /dev/urandom if you can as /dev/random may block if it runs
- * out of random entries.
- */
+# if defined(OPENSSL_RAND_SEED_DEVRANDOM) && !defined(DEVRANDOM)
+# error "Seeding uses urandom but DEVRANDOM is not configured"
+# endif
- for (i = 0; (i < OSSL_NELEM(randomfiles)) && (n < RANDOMNESS_NEEDED); i++) {
- if ((fd = open(randomfiles[i], O_RDONLY
-# ifdef O_NONBLOCK
- | O_NONBLOCK
-# endif
-# ifdef O_BINARY
- | O_BINARY
-# endif
-# ifdef O_NOCTTY /* If it happens to be a TTY (god forbid), do
- * not make it our controlling tty */
- | O_NOCTTY
+# if defined(OPENSSL_RAND_SEED_OS)
+# if defined(DEVRANDOM)
+# define OPENSSL_RAND_SEED_DEVRANDOM
+# else
+# error "OS seeding requires DEVRANDOM to be configured"
# endif
- )) >= 0) {
- int usec = 10 * 1000; /* spend 10ms on each file */
- int r;
- unsigned int j;
- struct stat *st = &randomstats[i];
-
- /*
- * Avoid using same input... Used to be O_NOFOLLOW above, but
- * it's not universally appropriate...
- */
- if (fstat(fd, st) != 0) {
- close(fd);
- continue;
- }
- for (j = 0; j < i; j++) {
- if (randomstats[j].st_ino == st->st_ino &&
- randomstats[j].st_dev == st->st_dev)
- break;
- }
- if (j < i) {
- close(fd);
- continue;
- }
-
- do {
- int try_read = 0;
-
-# if defined(OPENSSL_SYS_LINUX)
- /* use poll() */
- struct pollfd pset;
-
- pset.fd = fd;
- pset.events = POLLIN;
- pset.revents = 0;
-
- if (poll(&pset, 1, usec / 1000) < 0)
- usec = 0;
- else
- try_read = (pset.revents & POLLIN) != 0;
+# endif
-# else
- /* use select() */
- fd_set fset;
- struct timeval t;
+# if defined(OPENSSL_RAND_SEED_LIBRANDOM)
+# error "librandom not (yet) supported"
+# endif
- t.tv_sec = 0;
- t.tv_usec = usec;
+int RAND_poll(void)
+{
+# ifdef OPENSSL_RAND_SEED_NONE
+ return 0;
+# else
+ int ok = 0;
+ char temp[RANDOMNESS_NEEDED];
+# define TEMPSIZE (int)sizeof(temp)
- if (FD_SETSIZE > 0 && (unsigned)fd >= FD_SETSIZE) {
- /*
- * can't use select, so just try to read once anyway
- */
- try_read = 1;
- } else {
- FD_ZERO(&fset);
- FD_SET(fd, &fset);
+# ifdef OPENSSL_RAND_SEED_RDTSC
+ rand_rdtsc();
+# endif
- if (select(fd + 1, &fset, NULL, NULL, &t) >= 0) {
- usec = t.tv_usec;
- if (FD_ISSET(fd, &fset))
- try_read = 1;
- } else
- usec = 0;
- }
+# ifdef OPENSSL_RAND_SEED_RDCPU
+ if (rand_rdcpu())
+ ok++;
# endif
- if (try_read) {
- r = read(fd, (unsigned char *)tmpbuf + n,
- RANDOMNESS_NEEDED - n);
- if (r > 0)
- n += r;
- } else
- r = -1;
+# ifdef OPENSSL_RAND_SEED_EGD
+ {
+ static const char *paths[] = { DEVRANDOM_EGD, NULL };
+ int i;
- /*
- * Some Unixen will update t in select(), some won't. For
- * those who won't, or if we didn't use select() in the first
- * place, give up here, otherwise, we will do this once again
- * for the remaining time.
- */
- if (usec == 10 * 1000)
- usec = 0;
+ for (i = 0; paths[i] != NULL; i++) {
+ if (RAND_query_egd_bytes(paths[i], temp, TEMPSIZE) == TEMPSIZE) {
+ RAND_add(temp, TEMPSIZE, TEMPSIZE);
+ ok++;
+ break;
}
- while ((r > 0 ||
- (errno == EINTR || errno == EAGAIN)) && usec != 0
- && n < RANDOMNESS_NEEDED);
-
- close(fd);
}
}
-# endif /* defined(DEVRANDOM) */
-
-# if !defined(OPENSSL_NO_EGD) && defined(DEVRANDOM_EGD)
- /*
- * Use an EGD socket to read randomness from the daemon.
- */
-
- for (egdsocket = egdsockets; *egdsocket && n < RANDOMNESS_NEEDED;
- egdsocket++) {
- int r;
+# endif
- r = RAND_query_egd_bytes(*egdsocket, (unsigned char *)tmpbuf + n,
- RANDOMNESS_NEEDED - n);
- if (r > 0)
- n += r;
- }
-# endif /* defined(DEVRANDOM_EGD) */
+# ifdef OPENSSL_RAND_SEED_DEVRANDOM
+ {
+ static const char *paths[] = { DEVRANDOM, NULL };
+ FILE *fp;
+ int i;
-# if defined(DEVRANDOM) || (!defined(OPENSSL_NO_EGD) && defined(DEVRANDOM_EGD))
- if (n > 0) {
- RAND_add(tmpbuf, sizeof tmpbuf, (double)n);
- OPENSSL_cleanse(tmpbuf, n);
+ for (i = 0; paths[i] != NULL; i++) {
+ if ((fp = fopen(paths[i], "rb")) == NULL)
+ continue;
+ setbuf(fp, NULL);
+ if (fread(temp, 1, TEMPSIZE, fp) == TEMPSIZE) {
+ RAND_add(temp, TEMPSIZE, TEMPSIZE);
+ ok++;
+ fclose(fp);
+ break;
+ }
+ }
}
-# endif
+# endif
- /* put in some default random data, we need more than just this */
- l = curr_pid;
- RAND_add(&l, sizeof(l), 0.0);
- l = getuid();
- RAND_add(&l, sizeof(l), 0.0);
+# ifdef OPENSSL_RAND_SEED_GETRANDOM
+ {
+ int i = getrandom(temp, TEMPSIZE, 0);
- l = time(NULL);
- RAND_add(&l, sizeof(l), 0.0);
+ if (i >= 0) {
+ RAND_add(temp, i, i);
+ if (i == TEMPSIZE)
+ ok++;
+ }
+ }
+# endif
-# if defined(DEVRANDOM) || (!defined(OPENSSL_NO_EGD) && defined(DEVRANDOM_EGD))
- return 1;
-# else
- return 0;
+ OPENSSL_cleanse(temp, TEMPSIZE);
+ return ok > 0 ? 1 : 0;
# endif
}
+# endif
-# endif /* defined(__OpenBSD__) */
-#endif /* !(defined(OPENSSL_SYS_WINDOWS) ||
- * defined(OPENSSL_SYS_WIN32) ||
- * defined(OPENSSL_SYS_VMS) ||
- * defined(OPENSSL_SYS_VXWORKS) */
-
-#if defined(OPENSSL_SYS_VXWORKS) || defined(OPENSSL_SYS_UEFI)
-int RAND_poll(void)
-{
- return 0;
-}
#endif
diff --git a/crypto/rand/rand_vms.c b/crypto/rand/rand_vms.c
index ec99dbfe26..16afae7a2e 100644
--- a/crypto/rand/rand_vms.c
+++ b/crypto/rand/rand_vms.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2001-2016 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2001-2017 The OpenSSL Project Authors. All Rights Reserved.
*
* Licensed under the OpenSSL license (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
@@ -21,6 +21,10 @@
# pragma message disable DOLLARID
# endif
+# ifndef OPENSSL_RAND_SEED_OS
+# error "Unsupported seeding method configured; must be os"
+# endif
+
/*
* Use 32-bit pointers almost everywhere. Define the type to which to cast a
* pointer passed to an external function.
diff --git a/crypto/rand/rand_win.c b/crypto/rand/rand_win.c
index 1be0ed3c9a..acc428640e 100644
--- a/crypto/rand/rand_win.c
+++ b/crypto/rand/rand_win.c
@@ -1,5 +1,5 @@
/*
- * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2017 The OpenSSL Project Authors. All Rights Reserved.
*
* Licensed under the OpenSSL license (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
@@ -12,13 +12,18 @@
#include "rand_lcl.h"
#if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_WIN32)
+
+# ifndef OPENSSL_RAND_SEED_OS
+# error "Unsupported seeding method configured; must be os"
+# endif
+
# include <windows.h>
/* On Windows 7 or higher use BCrypt instead of the legacy CryptoAPI */
-# if defined(_MSC_VER) && defined(_WIN32_WINNT) && _WIN32_WINNT>=0x0601
-# define RAND_WINDOWS_USE_BCRYPT
+# if defined(_MSC_VER) && defined(_WIN32_WINNT) && _WIN32_WINNT >= 0x0601
+# define USE_BCRYPTGENRANDOM
# endif
-# ifdef RAND_WINDOWS_USE_BCRYPT
+# ifdef USE_BCRYPTGENRANDOM
# include <bcrypt.h>
# pragma comment(lib, "bcrypt.lib")
# ifndef STATUS_SUCCESS
@@ -34,52 +39,52 @@
# define INTEL_DEF_PROV L"Intel Hardware Cryptographic Service Provider"
# endif
-static void readtimer(void);
-
int RAND_poll(void)
{
- MEMORYSTATUS mst;
-# ifndef RAND_WINDOWS_USE_BCRYPT
+# ifndef USE_BCRYPTGENRANDOM
HCRYPTPROV hProvider;
# endif
DWORD w;
- BYTE buf[64];
+ BYTE buf[RANDOMNESS_NEEDED];
+ int ok = 0;
-# ifdef RAND_WINDOWS_USE_BCRYPT
- if (BCryptGenRandom(NULL, buf, (ULONG)sizeof(buf), BCRYPT_USE_SYSTEM_PREFERRED_RNG) == STATUS_SUCCESS) {
- RAND_add(buf, sizeof(buf), sizeof(buf));
- }
+# ifdef OPENSSL_RAND_SEED_RDTSC
+ rand_rdtsc();
+# endif
+# ifdef OPENSSL_RAND_SEED_RDCPU
+ if (rand_rdcpu())
+ ok++;
+# endif
+
+# ifdef USE_BCRYPTGENRANDOM
+ if (BCryptGenRandom(NULL, buf, (ULONG)sizeof(buf),
+ BCRYPT_USE_SYSTEM_PREFERRED_RNG) != STATUS_SUCCESS)
+ return 0;
+ RAND_add(buf, sizeof(buf), sizeof(buf));
+ return 1;
# else
/* poll the CryptoAPI PRNG */
- /* The CryptoAPI returns sizeof(buf) bytes of randomness */
- if (CryptAcquireContextW(&hProvider, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT | CRYPT_SILENT)) {
+ if (CryptAcquireContextW(&hProvider, NULL, NULL, PROV_RSA_FULL,
+ CRYPT_VERIFYCONTEXT | CRYPT_SILENT) != 0) {
if (CryptGenRandom(hProvider, (DWORD)sizeof(buf), buf) != 0) {
RAND_add(buf, sizeof(buf), sizeof(buf));
+ ok++;
}
CryptReleaseContext(hProvider, 0);
}
/* poll the Pentium PRG with CryptoAPI */
- if (CryptAcquireContextW(&hProvider, NULL, INTEL_DEF_PROV, PROV_INTEL_SEC, CRYPT_VERIFYCONTEXT | CRYPT_SILENT)) {
+ if (CryptAcquireContextW(&hProvider, NULL, INTEL_DEF_PROV, PROV_INTEL_SEC,
+ CRYPT_VERIFYCONTEXT | CRYPT_SILENT) != 0) {
if (CryptGenRandom(hProvider, (DWORD)sizeof(buf), buf) != 0) {
RAND_add(buf, sizeof(buf), sizeof(buf));
+ ok++;
}
CryptReleaseContext(hProvider, 0);
}
# endif
- /* timer data */
- readtimer();
-
- /* memory usage statistics */
- GlobalMemoryStatus(&mst);
- RAND_add(&mst, sizeof(mst), 1);
-
- /* process ID */
- w = GetCurrentProcessId();
- RAND_add(&w, sizeof(w), 1);
-
- return (1);
+ return ok ? 1 : 0;
}
#if OPENSSL_API_COMPAT < 0x10100000L
@@ -95,41 +100,4 @@ void RAND_screen(void)
}
#endif
-/* feed timing information to the PRNG */
-static void readtimer(void)
-{
- DWORD w;
- LARGE_INTEGER l;
- static int have_perfc = 1;
-# if defined(_MSC_VER) && defined(_M_X86)
- static int have_tsc = 1;
- DWORD cyclecount;
-
- if (have_tsc) {
- __try {
- __asm {
- _emit 0x0f _emit 0x31 mov cyclecount, eax}
- RAND_add(&cyclecount, sizeof(cyclecount), 1);
- }
- __except(EXCEPTION_EXECUTE_HANDLER) {
- have_tsc = 0;
- }
- }
-# else
-# define have_tsc 0
-# endif
-
- if (have_perfc) {
- if (QueryPerformanceCounter(&l) == 0)
- have_perfc = 0;
- else
- RAND_add(&l, sizeof(l), 0);
- }
-
- if (!have_tsc && !have_perfc) {
- w = GetTickCount();
- RAND_add(&w, sizeof(w), 0);
- }
-}
-
#endif