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:

committed by
Love Hornquist Astrand

parent
dd34c02329
commit
887993e8b3
@@ -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 = {
|
||||
|
Reference in New Issue
Block a user