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 if (!FIPS_drbg_init(dctx, td->nid, td->flags))
211 if (!FIPS_drbg_set_callbacks(dctx, test_entropy, 0, 0, test_nonce, 0))
214 FIPS_drbg_set_app_data(dctx, &t);
217 t.entlen = td->entlen;
219 t.noncelen = td->noncelen;
223 if (!FIPS_drbg_instantiate(dctx, td->pers, td->perslen))
226 /* Note for CTR without DF some additional input values
227 * ignore bytes after the keylength: so reduce adinlen
228 * to half to ensure invalid data is fed in.
230 if (!fips_post_corrupt(FIPS_TEST_DRBG, dctx->type, &dctx->iflags))
231 adinlen = td->adinlen / 2;
233 adinlen = td->adinlen;
234 if (!FIPS_drbg_generate(dctx, randout, td->katlen, 0,
238 if (memcmp(randout, td->kat, td->katlen))
240 FIPSerr(FIPS_F_FIPS_DRBG_SINGLE_KAT, FIPS_R_NOPR_TEST1_FAILURE);
250 t.ent = td->entreseed;
251 t.entlen = td->entreseedlen;
253 if (!FIPS_drbg_reseed(dctx, td->adinreseed, td->adinreseedlen))
256 if (!FIPS_drbg_generate(dctx, randout, td->kat2len, 0,
257 td->adin2, td->adin2len))
260 if (memcmp(randout, td->kat2, td->kat2len))
262 FIPSerr(FIPS_F_FIPS_DRBG_SINGLE_KAT, FIPS_R_NOPR_TEST2_FAILURE);
266 FIPS_drbg_uninstantiate(dctx);
268 /* Now test with PR */
269 if (!FIPS_drbg_init(dctx, td->nid, td->flags))
271 if (!FIPS_drbg_set_callbacks(dctx, test_entropy, 0, 0, test_nonce, 0))
274 FIPS_drbg_set_app_data(dctx, &t);
277 t.entlen = td->entlen_pr;
278 t.nonce = td->nonce_pr;
279 t.noncelen = td->noncelen_pr;
283 if (!FIPS_drbg_instantiate(dctx, td->pers_pr, td->perslen_pr))
286 t.ent = td->entpr_pr;
287 t.entlen = td->entprlen_pr;
289 /* Note for CTR without DF some additional input values
290 * ignore bytes after the keylength: so reduce adinlen
291 * to half to ensure invalid data is fed in.
293 if (!fips_post_corrupt(FIPS_TEST_DRBG, dctx->type, &dctx->iflags))
294 adinlen = td->adinlen_pr / 2;
296 adinlen = td->adinlen_pr;
297 if (!FIPS_drbg_generate(dctx, randout, td->katlen_pr, 1,
298 td->adin_pr, adinlen))
301 if (memcmp(randout, td->kat_pr, td->katlen_pr))
303 FIPSerr(FIPS_F_FIPS_DRBG_SINGLE_KAT, FIPS_R_PR_TEST1_FAILURE);
308 t.entlen = td->entglen_pr;
310 if (!FIPS_drbg_generate(dctx, randout, td->kat2len_pr, 1,
311 td->ading_pr, td->adinglen_pr))
314 if (memcmp(randout, td->kat2_pr, td->kat2len_pr))
316 FIPSerr(FIPS_F_FIPS_DRBG_SINGLE_KAT, FIPS_R_PR_TEST2_FAILURE);
324 FIPSerr(FIPS_F_FIPS_DRBG_SINGLE_KAT, FIPS_R_SELFTEST_FAILED);
326 FIPS_drbg_uninstantiate(dctx);
332 /* Initialise a DRBG based on selftest data */
334 static int do_drbg_init(DRBG_CTX *dctx, DRBG_SELFTEST_DATA *td, TEST_ENT *t)
337 if (!FIPS_drbg_init(dctx, td->nid, td->flags))
340 if (!FIPS_drbg_set_callbacks(dctx, test_entropy, 0, 0, test_nonce, 0))
343 FIPS_drbg_set_app_data(dctx, t);
346 t->entlen = td->entlen;
347 t->nonce = td->nonce;
348 t->noncelen = td->noncelen;
354 /* Initialise and instantiate DRBG based on selftest data */
355 static int do_drbg_instantiate(DRBG_CTX *dctx, DRBG_SELFTEST_DATA *td,
358 if (!do_drbg_init(dctx, td, t))
360 if (!FIPS_drbg_instantiate(dctx, td->pers, td->perslen))
366 /* This is the "health check" function required by SP800-90. Induce several
367 * failure modes and check an error condition is set.
370 static int fips_drbg_health_check(DRBG_CTX *dctx, DRBG_SELFTEST_DATA *td)
372 unsigned char randout[1024];
375 unsigned int reseed_counter_tmp;
376 unsigned char *p = (unsigned char *)dctx;
378 /* Initialise DRBG */
380 if (!do_drbg_init(dctx, td, &t))
383 /* Don't report induced errors */
384 dctx->iflags |= DRBG_FLAG_NOERR;
386 /* Personalisation string tests */
388 /* Test detection of too large personlisation string */
390 if (FIPS_drbg_instantiate(dctx, td->pers, dctx->max_pers + 1) > 0)
392 FIPSerr(FIPS_F_FIPS_DRBG_HEALTH_CHECK, FIPS_R_PERSONALISATION_ERROR_UNDETECTED);
396 /* Entropy source tests */
398 /* Test entropy source failure detecion: i.e. returns no data */
402 if (FIPS_drbg_instantiate(dctx, td->pers, td->perslen) > 0)
404 FIPSerr(FIPS_F_FIPS_DRBG_HEALTH_CHECK, FIPS_R_ENTROPY_ERROR_UNDETECTED);
408 /* Try to generate output from uninstantiated DRBG */
409 if (FIPS_drbg_generate(dctx, randout, td->katlen, 0,
410 td->adin, td->adinlen))
412 FIPSerr(FIPS_F_FIPS_DRBG_HEALTH_CHECK, FIPS_R_GENERATE_ERROR_UNDETECTED);
416 dctx->iflags &= ~DRBG_FLAG_NOERR;
417 if (!FIPS_drbg_uninstantiate(dctx))
419 FIPSerr(FIPS_F_FIPS_DRBG_HEALTH_CHECK, FIPS_R_UNINSTANTIATE_ERROR);
423 if (!do_drbg_init(dctx, td, &t))
426 dctx->iflags |= DRBG_FLAG_NOERR;
428 /* Test insufficient entropy */
430 t.entlen = dctx->min_entropy - 1;
432 if (FIPS_drbg_instantiate(dctx, td->pers, td->perslen) > 0)
434 FIPSerr(FIPS_F_FIPS_DRBG_HEALTH_CHECK, FIPS_R_ENTROPY_ERROR_UNDETECTED);
438 dctx->iflags &= ~DRBG_FLAG_NOERR;
439 if (!FIPS_drbg_uninstantiate(dctx))
441 FIPSerr(FIPS_F_FIPS_DRBG_HEALTH_CHECK, FIPS_R_UNINSTANTIATE_ERROR);
445 /* Test too much entropy */
447 if (!do_drbg_init(dctx, td, &t))
450 dctx->iflags |= DRBG_FLAG_NOERR;
452 t.entlen = dctx->max_entropy + 1;
454 if (FIPS_drbg_instantiate(dctx, td->pers, td->perslen) > 0)
456 FIPSerr(FIPS_F_FIPS_DRBG_HEALTH_CHECK, FIPS_R_ENTROPY_ERROR_UNDETECTED);
460 dctx->iflags &= ~DRBG_FLAG_NOERR;
461 if (!FIPS_drbg_uninstantiate(dctx))
463 FIPSerr(FIPS_F_FIPS_DRBG_HEALTH_CHECK, FIPS_R_UNINSTANTIATE_ERROR);
469 /* Test too small nonce */
474 if (!do_drbg_init(dctx, td, &t))
477 dctx->iflags |= DRBG_FLAG_NOERR;
479 t.noncelen = dctx->min_nonce - 1;
481 if (FIPS_drbg_instantiate(dctx, td->pers, td->perslen) > 0)
483 FIPSerr(FIPS_F_FIPS_DRBG_HEALTH_CHECK, FIPS_R_NONCE_ERROR_UNDETECTED);
487 dctx->iflags &= ~DRBG_FLAG_NOERR;
488 if (!FIPS_drbg_uninstantiate(dctx))
490 FIPSerr(FIPS_F_FIPS_DRBG_HEALTH_CHECK, FIPS_R_UNINSTANTIATE_ERROR);
496 /* Test too large nonce */
501 if (!do_drbg_init(dctx, td, &t))
504 dctx->iflags |= DRBG_FLAG_NOERR;
506 t.noncelen = dctx->max_nonce + 1;
508 if (FIPS_drbg_instantiate(dctx, td->pers, td->perslen) > 0)
510 FIPSerr(FIPS_F_FIPS_DRBG_HEALTH_CHECK, FIPS_R_NONCE_ERROR_UNDETECTED);
514 dctx->iflags &= ~DRBG_FLAG_NOERR;
515 if (!FIPS_drbg_uninstantiate(dctx))
517 FIPSerr(FIPS_F_FIPS_DRBG_HEALTH_CHECK, FIPS_R_UNINSTANTIATE_ERROR);
523 /* Instantiate with valid data. */
524 if (!do_drbg_instantiate(dctx, td, &t))
527 /* Check generation is now OK */
528 if (!FIPS_drbg_generate(dctx, randout, td->katlen, 0,
529 td->adin, td->adinlen))
532 dctx->iflags |= DRBG_FLAG_NOERR;
534 /* Request too much data for one request */
535 if (FIPS_drbg_generate(dctx, randout, dctx->max_request + 1, 0,
536 td->adin, td->adinlen))
538 FIPSerr(FIPS_F_FIPS_DRBG_HEALTH_CHECK, FIPS_R_REQUEST_LENGTH_ERROR_UNDETECTED);
542 /* Try too large additional input */
543 if (FIPS_drbg_generate(dctx, randout, td->katlen, 0,
544 td->adin, dctx->max_adin + 1))
546 FIPSerr(FIPS_F_FIPS_DRBG_HEALTH_CHECK, FIPS_R_ADDITIONAL_INPUT_ERROR_UNDETECTED);
550 /* Check prediction resistance request fails if entropy source
556 if (FIPS_drbg_generate(dctx, randout, td->katlen, 1,
557 td->adin, td->adinlen))
559 FIPSerr(FIPS_F_FIPS_DRBG_HEALTH_CHECK, FIPS_R_ENTROPY_ERROR_UNDETECTED);
563 dctx->iflags &= ~DRBG_FLAG_NOERR;
565 if (!FIPS_drbg_uninstantiate(dctx))
567 FIPSerr(FIPS_F_FIPS_DRBG_HEALTH_CHECK, FIPS_R_UNINSTANTIATE_ERROR);
572 /* Instantiate again with valid data */
574 if (!do_drbg_instantiate(dctx, td, &t))
576 /* Test reseed counter works */
577 /* Save initial reseed counter */
578 reseed_counter_tmp = dctx->reseed_counter;
579 /* Set reseed counter to beyond interval */
580 dctx->reseed_counter = dctx->reseed_interval;
582 /* Generate output and check entropy has been requested for reseed */
584 if (!FIPS_drbg_generate(dctx, randout, td->katlen, 0,
585 td->adin, td->adinlen))
589 FIPSerr(FIPS_F_FIPS_DRBG_HEALTH_CHECK, FIPS_R_ENTROPY_NOT_REQUESTED_FOR_RESEED);
592 /* Check reseed counter has been reset */
593 if (dctx->reseed_counter != reseed_counter_tmp + 1)
595 FIPSerr(FIPS_F_FIPS_DRBG_HEALTH_CHECK, FIPS_R_RESEED_COUNTER_ERROR);
599 /* Explicit reseed tests */
601 /* Test explicit reseed with too large additional input */
602 if (!do_drbg_init(dctx, td, &t))
605 dctx->iflags |= DRBG_FLAG_NOERR;
607 if (FIPS_drbg_reseed(dctx, td->adin, dctx->max_adin + 1) > 0)
609 FIPSerr(FIPS_F_FIPS_DRBG_HEALTH_CHECK, FIPS_R_ADDITIONAL_INPUT_ERROR_UNDETECTED);
613 /* Test explicit reseed with entropy source failure */
615 /* Check prediction resistance request fails if entropy source
621 if (FIPS_drbg_generate(dctx, randout, td->katlen, 1,
622 td->adin, td->adinlen))
624 FIPSerr(FIPS_F_FIPS_DRBG_HEALTH_CHECK, FIPS_R_ENTROPY_ERROR_UNDETECTED);
628 dctx->iflags &= ~DRBG_FLAG_NOERR;
630 if (!FIPS_drbg_uninstantiate(dctx))
632 FIPSerr(FIPS_F_FIPS_DRBG_HEALTH_CHECK, FIPS_R_UNINSTANTIATE_ERROR);
637 if (!do_drbg_instantiate(dctx, td, &t))
639 /* Test reseed counter works */
640 /* Save initial reseed counter */
641 reseed_counter_tmp = dctx->reseed_counter;
642 /* Set reseed counter to beyond interval */
643 dctx->reseed_counter = dctx->reseed_interval;
645 /* Generate output and check entropy has been requested for reseed */
647 if (!FIPS_drbg_generate(dctx, randout, td->katlen, 0,
648 td->adin, td->adinlen))
652 FIPSerr(FIPS_F_FIPS_DRBG_HEALTH_CHECK, FIPS_R_ENTROPY_NOT_REQUESTED_FOR_RESEED);
655 /* Check reseed counter has been reset */
656 if (dctx->reseed_counter != reseed_counter_tmp + 1)
658 FIPSerr(FIPS_F_FIPS_DRBG_HEALTH_CHECK, FIPS_R_RESEED_COUNTER_ERROR);
662 /* Explicit reseed tests */
664 /* Test explicit reseed with too large additional input */
665 if (!do_drbg_init(dctx, td, &t))
668 dctx->iflags |= DRBG_FLAG_NOERR;
670 if (FIPS_drbg_reseed(dctx, td->adin, dctx->max_adin + 1) > 0)
672 FIPSerr(FIPS_F_FIPS_DRBG_HEALTH_CHECK, FIPS_R_ADDITIONAL_INPUT_ERROR_UNDETECTED);
676 /* Test explicit reseed with entropy source failure */
678 if (!do_drbg_init(dctx, td, &t))
681 dctx->iflags |= DRBG_FLAG_NOERR;
685 if (FIPS_drbg_reseed(dctx, td->adin, td->adinlen) > 0)
687 FIPSerr(FIPS_F_FIPS_DRBG_HEALTH_CHECK, FIPS_R_ENTROPY_ERROR_UNDETECTED);
691 if (!FIPS_drbg_uninstantiate(dctx))
693 FIPSerr(FIPS_F_FIPS_DRBG_HEALTH_CHECK, FIPS_R_UNINSTANTIATE_ERROR);
697 /* Test explicit reseed with too much entropy */
699 if (!do_drbg_init(dctx, td, &t))
702 dctx->iflags |= DRBG_FLAG_NOERR;
704 t.entlen = dctx->max_entropy + 1;
706 if (FIPS_drbg_reseed(dctx, td->adin, td->adinlen) > 0)
708 FIPSerr(FIPS_F_FIPS_DRBG_HEALTH_CHECK, FIPS_R_ENTROPY_ERROR_UNDETECTED);
712 if (!FIPS_drbg_uninstantiate(dctx))
714 FIPSerr(FIPS_F_FIPS_DRBG_HEALTH_CHECK, FIPS_R_UNINSTANTIATE_ERROR);
718 /* Test explicit reseed with too little entropy */
720 if (!do_drbg_init(dctx, td, &t))
723 dctx->iflags |= DRBG_FLAG_NOERR;
725 t.entlen = dctx->min_entropy - 1;
727 if (FIPS_drbg_reseed(dctx, td->adin, td->adinlen) > 0)
729 FIPSerr(FIPS_F_FIPS_DRBG_HEALTH_CHECK, FIPS_R_ENTROPY_ERROR_UNDETECTED);
733 if (!FIPS_drbg_uninstantiate(dctx))
735 FIPSerr(FIPS_F_FIPS_DRBG_HEALTH_CHECK, FIPS_R_UNINSTANTIATE_ERROR);
739 p = (unsigned char *)&dctx->d;
740 /* Standard says we have to check uninstantiate really zeroes
743 for (i = 0; i < sizeof(dctx->d); i++)
747 FIPSerr(FIPS_F_FIPS_DRBG_HEALTH_CHECK, FIPS_R_UNINSTANTIATE_ZEROISE_ERROR);
756 /* A real error as opposed to an induced one: underlying function will
757 * indicate the error.
759 if (!(dctx->iflags & DRBG_FLAG_NOERR))
760 FIPSerr(FIPS_F_FIPS_DRBG_HEALTH_CHECK, FIPS_R_FUNCTION_ERROR);
761 FIPS_drbg_uninstantiate(dctx);
766 int fips_drbg_kat(DRBG_CTX *dctx, int nid, unsigned int flags)
769 DRBG_SELFTEST_DATA *td;
770 flags |= DRBG_FLAG_TEST;
771 for (td = drbg_test; td->nid != 0; td++)
773 if (td->nid == nid && td->flags == flags)
775 if (!fips_drbg_single_kat(dctx, td, 0))
777 return fips_drbg_health_check(dctx, td);
783 int FIPS_drbg_test(DRBG_CTX *dctx)
786 DRBG_CTX *tctx = NULL;
787 tctx = FIPS_drbg_new(0, 0);
788 fips_post_started(FIPS_TEST_DRBG, dctx->type, &dctx->xflags);
791 rv = fips_drbg_kat(tctx, dctx->type, dctx->xflags);
793 FIPS_drbg_free(tctx);
795 fips_post_success(FIPS_TEST_DRBG, dctx->type, &dctx->xflags);
797 fips_post_failed(FIPS_TEST_DRBG, dctx->type, &dctx->xflags);
801 int FIPS_selftest_drbg(void)
804 DRBG_SELFTEST_DATA *td;
806 dctx = FIPS_drbg_new(0, 0);
809 for (td = drbg_test; td->nid != 0; td++)
813 if (!fips_post_started(FIPS_TEST_DRBG, td->nid, &td->flags))
815 if (!fips_drbg_single_kat(dctx, td, 1))
817 fips_post_failed(FIPS_TEST_DRBG, td->nid, &td->flags);
821 if (!fips_post_success(FIPS_TEST_DRBG, td->nid, &td->flags))
824 FIPS_drbg_free(dctx);
829 int FIPS_selftest_drbg_all(void)
832 DRBG_SELFTEST_DATA *td;
834 dctx = FIPS_drbg_new(0, 0);
837 for (td = drbg_test; td->nid != 0; td++)
839 if (!fips_post_started(FIPS_TEST_DRBG, td->nid, &td->flags))
841 if (!fips_drbg_single_kat(dctx, td, 0))
843 fips_post_failed(FIPS_TEST_DRBG, td->nid, &td->flags);
847 if (!fips_drbg_health_check(dctx, td))
849 fips_post_failed(FIPS_TEST_DRBG, td->nid, &td->flags);
853 if (!fips_post_success(FIPS_TEST_DRBG, td->nid, &td->flags))
856 FIPS_drbg_free(dctx);