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.)
diff --git a/system/core/compat/hash.php b/system/core/compat/hash.php
index a9f59f1..b217010 100644
--- a/system/core/compat/hash.php
+++ b/system/core/compat/hash.php
@@ -39,6 +39,52 @@
// ------------------------------------------------------------------------
+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;