LCOV - code coverage report
Current view: top level - tests - random.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 162 329 49.2 %
Date: 2017-03-02 16:44:37 Functions: 8 13 61.5 %

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

Generated by: LCOV version 1.13