mirror of https://lore.kernel.org/lkml/
 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 13/14] random: count only catastrophic reseeds for initialization
Date: Sat, 14 Dec 2013 21:01:58 -0500	[thread overview]
Message-ID: <20131215020158.GM27191@athena.dialup.mit.edu> (raw)
In-Reply-To: <cover.1387067223.git.price@mit.edu>

In the earlier commit "random: direct all routine input via input pool",
we made sure that input comes in large reseeds which should be big
enough to prevent an attacker from brute-forcing any one of them.
This is important because a succession of small reseeds, if
interspersed with output an attacker sees, could be brute-forced one
by one.  Now update our accounting accordingly so that we track the
largest single reseed, rather than the total of potentially small
reseeds, and call ourselves initialized only with one large reseed.

This shouldn't make much difference with the current code, as we
don't make repeated small reseeds anyway, but it's best to be clear.

Rename entropy_total to seed_entropy_bits to reflect its new function.

While touching the not-yet-initialized warnings, checkpatch complains
about printk(KERN_NOTICE, ...), so switch to pr_notice etc.

Signed-off-by: Greg Price <price@mit.edu>
---
 drivers/char/random.c         | 24 ++++++++++++------------
 include/trace/events/random.h | 13 +++++++------
 2 files changed, 19 insertions(+), 18 deletions(-)

diff --git a/drivers/char/random.c b/drivers/char/random.c
index b354fd15f..855e401e5 100644
--- a/drivers/char/random.c
+++ b/drivers/char/random.c
@@ -432,7 +432,7 @@ struct entropy_store {
 	unsigned short input_rotate;
 	int entropy_count;
 	int entropy_since_push;
-	int entropy_total;
+	int seed_entropy_bits;
 	unsigned int initialized:1;
 	unsigned int limit:1;
 	unsigned int last_data_init:1;
@@ -670,8 +670,9 @@ retry:
 		goto retry;
 
 	if (r == &nonblocking_pool) {
-		r->entropy_total += nbits;
-		if (!r->initialized && r->entropy_total >= min_reseed_bits) {
+		r->seed_entropy_bits = max(nbits, r->seed_entropy_bits);
+		if (!r->initialized &&
+		    r->seed_entropy_bits >= min_reseed_bits) {
 			r->initialized = 1;
 			prandom_reseed_late();
 			pr_notice("random: %s pool is initialized\n", r->name);
@@ -681,7 +682,7 @@ retry:
 	trace_credit_entropy_bits(r->name, nbits,
 				  entropy_count >> ENTROPY_SHIFT,
 				  r->entropy_since_push,
-				  r->entropy_total, _RET_IP_);
+				  r->seed_entropy_bits, _RET_IP_);
 
 	if (r == &input_pool) {
 		int entropy_bits = entropy_count >> ENTROPY_SHIFT;
@@ -944,7 +945,7 @@ static void account_xfer(struct entropy_store *dest, int nbytes,
 		 * 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);
+				 (2*dest->seed_entropy_bits + 7) / 8);
 	}
 
 	/* Reserve a reseed's worth for the nonblocking pool early on
@@ -1215,10 +1216,9 @@ void get_random_bytes(void *buf, int nbytes)
 {
 #if DEBUG_RANDOM_BOOT > 0
 	if (unlikely(nonblocking_pool.initialized == 0))
-		printk(KERN_NOTICE "random: %pF get_random_bytes called "
-		       "with %d bits of entropy available\n",
-		       (void *) _RET_IP_,
-		       nonblocking_pool.entropy_total);
+		pr_notice(
+		    "random: %pF get_random_bytes called with only %d bits of seed entropy available\n",
+		    (void *) _RET_IP_, nonblocking_pool.seed_entropy_bits);
 #endif
 	trace_get_random_bytes(nbytes, _RET_IP_);
 	extract_entropy(&nonblocking_pool, buf, nbytes, NULL, NULL);
@@ -1355,9 +1355,9 @@ urandom_read(struct file *file, char __user *buf, size_t nbytes, loff_t *ppos)
 	int ret;
 
 	if (unlikely(nonblocking_pool.initialized == 0))
-		printk_once(KERN_NOTICE "random: %s urandom read "
-			    "with %d bits of entropy available\n",
-			    current->comm, nonblocking_pool.entropy_total);
+		pr_notice_once(
+		    "random: %s urandom read with only %d bits of seed entropy available\n",
+		    current->comm, nonblocking_pool.seed_entropy_bits);
 
 	ret = extract_entropy_user(&nonblocking_pool, buf, nbytes);
 
diff --git a/include/trace/events/random.h b/include/trace/events/random.h
index 4edf5ceb5..d07a80146 100644
--- a/include/trace/events/random.h
+++ b/include/trace/events/random.h
@@ -61,17 +61,18 @@ DEFINE_EVENT(random__mix_pool_bytes, mix_pool_bytes_nolock,
 
 TRACE_EVENT(credit_entropy_bits,
 	TP_PROTO(const char *pool_name, int bits, int entropy_count,
-		 int entropy_since_push, int entropy_total, unsigned long IP),
+		 int entropy_since_push, int seed_entropy_bits,
+		 unsigned long IP),
 
 	TP_ARGS(pool_name, bits, entropy_count, entropy_since_push,
-		entropy_total, IP),
+		seed_entropy_bits, IP),
 
 	TP_STRUCT__entry(
 		__field( const char *,	pool_name		)
 		__field(	  int,	bits			)
 		__field(	  int,	entropy_count		)
 		__field(	  int,	entropy_since_push	)
-		__field(	  int,	entropy_total		)
+		__field(	  int,	seed_entropy_bits	)
 		__field(unsigned long,	IP			)
 	),
 
@@ -80,14 +81,14 @@ TRACE_EVENT(credit_entropy_bits,
 		__entry->bits			= bits;
 		__entry->entropy_count		= entropy_count;
 		__entry->entropy_since_push	= entropy_since_push;
-		__entry->entropy_total		= entropy_total;
+		__entry->seed_entropy_bits	= seed_entropy_bits;
 		__entry->IP			= IP;
 	),
 
 	TP_printk("%s pool: bits %d entropy_count %d entropy_since_push %d "
-		  "entropy_total %d caller %pF", __entry->pool_name,
+		  "seed_entropy_bits %d caller %pF", __entry->pool_name,
 		  __entry->bits, __entry->entropy_count,
-		  __entry->entropy_since_push, __entry->entropy_total,
+		  __entry->entropy_since_push, __entry->seed_entropy_bits,
 		  (void *)__entry->IP)
 );
 
-- 
1.8.3.2


  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 ` Greg Price [this message]
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=20131215020158.GM27191@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®