PluginProbe
ManageWP Worker / 4.9.25
ManageWP Worker v4.9.25
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 / src / PHPSecLib / Crypt / RC2.php

RC2.php in ManageWP Worker 4.9.25, at src/PHPSecLib/Crypt/RC2.php

661 lines 21.9 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 /**
4 * Pure-PHP implementation of RC2.
5 *
6 * Uses mcrypt, if available, and an internal implementation, otherwise.
7 *
8 * PHP versions 4 and 5
9 *
10 * Useful resources are as follows:
11 *
12 * - {@link http://tools.ietf.org/html/rfc2268}
13 *
14 * Here's a short example of how to use this library:
15 * <code>
16 * <?php
17 * include 'Crypt/RC2.php';
18 *
19 * $rc2 = new Crypt_RC2();
20 *
21 * $rc2->setKey('abcdefgh');
22 *
23 * $plaintext = str_repeat('a', 1024);
24 *
25 * echo $rc2->decrypt($rc2->encrypt($plaintext));
26 * ?>
27 * </code>
28 *
29 * LICENSE: Permission is hereby granted, free of charge, to any person obtaining a copy
30 * of this software and associated documentation files (the "Software"), to deal
31 * in the Software without restriction, including without limitation the rights
32 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
33 * copies of the Software, and to permit persons to whom the Software is
34 * furnished to do so, subject to the following conditions:
35 *
36 * The above copyright notice and this permission notice shall be included in
37 * all copies or substantial portions of the Software.
38 *
39 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
40 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
41 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
42 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
43 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
44 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
45 * THE SOFTWARE.
46 *
47 * @category Crypt
48 * @package Crypt_RC2
49 * @author Patrick Monnerat <pm@datasphere.ch>
50 * @license http://www.opensource.org/licenses/mit-license.html MIT License
51 * @link http://phpseclib.sourceforge.net
52 */
53
54 /**
55 * Include Crypt_Base
56 *
57 * Base cipher class
58 */
59 if (!class_exists('Crypt_Base')) {
60 require_once dirname(__FILE__).'/Base.php';
61 }
62
63 /**#@+
64 * @access public
65 * @see Crypt_RC2::encrypt()
66 * @see Crypt_RC2::decrypt()
67 */
68 /**
69 * Encrypt / decrypt using the Counter mode.
70 *
71 * Set to -1 since that's what Crypt/Random.php uses to index the CTR mode.
72 *
73 * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Counter_.28CTR.29
74 */
75 define('CRYPT_RC2_MODE_CTR', CRYPT_MODE_CTR);
76 /**
77 * Encrypt / decrypt using the Electronic Code Book mode.
78 *
79 * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Electronic_codebook_.28ECB.29
80 */
81 define('CRYPT_RC2_MODE_ECB', CRYPT_MODE_ECB);
82 /**
83 * Encrypt / decrypt using the Code Book Chaining mode.
84 *
85 * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Cipher-block_chaining_.28CBC.29
86 */
87 define('CRYPT_RC2_MODE_CBC', CRYPT_MODE_CBC);
88 /**
89 * Encrypt / decrypt using the Cipher Feedback mode.
90 *
91 * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Cipher_feedback_.28CFB.29
92 */
93 define('CRYPT_RC2_MODE_CFB', CRYPT_MODE_CFB);
94 /**
95 * Encrypt / decrypt using the Cipher Feedback mode.
96 *
97 * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Output_feedback_.28OFB.29
98 */
99 define('CRYPT_RC2_MODE_OFB', CRYPT_MODE_OFB);
100 /**#@-*/
101
102 /**#@+
103 * @access private
104 * @see Crypt_RC2::Crypt_RC2()
105 */
106 /**
107 * Toggles the internal implementation
108 */
109 define('CRYPT_RC2_MODE_INTERNAL', CRYPT_MODE_INTERNAL);
110 /**
111 * Toggles the mcrypt implementation
112 */
113 define('CRYPT_RC2_MODE_MCRYPT', CRYPT_MODE_MCRYPT);
114 /**#@-*/
115
116 /**
117 * Pure-PHP implementation of RC2.
118 *
119 * @package Crypt_RC2
120 * @access public
121 */
122 class Crypt_RC2 extends Crypt_Base
123 {
124 /**
125 * Block Length of the cipher
126 *
127 * @see Crypt_Base::block_size
128 * @var Integer
129 * @access private
130 */
131 public $block_size = 8;
132
133 /**
134 * The Key
135 *
136 * @see Crypt_Base::key
137 * @see setKey()
138 * @var String
139 * @access private
140 */
141 public $key = "\0";
142
143 /**
144 * The default password key_size used by setPassword()
145 *
146 * @see Crypt_Base::password_key_size
147 * @see Crypt_Base::setPassword()
148 * @var Integer
149 * @access private
150 */
151 public $password_key_size = 16; // = 128 bits
152
153 /**
154 * The namespace used by the cipher for its constants.
155 *
156 * @see Crypt_Base::const_namespace
157 * @var String
158 * @access private
159 */
160 public $const_namespace = 'RC2';
161
162 /**
163 * The mcrypt specific name of the cipher
164 *
165 * @see Crypt_Base::cipher_name_mcrypt
166 * @var String
167 * @access private
168 */
169 public $cipher_name_mcrypt = 'rc2';
170
171 /**
172 * Optimizing value while CFB-encrypting
173 *
174 * @see Crypt_Base::cfb_init_len
175 * @var Integer
176 * @access private
177 */
178 public $cfb_init_len = 500;
179
180 /**
181 * The key length in bits.
182 *
183 * @see Crypt_RC2::setKeyLength()
184 * @see Crypt_RC2::setKey()
185 * @var Integer
186 * @access private
187 * @internal Should be in range [1..1024].
188 * @internal Changing this value after setting the key has no effect.
189 */
190 public $default_key_length = 1024;
191
192 /**
193 * The Key Schedule
194 *
195 * @see Crypt_RC2::_setupKey()
196 * @var Array
197 * @access private
198 */
199 public $keys;
200
201 /**
202 * Key expansion randomization table.
203 * Twice the same 256-value sequence to save a modulus in key expansion.
204 *
205 * @see Crypt_RC2::setKey()
206 * @var Array
207 * @access private
208 */
209 var $pitable = array(
210 0xD9, 0x78, 0xF9, 0xC4, 0x19, 0xDD, 0xB5, 0xED,
211 0x28, 0xE9, 0xFD, 0x79, 0x4A, 0xA0, 0xD8, 0x9D,
212 0xC6, 0x7E, 0x37, 0x83, 0x2B, 0x76, 0x53, 0x8E,
213 0x62, 0x4C, 0x64, 0x88, 0x44, 0x8B, 0xFB, 0xA2,
214 0x17, 0x9A, 0x59, 0xF5, 0x87, 0xB3, 0x4F, 0x13,
215 0x61, 0x45, 0x6D, 0x8D, 0x09, 0x81, 0x7D, 0x32,
216 0xBD, 0x8F, 0x40, 0xEB, 0x86, 0xB7, 0x7B, 0x0B,
217 0xF0, 0x95, 0x21, 0x22, 0x5C, 0x6B, 0x4E, 0x82,
218 0x54, 0xD6, 0x65, 0x93, 0xCE, 0x60, 0xB2, 0x1C,
219 0x73, 0x56, 0xC0, 0x14, 0xA7, 0x8C, 0xF1, 0xDC,
220 0x12, 0x75, 0xCA, 0x1F, 0x3B, 0xBE, 0xE4, 0xD1,
221 0x42, 0x3D, 0xD4, 0x30, 0xA3, 0x3C, 0xB6, 0x26,
222 0x6F, 0xBF, 0x0E, 0xDA, 0x46, 0x69, 0x07, 0x57,
223 0x27, 0xF2, 0x1D, 0x9B, 0xBC, 0x94, 0x43, 0x03,
224 0xF8, 0x11, 0xC7, 0xF6, 0x90, 0xEF, 0x3E, 0xE7,
225 0x06, 0xC3, 0xD5, 0x2F, 0xC8, 0x66, 0x1E, 0xD7,
226 0x08, 0xE8, 0xEA, 0xDE, 0x80, 0x52, 0xEE, 0xF7,
227 0x84, 0xAA, 0x72, 0xAC, 0x35, 0x4D, 0x6A, 0x2A,
228 0x96, 0x1A, 0xD2, 0x71, 0x5A, 0x15, 0x49, 0x74,
229 0x4B, 0x9F, 0xD0, 0x5E, 0x04, 0x18, 0xA4, 0xEC,
230 0xC2, 0xE0, 0x41, 0x6E, 0x0F, 0x51, 0xCB, 0xCC,
231 0x24, 0x91, 0xAF, 0x50, 0xA1, 0xF4, 0x70, 0x39,
232 0x99, 0x7C, 0x3A, 0x85, 0x23, 0xB8, 0xB4, 0x7A,
233 0xFC, 0x02, 0x36, 0x5B, 0x25, 0x55, 0x97, 0x31,
234 0x2D, 0x5D, 0xFA, 0x98, 0xE3, 0x8A, 0x92, 0xAE,
235 0x05, 0xDF, 0x29, 0x10, 0x67, 0x6C, 0xBA, 0xC9,
236 0xD3, 0x00, 0xE6, 0xCF, 0xE1, 0x9E, 0xA8, 0x2C,
237 0x63, 0x16, 0x01, 0x3F, 0x58, 0xE2, 0x89, 0xA9,
238 0x0D, 0x38, 0x34, 0x1B, 0xAB, 0x33, 0xFF, 0xB0,
239 0xBB, 0x48, 0x0C, 0x5F, 0xB9, 0xB1, 0xCD, 0x2E,
240 0xC5, 0xF3, 0xDB, 0x47, 0xE5, 0xA5, 0x9C, 0x77,
241 0x0A, 0xA6, 0x20, 0x68, 0xFE, 0x7F, 0xC1, 0xAD,
242 0xD9, 0x78, 0xF9, 0xC4, 0x19, 0xDD, 0xB5, 0xED,
243 0x28, 0xE9, 0xFD, 0x79, 0x4A, 0xA0, 0xD8, 0x9D,
244 0xC6, 0x7E, 0x37, 0x83, 0x2B, 0x76, 0x53, 0x8E,
245 0x62, 0x4C, 0x64, 0x88, 0x44, 0x8B, 0xFB, 0xA2,
246 0x17, 0x9A, 0x59, 0xF5, 0x87, 0xB3, 0x4F, 0x13,
247 0x61, 0x45, 0x6D, 0x8D, 0x09, 0x81, 0x7D, 0x32,
248 0xBD, 0x8F, 0x40, 0xEB, 0x86, 0xB7, 0x7B, 0x0B,
249 0xF0, 0x95, 0x21, 0x22, 0x5C, 0x6B, 0x4E, 0x82,
250 0x54, 0xD6, 0x65, 0x93, 0xCE, 0x60, 0xB2, 0x1C,
251 0x73, 0x56, 0xC0, 0x14, 0xA7, 0x8C, 0xF1, 0xDC,
252 0x12, 0x75, 0xCA, 0x1F, 0x3B, 0xBE, 0xE4, 0xD1,
253 0x42, 0x3D, 0xD4, 0x30, 0xA3, 0x3C, 0xB6, 0x26,
254 0x6F, 0xBF, 0x0E, 0xDA, 0x46, 0x69, 0x07, 0x57,
255 0x27, 0xF2, 0x1D, 0x9B, 0xBC, 0x94, 0x43, 0x03,
256 0xF8, 0x11, 0xC7, 0xF6, 0x90, 0xEF, 0x3E, 0xE7,
257 0x06, 0xC3, 0xD5, 0x2F, 0xC8, 0x66, 0x1E, 0xD7,
258 0x08, 0xE8, 0xEA, 0xDE, 0x80, 0x52, 0xEE, 0xF7,
259 0x84, 0xAA, 0x72, 0xAC, 0x35, 0x4D, 0x6A, 0x2A,
260 0x96, 0x1A, 0xD2, 0x71, 0x5A, 0x15, 0x49, 0x74,
261 0x4B, 0x9F, 0xD0, 0x5E, 0x04, 0x18, 0xA4, 0xEC,
262 0xC2, 0xE0, 0x41, 0x6E, 0x0F, 0x51, 0xCB, 0xCC,
263 0x24, 0x91, 0xAF, 0x50, 0xA1, 0xF4, 0x70, 0x39,
264 0x99, 0x7C, 0x3A, 0x85, 0x23, 0xB8, 0xB4, 0x7A,
265 0xFC, 0x02, 0x36, 0x5B, 0x25, 0x55, 0x97, 0x31,
266 0x2D, 0x5D, 0xFA, 0x98, 0xE3, 0x8A, 0x92, 0xAE,
267 0x05, 0xDF, 0x29, 0x10, 0x67, 0x6C, 0xBA, 0xC9,
268 0xD3, 0x00, 0xE6, 0xCF, 0xE1, 0x9E, 0xA8, 0x2C,
269 0x63, 0x16, 0x01, 0x3F, 0x58, 0xE2, 0x89, 0xA9,
270 0x0D, 0x38, 0x34, 0x1B, 0xAB, 0x33, 0xFF, 0xB0,
271 0xBB, 0x48, 0x0C, 0x5F, 0xB9, 0xB1, 0xCD, 0x2E,
272 0xC5, 0xF3, 0xDB, 0x47, 0xE5, 0xA5, 0x9C, 0x77,
273 0x0A, 0xA6, 0x20, 0x68, 0xFE, 0x7F, 0xC1, 0xAD,
274 );
275
276 /**
277 * Inverse key expansion randomization table.
278 *
279 * @see Crypt_RC2::setKey()
280 * @var Array
281 * @access private
282 */
283 var $invpitable = array(
284 0xD1, 0xDA, 0xB9, 0x6F, 0x9C, 0xC8, 0x78, 0x66,
285 0x80, 0x2C, 0xF8, 0x37, 0xEA, 0xE0, 0x62, 0xA4,
286 0xCB, 0x71, 0x50, 0x27, 0x4B, 0x95, 0xD9, 0x20,
287 0x9D, 0x04, 0x91, 0xE3, 0x47, 0x6A, 0x7E, 0x53,
288 0xFA, 0x3A, 0x3B, 0xB4, 0xA8, 0xBC, 0x5F, 0x68,
289 0x08, 0xCA, 0x8F, 0x14, 0xD7, 0xC0, 0xEF, 0x7B,
290 0x5B, 0xBF, 0x2F, 0xE5, 0xE2, 0x8C, 0xBA, 0x12,
291 0xE1, 0xAF, 0xB2, 0x54, 0x5D, 0x59, 0x76, 0xDB,
292 0x32, 0xA2, 0x58, 0x6E, 0x1C, 0x29, 0x64, 0xF3,
293 0xE9, 0x96, 0x0C, 0x98, 0x19, 0x8D, 0x3E, 0x26,
294 0xAB, 0xA5, 0x85, 0x16, 0x40, 0xBD, 0x49, 0x67,
295 0xDC, 0x22, 0x94, 0xBB, 0x3C, 0xC1, 0x9B, 0xEB,
296 0x45, 0x28, 0x18, 0xD8, 0x1A, 0x42, 0x7D, 0xCC,
297 0xFB, 0x65, 0x8E, 0x3D, 0xCD, 0x2A, 0xA3, 0x60,
298 0xAE, 0x93, 0x8A, 0x48, 0x97, 0x51, 0x15, 0xF7,
299 0x01, 0x0B, 0xB7, 0x36, 0xB1, 0x2E, 0x11, 0xFD,
300 0x84, 0x2D, 0x3F, 0x13, 0x88, 0xB3, 0x34, 0x24,
301 0x1B, 0xDE, 0xC5, 0x1D, 0x4D, 0x2B, 0x17, 0x31,
302 0x74, 0xA9, 0xC6, 0x43, 0x6D, 0x39, 0x90, 0xBE,
303 0xC3, 0xB0, 0x21, 0x6B, 0xF6, 0x0F, 0xD5, 0x99,
304 0x0D, 0xAC, 0x1F, 0x5C, 0x9E, 0xF5, 0xF9, 0x4C,
305 0xD6, 0xDF, 0x89, 0xE4, 0x8B, 0xFF, 0xC7, 0xAA,
306 0xE7, 0xED, 0x46, 0x25, 0xB6, 0x06, 0x5E, 0x35,
307 0xB5, 0xEC, 0xCE, 0xE8, 0x6C, 0x30, 0x55, 0x61,
308 0x4A, 0xFE, 0xA0, 0x79, 0x03, 0xF0, 0x10, 0x72,
309 0x7C, 0xCF, 0x52, 0xA6, 0xA7, 0xEE, 0x44, 0xD3,
310 0x9A, 0x57, 0x92, 0xD0, 0x5A, 0x7A, 0x41, 0x7F,
311 0x0E, 0x00, 0x63, 0xF2, 0x4F, 0x05, 0x83, 0xC9,
312 0xA1, 0xD4, 0xDD, 0xC4, 0x56, 0xF4, 0xD2, 0x77,
313 0x81, 0x09, 0x82, 0x33, 0x9F, 0x07, 0x86, 0x75,
314 0x38, 0x4E, 0x69, 0xF1, 0xAD, 0x23, 0x73, 0x87,
315 0x70, 0x02, 0xC2, 0x1E, 0xB8, 0x0A, 0xFC, 0xE6,
316 );
317
318 /**
319 * Default Constructor.
320 *
321 * Determines whether or not the mcrypt extension should be used.
322 *
323 * $mode could be:
324 *
325 * - CRYPT_RC2_MODE_ECB
326 *
327 * - CRYPT_RC2_MODE_CBC
328 *
329 * - CRYPT_RC2_MODE_CTR
330 *
331 * - CRYPT_RC2_MODE_CFB
332 *
333 * - CRYPT_RC2_MODE_OFB
334 *
335 * If not explicitly set, CRYPT_RC2_MODE_CBC will be used.
336 *
337 * @see Crypt_Base::Crypt_Base()
338 *
339 * @param optional Integer $mode
340 *
341 * @access public
342 */
343 public function __construct($mode = CRYPT_RC2_MODE_CBC)
344 {
345 parent::__construct($mode);
346 $this->setKey('');
347 }
348
349 /**
350 * Sets the key length
351 *
352 * Valid key lengths are 1 to 1024.
353 * Calling this function after setting the key has no effect until the next
354 * Crypt_RC2::setKey() call.
355 *
356 * @access public
357 *
358 * @param Integer $length in bits
359 */
360 public function setKeyLength($length)
361 {
362 if ($length >= 1 && $length <= 1024) {
363 $this->default_key_length = $length;
364 }
365 }
366
367 /**
368 * Sets the key.
369 *
370 * Keys can be of any length. RC2, itself, uses 1 to 1024 bit keys (eg.
371 * strlen($key) <= 128), however, we only use the first 128 bytes if $key
372 * has more then 128 bytes in it, and set $key to a single null byte if
373 * it is empty.
374 *
375 * If the key is not explicitly set, it'll be assumed to be a single
376 * null byte.
377 *
378 * @see Crypt_Base::setKey()
379 * @access public
380 *
381 * @param String $key
382 * @param Integer $t1 optional Effective key length in bits.
383 */
384 public function setKey($key, $t1 = 0)
385 {
386 if ($t1 <= 0) {
387 $t1 = $this->default_key_length;
388 } elseif ($t1 > 1024) {
389 $t1 = 1024;
390 }
391 // Key byte count should be 1..128.
392 $key = strlen($key) ? substr($key, 0, 128) : "\x00";
393 $t = strlen($key);
394
395 // The mcrypt RC2 implementation only supports effective key length
396 // of 1024 bits. It is however possible to handle effective key
397 // lengths in range 1..1024 by expanding the key and applying
398 // inverse pitable mapping to the first byte before submitting it
399 // to mcrypt.
400
401 // Key expansion.
402 $l = array_values(unpack('C*', $key));
403 $t8 = ($t1 + 7) >> 3;
404 $tm = 0xFF >> (8 * $t8 - $t1);
405
406 // Expand key.
407 $pitable = $this->pitable;
408 for ($i = $t; $i < 128; $i++) {
409 $l[$i] = $pitable[$l[$i - 1] + $l[$i - $t]];
410 }
411 $i = 128 - $t8;
412 $l[$i] = $pitable[$l[$i] & $tm];
413 while ($i--) {
414 $l[$i] = $pitable[$l[$i + 1] ^ $l[$i + $t8]];
415 }
416
417 // Prepare the key for mcrypt.
418 $l[0] = $this->invpitable[$l[0]];
419 array_unshift($l, 'C*');
420 parent::setKey(call_user_func_array('pack', $l));
421 }
422
423 /**
424 * Encrypts a block
425 *
426 * @see Crypt_Base::_encryptBlock()
427 * @see Crypt_Base::encrypt()
428 * @access private
429 *
430 * @param String $in
431 *
432 * @return String
433 */
434 public function _encryptBlock($in)
435 {
436 list($r0, $r1, $r2, $r3) = array_values(unpack('v*', $in));
437 $keys = $this->keys;
438 $limit = 20;
439 $actions = array($limit => 44, 44 => 64);
440 $j = 0;
441
442 for (;;) {
443 // Mixing round.
444 $r0 = (($r0 + $keys[$j++] + ((($r1 ^ $r2) & $r3) ^ $r1)) & 0xFFFF) << 1;
445 $r0 |= $r0 >> 16;
446 $r1 = (($r1 + $keys[$j++] + ((($r2 ^ $r3) & $r0) ^ $r2)) & 0xFFFF) << 2;
447 $r1 |= $r1 >> 16;
448 $r2 = (($r2 + $keys[$j++] + ((($r3 ^ $r0) & $r1) ^ $r3)) & 0xFFFF) << 3;
449 $r2 |= $r2 >> 16;
450 $r3 = (($r3 + $keys[$j++] + ((($r0 ^ $r1) & $r2) ^ $r0)) & 0xFFFF) << 5;
451 $r3 |= $r3 >> 16;
452
453 if ($j === $limit) {
454 if ($limit === 64) {
455 break;
456 }
457
458 // Mashing round.
459 $r0 += $keys[$r3 & 0x3F];
460 $r1 += $keys[$r0 & 0x3F];
461 $r2 += $keys[$r1 & 0x3F];
462 $r3 += $keys[$r2 & 0x3F];
463 $limit = $actions[$limit];
464 }
465 }
466
467 return pack('vvvv', $r0, $r1, $r2, $r3);
468 }
469
470 /**
471 * Decrypts a block
472 *
473 * @see Crypt_Base::_decryptBlock()
474 * @see Crypt_Base::decrypt()
475 * @access private
476 *
477 * @param String $in
478 *
479 * @return String
480 */
481 public function _decryptBlock($in)
482 {
483 list($r0, $r1, $r2, $r3) = array_values(unpack('v*', $in));
484 $keys = $this->keys;
485 $limit = 44;
486 $actions = array($limit => 20, 20 => 0);
487 $j = 64;
488
489 for (;;) {
490 // R-mixing round.
491 $r3 = ($r3 | ($r3 << 16)) >> 5;
492 $r3 = ($r3 - $keys[--$j] - ((($r0 ^ $r1) & $r2) ^ $r0)) & 0xFFFF;
493 $r2 = ($r2 | ($r2 << 16)) >> 3;
494 $r2 = ($r2 - $keys[--$j] - ((($r3 ^ $r0) & $r1) ^ $r3)) & 0xFFFF;
495 $r1 = ($r1 | ($r1 << 16)) >> 2;
496 $r1 = ($r1 - $keys[--$j] - ((($r2 ^ $r3) & $r0) ^ $r2)) & 0xFFFF;
497 $r0 = ($r0 | ($r0 << 16)) >> 1;
498 $r0 = ($r0 - $keys[--$j] - ((($r1 ^ $r2) & $r3) ^ $r1)) & 0xFFFF;
499
500 if ($j === $limit) {
501 if ($limit === 0) {
502 break;
503 }
504
505 // R-mashing round.
506 $r3 = ($r3 - $keys[$r2 & 0x3F]) & 0xFFFF;
507 $r2 = ($r2 - $keys[$r1 & 0x3F]) & 0xFFFF;
508 $r1 = ($r1 - $keys[$r0 & 0x3F]) & 0xFFFF;
509 $r0 = ($r0 - $keys[$r3 & 0x3F]) & 0xFFFF;
510 $limit = $actions[$limit];
511 }
512 }
513
514 return pack('vvvv', $r0, $r1, $r2, $r3);
515 }
516
517 /**
518 * Creates the key schedule
519 *
520 * @see Crypt_Base::_setupKey()
521 * @access private
522 */
523 public function _setupKey()
524 {
525 // Key has already been expanded in Crypt_RC2::setKey():
526 // Only the first value must be altered.
527 $l = unpack('Ca/Cb/v*', $this->key);
528 array_unshift($l, $this->pitable[$l['a']] | ($l['b'] << 8));
529 unset($l['a']);
530 unset($l['b']);
531 $this->keys = $l;
532 }
533
534 /**
535 * Setup the performance-optimized function for de/encrypt()
536 *
537 * @see Crypt_Base::_setupInlineCrypt()
538 * @access private
539 */
540 public function _setupInlineCrypt()
541 {
542 $lambda_functions = &Crypt_RC2::_getLambdaFunctions();
543
544 // The first 10 generated $lambda_functions will use the $keys hardcoded as integers
545 // for the mixing rounds, for better inline crypt performance [~20% faster].
546 // But for memory reason we have to limit those ultra-optimized $lambda_functions to an amount of 10.
547 $keys = $this->keys;
548 if (count($lambda_functions) >= 10) {
549 foreach ($this->keys as $k => $v) {
550 $keys[$k] = '$keys['.$k.']';
551 }
552 }
553
554 $code_hash = md5(str_pad("Crypt_RC2, {$this->mode}, ", 32, "\0").implode(',', $keys));
555
556 // Is there a re-usable $lambda_functions in there?
557 // If not, we have to create it.
558 if (!isset($lambda_functions[$code_hash])) {
559 // Init code for both, encrypt and decrypt.
560 $init_crypt = '$keys = $self->keys;';
561
562 // $in is the current 8 bytes block which has to be en/decrypt
563 $encrypt_block = $decrypt_block = '
564 $in = unpack("v4", $in);
565 $r0 = $in[1];
566 $r1 = $in[2];
567 $r2 = $in[3];
568 $r3 = $in[4];
569 ';
570
571 // Create code for encryption.
572 $limit = 20;
573 $actions = array($limit => 44, 44 => 64);
574 $j = 0;
575
576 for (;;) {
577 // Mixing round.
578 $encrypt_block .= '
579 $r0 = (($r0 + '.$keys[$j++].' +
580 ((($r1 ^ $r2) & $r3) ^ $r1)) & 0xFFFF) << 1;
581 $r0 |= $r0 >> 16;
582 $r1 = (($r1 + '.$keys[$j++].' +
583 ((($r2 ^ $r3) & $r0) ^ $r2)) & 0xFFFF) << 2;
584 $r1 |= $r1 >> 16;
585 $r2 = (($r2 + '.$keys[$j++].' +
586 ((($r3 ^ $r0) & $r1) ^ $r3)) & 0xFFFF) << 3;
587 $r2 |= $r2 >> 16;
588 $r3 = (($r3 + '.$keys[$j++].' +
589 ((($r0 ^ $r1) & $r2) ^ $r0)) & 0xFFFF) << 5;
590 $r3 |= $r3 >> 16;';
591
592 if ($j === $limit) {
593 if ($limit === 64) {
594 break;
595 }
596
597 // Mashing round.
598 $encrypt_block .= '
599 $r0 += $keys[$r3 & 0x3F];
600 $r1 += $keys[$r0 & 0x3F];
601 $r2 += $keys[$r1 & 0x3F];
602 $r3 += $keys[$r2 & 0x3F];';
603 $limit = $actions[$limit];
604 }
605 }
606
607 $encrypt_block .= '$in = pack("v4", $r0, $r1, $r2, $r3);';
608
609 // Create code for decryption.
610 $limit = 44;
611 $actions = array($limit => 20, 20 => 0);
612 $j = 64;
613
614 for (;;) {
615 // R-mixing round.
616 $decrypt_block .= '
617 $r3 = ($r3 | ($r3 << 16)) >> 5;
618 $r3 = ($r3 - '.$keys[--$j].' -
619 ((($r0 ^ $r1) & $r2) ^ $r0)) & 0xFFFF;
620 $r2 = ($r2 | ($r2 << 16)) >> 3;
621 $r2 = ($r2 - '.$keys[--$j].' -
622 ((($r3 ^ $r0) & $r1) ^ $r3)) & 0xFFFF;
623 $r1 = ($r1 | ($r1 << 16)) >> 2;
624 $r1 = ($r1 - '.$keys[--$j].' -
625 ((($r2 ^ $r3) & $r0) ^ $r2)) & 0xFFFF;
626 $r0 = ($r0 | ($r0 << 16)) >> 1;
627 $r0 = ($r0 - '.$keys[--$j].' -
628 ((($r1 ^ $r2) & $r3) ^ $r1)) & 0xFFFF;';
629
630 if ($j === $limit) {
631 if ($limit === 0) {
632 break;
633 }
634
635 // R-mashing round.
636 $decrypt_block .= '
637 $r3 = ($r3 - $keys[$r2 & 0x3F]) & 0xFFFF;
638 $r2 = ($r2 - $keys[$r1 & 0x3F]) & 0xFFFF;
639 $r1 = ($r1 - $keys[$r0 & 0x3F]) & 0xFFFF;
640 $r0 = ($r0 - $keys[$r3 & 0x3F]) & 0xFFFF;';
641 $limit = $actions[$limit];
642 }
643 }
644
645 $decrypt_block .= '$in = pack("v4", $r0, $r1, $r2, $r3);';
646
647 // Creates the inline-crypt function
648 $lambda_functions[$code_hash] = $this->_createInlineCryptFunction(
649 array(
650 'init_crypt' => $init_crypt,
651 'encrypt_block' => $encrypt_block,
652 'decrypt_block' => $decrypt_block,
653 )
654 );
655 }
656
657 // Set the inline-crypt function as callback in: $this->inline_crypt
658 $this->inline_crypt = $lambda_functions[$code_hash];
659 }
660 }
661