random_get_pseudo_bytes() should not provide cryptographic strength entr...

...opy

Perf profiling of dd on a zvol revealed that my system spent 3.16% of
its time in random_get_pseudo_bytes(). In addition, we were mapping a
function that does not require cryptographic strength entropy to a Linux
kernel function that provides non-blocking cryptographic strength
entropy from the system's entropy pool. Draining the system's entropy
pool could weaken anything using it that requires cryptographic strength
entropy, so we need to obtain entropy in a way that does not do that.

The Linux kernel did not export a suitable function for this until it
exported get_random_int() in Linux 3.10. While we could implement an
autotools check so that we use it when it is available or even try to
access the symbol on older kernels where it is not exported using the
fact that it is exported on newer ones as justification, we can instead
implement our own entropy generator. For this purpose, I have written
one based on one proposed in a paper by Sebastiano Vigna that itself was
based on work by the late George Marsaglia.

http://arxiv.org/pdf/1402.6246v2.pdf

The generator presented in the paper and the generator that we implement
differs in how entropy is obtained. In the paper, the entropy is
obtained once at start. Our implementation instead starts with no
entropy and continuously adds entropy by summing the current entropy
pool with the value of lbolt64 before calculating the next value. We do
this to avoid the necessity of initializing the entropy pool at system
boot when the value of lbolt64 is predictable in the belief that the
value will become unpredictable after a few function invocations as a
consequence of the system scheduler.

In addition, the manner in which the entropy pool is accessed has no
thread safety by design. The belief is that allowing different threads
to race with one another when accessing the value in memory will
increase the unpredictability of the generator.

Profiling the same benchmark with this patch applied showed that time
spent in random_get_pseudo_bytes() dropped to 0.02%. That is a factor of
158 improvement.

Signed-off-by: Richard Yao <ryao@gentoo.org>