linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] /dev/random: Insufficient of entropy on many architectures
@ 2013-09-10 11:31 Stephan Mueller
  2013-09-10 11:46 ` Geert Uytterhoeven
                   ` (2 more replies)
  0 siblings, 3 replies; 58+ messages in thread
From: Stephan Mueller @ 2013-09-10 11:31 UTC (permalink / raw)
  To: Theodore Ts'o, LKML; +Cc: dave.taht

Hi,

/dev/random uses the get_cycles() function to obtain entropy in addition to jiffies and the event value of hardware events.

Typically the high-resolution timer of get_cycles delivers the majority of entropy, because the event value is quite deterministic and jiffies are very coarse.

However, on the following architectures, get_cycles will return 0:

- MIPS

- User mode Linux

- Sparc 32 bit

- M68K

- M32R

- Hexagon

- H8/300

- FR-V

- CRIS

- AVR32

- ARC

- METAG

- Microblaze

- SCORE

- SH

- Unicore32

That means that on those architectures, /dev/random will not deliver as much entropy as you would hope.

The following patch uses the clocksource clock for a time value in case get_cycles returns 0. As clocksource may not be available during boot time, a flag is introduced which allows random.c to check the availability of clocksource.

Patch tested with disabled call to get_cycles on an x86_64 system to verify that clocksource delivers data.

Ciao
Stephan

Signed-off-by: Stephan Mueller <smueller@chronox.de>

---
diff --git a/drivers/char/random.c b/drivers/char/random.c
index 0d91fe5..d2d14a1 100644
--- a/drivers/char/random.c
+++ b/drivers/char/random.c
@@ -255,6 +255,7 @@
 #include <linux/fips.h>
 #include <linux/ptrace.h>
 #include <linux/kmemcheck.h>
+#include <linux/time.h>
 
 #ifdef CONFIG_GENERIC_HARDIRQS
 # include <linux/irq.h>
@@ -633,6 +634,23 @@ struct timer_rand_state {
 	unsigned dont_count_entropy:1;
 };
 
+static inline __u64 get_nstime(void)
+{
+	struct timespec ts;
+	__u64 tmp = 0;
+
+	tmp = get_cycles();
+
+	if((0 == tmp) &&
+	   timekeeping_initialized() &&
+	   (0 == __getnstimeofday(&ts)))
+	{
+		tmp = ts.tv_sec;
+		tmp = tmp << 32;
+		tmp = tmp | ts.tv_nsec;
+	}
+	return tmp;
+}
 /*
  * Add device- or boot-specific data to the input and nonblocking
  * pools to help initialize them to unique values.
@@ -643,7 +661,7 @@ struct timer_rand_state {
  */
 void add_device_randomness(const void *buf, unsigned int size)
 {
-	unsigned long time = get_cycles() ^ jiffies;
+	unsigned long time = get_nstime() ^ jiffies;
 
 	mix_pool_bytes(&input_pool, buf, size, NULL);
 	mix_pool_bytes(&input_pool, &time, sizeof(time), NULL);
@@ -680,7 +698,7 @@ static void add_timer_randomness(struct timer_rand_state *state, unsigned num)
 		goto out;
 
 	sample.jiffies = jiffies;
-	sample.cycles = get_cycles();
+	sample.cycles = get_nstime();
 	sample.num = num;
 	mix_pool_bytes(&input_pool, &sample, sizeof(sample), NULL);
 
@@ -747,7 +765,7 @@ void add_interrupt_randomness(int irq, int irq_flags)
 	struct fast_pool	*fast_pool = &__get_cpu_var(irq_randomness);
 	struct pt_regs		*regs = get_irq_regs();
 	unsigned long		now = jiffies;
-	__u32			input[4], cycles = get_cycles();
+	__u32			input[4], cycles = get_nstime();
 
 	input[0] = cycles ^ jiffies;
 	input[1] = irq;
@@ -1486,7 +1504,7 @@ unsigned int get_random_int(void)
 
 	hash = get_cpu_var(get_random_int_hash);
 
-	hash[0] += current->pid + jiffies + get_cycles();
+	hash[0] += current->pid + jiffies + get_nstime();
 	md5_transform(hash, random_int_secret);
 	ret = hash[0];
 	put_cpu_var(get_random_int_hash);
diff --git a/include/linux/time.h b/include/linux/time.h
index d5d229b..0922661 100644
--- a/include/linux/time.h
+++ b/include/linux/time.h
@@ -180,6 +180,7 @@ extern int timekeeping_inject_offset(struct timespec *ts);
 extern s32 timekeeping_get_tai_offset(void);
 extern void timekeeping_set_tai_offset(s32 tai_offset);
 extern void timekeeping_clocktai(struct timespec *ts);
+extern bool timekeeping_initialized(void);
 
 struct tms;
 extern void do_sys_times(struct tms *);
diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c
index 48b9fff..75b1613 100644
--- a/kernel/time/timekeeping.c
+++ b/kernel/time/timekeeping.c
@@ -35,6 +35,7 @@ static struct timekeeper timekeeper;
 static DEFINE_RAW_SPINLOCK(timekeeper_lock);
 static seqcount_t timekeeper_seq;
 static struct timekeeper shadow_timekeeper;
+static bool timekeeper_enabled = 0;
 
 /* flag for if timekeeping is suspended */
 int __read_mostly timekeeping_suspended;
@@ -833,8 +834,15 @@ void __init timekeeping_init(void)
 
 	write_seqcount_end(&timekeeper_seq);
 	raw_spin_unlock_irqrestore(&timekeeper_lock, flags);
+	timekeeper_enabled = 1;
 }
 
+bool timekeeping_initialized(void)
+{
+	return timekeeper_enabled;
+}
+EXPORT_SYMBOL(timekeeping_initialized);
+
 /* time in seconds when suspend began */
 static struct timespec timekeeping_suspend_time;
 


^ permalink raw reply related	[flat|nested] 58+ messages in thread

end of thread, other threads:[~2013-10-14 21:13 UTC | newest]

Thread overview: 58+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-09-10 11:31 [PATCH] /dev/random: Insufficient of entropy on many architectures Stephan Mueller
2013-09-10 11:46 ` Geert Uytterhoeven
2013-09-10 15:04 ` Theodore Ts'o
2013-09-10 16:54   ` Stephan Mueller
2013-09-10 18:25     ` Theodore Ts'o
2013-09-10 19:15       ` Stephan Mueller
2013-10-10  6:50       ` Pavel Machek
2013-10-14 21:13         ` Theodore Ts'o
2013-09-10 20:48   ` Geert Uytterhoeven
2013-09-10 21:14     ` Theodore Ts'o
2013-09-11  6:49       ` Stephan Mueller
2013-09-12 11:59         ` Geert Uytterhoeven
2013-09-12 12:08           ` Stephan Mueller
2013-09-12 12:15             ` Geert Uytterhoeven
2013-09-12 12:35               ` Stephan Mueller
2013-09-12 12:47                 ` Geert Uytterhoeven
2013-09-12 12:57                   ` Stephan Mueller
2013-09-12 21:18               ` Jörn Engel
2013-09-13 11:33             ` Thorsten Glaser
2013-09-12 14:25           ` Theodore Ts'o
2013-09-10 19:38 ` John Stultz
2013-09-10 19:44   ` John Stultz
2013-09-10 19:47   ` Stephan Mueller
2013-09-10 20:35     ` John Stultz
2013-09-10 20:38   ` Theodore Ts'o
2013-09-10 20:46     ` John Stultz
2013-09-10 21:10       ` Theodore Ts'o
2013-09-10 22:08         ` John Stultz
2013-09-10 22:33           ` Theodore Ts'o
2013-09-11  0:31             ` John Stultz
2013-09-11  0:50               ` Theodore Ts'o
2013-09-11  1:14                 ` John Stultz
2013-09-12 20:46                 ` H. Peter Anvin
2013-09-12 21:07                 ` Jörn Engel
2013-09-12 23:31                   ` Theodore Ts'o
2013-09-12 23:35                     ` Jörn Engel
2013-09-13  0:00                       ` Jörn Engel
2013-09-16 15:40                     ` [PATCH,RFC] random: make fast_mix() honor its name Jörn Engel
2013-09-21 21:25                       ` Theodore Ts'o
2013-09-21 21:41                         ` Theodore Ts'o
2013-09-22  3:05                           ` Theodore Ts'o
2013-09-22 21:01                             ` Jörg-Volker Peetz
2013-09-22 21:27                               ` Theodore Ts'o
2013-09-22 20:53                                 ` Jörn Engel
2013-09-22 23:36                                   ` Theodore Ts'o
2013-09-23  0:16                                     ` Jörn Engel
2013-09-23  2:43                                       ` Theodore Ts'o
2013-09-23 15:02                                         ` Jörn Engel
2013-09-23  7:39                                 ` Jörg-Volker Peetz
2013-09-22 20:31                           ` Jörn Engel
2013-09-22 20:14                         ` Jörn Engel
2013-09-12 21:31           ` [PATCH] /dev/random: Insufficient of entropy on many architectures Jörn Engel
2013-09-13  5:36             ` Stephan Mueller
2013-09-13 11:54               ` Thorsten Glaser
2013-09-13 19:29                 ` Theodore Ts'o
2013-09-13 15:26               ` Jörn Engel
2013-09-13 18:59               ` Theodore Ts'o
2013-09-15 11:12                 ` Stephan Mueller

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).