Re: Different behavior for kernel entropy in 4.13 kernel

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Seems the attachment was stripped, probably an anti spam measure.  So,
I'll just put the text here.

>From 8be9a727727b2a264e55abe8faefb0e5d29b6fd6 Mon Sep 17 00:00:00 2001
From: Fedora Kernel Team <kernel-team@xxxxxxxxxxxxxxxxx>
Date: Sun, 20 Aug 2017 12:16:14 -0700
Subject: [PATCH] use input entropy to reseed crng based on timer and
input entropy pool level

---
 drivers/char/random.c | 62
++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 52
insertions(+), 10 deletions(-)

diff --git a/drivers/char/random.c b/drivers/char/random.c
index 8ad9270..07da211 100644
--- a/drivers/char/random.c
+++ b/drivers/char/random.c
@@ -315,6 +315,13 @@ static int random_read_wakeup_bits = 64;
 static int random_write_wakeup_bits = 28 * OUTPUT_POOL_WORDS;
 
 /*
+ * The minimum number of seconds between urandom pool reseeding.  We
+ * do this to limit the amount of entropy that can be drained from the
+ * input pool even if there are heavy demands on /dev/urandom.
+ */
+static int random_min_urandom_seed = 60;
+
+/*
  * Originally, we used a primitive polynomial of degree .poolwords
  * over GF(2).  The taps for various sizes are defined below.  They
  * were chosen to be evenly spaced except for the last tap, which is 1
@@ -399,6 +406,8 @@ static struct poolinfo {
 #endif
 };
 
+#define CRNG_RESEED_INTERVAL (random_min_urandom_seed*HZ)
+
 /*
  * Static global variables
  */
@@ -472,6 +481,7 @@ static ssize_t _extract_entropy(struct
entropy_store *r, void *buf, size_t nbytes, int fips);
 
 static void crng_reseed(struct crng_state *crng, struct entropy_store
*r); +static void crng_entropy_reseed(struct crng_state *crng, struct
entropy_store *r); static void push_to_pool(struct work_struct *work);
 static __u32 input_pool_data[INPUT_POOL_WORDS] __latent_entropy;
 static __u32 blocking_pool_data[OUTPUT_POOL_WORDS] __latent_entropy;
@@ -702,13 +712,23 @@ static void credit_entropy_bits(struct
entropy_store *r, int nbits) r->entropy_total, _RET_IP_);
 
 	if (r == &input_pool) {
-		int entropy_bits = entropy_count >> ENTROPY_SHIFT;
-
-		if (crng_init < 2 && entropy_bits >= 128) {
-			crng_reseed(&primary_crng, r);
-			entropy_bits = r->entropy_count >>
ENTROPY_SHIFT;
+    int entropy_bits;
+		if (crng_init < 2)
+    { entropy_bits = entropy_count >> ENTROPY_SHIFT;
+      if (entropy_bits >= 128)
+      { crng_reseed(&primary_crng, r);
+        entropy_bits = r->entropy_count >> ENTROPY_SHIFT;
+      }
+		}
+    else if (crng_init == 2)
+    { if (r->entropy_count >= 4000)
+      { struct crng_state *crng = &primary_crng;
+        if (time_after(jiffies, crng->init_time +
CRNG_RESEED_INTERVAL))
+        { crng_entropy_reseed(crng, r);
+          entropy_bits = r->entropy_count - 256;
+        }
+      }
 		}
-
 		/* should we wake readers? */
 		if (entropy_bits >= random_read_wakeup_bits) {
 			wake_up_interruptible(&random_read_wait);
@@ -721,7 +741,6 @@ static void credit_entropy_bits(struct
entropy_store *r, int nbits) r->initialized &&
 		    r->entropy_total >= 2*random_read_wakeup_bits) {
 			struct entropy_store *other = &blocking_pool;
-
 			if (other->entropy_count <=
 			    3 * other->poolinfo->poolfracbits / 4) {
 				schedule_work(&other->push_work);
@@ -751,8 +770,6 @@ static int credit_entropy_bits_safe(struct
entropy_store *r, int nbits) *
  *********************************************************************/
 
-#define CRNG_RESEED_INTERVAL (300*HZ)
-
 static DECLARE_WAIT_QUEUE_HEAD(crng_init_wait);
 
 #ifdef CONFIG_NUMA
@@ -851,6 +868,32 @@ static void crng_reseed(struct crng_state *crng,
struct entropy_store *r) }
 }
 
+static void crng_entropy_reseed(struct crng_state *crng, struct
entropy_store *r) +{
+	unsigned long	flags;
+	int		i, num;
+	union {
+		__u8	block[CHACHA20_BLOCK_SIZE];
+		__u32	key[8];
+	} buf;
+
+	if (r) {
+		num = extract_entropy(r, &buf, 32, 16, 0);
+		if (num == 0)
+			return;
+	}
+	spin_lock_irqsave(&primary_crng.lock, flags);
+	for (i = 0; i < 8; i++) {
+		crng->state[i+4] ^= buf.key[i];
+	}
+	memzero_explicit(&buf, sizeof(buf));
+	crng->init_time = jiffies;
+	spin_unlock_irqrestore(&primary_crng.lock, flags);
+	if (crng == &primary_crng && crng_init == 2) {
+		pr_notice("random: crng entropy reseed done\n");
+	}
+}
+
 static void _extract_crng(struct crng_state *crng,
 			  __u8 out[CHACHA20_BLOCK_SIZE])
 {
@@ -1942,7 +1985,6 @@ SYSCALL_DEFINE3(getrandom, char __user *, buf,
size_t, count, static int min_read_thresh = 8, min_write_thresh;
 static int max_read_thresh = OUTPUT_POOL_WORDS * 32;
 static int max_write_thresh = INPUT_POOL_WORDS * 32;
-static int random_min_urandom_seed = 60;
 static char sysctl_bootid[16];
 
 /*
-- 
2.9.5
_______________________________________________
kernel mailing list -- kernel@xxxxxxxxxxxxxxxxxxxxxxx
To unsubscribe send an email to kernel-leave@xxxxxxxxxxxxxxxxxxxxxxx




[Index of Archives]     [Fedora General Discussion]     [Older Fedora Users Archive]     [Fedora Advisory Board]     [Fedora Security]     [Fedora Devel Java]     [Fedora Legacy]     [Fedora Desktop]     [ATA RAID]     [Fedora Marketing]     [Fedora Mentors]     [Fedora Package Announce]     [Fedora Package Review]     [Fedora Music]     [Fedora Packaging]     [Centos]     [Fedora SELinux]     [Coolkey]     [Yum Users]     [Tux]     [Yosemite News]     [KDE Users]     [Fedora Art]     [Fedora Docs]     [USB]     [Asterisk PBX]

  Powered by Linux