summaryrefslogtreecommitdiff
path: root/lib/nettle/rnd.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/nettle/rnd.c')
-rw-r--r--lib/nettle/rnd.c641
1 files changed, 310 insertions, 331 deletions
diff --git a/lib/nettle/rnd.c b/lib/nettle/rnd.c
index 46a76d4f4a..cd988c2be6 100644
--- a/lib/nettle/rnd.c
+++ b/lib/nettle/rnd.c
@@ -33,10 +33,10 @@
#include <gnutls_num.h>
#include <nettle/yarrow.h>
#ifdef HAVE_GETPID
-# include <unistd.h> /* getpid */
+#include <unistd.h> /* getpid */
#endif
#ifdef HAVE_GETRUSAGE
-# include <sys/resource.h>
+#include <sys/resource.h>
#endif
#include <errno.h>
@@ -45,10 +45,9 @@
#define RND_LOCK if (gnutls_mutex_lock(&rnd_mutex)!=0) abort()
#define RND_UNLOCK if (gnutls_mutex_unlock(&rnd_mutex)!=0) abort()
-enum
-{
- RANDOM_SOURCE_TRIVIA = 0,
- RANDOM_SOURCE_DEVICE,
+enum {
+ RANDOM_SOURCE_TRIVIA = 0,
+ RANDOM_SOURCE_DEVICE,
};
static struct yarrow256_ctx yctx;
@@ -60,73 +59,68 @@ static struct timespec current_time = { 0, 0 };
static time_t trivia_previous_time = 0;
static time_t trivia_time_count = 0;
#ifdef HAVE_GETPID
-static pid_t pid; /* detect fork() */
+static pid_t pid; /* detect fork() */
#endif
static void *rnd_mutex;
inline static unsigned int
-timespec_sub_sec (struct timespec *a, struct timespec *b)
+timespec_sub_sec(struct timespec *a, struct timespec *b)
{
- return (a->tv_sec - b->tv_sec);
+ return (a->tv_sec - b->tv_sec);
}
#define DEVICE_READ_INTERVAL (1200)
/* universal functions */
-static int
-do_trivia_source (int init)
+static int do_trivia_source(int init)
{
- static struct
- {
- struct timespec now;
+ static struct {
+ struct timespec now;
#ifdef HAVE_GETRUSAGE
- struct rusage rusage;
+ struct rusage rusage;
#endif
#ifdef HAVE_GETPID
- pid_t pid;
+ pid_t pid;
#endif
- unsigned count;
- } event;
- unsigned entropy = 0;
+ unsigned count;
+ } event;
+ unsigned entropy = 0;
- memcpy(&event.now, &current_time, sizeof(event.now));
+ memcpy(&event.now, &current_time, sizeof(event.now));
#ifdef HAVE_GETRUSAGE
- if (getrusage (RUSAGE_SELF, &event.rusage) < 0)
- {
- _gnutls_debug_log ("getrusage failed: %s\n", strerror (errno));
- abort ();
- }
+ if (getrusage(RUSAGE_SELF, &event.rusage) < 0) {
+ _gnutls_debug_log("getrusage failed: %s\n",
+ strerror(errno));
+ abort();
+ }
#endif
- event.count = 0;
- if (init)
- {
- trivia_time_count = 0;
- }
- else
- {
- event.count = trivia_time_count++;
-
- if (event.now.tv_sec != trivia_previous_time)
- {
- /* Count one bit of entropy if we either have more than two
- * invocations in one second, or more than two seconds
- * between invocations. */
- if ((trivia_time_count > 2)
- || ((event.now.tv_sec - trivia_previous_time) > 2))
- entropy++;
-
- trivia_time_count = 0;
- }
- }
- trivia_previous_time = event.now.tv_sec;
+ event.count = 0;
+ if (init) {
+ trivia_time_count = 0;
+ } else {
+ event.count = trivia_time_count++;
+
+ if (event.now.tv_sec != trivia_previous_time) {
+ /* Count one bit of entropy if we either have more than two
+ * invocations in one second, or more than two seconds
+ * between invocations. */
+ if ((trivia_time_count > 2)
+ || ((event.now.tv_sec - trivia_previous_time) >
+ 2))
+ entropy++;
+
+ trivia_time_count = 0;
+ }
+ }
+ trivia_previous_time = event.now.tv_sec;
#ifdef HAVE_GETPID
- event.pid = pid;
+ event.pid = pid;
#endif
-
- return yarrow256_update (&yctx, RANDOM_SOURCE_TRIVIA, entropy,
- sizeof (event), (void *) &event);
+
+ return yarrow256_update(&yctx, RANDOM_SOURCE_TRIVIA, entropy,
+ sizeof(event), (void *) &event);
}
@@ -142,61 +136,60 @@ do_trivia_source (int init)
static HCRYPTPROV device_fd = 0;
-static int
-do_device_source (int init)
+static int do_device_source(int init)
{
- int read_size = DEVICE_READ_SIZE;
-
- if (init)
- {
- int old;
-
- if (!CryptAcquireContext
- (&device_fd, NULL, NULL, PROV_RSA_FULL,
- CRYPT_SILENT | CRYPT_VERIFYCONTEXT))
- {
- _gnutls_debug_log ("error in CryptAcquireContext!\n");
- return GNUTLS_E_RANDOM_DEVICE_ERROR;
- }
- gettime(&device_last_read);
- read_size = DEVICE_READ_SIZE_MAX; /* initially read more data */
- }
-
- if ((device_fd != 0)
- && (init || timespec_sub_sec(&current_time, &device_last_read) > DEVICE_READ_INTERVAL))
- {
-
- /* More than 20 minutes since we last read the device */
- uint8_t buf[DEVICE_READ_SIZE_MAX];
-
- if (!CryptGenRandom (device_fd, (DWORD) read_size, buf))
- {
- _gnutls_debug_log ("Error in CryptGenRandom: %s\n",
- GetLastError ());
- return GNUTLS_E_RANDOM_DEVICE_ERROR;
- }
-
- memcpy(&device_last_read, &current_time, sizeof(device_last_read));
- return yarrow256_update (&yctx, RANDOM_SOURCE_DEVICE,
- read_size * 8 /
- 2 /* we trust the system RNG */ ,
- read_size, buf);
- }
- return 0;
+ int read_size = DEVICE_READ_SIZE;
+
+ if (init) {
+ int old;
+
+ if (!CryptAcquireContext
+ (&device_fd, NULL, NULL, PROV_RSA_FULL,
+ CRYPT_SILENT | CRYPT_VERIFYCONTEXT)) {
+ _gnutls_debug_log
+ ("error in CryptAcquireContext!\n");
+ return GNUTLS_E_RANDOM_DEVICE_ERROR;
+ }
+ gettime(&device_last_read);
+ read_size = DEVICE_READ_SIZE_MAX; /* initially read more data */
+ }
+
+ if ((device_fd != 0)
+ && (init
+ || timespec_sub_sec(&current_time,
+ &device_last_read) >
+ DEVICE_READ_INTERVAL)) {
+
+ /* More than 20 minutes since we last read the device */
+ uint8_t buf[DEVICE_READ_SIZE_MAX];
+
+ if (!CryptGenRandom(device_fd, (DWORD) read_size, buf)) {
+ _gnutls_debug_log("Error in CryptGenRandom: %s\n",
+ GetLastError());
+ return GNUTLS_E_RANDOM_DEVICE_ERROR;
+ }
+
+ memcpy(&device_last_read, &current_time,
+ sizeof(device_last_read));
+ return yarrow256_update(&yctx, RANDOM_SOURCE_DEVICE,
+ read_size * 8 /
+ 2 /* we trust the system RNG */ ,
+ read_size, buf);
+ }
+ return 0;
}
-static void
-wrap_nettle_rnd_deinit (void *ctx)
+static void wrap_nettle_rnd_deinit(void *ctx)
{
- RND_LOCK;
- CryptReleaseContext (device_fd, 0);
- RND_UNLOCK;
+ RND_LOCK;
+ CryptReleaseContext(device_fd, 0);
+ RND_UNLOCK;
- gnutls_mutex_deinit (&rnd_mutex);
- rnd_mutex = NULL;
+ gnutls_mutex_deinit(&rnd_mutex);
+ rnd_mutex = NULL;
}
-#else /* POSIX */
+#else /* POSIX */
#include <time.h>
#include <sys/types.h>
@@ -211,172 +204,167 @@ wrap_nettle_rnd_deinit (void *ctx)
static int device_fd;
-static int
-do_device_source_urandom (int init)
+static int do_device_source_urandom(int init)
{
- unsigned int read_size = DEVICE_READ_SIZE;
-
- if (init)
- {
- int old;
-
- device_fd = open ("/dev/urandom", O_RDONLY);
- if (device_fd < 0)
- {
- _gnutls_debug_log ("Cannot open urandom!\n");
- return GNUTLS_E_FILE_ERROR;
- }
-
- old = fcntl (device_fd, F_GETFD);
- if (old != -1)
- fcntl (device_fd, F_SETFD, old | FD_CLOEXEC);
- memcpy(&device_last_read, &current_time, sizeof(device_last_read));
-
- read_size = DEVICE_READ_SIZE_MAX; /* initially read more data */
- }
-
- if ((init || (timespec_sub_sec(&current_time, &device_last_read) > DEVICE_READ_INTERVAL)) && (device_fd > 0))
- {
- /* More than 20 minutes since we last read the device */
- uint8_t buf[DEVICE_READ_SIZE_MAX];
- uint32_t done;
-
- for (done = 0; done < read_size;)
- {
- int res;
- do
- res = read (device_fd, buf + done, sizeof (buf) - done);
- while (res < 0 && errno == EINTR);
-
- if (res <= 0)
- {
- if (res < 0)
- {
- _gnutls_debug_log ("Failed to read /dev/urandom: %s\n",
- strerror (errno));
- }
- else
- {
- _gnutls_debug_log
- ("Failed to read /dev/urandom: end of file\n");
- }
-
- return GNUTLS_E_RANDOM_DEVICE_ERROR;
- }
-
- done += res;
- }
-
- memcpy(&device_last_read, &current_time, sizeof(device_last_read));
- return yarrow256_update (&yctx, RANDOM_SOURCE_DEVICE,
- read_size * 8 / 2 /* we trust the RNG */ ,
- read_size, buf);
- }
- return 0;
+ unsigned int read_size = DEVICE_READ_SIZE;
+
+ if (init) {
+ int old;
+
+ device_fd = open("/dev/urandom", O_RDONLY);
+ if (device_fd < 0) {
+ _gnutls_debug_log("Cannot open urandom!\n");
+ return GNUTLS_E_FILE_ERROR;
+ }
+
+ old = fcntl(device_fd, F_GETFD);
+ if (old != -1)
+ fcntl(device_fd, F_SETFD, old | FD_CLOEXEC);
+ memcpy(&device_last_read, &current_time,
+ sizeof(device_last_read));
+
+ read_size = DEVICE_READ_SIZE_MAX; /* initially read more data */
+ }
+
+ if ((init
+ || (timespec_sub_sec(&current_time, &device_last_read) >
+ DEVICE_READ_INTERVAL)) && (device_fd > 0)) {
+ /* More than 20 minutes since we last read the device */
+ uint8_t buf[DEVICE_READ_SIZE_MAX];
+ uint32_t done;
+
+ for (done = 0; done < read_size;) {
+ int res;
+ do
+ res =
+ read(device_fd, buf + done,
+ sizeof(buf) - done);
+ while (res < 0 && errno == EINTR);
+
+ if (res <= 0) {
+ if (res < 0) {
+ _gnutls_debug_log
+ ("Failed to read /dev/urandom: %s\n",
+ strerror(errno));
+ } else {
+ _gnutls_debug_log
+ ("Failed to read /dev/urandom: end of file\n");
+ }
+
+ return GNUTLS_E_RANDOM_DEVICE_ERROR;
+ }
+
+ done += res;
+ }
+
+ memcpy(&device_last_read, &current_time,
+ sizeof(device_last_read));
+ return yarrow256_update(&yctx, RANDOM_SOURCE_DEVICE,
+ read_size * 8 /
+ 2 /* we trust the RNG */ ,
+ read_size, buf);
+ }
+ return 0;
}
-static int
-do_device_source_egd (int init)
+static int do_device_source_egd(int init)
{
- unsigned int read_size = DEVICE_READ_SIZE;
-
- if (init)
- {
- device_fd = _rndegd_connect_socket ();
- if (device_fd < 0)
- {
- _gnutls_debug_log ("Cannot open egd socket!\n");
- return gnutls_assert_val(GNUTLS_E_RANDOM_DEVICE_ERROR);
- }
-
- memcpy(&device_last_read, &current_time, sizeof(device_last_read));
-
- read_size = DEVICE_READ_SIZE_MAX; /* initially read more data */
- }
-
- if ((device_fd > 0)
- && (init || (timespec_sub_sec(&current_time, &device_last_read) > DEVICE_READ_INTERVAL)))
- {
-
- /* More than 20 minutes since we last read the device */
- uint8_t buf[DEVICE_READ_SIZE_MAX];
- uint32_t done;
-
- for (done = 0; done < read_size;)
- {
- int res;
- res = _rndegd_read (&device_fd, buf + done, sizeof (buf) - done);
- if (res <= 0)
- {
- if (res < 0)
- {
- _gnutls_debug_log ("Failed to read egd.\n");
- }
- else
- {
- _gnutls_debug_log ("Failed to read egd: end of file\n");
- }
-
- return gnutls_assert_val(GNUTLS_E_RANDOM_DEVICE_ERROR);
- }
- done += res;
- }
-
- memcpy(&device_last_read, &current_time, sizeof(device_last_read));
- return yarrow256_update (&yctx, RANDOM_SOURCE_DEVICE, read_size * 8 / 2,
- read_size, buf);
- }
- return 0;
+ unsigned int read_size = DEVICE_READ_SIZE;
+
+ if (init) {
+ device_fd = _rndegd_connect_socket();
+ if (device_fd < 0) {
+ _gnutls_debug_log("Cannot open egd socket!\n");
+ return
+ gnutls_assert_val
+ (GNUTLS_E_RANDOM_DEVICE_ERROR);
+ }
+
+ memcpy(&device_last_read, &current_time,
+ sizeof(device_last_read));
+
+ read_size = DEVICE_READ_SIZE_MAX; /* initially read more data */
+ }
+
+ if ((device_fd > 0)
+ && (init
+ || (timespec_sub_sec(&current_time, &device_last_read) >
+ DEVICE_READ_INTERVAL))) {
+
+ /* More than 20 minutes since we last read the device */
+ uint8_t buf[DEVICE_READ_SIZE_MAX];
+ uint32_t done;
+
+ for (done = 0; done < read_size;) {
+ int res;
+ res =
+ _rndegd_read(&device_fd, buf + done,
+ sizeof(buf) - done);
+ if (res <= 0) {
+ if (res < 0) {
+ _gnutls_debug_log
+ ("Failed to read egd.\n");
+ } else {
+ _gnutls_debug_log
+ ("Failed to read egd: end of file\n");
+ }
+
+ return
+ gnutls_assert_val
+ (GNUTLS_E_RANDOM_DEVICE_ERROR);
+ }
+ done += res;
+ }
+
+ memcpy(&device_last_read, &current_time,
+ sizeof(device_last_read));
+ return yarrow256_update(&yctx, RANDOM_SOURCE_DEVICE,
+ read_size * 8 / 2, read_size, buf);
+ }
+ return 0;
}
-static int
-do_device_source (int init)
+static int do_device_source(int init)
{
- int ret;
- static int (*do_source) (int init) = NULL;
+ int ret;
+ static int (*do_source) (int init) = NULL;
/* using static var here is ok since we are
* always called with mutexes down
*/
- if (init == 1)
- {
+ if (init == 1) {
#ifdef HAVE_GETPID
- pid = getpid();
+ pid = getpid();
#endif
- do_source = do_device_source_urandom;
- ret = do_source (init);
- if (ret < 0)
- {
- do_source = do_device_source_egd;
- ret = do_source (init);
- }
-
- if (ret < 0)
- {
- gnutls_assert ();
- return ret;
- }
-
- return ret;
- }
- else
- {
- ret = do_source (init);
-
- return ret;
- }
+ do_source = do_device_source_urandom;
+ ret = do_source(init);
+ if (ret < 0) {
+ do_source = do_device_source_egd;
+ ret = do_source(init);
+ }
+
+ if (ret < 0) {
+ gnutls_assert();
+ return ret;
+ }
+
+ return ret;
+ } else {
+ ret = do_source(init);
+
+ return ret;
+ }
}
-static void
-wrap_nettle_rnd_deinit (void *ctx)
+static void wrap_nettle_rnd_deinit(void *ctx)
{
- RND_LOCK;
- close (device_fd);
- RND_UNLOCK;
+ RND_LOCK;
+ close(device_fd);
+ RND_UNLOCK;
- gnutls_mutex_deinit (&rnd_mutex);
- rnd_mutex = NULL;
+ gnutls_mutex_deinit(&rnd_mutex);
+ rnd_mutex = NULL;
}
#endif
@@ -384,109 +372,100 @@ wrap_nettle_rnd_deinit (void *ctx)
/* API functions */
-static int
-wrap_nettle_rnd_init (void **ctx)
+static int wrap_nettle_rnd_init(void **ctx)
{
- int ret;
-
- ret = gnutls_mutex_init (&rnd_mutex);
- if (ret < 0)
- {
- gnutls_assert ();
- return ret;
- }
-
- yarrow256_init (&yctx, SOURCES, ysources);
- gettime(&current_time);
-
- ret = do_device_source (1);
- if (ret < 0)
- {
- gnutls_assert ();
- return ret;
- }
-
- ret = do_trivia_source (1);
- if (ret < 0)
- {
- gnutls_assert ();
- return ret;
- }
-
- yarrow256_slow_reseed (&yctx);
-
- return 0;
+ int ret;
+
+ ret = gnutls_mutex_init(&rnd_mutex);
+ if (ret < 0) {
+ gnutls_assert();
+ return ret;
+ }
+
+ yarrow256_init(&yctx, SOURCES, ysources);
+ gettime(&current_time);
+
+ ret = do_device_source(1);
+ if (ret < 0) {
+ gnutls_assert();
+ return ret;
+ }
+
+ ret = do_trivia_source(1);
+ if (ret < 0) {
+ gnutls_assert();
+ return ret;
+ }
+
+ yarrow256_slow_reseed(&yctx);
+
+ return 0;
}
static int
-wrap_nettle_rnd (void *_ctx, int level, void *data, size_t datasize)
+wrap_nettle_rnd(void *_ctx, int level, void *data, size_t datasize)
{
- int ret, reseed = 0;
+ int ret, reseed = 0;
- RND_LOCK;
+ RND_LOCK;
#ifdef HAVE_GETPID
- if (getpid() != pid)
- { /* fork() detected */
- memset(&device_last_read, 0, sizeof(device_last_read));
- pid = getpid();
- reseed = 1;
- }
+ if (getpid() != pid) { /* fork() detected */
+ memset(&device_last_read, 0, sizeof(device_last_read));
+ pid = getpid();
+ reseed = 1;
+ }
#endif
- /* update state only when having a non-nonce or if nonce
- * and nsecs%4096 == 0, i.e., one out of 4096 times called .
- *
- * The reason we do that is to avoid any delays when generating nonces.
- */
- if (level != GNUTLS_RND_NONCE || reseed != 0)
- {
- gettime(&current_time);
-
- ret = do_trivia_source (0);
- if (ret < 0)
- {
- RND_UNLOCK;
- gnutls_assert ();
- return ret;
- }
-
- ret = do_device_source (0);
- if (ret < 0)
- {
- RND_UNLOCK;
- gnutls_assert ();
- return ret;
- }
-
- if (reseed)
- yarrow256_slow_reseed (&yctx);
- }
-
- yarrow256_random (&yctx, datasize, data);
- RND_UNLOCK;
- return 0;
+ /* update state only when having a non-nonce or if nonce
+ * and nsecs%4096 == 0, i.e., one out of 4096 times called .
+ *
+ * The reason we do that is to avoid any delays when generating nonces.
+ */
+ if (level != GNUTLS_RND_NONCE || reseed != 0) {
+ gettime(&current_time);
+
+ ret = do_trivia_source(0);
+ if (ret < 0) {
+ RND_UNLOCK;
+ gnutls_assert();
+ return ret;
+ }
+
+ ret = do_device_source(0);
+ if (ret < 0) {
+ RND_UNLOCK;
+ gnutls_assert();
+ return ret;
+ }
+
+ if (reseed)
+ yarrow256_slow_reseed(&yctx);
+ }
+
+ yarrow256_random(&yctx, datasize, data);
+ RND_UNLOCK;
+ return 0;
}
-static void
-wrap_nettle_rnd_refresh (void *_ctx)
+static void wrap_nettle_rnd_refresh(void *_ctx)
{
- RND_LOCK;
- gettime(&current_time);
+ RND_LOCK;
+ gettime(&current_time);
- do_trivia_source (0);
- do_device_source (0);
+ do_trivia_source(0);
+ do_device_source(0);
- RND_UNLOCK;
- return;
+ RND_UNLOCK;
+ return;
}
int crypto_rnd_prio = INT_MAX;
gnutls_crypto_rnd_st _gnutls_rnd_ops = {
- .init = wrap_nettle_rnd_init,
- .deinit = wrap_nettle_rnd_deinit,
- .rnd = wrap_nettle_rnd,
- .rnd_refresh = wrap_nettle_rnd_refresh,
+ .init = wrap_nettle_rnd_init,
+ .deinit = wrap_nettle_rnd_deinit,
+ .rnd = wrap_nettle_rnd,
+ .rnd_refresh = wrap_nettle_rnd_refresh,
};