]>
Commit | Line | Data |
---|---|---|
12fb8c3d | 1 | /* |
33388b44 | 2 | * Copyright 2011-2020 The OpenSSL Project Authors. All Rights Reserved. |
12fb8c3d | 3 | * |
909f1a2e | 4 | * Licensed under the Apache License 2.0 (the "License"). You may not use |
12fb8c3d RS |
5 | * this file except in compliance with the License. You can obtain a copy |
6 | * in the file LICENSE in the source distribution or at | |
7 | * https://www.openssl.org/source/license.html | |
8 | */ | |
9 | ||
10 | #include <string.h> | |
176db6dc | 11 | #include "internal/nelem.h" |
12fb8c3d RS |
12 | #include <openssl/crypto.h> |
13 | #include <openssl/err.h> | |
14 | #include <openssl/rand.h> | |
15 | #include <openssl/obj_mac.h> | |
16 | #include <openssl/evp.h> | |
17 | #include <openssl/aes.h> | |
706457b7 | 18 | #include "../crypto/rand/rand_local.h" |
25f2138b | 19 | #include "../include/crypto/rand.h" |
12fb8c3d | 20 | |
440bce8f KR |
21 | #if defined(_WIN32) |
22 | # include <windows.h> | |
23 | #endif | |
24 | ||
84952925 DMSP |
25 | |
26 | #if defined(OPENSSL_SYS_UNIX) | |
27 | # include <sys/types.h> | |
28 | # include <sys/wait.h> | |
29 | # include <unistd.h> | |
30 | #endif | |
31 | ||
12fb8c3d RS |
32 | #include "testutil.h" |
33 | #include "drbgtest.h" | |
34 | ||
35 | typedef struct drbg_selftest_data_st { | |
36 | int post; | |
37 | int nid; | |
38 | unsigned int flags; | |
39 | ||
40 | /* KAT data for no PR */ | |
aa048aef DMSP |
41 | const unsigned char *entropy; |
42 | size_t entropylen; | |
12fb8c3d RS |
43 | const unsigned char *nonce; |
44 | size_t noncelen; | |
45 | const unsigned char *pers; | |
46 | size_t perslen; | |
47 | const unsigned char *adin; | |
48 | size_t adinlen; | |
aa048aef DMSP |
49 | const unsigned char *entropyreseed; |
50 | size_t entropyreseedlen; | |
12fb8c3d RS |
51 | const unsigned char *adinreseed; |
52 | size_t adinreseedlen; | |
53 | const unsigned char *adin2; | |
54 | size_t adin2len; | |
55 | const unsigned char *expected; | |
56 | size_t exlen; | |
57 | const unsigned char *kat2; | |
58 | size_t kat2len; | |
59 | ||
60 | /* KAT data for PR */ | |
aa048aef DMSP |
61 | const unsigned char *entropy_pr; |
62 | size_t entropylen_pr; | |
12fb8c3d RS |
63 | const unsigned char *nonce_pr; |
64 | size_t noncelen_pr; | |
65 | const unsigned char *pers_pr; | |
66 | size_t perslen_pr; | |
67 | const unsigned char *adin_pr; | |
68 | size_t adinlen_pr; | |
aa048aef DMSP |
69 | const unsigned char *entropypr_pr; |
70 | size_t entropyprlen_pr; | |
12fb8c3d RS |
71 | const unsigned char *ading_pr; |
72 | size_t adinglen_pr; | |
aa048aef DMSP |
73 | const unsigned char *entropyg_pr; |
74 | size_t entropyglen_pr; | |
12fb8c3d RS |
75 | const unsigned char *kat_pr; |
76 | size_t katlen_pr; | |
77 | const unsigned char *kat2_pr; | |
78 | size_t kat2len_pr; | |
79 | } DRBG_SELFTEST_DATA; | |
80 | ||
81 | #define make_drbg_test_data(nid, flag, pr, post) {\ | |
82 | post, nid, flag, \ | |
83 | pr##_entropyinput, sizeof(pr##_entropyinput), \ | |
84 | pr##_nonce, sizeof(pr##_nonce), \ | |
85 | pr##_personalizationstring, sizeof(pr##_personalizationstring), \ | |
86 | pr##_additionalinput, sizeof(pr##_additionalinput), \ | |
87 | pr##_entropyinputreseed, sizeof(pr##_entropyinputreseed), \ | |
88 | pr##_additionalinputreseed, sizeof(pr##_additionalinputreseed), \ | |
89 | pr##_additionalinput2, sizeof(pr##_additionalinput2), \ | |
90 | pr##_int_returnedbits, sizeof(pr##_int_returnedbits), \ | |
91 | pr##_returnedbits, sizeof(pr##_returnedbits), \ | |
92 | pr##_pr_entropyinput, sizeof(pr##_pr_entropyinput), \ | |
93 | pr##_pr_nonce, sizeof(pr##_pr_nonce), \ | |
94 | pr##_pr_personalizationstring, sizeof(pr##_pr_personalizationstring), \ | |
95 | pr##_pr_additionalinput, sizeof(pr##_pr_additionalinput), \ | |
96 | pr##_pr_entropyinputpr, sizeof(pr##_pr_entropyinputpr), \ | |
97 | pr##_pr_additionalinput2, sizeof(pr##_pr_additionalinput2), \ | |
98 | pr##_pr_entropyinputpr2, sizeof(pr##_pr_entropyinputpr2), \ | |
99 | pr##_pr_int_returnedbits, sizeof(pr##_pr_int_returnedbits), \ | |
100 | pr##_pr_returnedbits, sizeof(pr##_pr_returnedbits) \ | |
101 | } | |
102 | ||
8164d91d DMSP |
103 | #define make_drbg_test_data_use_df(nid, pr, p) \ |
104 | make_drbg_test_data(nid, 0, pr, p) | |
105 | ||
106 | #define make_drbg_test_data_no_df(nid, pr, p) \ | |
107 | make_drbg_test_data(nid, RAND_DRBG_FLAG_CTR_NO_DF, pr, p) | |
12fb8c3d | 108 | |
8bf36651 SL |
109 | #define make_drbg_test_data_hash(nid, pr, p) \ |
110 | make_drbg_test_data(nid, RAND_DRBG_FLAG_HMAC, hmac_##pr, p), \ | |
111 | make_drbg_test_data(nid, 0, pr, p) | |
112 | ||
12fb8c3d | 113 | static DRBG_SELFTEST_DATA drbg_test[] = { |
f844f9eb | 114 | #ifndef FIPS_MODULE |
6c7d80ab | 115 | /* FIPS mode doesn't support CTR DRBG without a derivation function */ |
8164d91d DMSP |
116 | make_drbg_test_data_no_df (NID_aes_128_ctr, aes_128_no_df, 0), |
117 | make_drbg_test_data_no_df (NID_aes_192_ctr, aes_192_no_df, 0), | |
118 | make_drbg_test_data_no_df (NID_aes_256_ctr, aes_256_no_df, 1), | |
6c7d80ab | 119 | #endif |
8164d91d DMSP |
120 | make_drbg_test_data_use_df(NID_aes_128_ctr, aes_128_use_df, 0), |
121 | make_drbg_test_data_use_df(NID_aes_192_ctr, aes_192_use_df, 0), | |
122 | make_drbg_test_data_use_df(NID_aes_256_ctr, aes_256_use_df, 1), | |
8bf36651 SL |
123 | make_drbg_test_data_hash(NID_sha1, sha1, 0), |
124 | make_drbg_test_data_hash(NID_sha224, sha224, 0), | |
125 | make_drbg_test_data_hash(NID_sha256, sha256, 1), | |
126 | make_drbg_test_data_hash(NID_sha384, sha384, 0), | |
127 | make_drbg_test_data_hash(NID_sha512, sha512, 0), | |
12fb8c3d RS |
128 | }; |
129 | ||
12fb8c3d | 130 | /* |
75e2c877 | 131 | * Test context data, attached as EXDATA to the RAND_DRBG |
12fb8c3d RS |
132 | */ |
133 | typedef struct test_ctx_st { | |
aa048aef DMSP |
134 | const unsigned char *entropy; |
135 | size_t entropylen; | |
136 | int entropycnt; | |
12fb8c3d RS |
137 | const unsigned char *nonce; |
138 | size_t noncelen; | |
139 | int noncecnt; | |
140 | } TEST_CTX; | |
141 | ||
75e2c877 | 142 | static size_t kat_entropy(RAND_DRBG *drbg, unsigned char **pout, |
eb238134 KR |
143 | int entropy, size_t min_len, size_t max_len, |
144 | int prediction_resistance) | |
12fb8c3d | 145 | { |
09066cf2 | 146 | TEST_CTX *t = (TEST_CTX *)RAND_DRBG_get_callback_data(drbg); |
12fb8c3d | 147 | |
aa048aef DMSP |
148 | t->entropycnt++; |
149 | *pout = (unsigned char *)t->entropy; | |
150 | return t->entropylen; | |
12fb8c3d RS |
151 | } |
152 | ||
75e2c877 | 153 | static size_t kat_nonce(RAND_DRBG *drbg, unsigned char **pout, |
12fb8c3d RS |
154 | int entropy, size_t min_len, size_t max_len) |
155 | { | |
09066cf2 | 156 | TEST_CTX *t = (TEST_CTX *)RAND_DRBG_get_callback_data(drbg); |
12fb8c3d RS |
157 | |
158 | t->noncecnt++; | |
159 | *pout = (unsigned char *)t->nonce; | |
160 | return t->noncelen; | |
161 | } | |
162 | ||
d69226a3 P |
163 | /* |
164 | * Disable CRNG testing if it is enabled. | |
165 | * If the DRBG is ready or in an error state, this means an instantiate cycle | |
166 | * for which the default personalisation string is used. | |
167 | */ | |
168 | static int disable_crngt(RAND_DRBG *drbg) | |
169 | { | |
170 | static const char pers[] = DRBG_DEFAULT_PERS_STRING; | |
171 | const int instantiate = drbg->state != DRBG_UNINITIALISED; | |
172 | ||
173 | if (drbg->get_entropy != rand_crngt_get_entropy) | |
174 | return 1; | |
175 | ||
176 | if ((instantiate && !RAND_DRBG_uninstantiate(drbg)) | |
177 | || !TEST_true(RAND_DRBG_set_callbacks(drbg, &rand_drbg_get_entropy, | |
178 | &rand_drbg_cleanup_entropy, | |
179 | &rand_drbg_get_nonce, | |
180 | &rand_drbg_cleanup_nonce)) | |
181 | || (instantiate | |
182 | && !RAND_DRBG_instantiate(drbg, (const unsigned char *)pers, | |
183 | sizeof(pers) - 1))) | |
184 | return 0; | |
185 | return 1; | |
186 | } | |
187 | ||
75e2c877 | 188 | static int uninstantiate(RAND_DRBG *drbg) |
12fb8c3d | 189 | { |
75e2c877 | 190 | int ret = drbg == NULL ? 1 : RAND_DRBG_uninstantiate(drbg); |
12fb8c3d RS |
191 | |
192 | ERR_clear_error(); | |
193 | return ret; | |
194 | } | |
195 | ||
196 | /* | |
197 | * Do a single KAT test. Return 0 on failure. | |
198 | */ | |
199 | static int single_kat(DRBG_SELFTEST_DATA *td) | |
200 | { | |
75e2c877 | 201 | RAND_DRBG *drbg = NULL; |
12fb8c3d RS |
202 | TEST_CTX t; |
203 | int failures = 0; | |
204 | unsigned char buff[1024]; | |
205 | ||
206 | /* | |
207 | * Test without PR: Instantiate DRBG with test entropy, nonce and | |
208 | * personalisation string. | |
209 | */ | |
75e2c877 | 210 | if (!TEST_ptr(drbg = RAND_DRBG_new(td->nid, td->flags, NULL))) |
12fb8c3d | 211 | return 0; |
75e2c877 | 212 | if (!TEST_true(RAND_DRBG_set_callbacks(drbg, kat_entropy, NULL, |
d69226a3 | 213 | kat_nonce, NULL)) |
09066cf2 | 214 | || !TEST_true(RAND_DRBG_set_callback_data(drbg, &t)) |
d69226a3 | 215 | || !TEST_true(disable_crngt(drbg))) { |
12fb8c3d RS |
216 | failures++; |
217 | goto err; | |
218 | } | |
219 | memset(&t, 0, sizeof(t)); | |
aa048aef DMSP |
220 | t.entropy = td->entropy; |
221 | t.entropylen = td->entropylen; | |
12fb8c3d RS |
222 | t.nonce = td->nonce; |
223 | t.noncelen = td->noncelen; | |
12fb8c3d | 224 | |
75e2c877 RS |
225 | if (!TEST_true(RAND_DRBG_instantiate(drbg, td->pers, td->perslen)) |
226 | || !TEST_true(RAND_DRBG_generate(drbg, buff, td->exlen, 0, | |
12fb8c3d RS |
227 | td->adin, td->adinlen)) |
228 | || !TEST_mem_eq(td->expected, td->exlen, buff, td->exlen)) | |
229 | failures++; | |
230 | ||
231 | /* Reseed DRBG with test entropy and additional input */ | |
aa048aef DMSP |
232 | t.entropy = td->entropyreseed; |
233 | t.entropylen = td->entropyreseedlen; | |
eb238134 | 234 | if (!TEST_true(RAND_DRBG_reseed(drbg, td->adinreseed, td->adinreseedlen, 0) |
75e2c877 | 235 | || !TEST_true(RAND_DRBG_generate(drbg, buff, td->kat2len, 0, |
12fb8c3d RS |
236 | td->adin2, td->adin2len)) |
237 | || !TEST_mem_eq(td->kat2, td->kat2len, buff, td->kat2len))) | |
238 | failures++; | |
75e2c877 | 239 | uninstantiate(drbg); |
12fb8c3d RS |
240 | |
241 | /* | |
242 | * Now test with PR: Instantiate DRBG with test entropy, nonce and | |
243 | * personalisation string. | |
244 | */ | |
75e2c877 RS |
245 | if (!TEST_true(RAND_DRBG_set(drbg, td->nid, td->flags)) |
246 | || !TEST_true(RAND_DRBG_set_callbacks(drbg, kat_entropy, NULL, | |
09066cf2 DMSP |
247 | kat_nonce, NULL)) |
248 | || !TEST_true(RAND_DRBG_set_callback_data(drbg, &t))) | |
12fb8c3d | 249 | failures++; |
aa048aef DMSP |
250 | t.entropy = td->entropy_pr; |
251 | t.entropylen = td->entropylen_pr; | |
12fb8c3d RS |
252 | t.nonce = td->nonce_pr; |
253 | t.noncelen = td->noncelen_pr; | |
aa048aef | 254 | t.entropycnt = 0; |
12fb8c3d | 255 | t.noncecnt = 0; |
75e2c877 | 256 | if (!TEST_true(RAND_DRBG_instantiate(drbg, td->pers_pr, td->perslen_pr))) |
12fb8c3d RS |
257 | failures++; |
258 | ||
259 | /* | |
260 | * Now generate with PR: we need to supply entropy as this will | |
261 | * perform a reseed operation. | |
262 | */ | |
aa048aef DMSP |
263 | t.entropy = td->entropypr_pr; |
264 | t.entropylen = td->entropyprlen_pr; | |
75e2c877 | 265 | if (!TEST_true(RAND_DRBG_generate(drbg, buff, td->katlen_pr, 1, |
12fb8c3d RS |
266 | td->adin_pr, td->adinlen_pr)) |
267 | || !TEST_mem_eq(td->kat_pr, td->katlen_pr, buff, td->katlen_pr)) | |
268 | failures++; | |
269 | ||
270 | /* | |
271 | * Now generate again with PR: supply new entropy again. | |
272 | */ | |
aa048aef DMSP |
273 | t.entropy = td->entropyg_pr; |
274 | t.entropylen = td->entropyglen_pr; | |
12fb8c3d | 275 | |
75e2c877 | 276 | if (!TEST_true(RAND_DRBG_generate(drbg, buff, td->kat2len_pr, 1, |
12fb8c3d RS |
277 | td->ading_pr, td->adinglen_pr)) |
278 | || !TEST_mem_eq(td->kat2_pr, td->kat2len_pr, | |
279 | buff, td->kat2len_pr)) | |
280 | failures++; | |
281 | ||
282 | err: | |
75e2c877 RS |
283 | uninstantiate(drbg); |
284 | RAND_DRBG_free(drbg); | |
12fb8c3d RS |
285 | return failures == 0; |
286 | } | |
287 | ||
288 | /* | |
289 | * Initialise a DRBG based on selftest data | |
290 | */ | |
75e2c877 | 291 | static int init(RAND_DRBG *drbg, DRBG_SELFTEST_DATA *td, TEST_CTX *t) |
12fb8c3d | 292 | { |
75e2c877 RS |
293 | if (!TEST_true(RAND_DRBG_set(drbg, td->nid, td->flags)) |
294 | || !TEST_true(RAND_DRBG_set_callbacks(drbg, kat_entropy, NULL, | |
12fb8c3d RS |
295 | kat_nonce, NULL))) |
296 | return 0; | |
09066cf2 | 297 | RAND_DRBG_set_callback_data(drbg, t); |
aa048aef DMSP |
298 | t->entropy = td->entropy; |
299 | t->entropylen = td->entropylen; | |
12fb8c3d RS |
300 | t->nonce = td->nonce; |
301 | t->noncelen = td->noncelen; | |
aa048aef | 302 | t->entropycnt = 0; |
12fb8c3d RS |
303 | t->noncecnt = 0; |
304 | return 1; | |
305 | } | |
306 | ||
307 | /* | |
308 | * Initialise and instantiate DRBG based on selftest data | |
309 | */ | |
75e2c877 | 310 | static int instantiate(RAND_DRBG *drbg, DRBG_SELFTEST_DATA *td, |
12fb8c3d RS |
311 | TEST_CTX *t) |
312 | { | |
75e2c877 RS |
313 | if (!TEST_true(init(drbg, td, t)) |
314 | || !TEST_true(RAND_DRBG_instantiate(drbg, td->pers, td->perslen))) | |
12fb8c3d RS |
315 | return 0; |
316 | return 1; | |
317 | } | |
318 | ||
319 | /* | |
320 | * Perform extensive error checking as required by SP800-90. | |
321 | * Induce several failure modes and check an error condition is set. | |
322 | */ | |
323 | static int error_check(DRBG_SELFTEST_DATA *td) | |
324 | { | |
75e2c877 RS |
325 | static char zero[sizeof(RAND_DRBG)]; |
326 | RAND_DRBG *drbg = NULL; | |
12fb8c3d RS |
327 | TEST_CTX t; |
328 | unsigned char buff[1024]; | |
8bf36651 | 329 | unsigned int reseed_counter_tmp; |
12fb8c3d RS |
330 | int ret = 0; |
331 | ||
d69226a3 P |
332 | if (!TEST_ptr(drbg = RAND_DRBG_new(td->nid, td->flags, NULL)) |
333 | || !TEST_true(disable_crngt(drbg))) | |
12fb8c3d RS |
334 | goto err; |
335 | ||
336 | /* | |
337 | * Personalisation string tests | |
338 | */ | |
339 | ||
c2969ff6 | 340 | /* Test detection of too large personalisation string */ |
75e2c877 | 341 | if (!init(drbg, td, &t) |
aa048aef | 342 | || RAND_DRBG_instantiate(drbg, td->pers, drbg->max_perslen + 1) > 0) |
12fb8c3d RS |
343 | goto err; |
344 | ||
345 | /* | |
346 | * Entropy source tests | |
347 | */ | |
348 | ||
8bf36651 | 349 | /* Test entropy source failure detection: i.e. returns no data */ |
aa048aef | 350 | t.entropylen = 0; |
75e2c877 | 351 | if (TEST_int_le(RAND_DRBG_instantiate(drbg, td->pers, td->perslen), 0)) |
12fb8c3d RS |
352 | goto err; |
353 | ||
354 | /* Try to generate output from uninstantiated DRBG */ | |
75e2c877 | 355 | if (!TEST_false(RAND_DRBG_generate(drbg, buff, td->exlen, 0, |
12fb8c3d | 356 | td->adin, td->adinlen)) |
75e2c877 | 357 | || !uninstantiate(drbg)) |
12fb8c3d RS |
358 | goto err; |
359 | ||
360 | /* Test insufficient entropy */ | |
aa048aef | 361 | t.entropylen = drbg->min_entropylen - 1; |
75e2c877 RS |
362 | if (!init(drbg, td, &t) |
363 | || RAND_DRBG_instantiate(drbg, td->pers, td->perslen) > 0 | |
364 | || !uninstantiate(drbg)) | |
12fb8c3d RS |
365 | goto err; |
366 | ||
367 | /* Test too much entropy */ | |
aa048aef | 368 | t.entropylen = drbg->max_entropylen + 1; |
75e2c877 RS |
369 | if (!init(drbg, td, &t) |
370 | || RAND_DRBG_instantiate(drbg, td->pers, td->perslen) > 0 | |
371 | || !uninstantiate(drbg)) | |
12fb8c3d RS |
372 | goto err; |
373 | ||
374 | /* | |
375 | * Nonce tests | |
376 | */ | |
377 | ||
378 | /* Test too small nonce */ | |
aa048aef DMSP |
379 | if (drbg->min_noncelen) { |
380 | t.noncelen = drbg->min_noncelen - 1; | |
75e2c877 RS |
381 | if (!init(drbg, td, &t) |
382 | || RAND_DRBG_instantiate(drbg, td->pers, td->perslen) > 0 | |
383 | || !uninstantiate(drbg)) | |
12fb8c3d RS |
384 | goto err; |
385 | } | |
386 | ||
387 | /* Test too large nonce */ | |
aa048aef DMSP |
388 | if (drbg->max_noncelen) { |
389 | t.noncelen = drbg->max_noncelen + 1; | |
75e2c877 RS |
390 | if (!init(drbg, td, &t) |
391 | || RAND_DRBG_instantiate(drbg, td->pers, td->perslen) > 0 | |
392 | || !uninstantiate(drbg)) | |
12fb8c3d RS |
393 | goto err; |
394 | } | |
395 | ||
396 | /* Instantiate with valid data, Check generation is now OK */ | |
75e2c877 RS |
397 | if (!instantiate(drbg, td, &t) |
398 | || !TEST_true(RAND_DRBG_generate(drbg, buff, td->exlen, 0, | |
12fb8c3d RS |
399 | td->adin, td->adinlen))) |
400 | goto err; | |
401 | ||
402 | /* Request too much data for one request */ | |
75e2c877 | 403 | if (!TEST_false(RAND_DRBG_generate(drbg, buff, drbg->max_request + 1, 0, |
12fb8c3d RS |
404 | td->adin, td->adinlen))) |
405 | goto err; | |
406 | ||
407 | /* Try too large additional input */ | |
75e2c877 | 408 | if (!TEST_false(RAND_DRBG_generate(drbg, buff, td->exlen, 0, |
aa048aef | 409 | td->adin, drbg->max_adinlen + 1))) |
12fb8c3d RS |
410 | goto err; |
411 | ||
412 | /* | |
413 | * Check prediction resistance request fails if entropy source | |
414 | * failure. | |
415 | */ | |
aa048aef | 416 | t.entropylen = 0; |
75e2c877 | 417 | if (TEST_false(RAND_DRBG_generate(drbg, buff, td->exlen, 1, |
12fb8c3d | 418 | td->adin, td->adinlen)) |
75e2c877 | 419 | || !uninstantiate(drbg)) |
12fb8c3d RS |
420 | goto err; |
421 | ||
4468b6ed | 422 | /* Instantiate again with valid data */ |
75e2c877 | 423 | if (!instantiate(drbg, td, &t)) |
12fb8c3d | 424 | goto err; |
8bf36651 SL |
425 | reseed_counter_tmp = drbg->reseed_gen_counter; |
426 | drbg->reseed_gen_counter = drbg->reseed_interval; | |
12fb8c3d RS |
427 | |
428 | /* Generate output and check entropy has been requested for reseed */ | |
aa048aef | 429 | t.entropycnt = 0; |
75e2c877 | 430 | if (!TEST_true(RAND_DRBG_generate(drbg, buff, td->exlen, 0, |
12fb8c3d | 431 | td->adin, td->adinlen)) |
aa048aef | 432 | || !TEST_int_eq(t.entropycnt, 1) |
8bf36651 | 433 | || !TEST_int_eq(drbg->reseed_gen_counter, reseed_counter_tmp + 1) |
75e2c877 | 434 | || !uninstantiate(drbg)) |
12fb8c3d RS |
435 | goto err; |
436 | ||
437 | /* | |
438 | * Check prediction resistance request fails if entropy source | |
439 | * failure. | |
440 | */ | |
aa048aef | 441 | t.entropylen = 0; |
75e2c877 | 442 | if (!TEST_false(RAND_DRBG_generate(drbg, buff, td->exlen, 1, |
12fb8c3d | 443 | td->adin, td->adinlen)) |
75e2c877 | 444 | || !uninstantiate(drbg)) |
12fb8c3d RS |
445 | goto err; |
446 | ||
447 | /* Test reseed counter works */ | |
75e2c877 | 448 | if (!instantiate(drbg, td, &t)) |
12fb8c3d | 449 | goto err; |
8bf36651 SL |
450 | reseed_counter_tmp = drbg->reseed_gen_counter; |
451 | drbg->reseed_gen_counter = drbg->reseed_interval; | |
12fb8c3d RS |
452 | |
453 | /* Generate output and check entropy has been requested for reseed */ | |
aa048aef | 454 | t.entropycnt = 0; |
75e2c877 | 455 | if (!TEST_true(RAND_DRBG_generate(drbg, buff, td->exlen, 0, |
12fb8c3d | 456 | td->adin, td->adinlen)) |
aa048aef | 457 | || !TEST_int_eq(t.entropycnt, 1) |
8bf36651 | 458 | || !TEST_int_eq(drbg->reseed_gen_counter, reseed_counter_tmp + 1) |
75e2c877 | 459 | || !uninstantiate(drbg)) |
12fb8c3d RS |
460 | goto err; |
461 | ||
462 | /* | |
463 | * Explicit reseed tests | |
464 | */ | |
465 | ||
466 | /* Test explicit reseed with too large additional input */ | |
b1522fa5 | 467 | if (!instantiate(drbg, td, &t) |
eb238134 | 468 | || RAND_DRBG_reseed(drbg, td->adin, drbg->max_adinlen + 1, 0) > 0) |
12fb8c3d RS |
469 | goto err; |
470 | ||
471 | /* Test explicit reseed with entropy source failure */ | |
aa048aef | 472 | t.entropylen = 0; |
eb238134 | 473 | if (!TEST_int_le(RAND_DRBG_reseed(drbg, td->adin, td->adinlen, 0), 0) |
75e2c877 | 474 | || !uninstantiate(drbg)) |
12fb8c3d RS |
475 | goto err; |
476 | ||
477 | /* Test explicit reseed with too much entropy */ | |
b1522fa5 | 478 | if (!instantiate(drbg, td, &t)) |
12fb8c3d | 479 | goto err; |
aa048aef | 480 | t.entropylen = drbg->max_entropylen + 1; |
eb238134 | 481 | if (!TEST_int_le(RAND_DRBG_reseed(drbg, td->adin, td->adinlen, 0), 0) |
75e2c877 | 482 | || !uninstantiate(drbg)) |
12fb8c3d RS |
483 | goto err; |
484 | ||
485 | /* Test explicit reseed with too little entropy */ | |
b1522fa5 | 486 | if (!instantiate(drbg, td, &t)) |
12fb8c3d | 487 | goto err; |
aa048aef | 488 | t.entropylen = drbg->min_entropylen - 1; |
eb238134 | 489 | if (!TEST_int_le(RAND_DRBG_reseed(drbg, td->adin, td->adinlen, 0), 0) |
75e2c877 | 490 | || !uninstantiate(drbg)) |
12fb8c3d RS |
491 | goto err; |
492 | ||
493 | /* Standard says we have to check uninstantiate really zeroes */ | |
8212d505 | 494 | if (!TEST_mem_eq(zero, sizeof(drbg->data), &drbg->data, sizeof(drbg->data))) |
12fb8c3d RS |
495 | goto err; |
496 | ||
497 | ret = 1; | |
498 | ||
499 | err: | |
75e2c877 RS |
500 | uninstantiate(drbg); |
501 | RAND_DRBG_free(drbg); | |
12fb8c3d RS |
502 | return ret; |
503 | } | |
504 | ||
505 | static int test_kats(int i) | |
506 | { | |
507 | DRBG_SELFTEST_DATA *td = &drbg_test[i]; | |
508 | int rv = 0; | |
509 | ||
510 | if (!single_kat(td)) | |
511 | goto err; | |
512 | rv = 1; | |
513 | ||
514 | err: | |
515 | return rv; | |
516 | } | |
517 | ||
518 | static int test_error_checks(int i) | |
519 | { | |
520 | DRBG_SELFTEST_DATA *td = &drbg_test[i]; | |
521 | int rv = 0; | |
522 | ||
523 | if (error_check(td)) | |
524 | goto err; | |
525 | rv = 1; | |
526 | ||
527 | err: | |
528 | return rv; | |
529 | } | |
530 | ||
a93ba405 DMSP |
531 | /* |
532 | * Hook context data, attached as EXDATA to the RAND_DRBG | |
533 | */ | |
534 | typedef struct hook_ctx_st { | |
535 | RAND_DRBG *drbg; | |
536 | /* | |
537 | * Currently, all DRBGs use the same get_entropy() callback. | |
538 | * The tests however, don't assume this and store | |
539 | * the original callback for every DRBG separately. | |
540 | */ | |
541 | RAND_DRBG_get_entropy_fn get_entropy; | |
542 | /* forces a failure of the get_entropy() call if nonzero */ | |
543 | int fail; | |
544 | /* counts successful reseeds */ | |
545 | int reseed_count; | |
546 | } HOOK_CTX; | |
547 | ||
548 | static HOOK_CTX master_ctx, public_ctx, private_ctx; | |
549 | ||
550 | static HOOK_CTX *get_hook_ctx(RAND_DRBG *drbg) | |
551 | { | |
09066cf2 | 552 | return (HOOK_CTX *)RAND_DRBG_get_callback_data(drbg); |
a93ba405 DMSP |
553 | } |
554 | ||
555 | /* Intercepts and counts calls to the get_entropy() callback */ | |
556 | static size_t get_entropy_hook(RAND_DRBG *drbg, unsigned char **pout, | |
eb238134 KR |
557 | int entropy, size_t min_len, size_t max_len, |
558 | int prediction_resistance) | |
a93ba405 DMSP |
559 | { |
560 | size_t ret; | |
561 | HOOK_CTX *ctx = get_hook_ctx(drbg); | |
562 | ||
563 | if (ctx->fail != 0) | |
564 | return 0; | |
565 | ||
eb238134 KR |
566 | ret = ctx->get_entropy(drbg, pout, entropy, min_len, max_len, |
567 | prediction_resistance); | |
a93ba405 DMSP |
568 | |
569 | if (ret != 0) | |
570 | ctx->reseed_count++; | |
571 | return ret; | |
572 | } | |
573 | ||
574 | /* Installs a hook for the get_entropy() callback of the given drbg */ | |
575 | static void hook_drbg(RAND_DRBG *drbg, HOOK_CTX *ctx) | |
576 | { | |
577 | memset(ctx, 0, sizeof(*ctx)); | |
578 | ctx->drbg = drbg; | |
579 | ctx->get_entropy = drbg->get_entropy; | |
09066cf2 DMSP |
580 | |
581 | /* | |
582 | * We can't use the public API here, since it prohibits modifying | |
583 | * the callbacks or the callback data of chained DRBGs. | |
584 | */ | |
a93ba405 | 585 | drbg->get_entropy = get_entropy_hook; |
09066cf2 | 586 | drbg->callback_data = ctx; |
a93ba405 DMSP |
587 | } |
588 | ||
589 | /* Installs the hook for the get_entropy() callback of the given drbg */ | |
590 | static void unhook_drbg(RAND_DRBG *drbg) | |
591 | { | |
09066cf2 | 592 | HOOK_CTX *ctx = drbg->callback_data; |
a93ba405 | 593 | |
09066cf2 DMSP |
594 | if (ctx != NULL) |
595 | drbg->get_entropy = ctx->get_entropy; | |
a93ba405 | 596 | } |
75e2c877 | 597 | |
a93ba405 DMSP |
598 | /* Resets the given hook context */ |
599 | static void reset_hook_ctx(HOOK_CTX *ctx) | |
75e2c877 | 600 | { |
a93ba405 DMSP |
601 | ctx->fail = 0; |
602 | ctx->reseed_count = 0; | |
603 | } | |
604 | ||
605 | /* Resets all drbg hook contexts */ | |
3cb7c5cf | 606 | static void reset_drbg_hook_ctx(void) |
a93ba405 DMSP |
607 | { |
608 | reset_hook_ctx(&master_ctx); | |
609 | reset_hook_ctx(&public_ctx); | |
610 | reset_hook_ctx(&private_ctx); | |
611 | } | |
612 | ||
613 | /* | |
614 | * Generates random output using RAND_bytes() and RAND_priv_bytes() | |
615 | * and checks whether the three shared DRBGs were reseeded as | |
616 | * expected. | |
617 | * | |
618 | * |expect_success|: expected outcome (as reported by RAND_status()) | |
619 | * |master|, |public|, |private|: pointers to the three shared DRBGs | |
620 | * |expect_xxx_reseed| = | |
621 | * 1: it is expected that the specified DRBG is reseeded | |
622 | * 0: it is expected that the specified DRBG is not reseeded | |
623 | * -1: don't check whether the specified DRBG was reseeded or not | |
2bb1b5dd BE |
624 | * |reseed_time|: if nonzero, used instead of time(NULL) to set the |
625 | * |before_reseed| time. | |
a93ba405 DMSP |
626 | */ |
627 | static int test_drbg_reseed(int expect_success, | |
628 | RAND_DRBG *master, | |
629 | RAND_DRBG *public, | |
630 | RAND_DRBG *private, | |
631 | int expect_master_reseed, | |
632 | int expect_public_reseed, | |
2bb1b5dd BE |
633 | int expect_private_reseed, |
634 | time_t reseed_time | |
a93ba405 DMSP |
635 | ) |
636 | { | |
637 | unsigned char buf[32]; | |
08a65d96 | 638 | time_t before_reseed, after_reseed; |
a93ba405 DMSP |
639 | int expected_state = (expect_success ? DRBG_READY : DRBG_ERROR); |
640 | ||
641 | /* | |
642 | * step 1: check preconditions | |
643 | */ | |
644 | ||
645 | /* Test whether seed propagation is enabled */ | |
8bf36651 SL |
646 | if (!TEST_int_ne(master->reseed_prop_counter, 0) |
647 | || !TEST_int_ne(public->reseed_prop_counter, 0) | |
648 | || !TEST_int_ne(private->reseed_prop_counter, 0)) | |
a93ba405 DMSP |
649 | return 0; |
650 | ||
651 | /* Check whether the master DRBG's reseed counter is the largest one */ | |
8bf36651 SL |
652 | if (!TEST_int_le(public->reseed_prop_counter, master->reseed_prop_counter) |
653 | || !TEST_int_le(private->reseed_prop_counter, master->reseed_prop_counter)) | |
a93ba405 DMSP |
654 | return 0; |
655 | ||
656 | /* | |
657 | * step 2: generate random output | |
658 | */ | |
659 | ||
2bb1b5dd BE |
660 | if (reseed_time == 0) |
661 | reseed_time = time(NULL); | |
662 | ||
a93ba405 | 663 | /* Generate random output from the public and private DRBG */ |
2bb1b5dd | 664 | before_reseed = expect_master_reseed == 1 ? reseed_time : 0; |
a93ba405 DMSP |
665 | if (!TEST_int_eq(RAND_bytes(buf, sizeof(buf)), expect_success) |
666 | || !TEST_int_eq(RAND_priv_bytes(buf, sizeof(buf)), expect_success)) | |
667 | return 0; | |
08a65d96 | 668 | after_reseed = time(NULL); |
a93ba405 DMSP |
669 | |
670 | ||
671 | /* | |
672 | * step 3: check postconditions | |
673 | */ | |
75e2c877 | 674 | |
a93ba405 DMSP |
675 | /* Test whether reseeding succeeded as expected */ |
676 | if (!TEST_int_eq(master->state, expected_state) | |
677 | || !TEST_int_eq(public->state, expected_state) | |
678 | || !TEST_int_eq(private->state, expected_state)) | |
75e2c877 | 679 | return 0; |
a93ba405 DMSP |
680 | |
681 | if (expect_master_reseed >= 0) { | |
682 | /* Test whether master DRBG was reseeded as expected */ | |
683 | if (!TEST_int_eq(master_ctx.reseed_count, expect_master_reseed)) | |
684 | return 0; | |
685 | } | |
686 | ||
687 | if (expect_public_reseed >= 0) { | |
688 | /* Test whether public DRBG was reseeded as expected */ | |
689 | if (!TEST_int_eq(public_ctx.reseed_count, expect_public_reseed)) | |
690 | return 0; | |
691 | } | |
692 | ||
693 | if (expect_private_reseed >= 0) { | |
694 | /* Test whether public DRBG was reseeded as expected */ | |
695 | if (!TEST_int_eq(private_ctx.reseed_count, expect_private_reseed)) | |
696 | return 0; | |
697 | } | |
698 | ||
699 | if (expect_success == 1) { | |
700 | /* Test whether all three reseed counters are synchronized */ | |
8bf36651 SL |
701 | if (!TEST_int_eq(public->reseed_prop_counter, master->reseed_prop_counter) |
702 | || !TEST_int_eq(private->reseed_prop_counter, master->reseed_prop_counter)) | |
a93ba405 | 703 | return 0; |
08a65d96 DMSP |
704 | |
705 | /* Test whether reseed time of master DRBG is set correctly */ | |
706 | if (!TEST_time_t_le(before_reseed, master->reseed_time) | |
707 | || !TEST_time_t_le(master->reseed_time, after_reseed)) | |
708 | return 0; | |
709 | ||
710 | /* Test whether reseed times of child DRBGs are synchronized with master */ | |
711 | if (!TEST_time_t_ge(public->reseed_time, master->reseed_time) | |
712 | || !TEST_time_t_ge(private->reseed_time, master->reseed_time)) | |
713 | return 0; | |
a93ba405 DMSP |
714 | } else { |
715 | ERR_clear_error(); | |
716 | } | |
717 | ||
75e2c877 RS |
718 | return 1; |
719 | } | |
720 | ||
84952925 DMSP |
721 | |
722 | #if defined(OPENSSL_SYS_UNIX) | |
723 | /* | |
724 | * Test whether master, public and private DRBG are reseeded after | |
725 | * forking the process. | |
726 | */ | |
727 | static int test_drbg_reseed_after_fork(RAND_DRBG *master, | |
728 | RAND_DRBG *public, | |
729 | RAND_DRBG *private) | |
730 | { | |
731 | pid_t pid; | |
732 | int status=0; | |
733 | ||
734 | pid = fork(); | |
735 | if (!TEST_int_ge(pid, 0)) | |
736 | return 0; | |
737 | ||
738 | if (pid > 0) { | |
739 | /* I'm the parent; wait for the child and check its exit code */ | |
740 | return TEST_int_eq(waitpid(pid, &status, 0), pid) && TEST_int_eq(status, 0); | |
741 | } | |
742 | ||
743 | /* I'm the child; check whether all three DRBGs reseed. */ | |
744 | if (!TEST_true(test_drbg_reseed(1, master, public, private, 1, 1, 1, 0))) | |
745 | status = 1; | |
746 | ||
747 | /* Remove hooks */ | |
748 | unhook_drbg(master); | |
749 | unhook_drbg(public); | |
750 | unhook_drbg(private); | |
751 | exit(status); | |
752 | } | |
753 | #endif | |
754 | ||
a93ba405 DMSP |
755 | /* |
756 | * Test whether the default rand_method (RAND_OpenSSL()) is | |
757 | * setup correctly, in particular whether reseeding works | |
758 | * as designed. | |
759 | */ | |
8817215d | 760 | static int test_rand_drbg_reseed(void) |
a93ba405 DMSP |
761 | { |
762 | RAND_DRBG *master, *public, *private; | |
763 | unsigned char rand_add_buf[256]; | |
764 | int rv=0; | |
2bb1b5dd | 765 | time_t before_reseed; |
a93ba405 DMSP |
766 | |
767 | /* Check whether RAND_OpenSSL() is the default method */ | |
768 | if (!TEST_ptr_eq(RAND_get_rand_method(), RAND_OpenSSL())) | |
769 | return 0; | |
770 | ||
771 | /* All three DRBGs should be non-null */ | |
772 | if (!TEST_ptr(master = RAND_DRBG_get0_master()) | |
773 | || !TEST_ptr(public = RAND_DRBG_get0_public()) | |
774 | || !TEST_ptr(private = RAND_DRBG_get0_private())) | |
775 | return 0; | |
776 | ||
777 | /* There should be three distinct DRBGs, two of them chained to master */ | |
778 | if (!TEST_ptr_ne(public, private) | |
779 | || !TEST_ptr_ne(public, master) | |
780 | || !TEST_ptr_ne(private, master) | |
781 | || !TEST_ptr_eq(public->parent, master) | |
782 | || !TEST_ptr_eq(private->parent, master)) | |
783 | return 0; | |
784 | ||
d69226a3 P |
785 | /* Disable CRNG testing for the master DRBG */ |
786 | if (!TEST_true(disable_crngt(master))) | |
787 | return 0; | |
788 | ||
59f124f9 DMSP |
789 | /* uninstantiate the three global DRBGs */ |
790 | RAND_DRBG_uninstantiate(private); | |
791 | RAND_DRBG_uninstantiate(public); | |
792 | RAND_DRBG_uninstantiate(master); | |
793 | ||
794 | ||
a93ba405 DMSP |
795 | /* Install hooks for the following tests */ |
796 | hook_drbg(master, &master_ctx); | |
797 | hook_drbg(public, &public_ctx); | |
798 | hook_drbg(private, &private_ctx); | |
799 | ||
59f124f9 DMSP |
800 | |
801 | /* | |
802 | * Test initial seeding of shared DRBGs | |
803 | */ | |
2bb1b5dd | 804 | if (!TEST_true(test_drbg_reseed(1, master, public, private, 1, 1, 1, 0))) |
59f124f9 DMSP |
805 | goto error; |
806 | reset_drbg_hook_ctx(); | |
807 | ||
808 | ||
a93ba405 | 809 | /* |
59f124f9 | 810 | * Test initial state of shared DRBGs |
a93ba405 | 811 | */ |
2bb1b5dd | 812 | if (!TEST_true(test_drbg_reseed(1, master, public, private, 0, 0, 0, 0))) |
a93ba405 DMSP |
813 | goto error; |
814 | reset_drbg_hook_ctx(); | |
815 | ||
816 | /* | |
817 | * Test whether the public and private DRBG are both reseeded when their | |
818 | * reseed counters differ from the master's reseed counter. | |
819 | */ | |
8bf36651 | 820 | master->reseed_prop_counter++; |
2bb1b5dd | 821 | if (!TEST_true(test_drbg_reseed(1, master, public, private, 0, 1, 1, 0))) |
a93ba405 DMSP |
822 | goto error; |
823 | reset_drbg_hook_ctx(); | |
824 | ||
825 | /* | |
826 | * Test whether the public DRBG is reseeded when its reseed counter differs | |
827 | * from the master's reseed counter. | |
828 | */ | |
8bf36651 SL |
829 | master->reseed_prop_counter++; |
830 | private->reseed_prop_counter++; | |
2bb1b5dd | 831 | if (!TEST_true(test_drbg_reseed(1, master, public, private, 0, 1, 0, 0))) |
a93ba405 DMSP |
832 | goto error; |
833 | reset_drbg_hook_ctx(); | |
834 | ||
835 | /* | |
836 | * Test whether the private DRBG is reseeded when its reseed counter differs | |
837 | * from the master's reseed counter. | |
838 | */ | |
8bf36651 SL |
839 | master->reseed_prop_counter++; |
840 | public->reseed_prop_counter++; | |
2bb1b5dd | 841 | if (!TEST_true(test_drbg_reseed(1, master, public, private, 0, 0, 1, 0))) |
a93ba405 DMSP |
842 | goto error; |
843 | reset_drbg_hook_ctx(); | |
844 | ||
84952925 DMSP |
845 | #if defined(OPENSSL_SYS_UNIX) |
846 | if (!TEST_true(test_drbg_reseed_after_fork(master, public, private))) | |
847 | goto error; | |
848 | #endif | |
a93ba405 DMSP |
849 | |
850 | /* fill 'randomness' buffer with some arbitrary data */ | |
851 | memset(rand_add_buf, 'r', sizeof(rand_add_buf)); | |
852 | ||
f844f9eb | 853 | #ifndef FIPS_MODULE |
a93ba405 | 854 | /* |
2bb1b5dd BE |
855 | * Test whether all three DRBGs are reseeded by RAND_add(). |
856 | * The before_reseed time has to be measured here and passed into the | |
857 | * test_drbg_reseed() test, because the master DRBG gets already reseeded | |
858 | * in RAND_add(), whence the check for the condition | |
859 | * before_reseed <= master->reseed_time will fail if the time value happens | |
860 | * to increase between the RAND_add() and the test_drbg_reseed() call. | |
a93ba405 | 861 | */ |
2bb1b5dd | 862 | before_reseed = time(NULL); |
a93ba405 | 863 | RAND_add(rand_add_buf, sizeof(rand_add_buf), sizeof(rand_add_buf)); |
2bb1b5dd BE |
864 | if (!TEST_true(test_drbg_reseed(1, master, public, private, 1, 1, 1, |
865 | before_reseed))) | |
a93ba405 DMSP |
866 | goto error; |
867 | reset_drbg_hook_ctx(); | |
868 | ||
869 | ||
870 | /* | |
871 | * Test whether none of the DRBGs is reseed if the master fails to reseed | |
872 | */ | |
873 | master_ctx.fail = 1; | |
8bf36651 | 874 | master->reseed_prop_counter++; |
a93ba405 | 875 | RAND_add(rand_add_buf, sizeof(rand_add_buf), sizeof(rand_add_buf)); |
2bb1b5dd | 876 | if (!TEST_true(test_drbg_reseed(0, master, public, private, 0, 0, 0, 0))) |
a93ba405 DMSP |
877 | goto error; |
878 | reset_drbg_hook_ctx(); | |
f844f9eb | 879 | #else /* FIPS_MODULE */ |
3a50a8a9 DMSP |
880 | /* |
881 | * In FIPS mode, random data provided by the application via RAND_add() | |
882 | * is not considered a trusted entropy source. It is only treated as | |
883 | * additional_data and no reseeding is forced. This test assures that | |
884 | * no reseeding occurs. | |
885 | */ | |
886 | before_reseed = time(NULL); | |
887 | RAND_add(rand_add_buf, sizeof(rand_add_buf), sizeof(rand_add_buf)); | |
888 | if (!TEST_true(test_drbg_reseed(1, master, public, private, 0, 0, 0, | |
889 | before_reseed))) | |
890 | goto error; | |
891 | reset_drbg_hook_ctx(); | |
892 | #endif | |
a93ba405 DMSP |
893 | |
894 | rv = 1; | |
895 | ||
896 | error: | |
897 | /* Remove hooks */ | |
898 | unhook_drbg(master); | |
899 | unhook_drbg(public); | |
900 | unhook_drbg(private); | |
901 | ||
902 | return rv; | |
903 | } | |
904 | ||
440bce8f | 905 | #if defined(OPENSSL_THREADS) |
43687d68 DMSP |
906 | static int multi_thread_rand_bytes_succeeded = 1; |
907 | static int multi_thread_rand_priv_bytes_succeeded = 1; | |
440bce8f KR |
908 | |
909 | static void run_multi_thread_test(void) | |
910 | { | |
911 | unsigned char buf[256]; | |
912 | time_t start = time(NULL); | |
7ecd6c51 | 913 | RAND_DRBG *public = NULL, *private = NULL; |
440bce8f | 914 | |
7ecd6c51 BE |
915 | if (!TEST_ptr(public = RAND_DRBG_get0_public()) |
916 | || !TEST_ptr(private = RAND_DRBG_get0_private())) { | |
917 | multi_thread_rand_bytes_succeeded = 0; | |
918 | return; | |
919 | } | |
440bce8f | 920 | RAND_DRBG_set_reseed_time_interval(private, 1); |
7ecd6c51 | 921 | RAND_DRBG_set_reseed_time_interval(public, 1); |
440bce8f KR |
922 | |
923 | do { | |
43687d68 DMSP |
924 | if (RAND_bytes(buf, sizeof(buf)) <= 0) |
925 | multi_thread_rand_bytes_succeeded = 0; | |
926 | if (RAND_priv_bytes(buf, sizeof(buf)) <= 0) | |
927 | multi_thread_rand_priv_bytes_succeeded = 0; | |
440bce8f KR |
928 | } |
929 | while(time(NULL) - start < 5); | |
930 | } | |
931 | ||
932 | # if defined(OPENSSL_SYS_WINDOWS) | |
933 | ||
934 | typedef HANDLE thread_t; | |
935 | ||
936 | static DWORD WINAPI thread_run(LPVOID arg) | |
937 | { | |
938 | run_multi_thread_test(); | |
03cdfe1e RL |
939 | /* |
940 | * Because we're linking with a static library, we must stop each | |
941 | * thread explicitly, or so says OPENSSL_thread_stop(3) | |
942 | */ | |
943 | OPENSSL_thread_stop(); | |
440bce8f KR |
944 | return 0; |
945 | } | |
946 | ||
947 | static int run_thread(thread_t *t) | |
948 | { | |
949 | *t = CreateThread(NULL, 0, thread_run, NULL, 0, NULL); | |
950 | return *t != NULL; | |
951 | } | |
952 | ||
953 | static int wait_for_thread(thread_t thread) | |
954 | { | |
955 | return WaitForSingleObject(thread, INFINITE) == 0; | |
956 | } | |
957 | ||
958 | # else | |
959 | ||
960 | typedef pthread_t thread_t; | |
961 | ||
962 | static void *thread_run(void *arg) | |
963 | { | |
964 | run_multi_thread_test(); | |
03cdfe1e RL |
965 | /* |
966 | * Because we're linking with a static library, we must stop each | |
967 | * thread explicitly, or so says OPENSSL_thread_stop(3) | |
968 | */ | |
969 | OPENSSL_thread_stop(); | |
440bce8f KR |
970 | return NULL; |
971 | } | |
972 | ||
973 | static int run_thread(thread_t *t) | |
974 | { | |
975 | return pthread_create(t, NULL, thread_run, NULL) == 0; | |
976 | } | |
977 | ||
978 | static int wait_for_thread(thread_t thread) | |
979 | { | |
980 | return pthread_join(thread, NULL) == 0; | |
981 | } | |
982 | ||
983 | # endif | |
984 | ||
985 | /* | |
986 | * The main thread will also run the test, so we'll have THREADS+1 parallel | |
987 | * tests running | |
988 | */ | |
43687d68 | 989 | # define THREADS 3 |
440bce8f KR |
990 | |
991 | static int test_multi_thread(void) | |
992 | { | |
993 | thread_t t[THREADS]; | |
994 | int i; | |
995 | ||
996 | for (i = 0; i < THREADS; i++) | |
997 | run_thread(&t[i]); | |
998 | run_multi_thread_test(); | |
999 | for (i = 0; i < THREADS; i++) | |
1000 | wait_for_thread(t[i]); | |
43687d68 DMSP |
1001 | |
1002 | if (!TEST_true(multi_thread_rand_bytes_succeeded)) | |
1003 | return 0; | |
1004 | if (!TEST_true(multi_thread_rand_priv_bytes_succeeded)) | |
1005 | return 0; | |
1006 | ||
440bce8f KR |
1007 | return 1; |
1008 | } | |
1009 | #endif | |
12fb8c3d | 1010 | |
2a70d65b | 1011 | /* |
8817215d DMSP |
1012 | * Test that instantiation with RAND_seed() works as expected |
1013 | * | |
1014 | * If no os entropy source is available then RAND_seed(buffer, bufsize) | |
1015 | * is expected to succeed if and only if the buffer length is at least | |
1016 | * rand_drbg_seedlen(master) bytes. | |
1017 | * | |
1018 | * If an os entropy source is available then RAND_seed(buffer, bufsize) | |
1019 | * is expected to succeed always. | |
2a70d65b | 1020 | */ |
8817215d | 1021 | static int test_rand_seed(void) |
2a70d65b | 1022 | { |
7ecd6c51 | 1023 | RAND_DRBG *master = NULL; |
8817215d DMSP |
1024 | unsigned char rand_buf[256]; |
1025 | size_t rand_buflen; | |
8817215d | 1026 | size_t required_seed_buflen = 0; |
7ecd6c51 | 1027 | |
d69226a3 P |
1028 | if (!TEST_ptr(master = RAND_DRBG_get0_master()) |
1029 | || !TEST_true(disable_crngt(master))) | |
7ecd6c51 BE |
1030 | return 0; |
1031 | ||
1032 | #ifdef OPENSSL_RAND_SEED_NONE | |
1033 | required_seed_buflen = rand_drbg_seedlen(master); | |
8817215d DMSP |
1034 | #endif |
1035 | ||
1036 | memset(rand_buf, 0xCD, sizeof(rand_buf)); | |
1037 | ||
1038 | for ( rand_buflen = 256 ; rand_buflen > 0 ; --rand_buflen ) { | |
1039 | RAND_DRBG_uninstantiate(master); | |
1040 | RAND_seed(rand_buf, rand_buflen); | |
1041 | ||
1042 | if (!TEST_int_eq(RAND_status(), | |
1043 | (rand_buflen >= required_seed_buflen))) | |
1044 | return 0; | |
1045 | } | |
1046 | ||
1047 | return 1; | |
2a70d65b KR |
1048 | } |
1049 | ||
1050 | /* | |
8817215d DMSP |
1051 | * Test that adding additional data with RAND_add() works as expected |
1052 | * when the master DRBG is instantiated (and below its reseed limit). | |
1053 | * | |
1054 | * This should succeed regardless of whether an os entropy source is | |
1055 | * available or not. | |
2a70d65b KR |
1056 | */ |
1057 | static int test_rand_add(void) | |
1058 | { | |
8817215d DMSP |
1059 | unsigned char rand_buf[256]; |
1060 | size_t rand_buflen; | |
2a70d65b | 1061 | |
8817215d | 1062 | memset(rand_buf, 0xCD, sizeof(rand_buf)); |
2a70d65b | 1063 | |
8817215d DMSP |
1064 | /* make sure it's instantiated */ |
1065 | RAND_seed(rand_buf, sizeof(rand_buf)); | |
1066 | if (!TEST_true(RAND_status())) | |
1067 | return 0; | |
2a70d65b | 1068 | |
8817215d DMSP |
1069 | for ( rand_buflen = 256 ; rand_buflen > 0 ; --rand_buflen ) { |
1070 | RAND_add(rand_buf, rand_buflen, 0.0); | |
1071 | if (!TEST_true(RAND_status())) | |
1072 | return 0; | |
1073 | } | |
1074 | ||
1075 | return 1; | |
2a70d65b KR |
1076 | } |
1077 | ||
65175163 P |
1078 | static int test_rand_drbg_prediction_resistance(void) |
1079 | { | |
1080 | RAND_DRBG *m = NULL, *i = NULL, *s = NULL; | |
1081 | unsigned char buf1[51], buf2[sizeof(buf1)]; | |
1082 | int ret = 0, mreseed, ireseed, sreseed; | |
1083 | ||
1084 | /* Initialise a three long DRBG chain */ | |
1085 | if (!TEST_ptr(m = RAND_DRBG_new(0, 0, NULL)) | |
1086 | || !TEST_true(disable_crngt(m)) | |
1087 | || !TEST_true(RAND_DRBG_instantiate(m, NULL, 0)) | |
1088 | || !TEST_ptr(i = RAND_DRBG_new(0, 0, m)) | |
1089 | || !TEST_true(RAND_DRBG_instantiate(i, NULL, 0)) | |
1090 | || !TEST_ptr(s = RAND_DRBG_new(0, 0, i)) | |
1091 | || !TEST_true(RAND_DRBG_instantiate(s, NULL, 0))) | |
1092 | goto err; | |
1093 | ||
1094 | /* During a normal reseed, only the slave DRBG should be reseed */ | |
1095 | mreseed = ++m->reseed_prop_counter; | |
1096 | ireseed = ++i->reseed_prop_counter; | |
1097 | sreseed = s->reseed_prop_counter; | |
1098 | if (!TEST_true(RAND_DRBG_reseed(s, NULL, 0, 0)) | |
1099 | || !TEST_int_eq(m->reseed_prop_counter, mreseed) | |
1100 | || !TEST_int_eq(i->reseed_prop_counter, ireseed) | |
1101 | || !TEST_int_gt(s->reseed_prop_counter, sreseed)) | |
1102 | goto err; | |
1103 | ||
1104 | /* | |
1105 | * When prediction resistance is requested, the request should be | |
1106 | * propagated to the master, so that the entire DRBG chain reseeds. | |
1107 | */ | |
1108 | sreseed = s->reseed_prop_counter; | |
1109 | if (!TEST_true(RAND_DRBG_reseed(s, NULL, 0, 1)) | |
1110 | || !TEST_int_gt(m->reseed_prop_counter, mreseed) | |
1111 | || !TEST_int_gt(i->reseed_prop_counter, ireseed) | |
1112 | || !TEST_int_gt(s->reseed_prop_counter, sreseed)) | |
1113 | goto err; | |
1114 | ||
1115 | /* During a normal generate, only the slave DRBG should be reseed */ | |
1116 | mreseed = ++m->reseed_prop_counter; | |
1117 | ireseed = ++i->reseed_prop_counter; | |
1118 | sreseed = s->reseed_prop_counter; | |
1119 | if (!TEST_true(RAND_DRBG_generate(s, buf1, sizeof(buf1), 0, NULL, 0)) | |
1120 | || !TEST_int_eq(m->reseed_prop_counter, mreseed) | |
1121 | || !TEST_int_eq(i->reseed_prop_counter, ireseed) | |
1122 | || !TEST_int_gt(s->reseed_prop_counter, sreseed)) | |
1123 | goto err; | |
1124 | ||
1125 | /* | |
1126 | * When a prediction resistant generate is requested, the request | |
1127 | * should be propagated to the master, reseeding the entire DRBG chain. | |
1128 | */ | |
1129 | sreseed = s->reseed_prop_counter; | |
1130 | if (!TEST_true(RAND_DRBG_generate(s, buf2, sizeof(buf2), 1, NULL, 0)) | |
1131 | || !TEST_int_gt(m->reseed_prop_counter, mreseed) | |
1132 | || !TEST_int_gt(i->reseed_prop_counter, ireseed) | |
1133 | || !TEST_int_gt(s->reseed_prop_counter, sreseed) | |
1134 | || !TEST_mem_ne(buf1, sizeof(buf1), buf2, sizeof(buf2))) | |
1135 | goto err; | |
1136 | ||
1137 | /* Verify that a normal reseed still only reseeds the slave DRBG */ | |
1138 | mreseed = ++m->reseed_prop_counter; | |
1139 | ireseed = ++i->reseed_prop_counter; | |
1140 | sreseed = s->reseed_prop_counter; | |
1141 | if (!TEST_true(RAND_DRBG_reseed(s, NULL, 0, 0)) | |
1142 | || !TEST_int_eq(m->reseed_prop_counter, mreseed) | |
1143 | || !TEST_int_eq(i->reseed_prop_counter, ireseed) | |
1144 | || !TEST_int_gt(s->reseed_prop_counter, sreseed)) | |
1145 | goto err; | |
1146 | ||
1147 | ret = 1; | |
1148 | err: | |
1149 | RAND_DRBG_free(s); | |
1150 | RAND_DRBG_free(i); | |
1151 | RAND_DRBG_free(m); | |
1152 | return ret; | |
1153 | } | |
1154 | ||
8bf36651 SL |
1155 | static int test_multi_set(void) |
1156 | { | |
1157 | int rv = 0; | |
1158 | RAND_DRBG *drbg = NULL; | |
1159 | ||
1160 | /* init drbg with default CTR initializer */ | |
d69226a3 P |
1161 | if (!TEST_ptr(drbg = RAND_DRBG_new(0, 0, NULL)) |
1162 | || !TEST_true(disable_crngt(drbg))) | |
8bf36651 SL |
1163 | goto err; |
1164 | /* change it to use hmac */ | |
1165 | if (!TEST_true(RAND_DRBG_set(drbg, NID_sha1, RAND_DRBG_FLAG_HMAC))) | |
1166 | goto err; | |
1167 | /* use same type */ | |
1168 | if (!TEST_true(RAND_DRBG_set(drbg, NID_sha1, RAND_DRBG_FLAG_HMAC))) | |
1169 | goto err; | |
1170 | /* change it to use hash */ | |
1171 | if (!TEST_true(RAND_DRBG_set(drbg, NID_sha256, 0))) | |
1172 | goto err; | |
1173 | /* use same type */ | |
1174 | if (!TEST_true(RAND_DRBG_set(drbg, NID_sha256, 0))) | |
1175 | goto err; | |
1176 | /* change it to use ctr */ | |
1177 | if (!TEST_true(RAND_DRBG_set(drbg, NID_aes_192_ctr, 0))) | |
1178 | goto err; | |
1179 | /* use same type */ | |
1180 | if (!TEST_true(RAND_DRBG_set(drbg, NID_aes_192_ctr, 0))) | |
1181 | goto err; | |
1182 | if (!TEST_int_gt(RAND_DRBG_instantiate(drbg, NULL, 0), 0)) | |
1183 | goto err; | |
1184 | ||
1185 | rv = 1; | |
1186 | err: | |
1187 | uninstantiate(drbg); | |
1188 | RAND_DRBG_free(drbg); | |
1189 | return rv; | |
1190 | } | |
1191 | ||
1192 | static int test_set_defaults(void) | |
1193 | { | |
7ecd6c51 | 1194 | RAND_DRBG *master = NULL, *public = NULL, *private = NULL; |
8bf36651 SL |
1195 | |
1196 | /* Check the default type and flags for master, public and private */ | |
7ecd6c51 BE |
1197 | return TEST_ptr(master = RAND_DRBG_get0_master()) |
1198 | && TEST_ptr(public = RAND_DRBG_get0_public()) | |
1199 | && TEST_ptr(private = RAND_DRBG_get0_private()) | |
1200 | && TEST_int_eq(master->type, RAND_DRBG_TYPE) | |
8bf36651 SL |
1201 | && TEST_int_eq(master->flags, |
1202 | RAND_DRBG_FLAGS | RAND_DRBG_FLAG_MASTER) | |
1203 | && TEST_int_eq(public->type, RAND_DRBG_TYPE) | |
1204 | && TEST_int_eq(public->flags, | |
1205 | RAND_DRBG_FLAGS | RAND_DRBG_FLAG_PUBLIC) | |
1206 | && TEST_int_eq(private->type, RAND_DRBG_TYPE) | |
1207 | && TEST_int_eq(private->flags, | |
1208 | RAND_DRBG_FLAGS | RAND_DRBG_FLAG_PRIVATE) | |
1209 | ||
1210 | /* change master DRBG and check again */ | |
1211 | && TEST_true(RAND_DRBG_set_defaults(NID_sha256, | |
1212 | RAND_DRBG_FLAG_MASTER)) | |
1213 | && TEST_true(RAND_DRBG_uninstantiate(master)) | |
1214 | && TEST_int_eq(master->type, NID_sha256) | |
1215 | && TEST_int_eq(master->flags, RAND_DRBG_FLAG_MASTER) | |
1216 | && TEST_int_eq(public->type, RAND_DRBG_TYPE) | |
1217 | && TEST_int_eq(public->flags, | |
1218 | RAND_DRBG_FLAGS | RAND_DRBG_FLAG_PUBLIC) | |
1219 | && TEST_int_eq(private->type, RAND_DRBG_TYPE) | |
1220 | && TEST_int_eq(private->flags, | |
1221 | RAND_DRBG_FLAGS | RAND_DRBG_FLAG_PRIVATE) | |
1222 | /* change private DRBG and check again */ | |
1223 | && TEST_true(RAND_DRBG_set_defaults(NID_sha256, | |
1224 | RAND_DRBG_FLAG_PRIVATE|RAND_DRBG_FLAG_HMAC)) | |
1225 | && TEST_true(RAND_DRBG_uninstantiate(private)) | |
1226 | && TEST_int_eq(master->type, NID_sha256) | |
1227 | && TEST_int_eq(master->flags, RAND_DRBG_FLAG_MASTER) | |
1228 | && TEST_int_eq(public->type, RAND_DRBG_TYPE) | |
1229 | && TEST_int_eq(public->flags, | |
1230 | RAND_DRBG_FLAGS | RAND_DRBG_FLAG_PUBLIC) | |
1231 | && TEST_int_eq(private->type, NID_sha256) | |
1232 | && TEST_int_eq(private->flags, | |
1233 | RAND_DRBG_FLAG_PRIVATE | RAND_DRBG_FLAG_HMAC) | |
1234 | /* change public DRBG and check again */ | |
1235 | && TEST_true(RAND_DRBG_set_defaults(NID_sha1, | |
1236 | RAND_DRBG_FLAG_PUBLIC | |
1237 | | RAND_DRBG_FLAG_HMAC)) | |
1238 | && TEST_true(RAND_DRBG_uninstantiate(public)) | |
1239 | && TEST_int_eq(master->type, NID_sha256) | |
1240 | && TEST_int_eq(master->flags, RAND_DRBG_FLAG_MASTER) | |
1241 | && TEST_int_eq(public->type, NID_sha1) | |
1242 | && TEST_int_eq(public->flags, | |
1243 | RAND_DRBG_FLAG_PUBLIC | RAND_DRBG_FLAG_HMAC) | |
1244 | && TEST_int_eq(private->type, NID_sha256) | |
1245 | && TEST_int_eq(private->flags, | |
1246 | RAND_DRBG_FLAG_PRIVATE | RAND_DRBG_FLAG_HMAC) | |
1247 | /* Change DRBG defaults and change public and check again */ | |
1248 | && TEST_true(RAND_DRBG_set_defaults(NID_sha256, 0)) | |
1249 | && TEST_true(RAND_DRBG_uninstantiate(public)) | |
1250 | && TEST_int_eq(public->type, NID_sha256) | |
1251 | && TEST_int_eq(public->flags, RAND_DRBG_FLAG_PUBLIC) | |
1252 | ||
6c7d80ab | 1253 | /* FIPS mode doesn't support CTR DRBG without a derivation function */ |
f844f9eb | 1254 | #ifndef FIPS_MODULE |
6c7d80ab | 1255 | /* Change DRBG defaults and change master and check again */ |
8bf36651 SL |
1256 | && TEST_true(RAND_DRBG_set_defaults(NID_aes_256_ctr, |
1257 | RAND_DRBG_FLAG_CTR_NO_DF)) | |
1258 | && TEST_true(RAND_DRBG_uninstantiate(master)) | |
1259 | && TEST_int_eq(master->type, NID_aes_256_ctr) | |
1260 | && TEST_int_eq(master->flags, | |
1b39bc9b | 1261 | RAND_DRBG_FLAG_MASTER|RAND_DRBG_FLAG_CTR_NO_DF) |
6c7d80ab | 1262 | #endif |
1b39bc9b MC |
1263 | /* Reset back to the standard defaults */ |
1264 | && TEST_true(RAND_DRBG_set_defaults(RAND_DRBG_TYPE, | |
1265 | RAND_DRBG_FLAGS | |
1266 | | RAND_DRBG_FLAG_MASTER | |
1267 | | RAND_DRBG_FLAG_PUBLIC | |
1268 | | RAND_DRBG_FLAG_PRIVATE)) | |
1269 | && TEST_true(RAND_DRBG_uninstantiate(master)) | |
1270 | && TEST_true(RAND_DRBG_uninstantiate(public)) | |
1271 | && TEST_true(RAND_DRBG_uninstantiate(private)); | |
8bf36651 SL |
1272 | } |
1273 | ||
d69226a3 P |
1274 | /* |
1275 | * A list of the FIPS DRGB types. | |
1276 | * Because of the way HMAC DRGBs are implemented, both the NID and flags | |
1277 | * are required. | |
1278 | */ | |
1279 | static const struct s_drgb_types { | |
1280 | int nid; | |
1281 | int flags; | |
1282 | } drgb_types[] = { | |
1283 | { NID_aes_128_ctr, 0 }, | |
1284 | { NID_aes_192_ctr, 0 }, | |
1285 | { NID_aes_256_ctr, 0 }, | |
1286 | { NID_sha1, 0 }, | |
1287 | { NID_sha224, 0 }, | |
1288 | { NID_sha256, 0 }, | |
1289 | { NID_sha384, 0 }, | |
1290 | { NID_sha512, 0 }, | |
1291 | { NID_sha512_224, 0 }, | |
1292 | { NID_sha512_256, 0 }, | |
1293 | { NID_sha3_224, 0 }, | |
1294 | { NID_sha3_256, 0 }, | |
1295 | { NID_sha3_384, 0 }, | |
1296 | { NID_sha3_512, 0 }, | |
1297 | { NID_sha1, RAND_DRBG_FLAG_HMAC }, | |
1298 | { NID_sha224, RAND_DRBG_FLAG_HMAC }, | |
1299 | { NID_sha256, RAND_DRBG_FLAG_HMAC }, | |
1300 | { NID_sha384, RAND_DRBG_FLAG_HMAC }, | |
1301 | { NID_sha512, RAND_DRBG_FLAG_HMAC }, | |
1302 | { NID_sha512_224, RAND_DRBG_FLAG_HMAC }, | |
1303 | { NID_sha512_256, RAND_DRBG_FLAG_HMAC }, | |
1304 | { NID_sha3_224, RAND_DRBG_FLAG_HMAC }, | |
1305 | { NID_sha3_256, RAND_DRBG_FLAG_HMAC }, | |
1306 | { NID_sha3_384, RAND_DRBG_FLAG_HMAC }, | |
1307 | { NID_sha3_512, RAND_DRBG_FLAG_HMAC }, | |
1308 | }; | |
1309 | ||
1310 | /* Six cases for each covers seed sizes up to 32 bytes */ | |
1311 | static const size_t crngt_num_cases = 6; | |
1312 | ||
1313 | static size_t crngt_case, crngt_idx; | |
1314 | ||
57ca171a MC |
1315 | static int crngt_entropy_cb(OPENSSL_CTX *ctx, RAND_POOL *pool, |
1316 | unsigned char *buf, unsigned char *md, | |
8094a694 | 1317 | unsigned int *md_size) |
d69226a3 P |
1318 | { |
1319 | size_t i, z; | |
1320 | ||
1321 | if (!TEST_int_lt(crngt_idx, crngt_num_cases)) | |
1322 | return 0; | |
1323 | /* Generate a block of unique data unless this is the duplication point */ | |
1324 | z = crngt_idx++; | |
1325 | if (z > 0 && crngt_case == z) | |
1326 | z--; | |
1327 | for (i = 0; i < CRNGT_BUFSIZ; i++) | |
1328 | buf[i] = (unsigned char)(i + 'A' + z); | |
8094a694 | 1329 | return EVP_Digest(buf, CRNGT_BUFSIZ, md, md_size, EVP_sha256(), NULL); |
d69226a3 P |
1330 | } |
1331 | ||
1332 | static int test_crngt(int n) | |
1333 | { | |
1334 | const struct s_drgb_types *dt = drgb_types + n / crngt_num_cases; | |
1335 | RAND_DRBG *drbg = NULL; | |
1336 | unsigned char buff[100]; | |
1337 | size_t ent; | |
1338 | int res = 0; | |
1339 | int expect; | |
4e297b74 | 1340 | OPENSSL_CTX *ctx = OPENSSL_CTX_new(); |
d69226a3 | 1341 | |
4e297b74 | 1342 | if (!TEST_ptr(ctx)) |
d69226a3 | 1343 | return 0; |
4e297b74 MC |
1344 | if (!TEST_ptr(drbg = RAND_DRBG_new_ex(ctx, dt->nid, dt->flags, NULL))) |
1345 | goto err; | |
d69226a3 P |
1346 | ent = (drbg->min_entropylen + CRNGT_BUFSIZ - 1) / CRNGT_BUFSIZ; |
1347 | crngt_case = n % crngt_num_cases; | |
1348 | crngt_idx = 0; | |
1349 | crngt_get_entropy = &crngt_entropy_cb; | |
f844f9eb | 1350 | #ifndef FIPS_MODULE |
d69226a3 P |
1351 | if (!TEST_true(RAND_DRBG_set_callbacks(drbg, &rand_crngt_get_entropy, |
1352 | &rand_crngt_cleanup_entropy, | |
1353 | &rand_drbg_get_nonce, | |
1354 | &rand_drbg_cleanup_nonce))) | |
1355 | goto err; | |
1356 | #endif | |
1357 | expect = crngt_case == 0 || crngt_case > ent; | |
1358 | if (!TEST_int_eq(RAND_DRBG_instantiate(drbg, NULL, 0), expect)) | |
1359 | goto err; | |
1360 | if (!expect) | |
1361 | goto fin; | |
1362 | if (!TEST_true(RAND_DRBG_generate(drbg, buff, sizeof(buff), 0, NULL, 0))) | |
1363 | goto err; | |
1364 | ||
1365 | expect = crngt_case == 0 || crngt_case > 2 * ent; | |
1366 | if (!TEST_int_eq(RAND_DRBG_reseed(drbg, NULL, 0, 0), expect)) | |
1367 | goto err; | |
1368 | if (!expect) | |
1369 | goto fin; | |
1370 | if (!TEST_true(RAND_DRBG_generate(drbg, buff, sizeof(buff), 0, NULL, 0))) | |
1371 | goto err; | |
1372 | ||
1373 | fin: | |
1374 | res = 1; | |
1375 | err: | |
1376 | if (!res) | |
1377 | TEST_note("DRBG %zd case %zd block %zd", n / crngt_num_cases, | |
1378 | crngt_case, crngt_idx); | |
1379 | uninstantiate(drbg); | |
1380 | RAND_DRBG_free(drbg); | |
1381 | crngt_get_entropy = &rand_crngt_get_entropy_cb; | |
4e297b74 | 1382 | OPENSSL_CTX_free(ctx); |
d69226a3 P |
1383 | return res; |
1384 | } | |
1385 | ||
ad887416 | 1386 | int setup_tests(void) |
12fb8c3d | 1387 | { |
12fb8c3d RS |
1388 | ADD_ALL_TESTS(test_kats, OSSL_NELEM(drbg_test)); |
1389 | ADD_ALL_TESTS(test_error_checks, OSSL_NELEM(drbg_test)); | |
8817215d DMSP |
1390 | ADD_TEST(test_rand_drbg_reseed); |
1391 | ADD_TEST(test_rand_seed); | |
2a70d65b | 1392 | ADD_TEST(test_rand_add); |
65175163 | 1393 | ADD_TEST(test_rand_drbg_prediction_resistance); |
8bf36651 SL |
1394 | ADD_TEST(test_multi_set); |
1395 | ADD_TEST(test_set_defaults); | |
440bce8f KR |
1396 | #if defined(OPENSSL_THREADS) |
1397 | ADD_TEST(test_multi_thread); | |
1398 | #endif | |
d69226a3 | 1399 | ADD_ALL_TESTS(test_crngt, crngt_num_cases * OSSL_NELEM(drgb_types)); |
ad887416 | 1400 | return 1; |
12fb8c3d | 1401 | } |