PluginProbe
Contact Forms by Cimatti / 1.9.2
Contact Forms by Cimatti v1.9.2
2.3.6 2.3.5 2.3.0 2.2.32 2.2.4 2.2.0 2.1.2 2.1.1 trunk 1.0 1.1 1.2 1.2.1 1.3 1.3.1 1.3.2 1.3.3 1.3.4 1.3.5 1.3.6 1.3.7 1.3.8 1.3.9 1.4.0 1.4.1 All 62 releases
← All changes | phpseclib-crypt/AES.php +66 -480 1.01.9.2 View file →
@@ -1,27 +1,30 @@
1 1 <?php
2 -/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
3 2
4 3 /**
5 4 * Pure-PHP implementation of AES.
6 5 *
7 - * Uses mcrypt, if available, and an internal implementation, otherwise.
6 + * Uses mcrypt, if available/possible, and an internal implementation, otherwise.
8 7 *
9 8 * PHP versions 4 and 5
10 9 *
11 - * If {@link Crypt_AES::setKeyLength() setKeyLength()} isn't called, it'll be calculated from
12 - * {@link Crypt_AES::setKey() setKey()}. ie. if the key is 128-bits, the key length will be 128-bits. If it's 136-bits
13 - * it'll be null-padded to 160-bits and 160 bits will be the key length until {@link Crypt_Rijndael::setKey() setKey()}
10 + * NOTE: Since AES.php is (for compatibility and phpseclib-historical reasons) virtually
11 + * just a wrapper to Rijndael.php you may consider using Rijndael.php instead of
12 + * to save one include_once().
13 + *
14 + * If {@link self::setKeyLength() setKeyLength()} isn't called, it'll be calculated from
15 + * {@link self::setKey() setKey()}. ie. if the key is 128-bits, the key length will be 128-bits. If it's 136-bits
16 + * it'll be null-padded to 192-bits and 192 bits will be the key length until {@link self::setKey() setKey()}
14 17 * is called, again, at which point, it'll be recalculated.
15 18 *
16 19 * Since Crypt_AES extends Crypt_Rijndael, some functions are available to be called that, in the context of AES, don't
17 - * make a whole lot of sense. {@link Crypt_AES::setBlockLength() setBlockLength()}, for instance. Calling that function,
20 + * make a whole lot of sense. {@link self::setBlockLength() setBlockLength()}, for instance. Calling that function,
18 21 * however possible, won't do anything (AES has a fixed block length whereas Rijndael has a variable one).
19 22 *
20 23 * Here's a short example of how to use this library:
21 24 * <code>
22 25 * <?php
23 - * include('Crypt/AES.php');
26 + * include 'Crypt/AES.php';
24 27 *
25 28 * $aes = new Crypt_AES();
26 29 *
27 30 * $aes->setKey('abcdefghijklmnop');
@@ -41,12 +44,12 @@
41 44 * in the Software without restriction, including without limitation the rights
42 45 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
43 46 * copies of the Software, and to permit persons to whom the Software is
44 47 * furnished to do so, subject to the following conditions:
45 - *
48 + *
46 49 * The above copyright notice and this permission notice shall be included in
47 50 * all copies or substantial portions of the Software.
48 - *
51 + *
49 52 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
50 53 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
51 54 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
52 55 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
@@ -53,15 +56,14 @@
53 56 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
54 57 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
55 58 * THE SOFTWARE.
56 59 *
57 - * @category Crypt
58 - * @package Crypt_AES
59 - * @author Jim Wigginton <terrafrost@php.net>
60 - * @copyright MMVIII Jim Wigginton
61 - * @license http://www.opensource.org/licenses/mit-license.html MIT License
62 - * @version $Id: AES.php,v 1.7 2010/02/09 06:10:25 terrafrost Exp $
63 - * @link http://phpseclib.sourceforge.net
60 + * @category Crypt
61 + * @package Crypt_AES
62 + * @author Jim Wigginton <terrafrost@php.net>
63 + * @copyright 2008 Jim Wigginton
64 + * @license http://www.opensource.org/licenses/mit-license.html MIT License
65 + * @link http://phpseclib.sourceforge.net
64 66 */
65 67
66 68 /**
67 69 * Include Crypt_Rijndael
@@ -66,15 +68,15 @@
66 68 /**
67 69 * Include Crypt_Rijndael
68 70 */
69 71 if (!class_exists('Crypt_Rijndael')) {
70 - require_once 'Rijndael.php';
72 + include_once 'Rijndael.php';
71 73 }
72 74
73 75 /**#@+
74 76 * @access public
75 - * @see Crypt_AES::encrypt()
76 - * @see Crypt_AES::decrypt()
77 + * @see self::encrypt()
78 + * @see self::decrypt()
77 79 */
78 80 /**
79 81 * Encrypt / decrypt using the Counter mode.
80 82 *
@@ -81,177 +83,61 @@
81 83 * Set to -1 since that's what Crypt/Random.php uses to index the CTR mode.
82 84 *
83 85 * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Counter_.28CTR.29
84 86 */
85 -define('CRYPT_AES_MODE_CTR', -1);
87 +define('CRYPT_AES_MODE_CTR', CRYPT_MODE_CTR);
86 88 /**
87 89 * Encrypt / decrypt using the Electronic Code Book mode.
88 90 *
89 91 * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Electronic_codebook_.28ECB.29
90 92 */
91 -define('CRYPT_AES_MODE_ECB', 1);
93 +define('CRYPT_AES_MODE_ECB', CRYPT_MODE_ECB);
92 94 /**
93 95 * Encrypt / decrypt using the Code Book Chaining mode.
94 96 *
95 97 * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Cipher-block_chaining_.28CBC.29
96 98 */
97 -define('CRYPT_AES_MODE_CBC', 2);
99 +define('CRYPT_AES_MODE_CBC', CRYPT_MODE_CBC);
98 100 /**
99 101 * Encrypt / decrypt using the Cipher Feedback mode.
100 102 *
101 103 * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Cipher_feedback_.28CFB.29
102 104 */
103 -define('CRYPT_AES_MODE_CFB', 3);
105 +define('CRYPT_AES_MODE_CFB', CRYPT_MODE_CFB);
104 106 /**
105 107 * Encrypt / decrypt using the Cipher Feedback mode.
106 108 *
107 109 * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Output_feedback_.28OFB.29
108 110 */
109 -define('CRYPT_AES_MODE_OFB', 4);
111 +define('CRYPT_AES_MODE_OFB', CRYPT_MODE_OFB);
110 112 /**#@-*/
111 113
112 -/**#@+
113 - * @access private
114 - * @see Crypt_AES::Crypt_AES()
115 - */
116 114 /**
117 - * Toggles the internal implementation
118 - */
119 -define('CRYPT_AES_MODE_INTERNAL', 1);
120 -/**
121 - * Toggles the mcrypt implementation
122 - */
123 -define('CRYPT_AES_MODE_MCRYPT', 2);
124 -/**#@-*/
125 -
126 -/**
127 115 * Pure-PHP implementation of AES.
128 116 *
117 + * @package Crypt_AES
129 118 * @author Jim Wigginton <terrafrost@php.net>
130 - * @version 0.1.0
131 119 * @access public
132 - * @package Crypt_AES
133 120 */
134 -class Crypt_AES extends Crypt_Rijndael {
121 +class Crypt_AES extends Crypt_Rijndael
122 +{
135 123 /**
136 - * mcrypt resource for encryption
124 + * The namespace used by the cipher for its constants.
137 125 *
138 - * The mcrypt resource can be recreated every time something needs to be created or it can be created just once.
139 - * Since mcrypt operates in continuous mode, by default, it'll need to be recreated when in non-continuous mode.
140 - *
141 - * @see Crypt_AES::encrypt()
142 - * @var String
126 + * @see Crypt_Base::const_namespace
127 + * @var string
143 128 * @access private
144 129 */
145 - var $enmcrypt;
130 + var $const_namespace = 'AES';
146 131
147 132 /**
148 - * mcrypt resource for decryption
149 - *
150 - * The mcrypt resource can be recreated every time something needs to be created or it can be created just once.
151 - * Since mcrypt operates in continuous mode, by default, it'll need to be recreated when in non-continuous mode.
152 - *
153 - * @see Crypt_AES::decrypt()
154 - * @var String
155 - * @access private
156 - */
157 - var $demcrypt;
158 -
159 - /**
160 - * mcrypt resource for CFB mode
161 - *
162 - * @see Crypt_AES::encrypt()
163 - * @see Crypt_AES::decrypt()
164 - * @var String
165 - * @access private
166 - */
167 - var $ecb;
168 -
169 - /**
170 - * Default Constructor.
171 - *
172 - * Determines whether or not the mcrypt extension should be used. $mode should only, at present, be
173 - * CRYPT_AES_MODE_ECB or CRYPT_AES_MODE_CBC. If not explictly set, CRYPT_AES_MODE_CBC will be used.
174 - *
175 - * @param optional Integer $mode
176 - * @return Crypt_AES
177 - * @access public
178 - */
179 - function Crypt_AES($mode = CRYPT_AES_MODE_CBC)
180 - {
181 - if ( !defined('CRYPT_AES_MODE') ) {
182 - switch (true) {
183 - case extension_loaded('mcrypt') && in_array('rijndael-128', mcrypt_list_algorithms()):
184 - define('CRYPT_AES_MODE', CRYPT_AES_MODE_MCRYPT);
185 - break;
186 - default:
187 - define('CRYPT_AES_MODE', CRYPT_AES_MODE_INTERNAL);
188 - }
189 - }
190 -
191 - switch ( CRYPT_AES_MODE ) {
192 - case CRYPT_AES_MODE_MCRYPT:
193 - switch ($mode) {
194 - case CRYPT_AES_MODE_ECB:
195 - $this->paddable = true;
196 - $this->mode = MCRYPT_MODE_ECB;
197 - break;
198 - case CRYPT_AES_MODE_CTR:
199 - // ctr doesn't have a constant associated with it even though it appears to be fairly widely
200 - // supported. in lieu of knowing just how widely supported it is, i've, for now, opted not to
201 - // include a compatibility layer. the layer has been implemented but, for now, is commented out.
202 - $this->mode = 'ctr';
203 - //$this->mode = in_array('ctr', mcrypt_list_modes()) ? 'ctr' : CRYPT_AES_MODE_CTR;
204 - break;
205 - case CRYPT_AES_MODE_CFB:
206 - $this->mode = 'ncfb';
207 - break;
208 - case CRYPT_AES_MODE_OFB:
209 - $this->mode = MCRYPT_MODE_NOFB;
210 - break;
211 - case CRYPT_AES_MODE_CBC:
212 - default:
213 - $this->paddable = true;
214 - $this->mode = MCRYPT_MODE_CBC;
215 - }
216 -
217 - $this->debuffer = $this->enbuffer = '';
218 -
219 - break;
220 - default:
221 - switch ($mode) {
222 - case CRYPT_AES_MODE_ECB:
223 - $this->paddable = true;
224 - $this->mode = CRYPT_RIJNDAEL_MODE_ECB;
225 - break;
226 - case CRYPT_AES_MODE_CTR:
227 - $this->mode = CRYPT_RIJNDAEL_MODE_CTR;
228 - break;
229 - case CRYPT_AES_MODE_CFB:
230 - $this->mode = CRYPT_RIJNDAEL_MODE_CFB;
231 - break;
232 - case CRYPT_AES_MODE_OFB:
233 - $this->mode = CRYPT_RIJNDAEL_MODE_OFB;
234 - break;
235 - case CRYPT_AES_MODE_CBC:
236 - default:
237 - $this->paddable = true;
238 - $this->mode = CRYPT_RIJNDAEL_MODE_CBC;
239 - }
240 - }
241 -
242 - if (CRYPT_AES_MODE == CRYPT_AES_MODE_INTERNAL) {
243 - parent::Crypt_Rijndael($this->mode);
244 - }
245 - }
246 -
247 - /**
248 133 * Dummy function
249 134 *
250 135 * Since Crypt_AES extends Crypt_Rijndael, this function is, technically, available, but it doesn't do anything.
251 136 *
137 + * @see Crypt_Rijndael::setBlockLength()
252 138 * @access public
253 - * @param Integer $length
139 + * @param int $length
254 140 */
255 141 function setBlockLength($length)
256 142 {
257 143 return;
@@ -256,356 +142,56 @@
256 142 {
257 143 return;
258 144 }
259 145
260 -
261 146 /**
262 - * Sets the initialization vector. (optional)
147 + * Sets the key length
263 148 *
264 - * SetIV is not required when CRYPT_RIJNDAEL_MODE_ECB is being used. If not explictly set, it'll be assumed
265 - * to be all zero's.
149 + * Valid key lengths are 128, 192, and 256. If the length is less than 128, it will be rounded up to
150 + * 128. If the length is greater than 128 and invalid, it will be rounded down to the closest valid amount.
266 151 *
152 + * @see Crypt_Rijndael:setKeyLength()
267 153 * @access public
268 - * @param String $iv
154 + * @param int $length
269 155 */
270 - function setIV($iv)
156 + function setKeyLength($length)
271 157 {
272 - parent::setIV($iv);
273 - if ( CRYPT_AES_MODE == CRYPT_AES_MODE_MCRYPT ) {
274 - $this->changed = true;
158 + switch ($length) {
159 + case 160:
160 + $length = 192;
161 + break;
162 + case 224:
163 + $length = 256;
275 164 }
165 + parent::setKeyLength($length);
276 166 }
277 167
278 168 /**
279 - * Encrypts a message.
169 + * Sets the key.
280 170 *
281 - * $plaintext will be padded with up to 16 additional bytes. Other AES implementations may or may not pad in the
282 - * same manner. Other common approaches to padding and the reasons why it's necessary are discussed in the following
283 - * URL:
171 + * Rijndael supports five different key lengths, AES only supports three.
284 172 *
285 - * {@link http://www.di-mgt.com.au/cryptopad.html http://www.di-mgt.com.au/cryptopad.html}
286 - *
287 - * An alternative to padding is to, separately, send the length of the file. This is what SSH, in fact, does.
288 - * strlen($plaintext) will still need to be a multiple of 16, however, arbitrary values can be added to make it that
289 - * length.
290 - *
291 - * @see Crypt_AES::decrypt()
173 + * @see Crypt_Rijndael:setKey()
174 + * @see setKeyLength()
292 175 * @access public
293 - * @param String $plaintext
176 + * @param string $key
294 177 */
295 - function encrypt($plaintext)
178 + function setKey($key)
296 179 {
297 - if ( CRYPT_AES_MODE == CRYPT_AES_MODE_MCRYPT ) {
298 - $changed = $this->changed;
299 - $this->_mcryptSetup();
300 - /*
301 - if ($this->mode == CRYPT_AES_MODE_CTR) {
302 - $iv = $this->encryptIV;
303 - $xor = mcrypt_generic($this->enmcrypt, $this->_generate_xor(strlen($plaintext), $iv));
304 - $ciphertext = $plaintext ^ $xor;
305 - if ($this->continuousBuffer) {
306 - $this->encryptIV = $iv;
307 - }
308 - return $ciphertext;
309 - }
310 - */
311 - // re: http://phpseclib.sourceforge.net/cfb-demo.phps
312 - // using mcrypt's default handing of CFB the above would output two different things. using phpseclib's
313 - // rewritten CFB implementation the above outputs the same thing twice.
314 - if ($this->mode == 'ncfb') {
315 - if ($changed) {
316 - $this->ecb = mcrypt_module_open(MCRYPT_RIJNDAEL_128, '', MCRYPT_MODE_ECB, '');
317 - mcrypt_generic_init($this->ecb, $this->key, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0");
318 - }
180 + parent::setKey($key);
319 181
320 - if (strlen($this->enbuffer)) {
321 - $ciphertext = $plaintext ^ substr($this->encryptIV, strlen($this->enbuffer));
322 - $this->enbuffer.= $ciphertext;
323 - if (strlen($this->enbuffer) == 16) {
324 - $this->encryptIV = $this->enbuffer;
325 - $this->enbuffer = '';
326 - mcrypt_generic_init($this->enmcrypt, $this->key, $this->encryptIV);
327 - }
328 - $plaintext = substr($plaintext, strlen($ciphertext));
329 - } else {
330 - $ciphertext = '';
331 - }
332 -
333 - $last_pos = strlen($plaintext) & 0xFFFFFFF0;
334 - $ciphertext.= $last_pos ? mcrypt_generic($this->enmcrypt, substr($plaintext, 0, $last_pos)) : '';
335 -
336 - if (strlen($plaintext) & 0xF) {
337 - if (strlen($ciphertext)) {
338 - $this->encryptIV = substr($ciphertext, -16);
339 - }
340 - $this->encryptIV = mcrypt_generic($this->ecb, $this->encryptIV);
341 - $this->enbuffer = substr($plaintext, $last_pos) ^ $this->encryptIV;
342 - $ciphertext.= $this->enbuffer;
343 - }
344 -
345 - return $ciphertext;
346 - }
347 -
348 - if ($this->paddable) {
349 - $plaintext = $this->_pad($plaintext);
350 - }
351 -
352 - $ciphertext = mcrypt_generic($this->enmcrypt, $plaintext);
353 -
354 - if (!$this->continuousBuffer) {
355 - mcrypt_generic_init($this->enmcrypt, $this->key, $this->iv);
356 - }
357 -
358 - return $ciphertext;
359 - }
360 -
361 - return parent::encrypt($plaintext);
362 - }
363 -
364 - /**
365 - * Decrypts a message.
366 - *
367 - * If strlen($ciphertext) is not a multiple of 16, null bytes will be added to the end of the string until it is.
368 - *
369 - * @see Crypt_AES::encrypt()
370 - * @access public
371 - * @param String $ciphertext
372 - */
373 - function decrypt($ciphertext)
374 - {
375 - if ( CRYPT_AES_MODE == CRYPT_AES_MODE_MCRYPT ) {
376 - $changed = $this->changed;
377 - $this->_mcryptSetup();
378 - /*
379 - if ($this->mode == CRYPT_AES_MODE_CTR) {
380 - $iv = $this->decryptIV;
381 - $xor = mcrypt_generic($this->enmcrypt, $this->_generate_xor(strlen($ciphertext), $iv));
382 - $plaintext = $ciphertext ^ $xor;
383 - if ($this->continuousBuffer) {
384 - $this->decryptIV = $iv;
385 - }
386 - return $plaintext;
387 - }
388 - */
389 - if ($this->mode == 'ncfb') {
390 - if ($changed) {
391 - $this->ecb = mcrypt_module_open(MCRYPT_RIJNDAEL_128, '', MCRYPT_MODE_ECB, '');
392 - mcrypt_generic_init($this->ecb, $this->key, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0");
393 - }
394 -
395 - if (strlen($this->debuffer)) {
396 - $plaintext = $ciphertext ^ substr($this->decryptIV, strlen($this->debuffer));
397 -
398 - $this->debuffer.= substr($ciphertext, 0, strlen($plaintext));
399 - if (strlen($this->debuffer) == 16) {
400 - $this->decryptIV = $this->debuffer;
401 - $this->debuffer = '';
402 - mcrypt_generic_init($this->demcrypt, $this->key, $this->decryptIV);
403 - }
404 - $ciphertext = substr($ciphertext, strlen($plaintext));
405 - } else {
406 - $plaintext = '';
407 - }
408 -
409 - $last_pos = strlen($ciphertext) & 0xFFFFFFF0;
410 - $plaintext.= $last_pos ? mdecrypt_generic($this->demcrypt, substr($ciphertext, 0, $last_pos)) : '';
411 -
412 - if (strlen($ciphertext) & 0xF) {
413 - if (strlen($plaintext)) {
414 - $this->decryptIV = substr($ciphertext, $last_pos - 16, 16);
415 - }
416 - $this->decryptIV = mcrypt_generic($this->ecb, $this->decryptIV);
417 - $this->debuffer = substr($ciphertext, $last_pos);
418 - $plaintext.= $this->debuffer ^ $this->decryptIV;
419 - }
420 -
421 - return $plaintext;
422 - }
423 -
424 - if ($this->paddable) {
425 - // we pad with chr(0) since that's what mcrypt_generic does. to quote from http://php.net/function.mcrypt-generic :
426 - // "The data is padded with "\0" to make sure the length of the data is n * blocksize."
427 - $ciphertext = str_pad($ciphertext, (strlen($ciphertext) + 15) & 0xFFFFFFF0, chr(0));
428 - }
429 -
430 - $plaintext = mdecrypt_generic($this->demcrypt, $ciphertext);
431 -
432 - if (!$this->continuousBuffer) {
433 - mcrypt_generic_init($this->demcrypt, $this->key, $this->iv);
434 - }
435 -
436 - return $this->paddable ? $this->_unpad($plaintext) : $plaintext;
437 - }
438 -
439 - return parent::decrypt($ciphertext);
440 - }
441 -
442 - /**
443 - * Setup mcrypt
444 - *
445 - * Validates all the variables.
446 - *
447 - * @access private
448 - */
449 - function _mcryptSetup()
450 - {
451 - if (!$this->changed) {
452 - return;
453 - }
454 -
455 182 if (!$this->explicit_key_length) {
456 - // this just copied from Crypt_Rijndael::_setup()
457 - $length = strlen($this->key) >> 2;
458 - if ($length > 8) {
459 - $length = 8;
460 - } else if ($length < 4) {
461 - $length = 4;
183 + $length = strlen($key);
184 + switch (true) {
185 + case $length <= 16:
186 + $this->key_length = 16;
187 + break;
188 + case $length <= 24:
189 + $this->key_length = 24;
190 + break;
191 + default:
192 + $this->key_length = 32;
462 193 }
463 - $this->Nk = $length;
464 - $this->key_size = $length << 2;
194 + $this->_setEngine();
465 195 }
466 -
467 - switch ($this->Nk) {
468 - case 4: // 128
469 - $this->key_size = 16;
470 - break;
471 - case 5: // 160
472 - case 6: // 192
473 - $this->key_size = 24;
474 - break;
475 - case 7: // 224
476 - case 8: // 256
477 - $this->key_size = 32;
478 - }
479 -
480 - $this->key = str_pad(substr($this->key, 0, $this->key_size), $this->key_size, chr(0));
481 - $this->encryptIV = $this->decryptIV = $this->iv = str_pad(substr($this->iv, 0, 16), 16, chr(0));
482 -
483 - if (!isset($this->enmcrypt)) {
484 - $mode = $this->mode;
485 - //$mode = $this->mode == CRYPT_AES_MODE_CTR ? MCRYPT_MODE_ECB : $this->mode;
486 -
487 - $this->demcrypt = mcrypt_module_open(MCRYPT_RIJNDAEL_128, '', $mode, '');
488 - $this->enmcrypt = mcrypt_module_open(MCRYPT_RIJNDAEL_128, '', $mode, '');
489 - } // else should mcrypt_generic_deinit be called?
490 -
491 - mcrypt_generic_init($this->demcrypt, $this->key, $this->iv);
492 - mcrypt_generic_init($this->enmcrypt, $this->key, $this->iv);
493 -
494 - $this->changed = false;
495 196 }
496 -
497 - /**
498 - * Encrypts a block
499 - *
500 - * Optimized over Crypt_Rijndael's implementation by means of loop unrolling.
501 - *
502 - * @see Crypt_Rijndael::_encryptBlock()
503 - * @access private
504 - * @param String $in
505 - * @return String
506 - */
507 - function _encryptBlock($in)
508 - {
509 - $state = unpack('N*word', $in);
510 -
511 - $Nr = $this->Nr;
512 - $w = $this->w;
513 - $t0 = $this->t0;
514 - $t1 = $this->t1;
515 - $t2 = $this->t2;
516 - $t3 = $this->t3;
517 -
518 - // addRoundKey and reindex $state
519 - $state = array(
520 - $state['word1'] ^ $w[0][0],
521 - $state['word2'] ^ $w[0][1],
522 - $state['word3'] ^ $w[0][2],
523 - $state['word4'] ^ $w[0][3]
524 - );
525 -
526 - // shiftRows + subWord + mixColumns + addRoundKey
527 - // we could loop unroll this and use if statements to do more rounds as necessary, but, in my tests, that yields
528 - // only a marginal improvement. since that also, imho, hinders the readability of the code, i've opted not to do it.
529 - for ($round = 1; $round < $this->Nr; $round++) {
530 - $state = array(
531 - $t0[$state[0] & 0xFF000000] ^ $t1[$state[1] & 0x00FF0000] ^ $t2[$state[2] & 0x0000FF00] ^ $t3[$state[3] & 0x000000FF] ^ $w[$round][0],
532 - $t0[$state[1] & 0xFF000000] ^ $t1[$state[2] & 0x00FF0000] ^ $t2[$state[3] & 0x0000FF00] ^ $t3[$state[0] & 0x000000FF] ^ $w[$round][1],
533 - $t0[$state[2] & 0xFF000000] ^ $t1[$state[3] & 0x00FF0000] ^ $t2[$state[0] & 0x0000FF00] ^ $t3[$state[1] & 0x000000FF] ^ $w[$round][2],
534 - $t0[$state[3] & 0xFF000000] ^ $t1[$state[0] & 0x00FF0000] ^ $t2[$state[1] & 0x0000FF00] ^ $t3[$state[2] & 0x000000FF] ^ $w[$round][3]
535 - );
536 -
537 - }
538 -
539 - // subWord
540 - $state = array(
541 - $this->_subWord($state[0]),
542 - $this->_subWord($state[1]),
543 - $this->_subWord($state[2]),
544 - $this->_subWord($state[3])
545 - );
546 -
547 - // shiftRows + addRoundKey
548 - $state = array(
549 - ($state[0] & 0xFF000000) ^ ($state[1] & 0x00FF0000) ^ ($state[2] & 0x0000FF00) ^ ($state[3] & 0x000000FF) ^ $this->w[$this->Nr][0],
550 - ($state[1] & 0xFF000000) ^ ($state[2] & 0x00FF0000) ^ ($state[3] & 0x0000FF00) ^ ($state[0] & 0x000000FF) ^ $this->w[$this->Nr][1],
551 - ($state[2] & 0xFF000000) ^ ($state[3] & 0x00FF0000) ^ ($state[0] & 0x0000FF00) ^ ($state[1] & 0x000000FF) ^ $this->w[$this->Nr][2],
552 - ($state[3] & 0xFF000000) ^ ($state[0] & 0x00FF0000) ^ ($state[1] & 0x0000FF00) ^ ($state[2] & 0x000000FF) ^ $this->w[$this->Nr][3]
553 - );
554 -
555 - return pack('N*', $state[0], $state[1], $state[2], $state[3]);
556 - }
557 -
558 - /**
559 - * Decrypts a block
560 - *
561 - * Optimized over Crypt_Rijndael's implementation by means of loop unrolling.
562 - *
563 - * @see Crypt_Rijndael::_decryptBlock()
564 - * @access private
565 - * @param String $in
566 - * @return String
567 - */
568 - function _decryptBlock($in)
569 - {
570 - $state = unpack('N*word', $in);
571 -
572 - $Nr = $this->Nr;
573 - $dw = $this->dw;
574 - $dt0 = $this->dt0;
575 - $dt1 = $this->dt1;
576 - $dt2 = $this->dt2;
577 - $dt3 = $this->dt3;
578 -
579 - // addRoundKey and reindex $state
580 - $state = array(
581 - $state['word1'] ^ $dw[$this->Nr][0],
582 - $state['word2'] ^ $dw[$this->Nr][1],
583 - $state['word3'] ^ $dw[$this->Nr][2],
584 - $state['word4'] ^ $dw[$this->Nr][3]
585 - );
586 -
587 -
588 - // invShiftRows + invSubBytes + invMixColumns + addRoundKey
589 - for ($round = $this->Nr - 1; $round > 0; $round--) {
590 - $state = array(
591 - $dt0[$state[0] & 0xFF000000] ^ $dt1[$state[3] & 0x00FF0000] ^ $dt2[$state[2] & 0x0000FF00] ^ $dt3[$state[1] & 0x000000FF] ^ $dw[$round][0],
592 - $dt0[$state[1] & 0xFF000000] ^ $dt1[$state[0] & 0x00FF0000] ^ $dt2[$state[3] & 0x0000FF00] ^ $dt3[$state[2] & 0x000000FF] ^ $dw[$round][1],
593 - $dt0[$state[2] & 0xFF000000] ^ $dt1[$state[1] & 0x00FF0000] ^ $dt2[$state[0] & 0x0000FF00] ^ $dt3[$state[3] & 0x000000FF] ^ $dw[$round][2],
594 - $dt0[$state[3] & 0xFF000000] ^ $dt1[$state[2] & 0x00FF0000] ^ $dt2[$state[1] & 0x0000FF00] ^ $dt3[$state[0] & 0x000000FF] ^ $dw[$round][3]
595 - );
596 - }
597 -
598 - // invShiftRows + invSubWord + addRoundKey
599 - $state = array(
600 - $this->_invSubWord(($state[0] & 0xFF000000) ^ ($state[3] & 0x00FF0000) ^ ($state[2] & 0x0000FF00) ^ ($state[1] & 0x000000FF)) ^ $dw[0][0],
601 - $this->_invSubWord(($state[1] & 0xFF000000) ^ ($state[0] & 0x00FF0000) ^ ($state[3] & 0x0000FF00) ^ ($state[2] & 0x000000FF)) ^ $dw[0][1],
602 - $this->_invSubWord(($state[2] & 0xFF000000) ^ ($state[1] & 0x00FF0000) ^ ($state[0] & 0x0000FF00) ^ ($state[3] & 0x000000FF)) ^ $dw[0][2],
603 - $this->_invSubWord(($state[3] & 0xFF000000) ^ ($state[2] & 0x00FF0000) ^ ($state[1] & 0x0000FF00) ^ ($state[0] & 0x000000FF)) ^ $dw[0][3]
604 - );
605 -
606 - return pack('N*', $state[0], $state[1], $state[2], $state[3]);
607 - }
608 197 }
609 -
610 -// vim: ts=4:sw=4:et:
611 -// vim6: fdl=1: