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