bedc62ca2cab39630716678cbd8b4205ecc7f728
[openssl.git] / test / drbgtest.c
1 /*
2  * Copyright 2011-2021 The OpenSSL Project Authors. All Rights Reserved.
3  *
4  * Licensed under the Apache License 2.0 (the "License").  You may not use
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 /* We need to use some deprecated APIs */
11 #define OPENSSL_SUPPRESS_DEPRECATED
12
13 #include <string.h>
14 #include "internal/nelem.h"
15 #include <openssl/crypto.h>
16 #include <openssl/err.h>
17 #include <openssl/rand.h>
18 #include <openssl/obj_mac.h>
19 #include <openssl/evp.h>
20 #include <openssl/aes.h>
21 #include "../crypto/rand/rand_local.h"
22 #include "../include/crypto/rand.h"
23 #include "../include/crypto/evp.h"
24 #include "../providers/implementations/rands/drbg_local.h"
25 #include "../crypto/evp/evp_local.h"
26
27 #if defined(_WIN32)
28 # include <windows.h>
29 #endif
30
31 #if defined(__TANDEM)
32 # if defined(OPENSSL_TANDEM_FLOSS)
33 #  include <floss.h(floss_fork)>
34 # endif
35 #endif
36
37 #if defined(OPENSSL_SYS_UNIX)
38 # include <sys/types.h>
39 # include <sys/wait.h>
40 # include <unistd.h>
41 #endif
42
43 #include "testutil.h"
44
45 /*
46  * DRBG generate wrappers
47  */
48 static int gen_bytes(EVP_RAND_CTX *drbg, unsigned char *buf, int num)
49 {
50     const RAND_METHOD *meth = RAND_get_rand_method();
51
52     if (meth != NULL && meth != RAND_OpenSSL()) {
53         if (meth->bytes != NULL)
54             return meth->bytes(buf, num);
55         return -1;
56     }
57
58     if (drbg != NULL)
59         return EVP_RAND_generate(drbg, buf, num, 0, 0, NULL, 0);
60     return 0;
61 }
62
63 static int rand_bytes(unsigned char *buf, int num)
64 {
65     return gen_bytes(RAND_get0_public(NULL), buf, num);
66 }
67
68 static int rand_priv_bytes(unsigned char *buf, int num)
69 {
70     return gen_bytes(RAND_get0_private(NULL), buf, num);
71 }
72
73
74 /* size of random output generated in test_drbg_reseed() */
75 #define RANDOM_SIZE 16
76
77 /*
78  * DRBG query functions
79  */
80 static int state(EVP_RAND_CTX *drbg)
81 {
82     return EVP_RAND_state(drbg);
83 }
84
85 static unsigned int query_rand_uint(EVP_RAND_CTX *drbg, const char *name)
86 {
87     OSSL_PARAM params[2] = { OSSL_PARAM_END, OSSL_PARAM_END };
88     unsigned int n;
89
90     *params = OSSL_PARAM_construct_uint(name, &n);
91     if (EVP_RAND_get_ctx_params(drbg, params))
92         return n;
93     return 0;
94 }
95
96 #define DRBG_UINT(name)                                 \
97     static unsigned int name(EVP_RAND_CTX *drbg)        \
98     {                                                   \
99         return query_rand_uint(drbg, #name);            \
100     }
101 DRBG_UINT(reseed_counter)
102
103 static PROV_DRBG *prov_rand(EVP_RAND_CTX *drbg)
104 {
105     return (PROV_DRBG *)drbg->data;
106 }
107
108 static void set_reseed_counter(EVP_RAND_CTX *drbg, unsigned int n)
109 {
110     PROV_DRBG *p = prov_rand(drbg);
111
112     p->reseed_counter = n;
113 }
114
115 static void inc_reseed_counter(EVP_RAND_CTX *drbg)
116 {
117     set_reseed_counter(drbg, reseed_counter(drbg) + 1);
118 }
119
120 static time_t reseed_time(EVP_RAND_CTX *drbg)
121 {
122     OSSL_PARAM params[2] = { OSSL_PARAM_END, OSSL_PARAM_END };
123     time_t t;
124
125     *params = OSSL_PARAM_construct_time_t(OSSL_DRBG_PARAM_RESEED_TIME, &t);
126     if (EVP_RAND_get_ctx_params(drbg, params))
127         return t;
128     return 0;
129 }
130
131 /*
132  * When building the FIPS module, it isn't possible to disable the continuous
133  * RNG tests.  Tests that require this are skipped.
134  */
135 static int crngt_skip(void)
136 {
137 #ifdef FIPS_MODULE
138     return 1;
139 #else
140     return 0;
141 #endif
142 }
143
144  /*
145  * Disable CRNG testing if it is enabled.
146  * This stub remains to indicate the calling locations where it is necessary.
147  * Once the RNG infrastructure is able to disable these tests, it should be
148  * reconstituted.
149  */
150 static int disable_crngt(EVP_RAND_CTX *drbg)
151 {
152     return 1;
153 }
154
155 /*
156  * Generates random output using rand_bytes() and rand_priv_bytes()
157  * and checks whether the three shared DRBGs were reseeded as
158  * expected.
159  *
160  * |expect_success|: expected outcome (as reported by RAND_status())
161  * |primary|, |public|, |private|: pointers to the three shared DRBGs
162  * |public_random|, |private_random|: generated random output
163  * |expect_xxx_reseed| =
164  *       1:  it is expected that the specified DRBG is reseeded
165  *       0:  it is expected that the specified DRBG is not reseeded
166  *      -1:  don't check whether the specified DRBG was reseeded or not
167  * |reseed_when|: if nonzero, used instead of time(NULL) to set the
168  *                |before_reseed| time.
169  */
170 static int test_drbg_reseed(int expect_success,
171                             EVP_RAND_CTX *primary,
172                             EVP_RAND_CTX *public,
173                             EVP_RAND_CTX *private,
174                             unsigned char *public_random,
175                             unsigned char *private_random,
176                             int expect_primary_reseed,
177                             int expect_public_reseed,
178                             int expect_private_reseed,
179                             time_t reseed_when
180                            )
181 {
182     time_t before_reseed, after_reseed;
183     int expected_state = (expect_success ? DRBG_READY : DRBG_ERROR);
184     unsigned int primary_reseed, public_reseed, private_reseed;
185     unsigned char dummy[RANDOM_SIZE];
186
187     if (public_random == NULL)
188         public_random = dummy;
189
190     if (private_random == NULL)
191         private_random = dummy;
192
193     /*
194      * step 1: check preconditions
195      */
196
197     /* Test whether seed propagation is enabled */
198     if (!TEST_int_ne(primary_reseed = reseed_counter(primary), 0)
199         || !TEST_int_ne(public_reseed = reseed_counter(public), 0)
200         || !TEST_int_ne(private_reseed = reseed_counter(private), 0))
201         return 0;
202
203     /*
204      * step 2: generate random output
205      */
206
207     if (reseed_when == 0)
208         reseed_when = time(NULL);
209
210     /* Generate random output from the public and private DRBG */
211     before_reseed = expect_primary_reseed == 1 ? reseed_when : 0;
212     if (!TEST_int_eq(rand_bytes((unsigned char*)public_random,
213                                 RANDOM_SIZE), expect_success)
214         || !TEST_int_eq(rand_priv_bytes((unsigned char*) private_random,
215                                         RANDOM_SIZE), expect_success))
216         return 0;
217     after_reseed = time(NULL);
218
219
220     /*
221      * step 3: check postconditions
222      */
223
224     /* Test whether reseeding succeeded as expected */
225     if (!TEST_int_eq(state(primary), expected_state)
226         || !TEST_int_eq(state(public), expected_state)
227         || !TEST_int_eq(state(private), expected_state))
228         return 0;
229
230     if (expect_primary_reseed >= 0) {
231         /* Test whether primary DRBG was reseeded as expected */
232         if (!TEST_int_ge(reseed_counter(primary), primary_reseed))
233             return 0;
234     }
235
236     if (expect_public_reseed >= 0) {
237         /* Test whether public DRBG was reseeded as expected */
238         if (!TEST_int_ge(reseed_counter(public), public_reseed)
239                 || !TEST_uint_ge(reseed_counter(public),
240                                  reseed_counter(primary)))
241             return 0;
242     }
243
244     if (expect_private_reseed >= 0) {
245         /* Test whether public DRBG was reseeded as expected */
246         if (!TEST_int_ge(reseed_counter(private), private_reseed)
247                 || !TEST_uint_ge(reseed_counter(private),
248                                  reseed_counter(primary)))
249             return 0;
250     }
251
252     if (expect_success == 1) {
253         /* Test whether reseed time of primary DRBG is set correctly */
254         if (!TEST_time_t_le(before_reseed, reseed_time(primary))
255             || !TEST_time_t_le(reseed_time(primary), after_reseed))
256             return 0;
257
258         /* Test whether reseed times of child DRBGs are synchronized with primary */
259         if (!TEST_time_t_ge(reseed_time(public), reseed_time(primary))
260             || !TEST_time_t_ge(reseed_time(private), reseed_time(primary)))
261             return 0;
262     } else {
263         ERR_clear_error();
264     }
265
266     return 1;
267 }
268
269
270 #if defined(OPENSSL_SYS_UNIX)
271 /* number of children to fork */
272 #define DRBG_FORK_COUNT 9
273 /* two results per child, two for the parent */
274 #define DRBG_FORK_RESULT_COUNT (2 * (DRBG_FORK_COUNT + 1))
275
276 typedef struct drbg_fork_result_st {
277
278     unsigned char random[RANDOM_SIZE]; /* random output */
279
280     int pindex;               /* process index (0: parent, 1,2,3...: children)*/
281     pid_t pid;                /* process id */
282     int private;              /* true if the private drbg was used */
283     char name[10];            /* 'parent' resp. 'child 1', 'child 2', ... */
284 } drbg_fork_result;
285
286 /*
287  * Sort the drbg_fork_result entries in lexicographical order
288  *
289  * This simplifies finding duplicate random output and makes
290  * the printout in case of an error more readable.
291  */
292 static int compare_drbg_fork_result(const void * left, const void * right)
293 {
294     int result;
295     const drbg_fork_result *l = left;
296     const drbg_fork_result *r = right;
297
298     /* separate public and private results */
299     result = l->private - r->private;
300
301     if (result == 0)
302         result = memcmp(l->random, r->random, RANDOM_SIZE);
303
304     if (result == 0)
305         result = l->pindex - r->pindex;
306
307     return result;
308 }
309
310 /*
311  * Sort two-byte chunks of random data
312  *
313  * Used for finding collisions in two-byte chunks
314  */
315 static int compare_rand_chunk(const void * left, const void * right)
316 {
317     return memcmp(left, right, 2);
318 }
319
320 /*
321  * Test whether primary, public and private DRBG are reseeded
322  * in the child after forking the process. Collect the random
323  * output of the public and private DRBG and send it back to
324  * the parent process.
325  */
326 static int test_drbg_reseed_in_child(EVP_RAND_CTX *primary,
327                                      EVP_RAND_CTX *public,
328                                      EVP_RAND_CTX *private,
329                                      drbg_fork_result result[2])
330 {
331     int rv = 0, status;
332     int fd[2];
333     pid_t pid;
334     unsigned char random[2 * RANDOM_SIZE];
335
336     if (!TEST_int_ge(pipe(fd), 0))
337         return 0;
338
339     if (!TEST_int_ge(pid = fork(), 0)) {
340         close(fd[0]);
341         close(fd[1]);
342         return 0;
343     } else if (pid > 0) {
344
345         /* I'm the parent; close the write end */
346         close(fd[1]);
347
348         /* wait for children to terminate and collect their random output */
349         if (TEST_int_eq(waitpid(pid, &status, 0), pid)
350             && TEST_int_eq(status, 0)
351             && TEST_true(read(fd[0], &random[0], sizeof(random))
352                           == sizeof(random))) {
353
354             /* random output of public drbg */
355             result[0].pid = pid;
356             result[0].private = 0;
357             memcpy(result[0].random, &random[0], RANDOM_SIZE);
358
359             /* random output of private drbg */
360             result[1].pid = pid;
361             result[1].private = 1;
362             memcpy(result[1].random, &random[RANDOM_SIZE], RANDOM_SIZE);
363
364             rv = 1;
365         }
366
367         /* close the read end */
368         close(fd[0]);
369
370         return rv;
371
372     } else {
373
374         /* I'm the child; close the read end */
375         close(fd[0]);
376
377         /* check whether all three DRBGs reseed and send output to parent */
378         if (TEST_true(test_drbg_reseed(1, primary, public, private,
379                                         &random[0], &random[RANDOM_SIZE],
380                                        1, 1, 1, 0))
381             && TEST_true(write(fd[1], random, sizeof(random))
382                          == sizeof(random))) {
383
384             rv = 1;
385         }
386
387         /* close the write end */
388         close(fd[1]);
389
390         /* convert boolean to exit code */
391         exit(rv == 0);
392     }
393 }
394
395 static int test_rand_reseed_on_fork(EVP_RAND_CTX *primary,
396                                     EVP_RAND_CTX *public,
397                                     EVP_RAND_CTX *private)
398 {
399     unsigned int i;
400     pid_t pid = getpid();
401     int verbose = (getenv("V") != NULL);
402     int success = 1;
403     int duplicate[2] = {0, 0};
404     unsigned char random[2 * RANDOM_SIZE];
405     unsigned char sample[DRBG_FORK_RESULT_COUNT * RANDOM_SIZE];
406     unsigned char *psample = &sample[0];
407     drbg_fork_result result[DRBG_FORK_RESULT_COUNT];
408     drbg_fork_result *presult = &result[2];
409
410     memset(&result,  0, sizeof(result));
411
412     for (i = 1 ; i <= DRBG_FORK_COUNT ; ++i) {
413
414         presult[0].pindex = presult[1].pindex = i;
415
416         sprintf(presult[0].name, "child %d", i);
417         strcpy(presult[1].name, presult[0].name);
418
419         /* collect the random output of the children */
420         if (!TEST_true(test_drbg_reseed_in_child(primary,
421                                                  public,
422                                                  private,
423                                                  presult)))
424             return 0;
425
426         presult += 2;
427     }
428
429     /* collect the random output of the parent */
430     if (!TEST_true(test_drbg_reseed(1,
431                                     primary, public, private,
432                                     &random[0], &random[RANDOM_SIZE],
433                                     0, 0, 0, 0)))
434         return 0;
435
436     strcpy(result[0].name, "parent");
437     strcpy(result[1].name, "parent");
438
439     /* output of public drbg */
440     result[0].pid = pid;
441     result[0].private = 0;
442     memcpy(result[0].random, &random[0], RANDOM_SIZE);
443
444     /* output of private drbg */
445     result[1].pid = pid;
446     result[1].private = 1;
447     memcpy(result[1].random, &random[RANDOM_SIZE], RANDOM_SIZE);
448
449     /* collect all sampled random data in a single buffer */
450     for (i = 0 ; i < DRBG_FORK_RESULT_COUNT ; ++i) {
451         memcpy(psample, &result[i].random[0], RANDOM_SIZE);
452         psample += RANDOM_SIZE;
453     }
454
455     /* sort the results... */
456     qsort(result, DRBG_FORK_RESULT_COUNT, sizeof(drbg_fork_result),
457           compare_drbg_fork_result);
458
459     /* ...and count duplicate prefixes by looking at the first byte only */
460     for (i = 1 ; i < DRBG_FORK_RESULT_COUNT ; ++i) {
461         if (result[i].random[0] == result[i-1].random[0]) {
462             /* count public and private duplicates separately */
463             ++duplicate[result[i].private];
464         }
465     }
466
467     if (duplicate[0] >= DRBG_FORK_COUNT - 1) {
468         /* just too many duplicates to be a coincidence */
469         TEST_note("ERROR: %d duplicate prefixes in public random output", duplicate[0]);
470         success = 0;
471     }
472
473     if (duplicate[1] >= DRBG_FORK_COUNT - 1) {
474         /* just too many duplicates to be a coincidence */
475         TEST_note("ERROR: %d duplicate prefixes in private random output", duplicate[1]);
476         success = 0;
477     }
478
479     duplicate[0] = 0;
480
481     /* sort the two-byte chunks... */
482     qsort(sample, sizeof(sample)/2, 2, compare_rand_chunk);
483
484     /* ...and count duplicate chunks */
485     for (i = 2, psample = sample + 2 ; i < sizeof(sample) ; i += 2, psample += 2) {
486         if (compare_rand_chunk(psample - 2, psample) == 0)
487             ++duplicate[0];
488     }
489
490     if (duplicate[0] >= DRBG_FORK_COUNT - 1) {
491         /* just too many duplicates to be a coincidence */
492         TEST_note("ERROR: %d duplicate chunks in random output", duplicate[0]);
493         success = 0;
494     }
495
496     if (verbose || !success) {
497
498         for (i = 0 ; i < DRBG_FORK_RESULT_COUNT ; ++i) {
499             char *rand_hex = OPENSSL_buf2hexstr(result[i].random, RANDOM_SIZE);
500
501             TEST_note("    random: %s, pid: %d (%s, %s)",
502                       rand_hex,
503                       result[i].pid,
504                       result[i].name,
505                       result[i].private ? "private" : "public"
506                       );
507
508             OPENSSL_free(rand_hex);
509         }
510     }
511
512     return success;
513 }
514
515 static int test_rand_fork_safety(int i)
516 {
517     int success = 1;
518     unsigned char random[1];
519     EVP_RAND_CTX *primary, *public, *private;
520
521     /* All three DRBGs should be non-null */
522     if (!TEST_ptr(primary = RAND_get0_primary(NULL))
523         || !TEST_ptr(public = RAND_get0_public(NULL))
524         || !TEST_ptr(private = RAND_get0_private(NULL)))
525         return 0;
526
527     /* run the actual test */
528     if (!TEST_true(test_rand_reseed_on_fork(primary, public, private)))
529         success = 0;
530
531     /* request a single byte from each of the DRBGs before the next run */
532     if (!TEST_true(RAND_bytes(random, 1) && RAND_priv_bytes(random, 1)))
533         success = 0;
534
535     return success;
536 }
537 #endif
538
539 /*
540  * Test whether the default rand_method (RAND_OpenSSL()) is
541  * setup correctly, in particular whether reseeding  works
542  * as designed.
543  */
544 static int test_rand_reseed(void)
545 {
546     EVP_RAND_CTX *primary, *public, *private;
547     unsigned char rand_add_buf[256];
548     int rv = 0;
549     time_t before_reseed;
550
551     if (crngt_skip())
552         return TEST_skip("CRNGT cannot be disabled");
553
554     /* Check whether RAND_OpenSSL() is the default method */
555     if (!TEST_ptr_eq(RAND_get_rand_method(), RAND_OpenSSL()))
556         return 0;
557
558     /* All three DRBGs should be non-null */
559     if (!TEST_ptr(primary = RAND_get0_primary(NULL))
560         || !TEST_ptr(public = RAND_get0_public(NULL))
561         || !TEST_ptr(private = RAND_get0_private(NULL)))
562         return 0;
563
564     /* There should be three distinct DRBGs, two of them chained to primary */
565     if (!TEST_ptr_ne(public, private)
566         || !TEST_ptr_ne(public, primary)
567         || !TEST_ptr_ne(private, primary)
568         || !TEST_ptr_eq(prov_rand(public)->parent, prov_rand(primary))
569         || !TEST_ptr_eq(prov_rand(private)->parent, prov_rand(primary)))
570         return 0;
571
572     /* Disable CRNG testing for the primary DRBG */
573     if (!TEST_true(disable_crngt(primary)))
574         return 0;
575
576     /* uninstantiate the three global DRBGs */
577     EVP_RAND_uninstantiate(primary);
578     EVP_RAND_uninstantiate(private);
579     EVP_RAND_uninstantiate(public);
580
581
582     /*
583      * Test initial seeding of shared DRBGs
584      */
585     if (!TEST_true(test_drbg_reseed(1,
586                                     primary, public, private,
587                                     NULL, NULL,
588                                     1, 1, 1, 0)))
589         goto error;
590
591
592     /*
593      * Test initial state of shared DRBGs
594      */
595     if (!TEST_true(test_drbg_reseed(1,
596                                     primary, public, private,
597                                     NULL, NULL,
598                                     0, 0, 0, 0)))
599         goto error;
600
601     /*
602      * Test whether the public and private DRBG are both reseeded when their
603      * reseed counters differ from the primary's reseed counter.
604      */
605     inc_reseed_counter(primary);
606     if (!TEST_true(test_drbg_reseed(1,
607                                     primary, public, private,
608                                     NULL, NULL,
609                                     0, 1, 1, 0)))
610         goto error;
611
612     /*
613      * Test whether the public DRBG is reseeded when its reseed counter differs
614      * from the primary's reseed counter.
615      */
616     inc_reseed_counter(primary);
617     inc_reseed_counter(private);
618     if (!TEST_true(test_drbg_reseed(1,
619                                     primary, public, private,
620                                     NULL, NULL,
621                                     0, 1, 0, 0)))
622         goto error;
623
624     /*
625      * Test whether the private DRBG is reseeded when its reseed counter differs
626      * from the primary's reseed counter.
627      */
628     inc_reseed_counter(primary);
629     inc_reseed_counter(public);
630     if (!TEST_true(test_drbg_reseed(1,
631                                     primary, public, private,
632                                     NULL, NULL,
633                                     0, 0, 1, 0)))
634         goto error;
635
636     /* fill 'randomness' buffer with some arbitrary data */
637     memset(rand_add_buf, 'r', sizeof(rand_add_buf));
638
639 #ifndef FIPS_MODULE
640     /*
641      * Test whether all three DRBGs are reseeded by RAND_add().
642      * The before_reseed time has to be measured here and passed into the
643      * test_drbg_reseed() test, because the primary DRBG gets already reseeded
644      * in RAND_add(), whence the check for the condition
645      * before_reseed <= reseed_time(primary) will fail if the time value happens
646      * to increase between the RAND_add() and the test_drbg_reseed() call.
647      */
648     before_reseed = time(NULL);
649     RAND_add(rand_add_buf, sizeof(rand_add_buf), sizeof(rand_add_buf));
650     if (!TEST_true(test_drbg_reseed(1,
651                                     primary, public, private,
652                                     NULL, NULL,
653                                     1, 1, 1,
654                                     before_reseed)))
655         goto error;
656 #else /* FIPS_MODULE */
657     /*
658      * In FIPS mode, random data provided by the application via RAND_add()
659      * is not considered a trusted entropy source. It is only treated as
660      * additional_data and no reseeding is forced. This test assures that
661      * no reseeding occurs.
662      */
663     before_reseed = time(NULL);
664     RAND_add(rand_add_buf, sizeof(rand_add_buf), sizeof(rand_add_buf));
665     if (!TEST_true(test_drbg_reseed(1,
666                                     primary, public, private,
667                                     NULL, NULL,
668                                     0, 0, 0,
669                                     before_reseed)))
670         goto error;
671 #endif
672
673     rv = 1;
674
675 error:
676    return rv;
677 }
678
679 #if defined(OPENSSL_THREADS)
680 static int multi_thread_rand_bytes_succeeded = 1;
681 static int multi_thread_rand_priv_bytes_succeeded = 1;
682
683 static int set_reseed_time_interval(EVP_RAND_CTX *drbg, int t)
684 {
685     OSSL_PARAM params[2];
686
687     params[0] = OSSL_PARAM_construct_int(OSSL_DRBG_PARAM_RESEED_TIME_INTERVAL,
688                                          &t);
689     params[1] = OSSL_PARAM_construct_end();
690     return EVP_RAND_set_ctx_params(drbg, params);
691 }
692
693 static void run_multi_thread_test(void)
694 {
695     unsigned char buf[256];
696     time_t start = time(NULL);
697     EVP_RAND_CTX *public = NULL, *private = NULL;
698
699     if (!TEST_ptr(public = RAND_get0_public(NULL))
700             || !TEST_ptr(private = RAND_get0_private(NULL))
701             || !TEST_true(set_reseed_time_interval(private, 1))
702             || !TEST_true(set_reseed_time_interval(public, 1))) {
703         multi_thread_rand_bytes_succeeded = 0;
704         return;
705     }
706
707     do {
708         if (rand_bytes(buf, sizeof(buf)) <= 0)
709             multi_thread_rand_bytes_succeeded = 0;
710         if (rand_priv_bytes(buf, sizeof(buf)) <= 0)
711             multi_thread_rand_priv_bytes_succeeded = 0;
712     }
713     while (time(NULL) - start < 5);
714 }
715
716 # if defined(OPENSSL_SYS_WINDOWS)
717
718 typedef HANDLE thread_t;
719
720 static DWORD WINAPI thread_run(LPVOID arg)
721 {
722     run_multi_thread_test();
723     /*
724      * Because we're linking with a static library, we must stop each
725      * thread explicitly, or so says OPENSSL_thread_stop(3)
726      */
727     OPENSSL_thread_stop();
728     return 0;
729 }
730
731 static int run_thread(thread_t *t)
732 {
733     *t = CreateThread(NULL, 0, thread_run, NULL, 0, NULL);
734     return *t != NULL;
735 }
736
737 static int wait_for_thread(thread_t thread)
738 {
739     return WaitForSingleObject(thread, INFINITE) == 0;
740 }
741
742 # else
743
744 typedef pthread_t thread_t;
745
746 static void *thread_run(void *arg)
747 {
748     run_multi_thread_test();
749     /*
750      * Because we're linking with a static library, we must stop each
751      * thread explicitly, or so says OPENSSL_thread_stop(3)
752      */
753     OPENSSL_thread_stop();
754     return NULL;
755 }
756
757 static int run_thread(thread_t *t)
758 {
759     return pthread_create(t, NULL, thread_run, NULL) == 0;
760 }
761
762 static int wait_for_thread(thread_t thread)
763 {
764     return pthread_join(thread, NULL) == 0;
765 }
766
767 # endif
768
769 /*
770  * The main thread will also run the test, so we'll have THREADS+1 parallel
771  * tests running
772  */
773 # define THREADS 3
774
775 static int test_multi_thread(void)
776 {
777     thread_t t[THREADS];
778     int i;
779
780     for (i = 0; i < THREADS; i++)
781         run_thread(&t[i]);
782     run_multi_thread_test();
783     for (i = 0; i < THREADS; i++)
784         wait_for_thread(t[i]);
785
786     if (!TEST_true(multi_thread_rand_bytes_succeeded))
787         return 0;
788     if (!TEST_true(multi_thread_rand_priv_bytes_succeeded))
789         return 0;
790
791     return 1;
792 }
793 #endif
794
795 static EVP_RAND_CTX *new_drbg(EVP_RAND_CTX *parent)
796 {
797     OSSL_PARAM params[2];
798     EVP_RAND *rand = NULL;
799     EVP_RAND_CTX *drbg = NULL;
800
801     params[0] = OSSL_PARAM_construct_utf8_string(OSSL_DRBG_PARAM_CIPHER,
802                                                  "AES-256-CTR", 0);
803     params[1] = OSSL_PARAM_construct_end();
804
805     if (!TEST_ptr(rand = EVP_RAND_fetch(NULL, "CTR-DRBG", NULL))
806             || !TEST_ptr(drbg = EVP_RAND_CTX_new(rand, parent))
807             || !TEST_true(EVP_RAND_set_ctx_params(drbg, params))) {
808         EVP_RAND_CTX_free(drbg);
809         drbg = NULL;
810     }
811     EVP_RAND_free(rand);
812     return drbg;
813 }
814
815 static int test_rand_prediction_resistance(void)
816 {
817     EVP_RAND_CTX *x = NULL, *y = NULL, *z = NULL;
818     unsigned char buf1[51], buf2[sizeof(buf1)];
819     int ret = 0, xreseed, yreseed, zreseed;
820
821     if (crngt_skip())
822         return TEST_skip("CRNGT cannot be disabled");
823
824     /* Initialise a three long DRBG chain */
825     if (!TEST_ptr(x = new_drbg(NULL))
826         || !TEST_true(disable_crngt(x))
827         || !TEST_true(EVP_RAND_instantiate(x, 0, 0, NULL, 0))
828         || !TEST_ptr(y = new_drbg(x))
829         || !TEST_true(EVP_RAND_instantiate(y, 0, 0, NULL, 0))
830         || !TEST_ptr(z = new_drbg(y))
831         || !TEST_true(EVP_RAND_instantiate(z, 0, 0, NULL, 0)))
832         goto err;
833
834     /*
835      * During a normal reseed, only the last DRBG in the chain should
836      * be reseeded.
837      */
838     inc_reseed_counter(y);
839     xreseed = reseed_counter(x);
840     yreseed = reseed_counter(y);
841     zreseed = reseed_counter(z);
842     if (!TEST_true(EVP_RAND_reseed(z, 0, NULL, 0, NULL, 0))
843         || !TEST_int_eq(reseed_counter(x), xreseed)
844         || !TEST_int_eq(reseed_counter(y), yreseed)
845         || !TEST_int_gt(reseed_counter(z), zreseed))
846         goto err;
847
848     /*
849      * When prediction resistance is requested, the request should be
850      * propagated to the primary, so that the entire DRBG chain reseeds.
851      */
852     zreseed = reseed_counter(z);
853     if (!TEST_true(EVP_RAND_reseed(z, 1, NULL, 0, NULL, 0))
854         || !TEST_int_gt(reseed_counter(x), xreseed)
855         || !TEST_int_gt(reseed_counter(y), yreseed)
856         || !TEST_int_gt(reseed_counter(z), zreseed))
857         goto err;
858
859     /*
860      * During a normal generate, only the last DRBG should be reseed */
861     inc_reseed_counter(y);
862     xreseed = reseed_counter(x);
863     yreseed = reseed_counter(y);
864     zreseed = reseed_counter(z);
865     if (!TEST_true(EVP_RAND_generate(z, buf1, sizeof(buf1), 0, 0, NULL, 0))
866         || !TEST_int_eq(reseed_counter(x), xreseed)
867         || !TEST_int_eq(reseed_counter(y), yreseed)
868         || !TEST_int_gt(reseed_counter(z), zreseed))
869         goto err;
870
871     /*
872      * When a prediction resistant generate is requested, the request
873      * should be propagated to the primary, reseeding the entire DRBG chain.
874      */
875     zreseed = reseed_counter(z);
876     if (!TEST_true(EVP_RAND_generate(z, buf2, sizeof(buf2), 0, 1, NULL, 0))
877         || !TEST_int_gt(reseed_counter(x), xreseed)
878         || !TEST_int_gt(reseed_counter(y), yreseed)
879         || !TEST_int_gt(reseed_counter(z), zreseed)
880         || !TEST_mem_ne(buf1, sizeof(buf1), buf2, sizeof(buf2)))
881         goto err;
882
883     /* Verify that a normal reseed still only reseeds the last DRBG */
884     inc_reseed_counter(y);
885     xreseed = reseed_counter(x);
886     yreseed = reseed_counter(y);
887     zreseed = reseed_counter(z);
888     if (!TEST_true(EVP_RAND_reseed(z, 0, NULL, 0, NULL, 0))
889         || !TEST_int_eq(reseed_counter(x), xreseed)
890         || !TEST_int_eq(reseed_counter(y), yreseed)
891         || !TEST_int_gt(reseed_counter(z), zreseed))
892         goto err;
893
894     ret = 1;
895 err:
896     EVP_RAND_CTX_free(z);
897     EVP_RAND_CTX_free(y);
898     EVP_RAND_CTX_free(x);
899     return ret;
900 }
901
902 int setup_tests(void)
903 {
904     ADD_TEST(test_rand_reseed);
905 #if defined(OPENSSL_SYS_UNIX)
906     ADD_ALL_TESTS(test_rand_fork_safety, RANDOM_SIZE);
907 #endif
908     ADD_TEST(test_rand_prediction_resistance);
909 #if defined(OPENSSL_THREADS)
910     ADD_TEST(test_multi_thread);
911 #endif
912     return 1;
913 }