1
$\begingroup$

Edit for clarity: Does the "standard" test for initialization of the Linux non-blocking entropy pool, by attempting to read 1 byte from /dev/random, ignore seeding of /dev/urandom from file at boot, resulting in unnecessary hanging of any code that employs the "standard" test?

This article describes the Linux kernel as implementing three entropy pools; an input pool which feeds the CSPRNG and two output pools that are fed by the CSPRNG. One output pool is a blocking pool accessed by /dev/random and the other is a non-blocking pool accessed by /dev/urandom.

This answer describes how the kernel prioritises the seeding of the non-blocking pool at boot time:

the first 128 bits of entropy which the system collects get mixed directly into the nonblocking pool, bypassing the input 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.

Virtual machines without access to entropy from the host kernel, headless devices, and low end hardware, may not provide sufficient entropy at boot to seed the non-blocking pool, leaving services which access /dev/urandom such as SSH and OpenSSL vulnerable. 'Mining Your Ps and Qs' suggest this "boot-time entropy hole" may be the cause of duplicate SSH and TLS keys.

To check that the non-blocking pool is seeded, a method is proposed in the question, answered categorically 'yes' in the answer above:

if I succeed at reading a single byte from /dev/random, does this imply that /dev/urandom is seeded?

Elsewhere, this method is claimed to be the norm:

the standard way to wait until the system entropy pool is seeded is to read a single byte from /dev/random

It seems that this is the approach adopted by libsodium according to this github comment and the source code, causing PHP to hang on initialization for 3-5 minutes after boot on the type of systems described above. My own experiments replicate the 3-5 minute hanging on a VPS with low-end hardware, unless additional entropy is provided by rng-tools or PHP is compiled without libsodium.

All modern Linux systems save a random seed, usually 512 bytes, at shutdown and seed the non-blocking pool with this file early in the boot process. The standard method is described in the man page for random as well as the kernel source code for random.c, and implemented in the VPS I used.

The fact that libsodium causes PHP to hang despite the non-blocking pool being seeded during boot leads to the following questions:

  1. Is it the case that seeding the non-blocking pool as above, essentially cat /etc/random-seed > /dev/urandom, does not unblock the blocking pool?
  2. If so, is there no better approach for libsodium to test for seeding of the non-blocking pool? (auxiliary: what method does getrandom() use to test that "the urandom source has been initialized"?)
  3. Which pool is seeded by the above approach? My guess would be that the seed is going straight into the non-blocking pool, bypassing the input pool. The random man page and source code for random.c refer to "the entropy pool", but this is imprecise.
  4. If the blocking pool is unblocked by the above approach, then why is libsodium hanging? The libsodium usage manual suggests an entropy count less than 160 could cause initialization to hang, but I don't see where in the source code this would be the case.
$\endgroup$
  • $\begingroup$ Ok I'll ask on security.stackexchange.com. Thanks. $\endgroup$ – jksd Aug 12 '18 at 13:38
  • $\begingroup$ @e-sushi, would you mind moving the question to security.stackexchange.com please? Thanks. $\endgroup$ – jksd Aug 12 '18 at 13:43
  • 1
    $\begingroup$ Well, Security.SE mods that were asked agreed that this is more of a SO question since the question appears to be asking about the operation of a library (libsodium) rather than the security merits of differing randomness options. Migrating a question that has a high chance of getting closed as off-topic at the target site doesn't really make sense. Therefore, I'll have to respectfully decline your migration request. But: I'll reopen this for the benefit of the doubt. Just don't get mad at me in case the community down- or close-votes. $\endgroup$ – e-sushi Aug 12 '18 at 16:02
  • 3
    $\begingroup$ Writing to random devices doesn't increase the entropy estimates. You need the RNDADDENTROPY ioctl for that. $\endgroup$ – CodesInChaos Aug 12 '18 at 16:03
  • $\begingroup$ @e-sushi... 1), 3), & the general thrust is how the kernel operates entropy pools & the real question is does the "standard" test for urandom initialization ignore seeding from file, with implications beyond libsodium which is the canary in the goldmine. Security impacts already seen in the wild include workarounds such as downloading 100mb files from external servers at boot to generate entropy, using haveged, linking random to urandom. Surprised that a q. about entropy, seeding, & the "standard" solution to a well-known Linux security & crypto issue has no place on Security or Cryptography? $\endgroup$ – jksd Aug 12 '18 at 16:55

Your Answer

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

Browse other questions tagged or ask your own question.