]> CyberLeo.Net >> Repos - Github/sugarcrm.git/blob - include/Pear/Crypt_Blowfish/Blowfish.php
Release 6.5.0
[Github/sugarcrm.git] / include / Pear / Crypt_Blowfish / Blowfish.php
1 <?php
2 /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
3
4 /**
5  * Crypt_Blowfish allows for encryption and decryption on the fly using
6  * the Blowfish algorithm. Crypt_Blowfish does not require the mcrypt
7  * PHP extension, it uses only PHP.
8  * Crypt_Blowfish support encryption/decryption with or without a secret key.
9  *
10  *
11  * PHP versions 4 and 5
12  *
13  * LICENSE: This source file is subject to version 3.0 of the PHP license
14  * that is available through the world-wide-web at the following URI:
15  * http://www.php.net/license/3_0.txt.  If you did not receive a copy of
16  * the PHP License and are unable to obtain it through the web, please
17  * send a note to license@php.net so we can mail you a copy immediately.
18  *
19  * @category   Encryption
20  * @package    Crypt_Blowfish
21  * @author     Matthew Fonda <mfonda@php.net>
22  * @copyright  2005 Matthew Fonda
23  * @license    http://www.php.net/license/3_0.txt  PHP License 3.0
24
25  * @link       http://pear.php.net/package/Crypt_Blowfish
26  */
27
28
29
30
31 /**
32  *
33  * Example usage:
34  * $bf = new Crypt_Blowfish('some secret key!');
35  * $encrypted = $bf->encrypt('this is some example plain text');
36  * $plaintext = $bf->decrypt($encrypted);
37  * echo "plain text: $plaintext";
38  *
39  *
40  * @category   Encryption
41  * @package    Crypt_Blowfish
42  * @author     Matthew Fonda <mfonda@php.net>
43  * @copyright  2005 Matthew Fonda
44  * @license    http://www.php.net/license/3_0.txt  PHP License 3.0
45  * @link       http://pear.php.net/package/Crypt_Blowfish
46  * @version    @package_version@
47  * @access     public
48  */
49 class Crypt_Blowfish
50 {
51     /**
52      * P-Array contains 18 32-bit subkeys
53      *
54      * @var array
55      * @access private
56      */
57     var $_P = array();
58     
59     
60     /**
61      * Array of four S-Blocks each containing 256 32-bit entries
62      *
63      * @var array
64      * @access private
65      */
66     var $_S = array();
67
68     /**
69      * Mcrypt td resource
70      *
71      * @var resource
72      * @access private
73      */
74     var $_td = null;
75
76     /**
77      * Initialization vector
78      *
79      * @var string
80      * @access private
81      */
82     var $_iv = null;
83
84     
85     /**
86      * Crypt_Blowfish Constructor
87      * Initializes the Crypt_Blowfish object, and gives a sets
88      * the secret key
89      *
90      * @param string $key
91      * @access public
92      */
93     function Crypt_Blowfish($key)
94     {
95                 /*
96         if (extension_loaded('mcrypt')) {
97             $this->_td = mcrypt_module_open(MCRYPT_BLOWFISH, '', 'ecb', '');
98             $this->_iv = mcrypt_create_iv(8, MCRYPT_RAND);
99         }
100         */
101         $this->setKey($key);
102     }
103     
104     /**
105      * Deprecated isReady method
106      *
107      * @return bool
108      * @access public
109      * @deprecated
110      */
111     function isReady()
112     {
113         return true;
114     }
115     
116     /**
117      * Deprecated init method - init is now a private
118      * method and has been replaced with _init
119      *
120      * @return bool
121      * @access public
122      * @deprecated
123      * @see Crypt_Blowfish::_init()
124      */
125     function init()
126     {
127         $this->_init();
128     }
129     
130     /**
131      * Initializes the Crypt_Blowfish object
132      *
133      * @access private
134      */
135     function _init()
136     {
137         $defaults = new Crypt_Blowfish_DefaultKey();
138         $this->_P = $defaults->P;
139         $this->_S = $defaults->S;
140     }
141             
142     /**
143      * Enciphers a single 64 bit block
144      *
145      * @param int &$Xl
146      * @param int &$Xr
147      * @access private
148      */
149     function _encipher(&$Xl, &$Xr)
150     {
151         for ($i = 0; $i < 16; $i++) {
152             $temp = $Xl ^ $this->_P[$i];
153             $Xl = ((($this->_S[0][($temp>>24) & 255] +
154                             $this->_S[1][($temp>>16) & 255]) ^
155                             $this->_S[2][($temp>>8) & 255]) +
156                             $this->_S[3][$temp & 255]) ^ $Xr;
157             $Xr = $temp;
158         }
159         $Xr = $Xl ^ $this->_P[16];
160         $Xl = $temp ^ $this->_P[17];
161     }
162     
163     
164     /**
165      * Deciphers a single 64 bit block
166      *
167      * @param int &$Xl
168      * @param int &$Xr
169      * @access private
170      */
171     function _decipher(&$Xl, &$Xr)
172     {
173         for ($i = 17; $i > 1; $i--) {
174             $temp = $Xl ^ $this->_P[$i];
175             $Xl = ((($this->_S[0][($temp>>24) & 255] +
176                             $this->_S[1][($temp>>16) & 255]) ^
177                             $this->_S[2][($temp>>8) & 255]) +
178                             $this->_S[3][$temp & 255]) ^ $Xr;
179             $Xr = $temp;
180         }
181         $Xr = $Xl ^ $this->_P[1];
182         $Xl = $temp ^ $this->_P[0];
183     }
184     
185     
186     /**
187      * Encrypts a string
188      *
189      * @param string $plainText
190      * @return string Returns cipher text on success, PEAR_Error on failure
191      * @access public
192      */
193     function encrypt($plainText)
194     {
195         if (!is_string($plainText)) {
196             $GLOBALS['log']->fatal('Plain text must be a string');
197         }
198
199                 /*
200         if (extension_loaded('mcrypt')) {
201             return mcrypt_generic($this->_td, $plainText);
202         }
203         */
204
205         $cipherText = '';
206         $len = strlen($plainText);
207         $plainText .= str_repeat(chr(0),(8 - ($len%8))%8);
208         for ($i = 0; $i < $len; $i += 8) {
209             list(,$Xl,$Xr) = unpack("N2",substr($plainText,$i,8));
210             $this->_encipher($Xl, $Xr);
211             $cipherText .= pack("N2", $Xl, $Xr);
212         }
213         return $cipherText;
214     }
215     
216     
217     /**
218      * Decrypts an encrypted string
219      *
220      * @param string $cipherText
221      * @return string Returns plain text on success, PEAR_Error on failure
222      * @access public
223      */
224     function decrypt($cipherText)
225     {
226         if (!is_string($cipherText)) {
227             $GLOBALS['log']->fatal('Chiper text must be a string');
228         }
229
230                 /*
231         if (extension_loaded('mcrypt')) {
232             return mdecrypt_generic($this->_td, $cipherText);
233         }
234         */
235
236         $plainText = '';
237         $len = strlen($cipherText);
238         $cipherText .= str_repeat(chr(0),(8 - ($len%8))%8);
239         for ($i = 0; $i < $len; $i += 8) {
240             list(,$Xl,$Xr) = unpack("N2",substr($cipherText,$i,8));
241             $this->_decipher($Xl, $Xr);
242             $plainText .= pack("N2", $Xl, $Xr);
243         }
244         return $plainText;
245     }
246     
247     
248     /**
249      * Sets the secret key
250      * The key must be non-zero, and less than or equal to
251      * 56 characters in length.
252      *
253      * @param string $key
254      * @return bool  Returns true on success, PEAR_Error on failure
255      * @access public
256      */
257     function setKey($key)
258     {
259         if (!is_string($key)) {
260             $GLOBALS['log']->fatal('Key must be a string');
261         }
262
263         $len = strlen($key);
264
265         if ($len > 56 || $len == 0) {
266             $GLOBALS['log']->fatal('Key must be less than 56 characters and non-zero. Supplied key length: ' . $len);
267         }
268
269                 /*
270         if (extension_loaded('mcrypt')) {
271             mcrypt_generic_init($this->_td, $key, $this->_iv);
272             return true;
273         }
274         */
275
276         require_once 'include/Pear/Crypt_Blowfish/Blowfish/DefaultKey.php';
277
278         $this->_init();
279         
280         $k = 0;
281         $data = 0;
282         $datal = 0;
283         $datar = 0;
284         
285         for ($i = 0; $i < 18; $i++) {
286             $data = 0;
287             for ($j = 4; $j > 0; $j--) {
288                     $data = $data << 8 | ord($key{$k});
289                     $k = ($k+1) % $len;
290             }
291             $this->_P[$i] ^= $data;
292         }
293         
294         for ($i = 0; $i <= 16; $i += 2) {
295             $this->_encipher($datal, $datar);
296             $this->_P[$i] = $datal;
297             $this->_P[$i+1] = $datar;
298         }
299         for ($i = 0; $i < 256; $i += 2) {
300             $this->_encipher($datal, $datar);
301             $this->_S[0][$i] = $datal;
302             $this->_S[0][$i+1] = $datar;
303         }
304         for ($i = 0; $i < 256; $i += 2) {
305             $this->_encipher($datal, $datar);
306             $this->_S[1][$i] = $datal;
307             $this->_S[1][$i+1] = $datar;
308         }
309         for ($i = 0; $i < 256; $i += 2) {
310             $this->_encipher($datal, $datar);
311             $this->_S[2][$i] = $datal;
312             $this->_S[2][$i+1] = $datar;
313         }
314         for ($i = 0; $i < 256; $i += 2) {
315             $this->_encipher($datal, $datar);
316             $this->_S[3][$i] = $datal;
317             $this->_S[3][$i+1] = $datar;
318         }
319         
320         return true;
321     }
322     
323 }
324
325 ?>