PluginProbe
ManageWP Worker / 3.9.28
ManageWP Worker v3.9.28
4.9.38 4.9.37 4.9.36 4.9.35 4.9.34 3.8.7 3.8.8 3.9.0 3.9.1 3.9.10 3.9.11 3.9.12 3.9.13 3.9.14 3.9.15 3.9.16 3.9.17 3.9.18 3.9.19 3.9.2 3.9.20 3.9.21 3.9.22 3.9.23 3.9.24 All 73 releases
worker / lib / PHPSecLib / Crypt / Blowfish.php

Blowfish.php in ManageWP Worker 3.9.28, at lib/PHPSecLib/Crypt/Blowfish.php

1,469 lines 59.9 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
3
4 /**
5 * Pure-PHP implementation of Blowfish.
6 *
7 * Uses mcrypt, if available, and an internal implementation, otherwise.
8 *
9 * PHP versions 4 and 5
10 *
11 * Useful resources are as follows:
12 *
13 * - {@link http://en.wikipedia.org/wiki/Blowfish Wikipedia description of Blowfish}
14 *
15 * Here's a short example of how to use this library:
16 * <code>
17 * <?php
18 * include('Crypt/Blowfish.php');
19 *
20 * $blowfish = new Crypt_Blowfish();
21 *
22 * $blowfish->setKey('12345678901234567890123456789012');
23 *
24 * $plaintext = str_repeat('a', 1024);
25 *
26 * echo $blowfish->decrypt($blowfish->encrypt($plaintext));
27 * ?>
28 * </code>
29 *
30 * LICENSE: Permission is hereby granted, free of charge, to any person obtaining a copy
31 * of this software and associated documentation files (the "Software"), to deal
32 * in the Software without restriction, including without limitation the rights
33 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
34 * copies of the Software, and to permit persons to whom the Software is
35 * furnished to do so, subject to the following conditions:
36 *
37 * The above copyright notice and this permission notice shall be included in
38 * all copies or substantial portions of the Software.
39 *
40 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
41 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
42 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
43 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
44 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
45 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
46 * THE SOFTWARE.
47 *
48 * @category Crypt
49 * @package Crypt_Blowfish
50 * @author Jim Wigginton <terrafrost@php.net>
51 * @author Hans-Juergen Petrich <petrich@tronic-media.com>
52 * @copyright MMVII Jim Wigginton
53 * @license http://www.opensource.org/licenses/mit-license.html MIT License
54 * @version 1.0
55 * @link http://phpseclib.sourceforge.net
56 */
57
58 /**#@+
59 * @access public
60 * @see Crypt_Blowfish::encrypt()
61 * @see Crypt_Blowfish::decrypt()
62 */
63 /**
64 * Encrypt / decrypt using the Counter mode.
65 *
66 * Set to -1 since that's what Crypt/Random.php uses to index the CTR mode.
67 *
68 * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Counter_.28CTR.29
69 */
70 define('CRYPT_BLOWFISH_MODE_CTR', -1);
71 /**
72 * Encrypt / decrypt using the Electronic Code Book mode.
73 *
74 * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Electronic_codebook_.28ECB.29
75 */
76 define('CRYPT_BLOWFISH_MODE_ECB', 1);
77 /**
78 * Encrypt / decrypt using the Code Book Chaining mode.
79 *
80 * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Cipher-block_chaining_.28CBC.29
81 */
82 define('CRYPT_BLOWFISH_MODE_CBC', 2);
83 /**
84 * Encrypt / decrypt using the Cipher Feedback mode.
85 *
86 * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Cipher_feedback_.28CFB.29
87 */
88 define('CRYPT_BLOWFISH_MODE_CFB', 3);
89 /**
90 * Encrypt / decrypt using the Cipher Feedback mode.
91 *
92 * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Output_feedback_.28OFB.29
93 */
94 define('CRYPT_BLOWFISH_MODE_OFB', 4);
95 /**#@-*/
96
97 /**#@+
98 * @access private
99 * @see Crypt_Blowfish::Crypt_Blowfish()
100 */
101 /**
102 * Toggles the internal implementation
103 */
104 define('CRYPT_BLOWFISH_MODE_INTERNAL', 1);
105 /**
106 * Toggles the mcrypt implementation
107 */
108 define('CRYPT_BLOWFISH_MODE_MCRYPT', 2);
109 /**#@-*/
110
111 /**
112 * Pure-PHP implementation of Blowfish.
113 *
114 * @author Jim Wigginton <terrafrost@php.net>
115 * @author Hans-Juergen Petrich <petrich@tronic-media.com>
116 * @version 1.0
117 * @access public
118 * @package Crypt_Blowfish
119 */
120 class Crypt_Blowfish {
121 /**
122 * The Key as String
123 *
124 * @see Crypt_Blowfish::setKey()
125 * @var Array
126 * @access private
127 */
128 var $key = "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0";
129
130 /**
131 * The Encryption Mode
132 *
133 * @see Crypt_Blowfish::Crypt_Blowfish()
134 * @var Integer
135 * @access private
136 */
137 var $mode;
138
139 /**
140 * Continuous Buffer status
141 *
142 * @see Crypt_Blowfish::enableContinuousBuffer()
143 * @var Boolean
144 * @access private
145 */
146 var $continuousBuffer = false;
147
148 /**
149 * Padding status
150 *
151 * @see Crypt_Blowfish::enablePadding()
152 * @var Boolean
153 * @access private
154 */
155 var $padding = true;
156
157 /**
158 * The Initialization Vector
159 *
160 * @see Crypt_Blowfish::setIV()
161 * @var String
162 * @access private
163 */
164 var $iv = "\0\0\0\0\0\0\0\0";
165
166 /**
167 * A "sliding" Initialization Vector
168 *
169 * @see Crypt_Blowfish::enableContinuousBuffer()
170 * @var String
171 * @access private
172 */
173 var $encryptIV = "\0\0\0\0\0\0\0\0";
174
175 /**
176 * A "sliding" Initialization Vector
177 *
178 * @see Crypt_Blowfish::enableContinuousBuffer()
179 * @var String
180 * @access private
181 */
182 var $decryptIV = "\0\0\0\0\0\0\0\0";
183
184 /**
185 * mcrypt resource for encryption
186 *
187 * The mcrypt resource can be recreated every time something needs to be created or it can be created just once.
188 * Since mcrypt operates in continuous mode, by default, it'll need to be recreated when in non-continuous mode.
189 *
190 * @see Crypt_Blowfish::encrypt()
191 * @var String
192 * @access private
193 */
194 var $enmcrypt;
195
196 /**
197 * mcrypt resource for decryption
198 *
199 * The mcrypt resource can be recreated every time something needs to be created or it can be created just once.
200 * Since mcrypt operates in continuous mode, by default, it'll need to be recreated when in non-continuous mode.
201 *
202 * @see Crypt_Blowfish::decrypt()
203 * @var String
204 * @access private
205 */
206 var $demcrypt;
207
208 /**
209 * Does the enmcrypt resource need to be (re)initialized?
210 *
211 * @see Crypt_Blowfish::setKey()
212 * @see Crypt_Blowfish::setIV()
213 * @var Boolean
214 * @access private
215 */
216 var $enchanged = true;
217
218 /**
219 * Does the demcrypt resource need to be (re)initialized?
220 *
221 * @see Crypt_Blowfish::setKey()
222 * @see Crypt_Blowfish::setIV()
223 * @var Boolean
224 * @access private
225 */
226 var $dechanged = true;
227
228 /**
229 * Is the mode one that is paddable?
230 *
231 * @see Crypt_Blowfish::Crypt_Blowfish()
232 * @var Boolean
233 * @access private
234 */
235 var $paddable = false;
236
237 /**
238 * Encryption buffer for CTR, OFB and CFB modes
239 *
240 * @see Crypt_Blowfish::encrypt()
241 * @var Array
242 * @access private
243 */
244 var $enbuffer = array('encrypted' => '', 'xor' => '', 'pos' => 0, 'enmcrypt_init' => true);
245
246 /**
247 * Decryption buffer for CTR, OFB and CFB modes
248 *
249 * @see Crypt_Blowfish::decrypt()
250 * @var Array
251 * @access private
252 */
253 var $debuffer = array('ciphertext' => '', 'xor' => '', 'pos' => 0, 'demcrypt_init' => true);
254
255 /**
256 * mcrypt resource for CFB mode
257 *
258 * @see Crypt_Blowfish::encrypt()
259 * @see Crypt_Blowfish::decrypt()
260 * @var String
261 * @access private
262 */
263 var $ecb;
264
265 /**
266 * Performance-optimized callback function for en/decrypt()
267 *
268 * @var Callback
269 * @access private
270 */
271 var $inline_crypt;
272
273 /**
274 * The fixed subkeys boxes ($sbox0 - $sbox3) with 256 entries each
275 *
276 * S-Box 1
277 *
278 * @access private
279 * @var array
280 */
281 var $sbox0 = array (
282 0xd1310ba6, 0x98dfb5ac, 0x2ffd72db, 0xd01adfb7, 0xb8e1afed, 0x6a267e96, 0xba7c9045, 0xf12c7f99,
283 0x24a19947, 0xb3916cf7, 0x0801f2e2, 0x858efc16, 0x636920d8, 0x71574e69, 0xa458fea3, 0xf4933d7e,
284 0x0d95748f, 0x728eb658, 0x718bcd58, 0x82154aee, 0x7b54a41d, 0xc25a59b5, 0x9c30d539, 0x2af26013,
285 0xc5d1b023, 0x286085f0, 0xca417918, 0xb8db38ef, 0x8e79dcb0, 0x603a180e, 0x6c9e0e8b, 0xb01e8a3e,
286 0xd71577c1, 0xbd314b27, 0x78af2fda, 0x55605c60, 0xe65525f3, 0xaa55ab94, 0x57489862, 0x63e81440,
287 0x55ca396a, 0x2aab10b6, 0xb4cc5c34, 0x1141e8ce, 0xa15486af, 0x7c72e993, 0xb3ee1411, 0x636fbc2a,
288 0x2ba9c55d, 0x741831f6, 0xce5c3e16, 0x9b87931e, 0xafd6ba33, 0x6c24cf5c, 0x7a325381, 0x28958677,
289 0x3b8f4898, 0x6b4bb9af, 0xc4bfe81b, 0x66282193, 0x61d809cc, 0xfb21a991, 0x487cac60, 0x5dec8032,
290 0xef845d5d, 0xe98575b1, 0xdc262302, 0xeb651b88, 0x23893e81, 0xd396acc5, 0x0f6d6ff3, 0x83f44239,
291 0x2e0b4482, 0xa4842004, 0x69c8f04a, 0x9e1f9b5e, 0x21c66842, 0xf6e96c9a, 0x670c9c61, 0xabd388f0,
292 0x6a51a0d2, 0xd8542f68, 0x960fa728, 0xab5133a3, 0x6eef0b6c, 0x137a3be4, 0xba3bf050, 0x7efb2a98,
293 0xa1f1651d, 0x39af0176, 0x66ca593e, 0x82430e88, 0x8cee8619, 0x456f9fb4, 0x7d84a5c3, 0x3b8b5ebe,
294 0xe06f75d8, 0x85c12073, 0x401a449f, 0x56c16aa6, 0x4ed3aa62, 0x363f7706, 0x1bfedf72, 0x429b023d,
295 0x37d0d724, 0xd00a1248, 0xdb0fead3, 0x49f1c09b, 0x075372c9, 0x80991b7b, 0x25d479d8, 0xf6e8def7,
296 0xe3fe501a, 0xb6794c3b, 0x976ce0bd, 0x04c006ba, 0xc1a94fb6, 0x409f60c4, 0x5e5c9ec2, 0x196a2463,
297 0x68fb6faf, 0x3e6c53b5, 0x1339b2eb, 0x3b52ec6f, 0x6dfc511f, 0x9b30952c, 0xcc814544, 0xaf5ebd09,
298 0xbee3d004, 0xde334afd, 0x660f2807, 0x192e4bb3, 0xc0cba857, 0x45c8740f, 0xd20b5f39, 0xb9d3fbdb,
299 0x5579c0bd, 0x1a60320a, 0xd6a100c6, 0x402c7279, 0x679f25fe, 0xfb1fa3cc, 0x8ea5e9f8, 0xdb3222f8,
300 0x3c7516df, 0xfd616b15, 0x2f501ec8, 0xad0552ab, 0x323db5fa, 0xfd238760, 0x53317b48, 0x3e00df82,
301 0x9e5c57bb, 0xca6f8ca0, 0x1a87562e, 0xdf1769db, 0xd542a8f6, 0x287effc3, 0xac6732c6, 0x8c4f5573,
302 0x695b27b0, 0xbbca58c8, 0xe1ffa35d, 0xb8f011a0, 0x10fa3d98, 0xfd2183b8, 0x4afcb56c, 0x2dd1d35b,
303 0x9a53e479, 0xb6f84565, 0xd28e49bc, 0x4bfb9790, 0xe1ddf2da, 0xa4cb7e33, 0x62fb1341, 0xcee4c6e8,
304 0xef20cada, 0x36774c01, 0xd07e9efe, 0x2bf11fb4, 0x95dbda4d, 0xae909198, 0xeaad8e71, 0x6b93d5a0,
305 0xd08ed1d0, 0xafc725e0, 0x8e3c5b2f, 0x8e7594b7, 0x8ff6e2fb, 0xf2122b64, 0x8888b812, 0x900df01c,
306 0x4fad5ea0, 0x688fc31c, 0xd1cff191, 0xb3a8c1ad, 0x2f2f2218, 0xbe0e1777, 0xea752dfe, 0x8b021fa1,
307 0xe5a0cc0f, 0xb56f74e8, 0x18acf3d6, 0xce89e299, 0xb4a84fe0, 0xfd13e0b7, 0x7cc43b81, 0xd2ada8d9,
308 0x165fa266, 0x80957705, 0x93cc7314, 0x211a1477, 0xe6ad2065, 0x77b5fa86, 0xc75442f5, 0xfb9d35cf,
309 0xebcdaf0c, 0x7b3e89a0, 0xd6411bd3, 0xae1e7e49, 0x00250e2d, 0x2071b35e, 0x226800bb, 0x57b8e0af,
310 0x2464369b, 0xf009b91e, 0x5563911d, 0x59dfa6aa, 0x78c14389, 0xd95a537f, 0x207d5ba2, 0x02e5b9c5,
311 0x83260376, 0x6295cfa9, 0x11c81968, 0x4e734a41, 0xb3472dca, 0x7b14a94a, 0x1b510052, 0x9a532915,
312 0xd60f573f, 0xbc9bc6e4, 0x2b60a476, 0x81e67400, 0x08ba6fb5, 0x571be91f, 0xf296ec6b, 0x2a0dd915,
313 0xb6636521, 0xe7b9f9b6, 0xff34052e, 0xc5855664, 0x53b02d5d, 0xa99f8fa1, 0x08ba4799, 0x6e85076a
314 );
315
316 /**
317 * S-Box 1
318 *
319 * @access private
320 * @var array
321 */
322 var $sbox1 = array(
323 0x4b7a70e9, 0xb5b32944, 0xdb75092e, 0xc4192623, 0xad6ea6b0, 0x49a7df7d, 0x9cee60b8, 0x8fedb266,
324 0xecaa8c71, 0x699a17ff, 0x5664526c, 0xc2b19ee1, 0x193602a5, 0x75094c29, 0xa0591340, 0xe4183a3e,
325 0x3f54989a, 0x5b429d65, 0x6b8fe4d6, 0x99f73fd6, 0xa1d29c07, 0xefe830f5, 0x4d2d38e6, 0xf0255dc1,
326 0x4cdd2086, 0x8470eb26, 0x6382e9c6, 0x021ecc5e, 0x09686b3f, 0x3ebaefc9, 0x3c971814, 0x6b6a70a1,
327 0x687f3584, 0x52a0e286, 0xb79c5305, 0xaa500737, 0x3e07841c, 0x7fdeae5c, 0x8e7d44ec, 0x5716f2b8,
328 0xb03ada37, 0xf0500c0d, 0xf01c1f04, 0x0200b3ff, 0xae0cf51a, 0x3cb574b2, 0x25837a58, 0xdc0921bd,
329 0xd19113f9, 0x7ca92ff6, 0x94324773, 0x22f54701, 0x3ae5e581, 0x37c2dadc, 0xc8b57634, 0x9af3dda7,
330 0xa9446146, 0x0fd0030e, 0xecc8c73e, 0xa4751e41, 0xe238cd99, 0x3bea0e2f, 0x3280bba1, 0x183eb331,
331 0x4e548b38, 0x4f6db908, 0x6f420d03, 0xf60a04bf, 0x2cb81290, 0x24977c79, 0x5679b072, 0xbcaf89af,
332 0xde9a771f, 0xd9930810, 0xb38bae12, 0xdccf3f2e, 0x5512721f, 0x2e6b7124, 0x501adde6, 0x9f84cd87,
333 0x7a584718, 0x7408da17, 0xbc9f9abc, 0xe94b7d8c, 0xec7aec3a, 0xdb851dfa, 0x63094366, 0xc464c3d2,
334 0xef1c1847, 0x3215d908, 0xdd433b37, 0x24c2ba16, 0x12a14d43, 0x2a65c451, 0x50940002, 0x133ae4dd,
335 0x71dff89e, 0x10314e55, 0x81ac77d6, 0x5f11199b, 0x043556f1, 0xd7a3c76b, 0x3c11183b, 0x5924a509,
336 0xf28fe6ed, 0x97f1fbfa, 0x9ebabf2c, 0x1e153c6e, 0x86e34570, 0xeae96fb1, 0x860e5e0a, 0x5a3e2ab3,
337 0x771fe71c, 0x4e3d06fa, 0x2965dcb9, 0x99e71d0f, 0x803e89d6, 0x5266c825, 0x2e4cc978, 0x9c10b36a,
338 0xc6150eba, 0x94e2ea78, 0xa5fc3c53, 0x1e0a2df4, 0xf2f74ea7, 0x361d2b3d, 0x1939260f, 0x19c27960,
339 0x5223a708, 0xf71312b6, 0xebadfe6e, 0xeac31f66, 0xe3bc4595, 0xa67bc883, 0xb17f37d1, 0x018cff28,
340 0xc332ddef, 0xbe6c5aa5, 0x65582185, 0x68ab9802, 0xeecea50f, 0xdb2f953b, 0x2aef7dad, 0x5b6e2f84,
341 0x1521b628, 0x29076170, 0xecdd4775, 0x619f1510, 0x13cca830, 0xeb61bd96, 0x0334fe1e, 0xaa0363cf,
342 0xb5735c90, 0x4c70a239, 0xd59e9e0b, 0xcbaade14, 0xeecc86bc, 0x60622ca7, 0x9cab5cab, 0xb2f3846e,
343 0x648b1eaf, 0x19bdf0ca, 0xa02369b9, 0x655abb50, 0x40685a32, 0x3c2ab4b3, 0x319ee9d5, 0xc021b8f7,
344 0x9b540b19, 0x875fa099, 0x95f7997e, 0x623d7da8, 0xf837889a, 0x97e32d77, 0x11ed935f, 0x16681281,
345 0x0e358829, 0xc7e61fd6, 0x96dedfa1, 0x7858ba99, 0x57f584a5, 0x1b227263, 0x9b83c3ff, 0x1ac24696,
346 0xcdb30aeb, 0x532e3054, 0x8fd948e4, 0x6dbc3128, 0x58ebf2ef, 0x34c6ffea, 0xfe28ed61, 0xee7c3c73,
347 0x5d4a14d9, 0xe864b7e3, 0x42105d14, 0x203e13e0, 0x45eee2b6, 0xa3aaabea, 0xdb6c4f15, 0xfacb4fd0,
348 0xc742f442, 0xef6abbb5, 0x654f3b1d, 0x41cd2105, 0xd81e799e, 0x86854dc7, 0xe44b476a, 0x3d816250,
349 0xcf62a1f2, 0x5b8d2646, 0xfc8883a0, 0xc1c7b6a3, 0x7f1524c3, 0x69cb7492, 0x47848a0b, 0x5692b285,
350 0x095bbf00, 0xad19489d, 0x1462b174, 0x23820e00, 0x58428d2a, 0x0c55f5ea, 0x1dadf43e, 0x233f7061,
351 0x3372f092, 0x8d937e41, 0xd65fecf1, 0x6c223bdb, 0x7cde3759, 0xcbee7460, 0x4085f2a7, 0xce77326e,
352 0xa6078084, 0x19f8509e, 0xe8efd855, 0x61d99735, 0xa969a7aa, 0xc50c06c2, 0x5a04abfc, 0x800bcadc,
353 0x9e447a2e, 0xc3453484, 0xfdd56705, 0x0e1e9ec9, 0xdb73dbd3, 0x105588cd, 0x675fda79, 0xe3674340,
354 0xc5c43465, 0x713e38d8, 0x3d28f89e, 0xf16dff20, 0x153e21e7, 0x8fb03d4a, 0xe6e39f2b, 0xdb83adf7
355 );
356
357 /**
358 * S-Box 2
359 *
360 * @access private
361 * @var array
362 */
363 var $sbox2 = array(
364 0xe93d5a68, 0x948140f7, 0xf64c261c, 0x94692934, 0x411520f7, 0x7602d4f7, 0xbcf46b2e, 0xd4a20068,
365 0xd4082471, 0x3320f46a, 0x43b7d4b7, 0x500061af, 0x1e39f62e, 0x97244546, 0x14214f74, 0xbf8b8840,
366 0x4d95fc1d, 0x96b591af, 0x70f4ddd3, 0x66a02f45, 0xbfbc09ec, 0x03bd9785, 0x7fac6dd0, 0x31cb8504,
367 0x96eb27b3, 0x55fd3941, 0xda2547e6, 0xabca0a9a, 0x28507825, 0x530429f4, 0x0a2c86da, 0xe9b66dfb,
368 0x68dc1462, 0xd7486900, 0x680ec0a4, 0x27a18dee, 0x4f3ffea2, 0xe887ad8c, 0xb58ce006, 0x7af4d6b6,
369 0xaace1e7c, 0xd3375fec, 0xce78a399, 0x406b2a42, 0x20fe9e35, 0xd9f385b9, 0xee39d7ab, 0x3b124e8b,
370 0x1dc9faf7, 0x4b6d1856, 0x26a36631, 0xeae397b2, 0x3a6efa74, 0xdd5b4332, 0x6841e7f7, 0xca7820fb,
371 0xfb0af54e, 0xd8feb397, 0x454056ac, 0xba489527, 0x55533a3a, 0x20838d87, 0xfe6ba9b7, 0xd096954b,
372 0x55a867bc, 0xa1159a58, 0xcca92963, 0x99e1db33, 0xa62a4a56, 0x3f3125f9, 0x5ef47e1c, 0x9029317c,
373 0xfdf8e802, 0x04272f70, 0x80bb155c, 0x05282ce3, 0x95c11548, 0xe4c66d22, 0x48c1133f, 0xc70f86dc,
374 0x07f9c9ee, 0x41041f0f, 0x404779a4, 0x5d886e17, 0x325f51eb, 0xd59bc0d1, 0xf2bcc18f, 0x41113564,
375 0x257b7834, 0x602a9c60, 0xdff8e8a3, 0x1f636c1b, 0x0e12b4c2, 0x02e1329e, 0xaf664fd1, 0xcad18115,
376 0x6b2395e0, 0x333e92e1, 0x3b240b62, 0xeebeb922, 0x85b2a20e, 0xe6ba0d99, 0xde720c8c, 0x2da2f728,
377 0xd0127845, 0x95b794fd, 0x647d0862, 0xe7ccf5f0, 0x5449a36f, 0x877d48fa, 0xc39dfd27, 0xf33e8d1e,
378 0x0a476341, 0x992eff74, 0x3a6f6eab, 0xf4f8fd37, 0xa812dc60, 0xa1ebddf8, 0x991be14c, 0xdb6e6b0d,
379 0xc67b5510, 0x6d672c37, 0x2765d43b, 0xdcd0e804, 0xf1290dc7, 0xcc00ffa3, 0xb5390f92, 0x690fed0b,
380 0x667b9ffb, 0xcedb7d9c, 0xa091cf0b, 0xd9155ea3, 0xbb132f88, 0x515bad24, 0x7b9479bf, 0x763bd6eb,
381 0x37392eb3, 0xcc115979, 0x8026e297, 0xf42e312d, 0x6842ada7, 0xc66a2b3b, 0x12754ccc, 0x782ef11c,
382 0x6a124237, 0xb79251e7, 0x06a1bbe6, 0x4bfb6350, 0x1a6b1018, 0x11caedfa, 0x3d25bdd8, 0xe2e1c3c9,
383 0x44421659, 0x0a121386, 0xd90cec6e, 0xd5abea2a, 0x64af674e, 0xda86a85f, 0xbebfe988, 0x64e4c3fe,
384 0x9dbc8057, 0xf0f7c086, 0x60787bf8, 0x6003604d, 0xd1fd8346, 0xf6381fb0, 0x7745ae04, 0xd736fccc,
385 0x83426b33, 0xf01eab71, 0xb0804187, 0x3c005e5f, 0x77a057be, 0xbde8ae24, 0x55464299, 0xbf582e61,
386 0x4e58f48f, 0xf2ddfda2, 0xf474ef38, 0x8789bdc2, 0x5366f9c3, 0xc8b38e74, 0xb475f255, 0x46fcd9b9,
387 0x7aeb2661, 0x8b1ddf84, 0x846a0e79, 0x915f95e2, 0x466e598e, 0x20b45770, 0x8cd55591, 0xc902de4c,
388 0xb90bace1, 0xbb8205d0, 0x11a86248, 0x7574a99e, 0xb77f19b6, 0xe0a9dc09, 0x662d09a1, 0xc4324633,
389 0xe85a1f02, 0x09f0be8c, 0x4a99a025, 0x1d6efe10, 0x1ab93d1d, 0x0ba5a4df, 0xa186f20f, 0x2868f169,
390 0xdcb7da83, 0x573906fe, 0xa1e2ce9b, 0x4fcd7f52, 0x50115e01, 0xa70683fa, 0xa002b5c4, 0x0de6d027,
391 0x9af88c27, 0x773f8641, 0xc3604c06, 0x61a806b5, 0xf0177a28, 0xc0f586e0, 0x006058aa, 0x30dc7d62,
392 0x11e69ed7, 0x2338ea63, 0x53c2dd94, 0xc2c21634, 0xbbcbee56, 0x90bcb6de, 0xebfc7da1, 0xce591d76,
393 0x6f05e409, 0x4b7c0188, 0x39720a3d, 0x7c927c24, 0x86e3725f, 0x724d9db9, 0x1ac15bb4, 0xd39eb8fc,
394 0xed545578, 0x08fca5b5, 0xd83d7cd3, 0x4dad0fc4, 0x1e50ef5e, 0xb161e6f8, 0xa28514d9, 0x6c51133c,
395 0x6fd5c7e7, 0x56e14ec4, 0x362abfce, 0xddc6c837, 0xd79a3234, 0x92638212, 0x670efa8e, 0x406000e0
396 );
397
398 /**
399 * S-Box 3
400 *
401 * @access private
402 * @var array
403 */
404 var $sbox3 = array(
405 0x3a39ce37, 0xd3faf5cf, 0xabc27737, 0x5ac52d1b, 0x5cb0679e, 0x4fa33742, 0xd3822740, 0x99bc9bbe,
406 0xd5118e9d, 0xbf0f7315, 0xd62d1c7e, 0xc700c47b, 0xb78c1b6b, 0x21a19045, 0xb26eb1be, 0x6a366eb4,
407 0x5748ab2f, 0xbc946e79, 0xc6a376d2, 0x6549c2c8, 0x530ff8ee, 0x468dde7d, 0xd5730a1d, 0x4cd04dc6,
408 0x2939bbdb, 0xa9ba4650, 0xac9526e8, 0xbe5ee304, 0xa1fad5f0, 0x6a2d519a, 0x63ef8ce2, 0x9a86ee22,
409 0xc089c2b8, 0x43242ef6, 0xa51e03aa, 0x9cf2d0a4, 0x83c061ba, 0x9be96a4d, 0x8fe51550, 0xba645bd6,
410 0x2826a2f9, 0xa73a3ae1, 0x4ba99586, 0xef5562e9, 0xc72fefd3, 0xf752f7da, 0x3f046f69, 0x77fa0a59,
411 0x80e4a915, 0x87b08601, 0x9b09e6ad, 0x3b3ee593, 0xe990fd5a, 0x9e34d797, 0x2cf0b7d9, 0x022b8b51,
412 0x96d5ac3a, 0x017da67d, 0xd1cf3ed6, 0x7c7d2d28, 0x1f9f25cf, 0xadf2b89b, 0x5ad6b472, 0x5a88f54c,
413 0xe029ac71, 0xe019a5e6, 0x47b0acfd, 0xed93fa9b, 0xe8d3c48d, 0x283b57cc, 0xf8d56629, 0x79132e28,
414 0x785f0191, 0xed756055, 0xf7960e44, 0xe3d35e8c, 0x15056dd4, 0x88f46dba, 0x03a16125, 0x0564f0bd,
415 0xc3eb9e15, 0x3c9057a2, 0x97271aec, 0xa93a072a, 0x1b3f6d9b, 0x1e6321f5, 0xf59c66fb, 0x26dcf319,
416 0x7533d928, 0xb155fdf5, 0x03563482, 0x8aba3cbb, 0x28517711, 0xc20ad9f8, 0xabcc5167, 0xccad925f,
417 0x4de81751, 0x3830dc8e, 0x379d5862, 0x9320f991, 0xea7a90c2, 0xfb3e7bce, 0x5121ce64, 0x774fbe32,
418 0xa8b6e37e, 0xc3293d46, 0x48de5369, 0x6413e680, 0xa2ae0810, 0xdd6db224, 0x69852dfd, 0x09072166,
419 0xb39a460a, 0x6445c0dd, 0x586cdecf, 0x1c20c8ae, 0x5bbef7dd, 0x1b588d40, 0xccd2017f, 0x6bb4e3bb,
420 0xdda26a7e, 0x3a59ff45, 0x3e350a44, 0xbcb4cdd5, 0x72eacea8, 0xfa6484bb, 0x8d6612ae, 0xbf3c6f47,
421 0xd29be463, 0x542f5d9e, 0xaec2771b, 0xf64e6370, 0x740e0d8d, 0xe75b1357, 0xf8721671, 0xaf537d5d,
422 0x4040cb08, 0x4eb4e2cc, 0x34d2466a, 0x0115af84, 0xe1b00428, 0x95983a1d, 0x06b89fb4, 0xce6ea048,
423 0x6f3f3b82, 0x3520ab82, 0x011a1d4b, 0x277227f8, 0x611560b1, 0xe7933fdc, 0xbb3a792b, 0x344525bd,
424 0xa08839e1, 0x51ce794b, 0x2f32c9b7, 0xa01fbac9, 0xe01cc87e, 0xbcc7d1f6, 0xcf0111c3, 0xa1e8aac7,
425 0x1a908749, 0xd44fbd9a, 0xd0dadecb, 0xd50ada38, 0x0339c32a, 0xc6913667, 0x8df9317c, 0xe0b12b4f,
426 0xf79e59b7, 0x43f5bb3a, 0xf2d519ff, 0x27d9459c, 0xbf97222c, 0x15e6fc2a, 0x0f91fc71, 0x9b941525,
427 0xfae59361, 0xceb69ceb, 0xc2a86459, 0x12baa8d1, 0xb6c1075e, 0xe3056a0c, 0x10d25065, 0xcb03a442,
428 0xe0ec6e0e, 0x1698db3b, 0x4c98a0be, 0x3278e964, 0x9f1f9532, 0xe0d392df, 0xd3a0342b, 0x8971f21e,
429 0x1b0a7441, 0x4ba3348c, 0xc5be7120, 0xc37632d8, 0xdf359f8d, 0x9b992f2e, 0xe60b6f47, 0x0fe3f11d,
430 0xe54cda54, 0x1edad891, 0xce6279cf, 0xcd3e7e6f, 0x1618b166, 0xfd2c1d05, 0x848fd2c5, 0xf6fb2299,
431 0xf523f357, 0xa6327623, 0x93a83531, 0x56cccd02, 0xacf08162, 0x5a75ebb5, 0x6e163697, 0x88d273cc,
432 0xde966292, 0x81b949d0, 0x4c50901b, 0x71c65614, 0xe6c6c7bd, 0x327a140a, 0x45e1d006, 0xc3f27b9a,
433 0xc9aa53fd, 0x62a80f00, 0xbb25bfe2, 0x35bdd2f6, 0x71126905, 0xb2040222, 0xb6cbcf7c, 0xcd769c2b,
434 0x53113ec0, 0x1640e3d3, 0x38abbd60, 0x2547adf0, 0xba38209c, 0xf746ce76, 0x77afa1c5, 0x20756060,
435 0x85cbfe4e, 0x8ae88dd8, 0x7aaaf9b0, 0x4cf9aa7e, 0x1948c25c, 0x02fb8a8c, 0x01c36ae4, 0xd6ebe1f9,
436 0x90d4f869, 0xa65cdea0, 0x3f09252d, 0xc208e69f, 0xb74e6132, 0xce77e25b, 0x578fdfe3, 0x3ac372e6
437 );
438
439 /**
440 * P-Array consists of 18 32-bit subkeys
441 *
442 * @var array $parray
443 * @access private
444 */
445 var $parray = array(
446 0x243f6a88, 0x85a308d3, 0x13198a2e, 0x03707344, 0xa4093822, 0x299f31d0,
447 0x082efa98, 0xec4e6c89, 0x452821e6, 0x38d01377, 0xbe5466cf, 0x34e90c6c,
448 0xc0ac29b7, 0xc97c50dd, 0x3f84d5b5, 0xb5470917, 0x9216d5d9, 0x8979fb1b
449 );
450
451 /**
452 * The BCTX-working Array
453 *
454 * Holds the expanded key [p] and the key-depended s-boxes [sb]
455 *
456 * @var array $bctx
457 * @access private
458 */
459 var $bctx = array();
460
461 /**
462 * Default Constructor.
463 *
464 * Determines whether or not the mcrypt extension should be used.
465 * If not explictly set, CRYPT_BLOWFISH_MODE_CBC will be used.
466 *
467 * @param optional Integer $mode
468 * @access public
469 */
470 function Crypt_Blowfish($mode = CRYPT_BLOWFISH_MODE_CBC)
471 {
472 if ( !defined('CRYPT_BLOWFISH_MODE') ) {
473 switch (true) {
474 case extension_loaded('mcrypt') && in_array('blowfish', mcrypt_list_algorithms()):
475 define('CRYPT_BLOWFISH_MODE', CRYPT_BLOWFISH_MODE_MCRYPT);
476 break;
477 default:
478 define('CRYPT_BLOWFISH_MODE', CRYPT_BLOWFISH_MODE_INTERNAL);
479 }
480 }
481
482 switch ( CRYPT_BLOWFISH_MODE ) {
483 case CRYPT_BLOWFISH_MODE_MCRYPT:
484 switch ($mode) {
485 case CRYPT_BLOWFISH_MODE_ECB:
486 $this->paddable = true;
487 $this->mode = MCRYPT_MODE_ECB;
488 break;
489 case CRYPT_BLOWFISH_MODE_CTR:
490 $this->mode = 'ctr';
491 break;
492 case CRYPT_BLOWFISH_MODE_CFB:
493 $this->mode = 'ncfb';
494 $this->ecb = mcrypt_module_open(MCRYPT_BLOWFISH, '', MCRYPT_MODE_ECB, '');
495 break;
496 case CRYPT_BLOWFISH_MODE_OFB:
497 $this->mode = MCRYPT_MODE_NOFB;
498 break;
499 case CRYPT_BLOWFISH_MODE_CBC:
500 default:
501 $this->paddable = true;
502 $this->mode = MCRYPT_MODE_CBC;
503 }
504 $this->enmcrypt = mcrypt_module_open(MCRYPT_BLOWFISH, '', $this->mode, '');
505 $this->demcrypt = mcrypt_module_open(MCRYPT_BLOWFISH, '', $this->mode, '');
506
507 break;
508 default:
509 switch ($mode) {
510 case CRYPT_BLOWFISH_MODE_ECB:
511 case CRYPT_BLOWFISH_MODE_CBC:
512 $this->paddable = true;
513 $this->mode = $mode;
514 break;
515 case CRYPT_BLOWFISH_MODE_CTR:
516 case CRYPT_BLOWFISH_MODE_CFB:
517 case CRYPT_BLOWFISH_MODE_OFB:
518 $this->mode = $mode;
519 break;
520 default:
521 $this->paddable = true;
522 $this->mode = CRYPT_BLOWFISH_MODE_CBC;
523 }
524 $this->inline_crypt_setup();
525 }
526 }
527
528 /**
529 * Sets the key.
530 *
531 * Keys can be of any length. Blowfish, itself, requires the use of a key between 32 and max. 448-bits long.
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
533 * with mcrypt because mcrypt act this way with blowfish key's < 32 bits.
534 *
535 * If the key is more than 448-bits, we trim the excess bits.
536 *
537 * If the key is not explicitly set, or empty, it'll be assumed a 128 bits key to be all null bytes.
538 *
539 * @access public
540 * @param String $key
541 */
542 function setKey($key)
543 {
544 $keylength = strlen($key);
545
546 if (!$keylength) {
547 $key = "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0";
548 }
549 elseif ($keylength > 56) {
550 $key = substr($key, 0, 56);
551 }
552
553 $this->key = $key;
554
555 $this->enchanged = true;
556 $this->dechanged = true;
557
558 if (CRYPT_BLOWFISH_MODE == CRYPT_BLOWFISH_MODE_MCRYPT) {
559 return;
560 }
561
562 /* key-expanding p[] and S-Box building sb[] */
563 $this->bctx = array(
564 'p' => array(),
565 'sb' => array(
566 $this->sbox0,
567 $this->sbox1,
568 $this->sbox2,
569 $this->sbox3
570 )
571 );
572
573 // unpack binary string in unsigned chars
574 $key = array_values(unpack('C*', $key));
575 $keyl = count($key);
576 for ($j = 0, $i = 0; $i < 18; ++$i) {
577 // xor P1 with the first 32-bits of the key, xor P2 with the second 32-bits ...
578 for ($data = 0, $k = 0; $k < 4; ++$k) {
579 $data = ($data << 8) | $key[$j];
580 if (++$j >= $keyl) {
581 $j = 0;
582 }
583 }
584 $this->bctx['p'][] = $this->parray[$i] ^ $data;
585 }
586
587 // encrypt the zero-string, replace P1 and P2 with the encrypted data,
588 // encrypt P3 and P4 with the new P1 and P2, do it with all P-array and subkeys
589 $datal = 0;
590 $datar = 0;
591 for ($i = 0; $i < 18; $i += 2) {
592 $this->_encryptBlock($datal, $datar);
593 $this->bctx['p'][$i ] = $datal;
594 $this->bctx['p'][$i + 1] = $datar;
595 }
596 for ($i = 0; $i < 4; ++$i) {
597 for ($j = 0; $j < 256; $j += 2) {
598 $this->_encryptBlock($datal, $datar);
599 $this->bctx['sb'][$i][$j ] = $datal;
600 $this->bctx['sb'][$i][$j + 1] = $datar;
601 }
602 }
603 }
604
605 /**
606 * Encrypt the block.
607 *
608 * @access private
609 * @param int $Xl left uInt32 part of the block
610 * @param int $Xr right uInt32 part of the block
611 * @return void
612 */
613 function _encryptBlock(&$Xl, &$Xr)
614 {
615 $p = $this->bctx['p'];
616 $sb_0 = $this->bctx['sb'][0];
617 $sb_1 = $this->bctx['sb'][1];
618 $sb_2 = $this->bctx['sb'][2];
619 $sb_3 = $this->bctx['sb'][3];
620 $l = $Xl;
621 $r = $Xr;
622
623 $i = -1;
624 while ($i < 15) {
625 $l^= $p[++$i];
626 $r^= ($sb_0[$l >> 24 & 0xff] +
627 $sb_1[$l >> 16 & 0xff] ^
628 $sb_2[$l >> 8 & 0xff]) +
629 $sb_3[$l & 0xff];
630
631 $r^= $p[++$i];
632 $l^= ($sb_0[$r >> 24 & 0xff] +
633 $sb_1[$r >> 16 & 0xff] ^
634 $sb_2[$r >> 8 & 0xff]) +
635 $sb_3[$r & 0xff];
636
637 }
638 $Xr = $l ^ $p[16];
639 $Xl = $r ^ $p[17];
640 }
641
642 /**
643 * Sets the password.
644 *
645 * Depending on what $method is set to, setPassword()'s (optional) parameters are as follows:
646 * {@link http://en.wikipedia.org/wiki/PBKDF2 pbkdf2}:
647 * $hash, $salt, $count
648 *
649 * @param String $password
650 * @param optional String $method
651 * @access public
652 */
653 function setPassword($password, $method = 'pbkdf2')
654 {
655 $key = '';
656
657 switch ($method) {
658 default: // 'pbkdf2'
659 list(, , $hash, $salt, $count) = func_get_args();
660 if (!isset($hash)) {
661 $hash = 'sha1';
662 }
663 // WPA and WPA2 use the SSID as the salt
664 if (!isset($salt)) {
665 $salt = 'phpseclib/salt';
666 }
667 // RFC2898#section-4.2 uses 1,000 iterations by default
668 // WPA and WPA2 use 4,096.
669 if (!isset($count)) {
670 $count = 1000;
671 }
672
673 if (!class_exists('Crypt_Hash')) {
674 require_once('Crypt/Hash.php');
675 }
676
677 $i = 1;
678 while (strlen($key) < 56) {
679 //$dk.= $this->_pbkdf($password, $salt, $count, $i++);
680 $hmac = new Crypt_Hash();
681 $hmac->setHash($hash);
682 $hmac->setKey($password);
683 $f = $u = $hmac->hash($salt . pack('N', $i++));
684 for ($j = 2; $j <= $count; $j++) {
685 $u = $hmac->hash($u);
686 $f^= $u;
687 }
688 $key.= $f;
689 }
690 }
691
692 $this->setKey($key);
693 }
694
695 /**
696 * Sets the initialization vector. (optional)
697 *
698 * SetIV is not required when CRYPT_BLOWFISH_MODE_ECB is being used. If not explictly set, it'll be assumed
699 * to be all null bytes.
700 *
701 * @access public
702 * @param String $iv
703 */
704 function setIV($iv)
705 {
706 $this->encryptIV = $this->decryptIV = $this->iv = str_pad(substr($iv, 0, 8), 8, chr(0));
707 $this->enchanged = true;
708 $this->dechanged = true;
709 }
710
711 /**
712 * Encrypts a message.
713 *
714 * $plaintext will be padded with up to 8 additional bytes. Other Blowfish implementations may or may not pad in the
715 * same manner. Other common approaches to padding and the reasons why it's necessary are discussed in the following
716 * URL:
717 *
718 * {@link http://www.di-mgt.com.au/cryptopad.html http://www.di-mgt.com.au/cryptopad.html}
719 *
720 * An alternative to padding is to, separately, send the length of the file. This is what SSH, in fact, does.
721 * strlen($plaintext) will still need to be a multiple of 8, however, arbitrary values can be added to make it that
722 * length.
723 *
724 * @see Crypt_Blowfish::decrypt()
725 * @access public
726 * @param String $plaintext
727 */
728 function encrypt($plaintext)
729 {
730 if ( CRYPT_BLOWFISH_MODE == CRYPT_BLOWFISH_MODE_MCRYPT ) {
731 if ($this->paddable) {
732 $plaintext = $this->_pad($plaintext);
733 }
734
735 if ($this->enchanged) {
736 mcrypt_generic_init($this->enmcrypt, $this->key, $this->encryptIV);
737 if ($this->mode == 'ncfb') {
738 mcrypt_generic_init($this->ecb, $this->key, "\0\0\0\0\0\0\0\0");
739 }
740 $this->enchanged = false;
741 }
742
743 if ($this->mode != 'ncfb' || !$this->continuousBuffer) {
744 $ciphertext = mcrypt_generic($this->enmcrypt, $plaintext);
745 } else {
746 $iv = &$this->encryptIV;
747 $pos = &$this->enbuffer['pos'];
748 $len = strlen($plaintext);
749 $ciphertext = '';
750 $i = 0;
751 if ($pos) {
752 $orig_pos = $pos;
753 $max = 8 - $pos;
754 if ($len >= $max) {
755 $i = $max;
756 $len-= $max;
757 $pos = 0;
758 } else {
759 $i = $len;
760 $pos+= $len;
761 $len = 0;
762 }
763 $ciphertext = substr($iv, $orig_pos) ^ $plaintext;
764 $iv = substr_replace($iv, $ciphertext, $orig_pos, $i);
765 $this->enbuffer['enmcrypt_init'] = true;
766 }
767 if ($len >= 8) {
768 if ($this->enbuffer['enmcrypt_init'] === false || $len > 600) {
769 if ($this->enbuffer['enmcrypt_init'] === true) {
770 mcrypt_generic_init($this->enmcrypt, $this->key, $iv);
771 $this->enbuffer['enmcrypt_init'] = false;
772 }
773 $ciphertext.= mcrypt_generic($this->enmcrypt, substr($plaintext, $i, $len - $len % 8));
774 $iv = substr($ciphertext, -8);
775 $len%= 8;
776 } else {
777 while ($len >= 8) {
778 $iv = mcrypt_generic($this->ecb, $iv) ^ substr($plaintext, $i, 8);
779 $ciphertext.= $iv;
780 $len-= 8;
781 $i+= 8;
782 }
783 }
784 }
785 if ($len) {
786 $iv = mcrypt_generic($this->ecb, $iv);
787 $block = $iv ^ substr($plaintext, -$len);
788 $iv = substr_replace($iv, $block, 0, $len);
789 $ciphertext.= $block;
790 $pos = $len;
791 }
792 return $ciphertext;
793 }
794
795 if (!$this->continuousBuffer) {
796 mcrypt_generic_init($this->enmcrypt, $this->key, $this->encryptIV);
797 }
798
799 return $ciphertext;
800 }
801
802 if (empty($this->bctx)) {
803 $this->setKey($this->key);
804 }
805
806 $inline = $this->inline_crypt;
807 return $inline('encrypt', $this, $plaintext);
808 }
809
810 /**
811 * Decrypts a message.
812 *
813 * If strlen($ciphertext) is not a multiple of 8, null bytes will be added to the end of the string until it is.
814 *
815 * @see Crypt_Blowfish::encrypt()
816 * @access public
817 * @param String $ciphertext
818 */
819 function decrypt($ciphertext)
820 {
821 if ( CRYPT_BLOWFISH_MODE == CRYPT_BLOWFISH_MODE_MCRYPT ) {
822 if ($this->paddable) {
823 // we pad with chr(0) since that's what mcrypt_generic does. to quote from http://php.net/function.mcrypt-generic :
824 // "The data is padded with "\0" to make sure the length of the data is n * blocksize."
825 $ciphertext = str_pad($ciphertext, strlen($ciphertext) + (8 - strlen($ciphertext) % 8) % 8, chr(0));
826 }
827
828 if ($this->dechanged) {
829 mcrypt_generic_init($this->demcrypt, $this->key, $this->decryptIV);
830 if ($this->mode == 'ncfb') {
831 mcrypt_generic_init($this->ecb, $this->key, "\0\0\0\0\0\0\0\0");
832 }
833 $this->dechanged = false;
834 }
835
836 if ($this->mode != 'ncfb' || !$this->continuousBuffer) {
837 $plaintext = mdecrypt_generic($this->demcrypt, $ciphertext);
838 } else {
839 $iv = &$this->decryptIV;
840 $pos = &$this->debuffer['pos'];
841 $len = strlen($ciphertext);
842 $plaintext = '';
843 $i = 0;
844 if ($pos) {
845 $orig_pos = $pos;
846 $max = 8 - $pos;
847 if ($len >= $max) {
848 $i = $max;
849 $len-= $max;
850 $pos = 0;
851 } else {
852 $i = $len;
853 $pos+= $len;
854 $len = 0;
855 }
856 $plaintext = substr($iv, $orig_pos) ^ $ciphertext;
857 $iv = substr_replace($iv, substr($ciphertext, 0, $i), $orig_pos, $i);
858 }
859 if ($len >= 8) {
860 $cb = substr($ciphertext, $i, $len - $len % 8);
861 $plaintext.= mcrypt_generic($this->ecb, $iv . $cb) ^ $cb;
862 $iv = substr($cb, -8);
863 $len%= 8;
864 }
865 if ($len) {
866 $iv = mcrypt_generic($this->ecb, $iv);
867 $plaintext.= $iv ^ substr($ciphertext, -$len);
868 $iv = substr_replace($iv, substr($ciphertext, -$len), 0, $len);
869 $pos = $len;
870 }
871 return $plaintext;
872 }
873
874 if (!$this->continuousBuffer) {
875 mcrypt_generic_init($this->demcrypt, $this->key, $this->decryptIV);
876 }
877
878 return $this->paddable ? $this->_unpad($plaintext) : $plaintext;
879 }
880
881 if (empty($this->bctx)) {
882 $this->setKey($this->key);
883 }
884
885 $inline = $this->inline_crypt;
886 return $inline('decrypt', $this, $ciphertext);
887 }
888
889 /**
890 * Treat consecutive "packets" as if they are a continuous buffer.
891 *
892 * @see Crypt_Blowfish::disableContinuousBuffer()
893 * @access public
894 */
895 function enableContinuousBuffer()
896 {
897 $this->continuousBuffer = true;
898 }
899
900 /**
901 * Treat consecutive packets as if they are a discontinuous buffer.
902 *
903 * The default behavior.
904 *
905 * @see Crypt_Blowfish::enableContinuousBuffer()
906 * @access public
907 */
908 function disableContinuousBuffer()
909 {
910 $this->continuousBuffer = false;
911 $this->encryptIV = $this->iv;
912 $this->decryptIV = $this->iv;
913 $this->enbuffer = array('encrypted' => '', 'xor' => '', 'pos' => 0, 'enmcrypt_init' => true);
914 $this->debuffer = array('ciphertext' => '', 'xor' => '', 'pos' => 0, 'demcrypt_init' => true);
915
916 if (CRYPT_BLOWFISH_MODE == CRYPT_BLOWFISH_MODE_MCRYPT) {
917 mcrypt_generic_init($this->enmcrypt, $this->key, $this->iv);
918 mcrypt_generic_init($this->demcrypt, $this->key, $this->iv);
919 }
920 }
921
922 /**
923 * Pad "packets".
924 *
925 * Blowfish works by encrypting 8 bytes at a time. If you ever need to encrypt or decrypt something that's not
926 * a multiple of 8, it becomes necessary to pad the input so that it's length is a multiple of eight.
927 *
928 * Padding is enabled by default. Sometimes, however, it is undesirable to pad strings. Such is the case in SSH1,
929 * where "packets" are padded with random bytes before being encrypted. Unpad these packets and you risk stripping
930 * away characters that shouldn't be stripped away. (SSH knows how many bytes are added because the length is
931 * transmitted separately)
932 *
933 * @see Crypt_Blowfish::disablePadding()
934 * @access public
935 */
936 function enablePadding()
937 {
938 $this->padding = true;
939 }
940
941 /**
942 * Do not pad packets.
943 *
944 * @see Crypt_Blowfish::enablePadding()
945 * @access public
946 */
947 function disablePadding()
948 {
949 $this->padding = false;
950 }
951
952 /**
953 * Pads a string
954 *
955 * Pads a string using the RSA PKCS padding standards so that its length is a multiple of the blocksize (8).
956 *
957 * If padding is disabled and $text is not a multiple of the blocksize, the string will be padded regardless
958 * and padding will, hence forth, be enabled.
959 *
960 * @see Crypt_Blowfish::_unpad()
961 * @access private
962 */
963 function _pad($text)
964 {
965 $length = strlen($text);
966
967 if (!$this->padding) {
968 if ($length % 8 == 0) {
969 return $text;
970 } else {
971 user_error("The plaintext's length ($length) is not a multiple of the block size (8)");
972 $this->padding = true;
973 }
974 }
975
976 $pad = 8 - ($length % 8);
977
978 return str_pad($text, $length + $pad, chr($pad));
979 }
980
981 /**
982 * Unpads a string
983 *
984 * If padding is enabled and the reported padding length is invalid the encryption key will be assumed to be wrong
985 * and false will be returned.
986 *
987 * @see Crypt_Blowfish::_pad()
988 * @access private
989 */
990 function _unpad($text)
991 {
992 if (!$this->padding) {
993 return $text;
994 }
995
996 $length = ord($text[strlen($text) - 1]);
997
998 if (!$length || $length > 8) {
999 return false;
1000 }
1001
1002 return substr($text, 0, -$length);
1003 }
1004
1005 /**
1006 * String Shift
1007 *
1008 * Inspired by array_shift
1009 *
1010 * @param String $string
1011 * @return String
1012 * @access private
1013 */
1014 function _string_shift(&$string)
1015 {
1016 $substr = substr($string, 0, 8);
1017 $string = substr($string, 8);
1018 return $substr;
1019 }
1020
1021 /**
1022 * Generate CTR XOR encryption key
1023 *
1024 * Encrypt the output of this and XOR it against the ciphertext / plaintext to get the
1025 * plaintext / ciphertext in CTR mode.
1026 *
1027 * @see Crypt_Blowfish::decrypt()
1028 * @see Crypt_Blowfish::encrypt()
1029 * @access public
1030 * @param String $iv
1031 */
1032 function _generate_xor(&$iv)
1033 {
1034 $xor = $iv;
1035 for ($j = 4; $j <= 8; $j+=4) {
1036 $temp = substr($iv, -$j, 4);
1037 switch ($temp) {
1038 case "\xFF\xFF\xFF\xFF":
1039 $iv = substr_replace($iv, "\x00\x00\x00\x00", -$j, 4);
1040 break;
1041 case "\x7F\xFF\xFF\xFF":
1042 $iv = substr_replace($iv, "\x80\x00\x00\x00", -$j, 4);
1043 break 2;
1044 default:
1045 extract(unpack('Ncount', $temp));
1046 $iv = substr_replace($iv, pack('N', $count + 1), -$j, 4);
1047 break 2;
1048 }
1049 }
1050
1051 return $xor;
1052 }
1053
1054 /**
1055 * Creates performance-optimized function for de/encrypt(), storing it in $this->inline_crypt
1056 *
1057 * @access private
1058 */
1059 function inline_crypt_setup()
1060 {/*{{{*/
1061 $lambda_functions =& Crypt_Blowfish::get_lambda_functions();
1062 $block_size = 8;
1063 $mode = $this->mode;
1064 $code_hash = "$mode";
1065
1066 if (!isset($lambda_functions[$code_hash])) {
1067 $init_cryptBlock = '
1068 extract($self->bctx["p"], EXTR_PREFIX_ALL, "p");
1069 extract($self->bctx["sb"], EXTR_PREFIX_ALL, "sb");
1070 ';
1071
1072 // Generating encrypt code:
1073 $_encryptBlock = '
1074 $in = unpack("N*", $in);
1075 $l = $in[1];
1076 $r = $in[2];
1077 ';
1078 for ($i = 0; $i < 16; $i+= 2) {
1079 $_encryptBlock.= '
1080 $l^= $p_'.($i).';
1081 $r^= ($sb_0[$l >> 24 & 0xff] +
1082 $sb_1[$l >> 16 & 0xff] ^
1083 $sb_2[$l >> 8 & 0xff]) +
1084 $sb_3[$l & 0xff];
1085
1086 $r^= $p_'.($i + 1).';
1087 $l^= ($sb_0[$r >> 24 & 0xff] +
1088 $sb_1[$r >> 16 & 0xff] ^
1089 $sb_2[$r >> 8 & 0xff]) +
1090 $sb_3[$r & 0xff];
1091 ';
1092 }
1093 $_encryptBlock.= '
1094 $in = pack("N*", $r ^ $p_17, $l ^ $p_16);
1095 ';
1096
1097 // Generating decrypt code:
1098 $_decryptBlock = '
1099 $in = unpack("N*", $in);
1100 $l = $in[1];
1101 $r = $in[2];
1102 ';
1103
1104 for ($i = 17; $i > 2; $i-= 2) {
1105 $_decryptBlock.= '
1106 $l^= $p_'.($i).';
1107 $r^= ($sb_0[$l >> 24 & 0xff] +
1108 $sb_1[$l >> 16 & 0xff] ^
1109 $sb_2[$l >> 8 & 0xff]) +
1110 $sb_3[$l & 0xff];
1111
1112 $r^= $p_'.($i - 1).';
1113 $l^= ($sb_0[$r >> 24 & 0xff] +
1114 $sb_1[$r >> 16 & 0xff] ^
1115 $sb_2[$r >> 8 & 0xff]) +
1116 $sb_3[$r & 0xff];
1117 ';
1118 }
1119
1120 $_decryptBlock.= '
1121 $in = pack("N*", $r ^ $p_0, $l ^ $p_1);
1122 ';
1123
1124 // Generating mode of operation code:
1125 switch ($mode) {
1126 case CRYPT_BLOWFISH_MODE_ECB:
1127 $encrypt = '
1128 $ciphertext = "";
1129 $text = $self->_pad($text);
1130 $plaintext_len = strlen($text);
1131
1132 for ($i = 0; $i < $plaintext_len; $i+= '.$block_size.') {
1133 $in = substr($text, $i, '.$block_size.');
1134 '.$_encryptBlock.'
1135 $ciphertext.= $in;
1136 }
1137 return $ciphertext;
1138 ';
1139
1140 $decrypt = '
1141 $plaintext = "";
1142 $text = str_pad($text, strlen($text) + ('.$block_size.' - strlen($text) % '.$block_size.') % '.$block_size.', chr(0));
1143 $ciphertext_len = strlen($text);
1144
1145 for ($i = 0; $i < $ciphertext_len; $i+= '.$block_size.') {
1146 $in = substr($text, $i, '.$block_size.');
1147 '.$_decryptBlock.'
1148 $plaintext.= $in;
1149 }
1150
1151 return $self->_unpad($plaintext);
1152 ';
1153 break;
1154 case CRYPT_BLOWFISH_MODE_CBC:
1155 $encrypt = '
1156 $ciphertext = "";
1157 $text = $self->_pad($text);
1158 $plaintext_len = strlen($text);
1159
1160 $in = $self->encryptIV;
1161
1162 for ($i = 0; $i < $plaintext_len; $i+= '.$block_size.') {
1163 $in = substr($text, $i, '.$block_size.') ^ $in;
1164 '.$_encryptBlock.'
1165 $ciphertext.= $in;
1166 }
1167
1168 if ($self->continuousBuffer) {
1169 $self->encryptIV = $in;
1170 }
1171
1172 return $ciphertext;
1173 ';
1174
1175 $decrypt = '
1176 $plaintext = "";
1177 $text = str_pad($text, strlen($text) + ('.$block_size.' - strlen($text) % '.$block_size.') % '.$block_size.', chr(0));
1178 $ciphertext_len = strlen($text);
1179
1180 $iv = $self->decryptIV;
1181
1182 for ($i = 0; $i < $ciphertext_len; $i+= '.$block_size.') {
1183 $in = $block = substr($text, $i, '.$block_size.');
1184 '.$_decryptBlock.'
1185 $plaintext.= $in ^ $iv;
1186 $iv = $block;
1187 }
1188
1189 if ($self->continuousBuffer) {
1190 $self->decryptIV = $iv;
1191 }
1192
1193 return $self->_unpad($plaintext);
1194 ';
1195 break;
1196 case CRYPT_BLOWFISH_MODE_CTR:
1197 $encrypt = '
1198 $ciphertext = "";
1199 $plaintext_len = strlen($text);
1200 $xor = $self->encryptIV;
1201 $buffer = &$self->enbuffer;
1202
1203 if (strlen($buffer["encrypted"])) {
1204 for ($i = 0; $i < $plaintext_len; $i+= '.$block_size.') {
1205 $block = substr($text, $i, '.$block_size.');
1206 if (strlen($block) > strlen($buffer["encrypted"])) {
1207 $in = $self->_generate_xor($xor);
1208 '.$_encryptBlock.'
1209 $buffer["encrypted"].= $in;
1210 }
1211 $key = $self->_string_shift($buffer["encrypted"]);
1212 $ciphertext.= $block ^ $key;
1213 }
1214 } else {
1215 for ($i = 0; $i < $plaintext_len; $i+= '.$block_size.') {
1216 $block = substr($text, $i, '.$block_size.');
1217 $in = $self->_generate_xor($xor);
1218 '.$_encryptBlock.'
1219 $key = $in;
1220 $ciphertext.= $block ^ $key;
1221 }
1222 }
1223 if ($self->continuousBuffer) {
1224 $self->encryptIV = $xor;
1225 if ($start = $plaintext_len % '.$block_size.') {
1226 $buffer["encrypted"] = substr($key, $start) . $buffer["encrypted"];
1227 }
1228 }
1229
1230 return $ciphertext;
1231 ';
1232
1233 $decrypt = '
1234 $plaintext = "";
1235 $ciphertext_len = strlen($text);
1236 $xor = $self->decryptIV;
1237 $buffer = &$self->debuffer;
1238
1239 if (strlen($buffer["ciphertext"])) {
1240 for ($i = 0; $i < $ciphertext_len; $i+= '.$block_size.') {
1241 $block = substr($text, $i, '.$block_size.');
1242 if (strlen($block) > strlen($buffer["ciphertext"])) {
1243 $in = $self->_generate_xor($xor);
1244 '.$_encryptBlock.'
1245 $buffer["ciphertext"].= $in;
1246 }
1247 $key = $self->_string_shift($buffer["ciphertext"]);
1248 $plaintext.= $block ^ $key;
1249 }
1250 } else {
1251 for ($i = 0; $i < $ciphertext_len; $i+= '.$block_size.') {
1252 $block = substr($text, $i, '.$block_size.');
1253 $in = $self->_generate_xor($xor);
1254 '.$_encryptBlock.'
1255 $key = $in;
1256 $plaintext.= $block ^ $key;
1257 }
1258 }
1259 if ($self->continuousBuffer) {
1260 $self->decryptIV = $xor;
1261 if ($start = $ciphertext_len % '.$block_size.') {
1262 $buffer["ciphertext"] = substr($key, $start) . $buffer["ciphertext"];
1263 }
1264 }
1265 return $plaintext;
1266 ';
1267 break;
1268 case CRYPT_BLOWFISH_MODE_CFB:
1269 $encrypt = '
1270 $ciphertext = "";
1271 $buffer = &$self->enbuffer;
1272
1273 if ($self->continuousBuffer) {
1274 $iv = &$self->encryptIV;
1275 $pos = &$buffer["pos"];
1276 } else {
1277 $iv = $self->encryptIV;
1278 $pos = 0;
1279 }
1280 $len = strlen($text);
1281 $i = 0;
1282 if ($pos) {
1283 $orig_pos = $pos;
1284 $max = '.$block_size.' - $pos;
1285 if ($len >= $max) {
1286 $i = $max;
1287 $len-= $max;
1288 $pos = 0;
1289 } else {
1290 $i = $len;
1291 $pos+= $len;
1292 $len = 0;
1293 }
1294 $ciphertext = substr($iv, $orig_pos) ^ $text;
1295 $iv = substr_replace($iv, $ciphertext, $orig_pos, $i);
1296 }
1297 while ($len >= '.$block_size.') {
1298 $in = $iv;
1299 '.$_encryptBlock.';
1300 $iv = $in ^ substr($text, $i, '.$block_size.');
1301 $ciphertext.= $iv;
1302 $len-= '.$block_size.';
1303 $i+= '.$block_size.';
1304 }
1305 if ($len) {
1306 $in = $iv;
1307 '.$_encryptBlock.'
1308 $iv = $in;
1309 $block = $iv ^ substr($text, $i);
1310 $iv = substr_replace($iv, $block, 0, $len);
1311 $ciphertext.= $block;
1312 $pos = $len;
1313 }
1314 return $ciphertext;
1315 ';
1316
1317 $decrypt = '
1318 $plaintext = "";
1319 $buffer = &$self->debuffer;
1320
1321 if ($self->continuousBuffer) {
1322 $iv = &$self->decryptIV;
1323 $pos = &$buffer["pos"];
1324 } else {
1325 $iv = $self->decryptIV;
1326 $pos = 0;
1327 }
1328 $len = strlen($text);
1329 $i = 0;
1330 if ($pos) {
1331 $orig_pos = $pos;
1332 $max = '.$block_size.' - $pos;
1333 if ($len >= $max) {
1334 $i = $max;
1335 $len-= $max;
1336 $pos = 0;
1337 } else {
1338 $i = $len;
1339 $pos+= $len;
1340 $len = 0;
1341 }
1342 $plaintext = substr($iv, $orig_pos) ^ $text;
1343 $iv = substr_replace($iv, substr($text, 0, $i), $orig_pos, $i);
1344 }
1345 while ($len >= '.$block_size.') {
1346 $in = $iv;
1347 '.$_encryptBlock.'
1348 $iv = $in;
1349 $cb = substr($text, $i, '.$block_size.');
1350 $plaintext.= $iv ^ $cb;
1351 $iv = $cb;
1352 $len-= '.$block_size.';
1353 $i+= '.$block_size.';
1354 }
1355 if ($len) {
1356 $in = $iv;
1357 '.$_encryptBlock.'
1358 $iv = $in;
1359 $plaintext.= $iv ^ substr($text, $i);
1360 $iv = substr_replace($iv, substr($text, $i), 0, $len);
1361 $pos = $len;
1362 }
1363
1364 return $plaintext;
1365 ';
1366 break;
1367 case CRYPT_BLOWFISH_MODE_OFB:
1368 $encrypt = '
1369 $ciphertext = "";
1370 $plaintext_len = strlen($text);
1371 $xor = $self->encryptIV;
1372 $buffer = &$self->enbuffer;
1373
1374 if (strlen($buffer["xor"])) {
1375 for ($i = 0; $i < $plaintext_len; $i+= '.$block_size.') {
1376 $block = substr($text, $i, '.$block_size.');
1377 if (strlen($block) > strlen($buffer["xor"])) {
1378 $in = $xor;
1379 '.$_encryptBlock.'
1380 $xor = $in;
1381 $buffer["xor"].= $xor;
1382 }
1383 $key = $self->_string_shift($buffer["xor"]);
1384 $ciphertext.= $block ^ $key;
1385 }
1386 } else {
1387 for ($i = 0; $i < $plaintext_len; $i+= '.$block_size.') {
1388 $in = $xor;
1389 '.$_encryptBlock.'
1390 $xor = $in;
1391 $ciphertext.= substr($text, $i, '.$block_size.') ^ $xor;
1392 }
1393 $key = $xor;
1394 }
1395 if ($self->continuousBuffer) {
1396 $self->encryptIV = $xor;
1397 if ($start = $plaintext_len % '.$block_size.') {
1398 $buffer["xor"] = substr($key, $start) . $buffer["xor"];
1399 }
1400 }
1401 return $ciphertext;
1402 ';
1403
1404 $decrypt = '
1405 $plaintext = "";
1406 $ciphertext_len = strlen($text);
1407 $xor = $self->decryptIV;
1408 $buffer = &$self->debuffer;
1409
1410 if (strlen($buffer["xor"])) {
1411 for ($i = 0; $i < $ciphertext_len; $i+= '.$block_size.') {
1412 $block = substr($text, $i, '.$block_size.');
1413 if (strlen($block) > strlen($buffer["xor"])) {
1414 $in = $xor;
1415 '.$_encryptBlock.'
1416 $xor = $in;
1417 $buffer["xor"].= $xor;
1418 }
1419 $key = $self->_string_shift($buffer["xor"]);
1420 $plaintext.= $block ^ $key;
1421 }
1422 } else {
1423 for ($i = 0; $i < $ciphertext_len; $i+= '.$block_size.') {
1424 $in = $xor;
1425 '.$_encryptBlock.'
1426 $xor = $in;
1427 $plaintext.= substr($text, $i, '.$block_size.') ^ $xor;
1428 }
1429 $key = $xor;
1430 }
1431 if ($self->continuousBuffer) {
1432 $self->decryptIV = $xor;
1433 if ($start = $ciphertext_len % '.$block_size.') {
1434 $buffer["xor"] = substr($key, $start) . $buffer["xor"];
1435 }
1436 }
1437 return $plaintext;
1438 ';
1439 break;
1440 }
1441 $fnc_head = '$action, &$self, $text';
1442 $fnc_body = $init_cryptBlock . 'if ($action == "encrypt") { ' . $encrypt . ' } else { ' . $decrypt . ' }';
1443
1444 if (function_exists('create_function') && is_callable('create_function')) {
1445 $lambda_functions[$code_hash] = create_function($fnc_head, $fnc_body);
1446 } else {
1447 eval('function ' . ($lambda_functions[$code_hash] = 'f' . md5(microtime())) . '(' . $fnc_head . ') { ' . $fnc_body . ' }');
1448 }
1449 }
1450 $this->inline_crypt = $lambda_functions[$code_hash];
1451 }/*}}}*/
1452
1453 /**
1454 * Holds the lambda_functions table (classwide)
1455 *
1456 * @see inline_crypt_setup()
1457 * @return Array
1458 * @access private
1459 */
1460 function &get_lambda_functions()
1461 {
1462 static $functions = array();
1463 return $functions;
1464 }
1465 }
1466
1467 // vim: ts=4:sw=4:et:
1468 // vim6: fdl=1:
1469