Finish FIPS random test driver.
authorWerner Koch <wk@gnupg.org>
Tue, 16 Sep 2008 07:48:25 +0000 (07:48 +0000)
committerWerner Koch <wk@gnupg.org>
Tue, 16 Sep 2008 07:48:25 +0000 (07:48 +0000)
Disable re-seeding if in test mode.

random/ChangeLog
random/random-fips.c
tests/ChangeLog
tests/fipsrngdrv.c

index ed101f6..60702eb 100644 (file)
@@ -1,3 +1,7 @@
+2008-09-16  Werner Koch  <wk@g10code.com>
+
+       * random-fips.c (x931_aes_driver): No re-seeding with test contexts.
+
 2008-09-15  Werner Koch  <wk@g10code.com>
 
        * random.c (_gcry_random_init_external_test): New.
index 90499db..eb1706f 100644 (file)
@@ -455,8 +455,9 @@ x931_aes_driver (unsigned char *output, size_t length, rng_context_t rng_ctx)
 
   while (length)
     {
-      /* We require a new seed after some time.  */
-      if (rng_ctx->use_counter > SEED_TTL)
+      /* Unless we are running with a test context, we require a new
+         seed after some time.  */
+      if (!rng_ctx->test_dt_ptr && rng_ctx->use_counter > SEED_TTL)
         {
           x931_reseed (rng_ctx);
           rng_ctx->use_counter = 0;
index f4efdd1..23da9a9 100644 (file)
@@ -1,3 +1,7 @@
+2008-09-16  Werner Koch  <wk@g10code.com>
+
+       * fipsrngdrv.c: Bail out on write error.
+
 2008-09-15  Werner Koch  <wk@g10code.com>
 
        * fipsrngdrv.c: New.
index 6100f90..bda0bde 100644 (file)
 #include <stdlib.h>
 #include <string.h>
 #include <stdarg.h>
+#include <errno.h>
+#include <ctype.h>
+#ifndef HAVE_W32_SYSTEM
+# include <signal.h>
+#endif
 
-#include "../src/gcrypt.h"
+#include <gcrypt.h>
 
 #define PGM "fipsrngdrv"
 
+#define my_isascii(c) (!((c) & 0x80))
+#define digitp(p)   (*(p) >= '0' && *(p) <= '9')
+#define hexdigitp(a) (digitp (a)                     \
+                      || (*(a) >= 'A' && *(a) <= 'F')  \
+                      || (*(a) >= 'a' && *(a) <= 'f'))
+#define xtoi_1(p)   (*(p) <= '9'? (*(p)- '0'): \
+                     *(p) <= 'F'? (*(p)-'A'+10):(*(p)-'a'+10))
+#define xtoi_2(p)   ((xtoi_1(p) * 16) + xtoi_1((p)+1))
+
 
 static void
 die (const char *format, ...)
@@ -43,6 +57,37 @@ die (const char *format, ...)
 }
 
 
+/* Convert STRING consisting of hex characters into its binary
+   representation and store that at BUFFER.  BUFFER needs to be of
+   LENGTH bytes.  The function checks that the STRING will convert
+   exactly to LENGTH bytes. The string is delimited by either end of
+   string or a white space character.  The function returns -1 on
+   error or the length of the parsed string.  */
+int
+hex2bin (const char *string, void *buffer, size_t length)
+{
+  int i;
+  const char *s = string;
+
+  for (i=0; i < length; )
+    {
+      if (!hexdigitp (s) || !hexdigitp (s+1))
+        return -1;           /* Invalid hex digits. */
+      ((unsigned char*)buffer)[i++] = xtoi_2 (s);
+      s += 2;
+    }
+  if (*s && (!my_isascii (*s) || !isspace (*s)) )
+    return -1;             /* Not followed by Nul or white space.  */
+  if (i != length)
+    return -1;             /* Not of expected length.  */
+  if (*s)
+    s++; /* Skip the delimiter. */
+  return s - string;
+}
+
+
+
+
 static gcry_error_t
 init_external_test (void **r_context, 
                     unsigned int flags,
@@ -81,36 +126,115 @@ print_buffer (const unsigned char *buffer, size_t length)
 int
 main (int argc, char **argv)
 {
+  int last_argc = -1;
+  int verbose = 0;
+  int binary = 0;
+  int loop = 0;
+  int progress = 0;
+  unsigned char key[16];
+  unsigned char seed[16];
+  unsigned char dt[16];
   void *context;
   gpg_error_t err;
-  int block;
   unsigned char buffer[16];
 
-  (void)argc;
-  (void)argv;
+  if (argc)
+    { argc--; argv++; }
 
+  while (argc && last_argc != argc )
+    {
+      last_argc = argc;
+      if (!strcmp (*argv, "--"))
+        {
+          argc--; argv++;
+          break;
+        }
+      else if (!strcmp (*argv, "--verbose"))
+        {
+          verbose = 2;
+          argc--; argv++;
+        }
+      else if (!strcmp (*argv, "--binary"))
+        {
+          binary = 1;
+          argc--; argv++;
+        }
+      else if (!strcmp (*argv, "--loop"))
+        {
+          loop = 1;
+          argc--; argv++;
+        }
+      else if (!strcmp (*argv, "--progress"))
+        {
+          progress = 1;
+          argc--; argv++;
+        }
+    }          
+  
+  if (!argc)
+    {
+      memcpy (key,  "1234567890123456", 16);
+      memcpy (seed, "abcdefghijklmnop", 16);
+      memcpy (dt,   "XXXXXXXXXXXXXXXX", 16);
+    }
+  else if (argc == 3)
+    {
+      if (    hex2bin (argv[0], key, 16) < 0
+           || hex2bin (argv[1], seed, 16) < 0
+           || hex2bin (argv[2], dt, 16) < 0 )
+        die ("args are not 32 hex digits each\n");
+    }
+  else
+    die ("invalid usage\n");
+
+#ifndef HAVE_W32_SYSTEM
+  if (loop)
+    signal (SIGPIPE, SIG_IGN);
+#endif
+
+  gcry_control (GCRYCTL_SET_VERBOSITY, (int)verbose);
   gcry_control (GCRYCTL_FORCE_FIPS_MODE, 0);
-  if (!gcry_check_version (GCRYPT_VERSION))
+  if (!gcry_check_version ("1.4.3"))
     die ("version mismatch\n");
   gcry_control (GCRYCTL_DISABLE_SECMEM, 0);
-  gcry_control (GCRYCTL_SET_VERBOSITY, 2);
   gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0);
 
-  err = init_external_test (&context, 0,
-                            "1234567890123456", 16,
-                            "abcdefghijklmnop", 16,
-                            "XXXXXXXXXXXXXXXX", 16);
+  err = init_external_test (&context, 0, key, 16, seed, 16, dt, 16);
   if (err)
     die ("init external test failed: %s\n", gpg_strerror (err));
 
-  for (block=0; block < 10; block++)
+  do 
     {
       err = run_external_test (context, buffer, sizeof buffer);
       if (err)
         die ("run external test failed: %s\n", gpg_strerror (err));
-      print_buffer (buffer, sizeof buffer);
-      putchar ('\n');
+      if (binary)
+        {
+          if (fwrite (buffer, 16, 1, stdout) != 1)
+            {
+#ifndef HAVE_W32_SYSTEM
+              if (loop && errno == EPIPE)
+                break;
+#endif
+              die ("writing output failed: %s\n", strerror (errno));
+            }
+          fflush (stdout);
+        }
+      else
+        {
+          print_buffer (buffer, sizeof buffer);
+          putchar ('\n');
+        }
+      if (progress)
+        {
+          putc ('.', stderr);
+          fflush (stderr);
+        }
     }
+  while (loop);
+
+  if (progress)
+    putc ('\n', stderr);
 
   deinit_external_test (context);