Commit 1e803100 authored by Dr. Stephen Henson's avatar Dr. Stephen Henson
Browse files

Implement continuous RNG test for SP800-90 DRBGs.

parent 96ec46f7
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -84,6 +84,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_GENERATE),	"FIPS_drbg_generate"},
{ERR_FUNC(FIPS_F_FIPS_DRBG_GENERATE_INTERNAL),	"FIPS_DRBG_GENERATE_INTERNAL"},
{ERR_FUNC(FIPS_F_FIPS_DRBG_HEALTH_CHECK),	"FIPS_DRBG_HEALTH_CHECK"},
{ERR_FUNC(FIPS_F_FIPS_DRBG_INIT),	"FIPS_drbg_init"},
{ERR_FUNC(FIPS_F_FIPS_DRBG_INSTANTIATE),	"FIPS_drbg_instantiate"},
@@ -118,6 +119,7 @@ static ERR_STRING_DATA FIPS_str_reasons[]=
{ERR_REASON(FIPS_R_CANNOT_READ_EXE)      ,"cannot read exe"},
{ERR_REASON(FIPS_R_CANNOT_READ_EXE_DIGEST),"cannot read exe digest"},
{ERR_REASON(FIPS_R_CONTRADICTING_EVIDENCE),"contradicting evidence"},
{ERR_REASON(FIPS_R_DRBG_STUCK)           ,"drbg stuck"},
{ERR_REASON(FIPS_R_ENTROPY_ERROR_UNDETECTED),"entropy error undetected"},
{ERR_REASON(FIPS_R_ENTROPY_NOT_REQUESTED_FOR_RESEED),"entropy not requested for reseed"},
{ERR_REASON(FIPS_R_ERROR_INITIALISING_DRBG),"error initialising drbg"},
+2 −0
Original line number Diff line number Diff line
@@ -194,6 +194,7 @@ void ERR_load_FIPS_strings(void);
#define FIPS_F_FIPS_CIPHERINIT				 128
#define FIPS_F_FIPS_DIGESTINIT				 127
#define FIPS_F_FIPS_DRBG_GENERATE			 132
#define FIPS_F_FIPS_DRBG_GENERATE_INTERNAL		 138
#define FIPS_F_FIPS_DRBG_HEALTH_CHECK			 137
#define FIPS_F_FIPS_DRBG_INIT				 136
#define FIPS_F_FIPS_DRBG_INSTANTIATE			 133
@@ -225,6 +226,7 @@ void ERR_load_FIPS_strings(void);
#define FIPS_R_CANNOT_READ_EXE				 103
#define FIPS_R_CANNOT_READ_EXE_DIGEST			 104
#define FIPS_R_CONTRADICTING_EVIDENCE			 114
#define FIPS_R_DRBG_STUCK				 142
#define FIPS_R_ENTROPY_ERROR_UNDETECTED			 133
#define FIPS_R_ENTROPY_NOT_REQUESTED_FOR_RESEED		 134
#define FIPS_R_ERROR_INITIALISING_DRBG			 120
+66 −2
Original line number Diff line number Diff line
@@ -263,7 +263,8 @@ int FIPS_drbg_reseed(DRBG_CTX *dctx,
	}


int FIPS_drbg_generate(DRBG_CTX *dctx, unsigned char *out, size_t outlen,
static int fips_drbg_generate_internal(DRBG_CTX *dctx,
			unsigned char *out, size_t outlen,
			int strength, int prediction_resistance,
			const unsigned char *adin, size_t adinlen)
	{
@@ -313,13 +314,76 @@ int FIPS_drbg_generate(DRBG_CTX *dctx, unsigned char *out, size_t outlen,
	if (r)
		{
		if (!(dctx->flags & DRBG_FLAG_NOERR))
			FIPSerr(FIPS_F_FIPS_DRBG_GENERATE, r);
			FIPSerr(FIPS_F_FIPS_DRBG_GENERATE_INTERNAL, r);
		return 0;
		}

	return 1;
	}

/* external generate function: incorporates continuous RNG test if not
 * in test mode.
 */

int FIPS_drbg_generate(DRBG_CTX *dctx,
			unsigned char *out, size_t outlen,
			int strength, int prediction_resistance,
			const unsigned char *adin, size_t adinlen)
	{
	unsigned char tmp[16], *pout;
	size_t poutlen;
	/* If test mode don't run continuous RNG test */
	if (dctx->flags & DRBG_FLAG_TEST)
		{
		return fips_drbg_generate_internal(dctx, out, outlen,
							strength,
							prediction_resistance,
							adin, adinlen);
		}
	/* If this is the first call generate block and save buffer */
	if (!dctx->lb_valid)
		{
		if (!fips_drbg_generate_internal(dctx, dctx->lb, 16,
						strength, prediction_resistance,
						adin, adinlen))
			return 0;
		dctx->lb_valid = 1;
		}

	/* If request less that 16 bytes request 16 in temp buffer */

	if (outlen < 16)
		{
		pout = tmp;
		poutlen = 16;
		}
	else
		{
		pout = out;
		poutlen = outlen;
		}

	/* Generate data */
	if (!fips_drbg_generate_internal(dctx, pout, poutlen,
						strength, prediction_resistance,
						adin, adinlen))
			return 0;
	/* Compare to last block for continuous PRNG test */
	if (!memcmp(pout, dctx->lb, 16))
		{
		FIPSerr(FIPS_F_FIPS_DRBG_GENERATE, FIPS_R_DRBG_STUCK);
		return 0;
		}
	/* Update last block */
	memcpy(dctx->lb, pout, 16);
	/* Copy to output buffer if needed */
	if (outlen < 16)
		memcpy(out, pout, outlen);

	return 1;

	}

int FIPS_drbg_uninstantiate(DRBG_CTX *dctx)
	{
	int rv;
+6 −0
Original line number Diff line number Diff line
@@ -167,6 +167,12 @@ struct drbg_ctx_st
	size_t (*get_nonce)(DRBG_CTX *ctx, unsigned char *out,
				int entropy, size_t min_len, size_t max_len);

	/* Continuous random number test temporary area */
	/* Last block */	
	unsigned char lb[16];
	/* set if lb is valid */
	int lb_valid;

	};