From cd46dc479cf975cbb843c360f1240203aebfcb32 Mon Sep 17 00:00:00 2001 From: Bharat Mediratta Date: Sun, 1 Apr 2012 12:39:48 -0700 Subject: [PATCH] Beef up the random number generator by using Joomla's new implementation. --- modules/gallery/helpers/random.php | 6 +- modules/gallery/vendor/joomla/crypt.php | 151 ++++++++++++++++++++++++ modules/rest/helpers/rest_event.php | 6 +- 3 files changed, 158 insertions(+), 5 deletions(-) create mode 100644 modules/gallery/vendor/joomla/crypt.php diff --git a/modules/gallery/helpers/random.php b/modules/gallery/helpers/random.php index 0ee83f497b..ea08815a87 100644 --- a/modules/gallery/helpers/random.php +++ b/modules/gallery/helpers/random.php @@ -17,13 +17,15 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ + class random_Core { /** * Return a random 32 byte hash value. * @param string extra entropy data */ - static function hash($entropy="") { - return md5($entropy . uniqid(mt_rand(), true)); + static function hash($length=32) { + require_once(MODPATH . "gallery/vendor/joomla/crypt.php"); + return md5(JCrypt::genRandomBytes($length)); } /** diff --git a/modules/gallery/vendor/joomla/crypt.php b/modules/gallery/vendor/joomla/crypt.php new file mode 100644 index 0000000000..c7d477dd03 --- /dev/null +++ b/modules/gallery/vendor/joomla/crypt.php @@ -0,0 +1,151 @@ += 0 + || substr(PHP_OS, 0, 3) !== 'WIN' + ) + ) + { + $sslStr = openssl_random_pseudo_bytes($length, $strong); + if ($strong) + { + return $sslStr; + } + } + + /* + * Collect any entropy available in the system along with a number + * of time measurements of operating system randomness. + */ + $bitsPerRound = 2; + $maxTimeMicro = 400; + $shaHashLength = 20; + $randomStr = ''; + $total = $length; + + // Check if we can use /dev/urandom. + $urandom = false; + $handle = null; + if (function_exists('stream_set_read_buffer') && @is_readable('/dev/urandom')) + { + $handle = @fopen('/dev/urandom', 'rb'); + if ($handle) + { + $urandom = true; + } + } + + while ($length > strlen($randomStr)) + { + $bytes = ($total > $shaHashLength)? $shaHashLength : $total; + $total -= $bytes; + /* + * Collect any entropy available from the PHP system and filesystem. + * If we have ssl data that isn't strong, we use it once. + */ + $entropy = rand() . uniqid(mt_rand(), true) . $sslStr; + $entropy .= implode('', @fstat(fopen( __FILE__, 'r'))); + $entropy .= memory_get_usage(); + $sslStr = ''; + if ($urandom) + { + stream_set_read_buffer($handle, 0); + $entropy .= @fread($handle, $bytes); + } + else + { + /* + * There is no external source of entropy so we repeat calls + * to mt_rand until we are assured there's real randomness in + * the result. + * + * Measure the time that the operations will take on average. + */ + $samples = 3; + $duration = 0; + for ($pass = 0; $pass < $samples; ++$pass) + { + $microStart = microtime(true) * 1000000; + $hash = sha1(mt_rand(), true); + for ($count = 0; $count < 50; ++$count) + { + $hash = sha1($hash, true); + } + $microEnd = microtime(true) * 1000000; + $entropy .= $microStart . $microEnd; + if ($microStart > $microEnd) { + $microEnd += 1000000; + } + $duration += $microEnd - $microStart; + } + $duration = $duration / $samples; + + /* + * Based on the average time, determine the total rounds so that + * the total running time is bounded to a reasonable number. + */ + $rounds = (int)(($maxTimeMicro / $duration) * 50); + + /* + * Take additional measurements. On average we can expect + * at least $bitsPerRound bits of entropy from each measurement. + */ + $iter = $bytes * (int) ceil(8 / $bitsPerRound); + for ($pass = 0; $pass < $iter; ++$pass) + { + $microStart = microtime(true); + $hash = sha1(mt_rand(), true); + for ($count = 0; $count < $rounds; ++$count) + { + $hash = sha1($hash, true); + } + $entropy .= $microStart . microtime(true); + } + } + + $randomStr .= sha1($entropy, true); + } + + if ($urandom) + { + @fclose($handle); + } + + return substr($randomStr, 0, $length); + } +} diff --git a/modules/rest/helpers/rest_event.php b/modules/rest/helpers/rest_event.php index 0204eb55bb..ec50088456 100644 --- a/modules/rest/helpers/rest_event.php +++ b/modules/rest/helpers/rest_event.php @@ -43,7 +43,7 @@ static function change_provider($new_provider) { static function user_add_form_admin_completed($user, $form) { $key = ORM::factory("user_access_key"); $key->user_id = $user->id; - $key->access_key = random::hash($user->name); + $key->access_key = random::hash(); $key->save(); } @@ -64,7 +64,7 @@ static function _get_access_key_form($user, $form) { if (!$key->loaded()) { $key->user_id = $user->id; - $key->access_key = random::hash($user->name); + $key->access_key = random::hash(); $key->save(); } @@ -93,7 +93,7 @@ static function show_user_profile($data) { if (!$key->loaded()) { $key->user_id = $data->user->id; - $key->access_key = random::hash($data->user->name); + $key->access_key = random::hash(); $key->save(); } $view->rest_key = $key->access_key;