/* random.c - part of the Libgcrypt test suite.
   Copyright (C) 2005 Free Software Foundation, Inc.

   This program is free software; you can redistribute it and/or
   modify it under the terms of the GNU General Public License as
   published by the Free Software Foundation; either version 2 of the
   License, or (at your option) any later version.

   This program is distributed in the hope that it will be useful, but
   WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
   USA.  */

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <assert.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#ifndef HAVE_W32_SYSTEM
# include <signal.h>
# include <unistd.h>
# include <sys/wait.h>
#endif

#include "../src/gcrypt-int.h"

#define PGM "random"


static int verbose;
static int debug;
static int with_progress;

static void
die (const char *format, ...)
{
  va_list arg_ptr;

  va_start (arg_ptr, format);
  fputs ( PGM ": ", stderr);
  vfprintf (stderr, format, arg_ptr);
  va_end (arg_ptr);
  exit (1);
}


static void
inf (const char *format, ...)
{
  va_list arg_ptr;

  va_start (arg_ptr, format);
  fputs ( PGM ": ", stderr);
  vfprintf (stderr, format, arg_ptr);
  va_end (arg_ptr);
}


static void
print_hex (const char *text, const void *buf, size_t n)
{
  const unsigned char *p = buf;

  inf ("%s", text);
  for (; n; n--, p++)
    fprintf (stderr, "%02X", *p);
  putc ('\n', stderr);
}


static void
progress_cb (void *cb_data, const char *what, int printchar,
             int current, int total)
{
  (void)cb_data;

  inf ("progress (%s %c %d %d)\n", what, printchar, current, total);
  fflush (stderr);
}



static int
writen (int fd, const void *buf, size_t nbytes)
{
  size_t nleft = nbytes;
  int nwritten;

  while (nleft > 0)
    {
      nwritten = write (fd, buf, nleft);
      if (nwritten < 0)
        {
          if (errno == EINTR)
            nwritten = 0;
          else
            return -1;
        }
      nleft -= nwritten;
      buf = (const char*)buf + nwritten;
    }

  return 0;
}

static int
readn (int fd, void *buf, size_t buflen, size_t *ret_nread)
{
  size_t nleft = buflen;
  int nread;

  while ( nleft > 0 )
    {
      nread = read ( fd, buf, nleft );
      if (nread < 0)
        {
          if (nread == EINTR)
            nread = 0;
          else
            return -1;
        }
      else if (!nread)
        break; /* EOF */
      nleft -= nread;
      buf = (char*)buf + nread;
    }
  if (ret_nread)
    *ret_nread = buflen - nleft;
  return 0;
}



/* Check that forking won't return the same random. */
static void
check_forking (void)
{
#ifdef HAVE_W32_SYSTEM
  if (verbose)
    inf ("check_forking skipped: not applicable on Windows\n");
#else /*!HAVE_W32_SYSTEM*/
  pid_t pid;
  int rp[2];
  int i, status;
  size_t nread;
  char tmp1[16], tmp1c[16], tmp1p[16];

  if (verbose)
    inf ("checking that a fork won't cause the same random output\n");

  /* We better make sure that the RNG has been initialzied. */
  gcry_randomize (tmp1, sizeof tmp1, GCRY_STRONG_RANDOM);
  if (verbose)
    print_hex ("initial random: ", tmp1, sizeof tmp1);

  if (pipe (rp) == -1)
    die ("pipe failed: %s\n", strerror (errno));

  pid = fork ();
  if (pid == (pid_t)(-1))
    die ("fork failed: %s\n", strerror (errno));
  if (!pid)
    {
      gcry_randomize (tmp1c, sizeof tmp1c, GCRY_STRONG_RANDOM);
      if (writen (rp[1], tmp1c, sizeof tmp1c))
        die ("write failed: %s\n", strerror (errno));
      if (verbose)
        {
          print_hex ("  child random: ", tmp1c, sizeof tmp1c);
          fflush (stdout);
        }
      _exit (0);
    }
  gcry_randomize (tmp1p, sizeof tmp1p, GCRY_STRONG_RANDOM);
  if (verbose)
    print_hex (" parent random: ", tmp1p, sizeof tmp1p);

  close (rp[1]);
  if (readn (rp[0], tmp1c, sizeof tmp1c, &nread))
    die ("read failed: %s\n", strerror (errno));
  if (nread != sizeof tmp1c)
    die ("read too short\n");

  while ( (i=waitpid (pid, &status, 0)) == -1 && errno == EINTR)
    ;
  if (i != (pid_t)(-1)
      && WIFEXITED (status) && !WEXITSTATUS (status))
    ;
  else
    die ("child failed\n");

  if (!memcmp (tmp1p, tmp1c, sizeof tmp1c))
    die ("parent and child got the same random number\n");
#endif  /*!HAVE_W32_SYSTEM*/
}



/* Check that forking won't return the same nonce. */
static void
check_nonce_forking (void)
{
#ifdef HAVE_W32_SYSTEM
  if (verbose)
    inf ("check_nonce_forking skipped: not applicable on Windows\n");
#else /*!HAVE_W32_SYSTEM*/
  pid_t pid;
  int rp[2];
  int i, status;
  size_t nread;
  char nonce1[10], nonce1c[10], nonce1p[10];

  if (verbose)
    inf ("checking that a fork won't cause the same nonce output\n");

  /* We won't get the same nonce back if we never initialized the
     nonce subsystem, thus we get one nonce here and forget about
     it. */
  gcry_create_nonce (nonce1, sizeof nonce1);
  if (verbose)
    print_hex ("initial nonce: ", nonce1, sizeof nonce1);

  if (pipe (rp) == -1)
    die ("pipe failed: %s\n", strerror (errno));

  pid = fork ();
  if (pid == (pid_t)(-1))
    die ("fork failed: %s\n", strerror (errno));
  if (!pid)
    {
      gcry_create_nonce (nonce1c, sizeof nonce1c);
      if (writen (rp[1], nonce1c, sizeof nonce1c))
        die ("write failed: %s\n", strerror (errno));
      if (verbose)
        {
          print_hex ("  child nonce: ", nonce1c, sizeof nonce1c);
          fflush (stdout);
        }
      _exit (0);
    }
  gcry_create_nonce (nonce1p, sizeof nonce1p);
  if (verbose)
    print_hex (" parent nonce: ", nonce1p, sizeof nonce1p);

  close (rp[1]);
  if (readn (rp[0], nonce1c, sizeof nonce1c, &nread))
    die ("read failed: %s\n", strerror (errno));
  if (nread != sizeof nonce1c)
    die ("read too short\n");

  while ( (i=waitpid (pid, &status, 0)) == -1 && errno == EINTR)
    ;
  if (i != (pid_t)(-1)
      && WIFEXITED (status) && !WEXITSTATUS (status))
    ;
  else
    die ("child failed\n");

  if (!memcmp (nonce1p, nonce1c, sizeof nonce1c))
    die ("parent and child got the same nonce\n");
#endif  /*!HAVE_W32_SYSTEM*/
}


/* Check that a closed random device os re-opened if needed. */
static void
check_close_random_device (void)
{
#ifdef HAVE_W32_SYSTEM
  if (verbose)
    inf ("check_close_random_device skipped: not applicable on Windows\n");
#else /*!HAVE_W32_SYSTEM*/
  pid_t pid;
  int i, status;
  char buf[4];

  if (verbose)
    inf ("checking that close_random_device works\n");

  gcry_randomize (buf, sizeof buf, GCRY_STRONG_RANDOM);
  if (verbose)
    print_hex ("parent random: ", buf, sizeof buf);

  pid = fork ();
  if (pid == (pid_t)(-1))
    die ("fork failed: %s\n", strerror (errno));
  if (!pid)
    {
      gcry_control (GCRYCTL_CLOSE_RANDOM_DEVICE, 0);

      /* The next call will re-open the device.  */
      gcry_randomize (buf, sizeof buf, GCRY_STRONG_RANDOM);
      if (verbose)
        {
          print_hex ("child random : ", buf, sizeof buf);
          fflush (stdout);
        }
      _exit (0);
    }

  while ( (i=waitpid (pid, &status, 0)) == -1 && errno == EINTR)
    ;
  if (i != (pid_t)(-1)
      && WIFEXITED (status) && !WEXITSTATUS (status))
    ;
  else
    die ("child failed\n");

#endif  /*!HAVE_W32_SYSTEM*/
}


static int
rng_type (void)
{
  int rngtype;
  if (gcry_control (GCRYCTL_GET_CURRENT_RNG_TYPE, &rngtype))
    die ("retrieving RNG type failed\n");
  return rngtype;
}


static void
check_rng_type_switching (void)
{
  int rngtype, initial;
  char tmp1[4];

  if (verbose)
    inf ("checking whether RNG type switching works\n");

  rngtype = rng_type ();
  if (debug)
    inf ("rng type: %d\n", rngtype);
  initial = rngtype;
  gcry_randomize (tmp1, sizeof tmp1, GCRY_STRONG_RANDOM);
  if (debug)
    print_hex ("  sample: ", tmp1, sizeof tmp1);
  if (rngtype != rng_type ())
    die ("RNG type unexpectedly changed\n");

  gcry_control (GCRYCTL_SET_PREFERRED_RNG_TYPE, GCRY_RNG_TYPE_SYSTEM);

  rngtype = rng_type ();
  if (debug)
    inf ("rng type: %d\n", rngtype);
  if (rngtype != initial)
    die ("switching to System RNG unexpectedly succeeded\n");
  gcry_randomize (tmp1, sizeof tmp1, GCRY_STRONG_RANDOM);
  if (debug)
    print_hex ("  sample: ", tmp1, sizeof tmp1);
  if (rngtype != rng_type ())
    die ("RNG type unexpectedly changed\n");

  gcry_control (GCRYCTL_SET_PREFERRED_RNG_TYPE, GCRY_RNG_TYPE_FIPS);

  rngtype = rng_type ();
  if (debug)
    inf ("rng type: %d\n", rngtype);
  if (rngtype != initial)
    die ("switching to FIPS RNG unexpectedly succeeded\n");
  gcry_randomize (tmp1, sizeof tmp1, GCRY_STRONG_RANDOM);
  if (debug)
    print_hex ("  sample: ", tmp1, sizeof tmp1);
  if (rngtype != rng_type ())
    die ("RNG type unexpectedly changed\n");

  gcry_control (GCRYCTL_SET_PREFERRED_RNG_TYPE, GCRY_RNG_TYPE_STANDARD);

  rngtype = rng_type ();
  if (debug)
    inf ("rng type: %d\n", rngtype);
  if (rngtype != GCRY_RNG_TYPE_STANDARD)
    die ("switching to standard RNG failed\n");
  gcry_randomize (tmp1, sizeof tmp1, GCRY_STRONG_RANDOM);
  if (debug)
    print_hex ("  sample: ", tmp1, sizeof tmp1);
  if (rngtype != rng_type ())
    die ("RNG type unexpectedly changed\n");
}


static void
check_early_rng_type_switching (void)
{
  int rngtype, initial;

  if (verbose)
    inf ("checking whether RNG type switching works in the early stage\n");

  rngtype = rng_type ();
  if (debug)
    inf ("rng type: %d\n", rngtype);
  initial = rngtype;

  gcry_control (GCRYCTL_SET_PREFERRED_RNG_TYPE, GCRY_RNG_TYPE_SYSTEM);

  rngtype = rng_type ();
  if (debug)
    inf ("rng type: %d\n", rngtype);
  if (initial >= GCRY_RNG_TYPE_SYSTEM && rngtype != GCRY_RNG_TYPE_SYSTEM)
    die ("switching to System RNG failed\n");

  gcry_control (GCRYCTL_SET_PREFERRED_RNG_TYPE, GCRY_RNG_TYPE_FIPS);

  rngtype = rng_type ();
  if (debug)
    inf ("rng type: %d\n", rngtype);
  if (initial >= GCRY_RNG_TYPE_FIPS && rngtype != GCRY_RNG_TYPE_FIPS)
    die ("switching to FIPS RNG failed\n");

  gcry_control (GCRYCTL_SET_PREFERRED_RNG_TYPE, GCRY_RNG_TYPE_STANDARD);

  rngtype = rng_type ();
  if (debug)
    inf ("rng type: %d\n", rngtype);
  if (rngtype != GCRY_RNG_TYPE_STANDARD)
    die ("switching to standard RNG failed\n");
}


/* Because we want to check initialization behaviour, we need to
   fork/exec this program with several command line arguments.  We use
   system, so that these tests work also on Windows.  */
static void
run_all_rng_tests (const char *program)
{
  static const char *options[] = {
    "--early-rng-check",
    "--early-rng-check --prefer-standard-rng",
    "--early-rng-check --prefer-fips-rng",
    "--early-rng-check --prefer-system-rng",
    "--prefer-standard-rng",
    "--prefer-fips-rng",
    "--prefer-system-rng",
    NULL
  };
  int idx;
  size_t len, maxlen;
  char *cmdline;

  maxlen = 0;
  for (idx=0; options[idx]; idx++)
    {
      len = strlen (options[idx]);
      if (len > maxlen)
        maxlen = len;
    }
  maxlen += strlen (program);
  maxlen += strlen (" --in-recursion --verbose --debug --progress");
  maxlen++;
  cmdline = malloc (maxlen + 1);
  if (!cmdline)
    die ("out of core\n");

  for (idx=0; options[idx]; idx++)
    {
      if (verbose)
        inf ("now running with options '%s'\n", options[idx]);
      strcpy (cmdline, program);
      strcat (cmdline, " --in-recursion");
      if (verbose)
        strcat (cmdline, " --verbose");
      if (debug)
        strcat (cmdline, " --debug");
      if (with_progress)
        strcat (cmdline, " --progress");
      strcat (cmdline, " ");
      strcat (cmdline, options[idx]);
      if (system (cmdline))
        die ("running '%s' failed\n", cmdline);
    }

  free (cmdline);
}

int
main (int argc, char **argv)
{
  int last_argc = -1;
  int early_rng = 0;
  int in_recursion = 0;
  const char *program = NULL;

  if (argc)
    {
      program = *argv;
      argc--; argv++;
    }
  else
    die ("argv[0] missing\n");

  while (argc && last_argc != argc )
    {
      last_argc = argc;
      if (!strcmp (*argv, "--"))
        {
          argc--; argv++;
          break;
        }
      else if (!strcmp (*argv, "--help"))
        {
          fputs ("usage: random [options]\n", stdout);
          exit (0);
        }
      else if (!strcmp (*argv, "--verbose"))
        {
          verbose = 1;
          argc--; argv++;
        }
      else if (!strcmp (*argv, "--debug"))
        {
          debug = verbose = 1;
          argc--; argv++;
        }
      else if (!strcmp (*argv, "--progress"))
        {
          argc--; argv++;
          with_progress = 1;
        }
      else if (!strcmp (*argv, "--in-recursion"))
        {
          in_recursion = 1;
          argc--; argv++;
        }
      else if (!strcmp (*argv, "--early-rng-check"))
        {
          early_rng = 1;
          argc--; argv++;
        }
      else if (!strcmp (*argv, "--prefer-standard-rng"))
        {
          /* This is anyway the default, but we may want to use it for
             debugging. */
          gcry_control (GCRYCTL_SET_PREFERRED_RNG_TYPE, GCRY_RNG_TYPE_STANDARD);
          argc--; argv++;
        }
      else if (!strcmp (*argv, "--prefer-fips-rng"))
        {
          gcry_control (GCRYCTL_SET_PREFERRED_RNG_TYPE, GCRY_RNG_TYPE_FIPS);
          argc--; argv++;
        }
      else if (!strcmp (*argv, "--prefer-system-rng"))
        {
          gcry_control (GCRYCTL_SET_PREFERRED_RNG_TYPE, GCRY_RNG_TYPE_SYSTEM);
          argc--; argv++;
        }
    }

#ifndef HAVE_W32_SYSTEM
  signal (SIGPIPE, SIG_IGN);
#endif

  if (early_rng)
    check_early_rng_type_switching ();

  gcry_control (GCRYCTL_DISABLE_SECMEM, 0);
  if (!gcry_check_version (GCRYPT_VERSION))
    die ("version mismatch\n");

  if (with_progress)
    gcry_set_progress_handler (progress_cb, NULL);

  gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0);
  if (debug)
    gcry_control (GCRYCTL_SET_DEBUG_FLAGS, 1u, 0);

  if (!in_recursion)
    {
      check_forking ();
      check_nonce_forking ();
      check_close_random_device ();
    }
  check_rng_type_switching ();

  if (!in_recursion)
    run_all_rng_tests (program);

  return 0;
}
