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