diff options
author | Dr. Stephen Henson <steve@openssl.org> | 2011-03-17 18:53:33 +0000 |
---|---|---|
committer | Dr. Stephen Henson <steve@openssl.org> | 2011-03-17 18:53:33 +0000 |
commit | 1e803100de9e88fff6fc586a54e12dda5861557b (patch) | |
tree | 4684ba2eb2d07755572b190d84f6761796491a12 /fips | |
parent | 96ec46f7c03a94f74cc05ebdf7a8889174acb28d (diff) |
Implement continuous RNG test for SP800-90 DRBGs.
Diffstat (limited to 'fips')
-rw-r--r-- | fips/fips.h | 2 | ||||
-rw-r--r-- | fips/rand/fips_drbg_lib.c | 68 | ||||
-rw-r--r-- | fips/rand/fips_rand_lcl.h | 6 |
3 files changed, 74 insertions, 2 deletions
diff --git a/fips/fips.h b/fips/fips.h index af36f03236..6dadc1ee18 100644 --- a/fips/fips.h +++ b/fips/fips.h @@ -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 diff --git a/fips/rand/fips_drbg_lib.c b/fips/rand/fips_drbg_lib.c index 0e06273cef..94bc36a31f 100644 --- a/fips/rand/fips_drbg_lib.c +++ b/fips/rand/fips_drbg_lib.c @@ -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; diff --git a/fips/rand/fips_rand_lcl.h b/fips/rand/fips_rand_lcl.h index 7e64bb491f..8f97ac00be 100644 --- a/fips/rand/fips_rand_lcl.h +++ b/fips/rand/fips_rand_lcl.h @@ -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; + }; |