Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F132909999
D16760.id46936.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
25 KB
Referenced Files
None
Subscribers
None
D16760.id46936.diff
View Options
Index: ObsoleteFiles.inc
===================================================================
--- ObsoleteFiles.inc
+++ ObsoleteFiles.inc
@@ -38,6 +38,9 @@
# xargs -n1 | sort | uniq -d;
# done
+# 2018XXXX: Remove deprecated arc4random(3) stir/addrandom interfaces
+OLD_FILES+=usr/share/man/man3/arc4random_addrandom.3.gz
+OLD_FILES+=usr/share/man/man3/arc4random_stir.3.gz
# 20180725: Cleanup old libcasper.so.0
OLD_LIBS+=lib/libcasper.so.0
# 20180722: indent(1) option renamed, test files follow
Index: contrib/ntp/lib/isc/random.c
===================================================================
--- contrib/ntp/lib/isc/random.c
+++ contrib/ntp/lib/isc/random.c
@@ -67,8 +67,6 @@
#ifndef HAVE_ARC4RANDOM
srand(seed);
-#else
- arc4random_addrandom((u_char *) &seed, sizeof(isc_uint32_t));
#endif
}
Index: contrib/ntp/sntp/libevent/evutil_rand.c
===================================================================
--- contrib/ntp/sntp/libevent/evutil_rand.c
+++ contrib/ntp/sntp/libevent/evutil_rand.c
@@ -195,8 +195,6 @@
void
evutil_secure_rng_add_bytes(const char *buf, size_t n)
{
- arc4random_addrandom((unsigned char*)buf,
- n>(size_t)INT_MAX ? INT_MAX : (int)n);
}
void
Index: crypto/heimdal/lib/roken/rand.c
===================================================================
--- crypto/heimdal/lib/roken/rand.c
+++ crypto/heimdal/lib/roken/rand.c
@@ -37,7 +37,6 @@
rk_random_init(void)
{
#if defined(HAVE_ARC4RANDOM)
- arc4random_stir();
#elif defined(HAVE_SRANDOMDEV)
srandomdev();
#elif defined(HAVE_RANDOM)
Index: crypto/openssh/config.h
===================================================================
--- crypto/openssh/config.h
+++ crypto/openssh/config.h
@@ -191,7 +191,7 @@
#define HAVE_ARC4RANDOM_BUF 1
/* Define to 1 if you have the `arc4random_stir' function. */
-#define HAVE_ARC4RANDOM_STIR 1
+/* #undef HAVE_ARC4RANDOM_STIR */
/* Define to 1 if you have the `arc4random_uniform' function. */
#define HAVE_ARC4RANDOM_UNIFORM 1
Index: include/stdlib.h
===================================================================
--- include/stdlib.h
+++ include/stdlib.h
@@ -250,11 +250,16 @@
void abort2(const char *, int, void **) __dead2;
__uint32_t
arc4random(void);
-void arc4random_addrandom(unsigned char *, int);
void arc4random_buf(void *, size_t);
-void arc4random_stir(void);
__uint32_t
arc4random_uniform(__uint32_t);
+
+#if !defined(BURN_BRIDGES)
+/* Deprecated arc4random() functions */
+#define arc4random_stir()
+#define arc4random_addrandom(a,b)
+#endif
+
#ifdef __BLOCKS__
int atexit_b(void (^ _Nonnull)(void));
void *bsearch_b(const void *, const void *, size_t,
Index: lib/libc/gen/Makefile.inc
===================================================================
--- lib/libc/gen/Makefile.inc
+++ lib/libc/gen/Makefile.inc
@@ -16,6 +16,7 @@
_thread_init.c \
alarm.c \
arc4random.c \
+ arc4random-compat.c \
arc4random_uniform.c \
assert.c \
auxv.c \
@@ -166,6 +167,8 @@
unvis-compat.c
.endif
+CFLAGS.arc4random.c= -I${SRCTOP}/sys -I${SRCTOP}/sys/crypto/chacha20
+
.PATH: ${SRCTOP}/contrib/libc-pwcache
SRCS+= pwcache.c pwcache.h
@@ -316,9 +319,7 @@
vis.3 \
wordexp.3
-MLINKS+=arc4random.3 arc4random_addrandom.3 \
- arc4random.3 arc4random_stir.3 \
- arc4random.3 arc4random_buf.3 \
+MLINKS+=arc4random.3 arc4random_buf.3 \
arc4random.3 arc4random_uniform.3
MLINKS+=ctermid.3 ctermid_r.3
MLINKS+=devname.3 devname_r.3
Index: lib/libc/gen/Symbol.map
===================================================================
--- lib/libc/gen/Symbol.map
+++ lib/libc/gen/Symbol.map
@@ -65,8 +65,6 @@
pthread_testcancel;
alarm;
arc4random;
- arc4random_addrandom;
- arc4random_stir;
__assert;
check_utility_compat;
clock;
Index: lib/libc/gen/arc4random-compat.c
===================================================================
--- /dev/null
+++ lib/libc/gen/arc4random-compat.c
@@ -0,0 +1,72 @@
+/*-
+ * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ *
+ * Copyright (c) 2018 Google LLC
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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.
+ *
+ * $FreeBSD$
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/types.h>
+#include <stdbool.h>
+#include <syslog.h>
+
+/*
+ * The following functions were removed from OpenBSD for good reasons:
+ *
+ * - arc4random_stir()
+ * - arc4random_addrandom()
+ *
+ * On FreeBSD, for backward ABI compatibility, we provide two wrapper which
+ * logs this event and returns.
+ */
+
+void __arc4random_stir_fbsd11(void);
+void __arc4random_addrandom_fbsd11(u_char *, int);
+
+void
+__arc4random_stir_fbsd11(void)
+{
+ static bool warned = false;
+
+ if (!warned)
+ syslog(LOG_DEBUG, "Deprecated function arc4random_stir() called");
+ warned = true;
+}
+
+void
+__arc4random_addrandom_fbsd11(u_char * dummy1 __unused, int dummy2 __unused)
+{
+ static bool warned = false;
+
+ if (!warned)
+ syslog(LOG_DEBUG, "Deprecated function arc4random_addrandom() called");
+ warned = true;
+}
+
+__sym_compat(arc4random_stir, __arc4random_stir_fbsd11, FBSD_1.0);
+__sym_compat(arc4random_addrandom, __arc4random_addrandom_fbsd11, FBSD_1.0);
Index: lib/libc/gen/arc4random.h
===================================================================
--- /dev/null
+++ lib/libc/gen/arc4random.h
@@ -0,0 +1,74 @@
+/* $OpenBSD: arc4random.h,v 1.4 2015/01/15 06:57:18 deraadt Exp $ */
+
+/*
+ * Copyright (c) 1996, David Mazieres <dm@uun.org>
+ * Copyright (c) 2008, Damien Miller <djm@openbsd.org>
+ * Copyright (c) 2013, Markus Friedl <markus@openbsd.org>
+ * Copyright (c) 2014, Theo de Raadt <deraadt@openbsd.org>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * $FreeBSD$
+ */
+
+/*
+ * Stub functions for portability.
+ */
+#include <sys/mman.h>
+
+#include <signal.h>
+
+static pthread_mutex_t arc4random_mtx = PTHREAD_MUTEX_INITIALIZER;
+#define _ARC4_LOCK() \
+ do { \
+ if (__isthreaded) \
+ _pthread_mutex_lock(&arc4random_mtx); \
+ } while (0)
+
+#define _ARC4_UNLOCK() \
+ do { \
+ if (__isthreaded) \
+ _pthread_mutex_unlock(&arc4random_mtx); \
+ } while (0)
+
+static inline void
+_getentropy_fail(void)
+{
+ raise(SIGKILL);
+}
+
+static inline int
+_rs_allocate(struct _rs **rsp, struct _rsx **rsxp)
+{
+ struct {
+ struct _rs rs;
+ struct _rsx rsx;
+ } *p;
+
+ if ((p = mmap(NULL, sizeof(*p), PROT_READ|PROT_WRITE,
+ MAP_ANON|MAP_PRIVATE, -1, 0)) == MAP_FAILED)
+ return (-1);
+ if (minherit(p, sizeof(*p), INHERIT_ZERO) == -1) {
+ munmap(p, sizeof(*p));
+ return (-1);
+ }
+
+ *rsp = &p->rs;
+ *rsxp = &p->rsx;
+ return (0);
+}
+
+static inline void
+_rs_forkdetect(void)
+{
+}
Index: lib/libc/gen/arc4random.3
===================================================================
--- lib/libc/gen/arc4random.3
+++ lib/libc/gen/arc4random.3
@@ -1,4 +1,5 @@
-.\" $OpenBSD: arc4random.3,v 1.2 1997/04/27 22:40:25 angelos Exp $
+.\" $OpenBSD: arc4random.3,v 1.35 2014/11/25 16:45:24 millert Exp $
+.\"
.\" Copyright 1997 Niels Provos <provos@physnet.uni-hamburg.de>
.\" All rights reserved.
.\"
@@ -30,16 +31,14 @@
.\" Manual page, using -mandoc macros
.\" $FreeBSD$
.\"
-.Dd April 15, 1997
+.Dd July 19, 2014
.Dt ARC4RANDOM 3
.Os
.Sh NAME
.Nm arc4random ,
.Nm arc4random_buf ,
-.Nm arc4random_uniform ,
-.Nm arc4random_stir ,
-.Nm arc4random_addrandom
-.Nd arc4 random number generator
+.Nm arc4random_uniform
+.Nd random number generator
.Sh LIBRARY
.Lb libc
.Sh SYNOPSIS
@@ -50,20 +49,36 @@
.Fn arc4random_buf "void *buf" "size_t nbytes"
.Ft uint32_t
.Fn arc4random_uniform "uint32_t upper_bound"
-.Ft void
-.Fn arc4random_stir "void"
-.Ft void
-.Fn arc4random_addrandom "unsigned char *dat" "int datlen"
.Sh DESCRIPTION
+This family of functions provides higher quality data than those
+described in
+.Xr rand 3 ,
+.Xr random 3 ,
+and
+.Xr rand48 3 .
+.Pp
+Use of these functions is encouraged for almost all random number
+consumption because the other interfaces are deficient in either
+quality, portability, standardization, or availability.
+These functions can be called in almost all coding environments,
+including
+.Xr pthreads 3
+and
+.Xr chroot 2 .
+.Pp
+High quality 32-bit pseudo-random numbers are generated very quickly.
+On each call, a cryptographic pseudo-random number generator is used
+to generate a new result.
+One data pool is used for all consumers in a process, so that consumption
+under program flow can act as additional stirring.
+The subsystem is re-seeded from the kernel random number subsystem using
+.Xr getentropy 2
+on a regular basis, and also upon
+.Xr fork 2 .
+.Pp
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.
+function returns a single 32-bit value.
The
.Fn arc4random
function returns pseudo-random numbers in the range of 0 to
@@ -75,33 +90,24 @@
.Xr random 3 .
.Pp
.Fn arc4random_buf
-function fills the region
+fills the region
.Fa buf
of length
.Fa nbytes
-with ARC4-derived random data.
+with random data.
.Pp
.Fn arc4random_uniform
-will return a uniformly distributed random number less than
+will return a single 32-bit value, uniformly distributed but less than
.Fa upper_bound .
-.Fn arc4random_uniform
-is recommended over constructions like
+This is recommended over constructions like
.Dq Li arc4random() % upper_bound
as it avoids "modulo bias" when the upper bound is not a power of two.
-.Pp
-The
-.Fn arc4random_stir
-function reads data from
-.Pa /dev/urandom
-and uses it to permute the S-Boxes via
-.Fn arc4random_addrandom .
-.Pp
-There is no need to call
-.Fn arc4random_stir
-before using
-.Fn arc4random
-functions family, since
-they automatically initialize themselves.
+In the worst case, this function may consume multiple iterations
+to ensure uniformity; see the source code to understand the problem
+and solution.
+.Sh RETURN VALUES
+These functions are always successful, and no return value is
+reserved to indicate an error.
.Sh EXAMPLES
The following produces a drop-in replacement for the traditional
.Fn rand
@@ -113,15 +119,25 @@
.Dl "#define foo4random() (arc4random() % ((unsigned)RAND_MAX + 1))"
.Sh SEE ALSO
.Xr rand 3 ,
-.Xr random 3 ,
-.Xr srandomdev 3
+.Xr rand48 3 ,
+.Xr random 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 referred to as
-.Pa ARC4 .
+These functions first appeared in
+.Ox 2.1 .
+.Pp
+The original version of this random number generator used the
+RC4 (also known as ARC4) algorithm.
+In
+.Ox 5.5
+it was replaced with the ChaCha20 cipher, and it may be replaced
+again in the future as cryptographic techniques advance.
+A good mnemonic is
+.Dq A Replacement Call for Random .
+.Pp
+The
+.Fn arc4random
+random number generator was first introduced in
+.Fx 2.2.6 .
+The ChaCha20 based implementation was introduced in
+.Fx 12.0 ,
+with obsolete stir and addrandom interfaces removed at the same time.
Index: lib/libc/gen/arc4random.c
===================================================================
--- lib/libc/gen/arc4random.c
+++ lib/libc/gen/arc4random.c
@@ -1,8 +1,10 @@
-/* $OpenBSD: arc4random.c,v 1.24 2013/06/11 16:59:50 deraadt Exp $ */
+/* $OpenBSD: arc4random.c,v 1.54 2015/09/13 08:31:47 guenther Exp $ */
/*
* Copyright (c) 1996, David Mazieres <dm@uun.org>
* Copyright (c) 2008, Damien Miller <djm@openbsd.org>
+ * Copyright (c) 2013, Markus Friedl <markus@openbsd.org>
+ * Copyright (c) 2014, Theo de Raadt <deraadt@openbsd.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -18,15 +20,7 @@
*/
/*
- * Arc4 random number generator for OpenBSD.
- *
- * 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.
- *
- * RC4 is a registered trademark of RSA Laboratories.
+ * ChaCha based random number generator for OpenBSD.
*/
#include <sys/cdefs.h>
@@ -35,232 +29,176 @@
#include "namespace.h"
#include <fcntl.h>
#include <limits.h>
+#include <pthread.h>
+#include <signal.h>
+#include <stdint.h>
#include <stdlib.h>
+#include <string.h>
#include <unistd.h>
-#include <sys/param.h>
-#include <sys/sysctl.h>
+#include <sys/types.h>
#include <sys/time.h>
-#include <pthread.h>
-
+
#include "libc_private.h"
#include "un-namespace.h"
-#ifdef __GNUC__
+#define KEYSTREAM_ONLY
+#include "chacha.c"
+
+#define minimum(a, b) ((a) < (b) ? (a) : (b))
+
+#if defined(__GNUC__) || defined(_MSC_VER)
#define inline __inline
-#else /* !__GNUC__ */
+#else /* __GNUC__ || _MSC_VER */
#define inline
-#endif /* !__GNUC__ */
+#endif /* !__GNUC__ && !_MSC_VER */
-struct arc4_stream {
- u_int8_t i;
- u_int8_t j;
- u_int8_t s[256];
-};
+#define KEYSZ 32
+#define IVSZ 8
+#define BLOCKSZ 64
+#define RSBUFSZ (16*BLOCKSZ)
-static pthread_mutex_t arc4random_mtx = PTHREAD_MUTEX_INITIALIZER;
+/* Marked INHERIT_ZERO, so zero'd out in fork children. */
+static struct _rs {
+ size_t rs_have; /* valid bytes at end of rs_buf */
+ size_t rs_count; /* bytes till reseed */
+} *rs;
-#define KEYSIZE 128
-#define _ARC4_LOCK() \
- do { \
- if (__isthreaded) \
- _pthread_mutex_lock(&arc4random_mtx); \
- } while (0)
+/* Maybe be preserved in fork children, if _rs_allocate() decides. */
+static struct _rsx {
+ chacha_ctx rs_chacha; /* chacha context for random keystream */
+ u_char rs_buf[RSBUFSZ]; /* keystream blocks */
+} *rsx;
-#define _ARC4_UNLOCK() \
- do { \
- if (__isthreaded) \
- _pthread_mutex_unlock(&arc4random_mtx); \
- } while (0)
+static inline int _rs_allocate(struct _rs **, struct _rsx **);
+static inline void _rs_forkdetect(void);
+#include "arc4random.h"
-static int rs_initialized;
-static struct arc4_stream rs;
-static pid_t arc4_stir_pid;
-static int arc4_count;
+static inline void _rs_rekey(u_char *dat, size_t datlen);
-extern int __sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp,
- void *newp, size_t newlen);
-
-static inline u_int8_t arc4_getbyte(void);
-static void arc4_stir(void);
-
static inline void
-arc4_init(void)
+_rs_init(u_char *buf, size_t n)
{
- int n;
+ if (n < KEYSZ + IVSZ)
+ return;
- for (n = 0; n < 256; n++)
- rs.s[n] = n;
- rs.i = 0;
- rs.j = 0;
-}
-
-static inline void
-arc4_addrandom(u_char *dat, int datlen)
-{
- int n;
- u_int8_t si;
-
- rs.i--;
- for (n = 0; n < 256; n++) {
- rs.i = (rs.i + 1);
- si = rs.s[rs.i];
- rs.j = (rs.j + si + dat[n % datlen]);
- rs.s[rs.i] = rs.s[rs.j];
- rs.s[rs.j] = si;
+ if (rs == NULL) {
+ if (_rs_allocate(&rs, &rsx) == -1)
+ abort();
}
- rs.j = rs.i;
+
+ chacha_keysetup(&rsx->rs_chacha, buf, KEYSZ * 8);
+ chacha_ivsetup(&rsx->rs_chacha, buf + KEYSZ, NULL);
}
-size_t
-__arc4_sysctl(u_char *buf, size_t size)
+static void
+_rs_stir(void)
{
- int mib[2];
- size_t len, done;
+ u_char rnd[KEYSZ + IVSZ];
- mib[0] = CTL_KERN;
- mib[1] = KERN_ARND;
- done = 0;
+ if (getentropy(rnd, sizeof rnd) == -1)
+ _getentropy_fail();
- do {
- len = size;
- if (__sysctl(mib, 2, buf, &len, NULL, 0) == -1)
- return (done);
- done += len;
- buf += len;
- size -= len;
- } while (size > 0);
+ if (!rs)
+ _rs_init(rnd, sizeof(rnd));
+ else
+ _rs_rekey(rnd, sizeof(rnd));
+ explicit_bzero(rnd, sizeof(rnd)); /* discard source seed */
- return (done);
+ /* invalidate rs_buf */
+ rs->rs_have = 0;
+ memset(rsx->rs_buf, 0, sizeof(rsx->rs_buf));
+
+ rs->rs_count = 1600000;
}
-static void
-arc4_stir(void)
+static inline void
+_rs_stir_if_needed(size_t len)
{
- u_char rdat[KEYSIZE];
- int i;
-
- if (!rs_initialized) {
- arc4_init();
- rs_initialized = 1;
- }
- if (__arc4_sysctl(rdat, KEYSIZE) != KEYSIZE) {
- /*
- * The sysctl cannot fail. If it does fail on some FreeBSD
- * derivative or after some future change, just abort so that
- * the problem will be found and fixed. abort is not normally
- * suitable for a library but makes sense here.
- */
- abort();
- }
-
- arc4_addrandom(rdat, KEYSIZE);
-
- /*
- * Discard early keystream, as per recommendations in:
- * "(Not So) Random Shuffles of RC4" by Ilya Mironov.
- */
- for (i = 0; i < 3072; i++)
- (void)arc4_getbyte();
- arc4_count = 1600000;
+ _rs_forkdetect();
+ if (!rs || rs->rs_count <= len)
+ _rs_stir();
+ if (rs->rs_count <= len)
+ rs->rs_count = 0;
+ else
+ rs->rs_count -= len;
}
-static void
-arc4_stir_if_needed(void)
+static inline void
+_rs_rekey(u_char *dat, size_t datlen)
{
- pid_t pid = getpid();
+#ifndef KEYSTREAM_ONLY
+ memset(rsx->rs_buf, 0, sizeof(rsx->rs_buf));
+#endif
+ /* fill rs_buf with the keystream */
+ chacha_encrypt_bytes(&rsx->rs_chacha, rsx->rs_buf,
+ rsx->rs_buf, sizeof(rsx->rs_buf));
+ /* mix in optional user provided data */
+ if (dat) {
+ size_t i, m;
- if (arc4_count <= 0 || !rs_initialized || arc4_stir_pid != pid) {
- arc4_stir_pid = pid;
- arc4_stir();
+ m = minimum(datlen, KEYSZ + IVSZ);
+ for (i = 0; i < m; i++)
+ rsx->rs_buf[i] ^= dat[i];
}
+ /* immediately reinit for backtracking resistance */
+ _rs_init(rsx->rs_buf, KEYSZ + IVSZ);
+ memset(rsx->rs_buf, 0, KEYSZ + IVSZ);
+ rs->rs_have = sizeof(rsx->rs_buf) - KEYSZ - IVSZ;
}
-static inline u_int8_t
-arc4_getbyte(void)
+static inline void
+_rs_random_buf(void *_buf, size_t n)
{
- u_int8_t si, sj;
+ u_char *buf = (u_char *)_buf;
+ u_char *keystream;
+ size_t m;
- rs.i = (rs.i + 1);
- si = rs.s[rs.i];
- rs.j = (rs.j + si);
- sj = rs.s[rs.j];
- rs.s[rs.i] = sj;
- rs.s[rs.j] = si;
- return (rs.s[(si + sj) & 0xff]);
+ _rs_stir_if_needed(n);
+ while (n > 0) {
+ if (rs->rs_have > 0) {
+ m = minimum(n, rs->rs_have);
+ keystream = rsx->rs_buf + sizeof(rsx->rs_buf)
+ - rs->rs_have;
+ memcpy(buf, keystream, m);
+ memset(keystream, 0, m);
+ buf += m;
+ n -= m;
+ rs->rs_have -= m;
+ }
+ if (rs->rs_have == 0)
+ _rs_rekey(NULL, 0);
+ }
}
-static inline u_int32_t
-arc4_getword(void)
+static inline void
+_rs_random_u32(uint32_t *val)
{
- u_int32_t val;
- val = arc4_getbyte() << 24;
- val |= arc4_getbyte() << 16;
- val |= arc4_getbyte() << 8;
- val |= arc4_getbyte();
- return val;
-}
+ u_char *keystream;
-void
-arc4random_stir(void)
-{
- _ARC4_LOCK();
- arc4_stir();
- _ARC4_UNLOCK();
+ _rs_stir_if_needed(sizeof(*val));
+ if (rs->rs_have < sizeof(*val))
+ _rs_rekey(NULL, 0);
+ keystream = rsx->rs_buf + sizeof(rsx->rs_buf) - rs->rs_have;
+ memcpy(val, keystream, sizeof(*val));
+ memset(keystream, 0, sizeof(*val));
+ rs->rs_have -= sizeof(*val);
}
-void
-arc4random_addrandom(u_char *dat, int datlen)
-{
- _ARC4_LOCK();
- if (!rs_initialized)
- arc4_stir();
- arc4_addrandom(dat, datlen);
- _ARC4_UNLOCK();
-}
-
-u_int32_t
+uint32_t
arc4random(void)
{
- u_int32_t val;
+ uint32_t val;
+
_ARC4_LOCK();
- arc4_count -= 4;
- arc4_stir_if_needed();
- val = arc4_getword();
+ _rs_random_u32(&val);
_ARC4_UNLOCK();
return val;
}
void
-arc4random_buf(void *_buf, size_t n)
+arc4random_buf(void *buf, size_t n)
{
- u_char *buf = (u_char *)_buf;
_ARC4_LOCK();
- arc4_stir_if_needed();
- while (n--) {
- if (--arc4_count <= 0)
- arc4_stir();
- buf[n] = arc4_getbyte();
- }
+ _rs_random_buf(buf, n);
_ARC4_UNLOCK();
}
-
-#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
Index: lib/libc/gen/getentropy.c
===================================================================
--- lib/libc/gen/getentropy.c
+++ lib/libc/gen/getentropy.c
@@ -31,12 +31,37 @@
#include <sys/param.h>
#include <sys/random.h>
+#include <sys/sysctl.h>
#include <errno.h>
#include <stdlib.h>
#include "libc_private.h"
+extern int __sysctl(int *, u_int, void *, size_t *, void *, size_t);
+
+static size_t
+arnd_sysctl(u_char *buf, size_t size)
+{
+ int mib[2];
+ size_t len, done;
+
+ mib[0] = CTL_KERN;
+ mib[1] = KERN_ARND;
+ done = 0;
+
+ do {
+ len = size;
+ if (__sysctl(mib, 2, buf, &len, NULL, 0) == -1)
+ return (done);
+ done += len;
+ buf += len;
+ size -= len;
+ } while (size > 0);
+
+ return (done);
+}
+
/*
* If a newer libc is accidentally installed on an older kernel, provide high
* quality random data anyway. The sysctl interface is not as fast and does
@@ -54,7 +79,7 @@
errno = EFAULT;
return (-1);
}
- if (__arc4_sysctl(buf, buflen) != buflen) {
+ if (arnd_sysctl(buf, buflen) != buflen) {
if (errno == EFAULT)
return (-1);
/*
Index: lib/libc/include/libc_private.h
===================================================================
--- lib/libc/include/libc_private.h
+++ lib/libc/include/libc_private.h
@@ -405,8 +405,6 @@
int __sys_utimensat(int fd, const char *path,
const struct timespec *times, int flag) __hidden;
-__size_t __arc4_sysctl(unsigned char *, __size_t);
-
/* execve() with PATH processing to implement posix_spawnp() */
int _execvpe(const char *, char * const *, char * const *);
Index: sys/crypto/chacha20/chacha.h
===================================================================
--- sys/crypto/chacha20/chacha.h
+++ sys/crypto/chacha20/chacha.h
@@ -23,9 +23,15 @@
#define CHACHA_STATELEN (CHACHA_NONCELEN+CHACHA_CTRLEN)
#define CHACHA_BLOCKLEN 64
-void chacha_keysetup(struct chacha_ctx *x, const u_char *k, u_int kbits);
-void chacha_ivsetup(struct chacha_ctx *x, const u_char *iv, const u_char *ctr);
-void chacha_encrypt_bytes(struct chacha_ctx *x, const u_char *m,
+#ifdef _KERNEL
+#define LOCAL
+#else
+#define LOCAL static
+#endif
+
+LOCAL void chacha_keysetup(struct chacha_ctx *x, const u_char *k, u_int kbits);
+LOCAL void chacha_ivsetup(struct chacha_ctx *x, const u_char *iv, const u_char *ctr);
+LOCAL void chacha_encrypt_bytes(struct chacha_ctx *x, const u_char *m,
u_char *c, u_int bytes);
#endif /* CHACHA_H */
Index: sys/crypto/chacha20/chacha.c
===================================================================
--- sys/crypto/chacha20/chacha.c
+++ sys/crypto/chacha20/chacha.c
@@ -14,7 +14,6 @@
#include <crypto/chacha20/chacha.h>
-
typedef uint8_t u8;
typedef uint32_t u32;
@@ -57,7 +56,7 @@
static const char sigma[16] = "expand 32-byte k";
static const char tau[16] = "expand 16-byte k";
-void
+LOCAL void
chacha_keysetup(chacha_ctx *x,const u8 *k,u32 kbits)
{
const char *constants;
@@ -82,7 +81,7 @@
x->input[3] = U8TO32_LITTLE(constants + 12);
}
-void
+LOCAL void
chacha_ivsetup(chacha_ctx *x, const u8 *iv, const u8 *counter)
{
x->input[12] = counter == NULL ? 0 : U8TO32_LITTLE(counter + 0);
@@ -91,7 +90,7 @@
x->input[15] = U8TO32_LITTLE(iv + 4);
}
-void
+LOCAL void
chacha_encrypt_bytes(chacha_ctx *x,const u8 *m,u8 *c,u32 bytes)
{
u32 x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15;
@@ -169,6 +168,7 @@
x14 = PLUS(x14,j14);
x15 = PLUS(x15,j15);
+#ifndef KEYSTREAM_ONLY
x0 = XOR(x0,U8TO32_LITTLE(m + 0));
x1 = XOR(x1,U8TO32_LITTLE(m + 4));
x2 = XOR(x2,U8TO32_LITTLE(m + 8));
@@ -185,6 +185,7 @@
x13 = XOR(x13,U8TO32_LITTLE(m + 52));
x14 = XOR(x14,U8TO32_LITTLE(m + 56));
x15 = XOR(x15,U8TO32_LITTLE(m + 60));
+#endif
j12 = PLUSONE(j12);
if (!j12) {
@@ -219,6 +220,8 @@
}
bytes -= 64;
c += 64;
+#ifndef KEYSTREAM_ONLY
m += 64;
+#endif
}
}
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Wed, Oct 22, 2:37 AM (1 h, 11 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
24037552
Default Alt Text
D16760.id46936.diff (25 KB)
Attached To
Mode
D16760: Use Chacha20 for userland arc4random() and friends
Attached
Detach File
Event Timeline
Log In to Comment