2 /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=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.
11 * PHP versions 4 and 5
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.
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
25 * @link http://pear.php.net/package/Crypt_Blowfish
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";
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@
52 * P-Array contains 18 32-bit subkeys
61 * Array of four S-Blocks each containing 256 32-bit entries
77 * Initialization vector
86 * Crypt_Blowfish Constructor
87 * Initializes the Crypt_Blowfish object, and gives a sets
93 function Crypt_Blowfish($key)
96 if (extension_loaded('mcrypt')) {
97 $this->_td = mcrypt_module_open(MCRYPT_BLOWFISH, '', 'ecb', '');
98 $this->_iv = mcrypt_create_iv(8, MCRYPT_RAND);
105 * Deprecated isReady method
117 * Deprecated init method - init is now a private
118 * method and has been replaced with _init
123 * @see Crypt_Blowfish::_init()
131 * Initializes the Crypt_Blowfish object
137 $defaults = new Crypt_Blowfish_DefaultKey();
138 $this->_P = $defaults->P;
139 $this->_S = $defaults->S;
143 * Enciphers a single 64 bit block
149 function _encipher(&$Xl, &$Xr)
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;
159 $Xr = $Xl ^ $this->_P[16];
160 $Xl = $temp ^ $this->_P[17];
165 * Deciphers a single 64 bit block
171 function _decipher(&$Xl, &$Xr)
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;
181 $Xr = $Xl ^ $this->_P[1];
182 $Xl = $temp ^ $this->_P[0];
189 * @param string $plainText
190 * @return string Returns cipher text on success, PEAR_Error on failure
193 function encrypt($plainText)
195 if (!is_string($plainText)) {
196 $GLOBALS['log']->fatal('Plain text must be a string');
200 if (extension_loaded('mcrypt')) {
201 return mcrypt_generic($this->_td, $plainText);
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);
218 * Decrypts an encrypted string
220 * @param string $cipherText
221 * @return string Returns plain text on success, PEAR_Error on failure
224 function decrypt($cipherText)
226 if (!is_string($cipherText)) {
227 $GLOBALS['log']->fatal('Chiper text must be a string');
231 if (extension_loaded('mcrypt')) {
232 return mdecrypt_generic($this->_td, $cipherText);
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);
249 * Sets the secret key
250 * The key must be non-zero, and less than or equal to
251 * 56 characters in length.
254 * @return bool Returns true on success, PEAR_Error on failure
257 function setKey($key)
259 if (!is_string($key)) {
260 $GLOBALS['log']->fatal('Key must be a string');
265 if ($len > 56 || $len == 0) {
266 $GLOBALS['log']->fatal('Key must be less than 56 characters and non-zero. Supplied key length: ' . $len);
270 if (extension_loaded('mcrypt')) {
271 mcrypt_generic_init($this->_td, $key, $this->_iv);
276 require_once 'include/Pear/Crypt_Blowfish/Blowfish/DefaultKey.php';
285 for ($i = 0; $i < 18; $i++) {
287 for ($j = 4; $j > 0; $j--) {
288 $data = $data << 8 | ord($key{$k});
291 $this->_P[$i] ^= $data;
294 for ($i = 0; $i <= 16; $i += 2) {
295 $this->_encipher($datal, $datar);
296 $this->_P[$i] = $datal;
297 $this->_P[$i+1] = $datar;
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;
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;
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;
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;