
The getrandom(2) system call was requested by the LibreSSL Portable developers - gnuvince
http://lists.openwall.net/linux-kernel/2014/07/17/235
======
agwa
This is huge. Not only does it let you get entropy without having to open a
device file (which has problems with chroots and file descriptor exhaustion),
it also provides the much-needed middle ground between /dev/random and
/dev/urandom. Assuming this patch is applied (it's from Theodore Ts'o, so
chances seem good), Linux will finally have a decent way to get randomness,
which would make me very happy.

Hopefully proper fork detection will be next up.

~~~
sillysaurus3
_it also provides the much-needed middle ground between /dev/random and
/dev/urandom._

What do you mean?

~~~
agwa
/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.)

An in-depth explanation: [http://www.2uo.de/myths-about-
urandom/](http://www.2uo.de/myths-about-urandom/)

~~~
tptacek
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.

~~~
agwa
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.

~~~
giovannibajo1
> I agree that just using the kernel's CSPRNG is the sanest solution to this
> mess.

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...](https://github.com/AGWA/git-
crypt/commit/34432e915e8415b112c09dc1a50366a457d0322e)

~~~
agwa
Oh boy, I should have seen this one coming :-)

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.

------
mrb
The third paragraph in the DESCRIPTION section of the manpage contains a lot
of errors:

\- "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.

~~~
judofyr
> \- "Unlike reading from the /dev/urandom" -> author meant /dev/random

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.

~~~
mrb
I see, this one makes sense.

------
wtbob
> The /dev/random pool is limited based on the entropy that can be obtained
> from environmental noise, so if there is insufficient entropy, the requested
> number of bytes may not be returned. If there is no entropy available at
> all, getrandom(2) will either return an error with errno set to EAGAIN, or
> block if the GRND_BLOCK flags bit is set.

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).

~~~
gioele
> 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.

~~~
wtbob
No, /dev/urandom fails the 'properly-seeded' criterion during early boot.

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.

------
acqq
"Any userspace program which uses this new functionality must make sure that
if it is used in early boot, that it will not cause the boot up scripts or
other portions of the system startup to hang indefinitely."

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?

~~~
derekp7
It can use the expect() system call and timeout / fail after a reasonable
period of time if no bits are returned.

~~~
justincormack
expect() is not a system call.

~~~
derekp7
Sorry, I meant select(). Don't know where my head was when I typed that.

~~~
nitrogen
Can you select() a system call (the new proposal) instead of an fd (the old
interface)?

~~~
lunixbochs
You don't get a file handle to a syscall. You just load up some
registers/stack and call a `SYSENTER`, `SYSCALL` or `INT 0x80` instruction.

select is itself a separate syscall that takes in file handles or something.

~~~
nitrogen
Yeah, I know, but it wasn't clear if the parent comment was referring to
select() on /dev/random, or the new syscall interface.

------
cnst
Proper link that lets you see the discussion:

[https://lkml.org/lkml/2014/7/17/145](https://lkml.org/lkml/2014/7/17/145)

------
egwor
In the synopsis, it says "It should not be used [by] Monte Carlo simulations
or for other probabilistic sampling applications." Does anyone know why not?

~~~
colanderman
Probably because it will be slow and deplete the entropy pool. Statistical
sampling doesn't require cryptographically-secure random number generation.

~~~
lomnakkus
"deplete the entropy pool" isn't really a meaningful phrase given the way the
Linux /dev/{random,urandom} work. AFAIK /dev/random and /dev/urandom use the
same CSPRNG (different instances) which is periodically reseeded with entropy
gathered from the system (hw, interrupt timings, etc.), the only difference
being that the /dev/random device blocks if an entropy estimator says that
there's "too little entropy".

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.)

------
ZoFreX
> If the GRND_RANDOM flags bit is set, then draw from the /dev/random pool
> instead of /dev/urandom pool. The /dev/random pool is limited based on the
> entropy that can be obtained from environmental noise, so if there is
> insufficient entropy, the requested number of bytes may not be returned. If
> there is no entropy available at all, getrandom(2) will either return an
> error with errno set to EAGAIN, or block if the GRND_BLOCK flags bit is set.

> 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.

------
lvh
Yay! However, a few things that are a bit unfortunate:

\- 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 :-(

~~~
mackal
Its more an example of using the wrong tool for the job. You don't use a
sludge hammer to hammer a nail in. Monte Carlo simulations don't need CSPRNG.

------
Rygu
Slightly off-topic, but I couldn't help but notice as a programmer. I find the
coding style of the patch kind of random. The if statements, some of them have
braces and some don't. Without a pattern it seems.

What is this style called?

~~~
Gracana
I only see one place where an if statement has curly braces where it doesn't
need them. The rest of them only have curly braces if they're necessary.

~~~
Rygu
Oh right, I see the second if statement at block @@ -1533,6 +1544,26 @@ indeed
threw me off. I would value consistency over necessity. The else-if at the
same block looks weird and the use of new lines could also help the code to be
more legible and maintainable.

Anyway, sorry went off-topic.

------
kazinator
The rationale for this system call is poor. If you're out of descriptors, so
that you cannot open another one, then bail loudly! Do not fall back on some
ill-conceived code that uses poor quality pseudo-random bits in a situation
where such bits must not be used!

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.

~~~
Afforess
You missed the 3rd reason for this. Calls to /dev/urandom can not block, so it
a script or program requests random bytes before entropy has been set up, it
can get back bad random bytes. The new system call getrandoms does block, so
early scripts will not get bad entropy data.

~~~
kazinator
The newly proposed system call, as implemented in the mailing list patch,
provides the functionality of both random and urandom: the behaviors are
distinguished by a bitmask.

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.

~~~
Dylan16807
Sure, blocking is a flag. You're ignoring the point, which is that it will
never return bad data.

~~~
kazinator
I see; if the point is that /dev/urandom doesn't even block when it is
uninitialized, that is valid.

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.

------
cmhamill
Does anyone have any idea _why_ Linux has a distinction between /dev/random
and /dev/urandom?

Legacy adherence to some defunct interface? Ignorance on the part of kernel
devs (seems unlikely)?

~~~
bowyakka
I think its because linux got there first and designed these interfaces

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. _

------
AlyssaRowan
Awesome. Thanks, Theo!

------
gpvos
So, does this mean that security issues are causing the end of the Unix
"everything is a file" philosophy?

~~~
pjc50
That hasn't really been true for a very long time, especially in the area of
X11.

~~~
gpvos
X11 has always been a bit of a weird beast. And things like /proc are
definitely in everything-is-a-file tradition, so it wasn't quite dead. (Maybe
just pining for the fjords?)

------
kazinator
Here is a problem:

/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.

~~~
syncsynchalt
What's the security case for locking down /dev/random?

~~~
maccam94
I think the concern is that a process could then exhaust all available
entropy, and DOS any other processes depending on /dev/random. Currently, a
chroot could protect against that.

~~~
X-Istence
Yes, and it is exactly that chroot that is cause for concern and why this
system call is being introduced...

------
kps

      > 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.

~~~
aylons
I didn't understand what you meant by you commentary.

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.

~~~
tptacek
They took the sane design from BSD ("here's a single system call that gives
you crypto-safe entropy") and effectively made a family of system calls that
replicate all the pointless drama of /dev/random and urandom. The NIH
criticism is valid.

~~~
clarry
It seems pointless indeed. On the other hand, I'm almost glad the
overengineering only went that far. Actually I'm expecting much worse after
reading Theodore's ideas on the IETF list.. we'll see what kind of a library
interface they'll come up with, if they make something besides getentropy().

    
    
      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...](https://www.ietf.org/mail-
archive/web/dsfjdssdfsd/current/msg00120.html)

~~~
MichaelGG
What is a case where a random IV needs a different entropy source than a
session key?

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.

------
easytiger
Why? So in future they can complain they can't control the entropy sources?

