Follow @Openwall on Twitter for new release announcements and other news
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date: Wed, 28 Jan 2015 14:20:16 -0600
From: Brent Cook <busterb@...il.com>
To: musl@...ts.openwall.com
Subject: Re: getrandom syscall


> On Jan 28, 2015, at 1:17 PM, Rich Felker <dalias@...c.org> wrote:
> 
> On Wed, Jan 28, 2015 at 11:43:17AM -0600, Brent Cook wrote:
>> Here is the wrapper in LibreSSL for getrandom, to hopefully lend to
>> the discussion:
>> 
>> https://github.com/libressl-portable/openbsd/blob/master/src/lib/libcrypto/crypto/getentropy_linux.c#L194
> 
> This version is failing to set errno when rejecting len>256, which
> looks bad.

Right, it's not actually a problem in context of the whole file.
This is just the first of several fallbacks called by getentropy.

I think that was there originally just to remind what the limit is
before it changes blocking behavior. In this context, it can also fail
with ENOSYS too, so this on function is not a standalone gententropy
emulation.

>> It tries to avoid a couple of possible issues. FIrst, while <= 256
>> byte getrandom should not interrupt, it appears that if the kernel
>> entropy pool has not been initialized yet, it would still return EINTR
>> if called early enough in the boot process. How likely this is in
>> practice, I don't know.
> 
> You mean it would block and be subject to EINTR if a signal occurs? In
> this case I would think you'd probably _want_ the EINTR to cause it to
> fail. I can imagine an early-boot program using SIGALRM to prevent
> waiting too-long/forever for entropy that's not going to arrive.

Yes, that is a better description. Failing when receiving EINTR to avoid
an infinite loop is an interesting idea, but getentropy is documented
as only failing under a very narrow range of conditions:

http://www.openbsd.org/cgi-bin/man.cgi/OpenBSD-current/man2/getentropy.2

>> Then, to avoid modifying errno even though there was an actual
>> success, the wrapper restores the previous errno value when it
>> succeeds.
> 
> Avoiding modification of errno when the call succeeds is not necessary
> or desirable. Callers should not be assuming errno is untouched after
> success.

I think the difference here was that this is attempting to emulate a
syscall, rather than a library function, so its trying to only set
errno on failure. This was suggested to me by Theo de Raadt.

But, you're right, callers shouldn't expect either anyway.

>> I just realized that the length check in getentropy_getrandom() is
>> redundant, since it is checked earlier in getentropy() as well, but
>> hopefully this is helpful.
> 
> Indeed, that masks the issue I mentioned above.

Right, this is just one of several entropy methods that it calls in
order to perform the emulation. The outer getentropy() function is the
one that matters.

> So, their version of getentropy is aiming to provide a meaningful
> result even on systems that don't have SYS_getrandom. Should we be
> doing the same?
> 
>> If a getentropy() were added to musl libc, but in such a way that it
>> might fail on older kernels, that would cause some problems with
>> LibreSSL, and now OpenNTPD. They will both try to use getentropy()
>> with arc4random() if it is found in a system, and arc4random() will
>> treat a getentropy() failure as fatal.
> 
> Yes, this sounds bad. So what fallbacks should we implement? Do we
> need a strong CSPRNG on top of AT_RANDOM?

You can see a variety of fallbacks there, and AT_RANDOM is included,
though that is not available on every kernel either. If you're going to
implement such a CSPRNG, the C library seems the place to do it though.

  - Brent

Powered by blists - more mailing lists

Confused about mailing lists and their use? Read about mailing lists on Wikipedia and check out these guidelines on proper formatting of your messages.