summaryrefslogtreecommitdiff
path: root/source4/heimdal/lib/hcrypto/rand-fortuna.c
diff options
context:
space:
mode:
Diffstat (limited to 'source4/heimdal/lib/hcrypto/rand-fortuna.c')
-rw-r--r--source4/heimdal/lib/hcrypto/rand-fortuna.c44
1 files changed, 41 insertions, 3 deletions
diff --git a/source4/heimdal/lib/hcrypto/rand-fortuna.c b/source4/heimdal/lib/hcrypto/rand-fortuna.c
index c81eb9e2d7..11027b46cf 100644
--- a/source4/heimdal/lib/hcrypto/rand-fortuna.c
+++ b/source4/heimdal/lib/hcrypto/rand-fortuna.c
@@ -34,6 +34,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <rand.h>
+#include <heim_threads.h>
#ifdef KRB5
#include <krb5-types.h>
@@ -442,10 +443,20 @@ static int have_entropy;
static unsigned resend_bytes;
/*
+ * This mutex protects all of the above static elements from concurrent
+ * access by multiple threads
+ */
+static HEIMDAL_MUTEX fortuna_mutex = HEIMDAL_MUTEX_INITIALIZER;
+
+/*
* Try our best to do an inital seed
*/
#define INIT_BYTES 128
+/*
+ * fortuna_mutex must be held across calls to this function
+ */
+
static int
fortuna_reseed(void)
{
@@ -537,6 +548,9 @@ fortuna_reseed(void)
return entropy_p;
}
+/*
+ * fortuna_mutex must be held by callers of this function
+ */
static int
fortuna_init(void)
{
@@ -555,32 +569,50 @@ fortuna_init(void)
static void
fortuna_seed(const void *indata, int size)
{
+ HEIMDAL_MUTEX_lock(&fortuna_mutex);
+
fortuna_init();
add_entropy(&main_state, indata, size);
if (size >= INIT_BYTES)
have_entropy = 1;
+
+ HEIMDAL_MUTEX_unlock(&fortuna_mutex);
}
static int
fortuna_bytes(unsigned char *outdata, int size)
{
+ int ret = 0;
+
+ HEIMDAL_MUTEX_lock(&fortuna_mutex);
+
if (!fortuna_init())
- return 0;
+ goto out;
+
resend_bytes += size;
if (resend_bytes > FORTUNA_RESEED_BYTE || resend_bytes < size) {
resend_bytes = 0;
fortuna_reseed();
}
extract_data(&main_state, size, outdata);
- return 1;
+ ret = 1;
+
+out:
+ HEIMDAL_MUTEX_unlock(&fortuna_mutex);
+
+ return ret;
}
static void
fortuna_cleanup(void)
{
+ HEIMDAL_MUTEX_lock(&fortuna_mutex);
+
init_done = 0;
have_entropy = 0;
memset(&main_state, 0, sizeof(main_state));
+
+ HEIMDAL_MUTEX_unlock(&fortuna_mutex);
}
static void
@@ -598,7 +630,13 @@ fortuna_pseudorand(unsigned char *outdata, int size)
static int
fortuna_status(void)
{
- return fortuna_init() ? 1 : 0;
+ int result;
+
+ HEIMDAL_MUTEX_lock(&fortuna_mutex);
+ result = fortuna_init();
+ HEIMDAL_MUTEX_unlock(&fortuna_mutex);
+
+ return result ? 1 : 0;
}
const RAND_METHOD hc_rand_fortuna_method = {