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.

  • 2
    $\begingroup$ Take a look specially to the second link on this question: security.stackexchange.com/questions/117496/…. It addresses your question and some extra related points that could be useful. $\endgroup$ – Sergio A. Figueroa Mar 27 '16 at 16:17
  • $\begingroup$ @SergioAndrésFigueroaSantos What part of that article do you believe addresses my question? The closest it seems to come is that part that says you can work around /dev/urandom's bad behavior by saving a seed at shutdown and writing it back at boot time. $\endgroup$ – Daniel Franke Mar 27 '16 at 16:29
  • $\begingroup$ All of it, but around the middle of the page there is a drawing representing the fact that the only difference between the two sources is that /dev/random blocks. $\endgroup$ – Sergio A. Figueroa Mar 27 '16 at 16:46
  • $\begingroup$ @SergioAndrésFigueroaSantos that diagram, although I suppose it would imply an affirmative answer to my question, is inaccurate. If you refer to the kernel code I linked in my question, you'll see that there are in fact three entropy pools, not just one as the diagram depicts. One is for /dev/random, one is for /dev/urandom, and one feeds the other two. Yes, they all use the same mixing and extraction algorithms, but they may be fed at different times. My question concerns the details of this timing. $\endgroup$ – Daniel Franke Mar 27 '16 at 17:18
  • 3
    $\begingroup$ @SergioAndrésFigueroaSantos yes, once a sufficient amount of entropy has been added to the /dev/urandom pool, it's good indefinitely until the next reboot. Its longstanding flaw, which is one of the things getrandom() was written to address, is that it will return data even before that, which is a hazard for any code that might run early in the boot process. For code that has this concern, the cleanest solution is to use getrandom(), but I'm investigating the soundness of "select() on /dev/random before reading from /dev/urandom" as an alternative approach for older systems. $\endgroup$ – Daniel Franke Mar 27 '16 at 18:26

I finally untangled what this code is doing.


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 ? &input_pool : &nonblocking_pool;


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:

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.