public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: Greg Price <price@MIT.EDU>
To: "Theodore Ts'o" <tytso@MIT.EDU>
Cc: linux-kernel@vger.kernel.org
Subject: [PATCH 12/14] random: separate minimum reseed size from minimum /dev/random read
Date: Sat, 14 Dec 2013 21:01:53 -0500	[thread overview]
Message-ID: <20131215020153.GL27191@athena.dialup.mit.edu> (raw)
In-Reply-To: <cover.1387067223.git.price@mit.edu>

We've used random_read_wakeup_bits for two quite different purposes
that may be best with different values.  The minimum number of bits
to wake up a blocked /dev/random reader has long been 64 by
default, and users may want to keep it there.  The minimum number
of bits in a seed for /dev/urandom and the kernel's general use, on
the other hand, should be at least 128 for good commercial security
and users may want it higher.

Make a new parameter for the minimum size of a reseed, and make it
128 by default.

Signed-off-by: Greg Price <price@mit.edu>
---
 drivers/char/random.c | 46 ++++++++++++++++++++++++++++++++--------------
 1 file changed, 32 insertions(+), 14 deletions(-)

diff --git a/drivers/char/random.c b/drivers/char/random.c
index 1f9c69662..b354fd15f 100644
--- a/drivers/char/random.c
+++ b/drivers/char/random.c
@@ -292,8 +292,14 @@
 #define ENTROPY_BITS(r) ((r)->entropy_count >> ENTROPY_SHIFT)
 
 /*
+ * The minimum number of bits of estimated entropy to use in a reseed
+ * of the main output pool.
+ */
+static int min_reseed_bits = 128;
+
+/*
  * The minimum number of bits of entropy before we wake up a read on
- * /dev/random.  Should be enough to do a significant reseed.
+ * /dev/random.
  */
 static int random_read_wakeup_bits = 64;
 
@@ -594,7 +600,7 @@ random_readable(int input_entropy_bits)
 	int thresh = random_read_wakeup_bits;
 	if (!nonblocking_pool.initialized)
 		/* ... that aren't reserved for the nonblocking pool. */
-		thresh += random_read_wakeup_bits;
+		thresh += min_reseed_bits;
 	return input_entropy_bits >= thresh;
 }
 
@@ -665,7 +671,7 @@ retry:
 
 	if (r == &nonblocking_pool) {
 		r->entropy_total += nbits;
-		if (!r->initialized && r->entropy_total > 128) {
+		if (!r->initialized && r->entropy_total >= min_reseed_bits) {
 			r->initialized = 1;
 			prandom_reseed_late();
 			pr_notice("random: %s pool is initialized\n", r->name);
@@ -692,7 +698,7 @@ retry:
 		 */
 		r->entropy_since_push += nbits;
 		if (entropy_bits > random_write_wakeup_bits &&
-		    r->entropy_since_push >= 2*random_read_wakeup_bits) {
+		    r->entropy_since_push >= min_reseed_bits) {
 			static struct entropy_store *last = &blocking_pool;
 			struct entropy_store *other = &blocking_pool;
 
@@ -929,15 +935,15 @@ static void xfer_secondary_pool(struct entropy_store *r, size_t nbytes)
 static void account_xfer(struct entropy_store *dest, int nbytes,
 			 int *min_bytes, int *reserved_bytes)
 {
-	/* Try to pull a full wakeup's worth if we might have just woken up
-	 * for it, and a full reseed's worth (which is controlled by the same
-	 * parameter) for the nonblocking pool... */
-	if (dest == &blocking_pool || dest->initialized) {
+	/* Try to pull a full wakeup's worth if we might have just
+	 * woken up for it... */
+	if (dest == &blocking_pool) {
 		*min_bytes = random_read_wakeup_bits / 8;
 	} else {
-		/* ... except if we're hardly seeded at all, we'll settle for
-		 * enough to double what we have. */
-		*min_bytes = min(random_read_wakeup_bits / 8,
+		/* ... 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,
 				 (dest->entropy_total+7) / 8);
 	}
 
@@ -945,7 +951,7 @@ static void account_xfer(struct entropy_store *dest, int nbytes,
 	 * when we really need it; later, reserve some for /dev/random */
 	*reserved_bytes = 0;
 	if (dest == &blocking_pool && !nonblocking_pool.initialized)
-		*reserved_bytes = random_read_wakeup_bits / 8;
+		*reserved_bytes = min_reseed_bits / 8;
 	else if (dest == &nonblocking_pool && dest->initialized)
 		*reserved_bytes = 2 * (random_read_wakeup_bits / 8);
 }
@@ -974,7 +980,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, random_read_wakeup_bits/8);
+	_xfer_secondary_pool(r, min_reseed_bits/8);
 	trace_push_to_pool(r->name, r->entropy_count >> ENTROPY_SHIFT,
 			   r->pull->entropy_count >> ENTROPY_SHIFT);
 }
@@ -1516,8 +1522,11 @@ EXPORT_SYMBOL(generate_random_uuid);
 
 #include <linux/sysctl.h>
 
-static int min_read_thresh = 8, min_write_thresh;
+static int min_min_reseed_bits = 32;
+static int max_min_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;
 static int max_write_thresh = INPUT_POOL_WORDS * 32;
 static char sysctl_bootid[16];
 
@@ -1592,6 +1601,15 @@ struct ctl_table random_table[] = {
 		.data		= &input_pool.entropy_count,
 	},
 	{
+		.procname	= "min_reseed_bits",
+		.data		= &min_reseed_bits,
+		.maxlen		= sizeof(int),
+		.mode		= 0644,
+		.proc_handler	= proc_dointvec_minmax,
+		.extra1		= &min_min_reseed_bits,
+		.extra2		= &max_min_reseed_bits,
+	},
+	{
 		.procname	= "read_wakeup_threshold",
 		.data		= &random_read_wakeup_bits,
 		.maxlen		= sizeof(int),
-- 
1.8.3.2


  parent reply	other threads:[~2013-12-15  2:01 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 ` Greg Price [this message]
2013-12-15  2:01 ` [PATCH 13/14] random: count only catastrophic reseeds for initialization Greg Price
2013-12-15  2:02 ` [PATCH 14/14] random: target giant reseeds, to be conservative Greg Price

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=20131215020153.GL27191@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