/dev/urandom never blocks, even if it means returning randomness before the system has gathered enough entropy to safely seed a CSPRNG.
/dev/random blocks whenever the system's "entropy count" is too low, even if the system has previously gathered enough entropy to produce secure randomness. The frequent blocking of /dev/random makes it unsuitable for practical use while providing questionable security benefit.
getrandom() blocks only until the system has gathered enough entropy to safely seed a CSPRNG, and then never blocks again. (Assuming the GRND_BLOCK flag and not the GRND_RANDOM flag.)
I'm not really thrilled with the idea that you should use urandom to seed a CSPRNG; urandom should be your only CSPRNG. This most recent libressl kerfuffle is an illustration of why userspace CSPRNGs are a bad idea.
When I said "seed a CSPRNG" I was talking about the kernel seeding its own CSPRNG. I agree that just using the kernel's CSPRNG is the sanest solution to this mess.
By "this mess" I meant the LibreSSL fork/chroot mess. I think crypto libraries should just use whatever the OS provides and not try to implement their own CSPRNGs. But git-crypt is a cross-platform application, not a crypto library. Implementing my own cross-platform wrapper around OS CSPRNGs would be decidedly less sane (and more error-prone) than just using the crypto library's CSPRNG, even if I disagree with how the library has done things.
I know you said "CS-", but seed-able PRNGs in user-space can be immensely useful in tons of other situations, allowing things to be debugged, replayed, and synchronized.
So even if you convince to use urandom for their crypto needs on *nix platforms, it'll still have to be easy to seed one in userspace if someone really wanted to.
What about a non-global blocks-until-seeded CS-PRNG character device? I.e. you open an rw file descriptor to /dev/csprng, write(2) your seed to it, and then read(2) bytes from it. Open another file descriptor, and you get another CSPRNG that wants a separate seed.
This way, you could, say, somewhat simulate the behaviour of ZeroVM with Docker containers, by having the CSPRNG seed be a configuration parameter passed to `docker run`.
That's not what tptacek means when he says "[user space] CSPRNG", and is more appropriately called a keystream generator, not a CSPRNG, and the input is more appropriately called a key, not a seed.
/dev/urandom is insecure. Always use /dev/random for cryptographic purposes.
Fact: /dev/urandom is the preferred source of cryptographic randomness on UNIX-like systems.
This seems to contradict your first point, which is that /dev/urandom is insecure in some situations. (Returning randomness without sufficient entropy is a security problem.)
Further down, under "Not everything is perfect," the author addresses the problem with /dev/urandom never blocking.
Seeding /dev/urandom from /dev/random is a trick that can be used early in the boot sequence to ensure that /dev/urandom is henceforth secure. (In practice, distros carry over a seed from the previous boot which accomplishes the same effect.)
I know that we need to support old programs that expect these behaviours of these device nodes. However, how about a workaround like "udev only creates /dev/urandom once /dev/random has been seeded"?
/dev/random blocks whenever the system's "entropy count" is too low, even if the system has previously gathered enough entropy to produce secure randomness. The frequent blocking of /dev/random makes it unsuitable for practical use while providing questionable security benefit.
getrandom() blocks only until the system has gathered enough entropy to safely seed a CSPRNG, and then never blocks again. (Assuming the GRND_BLOCK flag and not the GRND_RANDOM flag.)
An in-depth explanation: http://www.2uo.de/myths-about-urandom/