Re: [dsfjdssdfsd] getentropy(2)

Theodore Ts'o <> Tue, 15 July 2014 08:25 UTC

Return-Path: <>
Received: from localhost ( []) by (Postfix) with ESMTP id C16D61B283F for <>; Tue, 15 Jul 2014 01:25:15 -0700 (PDT)
X-Virus-Scanned: amavisd-new at
X-Spam-Flag: NO
X-Spam-Score: -1.952
X-Spam-Status: No, score=-1.952 tagged_above=-999 required=5 tests=[BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, J_CHICKENPOX_36=0.6, RP_MATCHES_RCVD=-0.651, SPF_PASS=-0.001] autolearn=ham
Received: from ([]) by localhost ( []) (amavisd-new, port 10024) with ESMTP id sOzSAuJazkPw for <>; Tue, 15 Jul 2014 01:25:13 -0700 (PDT)
Received: from ( [IPv6:2600:3c02::f03c:91ff:fe96:be03]) (using TLSv1.2 with cipher DHE-RSA-AES128-SHA (128/128 bits)) (No client certificate requested) by (Postfix) with ESMTPS id 1CA881A0343 for <>; Tue, 15 Jul 2014 01:25:12 -0700 (PDT)
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed;; s=ef5046eb; h=In-Reply-To:Content-Type:MIME-Version:References:Message-ID:Subject:Cc:To:From:Date; bh=b4Wk4yw8kiVdSTgMIcffXLInE9fIqxqA5g6uauS7C4Q=; b=mnm0rBD8Cmw8ljg7zxg5aT13pwd9bP7f1PhYlB4sQoRnoRTXLnqSs/8kuMWnbv690/V3x4TVGRMQhXWdNbtWsA6GgEI5d/3PDVOfZsdGPP0xt8Pq1dI37WMqvmlY+UHoo/6MBzuy/zrKcr2FQkfi7om1Y5q538hF9iKggiR/qPk=;
Received: from root ( by with local-esmtp (Exim 4.80) (envelope-from <>) id 1X6y2x-00059U-5t; Tue, 15 Jul 2014 08:25:11 +0000
Received: by (Postfix, from userid 15806) id 4DE19580372; Tue, 15 Jul 2014 04:25:07 -0400 (EDT)
Date: Tue, 15 Jul 2014 04:25:07 -0400
From: Theodore Ts'o <>
To: Watson Ladd <>
Message-ID: <>
References: <>
MIME-Version: 1.0
Content-Type: text/plain; charset="us-ascii"
Content-Disposition: inline
In-Reply-To: <>
User-Agent: Mutt/1.5.23 (2014-03-12)
X-SA-Exim-Connect-IP: <locally generated>
X-SA-Exim-Scanned: No (on; SAEximRunCond expanded to false
Cc: "" <>
Subject: Re: [dsfjdssdfsd] getentropy(2)
X-Mailman-Version: 2.1.15
Precedence: list
List-Id: "The dsfjdssdfsd list provides a venue for discussion of randomness in IETF protocols, for example related to updating RFC 4086." <>
List-Unsubscribe: <>, <>
List-Archive: <>
List-Post: <>
List-Help: <>
List-Subscribe: <>, <>
X-List-Received-Date: Tue, 15 Jul 2014 08:25:16 -0000

On Mon, Jul 14, 2014 at 07:54:33PM -0700, Watson Ladd wrote:
> Dear all,
> The absence of getentropy(2) on Linux is a major pain point for
> everyone. It turns out that chroot jails are not compatible with
> /dev/urandom. which doesn't work on linux anyway (because it will
> return junk before initialization). As a TLS developer myself
> (slowly!) I feel that pain: random number generation is the single
> nastiest problem I have to deal with.

I've been talking to Bob Beck about this; and I'm not really convinced
how important the presense or lack of getneoptry(2) really is.  A
couple of high points about our conversation:

1) The question of what to do if /dev is not properly set up is a bit
of a red herring.  The OpenBSD folks have said that this is not a high
priority for them.  My perspective is that given that the ELF loader
requires that /dev/null be present so it can mmap in zero pages,
worrying about what to do if /dev is not properly set up is probably
not that big of a deal, and aborting if /dev/[u]random is not present is
probably the right thing to do.

2) OpenBSD's primary concern is to protect against the case when the
attacker has consumed all available file descriptors, so the attempt
to open /dev/[u]random fails.  Whether this is something that
justifies a new system call is a bit of a philosophical question.
After all, if the system is under such an attack, it's likely that
many other things will fail, and so failing hard may be better than
failing in a soft fashion.  There may be other portions of the system
that aren't properly checking for these sorts of failure.  For
example, are applications or libraries that try opening files such as
/etc/hosts.deny, if they receive an error, are they distinguishing
between ENOENT and EMFILE or ENFILE?  Or are the applications just
saying, "gee, open("/etc/hosts.deny", O_RDONLY) returned -1, all is
good, let's proceed"?

So points (1) and (2) means that from a philosophical point of view,
you can certainly make the argument that it's actually better to try
opening /dev/[u]random, and if it fails for any reason, it's better to
hard fail the application with a LOG_ERR or LOG_CRIT syslog followed
by an abort() call.

3) OpenBSD's man page for getentropy(2) talks about "seed grade"
entropy, but this is a bit of a misnomer for those people who are
obsessed about the difference between a DRBG and NRBG in SP 800-90A
speak.  Hence, getentropy(2) is non-blocking, and in practice, never
fails (or at least applications are written assuming that it
non-blocks and never fails).

I'm willing in practice to try seeing if I can get consensus for
adding a system call that works like getentropy(2).  I'm probably
going to add a flags field so that the application can select between
a blocking /dev/random read versus a non-blocking /dev/urandom read.
However, it's not clear that enough people will believe that adding a
system call just to justify allowing the userspace arc4random pool to
be able to initialize, only to have some other part of the application
fail due to a file open failing, or worse, silently compromising
security due to an open of some file such as /etc/hosts.deny failing,
is really worth adding a whole new system call.

> Yes, this is different from the usual IETF standard. But application
> and library developers need a portable way to get entropy, and that
> has to be the same across all platforms, work every time. Nothing
> short of a standard system call will work. Perhaps there is a more
> appropriate venue like the Open Group or POSIX or the Cxx committee
> (no doubt C++ will happily adopt it: a feature not in C++ is always a
> bug).

What I'd much rather see is a standard library that *all* applications
can rely upon and use to get entropy.  I don't trust most application
programmers to write a userspace library correctly.  One approach is
to simply advise all applications to use something like getentropy(2)
directly --- even if all that is needed is random padding or IV's.
The problem is that if you do this, for systems that are trying make
some kind of distinction between DRBG and NRBG, you can very quickly
exhaust the supply of hardware-derived entropy.

I accept that there is significant disagreement about whether such
differences should be made, but to the extent that Intel felt it was
necessary to add an RDSEED instruction as well as RDRAND, it's clear
that the difference is something that at least some people care about.
And I suspect it's unfair to say that the only people who care are the
crazies^H^H^H^H^H^H^H engineers who think that FIPS certification
makes any sense other than a purely commercial one (i.e., being able
to sell to the US Government).

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.

Basically, I don't want to leave this choice up to the application
writer, since many application writers won't be competent to make this
choice, and having consistency across different applications which are
conform to the organization's designated security officer seems to be
something that at least some organizations would want.


						- Ted