Implement continuous RNG test for SP800-90 DRBGs.
This commit is contained in:
parent
96ec46f7c0
commit
1e803100de
@ -84,6 +84,7 @@ static ERR_STRING_DATA FIPS_str_functs[]=
|
|||||||
{ERR_FUNC(FIPS_F_FIPS_CIPHERINIT), "FIPS_CIPHERINIT"},
|
{ERR_FUNC(FIPS_F_FIPS_CIPHERINIT), "FIPS_CIPHERINIT"},
|
||||||
{ERR_FUNC(FIPS_F_FIPS_DIGESTINIT), "FIPS_DIGESTINIT"},
|
{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), "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_HEALTH_CHECK), "FIPS_DRBG_HEALTH_CHECK"},
|
||||||
{ERR_FUNC(FIPS_F_FIPS_DRBG_INIT), "FIPS_drbg_init"},
|
{ERR_FUNC(FIPS_F_FIPS_DRBG_INIT), "FIPS_drbg_init"},
|
||||||
{ERR_FUNC(FIPS_F_FIPS_DRBG_INSTANTIATE), "FIPS_drbg_instantiate"},
|
{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) ,"cannot read exe"},
|
||||||
{ERR_REASON(FIPS_R_CANNOT_READ_EXE_DIGEST),"cannot read exe digest"},
|
{ERR_REASON(FIPS_R_CANNOT_READ_EXE_DIGEST),"cannot read exe digest"},
|
||||||
{ERR_REASON(FIPS_R_CONTRADICTING_EVIDENCE),"contradicting evidence"},
|
{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_ERROR_UNDETECTED),"entropy error undetected"},
|
||||||
{ERR_REASON(FIPS_R_ENTROPY_NOT_REQUESTED_FOR_RESEED),"entropy not requested for reseed"},
|
{ERR_REASON(FIPS_R_ENTROPY_NOT_REQUESTED_FOR_RESEED),"entropy not requested for reseed"},
|
||||||
{ERR_REASON(FIPS_R_ERROR_INITIALISING_DRBG),"error initialising drbg"},
|
{ERR_REASON(FIPS_R_ERROR_INITIALISING_DRBG),"error initialising drbg"},
|
||||||
|
@ -194,6 +194,7 @@ void ERR_load_FIPS_strings(void);
|
|||||||
#define FIPS_F_FIPS_CIPHERINIT 128
|
#define FIPS_F_FIPS_CIPHERINIT 128
|
||||||
#define FIPS_F_FIPS_DIGESTINIT 127
|
#define FIPS_F_FIPS_DIGESTINIT 127
|
||||||
#define FIPS_F_FIPS_DRBG_GENERATE 132
|
#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_HEALTH_CHECK 137
|
||||||
#define FIPS_F_FIPS_DRBG_INIT 136
|
#define FIPS_F_FIPS_DRBG_INIT 136
|
||||||
#define FIPS_F_FIPS_DRBG_INSTANTIATE 133
|
#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 103
|
||||||
#define FIPS_R_CANNOT_READ_EXE_DIGEST 104
|
#define FIPS_R_CANNOT_READ_EXE_DIGEST 104
|
||||||
#define FIPS_R_CONTRADICTING_EVIDENCE 114
|
#define FIPS_R_CONTRADICTING_EVIDENCE 114
|
||||||
|
#define FIPS_R_DRBG_STUCK 142
|
||||||
#define FIPS_R_ENTROPY_ERROR_UNDETECTED 133
|
#define FIPS_R_ENTROPY_ERROR_UNDETECTED 133
|
||||||
#define FIPS_R_ENTROPY_NOT_REQUESTED_FOR_RESEED 134
|
#define FIPS_R_ENTROPY_NOT_REQUESTED_FOR_RESEED 134
|
||||||
#define FIPS_R_ERROR_INITIALISING_DRBG 120
|
#define FIPS_R_ERROR_INITIALISING_DRBG 120
|
||||||
|
@ -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,
|
int strength, int prediction_resistance,
|
||||||
const unsigned char *adin, size_t adinlen)
|
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 (r)
|
||||||
{
|
{
|
||||||
if (!(dctx->flags & DRBG_FLAG_NOERR))
|
if (!(dctx->flags & DRBG_FLAG_NOERR))
|
||||||
FIPSerr(FIPS_F_FIPS_DRBG_GENERATE, r);
|
FIPSerr(FIPS_F_FIPS_DRBG_GENERATE_INTERNAL, r);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 1;
|
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 FIPS_drbg_uninstantiate(DRBG_CTX *dctx)
|
||||||
{
|
{
|
||||||
int rv;
|
int rv;
|
||||||
|
@ -167,6 +167,12 @@ struct drbg_ctx_st
|
|||||||
size_t (*get_nonce)(DRBG_CTX *ctx, unsigned char *out,
|
size_t (*get_nonce)(DRBG_CTX *ctx, unsigned char *out,
|
||||||
int entropy, size_t min_len, size_t max_len);
|
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;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user