Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F147341222
D22838.1782971700.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Flag For Later
Award Token
Size
8 KB
Referenced Files
None
Subscribers
None
D22838.1782971700.diff
View Options
Index: sys/dev/random/fenestrasX/fx_brng.c
===================================================================
--- sys/dev/random/fenestrasX/fx_brng.c
+++ 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: sys/dev/random/fenestrasX/fx_main.c
===================================================================
--- sys/dev/random/fenestrasX/fx_main.c
+++ 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,10 +248,32 @@
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
fxrng_init_alg(void *dummy __unused)
{
Index: sys/dev/random/fenestrasX/fx_pool.c
===================================================================
--- sys/dev/random/fenestrasX/fx_pool.c
+++ sys/dev/random/fenestrasX/fx_pool.c
@@ -52,6 +52,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: sys/dev/random/fenestrasX/fx_priv.h
===================================================================
--- sys/dev/random/fenestrasX/fx_priv.h
+++ 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: sys/dev/random/fenestrasX/fx_pub.h
===================================================================
--- sys/dev/random/fenestrasX/fx_pub.h
+++ sys/dev/random/fenestrasX/fx_pub.h
@@ -28,22 +28,26 @@
*/
#pragma once
-#define ASSERT(x, fmt, ...) do { \
- if (__predict_true(x)) \
- break; \
- panic("%s:%d: Assertion '" #x "' in function %s failed: " fmt, \
- __FILE__, __LINE__, __func__, ## __VA_ARGS__); \
-} while (false)
-#ifdef INVARIANTS
-#define ASSERT_DEBUG(x, fmt, ...) do { \
- if (__predict_true(x)) \
- break; \
- panic("%s:%d: Assertion '" #x "' in function %s failed: " fmt, \
- __FILE__, __LINE__, __func__, ## __VA_ARGS__); \
-} while (false)
-#else
-#define ASSERT_DEBUG(...)
-#endif
+#include <sys/systm.h>
-extern struct fxrng_buffered_rng fxrng_root;
+/*
+ * 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: sys/dev/random/randomdev.c
===================================================================
--- sys/dev/random/randomdev.c
+++ sys/dev/random/randomdev.c
@@ -387,8 +387,10 @@
selwakeuppri(&rsel, PUSER);
wakeup(&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: sys/libkern/arc4random.c
===================================================================
--- sys/libkern/arc4random.c
+++ 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: sys/sys/libkern.h
===================================================================
--- sys/sys/libkern.h
+++ sys/sys/libkern.h
@@ -118,10 +118,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
Details
Attached
Mime Type
text/plain
Expires
Thu, Jul 2, 5:55 AM (4 h, 32 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
29004659
Default Alt Text
D22838.1782971700.diff (8 KB)
Attached To
Mode
D22838: arc4random(9): Integrate with RANDOM_FENESTRASX push-reseed
Attached
Detach File
Event Timeline
Log In to Comment