The getrandom(2) system call was requested by the LibreSSL Portable developers
lists.openwall.net
lists.openwall.net
Hopefully proper fork detection will be next up.
Another approach would be giving every process an ID that never repeats and is unique across all namespaces, and use that for comparison instead of the PID.
Doubly difficult from within library code that needs to work in arbitrary programs, and thus cannot mess with signal handling.
For example, 12.04 LTS release had 12.04.4 with a backported kernel as a standard update.
https://wiki.ubuntu.com/PrecisePangolin/ReleaseNotes/ChangeS...
I suppose that if the state of your PRNG neatly fits into (almost) a multiple of 4KB, it makes sense to allocate that space explicitly and put a guard bit in there, then mark the entire region as INHERIT_ZERO. This has the added benefit of making it less like that PRNG state is leaked somewhere.
The only advantage I see is that the current solution allows one to implement the random number generator independently of the kernel. Introducing that bit creates a tight coupling.
The futex API (including set_tid_address) is precedence for this kind of syscall.
This seems like a nice choice. PRNG seeds aside, it's always bothered me that processes aren't uniquely identified, which makes monitoring them kind of a pain.
Well, currently. (~585 years to overflow at 1 billion PIDs/sec. Seems absurd, but then again, there are so many cases where we've gone "this should be good enough"...)
What do you mean?
/dev/urandom is too loose. It's designed to be computationally secure, which means that you could use it if your adversaries were stuck in our universe and had to make their computers out of matter and power them with energy. However, it never blocks, even if there isn't enough entropy in the pool.
We just need a PRNG that will spit out numbers as long as, say, 256 random bits were added to the pool at some point. Once you have that many bits, just keep on spitting out numbers.
urandom is not too loose. There is exactly one Linux issue with urandom: it will service requests before the urandom pool is initialized. Linux distros work around this by trying to make sure urandom is initialized securely very early in the boot process.
Once urandom is initialized, the idea that it can ever "run out of entropy" is nonsensical; urandom is structurally the same as a stream cipher keystream generator, and we generally don't fret about whether AES-CTR keystreams will "run out of key". Nonetheless, the belief that urandom will sporadically "run out of entropy" is virulent.
The motivation behind the new system call has more to do with chroot environments, where the device might not be available at all. It's a good change; randomness should be provided by a system call and not a device. Unfortunately, by adding the flag, they've basically managed to add two system calls: getrandom and geturandom. >HEADDESK<
https://blogs.oracle.com/darren/entry/solaris_random_number_...
I'm certain OpenBSD differs here as well.
If the seed value for urandom were compromised or you were unsure of its provenance (some systems carry over from last boot), would you not be safer calling /dev/random for something sensitive like key generation? What if you did not trust the PRNG that urandom used?
EDIT: Thanks for the clarification tptacek. I don't mean to disagree -- in fact it was you who explained this to me last time as well.
Unless you are concerned about where the seed came from (e.g. not storage like /var/run/random-seed) or have any concerns that there is a flaw in the PRNG that could leak information.
Something doesn't add up. Supposedly the reasons for creating urandom were to avoid blocking - but at the same time all the docs warn about entropy depletion. Are you now saying this is meaningless? If so, then why ever use /dev/random?
Exactly. The warnings about "entropy depletion" are only relevant to theoretical attacks which require either impossibly large computational resources or a flaw in the PRNG algorithm. Since either assumption breaks all our crypto for other, unrelated reasons, we use /dev/urandom.
That, and if you use /dev/urandom before it's seeded, you expose yourself to real attacks.
Why is /dev/urandom spitting out anything before it has acquired enough entropy for the initial seed? Wouldn't it be a good idea for it to initially block?
On a system with a recent Intel processor, there's a instruction (RDSEED) that uses on on-die hardware RNG. I'm not familiar with the standard linux boot-up process, but it could in principle seed urandom using RDSEED arbitrarily early in the process. That should work on VMs too unless the hypervisor is blocking access (can't imagine a good reason for that).
Via has on-die RNG considerably longer, though it's accessed slightly differently. I don't believe AMD or ARM has anything similar.
Given the lack of the "middle ground" introduced by this patch, you have (had) a choice between the failure mode of "block for a very long time" and the failure mode of "might generate easily predicted cryptographic keys under certain extremely rare circumstances". You use /dev/random if you prefer the first failure mode.
Edit: The whole situation didn't make sense from a system design point of view (unless you don't believe in CSPRNGs, but then you're basically screwed anyway), but given the unreasonable interface as a constraint, it's conceivable that somebody might have reasonably made the choice to use /dev/random.
no, he's not saying that - he's saying that there's no such thing as entropy depletion - and so urandom is secure. Which makes me ask after urandom was created - why EVER bother using /dev/random with it's blocking flaw/deficiency?
Use /dev/urandom. Don't use /dev/random. On sane systems (FreeBSD for example), /dev/urandom is a symlink to /dev/random and /dev/random only blocks once, upon startup to gather entropy, after that it never blocks!
/dev/random is also stupid, but it does protect you against that particular failure mode.
Why wouldn't one simply create the appropriate device node inside the chroot? This argument strikes me as nonsense.
Forcing urandom to exist also precludes mounting partions 'nodev' which has secuirty implications in a chroot enviroment.
Lastly, relying on a devicefile makes you prone to things like fd exhaustion attacks.
Is there a specific quote that isn't correct?
This particular way in which tptacek's comment is "mistaken" is related to the tone and attitude tptacek takes in his comments. If this were the only instance, even the only instance for this particular topic, it would be one thing, but this is a common issue with tptacek's comments. The pattern is that there are certain "common misconceptions" that everyone has, and tptacek is not generous to the poster of any specific comment that they might not possess them.
I further believe that it is a serious problem on Hacker News that people do not address these kinds of tone issues: that it is perfectly fine to "HEADDESK", claim that certain beliefs are "virulent", and to even use the word "nonsensical" to describe someone's idea, and yet attempts to point out issues in the tone of peoples' comments is somehow a problem: something where you feel the need to say "don't make this conversation personal". More people need to stand up to this.
I, myself, have done some of these things in my own comments. I feel like most of these cases were situations where I was responding to someone else doing it to me, but I've found at least a few instances where that is not the case. It makes me very unhappy that I contributed to this problem: someone should have also complained about my tone in those instances. It needs to be ok to exit the topic and address how someone is saying something, not just what was said.
To be clear, tptacek's position is correct: we don't need a new interface; klodolph's argument largely ends up arguing for fixing /dev/urandom. However, tptacek doesn't say this, as he has assumed that klodolph doesn't understand the difference between /dev/urandom and /dev/random, and then argued based on that assumption. If you read the other comments from klodolph, it is very very clear that he understands perfectly. tptacek could at least apologize.
(If you re-read my comment, you'll also find that the >HEADDESK< isn't addressed to 'klodolph at all, but to the designers of the Linux randomness system call).
You could probably mail me further thoughts you have about my comments on HN, if you wanted to keep talking about it.
It turns out Fortuna and variants thereof score very well in this metric, but this does not have any bearing on the quality of the output, or whether it loses entropy by generating more bytes.
/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/
well, you agree up to the point you actually need to convert your words into facts, at that point you don't agree anymore :)
https://github.com/AGWA/git-crypt/commit/34432e915e8415b112c...
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.
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.
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`.
/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.)
Can urandom ever be used insecurely? Tptacek has said many times that you should just seed /dev/urandom from /dev/random, then never use /dev/random again: http://hn.algolia.com/#!/comment/forever/prefix/0/author%3At...
Is LibreSSL's situation different? If so, why?
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.)
Agreed.
- "then the /dev/raundom pool will be used" -> should be /dev/urandom
- "Unlike reading from the /dev/urandom" -> author meant /dev/random
- "EGAIN" -> should be EAGAIN
- In fact the entire sentence "Unlike reading from /dev/random, [it either blocks or returns EAGAIN]" should be removed. This blocking/EAGAIN behavior is the same regardless if you read from random or urandom.
Pretty sure he doesn't. He's describing the differences between using the /dev/urandom pool (through getrandom(2)) and actually reading from /dev/urandom.
Man, that's an ugly interface. So, if there are 8 bits of entropy available and I ask for 16, it will return 8, but if there are none available and I ask for 16 it will block and then return 16.
Also, it's not possible to know how much entropy is available. I'd really like to emphasise that: entropy estimation is nonsense.
Don't block; seriously, don't block. Just spit out the output of a properly-seeded PRF (e.g. AES in CTR mode).
/dev/urandom does that and it is the suggested way to get secure random numbers for 99% of the applications.
The real answer is to just change the interface and be done with it, and to hell with backwards-compatibility, but that'll never happen.
The really real answer is to make /dev/random and /dev/urandom the same CSPRNG, seeded as early in boot as possible (and continually refreshed with more entropy, of course), and never blocking thereafter, but that'll never happen either.
How can the userspace program "make sure that it doesn't hang indefinitely" if it is started early in the boot process and the call blocks?
select is itself a separate syscall that takes in file handles or something.
It's not that /dev/random has been "depleted" (which is meaningless given how a CSPRNG works), it's just that some entropy estimation code thinks that it might not be a source of perfect entropy/randomness at a particular time. (This practice is pretty questionable, hence the proposed new syscall.)
With this, entropy pool depletion is not really that much of a concern; "urandom reads" from getrandom(2) will have at least one good seed.
> I would hope that people would agree there should be a difference between what is needed for a Monte Carlo simulation and other various cryptographic use cases. (I've gotten bug reports from people who insisted on using /dev/urandom for Monte Carlo simulations, and who then complained when it was too slow for their purposes....)
https://www.ietf.org/mail-archive/web/dsfjdssdfsd/current/ms...
The recommendation is probably a way to say "please don't abuse, and please don't make the kernel spin".
Doesn't appear many people on this thread are considering such use cases, but it appears the authors have.
Deleted comment
* Suppose /dev/urandom is not receiving randomness at all, and the Monte Carlo application keeps drawing bits from it like crazy. Then this device is reduced, effectively, to a PRNG. Maybe, as such, it is not a particularly good PRNG; it is not intended to be used that way. It is supposed to take some real entropy bits, and "stretch" them to cover a larger request---but not ridiculously so.
* Simulation applications benefit from repeatability: the same seed fetches exactly the same results. You lose that with urandom.
> If the GRND_RANDOM flags bit is not set, then the /dev/raundom pool will be used. Unlike reading from the /dev/urandom, if the urandom pool has not been sufficiently initialized, getrandom(2) will either return an error with errno set to EGAIN, or block if the GRND_BLOCK flags bit is set.
Is this complexity necessary? I'm concerned that this will be hard to use properly as there's lots of different behaviours based on the parameters, and different types of failure modes. Security code that is hard to call right or hard to understand tends to get misused, causing security bugs in application code.
- It suggests that I use that entropy to seed a PRNG. No. It should be the PRNG. - Fill the buffer with "up to buflen random bytes"? I asked for n bytes. Please give me actually n bytes. If there's a way to get this wrong, people will get it wrong: the BSD socket API does the same thing and at least it has good reason. However, the wording seems to imply that if you use the "urandom" source, it won't do that? - "It should not be used Monte Carlo simulations or for other probabilistic sampling applications.". Doesn't mention why. Sounds like "run out of entropy" FUD :-(
What is this style called?
Anyway, sorry went off-topic.
Also, an descriptor to /dev/urandom can be acquired early and retained for the life of the process. When you need bits, you just read from it. This gets around subsequent chroots and descriptor exhaustion.
Take a look at the code. If the flag GRND_RANDOM is used, then it uses the random device, otherwise urandom.
Independently of this, blocking behavior is requested with GRND_BLOCK. If this is omitted, then the random device bails with errno == EAGAIN if it doesn't have enough entropy, otherwise it blocks.
If GRND_BLOCK is omitted with the urandom method (GRND_RANDOM is omitted), then it will bail with -EAGAIN if the urandom device is not initialized; otherwise it just calls urandom_read. With GRND_BLOCK, it will block for urandom to initialize, if necessary.
The new system call only blocks when given GRND_BLOCK, and it uses urandom unless given the flag GRND_RANDOM. If it is given GRND_RANDOM, but not GRND_BLOCK, and not enough entropy is available, then the system call with bail with errno == EAGAIN. If there is no GRND_RANDOM then it falls back on urandom_read: that is usually non-blocking.
This system call (when used to access urandom) will either block on urandom to be initialized, or else fail loudly with -EAGAIN, which is an improved interface.
Legacy adherence to some defunct interface? Ignorance on the part of kernel devs (seems unlikely)?
To quote Ted Tso (author of the above patch and the original writer of /dev/random in the first place)
The two other interfaces are two character devices /dev/random and * /dev/urandom. /dev/random is suitable for use when very high * quality randomness is desired (for example, for key generation or * one-time pads), as it will only return a maximum of the number of * bits of randomness (as estimated by the random number generator) * contained in the entropy pool. * * The /dev/urandom device does not have this limit, and will return * as many bytes as are requested. As more and more random bytes are * requested without giving time for the entropy pool to recharge, * this will result in random numbers that are merely cryptographically * strong. For many applications, however, this is acceptable.
/dev/random and /dev/urandom have security attributes: ownership and permission. The newly proposed syscall makes no security checks whatsoever to protect the entropy resource: it punches a hole through these perms, effectively.
crw-rw-rw- 1 root root 1, 8 Jul 15 11:27 /dev/random
crw-rw-rw- 1 root root 1, 9 Jul 15 11:27 /dev/urandom
So, if the default permission is read/write by any user, what limitation should this new syscall add?
Someone somewhere could be setting up permissions in their Linux-based system based on this type of reasoning.
It's a security regression if a character device can be suddenly accessed through a back-channel that ignores permissions.
If you can trust a CSPRNG, then you should be able to trust urandom, as long as it's been properly initialized once. It won't drain out. It doesn't run out of bits. One application reading it doesn't make it unavailable for others. The same is true of the syscall.
https://blogs.oracle.com/darren/entry/solaris_random_number_generation
Short version is, on Solaris, you should use /dev/random for long-term keys and other high-value keying material. /dev/urandom should be used for everything else such as less demanding or shorter-term cryptographic uses like short-term session keys, paddings, and challenge strings.1. It's not safe to use a weak RNG for session keys or even padding. Cryptosystems often fail catastrophically when their most obscure parameters are weak --- in fact, more exploitable cryptosystem flaws derive from issues like padding and IVs than keys.
2. FIPS 186-2 is a SHA-based DRBG. It doesn't "run out of entropy". What am I missing? The situation on Solaris w/r/t urandom appears to be identical to that of Linux.
2. /dev/random basically only uses bits from entropy sources while /dev/urandom just uses a few bits from /dev/random as a seed. Read the post I linked again.
Again, I would reiterate, the situation is somewhat different for Solaris. Usage of /dev/random vs. /dev/urandom is actually considered different.
* I think the distinction this post is drawing between Solaris random and urandom is functionally very similar to the distinction between Linux random and urandom (I think the distinction on Solaris might be that random has a higher quality rekeying system than urandom).
* I can read a straightforward description of a SHA1 PRNG keyed by kernel entropy, which is what this blog post describes, and unless I'm missing something in the article, I don't see how it is any less cryptographically secure than Solaris /dev/random. It seems to be less forward-secure than /dev/random. That's about it.
Since you appear to have grokked this article better than I did in either of the two cases I read it, could you give a short summary of the argument it presents for avoiding urandom for long-term secrets?
2) From a cryptography standpoint, the precise implementation of the current framework makes /dev/urandom suitable for short-term session keys and padding. This may not hold true for Linux, but for Solaris it has been reviewed and deemed appropriate usage. Fundamentally, it's about constraints placed on the implementation that currently make /dev/random more "secure".
In conversing with one of the crypto developers for Solaris, they are considering whether to lessen the distinction between /dev/random and /dev/urandom further in the future.
> The getrandom(2) system call was requested by the LibreSSL Portable
> developers. It is analoguous to the getentropy(2) system call in
> OpenBSD.
Oh the joy of NIH.> The getrandom(2) system call is a superset of getentropy(2).
> The reason for the additional flags is that I'm trying to solve more problems than just getentropy()'s raison d'etre.
And you can implement getentropy(2) on top of getrandom(2) if you so desire, which they plan to do in glibc.
The above excerpt shows they assuming upfront that they got the idea from BSD. As a system call is not an application that may be ported, they need to recode it.
If the point was the name change, I guess this is only to keep consistency within the system, and far from a problem.
But if we get all applications to use the same library, we can
abstract away not only differences in operating system but also
security policies vis-a-vis DRBG/NDRBG blocking/nonblocking. So what
*I* would prefer is a library interface where the application declares
what it wants the random numbers for:
* Monte carlo simulations
* Padding
* IV
* Session key
* long-term key
etc. The library can then decide whether or not the overall system
policy should force application to block when generating long-term
keys, ala gpg, or whether it should getting non-blocking entropy
directly from the kernel, or whether using a userspace DRBG which is
initialized from kernel-supplied entropy is the right answer.
From https://www.ietf.org/mail-archive/web/dsfjdssdfsd/current/ms...And if we're assuming the entropy pool is being compromised (full state read by attacker) from time to time, isn't it foolish to be generating keys on such a machine? Why would new state not be compromised in he same way the previous state was? I understand the system design may want to provide a robust RNG, but further than that seems slightly pointless.