On Linux, does /dev/random unblocking imply that /dev/urandom is seeded? Linux has the familiar problem that /dev/random blocks too much (insisting on being information-theoretically secure), while /dev/urandom doesn't block enough (it will return data before it's been adequately seeded). The new getrandom() system call does the Right Thing, but as of this writing it's not yet universally available in the major distros.

My question is: if I succeed at reading a single byte from /dev/random, does this imply that /dev/urandom is seeded? I've spent some time staring at http://lxr.free-electrons.com/source/drivers/char/random.c but haven't been able to figure this out. Entropy provided by device drivers gets mixed into the input pool, then the input pool feeds separate /dev/random and /dev/urandom output pools, but I can't glean the conditions which trigger transfers from the input pool to the output pools, or (consequently) whether it's possible for /dev/random to be fed while /dev/urandom starves.
I finally untangled what this code is doing.

YES.

The quick version of why this is true is that the first 128 bits of entropy which the system collects get mixed directly into the nonblocking pool, bypassing the input pool. The logic which implements this is part of each of the add_foo_randomness() functions:

 r = nonblocking_pool.initialized ? &amp;input_pool : &amp;nonblocking_pool;


http://lxr.free-electrons.com/source/drivers/char/random.c?v=4.5#L804
http://lxr.free-electrons.com/source/drivers/char/random.c?v=4.5#L924

And per http://lxr.free-electrons.com/source/drivers/char/random.c?v=4.5#L677, nonblocking_pool.initialized is set when its entropy_total exceeds 128 bits. So by the time anything is available from /dev/random, /dev/urandom has been seeded.

For completeness, here's the rest of the story on how the entropy pools are managed:


All pools, even the nonblocking pool, have entropy estimates that are credited when new entropy is mixed in and debited when entropy is extracted.
As detailed above, the first 128 bits of entropy collected get written and credited to the nonblocking pool; everything thereafter gets written and credited to the input pool.
If the input pool is overflowing (i.e. its entropy estimate is approaching its total size), then this triggers a transfer from the input pool to either the blocking or the nonblocking pool, on an alternating basis. Pools skip their turn if they're already at least 75% full. (http://lxr.free-electrons.com/source/drivers/char/random.c?v=4.5#L692)
Reading from /dev/random always triggers a transfer from the input pool to the blocking pool (http://lxr.free-electrons.com/source/drivers/char/random.c?v=4.5#L1177). Reading from /dev/urandom triggers a transfer from the input pool to the nonblocking pool only if there has been no such transfer in the past 60 seconds (http://lxr.free-electrons.com/source/drivers/char/random.c?v=4.5#L983).
The amount transferred is (http://lxr.free-electrons.com/source/drivers/char/random.c?v=4.5#L995):


Typically equal to the amount being read from /dev/{u}random
But at least 64 bits
But not more than the current entropy estimate for the input pool
And not more than that estimate minus 128 bits if the transfer is to the nonblocking pool. (EDIT: I think this is a bug. See http://marc.info/?l=linux-kernel&amp;m=145945873501946&amp;w=2)