From a5621b8965ebcec213d3a5b07500cfcc3a730ada Mon Sep 17 00:00:00 2001 From: Andrey Andreev Date: Fri, 9 May 2014 11:23:08 +0300 Subject: Add hash_equals() to ext/hash compat layer Introduced in PHP 5.6 Beta 1 (unfortunately, still undocumented). RFC: https://wiki.php.net/rfc/timing_attack (Yes, I am aware that the RFC talks about hash_compare(), the function was later renamed in the implementation.) --- system/core/compat/hash.php | 46 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) (limited to 'system/core') diff --git a/system/core/compat/hash.php b/system/core/compat/hash.php index a9f59f110..b2170103e 100644 --- a/system/core/compat/hash.php +++ b/system/core/compat/hash.php @@ -39,6 +39,52 @@ defined('BASEPATH') OR exit('No direct script access allowed'); // ------------------------------------------------------------------------ +if (is_php('5.6')) +{ + return; +} + +// ------------------------------------------------------------------------ + +if ( ! function_exists('hash_equals')) +{ + /** + * hash_equals() + * + * @link http://php.net/hash_equals + * @param string $known_string + * @param string $user_string + * @return bool + */ + function hash_equals($known_string, $user_string) + { + if ( ! is_string($known_string)) + { + trigger_error('hash_equals(): Expected known_string to be a string, '.strtolower(gettype($known_string)).' given', E_USER_WARNING); + return FALSE; + } + elseif ( ! is_string($user_string)) + { + trigger_error('hash_equals(): Expected user_string to be a string, '.strtolower(gettype($user_string)).' given', E_USER_WARNING); + return FALSE; + } + elseif (($length = strlen($known_string)) !== strlen($user_string)) + { + return FALSE; + } + + $diff = 0; + for ($i = 0; $i < $length; $i++) + { + $diff |= ord($known_string[$i]) ^ ord($user_string[$i]); + } + + return ($diff === 0); + } +} + +// ------------------------------------------------------------------------ + if (is_php('5.5')) { return; -- cgit v1.2.3-24-g4f1b