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 / DES.php

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

2,537 lines 113.5 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 DES.
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/DES_supplementary_material Wikipedia: DES supplementary material}
14 * - {@link http://www.itl.nist.gov/fipspubs/fip46-2.htm FIPS 46-2 - (DES), Data Encryption Standard}
15 * - {@link http://www.cs.eku.edu/faculty/styer/460/Encrypt/JS-DES.html JavaScript DES Example}
16 *
17 * Here's a short example of how to use this library:
18 * <code>
19 * <?php
20 * include('Crypt/DES.php');
21 *
22 * $des = new Crypt_DES();
23 *
24 * $des->setKey('abcdefgh');
25 *
26 * $size = 10 * 1024;
27 * $plaintext = '';
28 * for ($i = 0; $i < $size; $i++) {
29 * $plaintext.= 'a';
30 * }
31 *
32 * echo $des->decrypt($des->encrypt($plaintext));
33 * ?>
34 * </code>
35 *
36 * LICENSE: Permission is hereby granted, free of charge, to any person obtaining a copy
37 * of this software and associated documentation files (the "Software"), to deal
38 * in the Software without restriction, including without limitation the rights
39 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
40 * copies of the Software, and to permit persons to whom the Software is
41 * furnished to do so, subject to the following conditions:
42 *
43 * The above copyright notice and this permission notice shall be included in
44 * all copies or substantial portions of the Software.
45 *
46 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
47 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
48 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
49 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
50 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
51 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
52 * THE SOFTWARE.
53 *
54 * @category Crypt
55 * @package Crypt_DES
56 * @author Jim Wigginton <terrafrost@php.net>
57 * @copyright MMVII Jim Wigginton
58 * @license http://www.opensource.org/licenses/mit-license.html MIT License
59 * @link http://phpseclib.sourceforge.net
60 */
61
62 /**#@+
63 * @access private
64 * @see Crypt_DES::_prepareKey()
65 * @see Crypt_DES::_processBlock()
66 */
67 /**
68 * Contains array_reverse($keys[CRYPT_DES_DECRYPT])
69 */
70 define('CRYPT_DES_ENCRYPT', 0);
71 /**
72 * Contains array_reverse($keys[CRYPT_DES_ENCRYPT])
73 */
74 define('CRYPT_DES_DECRYPT', 1);
75 /**
76 * Contains $keys[CRYPT_DES_ENCRYPT] as 1-dim array
77 */
78 define('CRYPT_DES_ENCRYPT_1DIM', 2);
79 /**
80 * Contains $keys[CRYPT_DES_DECRYPT] as 1-dim array
81 */
82 define('CRYPT_DES_DECRYPT_1DIM', 3);
83 /**#@-*/
84
85 /**#@+
86 * @access public
87 * @see Crypt_DES::encrypt()
88 * @see Crypt_DES::decrypt()
89 */
90 /**
91 * Encrypt / decrypt using the Counter mode.
92 *
93 * Set to -1 since that's what Crypt/Random.php uses to index the CTR mode.
94 *
95 * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Counter_.28CTR.29
96 */
97 define('CRYPT_DES_MODE_CTR', -1);
98 /**
99 * Encrypt / decrypt using the Electronic Code Book mode.
100 *
101 * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Electronic_codebook_.28ECB.29
102 */
103 define('CRYPT_DES_MODE_ECB', 1);
104 /**
105 * Encrypt / decrypt using the Code Book Chaining mode.
106 *
107 * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Cipher-block_chaining_.28CBC.29
108 */
109 define('CRYPT_DES_MODE_CBC', 2);
110 /**
111 * Encrypt / decrypt using the Cipher Feedback mode.
112 *
113 * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Cipher_feedback_.28CFB.29
114 */
115 define('CRYPT_DES_MODE_CFB', 3);
116 /**
117 * Encrypt / decrypt using the Cipher Feedback mode.
118 *
119 * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Output_feedback_.28OFB.29
120 */
121 define('CRYPT_DES_MODE_OFB', 4);
122 /**#@-*/
123
124 /**#@+
125 * @access private
126 * @see Crypt_DES::Crypt_DES()
127 */
128 /**
129 * Toggles the internal implementation
130 */
131 define('CRYPT_DES_MODE_INTERNAL', 1);
132 /**
133 * Toggles the mcrypt implementation
134 */
135 define('CRYPT_DES_MODE_MCRYPT', 2);
136 /**#@-*/
137
138 /**
139 * Pure-PHP implementation of DES.
140 *
141 * @author Jim Wigginton <terrafrost@php.net>
142 * @version 0.1.0
143 * @access public
144 * @package Crypt_DES
145 */
146 class Crypt_DES {
147 /**
148 * The Key Schedule
149 *
150 * @see Crypt_DES::setKey()
151 * @var Array
152 * @access private
153 */
154 var $keys = "\0\0\0\0\0\0\0\0";
155
156 /**
157 * The Encryption Mode
158 *
159 * @see Crypt_DES::Crypt_DES()
160 * @var Integer
161 * @access private
162 */
163 var $mode;
164
165 /**
166 * Continuous Buffer status
167 *
168 * @see Crypt_DES::enableContinuousBuffer()
169 * @var Boolean
170 * @access private
171 */
172 var $continuousBuffer = false;
173
174 /**
175 * Padding status
176 *
177 * @see Crypt_DES::enablePadding()
178 * @var Boolean
179 * @access private
180 */
181 var $padding = true;
182
183 /**
184 * The Initialization Vector
185 *
186 * @see Crypt_DES::setIV()
187 * @var String
188 * @access private
189 */
190 var $iv = "\0\0\0\0\0\0\0\0";
191
192 /**
193 * A "sliding" Initialization Vector
194 *
195 * @see Crypt_DES::enableContinuousBuffer()
196 * @var String
197 * @access private
198 */
199 var $encryptIV = "\0\0\0\0\0\0\0\0";
200
201 /**
202 * A "sliding" Initialization Vector
203 *
204 * @see Crypt_DES::enableContinuousBuffer()
205 * @var String
206 * @access private
207 */
208 var $decryptIV = "\0\0\0\0\0\0\0\0";
209
210 /**
211 * mcrypt resource for encryption
212 *
213 * The mcrypt resource can be recreated every time something needs to be created or it can be created just once.
214 * Since mcrypt operates in continuous mode, by default, it'll need to be recreated when in non-continuous mode.
215 *
216 * @see Crypt_DES::encrypt()
217 * @var String
218 * @access private
219 */
220 var $enmcrypt;
221
222 /**
223 * mcrypt resource for decryption
224 *
225 * The mcrypt resource can be recreated every time something needs to be created or it can be created just once.
226 * Since mcrypt operates in continuous mode, by default, it'll need to be recreated when in non-continuous mode.
227 *
228 * @see Crypt_DES::decrypt()
229 * @var String
230 * @access private
231 */
232 var $demcrypt;
233
234 /**
235 * Does the enmcrypt resource need to be (re)initialized?
236 *
237 * @see Crypt_DES::setKey()
238 * @see Crypt_DES::setIV()
239 * @var Boolean
240 * @access private
241 */
242 var $enchanged = true;
243
244 /**
245 * Does the demcrypt resource need to be (re)initialized?
246 *
247 * @see Crypt_DES::setKey()
248 * @see Crypt_DES::setIV()
249 * @var Boolean
250 * @access private
251 */
252 var $dechanged = true;
253
254 /**
255 * Is the mode one that is paddable?
256 *
257 * @see Crypt_DES::Crypt_DES()
258 * @var Boolean
259 * @access private
260 */
261 var $paddable = false;
262
263 /**
264 * Encryption buffer for CTR, OFB and CFB modes
265 *
266 * @see Crypt_DES::encrypt()
267 * @var Array
268 * @access private
269 */
270 var $enbuffer = array('encrypted' => '', 'xor' => '', 'pos' => 0, 'enmcrypt_init' => true);
271
272 /**
273 * Decryption buffer for CTR, OFB and CFB modes
274 *
275 * @see Crypt_DES::decrypt()
276 * @var Array
277 * @access private
278 */
279 var $debuffer = array('ciphertext' => '', 'xor' => '', 'pos' => 0, 'demcrypt_init' => true);
280
281 /**
282 * mcrypt resource for CFB mode
283 *
284 * @see Crypt_DES::encrypt()
285 * @see Crypt_DES::decrypt()
286 * @var String
287 * @access private
288 */
289 var $ecb;
290
291 /**
292 * Performance-optimized callback function for en/decrypt()
293 *
294 * @var Callback
295 * @access private
296 */
297 var $inline_crypt;
298
299 /**
300 * Holds whether performance-optimized $inline_crypt should be used or not.
301 *
302 * @var Boolean
303 * @access private
304 */
305 var $use_inline_crypt = false;
306
307 /**
308 * Shuffle table.
309 *
310 * For each byte value index, the entry holds an 8-byte string
311 * with each byte containing all bits in the same state as the
312 * corresponding bit in the index value.
313 *
314 * @see Crypt_DES::_processBlock()
315 * @see Crypt_DES::_prepareKey()
316 * @var Array
317 * @access private
318 */
319 var $shuffle = array(
320 "\x00\x00\x00\x00\x00\x00\x00\x00", "\x00\x00\x00\x00\x00\x00\x00\xFF",
321 "\x00\x00\x00\x00\x00\x00\xFF\x00", "\x00\x00\x00\x00\x00\x00\xFF\xFF",
322 "\x00\x00\x00\x00\x00\xFF\x00\x00", "\x00\x00\x00\x00\x00\xFF\x00\xFF",
323 "\x00\x00\x00\x00\x00\xFF\xFF\x00", "\x00\x00\x00\x00\x00\xFF\xFF\xFF",
324 "\x00\x00\x00\x00\xFF\x00\x00\x00", "\x00\x00\x00\x00\xFF\x00\x00\xFF",
325 "\x00\x00\x00\x00\xFF\x00\xFF\x00", "\x00\x00\x00\x00\xFF\x00\xFF\xFF",
326 "\x00\x00\x00\x00\xFF\xFF\x00\x00", "\x00\x00\x00\x00\xFF\xFF\x00\xFF",
327 "\x00\x00\x00\x00\xFF\xFF\xFF\x00", "\x00\x00\x00\x00\xFF\xFF\xFF\xFF",
328 "\x00\x00\x00\xFF\x00\x00\x00\x00", "\x00\x00\x00\xFF\x00\x00\x00\xFF",
329 "\x00\x00\x00\xFF\x00\x00\xFF\x00", "\x00\x00\x00\xFF\x00\x00\xFF\xFF",
330 "\x00\x00\x00\xFF\x00\xFF\x00\x00", "\x00\x00\x00\xFF\x00\xFF\x00\xFF",
331 "\x00\x00\x00\xFF\x00\xFF\xFF\x00", "\x00\x00\x00\xFF\x00\xFF\xFF\xFF",
332 "\x00\x00\x00\xFF\xFF\x00\x00\x00", "\x00\x00\x00\xFF\xFF\x00\x00\xFF",
333 "\x00\x00\x00\xFF\xFF\x00\xFF\x00", "\x00\x00\x00\xFF\xFF\x00\xFF\xFF",
334 "\x00\x00\x00\xFF\xFF\xFF\x00\x00", "\x00\x00\x00\xFF\xFF\xFF\x00\xFF",
335 "\x00\x00\x00\xFF\xFF\xFF\xFF\x00", "\x00\x00\x00\xFF\xFF\xFF\xFF\xFF",
336 "\x00\x00\xFF\x00\x00\x00\x00\x00", "\x00\x00\xFF\x00\x00\x00\x00\xFF",
337 "\x00\x00\xFF\x00\x00\x00\xFF\x00", "\x00\x00\xFF\x00\x00\x00\xFF\xFF",
338 "\x00\x00\xFF\x00\x00\xFF\x00\x00", "\x00\x00\xFF\x00\x00\xFF\x00\xFF",
339 "\x00\x00\xFF\x00\x00\xFF\xFF\x00", "\x00\x00\xFF\x00\x00\xFF\xFF\xFF",
340 "\x00\x00\xFF\x00\xFF\x00\x00\x00", "\x00\x00\xFF\x00\xFF\x00\x00\xFF",
341 "\x00\x00\xFF\x00\xFF\x00\xFF\x00", "\x00\x00\xFF\x00\xFF\x00\xFF\xFF",
342 "\x00\x00\xFF\x00\xFF\xFF\x00\x00", "\x00\x00\xFF\x00\xFF\xFF\x00\xFF",
343 "\x00\x00\xFF\x00\xFF\xFF\xFF\x00", "\x00\x00\xFF\x00\xFF\xFF\xFF\xFF",
344 "\x00\x00\xFF\xFF\x00\x00\x00\x00", "\x00\x00\xFF\xFF\x00\x00\x00\xFF",
345 "\x00\x00\xFF\xFF\x00\x00\xFF\x00", "\x00\x00\xFF\xFF\x00\x00\xFF\xFF",
346 "\x00\x00\xFF\xFF\x00\xFF\x00\x00", "\x00\x00\xFF\xFF\x00\xFF\x00\xFF",
347 "\x00\x00\xFF\xFF\x00\xFF\xFF\x00", "\x00\x00\xFF\xFF\x00\xFF\xFF\xFF",
348 "\x00\x00\xFF\xFF\xFF\x00\x00\x00", "\x00\x00\xFF\xFF\xFF\x00\x00\xFF",
349 "\x00\x00\xFF\xFF\xFF\x00\xFF\x00", "\x00\x00\xFF\xFF\xFF\x00\xFF\xFF",
350 "\x00\x00\xFF\xFF\xFF\xFF\x00\x00", "\x00\x00\xFF\xFF\xFF\xFF\x00\xFF",
351 "\x00\x00\xFF\xFF\xFF\xFF\xFF\x00", "\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF",
352 "\x00\xFF\x00\x00\x00\x00\x00\x00", "\x00\xFF\x00\x00\x00\x00\x00\xFF",
353 "\x00\xFF\x00\x00\x00\x00\xFF\x00", "\x00\xFF\x00\x00\x00\x00\xFF\xFF",
354 "\x00\xFF\x00\x00\x00\xFF\x00\x00", "\x00\xFF\x00\x00\x00\xFF\x00\xFF",
355 "\x00\xFF\x00\x00\x00\xFF\xFF\x00", "\x00\xFF\x00\x00\x00\xFF\xFF\xFF",
356 "\x00\xFF\x00\x00\xFF\x00\x00\x00", "\x00\xFF\x00\x00\xFF\x00\x00\xFF",
357 "\x00\xFF\x00\x00\xFF\x00\xFF\x00", "\x00\xFF\x00\x00\xFF\x00\xFF\xFF",
358 "\x00\xFF\x00\x00\xFF\xFF\x00\x00", "\x00\xFF\x00\x00\xFF\xFF\x00\xFF",
359 "\x00\xFF\x00\x00\xFF\xFF\xFF\x00", "\x00\xFF\x00\x00\xFF\xFF\xFF\xFF",
360 "\x00\xFF\x00\xFF\x00\x00\x00\x00", "\x00\xFF\x00\xFF\x00\x00\x00\xFF",
361 "\x00\xFF\x00\xFF\x00\x00\xFF\x00", "\x00\xFF\x00\xFF\x00\x00\xFF\xFF",
362 "\x00\xFF\x00\xFF\x00\xFF\x00\x00", "\x00\xFF\x00\xFF\x00\xFF\x00\xFF",
363 "\x00\xFF\x00\xFF\x00\xFF\xFF\x00", "\x00\xFF\x00\xFF\x00\xFF\xFF\xFF",
364 "\x00\xFF\x00\xFF\xFF\x00\x00\x00", "\x00\xFF\x00\xFF\xFF\x00\x00\xFF",
365 "\x00\xFF\x00\xFF\xFF\x00\xFF\x00", "\x00\xFF\x00\xFF\xFF\x00\xFF\xFF",
366 "\x00\xFF\x00\xFF\xFF\xFF\x00\x00", "\x00\xFF\x00\xFF\xFF\xFF\x00\xFF",
367 "\x00\xFF\x00\xFF\xFF\xFF\xFF\x00", "\x00\xFF\x00\xFF\xFF\xFF\xFF\xFF",
368 "\x00\xFF\xFF\x00\x00\x00\x00\x00", "\x00\xFF\xFF\x00\x00\x00\x00\xFF",
369 "\x00\xFF\xFF\x00\x00\x00\xFF\x00", "\x00\xFF\xFF\x00\x00\x00\xFF\xFF",
370 "\x00\xFF\xFF\x00\x00\xFF\x00\x00", "\x00\xFF\xFF\x00\x00\xFF\x00\xFF",
371 "\x00\xFF\xFF\x00\x00\xFF\xFF\x00", "\x00\xFF\xFF\x00\x00\xFF\xFF\xFF",
372 "\x00\xFF\xFF\x00\xFF\x00\x00\x00", "\x00\xFF\xFF\x00\xFF\x00\x00\xFF",
373 "\x00\xFF\xFF\x00\xFF\x00\xFF\x00", "\x00\xFF\xFF\x00\xFF\x00\xFF\xFF",
374 "\x00\xFF\xFF\x00\xFF\xFF\x00\x00", "\x00\xFF\xFF\x00\xFF\xFF\x00\xFF",
375 "\x00\xFF\xFF\x00\xFF\xFF\xFF\x00", "\x00\xFF\xFF\x00\xFF\xFF\xFF\xFF",
376 "\x00\xFF\xFF\xFF\x00\x00\x00\x00", "\x00\xFF\xFF\xFF\x00\x00\x00\xFF",
377 "\x00\xFF\xFF\xFF\x00\x00\xFF\x00", "\x00\xFF\xFF\xFF\x00\x00\xFF\xFF",
378 "\x00\xFF\xFF\xFF\x00\xFF\x00\x00", "\x00\xFF\xFF\xFF\x00\xFF\x00\xFF",
379 "\x00\xFF\xFF\xFF\x00\xFF\xFF\x00", "\x00\xFF\xFF\xFF\x00\xFF\xFF\xFF",
380 "\x00\xFF\xFF\xFF\xFF\x00\x00\x00", "\x00\xFF\xFF\xFF\xFF\x00\x00\xFF",
381 "\x00\xFF\xFF\xFF\xFF\x00\xFF\x00", "\x00\xFF\xFF\xFF\xFF\x00\xFF\xFF",
382 "\x00\xFF\xFF\xFF\xFF\xFF\x00\x00", "\x00\xFF\xFF\xFF\xFF\xFF\x00\xFF",
383 "\x00\xFF\xFF\xFF\xFF\xFF\xFF\x00", "\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF",
384 "\xFF\x00\x00\x00\x00\x00\x00\x00", "\xFF\x00\x00\x00\x00\x00\x00\xFF",
385 "\xFF\x00\x00\x00\x00\x00\xFF\x00", "\xFF\x00\x00\x00\x00\x00\xFF\xFF",
386 "\xFF\x00\x00\x00\x00\xFF\x00\x00", "\xFF\x00\x00\x00\x00\xFF\x00\xFF",
387 "\xFF\x00\x00\x00\x00\xFF\xFF\x00", "\xFF\x00\x00\x00\x00\xFF\xFF\xFF",
388 "\xFF\x00\x00\x00\xFF\x00\x00\x00", "\xFF\x00\x00\x00\xFF\x00\x00\xFF",
389 "\xFF\x00\x00\x00\xFF\x00\xFF\x00", "\xFF\x00\x00\x00\xFF\x00\xFF\xFF",
390 "\xFF\x00\x00\x00\xFF\xFF\x00\x00", "\xFF\x00\x00\x00\xFF\xFF\x00\xFF",
391 "\xFF\x00\x00\x00\xFF\xFF\xFF\x00", "\xFF\x00\x00\x00\xFF\xFF\xFF\xFF",
392 "\xFF\x00\x00\xFF\x00\x00\x00\x00", "\xFF\x00\x00\xFF\x00\x00\x00\xFF",
393 "\xFF\x00\x00\xFF\x00\x00\xFF\x00", "\xFF\x00\x00\xFF\x00\x00\xFF\xFF",
394 "\xFF\x00\x00\xFF\x00\xFF\x00\x00", "\xFF\x00\x00\xFF\x00\xFF\x00\xFF",
395 "\xFF\x00\x00\xFF\x00\xFF\xFF\x00", "\xFF\x00\x00\xFF\x00\xFF\xFF\xFF",
396 "\xFF\x00\x00\xFF\xFF\x00\x00\x00", "\xFF\x00\x00\xFF\xFF\x00\x00\xFF",
397 "\xFF\x00\x00\xFF\xFF\x00\xFF\x00", "\xFF\x00\x00\xFF\xFF\x00\xFF\xFF",
398 "\xFF\x00\x00\xFF\xFF\xFF\x00\x00", "\xFF\x00\x00\xFF\xFF\xFF\x00\xFF",
399 "\xFF\x00\x00\xFF\xFF\xFF\xFF\x00", "\xFF\x00\x00\xFF\xFF\xFF\xFF\xFF",
400 "\xFF\x00\xFF\x00\x00\x00\x00\x00", "\xFF\x00\xFF\x00\x00\x00\x00\xFF",
401 "\xFF\x00\xFF\x00\x00\x00\xFF\x00", "\xFF\x00\xFF\x00\x00\x00\xFF\xFF",
402 "\xFF\x00\xFF\x00\x00\xFF\x00\x00", "\xFF\x00\xFF\x00\x00\xFF\x00\xFF",
403 "\xFF\x00\xFF\x00\x00\xFF\xFF\x00", "\xFF\x00\xFF\x00\x00\xFF\xFF\xFF",
404 "\xFF\x00\xFF\x00\xFF\x00\x00\x00", "\xFF\x00\xFF\x00\xFF\x00\x00\xFF",
405 "\xFF\x00\xFF\x00\xFF\x00\xFF\x00", "\xFF\x00\xFF\x00\xFF\x00\xFF\xFF",
406 "\xFF\x00\xFF\x00\xFF\xFF\x00\x00", "\xFF\x00\xFF\x00\xFF\xFF\x00\xFF",
407 "\xFF\x00\xFF\x00\xFF\xFF\xFF\x00", "\xFF\x00\xFF\x00\xFF\xFF\xFF\xFF",
408 "\xFF\x00\xFF\xFF\x00\x00\x00\x00", "\xFF\x00\xFF\xFF\x00\x00\x00\xFF",
409 "\xFF\x00\xFF\xFF\x00\x00\xFF\x00", "\xFF\x00\xFF\xFF\x00\x00\xFF\xFF",
410 "\xFF\x00\xFF\xFF\x00\xFF\x00\x00", "\xFF\x00\xFF\xFF\x00\xFF\x00\xFF",
411 "\xFF\x00\xFF\xFF\x00\xFF\xFF\x00", "\xFF\x00\xFF\xFF\x00\xFF\xFF\xFF",
412 "\xFF\x00\xFF\xFF\xFF\x00\x00\x00", "\xFF\x00\xFF\xFF\xFF\x00\x00\xFF",
413 "\xFF\x00\xFF\xFF\xFF\x00\xFF\x00", "\xFF\x00\xFF\xFF\xFF\x00\xFF\xFF",
414 "\xFF\x00\xFF\xFF\xFF\xFF\x00\x00", "\xFF\x00\xFF\xFF\xFF\xFF\x00\xFF",
415 "\xFF\x00\xFF\xFF\xFF\xFF\xFF\x00", "\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF",
416 "\xFF\xFF\x00\x00\x00\x00\x00\x00", "\xFF\xFF\x00\x00\x00\x00\x00\xFF",
417 "\xFF\xFF\x00\x00\x00\x00\xFF\x00", "\xFF\xFF\x00\x00\x00\x00\xFF\xFF",
418 "\xFF\xFF\x00\x00\x00\xFF\x00\x00", "\xFF\xFF\x00\x00\x00\xFF\x00\xFF",
419 "\xFF\xFF\x00\x00\x00\xFF\xFF\x00", "\xFF\xFF\x00\x00\x00\xFF\xFF\xFF",
420 "\xFF\xFF\x00\x00\xFF\x00\x00\x00", "\xFF\xFF\x00\x00\xFF\x00\x00\xFF",
421 "\xFF\xFF\x00\x00\xFF\x00\xFF\x00", "\xFF\xFF\x00\x00\xFF\x00\xFF\xFF",
422 "\xFF\xFF\x00\x00\xFF\xFF\x00\x00", "\xFF\xFF\x00\x00\xFF\xFF\x00\xFF",
423 "\xFF\xFF\x00\x00\xFF\xFF\xFF\x00", "\xFF\xFF\x00\x00\xFF\xFF\xFF\xFF",
424 "\xFF\xFF\x00\xFF\x00\x00\x00\x00", "\xFF\xFF\x00\xFF\x00\x00\x00\xFF",
425 "\xFF\xFF\x00\xFF\x00\x00\xFF\x00", "\xFF\xFF\x00\xFF\x00\x00\xFF\xFF",
426 "\xFF\xFF\x00\xFF\x00\xFF\x00\x00", "\xFF\xFF\x00\xFF\x00\xFF\x00\xFF",
427 "\xFF\xFF\x00\xFF\x00\xFF\xFF\x00", "\xFF\xFF\x00\xFF\x00\xFF\xFF\xFF",
428 "\xFF\xFF\x00\xFF\xFF\x00\x00\x00", "\xFF\xFF\x00\xFF\xFF\x00\x00\xFF",
429 "\xFF\xFF\x00\xFF\xFF\x00\xFF\x00", "\xFF\xFF\x00\xFF\xFF\x00\xFF\xFF",
430 "\xFF\xFF\x00\xFF\xFF\xFF\x00\x00", "\xFF\xFF\x00\xFF\xFF\xFF\x00\xFF",
431 "\xFF\xFF\x00\xFF\xFF\xFF\xFF\x00", "\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF",
432 "\xFF\xFF\xFF\x00\x00\x00\x00\x00", "\xFF\xFF\xFF\x00\x00\x00\x00\xFF",
433 "\xFF\xFF\xFF\x00\x00\x00\xFF\x00", "\xFF\xFF\xFF\x00\x00\x00\xFF\xFF",
434 "\xFF\xFF\xFF\x00\x00\xFF\x00\x00", "\xFF\xFF\xFF\x00\x00\xFF\x00\xFF",
435 "\xFF\xFF\xFF\x00\x00\xFF\xFF\x00", "\xFF\xFF\xFF\x00\x00\xFF\xFF\xFF",
436 "\xFF\xFF\xFF\x00\xFF\x00\x00\x00", "\xFF\xFF\xFF\x00\xFF\x00\x00\xFF",
437 "\xFF\xFF\xFF\x00\xFF\x00\xFF\x00", "\xFF\xFF\xFF\x00\xFF\x00\xFF\xFF",
438 "\xFF\xFF\xFF\x00\xFF\xFF\x00\x00", "\xFF\xFF\xFF\x00\xFF\xFF\x00\xFF",
439 "\xFF\xFF\xFF\x00\xFF\xFF\xFF\x00", "\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF",
440 "\xFF\xFF\xFF\xFF\x00\x00\x00\x00", "\xFF\xFF\xFF\xFF\x00\x00\x00\xFF",
441 "\xFF\xFF\xFF\xFF\x00\x00\xFF\x00", "\xFF\xFF\xFF\xFF\x00\x00\xFF\xFF",
442 "\xFF\xFF\xFF\xFF\x00\xFF\x00\x00", "\xFF\xFF\xFF\xFF\x00\xFF\x00\xFF",
443 "\xFF\xFF\xFF\xFF\x00\xFF\xFF\x00", "\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF",
444 "\xFF\xFF\xFF\xFF\xFF\x00\x00\x00", "\xFF\xFF\xFF\xFF\xFF\x00\x00\xFF",
445 "\xFF\xFF\xFF\xFF\xFF\x00\xFF\x00", "\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF",
446 "\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00", "\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF",
447 "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00", "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
448 );
449
450 /**
451 * IP mapping helper table.
452 *
453 * Indexing this table with each source byte performs the initial bit permutation.
454 *
455 * @var Array
456 * @access private
457 */
458 var $ipmap = array(
459 0x00, 0x10, 0x01, 0x11, 0x20, 0x30, 0x21, 0x31,
460 0x02, 0x12, 0x03, 0x13, 0x22, 0x32, 0x23, 0x33,
461 0x40, 0x50, 0x41, 0x51, 0x60, 0x70, 0x61, 0x71,
462 0x42, 0x52, 0x43, 0x53, 0x62, 0x72, 0x63, 0x73,
463 0x04, 0x14, 0x05, 0x15, 0x24, 0x34, 0x25, 0x35,
464 0x06, 0x16, 0x07, 0x17, 0x26, 0x36, 0x27, 0x37,
465 0x44, 0x54, 0x45, 0x55, 0x64, 0x74, 0x65, 0x75,
466 0x46, 0x56, 0x47, 0x57, 0x66, 0x76, 0x67, 0x77,
467 0x80, 0x90, 0x81, 0x91, 0xA0, 0xB0, 0xA1, 0xB1,
468 0x82, 0x92, 0x83, 0x93, 0xA2, 0xB2, 0xA3, 0xB3,
469 0xC0, 0xD0, 0xC1, 0xD1, 0xE0, 0xF0, 0xE1, 0xF1,
470 0xC2, 0xD2, 0xC3, 0xD3, 0xE2, 0xF2, 0xE3, 0xF3,
471 0x84, 0x94, 0x85, 0x95, 0xA4, 0xB4, 0xA5, 0xB5,
472 0x86, 0x96, 0x87, 0x97, 0xA6, 0xB6, 0xA7, 0xB7,
473 0xC4, 0xD4, 0xC5, 0xD5, 0xE4, 0xF4, 0xE5, 0xF5,
474 0xC6, 0xD6, 0xC7, 0xD7, 0xE6, 0xF6, 0xE7, 0xF7,
475 0x08, 0x18, 0x09, 0x19, 0x28, 0x38, 0x29, 0x39,
476 0x0A, 0x1A, 0x0B, 0x1B, 0x2A, 0x3A, 0x2B, 0x3B,
477 0x48, 0x58, 0x49, 0x59, 0x68, 0x78, 0x69, 0x79,
478 0x4A, 0x5A, 0x4B, 0x5B, 0x6A, 0x7A, 0x6B, 0x7B,
479 0x0C, 0x1C, 0x0D, 0x1D, 0x2C, 0x3C, 0x2D, 0x3D,
480 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F,
481 0x4C, 0x5C, 0x4D, 0x5D, 0x6C, 0x7C, 0x6D, 0x7D,
482 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F,
483 0x88, 0x98, 0x89, 0x99, 0xA8, 0xB8, 0xA9, 0xB9,
484 0x8A, 0x9A, 0x8B, 0x9B, 0xAA, 0xBA, 0xAB, 0xBB,
485 0xC8, 0xD8, 0xC9, 0xD9, 0xE8, 0xF8, 0xE9, 0xF9,
486 0xCA, 0xDA, 0xCB, 0xDB, 0xEA, 0xFA, 0xEB, 0xFB,
487 0x8C, 0x9C, 0x8D, 0x9D, 0xAC, 0xBC, 0xAD, 0xBD,
488 0x8E, 0x9E, 0x8F, 0x9F, 0xAE, 0xBE, 0xAF, 0xBF,
489 0xCC, 0xDC, 0xCD, 0xDD, 0xEC, 0xFC, 0xED, 0xFD,
490 0xCE, 0xDE, 0xCF, 0xDF, 0xEE, 0xFE, 0xEF, 0xFF
491 );
492
493 /**
494 * Inverse IP mapping helper table.
495 * Indexing this table with a byte value reverses the bit order.
496 *
497 * @var Array
498 * @access private
499 */
500 var $invipmap = array(
501 0x00, 0x80, 0x40, 0xC0, 0x20, 0xA0, 0x60, 0xE0,
502 0x10, 0x90, 0x50, 0xD0, 0x30, 0xB0, 0x70, 0xF0,
503 0x08, 0x88, 0x48, 0xC8, 0x28, 0xA8, 0x68, 0xE8,
504 0x18, 0x98, 0x58, 0xD8, 0x38, 0xB8, 0x78, 0xF8,
505 0x04, 0x84, 0x44, 0xC4, 0x24, 0xA4, 0x64, 0xE4,
506 0x14, 0x94, 0x54, 0xD4, 0x34, 0xB4, 0x74, 0xF4,
507 0x0C, 0x8C, 0x4C, 0xCC, 0x2C, 0xAC, 0x6C, 0xEC,
508 0x1C, 0x9C, 0x5C, 0xDC, 0x3C, 0xBC, 0x7C, 0xFC,
509 0x02, 0x82, 0x42, 0xC2, 0x22, 0xA2, 0x62, 0xE2,
510 0x12, 0x92, 0x52, 0xD2, 0x32, 0xB2, 0x72, 0xF2,
511 0x0A, 0x8A, 0x4A, 0xCA, 0x2A, 0xAA, 0x6A, 0xEA,
512 0x1A, 0x9A, 0x5A, 0xDA, 0x3A, 0xBA, 0x7A, 0xFA,
513 0x06, 0x86, 0x46, 0xC6, 0x26, 0xA6, 0x66, 0xE6,
514 0x16, 0x96, 0x56, 0xD6, 0x36, 0xB6, 0x76, 0xF6,
515 0x0E, 0x8E, 0x4E, 0xCE, 0x2E, 0xAE, 0x6E, 0xEE,
516 0x1E, 0x9E, 0x5E, 0xDE, 0x3E, 0xBE, 0x7E, 0xFE,
517 0x01, 0x81, 0x41, 0xC1, 0x21, 0xA1, 0x61, 0xE1,
518 0x11, 0x91, 0x51, 0xD1, 0x31, 0xB1, 0x71, 0xF1,
519 0x09, 0x89, 0x49, 0xC9, 0x29, 0xA9, 0x69, 0xE9,
520 0x19, 0x99, 0x59, 0xD9, 0x39, 0xB9, 0x79, 0xF9,
521 0x05, 0x85, 0x45, 0xC5, 0x25, 0xA5, 0x65, 0xE5,
522 0x15, 0x95, 0x55, 0xD5, 0x35, 0xB5, 0x75, 0xF5,
523 0x0D, 0x8D, 0x4D, 0xCD, 0x2D, 0xAD, 0x6D, 0xED,
524 0x1D, 0x9D, 0x5D, 0xDD, 0x3D, 0xBD, 0x7D, 0xFD,
525 0x03, 0x83, 0x43, 0xC3, 0x23, 0xA3, 0x63, 0xE3,
526 0x13, 0x93, 0x53, 0xD3, 0x33, 0xB3, 0x73, 0xF3,
527 0x0B, 0x8B, 0x4B, 0xCB, 0x2B, 0xAB, 0x6B, 0xEB,
528 0x1B, 0x9B, 0x5B, 0xDB, 0x3B, 0xBB, 0x7B, 0xFB,
529 0x07, 0x87, 0x47, 0xC7, 0x27, 0xA7, 0x67, 0xE7,
530 0x17, 0x97, 0x57, 0xD7, 0x37, 0xB7, 0x77, 0xF7,
531 0x0F, 0x8F, 0x4F, 0xCF, 0x2F, 0xAF, 0x6F, 0xEF,
532 0x1F, 0x9F, 0x5F, 0xDF, 0x3F, 0xBF, 0x7F, 0xFF
533 );
534
535 /**
536 * Pre-permuted S-box1
537 *
538 * Each box ($sbox1-$sbox8) has been vectorized, then each value pre-permuted using the
539 * P table: concatenation can then be replaced by exclusive ORs.
540 *
541 * @var Array
542 * @access private
543 */
544 var $sbox1 = array(
545 0x00808200, 0x00000000, 0x00008000, 0x00808202,
546 0x00808002, 0x00008202, 0x00000002, 0x00008000,
547 0x00000200, 0x00808200, 0x00808202, 0x00000200,
548 0x00800202, 0x00808002, 0x00800000, 0x00000002,
549 0x00000202, 0x00800200, 0x00800200, 0x00008200,
550 0x00008200, 0x00808000, 0x00808000, 0x00800202,
551 0x00008002, 0x00800002, 0x00800002, 0x00008002,
552 0x00000000, 0x00000202, 0x00008202, 0x00800000,
553 0x00008000, 0x00808202, 0x00000002, 0x00808000,
554 0x00808200, 0x00800000, 0x00800000, 0x00000200,
555 0x00808002, 0x00008000, 0x00008200, 0x00800002,
556 0x00000200, 0x00000002, 0x00800202, 0x00008202,
557 0x00808202, 0x00008002, 0x00808000, 0x00800202,
558 0x00800002, 0x00000202, 0x00008202, 0x00808200,
559 0x00000202, 0x00800200, 0x00800200, 0x00000000,
560 0x00008002, 0x00008200, 0x00000000, 0x00808002
561 );
562
563 /**
564 * Pre-permuted S-box2
565 *
566 * @var Array
567 * @access private
568 */
569 var $sbox2 = array(
570 0x40084010, 0x40004000, 0x00004000, 0x00084010,
571 0x00080000, 0x00000010, 0x40080010, 0x40004010,
572 0x40000010, 0x40084010, 0x40084000, 0x40000000,
573 0x40004000, 0x00080000, 0x00000010, 0x40080010,
574 0x00084000, 0x00080010, 0x40004010, 0x00000000,
575 0x40000000, 0x00004000, 0x00084010, 0x40080000,
576 0x00080010, 0x40000010, 0x00000000, 0x00084000,
577 0x00004010, 0x40084000, 0x40080000, 0x00004010,
578 0x00000000, 0x00084010, 0x40080010, 0x00080000,
579 0x40004010, 0x40080000, 0x40084000, 0x00004000,
580 0x40080000, 0x40004000, 0x00000010, 0x40084010,
581 0x00084010, 0x00000010, 0x00004000, 0x40000000,
582 0x00004010, 0x40084000, 0x00080000, 0x40000010,
583 0x00080010, 0x40004010, 0x40000010, 0x00080010,
584 0x00084000, 0x00000000, 0x40004000, 0x00004010,
585 0x40000000, 0x40080010, 0x40084010, 0x00084000
586 );
587
588 /**
589 * Pre-permuted S-box3
590 *
591 * @var Array
592 * @access private
593 */
594 var $sbox3 = array(
595 0x00000104, 0x04010100, 0x00000000, 0x04010004,
596 0x04000100, 0x00000000, 0x00010104, 0x04000100,
597 0x00010004, 0x04000004, 0x04000004, 0x00010000,
598 0x04010104, 0x00010004, 0x04010000, 0x00000104,
599 0x04000000, 0x00000004, 0x04010100, 0x00000100,
600 0x00010100, 0x04010000, 0x04010004, 0x00010104,
601 0x04000104, 0x00010100, 0x00010000, 0x04000104,
602 0x00000004, 0x04010104, 0x00000100, 0x04000000,
603 0x04010100, 0x04000000, 0x00010004, 0x00000104,
604 0x00010000, 0x04010100, 0x04000100, 0x00000000,
605 0x00000100, 0x00010004, 0x04010104, 0x04000100,
606 0x04000004, 0x00000100, 0x00000000, 0x04010004,
607 0x04000104, 0x00010000, 0x04000000, 0x04010104,
608 0x00000004, 0x00010104, 0x00010100, 0x04000004,
609 0x04010000, 0x04000104, 0x00000104, 0x04010000,
610 0x00010104, 0x00000004, 0x04010004, 0x00010100
611 );
612
613 /**
614 * Pre-permuted S-box4
615 *
616 * @var Array
617 * @access private
618 */
619 var $sbox4 = array(
620 0x80401000, 0x80001040, 0x80001040, 0x00000040,
621 0x00401040, 0x80400040, 0x80400000, 0x80001000,
622 0x00000000, 0x00401000, 0x00401000, 0x80401040,
623 0x80000040, 0x00000000, 0x00400040, 0x80400000,
624 0x80000000, 0x00001000, 0x00400000, 0x80401000,
625 0x00000040, 0x00400000, 0x80001000, 0x00001040,
626 0x80400040, 0x80000000, 0x00001040, 0x00400040,
627 0x00001000, 0x00401040, 0x80401040, 0x80000040,
628 0x00400040, 0x80400000, 0x00401000, 0x80401040,
629 0x80000040, 0x00000000, 0x00000000, 0x00401000,
630 0x00001040, 0x00400040, 0x80400040, 0x80000000,
631 0x80401000, 0x80001040, 0x80001040, 0x00000040,
632 0x80401040, 0x80000040, 0x80000000, 0x00001000,
633 0x80400000, 0x80001000, 0x00401040, 0x80400040,
634 0x80001000, 0x00001040, 0x00400000, 0x80401000,
635 0x00000040, 0x00400000, 0x00001000, 0x00401040
636 );
637
638 /**
639 * Pre-permuted S-box5
640 *
641 * @var Array
642 * @access private
643 */
644 var $sbox5 = array(
645 0x00000080, 0x01040080, 0x01040000, 0x21000080,
646 0x00040000, 0x00000080, 0x20000000, 0x01040000,
647 0x20040080, 0x00040000, 0x01000080, 0x20040080,
648 0x21000080, 0x21040000, 0x00040080, 0x20000000,
649 0x01000000, 0x20040000, 0x20040000, 0x00000000,
650 0x20000080, 0x21040080, 0x21040080, 0x01000080,
651 0x21040000, 0x20000080, 0x00000000, 0x21000000,
652 0x01040080, 0x01000000, 0x21000000, 0x00040080,
653 0x00040000, 0x21000080, 0x00000080, 0x01000000,
654 0x20000000, 0x01040000, 0x21000080, 0x20040080,
655 0x01000080, 0x20000000, 0x21040000, 0x01040080,
656 0x20040080, 0x00000080, 0x01000000, 0x21040000,
657 0x21040080, 0x00040080, 0x21000000, 0x21040080,
658 0x01040000, 0x00000000, 0x20040000, 0x21000000,
659 0x00040080, 0x01000080, 0x20000080, 0x00040000,
660 0x00000000, 0x20040000, 0x01040080, 0x20000080
661 );
662
663 /**
664 * Pre-permuted S-box6
665 *
666 * @var Array
667 * @access private
668 */
669 var $sbox6 = array(
670 0x10000008, 0x10200000, 0x00002000, 0x10202008,
671 0x10200000, 0x00000008, 0x10202008, 0x00200000,
672 0x10002000, 0x00202008, 0x00200000, 0x10000008,
673 0x00200008, 0x10002000, 0x10000000, 0x00002008,
674 0x00000000, 0x00200008, 0x10002008, 0x00002000,
675 0x00202000, 0x10002008, 0x00000008, 0x10200008,
676 0x10200008, 0x00000000, 0x00202008, 0x10202000,
677 0x00002008, 0x00202000, 0x10202000, 0x10000000,
678 0x10002000, 0x00000008, 0x10200008, 0x00202000,
679 0x10202008, 0x00200000, 0x00002008, 0x10000008,
680 0x00200000, 0x10002000, 0x10000000, 0x00002008,
681 0x10000008, 0x10202008, 0x00202000, 0x10200000,
682 0x00202008, 0x10202000, 0x00000000, 0x10200008,
683 0x00000008, 0x00002000, 0x10200000, 0x00202008,
684 0x00002000, 0x00200008, 0x10002008, 0x00000000,
685 0x10202000, 0x10000000, 0x00200008, 0x10002008
686 );
687
688 /**
689 * Pre-permuted S-box7
690 *
691 * @var Array
692 * @access private
693 */
694 var $sbox7 = array(
695 0x00100000, 0x02100001, 0x02000401, 0x00000000,
696 0x00000400, 0x02000401, 0x00100401, 0x02100400,
697 0x02100401, 0x00100000, 0x00000000, 0x02000001,
698 0x00000001, 0x02000000, 0x02100001, 0x00000401,
699 0x02000400, 0x00100401, 0x00100001, 0x02000400,
700 0x02000001, 0x02100000, 0x02100400, 0x00100001,
701 0x02100000, 0x00000400, 0x00000401, 0x02100401,
702 0x00100400, 0x00000001, 0x02000000, 0x00100400,
703 0x02000000, 0x00100400, 0x00100000, 0x02000401,
704 0x02000401, 0x02100001, 0x02100001, 0x00000001,
705 0x00100001, 0x02000000, 0x02000400, 0x00100000,
706 0x02100400, 0x00000401, 0x00100401, 0x02100400,
707 0x00000401, 0x02000001, 0x02100401, 0x02100000,
708 0x00100400, 0x00000000, 0x00000001, 0x02100401,
709 0x00000000, 0x00100401, 0x02100000, 0x00000400,
710 0x02000001, 0x02000400, 0x00000400, 0x00100001
711 );
712
713 /**
714 * Pre-permuted S-box8
715 *
716 * @var Array
717 * @access private
718 */
719 var $sbox8 = array(
720 0x08000820, 0x00000800, 0x00020000, 0x08020820,
721 0x08000000, 0x08000820, 0x00000020, 0x08000000,
722 0x00020020, 0x08020000, 0x08020820, 0x00020800,
723 0x08020800, 0x00020820, 0x00000800, 0x00000020,
724 0x08020000, 0x08000020, 0x08000800, 0x00000820,
725 0x00020800, 0x00020020, 0x08020020, 0x08020800,
726 0x00000820, 0x00000000, 0x00000000, 0x08020020,
727 0x08000020, 0x08000800, 0x00020820, 0x00020000,
728 0x00020820, 0x00020000, 0x08020800, 0x00000800,
729 0x00000020, 0x08020020, 0x00000800, 0x00020820,
730 0x08000800, 0x00000020, 0x08000020, 0x08020000,
731 0x08020020, 0x08000000, 0x00020000, 0x08000820,
732 0x00000000, 0x08020820, 0x00020020, 0x08000020,
733 0x08020000, 0x08000800, 0x08000820, 0x00000000,
734 0x08020820, 0x00020800, 0x00020800, 0x00000820,
735 0x00000820, 0x00020020, 0x08000000, 0x08020800
736 );
737
738 /**
739 * Default Constructor.
740 *
741 * Determines whether or not the mcrypt extension should be used. $mode should only, at present, be
742 * CRYPT_DES_MODE_ECB or CRYPT_DES_MODE_CBC. If not explictly set, CRYPT_DES_MODE_CBC will be used.
743 *
744 * @param optional Integer $mode
745 * @return Crypt_DES
746 * @access public
747 */
748 function Crypt_DES($mode = CRYPT_DES_MODE_CBC)
749 {
750 if ( !defined('CRYPT_DES_MODE') ) {
751 switch (true) {
752 case extension_loaded('mcrypt') && in_array('des', mcrypt_list_algorithms()):
753 define('CRYPT_DES_MODE', CRYPT_DES_MODE_MCRYPT);
754 break;
755 default:
756 define('CRYPT_DES_MODE', CRYPT_DES_MODE_INTERNAL);
757 }
758 }
759
760 switch ( CRYPT_DES_MODE ) {
761 case CRYPT_DES_MODE_MCRYPT:
762 switch ($mode) {
763 case CRYPT_DES_MODE_ECB:
764 $this->paddable = true;
765 $this->mode = MCRYPT_MODE_ECB;
766 break;
767 case CRYPT_DES_MODE_CTR:
768 $this->mode = 'ctr';
769 //$this->mode = in_array('ctr', mcrypt_list_modes()) ? 'ctr' : CRYPT_DES_MODE_CTR;
770 break;
771 case CRYPT_DES_MODE_CFB:
772 $this->mode = 'ncfb';
773 $this->ecb = mcrypt_module_open(MCRYPT_DES, '', MCRYPT_MODE_ECB, '');
774 break;
775 case CRYPT_DES_MODE_OFB:
776 $this->mode = MCRYPT_MODE_NOFB;
777 break;
778 case CRYPT_DES_MODE_CBC:
779 default:
780 $this->paddable = true;
781 $this->mode = MCRYPT_MODE_CBC;
782 }
783 $this->enmcrypt = mcrypt_module_open(MCRYPT_DES, '', $this->mode, '');
784 $this->demcrypt = mcrypt_module_open(MCRYPT_DES, '', $this->mode, '');
785
786 break;
787 default:
788 switch ($mode) {
789 case CRYPT_DES_MODE_ECB:
790 case CRYPT_DES_MODE_CBC:
791 $this->paddable = true;
792 $this->mode = $mode;
793 break;
794 case CRYPT_DES_MODE_CTR:
795 case CRYPT_DES_MODE_CFB:
796 case CRYPT_DES_MODE_OFB:
797 $this->mode = $mode;
798 break;
799 default:
800 $this->paddable = true;
801 $this->mode = CRYPT_DES_MODE_CBC;
802 }
803 if (function_exists('create_function') && is_callable('create_function')) {
804 $this->inline_crypt_setup();
805 $this->use_inline_crypt = true;
806 }
807 }
808 }
809
810 /**
811 * Sets the key.
812 *
813 * Keys can be of any length. DES, itself, uses 64-bit keys (eg. strlen($key) == 8), however, we
814 * only use the first eight, if $key has more then eight characters in it, and pad $key with the
815 * null byte if it is less then eight characters long.
816 *
817 * DES also requires that every eighth bit be a parity bit, however, we'll ignore that.
818 *
819 * If the key is not explicitly set, it'll be assumed to be all zero's.
820 *
821 * @access public
822 * @param String $key
823 */
824 function setKey($key)
825 {
826 $this->keys = ( CRYPT_DES_MODE == CRYPT_DES_MODE_MCRYPT ) ? str_pad(substr($key, 0, 8), 8, chr(0)) : $this->_prepareKey($key);
827 $this->enchanged = true;
828 $this->dechanged = true;
829 }
830
831 /**
832 * Sets the password.
833 *
834 * Depending on what $method is set to, setPassword()'s (optional) parameters are as follows:
835 * {@link http://en.wikipedia.org/wiki/PBKDF2 pbkdf2}:
836 * $hash, $salt, $count
837 *
838 * @param String $password
839 * @param optional String $method
840 * @access public
841 */
842 function setPassword($password, $method = 'pbkdf2')
843 {
844 $key = '';
845
846 switch ($method) {
847 default: // 'pbkdf2'
848 list(, , $hash, $salt, $count) = func_get_args();
849 if (!isset($hash)) {
850 $hash = 'sha1';
851 }
852 // WPA and WPA2 use the SSID as the salt
853 if (!isset($salt)) {
854 $salt = 'phpseclib/salt';
855 }
856 // RFC2898#section-4.2 uses 1,000 iterations by default
857 // WPA and WPA2 use 4,096.
858 if (!isset($count)) {
859 $count = 1000;
860 }
861
862 if (!class_exists('Crypt_Hash')) {
863 require_once('Crypt/Hash.php');
864 }
865
866 $i = 1;
867 while (strlen($key) < 8) { // $dkLen == 8
868 //$dk.= $this->_pbkdf($password, $salt, $count, $i++);
869 $hmac = new Crypt_Hash();
870 $hmac->setHash($hash);
871 $hmac->setKey($password);
872 $f = $u = $hmac->hash($salt . pack('N', $i++));
873 for ($j = 2; $j <= $count; $j++) {
874 $u = $hmac->hash($u);
875 $f^= $u;
876 }
877 $key.= $f;
878 }
879 }
880
881 $this->setKey($key);
882 }
883
884 /**
885 * Sets the initialization vector. (optional)
886 *
887 * SetIV is not required when CRYPT_DES_MODE_ECB is being used. If not explictly set, it'll be assumed
888 * to be all zero's.
889 *
890 * @access public
891 * @param String $iv
892 */
893 function setIV($iv)
894 {
895 $this->encryptIV = $this->decryptIV = $this->iv = str_pad(substr($iv, 0, 8), 8, chr(0));
896 $this->enchanged = true;
897 $this->dechanged = true;
898 }
899
900 /**
901 * Generate CTR XOR encryption key
902 *
903 * Encrypt the output of this and XOR it against the ciphertext / plaintext to get the
904 * plaintext / ciphertext in CTR mode.
905 *
906 * @see Crypt_DES::decrypt()
907 * @see Crypt_DES::encrypt()
908 * @access public
909 * @param String $iv
910 */
911 function _generate_xor(&$iv)
912 {
913 $xor = $iv;
914 for ($j = 4; $j <= 8; $j+=4) {
915 $temp = substr($iv, -$j, 4);
916 switch ($temp) {
917 case "\xFF\xFF\xFF\xFF":
918 $iv = substr_replace($iv, "\x00\x00\x00\x00", -$j, 4);
919 break;
920 case "\x7F\xFF\xFF\xFF":
921 $iv = substr_replace($iv, "\x80\x00\x00\x00", -$j, 4);
922 break 2;
923 default:
924 extract(unpack('Ncount', $temp));
925 $iv = substr_replace($iv, pack('N', $count + 1), -$j, 4);
926 break 2;
927 }
928 }
929
930 return $xor;
931 }
932
933 /**
934 * Encrypts a message.
935 *
936 * $plaintext will be padded with up to 8 additional bytes. Other DES implementations may or may not pad in the
937 * same manner. Other common approaches to padding and the reasons why it's necessary are discussed in the following
938 * URL:
939 *
940 * {@link http://www.di-mgt.com.au/cryptopad.html http://www.di-mgt.com.au/cryptopad.html}
941 *
942 * An alternative to padding is to, separately, send the length of the file. This is what SSH, in fact, does.
943 * strlen($plaintext) will still need to be a multiple of 8, however, arbitrary values can be added to make it that
944 * length.
945 *
946 * @see Crypt_DES::decrypt()
947 * @access public
948 * @param String $plaintext
949 */
950 function encrypt($plaintext)
951 {
952 if ($this->paddable) {
953 $plaintext = $this->_pad($plaintext);
954 }
955
956 if ( CRYPT_DES_MODE == CRYPT_DES_MODE_MCRYPT ) {
957 if ($this->enchanged) {
958 mcrypt_generic_init($this->enmcrypt, $this->keys, $this->encryptIV);
959 if ($this->mode == 'ncfb') {
960 mcrypt_generic_init($this->ecb, $this->keys, "\0\0\0\0\0\0\0\0");
961 }
962 $this->enchanged = false;
963 }
964
965 if ($this->mode != 'ncfb' || !$this->continuousBuffer) {
966 $ciphertext = mcrypt_generic($this->enmcrypt, $plaintext);
967 } else {
968 $iv = &$this->encryptIV;
969 $pos = &$this->enbuffer['pos'];
970 $len = strlen($plaintext);
971 $ciphertext = '';
972 $i = 0;
973 if ($pos) {
974 $orig_pos = $pos;
975 $max = 8 - $pos;
976 if ($len >= $max) {
977 $i = $max;
978 $len-= $max;
979 $pos = 0;
980 } else {
981 $i = $len;
982 $pos+= $len;
983 $len = 0;
984 }
985 $ciphertext = substr($iv, $orig_pos) ^ $plaintext;
986 $iv = substr_replace($iv, $ciphertext, $orig_pos, $i);
987 $this->enbuffer['enmcrypt_init'] = true;
988 }
989 if ($len >= 8) {
990 if ($this->enbuffer['enmcrypt_init'] === false || $len > 600) {
991 if ($this->enbuffer['enmcrypt_init'] === true) {
992 mcrypt_generic_init($this->enmcrypt, $this->keys, $iv);
993 $this->enbuffer['enmcrypt_init'] = false;
994 }
995 $ciphertext.= mcrypt_generic($this->enmcrypt, substr($plaintext, $i, $len - $len % 8));
996 $iv = substr($ciphertext, -8);
997 $len%= 8;
998 } else {
999 while ($len >= 8) {
1000 $iv = mcrypt_generic($this->ecb, $iv) ^ substr($plaintext, $i, 8);
1001 $ciphertext.= $iv;
1002 $len-= 8;
1003 $i+= 8;
1004 }
1005 }
1006 }
1007 if ($len) {
1008 $iv = mcrypt_generic($this->ecb, $iv);
1009 $block = $iv ^ substr($plaintext, -$len);
1010 $iv = substr_replace($iv, $block, 0, $len);
1011 $ciphertext.= $block;
1012 $pos = $len;
1013 }
1014 return $ciphertext;
1015 }
1016
1017 if (!$this->continuousBuffer) {
1018 mcrypt_generic_init($this->enmcrypt, $this->keys, $this->encryptIV);
1019 }
1020
1021 return $ciphertext;
1022 }
1023
1024 if (!is_array($this->keys)) {
1025 $this->keys = $this->_prepareKey("\0\0\0\0\0\0\0\0");
1026 }
1027
1028 if ($this->use_inline_crypt) {
1029 $inline = $this->inline_crypt;
1030 return $inline('encrypt', $this, $plaintext);
1031 }
1032
1033 $buffer = &$this->enbuffer;
1034 $continuousBuffer = $this->continuousBuffer;
1035 $ciphertext = '';
1036 switch ($this->mode) {
1037 case CRYPT_DES_MODE_ECB:
1038 for ($i = 0; $i < strlen($plaintext); $i+=8) {
1039 $ciphertext.= $this->_processBlock(substr($plaintext, $i, 8), CRYPT_DES_ENCRYPT);
1040 }
1041 break;
1042 case CRYPT_DES_MODE_CBC:
1043 $xor = $this->encryptIV;
1044 for ($i = 0; $i < strlen($plaintext); $i+=8) {
1045 $block = substr($plaintext, $i, 8);
1046 $block = $this->_processBlock($block ^ $xor, CRYPT_DES_ENCRYPT);
1047 $xor = $block;
1048 $ciphertext.= $block;
1049 }
1050 if ($this->continuousBuffer) {
1051 $this->encryptIV = $xor;
1052 }
1053 break;
1054 case CRYPT_DES_MODE_CTR:
1055 $xor = $this->encryptIV;
1056 if (strlen($buffer['encrypted'])) {
1057 for ($i = 0; $i < strlen($plaintext); $i+=8) {
1058 $block = substr($plaintext, $i, 8);
1059 if (strlen($block) > strlen($buffer['encrypted'])) {
1060 $buffer['encrypted'].= $this->_processBlock($this->_generate_xor($xor), CRYPT_DES_ENCRYPT);
1061 }
1062 $key = $this->_string_shift($buffer['encrypted']);
1063 $ciphertext.= $block ^ $key;
1064 }
1065 } else {
1066 for ($i = 0; $i < strlen($plaintext); $i+=8) {
1067 $block = substr($plaintext, $i, 8);
1068 $key = $this->_processBlock($this->_generate_xor($xor), CRYPT_DES_ENCRYPT);
1069 $ciphertext.= $block ^ $key;
1070 }
1071 }
1072 if ($this->continuousBuffer) {
1073 $this->encryptIV = $xor;
1074 if ($start = strlen($plaintext) & 7) {
1075 $buffer['encrypted'] = substr($key, $start) . $buffer['encrypted'];
1076 }
1077 }
1078 break;
1079 case CRYPT_DES_MODE_CFB:
1080 if ($this->continuousBuffer) {
1081 $iv = &$this->encryptIV;
1082 $pos = &$buffer['pos'];
1083 } else {
1084 $iv = $this->encryptIV;
1085 $pos = 0;
1086 }
1087 $len = strlen($plaintext);
1088 $i = 0;
1089 if ($pos) {
1090 $orig_pos = $pos;
1091 $max = 8 - $pos;
1092 if ($len >= $max) {
1093 $i = $max;
1094 $len-= $max;
1095 $pos = 0;
1096 } else {
1097 $i = $len;
1098 $pos+= $len;
1099 $len = 0;
1100 }
1101 $ciphertext = substr($iv, $orig_pos) ^ $plaintext;
1102 $iv = substr_replace($iv, $ciphertext, $orig_pos, $i);
1103 }
1104 while ($len >= 8) {
1105 $iv = $this->_processBlock($iv, CRYPT_DES_ENCRYPT) ^ substr($plaintext, $i, 8);
1106 $ciphertext.= $iv;
1107 $len-= 8;
1108 $i+= 8;
1109 }
1110 if ($len) {
1111 $iv = $this->_processBlock($iv, CRYPT_DES_ENCRYPT);
1112 $block = $iv ^ substr($plaintext, $i);
1113 $iv = substr_replace($iv, $block, 0, $len);
1114 $ciphertext.= $block;
1115 $pos = $len;
1116 }
1117 return $ciphertext;
1118 case CRYPT_DES_MODE_OFB:
1119 $xor = $this->encryptIV;
1120 if (strlen($buffer['xor'])) {
1121 for ($i = 0; $i < strlen($plaintext); $i+=8) {
1122 $block = substr($plaintext, $i, 8);
1123 if (strlen($block) > strlen($buffer['xor'])) {
1124 $xor = $this->_processBlock($xor, CRYPT_DES_ENCRYPT);
1125 $buffer['xor'].= $xor;
1126 }
1127 $key = $this->_string_shift($buffer['xor']);
1128 $ciphertext.= $block ^ $key;
1129 }
1130 } else {
1131 for ($i = 0; $i < strlen($plaintext); $i+=8) {
1132 $xor = $this->_processBlock($xor, CRYPT_DES_ENCRYPT);
1133 $ciphertext.= substr($plaintext, $i, 8) ^ $xor;
1134 }
1135 $key = $xor;
1136 }
1137 if ($this->continuousBuffer) {
1138 $this->encryptIV = $xor;
1139 if ($start = strlen($plaintext) & 7) {
1140 $buffer['xor'] = substr($key, $start) . $buffer['xor'];
1141 }
1142 }
1143 }
1144
1145 return $ciphertext;
1146 }
1147
1148 /**
1149 * Decrypts a message.
1150 *
1151 * If strlen($ciphertext) is not a multiple of 8, null bytes will be added to the end of the string until it is.
1152 *
1153 * @see Crypt_DES::encrypt()
1154 * @access public
1155 * @param String $ciphertext
1156 */
1157 function decrypt($ciphertext)
1158 {
1159 if ($this->paddable) {
1160 // we pad with chr(0) since that's what mcrypt_generic does. to quote from http://php.net/function.mcrypt-generic :
1161 // "The data is padded with "\0" to make sure the length of the data is n * blocksize."
1162 $ciphertext = str_pad($ciphertext, (strlen($ciphertext) + 7) & 0xFFFFFFF8, chr(0));
1163 }
1164
1165 if ( CRYPT_DES_MODE == CRYPT_DES_MODE_MCRYPT ) {
1166 if ($this->dechanged) {
1167 mcrypt_generic_init($this->demcrypt, $this->keys, $this->decryptIV);
1168 if ($this->mode == 'ncfb') {
1169 mcrypt_generic_init($this->ecb, $this->keys, "\0\0\0\0\0\0\0\0");
1170 }
1171 $this->dechanged = false;
1172 }
1173
1174 if ($this->mode != 'ncfb' || !$this->continuousBuffer) {
1175 $plaintext = mdecrypt_generic($this->demcrypt, $ciphertext);
1176 } else {
1177 $iv = &$this->decryptIV;
1178 $pos = &$this->debuffer['pos'];
1179 $len = strlen($ciphertext);
1180 $plaintext = '';
1181 $i = 0;
1182 if ($pos) {
1183 $orig_pos = $pos;
1184 $max = 8 - $pos;
1185 if ($len >= $max) {
1186 $i = $max;
1187 $len-= $max;
1188 $pos = 0;
1189 } else {
1190 $i = $len;
1191 $pos+= $len;
1192 $len = 0;
1193 }
1194 $plaintext = substr($iv, $orig_pos) ^ $ciphertext;
1195 $iv = substr_replace($iv, substr($ciphertext, 0, $i), $orig_pos, $i);
1196 }
1197 if ($len >= 8) {
1198 $cb = substr($ciphertext, $i, $len - $len % 8);
1199 $plaintext.= mcrypt_generic($this->ecb, $iv . $cb) ^ $cb;
1200 $iv = substr($cb, -8);
1201 $len%= 8;
1202 }
1203 if ($len) {
1204 $iv = mcrypt_generic($this->ecb, $iv);
1205 $plaintext.= $iv ^ substr($ciphertext, -$len);
1206 $iv = substr_replace($iv, substr($ciphertext, -$len), 0, $len);
1207 $pos = $len;
1208 }
1209 return $plaintext;
1210 }
1211
1212 if (!$this->continuousBuffer) {
1213 mcrypt_generic_init($this->demcrypt, $this->keys, $this->decryptIV);
1214 }
1215
1216 return $this->paddable ? $this->_unpad($plaintext) : $plaintext;
1217 }
1218
1219 if (!is_array($this->keys)) {
1220 $this->keys = $this->_prepareKey("\0\0\0\0\0\0\0\0");
1221 }
1222
1223 if ($this->use_inline_crypt) {
1224 $inline = $this->inline_crypt;
1225 return $inline('decrypt', $this, $ciphertext);
1226 }
1227
1228 $buffer = &$this->debuffer;
1229 $continuousBuffer = $this->continuousBuffer;
1230 $plaintext = '';
1231 switch ($this->mode) {
1232 case CRYPT_DES_MODE_ECB:
1233 for ($i = 0; $i < strlen($ciphertext); $i+=8) {
1234 $plaintext.= $this->_processBlock(substr($ciphertext, $i, 8), CRYPT_DES_DECRYPT);
1235 }
1236 break;
1237 case CRYPT_DES_MODE_CBC:
1238 $xor = $this->decryptIV;
1239 for ($i = 0; $i < strlen($ciphertext); $i+=8) {
1240 $block = substr($ciphertext, $i, 8);
1241 $plaintext.= $this->_processBlock($block, CRYPT_DES_DECRYPT) ^ $xor;
1242 $xor = $block;
1243 }
1244 if ($this->continuousBuffer) {
1245 $this->decryptIV = $xor;
1246 }
1247 break;
1248 case CRYPT_DES_MODE_CTR:
1249 $xor = $this->decryptIV;
1250 if (strlen($buffer['ciphertext'])) {
1251 for ($i = 0; $i < strlen($ciphertext); $i+=8) {
1252 $block = substr($ciphertext, $i, 8);
1253 if (strlen($block) > strlen($buffer['ciphertext'])) {
1254 $buffer['ciphertext'].= $this->_processBlock($this->_generate_xor($xor), CRYPT_DES_ENCRYPT);
1255 }
1256 $key = $this->_string_shift($buffer['ciphertext']);
1257 $plaintext.= $block ^ $key;
1258 }
1259 } else {
1260 for ($i = 0; $i < strlen($ciphertext); $i+=8) {
1261 $block = substr($ciphertext, $i, 8);
1262 $key = $this->_processBlock($this->_generate_xor($xor), CRYPT_DES_ENCRYPT);
1263 $plaintext.= $block ^ $key;
1264 }
1265 }
1266 if ($this->continuousBuffer) {
1267 $this->decryptIV = $xor;
1268 if ($start = strlen($ciphertext) % 8) {
1269 $buffer['ciphertext'] = substr($key, $start) . $buffer['ciphertext'];
1270 }
1271 }
1272 break;
1273 case CRYPT_DES_MODE_CFB:
1274 if ($this->continuousBuffer) {
1275 $iv = &$this->decryptIV;
1276 $pos = &$buffer['pos'];
1277 } else {
1278 $iv = $this->decryptIV;
1279 $pos = 0;
1280 }
1281 $len = strlen($ciphertext);
1282 $i = 0;
1283 if ($pos) {
1284 $orig_pos = $pos;
1285 $max = 8 - $pos;
1286 if ($len >= $max) {
1287 $i = $max;
1288 $len-= $max;
1289 $pos = 0;
1290 } else {
1291 $i = $len;
1292 $pos+= $len;
1293 $len = 0;
1294 }
1295 $plaintext = substr($iv, $orig_pos) ^ $ciphertext;
1296 $iv = substr_replace($iv, substr($ciphertext, 0, $i), $orig_pos, $i);
1297 }
1298 while ($len >= 8) {
1299 $iv = $this->_processBlock($iv, CRYPT_DES_ENCRYPT);
1300 $cb = substr($ciphertext, $i, 8);
1301 $plaintext.= $iv ^ $cb;
1302 $iv = $cb;
1303 $len-= 8;
1304 $i+= 8;
1305 }
1306 if ($len) {
1307 $iv = $this->_processBlock($iv, CRYPT_DES_ENCRYPT);
1308 $plaintext.= $iv ^ substr($ciphertext, $i);
1309 $iv = substr_replace($iv, substr($ciphertext, $i), 0, $len);
1310 $pos = $len;
1311 }
1312 return $plaintext;
1313 case CRYPT_DES_MODE_OFB:
1314 $xor = $this->decryptIV;
1315 if (strlen($buffer['xor'])) {
1316 for ($i = 0; $i < strlen($ciphertext); $i+=8) {
1317 $block = substr($ciphertext, $i, 8);
1318 if (strlen($block) > strlen($buffer['xor'])) {
1319 $xor = $this->_processBlock($xor, CRYPT_DES_ENCRYPT);
1320 $buffer['xor'].= $xor;
1321 }
1322 $key = $this->_string_shift($buffer['xor']);
1323 $plaintext.= $block ^ $key;
1324 }
1325 } else {
1326 for ($i = 0; $i < strlen($ciphertext); $i+=8) {
1327 $xor = $this->_processBlock($xor, CRYPT_DES_ENCRYPT);
1328 $plaintext.= substr($ciphertext, $i, 8) ^ $xor;
1329 }
1330 $key = $xor;
1331 }
1332 if ($this->continuousBuffer) {
1333 $this->decryptIV = $xor;
1334 if ($start = strlen($ciphertext) % 8) {
1335 $buffer['xor'] = substr($key, $start) . $buffer['xor'];
1336 }
1337 }
1338 }
1339
1340 return $this->paddable ? $this->_unpad($plaintext) : $plaintext;
1341 }
1342
1343 /**
1344 * Treat consecutive "packets" as if they are a continuous buffer.
1345 *
1346 * Say you have a 16-byte plaintext $plaintext. Using the default behavior, the two following code snippets
1347 * will yield different outputs:
1348 *
1349 * <code>
1350 * echo $des->encrypt(substr($plaintext, 0, 8));
1351 * echo $des->encrypt(substr($plaintext, 8, 8));
1352 * </code>
1353 * <code>
1354 * echo $des->encrypt($plaintext);
1355 * </code>
1356 *
1357 * The solution is to enable the continuous buffer. Although this will resolve the above discrepancy, it creates
1358 * another, as demonstrated with the following:
1359 *
1360 * <code>
1361 * $des->encrypt(substr($plaintext, 0, 8));
1362 * echo $des->decrypt($des->encrypt(substr($plaintext, 8, 8)));
1363 * </code>
1364 * <code>
1365 * echo $des->decrypt($des->encrypt(substr($plaintext, 8, 8)));
1366 * </code>
1367 *
1368 * With the continuous buffer disabled, these would yield the same output. With it enabled, they yield different
1369 * outputs. The reason is due to the fact that the initialization vector's change after every encryption /
1370 * decryption round when the continuous buffer is enabled. When it's disabled, they remain constant.
1371 *
1372 * Put another way, when the continuous buffer is enabled, the state of the Crypt_DES() object changes after each
1373 * encryption / decryption round, whereas otherwise, it'd remain constant. For this reason, it's recommended that
1374 * continuous buffers not be used. They do offer better security and are, in fact, sometimes required (SSH uses them),
1375 * however, they are also less intuitive and more likely to cause you problems.
1376 *
1377 * @see Crypt_DES::disableContinuousBuffer()
1378 * @access public
1379 */
1380 function enableContinuousBuffer()
1381 {
1382 $this->continuousBuffer = true;
1383 }
1384
1385 /**
1386 * Treat consecutive packets as if they are a discontinuous buffer.
1387 *
1388 * The default behavior.
1389 *
1390 * @see Crypt_DES::enableContinuousBuffer()
1391 * @access public
1392 */
1393 function disableContinuousBuffer()
1394 {
1395 $this->continuousBuffer = false;
1396 $this->encryptIV = $this->iv;
1397 $this->decryptIV = $this->iv;
1398 $this->enbuffer = array('encrypted' => '', 'xor' => '', 'pos' => 0, 'enmcrypt_init' => true);
1399 $this->debuffer = array('ciphertext' => '', 'xor' => '', 'pos' => 0, 'demcrypt_init' => true);
1400
1401 if (CRYPT_DES_MODE == CRYPT_DES_MODE_MCRYPT) {
1402 mcrypt_generic_init($this->enmcrypt, $this->keys, $this->iv);
1403 mcrypt_generic_init($this->demcrypt, $this->keys, $this->iv);
1404 }
1405 }
1406
1407 /**
1408 * Pad "packets".
1409 *
1410 * DES works by encrypting eight bytes at a time. If you ever need to encrypt or decrypt something that's not
1411 * a multiple of eight, it becomes necessary to pad the input so that it's length is a multiple of eight.
1412 *
1413 * Padding is enabled by default. Sometimes, however, it is undesirable to pad strings. Such is the case in SSH1,
1414 * where "packets" are padded with random bytes before being encrypted. Unpad these packets and you risk stripping
1415 * away characters that shouldn't be stripped away. (SSH knows how many bytes are added because the length is
1416 * transmitted separately)
1417 *
1418 * @see Crypt_DES::disablePadding()
1419 * @access public
1420 */
1421 function enablePadding()
1422 {
1423 $this->padding = true;
1424 }
1425
1426 /**
1427 * Do not pad packets.
1428 *
1429 * @see Crypt_DES::enablePadding()
1430 * @access public
1431 */
1432 function disablePadding()
1433 {
1434 $this->padding = false;
1435 }
1436
1437 /**
1438 * Pads a string
1439 *
1440 * Pads a string using the RSA PKCS padding standards so that its length is a multiple of the blocksize (8).
1441 * 8 - (strlen($text) & 7) bytes are added, each of which is equal to chr(8 - (strlen($text) & 7)
1442 *
1443 * If padding is disabled and $text is not a multiple of the blocksize, the string will be padded regardless
1444 * and padding will, hence forth, be enabled.
1445 *
1446 * @see Crypt_DES::_unpad()
1447 * @access private
1448 */
1449 function _pad($text)
1450 {
1451 $length = strlen($text);
1452
1453 if (!$this->padding) {
1454 if (($length & 7) == 0) {
1455 return $text;
1456 } else {
1457 user_error("The plaintext's length ($length) is not a multiple of the block size (8)");
1458 $this->padding = true;
1459 }
1460 }
1461
1462 $pad = 8 - ($length & 7);
1463 return str_pad($text, $length + $pad, chr($pad));
1464 }
1465
1466 /**
1467 * Unpads a string
1468 *
1469 * If padding is enabled and the reported padding length is invalid the encryption key will be assumed to be wrong
1470 * and false will be returned.
1471 *
1472 * @see Crypt_DES::_pad()
1473 * @access private
1474 */
1475 function _unpad($text)
1476 {
1477 if (!$this->padding) {
1478 return $text;
1479 }
1480
1481 $length = ord($text[strlen($text) - 1]);
1482
1483 if (!$length || $length > 8) {
1484 return false;
1485 }
1486
1487 return substr($text, 0, -$length);
1488 }
1489
1490 /**
1491 * Encrypts or decrypts a 64-bit block
1492 *
1493 * $mode should be either CRYPT_DES_ENCRYPT or CRYPT_DES_DECRYPT. See
1494 * {@link http://en.wikipedia.org/wiki/Image:Feistel.png Feistel.png} to get a general
1495 * idea of what this function does.
1496 *
1497 * @access private
1498 * @param String $block
1499 * @param Integer $mode
1500 * @return String
1501 */
1502 function _processBlock($block, $mode)
1503 {
1504 $shuffle = $this->shuffle;
1505 $invipmap = $this->invipmap;
1506 $ipmap = $this->ipmap;
1507 $sbox1 = $this->sbox1;
1508 $sbox2 = $this->sbox2;
1509 $sbox3 = $this->sbox3;
1510 $sbox4 = $this->sbox4;
1511 $sbox5 = $this->sbox5;
1512 $sbox6 = $this->sbox6;
1513 $sbox7 = $this->sbox7;
1514 $sbox8 = $this->sbox8;
1515 $keys = $this->keys[$mode];
1516
1517 // Do the initial IP permutation.
1518 $t = unpack('Nl/Nr', $block);
1519 list($l, $r) = array($t['l'], $t['r']);
1520 $block = ($shuffle[$ipmap[$r & 0xFF]] & "\x80\x80\x80\x80\x80\x80\x80\x80") |
1521 ($shuffle[$ipmap[($r >> 8) & 0xFF]] & "\x40\x40\x40\x40\x40\x40\x40\x40") |
1522 ($shuffle[$ipmap[($r >> 16) & 0xFF]] & "\x20\x20\x20\x20\x20\x20\x20\x20") |
1523 ($shuffle[$ipmap[($r >> 24) & 0xFF]] & "\x10\x10\x10\x10\x10\x10\x10\x10") |
1524 ($shuffle[$ipmap[$l & 0xFF]] & "\x08\x08\x08\x08\x08\x08\x08\x08") |
1525 ($shuffle[$ipmap[($l >> 8) & 0xFF]] & "\x04\x04\x04\x04\x04\x04\x04\x04") |
1526 ($shuffle[$ipmap[($l >> 16) & 0xFF]] & "\x02\x02\x02\x02\x02\x02\x02\x02") |
1527 ($shuffle[$ipmap[($l >> 24) & 0xFF]] & "\x01\x01\x01\x01\x01\x01\x01\x01");
1528
1529 // Extract L0 and R0.
1530 $t = unpack('Nl/Nr', $block);
1531 list($l, $r) = array($t['l'], $t['r']);
1532
1533 // Perform the 16 steps.
1534 for ($i = 0; $i < 16; $i++) {
1535 // start of "the Feistel (F) function" - see the following URL:
1536 // http://en.wikipedia.org/wiki/Image:Data_Encryption_Standard_InfoBox_Diagram.png
1537 // Merge key schedule.
1538 $b1 = (($r >> 3) & 0x1FFFFFFF) ^ ($r << 29) ^ $keys[$i][0];
1539 $b2 = (($r >> 31) & 0x00000001) ^ ($r << 1) ^ $keys[$i][1];
1540
1541 // S-box indexing.
1542 $t = $sbox1[($b1 >> 24) & 0x3F] ^ $sbox2[($b2 >> 24) & 0x3F] ^
1543 $sbox3[($b1 >> 16) & 0x3F] ^ $sbox4[($b2 >> 16) & 0x3F] ^
1544 $sbox5[($b1 >> 8) & 0x3F] ^ $sbox6[($b2 >> 8) & 0x3F] ^
1545 $sbox7[$b1 & 0x3F] ^ $sbox8[$b2 & 0x3F] ^ $l;
1546 // end of "the Feistel (F) function"
1547
1548 $l = $r;
1549 $r = $t;
1550 }
1551
1552 // Perform the inverse IP permutation.
1553 return ($shuffle[$invipmap[($l >> 24) & 0xFF]] & "\x80\x80\x80\x80\x80\x80\x80\x80") |
1554 ($shuffle[$invipmap[($r >> 24) & 0xFF]] & "\x40\x40\x40\x40\x40\x40\x40\x40") |
1555 ($shuffle[$invipmap[($l >> 16) & 0xFF]] & "\x20\x20\x20\x20\x20\x20\x20\x20") |
1556 ($shuffle[$invipmap[($r >> 16) & 0xFF]] & "\x10\x10\x10\x10\x10\x10\x10\x10") |
1557 ($shuffle[$invipmap[($l >> 8) & 0xFF]] & "\x08\x08\x08\x08\x08\x08\x08\x08") |
1558 ($shuffle[$invipmap[($r >> 8) & 0xFF]] & "\x04\x04\x04\x04\x04\x04\x04\x04") |
1559 ($shuffle[$invipmap[$l & 0xFF]] & "\x02\x02\x02\x02\x02\x02\x02\x02") |
1560 ($shuffle[$invipmap[$r & 0xFF]] & "\x01\x01\x01\x01\x01\x01\x01\x01");
1561 }
1562
1563 /**
1564 * Creates the key schedule.
1565 *
1566 * @access private
1567 * @param String $key
1568 * @return Array
1569 */
1570 function _prepareKey($key)
1571 {
1572 static $shifts = array( // number of key bits shifted per round
1573 1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1
1574 );
1575
1576 static $pc1map = array(
1577 0x00, 0x00, 0x08, 0x08, 0x04, 0x04, 0x0C, 0x0C,
1578 0x02, 0x02, 0x0A, 0x0A, 0x06, 0x06, 0x0E, 0x0E,
1579 0x10, 0x10, 0x18, 0x18, 0x14, 0x14, 0x1C, 0x1C,
1580 0x12, 0x12, 0x1A, 0x1A, 0x16, 0x16, 0x1E, 0x1E,
1581 0x20, 0x20, 0x28, 0x28, 0x24, 0x24, 0x2C, 0x2C,
1582 0x22, 0x22, 0x2A, 0x2A, 0x26, 0x26, 0x2E, 0x2E,
1583 0x30, 0x30, 0x38, 0x38, 0x34, 0x34, 0x3C, 0x3C,
1584 0x32, 0x32, 0x3A, 0x3A, 0x36, 0x36, 0x3E, 0x3E,
1585 0x40, 0x40, 0x48, 0x48, 0x44, 0x44, 0x4C, 0x4C,
1586 0x42, 0x42, 0x4A, 0x4A, 0x46, 0x46, 0x4E, 0x4E,
1587 0x50, 0x50, 0x58, 0x58, 0x54, 0x54, 0x5C, 0x5C,
1588 0x52, 0x52, 0x5A, 0x5A, 0x56, 0x56, 0x5E, 0x5E,
1589 0x60, 0x60, 0x68, 0x68, 0x64, 0x64, 0x6C, 0x6C,
1590 0x62, 0x62, 0x6A, 0x6A, 0x66, 0x66, 0x6E, 0x6E,
1591 0x70, 0x70, 0x78, 0x78, 0x74, 0x74, 0x7C, 0x7C,
1592 0x72, 0x72, 0x7A, 0x7A, 0x76, 0x76, 0x7E, 0x7E,
1593 0x80, 0x80, 0x88, 0x88, 0x84, 0x84, 0x8C, 0x8C,
1594 0x82, 0x82, 0x8A, 0x8A, 0x86, 0x86, 0x8E, 0x8E,
1595 0x90, 0x90, 0x98, 0x98, 0x94, 0x94, 0x9C, 0x9C,
1596 0x92, 0x92, 0x9A, 0x9A, 0x96, 0x96, 0x9E, 0x9E,
1597 0xA0, 0xA0, 0xA8, 0xA8, 0xA4, 0xA4, 0xAC, 0xAC,
1598 0xA2, 0xA2, 0xAA, 0xAA, 0xA6, 0xA6, 0xAE, 0xAE,
1599 0xB0, 0xB0, 0xB8, 0xB8, 0xB4, 0xB4, 0xBC, 0xBC,
1600 0xB2, 0xB2, 0xBA, 0xBA, 0xB6, 0xB6, 0xBE, 0xBE,
1601 0xC0, 0xC0, 0xC8, 0xC8, 0xC4, 0xC4, 0xCC, 0xCC,
1602 0xC2, 0xC2, 0xCA, 0xCA, 0xC6, 0xC6, 0xCE, 0xCE,
1603 0xD0, 0xD0, 0xD8, 0xD8, 0xD4, 0xD4, 0xDC, 0xDC,
1604 0xD2, 0xD2, 0xDA, 0xDA, 0xD6, 0xD6, 0xDE, 0xDE,
1605 0xE0, 0xE0, 0xE8, 0xE8, 0xE4, 0xE4, 0xEC, 0xEC,
1606 0xE2, 0xE2, 0xEA, 0xEA, 0xE6, 0xE6, 0xEE, 0xEE,
1607 0xF0, 0xF0, 0xF8, 0xF8, 0xF4, 0xF4, 0xFC, 0xFC,
1608 0xF2, 0xF2, 0xFA, 0xFA, 0xF6, 0xF6, 0xFE, 0xFE
1609 );
1610
1611 // Mapping tables for the PC-2 transformation.
1612 static $pc2mapc1 = array(
1613 0x00000000, 0x00000400, 0x00200000, 0x00200400,
1614 0x00000001, 0x00000401, 0x00200001, 0x00200401,
1615 0x02000000, 0x02000400, 0x02200000, 0x02200400,
1616 0x02000001, 0x02000401, 0x02200001, 0x02200401
1617 );
1618 static $pc2mapc2 = array(
1619 0x00000000, 0x00000800, 0x08000000, 0x08000800,
1620 0x00010000, 0x00010800, 0x08010000, 0x08010800,
1621 0x00000000, 0x00000800, 0x08000000, 0x08000800,
1622 0x00010000, 0x00010800, 0x08010000, 0x08010800,
1623 0x00000100, 0x00000900, 0x08000100, 0x08000900,
1624 0x00010100, 0x00010900, 0x08010100, 0x08010900,
1625 0x00000100, 0x00000900, 0x08000100, 0x08000900,
1626 0x00010100, 0x00010900, 0x08010100, 0x08010900,
1627 0x00000010, 0x00000810, 0x08000010, 0x08000810,
1628 0x00010010, 0x00010810, 0x08010010, 0x08010810,
1629 0x00000010, 0x00000810, 0x08000010, 0x08000810,
1630 0x00010010, 0x00010810, 0x08010010, 0x08010810,
1631 0x00000110, 0x00000910, 0x08000110, 0x08000910,
1632 0x00010110, 0x00010910, 0x08010110, 0x08010910,
1633 0x00000110, 0x00000910, 0x08000110, 0x08000910,
1634 0x00010110, 0x00010910, 0x08010110, 0x08010910,
1635 0x00040000, 0x00040800, 0x08040000, 0x08040800,
1636 0x00050000, 0x00050800, 0x08050000, 0x08050800,
1637 0x00040000, 0x00040800, 0x08040000, 0x08040800,
1638 0x00050000, 0x00050800, 0x08050000, 0x08050800,
1639 0x00040100, 0x00040900, 0x08040100, 0x08040900,
1640 0x00050100, 0x00050900, 0x08050100, 0x08050900,
1641 0x00040100, 0x00040900, 0x08040100, 0x08040900,
1642 0x00050100, 0x00050900, 0x08050100, 0x08050900,
1643 0x00040010, 0x00040810, 0x08040010, 0x08040810,
1644 0x00050010, 0x00050810, 0x08050010, 0x08050810,
1645 0x00040010, 0x00040810, 0x08040010, 0x08040810,
1646 0x00050010, 0x00050810, 0x08050010, 0x08050810,
1647 0x00040110, 0x00040910, 0x08040110, 0x08040910,
1648 0x00050110, 0x00050910, 0x08050110, 0x08050910,
1649 0x00040110, 0x00040910, 0x08040110, 0x08040910,
1650 0x00050110, 0x00050910, 0x08050110, 0x08050910,
1651 0x01000000, 0x01000800, 0x09000000, 0x09000800,
1652 0x01010000, 0x01010800, 0x09010000, 0x09010800,
1653 0x01000000, 0x01000800, 0x09000000, 0x09000800,
1654 0x01010000, 0x01010800, 0x09010000, 0x09010800,
1655 0x01000100, 0x01000900, 0x09000100, 0x09000900,
1656 0x01010100, 0x01010900, 0x09010100, 0x09010900,
1657 0x01000100, 0x01000900, 0x09000100, 0x09000900,
1658 0x01010100, 0x01010900, 0x09010100, 0x09010900,
1659 0x01000010, 0x01000810, 0x09000010, 0x09000810,
1660 0x01010010, 0x01010810, 0x09010010, 0x09010810,
1661 0x01000010, 0x01000810, 0x09000010, 0x09000810,
1662 0x01010010, 0x01010810, 0x09010010, 0x09010810,
1663 0x01000110, 0x01000910, 0x09000110, 0x09000910,
1664 0x01010110, 0x01010910, 0x09010110, 0x09010910,
1665 0x01000110, 0x01000910, 0x09000110, 0x09000910,
1666 0x01010110, 0x01010910, 0x09010110, 0x09010910,
1667 0x01040000, 0x01040800, 0x09040000, 0x09040800,
1668 0x01050000, 0x01050800, 0x09050000, 0x09050800,
1669 0x01040000, 0x01040800, 0x09040000, 0x09040800,
1670 0x01050000, 0x01050800, 0x09050000, 0x09050800,
1671 0x01040100, 0x01040900, 0x09040100, 0x09040900,
1672 0x01050100, 0x01050900, 0x09050100, 0x09050900,
1673 0x01040100, 0x01040900, 0x09040100, 0x09040900,
1674 0x01050100, 0x01050900, 0x09050100, 0x09050900,
1675 0x01040010, 0x01040810, 0x09040010, 0x09040810,
1676 0x01050010, 0x01050810, 0x09050010, 0x09050810,
1677 0x01040010, 0x01040810, 0x09040010, 0x09040810,
1678 0x01050010, 0x01050810, 0x09050010, 0x09050810,
1679 0x01040110, 0x01040910, 0x09040110, 0x09040910,
1680 0x01050110, 0x01050910, 0x09050110, 0x09050910,
1681 0x01040110, 0x01040910, 0x09040110, 0x09040910,
1682 0x01050110, 0x01050910, 0x09050110, 0x09050910
1683 );
1684 static $pc2mapc3 = array(
1685 0x00000000, 0x00000004, 0x00001000, 0x00001004,
1686 0x00000000, 0x00000004, 0x00001000, 0x00001004,
1687 0x10000000, 0x10000004, 0x10001000, 0x10001004,
1688 0x10000000, 0x10000004, 0x10001000, 0x10001004,
1689 0x00000020, 0x00000024, 0x00001020, 0x00001024,
1690 0x00000020, 0x00000024, 0x00001020, 0x00001024,
1691 0x10000020, 0x10000024, 0x10001020, 0x10001024,
1692 0x10000020, 0x10000024, 0x10001020, 0x10001024,
1693 0x00080000, 0x00080004, 0x00081000, 0x00081004,
1694 0x00080000, 0x00080004, 0x00081000, 0x00081004,
1695 0x10080000, 0x10080004, 0x10081000, 0x10081004,
1696 0x10080000, 0x10080004, 0x10081000, 0x10081004,
1697 0x00080020, 0x00080024, 0x00081020, 0x00081024,
1698 0x00080020, 0x00080024, 0x00081020, 0x00081024,
1699 0x10080020, 0x10080024, 0x10081020, 0x10081024,
1700 0x10080020, 0x10080024, 0x10081020, 0x10081024,
1701 0x20000000, 0x20000004, 0x20001000, 0x20001004,
1702 0x20000000, 0x20000004, 0x20001000, 0x20001004,
1703 0x30000000, 0x30000004, 0x30001000, 0x30001004,
1704 0x30000000, 0x30000004, 0x30001000, 0x30001004,
1705 0x20000020, 0x20000024, 0x20001020, 0x20001024,
1706 0x20000020, 0x20000024, 0x20001020, 0x20001024,
1707 0x30000020, 0x30000024, 0x30001020, 0x30001024,
1708 0x30000020, 0x30000024, 0x30001020, 0x30001024,
1709 0x20080000, 0x20080004, 0x20081000, 0x20081004,
1710 0x20080000, 0x20080004, 0x20081000, 0x20081004,
1711 0x30080000, 0x30080004, 0x30081000, 0x30081004,
1712 0x30080000, 0x30080004, 0x30081000, 0x30081004,
1713 0x20080020, 0x20080024, 0x20081020, 0x20081024,
1714 0x20080020, 0x20080024, 0x20081020, 0x20081024,
1715 0x30080020, 0x30080024, 0x30081020, 0x30081024,
1716 0x30080020, 0x30080024, 0x30081020, 0x30081024,
1717 0x00000002, 0x00000006, 0x00001002, 0x00001006,
1718 0x00000002, 0x00000006, 0x00001002, 0x00001006,
1719 0x10000002, 0x10000006, 0x10001002, 0x10001006,
1720 0x10000002, 0x10000006, 0x10001002, 0x10001006,
1721 0x00000022, 0x00000026, 0x00001022, 0x00001026,
1722 0x00000022, 0x00000026, 0x00001022, 0x00001026,
1723 0x10000022, 0x10000026, 0x10001022, 0x10001026,
1724 0x10000022, 0x10000026, 0x10001022, 0x10001026,
1725 0x00080002, 0x00080006, 0x00081002, 0x00081006,
1726 0x00080002, 0x00080006, 0x00081002, 0x00081006,
1727 0x10080002, 0x10080006, 0x10081002, 0x10081006,
1728 0x10080002, 0x10080006, 0x10081002, 0x10081006,
1729 0x00080022, 0x00080026, 0x00081022, 0x00081026,
1730 0x00080022, 0x00080026, 0x00081022, 0x00081026,
1731 0x10080022, 0x10080026, 0x10081022, 0x10081026,
1732 0x10080022, 0x10080026, 0x10081022, 0x10081026,
1733 0x20000002, 0x20000006, 0x20001002, 0x20001006,
1734 0x20000002, 0x20000006, 0x20001002, 0x20001006,
1735 0x30000002, 0x30000006, 0x30001002, 0x30001006,
1736 0x30000002, 0x30000006, 0x30001002, 0x30001006,
1737 0x20000022, 0x20000026, 0x20001022, 0x20001026,
1738 0x20000022, 0x20000026, 0x20001022, 0x20001026,
1739 0x30000022, 0x30000026, 0x30001022, 0x30001026,
1740 0x30000022, 0x30000026, 0x30001022, 0x30001026,
1741 0x20080002, 0x20080006, 0x20081002, 0x20081006,
1742 0x20080002, 0x20080006, 0x20081002, 0x20081006,
1743 0x30080002, 0x30080006, 0x30081002, 0x30081006,
1744 0x30080002, 0x30080006, 0x30081002, 0x30081006,
1745 0x20080022, 0x20080026, 0x20081022, 0x20081026,
1746 0x20080022, 0x20080026, 0x20081022, 0x20081026,
1747 0x30080022, 0x30080026, 0x30081022, 0x30081026,
1748 0x30080022, 0x30080026, 0x30081022, 0x30081026
1749 );
1750 static $pc2mapc4 = array(
1751 0x00000000, 0x00100000, 0x00000008, 0x00100008,
1752 0x00000200, 0x00100200, 0x00000208, 0x00100208,
1753 0x00000000, 0x00100000, 0x00000008, 0x00100008,
1754 0x00000200, 0x00100200, 0x00000208, 0x00100208,
1755 0x04000000, 0x04100000, 0x04000008, 0x04100008,
1756 0x04000200, 0x04100200, 0x04000208, 0x04100208,
1757 0x04000000, 0x04100000, 0x04000008, 0x04100008,
1758 0x04000200, 0x04100200, 0x04000208, 0x04100208,
1759 0x00002000, 0x00102000, 0x00002008, 0x00102008,
1760 0x00002200, 0x00102200, 0x00002208, 0x00102208,
1761 0x00002000, 0x00102000, 0x00002008, 0x00102008,
1762 0x00002200, 0x00102200, 0x00002208, 0x00102208,
1763 0x04002000, 0x04102000, 0x04002008, 0x04102008,
1764 0x04002200, 0x04102200, 0x04002208, 0x04102208,
1765 0x04002000, 0x04102000, 0x04002008, 0x04102008,
1766 0x04002200, 0x04102200, 0x04002208, 0x04102208,
1767 0x00000000, 0x00100000, 0x00000008, 0x00100008,
1768 0x00000200, 0x00100200, 0x00000208, 0x00100208,
1769 0x00000000, 0x00100000, 0x00000008, 0x00100008,
1770 0x00000200, 0x00100200, 0x00000208, 0x00100208,
1771 0x04000000, 0x04100000, 0x04000008, 0x04100008,
1772 0x04000200, 0x04100200, 0x04000208, 0x04100208,
1773 0x04000000, 0x04100000, 0x04000008, 0x04100008,
1774 0x04000200, 0x04100200, 0x04000208, 0x04100208,
1775 0x00002000, 0x00102000, 0x00002008, 0x00102008,
1776 0x00002200, 0x00102200, 0x00002208, 0x00102208,
1777 0x00002000, 0x00102000, 0x00002008, 0x00102008,
1778 0x00002200, 0x00102200, 0x00002208, 0x00102208,
1779 0x04002000, 0x04102000, 0x04002008, 0x04102008,
1780 0x04002200, 0x04102200, 0x04002208, 0x04102208,
1781 0x04002000, 0x04102000, 0x04002008, 0x04102008,
1782 0x04002200, 0x04102200, 0x04002208, 0x04102208,
1783 0x00020000, 0x00120000, 0x00020008, 0x00120008,
1784 0x00020200, 0x00120200, 0x00020208, 0x00120208,
1785 0x00020000, 0x00120000, 0x00020008, 0x00120008,
1786 0x00020200, 0x00120200, 0x00020208, 0x00120208,
1787 0x04020000, 0x04120000, 0x04020008, 0x04120008,
1788 0x04020200, 0x04120200, 0x04020208, 0x04120208,
1789 0x04020000, 0x04120000, 0x04020008, 0x04120008,
1790 0x04020200, 0x04120200, 0x04020208, 0x04120208,
1791 0x00022000, 0x00122000, 0x00022008, 0x00122008,
1792 0x00022200, 0x00122200, 0x00022208, 0x00122208,
1793 0x00022000, 0x00122000, 0x00022008, 0x00122008,
1794 0x00022200, 0x00122200, 0x00022208, 0x00122208,
1795 0x04022000, 0x04122000, 0x04022008, 0x04122008,
1796 0x04022200, 0x04122200, 0x04022208, 0x04122208,
1797 0x04022000, 0x04122000, 0x04022008, 0x04122008,
1798 0x04022200, 0x04122200, 0x04022208, 0x04122208,
1799 0x00020000, 0x00120000, 0x00020008, 0x00120008,
1800 0x00020200, 0x00120200, 0x00020208, 0x00120208,
1801 0x00020000, 0x00120000, 0x00020008, 0x00120008,
1802 0x00020200, 0x00120200, 0x00020208, 0x00120208,
1803 0x04020000, 0x04120000, 0x04020008, 0x04120008,
1804 0x04020200, 0x04120200, 0x04020208, 0x04120208,
1805 0x04020000, 0x04120000, 0x04020008, 0x04120008,
1806 0x04020200, 0x04120200, 0x04020208, 0x04120208,
1807 0x00022000, 0x00122000, 0x00022008, 0x00122008,
1808 0x00022200, 0x00122200, 0x00022208, 0x00122208,
1809 0x00022000, 0x00122000, 0x00022008, 0x00122008,
1810 0x00022200, 0x00122200, 0x00022208, 0x00122208,
1811 0x04022000, 0x04122000, 0x04022008, 0x04122008,
1812 0x04022200, 0x04122200, 0x04022208, 0x04122208,
1813 0x04022000, 0x04122000, 0x04022008, 0x04122008,
1814 0x04022200, 0x04122200, 0x04022208, 0x04122208
1815 );
1816 static $pc2mapd1 = array(
1817 0x00000000, 0x00000001, 0x08000000, 0x08000001,
1818 0x00200000, 0x00200001, 0x08200000, 0x08200001,
1819 0x00000002, 0x00000003, 0x08000002, 0x08000003,
1820 0x00200002, 0x00200003, 0x08200002, 0x08200003
1821 );
1822 static $pc2mapd2 = array(
1823 0x00000000, 0x00100000, 0x00000800, 0x00100800,
1824 0x00000000, 0x00100000, 0x00000800, 0x00100800,
1825 0x04000000, 0x04100000, 0x04000800, 0x04100800,
1826 0x04000000, 0x04100000, 0x04000800, 0x04100800,
1827 0x00000004, 0x00100004, 0x00000804, 0x00100804,
1828 0x00000004, 0x00100004, 0x00000804, 0x00100804,
1829 0x04000004, 0x04100004, 0x04000804, 0x04100804,
1830 0x04000004, 0x04100004, 0x04000804, 0x04100804,
1831 0x00000000, 0x00100000, 0x00000800, 0x00100800,
1832 0x00000000, 0x00100000, 0x00000800, 0x00100800,
1833 0x04000000, 0x04100000, 0x04000800, 0x04100800,
1834 0x04000000, 0x04100000, 0x04000800, 0x04100800,
1835 0x00000004, 0x00100004, 0x00000804, 0x00100804,
1836 0x00000004, 0x00100004, 0x00000804, 0x00100804,
1837 0x04000004, 0x04100004, 0x04000804, 0x04100804,
1838 0x04000004, 0x04100004, 0x04000804, 0x04100804,
1839 0x00000200, 0x00100200, 0x00000A00, 0x00100A00,
1840 0x00000200, 0x00100200, 0x00000A00, 0x00100A00,
1841 0x04000200, 0x04100200, 0x04000A00, 0x04100A00,
1842 0x04000200, 0x04100200, 0x04000A00, 0x04100A00,
1843 0x00000204, 0x00100204, 0x00000A04, 0x00100A04,
1844 0x00000204, 0x00100204, 0x00000A04, 0x00100A04,
1845 0x04000204, 0x04100204, 0x04000A04, 0x04100A04,
1846 0x04000204, 0x04100204, 0x04000A04, 0x04100A04,
1847 0x00000200, 0x00100200, 0x00000A00, 0x00100A00,
1848 0x00000200, 0x00100200, 0x00000A00, 0x00100A00,
1849 0x04000200, 0x04100200, 0x04000A00, 0x04100A00,
1850 0x04000200, 0x04100200, 0x04000A00, 0x04100A00,
1851 0x00000204, 0x00100204, 0x00000A04, 0x00100A04,
1852 0x00000204, 0x00100204, 0x00000A04, 0x00100A04,
1853 0x04000204, 0x04100204, 0x04000A04, 0x04100A04,
1854 0x04000204, 0x04100204, 0x04000A04, 0x04100A04,
1855 0x00020000, 0x00120000, 0x00020800, 0x00120800,
1856 0x00020000, 0x00120000, 0x00020800, 0x00120800,
1857 0x04020000, 0x04120000, 0x04020800, 0x04120800,
1858 0x04020000, 0x04120000, 0x04020800, 0x04120800,
1859 0x00020004, 0x00120004, 0x00020804, 0x00120804,
1860 0x00020004, 0x00120004, 0x00020804, 0x00120804,
1861 0x04020004, 0x04120004, 0x04020804, 0x04120804,
1862 0x04020004, 0x04120004, 0x04020804, 0x04120804,
1863 0x00020000, 0x00120000, 0x00020800, 0x00120800,
1864 0x00020000, 0x00120000, 0x00020800, 0x00120800,
1865 0x04020000, 0x04120000, 0x04020800, 0x04120800,
1866 0x04020000, 0x04120000, 0x04020800, 0x04120800,
1867 0x00020004, 0x00120004, 0x00020804, 0x00120804,
1868 0x00020004, 0x00120004, 0x00020804, 0x00120804,
1869 0x04020004, 0x04120004, 0x04020804, 0x04120804,
1870 0x04020004, 0x04120004, 0x04020804, 0x04120804,
1871 0x00020200, 0x00120200, 0x00020A00, 0x00120A00,
1872 0x00020200, 0x00120200, 0x00020A00, 0x00120A00,
1873 0x04020200, 0x04120200, 0x04020A00, 0x04120A00,
1874 0x04020200, 0x04120200, 0x04020A00, 0x04120A00,
1875 0x00020204, 0x00120204, 0x00020A04, 0x00120A04,
1876 0x00020204, 0x00120204, 0x00020A04, 0x00120A04,
1877 0x04020204, 0x04120204, 0x04020A04, 0x04120A04,
1878 0x04020204, 0x04120204, 0x04020A04, 0x04120A04,
1879 0x00020200, 0x00120200, 0x00020A00, 0x00120A00,
1880 0x00020200, 0x00120200, 0x00020A00, 0x00120A00,
1881 0x04020200, 0x04120200, 0x04020A00, 0x04120A00,
1882 0x04020200, 0x04120200, 0x04020A00, 0x04120A00,
1883 0x00020204, 0x00120204, 0x00020A04, 0x00120A04,
1884 0x00020204, 0x00120204, 0x00020A04, 0x00120A04,
1885 0x04020204, 0x04120204, 0x04020A04, 0x04120A04,
1886 0x04020204, 0x04120204, 0x04020A04, 0x04120A04
1887 );
1888 static $pc2mapd3 = array(
1889 0x00000000, 0x00010000, 0x02000000, 0x02010000,
1890 0x00000020, 0x00010020, 0x02000020, 0x02010020,
1891 0x00040000, 0x00050000, 0x02040000, 0x02050000,
1892 0x00040020, 0x00050020, 0x02040020, 0x02050020,
1893 0x00002000, 0x00012000, 0x02002000, 0x02012000,
1894 0x00002020, 0x00012020, 0x02002020, 0x02012020,
1895 0x00042000, 0x00052000, 0x02042000, 0x02052000,
1896 0x00042020, 0x00052020, 0x02042020, 0x02052020,
1897 0x00000000, 0x00010000, 0x02000000, 0x02010000,
1898 0x00000020, 0x00010020, 0x02000020, 0x02010020,
1899 0x00040000, 0x00050000, 0x02040000, 0x02050000,
1900 0x00040020, 0x00050020, 0x02040020, 0x02050020,
1901 0x00002000, 0x00012000, 0x02002000, 0x02012000,
1902 0x00002020, 0x00012020, 0x02002020, 0x02012020,
1903 0x00042000, 0x00052000, 0x02042000, 0x02052000,
1904 0x00042020, 0x00052020, 0x02042020, 0x02052020,
1905 0x00000010, 0x00010010, 0x02000010, 0x02010010,
1906 0x00000030, 0x00010030, 0x02000030, 0x02010030,
1907 0x00040010, 0x00050010, 0x02040010, 0x02050010,
1908 0x00040030, 0x00050030, 0x02040030, 0x02050030,
1909 0x00002010, 0x00012010, 0x02002010, 0x02012010,
1910 0x00002030, 0x00012030, 0x02002030, 0x02012030,
1911 0x00042010, 0x00052010, 0x02042010, 0x02052010,
1912 0x00042030, 0x00052030, 0x02042030, 0x02052030,
1913 0x00000010, 0x00010010, 0x02000010, 0x02010010,
1914 0x00000030, 0x00010030, 0x02000030, 0x02010030,
1915 0x00040010, 0x00050010, 0x02040010, 0x02050010,
1916 0x00040030, 0x00050030, 0x02040030, 0x02050030,
1917 0x00002010, 0x00012010, 0x02002010, 0x02012010,
1918 0x00002030, 0x00012030, 0x02002030, 0x02012030,
1919 0x00042010, 0x00052010, 0x02042010, 0x02052010,
1920 0x00042030, 0x00052030, 0x02042030, 0x02052030,
1921 0x20000000, 0x20010000, 0x22000000, 0x22010000,
1922 0x20000020, 0x20010020, 0x22000020, 0x22010020,
1923 0x20040000, 0x20050000, 0x22040000, 0x22050000,
1924 0x20040020, 0x20050020, 0x22040020, 0x22050020,
1925 0x20002000, 0x20012000, 0x22002000, 0x22012000,
1926 0x20002020, 0x20012020, 0x22002020, 0x22012020,
1927 0x20042000, 0x20052000, 0x22042000, 0x22052000,
1928 0x20042020, 0x20052020, 0x22042020, 0x22052020,
1929 0x20000000, 0x20010000, 0x22000000, 0x22010000,
1930 0x20000020, 0x20010020, 0x22000020, 0x22010020,
1931 0x20040000, 0x20050000, 0x22040000, 0x22050000,
1932 0x20040020, 0x20050020, 0x22040020, 0x22050020,
1933 0x20002000, 0x20012000, 0x22002000, 0x22012000,
1934 0x20002020, 0x20012020, 0x22002020, 0x22012020,
1935 0x20042000, 0x20052000, 0x22042000, 0x22052000,
1936 0x20042020, 0x20052020, 0x22042020, 0x22052020,
1937 0x20000010, 0x20010010, 0x22000010, 0x22010010,
1938 0x20000030, 0x20010030, 0x22000030, 0x22010030,
1939 0x20040010, 0x20050010, 0x22040010, 0x22050010,
1940 0x20040030, 0x20050030, 0x22040030, 0x22050030,
1941 0x20002010, 0x20012010, 0x22002010, 0x22012010,
1942 0x20002030, 0x20012030, 0x22002030, 0x22012030,
1943 0x20042010, 0x20052010, 0x22042010, 0x22052010,
1944 0x20042030, 0x20052030, 0x22042030, 0x22052030,
1945 0x20000010, 0x20010010, 0x22000010, 0x22010010,
1946 0x20000030, 0x20010030, 0x22000030, 0x22010030,
1947 0x20040010, 0x20050010, 0x22040010, 0x22050010,
1948 0x20040030, 0x20050030, 0x22040030, 0x22050030,
1949 0x20002010, 0x20012010, 0x22002010, 0x22012010,
1950 0x20002030, 0x20012030, 0x22002030, 0x22012030,
1951 0x20042010, 0x20052010, 0x22042010, 0x22052010,
1952 0x20042030, 0x20052030, 0x22042030, 0x22052030
1953 );
1954 static $pc2mapd4 = array(
1955 0x00000000, 0x00000400, 0x01000000, 0x01000400,
1956 0x00000000, 0x00000400, 0x01000000, 0x01000400,
1957 0x00000100, 0x00000500, 0x01000100, 0x01000500,
1958 0x00000100, 0x00000500, 0x01000100, 0x01000500,
1959 0x10000000, 0x10000400, 0x11000000, 0x11000400,
1960 0x10000000, 0x10000400, 0x11000000, 0x11000400,
1961 0x10000100, 0x10000500, 0x11000100, 0x11000500,
1962 0x10000100, 0x10000500, 0x11000100, 0x11000500,
1963 0x00080000, 0x00080400, 0x01080000, 0x01080400,
1964 0x00080000, 0x00080400, 0x01080000, 0x01080400,
1965 0x00080100, 0x00080500, 0x01080100, 0x01080500,
1966 0x00080100, 0x00080500, 0x01080100, 0x01080500,
1967 0x10080000, 0x10080400, 0x11080000, 0x11080400,
1968 0x10080000, 0x10080400, 0x11080000, 0x11080400,
1969 0x10080100, 0x10080500, 0x11080100, 0x11080500,
1970 0x10080100, 0x10080500, 0x11080100, 0x11080500,
1971 0x00000008, 0x00000408, 0x01000008, 0x01000408,
1972 0x00000008, 0x00000408, 0x01000008, 0x01000408,
1973 0x00000108, 0x00000508, 0x01000108, 0x01000508,
1974 0x00000108, 0x00000508, 0x01000108, 0x01000508,
1975 0x10000008, 0x10000408, 0x11000008, 0x11000408,
1976 0x10000008, 0x10000408, 0x11000008, 0x11000408,
1977 0x10000108, 0x10000508, 0x11000108, 0x11000508,
1978 0x10000108, 0x10000508, 0x11000108, 0x11000508,
1979 0x00080008, 0x00080408, 0x01080008, 0x01080408,
1980 0x00080008, 0x00080408, 0x01080008, 0x01080408,
1981 0x00080108, 0x00080508, 0x01080108, 0x01080508,
1982 0x00080108, 0x00080508, 0x01080108, 0x01080508,
1983 0x10080008, 0x10080408, 0x11080008, 0x11080408,
1984 0x10080008, 0x10080408, 0x11080008, 0x11080408,
1985 0x10080108, 0x10080508, 0x11080108, 0x11080508,
1986 0x10080108, 0x10080508, 0x11080108, 0x11080508,
1987 0x00001000, 0x00001400, 0x01001000, 0x01001400,
1988 0x00001000, 0x00001400, 0x01001000, 0x01001400,
1989 0x00001100, 0x00001500, 0x01001100, 0x01001500,
1990 0x00001100, 0x00001500, 0x01001100, 0x01001500,
1991 0x10001000, 0x10001400, 0x11001000, 0x11001400,
1992 0x10001000, 0x10001400, 0x11001000, 0x11001400,
1993 0x10001100, 0x10001500, 0x11001100, 0x11001500,
1994 0x10001100, 0x10001500, 0x11001100, 0x11001500,
1995 0x00081000, 0x00081400, 0x01081000, 0x01081400,
1996 0x00081000, 0x00081400, 0x01081000, 0x01081400,
1997 0x00081100, 0x00081500, 0x01081100, 0x01081500,
1998 0x00081100, 0x00081500, 0x01081100, 0x01081500,
1999 0x10081000, 0x10081400, 0x11081000, 0x11081400,
2000 0x10081000, 0x10081400, 0x11081000, 0x11081400,
2001 0x10081100, 0x10081500, 0x11081100, 0x11081500,
2002 0x10081100, 0x10081500, 0x11081100, 0x11081500,
2003 0x00001008, 0x00001408, 0x01001008, 0x01001408,
2004 0x00001008, 0x00001408, 0x01001008, 0x01001408,
2005 0x00001108, 0x00001508, 0x01001108, 0x01001508,
2006 0x00001108, 0x00001508, 0x01001108, 0x01001508,
2007 0x10001008, 0x10001408, 0x11001008, 0x11001408,
2008 0x10001008, 0x10001408, 0x11001008, 0x11001408,
2009 0x10001108, 0x10001508, 0x11001108, 0x11001508,
2010 0x10001108, 0x10001508, 0x11001108, 0x11001508,
2011 0x00081008, 0x00081408, 0x01081008, 0x01081408,
2012 0x00081008, 0x00081408, 0x01081008, 0x01081408,
2013 0x00081108, 0x00081508, 0x01081108, 0x01081508,
2014 0x00081108, 0x00081508, 0x01081108, 0x01081508,
2015 0x10081008, 0x10081408, 0x11081008, 0x11081408,
2016 0x10081008, 0x10081408, 0x11081008, 0x11081408,
2017 0x10081108, 0x10081508, 0x11081108, 0x11081508,
2018 0x10081108, 0x10081508, 0x11081108, 0x11081508
2019 );
2020
2021 // pad the key and remove extra characters as appropriate.
2022 $key = str_pad(substr($key, 0, 8), 8, chr(0));
2023
2024 // Perform the PC/1 transformation and compute C and D.
2025 $t = unpack('Nl/Nr', $key);
2026 list($l, $r) = array($t['l'], $t['r']);
2027 $key = ($this->shuffle[$pc1map[$r & 0xFF]] & "\x80\x80\x80\x80\x80\x80\x80\x00") |
2028 ($this->shuffle[$pc1map[($r >> 8) & 0xFF]] & "\x40\x40\x40\x40\x40\x40\x40\x00") |
2029 ($this->shuffle[$pc1map[($r >> 16) & 0xFF]] & "\x20\x20\x20\x20\x20\x20\x20\x00") |
2030 ($this->shuffle[$pc1map[($r >> 24) & 0xFF]] & "\x10\x10\x10\x10\x10\x10\x10\x00") |
2031 ($this->shuffle[$pc1map[$l & 0xFF]] & "\x08\x08\x08\x08\x08\x08\x08\x00") |
2032 ($this->shuffle[$pc1map[($l >> 8) & 0xFF]] & "\x04\x04\x04\x04\x04\x04\x04\x00") |
2033 ($this->shuffle[$pc1map[($l >> 16) & 0xFF]] & "\x02\x02\x02\x02\x02\x02\x02\x00") |
2034 ($this->shuffle[$pc1map[($l >> 24) & 0xFF]] & "\x01\x01\x01\x01\x01\x01\x01\x00");
2035 $key = unpack('Nc/Nd', $key);
2036 $c = ($key['c'] >> 4) & 0x0FFFFFFF;
2037 $d = (($key['d'] >> 4) & 0x0FFFFFF0) | ($key['c'] & 0x0F);
2038
2039 $keys = array();
2040 for ($i = 0; $i < 16; $i++) {
2041 $c <<= $shifts[$i];
2042 $c = ($c | ($c >> 28)) & 0x0FFFFFFF;
2043 $d <<= $shifts[$i];
2044 $d = ($d | ($d >> 28)) & 0x0FFFFFFF;
2045
2046 // Perform the PC-2 transformation.
2047 $cp = $pc2mapc1[$c >> 24] | $pc2mapc2[($c >> 16) & 0xFF] |
2048 $pc2mapc3[($c >> 8) & 0xFF] | $pc2mapc4[$c & 0xFF];
2049 $dp = $pc2mapd1[$d >> 24] | $pc2mapd2[($d >> 16) & 0xFF] |
2050 $pc2mapd3[($d >> 8) & 0xFF] | $pc2mapd4[$d & 0xFF];
2051
2052 // Reorder: odd bytes/even bytes. Push the result in key schedule.
2053 $keys[] = array(
2054 ($cp & 0xFF000000) | (($cp << 8) & 0x00FF0000) |
2055 (($dp >> 16) & 0x0000FF00) | (($dp >> 8) & 0x000000FF),
2056 (($cp << 8) & 0xFF000000) | (($cp << 16) & 0x00FF0000) |
2057 (($dp >> 8) & 0x0000FF00) | ($dp & 0x000000FF)
2058 );
2059 }
2060
2061 $keys = array(
2062 CRYPT_DES_ENCRYPT => $keys,
2063 CRYPT_DES_DECRYPT => array_reverse($keys),
2064 CRYPT_DES_ENCRYPT_1DIM => array(),
2065 CRYPT_DES_DECRYPT_1DIM => array()
2066 );
2067
2068 // Generate 1-dim arrays for inline en/decrypting
2069 for ($i = 0; $i < 16; ++$i) {
2070 $keys[CRYPT_DES_ENCRYPT_1DIM][] = $keys[CRYPT_DES_ENCRYPT][$i][0];
2071 $keys[CRYPT_DES_ENCRYPT_1DIM][] = $keys[CRYPT_DES_ENCRYPT][$i][1];
2072 $keys[CRYPT_DES_DECRYPT_1DIM][] = $keys[CRYPT_DES_DECRYPT][$i][0];
2073 $keys[CRYPT_DES_DECRYPT_1DIM][] = $keys[CRYPT_DES_DECRYPT][$i][1];
2074 }
2075
2076 return $keys;
2077 }
2078
2079 /**
2080 * String Shift
2081 *
2082 * Inspired by array_shift
2083 *
2084 * @param String $string
2085 * @return String
2086 * @access private
2087 */
2088 function _string_shift(&$string)
2089 {
2090 $substr = substr($string, 0, 8);
2091 $string = substr($string, 8);
2092 return $substr;
2093 }
2094
2095 /**
2096 * Creates performance-optimized function for de/encrypt(), storing it in $this->inline_crypt
2097 *
2098 * @param optional Integer $des_rounds (1 = DES[default], 3 = TribleDES)
2099 * @access private
2100 */
2101 function inline_crypt_setup($des_rounds = 1)
2102 {
2103 $lambda_functions =& Crypt_DES::get_lambda_functions();
2104 $block_size = 8;
2105 $mode = $this->mode;
2106
2107 $code_hash = "$mode,$des_rounds";
2108
2109 if (!isset($lambda_functions[$code_hash])) {
2110 // Generating encrypt code:
2111 $ki = -1;
2112 $init_cryptBlock = '
2113 $shuffle = $self->shuffle;
2114 $invipmap = $self->invipmap;
2115 $ipmap = $self->ipmap;
2116 $sbox1 = $self->sbox1;
2117 $sbox2 = $self->sbox2;
2118 $sbox3 = $self->sbox3;
2119 $sbox4 = $self->sbox4;
2120 $sbox5 = $self->sbox5;
2121 $sbox6 = $self->sbox6;
2122 $sbox7 = $self->sbox7;
2123 $sbox8 = $self->sbox8;
2124 ';
2125
2126 $_cryptBlock = '$in = unpack("N*", $in);'."\n";
2127 // Do the initial IP permutation.
2128 $_cryptBlock .= '
2129 $l = $in[1];
2130 $r = $in[2];
2131 $in = unpack("N*",
2132 ($shuffle[$ipmap[ $r & 0xFF]] & "\x80\x80\x80\x80\x80\x80\x80\x80") |
2133 ($shuffle[$ipmap[($r >> 8) & 0xFF]] & "\x40\x40\x40\x40\x40\x40\x40\x40") |
2134 ($shuffle[$ipmap[($r >> 16) & 0xFF]] & "\x20\x20\x20\x20\x20\x20\x20\x20") |
2135 ($shuffle[$ipmap[($r >> 24) & 0xFF]] & "\x10\x10\x10\x10\x10\x10\x10\x10") |
2136 ($shuffle[$ipmap[ $l & 0xFF]] & "\x08\x08\x08\x08\x08\x08\x08\x08") |
2137 ($shuffle[$ipmap[($l >> 8) & 0xFF]] & "\x04\x04\x04\x04\x04\x04\x04\x04") |
2138 ($shuffle[$ipmap[($l >> 16) & 0xFF]] & "\x02\x02\x02\x02\x02\x02\x02\x02") |
2139 ($shuffle[$ipmap[($l >> 24) & 0xFF]] & "\x01\x01\x01\x01\x01\x01\x01\x01")
2140 );
2141
2142 '.'' /* Extract L0 and R0 */ .'
2143 $l = $in[1];
2144 $r = $in[2];
2145 ';
2146
2147 $l = 'l';
2148 $r = 'r';
2149 for ($des_round = 0; $des_round < $des_rounds; ++$des_round) {
2150 // Perform the 16 steps.
2151 // start of "the Feistel (F) function" - see the following URL:
2152 // http://en.wikipedia.org/wiki/Image:Data_Encryption_Standard_InfoBox_Diagram.png
2153 // Merge key schedule.
2154 for ($i = 0; $i < 8; ++$i) {
2155 $_cryptBlock .= '
2156 $b1 = (($' . $r . ' >> 3) & 0x1FFFFFFF) ^ ($' . $r . ' << 29) ^ $k_'.(++$ki).';
2157 $b2 = (($' . $r . ' >> 31) & 0x00000001) ^ ($' . $r . ' << 1) ^ $k_'.(++$ki).';
2158 $' . $l . ' = $sbox1[($b1 >> 24) & 0x3F] ^ $sbox2[($b2 >> 24) & 0x3F] ^
2159 $sbox3[($b1 >> 16) & 0x3F] ^ $sbox4[($b2 >> 16) & 0x3F] ^
2160 $sbox5[($b1 >> 8) & 0x3F] ^ $sbox6[($b2 >> 8) & 0x3F] ^
2161 $sbox7[ $b1 & 0x3F] ^ $sbox8[ $b2 & 0x3F] ^ $' . $l . ';
2162
2163 $b1 = (($' . $l . ' >> 3) & 0x1FFFFFFF) ^ ($' . $l . ' << 29) ^ $k_'.(++$ki).';
2164 $b2 = (($' . $l . ' >> 31) & 0x00000001) ^ ($' . $l . ' << 1) ^ $k_'.(++$ki).';
2165 $' . $r . ' = $sbox1[($b1 >> 24) & 0x3F] ^ $sbox2[($b2 >> 24) & 0x3F] ^
2166 $sbox3[($b1 >> 16) & 0x3F] ^ $sbox4[($b2 >> 16) & 0x3F] ^
2167 $sbox5[($b1 >> 8) & 0x3F] ^ $sbox6[($b2 >> 8) & 0x3F] ^
2168 $sbox7[ $b1 & 0x3F] ^ $sbox8[ $b2 & 0x3F] ^ $' . $r . ';
2169 ';
2170 }
2171
2172 // Last step should not permute L & R.
2173 $t = $l;
2174 $l = $r;
2175 $r = $t;
2176 }
2177
2178 // Perform the inverse IP permutation.
2179 $_cryptBlock .= '$in = (
2180 ($shuffle[$invipmap[($' . $r . ' >> 24) & 0xFF]] & "\x80\x80\x80\x80\x80\x80\x80\x80") |
2181 ($shuffle[$invipmap[($' . $l . ' >> 24) & 0xFF]] & "\x40\x40\x40\x40\x40\x40\x40\x40") |
2182 ($shuffle[$invipmap[($' . $r . ' >> 16) & 0xFF]] & "\x20\x20\x20\x20\x20\x20\x20\x20") |
2183 ($shuffle[$invipmap[($' . $l . ' >> 16) & 0xFF]] & "\x10\x10\x10\x10\x10\x10\x10\x10") |
2184 ($shuffle[$invipmap[($' . $r . ' >> 8) & 0xFF]] & "\x08\x08\x08\x08\x08\x08\x08\x08") |
2185 ($shuffle[$invipmap[($' . $l . ' >> 8) & 0xFF]] & "\x04\x04\x04\x04\x04\x04\x04\x04") |
2186 ($shuffle[$invipmap[ $' . $r . ' & 0xFF]] & "\x02\x02\x02\x02\x02\x02\x02\x02") |
2187 ($shuffle[$invipmap[ $' . $l . ' & 0xFF]] & "\x01\x01\x01\x01\x01\x01\x01\x01")
2188 );
2189 ';
2190
2191 // Generating mode of operation code:
2192 switch ($mode) {
2193 case CRYPT_DES_MODE_ECB:
2194 $encrypt = $init_cryptBlock . '
2195 extract($self->keys[CRYPT_DES_ENCRYPT_1DIM], EXTR_PREFIX_ALL, "k");
2196 $ciphertext = "";
2197 $plaintext_len = strlen($text);
2198
2199 for ($i = 0; $i < $plaintext_len; $i+= '.$block_size.') {
2200 $in = substr($text, $i, '.$block_size.');
2201 '.$_cryptBlock.'
2202 $ciphertext.= $in;
2203 }
2204
2205 return $ciphertext;
2206 ';
2207
2208 $decrypt = $init_cryptBlock . '
2209 extract($self->keys[CRYPT_DES_DECRYPT_1DIM], EXTR_PREFIX_ALL, "k");
2210 $plaintext = "";
2211 $ciphertext_len = strlen($text);
2212
2213 for ($i = 0; $i < $ciphertext_len; $i+= '.$block_size.') {
2214 $in = substr($text, $i, '.$block_size.');
2215 '.$_cryptBlock.'
2216 $plaintext.= $in;
2217 }
2218
2219 return $self->_unpad($plaintext);
2220 ';
2221 break;
2222 case CRYPT_DES_MODE_CBC:
2223 $encrypt = $init_cryptBlock . '
2224 extract($self->keys[CRYPT_DES_ENCRYPT_1DIM], EXTR_PREFIX_ALL, "k");
2225 $ciphertext = "";
2226 $plaintext_len = strlen($text);
2227
2228 $in = $self->encryptIV;
2229
2230 for ($i = 0; $i < $plaintext_len; $i+= '.$block_size.') {
2231 $in = substr($text, $i, '.$block_size.') ^ $in;
2232 '.$_cryptBlock.'
2233 $ciphertext.= $in;
2234 }
2235
2236 if ($self->continuousBuffer) {
2237 $self->encryptIV = $in;
2238 }
2239
2240 return $ciphertext;
2241 ';
2242
2243 $decrypt = $init_cryptBlock . '
2244 extract($self->keys[CRYPT_DES_DECRYPT_1DIM], EXTR_PREFIX_ALL, "k");
2245 $plaintext = "";
2246 $ciphertext_len = strlen($text);
2247
2248 $iv = $self->decryptIV;
2249
2250 for ($i = 0; $i < $ciphertext_len; $i+= '.$block_size.') {
2251 $in = $block = substr($text, $i, '.$block_size.');
2252 '.$_cryptBlock.'
2253 $plaintext.= $in ^ $iv;
2254 $iv = $block;
2255 }
2256
2257 if ($self->continuousBuffer) {
2258 $self->decryptIV = $iv;
2259 }
2260
2261 return $self->_unpad($plaintext);
2262 ';
2263 break;
2264 case CRYPT_DES_MODE_CTR:
2265 $encrypt = $init_cryptBlock . '
2266 extract($self->keys[CRYPT_DES_ENCRYPT_1DIM], EXTR_PREFIX_ALL, "k");
2267 $ciphertext = "";
2268 $plaintext_len = strlen($text);
2269 $xor = $self->encryptIV;
2270 $buffer = &$self->enbuffer;
2271
2272 if (strlen($buffer["encrypted"])) {
2273 for ($i = 0; $i < $plaintext_len; $i+= '.$block_size.') {
2274 $block = substr($text, $i, '.$block_size.');
2275 if (strlen($block) > strlen($buffer["encrypted"])) {
2276 $in = $self->_generate_xor($xor);
2277 '.$_cryptBlock.'
2278 $buffer["encrypted"].= $in;
2279 }
2280 $key = $self->_string_shift($buffer["encrypted"]);
2281 $ciphertext.= $block ^ $key;
2282 }
2283 } else {
2284 for ($i = 0; $i < $plaintext_len; $i+= '.$block_size.') {
2285 $block = substr($text, $i, '.$block_size.');
2286 $in = $self->_generate_xor($xor);
2287 '.$_cryptBlock.'
2288 $key = $in;
2289 $ciphertext.= $block ^ $key;
2290 }
2291 }
2292 if ($self->continuousBuffer) {
2293 $self->encryptIV = $xor;
2294 if ($start = $plaintext_len % '.$block_size.') {
2295 $buffer["encrypted"] = substr($key, $start) . $buffer["encrypted"];
2296 }
2297 }
2298
2299 return $ciphertext;
2300 ';
2301
2302 $decrypt = $init_cryptBlock . '
2303 extract($self->keys[CRYPT_DES_ENCRYPT_1DIM], EXTR_PREFIX_ALL, "k");
2304 $plaintext = "";
2305 $ciphertext_len = strlen($text);
2306 $xor = $self->decryptIV;
2307 $buffer = &$self->debuffer;
2308
2309 if (strlen($buffer["ciphertext"])) {
2310 for ($i = 0; $i < $ciphertext_len; $i+= '.$block_size.') {
2311 $block = substr($text, $i, '.$block_size.');
2312 if (strlen($block) > strlen($buffer["ciphertext"])) {
2313 $in = $self->_generate_xor($xor);
2314 '.$_cryptBlock.'
2315 $buffer["ciphertext"].= $in;
2316 }
2317 $key = $self->_string_shift($buffer["ciphertext"]);
2318 $plaintext.= $block ^ $key;
2319 }
2320 } else {
2321 for ($i = 0; $i < $ciphertext_len; $i+= '.$block_size.') {
2322 $block = substr($text, $i, '.$block_size.');
2323 $in = $self->_generate_xor($xor);
2324 '.$_cryptBlock.'
2325 $key = $in;
2326 $plaintext.= $block ^ $key;
2327 }
2328 }
2329 if ($self->continuousBuffer) {
2330 $self->decryptIV = $xor;
2331 if ($start = $ciphertext_len % '.$block_size.') {
2332 $buffer["ciphertext"] = substr($key, $start) . $buffer["ciphertext"];
2333 }
2334 }
2335
2336 return $plaintext;
2337 ';
2338 break;
2339 case CRYPT_DES_MODE_CFB:
2340 $encrypt = $init_cryptBlock . '
2341 extract($self->keys[CRYPT_DES_ENCRYPT_1DIM], EXTR_PREFIX_ALL, "k");
2342 $ciphertext = "";
2343 $buffer = &$self->enbuffer;
2344
2345 if ($self->continuousBuffer) {
2346 $iv = &$self->encryptIV;
2347 $pos = &$buffer["pos"];
2348 } else {
2349 $iv = $self->encryptIV;
2350 $pos = 0;
2351 }
2352 $len = strlen($text);
2353 $i = 0;
2354 if ($pos) {
2355 $orig_pos = $pos;
2356 $max = '.$block_size.' - $pos;
2357 if ($len >= $max) {
2358 $i = $max;
2359 $len-= $max;
2360 $pos = 0;
2361 } else {
2362 $i = $len;
2363 $pos+= $len;
2364 $len = 0;
2365 }
2366 $ciphertext = substr($iv, $orig_pos) ^ $text;
2367 $iv = substr_replace($iv, $ciphertext, $orig_pos, $i);
2368 }
2369 while ($len >= '.$block_size.') {
2370 $in = $iv;
2371 '.$_cryptBlock.';
2372 $iv = $in ^ substr($text, $i, '.$block_size.');
2373 $ciphertext.= $iv;
2374 $len-= '.$block_size.';
2375 $i+= '.$block_size.';
2376 }
2377 if ($len) {
2378 $in = $iv;
2379 '.$_cryptBlock.'
2380 $iv = $in;
2381 $block = $iv ^ substr($text, $i);
2382 $iv = substr_replace($iv, $block, 0, $len);
2383 $ciphertext.= $block;
2384 $pos = $len;
2385 }
2386 return $ciphertext;
2387 ';
2388
2389 $decrypt = $init_cryptBlock . '
2390 extract($self->keys[CRYPT_DES_ENCRYPT_1DIM], EXTR_PREFIX_ALL, "k");
2391 $plaintext = "";
2392 $buffer = &$self->debuffer;
2393
2394 if ($self->continuousBuffer) {
2395 $iv = &$self->decryptIV;
2396 $pos = &$buffer["pos"];
2397 } else {
2398 $iv = $self->decryptIV;
2399 $pos = 0;
2400 }
2401 $len = strlen($text);
2402 $i = 0;
2403 if ($pos) {
2404 $orig_pos = $pos;
2405 $max = '.$block_size.' - $pos;
2406 if ($len >= $max) {
2407 $i = $max;
2408 $len-= $max;
2409 $pos = 0;
2410 } else {
2411 $i = $len;
2412 $pos+= $len;
2413 $len = 0;
2414 }
2415 $plaintext = substr($iv, $orig_pos) ^ $text;
2416 $iv = substr_replace($iv, substr($text, 0, $i), $orig_pos, $i);
2417 }
2418 while ($len >= '.$block_size.') {
2419 $in = $iv;
2420 '.$_cryptBlock.'
2421 $iv = $in;
2422 $cb = substr($text, $i, '.$block_size.');
2423 $plaintext.= $iv ^ $cb;
2424 $iv = $cb;
2425 $len-= '.$block_size.';
2426 $i+= '.$block_size.';
2427 }
2428 if ($len) {
2429 $in = $iv;
2430 '.$_cryptBlock.'
2431 $iv = $in;
2432 $plaintext.= $iv ^ substr($text, $i);
2433 $iv = substr_replace($iv, substr($text, $i), 0, $len);
2434 $pos = $len;
2435 }
2436
2437 return $plaintext;
2438 ';
2439 break;
2440 case CRYPT_DES_MODE_OFB:
2441 $encrypt = $init_cryptBlock . '
2442 extract($self->keys[CRYPT_DES_ENCRYPT_1DIM], EXTR_PREFIX_ALL, "k");
2443 $ciphertext = "";
2444 $plaintext_len = strlen($text);
2445 $xor = $self->encryptIV;
2446 $buffer = &$self->enbuffer;
2447
2448 if (strlen($buffer["xor"])) {
2449 for ($i = 0; $i < $plaintext_len; $i+= '.$block_size.') {
2450 $block = substr($text, $i, '.$block_size.');
2451 if (strlen($block) > strlen($buffer["xor"])) {
2452 $in = $xor;
2453 '.$_cryptBlock.'
2454 $xor = $in;
2455 $buffer["xor"].= $xor;
2456 }
2457 $key = $self->_string_shift($buffer["xor"]);
2458 $ciphertext.= $block ^ $key;
2459 }
2460 } else {
2461 for ($i = 0; $i < $plaintext_len; $i+= '.$block_size.') {
2462 $in = $xor;
2463 '.$_cryptBlock.'
2464 $xor = $in;
2465 $ciphertext.= substr($text, $i, '.$block_size.') ^ $xor;
2466 }
2467 $key = $xor;
2468 }
2469 if ($self->continuousBuffer) {
2470 $self->encryptIV = $xor;
2471 if ($start = $plaintext_len % '.$block_size.') {
2472 $buffer["xor"] = substr($key, $start) . $buffer["xor"];
2473 }
2474 }
2475 return $ciphertext;
2476 ';
2477
2478 $decrypt = $init_cryptBlock . '
2479 extract($self->keys[CRYPT_DES_ENCRYPT_1DIM], EXTR_PREFIX_ALL, "k");
2480 $plaintext = "";
2481 $ciphertext_len = strlen($text);
2482 $xor = $self->decryptIV;
2483 $buffer = &$self->debuffer;
2484
2485 if (strlen($buffer["xor"])) {
2486 for ($i = 0; $i < $ciphertext_len; $i+= '.$block_size.') {
2487 $block = substr($text, $i, '.$block_size.');
2488 if (strlen($block) > strlen($buffer["xor"])) {
2489 $in = $xor;
2490 '.$_cryptBlock.'
2491 $xor = $in;
2492 $buffer["xor"].= $xor;
2493 }
2494 $key = $self->_string_shift($buffer["xor"]);
2495 $plaintext.= $block ^ $key;
2496 }
2497 } else {
2498 for ($i = 0; $i < $ciphertext_len; $i+= '.$block_size.') {
2499 $in = $xor;
2500 '.$_cryptBlock.'
2501 $xor = $in;
2502 $plaintext.= substr($text, $i, '.$block_size.') ^ $xor;
2503 }
2504 $key = $xor;
2505 }
2506 if ($self->continuousBuffer) {
2507 $self->decryptIV = $xor;
2508 if ($start = $ciphertext_len % '.$block_size.') {
2509 $buffer["xor"] = substr($key, $start) . $buffer["xor"];
2510 }
2511 }
2512 return $plaintext;
2513 ';
2514 break;
2515 }
2516 $lambda_functions[$code_hash] = create_function('$action, &$self, $text', 'if ($action == "encrypt") { '.$encrypt.' } else { '.$decrypt.' }');
2517 }
2518 $this->inline_crypt = $lambda_functions[$code_hash];
2519 }
2520
2521 /**
2522 * Holds the lambda_functions table (classwide)
2523 *
2524 * @see inline_crypt_setup()
2525 * @return Array
2526 * @access private
2527 */
2528 function &get_lambda_functions()
2529 {
2530 static $functions = array();
2531 return $functions;
2532 }
2533 }
2534
2535 // vim: ts=4:sw=4:et:
2536 // vim6: fdl=1:
2537