See ChangeLog: Wed Dec 8 21:58:32 CET 1999 Werner Koch
[gnupg.git] / cipher / rndunix.c
index f0b6319..4ab9f65 100644 (file)
@@ -1,11 +1,52 @@
 /****************************************************************************
  *                                                                         *
- *   BeOS Randomness-Gathering Code                                        *
- *   Copyright Peter Gutmann, Paul Kendall, and Chris Wedgwood 1996-1998    *
- *   Copyright (C) 1998, 1999  Werner Koch
+ *                                                                         *
+ *   Unix Randomness-Gathering Code                                        *
+ *                                                                         *
+ *   Copyright Peter Gutmann, Paul Kendall, and Chris Wedgwood 1996-1999.   *
+ *   Heavily modified for GnuPG by Werner Koch                             *
+ *                                                                         *
  *                                                                         *
  ****************************************************************************/
 
+/* This module is part of the cryptlib continuously seeded pseudorandom
+   number generator.  For usage conditions, see lib_rand.c
+
+   [Here is the notice from lib_rand.c:]
+
+   This module and the misc/rnd*.c modules represent the cryptlib
+   continuously seeded pseudorandom number generator (CSPRNG) as described in
+   my 1998 Usenix Security Symposium paper "The generation of random numbers
+   for cryptographic purposes".
+
+   The CSPRNG code is copyright Peter Gutmann (and various others) 1996,
+   1997, 1998, 1999, all rights reserved.  Redistribution of the CSPRNG
+   modules and use in source and binary forms, with or without modification,
+   are permitted provided that the following conditions are met:
+
+   1. Redistributions of source code must retain the above copyright notice
+      and this permission notice in its entirety.
+
+   2. Redistributions in binary form must reproduce the copyright notice in
+      the documentation and/or other materials provided with the distribution.
+
+   3. A copy of any bugfixes or enhancements made must be provided to the
+      author, <pgut001@cs.auckland.ac.nz> to allow them to be added to the
+      baseline version of the code.
+
+  ALTERNATIVELY, the code may be distributed under the terms of the GNU
+  General Public License, version 2 or any later version published by the
+  Free Software Foundation, in which case the provisions of the GNU GPL are
+  required INSTEAD OF the above restrictions.
+
+  Although not required under the terms of the GPL, it would still be nice if
+  you could make any changes available to the author to allow a consistent
+  code base to be maintained */
+
+
+/* Fixme: We use plain mallocs here beucase it may be used as a module
+ * should be changed. */
+
 /* General includes */
 
 #include <config.h>
 #include <errno.h>
 
 #include "types.h"  /* for byte and u32 typedefs */
-#include "g10lib.h"
 #ifndef IS_MODULE
 #include "dynload.h"
 #endif
+#include "g10lib.h"
 
 #ifndef EAGAIN
   #define EAGAIN  EWOULDBLOCK
@@ -401,11 +442,8 @@ slow_poll(FILE *dbgfp, int dbgall, size_t *nbytes )
     fd_set fds;
   #if defined( __hpux )
     size_t maxFD = 0;
-    int pageSize = 4096;       /* PHUX doesn't have getpagesize() */
-  #elif defined( _M_XENIX ) || defined( __aux )
-    int maxFD = 0, pageSize = 4096;/* Nor do others, but they get fd right */
   #else
-    int maxFD = 0, pageSize = getpagesize();
+    int maxFD = 0;
   #endif /* OS-specific brokenness */
     int bufPos, i, usefulness = 0;
 
@@ -480,13 +518,14 @@ slow_poll(FILE *dbgfp, int dbgall, size_t *nbytes )
 
                        /* Try and estimate how much entropy we're getting
                         * from a data source */
-                       if (dataSources[i].usefulness)
+                       if (dataSources[i].usefulness) {
                            if (dataSources[i].usefulness < 0)
                                total = (dataSources[i].length + 999)
                                        / -dataSources[i].usefulness;
                            else
                                total = dataSources[i].length
                                        / dataSources[i].usefulness;
+                       }
                        if( dbgfp )
                            fprintf(dbgfp,
                               "%s %s contributed %d bytes, "
@@ -642,6 +681,9 @@ start_gatherer( int pipefd )
                    select(0, NULL, NULL, NULL, &tv);
                    continue;
                }
+               if( errno == EPIPE ) /* parent has exited, so give up */
+                  exit(0);
+
                /* we can't do very much here because stderr is closed */
                if( dbgfp )
                    fprintf(dbgfp, "gatherer can't write to pipe: %s\n",
@@ -709,6 +751,7 @@ gather_random( void (*add)(const void*, size_t, int), int requester,
     /* now read from the gatherer */
     while( length ) {
        int goodness;
+       ulong subtract;
 
        if( read_a_msg( pipedes[0], &msg ) ) {
            g10_log_error("reading from gatherer pipe failed: %s\n",
@@ -742,7 +785,9 @@ gather_random( void (*add)(const void*, size_t, int), int requester,
        (*add)( msg.data, n, requester );
 
        /* this is the trick how e cope with the goodness */
-       length -= (ulong)n * goodness / 100;
+       subtract = (ulong)n * goodness / 100;
+       /* subtract at least 1 byte to avoid infinite loops */
+       length -= subtract ? subtract : 1;
     }
 
     return 0;