From: Dr. Stephen Henson Date: Wed, 21 Sep 2011 18:24:12 +0000 (+0000) Subject: Perform health check on all reseed operations not associated with X-Git-Tag: OpenSSL-fips-2_0-rc1~131 X-Git-Url: https://git.openssl.org/gitweb/?p=openssl.git;a=commitdiff_plain;h=05272d4c516fb1167581d35b31a7f815eafa9c57;ds=sidebyside Perform health check on all reseed operations not associated with prediction resistance requests. Although SP 800-90 is arguably unclear on whether this is necessary adding an additional check has minimal penalty (very few applications will make an explicit reseed request). --- diff --git a/fips/rand/fips_drbg_lib.c b/fips/rand/fips_drbg_lib.c index c2e42896d1..9873742c45 100644 --- a/fips/rand/fips_drbg_lib.c +++ b/fips/rand/fips_drbg_lib.c @@ -273,8 +273,8 @@ int FIPS_drbg_instantiate(DRBG_CTX *dctx, } -int FIPS_drbg_reseed(DRBG_CTX *dctx, - const unsigned char *adin, size_t adinlen) +static int drbg_reseed(DRBG_CTX *dctx, + const unsigned char *adin, size_t adinlen, int hcheck) { unsigned char *entropy = NULL; size_t entlen; @@ -303,6 +303,17 @@ int FIPS_drbg_reseed(DRBG_CTX *dctx, } dctx->status = DRBG_STATUS_ERROR; + /* Peform health check on all reseed operations if not a prediction + * resistance request and not in test mode. + */ + if (hcheck && !(dctx->xflags & DRBG_FLAG_TEST)) + { + if (!FIPS_drbg_test(dctx)) + { + r = FIPS_R_SELFTEST_FAILURE; + goto end; + } + } entlen = fips_get_entropy(dctx, &entropy, dctx->strength, dctx->min_entropy, dctx->max_entropy); @@ -333,6 +344,12 @@ int FIPS_drbg_reseed(DRBG_CTX *dctx, return 0; } +int FIPS_drbg_reseed(DRBG_CTX *dctx, + const unsigned char *adin, size_t adinlen) + { + return drbg_reseed(dctx, adin, adinlen, 1); + } + static int fips_drbg_check(DRBG_CTX *dctx) { if (dctx->xflags & DRBG_FLAG_TEST) @@ -340,7 +357,7 @@ static int fips_drbg_check(DRBG_CTX *dctx) dctx->health_check_cnt++; if (dctx->health_check_cnt >= dctx->health_check_interval) { - if (FIPS_drbg_test(dctx) <= 0) + if (!FIPS_drbg_test(dctx)) { FIPSerr(FIPS_F_FIPS_DRBG_CHECK, FIPS_R_SELFTEST_FAILURE); dctx->status = DRBG_STATUS_ERROR; @@ -389,7 +406,10 @@ int FIPS_drbg_generate(DRBG_CTX *dctx, unsigned char *out, size_t outlen, if (dctx->status == DRBG_STATUS_RESEED || prediction_resistance) { - if (!FIPS_drbg_reseed(dctx, adin, adinlen)) + /* If prediction resistance request don't do health check */ + int hcheck = prediction_resistance ? 0 : 1; + + if (!drbg_reseed(dctx, adin, adinlen, hcheck)) { r = FIPS_R_RESEED_ERROR; goto end; diff --git a/fips/rand/fips_drbg_selftest.c b/fips/rand/fips_drbg_selftest.c index 76667a0167..3bc7eab95c 100644 --- a/fips/rand/fips_drbg_selftest.c +++ b/fips/rand/fips_drbg_selftest.c @@ -772,9 +772,8 @@ int fips_drbg_kat(DRBG_CTX *dctx, int nid, unsigned int flags) { if (td->nid == nid && td->flags == flags) { - rv = fips_drbg_single_kat(dctx, td, 0); - if (rv <= 0) - return rv; + if (!fips_drbg_single_kat(dctx, td, 0)) + return 0; return fips_drbg_health_check(dctx, td); } }