Add srandomdev() from FreeBSD for use by sendmail and others.
authormillert <millert@openbsd.org>
Mon, 3 Apr 2000 23:23:48 +0000 (23:23 +0000)
committermillert <millert@openbsd.org>
Mon, 3 Apr 2000 23:23:48 +0000 (23:23 +0000)
include/stdlib.h
lib/libc/shlib_version
lib/libc/stdlib/random.3
lib/libc/stdlib/random.c

index afd027a..51f8a26 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: stdlib.h,v 1.11 1999/11/27 13:20:25 espie Exp $       */
+/*     $OpenBSD: stdlib.h,v 1.12 2000/04/03 23:23:48 millert Exp $     */
 /*     $NetBSD: stdlib.h,v 1.25 1995/12/27 21:19:08 jtc Exp $  */
 
 /*-
@@ -179,6 +179,7 @@ long         random __P((void));
 char   *realpath __P((const char *, char *));
 char   *setstate __P((const char *));
 void    srandom __P((unsigned int));
+void    srandomdev __P((void));
 
 int     putenv __P((const char *));
 int     setenv __P((const char *, const char *, int));
index 410de65..19f3169 100644 (file)
@@ -1,2 +1,2 @@
 major=24
-minor=2
+minor=4
index 9558a67..260c239 100644 (file)
@@ -29,7 +29,7 @@
 .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 .\" SUCH DAMAGE.
 .\"
-.\"    $OpenBSD: random.3,v 1.10 2000/01/19 05:25:43 pjanzen Exp $
+.\"    $OpenBSD: random.3,v 1.11 2000/04/03 23:23:48 millert Exp $
 .\"
 .Dd April 19, 1991
 .Dt RANDOM 3
@@ -37,6 +37,7 @@
 .Sh NAME
 .Nm random ,
 .Nm srandom ,
+.Nm srandomdev ,
 .Nm initstate ,
 .Nm setstate
 .Nd better random number generator; routines for changing generators
@@ -46,6 +47,8 @@
 .Fn random void
 .Ft void
 .Fn srandom "unsigned int seed"
+.Ft void
+.Fn srandomdev void
 .Ft char *
 .Fn initstate "unsigned int seed" "char *state" "size_t n"
 .Ft char *
@@ -92,6 +95,19 @@ with
 as the seed.
 .Pp
 The
+.Fn srandomdev
+routine initialize a state array using the
+.Xr arandom 4
+random number device which returns good random numbers,
+suitable for cryptographic use.
+Note that this particular seeding procedure can generate
+states which are impossible to reproduce by calling
+.Fn srandom
+with any value, since the succeeding terms in the
+state buffer are no longer derived from the LC algorithm applied to
+a fixed seed.
+.Pp
+The
 .Fn initstate
 routine allows a state array, passed in as an argument, to be initialized
 for future use.  The size of the state array (in bytes) is used by
@@ -153,7 +169,8 @@ messages are printed on the standard error output.
 .Sh SEE ALSO
 .Xr arc4random 3 ,
 .Xr drand48 3 ,
-.Xr rand 3
+.Xr rand 3 ,
+.Xr random 4 ,
 .Sh STANDARDS
 The
 .Fn random ,
@@ -163,6 +180,10 @@ and
 .Fn setstate
 functions conform to
 .St -xpg4.2 .
+.Pp
+The
+.Fn srandomdev
+function is an extension.
 .Sh HISTORY
 These
 functions appeared in
index 79344f3..7c6e5f7 100644 (file)
  */
 
 #if defined(LIBC_SCCS) && !defined(lint)
-static char *rcsid = "$OpenBSD: random.c,v 1.6 1998/02/07 02:16:25 millert Exp $";
+static char *rcsid = "$OpenBSD: random.c,v 1.7 2000/04/03 23:23:48 millert Exp $";
 #endif /* LIBC_SCCS and not lint */
 
+#include <sys/types.h>
+#include <sys/time.h>
+#include <fcntl.h>
 #include <stdio.h>
 #include <stdlib.h>
+#include <unistd.h>
 
 /*
  * random.c:
@@ -219,6 +223,47 @@ srandom(x)
        }
 }
 
+/*
+ * srandomdev:
+ *
+ * Many programs choose the seed value in a totally predictable manner.
+ * This often causes problems.  We seed the generator using the much more
+ * secure arandom(4) interface.  Note that this particular seeding
+ * procedure can generate states which are impossible to reproduce by
+ * calling srandom() with any value, since the succeeding terms in the
+ * state buffer are no longer derived from the LC algorithm applied to
+ * a fixed seed.
+ */
+void
+srandomdev()
+{
+       int fd;
+       size_t len;
+
+       if (rand_type == TYPE_0)
+               len = sizeof(state[0]);
+       else
+               len = rand_deg * sizeof(state[0]);
+
+       if ((fd = open("/dev/arandom", O_RDONLY, 0)) != -1 &&
+           read(fd, (void *) state, len) == (ssize_t) len) {
+               close(fd);
+       } else {
+               struct timeval tv;
+               u_int junk;
+
+               /* XXX - this could be better */
+               gettimeofday(&tv, NULL);
+               srandom(getpid() ^ tv.tv_sec ^ tv.tv_usec ^ junk);
+               return;
+       }
+
+       if (rand_type != TYPE_0) {
+               fptr = &state[rand_sep];
+               rptr = &state[0];
+       }
+}
+
 /*
  * initstate:
  *