aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char
diff options
context:
space:
mode:
authorH. Peter Anvin <hpa@linux.intel.com>2014-03-17 19:36:28 -0400
committerTheodore Ts'o <tytso@mit.edu>2014-03-19 22:22:06 -0400
commit83664a6928a420b5ccfc0cf23ddbfe3634fea271 (patch)
treeb8849a88a88a0894c1131a0234100a98b0d73d02 /drivers/char
parentd20f78d252778e0fae8f8256e602bd682eb2185c (diff)
random: Use arch_get_random_seed*() at init time and once a second
Use arch_get_random_seed*() in two places in the Linux random driver (drivers/char/random.c): 1. During entropy pool initialization, use RDSEED in favor of RDRAND, with a fallback to the latter. Entropy exhaustion is unlikely to happen there on physical hardware as the machine is single-threaded at that point, but could happen in a virtual machine. In that case, the fallback to RDRAND will still provide more than adequate entropy pool initialization. 2. Once a second, issue RDSEED and, if successful, feed it to the entropy pool. To ensure an extra layer of security, only credit half the entropy just in case. Suggested-by: Linus Torvalds <torvalds@linux-foundation.org> Reviewed-by: Ingo Molnar <mingo@kernel.org> Signed-off-by: H. Peter Anvin <hpa@linux.intel.com> Signed-off-by: Theodore Ts'o <tytso@mit.edu>
Diffstat (limited to 'drivers/char')
-rw-r--r--drivers/char/random.c24
1 files changed, 20 insertions, 4 deletions
diff --git a/drivers/char/random.c b/drivers/char/random.c
index d07575c99a5f..a4bea7775e0f 100644
--- a/drivers/char/random.c
+++ b/drivers/char/random.c
@@ -844,6 +844,8 @@ void add_interrupt_randomness(int irq, int irq_flags)
844 cycles_t cycles = random_get_entropy(); 844 cycles_t cycles = random_get_entropy();
845 __u32 input[4], c_high, j_high; 845 __u32 input[4], c_high, j_high;
846 __u64 ip; 846 __u64 ip;
847 unsigned long seed;
848 int credit;
847 849
848 c_high = (sizeof(cycles) > 4) ? cycles >> 32 : 0; 850 c_high = (sizeof(cycles) > 4) ? cycles >> 32 : 0;
849 j_high = (sizeof(now) > 4) ? now >> 32 : 0; 851 j_high = (sizeof(now) > 4) ? now >> 32 : 0;
@@ -862,20 +864,33 @@ void add_interrupt_randomness(int irq, int irq_flags)
862 864
863 r = nonblocking_pool.initialized ? &input_pool : &nonblocking_pool; 865 r = nonblocking_pool.initialized ? &input_pool : &nonblocking_pool;
864 __mix_pool_bytes(r, &fast_pool->pool, sizeof(fast_pool->pool), NULL); 866 __mix_pool_bytes(r, &fast_pool->pool, sizeof(fast_pool->pool), NULL);
867
865 /* 868 /*
866 * If we don't have a valid cycle counter, and we see 869 * If we don't have a valid cycle counter, and we see
867 * back-to-back timer interrupts, then skip giving credit for 870 * back-to-back timer interrupts, then skip giving credit for
868 * any entropy. 871 * any entropy, otherwise credit 1 bit.
869 */ 872 */
873 credit = 1;
870 if (cycles == 0) { 874 if (cycles == 0) {
871 if (irq_flags & __IRQF_TIMER) { 875 if (irq_flags & __IRQF_TIMER) {
872 if (fast_pool->last_timer_intr) 876 if (fast_pool->last_timer_intr)
873 return; 877 credit = 0;
874 fast_pool->last_timer_intr = 1; 878 fast_pool->last_timer_intr = 1;
875 } else 879 } else
876 fast_pool->last_timer_intr = 0; 880 fast_pool->last_timer_intr = 0;
877 } 881 }
878 credit_entropy_bits(r, 1); 882
883 /*
884 * If we have architectural seed generator, produce a seed and
885 * add it to the pool. For the sake of paranoia count it as
886 * 50% entropic.
887 */
888 if (arch_get_random_seed_long(&seed)) {
889 __mix_pool_bytes(r, &seed, sizeof(seed), NULL);
890 credit += sizeof(seed) * 4;
891 }
892
893 credit_entropy_bits(r, credit);
879} 894}
880 895
881#ifdef CONFIG_BLOCK 896#ifdef CONFIG_BLOCK
@@ -1235,7 +1250,8 @@ static void init_std_data(struct entropy_store *r)
1235 r->last_pulled = jiffies; 1250 r->last_pulled = jiffies;
1236 mix_pool_bytes(r, &now, sizeof(now), NULL); 1251 mix_pool_bytes(r, &now, sizeof(now), NULL);
1237 for (i = r->poolinfo->poolbytes; i > 0; i -= sizeof(rv)) { 1252 for (i = r->poolinfo->poolbytes; i > 0; i -= sizeof(rv)) {
1238 if (!arch_get_random_long(&rv)) 1253 if (!arch_get_random_seed_long(&rv) &&
1254 !arch_get_random_long(&rv))
1239 rv = random_get_entropy(); 1255 rv = random_get_entropy();
1240 mix_pool_bytes(r, &rv, sizeof(rv), NULL); 1256 mix_pool_bytes(r, &rv, sizeof(rv), NULL);
1241 } 1257 }