lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20131215020158.GM27191@athena.dialup.mit.edu>
Date:	Sat, 14 Dec 2013 21:01:58 -0500
From:	Greg Price <price@....EDU>
To:	"Theodore Ts'o" <tytso@....edu>
Cc:	linux-kernel@...r.kernel.org
Subject: [PATCH 13/14] random: count only catastrophic reseeds for
 initialization

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@....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

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ