summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/libc/gen/Makefile.inc11
-rw-r--r--lib/libc/gen/arc4random.383
-rw-r--r--lib/libc/gen/arc4random.c172
3 files changed, 261 insertions, 5 deletions
diff --git a/lib/libc/gen/Makefile.inc b/lib/libc/gen/Makefile.inc
index e5f7a28..b223d9a 100644
--- a/lib/libc/gen/Makefile.inc
+++ b/lib/libc/gen/Makefile.inc
@@ -1,11 +1,11 @@
# @(#)Makefile.inc 8.6 (Berkeley) 5/4/95
-# $Id: Makefile.inc,v 1.33 1997/05/03 03:49:54 jb Exp $
+# $Id: Makefile.inc,v 1.34 1997/05/30 20:53:13 phk Exp $
# machine-independent gen sources
.PATH: ${.CURDIR}/../libc/${MACHINE}/gen ${.CURDIR}/../libc/gen
-SRCS+= alarm.c assert.c clock.c closedir.c config.c confstr.c crypt.c \
- ctermid.c daemon.c devname.c disklabel.c err.c errlst.c \
+SRCS+= alarm.c arc4random.c assert.c clock.c closedir.c config.c confstr.c \
+ crypt.c ctermid.c daemon.c devname.c disklabel.c err.c errlst.c \
exec.c fnmatch.c frexp.c fstab.c fts.c getbootfile.c getbsize.c \
getcap.c getcwd.c getdomainname.c getgrent.c getgrouplist.c \
gethostname.c getloadavg.c getlogin.c getmntinfo.c getnetgrent.c \
@@ -39,8 +39,8 @@ errlst.o errlst.po:
# Only build man pages with libc.
.if ${LIB} == "c"
-MAN3+= gen/alarm.3 gen/clock.3 gen/confstr.3 gen/config_open.3 \
- gen/crypt.3 gen/ctermid.3 \
+MAN3+= gen/alarm.3 gen/arc4random.3 gen/clock.3 gen/confstr.3 \
+ gen/config_open.3 gen/crypt.3 gen/ctermid.3 \
gen/daemon.3 gen/devname.3 gen/directory.3 gen/err.3 gen/exec.3 \
gen/fnmatch.3 gen/frexp.3 gen/fts.3 gen/getbsize.3 gen/getbootfile.3 \
gen/getcap.3 gen/getcwd.3 gen/getdiskbyname.3 gen/getdomainname.3 \
@@ -61,6 +61,7 @@ MAN3+= gen/alarm.3 gen/clock.3 gen/confstr.3 gen/config_open.3 \
gen/times.3 gen/timezone.3 gen/ttyname.3 gen/tzset.3 gen/ualarm.3 \
gen/uname.3 gen/unvis.3 gen/usleep.3 gen/utime.3 gen/valloc.3 gen/vis.3
+MLINKS+=arc4random.3 arc4random_stir.3 arc4random.3 arc4random_addrandom.3
MLINKS+=config_open.3 config_next.3 config_open.3 config_close.3 \
config_open.3 config_skip.3
MLINKS+=crypt.3 encrypt.3 crypt.3 setkey.3 crypt.3 des_setkey.3 \
diff --git a/lib/libc/gen/arc4random.3 b/lib/libc/gen/arc4random.3
new file mode 100644
index 0000000..42bb413
--- /dev/null
+++ b/lib/libc/gen/arc4random.3
@@ -0,0 +1,83 @@
+.\" $OpenBSD: arc4random.3,v 1.2 1997/04/27 22:40:25 angelos Exp $
+.\" Copyright 1997 Niels Provos <provos@physnet.uni-hamburg.de>
+.\" All rights reserved.
+.\"
+.\" Redistribution 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, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by Niels Provos.
+.\" 4. The name of the author may not be used to endorse or promote products
+.\" derived from this software without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+.\" IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+.\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+.\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+.\"
+.\" Manual page, using -mandoc macros
+.\"
+.Dd April 15, 1997
+.Dt ARC4RANDOM 3
+.Os
+.Sh NAME
+.Nm arc4random,
+.Nm arc4random_stir,
+.Nm arc4random_addrandom
+.Nd arc4 random number generator.
+.Sh SYNOPSIS
+.Fd #include <stdlib.h>
+.Ft u_int32_t
+.Fn arc4random "void"
+.Ft void
+.Fn arc4random_stir "void"
+.Ft void
+.Fn arc4random_addrandom "u_char *dat" "int datlen"
+.Sh DESCRIPTION
+The
+.Fn arc4random
+function uses the key stream generator employed by the
+arc4 cipher, which uses 8*8 8 bit S-Boxes. The S-Boxes
+can be in about
+.if t 2\u\s71700\s10\d
+.if n (2**1700)
+states.
+.Pp
+The
+.Fn arc4random_stir
+function reads data from
+.Pa /dev/urandom
+and uses it to permutate the S-Boxes via
+.Fn arc4random_addrandom .
+.Pp
+There is no need to call
+.Fn arc4random_stir
+before using
+.Fn arc4random ,
+since
+.Fn arc4random
+automatically initalizes itself.
+.Sh SEE ALSO
+.Xr rand 3 ,
+.Xr random 3 ,
+.Xr srandomdev 3
+.Sh HISTORY
+.Pa RC4
+has been designed by RSA Data Security, Inc. It was posted anonymously
+to the USENET and was confirmed to be equivalent by several sources who
+had access to the original cipher. Since
+.Pa RC4
+used to be a trade secret, the cipher is now refered to as
+.Pa ARC4 .
diff --git a/lib/libc/gen/arc4random.c b/lib/libc/gen/arc4random.c
new file mode 100644
index 0000000..b9f8a48
--- /dev/null
+++ b/lib/libc/gen/arc4random.c
@@ -0,0 +1,172 @@
+/* $Id: arc4random.c,v 1.1 1996/12/28 06:33:01 dm Exp $ */
+
+/*
+ * Arc4 random number generator for OpenBSD.
+ * Copyright 1996 David Mazieres <dm@lcs.mit.edu>.
+ *
+ * Modification and redistribution in source and binary forms is
+ * permitted provided that due credit is given to the author and the
+ * OpenBSD project (for instance by leaving this copyright notice
+ * intact).
+ */
+
+/*
+ * This code is derived from section 17.1 of Applied Cryptography,
+ * second edition, which describes a stream cipher allegedly
+ * compatible with RSA Labs "RC4" cipher (the actual description of
+ * which is a trade secret). The same algorithm is used as a stream
+ * cipher called "arcfour" in Tatu Ylonen's ssh package.
+ *
+ * Here the stream cipher has been modified always to include the time
+ * when initializing the state. That makes it impossible to
+ * regenerate the same random sequence twice, so this can't be used
+ * for encryption, but will generate good random numbers.
+ *
+ * RC4 is a registered trademark of RSA Laboratories.
+ */
+
+#include <stdlib.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/time.h>
+
+struct arc4_stream {
+ u_int8_t i;
+ u_int8_t j;
+ u_int8_t s[256];
+};
+
+static int rs_initialized;
+static struct arc4_stream rs;
+
+static inline void
+arc4_init(as)
+ struct arc4_stream *as;
+{
+ int n;
+
+ for (n = 0; n < 256; n++)
+ as->s[n] = n;
+ as->i = 0;
+ as->j = 0;
+}
+
+static inline void
+arc4_addrandom(as, dat, datlen)
+ struct arc4_stream *as;
+ u_char *dat;
+ int datlen;
+{
+ int n;
+ u_int8_t si;
+
+ as->i--;
+ for (n = 0; n < 256; n++) {
+ as->i = (as->i + 1);
+ si = as->s[as->i];
+ as->j = (as->j + si + dat[n % datlen]);
+ as->s[as->i] = as->s[as->j];
+ as->s[as->j] = si;
+ }
+}
+
+static void
+arc4_stir(as)
+ struct arc4_stream *as;
+{
+ int fd;
+ struct {
+ struct timeval tv;
+ pid_t pid;
+ u_int8_t rnd[128 - sizeof(struct timeval) - sizeof(pid_t)];
+ } rdat;
+
+ gettimeofday(&rdat.tv, NULL);
+ rdat.pid = getpid();
+ fd = open("/dev/urandom", O_RDONLY, 0);
+ if (fd >= 0) {
+ (void) read(fd, rdat.rnd, sizeof(rdat.rnd));
+ close(fd);
+ }
+ /* fd < 0? Ah, what the heck. We'll just take whatever was on the
+ * stack... */
+
+ arc4_addrandom(as, (void *) &rdat, sizeof(rdat));
+}
+
+static inline u_int8_t
+arc4_getbyte(as)
+ struct arc4_stream *as;
+{
+ u_int8_t si, sj;
+
+ as->i = (as->i + 1);
+ si = as->s[as->i];
+ as->j = (as->j + si);
+ sj = as->s[as->j];
+ as->s[as->i] = sj;
+ as->s[as->j] = si;
+ return (as->s[(si + sj) & 0xff]);
+}
+
+static inline u_int32_t
+arc4_getword(as)
+ struct arc4_stream *as;
+{
+ u_int32_t val;
+ val = arc4_getbyte(as) << 24;
+ val |= arc4_getbyte(as) << 16;
+ val |= arc4_getbyte(as) << 8;
+ val |= arc4_getbyte(as);
+ return val;
+}
+
+void
+arc4random_stir()
+{
+ if (!rs_initialized) {
+ arc4_init(&rs);
+ rs_initialized = 1;
+ }
+ arc4_stir(&rs);
+}
+
+void
+arc4random_addrandom(dat, datlen)
+ u_char *dat;
+ int datlen;
+{
+ if (!rs_initialized)
+ arc4random_stir();
+ arc4_addrandom(&rs, dat, datlen);
+}
+
+u_int32_t
+arc4random()
+{
+ if (!rs_initialized)
+ arc4random_stir();
+ return arc4_getword(&rs);
+}
+
+#if 0
+/*-------- Test code for i386 --------*/
+#include <stdio.h>
+#include <machine/pctr.h>
+int
+main(int argc, char **argv)
+{
+ const int iter = 1000000;
+ int i;
+ pctrval v;
+
+ v = rdtsc();
+ for (i = 0; i < iter; i++)
+ arc4random();
+ v = rdtsc() - v;
+ v /= iter;
+
+ printf("%qd cycles\n", v);
+}
+#endif
OpenPOWER on IntegriCloud