includes/rijndael.php
changeset 378 c1c7fa6b329f
parent 348 87e08a6e4fec
child 458 c433348f3628
equal deleted inserted replaced
377:bb3e6c3bd4f4 378:c1c7fa6b329f
   126     $this->debug = $debug;
   126     $this->debug = $debug;
   127   }
   127   }
   128   
   128   
   129   public static function singleton($key_size, $block_size)
   129   public static function singleton($key_size, $block_size)
   130   {
   130   {
   131     global $_aes_objcache;
   131     static $_aes_objcache;
   132     if ( isset($_aes_objcache["$key_size,$block_size"]) )
   132     if ( isset($_aes_objcache["$key_size,$block_size"]) )
   133     {
   133     {
   134       return $_aes_objcache["$key_size,$block_size"];
   134       return $_aes_objcache["$key_size,$block_size"];
   135     }
   135     }
   136     
   136     
   777     }
   777     }
   778     else
   778     else
   779     {
   779     {
   780       $key = $this->prepare_string($key);
   780       $key = $this->prepare_string($key);
   781       $text = $this->prepare_string($text);
   781       $text = $this->prepare_string($text);
       
   782       profiler_log('AES: Started encryption of a string');
   782       $cryptext = $this->rijndaelEncrypt($text, $key, 'ECB');
   783       $cryptext = $this->rijndaelEncrypt($text, $key, 'ECB');
       
   784       profiler_log('AES: Finished encryption of a string');
   783       if(!is_array($cryptext))
   785       if(!is_array($cryptext))
   784       {
   786       {
   785         echo 'Warning: encryption failed for string: '.print_r($text,true).'<br />';
   787         echo 'Warning: encryption failed for string: '.print_r($text,true).'<br />';
   786         return false;
   788         return false;
   787       }
   789       }
   812    
   814    
   813   function decrypt($text, $key, $input_encoding = ENC_HEX)
   815   function decrypt($text, $key, $input_encoding = ENC_HEX)
   814   {
   816   {
   815     if ( $text == '' )
   817     if ( $text == '' )
   816       return '';
   818       return '';
   817     $text_orig = $text;
   819     
   818     if ( isset($this->decrypt_cache[$key]) && is_array($this->decrypt_cache[$key]) )
       
   819     {
       
   820       if ( isset($this->decrypt_cache[$key][$text]) )
       
   821       {
       
   822         return $this->decrypt_cache[$key][$text];
       
   823       }
       
   824     }
       
   825     switch($input_encoding)
   820     switch($input_encoding)
   826     {
   821     {
   827       case ENC_BINARY:
   822       case ENC_BINARY:
   828       default:
   823       default:
   829         break;
   824         break;
   832         break;
   827         break;
   833       case ENC_BASE64:
   828       case ENC_BASE64:
   834         $text = base64_decode($text);
   829         $text = base64_decode($text);
   835         break;
   830         break;
   836     }
   831     }
   837     //$mod = strlen($text) % $this->blockSizeInBits;
   832     
   838     //if($mod != 96)
   833     // Run memory-cache check
   839       //die('modulus check failed: '.$mod);
   834     if ( isset($this->decrypt_cache[$key]) && is_array($this->decrypt_cache[$key]) )
       
   835     {
       
   836       if ( isset($this->decrypt_cache[$key][$text]) )
       
   837       {
       
   838         return $this->decrypt_cache[$key][$text];
       
   839       }
       
   840     }
       
   841     
       
   842     // Run disk-cache check
       
   843     $hash = sha1($text . '::' . $key);
       
   844     if ( $dypt = aes_decrypt_cache_fetch($hash) )
       
   845       return $dypt;
       
   846     
       
   847     $text_bin = $text;
       
   848     $key_bin = $key;
       
   849     
   840     if ( $this->mcrypt )
   850     if ( $this->mcrypt )
   841     {
   851     {
   842       $iv_size = mcrypt_get_iv_size($this->mcrypt, MCRYPT_MODE_ECB);
   852       $iv_size = mcrypt_get_iv_size($this->mcrypt, MCRYPT_MODE_ECB);
   843       $iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);
   853       $iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);
   844       $dypt = mcrypt_decrypt($this->mcrypt, $key, $text, MCRYPT_MODE_ECB, $iv);
   854       $dypt = mcrypt_decrypt($this->mcrypt, $key, $text, MCRYPT_MODE_ECB, $iv);
   846     else
   856     else
   847     {
   857     {
   848       $etext = $this->prepare_string($text);
   858       $etext = $this->prepare_string($text);
   849       $ekey  = $this->prepare_string($key);
   859       $ekey  = $this->prepare_string($key);
   850       $mod = count($etext) % $this->blockSizeInBits;
   860       $mod = count($etext) % $this->blockSizeInBits;
       
   861       profiler_log('AES: Started decryption of a string');
   851       $dypt = $this->rijndaelDecrypt($etext, $ekey, 'ECB');
   862       $dypt = $this->rijndaelDecrypt($etext, $ekey, 'ECB');
       
   863       profiler_log('AES: Finished decryption of a string');
   852       if(!$dypt)
   864       if(!$dypt)
   853       {
   865       {
   854         echo '<pre>'.print_r($dypt, true).'</pre>';
   866         echo '<pre>'.print_r($dypt, true).'</pre>';
   855         $this->trigger_error('Rijndael main decryption routine failed', E_USER_ERROR);
   867         $this->trigger_error('Rijndael main decryption routine failed', E_USER_ERROR);
   856       }
   868       }
   857       $dypt = $this->byteArrayToString($dypt);
   869       $dypt = $this->byteArrayToString($dypt);
   858     }
   870     }
   859     if ( !isset($this->decrypt_cache[$key]) )
   871     if ( !isset($this->decrypt_cache[$key_bin]) )
   860       $this->decrypt_cache[$key] = array();
   872       $this->decrypt_cache[$key_bin] = array();
   861     
   873     
   862     $this->decrypt_cache[$key][$text_orig] = $dypt;
   874     $this->decrypt_cache[$key_bin][$text_bin] = $dypt;
       
   875     
       
   876     aes_decrypt_cache_store($text_bin, $dypt, $key_bin);
   863     
   877     
   864     return $dypt;
   878     return $dypt;
   865   }
   879   }
   866   
   880   
   867   /**
   881   /**
   975     }
   989     }
   976     return $bin_key;
   990     return $bin_key;
   977   }
   991   }
   978 }
   992 }
   979 
   993 
   980 /**
   994 function aes_decrypt_cache_store($encrypted, $decrypted, $key)
   981  * XXTEA encryption arithmetic library.
   995 {
   982  *
   996   $cache_file = ENANO_ROOT . '/cache/aes_decrypt.php';
   983  * Copyright (C) 2006 Ma Bingyao <andot@ujn.edu.cn>
   997   // only cache if $decrypted is long enough to actually warrant caching
   984  * Version:      1.5
   998   if ( strlen($decrypted) < 32 )
   985  * LastModified: Dec 5, 2006
   999   {
   986  * This library is free.  You can redistribute it and/or modify it.
  1000     profiler_log("AES: Skipped caching a string (probably a password, we dunno) because it's too short");
   987  * 
  1001     return false;
   988  * From dandaman32: I am treating this code as GPL, as implied by the license statement above.
  1002   }
   989  */
  1003   if ( file_exists($cache_file) )
   990 class TEACrypt extends AESCrypt {
  1004   {
   991   function long2str($v, $w) {
  1005     require_once($cache_file);
   992       $len = count($v);
  1006     global $aes_decrypt_cache;
   993       $n = ($len - 1) << 2;
  1007     $cachekey = sha1($encrypted . '::' . $key);
   994       if ($w) {
  1008     $aes_decrypt_cache[$cachekey] = $decrypted;
   995           $m = $v[$len - 1];
  1009     
   996           if (($m < $n - 3) || ($m > $n)) return false;
  1010     if ( count($aes_decrypt_cache) > 5000 )
   997           $n = $m;
  1011     {
   998       }
  1012       // we've got a lot of strings in the cache, clear out a few
   999       $s = array();
  1013       $keys = array_keys($aes_decrypt_cache);
  1000       for ($i = 0; $i < $len; $i++) {
  1014       for ( $i = 0; $i < 2500; $i++ )
  1001           $s[$i] = pack("V", $v[$i]);
  1015       {
  1002       }
  1016         unset($aes_decrypt_cache[$keys[$i]]);
  1003       if ($w) {
  1017         unset($aes_decrypt_cache[$keys[$i]]);
  1004           return substr(join('', $s), 0, $n);
  1018       }
  1005       }
  1019     }
  1006       else {
  1020   }
  1007           return join('', $s);
  1021   else
  1008       }
  1022   {
  1009   }
  1023     $aes_decrypt_cache = array(
  1010    
  1024       sha1($encrypted . '::' . $key) => $decrypted
  1011   function str2long($s, $w) {
  1025     );
  1012       $v = unpack("V*", $s. str_repeat("\0", (4 - strlen($s) % 4) & 3));
  1026   }
  1013       $v = array_values($v);
  1027   // call var_export and collect contents
  1014       if ($w) {
  1028   ob_start();
  1015           $v[count($v)] = strlen($s);
  1029   var_export($aes_decrypt_cache);
  1016       }
  1030   $dec_cache_string = ob_get_contents();
  1017       return $v;
  1031   ob_end_clean();
  1018   }
  1032   $f = @fopen($cache_file, 'w');
  1019    
  1033   if ( !$f )
  1020   function int32($n) {
  1034     return false;
  1021       while ($n >= 2147483648) $n -= 4294967296;
  1035   fwrite($f, "<?php
  1022       while ($n <= -2147483649) $n += 4294967296;
  1036 \$GLOBALS['aes_decrypt_cache'] = $dec_cache_string;
  1023       return (int)$n;
  1037 ");
  1024   }
  1038   fclose($f);
  1025    
  1039   return true;
  1026   function encrypt($str, $key, $return_encoding = ENC_HEX) {
  1040 }
  1027       if ($str == "")
  1041 
  1028       {
  1042 function aes_decrypt_cache_fetch($hash)
  1029           return "";
  1043 {
  1030       }
  1044   $cache_file = ENANO_ROOT . '/cache/aes_decrypt.php';
  1031       $v = $this->str2long($str, true);
  1045   if ( !file_exists($cache_file) )
  1032       $k = $this->str2long($key, false);
  1046     return false;
  1033       if (count($k) < 4) {
  1047   
  1034           for ($i = count($k); $i < 4; $i++) {
  1048   require_once($cache_file);
  1035               $k[$i] = 0;
  1049   global $aes_decrypt_cache;
  1036           }
  1050   if ( isset($aes_decrypt_cache[$hash]) )
  1037       }
  1051   {
  1038       $n = count($v) - 1;
  1052     profiler_log("AES: Loaded cached decrypted string, hash is $hash");
  1039    
  1053     return $aes_decrypt_cache[$hash];
  1040       $z = $v[$n];
  1054   }
  1041       $y = $v[0];
  1055   
  1042       $delta = 0x9E3779B9;
  1056   return false;
  1043       $q = floor(6 + 52 / ($n + 1));
  1057 }
  1044       $sum = 0;
  1058 
  1045       while (0 < $q--) {
  1059 function aes_decrypt_cache_destroy($hash)
  1046           $sum = $this->int32($sum + $delta);
  1060 {
  1047           $e = $sum >> 2 & 3;
  1061   $cache_file = ENANO_ROOT . '/cache/aes_decrypt.php';
  1048           for ($p = 0; $p < $n; $p++) {
  1062   if ( !file_exists($cache_file) )
  1049               $y = $v[$p + 1];
  1063     return false;
  1050               $mx = $this->int32((($z >> 5 & 0x07ffffff) ^ $y << 2) + (($y >> 3 & 0x1fffffff) ^ $z << 4)) ^ $this->int32(($sum ^ $y) + ($k[$p & 3 ^ $e] ^ $z));
  1064   
  1051               $z = $v[$p] = $this->int32($v[$p] + $mx);
  1065   require_once($cache_file);
  1052           }
  1066   global $aes_decrypt_cache;
  1053           $y = $v[0];
  1067   
  1054           $mx = $this->int32((($z >> 5 & 0x07ffffff) ^ $y << 2) + (($y >> 3 & 0x1fffffff) ^ $z << 4)) ^ $this->int32(($sum ^ $y) + ($k[$p & 3 ^ $e] ^ $z));
  1068   if ( isset($aes_decrypt_cache[$hash]) )
  1055           $z = $v[$n] = $this->int32($v[$n] + $mx);
  1069     unset($aes_decrypt_cache[$hash]);
  1056       }
  1070   
  1057       return $this->long2str($v, false);
  1071   // call var_export and collect contents
  1058   }
  1072   ob_start();
  1059    
  1073   var_export($aes_decrypt_cache);
  1060   function decrypt($str, $key, $encoding = ENC_HEX) {
  1074   $dec_cache_string = ob_get_contents();
  1061       if ($str == "") {
  1075   ob_end_clean();
  1062           return "";
  1076   $f = @fopen($cache_file, 'w');
  1063       }
  1077   if ( !$f )
  1064       $v = $this->str2long($str, false);
  1078     return false;
  1065       $k = $this->str2long($key, false);
  1079   fwrite($f, "<?php
  1066       if (count($k) < 4) {
  1080 \$GLOBALS['aes_decrypt_cache'] = $dec_cache_string;
  1067           for ($i = count($k); $i < 4; $i++) {
  1081 ");
  1068               $k[$i] = 0;
  1082   fclose($f);
  1069           }
  1083   return true;
  1070       }
       
  1071       $n = count($v) - 1;
       
  1072    
       
  1073       $z = $v[$n];
       
  1074       $y = $v[0];
       
  1075       $delta = 0x9E3779B9;
       
  1076       $q = floor(6 + 52 / ($n + 1));
       
  1077       $sum = $this->int32($q * $delta);
       
  1078       while ($sum != 0) {
       
  1079           $e = $sum >> 2 & 3;
       
  1080           for ($p = $n; $p > 0; $p--) {
       
  1081               $z = $v[$p - 1];
       
  1082               $mx = $this->int32((($z >> 5 & 0x07ffffff) ^ $y << 2) + (($y >> 3 & 0x1fffffff) ^ $z << 4)) ^ $this->int32(($sum ^ $y) + ($k[$p & 3 ^ $e] ^ $z));
       
  1083               $y = $v[$p] = $this->int32($v[$p] - $mx);
       
  1084           }
       
  1085           $z = $v[$n];
       
  1086           $mx = $this->int32((($z >> 5 & 0x07ffffff) ^ $y << 2) + (($y >> 3 & 0x1fffffff) ^ $z << 4)) ^ $this->int32(($sum ^ $y) + ($k[$p & 3 ^ $e] ^ $z));
       
  1087           $y = $v[0] = $this->int32($v[0] - $mx);
       
  1088           $sum = $this->int32($sum - $delta);
       
  1089       }
       
  1090       return $this->long2str($v, true);
       
  1091   }
       
  1092 }
  1084 }
  1093 
  1085 
  1094 ?>
  1086 ?>