ILIAS  release_5-4 Revision v5.4.26-12-gabc799a52e6
Rijndael.php
Go to the documentation of this file.
1 <?php
2 
55 namespace phpseclib\Crypt;
56 
58 
66 class 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) {
251  case self::ENGINE_OPENSSL:
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;
258  case self::ENGINE_MCRYPT:
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 
276  function _encryptBlock($in)
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 
377  function _decryptBlock($in)
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 
771  function _setupInlineCrypt()
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 }
_decryptBlock($in)
Decrypts a block.
Definition: Rijndael.php:377
isValidEngine($engine)
Test for engine validity.
Definition: Rijndael.php:248
_setEngine()
Sets the engine as appropriate.
Definition: Base.php:1649
_hashInlineCryptFunction($bytes)
Generates a digest from $bytes.
Definition: Base.php:2523
_setupInlineCrypt()
Setup the performance-optimized function for de/encrypt()
Definition: Rijndael.php:771
& _getInvTables()
Provides the inverse mixColumns and inverse sboxes tables.
Definition: Rijndael.php:690
$s
Definition: pwgen.php:45
_openssl_translate_mode()
phpseclib <-> OpenSSL Mode Mapper
Definition: Base.php:1423
Pure-PHP implementations of keyed-hash message authentication codes (HMACs) and various cryptographic...
Definition: AES.php:50
& _getTables()
Provides the mixColumns and sboxes tables.
Definition: Rijndael.php:601
if(!array_key_exists('stateid', $_REQUEST)) $state
Handle linkback() response from LinkedIn.
Definition: linkback.php:10
Pure-PHP implementation of Rijndael.
$r
Definition: example_031.php:79
_subWord($word)
Performs S-Box substitutions.
Definition: Rijndael.php:579
_setupKey()
Setup the key (expansion)
Definition: Rijndael.php:466
_createInlineCryptFunction($cipher_code)
Creates the performance-optimized function for en/decrypt()
Definition: Base.php:2142
setBlockLength($length)
Sets the block length.
Definition: Rijndael.php:224
$row
if(php_sapi_name() !='cli') $in
Definition: Utf8Test.php:37
setKeyLength($length)
Sets the key length.
Definition: Rijndael.php:193
global $l
Definition: afr.php:30
$i
Definition: disco.tpl.php:19
Base Class for all * cipher classes.
_encryptBlock($in)
Encrypts a block.
Definition: Rijndael.php:276