blob: a9f59f110644f51bf19ad5a9ef261afffd1e3a5d [file] [log] [blame]
Andrey Andreev9a152a92014-02-18 16:29:53 +02001<?php
2/**
3 * CodeIgniter
4 *
5 * An open source application development framework for PHP 5.2.4 or newer
6 *
7 * NOTICE OF LICENSE
8 *
9 * Licensed under the Open Software License version 3.0
10 *
11 * This source file is subject to the Open Software License (OSL 3.0) that is
12 * bundled with this package in the files license.txt / license.rst. It is
13 * also available through the world wide web at this URL:
14 * http://opensource.org/licenses/OSL-3.0
15 * If you did not receive a copy of the license and are unable to obtain it
16 * through the world wide web, please send an email to
17 * licensing@ellislab.com so we can send you a copy immediately.
18 *
19 * @package CodeIgniter
20 * @author EllisLab Dev Team
21 * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/)
22 * @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
23 * @link http://codeigniter.com
24 * @since Version 3.0
25 * @filesource
26 */
27defined('BASEPATH') OR exit('No direct script access allowed');
28
29/**
30 * PHP ext/hash compatibility package
31 *
32 * @package CodeIgniter
33 * @subpackage CodeIgniter
34 * @category Compatibility
35 * @author Andrey Andreev
36 * @link http://codeigniter.com/user_guide/
37 * @link http://php.net/hash
38 */
39
40// ------------------------------------------------------------------------
41
42if (is_php('5.5'))
43{
44 return;
45}
46
47// ------------------------------------------------------------------------
48
49if ( ! function_exists('hash_pbkdf2'))
50{
51 /**
52 * hash_pbkdf2()
53 *
54 * @link http://php.net/hash_pbkdf2
55 * @param string $algo
56 * @param string $password
57 * @param string $salt
58 * @param int $iterations
59 * @param int $length
60 * @param bool $raw_output
61 * @return string
62 */
63 function hash_pbkdf2($algo, $password, $salt, $iterations, $length = 0, $raw_output = FALSE)
64 {
65 if ( ! in_array($algo, hash_algos(), TRUE))
66 {
67 trigger_error('hash_pbkdf2(): Unknown hashing algorithm: '.$algo, E_USER_WARNING);
68 return FALSE;
69 }
70
71 if (($type = gettype($iterations)) !== 'integer')
72 {
73 if ($type === 'object' && method_exists($iterations, '__toString'))
74 {
75 $iterations = (string) $iterations;
76 }
77
78 if (is_string($iterations) && is_numeric($iterations))
79 {
80 $iterations = (int) $iterations;
81 }
82 else
83 {
84 trigger_error('hash_pbkdf2() expects parameter 4 to be long, '.$type.' given', E_USER_WARNING);
85 return NULL;
86 }
87 }
88
89 if ($iterations < 1)
90 {
91 trigger_error('hash_pbkdf2(): Iterations must be a positive integer: '.$iterations, E_USER_WARNING);
92 return FALSE;
93 }
94
95 if (($type = gettype($length)) !== 'integer')
96 {
97 if ($type === 'object' && method_exists($length, '__toString'))
98 {
99 $length = (string) $length;
100 }
101
102 if (is_string($length) && is_numeric($length))
103 {
104 $length = (int) $length;
105 }
106 else
107 {
108 trigger_error('hash_pbkdf2() expects parameter 5 to be long, '.$type.' given', E_USER_WARNING);
109 return NULL;
110 }
111 }
112
113 if ($length < 0)
114 {
115 trigger_error('hash_pbkdf2(): Length must be greater than or equal to 0: '.$length, E_USER_WARNING);
116 return FALSE;
117 }
118
119 $hash_length = strlen(hash($algo, NULL, TRUE));
120 if (empty($length))
121 {
122 $length = $hash_length;
123 }
124
125 $hash = '';
126 // Note: Blocks are NOT 0-indexed
127 for ($bc = ceil($length / $hash_length), $bi = 1; $bi <= $bc; $bi++)
128 {
129 $key = $derived_key = hash_hmac($algo, $salt.pack('N', $bi), $password, TRUE);
130 for ($i = 1; $i < $iterations; $i++)
131 {
132 $derived_key ^= $key = hash_hmac($algo, $key, $password, TRUE);
133 }
134
135 $hash .= $derived_key;
136 }
137
138 // This is not RFC-compatible, but we're aiming for natural PHP compatibility
139 return substr($raw_output ? $hash : bin2hex($hash), 0, $length);
140 }
141}
142
143/* End of file hash.php */
144/* Location: ./system/core/compat/hash.php */