-/* $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 $ */
/*-
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));
major=24
-minor=2
+minor=4
.\" 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
.Sh NAME
.Nm random ,
.Nm srandom ,
+.Nm srandomdev ,
.Nm initstate ,
.Nm setstate
.Nd better random number generator; routines for changing generators
.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 *
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
.Sh SEE ALSO
.Xr arc4random 3 ,
.Xr drand48 3 ,
-.Xr rand 3
+.Xr rand 3 ,
+.Xr random 4 ,
.Sh STANDARDS
The
.Fn random ,
.Fn setstate
functions conform to
.St -xpg4.2 .
+.Pp
+The
+.Fn srandomdev
+function is an extension.
.Sh HISTORY
These
functions appeared in
*/
#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:
}
}
+/*
+ * 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:
*