From f1b824b5c0be76a818f44690294790d00fa9d066 Mon Sep 17 00:00:00 2001 From: Andreas Gohr Date: Thu, 30 May 2013 16:49:58 +0200 Subject: added HMAC support to PassHash class FS#2794 --- inc/PassHash.class.php | 47 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) (limited to 'inc/PassHash.class.php') diff --git a/inc/PassHash.class.php b/inc/PassHash.class.php index 080fb4778..61bd74939 100644 --- a/inc/PassHash.class.php +++ b/inc/PassHash.class.php @@ -494,4 +494,51 @@ class PassHash { $this->init_salt($salt, 8, false); return ':B:'.$salt.':'.md5($salt.'-'.md5($clear)); } + + /** + * Wraps around native hash_hmac() or reimplents it + * + * This is not directly used as password hashing method, and thus isn't callable via the + * verify_hash() method. It should be used to create signatures and might be used in other + * password hashing methods. + * + * @see hash_hmac() + * @author KC Cloyd + * @link http://www.php.net/manual/en/function.hash-hmac.php#93440 + * + * @param string $algo Name of selected hashing algorithm (i.e. "md5", "sha256", "haval160,4", + * etc..) See hash_algos() for a list of supported algorithms. + * @param string $data Message to be hashed. + * @param string $key Shared secret key used for generating the HMAC variant of the message digest. + * @param bool $raw_output When set to TRUE, outputs raw binary data. FALSE outputs lowercase hexits. + * + * @return string + */ + public static function hmac($algo, $data, $key, $raw_output = false) { + // use native function if available and not in unit test + if(function_exists('hash_hmac') && !defined('SIMPLE_TEST')){ + return hash_hmac($algo, $data, $key, $raw_output); + } + + $algo = strtolower($algo); + $pack = 'H' . strlen($algo('test')); + $size = 64; + $opad = str_repeat(chr(0x5C), $size); + $ipad = str_repeat(chr(0x36), $size); + + if(strlen($key) > $size) { + $key = str_pad(pack($pack, $algo($key)), $size, chr(0x00)); + } else { + $key = str_pad($key, $size, chr(0x00)); + } + + for($i = 0; $i < strlen($key) - 1; $i++) { + $opad[$i] = $opad[$i] ^ $key[$i]; + $ipad[$i] = $ipad[$i] ^ $key[$i]; + } + + $output = $algo($opad . pack($pack, $algo($ipad . $data))); + + return ($raw_output) ? pack($pack, $output) : $output; + } } -- cgit v1.2.3