2 /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
\r
5 * Pure-PHP implementation of Blowfish.
\r
7 * Uses mcrypt, if available, and an internal implementation, otherwise.
\r
9 * PHP versions 4 and 5
\r
11 * Useful resources are as follows:
\r
13 * - {@link http://en.wikipedia.org/wiki/Blowfish Wikipedia description of Blowfish}
\r
15 * Here's a short example of how to use this library:
\r
18 * include('Crypt/Blowfish.php');
\r
20 * $blowfish = new Crypt_Blowfish();
\r
22 * $blowfish->setKey('12345678901234567890123456789012');
\r
24 * $plaintext = str_repeat('a', 1024);
\r
26 * echo $blowfish->decrypt($blowfish->encrypt($plaintext));
\r
30 * LICENSE: Permission is hereby granted, free of charge, to any person obtaining a copy
\r
31 * of this software and associated documentation files (the "Software"), to deal
\r
32 * in the Software without restriction, including without limitation the rights
\r
33 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
\r
34 * copies of the Software, and to permit persons to whom the Software is
\r
35 * furnished to do so, subject to the following conditions:
\r
37 * The above copyright notice and this permission notice shall be included in
\r
38 * all copies or substantial portions of the Software.
\r
40 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
\r
41 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
\r
42 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
\r
43 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
\r
44 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
\r
45 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
\r
49 * @package Crypt_Blowfish
\r
50 * @author Jim Wigginton <terrafrost@php.net>
\r
51 * @author Hans-Juergen Petrich <petrich@tronic-media.com>
\r
52 * @copyright MMVII Jim Wigginton
\r
53 * @license http://www.opensource.org/licenses/mit-license.html MIT License
\r
55 * @link http://phpseclib.sourceforge.net
\r
60 * @see Crypt_Blowfish::encrypt()
\r
61 * @see Crypt_Blowfish::decrypt()
\r
64 * Encrypt / decrypt using the Counter mode.
\r
66 * Set to -1 since that's what Crypt/Random.php uses to index the CTR mode.
\r
68 * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Counter_.28CTR.29
\r
70 define('CRYPT_BLOWFISH_MODE_CTR', -1);
\r
72 * Encrypt / decrypt using the Electronic Code Book mode.
\r
74 * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Electronic_codebook_.28ECB.29
\r
76 define('CRYPT_BLOWFISH_MODE_ECB', 1);
\r
78 * Encrypt / decrypt using the Code Book Chaining mode.
\r
80 * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Cipher-block_chaining_.28CBC.29
\r
82 define('CRYPT_BLOWFISH_MODE_CBC', 2);
\r
84 * Encrypt / decrypt using the Cipher Feedback mode.
\r
86 * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Cipher_feedback_.28CFB.29
\r
88 define('CRYPT_BLOWFISH_MODE_CFB', 3);
\r
90 * Encrypt / decrypt using the Cipher Feedback mode.
\r
92 * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Output_feedback_.28OFB.29
\r
94 define('CRYPT_BLOWFISH_MODE_OFB', 4);
\r
99 * @see Crypt_Blowfish::Crypt_Blowfish()
\r
102 * Toggles the internal implementation
\r
104 define('CRYPT_BLOWFISH_MODE_INTERNAL', 1);
\r
106 * Toggles the mcrypt implementation
\r
108 define('CRYPT_BLOWFISH_MODE_MCRYPT', 2);
\r
112 * Pure-PHP implementation of Blowfish.
\r
114 * @author Jim Wigginton <terrafrost@php.net>
\r
115 * @author Hans-Juergen Petrich <petrich@tronic-media.com>
\r
118 * @package Crypt_Blowfish
\r
120 class Crypt_Blowfish {
\r
122 * The Key as String
\r
124 * @see Crypt_Blowfish::setKey()
\r
128 var $key = "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0";
\r
131 * The Encryption Mode
\r
133 * @see Crypt_Blowfish::Crypt_Blowfish()
\r
140 * Continuous Buffer status
\r
142 * @see Crypt_Blowfish::enableContinuousBuffer()
\r
146 var $continuousBuffer = false;
\r
151 * @see Crypt_Blowfish::enablePadding()
\r
155 var $padding = true;
\r
158 * The Initialization Vector
\r
160 * @see Crypt_Blowfish::setIV()
\r
164 var $iv = "\0\0\0\0\0\0\0\0";
\r
167 * A "sliding" Initialization Vector
\r
169 * @see Crypt_Blowfish::enableContinuousBuffer()
\r
173 var $encryptIV = "\0\0\0\0\0\0\0\0";
\r
176 * A "sliding" Initialization Vector
\r
178 * @see Crypt_Blowfish::enableContinuousBuffer()
\r
182 var $decryptIV = "\0\0\0\0\0\0\0\0";
\r
185 * mcrypt resource for encryption
\r
187 * The mcrypt resource can be recreated every time something needs to be created or it can be created just once.
\r
188 * Since mcrypt operates in continuous mode, by default, it'll need to be recreated when in non-continuous mode.
\r
190 * @see Crypt_Blowfish::encrypt()
\r
197 * mcrypt resource for decryption
\r
199 * The mcrypt resource can be recreated every time something needs to be created or it can be created just once.
\r
200 * Since mcrypt operates in continuous mode, by default, it'll need to be recreated when in non-continuous mode.
\r
202 * @see Crypt_Blowfish::decrypt()
\r
209 * Does the enmcrypt resource need to be (re)initialized?
\r
211 * @see Crypt_Blowfish::setKey()
\r
212 * @see Crypt_Blowfish::setIV()
\r
216 var $enchanged = true;
\r
219 * Does the demcrypt resource need to be (re)initialized?
\r
221 * @see Crypt_Blowfish::setKey()
\r
222 * @see Crypt_Blowfish::setIV()
\r
226 var $dechanged = true;
\r
229 * Is the mode one that is paddable?
\r
231 * @see Crypt_Blowfish::Crypt_Blowfish()
\r
235 var $paddable = false;
\r
238 * Encryption buffer for CTR, OFB and CFB modes
\r
240 * @see Crypt_Blowfish::encrypt()
\r
244 var $enbuffer = array('encrypted' => '', 'xor' => '', 'pos' => 0, 'enmcrypt_init' => true);
\r
247 * Decryption buffer for CTR, OFB and CFB modes
\r
249 * @see Crypt_Blowfish::decrypt()
\r
253 var $debuffer = array('ciphertext' => '', 'xor' => '', 'pos' => 0, 'demcrypt_init' => true);
\r
256 * mcrypt resource for CFB mode
\r
258 * @see Crypt_Blowfish::encrypt()
\r
259 * @see Crypt_Blowfish::decrypt()
\r
266 * Performance-optimized callback function for en/decrypt()
\r
274 * The fixed subkeys boxes ($sbox0 - $sbox3) with 256 entries each
\r
281 var $sbox0 = array (
\r
282 0xd1310ba6, 0x98dfb5ac, 0x2ffd72db, 0xd01adfb7, 0xb8e1afed, 0x6a267e96, 0xba7c9045, 0xf12c7f99,
\r
283 0x24a19947, 0xb3916cf7, 0x0801f2e2, 0x858efc16, 0x636920d8, 0x71574e69, 0xa458fea3, 0xf4933d7e,
\r
284 0x0d95748f, 0x728eb658, 0x718bcd58, 0x82154aee, 0x7b54a41d, 0xc25a59b5, 0x9c30d539, 0x2af26013,
\r
285 0xc5d1b023, 0x286085f0, 0xca417918, 0xb8db38ef, 0x8e79dcb0, 0x603a180e, 0x6c9e0e8b, 0xb01e8a3e,
\r
286 0xd71577c1, 0xbd314b27, 0x78af2fda, 0x55605c60, 0xe65525f3, 0xaa55ab94, 0x57489862, 0x63e81440,
\r
287 0x55ca396a, 0x2aab10b6, 0xb4cc5c34, 0x1141e8ce, 0xa15486af, 0x7c72e993, 0xb3ee1411, 0x636fbc2a,
\r
288 0x2ba9c55d, 0x741831f6, 0xce5c3e16, 0x9b87931e, 0xafd6ba33, 0x6c24cf5c, 0x7a325381, 0x28958677,
\r
289 0x3b8f4898, 0x6b4bb9af, 0xc4bfe81b, 0x66282193, 0x61d809cc, 0xfb21a991, 0x487cac60, 0x5dec8032,
\r
290 0xef845d5d, 0xe98575b1, 0xdc262302, 0xeb651b88, 0x23893e81, 0xd396acc5, 0x0f6d6ff3, 0x83f44239,
\r
291 0x2e0b4482, 0xa4842004, 0x69c8f04a, 0x9e1f9b5e, 0x21c66842, 0xf6e96c9a, 0x670c9c61, 0xabd388f0,
\r
292 0x6a51a0d2, 0xd8542f68, 0x960fa728, 0xab5133a3, 0x6eef0b6c, 0x137a3be4, 0xba3bf050, 0x7efb2a98,
\r
293 0xa1f1651d, 0x39af0176, 0x66ca593e, 0x82430e88, 0x8cee8619, 0x456f9fb4, 0x7d84a5c3, 0x3b8b5ebe,
\r
294 0xe06f75d8, 0x85c12073, 0x401a449f, 0x56c16aa6, 0x4ed3aa62, 0x363f7706, 0x1bfedf72, 0x429b023d,
\r
295 0x37d0d724, 0xd00a1248, 0xdb0fead3, 0x49f1c09b, 0x075372c9, 0x80991b7b, 0x25d479d8, 0xf6e8def7,
\r
296 0xe3fe501a, 0xb6794c3b, 0x976ce0bd, 0x04c006ba, 0xc1a94fb6, 0x409f60c4, 0x5e5c9ec2, 0x196a2463,
\r
297 0x68fb6faf, 0x3e6c53b5, 0x1339b2eb, 0x3b52ec6f, 0x6dfc511f, 0x9b30952c, 0xcc814544, 0xaf5ebd09,
\r
298 0xbee3d004, 0xde334afd, 0x660f2807, 0x192e4bb3, 0xc0cba857, 0x45c8740f, 0xd20b5f39, 0xb9d3fbdb,
\r
299 0x5579c0bd, 0x1a60320a, 0xd6a100c6, 0x402c7279, 0x679f25fe, 0xfb1fa3cc, 0x8ea5e9f8, 0xdb3222f8,
\r
300 0x3c7516df, 0xfd616b15, 0x2f501ec8, 0xad0552ab, 0x323db5fa, 0xfd238760, 0x53317b48, 0x3e00df82,
\r
301 0x9e5c57bb, 0xca6f8ca0, 0x1a87562e, 0xdf1769db, 0xd542a8f6, 0x287effc3, 0xac6732c6, 0x8c4f5573,
\r
302 0x695b27b0, 0xbbca58c8, 0xe1ffa35d, 0xb8f011a0, 0x10fa3d98, 0xfd2183b8, 0x4afcb56c, 0x2dd1d35b,
\r
303 0x9a53e479, 0xb6f84565, 0xd28e49bc, 0x4bfb9790, 0xe1ddf2da, 0xa4cb7e33, 0x62fb1341, 0xcee4c6e8,
\r
304 0xef20cada, 0x36774c01, 0xd07e9efe, 0x2bf11fb4, 0x95dbda4d, 0xae909198, 0xeaad8e71, 0x6b93d5a0,
\r
305 0xd08ed1d0, 0xafc725e0, 0x8e3c5b2f, 0x8e7594b7, 0x8ff6e2fb, 0xf2122b64, 0x8888b812, 0x900df01c,
\r
306 0x4fad5ea0, 0x688fc31c, 0xd1cff191, 0xb3a8c1ad, 0x2f2f2218, 0xbe0e1777, 0xea752dfe, 0x8b021fa1,
\r
307 0xe5a0cc0f, 0xb56f74e8, 0x18acf3d6, 0xce89e299, 0xb4a84fe0, 0xfd13e0b7, 0x7cc43b81, 0xd2ada8d9,
\r
308 0x165fa266, 0x80957705, 0x93cc7314, 0x211a1477, 0xe6ad2065, 0x77b5fa86, 0xc75442f5, 0xfb9d35cf,
\r
309 0xebcdaf0c, 0x7b3e89a0, 0xd6411bd3, 0xae1e7e49, 0x00250e2d, 0x2071b35e, 0x226800bb, 0x57b8e0af,
\r
310 0x2464369b, 0xf009b91e, 0x5563911d, 0x59dfa6aa, 0x78c14389, 0xd95a537f, 0x207d5ba2, 0x02e5b9c5,
\r
311 0x83260376, 0x6295cfa9, 0x11c81968, 0x4e734a41, 0xb3472dca, 0x7b14a94a, 0x1b510052, 0x9a532915,
\r
312 0xd60f573f, 0xbc9bc6e4, 0x2b60a476, 0x81e67400, 0x08ba6fb5, 0x571be91f, 0xf296ec6b, 0x2a0dd915,
\r
313 0xb6636521, 0xe7b9f9b6, 0xff34052e, 0xc5855664, 0x53b02d5d, 0xa99f8fa1, 0x08ba4799, 0x6e85076a
\r
322 var $sbox1 = array(
\r
323 0x4b7a70e9, 0xb5b32944, 0xdb75092e, 0xc4192623, 0xad6ea6b0, 0x49a7df7d, 0x9cee60b8, 0x8fedb266,
\r
324 0xecaa8c71, 0x699a17ff, 0x5664526c, 0xc2b19ee1, 0x193602a5, 0x75094c29, 0xa0591340, 0xe4183a3e,
\r
325 0x3f54989a, 0x5b429d65, 0x6b8fe4d6, 0x99f73fd6, 0xa1d29c07, 0xefe830f5, 0x4d2d38e6, 0xf0255dc1,
\r
326 0x4cdd2086, 0x8470eb26, 0x6382e9c6, 0x021ecc5e, 0x09686b3f, 0x3ebaefc9, 0x3c971814, 0x6b6a70a1,
\r
327 0x687f3584, 0x52a0e286, 0xb79c5305, 0xaa500737, 0x3e07841c, 0x7fdeae5c, 0x8e7d44ec, 0x5716f2b8,
\r
328 0xb03ada37, 0xf0500c0d, 0xf01c1f04, 0x0200b3ff, 0xae0cf51a, 0x3cb574b2, 0x25837a58, 0xdc0921bd,
\r
329 0xd19113f9, 0x7ca92ff6, 0x94324773, 0x22f54701, 0x3ae5e581, 0x37c2dadc, 0xc8b57634, 0x9af3dda7,
\r
330 0xa9446146, 0x0fd0030e, 0xecc8c73e, 0xa4751e41, 0xe238cd99, 0x3bea0e2f, 0x3280bba1, 0x183eb331,
\r
331 0x4e548b38, 0x4f6db908, 0x6f420d03, 0xf60a04bf, 0x2cb81290, 0x24977c79, 0x5679b072, 0xbcaf89af,
\r
332 0xde9a771f, 0xd9930810, 0xb38bae12, 0xdccf3f2e, 0x5512721f, 0x2e6b7124, 0x501adde6, 0x9f84cd87,
\r
333 0x7a584718, 0x7408da17, 0xbc9f9abc, 0xe94b7d8c, 0xec7aec3a, 0xdb851dfa, 0x63094366, 0xc464c3d2,
\r
334 0xef1c1847, 0x3215d908, 0xdd433b37, 0x24c2ba16, 0x12a14d43, 0x2a65c451, 0x50940002, 0x133ae4dd,
\r
335 0x71dff89e, 0x10314e55, 0x81ac77d6, 0x5f11199b, 0x043556f1, 0xd7a3c76b, 0x3c11183b, 0x5924a509,
\r
336 0xf28fe6ed, 0x97f1fbfa, 0x9ebabf2c, 0x1e153c6e, 0x86e34570, 0xeae96fb1, 0x860e5e0a, 0x5a3e2ab3,
\r
337 0x771fe71c, 0x4e3d06fa, 0x2965dcb9, 0x99e71d0f, 0x803e89d6, 0x5266c825, 0x2e4cc978, 0x9c10b36a,
\r
338 0xc6150eba, 0x94e2ea78, 0xa5fc3c53, 0x1e0a2df4, 0xf2f74ea7, 0x361d2b3d, 0x1939260f, 0x19c27960,
\r
339 0x5223a708, 0xf71312b6, 0xebadfe6e, 0xeac31f66, 0xe3bc4595, 0xa67bc883, 0xb17f37d1, 0x018cff28,
\r
340 0xc332ddef, 0xbe6c5aa5, 0x65582185, 0x68ab9802, 0xeecea50f, 0xdb2f953b, 0x2aef7dad, 0x5b6e2f84,
\r
341 0x1521b628, 0x29076170, 0xecdd4775, 0x619f1510, 0x13cca830, 0xeb61bd96, 0x0334fe1e, 0xaa0363cf,
\r
342 0xb5735c90, 0x4c70a239, 0xd59e9e0b, 0xcbaade14, 0xeecc86bc, 0x60622ca7, 0x9cab5cab, 0xb2f3846e,
\r
343 0x648b1eaf, 0x19bdf0ca, 0xa02369b9, 0x655abb50, 0x40685a32, 0x3c2ab4b3, 0x319ee9d5, 0xc021b8f7,
\r
344 0x9b540b19, 0x875fa099, 0x95f7997e, 0x623d7da8, 0xf837889a, 0x97e32d77, 0x11ed935f, 0x16681281,
\r
345 0x0e358829, 0xc7e61fd6, 0x96dedfa1, 0x7858ba99, 0x57f584a5, 0x1b227263, 0x9b83c3ff, 0x1ac24696,
\r
346 0xcdb30aeb, 0x532e3054, 0x8fd948e4, 0x6dbc3128, 0x58ebf2ef, 0x34c6ffea, 0xfe28ed61, 0xee7c3c73,
\r
347 0x5d4a14d9, 0xe864b7e3, 0x42105d14, 0x203e13e0, 0x45eee2b6, 0xa3aaabea, 0xdb6c4f15, 0xfacb4fd0,
\r
348 0xc742f442, 0xef6abbb5, 0x654f3b1d, 0x41cd2105, 0xd81e799e, 0x86854dc7, 0xe44b476a, 0x3d816250,
\r
349 0xcf62a1f2, 0x5b8d2646, 0xfc8883a0, 0xc1c7b6a3, 0x7f1524c3, 0x69cb7492, 0x47848a0b, 0x5692b285,
\r
350 0x095bbf00, 0xad19489d, 0x1462b174, 0x23820e00, 0x58428d2a, 0x0c55f5ea, 0x1dadf43e, 0x233f7061,
\r
351 0x3372f092, 0x8d937e41, 0xd65fecf1, 0x6c223bdb, 0x7cde3759, 0xcbee7460, 0x4085f2a7, 0xce77326e,
\r
352 0xa6078084, 0x19f8509e, 0xe8efd855, 0x61d99735, 0xa969a7aa, 0xc50c06c2, 0x5a04abfc, 0x800bcadc,
\r
353 0x9e447a2e, 0xc3453484, 0xfdd56705, 0x0e1e9ec9, 0xdb73dbd3, 0x105588cd, 0x675fda79, 0xe3674340,
\r
354 0xc5c43465, 0x713e38d8, 0x3d28f89e, 0xf16dff20, 0x153e21e7, 0x8fb03d4a, 0xe6e39f2b, 0xdb83adf7
\r
363 var $sbox2 = array(
\r
364 0xe93d5a68, 0x948140f7, 0xf64c261c, 0x94692934, 0x411520f7, 0x7602d4f7, 0xbcf46b2e, 0xd4a20068,
\r
365 0xd4082471, 0x3320f46a, 0x43b7d4b7, 0x500061af, 0x1e39f62e, 0x97244546, 0x14214f74, 0xbf8b8840,
\r
366 0x4d95fc1d, 0x96b591af, 0x70f4ddd3, 0x66a02f45, 0xbfbc09ec, 0x03bd9785, 0x7fac6dd0, 0x31cb8504,
\r
367 0x96eb27b3, 0x55fd3941, 0xda2547e6, 0xabca0a9a, 0x28507825, 0x530429f4, 0x0a2c86da, 0xe9b66dfb,
\r
368 0x68dc1462, 0xd7486900, 0x680ec0a4, 0x27a18dee, 0x4f3ffea2, 0xe887ad8c, 0xb58ce006, 0x7af4d6b6,
\r
369 0xaace1e7c, 0xd3375fec, 0xce78a399, 0x406b2a42, 0x20fe9e35, 0xd9f385b9, 0xee39d7ab, 0x3b124e8b,
\r
370 0x1dc9faf7, 0x4b6d1856, 0x26a36631, 0xeae397b2, 0x3a6efa74, 0xdd5b4332, 0x6841e7f7, 0xca7820fb,
\r
371 0xfb0af54e, 0xd8feb397, 0x454056ac, 0xba489527, 0x55533a3a, 0x20838d87, 0xfe6ba9b7, 0xd096954b,
\r
372 0x55a867bc, 0xa1159a58, 0xcca92963, 0x99e1db33, 0xa62a4a56, 0x3f3125f9, 0x5ef47e1c, 0x9029317c,
\r
373 0xfdf8e802, 0x04272f70, 0x80bb155c, 0x05282ce3, 0x95c11548, 0xe4c66d22, 0x48c1133f, 0xc70f86dc,
\r
374 0x07f9c9ee, 0x41041f0f, 0x404779a4, 0x5d886e17, 0x325f51eb, 0xd59bc0d1, 0xf2bcc18f, 0x41113564,
\r
375 0x257b7834, 0x602a9c60, 0xdff8e8a3, 0x1f636c1b, 0x0e12b4c2, 0x02e1329e, 0xaf664fd1, 0xcad18115,
\r
376 0x6b2395e0, 0x333e92e1, 0x3b240b62, 0xeebeb922, 0x85b2a20e, 0xe6ba0d99, 0xde720c8c, 0x2da2f728,
\r
377 0xd0127845, 0x95b794fd, 0x647d0862, 0xe7ccf5f0, 0x5449a36f, 0x877d48fa, 0xc39dfd27, 0xf33e8d1e,
\r
378 0x0a476341, 0x992eff74, 0x3a6f6eab, 0xf4f8fd37, 0xa812dc60, 0xa1ebddf8, 0x991be14c, 0xdb6e6b0d,
\r
379 0xc67b5510, 0x6d672c37, 0x2765d43b, 0xdcd0e804, 0xf1290dc7, 0xcc00ffa3, 0xb5390f92, 0x690fed0b,
\r
380 0x667b9ffb, 0xcedb7d9c, 0xa091cf0b, 0xd9155ea3, 0xbb132f88, 0x515bad24, 0x7b9479bf, 0x763bd6eb,
\r
381 0x37392eb3, 0xcc115979, 0x8026e297, 0xf42e312d, 0x6842ada7, 0xc66a2b3b, 0x12754ccc, 0x782ef11c,
\r
382 0x6a124237, 0xb79251e7, 0x06a1bbe6, 0x4bfb6350, 0x1a6b1018, 0x11caedfa, 0x3d25bdd8, 0xe2e1c3c9,
\r
383 0x44421659, 0x0a121386, 0xd90cec6e, 0xd5abea2a, 0x64af674e, 0xda86a85f, 0xbebfe988, 0x64e4c3fe,
\r
384 0x9dbc8057, 0xf0f7c086, 0x60787bf8, 0x6003604d, 0xd1fd8346, 0xf6381fb0, 0x7745ae04, 0xd736fccc,
\r
385 0x83426b33, 0xf01eab71, 0xb0804187, 0x3c005e5f, 0x77a057be, 0xbde8ae24, 0x55464299, 0xbf582e61,
\r
386 0x4e58f48f, 0xf2ddfda2, 0xf474ef38, 0x8789bdc2, 0x5366f9c3, 0xc8b38e74, 0xb475f255, 0x46fcd9b9,
\r
387 0x7aeb2661, 0x8b1ddf84, 0x846a0e79, 0x915f95e2, 0x466e598e, 0x20b45770, 0x8cd55591, 0xc902de4c,
\r
388 0xb90bace1, 0xbb8205d0, 0x11a86248, 0x7574a99e, 0xb77f19b6, 0xe0a9dc09, 0x662d09a1, 0xc4324633,
\r
389 0xe85a1f02, 0x09f0be8c, 0x4a99a025, 0x1d6efe10, 0x1ab93d1d, 0x0ba5a4df, 0xa186f20f, 0x2868f169,
\r
390 0xdcb7da83, 0x573906fe, 0xa1e2ce9b, 0x4fcd7f52, 0x50115e01, 0xa70683fa, 0xa002b5c4, 0x0de6d027,
\r
391 0x9af88c27, 0x773f8641, 0xc3604c06, 0x61a806b5, 0xf0177a28, 0xc0f586e0, 0x006058aa, 0x30dc7d62,
\r
392 0x11e69ed7, 0x2338ea63, 0x53c2dd94, 0xc2c21634, 0xbbcbee56, 0x90bcb6de, 0xebfc7da1, 0xce591d76,
\r
393 0x6f05e409, 0x4b7c0188, 0x39720a3d, 0x7c927c24, 0x86e3725f, 0x724d9db9, 0x1ac15bb4, 0xd39eb8fc,
\r
394 0xed545578, 0x08fca5b5, 0xd83d7cd3, 0x4dad0fc4, 0x1e50ef5e, 0xb161e6f8, 0xa28514d9, 0x6c51133c,
\r
395 0x6fd5c7e7, 0x56e14ec4, 0x362abfce, 0xddc6c837, 0xd79a3234, 0x92638212, 0x670efa8e, 0x406000e0
\r
404 var $sbox3 = array(
\r
405 0x3a39ce37, 0xd3faf5cf, 0xabc27737, 0x5ac52d1b, 0x5cb0679e, 0x4fa33742, 0xd3822740, 0x99bc9bbe,
\r
406 0xd5118e9d, 0xbf0f7315, 0xd62d1c7e, 0xc700c47b, 0xb78c1b6b, 0x21a19045, 0xb26eb1be, 0x6a366eb4,
\r
407 0x5748ab2f, 0xbc946e79, 0xc6a376d2, 0x6549c2c8, 0x530ff8ee, 0x468dde7d, 0xd5730a1d, 0x4cd04dc6,
\r
408 0x2939bbdb, 0xa9ba4650, 0xac9526e8, 0xbe5ee304, 0xa1fad5f0, 0x6a2d519a, 0x63ef8ce2, 0x9a86ee22,
\r
409 0xc089c2b8, 0x43242ef6, 0xa51e03aa, 0x9cf2d0a4, 0x83c061ba, 0x9be96a4d, 0x8fe51550, 0xba645bd6,
\r
410 0x2826a2f9, 0xa73a3ae1, 0x4ba99586, 0xef5562e9, 0xc72fefd3, 0xf752f7da, 0x3f046f69, 0x77fa0a59,
\r
411 0x80e4a915, 0x87b08601, 0x9b09e6ad, 0x3b3ee593, 0xe990fd5a, 0x9e34d797, 0x2cf0b7d9, 0x022b8b51,
\r
412 0x96d5ac3a, 0x017da67d, 0xd1cf3ed6, 0x7c7d2d28, 0x1f9f25cf, 0xadf2b89b, 0x5ad6b472, 0x5a88f54c,
\r
413 0xe029ac71, 0xe019a5e6, 0x47b0acfd, 0xed93fa9b, 0xe8d3c48d, 0x283b57cc, 0xf8d56629, 0x79132e28,
\r
414 0x785f0191, 0xed756055, 0xf7960e44, 0xe3d35e8c, 0x15056dd4, 0x88f46dba, 0x03a16125, 0x0564f0bd,
\r
415 0xc3eb9e15, 0x3c9057a2, 0x97271aec, 0xa93a072a, 0x1b3f6d9b, 0x1e6321f5, 0xf59c66fb, 0x26dcf319,
\r
416 0x7533d928, 0xb155fdf5, 0x03563482, 0x8aba3cbb, 0x28517711, 0xc20ad9f8, 0xabcc5167, 0xccad925f,
\r
417 0x4de81751, 0x3830dc8e, 0x379d5862, 0x9320f991, 0xea7a90c2, 0xfb3e7bce, 0x5121ce64, 0x774fbe32,
\r
418 0xa8b6e37e, 0xc3293d46, 0x48de5369, 0x6413e680, 0xa2ae0810, 0xdd6db224, 0x69852dfd, 0x09072166,
\r
419 0xb39a460a, 0x6445c0dd, 0x586cdecf, 0x1c20c8ae, 0x5bbef7dd, 0x1b588d40, 0xccd2017f, 0x6bb4e3bb,
\r
420 0xdda26a7e, 0x3a59ff45, 0x3e350a44, 0xbcb4cdd5, 0x72eacea8, 0xfa6484bb, 0x8d6612ae, 0xbf3c6f47,
\r
421 0xd29be463, 0x542f5d9e, 0xaec2771b, 0xf64e6370, 0x740e0d8d, 0xe75b1357, 0xf8721671, 0xaf537d5d,
\r
422 0x4040cb08, 0x4eb4e2cc, 0x34d2466a, 0x0115af84, 0xe1b00428, 0x95983a1d, 0x06b89fb4, 0xce6ea048,
\r
423 0x6f3f3b82, 0x3520ab82, 0x011a1d4b, 0x277227f8, 0x611560b1, 0xe7933fdc, 0xbb3a792b, 0x344525bd,
\r
424 0xa08839e1, 0x51ce794b, 0x2f32c9b7, 0xa01fbac9, 0xe01cc87e, 0xbcc7d1f6, 0xcf0111c3, 0xa1e8aac7,
\r
425 0x1a908749, 0xd44fbd9a, 0xd0dadecb, 0xd50ada38, 0x0339c32a, 0xc6913667, 0x8df9317c, 0xe0b12b4f,
\r
426 0xf79e59b7, 0x43f5bb3a, 0xf2d519ff, 0x27d9459c, 0xbf97222c, 0x15e6fc2a, 0x0f91fc71, 0x9b941525,
\r
427 0xfae59361, 0xceb69ceb, 0xc2a86459, 0x12baa8d1, 0xb6c1075e, 0xe3056a0c, 0x10d25065, 0xcb03a442,
\r
428 0xe0ec6e0e, 0x1698db3b, 0x4c98a0be, 0x3278e964, 0x9f1f9532, 0xe0d392df, 0xd3a0342b, 0x8971f21e,
\r
429 0x1b0a7441, 0x4ba3348c, 0xc5be7120, 0xc37632d8, 0xdf359f8d, 0x9b992f2e, 0xe60b6f47, 0x0fe3f11d,
\r
430 0xe54cda54, 0x1edad891, 0xce6279cf, 0xcd3e7e6f, 0x1618b166, 0xfd2c1d05, 0x848fd2c5, 0xf6fb2299,
\r
431 0xf523f357, 0xa6327623, 0x93a83531, 0x56cccd02, 0xacf08162, 0x5a75ebb5, 0x6e163697, 0x88d273cc,
\r
432 0xde966292, 0x81b949d0, 0x4c50901b, 0x71c65614, 0xe6c6c7bd, 0x327a140a, 0x45e1d006, 0xc3f27b9a,
\r
433 0xc9aa53fd, 0x62a80f00, 0xbb25bfe2, 0x35bdd2f6, 0x71126905, 0xb2040222, 0xb6cbcf7c, 0xcd769c2b,
\r
434 0x53113ec0, 0x1640e3d3, 0x38abbd60, 0x2547adf0, 0xba38209c, 0xf746ce76, 0x77afa1c5, 0x20756060,
\r
435 0x85cbfe4e, 0x8ae88dd8, 0x7aaaf9b0, 0x4cf9aa7e, 0x1948c25c, 0x02fb8a8c, 0x01c36ae4, 0xd6ebe1f9,
\r
436 0x90d4f869, 0xa65cdea0, 0x3f09252d, 0xc208e69f, 0xb74e6132, 0xce77e25b, 0x578fdfe3, 0x3ac372e6
\r
440 * P-Array consists of 18 32-bit subkeys
\r
442 * @var array $parray
\r
445 var $parray = array(
\r
446 0x243f6a88, 0x85a308d3, 0x13198a2e, 0x03707344, 0xa4093822, 0x299f31d0,
\r
447 0x082efa98, 0xec4e6c89, 0x452821e6, 0x38d01377, 0xbe5466cf, 0x34e90c6c,
\r
448 0xc0ac29b7, 0xc97c50dd, 0x3f84d5b5, 0xb5470917, 0x9216d5d9, 0x8979fb1b
\r
452 * The BCTX-working Array
\r
454 * Holds the expanded key [p] and the key-depended s-boxes [sb]
\r
459 var $bctx = array();
\r
462 * Default Constructor.
\r
464 * Determines whether or not the mcrypt extension should be used.
\r
465 * If not explictly set, CRYPT_BLOWFISH_MODE_CBC will be used.
\r
467 * @param optional Integer $mode
\r
470 function Crypt_Blowfish($mode = CRYPT_BLOWFISH_MODE_CBC)
\r
472 if ( !defined('CRYPT_BLOWFISH_MODE') ) {
\r
474 case extension_loaded('mcrypt') && in_array('blowfish', mcrypt_list_algorithms()):
\r
475 define('CRYPT_BLOWFISH_MODE', CRYPT_BLOWFISH_MODE_MCRYPT);
\r
478 define('CRYPT_BLOWFISH_MODE', CRYPT_BLOWFISH_MODE_INTERNAL);
\r
482 switch ( CRYPT_BLOWFISH_MODE ) {
\r
483 case CRYPT_BLOWFISH_MODE_MCRYPT:
\r
485 case CRYPT_BLOWFISH_MODE_ECB:
\r
486 $this->paddable = true;
\r
487 $this->mode = MCRYPT_MODE_ECB;
\r
489 case CRYPT_BLOWFISH_MODE_CTR:
\r
490 $this->mode = 'ctr';
\r
492 case CRYPT_BLOWFISH_MODE_CFB:
\r
493 $this->mode = 'ncfb';
\r
494 $this->ecb = mcrypt_module_open(MCRYPT_BLOWFISH, '', MCRYPT_MODE_ECB, '');
\r
496 case CRYPT_BLOWFISH_MODE_OFB:
\r
497 $this->mode = MCRYPT_MODE_NOFB;
\r
499 case CRYPT_BLOWFISH_MODE_CBC:
\r
501 $this->paddable = true;
\r
502 $this->mode = MCRYPT_MODE_CBC;
\r
504 $this->enmcrypt = mcrypt_module_open(MCRYPT_BLOWFISH, '', $this->mode, '');
\r
505 $this->demcrypt = mcrypt_module_open(MCRYPT_BLOWFISH, '', $this->mode, '');
\r
510 case CRYPT_BLOWFISH_MODE_ECB:
\r
511 case CRYPT_BLOWFISH_MODE_CBC:
\r
512 $this->paddable = true;
\r
513 $this->mode = $mode;
\r
515 case CRYPT_BLOWFISH_MODE_CTR:
\r
516 case CRYPT_BLOWFISH_MODE_CFB:
\r
517 case CRYPT_BLOWFISH_MODE_OFB:
\r
518 $this->mode = $mode;
\r
521 $this->paddable = true;
\r
522 $this->mode = CRYPT_BLOWFISH_MODE_CBC;
\r
524 $this->inline_crypt_setup();
\r
531 * Keys can be of any length. Blowfish, itself, requires the use of a key between 32 and max. 448-bits long.
\r
532 * If the key is less than 32-bits we NOT fill the key to 32bit but let the key as it is to be compatible
\r
533 * with mcrypt because mcrypt act this way with blowfish key's < 32 bits.
\r
535 * If the key is more than 448-bits, we trim the excess bits.
\r
537 * If the key is not explicitly set, or empty, it'll be assumed a 128 bits key to be all null bytes.
\r
540 * @param String $key
\r
542 function setKey($key)
\r
544 $keylength = strlen($key);
\r
547 $key = "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0";
\r
549 elseif ($keylength > 56) {
\r
550 $key = substr($key, 0, 56);
\r
555 $this->enchanged = true;
\r
556 $this->dechanged = true;
\r
558 if (CRYPT_BLOWFISH_MODE == CRYPT_BLOWFISH_MODE_MCRYPT) {
\r
562 /* key-expanding p[] and S-Box building sb[] */
\r
563 $this->bctx = array(
\r
573 // unpack binary string in unsigned chars
\r
574 $key = array_values(unpack('C*', $key));
\r
575 $keyl = count($key);
\r
576 for ($j = 0, $i = 0; $i < 18; ++$i) {
\r
577 // xor P1 with the first 32-bits of the key, xor P2 with the second 32-bits ...
\r
578 for ($data = 0, $k = 0; $k < 4; ++$k) {
\r
579 $data = ($data << 8) | $key[$j];
\r
580 if (++$j >= $keyl) {
\r
584 $this->bctx['p'][] = $this->parray[$i] ^ $data;
\r
587 // encrypt the zero-string, replace P1 and P2 with the encrypted data,
\r
588 // encrypt P3 and P4 with the new P1 and P2, do it with all P-array and subkeys
\r
591 for ($i = 0; $i < 18; $i += 2) {
\r
592 $this->_encryptBlock($datal, $datar);
\r
593 $this->bctx['p'][$i ] = $datal;
\r
594 $this->bctx['p'][$i + 1] = $datar;
\r
596 for ($i = 0; $i < 4; ++$i) {
\r
597 for ($j = 0; $j < 256; $j += 2) {
\r
598 $this->_encryptBlock($datal, $datar);
\r
599 $this->bctx['sb'][$i][$j ] = $datal;
\r
600 $this->bctx['sb'][$i][$j + 1] = $datar;
\r
606 * Encrypt the block.
\r
609 * @param int $Xl left uInt32 part of the block
\r
610 * @param int $Xr right uInt32 part of the block
\r
613 function _encryptBlock(&$Xl, &$Xr)
\r
615 $p = $this->bctx['p'];
\r
616 $sb_0 = $this->bctx['sb'][0];
\r
617 $sb_1 = $this->bctx['sb'][1];
\r
618 $sb_2 = $this->bctx['sb'][2];
\r
619 $sb_3 = $this->bctx['sb'][3];
\r
626 $r^= ($sb_0[$l >> 24 & 0xff] +
\r
627 $sb_1[$l >> 16 & 0xff] ^
\r
628 $sb_2[$l >> 8 & 0xff]) +
\r
632 $l^= ($sb_0[$r >> 24 & 0xff] +
\r
633 $sb_1[$r >> 16 & 0xff] ^
\r
634 $sb_2[$r >> 8 & 0xff]) +
\r
643 * Sets the password.
\r
645 * Depending on what $method is set to, setPassword()'s (optional) parameters are as follows:
\r
646 * {@link http://en.wikipedia.org/wiki/PBKDF2 pbkdf2}:
\r
647 * $hash, $salt, $count
\r
649 * @param String $password
\r
650 * @param optional String $method
\r
653 function setPassword($password, $method = 'pbkdf2')
\r
658 default: // 'pbkdf2'
\r
659 list(, , $hash, $salt, $count) = func_get_args();
\r
660 if (!isset($hash)) {
\r
663 // WPA and WPA2 use the SSID as the salt
\r
664 if (!isset($salt)) {
\r
665 $salt = 'phpseclib/salt';
\r
667 // RFC2898#section-4.2 uses 1,000 iterations by default
\r
668 // WPA and WPA2 use 4,096.
\r
669 if (!isset($count)) {
\r
673 if (!class_exists('Crypt_Hash')) {
\r
674 require_once('Crypt/Hash.php');
\r
678 while (strlen($key) < 56) {
\r
679 //$dk.= $this->_pbkdf($password, $salt, $count, $i++);
\r
680 $hmac = new Crypt_Hash();
\r
681 $hmac->setHash($hash);
\r
682 $hmac->setKey($password);
\r
683 $f = $u = $hmac->hash($salt . pack('N', $i++));
\r
684 for ($j = 2; $j <= $count; $j++) {
\r
685 $u = $hmac->hash($u);
\r
692 $this->setKey($key);
\r
696 * Sets the initialization vector. (optional)
\r
698 * SetIV is not required when CRYPT_BLOWFISH_MODE_ECB is being used. If not explictly set, it'll be assumed
\r
699 * to be all null bytes.
\r
702 * @param String $iv
\r
704 function setIV($iv)
\r
706 $this->encryptIV = $this->decryptIV = $this->iv = str_pad(substr($iv, 0, 8), 8, chr(0));
\r
707 $this->enchanged = true;
\r
708 $this->dechanged = true;
\r
712 * Encrypts a message.
\r
714 * $plaintext will be padded with up to 8 additional bytes. Other Blowfish implementations may or may not pad in the
\r
715 * same manner. Other common approaches to padding and the reasons why it's necessary are discussed in the following
\r
718 * {@link http://www.di-mgt.com.au/cryptopad.html http://www.di-mgt.com.au/cryptopad.html}
\r
720 * An alternative to padding is to, separately, send the length of the file. This is what SSH, in fact, does.
\r
721 * strlen($plaintext) will still need to be a multiple of 8, however, arbitrary values can be added to make it that
\r
724 * @see Crypt_Blowfish::decrypt()
\r
726 * @param String $plaintext
\r
728 function encrypt($plaintext)
\r
730 if ( CRYPT_BLOWFISH_MODE == CRYPT_BLOWFISH_MODE_MCRYPT ) {
\r
731 if ($this->paddable) {
\r
732 $plaintext = $this->_pad($plaintext);
\r
735 if ($this->enchanged) {
\r
736 mcrypt_generic_init($this->enmcrypt, $this->key, $this->encryptIV);
\r
737 if ($this->mode == 'ncfb') {
\r
738 mcrypt_generic_init($this->ecb, $this->key, "\0\0\0\0\0\0\0\0");
\r
740 $this->enchanged = false;
\r
743 if ($this->mode != 'ncfb' || !$this->continuousBuffer) {
\r
744 $ciphertext = mcrypt_generic($this->enmcrypt, $plaintext);
\r
746 $iv = &$this->encryptIV;
\r
747 $pos = &$this->enbuffer['pos'];
\r
748 $len = strlen($plaintext);
\r
754 if ($len >= $max) {
\r
763 $ciphertext = substr($iv, $orig_pos) ^ $plaintext;
\r
764 $iv = substr_replace($iv, $ciphertext, $orig_pos, $i);
\r
765 $this->enbuffer['enmcrypt_init'] = true;
\r
768 if ($this->enbuffer['enmcrypt_init'] === false || $len > 600) {
\r
769 if ($this->enbuffer['enmcrypt_init'] === true) {
\r
770 mcrypt_generic_init($this->enmcrypt, $this->key, $iv);
\r
771 $this->enbuffer['enmcrypt_init'] = false;
\r
773 $ciphertext.= mcrypt_generic($this->enmcrypt, substr($plaintext, $i, $len - $len % 8));
\r
774 $iv = substr($ciphertext, -8);
\r
777 while ($len >= 8) {
\r
778 $iv = mcrypt_generic($this->ecb, $iv) ^ substr($plaintext, $i, 8);
\r
786 $iv = mcrypt_generic($this->ecb, $iv);
\r
787 $block = $iv ^ substr($plaintext, -$len);
\r
788 $iv = substr_replace($iv, $block, 0, $len);
\r
789 $ciphertext.= $block;
\r
792 return $ciphertext;
\r
795 if (!$this->continuousBuffer) {
\r
796 mcrypt_generic_init($this->enmcrypt, $this->key, $this->encryptIV);
\r
799 return $ciphertext;
\r
802 if (empty($this->bctx)) {
\r
803 $this->setKey($this->key);
\r
806 $inline = $this->inline_crypt;
\r
807 return $inline('encrypt', $this, $plaintext);
\r
811 * Decrypts a message.
\r
813 * If strlen($ciphertext) is not a multiple of 8, null bytes will be added to the end of the string until it is.
\r
815 * @see Crypt_Blowfish::encrypt()
\r
817 * @param String $ciphertext
\r
819 function decrypt($ciphertext)
\r
821 if ( CRYPT_BLOWFISH_MODE == CRYPT_BLOWFISH_MODE_MCRYPT ) {
\r
822 if ($this->paddable) {
\r
823 // we pad with chr(0) since that's what mcrypt_generic does. to quote from http://php.net/function.mcrypt-generic :
\r
824 // "The data is padded with "\0" to make sure the length of the data is n * blocksize."
\r
825 $ciphertext = str_pad($ciphertext, strlen($ciphertext) + (8 - strlen($ciphertext) % 8) % 8, chr(0));
\r
828 if ($this->dechanged) {
\r
829 mcrypt_generic_init($this->demcrypt, $this->key, $this->decryptIV);
\r
830 if ($this->mode == 'ncfb') {
\r
831 mcrypt_generic_init($this->ecb, $this->key, "\0\0\0\0\0\0\0\0");
\r
833 $this->dechanged = false;
\r
836 if ($this->mode != 'ncfb' || !$this->continuousBuffer) {
\r
837 $plaintext = mdecrypt_generic($this->demcrypt, $ciphertext);
\r
839 $iv = &$this->decryptIV;
\r
840 $pos = &$this->debuffer['pos'];
\r
841 $len = strlen($ciphertext);
\r
847 if ($len >= $max) {
\r
856 $plaintext = substr($iv, $orig_pos) ^ $ciphertext;
\r
857 $iv = substr_replace($iv, substr($ciphertext, 0, $i), $orig_pos, $i);
\r
860 $cb = substr($ciphertext, $i, $len - $len % 8);
\r
861 $plaintext.= mcrypt_generic($this->ecb, $iv . $cb) ^ $cb;
\r
862 $iv = substr($cb, -8);
\r
866 $iv = mcrypt_generic($this->ecb, $iv);
\r
867 $plaintext.= $iv ^ substr($ciphertext, -$len);
\r
868 $iv = substr_replace($iv, substr($ciphertext, -$len), 0, $len);
\r
874 if (!$this->continuousBuffer) {
\r
875 mcrypt_generic_init($this->demcrypt, $this->key, $this->decryptIV);
\r
878 return $this->paddable ? $this->_unpad($plaintext) : $plaintext;
\r
881 if (empty($this->bctx)) {
\r
882 $this->setKey($this->key);
\r
885 $inline = $this->inline_crypt;
\r
886 return $inline('decrypt', $this, $ciphertext);
\r
890 * Treat consecutive "packets" as if they are a continuous buffer.
\r
892 * @see Crypt_Blowfish::disableContinuousBuffer()
\r
895 function enableContinuousBuffer()
\r
897 $this->continuousBuffer = true;
\r
901 * Treat consecutive packets as if they are a discontinuous buffer.
\r
903 * The default behavior.
\r
905 * @see Crypt_Blowfish::enableContinuousBuffer()
\r
908 function disableContinuousBuffer()
\r
910 $this->continuousBuffer = false;
\r
911 $this->encryptIV = $this->iv;
\r
912 $this->decryptIV = $this->iv;
\r
913 $this->enbuffer = array('encrypted' => '', 'xor' => '', 'pos' => 0, 'enmcrypt_init' => true);
\r
914 $this->debuffer = array('ciphertext' => '', 'xor' => '', 'pos' => 0, 'demcrypt_init' => true);
\r
916 if (CRYPT_BLOWFISH_MODE == CRYPT_BLOWFISH_MODE_MCRYPT) {
\r
917 mcrypt_generic_init($this->enmcrypt, $this->key, $this->iv);
\r
918 mcrypt_generic_init($this->demcrypt, $this->key, $this->iv);
\r
925 * Blowfish works by encrypting 8 bytes at a time. If you ever need to encrypt or decrypt something that's not
\r
926 * a multiple of 8, it becomes necessary to pad the input so that it's length is a multiple of eight.
\r
928 * Padding is enabled by default. Sometimes, however, it is undesirable to pad strings. Such is the case in SSH1,
\r
929 * where "packets" are padded with random bytes before being encrypted. Unpad these packets and you risk stripping
\r
930 * away characters that shouldn't be stripped away. (SSH knows how many bytes are added because the length is
\r
931 * transmitted separately)
\r
933 * @see Crypt_Blowfish::disablePadding()
\r
936 function enablePadding()
\r
938 $this->padding = true;
\r
942 * Do not pad packets.
\r
944 * @see Crypt_Blowfish::enablePadding()
\r
947 function disablePadding()
\r
949 $this->padding = false;
\r
955 * Pads a string using the RSA PKCS padding standards so that its length is a multiple of the blocksize (8).
\r
957 * If padding is disabled and $text is not a multiple of the blocksize, the string will be padded regardless
\r
958 * and padding will, hence forth, be enabled.
\r
960 * @see Crypt_Blowfish::_unpad()
\r
963 function _pad($text)
\r
965 $length = strlen($text);
\r
967 if (!$this->padding) {
\r
968 if ($length % 8 == 0) {
\r
971 user_error("The plaintext's length ($length) is not a multiple of the block size (8)");
\r
972 $this->padding = true;
\r
976 $pad = 8 - ($length % 8);
\r
978 return str_pad($text, $length + $pad, chr($pad));
\r
984 * If padding is enabled and the reported padding length is invalid the encryption key will be assumed to be wrong
\r
985 * and false will be returned.
\r
987 * @see Crypt_Blowfish::_pad()
\r
990 function _unpad($text)
\r
992 if (!$this->padding) {
\r
996 $length = ord($text[strlen($text) - 1]);
\r
998 if (!$length || $length > 8) {
\r
1002 return substr($text, 0, -$length);
\r
1008 * Inspired by array_shift
\r
1010 * @param String $string
\r
1014 function _string_shift(&$string)
\r
1016 $substr = substr($string, 0, 8);
\r
1017 $string = substr($string, 8);
\r
1022 * Generate CTR XOR encryption key
\r
1024 * Encrypt the output of this and XOR it against the ciphertext / plaintext to get the
\r
1025 * plaintext / ciphertext in CTR mode.
\r
1027 * @see Crypt_Blowfish::decrypt()
\r
1028 * @see Crypt_Blowfish::encrypt()
\r
1030 * @param String $iv
\r
1032 function _generate_xor(&$iv)
\r
1035 for ($j = 4; $j <= 8; $j+=4) {
\r
1036 $temp = substr($iv, -$j, 4);
\r
1038 case "\xFF\xFF\xFF\xFF":
\r
1039 $iv = substr_replace($iv, "\x00\x00\x00\x00", -$j, 4);
\r
1041 case "\x7F\xFF\xFF\xFF":
\r
1042 $iv = substr_replace($iv, "\x80\x00\x00\x00", -$j, 4);
\r
1045 extract(unpack('Ncount', $temp));
\r
1046 $iv = substr_replace($iv, pack('N', $count + 1), -$j, 4);
\r
1055 * Creates performance-optimized function for de/encrypt(), storing it in $this->inline_crypt
\r
1059 function inline_crypt_setup()
\r
1061 $lambda_functions =& Crypt_Blowfish::get_lambda_functions();
\r
1063 $mode = $this->mode;
\r
1064 $code_hash = "$mode";
\r
1066 if (!isset($lambda_functions[$code_hash])) {
\r
1067 $init_cryptBlock = '
\r
1068 extract($self->bctx["p"], EXTR_PREFIX_ALL, "p");
\r
1069 extract($self->bctx["sb"], EXTR_PREFIX_ALL, "sb");
\r
1072 // Generating encrypt code:
\r
1073 $_encryptBlock = '
\r
1074 $in = unpack("N*", $in);
\r
1078 for ($i = 0; $i < 16; $i+= 2) {
\r
1079 $_encryptBlock.= '
\r
1081 $r^= ($sb_0[$l >> 24 & 0xff] +
\r
1082 $sb_1[$l >> 16 & 0xff] ^
\r
1083 $sb_2[$l >> 8 & 0xff]) +
\r
1086 $r^= $p_'.($i + 1).';
\r
1087 $l^= ($sb_0[$r >> 24 & 0xff] +
\r
1088 $sb_1[$r >> 16 & 0xff] ^
\r
1089 $sb_2[$r >> 8 & 0xff]) +
\r
1093 $_encryptBlock.= '
\r
1094 $in = pack("N*", $r ^ $p_17, $l ^ $p_16);
\r
1097 // Generating decrypt code:
\r
1098 $_decryptBlock = '
\r
1099 $in = unpack("N*", $in);
\r
1104 for ($i = 17; $i > 2; $i-= 2) {
\r
1105 $_decryptBlock.= '
\r
1107 $r^= ($sb_0[$l >> 24 & 0xff] +
\r
1108 $sb_1[$l >> 16 & 0xff] ^
\r
1109 $sb_2[$l >> 8 & 0xff]) +
\r
1112 $r^= $p_'.($i - 1).';
\r
1113 $l^= ($sb_0[$r >> 24 & 0xff] +
\r
1114 $sb_1[$r >> 16 & 0xff] ^
\r
1115 $sb_2[$r >> 8 & 0xff]) +
\r
1120 $_decryptBlock.= '
\r
1121 $in = pack("N*", $r ^ $p_0, $l ^ $p_1);
\r
1124 // Generating mode of operation code:
\r
1126 case CRYPT_BLOWFISH_MODE_ECB:
\r
1129 $text = $self->_pad($text);
\r
1130 $plaintext_len = strlen($text);
\r
1132 for ($i = 0; $i < $plaintext_len; $i+= '.$block_size.') {
\r
1133 $in = substr($text, $i, '.$block_size.');
\r
1134 '.$_encryptBlock.'
\r
1135 $ciphertext.= $in;
\r
1137 return $ciphertext;
\r
1142 $text = str_pad($text, strlen($text) + ('.$block_size.' - strlen($text) % '.$block_size.') % '.$block_size.', chr(0));
\r
1143 $ciphertext_len = strlen($text);
\r
1145 for ($i = 0; $i < $ciphertext_len; $i+= '.$block_size.') {
\r
1146 $in = substr($text, $i, '.$block_size.');
\r
1147 '.$_decryptBlock.'
\r
1151 return $self->_unpad($plaintext);
\r
1154 case CRYPT_BLOWFISH_MODE_CBC:
\r
1157 $text = $self->_pad($text);
\r
1158 $plaintext_len = strlen($text);
\r
1160 $in = $self->encryptIV;
\r
1162 for ($i = 0; $i < $plaintext_len; $i+= '.$block_size.') {
\r
1163 $in = substr($text, $i, '.$block_size.') ^ $in;
\r
1164 '.$_encryptBlock.'
\r
1165 $ciphertext.= $in;
\r
1168 if ($self->continuousBuffer) {
\r
1169 $self->encryptIV = $in;
\r
1172 return $ciphertext;
\r
1177 $text = str_pad($text, strlen($text) + ('.$block_size.' - strlen($text) % '.$block_size.') % '.$block_size.', chr(0));
\r
1178 $ciphertext_len = strlen($text);
\r
1180 $iv = $self->decryptIV;
\r
1182 for ($i = 0; $i < $ciphertext_len; $i+= '.$block_size.') {
\r
1183 $in = $block = substr($text, $i, '.$block_size.');
\r
1184 '.$_decryptBlock.'
\r
1185 $plaintext.= $in ^ $iv;
\r
1189 if ($self->continuousBuffer) {
\r
1190 $self->decryptIV = $iv;
\r
1193 return $self->_unpad($plaintext);
\r
1196 case CRYPT_BLOWFISH_MODE_CTR:
\r
1199 $plaintext_len = strlen($text);
\r
1200 $xor = $self->encryptIV;
\r
1201 $buffer = &$self->enbuffer;
\r
1203 if (strlen($buffer["encrypted"])) {
\r
1204 for ($i = 0; $i < $plaintext_len; $i+= '.$block_size.') {
\r
1205 $block = substr($text, $i, '.$block_size.');
\r
1206 if (strlen($block) > strlen($buffer["encrypted"])) {
\r
1207 $in = $self->_generate_xor($xor);
\r
1208 '.$_encryptBlock.'
\r
1209 $buffer["encrypted"].= $in;
\r
1211 $key = $self->_string_shift($buffer["encrypted"]);
\r
1212 $ciphertext.= $block ^ $key;
\r
1215 for ($i = 0; $i < $plaintext_len; $i+= '.$block_size.') {
\r
1216 $block = substr($text, $i, '.$block_size.');
\r
1217 $in = $self->_generate_xor($xor);
\r
1218 '.$_encryptBlock.'
\r
1220 $ciphertext.= $block ^ $key;
\r
1223 if ($self->continuousBuffer) {
\r
1224 $self->encryptIV = $xor;
\r
1225 if ($start = $plaintext_len % '.$block_size.') {
\r
1226 $buffer["encrypted"] = substr($key, $start) . $buffer["encrypted"];
\r
1230 return $ciphertext;
\r
1235 $ciphertext_len = strlen($text);
\r
1236 $xor = $self->decryptIV;
\r
1237 $buffer = &$self->debuffer;
\r
1239 if (strlen($buffer["ciphertext"])) {
\r
1240 for ($i = 0; $i < $ciphertext_len; $i+= '.$block_size.') {
\r
1241 $block = substr($text, $i, '.$block_size.');
\r
1242 if (strlen($block) > strlen($buffer["ciphertext"])) {
\r
1243 $in = $self->_generate_xor($xor);
\r
1244 '.$_encryptBlock.'
\r
1245 $buffer["ciphertext"].= $in;
\r
1247 $key = $self->_string_shift($buffer["ciphertext"]);
\r
1248 $plaintext.= $block ^ $key;
\r
1251 for ($i = 0; $i < $ciphertext_len; $i+= '.$block_size.') {
\r
1252 $block = substr($text, $i, '.$block_size.');
\r
1253 $in = $self->_generate_xor($xor);
\r
1254 '.$_encryptBlock.'
\r
1256 $plaintext.= $block ^ $key;
\r
1259 if ($self->continuousBuffer) {
\r
1260 $self->decryptIV = $xor;
\r
1261 if ($start = $ciphertext_len % '.$block_size.') {
\r
1262 $buffer["ciphertext"] = substr($key, $start) . $buffer["ciphertext"];
\r
1265 return $plaintext;
\r
1268 case CRYPT_BLOWFISH_MODE_CFB:
\r
1271 $buffer = &$self->enbuffer;
\r
1273 if ($self->continuousBuffer) {
\r
1274 $iv = &$self->encryptIV;
\r
1275 $pos = &$buffer["pos"];
\r
1277 $iv = $self->encryptIV;
\r
1280 $len = strlen($text);
\r
1284 $max = '.$block_size.' - $pos;
\r
1285 if ($len >= $max) {
\r
1294 $ciphertext = substr($iv, $orig_pos) ^ $text;
\r
1295 $iv = substr_replace($iv, $ciphertext, $orig_pos, $i);
\r
1297 while ($len >= '.$block_size.') {
\r
1299 '.$_encryptBlock.';
\r
1300 $iv = $in ^ substr($text, $i, '.$block_size.');
\r
1301 $ciphertext.= $iv;
\r
1302 $len-= '.$block_size.';
\r
1303 $i+= '.$block_size.';
\r
1307 '.$_encryptBlock.'
\r
1309 $block = $iv ^ substr($text, $i);
\r
1310 $iv = substr_replace($iv, $block, 0, $len);
\r
1311 $ciphertext.= $block;
\r
1314 return $ciphertext;
\r
1319 $buffer = &$self->debuffer;
\r
1321 if ($self->continuousBuffer) {
\r
1322 $iv = &$self->decryptIV;
\r
1323 $pos = &$buffer["pos"];
\r
1325 $iv = $self->decryptIV;
\r
1328 $len = strlen($text);
\r
1332 $max = '.$block_size.' - $pos;
\r
1333 if ($len >= $max) {
\r
1342 $plaintext = substr($iv, $orig_pos) ^ $text;
\r
1343 $iv = substr_replace($iv, substr($text, 0, $i), $orig_pos, $i);
\r
1345 while ($len >= '.$block_size.') {
\r
1347 '.$_encryptBlock.'
\r
1349 $cb = substr($text, $i, '.$block_size.');
\r
1350 $plaintext.= $iv ^ $cb;
\r
1352 $len-= '.$block_size.';
\r
1353 $i+= '.$block_size.';
\r
1357 '.$_encryptBlock.'
\r
1359 $plaintext.= $iv ^ substr($text, $i);
\r
1360 $iv = substr_replace($iv, substr($text, $i), 0, $len);
\r
1364 return $plaintext;
\r
1367 case CRYPT_BLOWFISH_MODE_OFB:
\r
1370 $plaintext_len = strlen($text);
\r
1371 $xor = $self->encryptIV;
\r
1372 $buffer = &$self->enbuffer;
\r
1374 if (strlen($buffer["xor"])) {
\r
1375 for ($i = 0; $i < $plaintext_len; $i+= '.$block_size.') {
\r
1376 $block = substr($text, $i, '.$block_size.');
\r
1377 if (strlen($block) > strlen($buffer["xor"])) {
\r
1379 '.$_encryptBlock.'
\r
1381 $buffer["xor"].= $xor;
\r
1383 $key = $self->_string_shift($buffer["xor"]);
\r
1384 $ciphertext.= $block ^ $key;
\r
1387 for ($i = 0; $i < $plaintext_len; $i+= '.$block_size.') {
\r
1389 '.$_encryptBlock.'
\r
1391 $ciphertext.= substr($text, $i, '.$block_size.') ^ $xor;
\r
1395 if ($self->continuousBuffer) {
\r
1396 $self->encryptIV = $xor;
\r
1397 if ($start = $plaintext_len % '.$block_size.') {
\r
1398 $buffer["xor"] = substr($key, $start) . $buffer["xor"];
\r
1401 return $ciphertext;
\r
1406 $ciphertext_len = strlen($text);
\r
1407 $xor = $self->decryptIV;
\r
1408 $buffer = &$self->debuffer;
\r
1410 if (strlen($buffer["xor"])) {
\r
1411 for ($i = 0; $i < $ciphertext_len; $i+= '.$block_size.') {
\r
1412 $block = substr($text, $i, '.$block_size.');
\r
1413 if (strlen($block) > strlen($buffer["xor"])) {
\r
1415 '.$_encryptBlock.'
\r
1417 $buffer["xor"].= $xor;
\r
1419 $key = $self->_string_shift($buffer["xor"]);
\r
1420 $plaintext.= $block ^ $key;
\r
1423 for ($i = 0; $i < $ciphertext_len; $i+= '.$block_size.') {
\r
1425 '.$_encryptBlock.'
\r
1427 $plaintext.= substr($text, $i, '.$block_size.') ^ $xor;
\r
1431 if ($self->continuousBuffer) {
\r
1432 $self->decryptIV = $xor;
\r
1433 if ($start = $ciphertext_len % '.$block_size.') {
\r
1434 $buffer["xor"] = substr($key, $start) . $buffer["xor"];
\r
1437 return $plaintext;
\r
1441 $fnc_head = '$action, &$self, $text';
\r
1442 $fnc_body = $init_cryptBlock . 'if ($action == "encrypt") { ' . $encrypt . ' } else { ' . $decrypt . ' }';
\r
1444 if (function_exists('create_function') && is_callable('create_function')) {
\r
1445 $lambda_functions[$code_hash] = create_function($fnc_head, $fnc_body);
\r
1447 eval('function ' . ($lambda_functions[$code_hash] = 'f' . md5(microtime())) . '(' . $fnc_head . ') { ' . $fnc_body . ' }');
\r
1450 $this->inline_crypt = $lambda_functions[$code_hash];
\r
1454 * Holds the lambda_functions table (classwide)
\r
1456 * @see inline_crypt_setup()
\r
1460 function &get_lambda_functions()
\r
1462 static $functions = array();
\r
1463 return $functions;
\r
1467 // vim: ts=4:sw=4:et:
\r