As the Wikipedia page says:
It is also possible to write to /dev/random. This allows any user to mix random data into the pool. Non-random data is harmless, because only a privileged user can issue the ioctl needed to increase the entropy estimate. The current amount of entropy and the size of the Linux kernel entropy pool are available in /proc/sys/kernel/random/, which can be displayed by the command cat /proc/sys/kernel/random/entropy_avail.
So, in your case, if you are really intent on injecting some randomness obtained from the RaspberryPi as a file, then all you need is to write the file into /dev/random
with a simple "cat randomfilefromrasp > /dev/random
". What would be more complex (and require extra rights) would be to assert that the extra randomness ensures some given value of extra "entropy". But it matters only for the irksome blocking mechanism of /dev/random
(this device tends to block when it supposes that it has burnt all its entropy); your extra file still gets added to the mix and will contribute to the actual entropy (i.e. you do get the security benefits, even if the kernel does not notice it).
Entropy is not only lost via /dev/{,u}random
, the kernel also takes some. For example, new processes have randomized addresses (ASLR) and network packets need random sequence numbers. Even the filesystem module may remove some entropy. See the comments in drivers/char/random.c. Also note that entropy_avail
refers to the input pool, not the output pools (basically the non-blocking /dev/urandom
and the blocking /dev/random
).
If you need to watch the entropy pool, do not use watch cat
, that will consume entropy at every invocation of cat
. In the past I also wanted to watch this pool as GPG was very slow at generating keys, therefore I wrote a C program with the sole purpose to watch the entropy pool: https://git.lekensteyn.nl/c-files/tree/entropy-watcher.c.
Note that there may be background processes which also consume entropy. Using tracepoints on an appropriate kernel you can see the processes that modify the entropy pool. Example usage that records all tracepoints related to the random subsystem including the callchain (-g
) on all CPUs (-a
) starting measuring after 1 second to ignore its own process (-D 1000
) and including timestamps (-T
):
sudo perf record -e random:\* -g -a -D 1000 -T sleep 60
Read it with either of these commands (change owner of perf.data
as needed):
perf report # opens an interactive overview
perf script # outputs events after each other with traces
The perf script
output gives an interesting insight and shows when about 8 bytes (64 bits) of entropy is periodically drained on my machine:
kworker/0:2 193 [000] 3292.235908: random:extract_entropy: ffffffff8173e956 pool: nbytes 8 entropy_count 921 caller _xfer_secondary_pool
5eb857 extract_entropy (/lib/modules/4.6.2-1-ARCH/build/vmlinux)
5eb984 _xfer_secondary_pool (/lib/modules/4.6.2-1-ARCH/build/vmlinux)
5ebae6 push_to_pool (/lib/modules/4.6.2-1-ARCH/build/vmlinux)
293a05 process_one_work (/lib/modules/4.6.2-1-ARCH/build/vmlinux)
293ce8 worker_thread (/lib/modules/4.6.2-1-ARCH/build/vmlinux)
299998 kthread (/lib/modules/4.6.2-1-ARCH/build/vmlinux)
7c7482 ret_from_fork (/lib/modules/4.6.2-1-ARCH/build/vmlinux)
kworker/0:2 193 [000] 3292.235911: random:debit_entropy: ffffffff8173e956: debit_bits 64
5eb3e8 account.part.12 (/lib/modules/4.6.2-1-ARCH/build/vmlinux)
5eb770 extract_entropy (/lib/modules/4.6.2-1-ARCH/build/vmlinux)
5eb984 _xfer_secondary_pool (/lib/modules/4.6.2-1-ARCH/build/vmlinux)
5ebae6 push_to_pool (/lib/modules/4.6.2-1-ARCH/build/vmlinux)
293a05 process_one_work (/lib/modules/4.6.2-1-ARCH/build/vmlinux)
293ce8 worker_thread (/lib/modules/4.6.2-1-ARCH/build/vmlinux)
299998 kthread (/lib/modules/4.6.2-1-ARCH/build/vmlinux)
7c7482 ret_from_fork (/lib/modules/4.6.2-1-ARCH/build/vmlinux)
...
swapper 0 [002] 3292.507720: random:credit_entropy_bits: ffffffff8173e956 pool: bits 2 entropy_count 859 entropy_total 2 caller add_interrupt_randomness
5eaab6 credit_entropy_bits (/lib/modules/4.6.2-1-ARCH/build/vmlinux)
5ec644 add_interrupt_randomness (/lib/modules/4.6.2-1-ARCH/build/vmlinux)
2d5729 handle_irq_event_percpu (/lib/modules/4.6.2-1-ARCH/build/vmlinux)
2d58b9 handle_irq_event (/lib/modules/4.6.2-1-ARCH/build/vmlinux)
2d8d1b handle_edge_irq (/lib/modules/4.6.2-1-ARCH/build/vmlinux)
230e6a handle_irq (/lib/modules/4.6.2-1-ARCH/build/vmlinux)
7c9abb do_IRQ (/lib/modules/4.6.2-1-ARCH/build/vmlinux)
7c7bc2 ret_from_intr (/lib/modules/4.6.2-1-ARCH/build/vmlinux)
6756c7 cpuidle_enter (/lib/modules/4.6.2-1-ARCH/build/vmlinux)
2bd9fa call_cpuidle (/lib/modules/4.6.2-1-ARCH/build/vmlinux)
2bde18 cpu_startup_entry (/lib/modules/4.6.2-1-ARCH/build/vmlinux)
2510e5 start_secondary (/lib/modules/4.6.2-1-ARCH/build/vmlinux)
Apparently this happens to prevent waste of entropy by transferring entropy from the input pool to outputs pools:
/*
* Credit (or debit) the entropy store with n bits of entropy.
* Use credit_entropy_bits_safe() if the value comes from userspace
* or otherwise should be checked for extreme values.
*/
static void credit_entropy_bits(struct entropy_store *r, int nbits)
{
...
/* If the input pool is getting full, send some
* entropy to the two output pools, flipping back and
* forth between them, until the output pools are 75%
* full.
*/
...
schedule_work(&last->push_work);
}
/*
* Used as a workqueue function so that when the input pool is getting
* full, we can "spill over" some entropy to the output pools. That
* way the output pools can store some of the excess entropy instead
* of letting it go to waste.
*/
static void push_to_pool(struct work_struct *work)
{
...
}
Best Answer
/dev/random
is not standardized. POSIX doesn't provide any way of generating cryptographically secure random data and doesn't have any notion of entropy.The Linux kernel's entropy calculation corresponds to an information-theoretic model of entropy which is not relevant to practical use. The only case where this is relevant is on a new device which has never had time to accumulate entropy (this includes live distributions; installed systems save their entropy from one boot to the next). Apart from this situation, there is always enough entropy, because entropy does not deplete. Since Linux's
/dev/random
blocks when it thinks it doesn't have enough entropy, use/dev/urandom
, which never blocks. Using/dev/urandom
is good for everything including generating cryptographic keys (except, as mentioned above, on a freshly minted device).In summary:
/dev/urandom
.Many, but not all unix systems have
/dev/urandom
and/dev/random
. See the Wikipedia page for a more detailed discussion.