1 /* fips/rand/fips_drbg_selftest.c */
2 /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
5 /* ====================================================================
6 * Copyright (c) 2011 The OpenSSL Project. All rights reserved.
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in
17 * the documentation and/or other materials provided with the
20 * 3. All advertising materials mentioning features or use of this
21 * software must display the following acknowledgment:
22 * "This product includes software developed by the OpenSSL Project
23 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
25 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
26 * endorse or promote products derived from this software without
27 * prior written permission. For written permission, please contact
28 * licensing@OpenSSL.org.
30 * 5. Products derived from this software may not be called "OpenSSL"
31 * nor may "OpenSSL" appear in their names without prior written
32 * permission of the OpenSSL Project.
34 * 6. Redistributions of any form whatsoever must retain the following
36 * "This product includes software developed by the OpenSSL Project
37 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
39 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
40 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
41 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
42 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
43 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
44 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
45 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
46 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
48 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
49 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
50 * OF THE POSSIBILITY OF SUCH DAMAGE.
51 * ====================================================================
54 #define OPENSSL_FIPSAPI
57 #include <openssl/crypto.h>
58 #include <openssl/err.h>
59 #include <openssl/fips_rand.h>
60 #include "fips_rand_lcl.h"
61 #include "fips_locl.h"
63 #include "fips_drbg_selftest.h"
70 /* KAT data for no PR */
71 const unsigned char *ent;
73 const unsigned char *nonce;
75 const unsigned char *pers;
77 const unsigned char *adin;
79 const unsigned char *entreseed;
81 const unsigned char *adinreseed;
83 const unsigned char *adin2;
85 const unsigned char *kat;
87 const unsigned char *kat2;
91 const unsigned char *ent_pr;
93 const unsigned char *nonce_pr;
95 const unsigned char *pers_pr;
97 const unsigned char *adin_pr;
99 const unsigned char *entpr_pr;
101 const unsigned char *ading_pr;
103 const unsigned char *entg_pr;
105 const unsigned char *kat_pr;
107 const unsigned char *kat2_pr;
110 } DRBG_SELFTEST_DATA;
112 #define make_drbg_test_data(nid, flag, pr, p) {p, nid, flag | DRBG_FLAG_TEST, \
113 pr##_entropyinput, sizeof(pr##_entropyinput), \
114 pr##_nonce, sizeof(pr##_nonce), \
115 pr##_personalizationstring, sizeof(pr##_personalizationstring), \
116 pr##_additionalinput, sizeof(pr##_additionalinput), \
117 pr##_entropyinputreseed, sizeof(pr##_entropyinputreseed), \
118 pr##_additionalinputreseed, sizeof(pr##_additionalinputreseed), \
119 pr##_additionalinput2, sizeof(pr##_additionalinput2), \
120 pr##_int_returnedbits, sizeof(pr##_int_returnedbits), \
121 pr##_returnedbits, sizeof(pr##_returnedbits), \
122 pr##_pr_entropyinput, sizeof(pr##_pr_entropyinput), \
123 pr##_pr_nonce, sizeof(pr##_pr_nonce), \
124 pr##_pr_personalizationstring, sizeof(pr##_pr_personalizationstring), \
125 pr##_pr_additionalinput, sizeof(pr##_pr_additionalinput), \
126 pr##_pr_entropyinputpr, sizeof(pr##_pr_entropyinputpr), \
127 pr##_pr_additionalinput2, sizeof(pr##_pr_additionalinput2), \
128 pr##_pr_entropyinputpr2, sizeof(pr##_pr_entropyinputpr2), \
129 pr##_pr_int_returnedbits, sizeof(pr##_pr_int_returnedbits), \
130 pr##_pr_returnedbits, sizeof(pr##_pr_returnedbits), \
133 #define make_drbg_test_data_df(nid, pr, p) \
134 make_drbg_test_data(nid, DRBG_FLAG_CTR_USE_DF, pr, p)
136 #define make_drbg_test_data_ec(curve, md, pr, p) \
137 make_drbg_test_data((curve << 16) | md , 0, pr, p)
139 static DRBG_SELFTEST_DATA drbg_test[] = {
140 make_drbg_test_data_df(NID_aes_128_ctr, aes_128_use_df, 0),
141 make_drbg_test_data_df(NID_aes_192_ctr, aes_192_use_df, 0),
142 make_drbg_test_data_df(NID_aes_256_ctr, aes_256_use_df, 1),
143 make_drbg_test_data(NID_aes_128_ctr, 0, aes_128_no_df, 0),
144 make_drbg_test_data(NID_aes_192_ctr, 0, aes_192_no_df, 0),
145 make_drbg_test_data(NID_aes_256_ctr, 0, aes_256_no_df, 1),
146 make_drbg_test_data(NID_sha1, 0, sha1, 0),
147 make_drbg_test_data(NID_sha224, 0, sha224, 0),
148 make_drbg_test_data(NID_sha256, 0, sha256, 1),
149 make_drbg_test_data(NID_sha384, 0, sha384, 0),
150 make_drbg_test_data(NID_sha512, 0, sha512, 0),
151 make_drbg_test_data(NID_hmacWithSHA1, 0, hmac_sha1, 0),
152 make_drbg_test_data(NID_hmacWithSHA224, 0, hmac_sha224, 0),
153 make_drbg_test_data(NID_hmacWithSHA256, 0, hmac_sha256, 1),
154 make_drbg_test_data(NID_hmacWithSHA384, 0, hmac_sha384, 0),
155 make_drbg_test_data(NID_hmacWithSHA512, 0, hmac_sha512, 0),
156 make_drbg_test_data_ec(NID_X9_62_prime256v1, NID_sha1, p_256_sha1, 0),
157 make_drbg_test_data_ec(NID_X9_62_prime256v1, NID_sha224, p_256_sha224, 0),
158 make_drbg_test_data_ec(NID_X9_62_prime256v1, NID_sha256, p_256_sha256, 1),
159 make_drbg_test_data_ec(NID_X9_62_prime256v1, NID_sha384, p_256_sha384, 0),
160 make_drbg_test_data_ec(NID_X9_62_prime256v1, NID_sha512, p_256_sha512, 0),
161 make_drbg_test_data_ec(NID_secp384r1, NID_sha224, p_384_sha224, 0),
162 make_drbg_test_data_ec(NID_secp384r1, NID_sha256, p_384_sha256, 0),
163 make_drbg_test_data_ec(NID_secp384r1, NID_sha384, p_384_sha384, 0),
164 make_drbg_test_data_ec(NID_secp384r1, NID_sha512, p_384_sha512, 0),
165 make_drbg_test_data_ec(NID_secp521r1, NID_sha256, p_521_sha256, 0),
166 make_drbg_test_data_ec(NID_secp521r1, NID_sha384, p_521_sha384, 0),
167 make_drbg_test_data_ec(NID_secp521r1, NID_sha512, p_521_sha512, 0),
173 const unsigned char *ent;
176 const unsigned char *nonce;
181 static size_t test_entropy(DRBG_CTX *dctx, unsigned char **pout,
182 int entropy, size_t min_len, size_t max_len)
184 TEST_ENT *t = FIPS_drbg_get_app_data(dctx);
185 *pout = (unsigned char *)t->ent;
190 static size_t test_nonce(DRBG_CTX *dctx, unsigned char **pout,
191 int entropy, size_t min_len, size_t max_len)
193 TEST_ENT *t = FIPS_drbg_get_app_data(dctx);
194 *pout = (unsigned char *)t->nonce;
199 static int fips_drbg_single_kat(DRBG_CTX *dctx, DRBG_SELFTEST_DATA *td,
205 unsigned char randout[1024];
207 /* Initial test without PR */
209 /* Instantiate DRBG with test entropy, nonce and personalisation
213 if (!FIPS_drbg_init(dctx, td->nid, td->flags))
215 if (!FIPS_drbg_set_callbacks(dctx, test_entropy, 0, 0, test_nonce, 0))
218 FIPS_drbg_set_app_data(dctx, &t);
221 t.entlen = td->entlen;
223 t.noncelen = td->noncelen;
227 if (!FIPS_drbg_instantiate(dctx, td->pers, td->perslen))
230 /* Note for CTR without DF some additional input values
231 * ignore bytes after the keylength: so reduce adinlen
232 * to half to ensure invalid data is fed in.
234 if (!fips_post_corrupt(FIPS_TEST_DRBG, dctx->type, &dctx->iflags))
235 adinlen = td->adinlen / 2;
237 adinlen = td->adinlen;
239 /* Generate with no PR and verify output matches expected data */
240 if (!FIPS_drbg_generate(dctx, randout, td->katlen, 0,
244 if (memcmp(randout, td->kat, td->katlen))
246 FIPSerr(FIPS_F_FIPS_DRBG_SINGLE_KAT, FIPS_R_NOPR_TEST1_FAILURE);
249 /* If abbreviated POST end of test */
255 /* Reseed DRBG with test entropy and additional input */
256 t.ent = td->entreseed;
257 t.entlen = td->entreseedlen;
259 if (!FIPS_drbg_reseed(dctx, td->adinreseed, td->adinreseedlen))
262 /* Generate with no PR and verify output matches expected data */
263 if (!FIPS_drbg_generate(dctx, randout, td->kat2len, 0,
264 td->adin2, td->adin2len))
267 if (memcmp(randout, td->kat2, td->kat2len))
269 FIPSerr(FIPS_F_FIPS_DRBG_SINGLE_KAT, FIPS_R_NOPR_TEST2_FAILURE);
273 FIPS_drbg_uninstantiate(dctx);
275 /* Now test with PR */
277 /* Instantiate DRBG with test entropy, nonce and personalisation
280 if (!FIPS_drbg_init(dctx, td->nid, td->flags))
282 if (!FIPS_drbg_set_callbacks(dctx, test_entropy, 0, 0, test_nonce, 0))
285 FIPS_drbg_set_app_data(dctx, &t);
288 t.entlen = td->entlen_pr;
289 t.nonce = td->nonce_pr;
290 t.noncelen = td->noncelen_pr;
294 if (!FIPS_drbg_instantiate(dctx, td->pers_pr, td->perslen_pr))
297 /* Now generate with PR: we need to supply entropy as this will
298 * perform a reseed operation. Check output matches expected value.
301 t.ent = td->entpr_pr;
302 t.entlen = td->entprlen_pr;
304 /* Note for CTR without DF some additional input values
305 * ignore bytes after the keylength: so reduce adinlen
306 * to half to ensure invalid data is fed in.
308 if (!fips_post_corrupt(FIPS_TEST_DRBG, dctx->type, &dctx->iflags))
309 adinlen = td->adinlen_pr / 2;
311 adinlen = td->adinlen_pr;
312 if (!FIPS_drbg_generate(dctx, randout, td->katlen_pr, 1,
313 td->adin_pr, adinlen))
316 if (memcmp(randout, td->kat_pr, td->katlen_pr))
318 FIPSerr(FIPS_F_FIPS_DRBG_SINGLE_KAT, FIPS_R_PR_TEST1_FAILURE);
322 /* Now generate again with PR: supply new entropy again.
323 * Check output matches expected value.
327 t.entlen = td->entglen_pr;
329 if (!FIPS_drbg_generate(dctx, randout, td->kat2len_pr, 1,
330 td->ading_pr, td->adinglen_pr))
333 if (memcmp(randout, td->kat2_pr, td->kat2len_pr))
335 FIPSerr(FIPS_F_FIPS_DRBG_SINGLE_KAT, FIPS_R_PR_TEST2_FAILURE);
338 /* All OK, test complete */
343 FIPSerr(FIPS_F_FIPS_DRBG_SINGLE_KAT, FIPS_R_SELFTEST_FAILED);
345 FIPS_drbg_uninstantiate(dctx);
351 /* Initialise a DRBG based on selftest data */
353 static int do_drbg_init(DRBG_CTX *dctx, DRBG_SELFTEST_DATA *td, TEST_ENT *t)
356 if (!FIPS_drbg_init(dctx, td->nid, td->flags))
359 if (!FIPS_drbg_set_callbacks(dctx, test_entropy, 0, 0, test_nonce, 0))
362 FIPS_drbg_set_app_data(dctx, t);
365 t->entlen = td->entlen;
366 t->nonce = td->nonce;
367 t->noncelen = td->noncelen;
373 /* Initialise and instantiate DRBG based on selftest data */
374 static int do_drbg_instantiate(DRBG_CTX *dctx, DRBG_SELFTEST_DATA *td,
377 if (!do_drbg_init(dctx, td, t))
379 if (!FIPS_drbg_instantiate(dctx, td->pers, td->perslen))
385 /* This function performs extensive error checking as required by SP800-90.
386 * Induce several failure modes and check an error condition is set.
387 * This function along with fips_drbg_single_kat peforms the health checking
391 static int fips_drbg_error_check(DRBG_CTX *dctx, DRBG_SELFTEST_DATA *td)
393 unsigned char randout[1024];
396 unsigned int reseed_counter_tmp;
397 unsigned char *p = (unsigned char *)dctx;
399 /* Initialise DRBG */
401 if (!do_drbg_init(dctx, td, &t))
404 /* Don't report induced errors */
405 dctx->iflags |= DRBG_FLAG_NOERR;
407 /* Personalisation string tests */
409 /* Test detection of too large personlisation string */
411 if (FIPS_drbg_instantiate(dctx, td->pers, dctx->max_pers + 1) > 0)
413 FIPSerr(FIPS_F_FIPS_DRBG_ERROR_CHECK, FIPS_R_PERSONALISATION_ERROR_UNDETECTED);
417 /* Entropy source tests */
419 /* Test entropy source failure detecion: i.e. returns no data */
423 if (FIPS_drbg_instantiate(dctx, td->pers, td->perslen) > 0)
425 FIPSerr(FIPS_F_FIPS_DRBG_ERROR_CHECK, FIPS_R_ENTROPY_ERROR_UNDETECTED);
429 /* Try to generate output from uninstantiated DRBG */
430 if (FIPS_drbg_generate(dctx, randout, td->katlen, 0,
431 td->adin, td->adinlen))
433 FIPSerr(FIPS_F_FIPS_DRBG_ERROR_CHECK, FIPS_R_GENERATE_ERROR_UNDETECTED);
437 dctx->iflags &= ~DRBG_FLAG_NOERR;
438 if (!FIPS_drbg_uninstantiate(dctx))
440 FIPSerr(FIPS_F_FIPS_DRBG_ERROR_CHECK, FIPS_R_UNINSTANTIATE_ERROR);
444 if (!do_drbg_init(dctx, td, &t))
447 dctx->iflags |= DRBG_FLAG_NOERR;
449 /* Test insufficient entropy */
451 t.entlen = dctx->min_entropy - 1;
453 if (FIPS_drbg_instantiate(dctx, td->pers, td->perslen) > 0)
455 FIPSerr(FIPS_F_FIPS_DRBG_ERROR_CHECK, FIPS_R_ENTROPY_ERROR_UNDETECTED);
459 dctx->iflags &= ~DRBG_FLAG_NOERR;
460 if (!FIPS_drbg_uninstantiate(dctx))
462 FIPSerr(FIPS_F_FIPS_DRBG_ERROR_CHECK, FIPS_R_UNINSTANTIATE_ERROR);
466 /* Test too much entropy */
468 if (!do_drbg_init(dctx, td, &t))
471 dctx->iflags |= DRBG_FLAG_NOERR;
473 t.entlen = dctx->max_entropy + 1;
475 if (FIPS_drbg_instantiate(dctx, td->pers, td->perslen) > 0)
477 FIPSerr(FIPS_F_FIPS_DRBG_ERROR_CHECK, FIPS_R_ENTROPY_ERROR_UNDETECTED);
481 dctx->iflags &= ~DRBG_FLAG_NOERR;
482 if (!FIPS_drbg_uninstantiate(dctx))
484 FIPSerr(FIPS_F_FIPS_DRBG_ERROR_CHECK, FIPS_R_UNINSTANTIATE_ERROR);
490 /* Test too small nonce */
495 if (!do_drbg_init(dctx, td, &t))
498 dctx->iflags |= DRBG_FLAG_NOERR;
500 t.noncelen = dctx->min_nonce - 1;
502 if (FIPS_drbg_instantiate(dctx, td->pers, td->perslen) > 0)
504 FIPSerr(FIPS_F_FIPS_DRBG_ERROR_CHECK, FIPS_R_NONCE_ERROR_UNDETECTED);
508 dctx->iflags &= ~DRBG_FLAG_NOERR;
509 if (!FIPS_drbg_uninstantiate(dctx))
511 FIPSerr(FIPS_F_FIPS_DRBG_ERROR_CHECK, FIPS_R_UNINSTANTIATE_ERROR);
517 /* Test too large nonce */
522 if (!do_drbg_init(dctx, td, &t))
525 dctx->iflags |= DRBG_FLAG_NOERR;
527 t.noncelen = dctx->max_nonce + 1;
529 if (FIPS_drbg_instantiate(dctx, td->pers, td->perslen) > 0)
531 FIPSerr(FIPS_F_FIPS_DRBG_ERROR_CHECK, FIPS_R_NONCE_ERROR_UNDETECTED);
535 dctx->iflags &= ~DRBG_FLAG_NOERR;
536 if (!FIPS_drbg_uninstantiate(dctx))
538 FIPSerr(FIPS_F_FIPS_DRBG_ERROR_CHECK, FIPS_R_UNINSTANTIATE_ERROR);
544 /* Instantiate with valid data. */
545 if (!do_drbg_instantiate(dctx, td, &t))
548 /* Check generation is now OK */
549 if (!FIPS_drbg_generate(dctx, randout, td->katlen, 0,
550 td->adin, td->adinlen))
553 dctx->iflags |= DRBG_FLAG_NOERR;
555 /* Request too much data for one request */
556 if (FIPS_drbg_generate(dctx, randout, dctx->max_request + 1, 0,
557 td->adin, td->adinlen))
559 FIPSerr(FIPS_F_FIPS_DRBG_ERROR_CHECK, FIPS_R_REQUEST_LENGTH_ERROR_UNDETECTED);
563 /* Try too large additional input */
564 if (FIPS_drbg_generate(dctx, randout, td->katlen, 0,
565 td->adin, dctx->max_adin + 1))
567 FIPSerr(FIPS_F_FIPS_DRBG_ERROR_CHECK, FIPS_R_ADDITIONAL_INPUT_ERROR_UNDETECTED);
571 /* Check prediction resistance request fails if entropy source
577 if (FIPS_drbg_generate(dctx, randout, td->katlen, 1,
578 td->adin, td->adinlen))
580 FIPSerr(FIPS_F_FIPS_DRBG_ERROR_CHECK, FIPS_R_ENTROPY_ERROR_UNDETECTED);
584 dctx->iflags &= ~DRBG_FLAG_NOERR;
585 if (!FIPS_drbg_uninstantiate(dctx))
587 FIPSerr(FIPS_F_FIPS_DRBG_ERROR_CHECK, FIPS_R_UNINSTANTIATE_ERROR);
592 /* Instantiate again with valid data */
594 if (!do_drbg_instantiate(dctx, td, &t))
596 /* Test reseed counter works */
597 /* Save initial reseed counter */
598 reseed_counter_tmp = dctx->reseed_counter;
599 /* Set reseed counter to beyond interval */
600 dctx->reseed_counter = dctx->reseed_interval;
602 /* Generate output and check entropy has been requested for reseed */
604 if (!FIPS_drbg_generate(dctx, randout, td->katlen, 0,
605 td->adin, td->adinlen))
609 FIPSerr(FIPS_F_FIPS_DRBG_ERROR_CHECK, FIPS_R_ENTROPY_NOT_REQUESTED_FOR_RESEED);
612 /* Check reseed counter has been reset */
613 if (dctx->reseed_counter != reseed_counter_tmp + 1)
615 FIPSerr(FIPS_F_FIPS_DRBG_ERROR_CHECK, FIPS_R_RESEED_COUNTER_ERROR);
619 dctx->iflags &= ~DRBG_FLAG_NOERR;
620 if (!FIPS_drbg_uninstantiate(dctx))
622 FIPSerr(FIPS_F_FIPS_DRBG_ERROR_CHECK, FIPS_R_UNINSTANTIATE_ERROR);
626 /* Check prediction resistance request fails if entropy source
632 dctx->iflags |= DRBG_FLAG_NOERR;
633 if (FIPS_drbg_generate(dctx, randout, td->katlen, 1,
634 td->adin, td->adinlen))
636 FIPSerr(FIPS_F_FIPS_DRBG_ERROR_CHECK, FIPS_R_ENTROPY_ERROR_UNDETECTED);
640 dctx->iflags &= ~DRBG_FLAG_NOERR;
642 if (!FIPS_drbg_uninstantiate(dctx))
644 FIPSerr(FIPS_F_FIPS_DRBG_ERROR_CHECK, FIPS_R_UNINSTANTIATE_ERROR);
649 if (!do_drbg_instantiate(dctx, td, &t))
651 /* Test reseed counter works */
652 /* Save initial reseed counter */
653 reseed_counter_tmp = dctx->reseed_counter;
654 /* Set reseed counter to beyond interval */
655 dctx->reseed_counter = dctx->reseed_interval;
657 /* Generate output and check entropy has been requested for reseed */
659 if (!FIPS_drbg_generate(dctx, randout, td->katlen, 0,
660 td->adin, td->adinlen))
664 FIPSerr(FIPS_F_FIPS_DRBG_ERROR_CHECK, FIPS_R_ENTROPY_NOT_REQUESTED_FOR_RESEED);
667 /* Check reseed counter has been reset */
668 if (dctx->reseed_counter != reseed_counter_tmp + 1)
670 FIPSerr(FIPS_F_FIPS_DRBG_ERROR_CHECK, FIPS_R_RESEED_COUNTER_ERROR);
674 dctx->iflags &= ~DRBG_FLAG_NOERR;
675 if (!FIPS_drbg_uninstantiate(dctx))
677 FIPSerr(FIPS_F_FIPS_DRBG_ERROR_CHECK, FIPS_R_UNINSTANTIATE_ERROR);
681 /* Explicit reseed tests */
683 /* Test explicit reseed with too large additional input */
684 if (!do_drbg_init(dctx, td, &t))
687 dctx->iflags |= DRBG_FLAG_NOERR;
689 if (FIPS_drbg_reseed(dctx, td->adin, dctx->max_adin + 1) > 0)
691 FIPSerr(FIPS_F_FIPS_DRBG_ERROR_CHECK, FIPS_R_ADDITIONAL_INPUT_ERROR_UNDETECTED);
695 /* Test explicit reseed with entropy source failure */
699 if (FIPS_drbg_reseed(dctx, td->adin, td->adinlen) > 0)
701 FIPSerr(FIPS_F_FIPS_DRBG_ERROR_CHECK, FIPS_R_ENTROPY_ERROR_UNDETECTED);
705 if (!FIPS_drbg_uninstantiate(dctx))
707 FIPSerr(FIPS_F_FIPS_DRBG_ERROR_CHECK, FIPS_R_UNINSTANTIATE_ERROR);
711 /* Test explicit reseed with too much entropy */
713 if (!do_drbg_init(dctx, td, &t))
716 dctx->iflags |= DRBG_FLAG_NOERR;
718 t.entlen = dctx->max_entropy + 1;
720 if (FIPS_drbg_reseed(dctx, td->adin, td->adinlen) > 0)
722 FIPSerr(FIPS_F_FIPS_DRBG_ERROR_CHECK, FIPS_R_ENTROPY_ERROR_UNDETECTED);
726 if (!FIPS_drbg_uninstantiate(dctx))
728 FIPSerr(FIPS_F_FIPS_DRBG_ERROR_CHECK, FIPS_R_UNINSTANTIATE_ERROR);
732 /* Test explicit reseed with too little entropy */
734 if (!do_drbg_init(dctx, td, &t))
737 dctx->iflags |= DRBG_FLAG_NOERR;
739 t.entlen = dctx->min_entropy - 1;
741 if (FIPS_drbg_reseed(dctx, td->adin, td->adinlen) > 0)
743 FIPSerr(FIPS_F_FIPS_DRBG_ERROR_CHECK, FIPS_R_ENTROPY_ERROR_UNDETECTED);
747 if (!FIPS_drbg_uninstantiate(dctx))
749 FIPSerr(FIPS_F_FIPS_DRBG_ERROR_CHECK, FIPS_R_UNINSTANTIATE_ERROR);
753 p = (unsigned char *)&dctx->d;
754 /* Standard says we have to check uninstantiate really zeroes
757 for (i = 0; i < sizeof(dctx->d); i++)
761 FIPSerr(FIPS_F_FIPS_DRBG_ERROR_CHECK, FIPS_R_UNINSTANTIATE_ZEROISE_ERROR);
770 /* A real error as opposed to an induced one: underlying function will
771 * indicate the error.
773 if (!(dctx->iflags & DRBG_FLAG_NOERR))
774 FIPSerr(FIPS_F_FIPS_DRBG_ERROR_CHECK, FIPS_R_FUNCTION_ERROR);
775 FIPS_drbg_uninstantiate(dctx);
780 int fips_drbg_kat(DRBG_CTX *dctx, int nid, unsigned int flags)
782 DRBG_SELFTEST_DATA *td;
783 flags |= DRBG_FLAG_TEST;
784 for (td = drbg_test; td->nid != 0; td++)
786 if (td->nid == nid && td->flags == flags)
788 if (!fips_drbg_single_kat(dctx, td, 0))
790 return fips_drbg_error_check(dctx, td);
796 int FIPS_drbg_health_check(DRBG_CTX *dctx)
799 DRBG_CTX *tctx = NULL;
800 tctx = FIPS_drbg_new(0, 0);
801 fips_post_started(FIPS_TEST_DRBG, dctx->type, &dctx->xflags);
804 rv = fips_drbg_kat(tctx, dctx->type, dctx->xflags);
806 FIPS_drbg_free(tctx);
808 fips_post_success(FIPS_TEST_DRBG, dctx->type, &dctx->xflags);
810 fips_post_failed(FIPS_TEST_DRBG, dctx->type, &dctx->xflags);
812 dctx->status = DRBG_STATUS_ERROR;
814 dctx->health_check_cnt = 0;
818 int FIPS_selftest_drbg(void)
821 DRBG_SELFTEST_DATA *td;
823 dctx = FIPS_drbg_new(0, 0);
826 for (td = drbg_test; td->nid != 0; td++)
830 if (!fips_post_started(FIPS_TEST_DRBG, td->nid, &td->flags))
832 if (!fips_drbg_single_kat(dctx, td, 1))
834 fips_post_failed(FIPS_TEST_DRBG, td->nid, &td->flags);
838 if (!fips_post_success(FIPS_TEST_DRBG, td->nid, &td->flags))
841 FIPS_drbg_free(dctx);
846 int FIPS_selftest_drbg_all(void)
849 DRBG_SELFTEST_DATA *td;
851 dctx = FIPS_drbg_new(0, 0);
854 for (td = drbg_test; td->nid != 0; td++)
856 if (!fips_post_started(FIPS_TEST_DRBG, td->nid, &td->flags))
858 if (!fips_drbg_single_kat(dctx, td, 0))
860 fips_post_failed(FIPS_TEST_DRBG, td->nid, &td->flags);
864 if (!fips_drbg_error_check(dctx, td))
866 fips_post_failed(FIPS_TEST_DRBG, td->nid, &td->flags);
870 if (!fips_post_success(FIPS_TEST_DRBG, td->nid, &td->flags))
873 FIPS_drbg_free(dctx);