Page MenuHomeFreeBSD

D22838.id.diff
No OneTemporary

D22838.id.diff

Index: head/sys/dev/random/fenestrasX/fx_brng.c
===================================================================
--- head/sys/dev/random/fenestrasX/fx_brng.c
+++ head/sys/dev/random/fenestrasX/fx_brng.c
@@ -48,6 +48,7 @@
#include <dev/random/fenestrasX/fx_brng.h>
#include <dev/random/fenestrasX/fx_priv.h>
+#include <dev/random/fenestrasX/fx_pub.h>
#include <dev/random/fenestrasX/fx_rng.h>
/*
Index: head/sys/dev/random/fenestrasX/fx_main.c
===================================================================
--- head/sys/dev/random/fenestrasX/fx_main.c
+++ head/sys/dev/random/fenestrasX/fx_main.c
@@ -88,7 +88,6 @@
* a while).
*
* Not yet implemented, not in scope, or todo:
- * - arc4random(9) injection/replacement
* - Userspace portions -- shared page, like timehands vdso?
*/
@@ -125,6 +124,7 @@
#include <dev/random/fenestrasX/fx_hash.h>
#include <dev/random/fenestrasX/fx_pool.h>
#include <dev/random/fenestrasX/fx_priv.h>
+#include <dev/random/fenestrasX/fx_pub.h>
#include <dev/random/fenestrasX/fx_rng.h>
struct fxrng_buffered_rng fxrng_root;
@@ -142,7 +142,7 @@
* the root generation number >0.
*/
static void
-fxrng_alg_read(uint8_t *output, size_t nbytes)
+_fxrng_alg_read(uint8_t *output, size_t nbytes, uint64_t *seed_version_out)
{
struct fxrng_buffered_rng **pcpu_brng_p, *rng, *tmp;
struct pcpu *pcpu;
@@ -248,8 +248,30 @@
have_valid_rng:
/* At this point we have a valid, initialized and seeded rng pointer. */
FXRNG_BRNG_LOCK(rng);
+ if (seed_version_out != NULL)
+ *seed_version_out = rng->brng_generation;
fxrng_brng_read(rng, output, nbytes);
FXRNG_BRNG_ASSERT_NOT(rng);
+}
+
+static void
+fxrng_alg_read(uint8_t *output, size_t nbytes)
+{
+ _fxrng_alg_read(output, nbytes, NULL);
+}
+
+/*
+ * External API for arc4random(9) to fetch new key material and associated seed
+ * version in chacha20_randomstir().
+ */
+void
+read_random_key(void *output, size_t nbytes, uint64_t *seed_version_out)
+{
+ /* Ensure _fxrng_alg_read invariant. */
+ if (__predict_false(atomic_load_acq_64(&fxrng_root_generation) == 0))
+ (void)fxrng_alg_seeded();
+
+ _fxrng_alg_read(output, nbytes, seed_version_out);
}
static void
Index: head/sys/dev/random/fenestrasX/fx_pool.c
===================================================================
--- head/sys/dev/random/fenestrasX/fx_pool.c
+++ head/sys/dev/random/fenestrasX/fx_pool.c
@@ -53,6 +53,7 @@
#include <dev/random/fenestrasX/fx_hash.h>
#include <dev/random/fenestrasX/fx_pool.h>
#include <dev/random/fenestrasX/fx_priv.h>
+#include <dev/random/fenestrasX/fx_pub.h>
/*
* Timer-based reseed interval growth factor and limit in seconds. (§ 3.2)
Index: head/sys/dev/random/fenestrasX/fx_priv.h
===================================================================
--- head/sys/dev/random/fenestrasX/fx_priv.h
+++ head/sys/dev/random/fenestrasX/fx_priv.h
@@ -46,4 +46,3 @@
#endif
extern struct fxrng_buffered_rng fxrng_root;
-extern uint64_t __read_mostly fxrng_root_generation;
Index: head/sys/dev/random/fenestrasX/fx_pub.h
===================================================================
--- head/sys/dev/random/fenestrasX/fx_pub.h
+++ head/sys/dev/random/fenestrasX/fx_pub.h
@@ -0,0 +1,53 @@
+/*-
+ * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ *
+ * Copyright (c) 2019 Conrad Meyer <cem@FreeBSD.org>
+ *
+ * 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$
+ */
+#pragma once
+
+#include <sys/systm.h>
+
+/*
+ * The root BRNG seed version, or generation.
+ *
+ * FenestrasX-aware downstream CSPRNGs (i.e., arc4random(9)) should track the
+ * generation number they seeded from, using the read_random_key(9) API below.
+ * If their current seed version is older than the root generation, they should
+ * reseed before producing output.
+ *
+ * The variable is read-only outside of the fenestrasX implementation and
+ * should be accessed using 'atomic_load_acq_64(&fxrng_root_generation)'.
+ * Reseeds are extremely infrequent, so callers may wish to hint to the
+ * compiler that a matching generation is the expected case, with
+ * __predict_true() or __predict_false().
+ */
+extern uint64_t __read_mostly fxrng_root_generation;
+
+/*
+ * A routine for generating seed/key material
+ * Bypasses random(4) for now, but conceivably could be incorporated into that.
+ */
+void read_random_key(void *buf, size_t nbytes, uint64_t *seed_version_out);
Index: head/sys/dev/random/randomdev.c
===================================================================
--- head/sys/dev/random/randomdev.c
+++ head/sys/dev/random/randomdev.c
@@ -373,8 +373,10 @@
selwakeuppri(&rsel, PUSER);
wakeup(p_random_alg_context);
printf("random: unblocking device.\n");
+#ifndef RANDOM_FENESTRASX
/* Do random(9) a favour while we are about it. */
(void)atomic_cmpset_int(&arc4rand_iniseed_state, ARC4_ENTR_NONE, ARC4_ENTR_HAVE);
+#endif
}
/* ARGSUSED */
Index: head/sys/libkern/arc4random.c
===================================================================
--- head/sys/libkern/arc4random.c
+++ head/sys/libkern/arc4random.c
@@ -40,10 +40,14 @@
#include <sys/smp.h>
#include <sys/time.h>
+#include <machine/cpu.h>
+
#include <crypto/chacha20/chacha.h>
#include <crypto/sha2/sha256.h>
#include <dev/random/randomdev.h>
-#include <machine/cpu.h>
+#ifdef RANDOM_FENESTRASX
+#include <dev/random/fenestrasX/fx_pub.h>
+#endif
#define CHACHA20_RESEED_BYTES 65536
#define CHACHA20_RESEED_SECONDS 300
@@ -52,7 +56,9 @@
CTASSERT(CHACHA20_KEYBYTES*8 >= CHACHA_MINKEYLEN);
+#ifndef RANDOM_FENESTRASX
int arc4rand_iniseed_state = ARC4_ENTR_NONE;
+#endif
MALLOC_DEFINE(M_CHACHA20RANDOM, "chacha20random", "chacha20random structures");
@@ -62,6 +68,9 @@
time_t t_reseed;
u_int8_t m_buffer[CHACHA20_BUFFER_SIZE];
struct chacha_ctx ctx;
+#ifdef RANDOM_FENESTRASX
+ uint64_t seed_version;
+#endif
} __aligned(CACHE_LINE_SIZE);
static struct chacha20_s *chacha20inst = NULL;
@@ -79,7 +88,10 @@
{
struct timeval tv_now;
u_int8_t key[CHACHA20_KEYBYTES];
+#ifdef RANDOM_FENESTRASX
+ uint64_t seed_version;
+#else
if (__predict_false(random_bypass_before_seeding && !is_random_seeded())) {
SHA256_CTX ctx;
uint64_t cc;
@@ -106,6 +118,10 @@
"make sure 256 bits is still 256 bits");
SHA256_Final(key, &ctx);
} else {
+#endif
+#ifdef RANDOM_FENESTRASX
+ read_random_key(key, CHACHA20_KEYBYTES, &seed_version);
+#else
/*
* If the loader(8) did not have an entropy stash from the
* previous shutdown to load, then we will block. The answer is
@@ -117,6 +133,7 @@
*/
read_random(key, CHACHA20_KEYBYTES);
}
+#endif
getmicrouptime(&tv_now);
mtx_lock(&chacha20->mtx);
chacha_keysetup(&chacha20->ctx, key, CHACHA20_KEYBYTES*8);
@@ -124,6 +141,9 @@
/* Reset for next reseed cycle. */
chacha20->t_reseed = tv_now.tv_sec + CHACHA20_RESEED_SECONDS;
chacha20->numbytes = 0;
+#ifdef RANDOM_FENESTRASX
+ chacha20->seed_version = seed_version;
+#endif
mtx_unlock(&chacha20->mtx);
}
@@ -173,9 +193,13 @@
u_int length;
u_int8_t *p;
+#ifdef RANDOM_FENESTRASX
+ if (__predict_false(reseed))
+#else
if (__predict_false(reseed ||
(arc4rand_iniseed_state == ARC4_ENTR_HAVE &&
atomic_cmpset_int(&arc4rand_iniseed_state, ARC4_ENTR_HAVE, ARC4_ENTR_SEED))))
+#endif
CHACHA20_FOREACH(chacha20)
chacha20_randomstir(chacha20);
@@ -185,8 +209,18 @@
if ((chacha20->numbytes > CHACHA20_RESEED_BYTES) || (tv.tv_sec > chacha20->t_reseed))
chacha20_randomstir(chacha20);
- p = ptr;
mtx_lock(&chacha20->mtx);
+#ifdef RANDOM_FENESTRASX
+ if (__predict_false(
+ atomic_load_acq_64(&fxrng_root_generation) != chacha20->seed_version
+ )) {
+ mtx_unlock(&chacha20->mtx);
+ chacha20_randomstir(chacha20);
+ mtx_lock(&chacha20->mtx);
+ }
+#endif
+
+ p = ptr;
while (len) {
length = MIN(CHACHA20_BUFFER_SIZE, len);
chacha_encrypt_bytes(&chacha20->ctx, chacha20->m_buffer, p, length);
Index: head/sys/sys/libkern.h
===================================================================
--- head/sys/sys/libkern.h
+++ head/sys/sys/libkern.h
@@ -116,10 +116,12 @@
static __inline long labs(long a) { return (a < 0 ? -a : a); }
static __inline quad_t qabs(quad_t a) { return (a < 0 ? -a : a); }
+#ifndef RANDOM_FENESTRASX
#define ARC4_ENTR_NONE 0 /* Don't have entropy yet. */
#define ARC4_ENTR_HAVE 1 /* Have entropy. */
#define ARC4_ENTR_SEED 2 /* Reseeding. */
extern int arc4rand_iniseed_state;
+#endif
/* Prototypes for non-quad routines. */
struct malloc_type;

File Metadata

Mime Type
text/plain
Expires
Fri, May 1, 8:18 AM (15 h, 43 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
32565398
Default Alt Text
D22838.id.diff (9 KB)

Event Timeline