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 <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <rand.h>
|
#include <rand.h>
|
||||||
|
#include <heim_threads.h>
|
||||||
|
|
||||||
#ifdef KRB5
|
#ifdef KRB5
|
||||||
#include <krb5-types.h>
|
#include <krb5-types.h>
|
||||||
@@ -441,11 +442,21 @@ static int have_entropy;
|
|||||||
#define FORTUNA_RESEED_BYTE 10000
|
#define FORTUNA_RESEED_BYTE 10000
|
||||||
static unsigned resend_bytes;
|
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
|
* Try our best to do an inital seed
|
||||||
*/
|
*/
|
||||||
#define INIT_BYTES 128
|
#define INIT_BYTES 128
|
||||||
|
|
||||||
|
/*
|
||||||
|
* fortuna_mutex must be held across calls to this function
|
||||||
|
*/
|
||||||
|
|
||||||
static int
|
static int
|
||||||
fortuna_reseed(void)
|
fortuna_reseed(void)
|
||||||
{
|
{
|
||||||
@@ -537,6 +548,9 @@ fortuna_reseed(void)
|
|||||||
return entropy_p;
|
return entropy_p;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* fortuna_mutex must be held by callers of this function
|
||||||
|
*/
|
||||||
static int
|
static int
|
||||||
fortuna_init(void)
|
fortuna_init(void)
|
||||||
{
|
{
|
||||||
@@ -555,32 +569,50 @@ fortuna_init(void)
|
|||||||
static void
|
static void
|
||||||
fortuna_seed(const void *indata, int size)
|
fortuna_seed(const void *indata, int size)
|
||||||
{
|
{
|
||||||
|
HEIMDAL_MUTEX_lock(&fortuna_mutex);
|
||||||
|
|
||||||
fortuna_init();
|
fortuna_init();
|
||||||
add_entropy(&main_state, indata, size);
|
add_entropy(&main_state, indata, size);
|
||||||
if (size >= INIT_BYTES)
|
if (size >= INIT_BYTES)
|
||||||
have_entropy = 1;
|
have_entropy = 1;
|
||||||
|
|
||||||
|
HEIMDAL_MUTEX_unlock(&fortuna_mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
fortuna_bytes(unsigned char *outdata, int size)
|
fortuna_bytes(unsigned char *outdata, int size)
|
||||||
{
|
{
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
HEIMDAL_MUTEX_lock(&fortuna_mutex);
|
||||||
|
|
||||||
if (!fortuna_init())
|
if (!fortuna_init())
|
||||||
return 0;
|
goto out;
|
||||||
|
|
||||||
resend_bytes += size;
|
resend_bytes += size;
|
||||||
if (resend_bytes > FORTUNA_RESEED_BYTE || resend_bytes < size) {
|
if (resend_bytes > FORTUNA_RESEED_BYTE || resend_bytes < size) {
|
||||||
resend_bytes = 0;
|
resend_bytes = 0;
|
||||||
fortuna_reseed();
|
fortuna_reseed();
|
||||||
}
|
}
|
||||||
extract_data(&main_state, size, outdata);
|
extract_data(&main_state, size, outdata);
|
||||||
return 1;
|
ret = 1;
|
||||||
|
|
||||||
|
out:
|
||||||
|
HEIMDAL_MUTEX_unlock(&fortuna_mutex);
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
fortuna_cleanup(void)
|
fortuna_cleanup(void)
|
||||||
{
|
{
|
||||||
|
HEIMDAL_MUTEX_lock(&fortuna_mutex);
|
||||||
|
|
||||||
init_done = 0;
|
init_done = 0;
|
||||||
have_entropy = 0;
|
have_entropy = 0;
|
||||||
memset(&main_state, 0, sizeof(main_state));
|
memset(&main_state, 0, sizeof(main_state));
|
||||||
|
|
||||||
|
HEIMDAL_MUTEX_unlock(&fortuna_mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -598,7 +630,13 @@ fortuna_pseudorand(unsigned char *outdata, int size)
|
|||||||
static int
|
static int
|
||||||
fortuna_status(void)
|
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 = {
|
const RAND_METHOD hc_rand_fortuna_method = {
|
||||||
|
Reference in New Issue
Block a user