Hi Lauri, On Thu, Feb 2, 2017 at 6:54 PM, Lauri Kenttä <lauri.ken...@gmail.com> wrote:
> I think this RFC is badly prepared. You're overhauling the whole mt_rand > system in one go, but you're not doing it properly. There is no > justification for breaking compability, not in 7.x and not even in 8.0 in > my opinion. > Which part are you referring as BC? I suppose it is <?php $state = mt_srand(1234); mt_rand($state); // Get static seed result ?> Current behavior is extremely bad because if there is srand()/mt_srand() call in execution path. 1) When seed is provided to srand()/mt_srand(), consecutive rand()/mt_rand() calls became non random. (Unacceptable) 2) 1) applies to across request. (Extremely bad) 3) Even without seed, srand()/mt_srand() call makes guess a lot easier than it should be. i.e. Combined LCG is weak. Suppose attacker find execution path that has static seed for srand()/mt_srand(), then attacker can predict exact random or can guess easily. a.php <?php // I need static random sequence srand(1234); for ($i = 0; $i < 10; $i++) $rand[] = rand(); ?> b.php <?php // I need random sequence, let PHP seed it for ($i = 0; $i < 10; $i++) $better_rand[] = mt_rand(); ?> If a.php is called, then b.php's mt_rand() is not random at all. Even if mt_rand()/rand() is predictable, this kind of behavior is _ABSOLUTELY_ unacceptable. IMO. It's BC, but how many srand()/mt_srand() calls are used in real apps? I know there are, but benefits outweighs BC impact. > > There's now three completely unrelated "issues": > > 1) You want to improve automatic seeding and GENERATE_SEED. You could just > generate a 32-bit value from php_random_bytes and silently use the current > as fallback; this solution was practically accepted already. You just waste > time with your arguments about CSPRNG being sooooo important: everybody has > already heard you, and most people seem to disagree. > True, but I've never heard of CSPRNG failure that could cause BC that matter as PHP problem yet. > > 2) You want to support long seeds. However, 2^32 is a lot of random > states. It's enough for almost any legitimate MT use case. As was earlier > discussed, adding this support to the global mt_srand is not practical. > Anyone who really needs a longer seed should most probably also use a PRNG > object to avoid cases where some internal function (say, shuffle) modifies > the MT state by accident. > > 3) You want to use long seeds by default. This would be possible, as > discussed earlier, by seeding the whole MT state buffer from a CSPRNG. > However, you should consider also the possible performance impact of > generating 2,5 kB from CSPRNG on each request/reseed. And again, 2^32 is > probably enough already. > > FWIW, my Raspberry Pi kernel log has several lines about /dev/urandom not > being properly seeded before the system is fully started, so using a CSPRNG > is not guaranteed to work so well. > Although users must never do this, but there are codes that generate random password/access key by mt_rand(). If algorithm is known to attacker, all attacker should do could be making very small size of dictionary or current computer is fast enough to compute next random string to be generated in short enough time. If MT rand is seed fully, above task becomes hard enough task attackers to avoid attacks. Reading data from CSPRNG shouldn't be too slow as you know. One in a hundred calls shouldn't matter. Even when it could matter, users may set PHP to reseed one in a million, but the default shouldn't be too large. When hardware TRNG is not available, CSPRNG could generate poor random until system corrects enough entropy events. i.e. matter of time. CSPRNG output should be available. If not, I'm surprised and I'll change my opinion. How many mt_rand()/rand() calls are executed during PHP process lifetime? With 32 bits seed, users will never use even 0.0000000000000001% of MT rand potential. It's too much waste of the algorithm, isn't it? Regards, -- Yasuo Ohgaki yohg...@ohgaki.net