From: Greg Price <price@MIT.EDU>
To: "Theodore Ts'o" <tytso@MIT.EDU>
Cc: linux-kernel@vger.kernel.org
Subject: [PATCH 14/14] random: target giant reseeds, to be conservative
Date: Sat, 14 Dec 2013 21:02:03 -0500 [thread overview]
Message-ID: <20131215020202.GN27191@athena.dialup.mit.edu> (raw)
In-Reply-To: <cover.1387067223.git.price@mit.edu>
A 128-bit seed provides reasonable security. We don't consider
ourselves initialized until we get a seed which we estimate has
entropy min_reseed_bits, by default 128. Our entropy estimates
are generally conservative (see e.g. the empirical analysis in
http://eprint.iacr.org/2012/251.pdf), but entropy estimation is
unavoidably heuristic and there may be circumstances where they
are too optimistic.
To hedge against this risk, even after getting a seed of minimum
size we continue taking bigger reseeds until we reach by default
512 bits of estimated entropy per reseed. Hopefully it should be
difficult to make our entropy estimates a factor of 4 too high.
As a bonus, when the estimates are good, this gives us seeds which
can't be brute-forced within the universe under the known laws of
physics, which ought to really be enough for anybody.
This hedging addresses the same issue that motivates systems like
Fortuna. Our change doesn't go as far in that direction as Fortuna,
but it's much simpler.
The cost is that reseeds will happen about four times (by default)
less often. This is not really a critical issue, as frequent reseeds
mainly help us "recover" if someone glimpses the internal state --
which is largely an academic question, given what an attacker who can
read kernel memory is usually able to do. We still take a
regular-sized seed up front so as not to delay getting initialized.
Signed-off-by: Greg Price <price@mit.edu>
---
drivers/char/random.c | 38 ++++++++++++++++++++++++++++----------
1 file changed, 28 insertions(+), 10 deletions(-)
diff --git a/drivers/char/random.c b/drivers/char/random.c
index 855e401e5..79aee65fe 100644
--- a/drivers/char/random.c
+++ b/drivers/char/random.c
@@ -293,11 +293,20 @@
/*
* The minimum number of bits of estimated entropy to use in a reseed
- * of the main output pool.
+ * of the main output pool (for /dev/urandom and the kernel's internal
+ * use) before considering it secure.
*/
static int min_reseed_bits = 128;
/*
+ * The number of bits of estimated entropy to use in a reseed of the
+ * main output pool in the steady state. If this is larger than
+ * min_reseed_bits, then it serves as a hedge against situations where
+ * our entropy estimates are for whatever reason too optimistic.
+ */
+static int target_reseed_bits = 512;
+
+/*
* The minimum number of bits of entropy before we wake up a read on
* /dev/random.
*/
@@ -699,7 +708,7 @@ retry:
*/
r->entropy_since_push += nbits;
if (entropy_bits > random_write_wakeup_bits &&
- r->entropy_since_push >= min_reseed_bits) {
+ r->entropy_since_push >= target_reseed_bits) {
static struct entropy_store *last = &blocking_pool;
struct entropy_store *other = &blocking_pool;
@@ -942,9 +951,9 @@ static void account_xfer(struct entropy_store *dest, int nbytes,
*min_bytes = random_read_wakeup_bits / 8;
} else {
/* ... or a full reseed's worth for the nonblocking
- * pool, except if we're hardly seeded at all, we'll
- * settle for enough to double what we have. */
- *min_bytes = min(min_reseed_bits / 8,
+ * pool, except early on we'll settle for enough to
+ * double what we have. */
+ *min_bytes = min(target_reseed_bits / 8,
(2*dest->seed_entropy_bits + 7) / 8);
}
@@ -981,7 +990,7 @@ static void push_to_pool(struct work_struct *work)
struct entropy_store *r = container_of(work, struct entropy_store,
push_work);
BUG_ON(!r);
- _xfer_secondary_pool(r, min_reseed_bits/8);
+ _xfer_secondary_pool(r, target_reseed_bits/8);
trace_push_to_pool(r->name, r->entropy_count >> ENTROPY_SHIFT,
r->pull->entropy_count >> ENTROPY_SHIFT);
}
@@ -1522,8 +1531,8 @@ EXPORT_SYMBOL(generate_random_uuid);
#include <linux/sysctl.h>
-static int min_min_reseed_bits = 32;
-static int max_min_reseed_bits = OUTPUT_POOL_WORDS * 32;
+static int hard_min_reseed_bits = 32;
+static int max_reseed_bits = OUTPUT_POOL_WORDS * 32;
static int min_read_thresh = 8;
static int max_read_thresh = OUTPUT_POOL_WORDS * 32;
static int min_write_thresh;
@@ -1606,8 +1615,17 @@ struct ctl_table random_table[] = {
.maxlen = sizeof(int),
.mode = 0644,
.proc_handler = proc_dointvec_minmax,
- .extra1 = &min_min_reseed_bits,
- .extra2 = &max_min_reseed_bits,
+ .extra1 = &hard_min_reseed_bits,
+ .extra2 = &target_reseed_bits,
+ },
+ {
+ .procname = "target_reseed_bits",
+ .data = &target_reseed_bits,
+ .maxlen = sizeof(int),
+ .mode = 0644,
+ .proc_handler = proc_dointvec_minmax,
+ .extra1 = &min_reseed_bits,
+ .extra2 = &max_reseed_bits,
},
{
.procname = "read_wakeup_threshold",
--
1.8.3.2
prev parent reply other threads:[~2013-12-15 2:02 UTC|newest]
Thread overview: 15+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-12-15 2:00 [PATCH 00/14] random: rework reseeding Greg Price
2013-12-15 2:00 ` [PATCH 01/14] random: fix signedness bug Greg Price
2013-12-15 2:00 ` [PATCH 02/14] random: fix a (harmless) overflow Greg Price
2013-12-15 2:01 ` [PATCH 03/14] random: reserve for /dev/random only once /dev/urandom seeded Greg Price
2013-12-15 2:01 ` [PATCH 04/14] random: accept small seeds early on Greg Price
2013-12-15 2:01 ` [PATCH 05/14] random: move transfer accounting into account() helper Greg Price
2013-12-15 2:01 ` [PATCH 06/14] random: separate quantity of bytes extracted and entropy to credit Greg Price
2013-12-15 2:01 ` [PATCH 07/14] random: exploit any extra entropy too when reseeding Greg Price
2013-12-15 2:01 ` [PATCH 08/14] random: rate-limit reseeding only after properly seeded Greg Price
2013-12-15 2:01 ` [PATCH 09/14] random: reserve entropy for nonblocking pool early on Greg Price
2013-12-15 2:01 ` [PATCH 10/14] random: direct all routine input via input pool Greg Price
2013-12-15 2:01 ` [PATCH 11/14] random: separate entropy since auto-push from entropy_total Greg Price
2013-12-15 2:01 ` [PATCH 12/14] random: separate minimum reseed size from minimum /dev/random read Greg Price
2013-12-15 2:01 ` [PATCH 13/14] random: count only catastrophic reseeds for initialization Greg Price
2013-12-15 2:02 ` Greg Price [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20131215020202.GN27191@athena.dialup.mit.edu \
--to=price@mit.edu \
--cc=linux-kernel@vger.kernel.org \
--cc=tytso@MIT.EDU \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®