Commit 48d6be95 authored by Theodore Ts'o's avatar Theodore Ts'o

random: limit the contribution of the hw rng to at most half

For people who don't trust a hardware RNG which can not be audited,
the changes to add support for RDSEED can be troubling since 97% or
more of the entropy will be contributed from the in-CPU hardware RNG.

We now have a in-kernel khwrngd, so for those people who do want to
implicitly trust the CPU-based system, we could create an arch-rng
hw_random driver, and allow khwrng refill the entropy pool.  This
allows system administrator whether or not they trust the CPU (I
assume the NSA will trust RDRAND/RDSEED implicitly :-), and if so,
what level of entropy derating they want to use.

The reason why this is a really good idea is that if different people
use different levels of entropy derating, it will make it much more
difficult to design a backdoor'ed hwrng that can be generally
exploited in terms of the output of /dev/random when different attack
targets are using differing levels of entropy derating.
Signed-off-by: default avatarTheodore Ts'o <tytso@mit.edu>
parent c6e9d6f3
...@@ -910,12 +910,13 @@ void add_interrupt_randomness(int irq, int irq_flags) ...@@ -910,12 +910,13 @@ void add_interrupt_randomness(int irq, int irq_flags)
/* /*
* If we have architectural seed generator, produce a seed and * If we have architectural seed generator, produce a seed and
* add it to the pool. For the sake of paranoia count it as * add it to the pool. For the sake of paranoia don't let the
* 50% entropic. * architectural seed generator dominate the input from the
* interrupt noise.
*/ */
if (arch_get_random_seed_long(&seed)) { if (arch_get_random_seed_long(&seed)) {
__mix_pool_bytes(r, &seed, sizeof(seed)); __mix_pool_bytes(r, &seed, sizeof(seed));
credit += sizeof(seed) * 4; credit = 1;
} }
spin_unlock(&r->lock); spin_unlock(&r->lock);
...@@ -1328,37 +1329,6 @@ void rand_initialize_disk(struct gendisk *disk) ...@@ -1328,37 +1329,6 @@ void rand_initialize_disk(struct gendisk *disk)
} }
#endif #endif
/*
* Attempt an emergency refill using arch_get_random_seed_long().
*
* As with add_interrupt_randomness() be paranoid and only
* credit the output as 50% entropic.
*/
static int arch_random_refill(void)
{
const unsigned int nlongs = 64; /* Arbitrary number */
unsigned int n = 0;
unsigned int i;
unsigned long buf[nlongs];
if (!arch_has_random_seed())
return 0;
for (i = 0; i < nlongs; i++) {
if (arch_get_random_seed_long(&buf[n]))
n++;
}
if (n) {
unsigned int rand_bytes = n * sizeof(unsigned long);
mix_pool_bytes(&input_pool, buf, rand_bytes);
credit_entropy_bits(&input_pool, rand_bytes*4);
}
return n;
}
static ssize_t static ssize_t
_random_read(int nonblock, char __user *buf, size_t nbytes) _random_read(int nonblock, char __user *buf, size_t nbytes)
{ {
...@@ -1379,11 +1349,6 @@ _random_read(int nonblock, char __user *buf, size_t nbytes) ...@@ -1379,11 +1349,6 @@ _random_read(int nonblock, char __user *buf, size_t nbytes)
return n; return n;
/* Pool is (near) empty. Maybe wait and retry. */ /* Pool is (near) empty. Maybe wait and retry. */
/* First try an emergency refill */
if (arch_random_refill())
continue;
if (nonblock) if (nonblock)
return -EAGAIN; return -EAGAIN;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment