--- /dev/null
+From c2557a303ab6712bb6e09447df828c557c710ac9 Mon Sep 17 00:00:00 2001
+From: Theodore Ts'o <tytso@mit.edu>
+Date: Thu, 5 Jul 2012 10:35:23 -0400
+Subject: random: add new get_random_bytes_arch() function
+
+From: Theodore Ts'o <tytso@mit.edu>
+
+commit c2557a303ab6712bb6e09447df828c557c710ac9 upstream.
+
+Create a new function, get_random_bytes_arch() which will use the
+architecture-specific hardware random number generator if it is
+present. Change get_random_bytes() to not use the HW RNG, even if it
+is avaiable.
+
+The reason for this is that the hw random number generator is fast (if
+it is present), but it requires that we trust the hardware
+manufacturer to have not put in a back door. (For example, an
+increasing counter encrypted by an AES key known to the NSA.)
+
+It's unlikely that Intel (for example) was paid off by the US
+Government to do this, but it's impossible for them to prove otherwise
+ --- especially since Bull Mountain is documented to use AES as a
+whitener. Hence, the output of an evil, trojan-horse version of
+RDRAND is statistically indistinguishable from an RDRAND implemented
+to the specifications claimed by Intel. Short of using a tunnelling
+electronic microscope to reverse engineer an Ivy Bridge chip and
+disassembling and analyzing the CPU microcode, there's no way for us
+to tell for sure.
+
+Since users of get_random_bytes() in the Linux kernel need to be able
+to support hardware systems where the HW RNG is not present, most
+time-sensitive users of this interface have already created their own
+cryptographic RNG interface which uses get_random_bytes() as a seed.
+So it's much better to use the HW RNG to improve the existing random
+number generator, by mixing in any entropy returned by the HW RNG into
+/dev/random's entropy pool, but to always _use_ /dev/random's entropy
+pool.
+
+This way we get almost of the benefits of the HW RNG without any
+potential liabilities. The only benefits we forgo is the
+speed/performance enhancements --- and generic kernel code can't
+depend on depend on get_random_bytes() having the speed of a HW RNG
+anyway.
+
+For those places that really want access to the arch-specific HW RNG,
+if it is available, we provide get_random_bytes_arch().
+
+Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/char/random.c | 27 +++++++++++++++++++++++----
+ include/linux/random.h | 1 +
+ 2 files changed, 24 insertions(+), 4 deletions(-)
+
+--- a/drivers/char/random.c
++++ b/drivers/char/random.c
+@@ -1038,11 +1038,28 @@ static ssize_t extract_entropy_user(stru
+
+ /*
+ * This function is the exported kernel interface. It returns some
+- * number of good random numbers, suitable for seeding TCP sequence
+- * numbers, etc.
++ * number of good random numbers, suitable for key generation, seeding
++ * TCP sequence numbers, etc. It does not use the hw random number
++ * generator, if available; use get_random_bytes_arch() for that.
+ */
+ void get_random_bytes(void *buf, int nbytes)
+ {
++ extract_entropy(&nonblocking_pool, buf, nbytes, 0, 0);
++}
++EXPORT_SYMBOL(get_random_bytes);
++
++/*
++ * This function will use the architecture-specific hardware random
++ * number generator if it is available. The arch-specific hw RNG will
++ * almost certainly be faster than what we can do in software, but it
++ * is impossible to verify that it is implemented securely (as
++ * opposed, to, say, the AES encryption of a sequence number using a
++ * key known by the NSA). So it's useful if we need the speed, but
++ * only if we're willing to trust the hardware manufacturer not to
++ * have put in a back door.
++ */
++void get_random_bytes_arch(void *buf, int nbytes)
++{
+ char *p = buf;
+
+ while (nbytes) {
+@@ -1057,9 +1074,11 @@ void get_random_bytes(void *buf, int nby
+ nbytes -= chunk;
+ }
+
+- extract_entropy(&nonblocking_pool, p, nbytes, 0, 0);
++ if (nbytes)
++ extract_entropy(&nonblocking_pool, p, nbytes, 0, 0);
+ }
+-EXPORT_SYMBOL(get_random_bytes);
++EXPORT_SYMBOL(get_random_bytes_arch);
++
+
+ /*
+ * init_std_data - initialize pool with system data
+--- a/include/linux/random.h
++++ b/include/linux/random.h
+@@ -56,6 +56,7 @@ extern void add_input_randomness(unsigne
+ extern void add_interrupt_randomness(int irq, int irq_flags);
+
+ extern void get_random_bytes(void *buf, int nbytes);
++extern void get_random_bytes_arch(void *buf, int nbytes);
+ void generate_random_uuid(unsigned char uuid_out[16]);
+
+ #ifndef MODULE
--- /dev/null
+From e6d4947b12e8ad947add1032dd754803c6004824 Mon Sep 17 00:00:00 2001
+From: Theodore Ts'o <tytso@mit.edu>
+Date: Thu, 5 Jul 2012 10:21:01 -0400
+Subject: random: use the arch-specific rng in xfer_secondary_pool
+
+From: Theodore Ts'o <tytso@mit.edu>
+
+commit e6d4947b12e8ad947add1032dd754803c6004824 upstream.
+
+If the CPU supports a hardware random number generator, use it in
+xfer_secondary_pool(), where it will significantly improve things and
+where we can afford it.
+
+Also, remove the use of the arch-specific rng in
+add_timer_randomness(), since the call is significantly slower than
+get_cycles(), and we're much better off using it in
+xfer_secondary_pool() anyway.
+
+Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/char/random.c | 25 ++++++++++++++++---------
+ 1 file changed, 16 insertions(+), 9 deletions(-)
+
+--- a/drivers/char/random.c
++++ b/drivers/char/random.c
+@@ -254,6 +254,7 @@
+ #include <linux/cryptohash.h>
+ #include <linux/fips.h>
+ #include <linux/ptrace.h>
++#include <linux/kmemcheck.h>
+
+ #ifdef CONFIG_GENERIC_HARDIRQS
+ # include <linux/irq.h>
+@@ -702,11 +703,7 @@ static void add_timer_randomness(struct
+ goto out;
+
+ sample.jiffies = jiffies;
+-
+- /* Use arch random value, fall back to cycles */
+- if (!arch_get_random_int(&sample.cycles))
+- sample.cycles = get_cycles();
+-
++ sample.cycles = get_cycles();
+ sample.num = num;
+ mix_pool_bytes(&input_pool, &sample, sizeof(sample), NULL);
+
+@@ -838,7 +835,11 @@ static ssize_t extract_entropy(struct en
+ */
+ static void xfer_secondary_pool(struct entropy_store *r, size_t nbytes)
+ {
+- __u32 tmp[OUTPUT_POOL_WORDS];
++ union {
++ __u32 tmp[OUTPUT_POOL_WORDS];
++ long hwrand[4];
++ } u;
++ int i;
+
+ if (r->pull && r->entropy_count < nbytes * 8 &&
+ r->entropy_count < r->poolinfo->POOLBITS) {
+@@ -849,17 +850,23 @@ static void xfer_secondary_pool(struct e
+ /* pull at least as many as BYTES as wakeup BITS */
+ bytes = max_t(int, bytes, random_read_wakeup_thresh / 8);
+ /* but never more than the buffer size */
+- bytes = min_t(int, bytes, sizeof(tmp));
++ bytes = min_t(int, bytes, sizeof(u.tmp));
+
+ DEBUG_ENT("going to reseed %s with %d bits "
+ "(%d of %d requested)\n",
+ r->name, bytes * 8, nbytes * 8, r->entropy_count);
+
+- bytes = extract_entropy(r->pull, tmp, bytes,
++ bytes = extract_entropy(r->pull, u.tmp, bytes,
+ random_read_wakeup_thresh / 8, rsvd);
+- mix_pool_bytes(r, tmp, bytes, NULL);
++ mix_pool_bytes(r, u.tmp, bytes, NULL);
+ credit_entropy_bits(r, bytes*8);
+ }
++ kmemcheck_mark_initialized(&u.hwrand, sizeof(u.hwrand));
++ for (i = 0; i < 4; i++)
++ if (arch_get_random_long(&u.hwrand[i]))
++ break;
++ if (i)
++ mix_pool_bytes(r, &u.hwrand, sizeof(u.hwrand), 0);
+ }
+
+ /*