Re: [dsfjdssdfsd] getentropy(2)

Alyssa Rowan <> Tue, 15 July 2014 18:10 UTC

Return-Path: <>
Received: from localhost ( []) by (Postfix) with ESMTP id 61B091A04E7 for <>; Tue, 15 Jul 2014 11:10:12 -0700 (PDT)
X-Virus-Scanned: amavisd-new at
X-Spam-Flag: NO
X-Spam-Score: -0.702
X-Spam-Status: No, score=-0.702 tagged_above=-999 required=5 tests=[BAYES_00=-1.9, J_CHICKENPOX_21=0.6, J_CHICKENPOX_36=0.6, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001] autolearn=no
Received: from ([]) by localhost ( []) (amavisd-new, port 10024) with ESMTP id 1BONylHjr7ln for <>; Tue, 15 Jul 2014 11:10:11 -0700 (PDT)
Received: from ( []) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by (Postfix) with ESMTPS id A95041A0005 for <>; Tue, 15 Jul 2014 11:10:10 -0700 (PDT)
Message-ID: <>
Date: Tue, 15 Jul 2014 19:10:07 +0100
From: Alyssa Rowan <>
MIME-Version: 1.0
References: <> <> <> <>
In-Reply-To: <>
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: 7bit
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 18:10:12 -0000

Hash: SHA512

On 15/07/2014 14:13, Theodore Ts'o wrote:

> I'm arguing that it might be better to have a standardized
> userspace library, ala OpenBSD's arc4random, which takes care of
> all of the OS specific issues, and also provides a crypto-based
> DRBG.  In that case, it saves even more syscalls, since it only
> needs to read entropy from the kernel at application startup time,
> and perhaps periodically every so often when it wants to reseed,
> but not every single time you need crypto-sensitive padding, IV's,
> session keys, etc.

I agree with that entirely - that should definitely be in the libc (we
need to take special care to ensure threads and forks never share a
context of this), and that is of course how arc4random(3) works.

We then have the thorny issue of how to seed it. Failure to seed
should definitely be considered a fatal error (OpenBSD bails with

The existing Linux RNG, though it has stood up well to the test of
time if I may say so, does not quite meet the needs of that use as it

Linux /dev/random estimates incoming entropy and blocks on warmup, but
cools down on output, assuming entropy is removed from the pool when
used. Many non-interactive systems without hardware TRNGs have
insufficient entropy to keep the pool from blocking frequently: it
would be impractical to make this a fatal error.

Linux /dev/urandom is the same, but never blocks - even if the
generator has not received sufficient initial seeding. This is a
problem which has resulted in many predictable keys in the wild,
especially in embedded devices (which are notoriously challenging
environments for entropy collection in the absence of a TRNG, and
which obviously did not collect enough at startup and just winged it).

What Linux doesn't seem to have is something in the middle; that
blocks until it's safely warmed up, but then doesn't need to block
again. That's the approach used by OpenBSD (as far as I know?). It
stops someone calling it before it's seeded, but also has no concept
of 'entropy exhaustion' as the DRBG is secure (hopefully!).

The fact that reading from Linux's RNG currently requires device file
accesses means access is not atomic and is dependent upon the finite
resources of file descriptors, as the libReSSL developers have clearly
pointed out.

I agree a better approach would be to have a syscall such as
getentropy(2) which:
- - requires no special privileges
- - provides a small amount of data into a provided buffer from a kernel
  CSPRNG (40-256 bytes, ish)
- - iff it has been correctly seeded beforehand with sufficient collected
- - returns an error (ENOENT?) if it has never been insufficiently seeded
  to operate securely
- - otherwise does not error (except if an invalid buffer or byte count
  is given) or block
- - does not reduce the entropy estimate in the accumulated buffer (the
  DRBG should be cryptographically secure so this is not a problem)
- - is suitable for seeding arc4random(3) or another CSPRNG, or for
  direct use if only small quantities are required
- - is atomic and uninterruptible

and then libc can use that to seed arc4random(3) using ChaCha20 or
another very good DRBG (i.e. not RC4!) and hopefully everyone can swim
in a sea of quite fast, long-term-key-grade random numbers.

If a blocking/pure-entropy mode analogous to /dev/random is required,
I think the best approach would be to run a second CSPRNG in parallel
which does reduce the entropy count when queried - and its first
secure output could be used to kickstart the main kernel CSPRNG, which
would be a reasonable implementation in practice I think.

I don't think a mode analogous to current /dev/urandom should be
provided, because it can be run completely unseeded. If someone wants
a non-cryptographic PRNG, they can do it much faster in user-space.

Of course, that is just my opinion, this isn't LKML but more of a case
study/general discussion here, and I am aware over the decade the
generator has been in Linux you've seen _plenty_ of opinions. :)

- --