Bug #24410
closedParameter for function "mcrypt_create_iv" not correct
Added by Wim Roukema almost 14 years ago. Updated about 6 years ago.
100%
Description
In a Windows environment the parameter "MCRYPT_DEV_URANDOM" is unknown. This parameter is defined in class.t3lib_div.php on line 1679.
The problem is solved by changing the parameter to: MCRYPT_RAND.
Complete statement:
$output = mcrypt_create_iv($count, MCRYPT_DEV_URANDOM);
changed to
$output = mcrypt_create_iv($count, MCRYPT_RAND);
(issue imported from #M16837)
Files
16837.diff (689 Bytes) 16837.diff | Administrator Admin, 2010-12-29 19:35 | ||
16837_v2.diff (580 Bytes) 16837_v2.diff | Administrator Admin, 2010-12-29 19:56 | ||
16837_v3.diff (720 Bytes) 16837_v3.diff | Administrator Admin, 2010-12-30 11:21 | ||
16837_v3a.diff (734 Bytes) 16837_v3a.diff | Administrator Admin, 2010-12-30 11:24 | ||
16837_v4.diff (1.02 KB) 16837_v4.diff | Administrator Admin, 2010-12-30 11:50 | ||
test_mcrypt_randoms.php (773 Bytes) test_mcrypt_randoms.php | Tomasz Krawczyk, 2011-08-24 11:35 |
Updated by Steffen Gebert almost 14 years ago
Hi Wim,
thanks for your report!
Are you able to create a patch against the subversion checkout from https://svn.typo3.org/TYPO3v4/Core/trunk/?
I would prefer the following solution:
$source = defined('MCRYPT_DEV_URANDOM') ? MCRYPT_DEV_URANDOM : MCRYPT_RAND; $output = mcrypt_create_iv($count, $source);
Could you please test this?
Thanks for your contribution
Steffen
Updated by Steffen Gebert almost 14 years ago
After looking at the code, I wonder why this bug exists at all:
if ($output === '' && version_compare(PHP_VERSION, '5.3.0', '>=')) { if (function_exists('mcrypt_create_iv')) { $source = defined('MCRYPT_DEV_URANDOM') ? MCRYPT_DEV_URANDOM : MCRYPT_RAND; $output = mcrypt_create_iv($count, $source); } }
PHP manual tells that MCRYPT_DEV_URANDOM is also available on Windows platforms starting with PHP 5.3.0 (see http://de3.php.net/mcrypt_create_iv).
However, could you please try the attached patch?
Updated by Steffen Gebert almost 14 years ago
I would go for v2, which checks
if (function_exists('mcrypt_create_iv') && defined('MCRYPT_DEV_URANDOM'))
as we're fine with pseudo-randomness and MCRYPT_RAND can get very slow.
Updated by Jan Reilink almost 14 years ago
Yes, MCRYPT_DEV_URANDOM is defined on Windows, but failes with a fatal error.
Shortened test-code:
$output = ''; $count = (int) '16'; $source = MCRYPT_DEV_URANDOM;
if (function_exists('mcrypt_create_iv')) {
$output = mcrypt_create_iv($count, $source);
echo 'output is: ' . $output;
}
Fatal error message:
Fatal error: mcrypt_create_iv(): Could not gather sufficient random data in [...] on line [...]
Updated by Steffen Gebert almost 14 years ago
Umm.. urandom should never get out of "random" data as it's only pseudo random.
I just found the following PHP bug report (which.. the funny thing.. also writes about TYPO3's generateRandomBytes()): http://bugs.php.net/bug.php?id=52523
Derick Rethands wrote:
This is a bug actually. /dev/random is supposed to wait as long as there is enough
entropy. /dev/urandom cares less (and is a worse source of entropy). The behaviour on
Windows needs to behave the same as on a Unix.
The bug is set to fixed after a commit on 2010-08-09 - could you try PHP 5.3.4?
There are also further comments regarding our used code, I will add them to the related #24440.
So.. Jan - could you try a more recent PHP version (5.3.4 seems to be the only possible one currently ;-))? Which one are you using currently?
Further steps? Dunno.. remove mcrypt_create_iv() as it doesn't work well? Using MCRYPT_RAND is IMHO no option (as this one can get very slow..).
Prefer openssl?
Updated by Wim Roukema almost 14 years ago
I tested the solution of Steffen Gebert, but the result is the same as Jan Reilink has mentioned.
The constant 'MCRYPT_DEV_URANDOM' is known, but the /dev/urandom directory is not present.
I implemented patch2 of related issue 16871.That works correct.
I don't notice a very slow performance of MCRYPT_RAND, even after clearing the typo3-cache.
Further on "phpf1.com" I found this note:
Note: When using MCRYPT_RAND, remember to call srand() before mcrypt_create_iv() to initialize the random number generator; it is not seeded automatically like rand() is.
Implement this?
Updated by Steffen Gebert almost 14 years ago
Silverstripe disabled mcrypt_create_iv() on windows: http://open.silverstripe.org/changeset/114510.
Jan, are you using IIS or Apache?
Updated by Steffen Gebert almost 14 years ago
@Wim
sorry, writing my previous comment took quite some time and appears below yours ;)
Of course, /dev/urandom is not known on Windows - that's why mycrypt is used ;)
You reported <em> In a Windows environment the parameter "MCRYPT_DEV_URANDOM" is unknown.</em>. What does "unknown" mean? Seems like it <em>is</em> defined, as Jan reported. Do you also get the "Could not gather sufficient random data" (I assume).
Problem with random generators is that you never know, when there comes a lack of random data. Relying on true random generator functions (instead of pseudo-randomness) can cause long waiting times.. dependent on no more random data being available (e.g. caused by other applications gathering data).
Please see the offical PHP manual, which states that srand() isn't needed anymore with PHP 5.3
http://de.php.net/mcrypt_create_iv
Updated by Jan Reilink almost 14 years ago
Hi Steffen,
I tested on Windows Server 2008 with IIS 7.5 and PHP version 5.3.3. I found the same bug reports on php.net.
Of course I can't set-up PHP 5.3.4 on a production web server of ours (earlier mentioned testingcode.org-URL), so I set it up on a test web server. Still no go.
My test PHP-souce (<br>'s removed):
// needed to disable Wincache caching
ini_set('wincache.fcenabled','0');
ini_set('wincache.ucenabled','0');
$output = ''; $count = (int) '16'; $source = MCRYPT_DEV_URANDOM;
echo('PHP version '. PHP_VERSION . ' on server operating system '
. $_SERVER['OS'] . ' with web server software ' . $_SERVER['SERVER_SOFTWARE']);
if (extension_loaded('mcrypt')) {
echo('extension mcrypt is loaded'); // mcrypt is statically linked
}
if (defined('MCRYPT_DEV_URANDOM')) {
echo('MCRYPT_DEV_URANDOM is defined');
}
if (function_exists('mcrypt_create_iv')) {
echo 'function mcrypt_create_iv exists';
$output = mcrypt_create_iv($count, $source);
echo 'output is: ' . $output;
}
?>
Under what circumstances gets MCRYPT_RAND slow? I would go with either MCRYPT_RAND if it isn't slow, or openssl.
PS: for performance, drop the CAPICOM ActiveX object support. It's not available by default on Windows.
Updated by Steffen Gebert almost 14 years ago
MCRYPT_RAND must be slow, if the server's Random Number Generator has a lack of entropy. I have no proof for MCRYPT_RAND in particular, but every RNG's performance is limited, while pseudo-RNGs are much faster.
Please try attached patch (v3), which suppresses the PHP warning and falls back to other RNGs, if mcrypt_create_iv() returned false.
Solution is taken from Marcus' refactoring PoC #23355
EDIT: v3a slightly improved
Updated by Jan Reilink almost 14 years ago
The patch doesn't work. The problem lies in the if .. elseif. The latter never gets executed, since the function mcrypt_create_iv exists. Further, despite suppressing the PHP error (!warning), the PHP execution still stops because it is a fatal error.
Quickest fix would be to go for MCRYPT_RAND, with openssl as second option or fallback.
Updated by Steffen Gebert almost 14 years ago
Ah, okay, wasn't aware that it emits a Fatal Error.
v4.. use MCRYPT_RAND for 5.3.0 <= PHP_version <= 5.3.3 and MCRYPT_DEV_URANDOM for PHP_version >= 5.3.4
If mcrypt_create_iv() returns FALSE (in case of this really happens sometimes.. at least the lousy PHP docu says this), openssl is used.
Updated by Jan Reilink almost 14 years ago
There is no "MCRYPT_RANDOM":
- $source = (version_compare(PHP_VERSION, '5.3.4', '>=') ? MCRYPT_DEV_URANDOM : MCRYPT_RANDOM);
+ $source = (version_compare(PHP_VERSION, '5.3.4', '>=') ? MCRYPT_DEV_URANDOM : MCRYPT_RAND);
http://nl.php.net/manual/en/mcrypt.constants.php
It runs on PHP 5.3.3 (because of mcrypt_rand) but still fails with a fatal error on 5.3.4. For the time being, please drop mcrypt_dev_urandom and stick with mcrypt_rand or openssl.
The error is still "Fatal error: mcrypt_create_iv(): Could not gather sufficient random data in [...]"
Updated by Steffen Gebert almost 14 years ago
Sorry for the typo. So let's go for MCRYPT_RAND. I don't want to spend more time on this PHP shit, seems like the bug is not fixed with 5.3.4.
Could you please send the RFC to the typo3-teams-core mailing list?
See http://typo3.org/teams/core/core-mailinglist-rules/
Updated by Ian Burman almost 14 years ago
Same problem after upgrading a Typo3 4.2 site to Typo3 4.4.6 on IIS 6 with PHP 5.3.5
Substituting MCRYPT_RAND for MCRYPT_DEV_URANDOM in class.t3lib_div.php on line 1613 allows the show to go on.
Updated by Tomasz Krawczyk about 13 years ago
- Target version deleted (
0)
Guys I have no such problems on the Apaches but I have this problem on the IIS 6.0. I use PHP 5.3.6.
I resolved the problem by changeing
$output = mcrypt_create_iv($count, MCRYPT_DEV_URANDOM);
to
$output = mcrypt_create_iv($count, MCRYPT_URAND);
So we should simply add condition
if $_SERVER['OS'] = 'Windows_NT') or $_SERVER['SERVER_SOFTWARE'] contains 'IIS' then use
$output = mcrypt_create_iv($count, MCRYPT_URAND);
else use
$output = mcrypt_create_iv($count, MCRYPT_DEV_URANDOM);
.
Updated by Helmut Hummel about 13 years ago
Thomasz: There is no "MCRYPT_URAND" only: MCRYPT_RAND, MCRYPT_DEV_RANDOM, MCRYPT_DEV_URANDOM
So you're using PHP 5.3.6 and MCRYPT_DEV_URANDOM does not work for you but MCRYPT_RAND does?
Updated by Tomasz Krawczyk about 13 years ago
Helmut: Yes, you are right. Sorry for the typo.
I would like to emphasize that it happens only on the IIS.
Updated by Helmut Hummel about 13 years ago
Thomasz: On e.g. apache on Windows with the same PHP version there's no problem?
Please check out:
https://review.typo3.org/4555
if it also fixes your problem.
Updated by Tomasz Krawczyk about 13 years ago
- File test_mcrypt_randoms.php test_mcrypt_randoms.php added
Yes. On the Apache there is no problems but on the IIS there is a problem.
I made simple script to test it (attached). On my two Apaches (WAMP with PHP 5.3.1 and PHP 5.3.6) everything works fine but on the IIS 6.0 with PHP 5.3.6 I have such result:
11:01:11 MCRYPT_RAND is defined MCRYPT_DEV_URANDOM is defined MCRYPT_DEV_RANDOM is defined MCRYPT_RAND - ר*�cdH� Fatal error: mcrypt_create_iv(): Could not gather sufficient random data in D:\(...)\test_mcrypt_randoms.php on line 24
If I switch line 24 with 25 result is the same.
I'll upgrade PHP to 5.3.7 and 5.3.8 and test it again, I'll also test your patch in the evening.
Updated by Tomasz Krawczyk about 13 years ago
I had some free time and development server available so, I tested PHP versions on IIS6 (NTS) with my test script. This are results:
5.3.2 - OK
5.3.3 - ERROR
5.3.4 - ERROR
5.3.5 - ERROR
5.3.6 - ERROR
5.3.7 - OK
5.3.8 - OK
It looks MCRYPT_RAND must be used on IIS with PHP from 5.3.3 to 5.3.6.
Updated by Tomasz Krawczyk about 13 years ago
Helmut: Method generateRandomBytes() from https://review.typo3.org/4555 works on IIS6 (PHP 5.3.6) and Apache (PHP 5.3.6).
Updated by Anonymous about 13 years ago
- Status changed from New to Resolved
- % Done changed from 0 to 100
Applied in changeset f7e9b0bc71906acc6bed19ab12fbb3dcbb1b592a.
Updated by David Bruchmann about 13 years ago
Had to change the proposed solution to
if (function_exists('mcrypt_create_iv')) { $source = defined('MCRYPT_DEV_URANDOM') ? (MCRYPT_DEV_URANDOM ? MCRYPT_DEV_URANDOM : MCRYPT_RAND) : MCRYPT_RAND; $output = $source ? @mcrypt_create_iv($count, $source) : ''; }
ENV:
php-5.3.3-Win32-VC6-x86 WinXP SP3 TYPO3 4.5.6
FE loaded after Steffen's Solution but BE still reported the Error-Message.
So a test if MCRYPT_DEV_URANDOM is defined is not enough, it has to be checked if it's filled with some value.
Furthermore mcrypt_create_iv() has only to be called if $source is filled - it occured that even with my extended 2nd line $source was empty.
Other Compilations of PHP may behave different - don't know, didn't succeed to enable VC9-compilations on this OS ...
still had to suppress errormessages in BE by prepending the function with '@'.
Updated by Andreas Wolf about 13 years ago
- Status changed from Resolved to Needs Feedback
I guess from the most recent commit that this issue is not solved, right? If there are still problems, could someone please open a new issue and link it to this one. This will be closed afterwards.
Updated by Anonymous almost 13 years ago
- Status changed from Needs Feedback to Resolved
Applied in changeset 98c2451df6e62dc809107b1e6ae2cba487f7fa69.