Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F132679797
D10048.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
20 KB
Referenced Files
None
Subscribers
None
D10048.diff
View Options
Index: head/sys/boot/forth/loader.conf
===================================================================
--- head/sys/boot/forth/loader.conf
+++ head/sys/boot/forth/loader.conf
@@ -48,7 +48,7 @@
entropy_cache_load="YES" # Set this to NO to disable loading
# entropy at boot time
entropy_cache_name="/boot/entropy" # Set this to the name of the file
-entropy_cache_type="/boot/entropy" # Required for the kernel to find
+entropy_cache_type="boot_entropy_cache" # Required for the kernel to find
# the boot-time entropy cache. This
# must not change value even if the
# _name above does change!
Index: head/sys/conf/files
===================================================================
--- head/sys/conf/files
+++ head/sys/conf/files
@@ -3810,6 +3810,7 @@
# the file should be moved to conf/files.<arch> from here.
#
libkern/arc4random.c standard
+crypto/chacha20/chacha.c standard
libkern/asprintf.c standard
libkern/bcd.c standard
libkern/bsearch.c standard
Index: head/sys/crypto/chacha20/chacha.h
===================================================================
--- head/sys/crypto/chacha20/chacha.h
+++ head/sys/crypto/chacha20/chacha.h
@@ -0,0 +1,32 @@
+/* $OpenBSD: chacha.h,v 1.4 2016/08/27 04:04:56 guenther Exp $ */
+
+/*
+chacha-merged.c version 20080118
+D. J. Bernstein
+Public domain.
+
+ $FreeBSD$
+*/
+
+#ifndef CHACHA_H
+#define CHACHA_H
+
+#include <sys/types.h>
+
+struct chacha_ctx {
+ u_int input[16];
+};
+
+#define CHACHA_MINKEYLEN 16
+#define CHACHA_NONCELEN 8
+#define CHACHA_CTRLEN 8
+#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,
+ u_char *c, u_int bytes);
+
+#endif /* CHACHA_H */
+
Index: head/sys/crypto/chacha20/chacha.c
===================================================================
--- head/sys/crypto/chacha20/chacha.c
+++ head/sys/crypto/chacha20/chacha.c
@@ -0,0 +1,224 @@
+/*
+chacha-merged.c version 20080118
+D. J. Bernstein
+Public domain.
+*/
+
+/* $OpenBSD: chacha.c,v 1.1 2013/11/21 00:45:44 djm Exp $ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/types.h>
+
+#include <crypto/chacha20/chacha.h>
+
+
+typedef uint8_t u8;
+typedef uint32_t u32;
+
+typedef struct chacha_ctx chacha_ctx;
+
+#define U8C(v) (v##U)
+#define U32C(v) (v##U)
+
+#define U8V(v) ((u8)(v) & U8C(0xFF))
+#define U32V(v) ((u32)(v) & U32C(0xFFFFFFFF))
+
+#define ROTL32(v, n) \
+ (U32V((v) << (n)) | ((v) >> (32 - (n))))
+
+#define U8TO32_LITTLE(p) \
+ (((u32)((p)[0]) ) | \
+ ((u32)((p)[1]) << 8) | \
+ ((u32)((p)[2]) << 16) | \
+ ((u32)((p)[3]) << 24))
+
+#define U32TO8_LITTLE(p, v) \
+ do { \
+ (p)[0] = U8V((v) ); \
+ (p)[1] = U8V((v) >> 8); \
+ (p)[2] = U8V((v) >> 16); \
+ (p)[3] = U8V((v) >> 24); \
+ } while (0)
+
+#define ROTATE(v,c) (ROTL32(v,c))
+#define XOR(v,w) ((v) ^ (w))
+#define PLUS(v,w) (U32V((v) + (w)))
+#define PLUSONE(v) (PLUS((v),1))
+
+#define QUARTERROUND(a,b,c,d) \
+ a = PLUS(a,b); d = ROTATE(XOR(d,a),16); \
+ c = PLUS(c,d); b = ROTATE(XOR(b,c),12); \
+ a = PLUS(a,b); d = ROTATE(XOR(d,a), 8); \
+ c = PLUS(c,d); b = ROTATE(XOR(b,c), 7);
+
+static const char sigma[16] = "expand 32-byte k";
+static const char tau[16] = "expand 16-byte k";
+
+void
+chacha_keysetup(chacha_ctx *x,const u8 *k,u32 kbits)
+{
+ const char *constants;
+
+ x->input[4] = U8TO32_LITTLE(k + 0);
+ x->input[5] = U8TO32_LITTLE(k + 4);
+ x->input[6] = U8TO32_LITTLE(k + 8);
+ x->input[7] = U8TO32_LITTLE(k + 12);
+ if (kbits == 256) { /* recommended */
+ k += 16;
+ constants = sigma;
+ } else { /* kbits == 128 */
+ constants = tau;
+ }
+ x->input[8] = U8TO32_LITTLE(k + 0);
+ x->input[9] = U8TO32_LITTLE(k + 4);
+ x->input[10] = U8TO32_LITTLE(k + 8);
+ x->input[11] = U8TO32_LITTLE(k + 12);
+ x->input[0] = U8TO32_LITTLE(constants + 0);
+ x->input[1] = U8TO32_LITTLE(constants + 4);
+ x->input[2] = U8TO32_LITTLE(constants + 8);
+ x->input[3] = U8TO32_LITTLE(constants + 12);
+}
+
+void
+chacha_ivsetup(chacha_ctx *x, const u8 *iv, const u8 *counter)
+{
+ x->input[12] = counter == NULL ? 0 : U8TO32_LITTLE(counter + 0);
+ x->input[13] = counter == NULL ? 0 : U8TO32_LITTLE(counter + 4);
+ x->input[14] = U8TO32_LITTLE(iv + 0);
+ x->input[15] = U8TO32_LITTLE(iv + 4);
+}
+
+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;
+ u32 j0, j1, j2, j3, j4, j5, j6, j7, j8, j9, j10, j11, j12, j13, j14, j15;
+ u8 *ctarget = NULL;
+ u8 tmp[64];
+ u_int i;
+
+ if (!bytes) return;
+
+ j0 = x->input[0];
+ j1 = x->input[1];
+ j2 = x->input[2];
+ j3 = x->input[3];
+ j4 = x->input[4];
+ j5 = x->input[5];
+ j6 = x->input[6];
+ j7 = x->input[7];
+ j8 = x->input[8];
+ j9 = x->input[9];
+ j10 = x->input[10];
+ j11 = x->input[11];
+ j12 = x->input[12];
+ j13 = x->input[13];
+ j14 = x->input[14];
+ j15 = x->input[15];
+
+ for (;;) {
+ if (bytes < 64) {
+ for (i = 0;i < bytes;++i) tmp[i] = m[i];
+ m = tmp;
+ ctarget = c;
+ c = tmp;
+ }
+ x0 = j0;
+ x1 = j1;
+ x2 = j2;
+ x3 = j3;
+ x4 = j4;
+ x5 = j5;
+ x6 = j6;
+ x7 = j7;
+ x8 = j8;
+ x9 = j9;
+ x10 = j10;
+ x11 = j11;
+ x12 = j12;
+ x13 = j13;
+ x14 = j14;
+ x15 = j15;
+ for (i = 20;i > 0;i -= 2) {
+ QUARTERROUND( x0, x4, x8,x12)
+ QUARTERROUND( x1, x5, x9,x13)
+ QUARTERROUND( x2, x6,x10,x14)
+ QUARTERROUND( x3, x7,x11,x15)
+ QUARTERROUND( x0, x5,x10,x15)
+ QUARTERROUND( x1, x6,x11,x12)
+ QUARTERROUND( x2, x7, x8,x13)
+ QUARTERROUND( x3, x4, x9,x14)
+ }
+ x0 = PLUS(x0,j0);
+ x1 = PLUS(x1,j1);
+ x2 = PLUS(x2,j2);
+ x3 = PLUS(x3,j3);
+ x4 = PLUS(x4,j4);
+ x5 = PLUS(x5,j5);
+ x6 = PLUS(x6,j6);
+ x7 = PLUS(x7,j7);
+ x8 = PLUS(x8,j8);
+ x9 = PLUS(x9,j9);
+ x10 = PLUS(x10,j10);
+ x11 = PLUS(x11,j11);
+ x12 = PLUS(x12,j12);
+ x13 = PLUS(x13,j13);
+ x14 = PLUS(x14,j14);
+ x15 = PLUS(x15,j15);
+
+ x0 = XOR(x0,U8TO32_LITTLE(m + 0));
+ x1 = XOR(x1,U8TO32_LITTLE(m + 4));
+ x2 = XOR(x2,U8TO32_LITTLE(m + 8));
+ x3 = XOR(x3,U8TO32_LITTLE(m + 12));
+ x4 = XOR(x4,U8TO32_LITTLE(m + 16));
+ x5 = XOR(x5,U8TO32_LITTLE(m + 20));
+ x6 = XOR(x6,U8TO32_LITTLE(m + 24));
+ x7 = XOR(x7,U8TO32_LITTLE(m + 28));
+ x8 = XOR(x8,U8TO32_LITTLE(m + 32));
+ x9 = XOR(x9,U8TO32_LITTLE(m + 36));
+ x10 = XOR(x10,U8TO32_LITTLE(m + 40));
+ x11 = XOR(x11,U8TO32_LITTLE(m + 44));
+ x12 = XOR(x12,U8TO32_LITTLE(m + 48));
+ x13 = XOR(x13,U8TO32_LITTLE(m + 52));
+ x14 = XOR(x14,U8TO32_LITTLE(m + 56));
+ x15 = XOR(x15,U8TO32_LITTLE(m + 60));
+
+ j12 = PLUSONE(j12);
+ if (!j12) {
+ j13 = PLUSONE(j13);
+ /* stopping at 2^70 bytes per nonce is user's responsibility */
+ }
+
+ U32TO8_LITTLE(c + 0,x0);
+ U32TO8_LITTLE(c + 4,x1);
+ U32TO8_LITTLE(c + 8,x2);
+ U32TO8_LITTLE(c + 12,x3);
+ U32TO8_LITTLE(c + 16,x4);
+ U32TO8_LITTLE(c + 20,x5);
+ U32TO8_LITTLE(c + 24,x6);
+ U32TO8_LITTLE(c + 28,x7);
+ U32TO8_LITTLE(c + 32,x8);
+ U32TO8_LITTLE(c + 36,x9);
+ U32TO8_LITTLE(c + 40,x10);
+ U32TO8_LITTLE(c + 44,x11);
+ U32TO8_LITTLE(c + 48,x12);
+ U32TO8_LITTLE(c + 52,x13);
+ U32TO8_LITTLE(c + 56,x14);
+ U32TO8_LITTLE(c + 60,x15);
+
+ if (bytes <= 64) {
+ if (bytes < 64) {
+ for (i = 0;i < bytes;++i) ctarget[i] = c[i];
+ }
+ x->input[12] = j12;
+ x->input[13] = j13;
+ return;
+ }
+ bytes -= 64;
+ c += 64;
+ m += 64;
+ }
+}
Index: head/sys/dev/random/random_harvestq.h
===================================================================
--- head/sys/dev/random/random_harvestq.h
+++ head/sys/dev/random/random_harvestq.h
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2013-2015 Mark R V Murray
+ * Copyright (c) 2013-2015, 2017 Mark R V Murray
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -45,8 +45,6 @@
void read_rate_increment(u_int);
-#define RANDOM_HARVESTQ_BOOT_ENTROPY_FILE "/boot/entropy"
-
#define RANDOM_HARVEST_INIT_LOCK(x) mtx_init(&harvest_context.hc_mtx, "entropy harvest mutex", NULL, MTX_SPIN)
#define RANDOM_HARVEST_LOCK(x) mtx_lock_spin(&harvest_context.hc_mtx)
#define RANDOM_HARVEST_UNLOCK(x) mtx_unlock_spin(&harvest_context.hc_mtx)
Index: head/sys/dev/random/random_harvestq.c
===================================================================
--- head/sys/dev/random/random_harvestq.c
+++ head/sys/dev/random/random_harvestq.c
@@ -352,10 +352,19 @@
* Get entropy that may have been preloaded by loader(8)
* and use it to pre-charge the entropy harvest queue.
*/
- keyfile = preload_search_by_type(RANDOM_HARVESTQ_BOOT_ENTROPY_FILE);
+ keyfile = preload_search_by_type(RANDOM_CACHED_BOOT_ENTROPY_MODULE);
+#ifndef NO_BACKWARD_COMPATIBILITY
+ if (keyfile == NULL)
+ keyfile = preload_search_by_type(RANDOM_LEGACY_BOOT_ENTROPY_MODULE);
+#endif
if (keyfile != NULL) {
data = preload_fetch_addr(keyfile);
size = preload_fetch_size(keyfile);
+ /* skip the first bit of the stash so others like arc4 can also have some. */
+ if (size > RANDOM_CACHED_SKIP_START) {
+ data += RANDOM_CACHED_SKIP_START;
+ size -= RANDOM_CACHED_SKIP_START;
+ }
/* Trim the size. If the admin has a file with a funny size, we lose some. Tough. */
size -= (size % sizeof(event.he_entropy));
if (data != NULL && size != 0) {
Index: head/sys/libkern/arc4random.c
===================================================================
--- head/sys/libkern/arc4random.c
+++ head/sys/libkern/arc4random.c
@@ -1,11 +1,28 @@
/*-
- * THE BEER-WARE LICENSE
+ * Copyright (c) 2017 The FreeBSD Foundation
+ * All rights reserved.
*
- * <dan@FreeBSD.ORG> wrote this file. As long as you retain this notice you
- * can do whatever you want with this stuff. If we meet some day, and you
- * think this stuff is worth it, you can buy me a beer in return.
+ * 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
+ * in this position and unchanged.
+ * 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 ``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.
*
- * Dan Moschuk
*/
#include <sys/cdefs.h>
@@ -14,144 +31,122 @@
#include <sys/types.h>
#include <sys/param.h>
#include <sys/kernel.h>
-#include <sys/random.h>
#include <sys/libkern.h>
+#include <sys/linker.h>
#include <sys/lock.h>
+#include <sys/malloc.h>
#include <sys/mutex.h>
-#include <sys/time.h>
+#include <sys/random.h>
#include <sys/smp.h>
-#include <sys/malloc.h>
+#include <sys/time.h>
+
+#include <crypto/chacha20/chacha.h>
-#define ARC4_RESEED_BYTES 65536
-#define ARC4_RESEED_SECONDS 300
-#define ARC4_KEYBYTES 256
+#define CHACHA20_RESEED_BYTES 65536
+#define CHACHA20_RESEED_SECONDS 300
+#define CHACHA20_KEYBYTES 32
+#define CHACHA20_BUFFER_SIZE 64
+
+CTASSERT(CHACHA20_KEYBYTES*8 >= CHACHA_MINKEYLEN);
int arc4rand_iniseed_state = ARC4_ENTR_NONE;
-MALLOC_DEFINE(M_ARC4RANDOM, "arc4random", "arc4random structures");
+MALLOC_DEFINE(M_CHACHA20RANDOM, "chacha20random", "chacha20random structures");
-struct arc4_s {
+struct chacha20_s {
struct mtx mtx;
- u_int8_t i, j;
- int numruns;
- u_int8_t sbox[256];
+ int numbytes;
+ int first_time_done;
time_t t_reseed;
-
+ u_int8_t m_buffer[CHACHA20_BUFFER_SIZE];
+ struct chacha_ctx ctx;
} __aligned(CACHE_LINE_SIZE);
-static struct arc4_s *arc4inst = NULL;
+static struct chacha20_s *chacha20inst = NULL;
-#define ARC4_FOREACH(_arc4) \
- for (_arc4 = &arc4inst[0]; _arc4 <= &arc4inst[mp_maxid]; _arc4++)
-
-static u_int8_t arc4_randbyte(struct arc4_s *arc4);
-
-static __inline void
-arc4_swap(u_int8_t *a, u_int8_t *b)
-{
- u_int8_t c;
-
- c = *a;
- *a = *b;
- *b = c;
-}
+#define CHACHA20_FOREACH(_chacha20) \
+ for (_chacha20 = &chacha20inst[0]; \
+ _chacha20 <= &chacha20inst[mp_maxid]; \
+ _chacha20++)
/*
- * Stir our S-box.
+ * Mix up the current context.
*/
static void
-arc4_randomstir(struct arc4_s* arc4)
+chacha20_randomstir(struct chacha20_s* chacha20)
{
- u_int8_t key[ARC4_KEYBYTES];
- int n;
struct timeval tv_now;
+ size_t n, size;
+ u_int8_t key[CHACHA20_KEYBYTES], *data;
+ caddr_t keyfile;
/*
- * XXX: FIX!! This isn't brilliant. Need more confidence.
- * This returns zero entropy before random(4) is seeded.
+ * This is making the best of what may be an insecure
+ * Situation. If the loader(8) did not have an entropy
+ * stash from the previous shutdown to load, then we will
+ * be improperly seeded. The answer is to make sure there
+ * is an entropy stash at shutdown time.
*/
- (void)read_random(key, ARC4_KEYBYTES);
- getmicrouptime(&tv_now);
- mtx_lock(&arc4->mtx);
- for (n = 0; n < 256; n++) {
- arc4->j = (arc4->j + arc4->sbox[n] + key[n]) % 256;
- arc4_swap(&arc4->sbox[n], &arc4->sbox[arc4->j]);
+ (void)read_random(key, CHACHA20_KEYBYTES);
+ if (!chacha20->first_time_done) {
+ keyfile = preload_search_by_type(RANDOM_CACHED_BOOT_ENTROPY_MODULE);
+ if (keyfile != NULL) {
+ data = preload_fetch_addr(keyfile);
+ size = MIN(preload_fetch_size(keyfile), CHACHA20_KEYBYTES);
+ for (n = 0; n < size; n++)
+ key[n] ^= data[n];
+ explicit_bzero(data, size);
+ if (bootverbose)
+ printf("arc4random: read %zu bytes from preloaded cache\n", size);
+ } else
+ printf("arc4random: no preloaded entropy cache\n");
+ chacha20->first_time_done = 1;
}
- arc4->i = arc4->j = 0;
+ getmicrouptime(&tv_now);
+ mtx_lock(&chacha20->mtx);
+ chacha_keysetup(&chacha20->ctx, key, CHACHA20_KEYBYTES*8);
+ chacha_ivsetup(&chacha20->ctx, (u_char *)&tv_now.tv_sec, (u_char *)&tv_now.tv_usec);
/* Reset for next reseed cycle. */
- arc4->t_reseed = tv_now.tv_sec + ARC4_RESEED_SECONDS;
- arc4->numruns = 0;
- /*
- * Throw away the first N words of output, as suggested in the
- * paper "Weaknesses in the Key Scheduling Algorithm of RC4"
- * by Fluher, Mantin, and Shamir. (N = 768 in our case.)
- *
- * http://dl.acm.org/citation.cfm?id=646557.694759
- */
- for (n = 0; n < 768*4; n++)
- arc4_randbyte(arc4);
-
- mtx_unlock(&arc4->mtx);
+ chacha20->t_reseed = tv_now.tv_sec + CHACHA20_RESEED_SECONDS;
+ chacha20->numbytes = 0;
+ mtx_unlock(&chacha20->mtx);
}
/*
- * Initialize our S-box to its beginning defaults.
+ * Initialize the contexts.
*/
static void
-arc4_init(void)
+chacha20_init(void)
{
- struct arc4_s *arc4;
- int n;
-
- arc4inst = malloc((mp_maxid + 1) * sizeof(struct arc4_s),
- M_ARC4RANDOM, M_NOWAIT | M_ZERO);
- KASSERT(arc4inst != NULL, ("arc4_init: memory allocation error"));
+ struct chacha20_s *chacha20;
- ARC4_FOREACH(arc4) {
- mtx_init(&arc4->mtx, "arc4_mtx", NULL, MTX_DEF);
-
- arc4->i = arc4->j = 0;
- for (n = 0; n < 256; n++)
- arc4->sbox[n] = (u_int8_t) n;
-
- arc4->t_reseed = -1;
- arc4->numruns = 0;
+ chacha20inst = malloc((mp_maxid + 1) * sizeof(struct chacha20_s),
+ M_CHACHA20RANDOM, M_NOWAIT | M_ZERO);
+ KASSERT(chacha20inst != NULL, ("chacha20_init: memory allocation error"));
+
+ CHACHA20_FOREACH(chacha20) {
+ mtx_init(&chacha20->mtx, "chacha20_mtx", NULL, MTX_DEF);
+ chacha20->t_reseed = -1;
+ chacha20->numbytes = 0;
+ chacha20->first_time_done = 0;
+ explicit_bzero(chacha20->m_buffer, CHACHA20_BUFFER_SIZE);
+ explicit_bzero(&chacha20->ctx, sizeof(chacha20->ctx));
}
}
-SYSINIT(arc4, SI_SUB_LOCK, SI_ORDER_ANY, arc4_init, NULL);
+SYSINIT(chacha20, SI_SUB_LOCK, SI_ORDER_ANY, chacha20_init, NULL);
static void
-arc4_uninit(void)
+chacha20_uninit(void)
{
- struct arc4_s *arc4;
+ struct chacha20_s *chacha20;
- ARC4_FOREACH(arc4) {
- mtx_destroy(&arc4->mtx);
- }
-
- free(arc4inst, M_ARC4RANDOM);
+ CHACHA20_FOREACH(chacha20)
+ mtx_destroy(&chacha20->mtx);
+ free(chacha20inst, M_CHACHA20RANDOM);
}
+SYSUNINIT(chacha20, SI_SUB_LOCK, SI_ORDER_ANY, chacha20_uninit, NULL);
-SYSUNINIT(arc4, SI_SUB_LOCK, SI_ORDER_ANY, arc4_uninit, NULL);
-
-
-/*
- * Generate a random byte.
- */
-static u_int8_t
-arc4_randbyte(struct arc4_s *arc4)
-{
- u_int8_t arc4_t;
-
- arc4->i = (arc4->i + 1) % 256;
- arc4->j = (arc4->j + arc4->sbox[arc4->i]) % 256;
-
- arc4_swap(&arc4->sbox[arc4->i], &arc4->sbox[arc4->j]);
-
- arc4_t = (arc4->sbox[arc4->i] + arc4->sbox[arc4->j]) % 256;
- return arc4->sbox[arc4_t];
-}
/*
* MPSAFE
@@ -159,28 +154,36 @@
void
arc4rand(void *ptr, u_int len, int reseed)
{
- u_char *p;
+ struct chacha20_s *chacha20;
struct timeval tv;
- struct arc4_s *arc4;
+ u_int length;
+ u_int8_t *p;
- if (reseed || atomic_cmpset_int(&arc4rand_iniseed_state,
- ARC4_ENTR_HAVE, ARC4_ENTR_SEED)) {
- ARC4_FOREACH(arc4)
- arc4_randomstir(arc4);
- }
+ if (reseed || atomic_cmpset_int(&arc4rand_iniseed_state, ARC4_ENTR_HAVE, ARC4_ENTR_SEED))
+ CHACHA20_FOREACH(chacha20)
+ chacha20_randomstir(chacha20);
- arc4 = &arc4inst[curcpu];
+ chacha20 = &chacha20inst[curcpu];
getmicrouptime(&tv);
- if ((arc4->numruns > ARC4_RESEED_BYTES) ||
- (tv.tv_sec > arc4->t_reseed))
- arc4_randomstir(arc4);
+ /* We may get unlucky and be migrated off this CPU, but that is expected to be infrequent */
+ if ((chacha20->numbytes > CHACHA20_RESEED_BYTES) || (tv.tv_sec > chacha20->t_reseed))
+ chacha20_randomstir(chacha20);
- mtx_lock(&arc4->mtx);
- arc4->numruns += len;
+ mtx_lock(&chacha20->mtx);
p = ptr;
- while (len--)
- *p++ = arc4_randbyte(arc4);
- mtx_unlock(&arc4->mtx);
+ while (len) {
+ length = MIN(CHACHA20_BUFFER_SIZE, len);
+ chacha_encrypt_bytes(&chacha20->ctx, chacha20->m_buffer, p, length);
+ p += length;
+ len -= length;
+ chacha20->numbytes += length;
+ if (chacha20->numbytes > CHACHA20_RESEED_BYTES) {
+ mtx_unlock(&chacha20->mtx);
+ chacha20_randomstir(chacha20);
+ mtx_lock(&chacha20->mtx);
+ }
+ }
+ mtx_unlock(&chacha20->mtx);
}
uint32_t
@@ -188,6 +191,13 @@
{
uint32_t ret;
- arc4rand(&ret, sizeof ret, 0);
+ arc4rand(&ret, sizeof(ret), 0);
return ret;
}
+
+void
+arc4random_buf(void *ptr, size_t len)
+{
+
+ arc4rand(ptr, len, 0);
+}
Index: head/sys/sys/libkern.h
===================================================================
--- head/sys/sys/libkern.h
+++ head/sys/sys/libkern.h
@@ -117,7 +117,8 @@
/* Prototypes for non-quad routines. */
struct malloc_type;
uint32_t arc4random(void);
-void arc4rand(void *ptr, u_int len, int reseed);
+void arc4random_buf(void *, size_t);
+void arc4rand(void *, u_int, int);
int bcmp(const void *, const void *, size_t);
int timingsafe_bcmp(const void *, const void *, size_t);
void *bsearch(const void *, const void *, size_t,
Index: head/sys/sys/random.h
===================================================================
--- head/sys/sys/random.h
+++ head/sys/sys/random.h
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2000-2015 Mark R. V. Murray
+ * Copyright (c) 2000-2015, 2017 Mark R. V. Murray
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -96,6 +96,10 @@
#define RANDOM_HARVEST_EVERYTHING_MASK ((1 << (RANDOM_ENVIRONMENTAL_END + 1)) - 1)
+#define RANDOM_LEGACY_BOOT_ENTROPY_MODULE "/boot/entropy"
+#define RANDOM_CACHED_BOOT_ENTROPY_MODULE "boot_entropy_cache"
+#define RANDOM_CACHED_SKIP_START 256
+
#if defined(DEV_RANDOM)
void random_harvest_queue(const void *, u_int, u_int, enum random_entropy_source);
void random_harvest_fast(const void *, u_int, u_int, enum random_entropy_source);
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Mon, Oct 20, 12:07 AM (10 h, 47 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
23949065
Default Alt Text
D10048.diff (20 KB)
Attached To
Mode
D10048: Replace the kernel RC4 with Chacha20.
Attached
Detach File
Event Timeline
Log In to Comment