Follow @Openwall on Twitter for new release announcements and other news
[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Message-ID: <54D91A9D.4000403@amacapital.net>
Date: Mon, 09 Feb 2015 12:37:49 -0800
From: Andy Lutomirski <luto@...capital.net>
To: musl@...ts.openwall.com
Subject: Re: getrandom syscall

On 01/28/2015 02:02 PM, Rich Felker wrote:
> On Wed, Jan 28, 2015 at 02:20:16PM -0600, Brent Cook wrote:
>>>> 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
>
> OK. The conditions for EIO are left sort of open-ended, but it seems
> the intent is that this function not fail with valid inputs. I think
> we should follow that intent if we provide the function, which means
> both ignoring EINTR and providing a fallback for ENOSYS.
>
>>> 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.
>
> At this point I think what's clear is that we should provide the
> syscall wrapper for getrandom. What to do with getentropy is less
> clear, and it looks to be a fair bit of work/code-size to get a robust
> getentropy suitable for application usage.
>
> I don't want to copy the idiotic stuff libressl is doing, but I think
> the following fallback sequence would be reasonable:
>
> 1. Try SYS_getrandom. Fails on even mildly-old kernels.
>
> 2. Try opening /dev/urandom. Fails under fd pressure or broken
>     chroots/containers/lsms/etc.
>
> 3. Try AT_RANDOM+CSPRNG. Fails on ancient (what version?) kernels.
>
> I don't know what to after that, but I suspect/hope that any kernel
> too old to have AT_RANDOM is full of so many gaping security holes
> that lack of working entropy source is the least of anyone's problems.
>
> As for CSPRNG, what would be acceptably small and secure? CTR mode
> using a block cipher and AT_RANDOM as the key? Could we reuse crypto
> code out of crypt/*.c? Or just call crypt_r directly?

Something backword secret (maybe the wrong term) would be nice, e.g., 
new_state, output = PRF(old_state).  This has the property that a leak 
of memory contents heartbleed-style doesn't leak *prior* CSPRNG outputs.

Defining PRF(x) = SHA256(x) with x being 128 bits is probably fine. 
That is, new_state is the first 128 bits of SHA256(old_state) and the 
output is the next 128 bits.  The quantum cryptographer in me would 
prefer 256-bit state, though, but I'm not sure that makes any sense in 
practice with AT_RANDOM.

I am not a serious cryptographer, so this should be taken with a small 
grain of salt.  If you wanted to depend on having an implementation of 
the Keccak sponge around, then there are very simple and much cleaner 
CSPRNGs in the literature that I could point you to, but they have the 
disadvantage of using larger internal states and therefore more memory. 
  Using a 128-bit state has the benefit that it could reuse the memory 
already allocated to AT_RANDOM.

--Andy

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.