ILIAS  release_5-4 Revision v5.4.26-12-gabc799a52e6
Rijndael.php
Go to the documentation of this file.
1<?php
2
55namespace phpseclib\Crypt;
56
58
66class Rijndael extends Base
67{
82 var $cipher_name_mcrypt = 'rijndael-128';
83
92 var $password_default_salt = 'phpseclib';
93
101 var $w;
102
110 var $dw;
111
123 var $Nb = 4;
124
136 var $key_length = 16;
137
146 var $Nk = 4;
147
155 var $Nr;
156
163 var $c;
164
171 var $kl;
172
193 function setKeyLength($length)
194 {
195 switch (true) {
196 case $length <= 128:
197 $this->key_length = 16;
198 break;
199 case $length <= 160:
200 $this->key_length = 20;
201 break;
202 case $length <= 192:
203 $this->key_length = 24;
204 break;
205 case $length <= 224:
206 $this->key_length = 28;
207 break;
208 default:
209 $this->key_length = 32;
210 }
211
212 parent::setKeyLength($length);
213 }
214
224 function setBlockLength($length)
225 {
226 $length >>= 5;
227 if ($length > 8) {
228 $length = 8;
229 } elseif ($length < 4) {
230 $length = 4;
231 }
232 $this->Nb = $length;
233 $this->block_size = $length << 2;
234 $this->changed = true;
235 $this->_setEngine();
236 }
237
249 {
250 switch ($engine) {
252 if ($this->block_size != 16) {
253 return false;
254 }
255 $this->cipher_name_openssl_ecb = 'aes-' . ($this->key_length << 3) . '-ecb';
256 $this->cipher_name_openssl = 'aes-' . ($this->key_length << 3) . '-' . $this->_openssl_translate_mode();
257 break;
259 $this->cipher_name_mcrypt = 'rijndael-' . ($this->block_size << 3);
260 if ($this->key_length % 8) { // is it a 160/224-bit key?
261 // mcrypt is not usable for them, only for 128/192/256-bit keys
262 return false;
263 }
264 }
265
266 return parent::isValidEngine($engine);
267 }
268
277 {
278 static $tables;
279 if (empty($tables)) {
280 $tables = &$this->_getTables();
281 }
282 $t0 = $tables[0];
283 $t1 = $tables[1];
284 $t2 = $tables[2];
285 $t3 = $tables[3];
286 $sbox = $tables[4];
287
288 $state = array();
289 $words = unpack('N*', $in);
290
291 $c = $this->c;
292 $w = $this->w;
293 $Nb = $this->Nb;
294 $Nr = $this->Nr;
295
296 // addRoundKey
297 $wc = $Nb - 1;
298 foreach ($words as $word) {
299 $state[] = $word ^ $w[++$wc];
300 }
301
302 // fips-197.pdf#page=19, "Figure 5. Pseudo Code for the Cipher", states that this loop has four components -
303 // subBytes, shiftRows, mixColumns, and addRoundKey. fips-197.pdf#page=30, "Implementation Suggestions Regarding
304 // Various Platforms" suggests that performs enhanced implementations are described in Rijndael-ammended.pdf.
305 // Rijndael-ammended.pdf#page=20, "Implementation aspects / 32-bit processor", discusses such an optimization.
306 // Unfortunately, the description given there is not quite correct. Per aes.spec.v316.pdf#page=19 [1],
307 // equation (7.4.7) is supposed to use addition instead of subtraction, so we'll do that here, as well.
308
309 // [1] http://fp.gladman.plus.com/cryptography_technology/rijndael/aes.spec.v316.pdf
310 $temp = array();
311 for ($round = 1; $round < $Nr; ++$round) {
312 $i = 0; // $c[0] == 0
313 $j = $c[1];
314 $k = $c[2];
315 $l = $c[3];
316
317 while ($i < $Nb) {
318 $temp[$i] = $t0[$state[$i] >> 24 & 0x000000FF] ^
319 $t1[$state[$j] >> 16 & 0x000000FF] ^
320 $t2[$state[$k] >> 8 & 0x000000FF] ^
321 $t3[$state[$l] & 0x000000FF] ^
322 $w[++$wc];
323 ++$i;
324 $j = ($j + 1) % $Nb;
325 $k = ($k + 1) % $Nb;
326 $l = ($l + 1) % $Nb;
327 }
328 $state = $temp;
329 }
330
331 // subWord
332 for ($i = 0; $i < $Nb; ++$i) {
333 $state[$i] = $sbox[$state[$i] & 0x000000FF] |
334 ($sbox[$state[$i] >> 8 & 0x000000FF] << 8) |
335 ($sbox[$state[$i] >> 16 & 0x000000FF] << 16) |
336 ($sbox[$state[$i] >> 24 & 0x000000FF] << 24);
337 }
338
339 // shiftRows + addRoundKey
340 $i = 0; // $c[0] == 0
341 $j = $c[1];
342 $k = $c[2];
343 $l = $c[3];
344 while ($i < $Nb) {
345 $temp[$i] = ($state[$i] & 0xFF000000) ^
346 ($state[$j] & 0x00FF0000) ^
347 ($state[$k] & 0x0000FF00) ^
348 ($state[$l] & 0x000000FF) ^
349 $w[$i];
350 ++$i;
351 $j = ($j + 1) % $Nb;
352 $k = ($k + 1) % $Nb;
353 $l = ($l + 1) % $Nb;
354 }
355
356 switch ($Nb) {
357 case 8:
358 return pack('N*', $temp[0], $temp[1], $temp[2], $temp[3], $temp[4], $temp[5], $temp[6], $temp[7]);
359 case 7:
360 return pack('N*', $temp[0], $temp[1], $temp[2], $temp[3], $temp[4], $temp[5], $temp[6]);
361 case 6:
362 return pack('N*', $temp[0], $temp[1], $temp[2], $temp[3], $temp[4], $temp[5]);
363 case 5:
364 return pack('N*', $temp[0], $temp[1], $temp[2], $temp[3], $temp[4]);
365 default:
366 return pack('N*', $temp[0], $temp[1], $temp[2], $temp[3]);
367 }
368 }
369
378 {
379 static $invtables;
380 if (empty($invtables)) {
381 $invtables = &$this->_getInvTables();
382 }
383 $dt0 = $invtables[0];
384 $dt1 = $invtables[1];
385 $dt2 = $invtables[2];
386 $dt3 = $invtables[3];
387 $isbox = $invtables[4];
388
389 $state = array();
390 $words = unpack('N*', $in);
391
392 $c = $this->c;
393 $dw = $this->dw;
394 $Nb = $this->Nb;
395 $Nr = $this->Nr;
396
397 // addRoundKey
398 $wc = $Nb - 1;
399 foreach ($words as $word) {
400 $state[] = $word ^ $dw[++$wc];
401 }
402
403 $temp = array();
404 for ($round = $Nr - 1; $round > 0; --$round) {
405 $i = 0; // $c[0] == 0
406 $j = $Nb - $c[1];
407 $k = $Nb - $c[2];
408 $l = $Nb - $c[3];
409
410 while ($i < $Nb) {
411 $temp[$i] = $dt0[$state[$i] >> 24 & 0x000000FF] ^
412 $dt1[$state[$j] >> 16 & 0x000000FF] ^
413 $dt2[$state[$k] >> 8 & 0x000000FF] ^
414 $dt3[$state[$l] & 0x000000FF] ^
415 $dw[++$wc];
416 ++$i;
417 $j = ($j + 1) % $Nb;
418 $k = ($k + 1) % $Nb;
419 $l = ($l + 1) % $Nb;
420 }
421 $state = $temp;
422 }
423
424 // invShiftRows + invSubWord + addRoundKey
425 $i = 0; // $c[0] == 0
426 $j = $Nb - $c[1];
427 $k = $Nb - $c[2];
428 $l = $Nb - $c[3];
429
430 while ($i < $Nb) {
431 $word = ($state[$i] & 0xFF000000) |
432 ($state[$j] & 0x00FF0000) |
433 ($state[$k] & 0x0000FF00) |
434 ($state[$l] & 0x000000FF);
435
436 $temp[$i] = $dw[$i] ^ ($isbox[$word & 0x000000FF] |
437 ($isbox[$word >> 8 & 0x000000FF] << 8) |
438 ($isbox[$word >> 16 & 0x000000FF] << 16) |
439 ($isbox[$word >> 24 & 0x000000FF] << 24));
440 ++$i;
441 $j = ($j + 1) % $Nb;
442 $k = ($k + 1) % $Nb;
443 $l = ($l + 1) % $Nb;
444 }
445
446 switch ($Nb) {
447 case 8:
448 return pack('N*', $temp[0], $temp[1], $temp[2], $temp[3], $temp[4], $temp[5], $temp[6], $temp[7]);
449 case 7:
450 return pack('N*', $temp[0], $temp[1], $temp[2], $temp[3], $temp[4], $temp[5], $temp[6]);
451 case 6:
452 return pack('N*', $temp[0], $temp[1], $temp[2], $temp[3], $temp[4], $temp[5]);
453 case 5:
454 return pack('N*', $temp[0], $temp[1], $temp[2], $temp[3], $temp[4]);
455 default:
456 return pack('N*', $temp[0], $temp[1], $temp[2], $temp[3]);
457 }
458 }
459
466 function _setupKey()
467 {
468 // Each number in $rcon is equal to the previous number multiplied by two in Rijndael's finite field.
469 // See http://en.wikipedia.org/wiki/Finite_field_arithmetic#Multiplicative_inverse
470 static $rcon = array(0,
471 0x01000000, 0x02000000, 0x04000000, 0x08000000, 0x10000000,
472 0x20000000, 0x40000000, 0x80000000, 0x1B000000, 0x36000000,
473 0x6C000000, 0xD8000000, 0xAB000000, 0x4D000000, 0x9A000000,
474 0x2F000000, 0x5E000000, 0xBC000000, 0x63000000, 0xC6000000,
475 0x97000000, 0x35000000, 0x6A000000, 0xD4000000, 0xB3000000,
476 0x7D000000, 0xFA000000, 0xEF000000, 0xC5000000, 0x91000000
477 );
478
479 if (isset($this->kl['key']) && $this->key === $this->kl['key'] && $this->key_length === $this->kl['key_length'] && $this->block_size === $this->kl['block_size']) {
480 // already expanded
481 return;
482 }
483 $this->kl = array('key' => $this->key, 'key_length' => $this->key_length, 'block_size' => $this->block_size);
484
485 $this->Nk = $this->key_length >> 2;
486 // see Rijndael-ammended.pdf#page=44
487 $this->Nr = max($this->Nk, $this->Nb) + 6;
488
489 // shift offsets for Nb = 5, 7 are defined in Rijndael-ammended.pdf#page=44,
490 // "Table 8: Shift offsets in Shiftrow for the alternative block lengths"
491 // shift offsets for Nb = 4, 6, 8 are defined in Rijndael-ammended.pdf#page=14,
492 // "Table 2: Shift offsets for different block lengths"
493 switch ($this->Nb) {
494 case 4:
495 case 5:
496 case 6:
497 $this->c = array(0, 1, 2, 3);
498 break;
499 case 7:
500 $this->c = array(0, 1, 2, 4);
501 break;
502 case 8:
503 $this->c = array(0, 1, 3, 4);
504 }
505
506 $w = array_values(unpack('N*words', $this->key));
507
508 $length = $this->Nb * ($this->Nr + 1);
509 for ($i = $this->Nk; $i < $length; $i++) {
510 $temp = $w[$i - 1];
511 if ($i % $this->Nk == 0) {
512 // according to <http://php.net/language.types.integer>, "the size of an integer is platform-dependent".
513 // on a 32-bit machine, it's 32-bits, and on a 64-bit machine, it's 64-bits. on a 32-bit machine,
514 // 0xFFFFFFFF << 8 == 0xFFFFFF00, but on a 64-bit machine, it equals 0xFFFFFFFF00. as such, doing 'and'
515 // with 0xFFFFFFFF (or 0xFFFFFF00) on a 32-bit machine is unnecessary, but on a 64-bit machine, it is.
516 $temp = (($temp << 8) & 0xFFFFFF00) | (($temp >> 24) & 0x000000FF); // rotWord
517 $temp = $this->_subWord($temp) ^ $rcon[$i / $this->Nk];
518 } elseif ($this->Nk > 6 && $i % $this->Nk == 4) {
519 $temp = $this->_subWord($temp);
520 }
521 $w[$i] = $w[$i - $this->Nk] ^ $temp;
522 }
523
524 // convert the key schedule from a vector of $Nb * ($Nr + 1) length to a matrix with $Nr + 1 rows and $Nb columns
525 // and generate the inverse key schedule. more specifically,
526 // according to <http://csrc.nist.gov/archive/aes/rijndael/Rijndael-ammended.pdf#page=23> (section 5.3.3),
527 // "The key expansion for the Inverse Cipher is defined as follows:
528 // 1. Apply the Key Expansion.
529 // 2. Apply InvMixColumn to all Round Keys except the first and the last one."
530 // also, see fips-197.pdf#page=27, "5.3.5 Equivalent Inverse Cipher"
531 list($dt0, $dt1, $dt2, $dt3) = $this->_getInvTables();
532 $temp = $this->w = $this->dw = array();
533 for ($i = $row = $col = 0; $i < $length; $i++, $col++) {
534 if ($col == $this->Nb) {
535 if ($row == 0) {
536 $this->dw[0] = $this->w[0];
537 } else {
538 // subWord + invMixColumn + invSubWord = invMixColumn
539 $j = 0;
540 while ($j < $this->Nb) {
541 $dw = $this->_subWord($this->w[$row][$j]);
542 $temp[$j] = $dt0[$dw >> 24 & 0x000000FF] ^
543 $dt1[$dw >> 16 & 0x000000FF] ^
544 $dt2[$dw >> 8 & 0x000000FF] ^
545 $dt3[$dw & 0x000000FF];
546 $j++;
547 }
548 $this->dw[$row] = $temp;
549 }
550
551 $col = 0;
552 $row++;
553 }
554 $this->w[$row][$col] = $w[$i];
555 }
556
557 $this->dw[$row] = $this->w[$row];
558
559 // Converting to 1-dim key arrays (both ascending)
560 $this->dw = array_reverse($this->dw);
561 $w = array_pop($this->w);
562 $dw = array_pop($this->dw);
563 foreach ($this->w as $r => $wr) {
564 foreach ($wr as $c => $wc) {
565 $w[] = $wc;
566 $dw[] = $this->dw[$r][$c];
567 }
568 }
569 $this->w = $w;
570 $this->dw = $dw;
571 }
572
579 function _subWord($word)
580 {
581 static $sbox;
582 if (empty($sbox)) {
583 list(, , , , $sbox) = $this->_getTables();
584 }
585
586 return $sbox[$word & 0x000000FF] |
587 ($sbox[$word >> 8 & 0x000000FF] << 8) |
588 ($sbox[$word >> 16 & 0x000000FF] << 16) |
589 ($sbox[$word >> 24 & 0x000000FF] << 24);
590 }
591
601 function &_getTables()
602 {
603 static $tables;
604 if (empty($tables)) {
605 // according to <http://csrc.nist.gov/archive/aes/rijndael/Rijndael-ammended.pdf#page=19> (section 5.2.1),
606 // precomputed tables can be used in the mixColumns phase. in that example, they're assigned t0...t3, so
607 // those are the names we'll use.
608 $t3 = array_map('intval', array(
609 // with array_map('intval', ...) we ensure we have only int's and not
610 // some slower floats converted by php automatically on high values
611 0x6363A5C6, 0x7C7C84F8, 0x777799EE, 0x7B7B8DF6, 0xF2F20DFF, 0x6B6BBDD6, 0x6F6FB1DE, 0xC5C55491,
612 0x30305060, 0x01010302, 0x6767A9CE, 0x2B2B7D56, 0xFEFE19E7, 0xD7D762B5, 0xABABE64D, 0x76769AEC,
613 0xCACA458F, 0x82829D1F, 0xC9C94089, 0x7D7D87FA, 0xFAFA15EF, 0x5959EBB2, 0x4747C98E, 0xF0F00BFB,
614 0xADADEC41, 0xD4D467B3, 0xA2A2FD5F, 0xAFAFEA45, 0x9C9CBF23, 0xA4A4F753, 0x727296E4, 0xC0C05B9B,
615 0xB7B7C275, 0xFDFD1CE1, 0x9393AE3D, 0x26266A4C, 0x36365A6C, 0x3F3F417E, 0xF7F702F5, 0xCCCC4F83,
616 0x34345C68, 0xA5A5F451, 0xE5E534D1, 0xF1F108F9, 0x717193E2, 0xD8D873AB, 0x31315362, 0x15153F2A,
617 0x04040C08, 0xC7C75295, 0x23236546, 0xC3C35E9D, 0x18182830, 0x9696A137, 0x05050F0A, 0x9A9AB52F,
618 0x0707090E, 0x12123624, 0x80809B1B, 0xE2E23DDF, 0xEBEB26CD, 0x2727694E, 0xB2B2CD7F, 0x75759FEA,
619 0x09091B12, 0x83839E1D, 0x2C2C7458, 0x1A1A2E34, 0x1B1B2D36, 0x6E6EB2DC, 0x5A5AEEB4, 0xA0A0FB5B,
620 0x5252F6A4, 0x3B3B4D76, 0xD6D661B7, 0xB3B3CE7D, 0x29297B52, 0xE3E33EDD, 0x2F2F715E, 0x84849713,
621 0x5353F5A6, 0xD1D168B9, 0x00000000, 0xEDED2CC1, 0x20206040, 0xFCFC1FE3, 0xB1B1C879, 0x5B5BEDB6,
622 0x6A6ABED4, 0xCBCB468D, 0xBEBED967, 0x39394B72, 0x4A4ADE94, 0x4C4CD498, 0x5858E8B0, 0xCFCF4A85,
623 0xD0D06BBB, 0xEFEF2AC5, 0xAAAAE54F, 0xFBFB16ED, 0x4343C586, 0x4D4DD79A, 0x33335566, 0x85859411,
624 0x4545CF8A, 0xF9F910E9, 0x02020604, 0x7F7F81FE, 0x5050F0A0, 0x3C3C4478, 0x9F9FBA25, 0xA8A8E34B,
625 0x5151F3A2, 0xA3A3FE5D, 0x4040C080, 0x8F8F8A05, 0x9292AD3F, 0x9D9DBC21, 0x38384870, 0xF5F504F1,
626 0xBCBCDF63, 0xB6B6C177, 0xDADA75AF, 0x21216342, 0x10103020, 0xFFFF1AE5, 0xF3F30EFD, 0xD2D26DBF,
627 0xCDCD4C81, 0x0C0C1418, 0x13133526, 0xECEC2FC3, 0x5F5FE1BE, 0x9797A235, 0x4444CC88, 0x1717392E,
628 0xC4C45793, 0xA7A7F255, 0x7E7E82FC, 0x3D3D477A, 0x6464ACC8, 0x5D5DE7BA, 0x19192B32, 0x737395E6,
629 0x6060A0C0, 0x81819819, 0x4F4FD19E, 0xDCDC7FA3, 0x22226644, 0x2A2A7E54, 0x9090AB3B, 0x8888830B,
630 0x4646CA8C, 0xEEEE29C7, 0xB8B8D36B, 0x14143C28, 0xDEDE79A7, 0x5E5EE2BC, 0x0B0B1D16, 0xDBDB76AD,
631 0xE0E03BDB, 0x32325664, 0x3A3A4E74, 0x0A0A1E14, 0x4949DB92, 0x06060A0C, 0x24246C48, 0x5C5CE4B8,
632 0xC2C25D9F, 0xD3D36EBD, 0xACACEF43, 0x6262A6C4, 0x9191A839, 0x9595A431, 0xE4E437D3, 0x79798BF2,
633 0xE7E732D5, 0xC8C8438B, 0x3737596E, 0x6D6DB7DA, 0x8D8D8C01, 0xD5D564B1, 0x4E4ED29C, 0xA9A9E049,
634 0x6C6CB4D8, 0x5656FAAC, 0xF4F407F3, 0xEAEA25CF, 0x6565AFCA, 0x7A7A8EF4, 0xAEAEE947, 0x08081810,
635 0xBABAD56F, 0x787888F0, 0x25256F4A, 0x2E2E725C, 0x1C1C2438, 0xA6A6F157, 0xB4B4C773, 0xC6C65197,
636 0xE8E823CB, 0xDDDD7CA1, 0x74749CE8, 0x1F1F213E, 0x4B4BDD96, 0xBDBDDC61, 0x8B8B860D, 0x8A8A850F,
637 0x707090E0, 0x3E3E427C, 0xB5B5C471, 0x6666AACC, 0x4848D890, 0x03030506, 0xF6F601F7, 0x0E0E121C,
638 0x6161A3C2, 0x35355F6A, 0x5757F9AE, 0xB9B9D069, 0x86869117, 0xC1C15899, 0x1D1D273A, 0x9E9EB927,
639 0xE1E138D9, 0xF8F813EB, 0x9898B32B, 0x11113322, 0x6969BBD2, 0xD9D970A9, 0x8E8E8907, 0x9494A733,
640 0x9B9BB62D, 0x1E1E223C, 0x87879215, 0xE9E920C9, 0xCECE4987, 0x5555FFAA, 0x28287850, 0xDFDF7AA5,
641 0x8C8C8F03, 0xA1A1F859, 0x89898009, 0x0D0D171A, 0xBFBFDA65, 0xE6E631D7, 0x4242C684, 0x6868B8D0,
642 0x4141C382, 0x9999B029, 0x2D2D775A, 0x0F0F111E, 0xB0B0CB7B, 0x5454FCA8, 0xBBBBD66D, 0x16163A2C
643 ));
644
645 foreach ($t3 as $t3i) {
646 $t0[] = (($t3i << 24) & 0xFF000000) | (($t3i >> 8) & 0x00FFFFFF);
647 $t1[] = (($t3i << 16) & 0xFFFF0000) | (($t3i >> 16) & 0x0000FFFF);
648 $t2[] = (($t3i << 8) & 0xFFFFFF00) | (($t3i >> 24) & 0x000000FF);
649 }
650
651 $tables = array(
652 // The Precomputed mixColumns tables t0 - t3
653 $t0,
654 $t1,
655 $t2,
656 $t3,
657 // The SubByte S-Box
658 array(
659 0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5, 0x30, 0x01, 0x67, 0x2B, 0xFE, 0xD7, 0xAB, 0x76,
660 0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0, 0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0,
661 0xB7, 0xFD, 0x93, 0x26, 0x36, 0x3F, 0xF7, 0xCC, 0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15,
662 0x04, 0xC7, 0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A, 0x07, 0x12, 0x80, 0xE2, 0xEB, 0x27, 0xB2, 0x75,
663 0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0xA0, 0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84,
664 0x53, 0xD1, 0x00, 0xED, 0x20, 0xFC, 0xB1, 0x5B, 0x6A, 0xCB, 0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF,
665 0xD0, 0xEF, 0xAA, 0xFB, 0x43, 0x4D, 0x33, 0x85, 0x45, 0xF9, 0x02, 0x7F, 0x50, 0x3C, 0x9F, 0xA8,
666 0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5, 0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2,
667 0xCD, 0x0C, 0x13, 0xEC, 0x5F, 0x97, 0x44, 0x17, 0xC4, 0xA7, 0x7E, 0x3D, 0x64, 0x5D, 0x19, 0x73,
668 0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A, 0x90, 0x88, 0x46, 0xEE, 0xB8, 0x14, 0xDE, 0x5E, 0x0B, 0xDB,
669 0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C, 0xC2, 0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79,
670 0xE7, 0xC8, 0x37, 0x6D, 0x8D, 0xD5, 0x4E, 0xA9, 0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A, 0xAE, 0x08,
671 0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6, 0xE8, 0xDD, 0x74, 0x1F, 0x4B, 0xBD, 0x8B, 0x8A,
672 0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E, 0x61, 0x35, 0x57, 0xB9, 0x86, 0xC1, 0x1D, 0x9E,
673 0xE1, 0xF8, 0x98, 0x11, 0x69, 0xD9, 0x8E, 0x94, 0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF,
674 0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68, 0x41, 0x99, 0x2D, 0x0F, 0xB0, 0x54, 0xBB, 0x16
675 )
676 );
677 }
678 return $tables;
679 }
680
690 function &_getInvTables()
691 {
692 static $tables;
693 if (empty($tables)) {
694 $dt3 = array_map('intval', array(
695 0xF4A75051, 0x4165537E, 0x17A4C31A, 0x275E963A, 0xAB6BCB3B, 0x9D45F11F, 0xFA58ABAC, 0xE303934B,
696 0x30FA5520, 0x766DF6AD, 0xCC769188, 0x024C25F5, 0xE5D7FC4F, 0x2ACBD7C5, 0x35448026, 0x62A38FB5,
697 0xB15A49DE, 0xBA1B6725, 0xEA0E9845, 0xFEC0E15D, 0x2F7502C3, 0x4CF01281, 0x4697A38D, 0xD3F9C66B,
698 0x8F5FE703, 0x929C9515, 0x6D7AEBBF, 0x5259DA95, 0xBE832DD4, 0x7421D358, 0xE0692949, 0xC9C8448E,
699 0xC2896A75, 0x8E7978F4, 0x583E6B99, 0xB971DD27, 0xE14FB6BE, 0x88AD17F0, 0x20AC66C9, 0xCE3AB47D,
700 0xDF4A1863, 0x1A3182E5, 0x51336097, 0x537F4562, 0x6477E0B1, 0x6BAE84BB, 0x81A01CFE, 0x082B94F9,
701 0x48685870, 0x45FD198F, 0xDE6C8794, 0x7BF8B752, 0x73D323AB, 0x4B02E272, 0x1F8F57E3, 0x55AB2A66,
702 0xEB2807B2, 0xB5C2032F, 0xC57B9A86, 0x3708A5D3, 0x2887F230, 0xBFA5B223, 0x036ABA02, 0x16825CED,
703 0xCF1C2B8A, 0x79B492A7, 0x07F2F0F3, 0x69E2A14E, 0xDAF4CD65, 0x05BED506, 0x34621FD1, 0xA6FE8AC4,
704 0x2E539D34, 0xF355A0A2, 0x8AE13205, 0xF6EB75A4, 0x83EC390B, 0x60EFAA40, 0x719F065E, 0x6E1051BD,
705 0x218AF93E, 0xDD063D96, 0x3E05AEDD, 0xE6BD464D, 0x548DB591, 0xC45D0571, 0x06D46F04, 0x5015FF60,
706 0x98FB2419, 0xBDE997D6, 0x4043CC89, 0xD99E7767, 0xE842BDB0, 0x898B8807, 0x195B38E7, 0xC8EEDB79,
707 0x7C0A47A1, 0x420FE97C, 0x841EC9F8, 0x00000000, 0x80868309, 0x2BED4832, 0x1170AC1E, 0x5A724E6C,
708 0x0EFFFBFD, 0x8538560F, 0xAED51E3D, 0x2D392736, 0x0FD9640A, 0x5CA62168, 0x5B54D19B, 0x362E3A24,
709 0x0A67B10C, 0x57E70F93, 0xEE96D2B4, 0x9B919E1B, 0xC0C54F80, 0xDC20A261, 0x774B695A, 0x121A161C,
710 0x93BA0AE2, 0xA02AE5C0, 0x22E0433C, 0x1B171D12, 0x090D0B0E, 0x8BC7ADF2, 0xB6A8B92D, 0x1EA9C814,
711 0xF1198557, 0x75074CAF, 0x99DDBBEE, 0x7F60FDA3, 0x01269FF7, 0x72F5BC5C, 0x663BC544, 0xFB7E345B,
712 0x4329768B, 0x23C6DCCB, 0xEDFC68B6, 0xE4F163B8, 0x31DCCAD7, 0x63851042, 0x97224013, 0xC6112084,
713 0x4A247D85, 0xBB3DF8D2, 0xF93211AE, 0x29A16DC7, 0x9E2F4B1D, 0xB230F3DC, 0x8652EC0D, 0xC1E3D077,
714 0xB3166C2B, 0x70B999A9, 0x9448FA11, 0xE9642247, 0xFC8CC4A8, 0xF03F1AA0, 0x7D2CD856, 0x3390EF22,
715 0x494EC787, 0x38D1C1D9, 0xCAA2FE8C, 0xD40B3698, 0xF581CFA6, 0x7ADE28A5, 0xB78E26DA, 0xADBFA43F,
716 0x3A9DE42C, 0x78920D50, 0x5FCC9B6A, 0x7E466254, 0x8D13C2F6, 0xD8B8E890, 0x39F75E2E, 0xC3AFF582,
717 0x5D80BE9F, 0xD0937C69, 0xD52DA96F, 0x2512B3CF, 0xAC993BC8, 0x187DA710, 0x9C636EE8, 0x3BBB7BDB,
718 0x267809CD, 0x5918F46E, 0x9AB701EC, 0x4F9AA883, 0x956E65E6, 0xFFE67EAA, 0xBCCF0821, 0x15E8E6EF,
719 0xE79BD9BA, 0x6F36CE4A, 0x9F09D4EA, 0xB07CD629, 0xA4B2AF31, 0x3F23312A, 0xA59430C6, 0xA266C035,
720 0x4EBC3774, 0x82CAA6FC, 0x90D0B0E0, 0xA7D81533, 0x04984AF1, 0xECDAF741, 0xCD500E7F, 0x91F62F17,
721 0x4DD68D76, 0xEFB04D43, 0xAA4D54CC, 0x9604DFE4, 0xD1B5E39E, 0x6A881B4C, 0x2C1FB8C1, 0x65517F46,
722 0x5EEA049D, 0x8C355D01, 0x877473FA, 0x0B412EFB, 0x671D5AB3, 0xDBD25292, 0x105633E9, 0xD647136D,
723 0xD7618C9A, 0xA10C7A37, 0xF8148E59, 0x133C89EB, 0xA927EECE, 0x61C935B7, 0x1CE5EDE1, 0x47B13C7A,
724 0xD2DF599C, 0xF2733F55, 0x14CE7918, 0xC737BF73, 0xF7CDEA53, 0xFDAA5B5F, 0x3D6F14DF, 0x44DB8678,
725 0xAFF381CA, 0x68C43EB9, 0x24342C38, 0xA3405FC2, 0x1DC37216, 0xE2250CBC, 0x3C498B28, 0x0D9541FF,
726 0xA8017139, 0x0CB3DE08, 0xB4E49CD8, 0x56C19064, 0xCB84617B, 0x32B670D5, 0x6C5C7448, 0xB85742D0
727 ));
728
729 foreach ($dt3 as $dt3i) {
730 $dt0[] = (($dt3i << 24) & 0xFF000000) | (($dt3i >> 8) & 0x00FFFFFF);
731 $dt1[] = (($dt3i << 16) & 0xFFFF0000) | (($dt3i >> 16) & 0x0000FFFF);
732 $dt2[] = (($dt3i << 8) & 0xFFFFFF00) | (($dt3i >> 24) & 0x000000FF);
733 };
734
735 $tables = array(
736 // The Precomputed inverse mixColumns tables dt0 - dt3
737 $dt0,
738 $dt1,
739 $dt2,
740 $dt3,
741 // The inverse SubByte S-Box
742 array(
743 0x52, 0x09, 0x6A, 0xD5, 0x30, 0x36, 0xA5, 0x38, 0xBF, 0x40, 0xA3, 0x9E, 0x81, 0xF3, 0xD7, 0xFB,
744 0x7C, 0xE3, 0x39, 0x82, 0x9B, 0x2F, 0xFF, 0x87, 0x34, 0x8E, 0x43, 0x44, 0xC4, 0xDE, 0xE9, 0xCB,
745 0x54, 0x7B, 0x94, 0x32, 0xA6, 0xC2, 0x23, 0x3D, 0xEE, 0x4C, 0x95, 0x0B, 0x42, 0xFA, 0xC3, 0x4E,
746 0x08, 0x2E, 0xA1, 0x66, 0x28, 0xD9, 0x24, 0xB2, 0x76, 0x5B, 0xA2, 0x49, 0x6D, 0x8B, 0xD1, 0x25,
747 0x72, 0xF8, 0xF6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xD4, 0xA4, 0x5C, 0xCC, 0x5D, 0x65, 0xB6, 0x92,
748 0x6C, 0x70, 0x48, 0x50, 0xFD, 0xED, 0xB9, 0xDA, 0x5E, 0x15, 0x46, 0x57, 0xA7, 0x8D, 0x9D, 0x84,
749 0x90, 0xD8, 0xAB, 0x00, 0x8C, 0xBC, 0xD3, 0x0A, 0xF7, 0xE4, 0x58, 0x05, 0xB8, 0xB3, 0x45, 0x06,
750 0xD0, 0x2C, 0x1E, 0x8F, 0xCA, 0x3F, 0x0F, 0x02, 0xC1, 0xAF, 0xBD, 0x03, 0x01, 0x13, 0x8A, 0x6B,
751 0x3A, 0x91, 0x11, 0x41, 0x4F, 0x67, 0xDC, 0xEA, 0x97, 0xF2, 0xCF, 0xCE, 0xF0, 0xB4, 0xE6, 0x73,
752 0x96, 0xAC, 0x74, 0x22, 0xE7, 0xAD, 0x35, 0x85, 0xE2, 0xF9, 0x37, 0xE8, 0x1C, 0x75, 0xDF, 0x6E,
753 0x47, 0xF1, 0x1A, 0x71, 0x1D, 0x29, 0xC5, 0x89, 0x6F, 0xB7, 0x62, 0x0E, 0xAA, 0x18, 0xBE, 0x1B,
754 0xFC, 0x56, 0x3E, 0x4B, 0xC6, 0xD2, 0x79, 0x20, 0x9A, 0xDB, 0xC0, 0xFE, 0x78, 0xCD, 0x5A, 0xF4,
755 0x1F, 0xDD, 0xA8, 0x33, 0x88, 0x07, 0xC7, 0x31, 0xB1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xEC, 0x5F,
756 0x60, 0x51, 0x7F, 0xA9, 0x19, 0xB5, 0x4A, 0x0D, 0x2D, 0xE5, 0x7A, 0x9F, 0x93, 0xC9, 0x9C, 0xEF,
757 0xA0, 0xE0, 0x3B, 0x4D, 0xAE, 0x2A, 0xF5, 0xB0, 0xC8, 0xEB, 0xBB, 0x3C, 0x83, 0x53, 0x99, 0x61,
758 0x17, 0x2B, 0x04, 0x7E, 0xBA, 0x77, 0xD6, 0x26, 0xE1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0C, 0x7D
759 )
760 );
761 }
762 return $tables;
763 }
764
772 {
773 // Note: _setupInlineCrypt() will be called only if $this->changed === true
774 // So here we are'nt under the same heavy timing-stress as we are in _de/encryptBlock() or de/encrypt().
775 // However...the here generated function- $code, stored as php callback in $this->inline_crypt, must work as fast as even possible.
776
777 $lambda_functions =& self::_getLambdaFunctions();
778
779 // We create max. 10 hi-optimized code for memory reason. Means: For each $key one ultra fast inline-crypt function.
780 // (Currently, for Crypt_Rijndael/AES, one generated $lambda_function cost on php5.5@32bit ~80kb unfreeable mem and ~130kb on php5.5@64bit)
781 // After that, we'll still create very fast optimized code but not the hi-ultimative code, for each $mode one.
782 $gen_hi_opt_code = (bool)(count($lambda_functions) < 10);
783
784 // Generation of a uniqe hash for our generated code
785 $code_hash = "Crypt_Rijndael, {$this->mode}, {$this->Nr}, {$this->Nb}";
786 if ($gen_hi_opt_code) {
787 $code_hash = str_pad($code_hash, 32) . $this->_hashInlineCryptFunction($this->key);
788 }
789
790 if (!isset($lambda_functions[$code_hash])) {
791 switch (true) {
792 case $gen_hi_opt_code:
793 // The hi-optimized $lambda_functions will use the key-words hardcoded for better performance.
794 $w = $this->w;
795 $dw = $this->dw;
796 $init_encrypt = '';
797 $init_decrypt = '';
798 break;
799 default:
800 for ($i = 0, $cw = count($this->w); $i < $cw; ++$i) {
801 $w[] = '$w[' . $i . ']';
802 $dw[] = '$dw[' . $i . ']';
803 }
804 $init_encrypt = '$w = $self->w;';
805 $init_decrypt = '$dw = $self->dw;';
806 }
807
808 $Nr = $this->Nr;
809 $Nb = $this->Nb;
810 $c = $this->c;
811
812 // Generating encrypt code:
813 $init_encrypt.= '
814 static $tables;
815 if (empty($tables)) {
816 $tables = &$self->_getTables();
817 }
818 $t0 = $tables[0];
819 $t1 = $tables[1];
820 $t2 = $tables[2];
821 $t3 = $tables[3];
822 $sbox = $tables[4];
823 ';
824
825 $s = 'e';
826 $e = 's';
827 $wc = $Nb - 1;
828
829 // Preround: addRoundKey
830 $encrypt_block = '$in = unpack("N*", $in);'."\n";
831 for ($i = 0; $i < $Nb; ++$i) {
832 $encrypt_block .= '$s'.$i.' = $in['.($i + 1).'] ^ '.$w[++$wc].";\n";
833 }
834
835 // Mainrounds: shiftRows + subWord + mixColumns + addRoundKey
836 for ($round = 1; $round < $Nr; ++$round) {
837 list($s, $e) = array($e, $s);
838 for ($i = 0; $i < $Nb; ++$i) {
839 $encrypt_block.=
840 '$'.$e.$i.' =
841 $t0[($'.$s.$i .' >> 24) & 0xff] ^
842 $t1[($'.$s.(($i + $c[1]) % $Nb).' >> 16) & 0xff] ^
843 $t2[($'.$s.(($i + $c[2]) % $Nb).' >> 8) & 0xff] ^
844 $t3[ $'.$s.(($i + $c[3]) % $Nb).' & 0xff] ^
845 '.$w[++$wc].";\n";
846 }
847 }
848
849 // Finalround: subWord + shiftRows + addRoundKey
850 for ($i = 0; $i < $Nb; ++$i) {
851 $encrypt_block.=
852 '$'.$e.$i.' =
853 $sbox[ $'.$e.$i.' & 0xff] |
854 ($sbox[($'.$e.$i.' >> 8) & 0xff] << 8) |
855 ($sbox[($'.$e.$i.' >> 16) & 0xff] << 16) |
856 ($sbox[($'.$e.$i.' >> 24) & 0xff] << 24);'."\n";
857 }
858 $encrypt_block .= '$in = pack("N*"'."\n";
859 for ($i = 0; $i < $Nb; ++$i) {
860 $encrypt_block.= ',
861 ($'.$e.$i .' & '.((int)0xFF000000).') ^
862 ($'.$e.(($i + $c[1]) % $Nb).' & 0x00FF0000 ) ^
863 ($'.$e.(($i + $c[2]) % $Nb).' & 0x0000FF00 ) ^
864 ($'.$e.(($i + $c[3]) % $Nb).' & 0x000000FF ) ^
865 '.$w[$i]."\n";
866 }
867 $encrypt_block .= ');';
868
869 // Generating decrypt code:
870 $init_decrypt.= '
871 static $invtables;
872 if (empty($invtables)) {
873 $invtables = &$self->_getInvTables();
874 }
875 $dt0 = $invtables[0];
876 $dt1 = $invtables[1];
877 $dt2 = $invtables[2];
878 $dt3 = $invtables[3];
879 $isbox = $invtables[4];
880 ';
881
882 $s = 'e';
883 $e = 's';
884 $wc = $Nb - 1;
885
886 // Preround: addRoundKey
887 $decrypt_block = '$in = unpack("N*", $in);'."\n";
888 for ($i = 0; $i < $Nb; ++$i) {
889 $decrypt_block .= '$s'.$i.' = $in['.($i + 1).'] ^ '.$dw[++$wc].';'."\n";
890 }
891
892 // Mainrounds: shiftRows + subWord + mixColumns + addRoundKey
893 for ($round = 1; $round < $Nr; ++$round) {
894 list($s, $e) = array($e, $s);
895 for ($i = 0; $i < $Nb; ++$i) {
896 $decrypt_block.=
897 '$'.$e.$i.' =
898 $dt0[($'.$s.$i .' >> 24) & 0xff] ^
899 $dt1[($'.$s.(($Nb + $i - $c[1]) % $Nb).' >> 16) & 0xff] ^
900 $dt2[($'.$s.(($Nb + $i - $c[2]) % $Nb).' >> 8) & 0xff] ^
901 $dt3[ $'.$s.(($Nb + $i - $c[3]) % $Nb).' & 0xff] ^
902 '.$dw[++$wc].";\n";
903 }
904 }
905
906 // Finalround: subWord + shiftRows + addRoundKey
907 for ($i = 0; $i < $Nb; ++$i) {
908 $decrypt_block.=
909 '$'.$e.$i.' =
910 $isbox[ $'.$e.$i.' & 0xff] |
911 ($isbox[($'.$e.$i.' >> 8) & 0xff] << 8) |
912 ($isbox[($'.$e.$i.' >> 16) & 0xff] << 16) |
913 ($isbox[($'.$e.$i.' >> 24) & 0xff] << 24);'."\n";
914 }
915 $decrypt_block .= '$in = pack("N*"'."\n";
916 for ($i = 0; $i < $Nb; ++$i) {
917 $decrypt_block.= ',
918 ($'.$e.$i. ' & '.((int)0xFF000000).') ^
919 ($'.$e.(($Nb + $i - $c[1]) % $Nb).' & 0x00FF0000 ) ^
920 ($'.$e.(($Nb + $i - $c[2]) % $Nb).' & 0x0000FF00 ) ^
921 ($'.$e.(($Nb + $i - $c[3]) % $Nb).' & 0x000000FF ) ^
922 '.$dw[$i]."\n";
923 }
924 $decrypt_block .= ');';
925
926 $lambda_functions[$code_hash] = $this->_createInlineCryptFunction(
927 array(
928 'init_crypt' => '',
929 'init_encrypt' => $init_encrypt,
930 'init_decrypt' => $init_decrypt,
931 'encrypt_block' => $encrypt_block,
932 'decrypt_block' => $decrypt_block
933 )
934 );
935 }
936 $this->inline_crypt = $lambda_functions[$code_hash];
937 }
938}
if(php_sapi_name() !='cli') $in
Definition: Utf8Test.php:37
global $l
Definition: afr.php:30
if(!array_key_exists('stateid', $_REQUEST)) $state
Handle linkback() response from LinkedIn.
Definition: linkback.php:10
An exception for terminatinating execution or to throw for unit testing.
_hashInlineCryptFunction($bytes)
Generates a digest from $bytes.
Definition: Base.php:2523
const ENGINE_OPENSSL
Base value for the mcrypt implementation $engine switch.
Definition: Base.php:117
const ENGINE_MCRYPT
Base value for the mcrypt implementation $engine switch.
Definition: Base.php:113
_setEngine()
Sets the engine as appropriate.
Definition: Base.php:1649
_openssl_translate_mode()
phpseclib <-> OpenSSL Mode Mapper
Definition: Base.php:1423
& _getLambdaFunctions()
Holds the lambda_functions table (classwide)
Definition: Base.php:2509
_createInlineCryptFunction($cipher_code)
Creates the performance-optimized function for en/decrypt()
Definition: Base.php:2142
_encryptBlock($in)
Encrypts a block.
Definition: Rijndael.php:276
_setupKey()
Setup the key (expansion)
Definition: Rijndael.php:466
& _getInvTables()
Provides the inverse mixColumns and inverse sboxes tables.
Definition: Rijndael.php:690
_setupInlineCrypt()
Setup the performance-optimized function for de/encrypt()
Definition: Rijndael.php:771
_subWord($word)
Performs S-Box substitutions.
Definition: Rijndael.php:579
& _getTables()
Provides the mixColumns and sboxes tables.
Definition: Rijndael.php:601
setBlockLength($length)
Sets the block length.
Definition: Rijndael.php:224
setKeyLength($length)
Sets the key length.
Definition: Rijndael.php:193
_decryptBlock($in)
Decrypts a block.
Definition: Rijndael.php:377
isValidEngine($engine)
Test for engine validity.
Definition: Rijndael.php:248
$i
Definition: disco.tpl.php:19
$r
Definition: example_031.php:79
$row
Base Class for all \phpseclib\Crypt* cipher classes.
Pure-PHP implementation of Rijndael.
Pure-PHP implementations of keyed-hash message authentication codes (HMACs) and various cryptographic...
Definition: AES.php:50
$s
Definition: pwgen.php:45