summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/libc/stdlib/rand.313
-rw-r--r--lib/libc/stdlib/rand.c34
2 files changed, 46 insertions, 1 deletions
diff --git a/lib/libc/stdlib/rand.3 b/lib/libc/stdlib/rand.3
index b47ff67..67955d9 100644
--- a/lib/libc/stdlib/rand.3
+++ b/lib/libc/stdlib/rand.3
@@ -42,6 +42,7 @@
.Sh NAME
.Nm rand ,
.Nm srand ,
+.Nm sranddev ,
.Nm rand_r
.Nd bad random number generator
.Sh LIBRARY
@@ -50,6 +51,8 @@
.Fd #include <stdlib.h>
.Ft void
.Fn srand "unsigned seed"
+.Ft void
+.Fn sranddev void
.Ft int
.Fn rand void
.Ft int
@@ -83,6 +86,13 @@ If no
value is provided, the functions are automatically
seeded with a value of 1.
.Pp
+The
+.Fn sranddev
+routine initialize a seed using
+.Xr urandom 4
+random number device which returns good random numbers,
+suitable for cryptographic use.
+.Pp
.Fn rand_r
provides the same functionality as
.Fn rand .
@@ -90,7 +100,8 @@ A pointer to the context value
.Fa ctx
must be supplied by the caller.
.Sh SEE ALSO
-.Xr random 3
+.Xr random 3 ,
+.Xr urandom 4
.Sh STANDARDS
The
.Fn rand
diff --git a/lib/libc/stdlib/rand.c b/lib/libc/stdlib/rand.c
index 70285bd..8de8ead 100644
--- a/lib/libc/stdlib/rand.c
+++ b/lib/libc/stdlib/rand.c
@@ -39,8 +39,11 @@
static char sccsid[] = "@(#)rand.c 8.1 (Berkeley) 6/14/93";
#endif /* LIBC_SCCS and not lint */
+#include <sys/time.h> /* for sranddev() */
#include <sys/types.h>
+#include <fcntl.h> /* for sranddev() */
#include <stdlib.h>
+#include <unistd.h> /* for sranddev() */
#ifdef TEST
#include <stdio.h>
@@ -101,6 +104,37 @@ u_int seed;
next = seed;
}
+
+/*
+ * sranddev:
+ *
+ * Many programs choose the seed value in a totally predictable manner.
+ * This often causes problems. We seed the generator using the much more
+ * secure urandom(4) interface.
+ */
+void
+sranddev()
+{
+ int fd, done;
+
+ done = 0;
+ fd = _open("/dev/urandom", O_RDONLY, 0);
+ if (fd >= 0) {
+ if (_read(fd, (void *) &next, sizeof(next)) == sizeof(next))
+ done = 1;
+ _close(fd);
+ }
+
+ if (!done) {
+ struct timeval tv;
+ unsigned long junk;
+
+ gettimeofday(&tv, NULL);
+ next = getpid() ^ tv.tv_sec ^ tv.tv_usec ^ junk;
+ }
+}
+
+
#ifdef TEST
main()
OpenPOWER on IntegriCloud