summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-07-04 11:16:01 -0400
committerPaul Gortmaker <paul.gortmaker@windriver.com>2012-08-17 15:36:05 -0400
commit79df207bf71de0fc8c2de8d0eead6cd9283a85ed (patch)
tree62a574397b2e65a3b0fc1981d4484988d6418450
parent9233ef75a68d43f82dbd4bf699177c4f9f55a1a3 (diff)
downloadlwn-79df207bf71de0fc8c2de8d0eead6cd9283a85ed.tar.gz
lwn-79df207bf71de0fc8c2de8d0eead6cd9283a85ed.zip
random: create add_device_randomness() interface
commit a2080a67abe9e314f9e9c2cc3a4a176e8a8f8793 upstream. Add a new interface, add_device_randomness() for adding data to the random pool that is likely to differ between two devices (or possibly even per boot). This would be things like MAC addresses or serial numbers, or the read-out of the RTC. This does *not* add any actual entropy to the pool, but it initializes the pool to different values for devices that might otherwise be identical and have very little entropy available to them (particularly common in the embedded world). [ Modified by tytso to mix in a timestamp, since there may be some variability caused by the time needed to detect/configure the hardware in question. ] Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> Signed-off-by: "Theodore Ts'o" <tytso@mit.edu> Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com>
-rw-r--r--drivers/char/random.c28
-rw-r--r--include/linux/random.h1
2 files changed, 29 insertions, 0 deletions
diff --git a/drivers/char/random.c b/drivers/char/random.c
index 3cfaf875aaf6..0c85b69cd8f6 100644
--- a/drivers/char/random.c
+++ b/drivers/char/random.c
@@ -125,10 +125,19 @@
* The current exported interfaces for gathering environmental noise
* from the devices are:
*
+ * void add_device_randomness(const void *buf, unsigned int size);
* void add_input_randomness(unsigned int type, unsigned int code,
* unsigned int value);
* void add_interrupt_randomness(int irq, int irq_flags);
*
+ * add_device_randomness() is for adding data to the random pool that
+ * is likely to differ between two devices (or possibly even per boot).
+ * This would be things like MAC addresses or serial numbers, or the
+ * read-out of the RTC. This does *not* add any actual entropy to the
+ * pool, but it initializes the pool to different values for devices
+ * that might otherwise be identical and have very little entropy
+ * available to them (particularly common in the embedded world).
+ *
* add_input_randomness() uses the input layer interrupt timing, as well as
* the event type information from the hardware.
*
@@ -639,6 +648,25 @@ static void set_timer_rand_state(unsigned int irq,
}
#endif
+/*
+ * Add device- or boot-specific data to the input and nonblocking
+ * pools to help initialize them to unique values.
+ *
+ * None of this adds any entropy, it is meant to avoid the
+ * problem of the nonblocking pool having similar initial state
+ * across largely identical devices.
+ */
+void add_device_randomness(const void *buf, unsigned int size)
+{
+ unsigned long time = get_cycles() ^ jiffies;
+
+ mix_pool_bytes(&input_pool, buf, size, NULL);
+ mix_pool_bytes(&input_pool, &time, sizeof(time), NULL);
+ mix_pool_bytes(&nonblocking_pool, buf, size, NULL);
+ mix_pool_bytes(&nonblocking_pool, &time, sizeof(time), NULL);
+}
+EXPORT_SYMBOL(add_device_randomness);
+
static struct timer_rand_state input_timer_state;
/*
diff --git a/include/linux/random.h b/include/linux/random.h
index 8a8560257af5..74510934b2a6 100644
--- a/include/linux/random.h
+++ b/include/linux/random.h
@@ -46,6 +46,7 @@ struct rand_pool_info {
extern void rand_initialize_irq(int irq);
+extern void add_device_randomness(const void *, unsigned int);
extern void add_input_randomness(unsigned int type, unsigned int code,
unsigned int value);
extern void add_interrupt_randomness(int irq, int irq_flags);