2 /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
\r
5 * Pure-PHP implementation of DES.
\r
7 * Uses mcrypt, if available, and an internal implementation, otherwise.
\r
9 * PHP versions 4 and 5
\r
11 * Useful resources are as follows:
\r
13 * - {@link http://en.wikipedia.org/wiki/DES_supplementary_material Wikipedia: DES supplementary material}
\r
14 * - {@link http://www.itl.nist.gov/fipspubs/fip46-2.htm FIPS 46-2 - (DES), Data Encryption Standard}
\r
15 * - {@link http://www.cs.eku.edu/faculty/styer/460/Encrypt/JS-DES.html JavaScript DES Example}
\r
17 * Here's a short example of how to use this library:
\r
20 * include('Crypt/DES.php');
\r
22 * $des = new Crypt_DES();
\r
24 * $des->setKey('abcdefgh');
\r
26 * $size = 10 * 1024;
\r
28 * for ($i = 0; $i < $size; $i++) {
\r
32 * echo $des->decrypt($des->encrypt($plaintext));
\r
36 * LICENSE: Permission is hereby granted, free of charge, to any person obtaining a copy
\r
37 * of this software and associated documentation files (the "Software"), to deal
\r
38 * in the Software without restriction, including without limitation the rights
\r
39 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
\r
40 * copies of the Software, and to permit persons to whom the Software is
\r
41 * furnished to do so, subject to the following conditions:
\r
43 * The above copyright notice and this permission notice shall be included in
\r
44 * all copies or substantial portions of the Software.
\r
46 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
\r
47 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
\r
48 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
\r
49 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
\r
50 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
\r
51 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
\r
55 * @package Crypt_DES
\r
56 * @author Jim Wigginton <terrafrost@php.net>
\r
57 * @copyright MMVII Jim Wigginton
\r
58 * @license http://www.opensource.org/licenses/mit-license.html MIT License
\r
59 * @link http://phpseclib.sourceforge.net
\r
64 * @see Crypt_DES::_prepareKey()
\r
65 * @see Crypt_DES::_processBlock()
\r
68 * Contains array_reverse($keys[CRYPT_DES_DECRYPT])
\r
70 define('CRYPT_DES_ENCRYPT', 0);
\r
72 * Contains array_reverse($keys[CRYPT_DES_ENCRYPT])
\r
74 define('CRYPT_DES_DECRYPT', 1);
\r
76 * Contains $keys[CRYPT_DES_ENCRYPT] as 1-dim array
\r
78 define('CRYPT_DES_ENCRYPT_1DIM', 2);
\r
80 * Contains $keys[CRYPT_DES_DECRYPT] as 1-dim array
\r
82 define('CRYPT_DES_DECRYPT_1DIM', 3);
\r
87 * @see Crypt_DES::encrypt()
\r
88 * @see Crypt_DES::decrypt()
\r
91 * Encrypt / decrypt using the Counter mode.
\r
93 * Set to -1 since that's what Crypt/Random.php uses to index the CTR mode.
\r
95 * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Counter_.28CTR.29
\r
97 define('CRYPT_DES_MODE_CTR', -1);
\r
99 * Encrypt / decrypt using the Electronic Code Book mode.
\r
101 * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Electronic_codebook_.28ECB.29
\r
103 define('CRYPT_DES_MODE_ECB', 1);
\r
105 * Encrypt / decrypt using the Code Book Chaining mode.
\r
107 * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Cipher-block_chaining_.28CBC.29
\r
109 define('CRYPT_DES_MODE_CBC', 2);
\r
111 * Encrypt / decrypt using the Cipher Feedback mode.
\r
113 * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Cipher_feedback_.28CFB.29
\r
115 define('CRYPT_DES_MODE_CFB', 3);
\r
117 * Encrypt / decrypt using the Cipher Feedback mode.
\r
119 * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Output_feedback_.28OFB.29
\r
121 define('CRYPT_DES_MODE_OFB', 4);
\r
126 * @see Crypt_DES::Crypt_DES()
\r
129 * Toggles the internal implementation
\r
131 define('CRYPT_DES_MODE_INTERNAL', 1);
\r
133 * Toggles the mcrypt implementation
\r
135 define('CRYPT_DES_MODE_MCRYPT', 2);
\r
139 * Pure-PHP implementation of DES.
\r
141 * @author Jim Wigginton <terrafrost@php.net>
\r
144 * @package Crypt_DES
\r
150 * @see Crypt_DES::setKey()
\r
154 var $keys = "\0\0\0\0\0\0\0\0";
\r
157 * The Encryption Mode
\r
159 * @see Crypt_DES::Crypt_DES()
\r
166 * Continuous Buffer status
\r
168 * @see Crypt_DES::enableContinuousBuffer()
\r
172 var $continuousBuffer = false;
\r
177 * @see Crypt_DES::enablePadding()
\r
181 var $padding = true;
\r
184 * The Initialization Vector
\r
186 * @see Crypt_DES::setIV()
\r
190 var $iv = "\0\0\0\0\0\0\0\0";
\r
193 * A "sliding" Initialization Vector
\r
195 * @see Crypt_DES::enableContinuousBuffer()
\r
199 var $encryptIV = "\0\0\0\0\0\0\0\0";
\r
202 * A "sliding" Initialization Vector
\r
204 * @see Crypt_DES::enableContinuousBuffer()
\r
208 var $decryptIV = "\0\0\0\0\0\0\0\0";
\r
211 * mcrypt resource for encryption
\r
213 * The mcrypt resource can be recreated every time something needs to be created or it can be created just once.
\r
214 * Since mcrypt operates in continuous mode, by default, it'll need to be recreated when in non-continuous mode.
\r
216 * @see Crypt_DES::encrypt()
\r
223 * mcrypt resource for decryption
\r
225 * The mcrypt resource can be recreated every time something needs to be created or it can be created just once.
\r
226 * Since mcrypt operates in continuous mode, by default, it'll need to be recreated when in non-continuous mode.
\r
228 * @see Crypt_DES::decrypt()
\r
235 * Does the enmcrypt resource need to be (re)initialized?
\r
237 * @see Crypt_DES::setKey()
\r
238 * @see Crypt_DES::setIV()
\r
242 var $enchanged = true;
\r
245 * Does the demcrypt resource need to be (re)initialized?
\r
247 * @see Crypt_DES::setKey()
\r
248 * @see Crypt_DES::setIV()
\r
252 var $dechanged = true;
\r
255 * Is the mode one that is paddable?
\r
257 * @see Crypt_DES::Crypt_DES()
\r
261 var $paddable = false;
\r
264 * Encryption buffer for CTR, OFB and CFB modes
\r
266 * @see Crypt_DES::encrypt()
\r
270 var $enbuffer = array('encrypted' => '', 'xor' => '', 'pos' => 0, 'enmcrypt_init' => true);
\r
273 * Decryption buffer for CTR, OFB and CFB modes
\r
275 * @see Crypt_DES::decrypt()
\r
279 var $debuffer = array('ciphertext' => '', 'xor' => '', 'pos' => 0, 'demcrypt_init' => true);
\r
282 * mcrypt resource for CFB mode
\r
284 * @see Crypt_DES::encrypt()
\r
285 * @see Crypt_DES::decrypt()
\r
292 * Performance-optimized callback function for en/decrypt()
\r
300 * Holds whether performance-optimized $inline_crypt should be used or not.
\r
305 var $use_inline_crypt = false;
\r
310 * For each byte value index, the entry holds an 8-byte string
\r
311 * with each byte containing all bits in the same state as the
\r
312 * corresponding bit in the index value.
\r
314 * @see Crypt_DES::_processBlock()
\r
315 * @see Crypt_DES::_prepareKey()
\r
319 var $shuffle = array(
\r
320 "\x00\x00\x00\x00\x00\x00\x00\x00", "\x00\x00\x00\x00\x00\x00\x00\xFF",
\r
321 "\x00\x00\x00\x00\x00\x00\xFF\x00", "\x00\x00\x00\x00\x00\x00\xFF\xFF",
\r
322 "\x00\x00\x00\x00\x00\xFF\x00\x00", "\x00\x00\x00\x00\x00\xFF\x00\xFF",
\r
323 "\x00\x00\x00\x00\x00\xFF\xFF\x00", "\x00\x00\x00\x00\x00\xFF\xFF\xFF",
\r
324 "\x00\x00\x00\x00\xFF\x00\x00\x00", "\x00\x00\x00\x00\xFF\x00\x00\xFF",
\r
325 "\x00\x00\x00\x00\xFF\x00\xFF\x00", "\x00\x00\x00\x00\xFF\x00\xFF\xFF",
\r
326 "\x00\x00\x00\x00\xFF\xFF\x00\x00", "\x00\x00\x00\x00\xFF\xFF\x00\xFF",
\r
327 "\x00\x00\x00\x00\xFF\xFF\xFF\x00", "\x00\x00\x00\x00\xFF\xFF\xFF\xFF",
\r
328 "\x00\x00\x00\xFF\x00\x00\x00\x00", "\x00\x00\x00\xFF\x00\x00\x00\xFF",
\r
329 "\x00\x00\x00\xFF\x00\x00\xFF\x00", "\x00\x00\x00\xFF\x00\x00\xFF\xFF",
\r
330 "\x00\x00\x00\xFF\x00\xFF\x00\x00", "\x00\x00\x00\xFF\x00\xFF\x00\xFF",
\r
331 "\x00\x00\x00\xFF\x00\xFF\xFF\x00", "\x00\x00\x00\xFF\x00\xFF\xFF\xFF",
\r
332 "\x00\x00\x00\xFF\xFF\x00\x00\x00", "\x00\x00\x00\xFF\xFF\x00\x00\xFF",
\r
333 "\x00\x00\x00\xFF\xFF\x00\xFF\x00", "\x00\x00\x00\xFF\xFF\x00\xFF\xFF",
\r
334 "\x00\x00\x00\xFF\xFF\xFF\x00\x00", "\x00\x00\x00\xFF\xFF\xFF\x00\xFF",
\r
335 "\x00\x00\x00\xFF\xFF\xFF\xFF\x00", "\x00\x00\x00\xFF\xFF\xFF\xFF\xFF",
\r
336 "\x00\x00\xFF\x00\x00\x00\x00\x00", "\x00\x00\xFF\x00\x00\x00\x00\xFF",
\r
337 "\x00\x00\xFF\x00\x00\x00\xFF\x00", "\x00\x00\xFF\x00\x00\x00\xFF\xFF",
\r
338 "\x00\x00\xFF\x00\x00\xFF\x00\x00", "\x00\x00\xFF\x00\x00\xFF\x00\xFF",
\r
339 "\x00\x00\xFF\x00\x00\xFF\xFF\x00", "\x00\x00\xFF\x00\x00\xFF\xFF\xFF",
\r
340 "\x00\x00\xFF\x00\xFF\x00\x00\x00", "\x00\x00\xFF\x00\xFF\x00\x00\xFF",
\r
341 "\x00\x00\xFF\x00\xFF\x00\xFF\x00", "\x00\x00\xFF\x00\xFF\x00\xFF\xFF",
\r
342 "\x00\x00\xFF\x00\xFF\xFF\x00\x00", "\x00\x00\xFF\x00\xFF\xFF\x00\xFF",
\r
343 "\x00\x00\xFF\x00\xFF\xFF\xFF\x00", "\x00\x00\xFF\x00\xFF\xFF\xFF\xFF",
\r
344 "\x00\x00\xFF\xFF\x00\x00\x00\x00", "\x00\x00\xFF\xFF\x00\x00\x00\xFF",
\r
345 "\x00\x00\xFF\xFF\x00\x00\xFF\x00", "\x00\x00\xFF\xFF\x00\x00\xFF\xFF",
\r
346 "\x00\x00\xFF\xFF\x00\xFF\x00\x00", "\x00\x00\xFF\xFF\x00\xFF\x00\xFF",
\r
347 "\x00\x00\xFF\xFF\x00\xFF\xFF\x00", "\x00\x00\xFF\xFF\x00\xFF\xFF\xFF",
\r
348 "\x00\x00\xFF\xFF\xFF\x00\x00\x00", "\x00\x00\xFF\xFF\xFF\x00\x00\xFF",
\r
349 "\x00\x00\xFF\xFF\xFF\x00\xFF\x00", "\x00\x00\xFF\xFF\xFF\x00\xFF\xFF",
\r
350 "\x00\x00\xFF\xFF\xFF\xFF\x00\x00", "\x00\x00\xFF\xFF\xFF\xFF\x00\xFF",
\r
351 "\x00\x00\xFF\xFF\xFF\xFF\xFF\x00", "\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF",
\r
352 "\x00\xFF\x00\x00\x00\x00\x00\x00", "\x00\xFF\x00\x00\x00\x00\x00\xFF",
\r
353 "\x00\xFF\x00\x00\x00\x00\xFF\x00", "\x00\xFF\x00\x00\x00\x00\xFF\xFF",
\r
354 "\x00\xFF\x00\x00\x00\xFF\x00\x00", "\x00\xFF\x00\x00\x00\xFF\x00\xFF",
\r
355 "\x00\xFF\x00\x00\x00\xFF\xFF\x00", "\x00\xFF\x00\x00\x00\xFF\xFF\xFF",
\r
356 "\x00\xFF\x00\x00\xFF\x00\x00\x00", "\x00\xFF\x00\x00\xFF\x00\x00\xFF",
\r
357 "\x00\xFF\x00\x00\xFF\x00\xFF\x00", "\x00\xFF\x00\x00\xFF\x00\xFF\xFF",
\r
358 "\x00\xFF\x00\x00\xFF\xFF\x00\x00", "\x00\xFF\x00\x00\xFF\xFF\x00\xFF",
\r
359 "\x00\xFF\x00\x00\xFF\xFF\xFF\x00", "\x00\xFF\x00\x00\xFF\xFF\xFF\xFF",
\r
360 "\x00\xFF\x00\xFF\x00\x00\x00\x00", "\x00\xFF\x00\xFF\x00\x00\x00\xFF",
\r
361 "\x00\xFF\x00\xFF\x00\x00\xFF\x00", "\x00\xFF\x00\xFF\x00\x00\xFF\xFF",
\r
362 "\x00\xFF\x00\xFF\x00\xFF\x00\x00", "\x00\xFF\x00\xFF\x00\xFF\x00\xFF",
\r
363 "\x00\xFF\x00\xFF\x00\xFF\xFF\x00", "\x00\xFF\x00\xFF\x00\xFF\xFF\xFF",
\r
364 "\x00\xFF\x00\xFF\xFF\x00\x00\x00", "\x00\xFF\x00\xFF\xFF\x00\x00\xFF",
\r
365 "\x00\xFF\x00\xFF\xFF\x00\xFF\x00", "\x00\xFF\x00\xFF\xFF\x00\xFF\xFF",
\r
366 "\x00\xFF\x00\xFF\xFF\xFF\x00\x00", "\x00\xFF\x00\xFF\xFF\xFF\x00\xFF",
\r
367 "\x00\xFF\x00\xFF\xFF\xFF\xFF\x00", "\x00\xFF\x00\xFF\xFF\xFF\xFF\xFF",
\r
368 "\x00\xFF\xFF\x00\x00\x00\x00\x00", "\x00\xFF\xFF\x00\x00\x00\x00\xFF",
\r
369 "\x00\xFF\xFF\x00\x00\x00\xFF\x00", "\x00\xFF\xFF\x00\x00\x00\xFF\xFF",
\r
370 "\x00\xFF\xFF\x00\x00\xFF\x00\x00", "\x00\xFF\xFF\x00\x00\xFF\x00\xFF",
\r
371 "\x00\xFF\xFF\x00\x00\xFF\xFF\x00", "\x00\xFF\xFF\x00\x00\xFF\xFF\xFF",
\r
372 "\x00\xFF\xFF\x00\xFF\x00\x00\x00", "\x00\xFF\xFF\x00\xFF\x00\x00\xFF",
\r
373 "\x00\xFF\xFF\x00\xFF\x00\xFF\x00", "\x00\xFF\xFF\x00\xFF\x00\xFF\xFF",
\r
374 "\x00\xFF\xFF\x00\xFF\xFF\x00\x00", "\x00\xFF\xFF\x00\xFF\xFF\x00\xFF",
\r
375 "\x00\xFF\xFF\x00\xFF\xFF\xFF\x00", "\x00\xFF\xFF\x00\xFF\xFF\xFF\xFF",
\r
376 "\x00\xFF\xFF\xFF\x00\x00\x00\x00", "\x00\xFF\xFF\xFF\x00\x00\x00\xFF",
\r
377 "\x00\xFF\xFF\xFF\x00\x00\xFF\x00", "\x00\xFF\xFF\xFF\x00\x00\xFF\xFF",
\r
378 "\x00\xFF\xFF\xFF\x00\xFF\x00\x00", "\x00\xFF\xFF\xFF\x00\xFF\x00\xFF",
\r
379 "\x00\xFF\xFF\xFF\x00\xFF\xFF\x00", "\x00\xFF\xFF\xFF\x00\xFF\xFF\xFF",
\r
380 "\x00\xFF\xFF\xFF\xFF\x00\x00\x00", "\x00\xFF\xFF\xFF\xFF\x00\x00\xFF",
\r
381 "\x00\xFF\xFF\xFF\xFF\x00\xFF\x00", "\x00\xFF\xFF\xFF\xFF\x00\xFF\xFF",
\r
382 "\x00\xFF\xFF\xFF\xFF\xFF\x00\x00", "\x00\xFF\xFF\xFF\xFF\xFF\x00\xFF",
\r
383 "\x00\xFF\xFF\xFF\xFF\xFF\xFF\x00", "\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF",
\r
384 "\xFF\x00\x00\x00\x00\x00\x00\x00", "\xFF\x00\x00\x00\x00\x00\x00\xFF",
\r
385 "\xFF\x00\x00\x00\x00\x00\xFF\x00", "\xFF\x00\x00\x00\x00\x00\xFF\xFF",
\r
386 "\xFF\x00\x00\x00\x00\xFF\x00\x00", "\xFF\x00\x00\x00\x00\xFF\x00\xFF",
\r
387 "\xFF\x00\x00\x00\x00\xFF\xFF\x00", "\xFF\x00\x00\x00\x00\xFF\xFF\xFF",
\r
388 "\xFF\x00\x00\x00\xFF\x00\x00\x00", "\xFF\x00\x00\x00\xFF\x00\x00\xFF",
\r
389 "\xFF\x00\x00\x00\xFF\x00\xFF\x00", "\xFF\x00\x00\x00\xFF\x00\xFF\xFF",
\r
390 "\xFF\x00\x00\x00\xFF\xFF\x00\x00", "\xFF\x00\x00\x00\xFF\xFF\x00\xFF",
\r
391 "\xFF\x00\x00\x00\xFF\xFF\xFF\x00", "\xFF\x00\x00\x00\xFF\xFF\xFF\xFF",
\r
392 "\xFF\x00\x00\xFF\x00\x00\x00\x00", "\xFF\x00\x00\xFF\x00\x00\x00\xFF",
\r
393 "\xFF\x00\x00\xFF\x00\x00\xFF\x00", "\xFF\x00\x00\xFF\x00\x00\xFF\xFF",
\r
394 "\xFF\x00\x00\xFF\x00\xFF\x00\x00", "\xFF\x00\x00\xFF\x00\xFF\x00\xFF",
\r
395 "\xFF\x00\x00\xFF\x00\xFF\xFF\x00", "\xFF\x00\x00\xFF\x00\xFF\xFF\xFF",
\r
396 "\xFF\x00\x00\xFF\xFF\x00\x00\x00", "\xFF\x00\x00\xFF\xFF\x00\x00\xFF",
\r
397 "\xFF\x00\x00\xFF\xFF\x00\xFF\x00", "\xFF\x00\x00\xFF\xFF\x00\xFF\xFF",
\r
398 "\xFF\x00\x00\xFF\xFF\xFF\x00\x00", "\xFF\x00\x00\xFF\xFF\xFF\x00\xFF",
\r
399 "\xFF\x00\x00\xFF\xFF\xFF\xFF\x00", "\xFF\x00\x00\xFF\xFF\xFF\xFF\xFF",
\r
400 "\xFF\x00\xFF\x00\x00\x00\x00\x00", "\xFF\x00\xFF\x00\x00\x00\x00\xFF",
\r
401 "\xFF\x00\xFF\x00\x00\x00\xFF\x00", "\xFF\x00\xFF\x00\x00\x00\xFF\xFF",
\r
402 "\xFF\x00\xFF\x00\x00\xFF\x00\x00", "\xFF\x00\xFF\x00\x00\xFF\x00\xFF",
\r
403 "\xFF\x00\xFF\x00\x00\xFF\xFF\x00", "\xFF\x00\xFF\x00\x00\xFF\xFF\xFF",
\r
404 "\xFF\x00\xFF\x00\xFF\x00\x00\x00", "\xFF\x00\xFF\x00\xFF\x00\x00\xFF",
\r
405 "\xFF\x00\xFF\x00\xFF\x00\xFF\x00", "\xFF\x00\xFF\x00\xFF\x00\xFF\xFF",
\r
406 "\xFF\x00\xFF\x00\xFF\xFF\x00\x00", "\xFF\x00\xFF\x00\xFF\xFF\x00\xFF",
\r
407 "\xFF\x00\xFF\x00\xFF\xFF\xFF\x00", "\xFF\x00\xFF\x00\xFF\xFF\xFF\xFF",
\r
408 "\xFF\x00\xFF\xFF\x00\x00\x00\x00", "\xFF\x00\xFF\xFF\x00\x00\x00\xFF",
\r
409 "\xFF\x00\xFF\xFF\x00\x00\xFF\x00", "\xFF\x00\xFF\xFF\x00\x00\xFF\xFF",
\r
410 "\xFF\x00\xFF\xFF\x00\xFF\x00\x00", "\xFF\x00\xFF\xFF\x00\xFF\x00\xFF",
\r
411 "\xFF\x00\xFF\xFF\x00\xFF\xFF\x00", "\xFF\x00\xFF\xFF\x00\xFF\xFF\xFF",
\r
412 "\xFF\x00\xFF\xFF\xFF\x00\x00\x00", "\xFF\x00\xFF\xFF\xFF\x00\x00\xFF",
\r
413 "\xFF\x00\xFF\xFF\xFF\x00\xFF\x00", "\xFF\x00\xFF\xFF\xFF\x00\xFF\xFF",
\r
414 "\xFF\x00\xFF\xFF\xFF\xFF\x00\x00", "\xFF\x00\xFF\xFF\xFF\xFF\x00\xFF",
\r
415 "\xFF\x00\xFF\xFF\xFF\xFF\xFF\x00", "\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF",
\r
416 "\xFF\xFF\x00\x00\x00\x00\x00\x00", "\xFF\xFF\x00\x00\x00\x00\x00\xFF",
\r
417 "\xFF\xFF\x00\x00\x00\x00\xFF\x00", "\xFF\xFF\x00\x00\x00\x00\xFF\xFF",
\r
418 "\xFF\xFF\x00\x00\x00\xFF\x00\x00", "\xFF\xFF\x00\x00\x00\xFF\x00\xFF",
\r
419 "\xFF\xFF\x00\x00\x00\xFF\xFF\x00", "\xFF\xFF\x00\x00\x00\xFF\xFF\xFF",
\r
420 "\xFF\xFF\x00\x00\xFF\x00\x00\x00", "\xFF\xFF\x00\x00\xFF\x00\x00\xFF",
\r
421 "\xFF\xFF\x00\x00\xFF\x00\xFF\x00", "\xFF\xFF\x00\x00\xFF\x00\xFF\xFF",
\r
422 "\xFF\xFF\x00\x00\xFF\xFF\x00\x00", "\xFF\xFF\x00\x00\xFF\xFF\x00\xFF",
\r
423 "\xFF\xFF\x00\x00\xFF\xFF\xFF\x00", "\xFF\xFF\x00\x00\xFF\xFF\xFF\xFF",
\r
424 "\xFF\xFF\x00\xFF\x00\x00\x00\x00", "\xFF\xFF\x00\xFF\x00\x00\x00\xFF",
\r
425 "\xFF\xFF\x00\xFF\x00\x00\xFF\x00", "\xFF\xFF\x00\xFF\x00\x00\xFF\xFF",
\r
426 "\xFF\xFF\x00\xFF\x00\xFF\x00\x00", "\xFF\xFF\x00\xFF\x00\xFF\x00\xFF",
\r
427 "\xFF\xFF\x00\xFF\x00\xFF\xFF\x00", "\xFF\xFF\x00\xFF\x00\xFF\xFF\xFF",
\r
428 "\xFF\xFF\x00\xFF\xFF\x00\x00\x00", "\xFF\xFF\x00\xFF\xFF\x00\x00\xFF",
\r
429 "\xFF\xFF\x00\xFF\xFF\x00\xFF\x00", "\xFF\xFF\x00\xFF\xFF\x00\xFF\xFF",
\r
430 "\xFF\xFF\x00\xFF\xFF\xFF\x00\x00", "\xFF\xFF\x00\xFF\xFF\xFF\x00\xFF",
\r
431 "\xFF\xFF\x00\xFF\xFF\xFF\xFF\x00", "\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF",
\r
432 "\xFF\xFF\xFF\x00\x00\x00\x00\x00", "\xFF\xFF\xFF\x00\x00\x00\x00\xFF",
\r
433 "\xFF\xFF\xFF\x00\x00\x00\xFF\x00", "\xFF\xFF\xFF\x00\x00\x00\xFF\xFF",
\r
434 "\xFF\xFF\xFF\x00\x00\xFF\x00\x00", "\xFF\xFF\xFF\x00\x00\xFF\x00\xFF",
\r
435 "\xFF\xFF\xFF\x00\x00\xFF\xFF\x00", "\xFF\xFF\xFF\x00\x00\xFF\xFF\xFF",
\r
436 "\xFF\xFF\xFF\x00\xFF\x00\x00\x00", "\xFF\xFF\xFF\x00\xFF\x00\x00\xFF",
\r
437 "\xFF\xFF\xFF\x00\xFF\x00\xFF\x00", "\xFF\xFF\xFF\x00\xFF\x00\xFF\xFF",
\r
438 "\xFF\xFF\xFF\x00\xFF\xFF\x00\x00", "\xFF\xFF\xFF\x00\xFF\xFF\x00\xFF",
\r
439 "\xFF\xFF\xFF\x00\xFF\xFF\xFF\x00", "\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF",
\r
440 "\xFF\xFF\xFF\xFF\x00\x00\x00\x00", "\xFF\xFF\xFF\xFF\x00\x00\x00\xFF",
\r
441 "\xFF\xFF\xFF\xFF\x00\x00\xFF\x00", "\xFF\xFF\xFF\xFF\x00\x00\xFF\xFF",
\r
442 "\xFF\xFF\xFF\xFF\x00\xFF\x00\x00", "\xFF\xFF\xFF\xFF\x00\xFF\x00\xFF",
\r
443 "\xFF\xFF\xFF\xFF\x00\xFF\xFF\x00", "\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF",
\r
444 "\xFF\xFF\xFF\xFF\xFF\x00\x00\x00", "\xFF\xFF\xFF\xFF\xFF\x00\x00\xFF",
\r
445 "\xFF\xFF\xFF\xFF\xFF\x00\xFF\x00", "\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF",
\r
446 "\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00", "\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF",
\r
447 "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00", "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
\r
451 * IP mapping helper table.
\r
453 * Indexing this table with each source byte performs the initial bit permutation.
\r
458 var $ipmap = array(
\r
459 0x00, 0x10, 0x01, 0x11, 0x20, 0x30, 0x21, 0x31,
\r
460 0x02, 0x12, 0x03, 0x13, 0x22, 0x32, 0x23, 0x33,
\r
461 0x40, 0x50, 0x41, 0x51, 0x60, 0x70, 0x61, 0x71,
\r
462 0x42, 0x52, 0x43, 0x53, 0x62, 0x72, 0x63, 0x73,
\r
463 0x04, 0x14, 0x05, 0x15, 0x24, 0x34, 0x25, 0x35,
\r
464 0x06, 0x16, 0x07, 0x17, 0x26, 0x36, 0x27, 0x37,
\r
465 0x44, 0x54, 0x45, 0x55, 0x64, 0x74, 0x65, 0x75,
\r
466 0x46, 0x56, 0x47, 0x57, 0x66, 0x76, 0x67, 0x77,
\r
467 0x80, 0x90, 0x81, 0x91, 0xA0, 0xB0, 0xA1, 0xB1,
\r
468 0x82, 0x92, 0x83, 0x93, 0xA2, 0xB2, 0xA3, 0xB3,
\r
469 0xC0, 0xD0, 0xC1, 0xD1, 0xE0, 0xF0, 0xE1, 0xF1,
\r
470 0xC2, 0xD2, 0xC3, 0xD3, 0xE2, 0xF2, 0xE3, 0xF3,
\r
471 0x84, 0x94, 0x85, 0x95, 0xA4, 0xB4, 0xA5, 0xB5,
\r
472 0x86, 0x96, 0x87, 0x97, 0xA6, 0xB6, 0xA7, 0xB7,
\r
473 0xC4, 0xD4, 0xC5, 0xD5, 0xE4, 0xF4, 0xE5, 0xF5,
\r
474 0xC6, 0xD6, 0xC7, 0xD7, 0xE6, 0xF6, 0xE7, 0xF7,
\r
475 0x08, 0x18, 0x09, 0x19, 0x28, 0x38, 0x29, 0x39,
\r
476 0x0A, 0x1A, 0x0B, 0x1B, 0x2A, 0x3A, 0x2B, 0x3B,
\r
477 0x48, 0x58, 0x49, 0x59, 0x68, 0x78, 0x69, 0x79,
\r
478 0x4A, 0x5A, 0x4B, 0x5B, 0x6A, 0x7A, 0x6B, 0x7B,
\r
479 0x0C, 0x1C, 0x0D, 0x1D, 0x2C, 0x3C, 0x2D, 0x3D,
\r
480 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F,
\r
481 0x4C, 0x5C, 0x4D, 0x5D, 0x6C, 0x7C, 0x6D, 0x7D,
\r
482 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F,
\r
483 0x88, 0x98, 0x89, 0x99, 0xA8, 0xB8, 0xA9, 0xB9,
\r
484 0x8A, 0x9A, 0x8B, 0x9B, 0xAA, 0xBA, 0xAB, 0xBB,
\r
485 0xC8, 0xD8, 0xC9, 0xD9, 0xE8, 0xF8, 0xE9, 0xF9,
\r
486 0xCA, 0xDA, 0xCB, 0xDB, 0xEA, 0xFA, 0xEB, 0xFB,
\r
487 0x8C, 0x9C, 0x8D, 0x9D, 0xAC, 0xBC, 0xAD, 0xBD,
\r
488 0x8E, 0x9E, 0x8F, 0x9F, 0xAE, 0xBE, 0xAF, 0xBF,
\r
489 0xCC, 0xDC, 0xCD, 0xDD, 0xEC, 0xFC, 0xED, 0xFD,
\r
490 0xCE, 0xDE, 0xCF, 0xDF, 0xEE, 0xFE, 0xEF, 0xFF
\r
494 * Inverse IP mapping helper table.
\r
495 * Indexing this table with a byte value reverses the bit order.
\r
500 var $invipmap = array(
\r
501 0x00, 0x80, 0x40, 0xC0, 0x20, 0xA0, 0x60, 0xE0,
\r
502 0x10, 0x90, 0x50, 0xD0, 0x30, 0xB0, 0x70, 0xF0,
\r
503 0x08, 0x88, 0x48, 0xC8, 0x28, 0xA8, 0x68, 0xE8,
\r
504 0x18, 0x98, 0x58, 0xD8, 0x38, 0xB8, 0x78, 0xF8,
\r
505 0x04, 0x84, 0x44, 0xC4, 0x24, 0xA4, 0x64, 0xE4,
\r
506 0x14, 0x94, 0x54, 0xD4, 0x34, 0xB4, 0x74, 0xF4,
\r
507 0x0C, 0x8C, 0x4C, 0xCC, 0x2C, 0xAC, 0x6C, 0xEC,
\r
508 0x1C, 0x9C, 0x5C, 0xDC, 0x3C, 0xBC, 0x7C, 0xFC,
\r
509 0x02, 0x82, 0x42, 0xC2, 0x22, 0xA2, 0x62, 0xE2,
\r
510 0x12, 0x92, 0x52, 0xD2, 0x32, 0xB2, 0x72, 0xF2,
\r
511 0x0A, 0x8A, 0x4A, 0xCA, 0x2A, 0xAA, 0x6A, 0xEA,
\r
512 0x1A, 0x9A, 0x5A, 0xDA, 0x3A, 0xBA, 0x7A, 0xFA,
\r
513 0x06, 0x86, 0x46, 0xC6, 0x26, 0xA6, 0x66, 0xE6,
\r
514 0x16, 0x96, 0x56, 0xD6, 0x36, 0xB6, 0x76, 0xF6,
\r
515 0x0E, 0x8E, 0x4E, 0xCE, 0x2E, 0xAE, 0x6E, 0xEE,
\r
516 0x1E, 0x9E, 0x5E, 0xDE, 0x3E, 0xBE, 0x7E, 0xFE,
\r
517 0x01, 0x81, 0x41, 0xC1, 0x21, 0xA1, 0x61, 0xE1,
\r
518 0x11, 0x91, 0x51, 0xD1, 0x31, 0xB1, 0x71, 0xF1,
\r
519 0x09, 0x89, 0x49, 0xC9, 0x29, 0xA9, 0x69, 0xE9,
\r
520 0x19, 0x99, 0x59, 0xD9, 0x39, 0xB9, 0x79, 0xF9,
\r
521 0x05, 0x85, 0x45, 0xC5, 0x25, 0xA5, 0x65, 0xE5,
\r
522 0x15, 0x95, 0x55, 0xD5, 0x35, 0xB5, 0x75, 0xF5,
\r
523 0x0D, 0x8D, 0x4D, 0xCD, 0x2D, 0xAD, 0x6D, 0xED,
\r
524 0x1D, 0x9D, 0x5D, 0xDD, 0x3D, 0xBD, 0x7D, 0xFD,
\r
525 0x03, 0x83, 0x43, 0xC3, 0x23, 0xA3, 0x63, 0xE3,
\r
526 0x13, 0x93, 0x53, 0xD3, 0x33, 0xB3, 0x73, 0xF3,
\r
527 0x0B, 0x8B, 0x4B, 0xCB, 0x2B, 0xAB, 0x6B, 0xEB,
\r
528 0x1B, 0x9B, 0x5B, 0xDB, 0x3B, 0xBB, 0x7B, 0xFB,
\r
529 0x07, 0x87, 0x47, 0xC7, 0x27, 0xA7, 0x67, 0xE7,
\r
530 0x17, 0x97, 0x57, 0xD7, 0x37, 0xB7, 0x77, 0xF7,
\r
531 0x0F, 0x8F, 0x4F, 0xCF, 0x2F, 0xAF, 0x6F, 0xEF,
\r
532 0x1F, 0x9F, 0x5F, 0xDF, 0x3F, 0xBF, 0x7F, 0xFF
\r
536 * Pre-permuted S-box1
\r
538 * Each box ($sbox1-$sbox8) has been vectorized, then each value pre-permuted using the
\r
539 * P table: concatenation can then be replaced by exclusive ORs.
\r
544 var $sbox1 = array(
\r
545 0x00808200, 0x00000000, 0x00008000, 0x00808202,
\r
546 0x00808002, 0x00008202, 0x00000002, 0x00008000,
\r
547 0x00000200, 0x00808200, 0x00808202, 0x00000200,
\r
548 0x00800202, 0x00808002, 0x00800000, 0x00000002,
\r
549 0x00000202, 0x00800200, 0x00800200, 0x00008200,
\r
550 0x00008200, 0x00808000, 0x00808000, 0x00800202,
\r
551 0x00008002, 0x00800002, 0x00800002, 0x00008002,
\r
552 0x00000000, 0x00000202, 0x00008202, 0x00800000,
\r
553 0x00008000, 0x00808202, 0x00000002, 0x00808000,
\r
554 0x00808200, 0x00800000, 0x00800000, 0x00000200,
\r
555 0x00808002, 0x00008000, 0x00008200, 0x00800002,
\r
556 0x00000200, 0x00000002, 0x00800202, 0x00008202,
\r
557 0x00808202, 0x00008002, 0x00808000, 0x00800202,
\r
558 0x00800002, 0x00000202, 0x00008202, 0x00808200,
\r
559 0x00000202, 0x00800200, 0x00800200, 0x00000000,
\r
560 0x00008002, 0x00008200, 0x00000000, 0x00808002
\r
564 * Pre-permuted S-box2
\r
569 var $sbox2 = array(
\r
570 0x40084010, 0x40004000, 0x00004000, 0x00084010,
\r
571 0x00080000, 0x00000010, 0x40080010, 0x40004010,
\r
572 0x40000010, 0x40084010, 0x40084000, 0x40000000,
\r
573 0x40004000, 0x00080000, 0x00000010, 0x40080010,
\r
574 0x00084000, 0x00080010, 0x40004010, 0x00000000,
\r
575 0x40000000, 0x00004000, 0x00084010, 0x40080000,
\r
576 0x00080010, 0x40000010, 0x00000000, 0x00084000,
\r
577 0x00004010, 0x40084000, 0x40080000, 0x00004010,
\r
578 0x00000000, 0x00084010, 0x40080010, 0x00080000,
\r
579 0x40004010, 0x40080000, 0x40084000, 0x00004000,
\r
580 0x40080000, 0x40004000, 0x00000010, 0x40084010,
\r
581 0x00084010, 0x00000010, 0x00004000, 0x40000000,
\r
582 0x00004010, 0x40084000, 0x00080000, 0x40000010,
\r
583 0x00080010, 0x40004010, 0x40000010, 0x00080010,
\r
584 0x00084000, 0x00000000, 0x40004000, 0x00004010,
\r
585 0x40000000, 0x40080010, 0x40084010, 0x00084000
\r
589 * Pre-permuted S-box3
\r
594 var $sbox3 = array(
\r
595 0x00000104, 0x04010100, 0x00000000, 0x04010004,
\r
596 0x04000100, 0x00000000, 0x00010104, 0x04000100,
\r
597 0x00010004, 0x04000004, 0x04000004, 0x00010000,
\r
598 0x04010104, 0x00010004, 0x04010000, 0x00000104,
\r
599 0x04000000, 0x00000004, 0x04010100, 0x00000100,
\r
600 0x00010100, 0x04010000, 0x04010004, 0x00010104,
\r
601 0x04000104, 0x00010100, 0x00010000, 0x04000104,
\r
602 0x00000004, 0x04010104, 0x00000100, 0x04000000,
\r
603 0x04010100, 0x04000000, 0x00010004, 0x00000104,
\r
604 0x00010000, 0x04010100, 0x04000100, 0x00000000,
\r
605 0x00000100, 0x00010004, 0x04010104, 0x04000100,
\r
606 0x04000004, 0x00000100, 0x00000000, 0x04010004,
\r
607 0x04000104, 0x00010000, 0x04000000, 0x04010104,
\r
608 0x00000004, 0x00010104, 0x00010100, 0x04000004,
\r
609 0x04010000, 0x04000104, 0x00000104, 0x04010000,
\r
610 0x00010104, 0x00000004, 0x04010004, 0x00010100
\r
614 * Pre-permuted S-box4
\r
619 var $sbox4 = array(
\r
620 0x80401000, 0x80001040, 0x80001040, 0x00000040,
\r
621 0x00401040, 0x80400040, 0x80400000, 0x80001000,
\r
622 0x00000000, 0x00401000, 0x00401000, 0x80401040,
\r
623 0x80000040, 0x00000000, 0x00400040, 0x80400000,
\r
624 0x80000000, 0x00001000, 0x00400000, 0x80401000,
\r
625 0x00000040, 0x00400000, 0x80001000, 0x00001040,
\r
626 0x80400040, 0x80000000, 0x00001040, 0x00400040,
\r
627 0x00001000, 0x00401040, 0x80401040, 0x80000040,
\r
628 0x00400040, 0x80400000, 0x00401000, 0x80401040,
\r
629 0x80000040, 0x00000000, 0x00000000, 0x00401000,
\r
630 0x00001040, 0x00400040, 0x80400040, 0x80000000,
\r
631 0x80401000, 0x80001040, 0x80001040, 0x00000040,
\r
632 0x80401040, 0x80000040, 0x80000000, 0x00001000,
\r
633 0x80400000, 0x80001000, 0x00401040, 0x80400040,
\r
634 0x80001000, 0x00001040, 0x00400000, 0x80401000,
\r
635 0x00000040, 0x00400000, 0x00001000, 0x00401040
\r
639 * Pre-permuted S-box5
\r
644 var $sbox5 = array(
\r
645 0x00000080, 0x01040080, 0x01040000, 0x21000080,
\r
646 0x00040000, 0x00000080, 0x20000000, 0x01040000,
\r
647 0x20040080, 0x00040000, 0x01000080, 0x20040080,
\r
648 0x21000080, 0x21040000, 0x00040080, 0x20000000,
\r
649 0x01000000, 0x20040000, 0x20040000, 0x00000000,
\r
650 0x20000080, 0x21040080, 0x21040080, 0x01000080,
\r
651 0x21040000, 0x20000080, 0x00000000, 0x21000000,
\r
652 0x01040080, 0x01000000, 0x21000000, 0x00040080,
\r
653 0x00040000, 0x21000080, 0x00000080, 0x01000000,
\r
654 0x20000000, 0x01040000, 0x21000080, 0x20040080,
\r
655 0x01000080, 0x20000000, 0x21040000, 0x01040080,
\r
656 0x20040080, 0x00000080, 0x01000000, 0x21040000,
\r
657 0x21040080, 0x00040080, 0x21000000, 0x21040080,
\r
658 0x01040000, 0x00000000, 0x20040000, 0x21000000,
\r
659 0x00040080, 0x01000080, 0x20000080, 0x00040000,
\r
660 0x00000000, 0x20040000, 0x01040080, 0x20000080
\r
664 * Pre-permuted S-box6
\r
669 var $sbox6 = array(
\r
670 0x10000008, 0x10200000, 0x00002000, 0x10202008,
\r
671 0x10200000, 0x00000008, 0x10202008, 0x00200000,
\r
672 0x10002000, 0x00202008, 0x00200000, 0x10000008,
\r
673 0x00200008, 0x10002000, 0x10000000, 0x00002008,
\r
674 0x00000000, 0x00200008, 0x10002008, 0x00002000,
\r
675 0x00202000, 0x10002008, 0x00000008, 0x10200008,
\r
676 0x10200008, 0x00000000, 0x00202008, 0x10202000,
\r
677 0x00002008, 0x00202000, 0x10202000, 0x10000000,
\r
678 0x10002000, 0x00000008, 0x10200008, 0x00202000,
\r
679 0x10202008, 0x00200000, 0x00002008, 0x10000008,
\r
680 0x00200000, 0x10002000, 0x10000000, 0x00002008,
\r
681 0x10000008, 0x10202008, 0x00202000, 0x10200000,
\r
682 0x00202008, 0x10202000, 0x00000000, 0x10200008,
\r
683 0x00000008, 0x00002000, 0x10200000, 0x00202008,
\r
684 0x00002000, 0x00200008, 0x10002008, 0x00000000,
\r
685 0x10202000, 0x10000000, 0x00200008, 0x10002008
\r
689 * Pre-permuted S-box7
\r
694 var $sbox7 = array(
\r
695 0x00100000, 0x02100001, 0x02000401, 0x00000000,
\r
696 0x00000400, 0x02000401, 0x00100401, 0x02100400,
\r
697 0x02100401, 0x00100000, 0x00000000, 0x02000001,
\r
698 0x00000001, 0x02000000, 0x02100001, 0x00000401,
\r
699 0x02000400, 0x00100401, 0x00100001, 0x02000400,
\r
700 0x02000001, 0x02100000, 0x02100400, 0x00100001,
\r
701 0x02100000, 0x00000400, 0x00000401, 0x02100401,
\r
702 0x00100400, 0x00000001, 0x02000000, 0x00100400,
\r
703 0x02000000, 0x00100400, 0x00100000, 0x02000401,
\r
704 0x02000401, 0x02100001, 0x02100001, 0x00000001,
\r
705 0x00100001, 0x02000000, 0x02000400, 0x00100000,
\r
706 0x02100400, 0x00000401, 0x00100401, 0x02100400,
\r
707 0x00000401, 0x02000001, 0x02100401, 0x02100000,
\r
708 0x00100400, 0x00000000, 0x00000001, 0x02100401,
\r
709 0x00000000, 0x00100401, 0x02100000, 0x00000400,
\r
710 0x02000001, 0x02000400, 0x00000400, 0x00100001
\r
714 * Pre-permuted S-box8
\r
719 var $sbox8 = array(
\r
720 0x08000820, 0x00000800, 0x00020000, 0x08020820,
\r
721 0x08000000, 0x08000820, 0x00000020, 0x08000000,
\r
722 0x00020020, 0x08020000, 0x08020820, 0x00020800,
\r
723 0x08020800, 0x00020820, 0x00000800, 0x00000020,
\r
724 0x08020000, 0x08000020, 0x08000800, 0x00000820,
\r
725 0x00020800, 0x00020020, 0x08020020, 0x08020800,
\r
726 0x00000820, 0x00000000, 0x00000000, 0x08020020,
\r
727 0x08000020, 0x08000800, 0x00020820, 0x00020000,
\r
728 0x00020820, 0x00020000, 0x08020800, 0x00000800,
\r
729 0x00000020, 0x08020020, 0x00000800, 0x00020820,
\r
730 0x08000800, 0x00000020, 0x08000020, 0x08020000,
\r
731 0x08020020, 0x08000000, 0x00020000, 0x08000820,
\r
732 0x00000000, 0x08020820, 0x00020020, 0x08000020,
\r
733 0x08020000, 0x08000800, 0x08000820, 0x00000000,
\r
734 0x08020820, 0x00020800, 0x00020800, 0x00000820,
\r
735 0x00000820, 0x00020020, 0x08000000, 0x08020800
\r
739 * Default Constructor.
\r
741 * Determines whether or not the mcrypt extension should be used. $mode should only, at present, be
\r
742 * CRYPT_DES_MODE_ECB or CRYPT_DES_MODE_CBC. If not explictly set, CRYPT_DES_MODE_CBC will be used.
\r
744 * @param optional Integer $mode
\r
745 * @return Crypt_DES
\r
748 function Crypt_DES($mode = CRYPT_DES_MODE_CBC)
\r
750 if ( !defined('CRYPT_DES_MODE') ) {
\r
752 case extension_loaded('mcrypt') && in_array('des', mcrypt_list_algorithms()):
\r
753 define('CRYPT_DES_MODE', CRYPT_DES_MODE_MCRYPT);
\r
756 define('CRYPT_DES_MODE', CRYPT_DES_MODE_INTERNAL);
\r
760 switch ( CRYPT_DES_MODE ) {
\r
761 case CRYPT_DES_MODE_MCRYPT:
\r
763 case CRYPT_DES_MODE_ECB:
\r
764 $this->paddable = true;
\r
765 $this->mode = MCRYPT_MODE_ECB;
\r
767 case CRYPT_DES_MODE_CTR:
\r
768 $this->mode = 'ctr';
\r
769 //$this->mode = in_array('ctr', mcrypt_list_modes()) ? 'ctr' : CRYPT_DES_MODE_CTR;
\r
771 case CRYPT_DES_MODE_CFB:
\r
772 $this->mode = 'ncfb';
\r
773 $this->ecb = mcrypt_module_open(MCRYPT_DES, '', MCRYPT_MODE_ECB, '');
\r
775 case CRYPT_DES_MODE_OFB:
\r
776 $this->mode = MCRYPT_MODE_NOFB;
\r
778 case CRYPT_DES_MODE_CBC:
\r
780 $this->paddable = true;
\r
781 $this->mode = MCRYPT_MODE_CBC;
\r
783 $this->enmcrypt = mcrypt_module_open(MCRYPT_DES, '', $this->mode, '');
\r
784 $this->demcrypt = mcrypt_module_open(MCRYPT_DES, '', $this->mode, '');
\r
789 case CRYPT_DES_MODE_ECB:
\r
790 case CRYPT_DES_MODE_CBC:
\r
791 $this->paddable = true;
\r
792 $this->mode = $mode;
\r
794 case CRYPT_DES_MODE_CTR:
\r
795 case CRYPT_DES_MODE_CFB:
\r
796 case CRYPT_DES_MODE_OFB:
\r
797 $this->mode = $mode;
\r
800 $this->paddable = true;
\r
801 $this->mode = CRYPT_DES_MODE_CBC;
\r
803 if (function_exists('create_function') && is_callable('create_function')) {
\r
804 $this->inline_crypt_setup();
\r
805 $this->use_inline_crypt = true;
\r
813 * Keys can be of any length. DES, itself, uses 64-bit keys (eg. strlen($key) == 8), however, we
\r
814 * only use the first eight, if $key has more then eight characters in it, and pad $key with the
\r
815 * null byte if it is less then eight characters long.
\r
817 * DES also requires that every eighth bit be a parity bit, however, we'll ignore that.
\r
819 * If the key is not explicitly set, it'll be assumed to be all zero's.
\r
822 * @param String $key
\r
824 function setKey($key)
\r
826 $this->keys = ( CRYPT_DES_MODE == CRYPT_DES_MODE_MCRYPT ) ? str_pad(substr($key, 0, 8), 8, chr(0)) : $this->_prepareKey($key);
\r
827 $this->enchanged = true;
\r
828 $this->dechanged = true;
\r
832 * Sets the password.
\r
834 * Depending on what $method is set to, setPassword()'s (optional) parameters are as follows:
\r
835 * {@link http://en.wikipedia.org/wiki/PBKDF2 pbkdf2}:
\r
836 * $hash, $salt, $count
\r
838 * @param String $password
\r
839 * @param optional String $method
\r
842 function setPassword($password, $method = 'pbkdf2')
\r
847 default: // 'pbkdf2'
\r
848 list(, , $hash, $salt, $count) = func_get_args();
\r
849 if (!isset($hash)) {
\r
852 // WPA and WPA2 use the SSID as the salt
\r
853 if (!isset($salt)) {
\r
854 $salt = 'phpseclib/salt';
\r
856 // RFC2898#section-4.2 uses 1,000 iterations by default
\r
857 // WPA and WPA2 use 4,096.
\r
858 if (!isset($count)) {
\r
862 if (!class_exists('Crypt_Hash')) {
\r
863 require_once('Crypt/Hash.php');
\r
867 while (strlen($key) < 8) { // $dkLen == 8
\r
868 //$dk.= $this->_pbkdf($password, $salt, $count, $i++);
\r
869 $hmac = new Crypt_Hash();
\r
870 $hmac->setHash($hash);
\r
871 $hmac->setKey($password);
\r
872 $f = $u = $hmac->hash($salt . pack('N', $i++));
\r
873 for ($j = 2; $j <= $count; $j++) {
\r
874 $u = $hmac->hash($u);
\r
881 $this->setKey($key);
\r
885 * Sets the initialization vector. (optional)
\r
887 * SetIV is not required when CRYPT_DES_MODE_ECB is being used. If not explictly set, it'll be assumed
\r
888 * to be all zero's.
\r
891 * @param String $iv
\r
893 function setIV($iv)
\r
895 $this->encryptIV = $this->decryptIV = $this->iv = str_pad(substr($iv, 0, 8), 8, chr(0));
\r
896 $this->enchanged = true;
\r
897 $this->dechanged = true;
\r
901 * Generate CTR XOR encryption key
\r
903 * Encrypt the output of this and XOR it against the ciphertext / plaintext to get the
\r
904 * plaintext / ciphertext in CTR mode.
\r
906 * @see Crypt_DES::decrypt()
\r
907 * @see Crypt_DES::encrypt()
\r
909 * @param String $iv
\r
911 function _generate_xor(&$iv)
\r
914 for ($j = 4; $j <= 8; $j+=4) {
\r
915 $temp = substr($iv, -$j, 4);
\r
917 case "\xFF\xFF\xFF\xFF":
\r
918 $iv = substr_replace($iv, "\x00\x00\x00\x00", -$j, 4);
\r
920 case "\x7F\xFF\xFF\xFF":
\r
921 $iv = substr_replace($iv, "\x80\x00\x00\x00", -$j, 4);
\r
924 extract(unpack('Ncount', $temp));
\r
925 $iv = substr_replace($iv, pack('N', $count + 1), -$j, 4);
\r
934 * Encrypts a message.
\r
936 * $plaintext will be padded with up to 8 additional bytes. Other DES implementations may or may not pad in the
\r
937 * same manner. Other common approaches to padding and the reasons why it's necessary are discussed in the following
\r
940 * {@link http://www.di-mgt.com.au/cryptopad.html http://www.di-mgt.com.au/cryptopad.html}
\r
942 * An alternative to padding is to, separately, send the length of the file. This is what SSH, in fact, does.
\r
943 * strlen($plaintext) will still need to be a multiple of 8, however, arbitrary values can be added to make it that
\r
946 * @see Crypt_DES::decrypt()
\r
948 * @param String $plaintext
\r
950 function encrypt($plaintext)
\r
952 if ($this->paddable) {
\r
953 $plaintext = $this->_pad($plaintext);
\r
956 if ( CRYPT_DES_MODE == CRYPT_DES_MODE_MCRYPT ) {
\r
957 if ($this->enchanged) {
\r
958 mcrypt_generic_init($this->enmcrypt, $this->keys, $this->encryptIV);
\r
959 if ($this->mode == 'ncfb') {
\r
960 mcrypt_generic_init($this->ecb, $this->keys, "\0\0\0\0\0\0\0\0");
\r
962 $this->enchanged = false;
\r
965 if ($this->mode != 'ncfb' || !$this->continuousBuffer) {
\r
966 $ciphertext = mcrypt_generic($this->enmcrypt, $plaintext);
\r
968 $iv = &$this->encryptIV;
\r
969 $pos = &$this->enbuffer['pos'];
\r
970 $len = strlen($plaintext);
\r
976 if ($len >= $max) {
\r
985 $ciphertext = substr($iv, $orig_pos) ^ $plaintext;
\r
986 $iv = substr_replace($iv, $ciphertext, $orig_pos, $i);
\r
987 $this->enbuffer['enmcrypt_init'] = true;
\r
990 if ($this->enbuffer['enmcrypt_init'] === false || $len > 600) {
\r
991 if ($this->enbuffer['enmcrypt_init'] === true) {
\r
992 mcrypt_generic_init($this->enmcrypt, $this->keys, $iv);
\r
993 $this->enbuffer['enmcrypt_init'] = false;
\r
995 $ciphertext.= mcrypt_generic($this->enmcrypt, substr($plaintext, $i, $len - $len % 8));
\r
996 $iv = substr($ciphertext, -8);
\r
999 while ($len >= 8) {
\r
1000 $iv = mcrypt_generic($this->ecb, $iv) ^ substr($plaintext, $i, 8);
\r
1001 $ciphertext.= $iv;
\r
1008 $iv = mcrypt_generic($this->ecb, $iv);
\r
1009 $block = $iv ^ substr($plaintext, -$len);
\r
1010 $iv = substr_replace($iv, $block, 0, $len);
\r
1011 $ciphertext.= $block;
\r
1014 return $ciphertext;
\r
1017 if (!$this->continuousBuffer) {
\r
1018 mcrypt_generic_init($this->enmcrypt, $this->keys, $this->encryptIV);
\r
1021 return $ciphertext;
\r
1024 if (!is_array($this->keys)) {
\r
1025 $this->keys = $this->_prepareKey("\0\0\0\0\0\0\0\0");
\r
1028 if ($this->use_inline_crypt) {
\r
1029 $inline = $this->inline_crypt;
\r
1030 return $inline('encrypt', $this, $plaintext);
\r
1033 $buffer = &$this->enbuffer;
\r
1034 $continuousBuffer = $this->continuousBuffer;
\r
1036 switch ($this->mode) {
\r
1037 case CRYPT_DES_MODE_ECB:
\r
1038 for ($i = 0; $i < strlen($plaintext); $i+=8) {
\r
1039 $ciphertext.= $this->_processBlock(substr($plaintext, $i, 8), CRYPT_DES_ENCRYPT);
\r
1042 case CRYPT_DES_MODE_CBC:
\r
1043 $xor = $this->encryptIV;
\r
1044 for ($i = 0; $i < strlen($plaintext); $i+=8) {
\r
1045 $block = substr($plaintext, $i, 8);
\r
1046 $block = $this->_processBlock($block ^ $xor, CRYPT_DES_ENCRYPT);
\r
1048 $ciphertext.= $block;
\r
1050 if ($this->continuousBuffer) {
\r
1051 $this->encryptIV = $xor;
\r
1054 case CRYPT_DES_MODE_CTR:
\r
1055 $xor = $this->encryptIV;
\r
1056 if (strlen($buffer['encrypted'])) {
\r
1057 for ($i = 0; $i < strlen($plaintext); $i+=8) {
\r
1058 $block = substr($plaintext, $i, 8);
\r
1059 if (strlen($block) > strlen($buffer['encrypted'])) {
\r
1060 $buffer['encrypted'].= $this->_processBlock($this->_generate_xor($xor), CRYPT_DES_ENCRYPT);
\r
1062 $key = $this->_string_shift($buffer['encrypted']);
\r
1063 $ciphertext.= $block ^ $key;
\r
1066 for ($i = 0; $i < strlen($plaintext); $i+=8) {
\r
1067 $block = substr($plaintext, $i, 8);
\r
1068 $key = $this->_processBlock($this->_generate_xor($xor), CRYPT_DES_ENCRYPT);
\r
1069 $ciphertext.= $block ^ $key;
\r
1072 if ($this->continuousBuffer) {
\r
1073 $this->encryptIV = $xor;
\r
1074 if ($start = strlen($plaintext) & 7) {
\r
1075 $buffer['encrypted'] = substr($key, $start) . $buffer['encrypted'];
\r
1079 case CRYPT_DES_MODE_CFB:
\r
1080 if ($this->continuousBuffer) {
\r
1081 $iv = &$this->encryptIV;
\r
1082 $pos = &$buffer['pos'];
\r
1084 $iv = $this->encryptIV;
\r
1087 $len = strlen($plaintext);
\r
1092 if ($len >= $max) {
\r
1101 $ciphertext = substr($iv, $orig_pos) ^ $plaintext;
\r
1102 $iv = substr_replace($iv, $ciphertext, $orig_pos, $i);
\r
1104 while ($len >= 8) {
\r
1105 $iv = $this->_processBlock($iv, CRYPT_DES_ENCRYPT) ^ substr($plaintext, $i, 8);
\r
1106 $ciphertext.= $iv;
\r
1111 $iv = $this->_processBlock($iv, CRYPT_DES_ENCRYPT);
\r
1112 $block = $iv ^ substr($plaintext, $i);
\r
1113 $iv = substr_replace($iv, $block, 0, $len);
\r
1114 $ciphertext.= $block;
\r
1117 return $ciphertext;
\r
1118 case CRYPT_DES_MODE_OFB:
\r
1119 $xor = $this->encryptIV;
\r
1120 if (strlen($buffer['xor'])) {
\r
1121 for ($i = 0; $i < strlen($plaintext); $i+=8) {
\r
1122 $block = substr($plaintext, $i, 8);
\r
1123 if (strlen($block) > strlen($buffer['xor'])) {
\r
1124 $xor = $this->_processBlock($xor, CRYPT_DES_ENCRYPT);
\r
1125 $buffer['xor'].= $xor;
\r
1127 $key = $this->_string_shift($buffer['xor']);
\r
1128 $ciphertext.= $block ^ $key;
\r
1131 for ($i = 0; $i < strlen($plaintext); $i+=8) {
\r
1132 $xor = $this->_processBlock($xor, CRYPT_DES_ENCRYPT);
\r
1133 $ciphertext.= substr($plaintext, $i, 8) ^ $xor;
\r
1137 if ($this->continuousBuffer) {
\r
1138 $this->encryptIV = $xor;
\r
1139 if ($start = strlen($plaintext) & 7) {
\r
1140 $buffer['xor'] = substr($key, $start) . $buffer['xor'];
\r
1145 return $ciphertext;
\r
1149 * Decrypts a message.
\r
1151 * If strlen($ciphertext) is not a multiple of 8, null bytes will be added to the end of the string until it is.
\r
1153 * @see Crypt_DES::encrypt()
\r
1155 * @param String $ciphertext
\r
1157 function decrypt($ciphertext)
\r
1159 if ($this->paddable) {
\r
1160 // we pad with chr(0) since that's what mcrypt_generic does. to quote from http://php.net/function.mcrypt-generic :
\r
1161 // "The data is padded with "\0" to make sure the length of the data is n * blocksize."
\r
1162 $ciphertext = str_pad($ciphertext, (strlen($ciphertext) + 7) & 0xFFFFFFF8, chr(0));
\r
1165 if ( CRYPT_DES_MODE == CRYPT_DES_MODE_MCRYPT ) {
\r
1166 if ($this->dechanged) {
\r
1167 mcrypt_generic_init($this->demcrypt, $this->keys, $this->decryptIV);
\r
1168 if ($this->mode == 'ncfb') {
\r
1169 mcrypt_generic_init($this->ecb, $this->keys, "\0\0\0\0\0\0\0\0");
\r
1171 $this->dechanged = false;
\r
1174 if ($this->mode != 'ncfb' || !$this->continuousBuffer) {
\r
1175 $plaintext = mdecrypt_generic($this->demcrypt, $ciphertext);
\r
1177 $iv = &$this->decryptIV;
\r
1178 $pos = &$this->debuffer['pos'];
\r
1179 $len = strlen($ciphertext);
\r
1185 if ($len >= $max) {
\r
1194 $plaintext = substr($iv, $orig_pos) ^ $ciphertext;
\r
1195 $iv = substr_replace($iv, substr($ciphertext, 0, $i), $orig_pos, $i);
\r
1198 $cb = substr($ciphertext, $i, $len - $len % 8);
\r
1199 $plaintext.= mcrypt_generic($this->ecb, $iv . $cb) ^ $cb;
\r
1200 $iv = substr($cb, -8);
\r
1204 $iv = mcrypt_generic($this->ecb, $iv);
\r
1205 $plaintext.= $iv ^ substr($ciphertext, -$len);
\r
1206 $iv = substr_replace($iv, substr($ciphertext, -$len), 0, $len);
\r
1209 return $plaintext;
\r
1212 if (!$this->continuousBuffer) {
\r
1213 mcrypt_generic_init($this->demcrypt, $this->keys, $this->decryptIV);
\r
1216 return $this->paddable ? $this->_unpad($plaintext) : $plaintext;
\r
1219 if (!is_array($this->keys)) {
\r
1220 $this->keys = $this->_prepareKey("\0\0\0\0\0\0\0\0");
\r
1223 if ($this->use_inline_crypt) {
\r
1224 $inline = $this->inline_crypt;
\r
1225 return $inline('decrypt', $this, $ciphertext);
\r
1228 $buffer = &$this->debuffer;
\r
1229 $continuousBuffer = $this->continuousBuffer;
\r
1231 switch ($this->mode) {
\r
1232 case CRYPT_DES_MODE_ECB:
\r
1233 for ($i = 0; $i < strlen($ciphertext); $i+=8) {
\r
1234 $plaintext.= $this->_processBlock(substr($ciphertext, $i, 8), CRYPT_DES_DECRYPT);
\r
1237 case CRYPT_DES_MODE_CBC:
\r
1238 $xor = $this->decryptIV;
\r
1239 for ($i = 0; $i < strlen($ciphertext); $i+=8) {
\r
1240 $block = substr($ciphertext, $i, 8);
\r
1241 $plaintext.= $this->_processBlock($block, CRYPT_DES_DECRYPT) ^ $xor;
\r
1244 if ($this->continuousBuffer) {
\r
1245 $this->decryptIV = $xor;
\r
1248 case CRYPT_DES_MODE_CTR:
\r
1249 $xor = $this->decryptIV;
\r
1250 if (strlen($buffer['ciphertext'])) {
\r
1251 for ($i = 0; $i < strlen($ciphertext); $i+=8) {
\r
1252 $block = substr($ciphertext, $i, 8);
\r
1253 if (strlen($block) > strlen($buffer['ciphertext'])) {
\r
1254 $buffer['ciphertext'].= $this->_processBlock($this->_generate_xor($xor), CRYPT_DES_ENCRYPT);
\r
1256 $key = $this->_string_shift($buffer['ciphertext']);
\r
1257 $plaintext.= $block ^ $key;
\r
1260 for ($i = 0; $i < strlen($ciphertext); $i+=8) {
\r
1261 $block = substr($ciphertext, $i, 8);
\r
1262 $key = $this->_processBlock($this->_generate_xor($xor), CRYPT_DES_ENCRYPT);
\r
1263 $plaintext.= $block ^ $key;
\r
1266 if ($this->continuousBuffer) {
\r
1267 $this->decryptIV = $xor;
\r
1268 if ($start = strlen($ciphertext) % 8) {
\r
1269 $buffer['ciphertext'] = substr($key, $start) . $buffer['ciphertext'];
\r
1273 case CRYPT_DES_MODE_CFB:
\r
1274 if ($this->continuousBuffer) {
\r
1275 $iv = &$this->decryptIV;
\r
1276 $pos = &$buffer['pos'];
\r
1278 $iv = $this->decryptIV;
\r
1281 $len = strlen($ciphertext);
\r
1286 if ($len >= $max) {
\r
1295 $plaintext = substr($iv, $orig_pos) ^ $ciphertext;
\r
1296 $iv = substr_replace($iv, substr($ciphertext, 0, $i), $orig_pos, $i);
\r
1298 while ($len >= 8) {
\r
1299 $iv = $this->_processBlock($iv, CRYPT_DES_ENCRYPT);
\r
1300 $cb = substr($ciphertext, $i, 8);
\r
1301 $plaintext.= $iv ^ $cb;
\r
1307 $iv = $this->_processBlock($iv, CRYPT_DES_ENCRYPT);
\r
1308 $plaintext.= $iv ^ substr($ciphertext, $i);
\r
1309 $iv = substr_replace($iv, substr($ciphertext, $i), 0, $len);
\r
1312 return $plaintext;
\r
1313 case CRYPT_DES_MODE_OFB:
\r
1314 $xor = $this->decryptIV;
\r
1315 if (strlen($buffer['xor'])) {
\r
1316 for ($i = 0; $i < strlen($ciphertext); $i+=8) {
\r
1317 $block = substr($ciphertext, $i, 8);
\r
1318 if (strlen($block) > strlen($buffer['xor'])) {
\r
1319 $xor = $this->_processBlock($xor, CRYPT_DES_ENCRYPT);
\r
1320 $buffer['xor'].= $xor;
\r
1322 $key = $this->_string_shift($buffer['xor']);
\r
1323 $plaintext.= $block ^ $key;
\r
1326 for ($i = 0; $i < strlen($ciphertext); $i+=8) {
\r
1327 $xor = $this->_processBlock($xor, CRYPT_DES_ENCRYPT);
\r
1328 $plaintext.= substr($ciphertext, $i, 8) ^ $xor;
\r
1332 if ($this->continuousBuffer) {
\r
1333 $this->decryptIV = $xor;
\r
1334 if ($start = strlen($ciphertext) % 8) {
\r
1335 $buffer['xor'] = substr($key, $start) . $buffer['xor'];
\r
1340 return $this->paddable ? $this->_unpad($plaintext) : $plaintext;
\r
1344 * Treat consecutive "packets" as if they are a continuous buffer.
\r
1346 * Say you have a 16-byte plaintext $plaintext. Using the default behavior, the two following code snippets
\r
1347 * will yield different outputs:
\r
1350 * echo $des->encrypt(substr($plaintext, 0, 8));
\r
1351 * echo $des->encrypt(substr($plaintext, 8, 8));
\r
1354 * echo $des->encrypt($plaintext);
\r
1357 * The solution is to enable the continuous buffer. Although this will resolve the above discrepancy, it creates
\r
1358 * another, as demonstrated with the following:
\r
1361 * $des->encrypt(substr($plaintext, 0, 8));
\r
1362 * echo $des->decrypt($des->encrypt(substr($plaintext, 8, 8)));
\r
1365 * echo $des->decrypt($des->encrypt(substr($plaintext, 8, 8)));
\r
1368 * With the continuous buffer disabled, these would yield the same output. With it enabled, they yield different
\r
1369 * outputs. The reason is due to the fact that the initialization vector's change after every encryption /
\r
1370 * decryption round when the continuous buffer is enabled. When it's disabled, they remain constant.
\r
1372 * Put another way, when the continuous buffer is enabled, the state of the Crypt_DES() object changes after each
\r
1373 * encryption / decryption round, whereas otherwise, it'd remain constant. For this reason, it's recommended that
\r
1374 * continuous buffers not be used. They do offer better security and are, in fact, sometimes required (SSH uses them),
\r
1375 * however, they are also less intuitive and more likely to cause you problems.
\r
1377 * @see Crypt_DES::disableContinuousBuffer()
\r
1380 function enableContinuousBuffer()
\r
1382 $this->continuousBuffer = true;
\r
1386 * Treat consecutive packets as if they are a discontinuous buffer.
\r
1388 * The default behavior.
\r
1390 * @see Crypt_DES::enableContinuousBuffer()
\r
1393 function disableContinuousBuffer()
\r
1395 $this->continuousBuffer = false;
\r
1396 $this->encryptIV = $this->iv;
\r
1397 $this->decryptIV = $this->iv;
\r
1398 $this->enbuffer = array('encrypted' => '', 'xor' => '', 'pos' => 0, 'enmcrypt_init' => true);
\r
1399 $this->debuffer = array('ciphertext' => '', 'xor' => '', 'pos' => 0, 'demcrypt_init' => true);
\r
1401 if (CRYPT_DES_MODE == CRYPT_DES_MODE_MCRYPT) {
\r
1402 mcrypt_generic_init($this->enmcrypt, $this->keys, $this->iv);
\r
1403 mcrypt_generic_init($this->demcrypt, $this->keys, $this->iv);
\r
1410 * DES works by encrypting eight bytes at a time. If you ever need to encrypt or decrypt something that's not
\r
1411 * a multiple of eight, it becomes necessary to pad the input so that it's length is a multiple of eight.
\r
1413 * Padding is enabled by default. Sometimes, however, it is undesirable to pad strings. Such is the case in SSH1,
\r
1414 * where "packets" are padded with random bytes before being encrypted. Unpad these packets and you risk stripping
\r
1415 * away characters that shouldn't be stripped away. (SSH knows how many bytes are added because the length is
\r
1416 * transmitted separately)
\r
1418 * @see Crypt_DES::disablePadding()
\r
1421 function enablePadding()
\r
1423 $this->padding = true;
\r
1427 * Do not pad packets.
\r
1429 * @see Crypt_DES::enablePadding()
\r
1432 function disablePadding()
\r
1434 $this->padding = false;
\r
1440 * Pads a string using the RSA PKCS padding standards so that its length is a multiple of the blocksize (8).
\r
1441 * 8 - (strlen($text) & 7) bytes are added, each of which is equal to chr(8 - (strlen($text) & 7)
\r
1443 * If padding is disabled and $text is not a multiple of the blocksize, the string will be padded regardless
\r
1444 * and padding will, hence forth, be enabled.
\r
1446 * @see Crypt_DES::_unpad()
\r
1449 function _pad($text)
\r
1451 $length = strlen($text);
\r
1453 if (!$this->padding) {
\r
1454 if (($length & 7) == 0) {
\r
1457 user_error("The plaintext's length ($length) is not a multiple of the block size (8)");
\r
1458 $this->padding = true;
\r
1462 $pad = 8 - ($length & 7);
\r
1463 return str_pad($text, $length + $pad, chr($pad));
\r
1469 * If padding is enabled and the reported padding length is invalid the encryption key will be assumed to be wrong
\r
1470 * and false will be returned.
\r
1472 * @see Crypt_DES::_pad()
\r
1475 function _unpad($text)
\r
1477 if (!$this->padding) {
\r
1481 $length = ord($text[strlen($text) - 1]);
\r
1483 if (!$length || $length > 8) {
\r
1487 return substr($text, 0, -$length);
\r
1491 * Encrypts or decrypts a 64-bit block
\r
1493 * $mode should be either CRYPT_DES_ENCRYPT or CRYPT_DES_DECRYPT. See
\r
1494 * {@link http://en.wikipedia.org/wiki/Image:Feistel.png Feistel.png} to get a general
\r
1495 * idea of what this function does.
\r
1498 * @param String $block
\r
1499 * @param Integer $mode
\r
1502 function _processBlock($block, $mode)
\r
1504 $shuffle = $this->shuffle;
\r
1505 $invipmap = $this->invipmap;
\r
1506 $ipmap = $this->ipmap;
\r
1507 $sbox1 = $this->sbox1;
\r
1508 $sbox2 = $this->sbox2;
\r
1509 $sbox3 = $this->sbox3;
\r
1510 $sbox4 = $this->sbox4;
\r
1511 $sbox5 = $this->sbox5;
\r
1512 $sbox6 = $this->sbox6;
\r
1513 $sbox7 = $this->sbox7;
\r
1514 $sbox8 = $this->sbox8;
\r
1515 $keys = $this->keys[$mode];
\r
1517 // Do the initial IP permutation.
\r
1518 $t = unpack('Nl/Nr', $block);
\r
1519 list($l, $r) = array($t['l'], $t['r']);
\r
1520 $block = ($shuffle[$ipmap[$r & 0xFF]] & "\x80\x80\x80\x80\x80\x80\x80\x80") |
\r
1521 ($shuffle[$ipmap[($r >> 8) & 0xFF]] & "\x40\x40\x40\x40\x40\x40\x40\x40") |
\r
1522 ($shuffle[$ipmap[($r >> 16) & 0xFF]] & "\x20\x20\x20\x20\x20\x20\x20\x20") |
\r
1523 ($shuffle[$ipmap[($r >> 24) & 0xFF]] & "\x10\x10\x10\x10\x10\x10\x10\x10") |
\r
1524 ($shuffle[$ipmap[$l & 0xFF]] & "\x08\x08\x08\x08\x08\x08\x08\x08") |
\r
1525 ($shuffle[$ipmap[($l >> 8) & 0xFF]] & "\x04\x04\x04\x04\x04\x04\x04\x04") |
\r
1526 ($shuffle[$ipmap[($l >> 16) & 0xFF]] & "\x02\x02\x02\x02\x02\x02\x02\x02") |
\r
1527 ($shuffle[$ipmap[($l >> 24) & 0xFF]] & "\x01\x01\x01\x01\x01\x01\x01\x01");
\r
1529 // Extract L0 and R0.
\r
1530 $t = unpack('Nl/Nr', $block);
\r
1531 list($l, $r) = array($t['l'], $t['r']);
\r
1533 // Perform the 16 steps.
\r
1534 for ($i = 0; $i < 16; $i++) {
\r
1535 // start of "the Feistel (F) function" - see the following URL:
\r
1536 // http://en.wikipedia.org/wiki/Image:Data_Encryption_Standard_InfoBox_Diagram.png
\r
1537 // Merge key schedule.
\r
1538 $b1 = (($r >> 3) & 0x1FFFFFFF) ^ ($r << 29) ^ $keys[$i][0];
\r
1539 $b2 = (($r >> 31) & 0x00000001) ^ ($r << 1) ^ $keys[$i][1];
\r
1541 // S-box indexing.
\r
1542 $t = $sbox1[($b1 >> 24) & 0x3F] ^ $sbox2[($b2 >> 24) & 0x3F] ^
\r
1543 $sbox3[($b1 >> 16) & 0x3F] ^ $sbox4[($b2 >> 16) & 0x3F] ^
\r
1544 $sbox5[($b1 >> 8) & 0x3F] ^ $sbox6[($b2 >> 8) & 0x3F] ^
\r
1545 $sbox7[$b1 & 0x3F] ^ $sbox8[$b2 & 0x3F] ^ $l;
\r
1546 // end of "the Feistel (F) function"
\r
1552 // Perform the inverse IP permutation.
\r
1553 return ($shuffle[$invipmap[($l >> 24) & 0xFF]] & "\x80\x80\x80\x80\x80\x80\x80\x80") |
\r
1554 ($shuffle[$invipmap[($r >> 24) & 0xFF]] & "\x40\x40\x40\x40\x40\x40\x40\x40") |
\r
1555 ($shuffle[$invipmap[($l >> 16) & 0xFF]] & "\x20\x20\x20\x20\x20\x20\x20\x20") |
\r
1556 ($shuffle[$invipmap[($r >> 16) & 0xFF]] & "\x10\x10\x10\x10\x10\x10\x10\x10") |
\r
1557 ($shuffle[$invipmap[($l >> 8) & 0xFF]] & "\x08\x08\x08\x08\x08\x08\x08\x08") |
\r
1558 ($shuffle[$invipmap[($r >> 8) & 0xFF]] & "\x04\x04\x04\x04\x04\x04\x04\x04") |
\r
1559 ($shuffle[$invipmap[$l & 0xFF]] & "\x02\x02\x02\x02\x02\x02\x02\x02") |
\r
1560 ($shuffle[$invipmap[$r & 0xFF]] & "\x01\x01\x01\x01\x01\x01\x01\x01");
\r
1564 * Creates the key schedule.
\r
1567 * @param String $key
\r
1570 function _prepareKey($key)
\r
1572 static $shifts = array( // number of key bits shifted per round
\r
1573 1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1
\r
1576 static $pc1map = array(
\r
1577 0x00, 0x00, 0x08, 0x08, 0x04, 0x04, 0x0C, 0x0C,
\r
1578 0x02, 0x02, 0x0A, 0x0A, 0x06, 0x06, 0x0E, 0x0E,
\r
1579 0x10, 0x10, 0x18, 0x18, 0x14, 0x14, 0x1C, 0x1C,
\r
1580 0x12, 0x12, 0x1A, 0x1A, 0x16, 0x16, 0x1E, 0x1E,
\r
1581 0x20, 0x20, 0x28, 0x28, 0x24, 0x24, 0x2C, 0x2C,
\r
1582 0x22, 0x22, 0x2A, 0x2A, 0x26, 0x26, 0x2E, 0x2E,
\r
1583 0x30, 0x30, 0x38, 0x38, 0x34, 0x34, 0x3C, 0x3C,
\r
1584 0x32, 0x32, 0x3A, 0x3A, 0x36, 0x36, 0x3E, 0x3E,
\r
1585 0x40, 0x40, 0x48, 0x48, 0x44, 0x44, 0x4C, 0x4C,
\r
1586 0x42, 0x42, 0x4A, 0x4A, 0x46, 0x46, 0x4E, 0x4E,
\r
1587 0x50, 0x50, 0x58, 0x58, 0x54, 0x54, 0x5C, 0x5C,
\r
1588 0x52, 0x52, 0x5A, 0x5A, 0x56, 0x56, 0x5E, 0x5E,
\r
1589 0x60, 0x60, 0x68, 0x68, 0x64, 0x64, 0x6C, 0x6C,
\r
1590 0x62, 0x62, 0x6A, 0x6A, 0x66, 0x66, 0x6E, 0x6E,
\r
1591 0x70, 0x70, 0x78, 0x78, 0x74, 0x74, 0x7C, 0x7C,
\r
1592 0x72, 0x72, 0x7A, 0x7A, 0x76, 0x76, 0x7E, 0x7E,
\r
1593 0x80, 0x80, 0x88, 0x88, 0x84, 0x84, 0x8C, 0x8C,
\r
1594 0x82, 0x82, 0x8A, 0x8A, 0x86, 0x86, 0x8E, 0x8E,
\r
1595 0x90, 0x90, 0x98, 0x98, 0x94, 0x94, 0x9C, 0x9C,
\r
1596 0x92, 0x92, 0x9A, 0x9A, 0x96, 0x96, 0x9E, 0x9E,
\r
1597 0xA0, 0xA0, 0xA8, 0xA8, 0xA4, 0xA4, 0xAC, 0xAC,
\r
1598 0xA2, 0xA2, 0xAA, 0xAA, 0xA6, 0xA6, 0xAE, 0xAE,
\r
1599 0xB0, 0xB0, 0xB8, 0xB8, 0xB4, 0xB4, 0xBC, 0xBC,
\r
1600 0xB2, 0xB2, 0xBA, 0xBA, 0xB6, 0xB6, 0xBE, 0xBE,
\r
1601 0xC0, 0xC0, 0xC8, 0xC8, 0xC4, 0xC4, 0xCC, 0xCC,
\r
1602 0xC2, 0xC2, 0xCA, 0xCA, 0xC6, 0xC6, 0xCE, 0xCE,
\r
1603 0xD0, 0xD0, 0xD8, 0xD8, 0xD4, 0xD4, 0xDC, 0xDC,
\r
1604 0xD2, 0xD2, 0xDA, 0xDA, 0xD6, 0xD6, 0xDE, 0xDE,
\r
1605 0xE0, 0xE0, 0xE8, 0xE8, 0xE4, 0xE4, 0xEC, 0xEC,
\r
1606 0xE2, 0xE2, 0xEA, 0xEA, 0xE6, 0xE6, 0xEE, 0xEE,
\r
1607 0xF0, 0xF0, 0xF8, 0xF8, 0xF4, 0xF4, 0xFC, 0xFC,
\r
1608 0xF2, 0xF2, 0xFA, 0xFA, 0xF6, 0xF6, 0xFE, 0xFE
\r
1611 // Mapping tables for the PC-2 transformation.
\r
1612 static $pc2mapc1 = array(
\r
1613 0x00000000, 0x00000400, 0x00200000, 0x00200400,
\r
1614 0x00000001, 0x00000401, 0x00200001, 0x00200401,
\r
1615 0x02000000, 0x02000400, 0x02200000, 0x02200400,
\r
1616 0x02000001, 0x02000401, 0x02200001, 0x02200401
\r
1618 static $pc2mapc2 = array(
\r
1619 0x00000000, 0x00000800, 0x08000000, 0x08000800,
\r
1620 0x00010000, 0x00010800, 0x08010000, 0x08010800,
\r
1621 0x00000000, 0x00000800, 0x08000000, 0x08000800,
\r
1622 0x00010000, 0x00010800, 0x08010000, 0x08010800,
\r
1623 0x00000100, 0x00000900, 0x08000100, 0x08000900,
\r
1624 0x00010100, 0x00010900, 0x08010100, 0x08010900,
\r
1625 0x00000100, 0x00000900, 0x08000100, 0x08000900,
\r
1626 0x00010100, 0x00010900, 0x08010100, 0x08010900,
\r
1627 0x00000010, 0x00000810, 0x08000010, 0x08000810,
\r
1628 0x00010010, 0x00010810, 0x08010010, 0x08010810,
\r
1629 0x00000010, 0x00000810, 0x08000010, 0x08000810,
\r
1630 0x00010010, 0x00010810, 0x08010010, 0x08010810,
\r
1631 0x00000110, 0x00000910, 0x08000110, 0x08000910,
\r
1632 0x00010110, 0x00010910, 0x08010110, 0x08010910,
\r
1633 0x00000110, 0x00000910, 0x08000110, 0x08000910,
\r
1634 0x00010110, 0x00010910, 0x08010110, 0x08010910,
\r
1635 0x00040000, 0x00040800, 0x08040000, 0x08040800,
\r
1636 0x00050000, 0x00050800, 0x08050000, 0x08050800,
\r
1637 0x00040000, 0x00040800, 0x08040000, 0x08040800,
\r
1638 0x00050000, 0x00050800, 0x08050000, 0x08050800,
\r
1639 0x00040100, 0x00040900, 0x08040100, 0x08040900,
\r
1640 0x00050100, 0x00050900, 0x08050100, 0x08050900,
\r
1641 0x00040100, 0x00040900, 0x08040100, 0x08040900,
\r
1642 0x00050100, 0x00050900, 0x08050100, 0x08050900,
\r
1643 0x00040010, 0x00040810, 0x08040010, 0x08040810,
\r
1644 0x00050010, 0x00050810, 0x08050010, 0x08050810,
\r
1645 0x00040010, 0x00040810, 0x08040010, 0x08040810,
\r
1646 0x00050010, 0x00050810, 0x08050010, 0x08050810,
\r
1647 0x00040110, 0x00040910, 0x08040110, 0x08040910,
\r
1648 0x00050110, 0x00050910, 0x08050110, 0x08050910,
\r
1649 0x00040110, 0x00040910, 0x08040110, 0x08040910,
\r
1650 0x00050110, 0x00050910, 0x08050110, 0x08050910,
\r
1651 0x01000000, 0x01000800, 0x09000000, 0x09000800,
\r
1652 0x01010000, 0x01010800, 0x09010000, 0x09010800,
\r
1653 0x01000000, 0x01000800, 0x09000000, 0x09000800,
\r
1654 0x01010000, 0x01010800, 0x09010000, 0x09010800,
\r
1655 0x01000100, 0x01000900, 0x09000100, 0x09000900,
\r
1656 0x01010100, 0x01010900, 0x09010100, 0x09010900,
\r
1657 0x01000100, 0x01000900, 0x09000100, 0x09000900,
\r
1658 0x01010100, 0x01010900, 0x09010100, 0x09010900,
\r
1659 0x01000010, 0x01000810, 0x09000010, 0x09000810,
\r
1660 0x01010010, 0x01010810, 0x09010010, 0x09010810,
\r
1661 0x01000010, 0x01000810, 0x09000010, 0x09000810,
\r
1662 0x01010010, 0x01010810, 0x09010010, 0x09010810,
\r
1663 0x01000110, 0x01000910, 0x09000110, 0x09000910,
\r
1664 0x01010110, 0x01010910, 0x09010110, 0x09010910,
\r
1665 0x01000110, 0x01000910, 0x09000110, 0x09000910,
\r
1666 0x01010110, 0x01010910, 0x09010110, 0x09010910,
\r
1667 0x01040000, 0x01040800, 0x09040000, 0x09040800,
\r
1668 0x01050000, 0x01050800, 0x09050000, 0x09050800,
\r
1669 0x01040000, 0x01040800, 0x09040000, 0x09040800,
\r
1670 0x01050000, 0x01050800, 0x09050000, 0x09050800,
\r
1671 0x01040100, 0x01040900, 0x09040100, 0x09040900,
\r
1672 0x01050100, 0x01050900, 0x09050100, 0x09050900,
\r
1673 0x01040100, 0x01040900, 0x09040100, 0x09040900,
\r
1674 0x01050100, 0x01050900, 0x09050100, 0x09050900,
\r
1675 0x01040010, 0x01040810, 0x09040010, 0x09040810,
\r
1676 0x01050010, 0x01050810, 0x09050010, 0x09050810,
\r
1677 0x01040010, 0x01040810, 0x09040010, 0x09040810,
\r
1678 0x01050010, 0x01050810, 0x09050010, 0x09050810,
\r
1679 0x01040110, 0x01040910, 0x09040110, 0x09040910,
\r
1680 0x01050110, 0x01050910, 0x09050110, 0x09050910,
\r
1681 0x01040110, 0x01040910, 0x09040110, 0x09040910,
\r
1682 0x01050110, 0x01050910, 0x09050110, 0x09050910
\r
1684 static $pc2mapc3 = array(
\r
1685 0x00000000, 0x00000004, 0x00001000, 0x00001004,
\r
1686 0x00000000, 0x00000004, 0x00001000, 0x00001004,
\r
1687 0x10000000, 0x10000004, 0x10001000, 0x10001004,
\r
1688 0x10000000, 0x10000004, 0x10001000, 0x10001004,
\r
1689 0x00000020, 0x00000024, 0x00001020, 0x00001024,
\r
1690 0x00000020, 0x00000024, 0x00001020, 0x00001024,
\r
1691 0x10000020, 0x10000024, 0x10001020, 0x10001024,
\r
1692 0x10000020, 0x10000024, 0x10001020, 0x10001024,
\r
1693 0x00080000, 0x00080004, 0x00081000, 0x00081004,
\r
1694 0x00080000, 0x00080004, 0x00081000, 0x00081004,
\r
1695 0x10080000, 0x10080004, 0x10081000, 0x10081004,
\r
1696 0x10080000, 0x10080004, 0x10081000, 0x10081004,
\r
1697 0x00080020, 0x00080024, 0x00081020, 0x00081024,
\r
1698 0x00080020, 0x00080024, 0x00081020, 0x00081024,
\r
1699 0x10080020, 0x10080024, 0x10081020, 0x10081024,
\r
1700 0x10080020, 0x10080024, 0x10081020, 0x10081024,
\r
1701 0x20000000, 0x20000004, 0x20001000, 0x20001004,
\r
1702 0x20000000, 0x20000004, 0x20001000, 0x20001004,
\r
1703 0x30000000, 0x30000004, 0x30001000, 0x30001004,
\r
1704 0x30000000, 0x30000004, 0x30001000, 0x30001004,
\r
1705 0x20000020, 0x20000024, 0x20001020, 0x20001024,
\r
1706 0x20000020, 0x20000024, 0x20001020, 0x20001024,
\r
1707 0x30000020, 0x30000024, 0x30001020, 0x30001024,
\r
1708 0x30000020, 0x30000024, 0x30001020, 0x30001024,
\r
1709 0x20080000, 0x20080004, 0x20081000, 0x20081004,
\r
1710 0x20080000, 0x20080004, 0x20081000, 0x20081004,
\r
1711 0x30080000, 0x30080004, 0x30081000, 0x30081004,
\r
1712 0x30080000, 0x30080004, 0x30081000, 0x30081004,
\r
1713 0x20080020, 0x20080024, 0x20081020, 0x20081024,
\r
1714 0x20080020, 0x20080024, 0x20081020, 0x20081024,
\r
1715 0x30080020, 0x30080024, 0x30081020, 0x30081024,
\r
1716 0x30080020, 0x30080024, 0x30081020, 0x30081024,
\r
1717 0x00000002, 0x00000006, 0x00001002, 0x00001006,
\r
1718 0x00000002, 0x00000006, 0x00001002, 0x00001006,
\r
1719 0x10000002, 0x10000006, 0x10001002, 0x10001006,
\r
1720 0x10000002, 0x10000006, 0x10001002, 0x10001006,
\r
1721 0x00000022, 0x00000026, 0x00001022, 0x00001026,
\r
1722 0x00000022, 0x00000026, 0x00001022, 0x00001026,
\r
1723 0x10000022, 0x10000026, 0x10001022, 0x10001026,
\r
1724 0x10000022, 0x10000026, 0x10001022, 0x10001026,
\r
1725 0x00080002, 0x00080006, 0x00081002, 0x00081006,
\r
1726 0x00080002, 0x00080006, 0x00081002, 0x00081006,
\r
1727 0x10080002, 0x10080006, 0x10081002, 0x10081006,
\r
1728 0x10080002, 0x10080006, 0x10081002, 0x10081006,
\r
1729 0x00080022, 0x00080026, 0x00081022, 0x00081026,
\r
1730 0x00080022, 0x00080026, 0x00081022, 0x00081026,
\r
1731 0x10080022, 0x10080026, 0x10081022, 0x10081026,
\r
1732 0x10080022, 0x10080026, 0x10081022, 0x10081026,
\r
1733 0x20000002, 0x20000006, 0x20001002, 0x20001006,
\r
1734 0x20000002, 0x20000006, 0x20001002, 0x20001006,
\r
1735 0x30000002, 0x30000006, 0x30001002, 0x30001006,
\r
1736 0x30000002, 0x30000006, 0x30001002, 0x30001006,
\r
1737 0x20000022, 0x20000026, 0x20001022, 0x20001026,
\r
1738 0x20000022, 0x20000026, 0x20001022, 0x20001026,
\r
1739 0x30000022, 0x30000026, 0x30001022, 0x30001026,
\r
1740 0x30000022, 0x30000026, 0x30001022, 0x30001026,
\r
1741 0x20080002, 0x20080006, 0x20081002, 0x20081006,
\r
1742 0x20080002, 0x20080006, 0x20081002, 0x20081006,
\r
1743 0x30080002, 0x30080006, 0x30081002, 0x30081006,
\r
1744 0x30080002, 0x30080006, 0x30081002, 0x30081006,
\r
1745 0x20080022, 0x20080026, 0x20081022, 0x20081026,
\r
1746 0x20080022, 0x20080026, 0x20081022, 0x20081026,
\r
1747 0x30080022, 0x30080026, 0x30081022, 0x30081026,
\r
1748 0x30080022, 0x30080026, 0x30081022, 0x30081026
\r
1750 static $pc2mapc4 = array(
\r
1751 0x00000000, 0x00100000, 0x00000008, 0x00100008,
\r
1752 0x00000200, 0x00100200, 0x00000208, 0x00100208,
\r
1753 0x00000000, 0x00100000, 0x00000008, 0x00100008,
\r
1754 0x00000200, 0x00100200, 0x00000208, 0x00100208,
\r
1755 0x04000000, 0x04100000, 0x04000008, 0x04100008,
\r
1756 0x04000200, 0x04100200, 0x04000208, 0x04100208,
\r
1757 0x04000000, 0x04100000, 0x04000008, 0x04100008,
\r
1758 0x04000200, 0x04100200, 0x04000208, 0x04100208,
\r
1759 0x00002000, 0x00102000, 0x00002008, 0x00102008,
\r
1760 0x00002200, 0x00102200, 0x00002208, 0x00102208,
\r
1761 0x00002000, 0x00102000, 0x00002008, 0x00102008,
\r
1762 0x00002200, 0x00102200, 0x00002208, 0x00102208,
\r
1763 0x04002000, 0x04102000, 0x04002008, 0x04102008,
\r
1764 0x04002200, 0x04102200, 0x04002208, 0x04102208,
\r
1765 0x04002000, 0x04102000, 0x04002008, 0x04102008,
\r
1766 0x04002200, 0x04102200, 0x04002208, 0x04102208,
\r
1767 0x00000000, 0x00100000, 0x00000008, 0x00100008,
\r
1768 0x00000200, 0x00100200, 0x00000208, 0x00100208,
\r
1769 0x00000000, 0x00100000, 0x00000008, 0x00100008,
\r
1770 0x00000200, 0x00100200, 0x00000208, 0x00100208,
\r
1771 0x04000000, 0x04100000, 0x04000008, 0x04100008,
\r
1772 0x04000200, 0x04100200, 0x04000208, 0x04100208,
\r
1773 0x04000000, 0x04100000, 0x04000008, 0x04100008,
\r
1774 0x04000200, 0x04100200, 0x04000208, 0x04100208,
\r
1775 0x00002000, 0x00102000, 0x00002008, 0x00102008,
\r
1776 0x00002200, 0x00102200, 0x00002208, 0x00102208,
\r
1777 0x00002000, 0x00102000, 0x00002008, 0x00102008,
\r
1778 0x00002200, 0x00102200, 0x00002208, 0x00102208,
\r
1779 0x04002000, 0x04102000, 0x04002008, 0x04102008,
\r
1780 0x04002200, 0x04102200, 0x04002208, 0x04102208,
\r
1781 0x04002000, 0x04102000, 0x04002008, 0x04102008,
\r
1782 0x04002200, 0x04102200, 0x04002208, 0x04102208,
\r
1783 0x00020000, 0x00120000, 0x00020008, 0x00120008,
\r
1784 0x00020200, 0x00120200, 0x00020208, 0x00120208,
\r
1785 0x00020000, 0x00120000, 0x00020008, 0x00120008,
\r
1786 0x00020200, 0x00120200, 0x00020208, 0x00120208,
\r
1787 0x04020000, 0x04120000, 0x04020008, 0x04120008,
\r
1788 0x04020200, 0x04120200, 0x04020208, 0x04120208,
\r
1789 0x04020000, 0x04120000, 0x04020008, 0x04120008,
\r
1790 0x04020200, 0x04120200, 0x04020208, 0x04120208,
\r
1791 0x00022000, 0x00122000, 0x00022008, 0x00122008,
\r
1792 0x00022200, 0x00122200, 0x00022208, 0x00122208,
\r
1793 0x00022000, 0x00122000, 0x00022008, 0x00122008,
\r
1794 0x00022200, 0x00122200, 0x00022208, 0x00122208,
\r
1795 0x04022000, 0x04122000, 0x04022008, 0x04122008,
\r
1796 0x04022200, 0x04122200, 0x04022208, 0x04122208,
\r
1797 0x04022000, 0x04122000, 0x04022008, 0x04122008,
\r
1798 0x04022200, 0x04122200, 0x04022208, 0x04122208,
\r
1799 0x00020000, 0x00120000, 0x00020008, 0x00120008,
\r
1800 0x00020200, 0x00120200, 0x00020208, 0x00120208,
\r
1801 0x00020000, 0x00120000, 0x00020008, 0x00120008,
\r
1802 0x00020200, 0x00120200, 0x00020208, 0x00120208,
\r
1803 0x04020000, 0x04120000, 0x04020008, 0x04120008,
\r
1804 0x04020200, 0x04120200, 0x04020208, 0x04120208,
\r
1805 0x04020000, 0x04120000, 0x04020008, 0x04120008,
\r
1806 0x04020200, 0x04120200, 0x04020208, 0x04120208,
\r
1807 0x00022000, 0x00122000, 0x00022008, 0x00122008,
\r
1808 0x00022200, 0x00122200, 0x00022208, 0x00122208,
\r
1809 0x00022000, 0x00122000, 0x00022008, 0x00122008,
\r
1810 0x00022200, 0x00122200, 0x00022208, 0x00122208,
\r
1811 0x04022000, 0x04122000, 0x04022008, 0x04122008,
\r
1812 0x04022200, 0x04122200, 0x04022208, 0x04122208,
\r
1813 0x04022000, 0x04122000, 0x04022008, 0x04122008,
\r
1814 0x04022200, 0x04122200, 0x04022208, 0x04122208
\r
1816 static $pc2mapd1 = array(
\r
1817 0x00000000, 0x00000001, 0x08000000, 0x08000001,
\r
1818 0x00200000, 0x00200001, 0x08200000, 0x08200001,
\r
1819 0x00000002, 0x00000003, 0x08000002, 0x08000003,
\r
1820 0x00200002, 0x00200003, 0x08200002, 0x08200003
\r
1822 static $pc2mapd2 = array(
\r
1823 0x00000000, 0x00100000, 0x00000800, 0x00100800,
\r
1824 0x00000000, 0x00100000, 0x00000800, 0x00100800,
\r
1825 0x04000000, 0x04100000, 0x04000800, 0x04100800,
\r
1826 0x04000000, 0x04100000, 0x04000800, 0x04100800,
\r
1827 0x00000004, 0x00100004, 0x00000804, 0x00100804,
\r
1828 0x00000004, 0x00100004, 0x00000804, 0x00100804,
\r
1829 0x04000004, 0x04100004, 0x04000804, 0x04100804,
\r
1830 0x04000004, 0x04100004, 0x04000804, 0x04100804,
\r
1831 0x00000000, 0x00100000, 0x00000800, 0x00100800,
\r
1832 0x00000000, 0x00100000, 0x00000800, 0x00100800,
\r
1833 0x04000000, 0x04100000, 0x04000800, 0x04100800,
\r
1834 0x04000000, 0x04100000, 0x04000800, 0x04100800,
\r
1835 0x00000004, 0x00100004, 0x00000804, 0x00100804,
\r
1836 0x00000004, 0x00100004, 0x00000804, 0x00100804,
\r
1837 0x04000004, 0x04100004, 0x04000804, 0x04100804,
\r
1838 0x04000004, 0x04100004, 0x04000804, 0x04100804,
\r
1839 0x00000200, 0x00100200, 0x00000A00, 0x00100A00,
\r
1840 0x00000200, 0x00100200, 0x00000A00, 0x00100A00,
\r
1841 0x04000200, 0x04100200, 0x04000A00, 0x04100A00,
\r
1842 0x04000200, 0x04100200, 0x04000A00, 0x04100A00,
\r
1843 0x00000204, 0x00100204, 0x00000A04, 0x00100A04,
\r
1844 0x00000204, 0x00100204, 0x00000A04, 0x00100A04,
\r
1845 0x04000204, 0x04100204, 0x04000A04, 0x04100A04,
\r
1846 0x04000204, 0x04100204, 0x04000A04, 0x04100A04,
\r
1847 0x00000200, 0x00100200, 0x00000A00, 0x00100A00,
\r
1848 0x00000200, 0x00100200, 0x00000A00, 0x00100A00,
\r
1849 0x04000200, 0x04100200, 0x04000A00, 0x04100A00,
\r
1850 0x04000200, 0x04100200, 0x04000A00, 0x04100A00,
\r
1851 0x00000204, 0x00100204, 0x00000A04, 0x00100A04,
\r
1852 0x00000204, 0x00100204, 0x00000A04, 0x00100A04,
\r
1853 0x04000204, 0x04100204, 0x04000A04, 0x04100A04,
\r
1854 0x04000204, 0x04100204, 0x04000A04, 0x04100A04,
\r
1855 0x00020000, 0x00120000, 0x00020800, 0x00120800,
\r
1856 0x00020000, 0x00120000, 0x00020800, 0x00120800,
\r
1857 0x04020000, 0x04120000, 0x04020800, 0x04120800,
\r
1858 0x04020000, 0x04120000, 0x04020800, 0x04120800,
\r
1859 0x00020004, 0x00120004, 0x00020804, 0x00120804,
\r
1860 0x00020004, 0x00120004, 0x00020804, 0x00120804,
\r
1861 0x04020004, 0x04120004, 0x04020804, 0x04120804,
\r
1862 0x04020004, 0x04120004, 0x04020804, 0x04120804,
\r
1863 0x00020000, 0x00120000, 0x00020800, 0x00120800,
\r
1864 0x00020000, 0x00120000, 0x00020800, 0x00120800,
\r
1865 0x04020000, 0x04120000, 0x04020800, 0x04120800,
\r
1866 0x04020000, 0x04120000, 0x04020800, 0x04120800,
\r
1867 0x00020004, 0x00120004, 0x00020804, 0x00120804,
\r
1868 0x00020004, 0x00120004, 0x00020804, 0x00120804,
\r
1869 0x04020004, 0x04120004, 0x04020804, 0x04120804,
\r
1870 0x04020004, 0x04120004, 0x04020804, 0x04120804,
\r
1871 0x00020200, 0x00120200, 0x00020A00, 0x00120A00,
\r
1872 0x00020200, 0x00120200, 0x00020A00, 0x00120A00,
\r
1873 0x04020200, 0x04120200, 0x04020A00, 0x04120A00,
\r
1874 0x04020200, 0x04120200, 0x04020A00, 0x04120A00,
\r
1875 0x00020204, 0x00120204, 0x00020A04, 0x00120A04,
\r
1876 0x00020204, 0x00120204, 0x00020A04, 0x00120A04,
\r
1877 0x04020204, 0x04120204, 0x04020A04, 0x04120A04,
\r
1878 0x04020204, 0x04120204, 0x04020A04, 0x04120A04,
\r
1879 0x00020200, 0x00120200, 0x00020A00, 0x00120A00,
\r
1880 0x00020200, 0x00120200, 0x00020A00, 0x00120A00,
\r
1881 0x04020200, 0x04120200, 0x04020A00, 0x04120A00,
\r
1882 0x04020200, 0x04120200, 0x04020A00, 0x04120A00,
\r
1883 0x00020204, 0x00120204, 0x00020A04, 0x00120A04,
\r
1884 0x00020204, 0x00120204, 0x00020A04, 0x00120A04,
\r
1885 0x04020204, 0x04120204, 0x04020A04, 0x04120A04,
\r
1886 0x04020204, 0x04120204, 0x04020A04, 0x04120A04
\r
1888 static $pc2mapd3 = array(
\r
1889 0x00000000, 0x00010000, 0x02000000, 0x02010000,
\r
1890 0x00000020, 0x00010020, 0x02000020, 0x02010020,
\r
1891 0x00040000, 0x00050000, 0x02040000, 0x02050000,
\r
1892 0x00040020, 0x00050020, 0x02040020, 0x02050020,
\r
1893 0x00002000, 0x00012000, 0x02002000, 0x02012000,
\r
1894 0x00002020, 0x00012020, 0x02002020, 0x02012020,
\r
1895 0x00042000, 0x00052000, 0x02042000, 0x02052000,
\r
1896 0x00042020, 0x00052020, 0x02042020, 0x02052020,
\r
1897 0x00000000, 0x00010000, 0x02000000, 0x02010000,
\r
1898 0x00000020, 0x00010020, 0x02000020, 0x02010020,
\r
1899 0x00040000, 0x00050000, 0x02040000, 0x02050000,
\r
1900 0x00040020, 0x00050020, 0x02040020, 0x02050020,
\r
1901 0x00002000, 0x00012000, 0x02002000, 0x02012000,
\r
1902 0x00002020, 0x00012020, 0x02002020, 0x02012020,
\r
1903 0x00042000, 0x00052000, 0x02042000, 0x02052000,
\r
1904 0x00042020, 0x00052020, 0x02042020, 0x02052020,
\r
1905 0x00000010, 0x00010010, 0x02000010, 0x02010010,
\r
1906 0x00000030, 0x00010030, 0x02000030, 0x02010030,
\r
1907 0x00040010, 0x00050010, 0x02040010, 0x02050010,
\r
1908 0x00040030, 0x00050030, 0x02040030, 0x02050030,
\r
1909 0x00002010, 0x00012010, 0x02002010, 0x02012010,
\r
1910 0x00002030, 0x00012030, 0x02002030, 0x02012030,
\r
1911 0x00042010, 0x00052010, 0x02042010, 0x02052010,
\r
1912 0x00042030, 0x00052030, 0x02042030, 0x02052030,
\r
1913 0x00000010, 0x00010010, 0x02000010, 0x02010010,
\r
1914 0x00000030, 0x00010030, 0x02000030, 0x02010030,
\r
1915 0x00040010, 0x00050010, 0x02040010, 0x02050010,
\r
1916 0x00040030, 0x00050030, 0x02040030, 0x02050030,
\r
1917 0x00002010, 0x00012010, 0x02002010, 0x02012010,
\r
1918 0x00002030, 0x00012030, 0x02002030, 0x02012030,
\r
1919 0x00042010, 0x00052010, 0x02042010, 0x02052010,
\r
1920 0x00042030, 0x00052030, 0x02042030, 0x02052030,
\r
1921 0x20000000, 0x20010000, 0x22000000, 0x22010000,
\r
1922 0x20000020, 0x20010020, 0x22000020, 0x22010020,
\r
1923 0x20040000, 0x20050000, 0x22040000, 0x22050000,
\r
1924 0x20040020, 0x20050020, 0x22040020, 0x22050020,
\r
1925 0x20002000, 0x20012000, 0x22002000, 0x22012000,
\r
1926 0x20002020, 0x20012020, 0x22002020, 0x22012020,
\r
1927 0x20042000, 0x20052000, 0x22042000, 0x22052000,
\r
1928 0x20042020, 0x20052020, 0x22042020, 0x22052020,
\r
1929 0x20000000, 0x20010000, 0x22000000, 0x22010000,
\r
1930 0x20000020, 0x20010020, 0x22000020, 0x22010020,
\r
1931 0x20040000, 0x20050000, 0x22040000, 0x22050000,
\r
1932 0x20040020, 0x20050020, 0x22040020, 0x22050020,
\r
1933 0x20002000, 0x20012000, 0x22002000, 0x22012000,
\r
1934 0x20002020, 0x20012020, 0x22002020, 0x22012020,
\r
1935 0x20042000, 0x20052000, 0x22042000, 0x22052000,
\r
1936 0x20042020, 0x20052020, 0x22042020, 0x22052020,
\r
1937 0x20000010, 0x20010010, 0x22000010, 0x22010010,
\r
1938 0x20000030, 0x20010030, 0x22000030, 0x22010030,
\r
1939 0x20040010, 0x20050010, 0x22040010, 0x22050010,
\r
1940 0x20040030, 0x20050030, 0x22040030, 0x22050030,
\r
1941 0x20002010, 0x20012010, 0x22002010, 0x22012010,
\r
1942 0x20002030, 0x20012030, 0x22002030, 0x22012030,
\r
1943 0x20042010, 0x20052010, 0x22042010, 0x22052010,
\r
1944 0x20042030, 0x20052030, 0x22042030, 0x22052030,
\r
1945 0x20000010, 0x20010010, 0x22000010, 0x22010010,
\r
1946 0x20000030, 0x20010030, 0x22000030, 0x22010030,
\r
1947 0x20040010, 0x20050010, 0x22040010, 0x22050010,
\r
1948 0x20040030, 0x20050030, 0x22040030, 0x22050030,
\r
1949 0x20002010, 0x20012010, 0x22002010, 0x22012010,
\r
1950 0x20002030, 0x20012030, 0x22002030, 0x22012030,
\r
1951 0x20042010, 0x20052010, 0x22042010, 0x22052010,
\r
1952 0x20042030, 0x20052030, 0x22042030, 0x22052030
\r
1954 static $pc2mapd4 = array(
\r
1955 0x00000000, 0x00000400, 0x01000000, 0x01000400,
\r
1956 0x00000000, 0x00000400, 0x01000000, 0x01000400,
\r
1957 0x00000100, 0x00000500, 0x01000100, 0x01000500,
\r
1958 0x00000100, 0x00000500, 0x01000100, 0x01000500,
\r
1959 0x10000000, 0x10000400, 0x11000000, 0x11000400,
\r
1960 0x10000000, 0x10000400, 0x11000000, 0x11000400,
\r
1961 0x10000100, 0x10000500, 0x11000100, 0x11000500,
\r
1962 0x10000100, 0x10000500, 0x11000100, 0x11000500,
\r
1963 0x00080000, 0x00080400, 0x01080000, 0x01080400,
\r
1964 0x00080000, 0x00080400, 0x01080000, 0x01080400,
\r
1965 0x00080100, 0x00080500, 0x01080100, 0x01080500,
\r
1966 0x00080100, 0x00080500, 0x01080100, 0x01080500,
\r
1967 0x10080000, 0x10080400, 0x11080000, 0x11080400,
\r
1968 0x10080000, 0x10080400, 0x11080000, 0x11080400,
\r
1969 0x10080100, 0x10080500, 0x11080100, 0x11080500,
\r
1970 0x10080100, 0x10080500, 0x11080100, 0x11080500,
\r
1971 0x00000008, 0x00000408, 0x01000008, 0x01000408,
\r
1972 0x00000008, 0x00000408, 0x01000008, 0x01000408,
\r
1973 0x00000108, 0x00000508, 0x01000108, 0x01000508,
\r
1974 0x00000108, 0x00000508, 0x01000108, 0x01000508,
\r
1975 0x10000008, 0x10000408, 0x11000008, 0x11000408,
\r
1976 0x10000008, 0x10000408, 0x11000008, 0x11000408,
\r
1977 0x10000108, 0x10000508, 0x11000108, 0x11000508,
\r
1978 0x10000108, 0x10000508, 0x11000108, 0x11000508,
\r
1979 0x00080008, 0x00080408, 0x01080008, 0x01080408,
\r
1980 0x00080008, 0x00080408, 0x01080008, 0x01080408,
\r
1981 0x00080108, 0x00080508, 0x01080108, 0x01080508,
\r
1982 0x00080108, 0x00080508, 0x01080108, 0x01080508,
\r
1983 0x10080008, 0x10080408, 0x11080008, 0x11080408,
\r
1984 0x10080008, 0x10080408, 0x11080008, 0x11080408,
\r
1985 0x10080108, 0x10080508, 0x11080108, 0x11080508,
\r
1986 0x10080108, 0x10080508, 0x11080108, 0x11080508,
\r
1987 0x00001000, 0x00001400, 0x01001000, 0x01001400,
\r
1988 0x00001000, 0x00001400, 0x01001000, 0x01001400,
\r
1989 0x00001100, 0x00001500, 0x01001100, 0x01001500,
\r
1990 0x00001100, 0x00001500, 0x01001100, 0x01001500,
\r
1991 0x10001000, 0x10001400, 0x11001000, 0x11001400,
\r
1992 0x10001000, 0x10001400, 0x11001000, 0x11001400,
\r
1993 0x10001100, 0x10001500, 0x11001100, 0x11001500,
\r
1994 0x10001100, 0x10001500, 0x11001100, 0x11001500,
\r
1995 0x00081000, 0x00081400, 0x01081000, 0x01081400,
\r
1996 0x00081000, 0x00081400, 0x01081000, 0x01081400,
\r
1997 0x00081100, 0x00081500, 0x01081100, 0x01081500,
\r
1998 0x00081100, 0x00081500, 0x01081100, 0x01081500,
\r
1999 0x10081000, 0x10081400, 0x11081000, 0x11081400,
\r
2000 0x10081000, 0x10081400, 0x11081000, 0x11081400,
\r
2001 0x10081100, 0x10081500, 0x11081100, 0x11081500,
\r
2002 0x10081100, 0x10081500, 0x11081100, 0x11081500,
\r
2003 0x00001008, 0x00001408, 0x01001008, 0x01001408,
\r
2004 0x00001008, 0x00001408, 0x01001008, 0x01001408,
\r
2005 0x00001108, 0x00001508, 0x01001108, 0x01001508,
\r
2006 0x00001108, 0x00001508, 0x01001108, 0x01001508,
\r
2007 0x10001008, 0x10001408, 0x11001008, 0x11001408,
\r
2008 0x10001008, 0x10001408, 0x11001008, 0x11001408,
\r
2009 0x10001108, 0x10001508, 0x11001108, 0x11001508,
\r
2010 0x10001108, 0x10001508, 0x11001108, 0x11001508,
\r
2011 0x00081008, 0x00081408, 0x01081008, 0x01081408,
\r
2012 0x00081008, 0x00081408, 0x01081008, 0x01081408,
\r
2013 0x00081108, 0x00081508, 0x01081108, 0x01081508,
\r
2014 0x00081108, 0x00081508, 0x01081108, 0x01081508,
\r
2015 0x10081008, 0x10081408, 0x11081008, 0x11081408,
\r
2016 0x10081008, 0x10081408, 0x11081008, 0x11081408,
\r
2017 0x10081108, 0x10081508, 0x11081108, 0x11081508,
\r
2018 0x10081108, 0x10081508, 0x11081108, 0x11081508
\r
2021 // pad the key and remove extra characters as appropriate.
\r
2022 $key = str_pad(substr($key, 0, 8), 8, chr(0));
\r
2024 // Perform the PC/1 transformation and compute C and D.
\r
2025 $t = unpack('Nl/Nr', $key);
\r
2026 list($l, $r) = array($t['l'], $t['r']);
\r
2027 $key = ($this->shuffle[$pc1map[$r & 0xFF]] & "\x80\x80\x80\x80\x80\x80\x80\x00") |
\r
2028 ($this->shuffle[$pc1map[($r >> 8) & 0xFF]] & "\x40\x40\x40\x40\x40\x40\x40\x00") |
\r
2029 ($this->shuffle[$pc1map[($r >> 16) & 0xFF]] & "\x20\x20\x20\x20\x20\x20\x20\x00") |
\r
2030 ($this->shuffle[$pc1map[($r >> 24) & 0xFF]] & "\x10\x10\x10\x10\x10\x10\x10\x00") |
\r
2031 ($this->shuffle[$pc1map[$l & 0xFF]] & "\x08\x08\x08\x08\x08\x08\x08\x00") |
\r
2032 ($this->shuffle[$pc1map[($l >> 8) & 0xFF]] & "\x04\x04\x04\x04\x04\x04\x04\x00") |
\r
2033 ($this->shuffle[$pc1map[($l >> 16) & 0xFF]] & "\x02\x02\x02\x02\x02\x02\x02\x00") |
\r
2034 ($this->shuffle[$pc1map[($l >> 24) & 0xFF]] & "\x01\x01\x01\x01\x01\x01\x01\x00");
\r
2035 $key = unpack('Nc/Nd', $key);
\r
2036 $c = ($key['c'] >> 4) & 0x0FFFFFFF;
\r
2037 $d = (($key['d'] >> 4) & 0x0FFFFFF0) | ($key['c'] & 0x0F);
\r
2040 for ($i = 0; $i < 16; $i++) {
\r
2041 $c <<= $shifts[$i];
\r
2042 $c = ($c | ($c >> 28)) & 0x0FFFFFFF;
\r
2043 $d <<= $shifts[$i];
\r
2044 $d = ($d | ($d >> 28)) & 0x0FFFFFFF;
\r
2046 // Perform the PC-2 transformation.
\r
2047 $cp = $pc2mapc1[$c >> 24] | $pc2mapc2[($c >> 16) & 0xFF] |
\r
2048 $pc2mapc3[($c >> 8) & 0xFF] | $pc2mapc4[$c & 0xFF];
\r
2049 $dp = $pc2mapd1[$d >> 24] | $pc2mapd2[($d >> 16) & 0xFF] |
\r
2050 $pc2mapd3[($d >> 8) & 0xFF] | $pc2mapd4[$d & 0xFF];
\r
2052 // Reorder: odd bytes/even bytes. Push the result in key schedule.
\r
2054 ($cp & 0xFF000000) | (($cp << 8) & 0x00FF0000) |
\r
2055 (($dp >> 16) & 0x0000FF00) | (($dp >> 8) & 0x000000FF),
\r
2056 (($cp << 8) & 0xFF000000) | (($cp << 16) & 0x00FF0000) |
\r
2057 (($dp >> 8) & 0x0000FF00) | ($dp & 0x000000FF)
\r
2062 CRYPT_DES_ENCRYPT => $keys,
\r
2063 CRYPT_DES_DECRYPT => array_reverse($keys),
\r
2064 CRYPT_DES_ENCRYPT_1DIM => array(),
\r
2065 CRYPT_DES_DECRYPT_1DIM => array()
\r
2068 // Generate 1-dim arrays for inline en/decrypting
\r
2069 for ($i = 0; $i < 16; ++$i) {
\r
2070 $keys[CRYPT_DES_ENCRYPT_1DIM][] = $keys[CRYPT_DES_ENCRYPT][$i][0];
\r
2071 $keys[CRYPT_DES_ENCRYPT_1DIM][] = $keys[CRYPT_DES_ENCRYPT][$i][1];
\r
2072 $keys[CRYPT_DES_DECRYPT_1DIM][] = $keys[CRYPT_DES_DECRYPT][$i][0];
\r
2073 $keys[CRYPT_DES_DECRYPT_1DIM][] = $keys[CRYPT_DES_DECRYPT][$i][1];
\r
2082 * Inspired by array_shift
\r
2084 * @param String $string
\r
2088 function _string_shift(&$string)
\r
2090 $substr = substr($string, 0, 8);
\r
2091 $string = substr($string, 8);
\r
2096 * Creates performance-optimized function for de/encrypt(), storing it in $this->inline_crypt
\r
2098 * @param optional Integer $des_rounds (1 = DES[default], 3 = TribleDES)
\r
2101 function inline_crypt_setup($des_rounds = 1)
\r
2103 $lambda_functions =& Crypt_DES::get_lambda_functions();
\r
2105 $mode = $this->mode;
\r
2107 $code_hash = "$mode,$des_rounds";
\r
2109 if (!isset($lambda_functions[$code_hash])) {
\r
2110 // Generating encrypt code:
\r
2112 $init_cryptBlock = '
\r
2113 $shuffle = $self->shuffle;
\r
2114 $invipmap = $self->invipmap;
\r
2115 $ipmap = $self->ipmap;
\r
2116 $sbox1 = $self->sbox1;
\r
2117 $sbox2 = $self->sbox2;
\r
2118 $sbox3 = $self->sbox3;
\r
2119 $sbox4 = $self->sbox4;
\r
2120 $sbox5 = $self->sbox5;
\r
2121 $sbox6 = $self->sbox6;
\r
2122 $sbox7 = $self->sbox7;
\r
2123 $sbox8 = $self->sbox8;
\r
2126 $_cryptBlock = '$in = unpack("N*", $in);'."\n";
\r
2127 // Do the initial IP permutation.
\r
2131 $in = unpack("N*",
\r
2132 ($shuffle[$ipmap[ $r & 0xFF]] & "\x80\x80\x80\x80\x80\x80\x80\x80") |
\r
2133 ($shuffle[$ipmap[($r >> 8) & 0xFF]] & "\x40\x40\x40\x40\x40\x40\x40\x40") |
\r
2134 ($shuffle[$ipmap[($r >> 16) & 0xFF]] & "\x20\x20\x20\x20\x20\x20\x20\x20") |
\r
2135 ($shuffle[$ipmap[($r >> 24) & 0xFF]] & "\x10\x10\x10\x10\x10\x10\x10\x10") |
\r
2136 ($shuffle[$ipmap[ $l & 0xFF]] & "\x08\x08\x08\x08\x08\x08\x08\x08") |
\r
2137 ($shuffle[$ipmap[($l >> 8) & 0xFF]] & "\x04\x04\x04\x04\x04\x04\x04\x04") |
\r
2138 ($shuffle[$ipmap[($l >> 16) & 0xFF]] & "\x02\x02\x02\x02\x02\x02\x02\x02") |
\r
2139 ($shuffle[$ipmap[($l >> 24) & 0xFF]] & "\x01\x01\x01\x01\x01\x01\x01\x01")
\r
2142 '.'' /* Extract L0 and R0 */ .'
\r
2149 for ($des_round = 0; $des_round < $des_rounds; ++$des_round) {
\r
2150 // Perform the 16 steps.
\r
2151 // start of "the Feistel (F) function" - see the following URL:
\r
2152 // http://en.wikipedia.org/wiki/Image:Data_Encryption_Standard_InfoBox_Diagram.png
\r
2153 // Merge key schedule.
\r
2154 for ($i = 0; $i < 8; ++$i) {
\r
2156 $b1 = (($' . $r . ' >> 3) & 0x1FFFFFFF) ^ ($' . $r . ' << 29) ^ $k_'.(++$ki).';
\r
2157 $b2 = (($' . $r . ' >> 31) & 0x00000001) ^ ($' . $r . ' << 1) ^ $k_'.(++$ki).';
\r
2158 $' . $l . ' = $sbox1[($b1 >> 24) & 0x3F] ^ $sbox2[($b2 >> 24) & 0x3F] ^
\r
2159 $sbox3[($b1 >> 16) & 0x3F] ^ $sbox4[($b2 >> 16) & 0x3F] ^
\r
2160 $sbox5[($b1 >> 8) & 0x3F] ^ $sbox6[($b2 >> 8) & 0x3F] ^
\r
2161 $sbox7[ $b1 & 0x3F] ^ $sbox8[ $b2 & 0x3F] ^ $' . $l . ';
\r
2163 $b1 = (($' . $l . ' >> 3) & 0x1FFFFFFF) ^ ($' . $l . ' << 29) ^ $k_'.(++$ki).';
\r
2164 $b2 = (($' . $l . ' >> 31) & 0x00000001) ^ ($' . $l . ' << 1) ^ $k_'.(++$ki).';
\r
2165 $' . $r . ' = $sbox1[($b1 >> 24) & 0x3F] ^ $sbox2[($b2 >> 24) & 0x3F] ^
\r
2166 $sbox3[($b1 >> 16) & 0x3F] ^ $sbox4[($b2 >> 16) & 0x3F] ^
\r
2167 $sbox5[($b1 >> 8) & 0x3F] ^ $sbox6[($b2 >> 8) & 0x3F] ^
\r
2168 $sbox7[ $b1 & 0x3F] ^ $sbox8[ $b2 & 0x3F] ^ $' . $r . ';
\r
2172 // Last step should not permute L & R.
\r
2178 // Perform the inverse IP permutation.
\r
2179 $_cryptBlock .= '$in = (
\r
2180 ($shuffle[$invipmap[($' . $r . ' >> 24) & 0xFF]] & "\x80\x80\x80\x80\x80\x80\x80\x80") |
\r
2181 ($shuffle[$invipmap[($' . $l . ' >> 24) & 0xFF]] & "\x40\x40\x40\x40\x40\x40\x40\x40") |
\r
2182 ($shuffle[$invipmap[($' . $r . ' >> 16) & 0xFF]] & "\x20\x20\x20\x20\x20\x20\x20\x20") |
\r
2183 ($shuffle[$invipmap[($' . $l . ' >> 16) & 0xFF]] & "\x10\x10\x10\x10\x10\x10\x10\x10") |
\r
2184 ($shuffle[$invipmap[($' . $r . ' >> 8) & 0xFF]] & "\x08\x08\x08\x08\x08\x08\x08\x08") |
\r
2185 ($shuffle[$invipmap[($' . $l . ' >> 8) & 0xFF]] & "\x04\x04\x04\x04\x04\x04\x04\x04") |
\r
2186 ($shuffle[$invipmap[ $' . $r . ' & 0xFF]] & "\x02\x02\x02\x02\x02\x02\x02\x02") |
\r
2187 ($shuffle[$invipmap[ $' . $l . ' & 0xFF]] & "\x01\x01\x01\x01\x01\x01\x01\x01")
\r
2191 // Generating mode of operation code:
\r
2193 case CRYPT_DES_MODE_ECB:
\r
2194 $encrypt = $init_cryptBlock . '
\r
2195 extract($self->keys[CRYPT_DES_ENCRYPT_1DIM], EXTR_PREFIX_ALL, "k");
\r
2197 $plaintext_len = strlen($text);
\r
2199 for ($i = 0; $i < $plaintext_len; $i+= '.$block_size.') {
\r
2200 $in = substr($text, $i, '.$block_size.');
\r
2202 $ciphertext.= $in;
\r
2205 return $ciphertext;
\r
2208 $decrypt = $init_cryptBlock . '
\r
2209 extract($self->keys[CRYPT_DES_DECRYPT_1DIM], EXTR_PREFIX_ALL, "k");
\r
2211 $ciphertext_len = strlen($text);
\r
2213 for ($i = 0; $i < $ciphertext_len; $i+= '.$block_size.') {
\r
2214 $in = substr($text, $i, '.$block_size.');
\r
2219 return $self->_unpad($plaintext);
\r
2222 case CRYPT_DES_MODE_CBC:
\r
2223 $encrypt = $init_cryptBlock . '
\r
2224 extract($self->keys[CRYPT_DES_ENCRYPT_1DIM], EXTR_PREFIX_ALL, "k");
\r
2226 $plaintext_len = strlen($text);
\r
2228 $in = $self->encryptIV;
\r
2230 for ($i = 0; $i < $plaintext_len; $i+= '.$block_size.') {
\r
2231 $in = substr($text, $i, '.$block_size.') ^ $in;
\r
2233 $ciphertext.= $in;
\r
2236 if ($self->continuousBuffer) {
\r
2237 $self->encryptIV = $in;
\r
2240 return $ciphertext;
\r
2243 $decrypt = $init_cryptBlock . '
\r
2244 extract($self->keys[CRYPT_DES_DECRYPT_1DIM], EXTR_PREFIX_ALL, "k");
\r
2246 $ciphertext_len = strlen($text);
\r
2248 $iv = $self->decryptIV;
\r
2250 for ($i = 0; $i < $ciphertext_len; $i+= '.$block_size.') {
\r
2251 $in = $block = substr($text, $i, '.$block_size.');
\r
2253 $plaintext.= $in ^ $iv;
\r
2257 if ($self->continuousBuffer) {
\r
2258 $self->decryptIV = $iv;
\r
2261 return $self->_unpad($plaintext);
\r
2264 case CRYPT_DES_MODE_CTR:
\r
2265 $encrypt = $init_cryptBlock . '
\r
2266 extract($self->keys[CRYPT_DES_ENCRYPT_1DIM], EXTR_PREFIX_ALL, "k");
\r
2268 $plaintext_len = strlen($text);
\r
2269 $xor = $self->encryptIV;
\r
2270 $buffer = &$self->enbuffer;
\r
2272 if (strlen($buffer["encrypted"])) {
\r
2273 for ($i = 0; $i < $plaintext_len; $i+= '.$block_size.') {
\r
2274 $block = substr($text, $i, '.$block_size.');
\r
2275 if (strlen($block) > strlen($buffer["encrypted"])) {
\r
2276 $in = $self->_generate_xor($xor);
\r
2278 $buffer["encrypted"].= $in;
\r
2280 $key = $self->_string_shift($buffer["encrypted"]);
\r
2281 $ciphertext.= $block ^ $key;
\r
2284 for ($i = 0; $i < $plaintext_len; $i+= '.$block_size.') {
\r
2285 $block = substr($text, $i, '.$block_size.');
\r
2286 $in = $self->_generate_xor($xor);
\r
2289 $ciphertext.= $block ^ $key;
\r
2292 if ($self->continuousBuffer) {
\r
2293 $self->encryptIV = $xor;
\r
2294 if ($start = $plaintext_len % '.$block_size.') {
\r
2295 $buffer["encrypted"] = substr($key, $start) . $buffer["encrypted"];
\r
2299 return $ciphertext;
\r
2302 $decrypt = $init_cryptBlock . '
\r
2303 extract($self->keys[CRYPT_DES_ENCRYPT_1DIM], EXTR_PREFIX_ALL, "k");
\r
2305 $ciphertext_len = strlen($text);
\r
2306 $xor = $self->decryptIV;
\r
2307 $buffer = &$self->debuffer;
\r
2309 if (strlen($buffer["ciphertext"])) {
\r
2310 for ($i = 0; $i < $ciphertext_len; $i+= '.$block_size.') {
\r
2311 $block = substr($text, $i, '.$block_size.');
\r
2312 if (strlen($block) > strlen($buffer["ciphertext"])) {
\r
2313 $in = $self->_generate_xor($xor);
\r
2315 $buffer["ciphertext"].= $in;
\r
2317 $key = $self->_string_shift($buffer["ciphertext"]);
\r
2318 $plaintext.= $block ^ $key;
\r
2321 for ($i = 0; $i < $ciphertext_len; $i+= '.$block_size.') {
\r
2322 $block = substr($text, $i, '.$block_size.');
\r
2323 $in = $self->_generate_xor($xor);
\r
2326 $plaintext.= $block ^ $key;
\r
2329 if ($self->continuousBuffer) {
\r
2330 $self->decryptIV = $xor;
\r
2331 if ($start = $ciphertext_len % '.$block_size.') {
\r
2332 $buffer["ciphertext"] = substr($key, $start) . $buffer["ciphertext"];
\r
2336 return $plaintext;
\r
2339 case CRYPT_DES_MODE_CFB:
\r
2340 $encrypt = $init_cryptBlock . '
\r
2341 extract($self->keys[CRYPT_DES_ENCRYPT_1DIM], EXTR_PREFIX_ALL, "k");
\r
2343 $buffer = &$self->enbuffer;
\r
2345 if ($self->continuousBuffer) {
\r
2346 $iv = &$self->encryptIV;
\r
2347 $pos = &$buffer["pos"];
\r
2349 $iv = $self->encryptIV;
\r
2352 $len = strlen($text);
\r
2356 $max = '.$block_size.' - $pos;
\r
2357 if ($len >= $max) {
\r
2366 $ciphertext = substr($iv, $orig_pos) ^ $text;
\r
2367 $iv = substr_replace($iv, $ciphertext, $orig_pos, $i);
\r
2369 while ($len >= '.$block_size.') {
\r
2372 $iv = $in ^ substr($text, $i, '.$block_size.');
\r
2373 $ciphertext.= $iv;
\r
2374 $len-= '.$block_size.';
\r
2375 $i+= '.$block_size.';
\r
2381 $block = $iv ^ substr($text, $i);
\r
2382 $iv = substr_replace($iv, $block, 0, $len);
\r
2383 $ciphertext.= $block;
\r
2386 return $ciphertext;
\r
2389 $decrypt = $init_cryptBlock . '
\r
2390 extract($self->keys[CRYPT_DES_ENCRYPT_1DIM], EXTR_PREFIX_ALL, "k");
\r
2392 $buffer = &$self->debuffer;
\r
2394 if ($self->continuousBuffer) {
\r
2395 $iv = &$self->decryptIV;
\r
2396 $pos = &$buffer["pos"];
\r
2398 $iv = $self->decryptIV;
\r
2401 $len = strlen($text);
\r
2405 $max = '.$block_size.' - $pos;
\r
2406 if ($len >= $max) {
\r
2415 $plaintext = substr($iv, $orig_pos) ^ $text;
\r
2416 $iv = substr_replace($iv, substr($text, 0, $i), $orig_pos, $i);
\r
2418 while ($len >= '.$block_size.') {
\r
2422 $cb = substr($text, $i, '.$block_size.');
\r
2423 $plaintext.= $iv ^ $cb;
\r
2425 $len-= '.$block_size.';
\r
2426 $i+= '.$block_size.';
\r
2432 $plaintext.= $iv ^ substr($text, $i);
\r
2433 $iv = substr_replace($iv, substr($text, $i), 0, $len);
\r
2437 return $plaintext;
\r
2440 case CRYPT_DES_MODE_OFB:
\r
2441 $encrypt = $init_cryptBlock . '
\r
2442 extract($self->keys[CRYPT_DES_ENCRYPT_1DIM], EXTR_PREFIX_ALL, "k");
\r
2444 $plaintext_len = strlen($text);
\r
2445 $xor = $self->encryptIV;
\r
2446 $buffer = &$self->enbuffer;
\r
2448 if (strlen($buffer["xor"])) {
\r
2449 for ($i = 0; $i < $plaintext_len; $i+= '.$block_size.') {
\r
2450 $block = substr($text, $i, '.$block_size.');
\r
2451 if (strlen($block) > strlen($buffer["xor"])) {
\r
2455 $buffer["xor"].= $xor;
\r
2457 $key = $self->_string_shift($buffer["xor"]);
\r
2458 $ciphertext.= $block ^ $key;
\r
2461 for ($i = 0; $i < $plaintext_len; $i+= '.$block_size.') {
\r
2465 $ciphertext.= substr($text, $i, '.$block_size.') ^ $xor;
\r
2469 if ($self->continuousBuffer) {
\r
2470 $self->encryptIV = $xor;
\r
2471 if ($start = $plaintext_len % '.$block_size.') {
\r
2472 $buffer["xor"] = substr($key, $start) . $buffer["xor"];
\r
2475 return $ciphertext;
\r
2478 $decrypt = $init_cryptBlock . '
\r
2479 extract($self->keys[CRYPT_DES_ENCRYPT_1DIM], EXTR_PREFIX_ALL, "k");
\r
2481 $ciphertext_len = strlen($text);
\r
2482 $xor = $self->decryptIV;
\r
2483 $buffer = &$self->debuffer;
\r
2485 if (strlen($buffer["xor"])) {
\r
2486 for ($i = 0; $i < $ciphertext_len; $i+= '.$block_size.') {
\r
2487 $block = substr($text, $i, '.$block_size.');
\r
2488 if (strlen($block) > strlen($buffer["xor"])) {
\r
2492 $buffer["xor"].= $xor;
\r
2494 $key = $self->_string_shift($buffer["xor"]);
\r
2495 $plaintext.= $block ^ $key;
\r
2498 for ($i = 0; $i < $ciphertext_len; $i+= '.$block_size.') {
\r
2502 $plaintext.= substr($text, $i, '.$block_size.') ^ $xor;
\r
2506 if ($self->continuousBuffer) {
\r
2507 $self->decryptIV = $xor;
\r
2508 if ($start = $ciphertext_len % '.$block_size.') {
\r
2509 $buffer["xor"] = substr($key, $start) . $buffer["xor"];
\r
2512 return $plaintext;
\r
2516 $lambda_functions[$code_hash] = create_function('$action, &$self, $text', 'if ($action == "encrypt") { '.$encrypt.' } else { '.$decrypt.' }');
\r
2518 $this->inline_crypt = $lambda_functions[$code_hash];
\r
2522 * Holds the lambda_functions table (classwide)
\r
2524 * @see inline_crypt_setup()
\r
2528 function &get_lambda_functions()
\r
2530 static $functions = array();
\r
2531 return $functions;
\r
2535 // vim: ts=4:sw=4:et:
\r