X-Git-Url: https://git.openssl.org/gitweb/?p=openssl.git;a=blobdiff_plain;f=fips%2Frand%2Ffips_drbg_selftest.c;h=76667a0167e4d6302b1e69a3175b0e35d36f450a;hp=e38ba63c9eed410acb497c65976514a74b496559;hb=4420b3b17acf19f78f4fdea1a69d5f0a644c8154;hpb=74c40744caae40e6bd4717b1f07953f02a5d1480 diff --git a/fips/rand/fips_drbg_selftest.c b/fips/rand/fips_drbg_selftest.c index e38ba63c9e..76667a0167 100644 --- a/fips/rand/fips_drbg_selftest.c +++ b/fips/rand/fips_drbg_selftest.c @@ -133,6 +133,9 @@ typedef struct { #define make_drbg_test_data_df(nid, pr, p) \ make_drbg_test_data(nid, DRBG_FLAG_CTR_USE_DF, pr, p) +#define make_drbg_test_data_ec(curve, md, pr, p) \ + make_drbg_test_data((curve << 16) | md , 0, pr, p) + static DRBG_SELFTEST_DATA drbg_test[] = { make_drbg_test_data_df(NID_aes_128_ctr, aes_128_use_df, 0), make_drbg_test_data_df(NID_aes_192_ctr, aes_192_use_df, 0), @@ -150,6 +153,18 @@ static DRBG_SELFTEST_DATA drbg_test[] = { make_drbg_test_data(NID_hmacWithSHA256, 0, hmac_sha256, 1), make_drbg_test_data(NID_hmacWithSHA384, 0, hmac_sha384, 0), make_drbg_test_data(NID_hmacWithSHA512, 0, hmac_sha512, 0), + make_drbg_test_data_ec(NID_X9_62_prime256v1, NID_sha1, p_256_sha1, 0), + make_drbg_test_data_ec(NID_X9_62_prime256v1, NID_sha224, p_256_sha224, 0), + make_drbg_test_data_ec(NID_X9_62_prime256v1, NID_sha256, p_256_sha256, 1), + make_drbg_test_data_ec(NID_X9_62_prime256v1, NID_sha384, p_256_sha384, 0), + make_drbg_test_data_ec(NID_X9_62_prime256v1, NID_sha512, p_256_sha512, 0), + make_drbg_test_data_ec(NID_secp384r1, NID_sha224, p_384_sha224, 0), + make_drbg_test_data_ec(NID_secp384r1, NID_sha256, p_384_sha256, 0), + make_drbg_test_data_ec(NID_secp384r1, NID_sha384, p_384_sha384, 0), + make_drbg_test_data_ec(NID_secp384r1, NID_sha512, p_384_sha512, 0), + make_drbg_test_data_ec(NID_secp521r1, NID_sha256, p_521_sha256, 0), + make_drbg_test_data_ec(NID_secp521r1, NID_sha384, p_521_sha384, 0), + make_drbg_test_data_ec(NID_secp521r1, NID_sha512, p_521_sha512, 0), {0,0,0} }; @@ -181,7 +196,8 @@ static size_t test_nonce(DRBG_CTX *dctx, unsigned char **pout, return t->noncelen; } -static int fips_drbg_single_kat(DRBG_CTX *dctx, DRBG_SELFTEST_DATA *td) +static int fips_drbg_single_kat(DRBG_CTX *dctx, DRBG_SELFTEST_DATA *td, + int quick) { TEST_ENT t; int rv = 0; @@ -211,16 +227,25 @@ static int fips_drbg_single_kat(DRBG_CTX *dctx, DRBG_SELFTEST_DATA *td) * ignore bytes after the keylength: so reduce adinlen * to half to ensure invalid data is fed in. */ - if (!fips_post_corrupt(FIPS_TEST_DRBG, dctx->type, &dctx->flags)) + if (!fips_post_corrupt(FIPS_TEST_DRBG, dctx->type, &dctx->iflags)) adinlen = td->adinlen / 2; else adinlen = td->adinlen; - if (!FIPS_drbg_generate(dctx, randout, td->katlen, 0, 0, + if (!FIPS_drbg_generate(dctx, randout, td->katlen, 0, td->adin, adinlen)) goto err; if (memcmp(randout, td->kat, td->katlen)) + { + FIPSerr(FIPS_F_FIPS_DRBG_SINGLE_KAT, FIPS_R_NOPR_TEST1_FAILURE); + goto err2; + } + + if (quick) + { + rv = 1; goto err; + } t.ent = td->entreseed; t.entlen = td->entreseedlen; @@ -228,12 +253,15 @@ static int fips_drbg_single_kat(DRBG_CTX *dctx, DRBG_SELFTEST_DATA *td) if (!FIPS_drbg_reseed(dctx, td->adinreseed, td->adinreseedlen)) goto err; - if (!FIPS_drbg_generate(dctx, randout, td->kat2len, 0, 0, + if (!FIPS_drbg_generate(dctx, randout, td->kat2len, 0, td->adin2, td->adin2len)) goto err; if (memcmp(randout, td->kat2, td->kat2len)) - goto err; + { + FIPSerr(FIPS_F_FIPS_DRBG_SINGLE_KAT, FIPS_R_NOPR_TEST2_FAILURE); + goto err2; + } FIPS_drbg_uninstantiate(dctx); @@ -262,38 +290,79 @@ static int fips_drbg_single_kat(DRBG_CTX *dctx, DRBG_SELFTEST_DATA *td) * ignore bytes after the keylength: so reduce adinlen * to half to ensure invalid data is fed in. */ - if (!fips_post_corrupt(FIPS_TEST_DRBG, dctx->type, &dctx->flags)) + if (!fips_post_corrupt(FIPS_TEST_DRBG, dctx->type, &dctx->iflags)) adinlen = td->adinlen_pr / 2; else adinlen = td->adinlen_pr; - if (!FIPS_drbg_generate(dctx, randout, td->katlen_pr, 0, 1, + if (!FIPS_drbg_generate(dctx, randout, td->katlen_pr, 1, td->adin_pr, adinlen)) goto err; if (memcmp(randout, td->kat_pr, td->katlen_pr)) - goto err; + { + FIPSerr(FIPS_F_FIPS_DRBG_SINGLE_KAT, FIPS_R_PR_TEST1_FAILURE); + goto err2; + } t.ent = td->entg_pr; t.entlen = td->entglen_pr; - if (!FIPS_drbg_generate(dctx, randout, td->kat2len_pr, 0, 1, + if (!FIPS_drbg_generate(dctx, randout, td->kat2len_pr, 1, td->ading_pr, td->adinglen_pr)) goto err; if (memcmp(randout, td->kat2_pr, td->kat2len_pr)) - goto err; + { + FIPSerr(FIPS_F_FIPS_DRBG_SINGLE_KAT, FIPS_R_PR_TEST2_FAILURE); + goto err2; + } rv = 1; err: if (rv == 0) FIPSerr(FIPS_F_FIPS_DRBG_SINGLE_KAT, FIPS_R_SELFTEST_FAILED); + err2: FIPS_drbg_uninstantiate(dctx); return rv; } +/* Initialise a DRBG based on selftest data */ + +static int do_drbg_init(DRBG_CTX *dctx, DRBG_SELFTEST_DATA *td, TEST_ENT *t) + { + + if (!FIPS_drbg_init(dctx, td->nid, td->flags)) + return 0; + + if (!FIPS_drbg_set_callbacks(dctx, test_entropy, 0, 0, test_nonce, 0)) + return 0; + + FIPS_drbg_set_app_data(dctx, t); + + t->ent = td->ent; + t->entlen = td->entlen; + t->nonce = td->nonce; + t->noncelen = td->noncelen; + t->entcnt = 0; + t->noncecnt = 0; + return 1; + } + +/* Initialise and instantiate DRBG based on selftest data */ +static int do_drbg_instantiate(DRBG_CTX *dctx, DRBG_SELFTEST_DATA *td, + TEST_ENT *t) + { + if (!do_drbg_init(dctx, td, t)) + return 0; + if (!FIPS_drbg_instantiate(dctx, td->pers, td->perslen)) + return 0; + + return 1; + } + /* This is the "health check" function required by SP800-90. Induce several * failure modes and check an error condition is set. */ @@ -308,34 +377,28 @@ static int fips_drbg_health_check(DRBG_CTX *dctx, DRBG_SELFTEST_DATA *td) /* Initialise DRBG */ - if (!FIPS_drbg_init(dctx, td->nid, td->flags)) + if (!do_drbg_init(dctx, td, &t)) goto err; - if (!FIPS_drbg_set_callbacks(dctx, test_entropy, 0, 0, test_nonce, 0)) - goto err; + /* Don't report induced errors */ + dctx->iflags |= DRBG_FLAG_NOERR; - FIPS_drbg_set_app_data(dctx, &t); + /* Personalisation string tests */ - t.ent = td->ent; - t.entlen = td->entlen; - t.nonce = td->nonce; - t.noncelen = td->noncelen; - t.entcnt = 0; - t.noncecnt = 0; - - /* Don't report induced errors */ - dctx->flags |= DRBG_FLAG_NOERR; + /* Test detection of too large personlisation string */ - /* Try too large a personalisation length */ if (FIPS_drbg_instantiate(dctx, td->pers, dctx->max_pers + 1) > 0) { FIPSerr(FIPS_F_FIPS_DRBG_HEALTH_CHECK, FIPS_R_PERSONALISATION_ERROR_UNDETECTED); goto err; } - /* Test entropy source failure detection */ + /* Entropy source tests */ + + /* Test entropy source failure detecion: i.e. returns no data */ t.entlen = 0; + if (FIPS_drbg_instantiate(dctx, td->pers, td->perslen) > 0) { FIPSerr(FIPS_F_FIPS_DRBG_HEALTH_CHECK, FIPS_R_ENTROPY_ERROR_UNDETECTED); @@ -343,73 +406,161 @@ static int fips_drbg_health_check(DRBG_CTX *dctx, DRBG_SELFTEST_DATA *td) } /* Try to generate output from uninstantiated DRBG */ - if (FIPS_drbg_generate(dctx, randout, td->katlen, 0, 0, + if (FIPS_drbg_generate(dctx, randout, td->katlen, 0, td->adin, td->adinlen)) { FIPSerr(FIPS_F_FIPS_DRBG_HEALTH_CHECK, FIPS_R_GENERATE_ERROR_UNDETECTED); goto err; } - dctx->flags &= ~DRBG_FLAG_NOERR; + dctx->iflags &= ~DRBG_FLAG_NOERR; if (!FIPS_drbg_uninstantiate(dctx)) { FIPSerr(FIPS_F_FIPS_DRBG_HEALTH_CHECK, FIPS_R_UNINSTANTIATE_ERROR); goto err; } - /* Instantiate with valid data. NB: errors now reported again */ - if (!FIPS_drbg_init(dctx, td->nid, td->flags)) + if (!do_drbg_init(dctx, td, &t)) goto err; - if (!FIPS_drbg_set_callbacks(dctx, test_entropy, 0, 0, test_nonce, 0)) + + dctx->iflags |= DRBG_FLAG_NOERR; + + /* Test insufficient entropy */ + + t.entlen = dctx->min_entropy - 1; + + if (FIPS_drbg_instantiate(dctx, td->pers, td->perslen) > 0) + { + FIPSerr(FIPS_F_FIPS_DRBG_HEALTH_CHECK, FIPS_R_ENTROPY_ERROR_UNDETECTED); goto err; - FIPS_drbg_set_app_data(dctx, &t); + } - t.entlen = td->entlen; - if (!FIPS_drbg_instantiate(dctx, td->pers, td->perslen)) + dctx->iflags &= ~DRBG_FLAG_NOERR; + if (!FIPS_drbg_uninstantiate(dctx)) + { + FIPSerr(FIPS_F_FIPS_DRBG_HEALTH_CHECK, FIPS_R_UNINSTANTIATE_ERROR); goto err; + } - /* Check generation is now OK */ - if (!FIPS_drbg_generate(dctx, randout, td->katlen, 0, 0, - td->adin, td->adinlen)) + /* Test too much entropy */ + + if (!do_drbg_init(dctx, td, &t)) goto err; - /* Try to generate with too high a strength. - */ + dctx->iflags |= DRBG_FLAG_NOERR; + + t.entlen = dctx->max_entropy + 1; + + if (FIPS_drbg_instantiate(dctx, td->pers, td->perslen) > 0) + { + FIPSerr(FIPS_F_FIPS_DRBG_HEALTH_CHECK, FIPS_R_ENTROPY_ERROR_UNDETECTED); + goto err; + } + + dctx->iflags &= ~DRBG_FLAG_NOERR; + if (!FIPS_drbg_uninstantiate(dctx)) + { + FIPSerr(FIPS_F_FIPS_DRBG_HEALTH_CHECK, FIPS_R_UNINSTANTIATE_ERROR); + goto err; + } + + /* Nonce tests */ + + /* Test too small nonce */ + + if (dctx->min_nonce) + { + + if (!do_drbg_init(dctx, td, &t)) + goto err; + + dctx->iflags |= DRBG_FLAG_NOERR; + + t.noncelen = dctx->min_nonce - 1; + + if (FIPS_drbg_instantiate(dctx, td->pers, td->perslen) > 0) + { + FIPSerr(FIPS_F_FIPS_DRBG_HEALTH_CHECK, FIPS_R_NONCE_ERROR_UNDETECTED); + goto err; + } + + dctx->iflags &= ~DRBG_FLAG_NOERR; + if (!FIPS_drbg_uninstantiate(dctx)) + { + FIPSerr(FIPS_F_FIPS_DRBG_HEALTH_CHECK, FIPS_R_UNINSTANTIATE_ERROR); + goto err; + } + + } - dctx->flags |= DRBG_FLAG_NOERR; - if (dctx->strength != 256) + /* Test too large nonce */ + + if (dctx->max_nonce) { - if (FIPS_drbg_generate(dctx, randout, td->katlen, 256, 0, - td->adin, td->adinlen)) + + if (!do_drbg_init(dctx, td, &t)) + goto err; + + dctx->iflags |= DRBG_FLAG_NOERR; + + t.noncelen = dctx->max_nonce + 1; + + if (FIPS_drbg_instantiate(dctx, td->pers, td->perslen) > 0) { - FIPSerr(FIPS_F_FIPS_DRBG_HEALTH_CHECK, FIPS_R_STRENGTH_ERROR_UNDETECTED); + FIPSerr(FIPS_F_FIPS_DRBG_HEALTH_CHECK, FIPS_R_NONCE_ERROR_UNDETECTED); + goto err; + } + dctx->iflags &= ~DRBG_FLAG_NOERR; + if (!FIPS_drbg_uninstantiate(dctx)) + { + FIPSerr(FIPS_F_FIPS_DRBG_HEALTH_CHECK, FIPS_R_UNINSTANTIATE_ERROR); goto err; } + } + /* Instantiate with valid data. */ + if (!do_drbg_instantiate(dctx, td, &t)) + goto err; + + /* Check generation is now OK */ + if (!FIPS_drbg_generate(dctx, randout, td->katlen, 0, + td->adin, td->adinlen)) + goto err; + + dctx->iflags |= DRBG_FLAG_NOERR; + /* Request too much data for one request */ - if (FIPS_drbg_generate(dctx, randout, dctx->max_request + 1, 0, 0, + if (FIPS_drbg_generate(dctx, randout, dctx->max_request + 1, 0, td->adin, td->adinlen)) { FIPSerr(FIPS_F_FIPS_DRBG_HEALTH_CHECK, FIPS_R_REQUEST_LENGTH_ERROR_UNDETECTED); goto err; } + /* Try too large additional input */ + if (FIPS_drbg_generate(dctx, randout, td->katlen, 0, + td->adin, dctx->max_adin + 1)) + { + FIPSerr(FIPS_F_FIPS_DRBG_HEALTH_CHECK, FIPS_R_ADDITIONAL_INPUT_ERROR_UNDETECTED); + goto err; + } + /* Check prediction resistance request fails if entropy source * failure. */ t.entlen = 0; - if (FIPS_drbg_generate(dctx, randout, td->katlen, 0, 1, + if (FIPS_drbg_generate(dctx, randout, td->katlen, 1, td->adin, td->adinlen)) { FIPSerr(FIPS_F_FIPS_DRBG_HEALTH_CHECK, FIPS_R_ENTROPY_ERROR_UNDETECTED); goto err; } - dctx->flags &= ~DRBG_FLAG_NOERR; + dctx->iflags &= ~DRBG_FLAG_NOERR; if (!FIPS_drbg_uninstantiate(dctx)) { @@ -420,16 +571,72 @@ static int fips_drbg_health_check(DRBG_CTX *dctx, DRBG_SELFTEST_DATA *td) /* Instantiate again with valid data */ - if (!FIPS_drbg_init(dctx, td->nid, td->flags)) + if (!do_drbg_instantiate(dctx, td, &t)) + goto err; + /* Test reseed counter works */ + /* Save initial reseed counter */ + reseed_counter_tmp = dctx->reseed_counter; + /* Set reseed counter to beyond interval */ + dctx->reseed_counter = dctx->reseed_interval; + + /* Generate output and check entropy has been requested for reseed */ + t.entcnt = 0; + if (!FIPS_drbg_generate(dctx, randout, td->katlen, 0, + td->adin, td->adinlen)) goto err; - if (!FIPS_drbg_set_callbacks(dctx, test_entropy, 0, 0, test_nonce, 0)) + if (t.entcnt != 1) + { + FIPSerr(FIPS_F_FIPS_DRBG_HEALTH_CHECK, FIPS_R_ENTROPY_NOT_REQUESTED_FOR_RESEED); goto err; - FIPS_drbg_set_app_data(dctx, &t); + } + /* Check reseed counter has been reset */ + if (dctx->reseed_counter != reseed_counter_tmp + 1) + { + FIPSerr(FIPS_F_FIPS_DRBG_HEALTH_CHECK, FIPS_R_RESEED_COUNTER_ERROR); + goto err; + } - t.entlen = td->entlen; - /* Test reseed counter works */ - if (!FIPS_drbg_instantiate(dctx, td->pers, td->perslen)) + /* Explicit reseed tests */ + + /* Test explicit reseed with too large additional input */ + if (!do_drbg_init(dctx, td, &t)) + goto err; + + dctx->iflags |= DRBG_FLAG_NOERR; + + if (FIPS_drbg_reseed(dctx, td->adin, dctx->max_adin + 1) > 0) + { + FIPSerr(FIPS_F_FIPS_DRBG_HEALTH_CHECK, FIPS_R_ADDITIONAL_INPUT_ERROR_UNDETECTED); goto err; + } + + /* Test explicit reseed with entropy source failure */ + + /* Check prediction resistance request fails if entropy source + * failure. + */ + + t.entlen = 0; + + if (FIPS_drbg_generate(dctx, randout, td->katlen, 1, + td->adin, td->adinlen)) + { + FIPSerr(FIPS_F_FIPS_DRBG_HEALTH_CHECK, FIPS_R_ENTROPY_ERROR_UNDETECTED); + goto err; + } + + dctx->iflags &= ~DRBG_FLAG_NOERR; + + if (!FIPS_drbg_uninstantiate(dctx)) + { + FIPSerr(FIPS_F_FIPS_DRBG_HEALTH_CHECK, FIPS_R_UNINSTANTIATE_ERROR); + goto err; + } + + + if (!do_drbg_instantiate(dctx, td, &t)) + goto err; + /* Test reseed counter works */ /* Save initial reseed counter */ reseed_counter_tmp = dctx->reseed_counter; /* Set reseed counter to beyond interval */ @@ -437,7 +644,7 @@ static int fips_drbg_health_check(DRBG_CTX *dctx, DRBG_SELFTEST_DATA *td) /* Generate output and check entropy has been requested for reseed */ t.entcnt = 0; - if (!FIPS_drbg_generate(dctx, randout, td->katlen, 0, 0, + if (!FIPS_drbg_generate(dctx, randout, td->katlen, 0, td->adin, td->adinlen)) goto err; if (t.entcnt != 1) @@ -452,7 +659,83 @@ static int fips_drbg_health_check(DRBG_CTX *dctx, DRBG_SELFTEST_DATA *td) goto err; } - FIPS_drbg_uninstantiate(dctx); + /* Explicit reseed tests */ + + /* Test explicit reseed with too large additional input */ + if (!do_drbg_init(dctx, td, &t)) + goto err; + + dctx->iflags |= DRBG_FLAG_NOERR; + + if (FIPS_drbg_reseed(dctx, td->adin, dctx->max_adin + 1) > 0) + { + FIPSerr(FIPS_F_FIPS_DRBG_HEALTH_CHECK, FIPS_R_ADDITIONAL_INPUT_ERROR_UNDETECTED); + goto err; + } + + /* Test explicit reseed with entropy source failure */ + + if (!do_drbg_init(dctx, td, &t)) + goto err; + + dctx->iflags |= DRBG_FLAG_NOERR; + + t.entlen = 0; + + if (FIPS_drbg_reseed(dctx, td->adin, td->adinlen) > 0) + { + FIPSerr(FIPS_F_FIPS_DRBG_HEALTH_CHECK, FIPS_R_ENTROPY_ERROR_UNDETECTED); + goto err; + } + + if (!FIPS_drbg_uninstantiate(dctx)) + { + FIPSerr(FIPS_F_FIPS_DRBG_HEALTH_CHECK, FIPS_R_UNINSTANTIATE_ERROR); + goto err; + } + + /* Test explicit reseed with too much entropy */ + + if (!do_drbg_init(dctx, td, &t)) + goto err; + + dctx->iflags |= DRBG_FLAG_NOERR; + + t.entlen = dctx->max_entropy + 1; + + if (FIPS_drbg_reseed(dctx, td->adin, td->adinlen) > 0) + { + FIPSerr(FIPS_F_FIPS_DRBG_HEALTH_CHECK, FIPS_R_ENTROPY_ERROR_UNDETECTED); + goto err; + } + + if (!FIPS_drbg_uninstantiate(dctx)) + { + FIPSerr(FIPS_F_FIPS_DRBG_HEALTH_CHECK, FIPS_R_UNINSTANTIATE_ERROR); + goto err; + } + + /* Test explicit reseed with too little entropy */ + + if (!do_drbg_init(dctx, td, &t)) + goto err; + + dctx->iflags |= DRBG_FLAG_NOERR; + + t.entlen = dctx->min_entropy - 1; + + if (FIPS_drbg_reseed(dctx, td->adin, td->adinlen) > 0) + { + FIPSerr(FIPS_F_FIPS_DRBG_HEALTH_CHECK, FIPS_R_ENTROPY_ERROR_UNDETECTED); + goto err; + } + + if (!FIPS_drbg_uninstantiate(dctx)) + { + FIPSerr(FIPS_F_FIPS_DRBG_HEALTH_CHECK, FIPS_R_UNINSTANTIATE_ERROR); + goto err; + } + p = (unsigned char *)&dctx->d; /* Standard says we have to check uninstantiate really zeroes * the data... @@ -473,23 +756,23 @@ static int fips_drbg_health_check(DRBG_CTX *dctx, DRBG_SELFTEST_DATA *td) /* A real error as opposed to an induced one: underlying function will * indicate the error. */ - if (!(dctx->flags & DRBG_FLAG_NOERR)) + if (!(dctx->iflags & DRBG_FLAG_NOERR)) FIPSerr(FIPS_F_FIPS_DRBG_HEALTH_CHECK, FIPS_R_FUNCTION_ERROR); FIPS_drbg_uninstantiate(dctx); return 0; } - int fips_drbg_kat(DRBG_CTX *dctx, int nid, unsigned int flags) { int rv; DRBG_SELFTEST_DATA *td; + flags |= DRBG_FLAG_TEST; for (td = drbg_test; td->nid != 0; td++) { if (td->nid == nid && td->flags == flags) { - rv = fips_drbg_single_kat(dctx, td); + rv = fips_drbg_single_kat(dctx, td, 0); if (rv <= 0) return rv; return fips_drbg_health_check(dctx, td); @@ -498,6 +781,24 @@ int fips_drbg_kat(DRBG_CTX *dctx, int nid, unsigned int flags) return 0; } +int FIPS_drbg_test(DRBG_CTX *dctx) + { + int rv; + DRBG_CTX *tctx = NULL; + tctx = FIPS_drbg_new(0, 0); + fips_post_started(FIPS_TEST_DRBG, dctx->type, &dctx->xflags); + if (!tctx) + return 0; + rv = fips_drbg_kat(tctx, dctx->type, dctx->xflags); + if (tctx) + FIPS_drbg_free(tctx); + if (rv) + fips_post_success(FIPS_TEST_DRBG, dctx->type, &dctx->xflags); + else + fips_post_failed(FIPS_TEST_DRBG, dctx->type, &dctx->xflags); + return rv; + } + int FIPS_selftest_drbg(void) { DRBG_CTX *dctx; @@ -512,7 +813,7 @@ int FIPS_selftest_drbg(void) continue; if (!fips_post_started(FIPS_TEST_DRBG, td->nid, &td->flags)) return 1; - if (!fips_drbg_single_kat(dctx, td)) + if (!fips_drbg_single_kat(dctx, td, 1)) { fips_post_failed(FIPS_TEST_DRBG, td->nid, &td->flags); rv = 0; @@ -526,5 +827,34 @@ int FIPS_selftest_drbg(void) } - +int FIPS_selftest_drbg_all(void) + { + DRBG_CTX *dctx; + DRBG_SELFTEST_DATA *td; + int rv = 1; + dctx = FIPS_drbg_new(0, 0); + if (!dctx) + return 0; + for (td = drbg_test; td->nid != 0; td++) + { + if (!fips_post_started(FIPS_TEST_DRBG, td->nid, &td->flags)) + return 1; + if (!fips_drbg_single_kat(dctx, td, 0)) + { + fips_post_failed(FIPS_TEST_DRBG, td->nid, &td->flags); + rv = 0; + continue; + } + if (!fips_drbg_health_check(dctx, td)) + { + fips_post_failed(FIPS_TEST_DRBG, td->nid, &td->flags); + rv = 0; + continue; + } + if (!fips_post_success(FIPS_TEST_DRBG, td->nid, &td->flags)) + return 0; + } + FIPS_drbg_free(dctx); + return rv; + }