Re: Why does reading from /dev/urandom deplete entropy so much?

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

 



Alan Cox a écrit :
No matter what you consider as being better, changing a 12 years old and widely used userspace interface like /dev/urandom is simply not an option.

Fixing it to be more efficient in its use of entropy and also fixing the
fact its not actually a good random number source would be worth looking
at however.
Yes, since current behavior on network irq is very pessimistic.

If you have some trafic, (ie more than HZ/2 interrupts per second), then add_timer_randomness() feeds some entropy but gives no credit (calling credit_entropy_store() with nbits=0)

This is because we take into account only the jiffies difference, and not the get_cycles() that should give
us more entropy on most plaforms.

In this patch, I suggest that we feed only one u32 word of entropy, combination of the previous distinct words (with some of them being constant or so), so that the nbits estimation is less pessimistic, but also to
avoid injecting false entropy.

Signed-off-by: Eric Dumazet <[email protected]>


diff --git a/drivers/char/random.c b/drivers/char/random.c
index 5fee056..6eccfc9 100644
--- a/drivers/char/random.c
+++ b/drivers/char/random.c
@@ -550,8 +550,8 @@ static void credit_entropy_store(struct entropy_store *r, int nbits)
 
 /* There is one of these per entropy source */
 struct timer_rand_state {
-	cycles_t last_time;
-	long last_delta,last_delta2;
+	u32      last_word;
+	int last_delta,last_delta2;
 	unsigned dont_count_entropy:1;
 };
 
@@ -570,12 +570,17 @@ static struct timer_rand_state *irq_timer_state[NR_IRQS];
  */
 static void add_timer_randomness(struct timer_rand_state *state, unsigned num)
 {
-	struct {
-		cycles_t cycles;
-		long jiffies;
-		unsigned num;
+	union {
+		struct {
+			cycles_t cycles;
+			long jiffies;
+			unsigned num;
+		};
+		u32 words[1];
 	} sample;
-	long delta, delta2, delta3;
+	u32 word;
+	unsigned int ui;
+	int delta, delta2, delta3;
 
 	preempt_disable();
 	/* if over the trickle threshold, use only 1 in 4096 samples */
@@ -586,7 +591,12 @@ static void add_timer_randomness(struct timer_rand_state *state, unsigned num)
 	sample.jiffies = jiffies;
 	sample.cycles = get_cycles();
 	sample.num = num;
-	add_entropy_words(&input_pool, (u32 *)&sample, sizeof(sample)/4);
+
+	word = sample.words[0];
+	for (ui = 1; ui < sizeof(sample)/4; ui++)
+		word += sample.words[ui];
+
+	add_entropy_words(&input_pool, &word, 1);
 
 	/*
 	 * Calculate number of bits of randomness we probably added.
@@ -595,8 +605,8 @@ static void add_timer_randomness(struct timer_rand_state *state, unsigned num)
 	 */
 
 	if (!state->dont_count_entropy) {
-		delta = sample.jiffies - state->last_time;
-		state->last_time = sample.jiffies;
+		delta = word - state->last_word;
+		state->last_word = word;
 
 		delta2 = delta - state->last_delta;
 		state->last_delta = delta;

[Index of Archives]     [Kernel Newbies]     [Netfilter]     [Bugtraq]     [Photo]     [Stuff]     [Gimp]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Video 4 Linux]     [Linux for the blind]     [Linux Resources]
  Powered by Linux