On 10/19/15, 6:43 PM, "Ángel González" <keis...@gmail.com> wrote: > Tom Worster wrote: > > I've verified that password_hash() without /dev/urandom can > produce systematically predictable salts, repeating a sequence of > just two salts. There's nothing statistical involved. Reported in > bug 70743. > > > Seems crypt() is similarly afflicted. > > > Only providing two hashes *would* be very worrisome. Note however > that you are crippling rand() by always resetting the seed (those
My point was to show that password_hash()'s promises of security are nullified by use of an unrelated API. The docs do not explain how password_hash() can depend on the use of other functions, like the old rand() LCG, and there's no reason the user should suspect it. > two different outputs appear because it is xoring with the same > sequence). It's also reading unitialized memory in line 155, which > is probably accounting for the salts being different every time. And > a change in allocations for the first run being different. > > Whereas on a real world usage, even if a new php instance was used > every time, you would need a GENERATE_SEED() collision. It > initializes the seed using the timestamp, pid, microseconds and > thread id (plus any state change caused if different php scripts > were run). Security BCPs do not allow arguments of this nature. Security-related APIs need to be robust in all reasonable circumstances, not just in what you consider typical circumstances. > You have a very good point in that it would fail only if > /dev/urandom does not exist at all, my initial concerns came from > thinking that it could fail on a low-entropy case, but that won't > happen on Linux (urandom always works), and even a urandom blocking > OS (eg. on FreeBSD) wouldn't make it use the fallback code. Seems it > would only be used if (a) you don't have a /dev/urandom at all or > (b) it isn't the special file it is supposed to be (eg. it's a > regular file). In which case you are running a broken OS :) > So, changing my previous opinion, it'd be acceptable to drop it (I'd > prefer it being done in the point release, though). There's no such thing as "a low-entropy case" for our purposes. Once the system's CSPRNG is seeded it will produce an endless supply of random bytes. PHP has no alternative but to trust this. Anthony recently made this point in a humorously obscene manner on Twitter. /dev/random and /dev/urandom are the same thing on FreeBSD. The situation on OpenBSD, NetBSD and OS X is similar. FreeBSD's random device does not block except during a reseeding event. This happens immediately after boot for a short period but PHP can safely ignore that. The other causes for a reseeding event are very unlikely (and have nothing to do with "how much entropy is consumed" or any such nonsense) but if they do happen then the best thing PHP can do is hang and wait for the result. I believe PHP can take the same attitude on OpenBSD, NetBSD and OS X, although I admit I know less about these. We do not need to consider low-entropy cases. If we read from urandom and allow it to block, we should be safe. There is danger in libc arc4random but that's for another thread #70744. Tom -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php