Commit 14264b19 authored by Dr. Stephen Henson's avatar Dr. Stephen Henson
Browse files

Add periodic DRBG health checks as required by SP800-90.

parent 8da18ea1
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -82,6 +82,7 @@ static ERR_STRING_DATA FIPS_str_functs[]=
{ERR_FUNC(FIPS_F_FIPS_CIPHERINIT),	"FIPS_CIPHERINIT"},
{ERR_FUNC(FIPS_F_FIPS_DIGESTINIT),	"FIPS_DIGESTINIT"},
{ERR_FUNC(FIPS_F_FIPS_DRBG_BYTES),	"FIPS_DRBG_BYTES"},
{ERR_FUNC(FIPS_F_FIPS_DRBG_CHECK),	"FIPS_DRBG_CHECK"},
{ERR_FUNC(FIPS_F_FIPS_DRBG_CPRNG_TEST),	"FIPS_DRBG_CPRNG_TEST"},
{ERR_FUNC(FIPS_F_FIPS_DRBG_GENERATE),	"FIPS_drbg_generate"},
{ERR_FUNC(FIPS_F_FIPS_DRBG_HEALTH_CHECK),	"FIPS_DRBG_HEALTH_CHECK"},
+1 −0
Original line number Diff line number Diff line
@@ -244,6 +244,7 @@ void ERR_load_FIPS_strings(void);
#define FIPS_F_FIPS_CIPHERINIT				 109
#define FIPS_F_FIPS_DIGESTINIT				 110
#define FIPS_F_FIPS_DRBG_BYTES				 111
#define FIPS_F_FIPS_DRBG_CHECK				 146
#define FIPS_F_FIPS_DRBG_CPRNG_TEST			 112
#define FIPS_F_FIPS_DRBG_GENERATE			 113
#define FIPS_F_FIPS_DRBG_HEALTH_CHECK			 114
+29 −0
Original line number Diff line number Diff line
@@ -71,6 +71,9 @@ int FIPS_drbg_init(DRBG_CTX *dctx, int type, unsigned int flags)
	dctx->flags = flags;
	dctx->type = type;

	dctx->health_check_cnt = 0;
	dctx->health_check_interval = DRBG_HEALTH_INTERVAL;

	rv = fips_drbg_hash_init(dctx);

	if (rv == -2)
@@ -277,6 +280,24 @@ int FIPS_drbg_reseed(DRBG_CTX *dctx,
	return 0;
	}

static int fips_drbg_check(DRBG_CTX *dctx)
	{
	if (dctx->flags & DRBG_FLAG_TEST)
		return 1;
	dctx->health_check_cnt++;
	if (dctx->health_check_cnt >= dctx->health_check_interval)
		{
		DRBG_CTX tctx;
		if (!fips_drbg_kat(&tctx, dctx->type,
						dctx->flags | DRBG_FLAG_TEST))
			{
			FIPSerr(FIPS_F_FIPS_DRBG_CHECK, FIPS_R_SELFTEST_FAILURE);
			return 0;
			}
		dctx->health_check_cnt = 0;
		}
	return 1;
	}

int FIPS_drbg_generate(DRBG_CTX *dctx, unsigned char *out, size_t outlen,
			int strength, int prediction_resistance,
@@ -284,6 +305,9 @@ int FIPS_drbg_generate(DRBG_CTX *dctx, unsigned char *out, size_t outlen,
	{
	int r = 0;

	if (!fips_drbg_check(dctx))
		return 0;

	if (dctx->status != DRBG_STATUS_READY
		&& dctx->status != DRBG_STATUS_RESEED)
		{
@@ -408,6 +432,11 @@ int FIPS_drbg_get_strength(DRBG_CTX *dctx)
	return dctx->strength;
	}

void FIPS_drbg_set_check_interval(DRBG_CTX *dctx, int interval)
	{
	dctx->health_check_interval = interval;
	}

static int drbg_stick = 0;

void FIPS_drbg_stick(void)
+1 −0
Original line number Diff line number Diff line
@@ -108,6 +108,7 @@ void *FIPS_drbg_get_app_data(DRBG_CTX *ctx);
void FIPS_drbg_set_app_data(DRBG_CTX *ctx, void *app_data);
size_t FIPS_drbg_get_blocklength(DRBG_CTX *dctx);
int FIPS_drbg_get_strength(DRBG_CTX *dctx);
void FIPS_drbg_set_check_interval(DRBG_CTX *dctx, int interval);

DRBG_CTX *FIPS_get_default_drbg(void);
const RAND_METHOD *FIPS_drbg_method(void);
+4 −0
Original line number Diff line number Diff line
@@ -105,6 +105,8 @@ struct drbg_ctr_ctx_st
 */
#define DRBG_MAX_BLOCK			EVP_MAX_MD_SIZE

#define DRBG_HEALTH_INTERVAL		(1 << 24)

/* DRBG context structure */

struct drbg_ctx_st
@@ -114,6 +116,8 @@ struct drbg_ctx_st
	int type;
	/* Various flags */
	unsigned int flags;
	/* Used for periodic health checks */
	int health_check_cnt, health_check_interval;

	/* The following parameters are setup by mechanism drbg_init() call */
	int strength;