Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F137932157
D19944.id56360.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
10 KB
Referenced Files
None
Subscribers
None
D19944.id56360.diff
View Options
Index: UPDATING
===================================================================
--- UPDATING
+++ UPDATING
@@ -31,6 +31,30 @@
disable the most expensive debugging functionality run
"ln -s 'abort:false,junk:false' /etc/malloc.conf".)
+20190417:
+ The following knobs have been added related to tradeoffs between
+ safe use of the random device and availability in the absence of
+ entropy:
+
+ kern.random.initial_seeding.bypass_before_seeding: tunable; set
+ non-zero to bypass the random device prior to seeding, or zero to
+ block random requests until the random device is initially seeded.
+ For now, set to 1 (unsafe) by default to restore pre-r346250 boot
+ availability properties.
+
+ kern.random.initial_seeding.read_random_bypassed_before_seeding:
+ read-only diagnostic sysctl that is set when bypass is enabled and
+ read_random(9) is bypassed, to enable programmatic handling of this
+ initial condition, if desired.
+
+ kern.random.initial_seeding.arc4random_bypassed_before_seeding:
+ Similar to the above, but for for arc4random(9) initial seeding.
+
+ kern.random.initial_seeding.disable_bypass_warnings: tunable; set
+ non-zero to disable warnings in dmesg when the same conditions are
+ met as for the diagnostic sysctls above. Defaults to zero, i.e.,
+ produce warnings in dmesg when the conditions are met.
+
20190416:
The tunable "security.stack_protect.permit_nonrandom_cookies" may be
set to a non-zero value to boot systems that do not provide early
Index: sys/dev/random/random_infra.c
===================================================================
--- sys/dev/random/random_infra.c
+++ sys/dev/random/random_infra.c
@@ -43,7 +43,61 @@
#include <dev/random/randomdev.h>
/* Set up the sysctl root node for the entropy device */
-SYSCTL_NODE(_kern, OID_AUTO, random, CTLFLAG_RW, 0, "Cryptographically Secure Random Number Generator");
+SYSCTL_NODE(_kern, OID_AUTO, random, CTLFLAG_RW, 0,
+ "Cryptographically Secure Random Number Generator");
+SYSCTL_NODE(_kern_random, OID_AUTO, initial_seeding, CTLFLAG_RW, 0,
+ "Initial seeding control and information");
+
+/*
+ * N.B., this is a dangerous default, but it matches the behavior prior to
+ * r346250 (and, say, OpenBSD -- although they get some guaranteed saved
+ * entropy from the prior boot because of their KARL system, on RW media).
+ */
+bool random_bypass_before_seeding = true;
+SYSCTL_BOOL(_kern_random_initial_seeding, OID_AUTO,
+ bypass_before_seeding, CTLFLAG_RDTUN, &random_bypass_before_seeding,
+ 0, "If set non-zero, bypass the random device in requests for random "
+ "data when the random device is not yet seeded. This is considered "
+ "dangerous. Ordinarily, the random device will block requests until "
+ "it is seeded by sufficient entropy.");
+
+/*
+ * This is a read-only diagnostic that reports the combination of the former
+ * tunable and actual bypass. It is intended for programmatic inspection by
+ * userspace administrative utilities after boot.
+ */
+bool read_random_bypassed_before_seeding = false;
+SYSCTL_BOOL(_kern_random_initial_seeding, OID_AUTO,
+ read_random_bypassed_before_seeding, CTLFLAG_RD,
+ &read_random_bypassed_before_seeding, 0, "If non-zero, the random device "
+ "was bypassed because the 'bypass_before_seeding' knob was enabled and a "
+ "request was submitted prior to initial seeding.");
+
+/*
+ * This is a read-only diagnostic that reports the combination of the former
+ * tunable and actual bypass for arc4random initial seeding. It is intended
+ * for programmatic inspection by userspace administrative utilities after
+ * boot.
+ */
+bool arc4random_bypassed_before_seeding = false;
+SYSCTL_BOOL(_kern_random_initial_seeding, OID_AUTO,
+ arc4random_bypassed_before_seeding, CTLFLAG_RD,
+ &arc4random_bypassed_before_seeding, 0, "If non-zero, the random device "
+ "was bypassed when initially seeding the kernel arc4random(9), because "
+ "the 'bypass_before_seeding' knob was enabled and a request was submitted "
+ "prior to initial seeding.");
+
+/*
+ * This knob is for users who do not want additional warnings in their logs
+ * because they intend to handle bypass by inspecting the status of the
+ * diagnostic sysctls.
+ */
+bool random_bypass_disable_warnings = false;
+SYSCTL_BOOL(_kern_random_initial_seeding, OID_AUTO,
+ disable_bypass_warnings, CTLFLAG_RDTUN,
+ &random_bypass_disable_warnings, 0, "If non-zero, do not log a warning "
+ "if the 'bypass_before_seeding' knob is enabled and a request is "
+ "submitted prior to initial seeding.");
MALLOC_DEFINE(M_ENTROPY, "entropy", "Entropy harvesting buffers and data structures");
Index: sys/dev/random/randomdev.h
===================================================================
--- sys/dev/random/randomdev.h
+++ sys/dev/random/randomdev.h
@@ -37,6 +37,7 @@
#ifdef SYSCTL_DECL /* from sysctl.h */
SYSCTL_DECL(_kern_random);
+SYSCTL_DECL(_kern_random_initial_seeding);
#define RANDOM_CHECK_UINT(name, min, max) \
static int \
@@ -55,6 +56,11 @@
MALLOC_DECLARE(M_ENTROPY);
+extern bool random_bypass_before_seeding;
+extern bool read_random_bypassed_before_seeding;
+extern bool arc4random_bypassed_before_seeding;
+extern bool random_bypass_disable_warnings;
+
#endif /* _KERNEL */
struct harvest_event;
Index: sys/dev/random/randomdev.c
===================================================================
--- sys/dev/random/randomdev.c
+++ sys/dev/random/randomdev.c
@@ -236,11 +236,15 @@
}
/*-
- * Kernel API version of read_random().
- * This is similar to random_alg_read(),
- * except it doesn't interface with uio(9).
- * It cannot assumed that random_buf is a multiple of
- * RANDOM_BLOCKSIZE bytes.
+ * Kernel API version of read_random(). This is similar to read_random_uio(),
+ * except it doesn't interface with uio(9). It cannot assumed that random_buf
+ * is a multiple of RANDOM_BLOCKSIZE bytes.
+ *
+ * If the tunable 'kern.random.initial_seeding.bypass_before_seeding' is set
+ * non-zero, silently fail to emit random data (matching the pre-r346250
+ * behavior). If read_random is called prior to seeding and bypassed because
+ * of this tunable, the condition is reported in the read-only sysctl
+ * 'kern.random.initial_seeding.read_random_bypassed_before_seeding'.
*/
void
READ_RANDOM(void *random_buf, u_int len)
@@ -249,12 +253,31 @@
KASSERT(random_buf != NULL, ("No suitable random buffer in %s", __func__));
p_random_alg_context->ra_pre_read();
+
+ if (len == 0)
+ return;
+
/* (Un)Blocking logic */
- if (!p_random_alg_context->ra_seeded())
+ if (__predict_false(!p_random_alg_context->ra_seeded())) {
+ if (random_bypass_before_seeding) {
+ if (!read_random_bypassed_before_seeding) {
+ if (!random_bypass_disable_warnings)
+ printf("read_random: WARNING: bypassing"
+ " request for random data because "
+ "the random device is not yet "
+ "seeded and the knob "
+ "'bypass_before_seeding' was "
+ "enabled.\n");
+ read_random_bypassed_before_seeding = true;
+ }
+ /* Avoid potentially leaking stack garbage */
+ memset(random_buf, 0, len);
+ return;
+ }
+
(void)randomdev_wait_until_seeded(SEEDWAIT_UNINTERRUPTIBLE);
+ }
read_rate_increment(roundup2(len, sizeof(uint32_t)));
- if (len == 0)
- return;
/*
* The underlying generator expects multiples of
* RANDOM_BLOCKSIZE.
Index: sys/libkern/arc4random.c
===================================================================
--- sys/libkern/arc4random.c
+++ sys/libkern/arc4random.c
@@ -41,6 +41,9 @@
#include <sys/time.h>
#include <crypto/chacha20/chacha.h>
+#include <crypto/sha2/sha256.h>
+#include <dev/random/randomdev.h>
+#include <machine/cpu.h>
#define CHACHA20_RESEED_BYTES 65536
#define CHACHA20_RESEED_SECONDS 300
@@ -77,12 +80,43 @@
struct timeval tv_now;
u_int8_t key[CHACHA20_KEYBYTES];
- /*
- * If the loader(8) did not have an entropy stash from the previous
- * shutdown to load, then we will block. The answer is to make sure
- * there is an entropy stash at shutdown time.
- */
- read_random(key, CHACHA20_KEYBYTES);
+ if (__predict_false(random_bypass_before_seeding && !is_random_seeded())) {
+ SHA256_CTX ctx;
+ uint64_t cc;
+ uint32_t fver;
+
+ if (!arc4random_bypassed_before_seeding) {
+ arc4random_bypassed_before_seeding = true;
+ if (!random_bypass_disable_warnings)
+ printf("arc4random: WARNING: initial seeding "
+ "bypassed the cryptographic random device "
+ "because it was not yet seeded and the "
+ "knob 'bypass_before_seeding' was "
+ "enabled.\n");
+ }
+
+ /* Last ditch effort to inject something in a bad condition. */
+ cc = get_cyclecount();
+ SHA256_Init(&ctx);
+ SHA256_Update(&ctx, key, sizeof(key));
+ SHA256_Update(&ctx, &cc, sizeof(cc));
+ fver = __FreeBSD_version;
+ SHA256_Update(&ctx, &fver, sizeof(fver));
+ _Static_assert(sizeof(key) == SHA256_DIGEST_LENGTH,
+ "make sure 256 bits is still 256 bits");
+ SHA256_Final(key, &ctx);
+ } else {
+ /*
+ * If the loader(8) did not have an entropy stash from the
+ * previous shutdown to load, then we will block. The answer is
+ * to make sure there is an entropy stash at shutdown time.
+ *
+ * On the other hand, if the random_bypass_before_seeding knob
+ * was set and we landed in this branch, we know this won't
+ * block because we know the random device is seeded.
+ */
+ read_random(key, CHACHA20_KEYBYTES);
+ }
getmicrouptime(&tv_now);
mtx_lock(&chacha20->mtx);
chacha_keysetup(&chacha20->ctx, key, CHACHA20_KEYBYTES*8);
Index: sys/mips/conf/PB92
===================================================================
--- sys/mips/conf/PB92
+++ sys/mips/conf/PB92
@@ -133,5 +133,5 @@
device ether
#device md
#device bpf
-#device random
+device random
#device if_bridge
Index: sys/sys/param.h
===================================================================
--- sys/sys/param.h
+++ sys/sys/param.h
@@ -60,7 +60,7 @@
* in the range 5 to 9.
*/
#undef __FreeBSD_version
-#define __FreeBSD_version 1300019 /* Master, propagated to newvers */
+#define __FreeBSD_version 1300020 /* Master, propagated to newvers */
/*
* __FreeBSD_kernel__ indicates that this system uses the kernel of FreeBSD,
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Fri, Nov 28, 9:42 AM (10 h, 32 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
26280258
Default Alt Text
D19944.id56360.diff (10 KB)
Attached To
Mode
D19944: random(4): Restore availability tradeoff prior to r346250
Attached
Detach File
Event Timeline
Log In to Comment