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 rv
= fips_drbg_single_kat(dctx
, td
, 0);
778 return fips_drbg_health_check(dctx
, td
);
784 int FIPS_drbg_test(DRBG_CTX
*dctx
)
787 DRBG_CTX
*tctx
= NULL
;
788 tctx
= FIPS_drbg_new(0, 0);
789 fips_post_started(FIPS_TEST_DRBG
, dctx
->type
, &dctx
->xflags
);
792 rv
= fips_drbg_kat(tctx
, dctx
->type
, dctx
->xflags
);
794 FIPS_drbg_free(tctx
);
796 fips_post_success(FIPS_TEST_DRBG
, dctx
->type
, &dctx
->xflags
);
798 fips_post_failed(FIPS_TEST_DRBG
, dctx
->type
, &dctx
->xflags
);
802 int FIPS_selftest_drbg(void)
805 DRBG_SELFTEST_DATA
*td
;
807 dctx
= FIPS_drbg_new(0, 0);
810 for (td
= drbg_test
; td
->nid
!= 0; td
++)
814 if (!fips_post_started(FIPS_TEST_DRBG
, td
->nid
, &td
->flags
))
816 if (!fips_drbg_single_kat(dctx
, td
, 1))
818 fips_post_failed(FIPS_TEST_DRBG
, td
->nid
, &td
->flags
);
822 if (!fips_post_success(FIPS_TEST_DRBG
, td
->nid
, &td
->flags
))
825 FIPS_drbg_free(dctx
);
830 int FIPS_selftest_drbg_all(void)
833 DRBG_SELFTEST_DATA
*td
;
835 dctx
= FIPS_drbg_new(0, 0);
838 for (td
= drbg_test
; td
->nid
!= 0; td
++)
840 if (!fips_post_started(FIPS_TEST_DRBG
, td
->nid
, &td
->flags
))
842 if (!fips_drbg_single_kat(dctx
, td
, 0))
844 fips_post_failed(FIPS_TEST_DRBG
, td
->nid
, &td
->flags
);
848 if (!fips_drbg_health_check(dctx
, td
))
850 fips_post_failed(FIPS_TEST_DRBG
, td
->nid
, &td
->flags
);
854 if (!fips_post_success(FIPS_TEST_DRBG
, td
->nid
, &td
->flags
))
857 FIPS_drbg_free(dctx
);