Issue #15039 has been updated by Freaky (Thomas Hurst).


naruse (Yui NARUSE) wrote:
> Freaky (Thomas Hurst) wrote:
> > ... but you've just described concerns over situations where such APIs are unavailable.  If you have no /dev/urandom why would you have a /dev/random?  If you have no non-blocking syscall for entropy why would you have a blocking one?
> 
> Even if /dev/random is not accessible, it can use getentropy(2).

As far as I know getentropy(2) behaves as urandom, just with a size limit.

> > > But the size of those entropy is limited.
> > 
> > Entropy's not really limited, the entire point of CSPRNGs is that you can stretch 256 bits of entropy out practically forever because the effort required to recover those bits and predict anything *exceeds the physical limitations of the universe*.
> 
> Yes.
> But Random.urandom shouldn't be limited.

Yes, with the caveat that it should block if the urandom source has yet to be seeded (because then it can't give a reasonable guarantee of cryptographic randomness, which is what it's for, right?)

> > GRND_NONBLOCK's only affect is to return an error instead of blocking if the urandom source hasn't been seeded - i.e. very early in the boot sequence, which I'm not sure Ruby should be caring about.  /dev/urandom also blocks like this on most platforms.
> 
> Ah, you are correct.
> But I mean GRND_RANDOM.

Well, that's not being used by Ruby.  And I don't think it ever should, it's basically just asking for the brain-dead Linux-style /dev/random behaviour where it tries to guess how much entropy is "used" and blocks arbitrarily based on guessing how much more it's gathered.

GRND_NONBLOCK *is* used if need_secure is false, which I suppose is fair enough - it can fall back to /dev/urandom and provided some maybe-predictable randomness instead.

> getentropy(2) always behaves as GRND_RANDOM and Random.urandom with getentropy(2) will require userspace CSPRNG.

What makes you think OpenBSD's getentropy blocks?

https://man.openbsd.org/getentropy.2: no mention of blocking, and the implementation:

https://github.com/openbsd/src/blob/b66614995ab119f75167daaa7755b34001836821/sys/dev/rnd.c#L916-L933

Literally just a kernel-space `arc4random_buf` call.

----------------------------------------
Bug #15039: Random.urandom and SecureRandom arc4random use
https://bugs.ruby-lang.org/issues/15039#change-73830

* Author: Freaky (Thomas Hurst)
* Status: Open
* Priority: Normal
* Assignee: 
* Target version: 
* ruby -v: 
* Backport: 2.3: UNKNOWN, 2.4: UNKNOWN, 2.5: UNKNOWN
----------------------------------------
Random.urandom defaults to arc4random() on a lot of platforms, including FreeBSD.

On all currently released versions of FreeBSD, arc4random() is, as the name suggests, a dubious ARC4-based userspace PRNG dating from circa 1997.  Given the entire point of #9569 was that using the userspace CSPRNG in OpenSSL over /dev/urandom or equivalent is a bad idea, this seems to mean it's regressed to an *even worse* state on these platforms.  Even in cases where it's using something more modern (FreeBSD 12, OpenBSD), it's still a userspace CSPRNG.

If that's fine, we might as well *pick a known-good one* and use that everywhere.  Like, say, OpenSSL's.

Since the conclusion of #9569 seems to have been otherwise, I'd suggest dropping arc4random() as a potential source for Random.urandom due to it not matching the desired semantics.

Rust's OsRng seems a good template for alternative _syscall implementations: https://docs.rs/rand/0.5.5/rand/rngs/struct.OsRng.html#platform-sources



-- 
https://bugs.ruby-lang.org/

Unsubscribe: <mailto:ruby-core-request / ruby-lang.org?subject=unsubscribe>
<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-core>