Add mutex protection for the fortuna PRNG

The fortuna PRNG has an statically held internal state. Prevent
concurrent access to this internal state by adding mutexes around
all of the access classes.

Signed-off-by: Love Hornquist Astrand <lha@h5l.org>
This commit is contained in:
Simon Wilkinson
2010-04-16 12:04:15 +01:00
committed by Love Hornquist Astrand
parent dd34c02329
commit 887993e8b3

View File

@@ -34,6 +34,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <rand.h>
#include <heim_threads.h>
#ifdef KRB5
#include <krb5-types.h>
@@ -441,11 +442,21 @@ static int have_entropy;
#define FORTUNA_RESEED_BYTE 10000
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 = {