FreeBSD Bugzilla – Attachment 196342 Details for
Bug 182610
[patch] arc4random(3): replace RC4 with ChaCha20, follow OpenBSD
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
Remove uses of arc4random_addrandom too and remove manual pages for deprecated interfaces
arc4random-chacha20-v3.diff (text/plain), 27.46 KB, created by
Xin LI
on 2018-08-19 09:34:31 UTC
(
hide
)
Description:
Remove uses of arc4random_addrandom too and remove manual pages for deprecated interfaces
Filename:
MIME Type:
Creator:
Xin LI
Created:
2018-08-19 09:34:31 UTC
Size:
27.46 KB
patch
obsolete
>Index: ObsoleteFiles.inc >=================================================================== >--- ObsoleteFiles.inc (revision 338040) >+++ ObsoleteFiles.inc (working copy) >@@ -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 (revision 338040) >+++ contrib/ntp/lib/isc/random.c (working copy) >@@ -68,7 +68,6 @@ isc_random_seed(isc_uint32_t seed) > #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 (revision 338040) >+++ contrib/ntp/sntp/libevent/evutil_rand.c (working copy) >@@ -195,8 +195,6 @@ evutil_secure_rng_get_bytes(void *buf, size_t n) > 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 (revision 338040) >+++ crypto/heimdal/lib/roken/rand.c (working copy) >@@ -37,7 +37,6 @@ void ROKEN_LIB_FUNCTION > 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 (revision 338040) >+++ crypto/openssh/config.h (working copy) >@@ -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 (revision 338040) >+++ include/stdlib.h (working copy) >@@ -250,11 +250,16 @@ extern void (*malloc_message)(void *, const char * > 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 (revision 338040) >+++ lib/libc/gen/Makefile.inc (working copy) >@@ -16,6 +16,7 @@ SRCS+= __getosreldate.c \ > _thread_init.c \ > alarm.c \ > arc4random.c \ >+ arc4random-compat.c \ > arc4random_uniform.c \ > assert.c \ > auxv.c \ >@@ -166,6 +167,8 @@ SRCS+= devname-compat11.c \ > 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 @@ MAN+= alarm.3 \ > 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 (revision 338040) >+++ lib/libc/gen/Symbol.map (working copy) >@@ -65,8 +65,6 @@ FBSD_1.0 { > pthread_testcancel; > alarm; > arc4random; >- arc4random_addrandom; >- arc4random_stir; > __assert; > check_utility_compat; > clock; >Index: lib/libc/gen/arc4random-compat.c >=================================================================== >--- lib/libc/gen/arc4random-compat.c (nonexistent) >+++ lib/libc/gen/arc4random-compat.c (working copy) >@@ -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); > >Property changes on: lib/libc/gen/arc4random-compat.c >___________________________________________________________________ >Added: svn:eol-style >## -0,0 +1 ## >+native >\ No newline at end of property >Added: svn:keywords >## -0,0 +1 ## >+FreeBSD=%H >\ No newline at end of property >Added: svn:mime-type >## -0,0 +1 ## >+text/plain >\ No newline at end of property >Index: lib/libc/gen/arc4random.3 >=================================================================== >--- lib/libc/gen/arc4random.3 (revision 338040) >+++ lib/libc/gen/arc4random.3 (working copy) >@@ -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 @@ and > .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 @@ functions using > .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 (revision 338040) >+++ lib/libc/gen/arc4random.c (working copy) >@@ -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 @@ __FBSDID("$FreeBSD$"); > #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; >+ if (rs == NULL) { >+ if (_rs_allocate(&rs, &rsx) == -1) >+ abort(); >+ } >+ >+ chacha_keysetup(&rsx->rs_chacha, buf, KEYSZ * 8); >+ chacha_ivsetup(&rsx->rs_chacha, buf + KEYSZ, NULL); > } > >-static inline void >-arc4_addrandom(u_char *dat, int datlen) >+static void >+_rs_stir(void) > { >- int n; >- u_int8_t si; >+ u_char rnd[KEYSZ + IVSZ]; > >- 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; >- } >- rs.j = rs.i; >-} >+ if (getentropy(rnd, sizeof rnd) == -1) >+ _getentropy_fail(); > >-size_t >-__arc4_sysctl(u_char *buf, size_t size) >-{ >- int mib[2]; >- size_t len, done; >+ if (!rs) >+ _rs_init(rnd, sizeof(rnd)); >+ else >+ _rs_rekey(rnd, sizeof(rnd)); >+ explicit_bzero(rnd, sizeof(rnd)); /* discard source seed */ > >- mib[0] = CTL_KERN; >- mib[1] = KERN_ARND; >- done = 0; >+ /* invalidate rs_buf */ >+ rs->rs_have = 0; >+ memset(rsx->rs_buf, 0, sizeof(rsx->rs_buf)); > >- 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); >+ 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) >+uint32_t >+arc4random(void) > { >- _ARC4_LOCK(); >- if (!rs_initialized) >- arc4_stir(); >- arc4_addrandom(dat, datlen); >- _ARC4_UNLOCK(); >-} >+ uint32_t val; > >-u_int32_t >-arc4random(void) >-{ >- u_int32_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 > >Property changes on: lib/libc/gen/arc4random.c >___________________________________________________________________ >Added: svn:mime-type >## -0,0 +1 ## >+text/plain >\ No newline at end of property >Index: lib/libc/gen/arc4random.h >=================================================================== >--- lib/libc/gen/arc4random.h (nonexistent) >+++ lib/libc/gen/arc4random.h (working copy) >@@ -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) >+{ >+} > >Property changes on: lib/libc/gen/arc4random.h >___________________________________________________________________ >Added: svn:eol-style >## -0,0 +1 ## >+native >\ No newline at end of property >Added: svn:keywords >## -0,0 +1 ## >+FreeBSD=%H >\ No newline at end of property >Added: svn:mime-type >## -0,0 +1 ## >+text/plain >\ No newline at end of property >Index: lib/libc/gen/getentropy.c >=================================================================== >--- lib/libc/gen/getentropy.c (revision 338040) >+++ lib/libc/gen/getentropy.c (working copy) >@@ -31,6 +31,7 @@ __FBSDID("$FreeBSD$"); > > #include <sys/param.h> > #include <sys/random.h> >+#include <sys/sysctl.h> > > #include <errno.h> > #include <stdlib.h> >@@ -37,6 +38,30 @@ __FBSDID("$FreeBSD$"); > > #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 @@ getentropy_fallback(void *buf, size_t buflen) > 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 (revision 338040) >+++ lib/libc/include/libc_private.h (working copy) >@@ -405,8 +405,6 @@ int __sys_futimens(int fd, const struct timespec > 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.c >=================================================================== >--- sys/crypto/chacha20/chacha.c (revision 338040) >+++ sys/crypto/chacha20/chacha.c (working copy) >@@ -14,7 +14,6 @@ __FBSDID("$FreeBSD$"); > > #include <crypto/chacha20/chacha.h> > >- > typedef uint8_t u8; > typedef uint32_t u32; > >@@ -57,7 +56,7 @@ typedef struct chacha_ctx chacha_ctx; > 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 @@ chacha_keysetup(chacha_ctx *x,const u8 *k,u32 kbit > 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 @@ chacha_ivsetup(chacha_ctx *x, const u8 *iv, const > 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 @@ chacha_encrypt_bytes(chacha_ctx *x,const u8 *m,u8 > 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 @@ chacha_encrypt_bytes(chacha_ctx *x,const u8 *m,u8 > 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 @@ chacha_encrypt_bytes(chacha_ctx *x,const u8 *m,u8 > } > bytes -= 64; > c += 64; >+#ifndef KEYSTREAM_ONLY > m += 64; >+#endif > } > } >Index: sys/crypto/chacha20/chacha.h >=================================================================== >--- sys/crypto/chacha20/chacha.h (revision 338040) >+++ sys/crypto/chacha20/chacha.h (working copy) >@@ -23,9 +23,15 @@ struct chacha_ctx { > #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 */
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 182610
:
147975
|
147976
|
149068
|
149507
|
189567
|
196272
|
196337
| 196342