[svn] gcry - r1400 - in trunk: random tests

svn author wk cvs at cvs.gnupg.org
Thu Jul 9 13:57:28 CEST 2009


Author: wk
Date: 2009-07-09 13:57:28 +0200 (Thu, 09 Jul 2009)
New Revision: 1400

Modified:
   trunk/random/ChangeLog
   trunk/random/rndlinux.c
   trunk/random/rndunix.c
   trunk/tests/ChangeLog
   trunk/tests/benchmark.c
Log:
[random/ChangeLog]

* rndlinux.c (_gcry_rndlinux_gather_random): Print real values for
the progess function and call it before blocking.  Suggested by
Christian Grothoff.
* rndunix.c (slow_poll): Add similar, but not yet functional, code.

SCALAR(0x81980e8)
 Copyright 2008, 2009 Free Software Foundation, Inc.
[tests/ChangeLog]
* benchmark.c (progress_cb): New.
(main): Add option --progress.


Modified: trunk/random/ChangeLog
===================================================================
--- trunk/random/ChangeLog	2009-07-02 14:12:44 UTC (rev 1399)
+++ trunk/random/ChangeLog	2009-07-09 11:57:28 UTC (rev 1400)
@@ -1,3 +1,10 @@
+2009-07-09  Werner Koch  <wk at g10code.com>
+
+	* rndlinux.c (_gcry_rndlinux_gather_random): Print real values for
+	the progess function and call it before blocking.  Suggested by
+	Christian Grothoff.
+	* rndunix.c (slow_poll): Add similar, but not yet functional, code.
+
 2009-07-02  Werner Koch  <wk at g10code.com>
 
 	* rndhw.c (poll_padlock): Asm change from Fedora.
@@ -120,7 +127,7 @@
 	here.
 	* Makefile.am: New.
 
- Copyright 2008 Free Software Foundation, Inc.
+ Copyright 2008, 2009 Free Software Foundation, Inc.
 
  This file is free software; as a special exception the author gives
  unlimited permission to copy and/or distribute it, with or without

Modified: trunk/tests/ChangeLog
===================================================================
--- trunk/tests/ChangeLog	2009-07-02 14:12:44 UTC (rev 1399)
+++ trunk/tests/ChangeLog	2009-07-09 11:57:28 UTC (rev 1400)
@@ -1,3 +1,8 @@
+2009-07-09  Werner Koch  <wk at g10code.com>
+
+	* benchmark.c (progress_cb): New.
+	(main): Add option --progress.
+
 2009-06-08  Werner Koch  <wk at g10code.com>
 
 	* benchmark.c (cipher_bench): Center labels.  Suggested by Brad Hards.

Modified: trunk/random/rndlinux.c
===================================================================
--- trunk/random/rndlinux.c	2009-07-02 14:12:44 UTC (rev 1399)
+++ trunk/random/rndlinux.c	2009-07-09 11:57:28 UTC (rev 1400)
@@ -1,5 +1,6 @@
 /* rndlinux.c  -  raw random number for OSes with /dev/random
- * Copyright (C) 1998, 2001, 2002, 2003, 2007  Free Software Foundation, Inc.
+ * Copyright (C) 1998, 2001, 2002, 2003, 2007,
+ *               2009  Free Software Foundation, Inc.
  *
  * This file is part of Libgcrypt.
  *
@@ -93,9 +94,12 @@
   static int fd_random = -1;
   int fd;
   int n;
-  int warn=0;
   byte buffer[768];
   size_t n_hw;
+  size_t want = length;
+  size_t last_so_far = 0;
+  int any_need_entropy = 0;
+  int delay;
 
   /* First read from a hardware source.  However let it account only
      for up to 50% of the requested bytes.  */
@@ -119,7 +123,11 @@
       fd = fd_urandom;
     }
 
-  /* And enter the read loop.  */
+  /* Enter the read loop.  */
+  delay = 0;  /* Start with 0 seconds so that we do no block on the
+                 first iteration and in turn call the progess function
+                 before blocking.  To give the OS a better chance to
+                 return with something we will actually use 100ms. */
   while (length)
     {
       fd_set rfds;
@@ -128,40 +136,49 @@
       
       FD_ZERO(&rfds);
       FD_SET(fd, &rfds);
-      tv.tv_sec = 3;
-      tv.tv_usec = 0;
-      if( !(rc=select(fd+1, &rfds, NULL, NULL, &tv)) )
+      tv.tv_sec = delay;
+      tv.tv_usec = delay? 0 : 100000;
+      if ( !(rc=select(fd+1, &rfds, NULL, NULL, &tv)) )
         {
-          if( !warn )
+          if (!any_need_entropy || last_so_far != (want - length) )
             {
-              _gcry_random_progress ("need_entropy", 'X', 0, (int)length);
-	      warn = 1;
+              last_so_far = want - length;
+              _gcry_random_progress ("need_entropy", 'X',
+                                     (int)last_so_far, (int)want);
+              any_need_entropy = 1;
 	    }
+          delay = 3; /* Use 3 seconds henceforth.  */
 	  continue;
 	}
-	else if( rc == -1 )
-          {
-	    log_error ("select() error: %s\n", strerror(errno));
-	    continue;
-          }
+      else if( rc == -1 )
+        {
+          log_error ("select() error: %s\n", strerror(errno));
+          if (!delay)
+            delay = 1; /* Use 1 second if we encounter an error before
+                          we have ever blocked.  */
+          continue;
+        }
 
-	do 
-          {
-	    int nbytes = length < sizeof(buffer)? length : sizeof(buffer);
-	    n = read(fd, buffer, nbytes );
-	    if( n >= 0 && n > nbytes ) 
-              {
-		log_error("bogus read from random device (n=%d)\n", n );
-		n = nbytes;
-              }
-          } 
-        while( n == -1 && errno == EINTR );
-	if( n == -1 )
-          log_fatal("read error on random device: %s\n", strerror(errno));
-	(*add)( buffer, n, origin );
-	length -= n;
+      do 
+        {
+          int nbytes = length < sizeof(buffer)? length : sizeof(buffer);
+          n = read(fd, buffer, nbytes );
+          if( n >= 0 && n > nbytes ) 
+            {
+              log_error("bogus read from random device (n=%d)\n", n );
+              n = nbytes;
+            }
+        } 
+      while( n == -1 && errno == EINTR );
+      if ( n == -1 )
+        log_fatal("read error on random device: %s\n", strerror(errno));
+      (*add)( buffer, n, origin );
+      length -= n;
     }
   memset(buffer, 0, sizeof(buffer) );
-
+  
+  if (any_need_entropy)
+    _gcry_random_progress ("need_entropy", 'X', (int)want, (int)want);
+  
   return 0; /* success */
 }

Modified: trunk/random/rndunix.c
===================================================================
--- trunk/random/rndunix.c	2009-07-02 14:12:44 UTC (rev 1399)
+++ trunk/random/rndunix.c	2009-07-09 11:57:28 UTC (rev 1400)
@@ -521,8 +521,11 @@
     int maxFD = 0;
 #endif /* OS-specific brokenness */
     int bufPos, i, usefulness = 0;
+    int last_so_far = 0;
+    int any_need_entropy = 0;
+    int delay;
+    int rc;
 
-
     /* Fire up each randomness source */
     FD_ZERO(&fds);
     for (i = 0; dataSources[i].path != NULL; i++) {
@@ -566,22 +569,41 @@
     /* Suck all the data we can get from each of the sources */
     bufPos = 0;
     moreSources = 1;
+    delay = 0; /* Return immediately (well, after 100ms) the first time.  */
     while (moreSources && bufPos <= gather_buffer_size) {
 	/* Wait for data to become available from any of the sources, with a
 	 * timeout of 10 seconds.  This adds even more randomness since data
 	 * becomes available in a nondeterministic fashion.  Kudos to HP's QA
 	 * department for managing to ship a select() which breaks its own
 	 * prototype */
-	tv.tv_sec = 10;
-	tv.tv_usec = 0;
+	tv.tv_sec = delay;
+	tv.tv_usec = delay? 0 : 100000;
 
 #if defined( __hpux ) && ( OS_VERSION == 9 )
-	if (select(maxFD + 1, (int *)&fds, NULL, NULL, &tv) == -1)
+	rc = select(maxFD + 1, (int *)&fds, NULL, NULL, &tv);
 #else  /*  */
-	if (select(maxFD + 1, &fds, NULL, NULL, &tv) == -1)
+	rc = select(maxFD + 1, &fds, NULL, NULL, &tv);
 #endif /* __hpux */
-	    break;
+        if (rc == -1)
+          break; /* Ooops; select failed. */
 
+        if (!rc)
+          {
+            /* FIXME: Because we run several tools at once it is
+               unlikely that we will see a block in select at all. */
+            if (!any_need_entropy 
+                || last_so_far != (gather_buffer_size - bufPos) )
+              {
+                last_so_far = gather_buffer_size - bufPos;
+                _gcry_random_progress ("need_entropy", 'X',
+                                       last_so_far, 
+                                       gather_buffer_size);
+                any_need_entropy = 1;
+              }
+            delay = 10; /* Use 10 seconds henceforth.  */
+            /* Note that the fd_set is setup again at the end of this loop.  */
+          }
+        
 	/* One of the sources has data available, read it into the buffer */
 	for (i = 0; dataSources[i].path != NULL; i++) {
 	    if( dataSources[i].pipe && FD_ISSET(dataSources[i].pipeFD, &fds)) {
@@ -661,6 +683,11 @@
 	}
     }
 
+    if (any_need_entropy)
+        _gcry_random_progress ("need_entropy", 'X',
+                               gather_buffer_size,
+                               gather_buffer_size);
+
     if( dbgfp ) {
 	fprintf(dbgfp, "Got %d bytes, usefulness = %d\n", bufPos, usefulness);
 	fflush(dbgfp);

Modified: trunk/tests/benchmark.c
===================================================================
--- trunk/tests/benchmark.c	2009-07-02 14:12:44 UTC (rev 1399)
+++ trunk/tests/benchmark.c	2009-07-09 11:57:28 UTC (rev 1400)
@@ -340,6 +340,18 @@
 
 
 static void
+progress_cb (void *cb_data, const char *what, int printchar,
+             int current, int total)
+{
+  (void)cb_data;
+  
+  fprintf (stderr, PGM ": progress (%s %c %d %d)\n",
+           what, printchar, current, total);
+  fflush (stderr);
+}
+
+
+static void
 random_bench (int very_strong)
 {
   char buf[128];
@@ -1002,6 +1014,7 @@
   int last_argc = -1;
   int no_blinding = 0;
   int use_random_daemon = 0;
+  int with_progress = 0;
 
   if (argc)
     { argc--; argv++; }
@@ -1056,6 +1069,11 @@
           /* This command needs to be called before gcry_check_version.  */
           gcry_control (GCRYCTL_FORCE_FIPS_MODE, 0);
         }
+      else if (!strcmp (*argv, "--progress"))
+        {
+          argc--; argv++;
+          with_progress = 1;
+        }
     }          
 
   gcry_control (GCRYCTL_SET_VERBOSITY, (int)verbose);
@@ -1074,9 +1092,12 @@
   if (use_random_daemon)
     gcry_control (GCRYCTL_USE_RANDOM_DAEMON, 1);
 
+  gcry_set_progress_handler (progress_cb, NULL);
+
   gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0);
 
 
+
   if (cipher_repetitions < 1)
     cipher_repetitions = 1;
   




More information about the Gnupg-commits mailing list