Fix building t-lock for WIN32
[libgcrypt.git] / tests / random.c
1 /* random.c - part of the Libgcrypt test suite.
2    Copyright (C) 2005 Free Software Foundation, Inc.
3
4    This program is free software; you can redistribute it and/or
5    modify it under the terms of the GNU General Public License as
6    published by the Free Software Foundation; either version 2 of the
7    License, or (at your option) any later version.
8
9    This program is distributed in the hope that it will be useful, but
10    WITHOUT ANY WARRANTY; without even the implied warranty of
11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12    General Public License for more details.
13
14    You should have received a copy of the GNU General Public License
15    along with this program; if not, write to the Free Software
16    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
17    USA.  */
18
19 #ifdef HAVE_CONFIG_H
20 #include <config.h>
21 #endif
22 #include <assert.h>
23 #include <stdio.h>
24 #include <string.h>
25 #include <stdlib.h>
26 #include <errno.h>
27 #include <unistd.h>
28 #ifndef HAVE_W32_SYSTEM
29 # include <signal.h>
30 # include <sys/wait.h>
31 #endif
32
33 #include "stopwatch.h"
34
35
36 #define PGM "random"
37 #define NEED_EXTRA_TEST_SUPPORT 1
38 #include "t-common.h"
39
40 static int with_progress;
41
42
43 /* Prepend FNAME with the srcdir environment variable's value and
44  * return an allocated filename.  */
45 static char *
46 prepend_srcdir (const char *fname)
47 {
48   static const char *srcdir;
49   char *result;
50
51   if (!srcdir && !(srcdir = getenv ("srcdir")))
52     srcdir = ".";
53
54   result = xmalloc (strlen (srcdir) + 1 + strlen (fname) + 1);
55   strcpy (result, srcdir);
56   strcat (result, "/");
57   strcat (result, fname);
58   return result;
59 }
60
61
62 static void
63 print_hex (const char *text, const void *buf, size_t n)
64 {
65   const unsigned char *p = buf;
66
67   info ("%s", text);
68   for (; n; n--, p++)
69     fprintf (stderr, "%02X", *p);
70   putc ('\n', stderr);
71 }
72
73
74 static void
75 progress_cb (void *cb_data, const char *what, int printchar,
76              int current, int total)
77 {
78   (void)cb_data;
79
80   info ("progress (%s %c %d %d)\n", what, printchar, current, total);
81   fflush (stderr);
82 }
83
84
85 #ifndef HAVE_W32_SYSTEM
86 static int
87 writen (int fd, const void *buf, size_t nbytes)
88 {
89   size_t nleft = nbytes;
90   int nwritten;
91
92   while (nleft > 0)
93     {
94       nwritten = write (fd, buf, nleft);
95       if (nwritten < 0)
96         {
97           if (errno == EINTR)
98             nwritten = 0;
99           else
100             return -1;
101         }
102       nleft -= nwritten;
103       buf = (const char*)buf + nwritten;
104     }
105
106   return 0;
107 }
108 #endif /*!HAVE_W32_SYSTEM*/
109
110
111 #ifndef HAVE_W32_SYSTEM
112 static int
113 readn (int fd, void *buf, size_t buflen, size_t *ret_nread)
114 {
115   size_t nleft = buflen;
116   int nread;
117
118   while ( nleft > 0 )
119     {
120       nread = read ( fd, buf, nleft );
121       if (nread < 0)
122         {
123           if (nread == EINTR)
124             nread = 0;
125           else
126             return -1;
127         }
128       else if (!nread)
129         break; /* EOF */
130       nleft -= nread;
131       buf = (char*)buf + nread;
132     }
133   if (ret_nread)
134     *ret_nread = buflen - nleft;
135   return 0;
136 }
137 #endif /*!HAVE_W32_SYSTEM*/
138
139
140 /* Check that forking won't return the same random. */
141 static void
142 check_forking (void)
143 {
144 #ifdef HAVE_W32_SYSTEM
145   if (verbose)
146     info ("check_forking skipped: not applicable on Windows\n");
147 #else /*!HAVE_W32_SYSTEM*/
148   pid_t pid;
149   int rp[2];
150   int i, status;
151   size_t nread;
152   char tmp1[16], tmp1c[16], tmp1p[16];
153
154   if (verbose)
155     info ("checking that a fork won't cause the same random output\n");
156
157   /* We better make sure that the RNG has been initialzied. */
158   gcry_randomize (tmp1, sizeof tmp1, GCRY_STRONG_RANDOM);
159   if (verbose)
160     print_hex ("initial random: ", tmp1, sizeof tmp1);
161
162   if (pipe (rp) == -1)
163     die ("pipe failed: %s\n", strerror (errno));
164
165   pid = fork ();
166   if (pid == (pid_t)(-1))
167     die ("fork failed: %s\n", strerror (errno));
168   if (!pid)
169     {
170       gcry_randomize (tmp1c, sizeof tmp1c, GCRY_STRONG_RANDOM);
171       if (writen (rp[1], tmp1c, sizeof tmp1c))
172         die ("write failed: %s\n", strerror (errno));
173       if (verbose)
174         {
175           print_hex ("  child random: ", tmp1c, sizeof tmp1c);
176           fflush (stdout);
177         }
178       _exit (0);
179     }
180   gcry_randomize (tmp1p, sizeof tmp1p, GCRY_STRONG_RANDOM);
181   if (verbose)
182     print_hex (" parent random: ", tmp1p, sizeof tmp1p);
183
184   close (rp[1]);
185   if (readn (rp[0], tmp1c, sizeof tmp1c, &nread))
186     die ("read failed: %s\n", strerror (errno));
187   if (nread != sizeof tmp1c)
188     die ("read too short\n");
189
190   while ( (i=waitpid (pid, &status, 0)) == -1 && errno == EINTR)
191     ;
192   if (i != (pid_t)(-1)
193       && WIFEXITED (status) && !WEXITSTATUS (status))
194     ;
195   else
196     die ("child failed\n");
197
198   if (!memcmp (tmp1p, tmp1c, sizeof tmp1c))
199     die ("parent and child got the same random number\n");
200 #endif  /*!HAVE_W32_SYSTEM*/
201 }
202
203
204
205 /* Check that forking won't return the same nonce. */
206 static void
207 check_nonce_forking (void)
208 {
209 #ifdef HAVE_W32_SYSTEM
210   if (verbose)
211     info ("check_nonce_forking skipped: not applicable on Windows\n");
212 #else /*!HAVE_W32_SYSTEM*/
213   pid_t pid;
214   int rp[2];
215   int i, status;
216   size_t nread;
217   char nonce1[10], nonce1c[10], nonce1p[10];
218
219   if (verbose)
220     info ("checking that a fork won't cause the same nonce output\n");
221
222   /* We won't get the same nonce back if we never initialized the
223      nonce subsystem, thus we get one nonce here and forget about
224      it. */
225   gcry_create_nonce (nonce1, sizeof nonce1);
226   if (verbose)
227     print_hex ("initial nonce: ", nonce1, sizeof nonce1);
228
229   if (pipe (rp) == -1)
230     die ("pipe failed: %s\n", strerror (errno));
231
232   pid = fork ();
233   if (pid == (pid_t)(-1))
234     die ("fork failed: %s\n", strerror (errno));
235   if (!pid)
236     {
237       gcry_create_nonce (nonce1c, sizeof nonce1c);
238       if (writen (rp[1], nonce1c, sizeof nonce1c))
239         die ("write failed: %s\n", strerror (errno));
240       if (verbose)
241         {
242           print_hex ("  child nonce: ", nonce1c, sizeof nonce1c);
243           fflush (stdout);
244         }
245       _exit (0);
246     }
247   gcry_create_nonce (nonce1p, sizeof nonce1p);
248   if (verbose)
249     print_hex (" parent nonce: ", nonce1p, sizeof nonce1p);
250
251   close (rp[1]);
252   if (readn (rp[0], nonce1c, sizeof nonce1c, &nread))
253     die ("read failed: %s\n", strerror (errno));
254   if (nread != sizeof nonce1c)
255     die ("read too short\n");
256
257   while ( (i=waitpid (pid, &status, 0)) == -1 && errno == EINTR)
258     ;
259   if (i != (pid_t)(-1)
260       && WIFEXITED (status) && !WEXITSTATUS (status))
261     ;
262   else
263     die ("child failed\n");
264
265   if (!memcmp (nonce1p, nonce1c, sizeof nonce1c))
266     die ("parent and child got the same nonce\n");
267 #endif  /*!HAVE_W32_SYSTEM*/
268 }
269
270
271 /* Check that a closed random device os re-opened if needed. */
272 static void
273 check_close_random_device (void)
274 {
275 #ifdef HAVE_W32_SYSTEM
276   if (verbose)
277     info ("check_close_random_device skipped: not applicable on Windows\n");
278 #else /*!HAVE_W32_SYSTEM*/
279   pid_t pid;
280   int i, status;
281   char buf[4];
282
283   if (verbose)
284     info ("checking that close_random_device works\n");
285
286   gcry_randomize (buf, sizeof buf, GCRY_STRONG_RANDOM);
287   if (verbose)
288     print_hex ("parent random: ", buf, sizeof buf);
289
290   pid = fork ();
291   if (pid == (pid_t)(-1))
292     die ("fork failed: %s\n", strerror (errno));
293   if (!pid)
294     {
295       xgcry_control ((GCRYCTL_CLOSE_RANDOM_DEVICE, 0));
296
297       /* The next call will re-open the device.  */
298       gcry_randomize (buf, sizeof buf, GCRY_STRONG_RANDOM);
299       if (verbose)
300         {
301           print_hex ("child random : ", buf, sizeof buf);
302           fflush (stdout);
303         }
304       _exit (0);
305     }
306
307   while ( (i=waitpid (pid, &status, 0)) == -1 && errno == EINTR)
308     ;
309   if (i != (pid_t)(-1)
310       && WIFEXITED (status) && !WEXITSTATUS (status))
311     ;
312   else
313     die ("child failed\n");
314
315 #endif  /*!HAVE_W32_SYSTEM*/
316 }
317
318
319 static int
320 rng_type (void)
321 {
322   int rngtype;
323   if (gcry_control (GCRYCTL_GET_CURRENT_RNG_TYPE, &rngtype))
324     die ("retrieving RNG type failed\n");
325   return rngtype;
326 }
327
328
329 static void
330 check_rng_type_switching (void)
331 {
332   int rngtype, initial;
333   char tmp1[4];
334
335   if (verbose)
336     info ("checking whether RNG type switching works\n");
337
338   rngtype = rng_type ();
339   if (debug)
340     info ("rng type: %d\n", rngtype);
341   initial = rngtype;
342   gcry_randomize (tmp1, sizeof tmp1, GCRY_STRONG_RANDOM);
343   if (debug)
344     print_hex ("  sample: ", tmp1, sizeof tmp1);
345   if (rngtype != rng_type ())
346     die ("RNG type unexpectedly changed\n");
347
348   xgcry_control ((GCRYCTL_SET_PREFERRED_RNG_TYPE, GCRY_RNG_TYPE_SYSTEM));
349
350   rngtype = rng_type ();
351   if (debug)
352     info ("rng type: %d\n", rngtype);
353   if (rngtype != initial)
354     die ("switching to System RNG unexpectedly succeeded\n");
355   gcry_randomize (tmp1, sizeof tmp1, GCRY_STRONG_RANDOM);
356   if (debug)
357     print_hex ("  sample: ", tmp1, sizeof tmp1);
358   if (rngtype != rng_type ())
359     die ("RNG type unexpectedly changed\n");
360
361   xgcry_control ((GCRYCTL_SET_PREFERRED_RNG_TYPE, GCRY_RNG_TYPE_FIPS));
362
363   rngtype = rng_type ();
364   if (debug)
365     info ("rng type: %d\n", rngtype);
366   if (rngtype != initial)
367     die ("switching to FIPS RNG unexpectedly succeeded\n");
368   gcry_randomize (tmp1, sizeof tmp1, GCRY_STRONG_RANDOM);
369   if (debug)
370     print_hex ("  sample: ", tmp1, sizeof tmp1);
371   if (rngtype != rng_type ())
372     die ("RNG type unexpectedly changed\n");
373
374   xgcry_control ((GCRYCTL_SET_PREFERRED_RNG_TYPE, GCRY_RNG_TYPE_STANDARD));
375
376   rngtype = rng_type ();
377   if (debug)
378     info ("rng type: %d\n", rngtype);
379   if (rngtype != GCRY_RNG_TYPE_STANDARD)
380     die ("switching to standard RNG failed\n");
381   gcry_randomize (tmp1, sizeof tmp1, GCRY_STRONG_RANDOM);
382   if (debug)
383     print_hex ("  sample: ", tmp1, sizeof tmp1);
384   if (rngtype != rng_type ())
385     die ("RNG type unexpectedly changed\n");
386 }
387
388
389 static void
390 check_early_rng_type_switching (void)
391 {
392   int rngtype, initial;
393
394   if (verbose)
395     info ("checking whether RNG type switching works in the early stage\n");
396
397   rngtype = rng_type ();
398   if (debug)
399     info ("rng type: %d\n", rngtype);
400   initial = rngtype;
401
402   xgcry_control ((GCRYCTL_SET_PREFERRED_RNG_TYPE, GCRY_RNG_TYPE_SYSTEM));
403
404   rngtype = rng_type ();
405   if (debug)
406     info ("rng type: %d\n", rngtype);
407   if (initial >= GCRY_RNG_TYPE_SYSTEM && rngtype != GCRY_RNG_TYPE_SYSTEM)
408     die ("switching to System RNG failed\n");
409
410   xgcry_control ((GCRYCTL_SET_PREFERRED_RNG_TYPE, GCRY_RNG_TYPE_FIPS));
411
412   rngtype = rng_type ();
413   if (debug)
414     info ("rng type: %d\n", rngtype);
415   if (initial >= GCRY_RNG_TYPE_FIPS && rngtype != GCRY_RNG_TYPE_FIPS)
416     die ("switching to FIPS RNG failed\n");
417
418   xgcry_control ((GCRYCTL_SET_PREFERRED_RNG_TYPE, GCRY_RNG_TYPE_STANDARD));
419
420   rngtype = rng_type ();
421   if (debug)
422     info ("rng type: %d\n", rngtype);
423   if (rngtype != GCRY_RNG_TYPE_STANDARD)
424     die ("switching to standard RNG failed\n");
425 }
426
427
428 static void
429 check_drbg_reinit (void)
430 {
431   static struct { const char *flags; } tv[] = {
432     { NULL },
433     { "" },
434     { "sha1" },
435     { "sha1 pr" },
436     { "sha256" },
437     { "sha256 pr" },
438     { "sha512" },
439     { "sha512 pr" },
440     { "hmac sha1" },
441     { "hmac sha1 pr" },
442     { "hmac sha256" },
443     { "hmac sha256 pr" },
444     { "hmac sha512" },
445     { "hmac sha512 pr" },
446     { "aes sym128" },
447     { "aes sym128 pr" },
448     { "aes sym192" },
449     { "aes sym192 pr" },
450     { "aes sym256" },
451     { "aes sym256 pr" }
452   };
453   int tidx;
454   gpg_error_t err;
455   char pers_string[] = "I'm a doctor, not an engineer.";
456   gcry_buffer_t pers[1];
457
458   if (verbose)
459     info ("checking DRBG_REINIT\n");
460
461   memset (pers, 0, sizeof pers);
462   pers[0].data = pers_string;
463   pers[0].len = strlen (pers_string);
464
465   err = gcry_control (GCRYCTL_DRBG_REINIT, "", NULL, 0, &err);
466   if (gpg_err_code (err) != GPG_ERR_INV_ARG)
467     die ("gcry_control(DRBG_REINIT) guard value did not work\n");
468
469   err = gcry_control (GCRYCTL_DRBG_REINIT, "", NULL, -1, NULL);
470   if (gpg_err_code (err) != GPG_ERR_INV_ARG)
471     die ("gcry_control(DRBG_REINIT) npers negative detection failed\n");
472
473   if (rng_type () != GCRY_RNG_TYPE_FIPS)
474     {
475       err = gcry_control (GCRYCTL_DRBG_REINIT, "", NULL, 0, NULL);
476       if (gpg_err_code (err) != GPG_ERR_NOT_SUPPORTED)
477         die ("DRBG_REINIT worked despite that DRBG is not active\n");
478       return;
479     }
480
481   err = gcry_control (GCRYCTL_DRBG_REINIT, "", NULL, 1, NULL);
482   if (gpg_err_code (err) != GPG_ERR_INV_ARG)
483     die ("_gcry_rngdrbg_reinit failed to detact: (!pers && npers)\n");
484   err = gcry_control (GCRYCTL_DRBG_REINIT, "", pers, 2, NULL);
485   if (gpg_err_code (err) != GPG_ERR_INV_ARG)
486     die ("_gcry_rngdrbg_reinit failed to detect: (pers && npers != 1)\n");
487
488   err = gcry_control (GCRYCTL_DRBG_REINIT, "aes sym128 bad pr ", pers, 1, NULL);
489   if (gpg_err_code (err) != GPG_ERR_INV_FLAG)
490     die ("_gcry_rngdrbg_reinit failed to detect a bad flag\n");
491
492   for (tidx=0; tidx < DIM(tv); tidx++)
493     {
494       err = gcry_control (GCRYCTL_DRBG_REINIT, tv[tidx].flags, NULL, 0, NULL);
495       if (err)
496         die ("_gcry_rngdrbg_reinit failed for \"%s\" w/o pers: %s\n",
497
498              tv[tidx].flags, gpg_strerror (err));
499       err = gcry_control (GCRYCTL_DRBG_REINIT, tv[tidx].flags, pers, 1, NULL);
500       if (err)
501         die ("_gcry_rngdrbg_reinit failed for \"%s\" with pers: %s\n",
502              tv[tidx].flags, gpg_strerror (err));
503       /* fixme: We should extract some random after each test.  */
504     }
505 }
506
507
508 /* Because we want to check initialization behaviour, we need to
509    fork/exec this program with several command line arguments.  We use
510    system, so that these tests work also on Windows.  */
511 static void
512 run_all_rng_tests (const char *program)
513 {
514   static const char *options[] = {
515     "--early-rng-check",
516     "--early-rng-check --prefer-standard-rng",
517     "--early-rng-check --prefer-fips-rng",
518     "--early-rng-check --prefer-system-rng",
519     "--prefer-standard-rng",
520     "--prefer-fips-rng",
521     "--prefer-system-rng",
522     NULL
523   };
524   int idx;
525   size_t len, maxlen;
526   char *cmdline;
527
528   maxlen = 0;
529   for (idx=0; options[idx]; idx++)
530     {
531       len = strlen (options[idx]);
532       if (len > maxlen)
533         maxlen = len;
534     }
535   maxlen += strlen (program);
536   maxlen += strlen (" --in-recursion --verbose --debug --progress");
537   maxlen++;
538   cmdline = malloc (maxlen + 1);
539   if (!cmdline)
540     die ("out of core\n");
541
542   for (idx=0; options[idx]; idx++)
543     {
544       if (verbose)
545         info ("now running with options '%s'\n", options[idx]);
546       strcpy (cmdline, program);
547       strcat (cmdline, " --in-recursion");
548       if (verbose)
549         strcat (cmdline, " --verbose");
550       if (debug)
551         strcat (cmdline, " --debug");
552       if (with_progress)
553         strcat (cmdline, " --progress");
554       strcat (cmdline, " ");
555       strcat (cmdline, options[idx]);
556       if (system (cmdline))
557         die ("running '%s' failed\n", cmdline);
558     }
559
560   free (cmdline);
561 }
562
563
564 static void
565 run_benchmark (void)
566 {
567   char rndbuf[32];
568   int i, j;
569
570   if (verbose)
571     info ("benchmarking GCRY_STRONG_RANDOM (/dev/urandom)\n");
572
573   start_timer ();
574   gcry_randomize (rndbuf, sizeof rndbuf, GCRY_STRONG_RANDOM);
575   stop_timer ();
576
577   info ("getting first 256 bits: %s", elapsed_time (1));
578
579   for (j=0; j < 5; j++)
580     {
581       start_timer ();
582       for (i=0; i < 100; i++)
583         gcry_randomize (rndbuf, sizeof rndbuf, GCRY_STRONG_RANDOM);
584       stop_timer ();
585
586       info ("100 calls of 256 bits each: %s", elapsed_time (100));
587     }
588
589 }
590
591
592 int
593 main (int argc, char **argv)
594 {
595   int last_argc = -1;
596   int early_rng = 0;
597   int in_recursion = 0;
598   int benchmark = 0;
599   int with_seed_file = 0;
600   const char *program = NULL;
601
602   if (argc)
603     {
604       program = *argv;
605       argc--; argv++;
606     }
607   else
608     die ("argv[0] missing\n");
609
610   while (argc && last_argc != argc )
611     {
612       last_argc = argc;
613       if (!strcmp (*argv, "--"))
614         {
615           argc--; argv++;
616           break;
617         }
618       else if (!strcmp (*argv, "--help"))
619         {
620           fputs ("usage: random [options]\n", stdout);
621           exit (0);
622         }
623       else if (!strcmp (*argv, "--verbose"))
624         {
625           verbose = 1;
626           argc--; argv++;
627         }
628       else if (!strcmp (*argv, "--debug"))
629         {
630           debug = verbose = 1;
631           argc--; argv++;
632         }
633       else if (!strcmp (*argv, "--progress"))
634         {
635           argc--; argv++;
636           with_progress = 1;
637         }
638       else if (!strcmp (*argv, "--in-recursion"))
639         {
640           in_recursion = 1;
641           argc--; argv++;
642         }
643       else if (!strcmp (*argv, "--benchmark"))
644         {
645           benchmark = 1;
646           argc--; argv++;
647         }
648       else if (!strcmp (*argv, "--early-rng-check"))
649         {
650           early_rng = 1;
651           argc--; argv++;
652         }
653       else if (!strcmp (*argv, "--with-seed-file"))
654         {
655           with_seed_file = 1;
656           argc--; argv++;
657         }
658       else if (!strcmp (*argv, "--prefer-standard-rng"))
659         {
660           /* This is anyway the default, but we may want to use it for
661              debugging. */
662           xgcry_control ((GCRYCTL_SET_PREFERRED_RNG_TYPE,
663                           GCRY_RNG_TYPE_STANDARD));
664           argc--; argv++;
665         }
666       else if (!strcmp (*argv, "--prefer-fips-rng"))
667         {
668           xgcry_control ((GCRYCTL_SET_PREFERRED_RNG_TYPE, GCRY_RNG_TYPE_FIPS));
669           argc--; argv++;
670         }
671       else if (!strcmp (*argv, "--prefer-system-rng"))
672         {
673           xgcry_control ((GCRYCTL_SET_PREFERRED_RNG_TYPE, GCRY_RNG_TYPE_SYSTEM));
674           argc--; argv++;
675         }
676       else if (!strcmp (*argv, "--disable-hwf"))
677         {
678           argc--;
679           argv++;
680           if (argc)
681             {
682               if (gcry_control (GCRYCTL_DISABLE_HWF, *argv, NULL))
683                 die ("unknown hardware feature `%s'\n", *argv);
684               argc--;
685               argv++;
686             }
687         }
688     }
689
690 #ifndef HAVE_W32_SYSTEM
691   signal (SIGPIPE, SIG_IGN);
692 #endif
693
694   if (benchmark && !verbose)
695     verbose = 1;
696
697   if (early_rng)
698     {
699       /* Don't switch RNG in fips mode. */
700       if (!gcry_fips_mode_active())
701         check_early_rng_type_switching ();
702     }
703
704   xgcry_control ((GCRYCTL_DISABLE_SECMEM, 0));
705   if (!gcry_check_version (GCRYPT_VERSION))
706     die ("version mismatch\n");
707
708   if (with_progress)
709     gcry_set_progress_handler (progress_cb, NULL);
710
711   if (with_seed_file)
712     {
713       char *fname = prepend_srcdir ("random.seed");
714
715       if (access (fname, F_OK))
716         info ("random seed file '%s' not found\n", fname);
717       gcry_control (GCRYCTL_SET_RANDOM_SEED_FILE, fname);
718       xfree (fname);
719     }
720
721   xgcry_control ((GCRYCTL_INITIALIZATION_FINISHED, 0));
722   if (debug)
723     xgcry_control ((GCRYCTL_SET_DEBUG_FLAGS, 1u, 0));
724
725   if (benchmark)
726     {
727       run_benchmark ();
728     }
729   else if (!in_recursion)
730     {
731       check_forking ();
732       check_nonce_forking ();
733       check_close_random_device ();
734     }
735   /* For now we do not run the drgb_reinit check from "make check" due
736      to its high requirement for entropy.  */
737   if (!benchmark && !getenv ("GCRYPT_IN_REGRESSION_TEST"))
738     check_drbg_reinit ();
739
740   /* Don't switch RNG in fips mode.  */
741   if (!benchmark && !gcry_fips_mode_active())
742     check_rng_type_switching ();
743
744   if (!in_recursion && !benchmark)
745     run_all_rng_tests (program);
746
747   /* Print this info last so that it does not influence the
748    * initialization and thus the benchmarking.  */
749   if (!in_recursion && verbose)
750     {
751       char *buf;
752       char *fields[5];
753
754       buf = gcry_get_config (0, "rng-type");
755       if (buf
756           && split_fields_colon (buf, fields, DIM (fields)) >= 5
757           && atoi (fields[4]) > 0)
758         info ("The JENT RNG was active\n");
759       gcry_free (buf);
760     }
761
762   if (debug)
763     xgcry_control ((GCRYCTL_DUMP_RANDOM_STATS));
764
765   return 0;
766 }