blob: aeacabdb950e124f9acc7ccb1e5ba974958d8833 [file] [log] [blame]
Andrey Andreev9a152a92014-02-18 16:29:53 +02001<?php
2/**
3 * CodeIgniter
4 *
Andrey Andreevfe9309d2015-01-09 17:48:58 +02005 * An open source application development framework for PHP
Andrey Andreev9a152a92014-02-18 16:29:53 +02006 *
Andrey Andreevbdb96ca2014-10-28 00:13:31 +02007 * This content is released under the MIT License (MIT)
Andrey Andreev9a152a92014-02-18 16:29:53 +02008 *
Andrey Andreevfe9309d2015-01-09 17:48:58 +02009 * Copyright (c) 2014 - 2015, British Columbia Institute of Technology
Andrey Andreev9a152a92014-02-18 16:29:53 +020010 *
Andrey Andreevbdb96ca2014-10-28 00:13:31 +020011 * Permission is hereby granted, free of charge, to any person obtaining a copy
12 * of this software and associated documentation files (the "Software"), to deal
13 * in the Software without restriction, including without limitation the rights
14 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
15 * copies of the Software, and to permit persons to whom the Software is
16 * furnished to do so, subject to the following conditions:
Andrey Andreev9a152a92014-02-18 16:29:53 +020017 *
Andrey Andreevbdb96ca2014-10-28 00:13:31 +020018 * The above copyright notice and this permission notice shall be included in
19 * all copies or substantial portions of the Software.
20 *
21 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
24 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
26 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
27 * THE SOFTWARE.
28 *
29 * @package CodeIgniter
30 * @author EllisLab Dev Team
Andrey Andreev9a152a92014-02-18 16:29:53 +020031 * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/)
Andrey Andreevfe9309d2015-01-09 17:48:58 +020032 * @copyright Copyright (c) 2014 - 2015, British Columbia Institute of Technology (http://bcit.ca/)
Andrey Andreevbdb96ca2014-10-28 00:13:31 +020033 * @license http://opensource.org/licenses/MIT MIT License
34 * @link http://codeigniter.com
35 * @since Version 3.0.0
Andrey Andreev9a152a92014-02-18 16:29:53 +020036 * @filesource
37 */
38defined('BASEPATH') OR exit('No direct script access allowed');
39
40/**
41 * PHP ext/hash compatibility package
42 *
43 * @package CodeIgniter
44 * @subpackage CodeIgniter
45 * @category Compatibility
46 * @author Andrey Andreev
47 * @link http://codeigniter.com/user_guide/
48 * @link http://php.net/hash
49 */
50
51// ------------------------------------------------------------------------
52
Andrey Andreeva5621b82014-05-09 11:23:08 +030053if (is_php('5.6'))
54{
55 return;
56}
57
58// ------------------------------------------------------------------------
59
60if ( ! function_exists('hash_equals'))
61{
62 /**
63 * hash_equals()
64 *
65 * @link http://php.net/hash_equals
66 * @param string $known_string
67 * @param string $user_string
68 * @return bool
69 */
70 function hash_equals($known_string, $user_string)
71 {
72 if ( ! is_string($known_string))
73 {
74 trigger_error('hash_equals(): Expected known_string to be a string, '.strtolower(gettype($known_string)).' given', E_USER_WARNING);
75 return FALSE;
76 }
77 elseif ( ! is_string($user_string))
78 {
79 trigger_error('hash_equals(): Expected user_string to be a string, '.strtolower(gettype($user_string)).' given', E_USER_WARNING);
80 return FALSE;
81 }
82 elseif (($length = strlen($known_string)) !== strlen($user_string))
83 {
84 return FALSE;
85 }
86
87 $diff = 0;
88 for ($i = 0; $i < $length; $i++)
89 {
90 $diff |= ord($known_string[$i]) ^ ord($user_string[$i]);
91 }
92
93 return ($diff === 0);
94 }
95}
96
97// ------------------------------------------------------------------------
98
Andrey Andreev9a152a92014-02-18 16:29:53 +020099if (is_php('5.5'))
100{
101 return;
102}
103
104// ------------------------------------------------------------------------
105
106if ( ! function_exists('hash_pbkdf2'))
107{
108 /**
109 * hash_pbkdf2()
110 *
111 * @link http://php.net/hash_pbkdf2
112 * @param string $algo
113 * @param string $password
114 * @param string $salt
115 * @param int $iterations
116 * @param int $length
117 * @param bool $raw_output
118 * @return string
119 */
120 function hash_pbkdf2($algo, $password, $salt, $iterations, $length = 0, $raw_output = FALSE)
121 {
122 if ( ! in_array($algo, hash_algos(), TRUE))
123 {
124 trigger_error('hash_pbkdf2(): Unknown hashing algorithm: '.$algo, E_USER_WARNING);
125 return FALSE;
126 }
127
128 if (($type = gettype($iterations)) !== 'integer')
129 {
130 if ($type === 'object' && method_exists($iterations, '__toString'))
131 {
132 $iterations = (string) $iterations;
133 }
134
135 if (is_string($iterations) && is_numeric($iterations))
136 {
137 $iterations = (int) $iterations;
138 }
139 else
140 {
141 trigger_error('hash_pbkdf2() expects parameter 4 to be long, '.$type.' given', E_USER_WARNING);
142 return NULL;
143 }
144 }
145
146 if ($iterations < 1)
147 {
148 trigger_error('hash_pbkdf2(): Iterations must be a positive integer: '.$iterations, E_USER_WARNING);
149 return FALSE;
150 }
151
152 if (($type = gettype($length)) !== 'integer')
153 {
154 if ($type === 'object' && method_exists($length, '__toString'))
155 {
156 $length = (string) $length;
157 }
158
159 if (is_string($length) && is_numeric($length))
160 {
161 $length = (int) $length;
162 }
163 else
164 {
165 trigger_error('hash_pbkdf2() expects parameter 5 to be long, '.$type.' given', E_USER_WARNING);
166 return NULL;
167 }
168 }
169
170 if ($length < 0)
171 {
172 trigger_error('hash_pbkdf2(): Length must be greater than or equal to 0: '.$length, E_USER_WARNING);
173 return FALSE;
174 }
175
176 $hash_length = strlen(hash($algo, NULL, TRUE));
177 if (empty($length))
178 {
179 $length = $hash_length;
180 }
181
182 $hash = '';
183 // Note: Blocks are NOT 0-indexed
184 for ($bc = ceil($length / $hash_length), $bi = 1; $bi <= $bc; $bi++)
185 {
186 $key = $derived_key = hash_hmac($algo, $salt.pack('N', $bi), $password, TRUE);
187 for ($i = 1; $i < $iterations; $i++)
188 {
189 $derived_key ^= $key = hash_hmac($algo, $key, $password, TRUE);
190 }
191
192 $hash .= $derived_key;
193 }
194
195 // This is not RFC-compatible, but we're aiming for natural PHP compatibility
196 return substr($raw_output ? $hash : bin2hex($hash), 0, $length);
197 }
198}
199
200/* End of file hash.php */
201/* Location: ./system/core/compat/hash.php */