From f7cdad0b784718e88dcfe03ae8ec2eddb59ff7e2 Mon Sep 17 00:00:00 2001 From: Mark Schouten Date: Wed, 5 Nov 2014 09:33:42 +0100 Subject: [PATCH] Create a hash_pbkdf2 function if it doesn't exist yet --- includes/misc.inc.php | 86 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 86 insertions(+) diff --git a/includes/misc.inc.php b/includes/misc.inc.php index a321832..1a094ae 100644 --- a/includes/misc.inc.php +++ b/includes/misc.inc.php @@ -176,4 +176,90 @@ function user_template_names() { return $templatenames; } + + +/* This function was taken from https://gist.github.com/rsky/5104756 to make +it available on older php versions. Thanks! */ + +if (!function_exists(hash_pbkdf2)) { + function hash_pbkdf2($algo, $password, $salt, $iterations, $length = 0, $rawOutput = false) { + // check for hashing algorithm + if (!in_array(strtolower($algo), hash_algos())) { + trigger_error(sprintf( + '%s(): Unknown hashing algorithm: %s', + __FUNCTION__, $algo + ), E_USER_WARNING); + return false; + } + + // check for type of iterations and length + foreach (array(4 => $iterations, 5 => $length) as $index => $value) { + if (!is_numeric($value)) { + trigger_error(sprintf( + '%s() expects parameter %d to be long, %s given', + __FUNCTION__, $index, gettype($value) + ), E_USER_WARNING); + return null; + } + } + + // check iterations + $iterations = (int)$iterations; + if ($iterations <= 0) { + trigger_error(sprintf( + '%s(): Iterations must be a positive integer: %d', + __FUNCTION__, $iterations + ), E_USER_WARNING); + return false; + } + + // check length + $length = (int)$length; + if ($length < 0) { + trigger_error(sprintf( + '%s(): Iterations must be greater than or equal to 0: %d', + __FUNCTION__, $length + ), E_USER_WARNING); + return false; + } + + // check salt + if (strlen($salt) > PHP_INT_MAX - 4) { + trigger_error(sprintf( + '%s(): Supplied salt is too long, max of INT_MAX - 4 bytes: %d supplied', + __FUNCTION__, strlen($salt) + ), E_USER_WARNING); + return false; + } + + // initialize + $derivedKey = ''; + $loops = 1; + if ($length > 0) { + $loops = (int)ceil($length / strlen(hash($algo, '', $rawOutput))); + } + + // hash for each blocks + for ($i = 1; $i <= $loops; $i++) { + $digest = hash_hmac($algo, $salt . pack('N', $i), $password, true); + $block = $digest; + for ($j = 1; $j < $iterations; $j++) { + $digest = hash_hmac($algo, $digest, $password, true); + $block ^= $digest; + } + $derivedKey .= $block; + } + + if (!$rawOutput) { + $derivedKey = bin2hex($derivedKey); + } + + if ($length > 0) { + return substr($derivedKey, 0, $length); + } + + return $derivedKey; + } +} + ?>