From 50f46959ed01f3785466e060c0c776387be119f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hans-J=C3=BCrgen=20Petrich?= Date: Fri, 31 Jan 2014 06:13:14 +0700 Subject: [PATCH 01/79] Ciphers: Adding setEngine() and some optimizations Ciphers: Adding setEngine() and some optimizations --- phpseclib/Crypt/AES.php | 10 +- phpseclib/Crypt/Base.php | 184 +++++--- phpseclib/Crypt/Blowfish.php | 43 +- phpseclib/Crypt/DES.php | 27 +- phpseclib/Crypt/RC2.php | 52 ++- phpseclib/Crypt/RC4.php | 6 +- phpseclib/Crypt/Rijndael.php | 814 ++++++++++++---------------------- phpseclib/Crypt/TripleDES.php | 30 +- phpseclib/Crypt/Twofish.php | 20 +- 9 files changed, 529 insertions(+), 657 deletions(-) diff --git a/phpseclib/Crypt/AES.php b/phpseclib/Crypt/AES.php index a00b2a9b..908d8c1e 100644 --- a/phpseclib/Crypt/AES.php +++ b/phpseclib/Crypt/AES.php @@ -7,6 +7,10 @@ * * PHP versions 4 and 5 * + * NOTE: Since AES.php is (for compatibility and phpseclib-historical reasons) virtually + * just a wrapper to Rijndael.php you may consider using Rijndael.php instead of + * to save one include_once(). + * * If {@link Crypt_AES::setKeyLength() setKeyLength()} isn't called, it'll be calculated from * {@link Crypt_AES::setKey() setKey()}. ie. if the key is 128-bits, the key length will be 128-bits. If it's 136-bits * it'll be null-padded to 192-bits and 192 bits will be the key length until {@link Crypt_AES::setKey() setKey()} @@ -19,7 +23,7 @@ * Here's a short example of how to use this library: * * - * @version 0.1.0 + * @version 0.1.1 * @access public */ class Crypt_AES extends Crypt_Rijndael diff --git a/phpseclib/Crypt/Base.php b/phpseclib/Crypt/Base.php index c458f267..844957bd 100644 --- a/phpseclib/Crypt/Base.php +++ b/phpseclib/Crypt/Base.php @@ -49,14 +49,14 @@ * @author Hans-Juergen Petrich * @copyright MMVII Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @version 1.0.1 * @link http://phpseclib.sourceforge.net */ /**#@+ - * @access public + * @access private * @see Crypt_Base::encrypt() * @see Crypt_Base::decrypt() + * @internal This constants are for internal usage only */ /** * Encrypt / decrypt using the Counter mode. @@ -100,6 +100,7 @@ define('CRYPT_MODE_STREAM', 5); /**#@+ * @access private * @see Crypt_Base::Crypt_Base() + * @internal This constants are for internal usage only */ /** * Base value for the internal implementation $engine switch @@ -117,7 +118,7 @@ define('CRYPT_MODE_MCRYPT', 2); * @package Crypt_Base * @author Jim Wigginton * @author Hans-Juergen Petrich - * @version 1.0.0 + * @version 1.0.1 * @access public */ class Crypt_Base @@ -449,28 +450,11 @@ class Crypt_Base { $const_crypt_mode = 'CRYPT_' . $this->const_namespace . '_MODE'; - // Determining the availibility of mcrypt support for the cipher - if (!defined($const_crypt_mode)) { - switch (true) { - case extension_loaded('mcrypt') && in_array($this->cipher_name_mcrypt, mcrypt_list_algorithms()): - define($const_crypt_mode, CRYPT_MODE_MCRYPT); - break; - default: - define($const_crypt_mode, CRYPT_MODE_INTERNAL); - } - } - - // Determining which internal $engine should be used. - // The fastes possible first. - switch (true) { - case empty($this->cipher_name_mcrypt): // The cipher module has no mcrypt-engine support at all so we force CRYPT_MODE_INTERNAL - $this->engine = CRYPT_MODE_INTERNAL; - break; - case constant($const_crypt_mode) == CRYPT_MODE_MCRYPT: - $this->engine = CRYPT_MODE_MCRYPT; - break; - default: - $this->engine = CRYPT_MODE_INTERNAL; + // Setup the internal crypt engine + if (defined($const_crypt_mode)) { + $this->engine = constant($const_crypt_mode); + } else { + define($const_crypt_mode, $this->setEngine()); } // $mode dependent settings @@ -503,10 +487,9 @@ class Crypt_Base * SetIV is not required when CRYPT_MODE_ECB (or ie for AES: CRYPT_AES_MODE_ECB) is being used. If not explictly set, it'll be assumed * to be all zero's. * - * Note: Could, but not must, extend by the child Crypt_* class - * * @access public * @param String $iv + * @internal Could, but not must, extend by the child Crypt_* class */ function setIV($iv) { @@ -528,10 +511,9 @@ class Crypt_Base * * If the key is not explicitly set, it'll be assumed to be all null bytes. * - * Note: Could, but not must, extend by the child Crypt_* class - * * @access public * @param String $key + * @internal Could, but not must, extend by the child Crypt_* class */ function setKey($key) { @@ -548,12 +530,11 @@ class Crypt_Base * * Where $hash (default = sha1) currently supports the following hashes: see: Crypt/Hash.php * - * Note: Could, but not must, extend by the child Crypt_* class - * * @see Crypt/Hash.php * @param String $password * @param optional String $method * @access public + * @internal Could, but not must, extend by the child Crypt_* class */ function setPassword($password, $method = 'pbkdf2') { @@ -620,12 +601,11 @@ class Crypt_Base * strlen($plaintext) will still need to be a multiple of the block size, however, arbitrary values can be added to make it that * length. * - * Note: Could, but not must, extend by the child Crypt_* class - * * @see Crypt_Base::decrypt() * @access public * @param String $plaintext * @return String $cipertext + * @internal Could, but not must, extend by the child Crypt_* class */ function encrypt($plaintext) { @@ -848,12 +828,11 @@ class Crypt_Base * If strlen($ciphertext) is not a multiple of the block size, null bytes will be added to the end of the string until * it is. * - * Note: Could, but not must, extend by the child Crypt_* class - * * @see Crypt_Base::encrypt() * @access public * @param String $ciphertext * @return String $plaintext + * @internal Could, but not must, extend by the child Crypt_* class */ function decrypt($ciphertext) { @@ -1119,10 +1098,9 @@ class Crypt_Base * continuous buffers not be used. They do offer better security and are, in fact, sometimes required (SSH uses them), * however, they are also less intuitive and more likely to cause you problems. * - * Note: Could, but not must, extend by the child Crypt_* class - * * @see Crypt_Base::disableContinuousBuffer() * @access public + * @internal Could, but not must, extend by the child Crypt_* class */ function enableContinuousBuffer() { @@ -1138,10 +1116,9 @@ class Crypt_Base * * The default behavior. * - * Note: Could, but not must, extend by the child Crypt_* class - * * @see Crypt_Base::enableContinuousBuffer() * @access public + * @internal Could, but not must, extend by the child Crypt_* class */ function disableContinuousBuffer() { @@ -1157,13 +1134,77 @@ class Crypt_Base } /** - * Encrypts a block + * Sets the internal crypt engine * - * Note: Must extend by the child Crypt_* class + * Will be called automatically on "__construct()", so normally it's not + * necessary to call setEngine() manually, but ie for debuging or testing. + * + * Currently, $engine could be: + * + * - CRYPT_MODE_MCRYPT [fast] + * + * - CRYPT_MODE_INTERNAL [slow] + * + * Respectivly the officially alias constants of the choosen cipher, + * ie for AES: CRYPT_AES_MODE_MCRYPT or CRYPT_AES_MODE_INTERNAL + * + * If $engine is not explictly set, the fastest available $engine + * will be set (currently: CRYPT_MODE_MCRYPT) + * + * If $engine == CRYPT_MODE_MCRYPT but the mcrypt extension is not loaded/available it + * will be set the next available fastest $engine (currently: CRYPT_MODE_INTERNAL) + * + * If called, all internal buffers and cipher states will be reset, so, + * for example, switching the $engine while enableContinuousBuffer() will + * reset the ContinuousBuffer's. + * + * setEngine() returns always the $engine which was effectively set. + * + * @see Crypt_Base::Crypt_Base() + * @param optional Integer $engine + * @access public + * @return Integer + * @internal Could, but not must, extend by the child Crypt_* class + */ + function setEngine($engine = CRYPT_MODE_MCRYPT) + { + switch ($engine) { + case CRYPT_MODE_INTERNAL: + $this->engine = CRYPT_MODE_INTERNAL; + break; + default: + if ($this->cipher_name_mcrypt && extension_loaded('mcrypt') && in_array($this->cipher_name_mcrypt, mcrypt_list_algorithms())) { + $this->engine = CRYPT_MODE_MCRYPT; + } else { + $this->engine = CRYPT_MODE_INTERNAL; + } + } + + if ($this->enmcrypt) { + // Closing the current mcrypt resource(s). _mcryptSetup() will, if needed, + // (re)open them with the module named in $this->cipher_name_mcrypt + mcrypt_module_close($this->enmcrypt); + mcrypt_module_close($this->demcrypt); + $this->enmcrypt = null; + $this->demcrypt = null; + + if ($this->ecb) { + mcrypt_module_close($this->ecb); + $this->ecb = null; + } + } + + $this->changed = true; + return $this->engine; + } + + /** + * Encrypts a block * * @access private * @param String $in * @return String + * @internal Must extend by the child Crypt_* class */ function _encryptBlock($in) { @@ -1173,11 +1214,10 @@ class Crypt_Base /** * Decrypts a block * - * Note: Must extend by the child Crypt_* class - * * @access private * @param String $in * @return String + * @internal Must extend by the child Crypt_* class */ function _decryptBlock($in) { @@ -1189,10 +1229,9 @@ class Crypt_Base * * Only used if $engine == CRYPT_MODE_INTERNAL * - * Note: Must extend by the child Crypt_* class - * * @see Crypt_Base::_setup() * @access private + * @internal Must extend by the child Crypt_* class */ function _setupKey() { @@ -1216,14 +1255,12 @@ class Crypt_Base * * - First run of encrypt() / decrypt() with no init-settings * - * Internally: _setup() is called always before(!) en/decryption. - * - * Note: Could, but not must, extend by the child Crypt_* class - * * @see setKey() * @see setIV() * @see disableContinuousBuffer() * @access private + * @internal _setup() is called always before(!) en/decryption. + * @internal Could, but not must, extend by the child Crypt_* class */ function _setup() { @@ -1252,13 +1289,11 @@ class Crypt_Base * * - First run of encrypt() / decrypt() * - * - * Note: Could, but not must, extend by the child Crypt_* class - * * @see setKey() * @see setIV() * @see disableContinuousBuffer() * @access private + * @internal Could, but not must, extend by the child Crypt_* class */ function _setupMcrypt() { @@ -1358,9 +1393,8 @@ class Crypt_Base * after disableContinuousBuffer() or on cipher $engine (re)init * ie after setKey() or setIV() * - * Note: Could, but not must, extend by the child Crypt_* class - * * @access public + * @internal Could, but not must, extend by the child Crypt_* class */ function _clearBuffers() { @@ -1487,11 +1521,10 @@ class Crypt_Base * @see Crypt_Base::encrypt() * @see Crypt_Base::decrypt() * @access private + * @internal If a Crypt_* class providing inline crypting it must extend _setupInlineCrypt() */ function _setupInlineCrypt() { - // If a Crypt_* class providing inline crypting it must extend _setupInlineCrypt() - // If, for any reason, an extending Crypt_Base() Crypt_* class // not using inline crypting then it must be ensured that: $this->use_inline_crypt = false // ie in the class var declaration of $use_inline_crypt in general for the Crypt_* class, @@ -1976,12 +2009,49 @@ class Crypt_Base * for which $mode the lambda function was created. * * @access private - * @return &Array + * @return Array &$functions */ function &_getLambdaFunctions() { static $functions = array(); return $functions; } + + /** + * Generates a digest from $bytes + * + * @see _setupInlineCrypt() + * @access private + * @param $bytes + * @return String + */ + function _trapdoor($bytes) + { + if (!defined('CRYPT_BASE_WHIRLPOOL_AVAILABLE')) { + define('CRYPT_BASE_WHIRLPOOL_AVAILABLE', (bool)(extension_loaded('hash') && in_array('whirlpool', hash_algos()))); + } + + // return pack('H*', md5($bytes) . sha1($bytes) . (CRYPT_BASE_WHIRLPOOL_AVAILABLE ? hash('whirlpool', $bytes) : '')); // Alternativ + + $result = ''; + $hash = $bytes; + + switch (true) { + case CRYPT_BASE_WHIRLPOOL_AVAILABLE: + foreach (str_split($bytes, 64) as $t) { + $hash = hash('whirlpool', $hash, true); + $result .= $t ^ $hash; + } + return $result . hash('whirlpool', $hash, true); + default: + $len = strlen($bytes); + for ($i = 0; $i < $len; $i+=20) { + $t = substr($bytes, $i, 20); + $hash = pack('H*', sha1($hash)); + $result .= $t ^ $hash; + } + return $result . pack('H*', sha1($hash)); + } + } } diff --git a/phpseclib/Crypt/Blowfish.php b/phpseclib/Crypt/Blowfish.php index 67593e5a..4b0f84ea 100644 --- a/phpseclib/Crypt/Blowfish.php +++ b/phpseclib/Crypt/Blowfish.php @@ -14,7 +14,7 @@ * Here's a short example of how to use this library: * * * @copyright MMVII Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @version 1.0 * @link http://phpseclib.sourceforge.net */ @@ -103,7 +102,7 @@ define('CRYPT_BLOWFISH_MODE_OFB', CRYPT_MODE_OFB); /**#@-*/ /**#@+ - * @access private + * @access public * @see Crypt_Blowfish::Crypt_Blowfish() */ /** @@ -122,7 +121,7 @@ define('CRYPT_BLOWFISH_MODE_MCRYPT', CRYPT_MODE_MCRYPT); * @package Crypt_Blowfish * @author Jim Wigginton * @author Hans-Juergen Petrich - * @version 1.0 + * @version 1.0.1 * @access public */ class Crypt_Blowfish extends Crypt_Base @@ -176,7 +175,7 @@ class Crypt_Blowfish extends Crypt_Base /** * The fixed subkeys boxes ($sbox0 - $sbox3) with 256 entries each * - * S-Box 1 + * S-Box 0 * * @access private * @var array @@ -502,17 +501,17 @@ class Crypt_Blowfish extends Crypt_Base $r = $in[2]; for ($i = 0; $i < 16; $i+= 2) { - $l^= $p[$i]; - $r^= ($sb_0[$l >> 24 & 0xff] + - $sb_1[$l >> 16 & 0xff] ^ - $sb_2[$l >> 8 & 0xff]) + - $sb_3[$l & 0xff]; + $l^= $p[$i]; + $r^= ($sb_0[$l >> 24 & 0xff] + + $sb_1[$l >> 16 & 0xff] ^ + $sb_2[$l >> 8 & 0xff]) + + $sb_3[$l & 0xff]; - $r^= $p[$i + 1]; - $l^= ($sb_0[$r >> 24 & 0xff] + - $sb_1[$r >> 16 & 0xff] ^ - $sb_2[$r >> 8 & 0xff]) + - $sb_3[$r & 0xff]; + $r^= $p[$i + 1]; + $l^= ($sb_0[$r >> 24 & 0xff] + + $sb_1[$r >> 16 & 0xff] ^ + $sb_2[$r >> 8 & 0xff]) + + $sb_3[$r & 0xff]; } return pack("N*", $r ^ $p[17], $l ^ $p[16]); } @@ -549,7 +548,6 @@ class Crypt_Blowfish extends Crypt_Base $sb_2[$r >> 8 & 0xff]) + $sb_3[$r & 0xff]; } - return pack("N*", $r ^ $p[0], $l ^ $p[1]); } @@ -564,15 +562,14 @@ class Crypt_Blowfish extends Crypt_Base $lambda_functions =& Crypt_Blowfish::_getLambdaFunctions(); // We create max. 10 hi-optimized code for memory reason. Means: For each $key one ultra fast inline-crypt function. + // (Currently, for Crypt_Blowfish, one generated $lambda_function cost on php5.5@32bit ~100kb unfreeable mem and ~180kb on php5.5@64bit) // After that, we'll still create very fast optimized code but not the hi-ultimative code, for each $mode one. - $gen_hi_opt_code = (bool)( count($lambda_functions) < 10); + $gen_hi_opt_code = (bool)( count($lambda_functions) < 10 ); - switch (true) { - case $gen_hi_opt_code: - $code_hash = md5(str_pad("Crypt_Blowfish, {$this->mode}, ", 32, "\0") . $this->key); - break; - default: - $code_hash = "Crypt_Blowfish, {$this->mode}"; + // Generation of a uniqe hash for our generated code + $code_hash = "Crypt_Blowfish, {$this->mode}"; + if ($gen_hi_opt_code) { + $code_hash = str_pad($code_hash, 32) . $this->_trapdoor($this->key); } if (!isset($lambda_functions[$code_hash])) { diff --git a/phpseclib/Crypt/DES.php b/phpseclib/Crypt/DES.php index 465f2512..7776e0bb 100644 --- a/phpseclib/Crypt/DES.php +++ b/phpseclib/Crypt/DES.php @@ -16,7 +16,7 @@ * Here's a short example of how to use this library: * * - * @version 0.1.0 + * @version 0.1.1 * @access public */ class Crypt_DES extends Crypt_Base @@ -1387,21 +1387,20 @@ class Crypt_DES extends Crypt_Base $des_rounds = $this->des_rounds; // We create max. 10 hi-optimized code for memory reason. Means: For each $key one ultra fast inline-crypt function. + // (Currently, for Crypt_DES, one generated $lambda_function cost on php5.5@32bit ~135kb unfreeable mem and ~230kb on php5.5@64bit) + // (Currently, for Crypt_TripleDES, one generated $lambda_function cost on php5.5@32bit ~240kb unfreeable mem and ~340kb on php5.5@64bit) // After that, we'll still create very fast optimized code but not the hi-ultimative code, for each $mode one $gen_hi_opt_code = (bool)( count($lambda_functions) < 10 ); // Generation of a uniqe hash for our generated code - switch (true) { - case $gen_hi_opt_code: - // For hi-optimized code, we create for each combination of - // $mode, $des_rounds and $this->key its own encrypt/decrypt function. - $code_hash = md5(str_pad("Crypt_DES, $des_rounds, {$this->mode}, ", 32, "\0") . $this->key); - break; - default: - // After max 10 hi-optimized functions, we create generic - // (still very fast.. but not ultra) functions for each $mode/$des_rounds - // Currently 2 * 5 generic functions will be then max. possible. - $code_hash = "Crypt_DES, $des_rounds, {$this->mode}"; + $code_hash = "Crypt_DES, $des_rounds, {$this->mode}"; + if ($gen_hi_opt_code) { + // For hi-optimized code, we create for each combination of + // $mode, $des_rounds and $this->key its own encrypt/decrypt function. + // After max 10 hi-optimized functions, we create generic + // (still very fast.. but not ultra) functions for each $mode/$des_rounds + // Currently 2 * 5 generic functions will be then max. possible. + $code_hash = str_pad($code_hash, 32) . $this->_trapdoor($this->key); } // Is there a re-usable $lambda_functions in there? If not, we have to create it. diff --git a/phpseclib/Crypt/RC2.php b/phpseclib/Crypt/RC2.php index 966a342d..488baf90 100755 --- a/phpseclib/Crypt/RC2.php +++ b/phpseclib/Crypt/RC2.php @@ -14,7 +14,7 @@ * Here's a short example of how to use this library: * * setKey(''); } /** @@ -507,6 +506,21 @@ class Crypt_RC2 extends Crypt_Base return pack('vvvv', $r0, $r1, $r2, $r3); } + /** + * Setup the CRYPT_MODE_MCRYPT $engine + * + * @see Crypt_Base::_setupMcrypt() + * @access private + */ + function _setupMcrypt() + { + if (!isset($this->key)) { + $this->setKey(''); + } + + parent::_setupMcrypt(); + } + /** * Creates the key schedule * @@ -515,6 +529,10 @@ class Crypt_RC2 extends Crypt_Base */ function _setupKey() { + if (!isset($this->key)) { + $this->setKey(''); + } + // Key has already been expanded in Crypt_RC2::setKey(): // Only the first value must be altered. $l = unpack('Ca/Cb/v*', $this->key); @@ -537,14 +555,14 @@ class Crypt_RC2 extends Crypt_Base // The first 10 generated $lambda_functions will use the $keys hardcoded as integers // for the mixing rounds, for better inline crypt performance [~20% faster]. // But for memory reason we have to limit those ultra-optimized $lambda_functions to an amount of 10. - $keys = $this->keys; - if (count($lambda_functions) >= 10) { - foreach ($this->keys as $k => $v) { - $keys[$k] = '$keys[' . $k . ']'; - } - } + // (Currently, for Crypt_RC2, one generated $lambda_function cost on php5.5@32bit ~60kb unfreeable mem and ~100kb on php5.5@64bit) + $gen_hi_opt_code = (bool)( count($lambda_functions) < 10 ); - $code_hash = md5(str_pad("Crypt_RC2, {$this->mode}, ", 32, "\0") . implode(',', $keys)); + // Generation of a uniqe hash for our generated code + $code_hash = "Crypt_RC2, {$this->mode}"; + if ($gen_hi_opt_code) { + $code_hash = str_pad($code_hash, 32) . $this->_trapdoor($this->key); + } // Is there a re-usable $lambda_functions in there? // If not, we have to create it. @@ -552,6 +570,16 @@ class Crypt_RC2 extends Crypt_Base // Init code for both, encrypt and decrypt. $init_crypt = '$keys = $self->keys;'; + switch (true) { + case $gen_hi_opt_code: + $keys = $this->keys; + default: + $keys = array(); + foreach ($this->keys as $k => $v) { + $keys[$k] = '$keys[' . $k . ']'; + } + } + // $in is the current 8 bytes block which has to be en/decrypt $encrypt_block = $decrypt_block = ' $in = unpack("v4", $in); diff --git a/phpseclib/Crypt/RC4.php b/phpseclib/Crypt/RC4.php index 148bee46..0beb86a3 100644 --- a/phpseclib/Crypt/RC4.php +++ b/phpseclib/Crypt/RC4.php @@ -18,7 +18,7 @@ * Here's a short example of how to use this library: * * - * @version 0.1.0 + * @version 0.1.1 * @access public */ class Crypt_RC4 extends Crypt_Base diff --git a/phpseclib/Crypt/Rijndael.php b/phpseclib/Crypt/Rijndael.php index 5a557929..0d4d0584 100644 --- a/phpseclib/Crypt/Rijndael.php +++ b/phpseclib/Crypt/Rijndael.php @@ -28,7 +28,7 @@ * Here's a short example of how to use this library: * * - * @version 0.1.0 + * @version 0.1.1 * @access public */ class Crypt_Rijndael extends Crypt_Base @@ -276,406 +276,6 @@ class Crypt_Rijndael extends Crypt_Base */ var $kl; - /** - * Precomputed mixColumns table - * - * According to (section 5.2.1), - * precomputed tables can be used in the mixColumns phase. in that example, they're assigned t0...t3, so - * those are the names we'll use. - * - * @see Crypt_Rijndael:_encryptBlock() - * @see Crypt_Rijndael:_decryptBlock() - * @var Array - * @access private - */ - var $t0 = array( - 0xC66363A5, 0xF87C7C84, 0xEE777799, 0xF67B7B8D, 0xFFF2F20D, 0xD66B6BBD, 0xDE6F6FB1, 0x91C5C554, - 0x60303050, 0x02010103, 0xCE6767A9, 0x562B2B7D, 0xE7FEFE19, 0xB5D7D762, 0x4DABABE6, 0xEC76769A, - 0x8FCACA45, 0x1F82829D, 0x89C9C940, 0xFA7D7D87, 0xEFFAFA15, 0xB25959EB, 0x8E4747C9, 0xFBF0F00B, - 0x41ADADEC, 0xB3D4D467, 0x5FA2A2FD, 0x45AFAFEA, 0x239C9CBF, 0x53A4A4F7, 0xE4727296, 0x9BC0C05B, - 0x75B7B7C2, 0xE1FDFD1C, 0x3D9393AE, 0x4C26266A, 0x6C36365A, 0x7E3F3F41, 0xF5F7F702, 0x83CCCC4F, - 0x6834345C, 0x51A5A5F4, 0xD1E5E534, 0xF9F1F108, 0xE2717193, 0xABD8D873, 0x62313153, 0x2A15153F, - 0x0804040C, 0x95C7C752, 0x46232365, 0x9DC3C35E, 0x30181828, 0x379696A1, 0x0A05050F, 0x2F9A9AB5, - 0x0E070709, 0x24121236, 0x1B80809B, 0xDFE2E23D, 0xCDEBEB26, 0x4E272769, 0x7FB2B2CD, 0xEA75759F, - 0x1209091B, 0x1D83839E, 0x582C2C74, 0x341A1A2E, 0x361B1B2D, 0xDC6E6EB2, 0xB45A5AEE, 0x5BA0A0FB, - 0xA45252F6, 0x763B3B4D, 0xB7D6D661, 0x7DB3B3CE, 0x5229297B, 0xDDE3E33E, 0x5E2F2F71, 0x13848497, - 0xA65353F5, 0xB9D1D168, 0x00000000, 0xC1EDED2C, 0x40202060, 0xE3FCFC1F, 0x79B1B1C8, 0xB65B5BED, - 0xD46A6ABE, 0x8DCBCB46, 0x67BEBED9, 0x7239394B, 0x944A4ADE, 0x984C4CD4, 0xB05858E8, 0x85CFCF4A, - 0xBBD0D06B, 0xC5EFEF2A, 0x4FAAAAE5, 0xEDFBFB16, 0x864343C5, 0x9A4D4DD7, 0x66333355, 0x11858594, - 0x8A4545CF, 0xE9F9F910, 0x04020206, 0xFE7F7F81, 0xA05050F0, 0x783C3C44, 0x259F9FBA, 0x4BA8A8E3, - 0xA25151F3, 0x5DA3A3FE, 0x804040C0, 0x058F8F8A, 0x3F9292AD, 0x219D9DBC, 0x70383848, 0xF1F5F504, - 0x63BCBCDF, 0x77B6B6C1, 0xAFDADA75, 0x42212163, 0x20101030, 0xE5FFFF1A, 0xFDF3F30E, 0xBFD2D26D, - 0x81CDCD4C, 0x180C0C14, 0x26131335, 0xC3ECEC2F, 0xBE5F5FE1, 0x359797A2, 0x884444CC, 0x2E171739, - 0x93C4C457, 0x55A7A7F2, 0xFC7E7E82, 0x7A3D3D47, 0xC86464AC, 0xBA5D5DE7, 0x3219192B, 0xE6737395, - 0xC06060A0, 0x19818198, 0x9E4F4FD1, 0xA3DCDC7F, 0x44222266, 0x542A2A7E, 0x3B9090AB, 0x0B888883, - 0x8C4646CA, 0xC7EEEE29, 0x6BB8B8D3, 0x2814143C, 0xA7DEDE79, 0xBC5E5EE2, 0x160B0B1D, 0xADDBDB76, - 0xDBE0E03B, 0x64323256, 0x743A3A4E, 0x140A0A1E, 0x924949DB, 0x0C06060A, 0x4824246C, 0xB85C5CE4, - 0x9FC2C25D, 0xBDD3D36E, 0x43ACACEF, 0xC46262A6, 0x399191A8, 0x319595A4, 0xD3E4E437, 0xF279798B, - 0xD5E7E732, 0x8BC8C843, 0x6E373759, 0xDA6D6DB7, 0x018D8D8C, 0xB1D5D564, 0x9C4E4ED2, 0x49A9A9E0, - 0xD86C6CB4, 0xAC5656FA, 0xF3F4F407, 0xCFEAEA25, 0xCA6565AF, 0xF47A7A8E, 0x47AEAEE9, 0x10080818, - 0x6FBABAD5, 0xF0787888, 0x4A25256F, 0x5C2E2E72, 0x381C1C24, 0x57A6A6F1, 0x73B4B4C7, 0x97C6C651, - 0xCBE8E823, 0xA1DDDD7C, 0xE874749C, 0x3E1F1F21, 0x964B4BDD, 0x61BDBDDC, 0x0D8B8B86, 0x0F8A8A85, - 0xE0707090, 0x7C3E3E42, 0x71B5B5C4, 0xCC6666AA, 0x904848D8, 0x06030305, 0xF7F6F601, 0x1C0E0E12, - 0xC26161A3, 0x6A35355F, 0xAE5757F9, 0x69B9B9D0, 0x17868691, 0x99C1C158, 0x3A1D1D27, 0x279E9EB9, - 0xD9E1E138, 0xEBF8F813, 0x2B9898B3, 0x22111133, 0xD26969BB, 0xA9D9D970, 0x078E8E89, 0x339494A7, - 0x2D9B9BB6, 0x3C1E1E22, 0x15878792, 0xC9E9E920, 0x87CECE49, 0xAA5555FF, 0x50282878, 0xA5DFDF7A, - 0x038C8C8F, 0x59A1A1F8, 0x09898980, 0x1A0D0D17, 0x65BFBFDA, 0xD7E6E631, 0x844242C6, 0xD06868B8, - 0x824141C3, 0x299999B0, 0x5A2D2D77, 0x1E0F0F11, 0x7BB0B0CB, 0xA85454FC, 0x6DBBBBD6, 0x2C16163A - ); - - /** - * Precomputed mixColumns table - * - * @see Crypt_Rijndael:_encryptBlock() - * @see Crypt_Rijndael:_decryptBlock() - * @var Array - * @access private - */ - var $t1 = array( - 0xA5C66363, 0x84F87C7C, 0x99EE7777, 0x8DF67B7B, 0x0DFFF2F2, 0xBDD66B6B, 0xB1DE6F6F, 0x5491C5C5, - 0x50603030, 0x03020101, 0xA9CE6767, 0x7D562B2B, 0x19E7FEFE, 0x62B5D7D7, 0xE64DABAB, 0x9AEC7676, - 0x458FCACA, 0x9D1F8282, 0x4089C9C9, 0x87FA7D7D, 0x15EFFAFA, 0xEBB25959, 0xC98E4747, 0x0BFBF0F0, - 0xEC41ADAD, 0x67B3D4D4, 0xFD5FA2A2, 0xEA45AFAF, 0xBF239C9C, 0xF753A4A4, 0x96E47272, 0x5B9BC0C0, - 0xC275B7B7, 0x1CE1FDFD, 0xAE3D9393, 0x6A4C2626, 0x5A6C3636, 0x417E3F3F, 0x02F5F7F7, 0x4F83CCCC, - 0x5C683434, 0xF451A5A5, 0x34D1E5E5, 0x08F9F1F1, 0x93E27171, 0x73ABD8D8, 0x53623131, 0x3F2A1515, - 0x0C080404, 0x5295C7C7, 0x65462323, 0x5E9DC3C3, 0x28301818, 0xA1379696, 0x0F0A0505, 0xB52F9A9A, - 0x090E0707, 0x36241212, 0x9B1B8080, 0x3DDFE2E2, 0x26CDEBEB, 0x694E2727, 0xCD7FB2B2, 0x9FEA7575, - 0x1B120909, 0x9E1D8383, 0x74582C2C, 0x2E341A1A, 0x2D361B1B, 0xB2DC6E6E, 0xEEB45A5A, 0xFB5BA0A0, - 0xF6A45252, 0x4D763B3B, 0x61B7D6D6, 0xCE7DB3B3, 0x7B522929, 0x3EDDE3E3, 0x715E2F2F, 0x97138484, - 0xF5A65353, 0x68B9D1D1, 0x00000000, 0x2CC1EDED, 0x60402020, 0x1FE3FCFC, 0xC879B1B1, 0xEDB65B5B, - 0xBED46A6A, 0x468DCBCB, 0xD967BEBE, 0x4B723939, 0xDE944A4A, 0xD4984C4C, 0xE8B05858, 0x4A85CFCF, - 0x6BBBD0D0, 0x2AC5EFEF, 0xE54FAAAA, 0x16EDFBFB, 0xC5864343, 0xD79A4D4D, 0x55663333, 0x94118585, - 0xCF8A4545, 0x10E9F9F9, 0x06040202, 0x81FE7F7F, 0xF0A05050, 0x44783C3C, 0xBA259F9F, 0xE34BA8A8, - 0xF3A25151, 0xFE5DA3A3, 0xC0804040, 0x8A058F8F, 0xAD3F9292, 0xBC219D9D, 0x48703838, 0x04F1F5F5, - 0xDF63BCBC, 0xC177B6B6, 0x75AFDADA, 0x63422121, 0x30201010, 0x1AE5FFFF, 0x0EFDF3F3, 0x6DBFD2D2, - 0x4C81CDCD, 0x14180C0C, 0x35261313, 0x2FC3ECEC, 0xE1BE5F5F, 0xA2359797, 0xCC884444, 0x392E1717, - 0x5793C4C4, 0xF255A7A7, 0x82FC7E7E, 0x477A3D3D, 0xACC86464, 0xE7BA5D5D, 0x2B321919, 0x95E67373, - 0xA0C06060, 0x98198181, 0xD19E4F4F, 0x7FA3DCDC, 0x66442222, 0x7E542A2A, 0xAB3B9090, 0x830B8888, - 0xCA8C4646, 0x29C7EEEE, 0xD36BB8B8, 0x3C281414, 0x79A7DEDE, 0xE2BC5E5E, 0x1D160B0B, 0x76ADDBDB, - 0x3BDBE0E0, 0x56643232, 0x4E743A3A, 0x1E140A0A, 0xDB924949, 0x0A0C0606, 0x6C482424, 0xE4B85C5C, - 0x5D9FC2C2, 0x6EBDD3D3, 0xEF43ACAC, 0xA6C46262, 0xA8399191, 0xA4319595, 0x37D3E4E4, 0x8BF27979, - 0x32D5E7E7, 0x438BC8C8, 0x596E3737, 0xB7DA6D6D, 0x8C018D8D, 0x64B1D5D5, 0xD29C4E4E, 0xE049A9A9, - 0xB4D86C6C, 0xFAAC5656, 0x07F3F4F4, 0x25CFEAEA, 0xAFCA6565, 0x8EF47A7A, 0xE947AEAE, 0x18100808, - 0xD56FBABA, 0x88F07878, 0x6F4A2525, 0x725C2E2E, 0x24381C1C, 0xF157A6A6, 0xC773B4B4, 0x5197C6C6, - 0x23CBE8E8, 0x7CA1DDDD, 0x9CE87474, 0x213E1F1F, 0xDD964B4B, 0xDC61BDBD, 0x860D8B8B, 0x850F8A8A, - 0x90E07070, 0x427C3E3E, 0xC471B5B5, 0xAACC6666, 0xD8904848, 0x05060303, 0x01F7F6F6, 0x121C0E0E, - 0xA3C26161, 0x5F6A3535, 0xF9AE5757, 0xD069B9B9, 0x91178686, 0x5899C1C1, 0x273A1D1D, 0xB9279E9E, - 0x38D9E1E1, 0x13EBF8F8, 0xB32B9898, 0x33221111, 0xBBD26969, 0x70A9D9D9, 0x89078E8E, 0xA7339494, - 0xB62D9B9B, 0x223C1E1E, 0x92158787, 0x20C9E9E9, 0x4987CECE, 0xFFAA5555, 0x78502828, 0x7AA5DFDF, - 0x8F038C8C, 0xF859A1A1, 0x80098989, 0x171A0D0D, 0xDA65BFBF, 0x31D7E6E6, 0xC6844242, 0xB8D06868, - 0xC3824141, 0xB0299999, 0x775A2D2D, 0x111E0F0F, 0xCB7BB0B0, 0xFCA85454, 0xD66DBBBB, 0x3A2C1616 - ); - - /** - * Precomputed mixColumns table - * - * @see Crypt_Rijndael:_encryptBlock() - * @see Crypt_Rijndael:_decryptBlock() - * @var Array - * @access private - */ - var $t2 = array( - 0x63A5C663, 0x7C84F87C, 0x7799EE77, 0x7B8DF67B, 0xF20DFFF2, 0x6BBDD66B, 0x6FB1DE6F, 0xC55491C5, - 0x30506030, 0x01030201, 0x67A9CE67, 0x2B7D562B, 0xFE19E7FE, 0xD762B5D7, 0xABE64DAB, 0x769AEC76, - 0xCA458FCA, 0x829D1F82, 0xC94089C9, 0x7D87FA7D, 0xFA15EFFA, 0x59EBB259, 0x47C98E47, 0xF00BFBF0, - 0xADEC41AD, 0xD467B3D4, 0xA2FD5FA2, 0xAFEA45AF, 0x9CBF239C, 0xA4F753A4, 0x7296E472, 0xC05B9BC0, - 0xB7C275B7, 0xFD1CE1FD, 0x93AE3D93, 0x266A4C26, 0x365A6C36, 0x3F417E3F, 0xF702F5F7, 0xCC4F83CC, - 0x345C6834, 0xA5F451A5, 0xE534D1E5, 0xF108F9F1, 0x7193E271, 0xD873ABD8, 0x31536231, 0x153F2A15, - 0x040C0804, 0xC75295C7, 0x23654623, 0xC35E9DC3, 0x18283018, 0x96A13796, 0x050F0A05, 0x9AB52F9A, - 0x07090E07, 0x12362412, 0x809B1B80, 0xE23DDFE2, 0xEB26CDEB, 0x27694E27, 0xB2CD7FB2, 0x759FEA75, - 0x091B1209, 0x839E1D83, 0x2C74582C, 0x1A2E341A, 0x1B2D361B, 0x6EB2DC6E, 0x5AEEB45A, 0xA0FB5BA0, - 0x52F6A452, 0x3B4D763B, 0xD661B7D6, 0xB3CE7DB3, 0x297B5229, 0xE33EDDE3, 0x2F715E2F, 0x84971384, - 0x53F5A653, 0xD168B9D1, 0x00000000, 0xED2CC1ED, 0x20604020, 0xFC1FE3FC, 0xB1C879B1, 0x5BEDB65B, - 0x6ABED46A, 0xCB468DCB, 0xBED967BE, 0x394B7239, 0x4ADE944A, 0x4CD4984C, 0x58E8B058, 0xCF4A85CF, - 0xD06BBBD0, 0xEF2AC5EF, 0xAAE54FAA, 0xFB16EDFB, 0x43C58643, 0x4DD79A4D, 0x33556633, 0x85941185, - 0x45CF8A45, 0xF910E9F9, 0x02060402, 0x7F81FE7F, 0x50F0A050, 0x3C44783C, 0x9FBA259F, 0xA8E34BA8, - 0x51F3A251, 0xA3FE5DA3, 0x40C08040, 0x8F8A058F, 0x92AD3F92, 0x9DBC219D, 0x38487038, 0xF504F1F5, - 0xBCDF63BC, 0xB6C177B6, 0xDA75AFDA, 0x21634221, 0x10302010, 0xFF1AE5FF, 0xF30EFDF3, 0xD26DBFD2, - 0xCD4C81CD, 0x0C14180C, 0x13352613, 0xEC2FC3EC, 0x5FE1BE5F, 0x97A23597, 0x44CC8844, 0x17392E17, - 0xC45793C4, 0xA7F255A7, 0x7E82FC7E, 0x3D477A3D, 0x64ACC864, 0x5DE7BA5D, 0x192B3219, 0x7395E673, - 0x60A0C060, 0x81981981, 0x4FD19E4F, 0xDC7FA3DC, 0x22664422, 0x2A7E542A, 0x90AB3B90, 0x88830B88, - 0x46CA8C46, 0xEE29C7EE, 0xB8D36BB8, 0x143C2814, 0xDE79A7DE, 0x5EE2BC5E, 0x0B1D160B, 0xDB76ADDB, - 0xE03BDBE0, 0x32566432, 0x3A4E743A, 0x0A1E140A, 0x49DB9249, 0x060A0C06, 0x246C4824, 0x5CE4B85C, - 0xC25D9FC2, 0xD36EBDD3, 0xACEF43AC, 0x62A6C462, 0x91A83991, 0x95A43195, 0xE437D3E4, 0x798BF279, - 0xE732D5E7, 0xC8438BC8, 0x37596E37, 0x6DB7DA6D, 0x8D8C018D, 0xD564B1D5, 0x4ED29C4E, 0xA9E049A9, - 0x6CB4D86C, 0x56FAAC56, 0xF407F3F4, 0xEA25CFEA, 0x65AFCA65, 0x7A8EF47A, 0xAEE947AE, 0x08181008, - 0xBAD56FBA, 0x7888F078, 0x256F4A25, 0x2E725C2E, 0x1C24381C, 0xA6F157A6, 0xB4C773B4, 0xC65197C6, - 0xE823CBE8, 0xDD7CA1DD, 0x749CE874, 0x1F213E1F, 0x4BDD964B, 0xBDDC61BD, 0x8B860D8B, 0x8A850F8A, - 0x7090E070, 0x3E427C3E, 0xB5C471B5, 0x66AACC66, 0x48D89048, 0x03050603, 0xF601F7F6, 0x0E121C0E, - 0x61A3C261, 0x355F6A35, 0x57F9AE57, 0xB9D069B9, 0x86911786, 0xC15899C1, 0x1D273A1D, 0x9EB9279E, - 0xE138D9E1, 0xF813EBF8, 0x98B32B98, 0x11332211, 0x69BBD269, 0xD970A9D9, 0x8E89078E, 0x94A73394, - 0x9BB62D9B, 0x1E223C1E, 0x87921587, 0xE920C9E9, 0xCE4987CE, 0x55FFAA55, 0x28785028, 0xDF7AA5DF, - 0x8C8F038C, 0xA1F859A1, 0x89800989, 0x0D171A0D, 0xBFDA65BF, 0xE631D7E6, 0x42C68442, 0x68B8D068, - 0x41C38241, 0x99B02999, 0x2D775A2D, 0x0F111E0F, 0xB0CB7BB0, 0x54FCA854, 0xBBD66DBB, 0x163A2C16 - ); - - /** - * Precomputed mixColumns table - * - * @see Crypt_Rijndael:_encryptBlock() - * @see Crypt_Rijndael:_decryptBlock() - * @var Array - * @access private - */ - var $t3 = array( - 0x6363A5C6, 0x7C7C84F8, 0x777799EE, 0x7B7B8DF6, 0xF2F20DFF, 0x6B6BBDD6, 0x6F6FB1DE, 0xC5C55491, - 0x30305060, 0x01010302, 0x6767A9CE, 0x2B2B7D56, 0xFEFE19E7, 0xD7D762B5, 0xABABE64D, 0x76769AEC, - 0xCACA458F, 0x82829D1F, 0xC9C94089, 0x7D7D87FA, 0xFAFA15EF, 0x5959EBB2, 0x4747C98E, 0xF0F00BFB, - 0xADADEC41, 0xD4D467B3, 0xA2A2FD5F, 0xAFAFEA45, 0x9C9CBF23, 0xA4A4F753, 0x727296E4, 0xC0C05B9B, - 0xB7B7C275, 0xFDFD1CE1, 0x9393AE3D, 0x26266A4C, 0x36365A6C, 0x3F3F417E, 0xF7F702F5, 0xCCCC4F83, - 0x34345C68, 0xA5A5F451, 0xE5E534D1, 0xF1F108F9, 0x717193E2, 0xD8D873AB, 0x31315362, 0x15153F2A, - 0x04040C08, 0xC7C75295, 0x23236546, 0xC3C35E9D, 0x18182830, 0x9696A137, 0x05050F0A, 0x9A9AB52F, - 0x0707090E, 0x12123624, 0x80809B1B, 0xE2E23DDF, 0xEBEB26CD, 0x2727694E, 0xB2B2CD7F, 0x75759FEA, - 0x09091B12, 0x83839E1D, 0x2C2C7458, 0x1A1A2E34, 0x1B1B2D36, 0x6E6EB2DC, 0x5A5AEEB4, 0xA0A0FB5B, - 0x5252F6A4, 0x3B3B4D76, 0xD6D661B7, 0xB3B3CE7D, 0x29297B52, 0xE3E33EDD, 0x2F2F715E, 0x84849713, - 0x5353F5A6, 0xD1D168B9, 0x00000000, 0xEDED2CC1, 0x20206040, 0xFCFC1FE3, 0xB1B1C879, 0x5B5BEDB6, - 0x6A6ABED4, 0xCBCB468D, 0xBEBED967, 0x39394B72, 0x4A4ADE94, 0x4C4CD498, 0x5858E8B0, 0xCFCF4A85, - 0xD0D06BBB, 0xEFEF2AC5, 0xAAAAE54F, 0xFBFB16ED, 0x4343C586, 0x4D4DD79A, 0x33335566, 0x85859411, - 0x4545CF8A, 0xF9F910E9, 0x02020604, 0x7F7F81FE, 0x5050F0A0, 0x3C3C4478, 0x9F9FBA25, 0xA8A8E34B, - 0x5151F3A2, 0xA3A3FE5D, 0x4040C080, 0x8F8F8A05, 0x9292AD3F, 0x9D9DBC21, 0x38384870, 0xF5F504F1, - 0xBCBCDF63, 0xB6B6C177, 0xDADA75AF, 0x21216342, 0x10103020, 0xFFFF1AE5, 0xF3F30EFD, 0xD2D26DBF, - 0xCDCD4C81, 0x0C0C1418, 0x13133526, 0xECEC2FC3, 0x5F5FE1BE, 0x9797A235, 0x4444CC88, 0x1717392E, - 0xC4C45793, 0xA7A7F255, 0x7E7E82FC, 0x3D3D477A, 0x6464ACC8, 0x5D5DE7BA, 0x19192B32, 0x737395E6, - 0x6060A0C0, 0x81819819, 0x4F4FD19E, 0xDCDC7FA3, 0x22226644, 0x2A2A7E54, 0x9090AB3B, 0x8888830B, - 0x4646CA8C, 0xEEEE29C7, 0xB8B8D36B, 0x14143C28, 0xDEDE79A7, 0x5E5EE2BC, 0x0B0B1D16, 0xDBDB76AD, - 0xE0E03BDB, 0x32325664, 0x3A3A4E74, 0x0A0A1E14, 0x4949DB92, 0x06060A0C, 0x24246C48, 0x5C5CE4B8, - 0xC2C25D9F, 0xD3D36EBD, 0xACACEF43, 0x6262A6C4, 0x9191A839, 0x9595A431, 0xE4E437D3, 0x79798BF2, - 0xE7E732D5, 0xC8C8438B, 0x3737596E, 0x6D6DB7DA, 0x8D8D8C01, 0xD5D564B1, 0x4E4ED29C, 0xA9A9E049, - 0x6C6CB4D8, 0x5656FAAC, 0xF4F407F3, 0xEAEA25CF, 0x6565AFCA, 0x7A7A8EF4, 0xAEAEE947, 0x08081810, - 0xBABAD56F, 0x787888F0, 0x25256F4A, 0x2E2E725C, 0x1C1C2438, 0xA6A6F157, 0xB4B4C773, 0xC6C65197, - 0xE8E823CB, 0xDDDD7CA1, 0x74749CE8, 0x1F1F213E, 0x4B4BDD96, 0xBDBDDC61, 0x8B8B860D, 0x8A8A850F, - 0x707090E0, 0x3E3E427C, 0xB5B5C471, 0x6666AACC, 0x4848D890, 0x03030506, 0xF6F601F7, 0x0E0E121C, - 0x6161A3C2, 0x35355F6A, 0x5757F9AE, 0xB9B9D069, 0x86869117, 0xC1C15899, 0x1D1D273A, 0x9E9EB927, - 0xE1E138D9, 0xF8F813EB, 0x9898B32B, 0x11113322, 0x6969BBD2, 0xD9D970A9, 0x8E8E8907, 0x9494A733, - 0x9B9BB62D, 0x1E1E223C, 0x87879215, 0xE9E920C9, 0xCECE4987, 0x5555FFAA, 0x28287850, 0xDFDF7AA5, - 0x8C8C8F03, 0xA1A1F859, 0x89898009, 0x0D0D171A, 0xBFBFDA65, 0xE6E631D7, 0x4242C684, 0x6868B8D0, - 0x4141C382, 0x9999B029, 0x2D2D775A, 0x0F0F111E, 0xB0B0CB7B, 0x5454FCA8, 0xBBBBD66D, 0x16163A2C - ); - - /** - * Precomputed invMixColumns table - * - * @see Crypt_Rijndael:_encryptBlock() - * @see Crypt_Rijndael:_decryptBlock() - * @var Array - * @access private - */ - var $dt0 = array( - 0x51F4A750, 0x7E416553, 0x1A17A4C3, 0x3A275E96, 0x3BAB6BCB, 0x1F9D45F1, 0xACFA58AB, 0x4BE30393, - 0x2030FA55, 0xAD766DF6, 0x88CC7691, 0xF5024C25, 0x4FE5D7FC, 0xC52ACBD7, 0x26354480, 0xB562A38F, - 0xDEB15A49, 0x25BA1B67, 0x45EA0E98, 0x5DFEC0E1, 0xC32F7502, 0x814CF012, 0x8D4697A3, 0x6BD3F9C6, - 0x038F5FE7, 0x15929C95, 0xBF6D7AEB, 0x955259DA, 0xD4BE832D, 0x587421D3, 0x49E06929, 0x8EC9C844, - 0x75C2896A, 0xF48E7978, 0x99583E6B, 0x27B971DD, 0xBEE14FB6, 0xF088AD17, 0xC920AC66, 0x7DCE3AB4, - 0x63DF4A18, 0xE51A3182, 0x97513360, 0x62537F45, 0xB16477E0, 0xBB6BAE84, 0xFE81A01C, 0xF9082B94, - 0x70486858, 0x8F45FD19, 0x94DE6C87, 0x527BF8B7, 0xAB73D323, 0x724B02E2, 0xE31F8F57, 0x6655AB2A, - 0xB2EB2807, 0x2FB5C203, 0x86C57B9A, 0xD33708A5, 0x302887F2, 0x23BFA5B2, 0x02036ABA, 0xED16825C, - 0x8ACF1C2B, 0xA779B492, 0xF307F2F0, 0x4E69E2A1, 0x65DAF4CD, 0x0605BED5, 0xD134621F, 0xC4A6FE8A, - 0x342E539D, 0xA2F355A0, 0x058AE132, 0xA4F6EB75, 0x0B83EC39, 0x4060EFAA, 0x5E719F06, 0xBD6E1051, - 0x3E218AF9, 0x96DD063D, 0xDD3E05AE, 0x4DE6BD46, 0x91548DB5, 0x71C45D05, 0x0406D46F, 0x605015FF, - 0x1998FB24, 0xD6BDE997, 0x894043CC, 0x67D99E77, 0xB0E842BD, 0x07898B88, 0xE7195B38, 0x79C8EEDB, - 0xA17C0A47, 0x7C420FE9, 0xF8841EC9, 0x00000000, 0x09808683, 0x322BED48, 0x1E1170AC, 0x6C5A724E, - 0xFD0EFFFB, 0x0F853856, 0x3DAED51E, 0x362D3927, 0x0A0FD964, 0x685CA621, 0x9B5B54D1, 0x24362E3A, - 0x0C0A67B1, 0x9357E70F, 0xB4EE96D2, 0x1B9B919E, 0x80C0C54F, 0x61DC20A2, 0x5A774B69, 0x1C121A16, - 0xE293BA0A, 0xC0A02AE5, 0x3C22E043, 0x121B171D, 0x0E090D0B, 0xF28BC7AD, 0x2DB6A8B9, 0x141EA9C8, - 0x57F11985, 0xAF75074C, 0xEE99DDBB, 0xA37F60FD, 0xF701269F, 0x5C72F5BC, 0x44663BC5, 0x5BFB7E34, - 0x8B432976, 0xCB23C6DC, 0xB6EDFC68, 0xB8E4F163, 0xD731DCCA, 0x42638510, 0x13972240, 0x84C61120, - 0x854A247D, 0xD2BB3DF8, 0xAEF93211, 0xC729A16D, 0x1D9E2F4B, 0xDCB230F3, 0x0D8652EC, 0x77C1E3D0, - 0x2BB3166C, 0xA970B999, 0x119448FA, 0x47E96422, 0xA8FC8CC4, 0xA0F03F1A, 0x567D2CD8, 0x223390EF, - 0x87494EC7, 0xD938D1C1, 0x8CCAA2FE, 0x98D40B36, 0xA6F581CF, 0xA57ADE28, 0xDAB78E26, 0x3FADBFA4, - 0x2C3A9DE4, 0x5078920D, 0x6A5FCC9B, 0x547E4662, 0xF68D13C2, 0x90D8B8E8, 0x2E39F75E, 0x82C3AFF5, - 0x9F5D80BE, 0x69D0937C, 0x6FD52DA9, 0xCF2512B3, 0xC8AC993B, 0x10187DA7, 0xE89C636E, 0xDB3BBB7B, - 0xCD267809, 0x6E5918F4, 0xEC9AB701, 0x834F9AA8, 0xE6956E65, 0xAAFFE67E, 0x21BCCF08, 0xEF15E8E6, - 0xBAE79BD9, 0x4A6F36CE, 0xEA9F09D4, 0x29B07CD6, 0x31A4B2AF, 0x2A3F2331, 0xC6A59430, 0x35A266C0, - 0x744EBC37, 0xFC82CAA6, 0xE090D0B0, 0x33A7D815, 0xF104984A, 0x41ECDAF7, 0x7FCD500E, 0x1791F62F, - 0x764DD68D, 0x43EFB04D, 0xCCAA4D54, 0xE49604DF, 0x9ED1B5E3, 0x4C6A881B, 0xC12C1FB8, 0x4665517F, - 0x9D5EEA04, 0x018C355D, 0xFA877473, 0xFB0B412E, 0xB3671D5A, 0x92DBD252, 0xE9105633, 0x6DD64713, - 0x9AD7618C, 0x37A10C7A, 0x59F8148E, 0xEB133C89, 0xCEA927EE, 0xB761C935, 0xE11CE5ED, 0x7A47B13C, - 0x9CD2DF59, 0x55F2733F, 0x1814CE79, 0x73C737BF, 0x53F7CDEA, 0x5FFDAA5B, 0xDF3D6F14, 0x7844DB86, - 0xCAAFF381, 0xB968C43E, 0x3824342C, 0xC2A3405F, 0x161DC372, 0xBCE2250C, 0x283C498B, 0xFF0D9541, - 0x39A80171, 0x080CB3DE, 0xD8B4E49C, 0x6456C190, 0x7BCB8461, 0xD532B670, 0x486C5C74, 0xD0B85742 - ); - - /** - * Precomputed invMixColumns table - * - * @see Crypt_Rijndael:_encryptBlock() - * @see Crypt_Rijndael:_decryptBlock() - * @var Array - * @access private - */ - var $dt1 = array( - 0x5051F4A7, 0x537E4165, 0xC31A17A4, 0x963A275E, 0xCB3BAB6B, 0xF11F9D45, 0xABACFA58, 0x934BE303, - 0x552030FA, 0xF6AD766D, 0x9188CC76, 0x25F5024C, 0xFC4FE5D7, 0xD7C52ACB, 0x80263544, 0x8FB562A3, - 0x49DEB15A, 0x6725BA1B, 0x9845EA0E, 0xE15DFEC0, 0x02C32F75, 0x12814CF0, 0xA38D4697, 0xC66BD3F9, - 0xE7038F5F, 0x9515929C, 0xEBBF6D7A, 0xDA955259, 0x2DD4BE83, 0xD3587421, 0x2949E069, 0x448EC9C8, - 0x6A75C289, 0x78F48E79, 0x6B99583E, 0xDD27B971, 0xB6BEE14F, 0x17F088AD, 0x66C920AC, 0xB47DCE3A, - 0x1863DF4A, 0x82E51A31, 0x60975133, 0x4562537F, 0xE0B16477, 0x84BB6BAE, 0x1CFE81A0, 0x94F9082B, - 0x58704868, 0x198F45FD, 0x8794DE6C, 0xB7527BF8, 0x23AB73D3, 0xE2724B02, 0x57E31F8F, 0x2A6655AB, - 0x07B2EB28, 0x032FB5C2, 0x9A86C57B, 0xA5D33708, 0xF2302887, 0xB223BFA5, 0xBA02036A, 0x5CED1682, - 0x2B8ACF1C, 0x92A779B4, 0xF0F307F2, 0xA14E69E2, 0xCD65DAF4, 0xD50605BE, 0x1FD13462, 0x8AC4A6FE, - 0x9D342E53, 0xA0A2F355, 0x32058AE1, 0x75A4F6EB, 0x390B83EC, 0xAA4060EF, 0x065E719F, 0x51BD6E10, - 0xF93E218A, 0x3D96DD06, 0xAEDD3E05, 0x464DE6BD, 0xB591548D, 0x0571C45D, 0x6F0406D4, 0xFF605015, - 0x241998FB, 0x97D6BDE9, 0xCC894043, 0x7767D99E, 0xBDB0E842, 0x8807898B, 0x38E7195B, 0xDB79C8EE, - 0x47A17C0A, 0xE97C420F, 0xC9F8841E, 0x00000000, 0x83098086, 0x48322BED, 0xAC1E1170, 0x4E6C5A72, - 0xFBFD0EFF, 0x560F8538, 0x1E3DAED5, 0x27362D39, 0x640A0FD9, 0x21685CA6, 0xD19B5B54, 0x3A24362E, - 0xB10C0A67, 0x0F9357E7, 0xD2B4EE96, 0x9E1B9B91, 0x4F80C0C5, 0xA261DC20, 0x695A774B, 0x161C121A, - 0x0AE293BA, 0xE5C0A02A, 0x433C22E0, 0x1D121B17, 0x0B0E090D, 0xADF28BC7, 0xB92DB6A8, 0xC8141EA9, - 0x8557F119, 0x4CAF7507, 0xBBEE99DD, 0xFDA37F60, 0x9FF70126, 0xBC5C72F5, 0xC544663B, 0x345BFB7E, - 0x768B4329, 0xDCCB23C6, 0x68B6EDFC, 0x63B8E4F1, 0xCAD731DC, 0x10426385, 0x40139722, 0x2084C611, - 0x7D854A24, 0xF8D2BB3D, 0x11AEF932, 0x6DC729A1, 0x4B1D9E2F, 0xF3DCB230, 0xEC0D8652, 0xD077C1E3, - 0x6C2BB316, 0x99A970B9, 0xFA119448, 0x2247E964, 0xC4A8FC8C, 0x1AA0F03F, 0xD8567D2C, 0xEF223390, - 0xC787494E, 0xC1D938D1, 0xFE8CCAA2, 0x3698D40B, 0xCFA6F581, 0x28A57ADE, 0x26DAB78E, 0xA43FADBF, - 0xE42C3A9D, 0x0D507892, 0x9B6A5FCC, 0x62547E46, 0xC2F68D13, 0xE890D8B8, 0x5E2E39F7, 0xF582C3AF, - 0xBE9F5D80, 0x7C69D093, 0xA96FD52D, 0xB3CF2512, 0x3BC8AC99, 0xA710187D, 0x6EE89C63, 0x7BDB3BBB, - 0x09CD2678, 0xF46E5918, 0x01EC9AB7, 0xA8834F9A, 0x65E6956E, 0x7EAAFFE6, 0x0821BCCF, 0xE6EF15E8, - 0xD9BAE79B, 0xCE4A6F36, 0xD4EA9F09, 0xD629B07C, 0xAF31A4B2, 0x312A3F23, 0x30C6A594, 0xC035A266, - 0x37744EBC, 0xA6FC82CA, 0xB0E090D0, 0x1533A7D8, 0x4AF10498, 0xF741ECDA, 0x0E7FCD50, 0x2F1791F6, - 0x8D764DD6, 0x4D43EFB0, 0x54CCAA4D, 0xDFE49604, 0xE39ED1B5, 0x1B4C6A88, 0xB8C12C1F, 0x7F466551, - 0x049D5EEA, 0x5D018C35, 0x73FA8774, 0x2EFB0B41, 0x5AB3671D, 0x5292DBD2, 0x33E91056, 0x136DD647, - 0x8C9AD761, 0x7A37A10C, 0x8E59F814, 0x89EB133C, 0xEECEA927, 0x35B761C9, 0xEDE11CE5, 0x3C7A47B1, - 0x599CD2DF, 0x3F55F273, 0x791814CE, 0xBF73C737, 0xEA53F7CD, 0x5B5FFDAA, 0x14DF3D6F, 0x867844DB, - 0x81CAAFF3, 0x3EB968C4, 0x2C382434, 0x5FC2A340, 0x72161DC3, 0x0CBCE225, 0x8B283C49, 0x41FF0D95, - 0x7139A801, 0xDE080CB3, 0x9CD8B4E4, 0x906456C1, 0x617BCB84, 0x70D532B6, 0x74486C5C, 0x42D0B857 - ); - - /** - * Precomputed invMixColumns table - * - * @see Crypt_Rijndael:_encryptBlock() - * @see Crypt_Rijndael:_decryptBlock() - * @var Array - * @access private - */ - var $dt2 = array( - 0xA75051F4, 0x65537E41, 0xA4C31A17, 0x5E963A27, 0x6BCB3BAB, 0x45F11F9D, 0x58ABACFA, 0x03934BE3, - 0xFA552030, 0x6DF6AD76, 0x769188CC, 0x4C25F502, 0xD7FC4FE5, 0xCBD7C52A, 0x44802635, 0xA38FB562, - 0x5A49DEB1, 0x1B6725BA, 0x0E9845EA, 0xC0E15DFE, 0x7502C32F, 0xF012814C, 0x97A38D46, 0xF9C66BD3, - 0x5FE7038F, 0x9C951592, 0x7AEBBF6D, 0x59DA9552, 0x832DD4BE, 0x21D35874, 0x692949E0, 0xC8448EC9, - 0x896A75C2, 0x7978F48E, 0x3E6B9958, 0x71DD27B9, 0x4FB6BEE1, 0xAD17F088, 0xAC66C920, 0x3AB47DCE, - 0x4A1863DF, 0x3182E51A, 0x33609751, 0x7F456253, 0x77E0B164, 0xAE84BB6B, 0xA01CFE81, 0x2B94F908, - 0x68587048, 0xFD198F45, 0x6C8794DE, 0xF8B7527B, 0xD323AB73, 0x02E2724B, 0x8F57E31F, 0xAB2A6655, - 0x2807B2EB, 0xC2032FB5, 0x7B9A86C5, 0x08A5D337, 0x87F23028, 0xA5B223BF, 0x6ABA0203, 0x825CED16, - 0x1C2B8ACF, 0xB492A779, 0xF2F0F307, 0xE2A14E69, 0xF4CD65DA, 0xBED50605, 0x621FD134, 0xFE8AC4A6, - 0x539D342E, 0x55A0A2F3, 0xE132058A, 0xEB75A4F6, 0xEC390B83, 0xEFAA4060, 0x9F065E71, 0x1051BD6E, - 0x8AF93E21, 0x063D96DD, 0x05AEDD3E, 0xBD464DE6, 0x8DB59154, 0x5D0571C4, 0xD46F0406, 0x15FF6050, - 0xFB241998, 0xE997D6BD, 0x43CC8940, 0x9E7767D9, 0x42BDB0E8, 0x8B880789, 0x5B38E719, 0xEEDB79C8, - 0x0A47A17C, 0x0FE97C42, 0x1EC9F884, 0x00000000, 0x86830980, 0xED48322B, 0x70AC1E11, 0x724E6C5A, - 0xFFFBFD0E, 0x38560F85, 0xD51E3DAE, 0x3927362D, 0xD9640A0F, 0xA621685C, 0x54D19B5B, 0x2E3A2436, - 0x67B10C0A, 0xE70F9357, 0x96D2B4EE, 0x919E1B9B, 0xC54F80C0, 0x20A261DC, 0x4B695A77, 0x1A161C12, - 0xBA0AE293, 0x2AE5C0A0, 0xE0433C22, 0x171D121B, 0x0D0B0E09, 0xC7ADF28B, 0xA8B92DB6, 0xA9C8141E, - 0x198557F1, 0x074CAF75, 0xDDBBEE99, 0x60FDA37F, 0x269FF701, 0xF5BC5C72, 0x3BC54466, 0x7E345BFB, - 0x29768B43, 0xC6DCCB23, 0xFC68B6ED, 0xF163B8E4, 0xDCCAD731, 0x85104263, 0x22401397, 0x112084C6, - 0x247D854A, 0x3DF8D2BB, 0x3211AEF9, 0xA16DC729, 0x2F4B1D9E, 0x30F3DCB2, 0x52EC0D86, 0xE3D077C1, - 0x166C2BB3, 0xB999A970, 0x48FA1194, 0x642247E9, 0x8CC4A8FC, 0x3F1AA0F0, 0x2CD8567D, 0x90EF2233, - 0x4EC78749, 0xD1C1D938, 0xA2FE8CCA, 0x0B3698D4, 0x81CFA6F5, 0xDE28A57A, 0x8E26DAB7, 0xBFA43FAD, - 0x9DE42C3A, 0x920D5078, 0xCC9B6A5F, 0x4662547E, 0x13C2F68D, 0xB8E890D8, 0xF75E2E39, 0xAFF582C3, - 0x80BE9F5D, 0x937C69D0, 0x2DA96FD5, 0x12B3CF25, 0x993BC8AC, 0x7DA71018, 0x636EE89C, 0xBB7BDB3B, - 0x7809CD26, 0x18F46E59, 0xB701EC9A, 0x9AA8834F, 0x6E65E695, 0xE67EAAFF, 0xCF0821BC, 0xE8E6EF15, - 0x9BD9BAE7, 0x36CE4A6F, 0x09D4EA9F, 0x7CD629B0, 0xB2AF31A4, 0x23312A3F, 0x9430C6A5, 0x66C035A2, - 0xBC37744E, 0xCAA6FC82, 0xD0B0E090, 0xD81533A7, 0x984AF104, 0xDAF741EC, 0x500E7FCD, 0xF62F1791, - 0xD68D764D, 0xB04D43EF, 0x4D54CCAA, 0x04DFE496, 0xB5E39ED1, 0x881B4C6A, 0x1FB8C12C, 0x517F4665, - 0xEA049D5E, 0x355D018C, 0x7473FA87, 0x412EFB0B, 0x1D5AB367, 0xD25292DB, 0x5633E910, 0x47136DD6, - 0x618C9AD7, 0x0C7A37A1, 0x148E59F8, 0x3C89EB13, 0x27EECEA9, 0xC935B761, 0xE5EDE11C, 0xB13C7A47, - 0xDF599CD2, 0x733F55F2, 0xCE791814, 0x37BF73C7, 0xCDEA53F7, 0xAA5B5FFD, 0x6F14DF3D, 0xDB867844, - 0xF381CAAF, 0xC43EB968, 0x342C3824, 0x405FC2A3, 0xC372161D, 0x250CBCE2, 0x498B283C, 0x9541FF0D, - 0x017139A8, 0xB3DE080C, 0xE49CD8B4, 0xC1906456, 0x84617BCB, 0xB670D532, 0x5C74486C, 0x5742D0B8 - ); - - /** - * Precomputed invMixColumns table - * - * @see Crypt_Rijndael:_encryptBlock() - * @see Crypt_Rijndael:_decryptBlock() - * @var Array - * @access private - */ - var $dt3 = array( - 0xF4A75051, 0x4165537E, 0x17A4C31A, 0x275E963A, 0xAB6BCB3B, 0x9D45F11F, 0xFA58ABAC, 0xE303934B, - 0x30FA5520, 0x766DF6AD, 0xCC769188, 0x024C25F5, 0xE5D7FC4F, 0x2ACBD7C5, 0x35448026, 0x62A38FB5, - 0xB15A49DE, 0xBA1B6725, 0xEA0E9845, 0xFEC0E15D, 0x2F7502C3, 0x4CF01281, 0x4697A38D, 0xD3F9C66B, - 0x8F5FE703, 0x929C9515, 0x6D7AEBBF, 0x5259DA95, 0xBE832DD4, 0x7421D358, 0xE0692949, 0xC9C8448E, - 0xC2896A75, 0x8E7978F4, 0x583E6B99, 0xB971DD27, 0xE14FB6BE, 0x88AD17F0, 0x20AC66C9, 0xCE3AB47D, - 0xDF4A1863, 0x1A3182E5, 0x51336097, 0x537F4562, 0x6477E0B1, 0x6BAE84BB, 0x81A01CFE, 0x082B94F9, - 0x48685870, 0x45FD198F, 0xDE6C8794, 0x7BF8B752, 0x73D323AB, 0x4B02E272, 0x1F8F57E3, 0x55AB2A66, - 0xEB2807B2, 0xB5C2032F, 0xC57B9A86, 0x3708A5D3, 0x2887F230, 0xBFA5B223, 0x036ABA02, 0x16825CED, - 0xCF1C2B8A, 0x79B492A7, 0x07F2F0F3, 0x69E2A14E, 0xDAF4CD65, 0x05BED506, 0x34621FD1, 0xA6FE8AC4, - 0x2E539D34, 0xF355A0A2, 0x8AE13205, 0xF6EB75A4, 0x83EC390B, 0x60EFAA40, 0x719F065E, 0x6E1051BD, - 0x218AF93E, 0xDD063D96, 0x3E05AEDD, 0xE6BD464D, 0x548DB591, 0xC45D0571, 0x06D46F04, 0x5015FF60, - 0x98FB2419, 0xBDE997D6, 0x4043CC89, 0xD99E7767, 0xE842BDB0, 0x898B8807, 0x195B38E7, 0xC8EEDB79, - 0x7C0A47A1, 0x420FE97C, 0x841EC9F8, 0x00000000, 0x80868309, 0x2BED4832, 0x1170AC1E, 0x5A724E6C, - 0x0EFFFBFD, 0x8538560F, 0xAED51E3D, 0x2D392736, 0x0FD9640A, 0x5CA62168, 0x5B54D19B, 0x362E3A24, - 0x0A67B10C, 0x57E70F93, 0xEE96D2B4, 0x9B919E1B, 0xC0C54F80, 0xDC20A261, 0x774B695A, 0x121A161C, - 0x93BA0AE2, 0xA02AE5C0, 0x22E0433C, 0x1B171D12, 0x090D0B0E, 0x8BC7ADF2, 0xB6A8B92D, 0x1EA9C814, - 0xF1198557, 0x75074CAF, 0x99DDBBEE, 0x7F60FDA3, 0x01269FF7, 0x72F5BC5C, 0x663BC544, 0xFB7E345B, - 0x4329768B, 0x23C6DCCB, 0xEDFC68B6, 0xE4F163B8, 0x31DCCAD7, 0x63851042, 0x97224013, 0xC6112084, - 0x4A247D85, 0xBB3DF8D2, 0xF93211AE, 0x29A16DC7, 0x9E2F4B1D, 0xB230F3DC, 0x8652EC0D, 0xC1E3D077, - 0xB3166C2B, 0x70B999A9, 0x9448FA11, 0xE9642247, 0xFC8CC4A8, 0xF03F1AA0, 0x7D2CD856, 0x3390EF22, - 0x494EC787, 0x38D1C1D9, 0xCAA2FE8C, 0xD40B3698, 0xF581CFA6, 0x7ADE28A5, 0xB78E26DA, 0xADBFA43F, - 0x3A9DE42C, 0x78920D50, 0x5FCC9B6A, 0x7E466254, 0x8D13C2F6, 0xD8B8E890, 0x39F75E2E, 0xC3AFF582, - 0x5D80BE9F, 0xD0937C69, 0xD52DA96F, 0x2512B3CF, 0xAC993BC8, 0x187DA710, 0x9C636EE8, 0x3BBB7BDB, - 0x267809CD, 0x5918F46E, 0x9AB701EC, 0x4F9AA883, 0x956E65E6, 0xFFE67EAA, 0xBCCF0821, 0x15E8E6EF, - 0xE79BD9BA, 0x6F36CE4A, 0x9F09D4EA, 0xB07CD629, 0xA4B2AF31, 0x3F23312A, 0xA59430C6, 0xA266C035, - 0x4EBC3774, 0x82CAA6FC, 0x90D0B0E0, 0xA7D81533, 0x04984AF1, 0xECDAF741, 0xCD500E7F, 0x91F62F17, - 0x4DD68D76, 0xEFB04D43, 0xAA4D54CC, 0x9604DFE4, 0xD1B5E39E, 0x6A881B4C, 0x2C1FB8C1, 0x65517F46, - 0x5EEA049D, 0x8C355D01, 0x877473FA, 0x0B412EFB, 0x671D5AB3, 0xDBD25292, 0x105633E9, 0xD647136D, - 0xD7618C9A, 0xA10C7A37, 0xF8148E59, 0x133C89EB, 0xA927EECE, 0x61C935B7, 0x1CE5EDE1, 0x47B13C7A, - 0xD2DF599C, 0xF2733F55, 0x14CE7918, 0xC737BF73, 0xF7CDEA53, 0xFDAA5B5F, 0x3D6F14DF, 0x44DB8678, - 0xAFF381CA, 0x68C43EB9, 0x24342C38, 0xA3405FC2, 0x1DC37216, 0xE2250CBC, 0x3C498B28, 0x0D9541FF, - 0xA8017139, 0x0CB3DE08, 0xB4E49CD8, 0x56C19064, 0xCB84617B, 0x32B670D5, 0x6C5C7448, 0xB85742D0 - ); - - /** - * The SubByte S-Box - * - * @see Crypt_Rijndael::_encryptBlock() - * @var Array - * @access private - */ - var $sbox = array( - 0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5, 0x30, 0x01, 0x67, 0x2B, 0xFE, 0xD7, 0xAB, 0x76, - 0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0, 0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0, - 0xB7, 0xFD, 0x93, 0x26, 0x36, 0x3F, 0xF7, 0xCC, 0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15, - 0x04, 0xC7, 0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A, 0x07, 0x12, 0x80, 0xE2, 0xEB, 0x27, 0xB2, 0x75, - 0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0xA0, 0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84, - 0x53, 0xD1, 0x00, 0xED, 0x20, 0xFC, 0xB1, 0x5B, 0x6A, 0xCB, 0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF, - 0xD0, 0xEF, 0xAA, 0xFB, 0x43, 0x4D, 0x33, 0x85, 0x45, 0xF9, 0x02, 0x7F, 0x50, 0x3C, 0x9F, 0xA8, - 0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5, 0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2, - 0xCD, 0x0C, 0x13, 0xEC, 0x5F, 0x97, 0x44, 0x17, 0xC4, 0xA7, 0x7E, 0x3D, 0x64, 0x5D, 0x19, 0x73, - 0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A, 0x90, 0x88, 0x46, 0xEE, 0xB8, 0x14, 0xDE, 0x5E, 0x0B, 0xDB, - 0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C, 0xC2, 0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79, - 0xE7, 0xC8, 0x37, 0x6D, 0x8D, 0xD5, 0x4E, 0xA9, 0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A, 0xAE, 0x08, - 0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6, 0xE8, 0xDD, 0x74, 0x1F, 0x4B, 0xBD, 0x8B, 0x8A, - 0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E, 0x61, 0x35, 0x57, 0xB9, 0x86, 0xC1, 0x1D, 0x9E, - 0xE1, 0xF8, 0x98, 0x11, 0x69, 0xD9, 0x8E, 0x94, 0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF, - 0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68, 0x41, 0x99, 0x2D, 0x0F, 0xB0, 0x54, 0xBB, 0x16 - ); - - /** - * The inverse SubByte S-Box - * - * @see Crypt_Rijndael::_decryptBlock() - * @var Array - * @access private - */ - var $isbox = array( - 0x52, 0x09, 0x6A, 0xD5, 0x30, 0x36, 0xA5, 0x38, 0xBF, 0x40, 0xA3, 0x9E, 0x81, 0xF3, 0xD7, 0xFB, - 0x7C, 0xE3, 0x39, 0x82, 0x9B, 0x2F, 0xFF, 0x87, 0x34, 0x8E, 0x43, 0x44, 0xC4, 0xDE, 0xE9, 0xCB, - 0x54, 0x7B, 0x94, 0x32, 0xA6, 0xC2, 0x23, 0x3D, 0xEE, 0x4C, 0x95, 0x0B, 0x42, 0xFA, 0xC3, 0x4E, - 0x08, 0x2E, 0xA1, 0x66, 0x28, 0xD9, 0x24, 0xB2, 0x76, 0x5B, 0xA2, 0x49, 0x6D, 0x8B, 0xD1, 0x25, - 0x72, 0xF8, 0xF6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xD4, 0xA4, 0x5C, 0xCC, 0x5D, 0x65, 0xB6, 0x92, - 0x6C, 0x70, 0x48, 0x50, 0xFD, 0xED, 0xB9, 0xDA, 0x5E, 0x15, 0x46, 0x57, 0xA7, 0x8D, 0x9D, 0x84, - 0x90, 0xD8, 0xAB, 0x00, 0x8C, 0xBC, 0xD3, 0x0A, 0xF7, 0xE4, 0x58, 0x05, 0xB8, 0xB3, 0x45, 0x06, - 0xD0, 0x2C, 0x1E, 0x8F, 0xCA, 0x3F, 0x0F, 0x02, 0xC1, 0xAF, 0xBD, 0x03, 0x01, 0x13, 0x8A, 0x6B, - 0x3A, 0x91, 0x11, 0x41, 0x4F, 0x67, 0xDC, 0xEA, 0x97, 0xF2, 0xCF, 0xCE, 0xF0, 0xB4, 0xE6, 0x73, - 0x96, 0xAC, 0x74, 0x22, 0xE7, 0xAD, 0x35, 0x85, 0xE2, 0xF9, 0x37, 0xE8, 0x1C, 0x75, 0xDF, 0x6E, - 0x47, 0xF1, 0x1A, 0x71, 0x1D, 0x29, 0xC5, 0x89, 0x6F, 0xB7, 0x62, 0x0E, 0xAA, 0x18, 0xBE, 0x1B, - 0xFC, 0x56, 0x3E, 0x4B, 0xC6, 0xD2, 0x79, 0x20, 0x9A, 0xDB, 0xC0, 0xFE, 0x78, 0xCD, 0x5A, 0xF4, - 0x1F, 0xDD, 0xA8, 0x33, 0x88, 0x07, 0xC7, 0x31, 0xB1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xEC, 0x5F, - 0x60, 0x51, 0x7F, 0xA9, 0x19, 0xB5, 0x4A, 0x0D, 0x2D, 0xE5, 0x7A, 0x9F, 0x93, 0xC9, 0x9C, 0xEF, - 0xA0, 0xE0, 0x3B, 0x4D, 0xAE, 0x2A, 0xF5, 0xB0, 0xC8, 0xEB, 0xBB, 0x3C, 0x83, 0x53, 0x99, 0x61, - 0x17, 0x2B, 0x04, 0x7E, 0xBA, 0x77, 0xD6, 0x26, 0xE1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0C, 0x7D - ); - /** * Default Constructor. * @@ -823,45 +423,19 @@ class Crypt_Rijndael extends Crypt_Base */ function _setupEngine() { - if (constant('CRYPT_' . $this->const_namespace . '_MODE') == CRYPT_MODE_INTERNAL) { - // No mcrypt support at all for rijndael - return; - } + // Set the mcrypt module name for the current $block_size of rijndael + $this->cipher_name_mcrypt = 'rijndael-' . ($this->block_size << 3); - // The required mcrypt module name for the current $block_size of rijndael - $cipher_name_mcrypt = 'rijndael-' . ($this->block_size << 3); - - // Determining the availibility/usability of $cipher_name_mcrypt - switch (true) { - case $this->key_size % 8: // mcrypt is not usable for 160/224-bit keys, only for 128/192/256-bit keys - case !in_array($cipher_name_mcrypt, mcrypt_list_algorithms()): // $cipher_name_mcrypt is not available for the current $block_size - $engine = CRYPT_MODE_INTERNAL; - break; - default: - $engine = CRYPT_MODE_MCRYPT; - } - - if ($this->engine == $engine && $this->cipher_name_mcrypt == $cipher_name_mcrypt) { - // allready set, so we not unnecessary close $this->enmcrypt/demcrypt/ecb - return; - } - - // Set the $engine - $this->engine = $engine; - $this->cipher_name_mcrypt = $cipher_name_mcrypt; - - if ($this->enmcrypt) { - // Closing the current mcrypt resource(s). _mcryptSetup() will, if needed, - // (re)open them with the module named in $this->cipher_name_mcrypt - mcrypt_module_close($this->enmcrypt); - mcrypt_module_close($this->demcrypt); - $this->enmcrypt = null; - $this->demcrypt = null; - - if ($this->ecb) { - mcrypt_module_close($this->ecb); - $this->ecb = null; - } + // Set the engine + if ($this->key_size % 8) { // is it a 160/224-bit key? + // mcrypt is not usable for them, only for 128/192/256-bit keys + // so we are forced to set the slower MODE_INTERNAL $engine + $this->setEngine(CRYPT_MODE_INTERNAL); + } else { + // Set what is set/preferred in CRYPT_RIJNDAEL_MODE + // If its CRYPT_RIJNDAEL_MODE_MCRYPT and $this->cipher_name_mcrypt not available + // setEngine() will set to CRYPT_RIJNDAEL_MODE_INTERNAL automatically + $this->setEngine(constant('CRYPT_' . $this->const_namespace . '_MODE')); } } @@ -886,16 +460,15 @@ class Crypt_Rijndael extends Crypt_Base */ function _encryptBlock($in) { - static $t0, $t1, $t2, $t3, $sbox; - if (!$t0) { - for ($i = 0; $i < 256; ++$i) { - $t0[] = (int)$this->t0[$i]; - $t1[] = (int)$this->t1[$i]; - $t2[] = (int)$this->t2[$i]; - $t3[] = (int)$this->t3[$i]; - $sbox[] = (int)$this->sbox[$i]; - } + static $tables; + if (empty($tables)) { + $tables = &$this->_getTables(); } + $t0 = $tables[0]; + $t1 = $tables[1]; + $t2 = $tables[2]; + $t3 = $tables[3]; + $sbox = $tables[4]; $state = array(); $words = unpack('N*', $in); @@ -906,9 +479,9 @@ class Crypt_Rijndael extends Crypt_Base $Nr = $this->Nr; // addRoundKey - $i = -1; + $wc = $Nb - 1; foreach ($words as $word) { - $state[] = $word ^ $w[0][++$i]; + $state[] = $word ^ $w[++$wc]; } // fips-197.pdf#page=19, "Figure 5. Pseudo Code for the Cipher", states that this loop has four components - @@ -931,7 +504,7 @@ class Crypt_Rijndael extends Crypt_Base $t1[$state[$j] >> 16 & 0x000000FF] ^ $t2[$state[$k] >> 8 & 0x000000FF] ^ $t3[$state[$l] & 0x000000FF] ^ - $w[$round][$i]; + $w[++$wc]; ++$i; $j = ($j + 1) % $Nb; $k = ($k + 1) % $Nb; @@ -958,7 +531,7 @@ class Crypt_Rijndael extends Crypt_Base ($state[$j] & 0x00FF0000) ^ ($state[$k] & 0x0000FF00) ^ ($state[$l] & 0x000000FF) ^ - $w[$Nr][$i]; + $w[$i]; ++$i; $j = ($j + 1) % $Nb; $k = ($k + 1) % $Nb; @@ -988,16 +561,15 @@ class Crypt_Rijndael extends Crypt_Base */ function _decryptBlock($in) { - static $dt0, $dt1, $dt2, $dt3, $isbox; - if (!$dt0) { - for ($i = 0; $i < 256; ++$i) { - $dt0[] = (int)$this->dt0[$i]; - $dt1[] = (int)$this->dt1[$i]; - $dt2[] = (int)$this->dt2[$i]; - $dt3[] = (int)$this->dt3[$i]; - $isbox[] = (int)$this->isbox[$i]; - } + static $invtables; + if (empty($invtables)) { + $invtables = &$this->_getInvTables(); } + $dt0 = $invtables[0]; + $dt1 = $invtables[1]; + $dt2 = $invtables[2]; + $dt3 = $invtables[3]; + $isbox = $invtables[4]; $state = array(); $words = unpack('N*', $in); @@ -1008,9 +580,9 @@ class Crypt_Rijndael extends Crypt_Base $Nr = $this->Nr; // addRoundKey - $i = -1; + $wc = $Nb - 1; foreach ($words as $word) { - $state[] = $word ^ $dw[$Nr][++$i]; + $state[] = $word ^ $dw[++$wc]; } $temp = array(); @@ -1025,7 +597,7 @@ class Crypt_Rijndael extends Crypt_Base $dt1[$state[$j] >> 16 & 0x000000FF] ^ $dt2[$state[$k] >> 8 & 0x000000FF] ^ $dt3[$state[$l] & 0x000000FF] ^ - $dw[$round][$i]; + $dw[++$wc]; ++$i; $j = ($j + 1) % $Nb; $k = ($k + 1) % $Nb; @@ -1046,10 +618,10 @@ class Crypt_Rijndael extends Crypt_Base ($state[$k] & 0x0000FF00) | ($state[$l] & 0x000000FF); - $temp[$i] = $dw[0][$i] ^ ($isbox[$word & 0x000000FF] | - ($isbox[$word >> 8 & 0x000000FF] << 8) | - ($isbox[$word >> 16 & 0x000000FF] << 16) | - ($isbox[$word >> 24 & 0x000000FF] << 24)); + $temp[$i] = $dw[$i] ^ ($isbox[$word & 0x000000FF] | + ($isbox[$word >> 8 & 0x000000FF] << 8) | + ($isbox[$word >> 16 & 0x000000FF] << 16) | + ($isbox[$word >> 24 & 0x000000FF] << 24)); ++$i; $j = ($j + 1) % $Nb; $k = ($k + 1) % $Nb; @@ -1143,6 +715,7 @@ class Crypt_Rijndael extends Crypt_Base // 1. Apply the Key Expansion. // 2. Apply InvMixColumn to all Round Keys except the first and the last one." // also, see fips-197.pdf#page=27, "5.3.5 Equivalent Inverse Cipher" + list($dt0, $dt1, $dt2, $dt3) = $this->_getInvTables(); $temp = $this->w = $this->dw = array(); for ($i = $row = $col = 0; $i < $length; $i++, $col++) { if ($col == $this->Nb) { @@ -1153,10 +726,10 @@ class Crypt_Rijndael extends Crypt_Base $j = 0; while ($j < $this->Nb) { $dw = $this->_subWord($this->w[$row][$j]); - $temp[$j] = $this->dt0[$dw >> 24 & 0x000000FF] ^ - $this->dt1[$dw >> 16 & 0x000000FF] ^ - $this->dt2[$dw >> 8 & 0x000000FF] ^ - $this->dt3[$dw & 0x000000FF]; + $temp[$j] = $dt0[$dw >> 24 & 0x000000FF] ^ + $dt1[$dw >> 16 & 0x000000FF] ^ + $dt2[$dw >> 8 & 0x000000FF] ^ + $dt3[$dw & 0x000000FF]; $j++; } $this->dw[$row] = $temp; @@ -1170,20 +743,18 @@ class Crypt_Rijndael extends Crypt_Base $this->dw[$row] = $this->w[$row]; - // In case of $this->use_inline_crypt === true we have to use 1-dim key arrays (both ascending) - if ($this->use_inline_crypt) { - $this->dw = array_reverse($this->dw); - $w = array_pop($this->w); - $dw = array_pop($this->dw); - foreach ($this->w as $r => $wr) { - foreach ($wr as $c => $wc) { - $w[] = $wc; - $dw[] = $this->dw[$r][$c]; - } + // Converting to 1-dim key arrays (both ascending) + $this->dw = array_reverse($this->dw); + $w = array_pop($this->w); + $dw = array_pop($this->dw); + foreach ($this->w as $r => $wr) { + foreach ($wr as $c => $wc) { + $w[] = $wc; + $dw[] = $this->dw[$r][$c]; } - $this->w = $w; - $this->dw = $dw; } + $this->w = $w; + $this->dw = $dw; } /** @@ -1194,7 +765,10 @@ class Crypt_Rijndael extends Crypt_Base */ function _subWord($word) { - $sbox = $this->sbox; + static $sbox; + if (empty($sbox)) { + list(,,,, $sbox) = $this->_getTables(); + } return $sbox[$word & 0x000000FF] | ($sbox[$word >> 8 & 0x000000FF] << 8) | @@ -1202,6 +776,179 @@ class Crypt_Rijndael extends Crypt_Base ($sbox[$word >> 24 & 0x000000FF] << 24); } + /** + * Provides the mixColumns and sboxes tables + * + * @see Crypt_Rijndael:_encryptBlock() + * @see Crypt_Rijndael:_setupInlineCrypt() + * @see Crypt_Rijndael:_subWord() + * @access private + * @return Array &$tables + */ + function &_getTables() + { + static $tables; + if (empty($tables)) { + // according to (section 5.2.1), + // precomputed tables can be used in the mixColumns phase. in that example, they're assigned t0...t3, so + // those are the names we'll use. + $t3 = array_map('intval', array( + // with array_map('intval', ...) we ensure we have only int's and not + // some slower floats converted by php automatically on high values + 0x6363A5C6, 0x7C7C84F8, 0x777799EE, 0x7B7B8DF6, 0xF2F20DFF, 0x6B6BBDD6, 0x6F6FB1DE, 0xC5C55491, + 0x30305060, 0x01010302, 0x6767A9CE, 0x2B2B7D56, 0xFEFE19E7, 0xD7D762B5, 0xABABE64D, 0x76769AEC, + 0xCACA458F, 0x82829D1F, 0xC9C94089, 0x7D7D87FA, 0xFAFA15EF, 0x5959EBB2, 0x4747C98E, 0xF0F00BFB, + 0xADADEC41, 0xD4D467B3, 0xA2A2FD5F, 0xAFAFEA45, 0x9C9CBF23, 0xA4A4F753, 0x727296E4, 0xC0C05B9B, + 0xB7B7C275, 0xFDFD1CE1, 0x9393AE3D, 0x26266A4C, 0x36365A6C, 0x3F3F417E, 0xF7F702F5, 0xCCCC4F83, + 0x34345C68, 0xA5A5F451, 0xE5E534D1, 0xF1F108F9, 0x717193E2, 0xD8D873AB, 0x31315362, 0x15153F2A, + 0x04040C08, 0xC7C75295, 0x23236546, 0xC3C35E9D, 0x18182830, 0x9696A137, 0x05050F0A, 0x9A9AB52F, + 0x0707090E, 0x12123624, 0x80809B1B, 0xE2E23DDF, 0xEBEB26CD, 0x2727694E, 0xB2B2CD7F, 0x75759FEA, + 0x09091B12, 0x83839E1D, 0x2C2C7458, 0x1A1A2E34, 0x1B1B2D36, 0x6E6EB2DC, 0x5A5AEEB4, 0xA0A0FB5B, + 0x5252F6A4, 0x3B3B4D76, 0xD6D661B7, 0xB3B3CE7D, 0x29297B52, 0xE3E33EDD, 0x2F2F715E, 0x84849713, + 0x5353F5A6, 0xD1D168B9, 0x00000000, 0xEDED2CC1, 0x20206040, 0xFCFC1FE3, 0xB1B1C879, 0x5B5BEDB6, + 0x6A6ABED4, 0xCBCB468D, 0xBEBED967, 0x39394B72, 0x4A4ADE94, 0x4C4CD498, 0x5858E8B0, 0xCFCF4A85, + 0xD0D06BBB, 0xEFEF2AC5, 0xAAAAE54F, 0xFBFB16ED, 0x4343C586, 0x4D4DD79A, 0x33335566, 0x85859411, + 0x4545CF8A, 0xF9F910E9, 0x02020604, 0x7F7F81FE, 0x5050F0A0, 0x3C3C4478, 0x9F9FBA25, 0xA8A8E34B, + 0x5151F3A2, 0xA3A3FE5D, 0x4040C080, 0x8F8F8A05, 0x9292AD3F, 0x9D9DBC21, 0x38384870, 0xF5F504F1, + 0xBCBCDF63, 0xB6B6C177, 0xDADA75AF, 0x21216342, 0x10103020, 0xFFFF1AE5, 0xF3F30EFD, 0xD2D26DBF, + 0xCDCD4C81, 0x0C0C1418, 0x13133526, 0xECEC2FC3, 0x5F5FE1BE, 0x9797A235, 0x4444CC88, 0x1717392E, + 0xC4C45793, 0xA7A7F255, 0x7E7E82FC, 0x3D3D477A, 0x6464ACC8, 0x5D5DE7BA, 0x19192B32, 0x737395E6, + 0x6060A0C0, 0x81819819, 0x4F4FD19E, 0xDCDC7FA3, 0x22226644, 0x2A2A7E54, 0x9090AB3B, 0x8888830B, + 0x4646CA8C, 0xEEEE29C7, 0xB8B8D36B, 0x14143C28, 0xDEDE79A7, 0x5E5EE2BC, 0x0B0B1D16, 0xDBDB76AD, + 0xE0E03BDB, 0x32325664, 0x3A3A4E74, 0x0A0A1E14, 0x4949DB92, 0x06060A0C, 0x24246C48, 0x5C5CE4B8, + 0xC2C25D9F, 0xD3D36EBD, 0xACACEF43, 0x6262A6C4, 0x9191A839, 0x9595A431, 0xE4E437D3, 0x79798BF2, + 0xE7E732D5, 0xC8C8438B, 0x3737596E, 0x6D6DB7DA, 0x8D8D8C01, 0xD5D564B1, 0x4E4ED29C, 0xA9A9E049, + 0x6C6CB4D8, 0x5656FAAC, 0xF4F407F3, 0xEAEA25CF, 0x6565AFCA, 0x7A7A8EF4, 0xAEAEE947, 0x08081810, + 0xBABAD56F, 0x787888F0, 0x25256F4A, 0x2E2E725C, 0x1C1C2438, 0xA6A6F157, 0xB4B4C773, 0xC6C65197, + 0xE8E823CB, 0xDDDD7CA1, 0x74749CE8, 0x1F1F213E, 0x4B4BDD96, 0xBDBDDC61, 0x8B8B860D, 0x8A8A850F, + 0x707090E0, 0x3E3E427C, 0xB5B5C471, 0x6666AACC, 0x4848D890, 0x03030506, 0xF6F601F7, 0x0E0E121C, + 0x6161A3C2, 0x35355F6A, 0x5757F9AE, 0xB9B9D069, 0x86869117, 0xC1C15899, 0x1D1D273A, 0x9E9EB927, + 0xE1E138D9, 0xF8F813EB, 0x9898B32B, 0x11113322, 0x6969BBD2, 0xD9D970A9, 0x8E8E8907, 0x9494A733, + 0x9B9BB62D, 0x1E1E223C, 0x87879215, 0xE9E920C9, 0xCECE4987, 0x5555FFAA, 0x28287850, 0xDFDF7AA5, + 0x8C8C8F03, 0xA1A1F859, 0x89898009, 0x0D0D171A, 0xBFBFDA65, 0xE6E631D7, 0x4242C684, 0x6868B8D0, + 0x4141C382, 0x9999B029, 0x2D2D775A, 0x0F0F111E, 0xB0B0CB7B, 0x5454FCA8, 0xBBBBD66D, 0x16163A2C + )); + + foreach ($t3 as $t3i) { + $t0[] = (($t3i << 24) & 0xFF000000) | (($t3i >> 8) & 0x00FFFFFF); + $t1[] = (($t3i << 16) & 0xFFFF0000) | (($t3i >> 16) & 0x0000FFFF); + $t2[] = (($t3i << 8) & 0xFFFFFF00) | (($t3i >> 24) & 0x000000FF); + } + + $tables = array( + // The Precomputed mixColumns tables t0 - t3 + $t0, + $t1, + $t2, + $t3, + // The SubByte S-Box + array( + 0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5, 0x30, 0x01, 0x67, 0x2B, 0xFE, 0xD7, 0xAB, 0x76, + 0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0, 0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0, + 0xB7, 0xFD, 0x93, 0x26, 0x36, 0x3F, 0xF7, 0xCC, 0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15, + 0x04, 0xC7, 0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A, 0x07, 0x12, 0x80, 0xE2, 0xEB, 0x27, 0xB2, 0x75, + 0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0xA0, 0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84, + 0x53, 0xD1, 0x00, 0xED, 0x20, 0xFC, 0xB1, 0x5B, 0x6A, 0xCB, 0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF, + 0xD0, 0xEF, 0xAA, 0xFB, 0x43, 0x4D, 0x33, 0x85, 0x45, 0xF9, 0x02, 0x7F, 0x50, 0x3C, 0x9F, 0xA8, + 0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5, 0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2, + 0xCD, 0x0C, 0x13, 0xEC, 0x5F, 0x97, 0x44, 0x17, 0xC4, 0xA7, 0x7E, 0x3D, 0x64, 0x5D, 0x19, 0x73, + 0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A, 0x90, 0x88, 0x46, 0xEE, 0xB8, 0x14, 0xDE, 0x5E, 0x0B, 0xDB, + 0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C, 0xC2, 0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79, + 0xE7, 0xC8, 0x37, 0x6D, 0x8D, 0xD5, 0x4E, 0xA9, 0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A, 0xAE, 0x08, + 0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6, 0xE8, 0xDD, 0x74, 0x1F, 0x4B, 0xBD, 0x8B, 0x8A, + 0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E, 0x61, 0x35, 0x57, 0xB9, 0x86, 0xC1, 0x1D, 0x9E, + 0xE1, 0xF8, 0x98, 0x11, 0x69, 0xD9, 0x8E, 0x94, 0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF, + 0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68, 0x41, 0x99, 0x2D, 0x0F, 0xB0, 0x54, 0xBB, 0x16 + ) + ); + } + return $tables; + } + + /** + * Provides the inverse mixColumns and inverse sboxes tables + * + * @see Crypt_Rijndael:_decryptBlock() + * @see Crypt_Rijndael:_setupInlineCrypt() + * @see Crypt_Rijndael:_setupKey() + * @access private + * @return Array &$tables + */ + function &_getInvTables() + { + static $tables; + if (empty($tables)) { + $dt3 = array_map('intval', array( + 0xF4A75051, 0x4165537E, 0x17A4C31A, 0x275E963A, 0xAB6BCB3B, 0x9D45F11F, 0xFA58ABAC, 0xE303934B, + 0x30FA5520, 0x766DF6AD, 0xCC769188, 0x024C25F5, 0xE5D7FC4F, 0x2ACBD7C5, 0x35448026, 0x62A38FB5, + 0xB15A49DE, 0xBA1B6725, 0xEA0E9845, 0xFEC0E15D, 0x2F7502C3, 0x4CF01281, 0x4697A38D, 0xD3F9C66B, + 0x8F5FE703, 0x929C9515, 0x6D7AEBBF, 0x5259DA95, 0xBE832DD4, 0x7421D358, 0xE0692949, 0xC9C8448E, + 0xC2896A75, 0x8E7978F4, 0x583E6B99, 0xB971DD27, 0xE14FB6BE, 0x88AD17F0, 0x20AC66C9, 0xCE3AB47D, + 0xDF4A1863, 0x1A3182E5, 0x51336097, 0x537F4562, 0x6477E0B1, 0x6BAE84BB, 0x81A01CFE, 0x082B94F9, + 0x48685870, 0x45FD198F, 0xDE6C8794, 0x7BF8B752, 0x73D323AB, 0x4B02E272, 0x1F8F57E3, 0x55AB2A66, + 0xEB2807B2, 0xB5C2032F, 0xC57B9A86, 0x3708A5D3, 0x2887F230, 0xBFA5B223, 0x036ABA02, 0x16825CED, + 0xCF1C2B8A, 0x79B492A7, 0x07F2F0F3, 0x69E2A14E, 0xDAF4CD65, 0x05BED506, 0x34621FD1, 0xA6FE8AC4, + 0x2E539D34, 0xF355A0A2, 0x8AE13205, 0xF6EB75A4, 0x83EC390B, 0x60EFAA40, 0x719F065E, 0x6E1051BD, + 0x218AF93E, 0xDD063D96, 0x3E05AEDD, 0xE6BD464D, 0x548DB591, 0xC45D0571, 0x06D46F04, 0x5015FF60, + 0x98FB2419, 0xBDE997D6, 0x4043CC89, 0xD99E7767, 0xE842BDB0, 0x898B8807, 0x195B38E7, 0xC8EEDB79, + 0x7C0A47A1, 0x420FE97C, 0x841EC9F8, 0x00000000, 0x80868309, 0x2BED4832, 0x1170AC1E, 0x5A724E6C, + 0x0EFFFBFD, 0x8538560F, 0xAED51E3D, 0x2D392736, 0x0FD9640A, 0x5CA62168, 0x5B54D19B, 0x362E3A24, + 0x0A67B10C, 0x57E70F93, 0xEE96D2B4, 0x9B919E1B, 0xC0C54F80, 0xDC20A261, 0x774B695A, 0x121A161C, + 0x93BA0AE2, 0xA02AE5C0, 0x22E0433C, 0x1B171D12, 0x090D0B0E, 0x8BC7ADF2, 0xB6A8B92D, 0x1EA9C814, + 0xF1198557, 0x75074CAF, 0x99DDBBEE, 0x7F60FDA3, 0x01269FF7, 0x72F5BC5C, 0x663BC544, 0xFB7E345B, + 0x4329768B, 0x23C6DCCB, 0xEDFC68B6, 0xE4F163B8, 0x31DCCAD7, 0x63851042, 0x97224013, 0xC6112084, + 0x4A247D85, 0xBB3DF8D2, 0xF93211AE, 0x29A16DC7, 0x9E2F4B1D, 0xB230F3DC, 0x8652EC0D, 0xC1E3D077, + 0xB3166C2B, 0x70B999A9, 0x9448FA11, 0xE9642247, 0xFC8CC4A8, 0xF03F1AA0, 0x7D2CD856, 0x3390EF22, + 0x494EC787, 0x38D1C1D9, 0xCAA2FE8C, 0xD40B3698, 0xF581CFA6, 0x7ADE28A5, 0xB78E26DA, 0xADBFA43F, + 0x3A9DE42C, 0x78920D50, 0x5FCC9B6A, 0x7E466254, 0x8D13C2F6, 0xD8B8E890, 0x39F75E2E, 0xC3AFF582, + 0x5D80BE9F, 0xD0937C69, 0xD52DA96F, 0x2512B3CF, 0xAC993BC8, 0x187DA710, 0x9C636EE8, 0x3BBB7BDB, + 0x267809CD, 0x5918F46E, 0x9AB701EC, 0x4F9AA883, 0x956E65E6, 0xFFE67EAA, 0xBCCF0821, 0x15E8E6EF, + 0xE79BD9BA, 0x6F36CE4A, 0x9F09D4EA, 0xB07CD629, 0xA4B2AF31, 0x3F23312A, 0xA59430C6, 0xA266C035, + 0x4EBC3774, 0x82CAA6FC, 0x90D0B0E0, 0xA7D81533, 0x04984AF1, 0xECDAF741, 0xCD500E7F, 0x91F62F17, + 0x4DD68D76, 0xEFB04D43, 0xAA4D54CC, 0x9604DFE4, 0xD1B5E39E, 0x6A881B4C, 0x2C1FB8C1, 0x65517F46, + 0x5EEA049D, 0x8C355D01, 0x877473FA, 0x0B412EFB, 0x671D5AB3, 0xDBD25292, 0x105633E9, 0xD647136D, + 0xD7618C9A, 0xA10C7A37, 0xF8148E59, 0x133C89EB, 0xA927EECE, 0x61C935B7, 0x1CE5EDE1, 0x47B13C7A, + 0xD2DF599C, 0xF2733F55, 0x14CE7918, 0xC737BF73, 0xF7CDEA53, 0xFDAA5B5F, 0x3D6F14DF, 0x44DB8678, + 0xAFF381CA, 0x68C43EB9, 0x24342C38, 0xA3405FC2, 0x1DC37216, 0xE2250CBC, 0x3C498B28, 0x0D9541FF, + 0xA8017139, 0x0CB3DE08, 0xB4E49CD8, 0x56C19064, 0xCB84617B, 0x32B670D5, 0x6C5C7448, 0xB85742D0 + )); + + foreach ($dt3 as $dt3i) { + $dt0[] = (($dt3i << 24) & 0xFF000000) | (($dt3i >> 8) & 0x00FFFFFF); + $dt1[] = (($dt3i << 16) & 0xFFFF0000) | (($dt3i >> 16) & 0x0000FFFF); + $dt2[] = (($dt3i << 8) & 0xFFFFFF00) | (($dt3i >> 24) & 0x000000FF); + }; + + $tables = array( + // The Precomputed inverse mixColumns tables dt0 - dt3 + $dt0, + $dt1, + $dt2, + $dt3, + // The inverse SubByte S-Box + array( + 0x52, 0x09, 0x6A, 0xD5, 0x30, 0x36, 0xA5, 0x38, 0xBF, 0x40, 0xA3, 0x9E, 0x81, 0xF3, 0xD7, 0xFB, + 0x7C, 0xE3, 0x39, 0x82, 0x9B, 0x2F, 0xFF, 0x87, 0x34, 0x8E, 0x43, 0x44, 0xC4, 0xDE, 0xE9, 0xCB, + 0x54, 0x7B, 0x94, 0x32, 0xA6, 0xC2, 0x23, 0x3D, 0xEE, 0x4C, 0x95, 0x0B, 0x42, 0xFA, 0xC3, 0x4E, + 0x08, 0x2E, 0xA1, 0x66, 0x28, 0xD9, 0x24, 0xB2, 0x76, 0x5B, 0xA2, 0x49, 0x6D, 0x8B, 0xD1, 0x25, + 0x72, 0xF8, 0xF6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xD4, 0xA4, 0x5C, 0xCC, 0x5D, 0x65, 0xB6, 0x92, + 0x6C, 0x70, 0x48, 0x50, 0xFD, 0xED, 0xB9, 0xDA, 0x5E, 0x15, 0x46, 0x57, 0xA7, 0x8D, 0x9D, 0x84, + 0x90, 0xD8, 0xAB, 0x00, 0x8C, 0xBC, 0xD3, 0x0A, 0xF7, 0xE4, 0x58, 0x05, 0xB8, 0xB3, 0x45, 0x06, + 0xD0, 0x2C, 0x1E, 0x8F, 0xCA, 0x3F, 0x0F, 0x02, 0xC1, 0xAF, 0xBD, 0x03, 0x01, 0x13, 0x8A, 0x6B, + 0x3A, 0x91, 0x11, 0x41, 0x4F, 0x67, 0xDC, 0xEA, 0x97, 0xF2, 0xCF, 0xCE, 0xF0, 0xB4, 0xE6, 0x73, + 0x96, 0xAC, 0x74, 0x22, 0xE7, 0xAD, 0x35, 0x85, 0xE2, 0xF9, 0x37, 0xE8, 0x1C, 0x75, 0xDF, 0x6E, + 0x47, 0xF1, 0x1A, 0x71, 0x1D, 0x29, 0xC5, 0x89, 0x6F, 0xB7, 0x62, 0x0E, 0xAA, 0x18, 0xBE, 0x1B, + 0xFC, 0x56, 0x3E, 0x4B, 0xC6, 0xD2, 0x79, 0x20, 0x9A, 0xDB, 0xC0, 0xFE, 0x78, 0xCD, 0x5A, 0xF4, + 0x1F, 0xDD, 0xA8, 0x33, 0x88, 0x07, 0xC7, 0x31, 0xB1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xEC, 0x5F, + 0x60, 0x51, 0x7F, 0xA9, 0x19, 0xB5, 0x4A, 0x0D, 0x2D, 0xE5, 0x7A, 0x9F, 0x93, 0xC9, 0x9C, 0xEF, + 0xA0, 0xE0, 0x3B, 0x4D, 0xAE, 0x2A, 0xF5, 0xB0, 0xC8, 0xEB, 0xBB, 0x3C, 0x83, 0x53, 0x99, 0x61, + 0x17, 0x2B, 0x04, 0x7E, 0xBA, 0x77, 0xD6, 0x26, 0xE1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0C, 0x7D + ) + ); + } + return $tables; + } + /** * Setup the performance-optimized function for de/encrypt() * @@ -1216,42 +963,50 @@ class Crypt_Rijndael extends Crypt_Base $lambda_functions =& Crypt_Rijndael::_getLambdaFunctions(); - // The first 10 generated $lambda_functions will use the key-words hardcoded for better performance. - // For memory reason we limit those ultra-optimized functions. - // After that, we use pure (extracted) integer vars for the key-words which is faster than accessing them via array. - if (count($lambda_functions) < 10) { - $w = $this->w; - $dw = $this->dw; - $init_encrypt = ''; - $init_decrypt = ''; - } else { - for ($i = 0, $cw = count($this->w); $i < $cw; ++$i) { - $w[] = '$w[' . $i . ']'; - $dw[] = '$dw[' . $i . ']'; - } - $init_encrypt = '$w = $self->w;'; - $init_decrypt = '$dw = $self->dw;'; + // We create max. 10 hi-optimized code for memory reason. Means: For each $key one ultra fast inline-crypt function. + // (Currently, for Crypt_Rijndael/AES, one generated $lambda_function cost on php5.5@32bit ~80kb unfreeable mem and ~130kb on php5.5@64bit) + // After that, we'll still create very fast optimized code but not the hi-ultimative code, for each $mode one. + $gen_hi_opt_code = (bool)( count($lambda_functions) < 10 ); + + // Generation of a uniqe hash for our generated code + $code_hash = "Crypt_Rijndael, {$this->mode}, {$this->Nr}, {$this->Nb}"; + if ($gen_hi_opt_code) { + $code_hash = str_pad($code_hash, 32) . $this->_trapdoor($this->key); } - $code_hash = md5(str_pad("Crypt_Rijndael, {$this->mode}, {$this->block_size}, ", 32, "\0") . implode(',', $w)); - if (!isset($lambda_functions[$code_hash])) { + switch (true) { + case $gen_hi_opt_code: + // The hi-optimized $lambda_functions will use the key-words hardcoded for better performance. + $w = $this->w; + $dw = $this->dw; + $init_encrypt = ''; + $init_decrypt = ''; + break; + default: + for ($i = 0, $cw = count($this->w); $i < $cw; ++$i) { + $w[] = '$w[' . $i . ']'; + $dw[] = '$dw[' . $i . ']'; + } + $init_encrypt = '$w = $self->w;'; + $init_decrypt = '$dw = $self->dw;'; + } + $Nr = $this->Nr; $Nb = $this->Nb; $c = $this->c; // Generating encrypt code: $init_encrypt.= ' - static $t0, $t1, $t2, $t3, $sbox; - if (!$t0) { - for ($i = 0; $i < 256; ++$i) { - $t0[$i] = (int)$self->t0[$i]; - $t1[$i] = (int)$self->t1[$i]; - $t2[$i] = (int)$self->t2[$i]; - $t3[$i] = (int)$self->t3[$i]; - $sbox[$i] = (int)$self->sbox[$i]; - } + static $tables; + if (empty($tables)) { + $tables = &$self->_getTables(); } + $t0 = $tables[0]; + $t1 = $tables[1]; + $t2 = $tables[2]; + $t3 = $tables[3]; + $sbox = $tables[4]; '; $s = 'e'; @@ -1290,26 +1045,25 @@ class Crypt_Rijndael extends Crypt_Base $encrypt_block .= '$in = pack("N*"'."\n"; for ($i = 0; $i < $Nb; ++$i) { $encrypt_block.= ', - ($'.$e.$i .' & 0xFF000000) ^ - ($'.$e.(($i + $c[1]) % $Nb).' & 0x00FF0000) ^ - ($'.$e.(($i + $c[2]) % $Nb).' & 0x0000FF00) ^ - ($'.$e.(($i + $c[3]) % $Nb).' & 0x000000FF) ^ + ($'.$e.$i .' & '.((int)0xFF000000).') ^ + ($'.$e.(($i + $c[1]) % $Nb).' & 0x00FF0000 ) ^ + ($'.$e.(($i + $c[2]) % $Nb).' & 0x0000FF00 ) ^ + ($'.$e.(($i + $c[3]) % $Nb).' & 0x000000FF ) ^ '.$w[$i]."\n"; } $encrypt_block .= ');'; // Generating decrypt code: $init_decrypt.= ' - static $dt0, $dt1, $dt2, $dt3, $isbox; - if (!$dt0) { - for ($i = 0; $i < 256; ++$i) { - $dt0[$i] = (int)$self->dt0[$i]; - $dt1[$i] = (int)$self->dt1[$i]; - $dt2[$i] = (int)$self->dt2[$i]; - $dt3[$i] = (int)$self->dt3[$i]; - $isbox[$i] = (int)$self->isbox[$i]; - } + static $invtables; + if (empty($invtables)) { + $invtables = &$self->_getInvTables(); } + $dt0 = $invtables[0]; + $dt1 = $invtables[1]; + $dt2 = $invtables[2]; + $dt3 = $invtables[3]; + $isbox = $invtables[4]; '; $s = 'e'; @@ -1348,10 +1102,10 @@ class Crypt_Rijndael extends Crypt_Base $decrypt_block .= '$in = pack("N*"'."\n"; for ($i = 0; $i < $Nb; ++$i) { $decrypt_block.= ', - ($'.$e.$i. ' & 0xFF000000) ^ - ($'.$e.(($Nb + $i - $c[1]) % $Nb).' & 0x00FF0000) ^ - ($'.$e.(($Nb + $i - $c[2]) % $Nb).' & 0x0000FF00) ^ - ($'.$e.(($Nb + $i - $c[3]) % $Nb).' & 0x000000FF) ^ + ($'.$e.$i. ' & '.((int)0xFF000000).') ^ + ($'.$e.(($Nb + $i - $c[1]) % $Nb).' & 0x00FF0000 ) ^ + ($'.$e.(($Nb + $i - $c[2]) % $Nb).' & 0x0000FF00 ) ^ + ($'.$e.(($Nb + $i - $c[3]) % $Nb).' & 0x000000FF ) ^ '.$dw[$i]."\n"; } $decrypt_block .= ');'; diff --git a/phpseclib/Crypt/TripleDES.php b/phpseclib/Crypt/TripleDES.php index ba2908fb..a57cbb0c 100644 --- a/phpseclib/Crypt/TripleDES.php +++ b/phpseclib/Crypt/TripleDES.php @@ -10,7 +10,7 @@ * Here's a short example of how to use this library: * * - * @version 0.1.0 + * @version 0.1.1 * @access public */ class Crypt_TripleDES extends Crypt_DES @@ -416,5 +420,25 @@ class Crypt_TripleDES extends Crypt_DES // setup our key parent::_setupKey(); } + + /** + * Sets the internal crypt engine + * + * @see Crypt_Base::Crypt_Base() + * @see Crypt_Base::setEngine() + * @param optional Integer $engine + * @access public + * @return Integer + */ + function setEngine($engine = CRYPT_DES_MODE_MCRYPT) + { + if ($this->mode_3cbc) { + $this->des[0]->setEngine($engine); + $this->des[1]->setEngine($engine); + $this->des[2]->setEngine($engine); + } + + return parent::setEngine($engine); + } } diff --git a/phpseclib/Crypt/Twofish.php b/phpseclib/Crypt/Twofish.php index 7dec037b..825ca9be 100644 --- a/phpseclib/Crypt/Twofish.php +++ b/phpseclib/Crypt/Twofish.php @@ -14,7 +14,7 @@ * Here's a short example of how to use this library: * * * @copyright MMVII Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @version 1.0 * @link http://phpseclib.sourceforge.net */ @@ -103,7 +102,7 @@ define('CRYPT_TWOFISH_MODE_OFB', CRYPT_MODE_OFB); /**#@-*/ /**#@+ - * @access private + * @access public * @see Crypt_Twofish::Crypt_Twofish() */ /** @@ -122,7 +121,7 @@ define('CRYPT_TWOFISH_MODE_MCRYPT', CRYPT_MODE_MCRYPT); * @package Crypt_Twofish * @author Jim Wigginton * @author Hans-Juergen Petrich - * @version 1.0 + * @version 1.0.1 * @access public */ class Crypt_Twofish extends Crypt_Base @@ -780,21 +779,19 @@ class Crypt_Twofish extends Crypt_Base $lambda_functions =& Crypt_Twofish::_getLambdaFunctions(); // Max. 10 Ultra-Hi-optimized inline-crypt functions. After that, we'll (still) create very fast code, but not the ultimate fast one. + // (Currently, for Crypt_Twofish, one generated $lambda_function cost on php5.5@32bit ~140kb unfreeable mem and ~240kb on php5.5@64bit) $gen_hi_opt_code = (bool)( count($lambda_functions) < 10 ); - switch (true) { - case $gen_hi_opt_code: - $code_hash = md5(str_pad("Crypt_Twofish, {$this->mode}, ", 32, "\0") . $this->key); - break; - default: - $code_hash = "Crypt_Twofish, {$this->mode}"; + // Generation of a uniqe hash for our generated code + $code_hash = "Crypt_Twofish, {$this->mode}"; + if ($gen_hi_opt_code) { + $code_hash = str_pad($code_hash, 32) . $this->_trapdoor($this->key); } if (!isset($lambda_functions[$code_hash])) { switch (true) { case $gen_hi_opt_code: $K = $this->K; - $init_crypt = ' static $S0, $S1, $S2, $S3; if (!$S0) { @@ -812,7 +809,6 @@ class Crypt_Twofish extends Crypt_Base for ($i = 0; $i < 40; ++$i) { $K[] = '$K_' . $i; } - $init_crypt = ' $S0 = $self->S0; $S1 = $self->S1; From ff4d563f4fb2adbaa61552bf5c7a541486988aaa Mon Sep 17 00:00:00 2001 From: terrafrost Date: Sat, 11 Oct 2014 23:20:44 -0500 Subject: [PATCH 02/79] SSH2: CS adjustments --- phpseclib/Net/SSH2.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/phpseclib/Net/SSH2.php b/phpseclib/Net/SSH2.php index ad996d7b..35127d7d 100644 --- a/phpseclib/Net/SSH2.php +++ b/phpseclib/Net/SSH2.php @@ -1104,7 +1104,7 @@ class Net_SSH2 'arcfour256', 'arcfour128', - //'arcfour', // OPTIONAL the ARCFOUR stream cipher with a 128-bit key + //'arcfour', // OPTIONAL the ARCFOUR stream cipher with a 128-bit key // CTR modes from : 'aes128-ctr', // RECOMMENDED AES (Rijndael) in SDCTR mode, with 128-bit key @@ -1132,7 +1132,7 @@ class Net_SSH2 '3des-ctr', // RECOMMENDED Three-key 3DES in SDCTR mode '3des-cbc', // REQUIRED three-key 3DES in CBC mode - //'none' // OPTIONAL no encryption; NOT RECOMMENDED + //'none' // OPTIONAL no encryption; NOT RECOMMENDED ); if (phpseclib_resolve_include_path('Crypt/RC4.php') === false) { From 959c0cefae8c94058620d45de2acd7debc39f5f6 Mon Sep 17 00:00:00 2001 From: terrafrost Date: Sat, 11 Oct 2014 23:26:46 -0500 Subject: [PATCH 03/79] SSH2: add setCryptoEngine() function --- phpseclib/Net/SSH2.php | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/phpseclib/Net/SSH2.php b/phpseclib/Net/SSH2.php index 35127d7d..c7760096 100644 --- a/phpseclib/Net/SSH2.php +++ b/phpseclib/Net/SSH2.php @@ -840,6 +840,16 @@ class Net_SSH2 */ var $windowRows = 24; + /** + * Crypto Engine + * + * @see Net_SSH2::setCryptoEngine() + * @see Net_SSH2::_key_exchange() + * @var Integer + * @access private + */ + var $crypto_engine = false; + /** * Default Constructor. * @@ -941,6 +951,20 @@ class Net_SSH2 $this->connectionTimeout = $timeout; } + /** + * Set Crypto Engine Mode + * + * Possible $engine values: + * CRYPT_MODE_INTERNAL, CRYPT_MODE_MCRYPT + * + * @param Integer $engine + * @access private + */ + function setCryptoEngine($engine) + { + $this->crypto_engine = $engine; + } + /** * Connect to an SSHv2 server * @@ -1646,6 +1670,9 @@ class Net_SSH2 $keyBytes = pack('Na*', strlen($keyBytes), $keyBytes); if ($this->encrypt) { + if ($this->crypto_engine) { + $this->encrypt->setEngine($this->crypto_engine); + } $this->encrypt->enableContinuousBuffer(); $this->encrypt->disablePadding(); @@ -1663,6 +1690,9 @@ class Net_SSH2 } if ($this->decrypt) { + if ($this->crypto_engine) { + $this->decrypt->setEngine($this->crypto_engine); + } $this->decrypt->enableContinuousBuffer(); $this->decrypt->disablePadding(); From 361b59fff9cad5c42533f5481b3cfad68132d257 Mon Sep 17 00:00:00 2001 From: terrafrost Date: Sat, 11 Oct 2014 23:40:56 -0500 Subject: [PATCH 04/79] SSH2: make setCryptoEngine() less cumbersome --- phpseclib/Net/SSH2.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/phpseclib/Net/SSH2.php b/phpseclib/Net/SSH2.php index c7760096..4c3c4c84 100644 --- a/phpseclib/Net/SSH2.php +++ b/phpseclib/Net/SSH2.php @@ -876,6 +876,11 @@ class Net_SSH2 include_once 'Crypt/Hash.php'; } + // include Crypt_Base so constants can be defined for setCryptoEngine() + if (!class_exists('Crypt_Base')) { + include_once 'Crypt/Base.php'; + } + $this->message_numbers = array( 1 => 'NET_SSH2_MSG_DISCONNECT', 2 => 'NET_SSH2_MSG_IGNORE', From c8b55b8929745e37bf3b7afb059c7ad3b856fb68 Mon Sep 17 00:00:00 2001 From: terrafrost Date: Sun, 12 Oct 2014 00:52:52 -0500 Subject: [PATCH 05/79] Rijndael: calling $rijndael->setEngine() didn't have any effect (CRYPT_RIJNDAEL_MODE constant was always over-riding it) --- phpseclib/Crypt/Rijndael.php | 5 ----- 1 file changed, 5 deletions(-) diff --git a/phpseclib/Crypt/Rijndael.php b/phpseclib/Crypt/Rijndael.php index 5fa05200..5f2b7519 100644 --- a/phpseclib/Crypt/Rijndael.php +++ b/phpseclib/Crypt/Rijndael.php @@ -437,11 +437,6 @@ class Crypt_Rijndael extends Crypt_Base // mcrypt is not usable for them, only for 128/192/256-bit keys // so we are forced to set the slower MODE_INTERNAL $engine $this->setEngine(CRYPT_MODE_INTERNAL); - } else { - // Set what is set/preferred in CRYPT_RIJNDAEL_MODE - // If its CRYPT_RIJNDAEL_MODE_MCRYPT and $this->cipher_name_mcrypt not available - // setEngine() will set to CRYPT_RIJNDAEL_MODE_INTERNAL automatically - $this->setEngine(constant('CRYPT_' . $this->const_namespace . '_MODE')); } } From e7708b0d20f1649382b435bc82071f8b35117d10 Mon Sep 17 00:00:00 2001 From: terrafrost Date: Wed, 15 Oct 2014 17:59:48 -0500 Subject: [PATCH 06/79] AES: update unit tests --- tests/Unit/Crypt/AES/InternalTest.php | 5 ++--- tests/Unit/Crypt/AES/McryptTest.php | 5 ++--- tests/Unit/Crypt/AES/TestCase.php | 8 +++++--- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/tests/Unit/Crypt/AES/InternalTest.php b/tests/Unit/Crypt/AES/InternalTest.php index 2a9652ca..41801c85 100644 --- a/tests/Unit/Crypt/AES/InternalTest.php +++ b/tests/Unit/Crypt/AES/InternalTest.php @@ -9,9 +9,8 @@ class Unit_Crypt_AES_InternalTest extends Unit_Crypt_AES_TestCase { static public function setUpBeforeClass() { - parent::setUpBeforeClass(); + self::$engine = CRYPT_MODE_INTERNAL; - self::ensureConstant('CRYPT_AES_MODE', CRYPT_AES_MODE_INTERNAL); - self::ensureConstant('CRYPT_RIJNDAEL_MODE', CRYPT_RIJNDAEL_MODE_INTERNAL); + parent::setUpBeforeClass(); } } diff --git a/tests/Unit/Crypt/AES/McryptTest.php b/tests/Unit/Crypt/AES/McryptTest.php index 4327c7ea..78902fc0 100644 --- a/tests/Unit/Crypt/AES/McryptTest.php +++ b/tests/Unit/Crypt/AES/McryptTest.php @@ -13,9 +13,8 @@ class Unit_Crypt_AES_McryptTest extends Unit_Crypt_AES_TestCase self::markTestSkipped('mcrypt extension is not available.'); } - parent::setUpBeforeClass(); + self::$engine = CRYPT_MODE_MCRYPT; - self::ensureConstant('CRYPT_AES_MODE', CRYPT_AES_MODE_MCRYPT); - self::ensureConstant('CRYPT_RIJNDAEL_MODE', CRYPT_RIJNDAEL_MODE_MCRYPT); + parent::setUpBeforeClass(); } } diff --git a/tests/Unit/Crypt/AES/TestCase.php b/tests/Unit/Crypt/AES/TestCase.php index 91cb9792..2a40450c 100644 --- a/tests/Unit/Crypt/AES/TestCase.php +++ b/tests/Unit/Crypt/AES/TestCase.php @@ -9,12 +9,11 @@ require_once 'Crypt/AES.php'; abstract class Unit_Crypt_AES_TestCase extends PhpseclibTestCase { + protected static $engine; + static public function setUpBeforeClass() { parent::setUpBeforeClass(); - - self::reRequireFile('Crypt/Rijndael.php'); - self::reRequireFile('Crypt/AES.php'); } /** @@ -64,6 +63,7 @@ abstract class Unit_Crypt_AES_TestCase extends PhpseclibTestCase public function testEncryptDecryptWithContinuousBuffer($mode, $plaintext, $iv, $key) { $aes = new Crypt_AES(constant($mode)); + $aes->setEngine(self::$engine); $aes->enableContinuousBuffer(); $aes->setIV($iv); $aes->setKey($key); @@ -85,6 +85,7 @@ abstract class Unit_Crypt_AES_TestCase extends PhpseclibTestCase // https://web.archive.org/web/20070209120224/http://fp.gladman.plus.com/cryptography_technology/rijndael/aesdvec.zip $aes = new Crypt_Rijndael(); + $aes->setEngine(self::$engine); $aes->disablePadding(); $aes->setKey(pack('H*', '2b7e151628aed2a6abf7158809cf4f3c762e7160')); // 160-bit key. Valid in Rijndael. $ciphertext = $aes->encrypt(pack('H*', '3243f6a8885a308d313198a2e0370734')); @@ -99,6 +100,7 @@ abstract class Unit_Crypt_AES_TestCase extends PhpseclibTestCase // same as the above - just with a different ciphertext $aes = new Crypt_AES(); + $aes->setEngine(self::$engine); $aes->disablePadding(); $aes->setKey(pack('H*', '2b7e151628aed2a6abf7158809cf4f3c762e7160')); // 160-bit key. AES should null pad to 192-bits $ciphertext = $aes->encrypt(pack('H*', '3243f6a8885a308d313198a2e0370734')); From f6e0c4b506b0bdb310314aabfca8d0b7244fe8ba Mon Sep 17 00:00:00 2001 From: terrafrost Date: Sat, 29 Nov 2014 07:39:21 -0600 Subject: [PATCH 07/79] Crypt: add OpenSSL support aside from the addition of OpenSSL support a few other changes have been included: - setEngine(), as added by petrich, is depricated (not that it was ever in trunk to begin with) it has been replaced with isValidEngine() and setPreferredEngine(). - replace _generate_xor() with increment_str() _increment_str() had extra functionality that wasn't being used. ie. it could concatenate multiple successive string increments to one another automatically. but not only was that functionality not used - it also made the function less versatile. _increment_str() can be used more easily for iterative brute forcing (for example) - rename Crypt_Base::_stringShift to Crypt_Base::_string_shift (for consistency) - more expansive unit test coverage --- phpseclib/Crypt/AES.php | 2 +- phpseclib/Crypt/Base.php | 625 +++++++++++++++++++++----- phpseclib/Crypt/Blowfish.php | 38 +- phpseclib/Crypt/DES.php | 49 +- phpseclib/Crypt/RC2.php | 112 ++++- phpseclib/Crypt/RC4.php | 46 +- phpseclib/Crypt/Rijndael.php | 65 ++- phpseclib/Crypt/TripleDES.php | 23 +- phpseclib/Crypt/Twofish.php | 14 - tests/Unit/Crypt/AES/InternalTest.php | 6 +- tests/Unit/Crypt/AES/McryptTest.php | 10 +- tests/Unit/Crypt/AES/OpenSSLTest.php | 14 + tests/Unit/Crypt/AES/TestCase.php | 113 ++++- tests/Unit/Crypt/DES.php | 69 +++ tests/Unit/Crypt/RC2.php | 71 +++ 15 files changed, 1018 insertions(+), 239 deletions(-) create mode 100644 tests/Unit/Crypt/AES/OpenSSLTest.php create mode 100644 tests/Unit/Crypt/DES.php create mode 100644 tests/Unit/Crypt/RC2.php diff --git a/phpseclib/Crypt/AES.php b/phpseclib/Crypt/AES.php index de006e1e..36364398 100644 --- a/phpseclib/Crypt/AES.php +++ b/phpseclib/Crypt/AES.php @@ -206,7 +206,7 @@ class Crypt_AES extends Crypt_Rijndael default: $this->key_size = 32; } - $this->_setupEngine(); + $this->_setEngine(); } } } diff --git a/phpseclib/Crypt/Base.php b/phpseclib/Crypt/Base.php index bf4b4585..d8be982b 100644 --- a/phpseclib/Crypt/Base.php +++ b/phpseclib/Crypt/Base.php @@ -110,6 +110,10 @@ define('CRYPT_MODE_INTERNAL', 1); * Base value for the mcrypt implementation $engine switch */ define('CRYPT_MODE_MCRYPT', 2); +/** + * Base value for the OpenSSL implementation $engine switch + */ +define('CRYPT_MODE_OPENSSL', 3); /**#@-*/ /** @@ -118,7 +122,7 @@ define('CRYPT_MODE_MCRYPT', 2); * @package Crypt_Base * @author Jim Wigginton * @author Hans-Juergen Petrich - * @version 1.0.1 + * @version 1.0.2 * @access public */ class Crypt_Base @@ -326,15 +330,11 @@ class Crypt_Base * which will be determined automatically on __construct() * * Currently available $engines are: + * - CRYPT_MODE_OPENSSL (very fast, php-extension: openssl, extension_loaded('openssl') required) * - CRYPT_MODE_MCRYPT (fast, php-extension: mcrypt, extension_loaded('mcrypt') required) * - CRYPT_MODE_INTERNAL (slower, pure php-engine, no php-extension required) * - * In the pipeline... maybe. But currently not available: - * - CRYPT_MODE_OPENSSL (very fast, php-extension: openssl, extension_loaded('openssl') required) - * - * If possible, CRYPT_MODE_MCRYPT will be used for each cipher. - * Otherwise CRYPT_MODE_INTERNAL - * + * @see Crypt_Base::_setEngine() * @see Crypt_Base::encrypt() * @see Crypt_Base::decrypt() * @var Integer @@ -342,6 +342,16 @@ class Crypt_Base */ var $engine; + /** + * Holds the preferred crypt engine + * + * @see Crypt_Base::_setEngine() + * @see Crypt_Base::setPreferredEngine() + * @var Integer + * @access private + */ + var $preferredEngine; + /** * The mcrypt specific name of the cipher * @@ -355,6 +365,29 @@ class Crypt_Base */ var $cipher_name_mcrypt; + /** + * The openssl specific name of the cipher + * + * Only used if $engine == CRYPT_MODE_OPENSSL + * + * @link http://www.php.net/openssl-get-cipher-methods + * @var String + * @access private + */ + var $cipher_name_openssl; + + /** + * The openssl specific name of the cipher in ECB mode + * + * If OpenSSL does not support the mode we're trying to use (CTR) + * it can still be emulated with ECB mode. + * + * @link http://www.php.net/openssl-get-cipher-methods + * @var String + * @access private + */ + var $cipher_name_openssl_ecb; + /** * The default password key_size used by setPassword() * @@ -422,6 +455,15 @@ class Crypt_Base */ var $use_inline_crypt; + /** + * If OpenSSL can be used in ECB but not in CTR we can emulate CTR + * + * @see Crypt_Base::_openssl_ctr_process() + * @var Boolean + * @access private + */ + var $openssl_emulate_ctr = false; + /** * Default Constructor. * @@ -448,20 +490,11 @@ class Crypt_Base */ function Crypt_Base($mode = CRYPT_MODE_CBC) { - $const_crypt_mode = 'CRYPT_' . $this->const_namespace . '_MODE'; - - // Setup the internal crypt engine - if (defined($const_crypt_mode)) { - $this->engine = constant($const_crypt_mode); - } else { - define($const_crypt_mode, $this->setEngine()); - } - // $mode dependent settings switch ($mode) { case CRYPT_MODE_ECB: $this->paddable = true; - $this->mode = $mode; + $this->mode = CRYPT_MODE_ECB; break; case CRYPT_MODE_CTR: case CRYPT_MODE_CFB: @@ -475,6 +508,8 @@ class Crypt_Base $this->mode = CRYPT_MODE_CBC; } + $this->_setEngine(); + // Determining whether inline crypting can be used by the cipher if ($this->use_inline_crypt !== false && function_exists('create_function')) { $this->use_inline_crypt = true; @@ -519,6 +554,7 @@ class Crypt_Base { $this->key = $key; $this->changed = true; + $this->_setEngine(); } /** @@ -631,12 +667,85 @@ class Crypt_Base * @see Crypt_Base::decrypt() * @access public * @param String $plaintext - * @return String $cipertext + * @return String $ciphertext * @internal Could, but not must, extend by the child Crypt_* class */ function encrypt($plaintext) { - if ($this->engine == CRYPT_MODE_MCRYPT) { + if ($this->paddable) { + $plaintext = $this->_pad($plaintext); + } + + if ($this->engine === CRYPT_MODE_OPENSSL) { + if ($this->changed) { + $this->_clearBuffers(); + $this->changed = false; + } + switch ($this->mode) { + case CRYPT_MODE_STREAM: + case CRYPT_MODE_ECB: + return openssl_encrypt($plaintext, $this->cipher_name_openssl, $this->key, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING); + case CRYPT_MODE_CBC: + $ciphertext = openssl_encrypt($plaintext, $this->cipher_name_openssl, $this->key, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING, $this->encryptIV); + if ($this->continuousBuffer) { + $this->encryptIV = substr($ciphertext, -$this->block_size); + } + return $ciphertext; + case CRYPT_MODE_CTR: + return $this->_openssl_ctr_process($plaintext, $this->encryptIV, $this->enbuffer); + case CRYPT_MODE_CFB: + // cfb loosely routines inspired by openssl's: + // {@link http://cvs.openssl.org/fileview?f=openssl/crypto/modes/cfb128.c&v=1.3.2.2.2.1} + if ($this->continuousBuffer) { + $iv = &$this->encryptIV; + $pos = &$this->enbuffer['pos']; + } else { + $iv = &$this->encryptIV; + $pos = 0; + } + $len = strlen($plaintext); + $i = 0; + if ($pos) { + $orig_pos = $pos; + $max = $this->block_size - $pos; + if ($len >= $max) { + $i = $max; + $len-= $max; + $pos = 0; + } else { + $i = $len; + $pos+= $len; + $len = 0; + } + // ie. $i = min($max, $len), $len-= $i, $pos+= $i, $pos%= $blocksize + $ciphertext = substr($iv, $orig_pos) ^ $plaintext; + $iv = substr_replace($iv, $ciphertext, $orig_pos, $i); + $plaintext = substr($plaintext, $i); + } + + $overflow = $len % $this->block_size; + + if ($overflow) { + $ciphertext.= openssl_encrypt(substr($plaintext, 0, -$overflow) . str_repeat("\0", $this->block_size), $this->cipher_name_openssl, $this->key, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING, $iv); + $iv = $this->_string_pop($ciphertext, $this->block_size); + + $size = $len - $overflow; + $block = $iv ^ substr($plaintext, -$overflow); + $iv = substr_replace($iv, $block, 0, $overflow); + $ciphertext.= $block; + $pos = $overflow; + } else if ($len) { + $ciphertext = openssl_encrypt($plaintext, $this->cipher_name_openssl, $this->key, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING, $iv); + $iv = substr($ciphertext, -$this->block_size); + } + + return $ciphertext; + case CRYPT_MODE_OFB: + return $this->_openssl_ofb_process($plaintext, $this->encryptIV, $this->enbuffer); + } + } + + if ($this->engine === CRYPT_MODE_MCRYPT) { if ($this->changed) { $this->_setupMcrypt(); $this->changed = false; @@ -702,10 +811,6 @@ class Crypt_Base return $ciphertext; } - if ($this->paddable) { - $plaintext = $this->_pad($plaintext); - } - $ciphertext = mcrypt_generic($this->enmcrypt, $plaintext); if (!$this->continuousBuffer) { @@ -723,9 +828,6 @@ class Crypt_Base $inline = $this->inline_crypt; return $inline('encrypt', $this, $plaintext); } - if ($this->paddable) { - $plaintext = $this->_pad($plaintext); - } $buffer = &$this->enbuffer; $block_size = $this->block_size; @@ -754,15 +856,17 @@ class Crypt_Base for ($i = 0; $i < strlen($plaintext); $i+=$block_size) { $block = substr($plaintext, $i, $block_size); if (strlen($block) > strlen($buffer['encrypted'])) { - $buffer['encrypted'].= $this->_encryptBlock($this->_generateXor($xor, $block_size)); + $buffer['encrypted'].= $this->_encryptBlock($xor); } - $key = $this->_stringShift($buffer['encrypted'], $block_size); + $this->_increment_str($xor); + $key = $this->_string_shift($buffer['encrypted'], $block_size); $ciphertext.= $block ^ $key; } } else { for ($i = 0; $i < strlen($plaintext); $i+=$block_size) { $block = substr($plaintext, $i, $block_size); - $key = $this->_encryptBlock($this->_generateXor($xor, $block_size)); + $key = $this->_encryptBlock($xor); + $this->_increment_str($xor); $ciphertext.= $block ^ $key; } } @@ -824,7 +928,7 @@ class Crypt_Base $xor = $this->_encryptBlock($xor); $buffer['xor'].= $xor; } - $key = $this->_stringShift($buffer['xor'], $block_size); + $key = $this->_string_shift($buffer['xor'], $block_size); $ciphertext.= $block ^ $key; } } else { @@ -863,7 +967,82 @@ class Crypt_Base */ function decrypt($ciphertext) { - if ($this->engine == CRYPT_MODE_MCRYPT) { + if ($this->paddable) { + // we pad with chr(0) since that's what mcrypt_generic does [...] + $ciphertext = str_pad($ciphertext, strlen($ciphertext) + ($this->block_size - strlen($ciphertext) % $this->block_size) % $this->block_size, chr(0)); + } + + if ($this->engine === CRYPT_MODE_OPENSSL) { + if ($this->changed) { + $this->_clearBuffers(); + $this->changed = false; + } + switch ($this->mode) { + case CRYPT_MODE_STREAM: + case CRYPT_MODE_ECB: + $plaintext = openssl_decrypt($ciphertext, $this->cipher_name_openssl, $this->key, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING); + break; + case CRYPT_MODE_CBC: + $plaintext = openssl_decrypt($ciphertext, $this->cipher_name_openssl, $this->key, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING, $this->decryptIV); + if ($this->continuousBuffer) { + $this->decryptIV = substr($ciphertext, -$this->block_size); + } + break; + case CRYPT_MODE_CTR: + $plaintext = $this->_openssl_ctr_process($ciphertext, $this->decryptIV, $this->debuffer); + break; + case CRYPT_MODE_CFB: + // cfb loosely routines inspired by openssl's: + // {@link http://cvs.openssl.org/fileview?f=openssl/crypto/modes/cfb128.c&v=1.3.2.2.2.1} + if ($this->continuousBuffer) { + $iv = &$this->decryptIV; + $pos = &$this->buffer['pos']; + } else { + $iv = $this->decryptIV; + $pos = 0; + } + $len = strlen($ciphertext); + $i = 0; + if ($pos) { + $orig_pos = $pos; + $max = $this->block_size - $pos; + if ($len >= $max) { + $i = $max; + $len-= $max; + $pos = 0; + } else { + $i = $len; + $pos+= $len; + $len = 0; + } + // ie. $i = min($max, $len), $len-= $i, $pos+= $i, $pos%= $this->blocksize + $plaintext = substr($iv, $orig_pos) ^ $ciphertext; + $iv = substr_replace($iv, substr($ciphertext, 0, $i), $orig_pos, $i); + $ciphertext = substr($ciphertext, $i); + } + $overflow = $len % $this->block_size; + if ($overflow) { + $plaintext.= openssl_decrypt(substr($ciphertext, 0, -$overflow), $this->cipher_name_openssl, $this->key, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING, $iv); + if ($len - $overflow) { + $iv = substr($ciphertext, -$overflow - $this->block_size, -$overflow); + } + $iv = openssl_encrypt(str_repeat("\0", $this->block_size), $this->cipher_name_openssl, $this->key, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING, $iv); + $plaintext.= $iv ^ substr($ciphertext, -$overflow); + $iv = substr_replace($iv, substr($ciphertext, -$overflow), 0, $overflow); + $pos = $overflow; + } else if ($len) { + $plaintext.= openssl_decrypt($ciphertext, $this->cipher_name_openssl, $this->key, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING, $iv); + $iv = substr($ciphertext, -$this->block_size); + } + break; + case CRYPT_MODE_OFB: + $plaintext = $this->_openssl_ofb_process($ciphertext, $this->decryptIV, $this->debuffer); + } + + return $this->paddable ? $this->_unpad($plaintext) : $plaintext; + } + + if ($this->engine === CRYPT_MODE_MCRYPT) { $block_size = $this->block_size; if ($this->changed) { $this->_setupMcrypt(); @@ -937,10 +1116,6 @@ class Crypt_Base } $block_size = $this->block_size; - if ($this->paddable) { - // we pad with chr(0) since that's what mcrypt_generic does [...] - $ciphertext = str_pad($ciphertext, strlen($ciphertext) + ($block_size - strlen($ciphertext) % $block_size) % $block_size, chr(0)); - } $buffer = &$this->debuffer; $plaintext = ''; @@ -967,15 +1142,17 @@ class Crypt_Base for ($i = 0; $i < strlen($ciphertext); $i+=$block_size) { $block = substr($ciphertext, $i, $block_size); if (strlen($block) > strlen($buffer['ciphertext'])) { - $buffer['ciphertext'].= $this->_encryptBlock($this->_generateXor($xor, $block_size)); + $buffer['ciphertext'].= $this->_encryptBlock($xor); + $this->_increment_str($xor); } - $key = $this->_stringShift($buffer['ciphertext'], $block_size); + $key = $this->_string_shift($buffer['ciphertext'], $block_size); $plaintext.= $block ^ $key; } } else { for ($i = 0; $i < strlen($ciphertext); $i+=$block_size) { $block = substr($ciphertext, $i, $block_size); - $key = $this->_encryptBlock($this->_generateXor($xor, $block_size)); + $key = $this->_encryptBlock($xor); + $this->_increment_str($xor); $plaintext.= $block ^ $key; } } @@ -1036,7 +1213,7 @@ class Crypt_Base $xor = $this->_encryptBlock($xor); $buffer['xor'].= $xor; } - $key = $this->_stringShift($buffer['xor'], $block_size); + $key = $this->_string_shift($buffer['xor'], $block_size); $plaintext.= $block ^ $key; } } else { @@ -1060,6 +1237,164 @@ class Crypt_Base return $this->paddable ? $this->_unpad($plaintext) : $plaintext; } + /** + * OpenSSL CTR Processor + * + * PHP's OpenSSL bindings do not operate in continuous mode so we'll wrap around it. Since the keystream + * for CTR is the same for both encrypting and decrypting this function is re-used by both Crypt_Base::encrypt() + * and Crypt_Base::decrypt(). Also, OpenSSL doesn't implement CTR for all of it's symmetric ciphers so this + * function will emulate CTR with ECB when necesary. + * + * @see Crypt_Base::encrypt() + * @see Crypt_Base::decrypt() + * @param String $plaintext + * @param String $encryptIV + * @param Array $buffer + * @return String + * @access private + */ + function _openssl_ctr_process($plaintext, &$encryptIV, &$buffer) + { + $ciphertext = ''; + + $block_size = $this->block_size; + $key = $this->key; + + if ($this->openssl_emulate_ctr) { + $xor = $encryptIV; + if (strlen($buffer['encrypted'])) { + for ($i = 0; $i < strlen($plaintext); $i+=$block_size) { + $block = substr($plaintext, $i, $block_size); + if (strlen($block) > strlen($buffer['encrypted'])) { + $buffer['encrypted'].= openssl_encrypt($xor, $this->cipher_name_openssl_ecb, $key, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING); + } + $this->_increment_str($xor); + $otp = $this->_string_shift($buffer['encrypted'], $block_size); + $ciphertext.= $block ^ $otp; + } + } else { + for ($i = 0; $i < strlen($plaintext); $i+=$block_size) { + $block = substr($plaintext, $i, $block_size); + $otp = openssl_encrypt($xor, $this->cipher_name_openssl_ecb, $key, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING); + $this->_increment_str($xor); + $ciphertext.= $block ^ $otp; + } + } + if ($this->continuousBuffer) { + $encryptIV = $xor; + if ($start = strlen($plaintext) % $block_size) { + $buffer['encrypted'] = substr($key, $start) . $buffer['encrypted']; + } + } + + return $ciphertext; + } + + if (strlen($buffer['encrypted'])) { + $ciphertext = $plaintext ^ $this->_string_shift($buffer['encrypted'], strlen($plaintext)); + $plaintext = substr($plaintext, strlen($ciphertext)); + + if (!strlen($plaintext)) { + return $ciphertext; + } + } + + $overflow = strlen($plaintext) % $block_size; + if ($overflow) { + $plaintext2 = $this->_string_pop($plaintext, $overflow); // ie. trim $plaintext to a multiple of $block_size and put rest of $plaintext in $plaintext2 + $encrypted = openssl_encrypt($plaintext . str_repeat("\0", $block_size), $this->cipher_name_openssl, $key, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING, $encryptIV); + $encryptIV = $this->_string_pop($encrypted, $block_size); + $ciphertext.= $encrypted . ($plaintext2 ^ $encryptIV); + $buffer['encrypted'] = substr($encryptIV, $overflow); + } else if (!strlen($buffer['encrypted'])) { + $ciphertext.= openssl_encrypt($plaintext . str_repeat("\0", $block_size), $this->cipher_name_openssl, $key, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING, $encryptIV); + $encryptIV = $this->_string_pop($ciphertext, $block_size); + } + $encryptIV = openssl_decrypt($encryptIV, $this->cipher_name_openssl_ecb, $key, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING); + if ($overflow) { + $this->_increment_str($encryptIV); + } + + return $ciphertext; + } + + /** + * OpenSSL OFB Processor + * + * PHP's OpenSSL bindings do not operate in continuous mode so we'll wrap around it. Since the keystream + * for OFB is the same for both encrypting and decrypting this function is re-used by both Crypt_Base::encrypt() + * and Crypt_Base::decrypt(). + * + * @see Crypt_Base::encrypt() + * @see Crypt_Base::decrypt() + * @param String $plaintext + * @param String $encryptIV + * @param Array $buffer + * @return String + * @access private + */ + function _openssl_ofb_process($plaintext, &$encryptIV, &$buffer) + { + if (strlen($buffer['xor'])) { + $ciphertext = $plaintext ^ $buffer['xor']; + $buffer['xor'] = substr($buffer['xor'], strlen($ciphertext)); + $plaintext = substr($plaintext, strlen($ciphertext)); + } else { + $ciphertext = ''; + } + + $block_size = $this->block_size; + + $len = strlen($plaintext); + $key = $this->key; + $overflow = $len % $block_size; + + if (strlen($plaintext)) { + if ($overflow) { + $ciphertext.= openssl_encrypt(substr($plaintext, 0, -$overflow) . str_repeat("\0", $block_size), $this->cipher_name_openssl, $key, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING, $encryptIV); + $xor = $this->_string_pop($ciphertext, $block_size); + if ($this->continuousBuffer) { + $encryptIV = $xor; + } + $ciphertext.= $this->_string_shift($xor, $overflow) ^ substr($plaintext, -$overflow); + if ($this->continuousBuffer) { + $buffer['xor'] = $xor; + } + } else { + $ciphertext = openssl_encrypt($plaintext, $this->cipher_name_openssl, $key, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING, $encryptIV); + if ($this->continuousBuffer) { + $encryptIV = substr($ciphertext, -$block_size) ^ substr($plaintext, -$block_size); + } + } + } + + return $ciphertext; + } + + /** + * phpseclib <-> OpenSSL Mode Mapper + * + * May need to be overwritten by classes extending this one in some cases + * + * @return Integer + * @access private + */ + function _openssl_translate_mode() + { + switch ($this->mode) { + case CRYPT_MODE_ECB: + return 'ecb'; + case CRYPT_MODE_CBC: + return 'cbc'; + case CRYPT_MODE_CTR: + return 'ctr'; + case CRYPT_MODE_CFB: + return 'cfb'; + case CRYPT_MODE_OFB: + return 'ofb'; + } + } + /** * Pad "packets". * @@ -1161,53 +1496,113 @@ class Crypt_Base } /** - * Sets the internal crypt engine + * Test for engine validity * - * Will be called automatically on "__construct()", so normally it's not - * necessary to call setEngine() manually, but ie for debuging or testing. + * @see Crypt_Base::Crypt_Base() + * @param Integer $engine + * @access public + * @return Boolean + */ + function isValidEngine($engine) + { + switch ($engine) { + case CRYPT_MODE_OPENSSL: + $this->openssl_emulate_ctr = false; + $result = $this->cipher_name_openssl && + extension_loaded('openssl') && + version_compare(PHP_VERSION, '5.3.0'); + if (!$result) { + return false; + } + $methods = openssl_get_cipher_methods(); + if (in_array($this->cipher_name_openssl, $methods)) { + return true; + } + // not all of openssl's symmetric cipher's support ctr. for those + // that don't we'll emulate it + switch ($this->mode) { + case CRYPT_MODE_CTR: + if (in_array($this->cipher_name_openssl_ecb, $methods)) { + $this->openssl_emulate_ctr = true; + return true; + } + } + return false; + case CRYPT_MODE_MCRYPT: + return $this->cipher_name_mcrypt && + extension_loaded('mcrypt') && + in_array($this->cipher_name_mcrypt, mcrypt_list_algorithms()); + case CRYPT_MODE_INTERNAL: + return true; + } + } + + /** + * Sets the preferred crypt engine * * Currently, $engine could be: * + * - CRYPT_MODE_OPENSSL [very fast] + * * - CRYPT_MODE_MCRYPT [fast] * * - CRYPT_MODE_INTERNAL [slow] * - * Respectivly the officially alias constants of the choosen cipher, - * ie for AES: CRYPT_AES_MODE_MCRYPT or CRYPT_AES_MODE_INTERNAL - * - * If $engine is not explictly set, the fastest available $engine - * will be set (currently: CRYPT_MODE_MCRYPT) - * - * If $engine == CRYPT_MODE_MCRYPT but the mcrypt extension is not loaded/available it - * will be set the next available fastest $engine (currently: CRYPT_MODE_INTERNAL) - * - * If called, all internal buffers and cipher states will be reset, so, - * for example, switching the $engine while enableContinuousBuffer() will - * reset the ContinuousBuffer's. - * - * setEngine() returns always the $engine which was effectively set. + * If the preferred crypt engine is not available the fastest available one will be used * * @see Crypt_Base::Crypt_Base() - * @param optional Integer $engine + * @param Integer $engine * @access public - * @return Integer - * @internal Could, but not must, extend by the child Crypt_* class */ - function setEngine($engine = CRYPT_MODE_MCRYPT) + function setPreferredEngine($engine) { switch ($engine) { + //case CRYPT_MODE_OPENSSL: + case CRYPT_MODE_MCRYPT: case CRYPT_MODE_INTERNAL: - $this->engine = CRYPT_MODE_INTERNAL; + $this->preferredEngine = $engine; break; default: - if ($this->cipher_name_mcrypt && extension_loaded('mcrypt') && in_array($this->cipher_name_mcrypt, mcrypt_list_algorithms())) { - $this->engine = CRYPT_MODE_MCRYPT; - } else { - $this->engine = CRYPT_MODE_INTERNAL; - } + $this->preferredEngine = CRYPT_MODE_OPENSSL; } - if ($this->enmcrypt) { + $this->_setEngine(); + } + + /** + * Returns the engine currently being utilized + * + * @see Crypt_Base::_setEngine() + * @access public + */ + function getEngine() + { + return $this->engine; + } + + /** + * Sets the engine as appropriate + * + * @see Crypt_Base::Crypt_Base() + * @access private + */ + function _setEngine() + { + switch (true) { + case $this->isValidEngine($this->preferredEngine): + $this->engine = $this->preferredEngine; + break; + case $this->isValidEngine(CRYPT_MODE_OPENSSL): + $this->engine = CRYPT_MODE_OPENSSL; + break; + case $this->isValidEngine(CRYPT_MODE_MCRYPT): + $this->engine = CRYPT_MODE_MCRYPT; + break; + default: + $this->engine = CRYPT_MODE_INTERNAL; + } + + if ($this->engine != CRYPT_MODE_MCRYPT && $this->enmcrypt) { // Closing the current mcrypt resource(s). _mcryptSetup() will, if needed, // (re)open them with the module named in $this->cipher_name_mcrypt mcrypt_module_close($this->enmcrypt); @@ -1222,7 +1617,6 @@ class Crypt_Base } $this->changed = true; - return $this->engine; } /** @@ -1443,7 +1837,7 @@ class Crypt_Base * @access private * @return String */ - function _stringShift(&$string, $index = 1) + function _string_shift(&$string, $index = 1) { $substr = substr($string, 0, $index); $string = substr($string, $index); @@ -1451,43 +1845,57 @@ class Crypt_Base } /** - * Generate CTR XOR encryption key + * String Pop * - * Encrypt the output of this and XOR it against the ciphertext / plaintext to get the - * plaintext / ciphertext in CTR mode. + * Inspired by array_pop + * + * @param String $string + * @param optional Integer $index + * @access private + * @return String + */ + function _string_pop(&$string, $index = 1) + { + $substr = substr($string, -$index); + $string = substr($string, 0, -$index); + return $substr; + } + + /** + * Increment the current string * * @see Crypt_Base::decrypt() * @see Crypt_Base::encrypt() - * @param String $iv - * @param Integer $length + * @param String $var * @access private - * @return String $xor */ - function _generateXor(&$iv, $length) + function _increment_str(&$var) { - $xor = ''; - $block_size = $this->block_size; - $num_blocks = floor(($length + ($block_size - 1)) / $block_size); - for ($i = 0; $i < $num_blocks; $i++) { - $xor.= $iv; - for ($j = 4; $j <= $block_size; $j+= 4) { - $temp = substr($iv, -$j, 4); - switch ($temp) { - case "\xFF\xFF\xFF\xFF": - $iv = substr_replace($iv, "\x00\x00\x00\x00", -$j, 4); - break; - case "\x7F\xFF\xFF\xFF": - $iv = substr_replace($iv, "\x80\x00\x00\x00", -$j, 4); - break 2; - default: - extract(unpack('Ncount', $temp)); - $iv = substr_replace($iv, pack('N', $count + 1), -$j, 4); - break 2; - } + for ($i = 4; $i <= strlen($var); $i+= 4) { + $temp = substr($var, -$i, 4); + switch ($temp) { + case "\xFF\xFF\xFF\xFF": + $var = substr_replace($var, "\x00\x00\x00\x00", -$i, 4); + break; + case "\x7F\xFF\xFF\xFF": + $var = substr_replace($var, "\x80\x00\x00\x00", -$i, 4); + return; + default: + $temp = unpack('Nnum', $temp); + $var = substr_replace($var, pack('N', $temp['num'] + 1), -$i, 4); + return; } } - return $xor; + $remainder = strlen($var) % 4; + + if ($remainder == 0) { + return; + } + + $temp = unpack('Nnum', str_pad(substr($var, 0, $remainder), 4, "\0", STR_PAD_LEFT)); + $temp = substr(pack('N', $temp['num'] + 1), -$remainder); + $var = substr_replace($var, $temp, 0, $remainder); } /** @@ -1691,7 +2099,6 @@ class Crypt_Base case CRYPT_MODE_ECB: $encrypt = $init_encrypt . ' $_ciphertext = ""; - $_text = $self->_pad($_text); $_plaintext_len = strlen($_text); for ($_i = 0; $_i < $_plaintext_len; $_i+= '.$block_size.') { @@ -1723,23 +2130,24 @@ class Crypt_Base $_plaintext_len = strlen($_text); $_xor = $self->encryptIV; $_buffer = &$self->enbuffer; - if (strlen($_buffer["encrypted"])) { for ($_i = 0; $_i < $_plaintext_len; $_i+= '.$block_size.') { $_block = substr($_text, $_i, '.$block_size.'); if (strlen($_block) > strlen($_buffer["encrypted"])) { - $in = $self->_generateXor($_xor, '.$block_size.'); + $in = $_xor; '.$encrypt_block.' + $self->_increment_str($_xor); $_buffer["encrypted"].= $in; } - $_key = $self->_stringShift($_buffer["encrypted"], '.$block_size.'); + $_key = $self->_string_shift($_buffer["encrypted"], '.$block_size.'); $_ciphertext.= $_block ^ $_key; } } else { for ($_i = 0; $_i < $_plaintext_len; $_i+= '.$block_size.') { $_block = substr($_text, $_i, '.$block_size.'); - $in = $self->_generateXor($_xor, '.$block_size.'); + $in = $_xor; '.$encrypt_block.' + $self->_increment_str($_xor); $_key = $in; $_ciphertext.= $_block ^ $_key; } @@ -1764,18 +2172,20 @@ class Crypt_Base for ($_i = 0; $_i < $_ciphertext_len; $_i+= '.$block_size.') { $_block = substr($_text, $_i, '.$block_size.'); if (strlen($_block) > strlen($_buffer["ciphertext"])) { - $in = $self->_generateXor($_xor, '.$block_size.'); + $in = $_xor; '.$encrypt_block.' + $self->_increment_str($_xor); $_buffer["ciphertext"].= $in; } - $_key = $self->_stringShift($_buffer["ciphertext"], '.$block_size.'); + $_key = $self->_string_shift($_buffer["ciphertext"], '.$block_size.'); $_plaintext.= $_block ^ $_key; } } else { for ($_i = 0; $_i < $_ciphertext_len; $_i+= '.$block_size.') { $_block = substr($_text, $_i, '.$block_size.'); - $in = $self->_generateXor($_xor, '.$block_size.'); + $in = $_xor; '.$encrypt_block.' + $self->_increment_str($_xor); $_key = $in; $_plaintext.= $_block ^ $_key; } @@ -1905,7 +2315,7 @@ class Crypt_Base $_xor = $in; $_buffer["xor"].= $_xor; } - $_key = $self->_stringShift($_buffer["xor"], '.$block_size.'); + $_key = $self->_string_shift($_buffer["xor"], '.$block_size.'); $_ciphertext.= $_block ^ $_key; } } else { @@ -1941,7 +2351,7 @@ class Crypt_Base $_xor = $in; $_buffer["xor"].= $_xor; } - $_key = $self->_stringShift($_buffer["xor"], '.$block_size.'); + $_key = $self->_string_shift($_buffer["xor"], '.$block_size.'); $_plaintext.= $_block ^ $_key; } } else { @@ -1978,7 +2388,6 @@ class Crypt_Base default: $encrypt = $init_encrypt . ' $_ciphertext = ""; - $_text = $self->_pad($_text); $_plaintext_len = strlen($_text); $in = $self->encryptIV; @@ -2058,7 +2467,7 @@ class Crypt_Base define('CRYPT_BASE_WHIRLPOOL_AVAILABLE', (bool)(extension_loaded('hash') && in_array('whirlpool', hash_algos()))); } - // return pack('H*', md5($bytes) . sha1($bytes) . (CRYPT_BASE_WHIRLPOOL_AVAILABLE ? hash('whirlpool', $bytes) : '')); // Alternativ + // return pack('H*', md5($bytes) . sha1($bytes) . (CRYPT_BASE_WHIRLPOOL_AVAILABLE ? hash('whirlpool', $bytes) : '')); // Alternative $result = ''; $hash = $bytes; diff --git a/phpseclib/Crypt/Blowfish.php b/phpseclib/Crypt/Blowfish.php index 61e1db72..7dfa419b 100644 --- a/phpseclib/Crypt/Blowfish.php +++ b/phpseclib/Crypt/Blowfish.php @@ -101,20 +101,6 @@ define('CRYPT_BLOWFISH_MODE_CFB', CRYPT_MODE_CFB); define('CRYPT_BLOWFISH_MODE_OFB', CRYPT_MODE_OFB); /**#@-*/ -/**#@+ - * @access private - * @see Crypt_Base::Crypt_Base() - */ -/** - * Toggles the internal implementation - */ -define('CRYPT_BLOWFISH_MODE_INTERNAL', CRYPT_MODE_INTERNAL); -/** - * Toggles the mcrypt implementation - */ -define('CRYPT_BLOWFISH_MODE_MCRYPT', CRYPT_MODE_MCRYPT); -/**#@-*/ - /** * Pure-PHP implementation of Blowfish. * @@ -384,7 +370,6 @@ class Crypt_Blowfish extends Crypt_Base * @param String $key */ function setKey($key) - { $keylength = strlen($key); if (!$keylength) { @@ -396,6 +381,29 @@ class Crypt_Blowfish extends Crypt_Base parent::setKey($key); } + /** + * Test for engine validity + * + * This is mainly just a wrapper to set things up for Crypt_Base::isValidEngine() + * + * @see Crypt_Base::Crypt_Base() + * @param Integer $engine + * @access public + * @return Boolean + */ + function isValidEngine($engine) + { + if ($engine == CRYPT_MODE_OPENSSL) { + if (strlen($this->key) != 16) { + return false; + } + $this->cipher_name_openssl_ecb = 'bf-ecb'; + $this->cipher_name_openssl = 'bf-' . $this->_openssl_translate_mode(); + } + + return parent::isValidEngine($engine); + } + /** * Setup the key (expansion) * diff --git a/phpseclib/Crypt/DES.php b/phpseclib/Crypt/DES.php index 778767bb..395f9d30 100644 --- a/phpseclib/Crypt/DES.php +++ b/phpseclib/Crypt/DES.php @@ -121,20 +121,6 @@ define('CRYPT_DES_MODE_CFB', CRYPT_MODE_CFB); define('CRYPT_DES_MODE_OFB', CRYPT_MODE_OFB); /**#@-*/ -/**#@+ - * @access private - * @see Crypt_Base::Crypt_Base() - */ -/** - * Toggles the internal implementation - */ -define('CRYPT_DES_MODE_INTERNAL', CRYPT_MODE_INTERNAL); -/** - * Toggles the mcrypt implementation - */ -define('CRYPT_DES_MODE_MCRYPT', CRYPT_MODE_MCRYPT); -/**#@-*/ - /** * Pure-PHP implementation of DES. * @@ -192,6 +178,21 @@ class Crypt_DES extends Crypt_Base */ var $cipher_name_mcrypt = 'des'; + /** + * The OpenSSL names of the cipher / modes + * + * @see Crypt_Base::openssl_mode_names + * @var Array + * @access private + */ + var $openssl_mode_names = array( + CRYPT_MODE_ECB => 'des-ecb', + CRYPT_MODE_CBC => 'des-cbc', + CRYPT_MODE_CFB => 'des-cfb', + CRYPT_MODE_OFB => 'des-ofb' + // CRYPT_MODE_CTR is undefined for DES + ); + /** * Optimizing value while CFB-encrypting * @@ -662,6 +663,26 @@ class Crypt_DES extends Crypt_Base 0x00000820, 0x00020020, 0x08000000, 0x08020800 ); + /** + * Test for engine validity + * + * This is mainly just a wrapper to set things up for Crypt_Base::isValidEngine() + * + * @see Crypt_Base::Crypt_Base() + * @param Integer $engine + * @access public + * @return Boolean + */ + function isValidEngine($engine) + { + if ($engine == CRYPT_MODE_OPENSSL) { + $this->cipher_name_openssl_ecb = 'des-ecb'; + $this->cipher_name_openssl = 'des-' . $this->_openssl_translate_mode(); + } + + return parent::isValidEngine($engine); + } + /** * Sets the key. * diff --git a/phpseclib/Crypt/RC2.php b/phpseclib/Crypt/RC2.php index 6a4c71db..f6857c7e 100644 --- a/phpseclib/Crypt/RC2.php +++ b/phpseclib/Crypt/RC2.php @@ -99,20 +99,6 @@ define('CRYPT_RC2_MODE_CFB', CRYPT_MODE_CFB); define('CRYPT_RC2_MODE_OFB', CRYPT_MODE_OFB); /**#@-*/ -/**#@+ - * @access public - * @see Crypt_RC2::Crypt_RC2() - */ -/** - * Toggles the internal implementation - */ -define('CRYPT_RC2_MODE_INTERNAL', CRYPT_MODE_INTERNAL); -/** - * Toggles the mcrypt implementation - */ -define('CRYPT_RC2_MODE_MCRYPT', CRYPT_MODE_MCRYPT); -/**#@-*/ - /** * Pure-PHP implementation of RC2. * @@ -141,6 +127,18 @@ class Crypt_RC2 extends Crypt_Base */ var $key; + /** + * The Original (unpadded) Key + * + * @see Crypt_Base::key + * @see setKey() + * @see encrypt() + * @see decrypt() + * @var String + * @access private + */ + var $orig_key; + /** * The default password key_size used by setPassword() * @@ -190,6 +188,17 @@ class Crypt_RC2 extends Crypt_Base */ var $default_key_length = 1024; + /** + * The key length in bits. + * + * @see Crypt_RC2::isValidEnine() + * @see Crypt_RC2::setKey() + * @var Integer + * @access private + * @internal Should be in range [1..1024]. + */ + var $current_key_length; + /** * The Key Schedule * @@ -344,6 +353,30 @@ class Crypt_RC2 extends Crypt_Base parent::Crypt_Base($mode); } + /** + * Test for engine validity + * + * This is mainly just a wrapper to set things up for Crypt_Base::isValidEngine() + * + * @see Crypt_Base::Crypt_Base() + * @param Integer $engine + * @access public + * @return Boolean + */ + function isValidEngine($engine) + { + switch ($engine) { + case CRYPT_MODE_OPENSSL: + if ($this->current_key_length != 128 && strlen($this->orig_key) != 16) { + return false; + } + $this->cipher_name_openssl_ecb = 'rc2-ecb'; + $this->cipher_name_openssl = 'rc2-' . $this->_openssl_translate_mode(); + } + + return parent::isValidEngine($engine); + } + /** * Sets the key length * @@ -375,15 +408,18 @@ class Crypt_RC2 extends Crypt_Base * @see Crypt_Base::setKey() * @access public * @param String $key - * @param Integer $t1 optional Effective key length in bits. + * @param Integer $t1 optional Effective key length in bits. */ function setKey($key, $t1 = 0) { + $this->orig_key = $key; + if ($t1 <= 0) { $t1 = $this->default_key_length; } else if ($t1 > 1024) { $t1 = 1024; } + $this->current_key_length = $t1; // Key byte count should be 1..128. $key = strlen($key) ? substr($key, 0, 128) : "\x00"; $t = strlen($key); @@ -416,6 +452,52 @@ class Crypt_RC2 extends Crypt_Base parent::setKey(call_user_func_array('pack', $l)); } + /** + * Encrypts a message. + * + * Mostly a wrapper for Crypt_Base::encrypt, with some additional OpenSSL handling code + * + * @see decrypt() + * @access public + * @param String $plaintext + * @return String $ciphertext + */ + function encrypt($plaintext) + { + if ($this->engine == CRYPT_MODE_OPENSSL) { + $temp = $this->key; + $this->key = $this->orig_key; + $result = parent::encrypt($plaintext); + $this->key = $temp; + return $result; + } + + return parent::encrypt($plaintext); + } + + /** + * Decrypts a message. + * + * Mostly a wrapper for Crypt_Base::decrypt, with some additional OpenSSL handling code + * + * @see encrypt() + * @access public + * @param String $ciphertext + * @return String $plaintext + */ + function decrypt($ciphertext) + { + if ($this->engine == CRYPT_MODE_OPENSSL) { + $temp = $this->key; + $this->key = $this->orig_key; + $result = parent::decrypt($ciphertext); + $this->key = $temp; + return $result; + } + + return parent::encrypt($ciphertext); + } + /** * Encrypts a block * diff --git a/phpseclib/Crypt/RC4.php b/phpseclib/Crypt/RC4.php index dca8dda9..4c473a01 100644 --- a/phpseclib/Crypt/RC4.php +++ b/phpseclib/Crypt/RC4.php @@ -69,20 +69,6 @@ if (!class_exists('Crypt_Base')) { include_once 'Base.php'; } -/**#@+ - * @access public - * @see Crypt_RC4::Crypt_RC4() - */ -/** - * Toggles the internal implementation - */ -define('CRYPT_RC4_MODE_INTERNAL', CRYPT_MODE_INTERNAL); -/** - * Toggles the mcrypt implementation - */ -define('CRYPT_RC4_MODE_MCRYPT', CRYPT_MODE_MCRYPT); -/**#@-*/ - /**#@+ * @access private * @see Crypt_RC4::_crypt() @@ -182,6 +168,38 @@ class Crypt_RC4 extends Crypt_Base parent::Crypt_Base(CRYPT_MODE_STREAM); } + /** + * Test for engine validity + * + * This is mainly just a wrapper to set things up for Crypt_Base::isValidEngine() + * + * @see Crypt_Base::Crypt_Base() + * @param Integer $engine + * @access public + * @return Boolean + */ + function isValidEngine($engine) + { + switch ($engine) { + case CRYPT_MODE_OPENSSL: + switch (strlen($this->key)) { + case 5: + $this->cipher_name_openssl = 'rc4-40'; + break; + case 8: + $this->cipher_name_openssl = 'rc4-64'; + break; + case 16: + $this->cipher_name_openssl = 'rc4'; + break; + default: + return false; + } + } + + return parent::isValidEngine($engine); + } + /** * Dummy function. * diff --git a/phpseclib/Crypt/Rijndael.php b/phpseclib/Crypt/Rijndael.php index 5f2b7519..18444e6c 100644 --- a/phpseclib/Crypt/Rijndael.php +++ b/phpseclib/Crypt/Rijndael.php @@ -118,20 +118,6 @@ define('CRYPT_RIJNDAEL_MODE_CFB', CRYPT_MODE_CFB); define('CRYPT_RIJNDAEL_MODE_OFB', CRYPT_MODE_OFB); /**#@-*/ -/**#@+ - * @access private - * @see Crypt_Base::Crypt_Base() - */ -/** - * Toggles the internal implementation - */ -define('CRYPT_RIJNDAEL_MODE_INTERNAL', CRYPT_MODE_INTERNAL); -/** - * Toggles the mcrypt implementation - */ -define('CRYPT_RIJNDAEL_MODE_MCRYPT', CRYPT_MODE_MCRYPT); -/**#@-*/ - /** * Pure-PHP implementation of Rijndael. * @@ -171,7 +157,7 @@ class Crypt_Rijndael extends Crypt_Base * * @see Crypt_Base::cipher_name_mcrypt * @see Crypt_Base::engine - * @see _setupEngine() + * @see isValidEngine() * @var String * @access private */ @@ -323,8 +309,6 @@ class Crypt_Rijndael extends Crypt_Base */ function setKey($key) { - parent::setKey($key); - if (!$this->explicit_key_length) { $length = strlen($key); switch (true) { @@ -343,8 +327,8 @@ class Crypt_Rijndael extends Crypt_Base default: $this->key_size = 32; } - $this->_setupEngine(); } + parent::setKey($key); } /** @@ -388,7 +372,7 @@ class Crypt_Rijndael extends Crypt_Base $this->explicit_key_length = true; $this->changed = true; - $this->_setupEngine(); + $this->_setEngine(); } /** @@ -411,33 +395,38 @@ class Crypt_Rijndael extends Crypt_Base $this->Nb = $length; $this->block_size = $length << 2; $this->changed = true; - $this->_setupEngine(); + $this->_setEngine(); } /** - * Setup the fastest possible $engine + * Test for engine validity * - * Determines if the mcrypt (MODE_MCRYPT) $engine available - * and usable for the current $block_size and $key_size. + * This is mainly just a wrapper to set things up for Crypt_Base::isValidEngine() * - * If not, the slower MODE_INTERNAL $engine will be set. - * - * @see setKey() - * @see setKeyLength() - * @see setBlockLength() - * @access private + * @see Crypt_Base::Crypt_Base() + * @param Integer $engine + * @access public + * @return Boolean */ - function _setupEngine() + function isValidEngine($engine) { - // Set the mcrypt module name for the current $block_size of rijndael - $this->cipher_name_mcrypt = 'rijndael-' . ($this->block_size << 3); - - // Set the engine - if ($this->key_size % 8) { // is it a 160/224-bit key? - // mcrypt is not usable for them, only for 128/192/256-bit keys - // so we are forced to set the slower MODE_INTERNAL $engine - $this->setEngine(CRYPT_MODE_INTERNAL); + switch ($engine) { + case CRYPT_MODE_OPENSSL: + if ($this->block_size != 16) { + return false; + } + $this->cipher_name_openssl_ecb = 'aes-' . ($this->key_size << 3) . '-ecb'; + $this->cipher_name_openssl = 'aes-' . ($this->key_size << 3) . '-' . $this->_openssl_translate_mode(); + break; + case CRYPT_MODE_MCRYPT: + $this->cipher_name_mcrypt = 'rijndael-' . ($this->block_size << 3); + if ($this->key_size % 8) { // is it a 160/224-bit key? + // mcrypt is not usable for them, only for 128/192/256-bit keys + return false; + } } + + return parent::isValidEngine($engine); } /** diff --git a/phpseclib/Crypt/TripleDES.php b/phpseclib/Crypt/TripleDES.php index 1945ab19..c75000ac 100644 --- a/phpseclib/Crypt/TripleDES.php +++ b/phpseclib/Crypt/TripleDES.php @@ -218,6 +218,27 @@ class Crypt_TripleDES extends Crypt_DES } } + /** + * Test for engine validity + * + * This is mainly just a wrapper to set things up for Crypt_Base::isValidEngine() + * + * @see Crypt_Base::Crypt_Base() + * @param Integer $engine + * @access public + * @return Boolean + */ + function isValidEngine($engine) + { + if ($engine == CRYPT_MODE_OPENSSL) { + $this->cipher_name_openssl_ecb = 'des-ede3'; + $mode = $this->_openssl_translate_mode(); + $this->cipher_name_openssl = $mode == 'ecb' ? 'des-ede3' : 'des-ede3-' . $mode; + } + + return parent::isValidEngine($engine); + } + /** * Sets the initialization vector. (optional) * @@ -260,7 +281,7 @@ class Crypt_TripleDES extends Crypt_DES $key = str_pad(substr($key, 0, 24), 24, chr(0)); // if $key is between 64 and 128-bits, use the first 64-bits as the last, per this: // http://php.net/function.mcrypt-encrypt#47973 - //$key = $length <= 16 ? substr_replace($key, substr($key, 0, 8), 16) : substr($key, 0, 24); + $key = $length <= 16 ? substr_replace($key, substr($key, 0, 8), 16) : substr($key, 0, 24); } else { $key = str_pad($key, 8, chr(0)); } diff --git a/phpseclib/Crypt/Twofish.php b/phpseclib/Crypt/Twofish.php index bb024adc..c99f3ad8 100644 --- a/phpseclib/Crypt/Twofish.php +++ b/phpseclib/Crypt/Twofish.php @@ -101,20 +101,6 @@ define('CRYPT_TWOFISH_MODE_CFB', CRYPT_MODE_CFB); define('CRYPT_TWOFISH_MODE_OFB', CRYPT_MODE_OFB); /**#@-*/ -/**#@+ - * @access private - * @see Crypt_Base::Crypt_Base() - */ -/** - * Toggles the internal implementation - */ -define('CRYPT_TWOFISH_MODE_INTERNAL', CRYPT_MODE_INTERNAL); -/** - * Toggles the mcrypt implementation - */ -define('CRYPT_TWOFISH_MODE_MCRYPT', CRYPT_MODE_MCRYPT); -/**#@-*/ - /** * Pure-PHP implementation of Twofish. * diff --git a/tests/Unit/Crypt/AES/InternalTest.php b/tests/Unit/Crypt/AES/InternalTest.php index 41801c85..73f39d0a 100644 --- a/tests/Unit/Crypt/AES/InternalTest.php +++ b/tests/Unit/Crypt/AES/InternalTest.php @@ -7,10 +7,8 @@ class Unit_Crypt_AES_InternalTest extends Unit_Crypt_AES_TestCase { - static public function setUpBeforeClass() + protected function setUp() { - self::$engine = CRYPT_MODE_INTERNAL; - - parent::setUpBeforeClass(); + $this->engine = CRYPT_MODE_INTERNAL; } } diff --git a/tests/Unit/Crypt/AES/McryptTest.php b/tests/Unit/Crypt/AES/McryptTest.php index 78902fc0..7830408b 100644 --- a/tests/Unit/Crypt/AES/McryptTest.php +++ b/tests/Unit/Crypt/AES/McryptTest.php @@ -7,14 +7,8 @@ class Unit_Crypt_AES_McryptTest extends Unit_Crypt_AES_TestCase { - static public function setUpBeforeClass() + protected function setUp() { - if (!extension_loaded('mcrypt')) { - self::markTestSkipped('mcrypt extension is not available.'); - } - - self::$engine = CRYPT_MODE_MCRYPT; - - parent::setUpBeforeClass(); + $this->engine = CRYPT_MODE_MCRYPT; } } diff --git a/tests/Unit/Crypt/AES/OpenSSLTest.php b/tests/Unit/Crypt/AES/OpenSSLTest.php new file mode 100644 index 00000000..ff950d08 --- /dev/null +++ b/tests/Unit/Crypt/AES/OpenSSLTest.php @@ -0,0 +1,14 @@ + + * @copyright MMXIII Andreas Fischer + * @license http://www.opensource.org/licenses/mit-license.html MIT License + */ + +class Unit_Crypt_AES_OpenSSLTest extends Unit_Crypt_AES_TestCase +{ + protected function setUp() + { + $this->engine = CRYPT_MODE_OPENSSL; + } +} diff --git a/tests/Unit/Crypt/AES/TestCase.php b/tests/Unit/Crypt/AES/TestCase.php index 2a40450c..6e7f8d65 100644 --- a/tests/Unit/Crypt/AES/TestCase.php +++ b/tests/Unit/Crypt/AES/TestCase.php @@ -9,11 +9,21 @@ require_once 'Crypt/AES.php'; abstract class Unit_Crypt_AES_TestCase extends PhpseclibTestCase { - protected static $engine; + protected $engine; - static public function setUpBeforeClass() + private function checkEngine($aes) { - parent::setUpBeforeClass(); + if ($aes->getEngine() != $this->engine) { + $engine = 'internal'; + switch ($this->engine) { + case CRYPT_MODE_OPENSSL: + $engine = 'OpenSSL'; + break; + case CRYPT_MODE_MCRYPT: + $engine = 'mcrypt'; + } + self::markTestSkipped('Unable to initialize ' . $engine . ' engine'); + } } /** @@ -63,11 +73,13 @@ abstract class Unit_Crypt_AES_TestCase extends PhpseclibTestCase public function testEncryptDecryptWithContinuousBuffer($mode, $plaintext, $iv, $key) { $aes = new Crypt_AES(constant($mode)); - $aes->setEngine(self::$engine); + $aes->setPreferredEngine($this->engine); $aes->enableContinuousBuffer(); $aes->setIV($iv); $aes->setKey($key); + $this->checkEngine($aes); + $actual = ''; for ($i = 0, $strlen = strlen($plaintext); $i < $strlen; ++$i) { $actual .= $aes->decrypt($aes->encrypt($plaintext[$i])); @@ -85,9 +97,10 @@ abstract class Unit_Crypt_AES_TestCase extends PhpseclibTestCase // https://web.archive.org/web/20070209120224/http://fp.gladman.plus.com/cryptography_technology/rijndael/aesdvec.zip $aes = new Crypt_Rijndael(); - $aes->setEngine(self::$engine); + $aes->setPreferredEngine($this->engine); $aes->disablePadding(); $aes->setKey(pack('H*', '2b7e151628aed2a6abf7158809cf4f3c762e7160')); // 160-bit key. Valid in Rijndael. + //$this->checkEngine($aes); // should only work in internal mode $ciphertext = $aes->encrypt(pack('H*', '3243f6a8885a308d313198a2e0370734')); $this->assertEquals($ciphertext, pack('H*', '231d844639b31b412211cfe93712b880')); } @@ -100,10 +113,96 @@ abstract class Unit_Crypt_AES_TestCase extends PhpseclibTestCase // same as the above - just with a different ciphertext $aes = new Crypt_AES(); - $aes->setEngine(self::$engine); + $aes->setPreferredEngine($this->engine); $aes->disablePadding(); $aes->setKey(pack('H*', '2b7e151628aed2a6abf7158809cf4f3c762e7160')); // 160-bit key. AES should null pad to 192-bits + $this->checkEngine($aes); $ciphertext = $aes->encrypt(pack('H*', '3243f6a8885a308d313198a2e0370734')); $this->assertEquals($ciphertext, pack('H*', 'c109292b173f841b88e0ee49f13db8c0')); } -} + + /** + * Produces all combinations of test values. + * + * @return array + */ + public function continuousBufferBatteryCombos() + { + $modes = array( + 'CRYPT_MODE_CTR', + 'CRYPT_MODE_OFB', + 'CRYPT_MODE_CFB', + ); + + $combos = array( + array(16), + array(17), + array(1, 16), + array(3, 6, 7), // (3 to test the openssl_encrypt call and the buffer creation, 6 to test the exclusive use of the buffer and 7 to test the buffer's exhaustion and recreation) + array(15, 4), // (15 to test openssl_encrypt call and buffer creation and 4 to test something that spans multpile bloc + array(3, 6, 10, 16), // this is why the strlen check in the buffer-only code was needed + array(16, 16), // two full size blocks + array(3, 6, 7, 16), // partial block + full size block + array(16, 3, 6, 7), + // a few others just for fun + array(32,32), + array(31,31), + array(17,17), + array(99, 99) + ); + + $result = array(); + + // @codingStandardsIgnoreStart + foreach ($modes as $mode) + foreach ($combos as $combo) + foreach (array('encrypt', 'decrypt') as $op) + $result[] = array($op, $mode, $combo); + // @codingStandardsIgnoreEnd + + return $result; + } + + /** + * @dataProvider continuousBufferBatteryCombos + */ + public function testContinuousBufferBattery($op, $mode, $test) + { + $iv = str_repeat('x', 16); + $key = str_repeat('a', 16); + + $aes = new Crypt_AES(constant($mode)); + $aes->setPreferredEngine($this->engine); + $aes->setKey($key); + $aes->setIV($iv); + + $this->checkEngine($aes); + + $str = ''; + $result = ''; + foreach ($test as $len) { + $temp = str_repeat('d', $len); + $str.= $temp; + } + + $c1 = $aes->$op($str); + + $aes = new Crypt_AES(constant($mode)); + $aes->setPreferredEngine($this->engine); + $aes->enableContinuousBuffer(); + $aes->setKey($key); + $aes->setIV($iv); + + $this->checkEngine($aes); + + foreach ($test as $len) { + $temp = str_repeat('d', $len); + $output = $aes->$op($temp); + $result.= $output; + } + + $c2 = $result; + + $this->assertSame(bin2hex($c1), bin2hex($c2)); + } +} \ No newline at end of file diff --git a/tests/Unit/Crypt/DES.php b/tests/Unit/Crypt/DES.php new file mode 100644 index 00000000..3b6d5a4b --- /dev/null +++ b/tests/Unit/Crypt/DES.php @@ -0,0 +1,69 @@ + + * @copyright MMXIII Andreas Fischer + * @license http://www.opensource.org/licenses/mit-license.html MIT License + */ + +require_once 'Crypt/DES.php'; + +// the AES tests establish the correctness of the modes of operation. this test is inteded to establish the consistency of +// key and iv padding between the multiple engines +class Unit_Crypt_DES_TestCase extends PhpseclibTestCase +{ + public function testEncryptPadding() + { + $des = new Crypt_DES(CRYPT_MODE_CBC); + $des->setKey('d'); + $des->setIV('d'); + + $des->setPreferredEngine(CRYPT_MODE_INTERNAL); + $internal = $des->encrypt('d'); + + $des->setPreferredEngine(CRYPT_MODE_MCRYPT); + if ($des->getEngine() == CRYPT_MODE_MCRYPT) { + $mcrypt = $des->encrypt('d'); + $this->assertEquals($internal, $mcrypt, 'Failed asserting that the internal and mcrypt engines produce identical results'); + } else { + self::markTestSkipped('Unable to initialize mcrypt engine'); + } + + $des->setPreferredEngine(CRYPT_MODE_OPENSSL); + if ($des->getEngine() == CRYPT_MODE_OPENSSL) { + $openssl = $des->encrypt('d'); + $this->assertEquals($internal, $openssl, 'Failed asserting that the internal and OpenSSL engines produce identical results'); + } else { + self::markTestSkipped('Unable to initialize OpenSSL engine'); + } + } + + // phpseclib null pads ciphertext's if they're not long enough and you're in ecb / cbc mode. this silent failure mode is consistent + // with mcrypt's behavior. maybe throwing an exception would be better but whatever. this test is more intended to establish consistent + // behavior between the various engine's + public function testDecryptPadding() + { + $des = new Crypt_DES(CRYPT_MODE_CBC); + // when the key and iv are not specified they should be null padded + //$des->setKey(); + //$des->setIV(); + + $des->setPreferredEngine(CRYPT_MODE_INTERNAL); + $internal = $des->decrypt('d'); + + $des->setPreferredEngine(CRYPT_MODE_MCRYPT); + if ($des->getEngine() == CRYPT_MODE_MCRYPT) { + $mcrypt = $des->decrypt('d'); + $this->assertEquals($internal, $mcrypt, 'Failed asserting that the internal and mcrypt engines produce identical results'); + } else { + self::markTestSkipped('Unable to initialize mcrypt engine'); + } + + $des->setPreferredEngine(CRYPT_MODE_OPENSSL); + if ($des->getEngine() == CRYPT_MODE_OPENSSL) { + $openssl = $des->decrypt('d'); + $this->assertEquals($internal, $openssl, 'Failed asserting that the internal and OpenSSL engines produce identical results'); + } else { + self::markTestSkipped('Unable to initialize OpenSSL engine'); + } + } +} \ No newline at end of file diff --git a/tests/Unit/Crypt/RC2.php b/tests/Unit/Crypt/RC2.php new file mode 100644 index 00000000..545df9b5 --- /dev/null +++ b/tests/Unit/Crypt/RC2.php @@ -0,0 +1,71 @@ + + * @copyright MMXIII Andreas Fischer + * @license http://www.opensource.org/licenses/mit-license.html MIT License + */ + +require_once 'Crypt/RC2.php'; + +// this test is just confirming RC2's key expansion +class Unit_Crypt_RC2_TestCase extends PhpseclibTestCase +{ + public function testEncryptPadding() + { + $rc2 = new Crypt_RC2(CRYPT_MODE_ECB); + + // unlike Crypt_AES / Crypt_Rijndael, when you tell Crypt_RC2 that the key length is 128-bits the key isn't null padded to that length. + // instead, RC2 key expansion is used to extend it out to that length. this isn't done for AES / Rijndael since that doesn't define any + // sort of key expansion algorithm. + + // admittedly, phpseclib is inconsistent in this regard. RC4 and Blowfish support arbitrary key lengths between a certain range, as well, + // and they don't have any way to set the key length. but then again, neither do those algorithms have their own key expansion algorithm, + // whereas RC2 does. and technically, AES / Rijndael (and even Twofish) don't support arbitrary key lengths - they support variable key + // lengths. so in some ways, i suppose this inconsistency somewhat makes sense, although the fact that Crypt_Twofish doesn't have a + // setKeyLength() function whereas Crypt_AES / Crypt_Rijndael do not is, itself, an inconsistency. + + // but that said, Crypt_RC2 is inconsistent in other ways: if you pass a 128-bit (16-byte) key to it via setKey() the key is not treated + // as a 128-bit key but rather as a 1024-bit key and is expanded accordingly, not via null padding, but via RC2's key expansion algorithm. + + // this behavior is in contrast to mcrypt, which extends keys via null padding to 1024 bits. it is also in contrast to OpenSSL, which + // extends keys, via null padding, to 128 bits. mcrypt's approach seems preferable as one can simulate 128 bit keys by using RC2's + // key expansion algorithm to extend the key to 1024 bits and then changing the first byte of the new key with an inverse pitable mapping. + // in contrast, to my knowledge, there is no technique for expanding a key less than 128 bits to 128 bits, via RC2 key expansion. the only + // scenario in that regard is null padding. + + // simple truncation is insufficient, since, quoting RFC2268, "the purpose of th key-expansion algorithm [in RC2] is to modify the key buffer + // so that each bit of the expanded key depends in a complicated way on every bit of the supplied input key". + + // now, to OpenSSL's credit, null padding is internally consistent with OpenSSL. OpenSSL only supports fixed length keys. For rc2, rc4 and + // bf (blowfish), all keys are 128 bits (or are null padded / truncated accordingly). to use 40-bit or 64-bit keys with RC4 with OpenSSL you + // don't use the rc4 algorithm - you use the rc4-40 or rc4-64 algorithm. and similarily, it's not aes-cbc that you use - it's either aes-128-cbc + // or aes-192-cbc or aes-256-cbc. this is in contrast to mcrypt, which (with the exception of RC2) actually supports variable and arbitrary + // length keys. + + // superficially, it seens like Rijndael would be another exception to mcrypt's key length handling, but it in fact is not. the reason being that, + // with mcrypt, when you specify MCRYPT_RIJNDAEL_128 or MCRYPT_RIJNDAEL_192 or MCRYPT_RIJNDAEL_256 the numbers at the end aren't referring to the + // key length, but rather, the block length. ie. Rijndael, unlike most block ciphers, doesn't just have a variable (but not arbitrary) key length - + // it also has a variable block length. AES's block length, however, is not variable, so technically, only MCRYPT_RIJNDAEL_128 is AES. + + $rc2->setKey(str_repeat('d', 16), 128); + + $rc2->setPreferredEngine(CRYPT_MODE_INTERNAL); + $internal = $rc2->encrypt('d'); + + $rc2->setPreferredEngine(CRYPT_MODE_MCRYPT); + if ($rc2->getEngine() == CRYPT_MODE_MCRYPT) { + $mcrypt = $rc2->encrypt('d'); + $this->assertEquals($internal, $mcrypt, 'Failed asserting that the internal and mcrypt engines produce identical results'); + } else { + self::markTestSkipped('Unable to initialize mcrypt engine'); + } + + $rc2->setPreferredEngine(CRYPT_MODE_OPENSSL); + if ($rc2->getEngine() == CRYPT_MODE_OPENSSL) { + $openssl = $rc2->encrypt('d'); + $this->assertEquals($internal, $openssl, 'Failed asserting that the internal and OpenSSL engines produce identical results'); + } else { + self::markTestSkipped('Unable to initialize OpenSSL engine'); + } + } +} \ No newline at end of file From 8476ae63835643d24ac43941ac0f6f33ca89e464 Mon Sep 17 00:00:00 2001 From: terrafrost Date: Sat, 29 Nov 2014 09:48:45 -0600 Subject: [PATCH 08/79] Crypt_Base: openssl_(en|de)crypt's parameters changed in PHP 5.4.0 --- phpseclib/Crypt/Base.php | 57 ++++++++++++++++++++++++++++------------ 1 file changed, 40 insertions(+), 17 deletions(-) diff --git a/phpseclib/Crypt/Base.php b/phpseclib/Crypt/Base.php index d8be982b..d26a1747 100644 --- a/phpseclib/Crypt/Base.php +++ b/phpseclib/Crypt/Base.php @@ -464,6 +464,15 @@ class Crypt_Base */ var $openssl_emulate_ctr = false; + /** + * Determines what options are passed to openssl_encrypt/decrypt + * + * @see Crypt_Base::isValidEngine() + * @var mixed + * @access private + */ + var $openssl_options; + /** * Default Constructor. * @@ -683,14 +692,16 @@ class Crypt_Base } switch ($this->mode) { case CRYPT_MODE_STREAM: + return openssl_encrypt($plaintext, $this->cipher_name_openssl, $this->key, $this->openssl_options); case CRYPT_MODE_ECB: - return openssl_encrypt($plaintext, $this->cipher_name_openssl, $this->key, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING); + $result = openssl_encrypt($plaintext, $this->cipher_name_openssl, $this->key, $this->openssl_options); + return !defined('OPENSSL_RAW_DATA') ? substr($result, 0, -$this->block_size) : $result; case CRYPT_MODE_CBC: - $ciphertext = openssl_encrypt($plaintext, $this->cipher_name_openssl, $this->key, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING, $this->encryptIV); + $ciphertext = openssl_encrypt($plaintext, $this->cipher_name_openssl, $this->key, $this->openssl_options, $this->encryptIV); if ($this->continuousBuffer) { $this->encryptIV = substr($ciphertext, -$this->block_size); } - return $ciphertext; + return !defined('OPENSSL_RAW_DATA') ? substr($result, 0, -$this->block_size) : $result; case CRYPT_MODE_CTR: return $this->_openssl_ctr_process($plaintext, $this->encryptIV, $this->enbuffer); case CRYPT_MODE_CFB: @@ -726,7 +737,7 @@ class Crypt_Base $overflow = $len % $this->block_size; if ($overflow) { - $ciphertext.= openssl_encrypt(substr($plaintext, 0, -$overflow) . str_repeat("\0", $this->block_size), $this->cipher_name_openssl, $this->key, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING, $iv); + $ciphertext.= openssl_encrypt(substr($plaintext, 0, -$overflow) . str_repeat("\0", $this->block_size), $this->cipher_name_openssl, $this->key, $this->openssl_options, $iv); $iv = $this->_string_pop($ciphertext, $this->block_size); $size = $len - $overflow; @@ -735,7 +746,7 @@ class Crypt_Base $ciphertext.= $block; $pos = $overflow; } else if ($len) { - $ciphertext = openssl_encrypt($plaintext, $this->cipher_name_openssl, $this->key, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING, $iv); + $ciphertext = openssl_encrypt($plaintext, $this->cipher_name_openssl, $this->key, $this->openssl_options, $iv); $iv = substr($ciphertext, -$this->block_size); } @@ -980,10 +991,10 @@ class Crypt_Base switch ($this->mode) { case CRYPT_MODE_STREAM: case CRYPT_MODE_ECB: - $plaintext = openssl_decrypt($ciphertext, $this->cipher_name_openssl, $this->key, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING); + $plaintext = openssl_decrypt($ciphertext, $this->cipher_name_openssl, $this->key, $this->openssl_options); break; case CRYPT_MODE_CBC: - $plaintext = openssl_decrypt($ciphertext, $this->cipher_name_openssl, $this->key, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING, $this->decryptIV); + $plaintext = openssl_decrypt($ciphertext, $this->cipher_name_openssl, $this->key, $this->openssl_options, $this->decryptIV); if ($this->continuousBuffer) { $this->decryptIV = substr($ciphertext, -$this->block_size); } @@ -1022,16 +1033,16 @@ class Crypt_Base } $overflow = $len % $this->block_size; if ($overflow) { - $plaintext.= openssl_decrypt(substr($ciphertext, 0, -$overflow), $this->cipher_name_openssl, $this->key, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING, $iv); + $plaintext.= openssl_decrypt(substr($ciphertext, 0, -$overflow), $this->cipher_name_openssl, $this->key, $this->openssl_options, $iv); if ($len - $overflow) { $iv = substr($ciphertext, -$overflow - $this->block_size, -$overflow); } - $iv = openssl_encrypt(str_repeat("\0", $this->block_size), $this->cipher_name_openssl, $this->key, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING, $iv); + $iv = openssl_encrypt(str_repeat("\0", $this->block_size), $this->cipher_name_openssl, $this->key, $this->openssl_options, $iv); $plaintext.= $iv ^ substr($ciphertext, -$overflow); $iv = substr_replace($iv, substr($ciphertext, -$overflow), 0, $overflow); $pos = $overflow; } else if ($len) { - $plaintext.= openssl_decrypt($ciphertext, $this->cipher_name_openssl, $this->key, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING, $iv); + $plaintext.= openssl_decrypt($ciphertext, $this->cipher_name_openssl, $this->key, $this->openssl_options, $iv); $iv = substr($ciphertext, -$this->block_size); } break; @@ -1266,7 +1277,9 @@ class Crypt_Base for ($i = 0; $i < strlen($plaintext); $i+=$block_size) { $block = substr($plaintext, $i, $block_size); if (strlen($block) > strlen($buffer['encrypted'])) { - $buffer['encrypted'].= openssl_encrypt($xor, $this->cipher_name_openssl_ecb, $key, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING); + $result = openssl_encrypt($xor, $this->cipher_name_openssl_ecb, $key, $this->openssl_options); + $result = !defined('OPENSSL_RAW_DATA') ? substr($result, 0, -$this->block_size) : $result; + $buffer['encrypted'].= $result; } $this->_increment_str($xor); $otp = $this->_string_shift($buffer['encrypted'], $block_size); @@ -1275,7 +1288,8 @@ class Crypt_Base } else { for ($i = 0; $i < strlen($plaintext); $i+=$block_size) { $block = substr($plaintext, $i, $block_size); - $otp = openssl_encrypt($xor, $this->cipher_name_openssl_ecb, $key, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING); + $otp = openssl_encrypt($xor, $this->cipher_name_openssl_ecb, $key, $this->openssl_options); + $otp = !defined('OPENSSL_RAW_DATA') ? substr($otp, 0, -$this->block_size) : $otp; $this->_increment_str($xor); $ciphertext.= $block ^ $otp; } @@ -1302,15 +1316,15 @@ class Crypt_Base $overflow = strlen($plaintext) % $block_size; if ($overflow) { $plaintext2 = $this->_string_pop($plaintext, $overflow); // ie. trim $plaintext to a multiple of $block_size and put rest of $plaintext in $plaintext2 - $encrypted = openssl_encrypt($plaintext . str_repeat("\0", $block_size), $this->cipher_name_openssl, $key, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING, $encryptIV); + $encrypted = openssl_encrypt($plaintext . str_repeat("\0", $block_size), $this->cipher_name_openssl, $key, $this->openssl_options, $encryptIV); $encryptIV = $this->_string_pop($encrypted, $block_size); $ciphertext.= $encrypted . ($plaintext2 ^ $encryptIV); $buffer['encrypted'] = substr($encryptIV, $overflow); } else if (!strlen($buffer['encrypted'])) { - $ciphertext.= openssl_encrypt($plaintext . str_repeat("\0", $block_size), $this->cipher_name_openssl, $key, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING, $encryptIV); + $ciphertext.= openssl_encrypt($plaintext . str_repeat("\0", $block_size), $this->cipher_name_openssl, $key, $this->openssl_options, $encryptIV); $encryptIV = $this->_string_pop($ciphertext, $block_size); } - $encryptIV = openssl_decrypt($encryptIV, $this->cipher_name_openssl_ecb, $key, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING); + $encryptIV = openssl_decrypt($encryptIV, $this->cipher_name_openssl_ecb, $key, $this->openssl_options); if ($overflow) { $this->_increment_str($encryptIV); } @@ -1351,7 +1365,7 @@ class Crypt_Base if (strlen($plaintext)) { if ($overflow) { - $ciphertext.= openssl_encrypt(substr($plaintext, 0, -$overflow) . str_repeat("\0", $block_size), $this->cipher_name_openssl, $key, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING, $encryptIV); + $ciphertext.= openssl_encrypt(substr($plaintext, 0, -$overflow) . str_repeat("\0", $block_size), $this->cipher_name_openssl, $key, $this->openssl_options, $encryptIV); $xor = $this->_string_pop($ciphertext, $block_size); if ($this->continuousBuffer) { $encryptIV = $xor; @@ -1361,7 +1375,7 @@ class Crypt_Base $buffer['xor'] = $xor; } } else { - $ciphertext = openssl_encrypt($plaintext, $this->cipher_name_openssl, $key, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING, $encryptIV); + $ciphertext = openssl_encrypt($plaintext, $this->cipher_name_openssl, $key, $this->openssl_options, $encryptIV); if ($this->continuousBuffer) { $encryptIV = substr($ciphertext, -$block_size) ^ substr($plaintext, -$block_size); } @@ -1514,6 +1528,15 @@ class Crypt_Base if (!$result) { return false; } + + // prior to PHP 5.4.0 OPENSSL_RAW_DATA and OPENSSL_ZERO_PADDING were not defined. instead of expecting an integer + // $options openssl_encrypt expected a boolean $raw_data. + if (!defined('OPENSSL_RAW_DATA')) { + $this->openssl_options = true; + } else { + $this->openssl_options = OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING; + } + $methods = openssl_get_cipher_methods(); if (in_array($this->cipher_name_openssl, $methods)) { return true; From 866b690248dc8ca964e7726d07dec6c088a06c43 Mon Sep 17 00:00:00 2001 From: terrafrost Date: Sat, 29 Nov 2014 09:52:14 -0600 Subject: [PATCH 09/79] Crypt: CS adjustments --- phpseclib/Crypt/Base.php | 6 +++--- phpseclib/Crypt/Rijndael.php | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/phpseclib/Crypt/Base.php b/phpseclib/Crypt/Base.php index d26a1747..cfc7789e 100644 --- a/phpseclib/Crypt/Base.php +++ b/phpseclib/Crypt/Base.php @@ -1322,7 +1322,7 @@ class Crypt_Base $buffer['encrypted'] = substr($encryptIV, $overflow); } else if (!strlen($buffer['encrypted'])) { $ciphertext.= openssl_encrypt($plaintext . str_repeat("\0", $block_size), $this->cipher_name_openssl, $key, $this->openssl_options, $encryptIV); - $encryptIV = $this->_string_pop($ciphertext, $block_size); + $encryptIV = $this->_string_pop($ciphertext, $block_size); } $encryptIV = openssl_decrypt($encryptIV, $this->cipher_name_openssl_ecb, $key, $this->openssl_options); if ($overflow) { @@ -1522,8 +1522,8 @@ class Crypt_Base switch ($engine) { case CRYPT_MODE_OPENSSL: $this->openssl_emulate_ctr = false; - $result = $this->cipher_name_openssl && - extension_loaded('openssl') && + $result = $this->cipher_name_openssl && + extension_loaded('openssl') && version_compare(PHP_VERSION, '5.3.0'); if (!$result) { return false; diff --git a/phpseclib/Crypt/Rijndael.php b/phpseclib/Crypt/Rijndael.php index 18444e6c..ae34d615 100644 --- a/phpseclib/Crypt/Rijndael.php +++ b/phpseclib/Crypt/Rijndael.php @@ -957,7 +957,7 @@ class Crypt_Rijndael extends Crypt_Base // (Currently, for Crypt_Rijndael/AES, one generated $lambda_function cost on php5.5@32bit ~80kb unfreeable mem and ~130kb on php5.5@64bit) // After that, we'll still create very fast optimized code but not the hi-ultimative code, for each $mode one. $gen_hi_opt_code = (bool)( count($lambda_functions) < 10 ); - + // Generation of a uniqe hash for our generated code $code_hash = "Crypt_Rijndael, {$this->mode}, {$this->Nr}, {$this->Nb}"; if ($gen_hi_opt_code) { From 6c09d6f5652c9ee839de08bab3c309ce51750612 Mon Sep 17 00:00:00 2001 From: terrafrost Date: Sat, 29 Nov 2014 16:18:17 -0600 Subject: [PATCH 10/79] Crypt_Base: fix E_NOTICEs --- phpseclib/Crypt/Base.php | 35 ++++++++++++++++++----------------- 1 file changed, 18 insertions(+), 17 deletions(-) diff --git a/phpseclib/Crypt/Base.php b/phpseclib/Crypt/Base.php index cfc7789e..ec6ad079 100644 --- a/phpseclib/Crypt/Base.php +++ b/phpseclib/Crypt/Base.php @@ -697,7 +697,7 @@ class Crypt_Base $result = openssl_encrypt($plaintext, $this->cipher_name_openssl, $this->key, $this->openssl_options); return !defined('OPENSSL_RAW_DATA') ? substr($result, 0, -$this->block_size) : $result; case CRYPT_MODE_CBC: - $ciphertext = openssl_encrypt($plaintext, $this->cipher_name_openssl, $this->key, $this->openssl_options, $this->encryptIV); + $result = openssl_encrypt($plaintext, $this->cipher_name_openssl, $this->key, $this->openssl_options, $this->encryptIV); if ($this->continuousBuffer) { $this->encryptIV = substr($ciphertext, -$this->block_size); } @@ -707,6 +707,7 @@ class Crypt_Base case CRYPT_MODE_CFB: // cfb loosely routines inspired by openssl's: // {@link http://cvs.openssl.org/fileview?f=openssl/crypto/modes/cfb128.c&v=1.3.2.2.2.1} + $ciphertext = ''; if ($this->continuousBuffer) { $iv = &$this->encryptIV; $pos = &$this->enbuffer['pos']; @@ -863,14 +864,14 @@ class Crypt_Base break; case CRYPT_MODE_CTR: $xor = $this->encryptIV; - if (strlen($buffer['encrypted'])) { + if (strlen($buffer['ciphertext'])) { for ($i = 0; $i < strlen($plaintext); $i+=$block_size) { $block = substr($plaintext, $i, $block_size); - if (strlen($block) > strlen($buffer['encrypted'])) { - $buffer['encrypted'].= $this->_encryptBlock($xor); + if (strlen($block) > strlen($buffer['ciphertext'])) { + $buffer['ciphertext'].= $this->_encryptBlock($xor); } $this->_increment_str($xor); - $key = $this->_string_shift($buffer['encrypted'], $block_size); + $key = $this->_string_shift($buffer['ciphertext'], $block_size); $ciphertext.= $block ^ $key; } } else { @@ -884,7 +885,7 @@ class Crypt_Base if ($this->continuousBuffer) { $this->encryptIV = $xor; if ($start = strlen($plaintext) % $block_size) { - $buffer['encrypted'] = substr($key, $start) . $buffer['encrypted']; + $buffer['ciphertext'] = substr($key, $start) . $buffer['ciphertext']; } } break; @@ -1005,6 +1006,7 @@ class Crypt_Base case CRYPT_MODE_CFB: // cfb loosely routines inspired by openssl's: // {@link http://cvs.openssl.org/fileview?f=openssl/crypto/modes/cfb128.c&v=1.3.2.2.2.1} + $plaintext = ''; if ($this->continuousBuffer) { $iv = &$this->decryptIV; $pos = &$this->buffer['pos']; @@ -1273,16 +1275,16 @@ class Crypt_Base if ($this->openssl_emulate_ctr) { $xor = $encryptIV; - if (strlen($buffer['encrypted'])) { + if (strlen($buffer['ciphertext'])) { for ($i = 0; $i < strlen($plaintext); $i+=$block_size) { $block = substr($plaintext, $i, $block_size); - if (strlen($block) > strlen($buffer['encrypted'])) { + if (strlen($block) > strlen($buffer['ciphertext'])) { $result = openssl_encrypt($xor, $this->cipher_name_openssl_ecb, $key, $this->openssl_options); $result = !defined('OPENSSL_RAW_DATA') ? substr($result, 0, -$this->block_size) : $result; - $buffer['encrypted'].= $result; + $buffer['ciphertext'].= $result; } $this->_increment_str($xor); - $otp = $this->_string_shift($buffer['encrypted'], $block_size); + $otp = $this->_string_shift($buffer['ciphertext'], $block_size); $ciphertext.= $block ^ $otp; } } else { @@ -1297,15 +1299,15 @@ class Crypt_Base if ($this->continuousBuffer) { $encryptIV = $xor; if ($start = strlen($plaintext) % $block_size) { - $buffer['encrypted'] = substr($key, $start) . $buffer['encrypted']; + $buffer['ciphertext'] = substr($key, $start) . $buffer['ciphertext']; } } return $ciphertext; } - if (strlen($buffer['encrypted'])) { - $ciphertext = $plaintext ^ $this->_string_shift($buffer['encrypted'], strlen($plaintext)); + if (strlen($buffer['ciphertext'])) { + $ciphertext = $plaintext ^ $this->_string_shift($buffer['ciphertext'], strlen($plaintext)); $plaintext = substr($plaintext, strlen($ciphertext)); if (!strlen($plaintext)) { @@ -1319,8 +1321,8 @@ class Crypt_Base $encrypted = openssl_encrypt($plaintext . str_repeat("\0", $block_size), $this->cipher_name_openssl, $key, $this->openssl_options, $encryptIV); $encryptIV = $this->_string_pop($encrypted, $block_size); $ciphertext.= $encrypted . ($plaintext2 ^ $encryptIV); - $buffer['encrypted'] = substr($encryptIV, $overflow); - } else if (!strlen($buffer['encrypted'])) { + $buffer['ciphertext'] = substr($encryptIV, $overflow); + } else if (!strlen($buffer['ciphertext'])) { $ciphertext.= openssl_encrypt($plaintext . str_repeat("\0", $block_size), $this->cipher_name_openssl, $key, $this->openssl_options, $encryptIV); $encryptIV = $this->_string_pop($ciphertext, $block_size); } @@ -1842,8 +1844,7 @@ class Crypt_Base */ function _clearBuffers() { - $this->enbuffer = array('encrypted' => '', 'xor' => '', 'pos' => 0, 'enmcrypt_init' => true); - $this->debuffer = array('ciphertext' => '', 'xor' => '', 'pos' => 0, 'demcrypt_init' => true); + $this->enbuffer = $this->debuffer = array('ciphertext' => '', 'xor' => '', 'pos' => 0, 'enmcrypt_init' => true); // mcrypt's handling of invalid's $iv: // $this->encryptIV = $this->decryptIV = strlen($this->iv) == $this->block_size ? $this->iv : str_repeat("\0", $this->block_size); From 129dc320b0618d55eca2936287c635da2f4c8079 Mon Sep 17 00:00:00 2001 From: terrafrost Date: Sat, 29 Nov 2014 22:26:42 -0600 Subject: [PATCH 11/79] Crypt_Base: fix the rest of the E_NOTICEs --- phpseclib/Crypt/Base.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/phpseclib/Crypt/Base.php b/phpseclib/Crypt/Base.php index ec6ad079..ee21273b 100644 --- a/phpseclib/Crypt/Base.php +++ b/phpseclib/Crypt/Base.php @@ -2154,16 +2154,16 @@ class Crypt_Base $_plaintext_len = strlen($_text); $_xor = $self->encryptIV; $_buffer = &$self->enbuffer; - if (strlen($_buffer["encrypted"])) { + if (strlen($_buffer["ciphertext"])) { for ($_i = 0; $_i < $_plaintext_len; $_i+= '.$block_size.') { $_block = substr($_text, $_i, '.$block_size.'); - if (strlen($_block) > strlen($_buffer["encrypted"])) { + if (strlen($_block) > strlen($_buffer["ciphertext"])) { $in = $_xor; '.$encrypt_block.' $self->_increment_str($_xor); - $_buffer["encrypted"].= $in; + $_buffer["ciphertext"].= $in; } - $_key = $self->_string_shift($_buffer["encrypted"], '.$block_size.'); + $_key = $self->_string_shift($_buffer["ciphertext"], '.$block_size.'); $_ciphertext.= $_block ^ $_key; } } else { @@ -2179,7 +2179,7 @@ class Crypt_Base if ($self->continuousBuffer) { $self->encryptIV = $_xor; if ($_start = $_plaintext_len % '.$block_size.') { - $_buffer["encrypted"] = substr($_key, $_start) . $_buffer["encrypted"]; + $_buffer["ciphertext"] = substr($_key, $_start) . $_buffer["ciphertext"]; } } From b35cedcb156a0ee0131d526931de01fc824bb411 Mon Sep 17 00:00:00 2001 From: terrafrost Date: Sat, 6 Dec 2014 23:36:26 -0600 Subject: [PATCH 12/79] Crypt_Base: deal with IV's more appropriately --- phpseclib/Crypt/Base.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/phpseclib/Crypt/Base.php b/phpseclib/Crypt/Base.php index ee21273b..e6f57187 100644 --- a/phpseclib/Crypt/Base.php +++ b/phpseclib/Crypt/Base.php @@ -1326,6 +1326,9 @@ class Crypt_Base $ciphertext.= openssl_encrypt($plaintext . str_repeat("\0", $block_size), $this->cipher_name_openssl, $key, $this->openssl_options, $encryptIV); $encryptIV = $this->_string_pop($ciphertext, $block_size); } + if (!defined('OPENSSL_RAW_DATA')) { + $encryptIV.= openssl_encrypt(str_repeat(chr($this->block_size), $this->block_size), $this->cipher_name_openssl_ecb, $key, $this->openssl_options); + } $encryptIV = openssl_decrypt($encryptIV, $this->cipher_name_openssl_ecb, $key, $this->openssl_options); if ($overflow) { $this->_increment_str($encryptIV); From 69614034ec225433416edd5a8884035885a78649 Mon Sep 17 00:00:00 2001 From: terrafrost Date: Sun, 7 Dec 2014 07:35:30 -0600 Subject: [PATCH 13/79] Crypt_Base: fix to the IV handling of the last commit --- phpseclib/Crypt/Base.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/phpseclib/Crypt/Base.php b/phpseclib/Crypt/Base.php index e6f57187..693c74f9 100644 --- a/phpseclib/Crypt/Base.php +++ b/phpseclib/Crypt/Base.php @@ -1327,7 +1327,7 @@ class Crypt_Base $encryptIV = $this->_string_pop($ciphertext, $block_size); } if (!defined('OPENSSL_RAW_DATA')) { - $encryptIV.= openssl_encrypt(str_repeat(chr($this->block_size), $this->block_size), $this->cipher_name_openssl_ecb, $key, $this->openssl_options); + $encryptIV.= openssl_encrypt('', $this->cipher_name_openssl_ecb, $key, $this->openssl_options); } $encryptIV = openssl_decrypt($encryptIV, $this->cipher_name_openssl_ecb, $key, $this->openssl_options); if ($overflow) { From 9a55ab18921c9666d7678d493a676492be354f64 Mon Sep 17 00:00:00 2001 From: terrafrost Date: Sun, 7 Dec 2014 14:43:30 -0600 Subject: [PATCH 14/79] Blowfish: syntax error --- phpseclib/Crypt/Blowfish.php | 1 + 1 file changed, 1 insertion(+) diff --git a/phpseclib/Crypt/Blowfish.php b/phpseclib/Crypt/Blowfish.php index 7dfa419b..9b41cca3 100644 --- a/phpseclib/Crypt/Blowfish.php +++ b/phpseclib/Crypt/Blowfish.php @@ -370,6 +370,7 @@ class Crypt_Blowfish extends Crypt_Base * @param String $key */ function setKey($key) + { $keylength = strlen($key); if (!$keylength) { From 4d6e7efda642b4d4788916b76b14927810956beb Mon Sep 17 00:00:00 2001 From: terrafrost Date: Sat, 13 Dec 2014 13:47:37 -0600 Subject: [PATCH 15/79] Tests: CS adjustments --- tests/Unit/Crypt/AES/TestCase.php | 22 +++++++++++----------- tests/Unit/Crypt/DES.php | 2 +- tests/Unit/Crypt/RC2.php | 4 ++-- 3 files changed, 14 insertions(+), 14 deletions(-) diff --git a/tests/Unit/Crypt/AES/TestCase.php b/tests/Unit/Crypt/AES/TestCase.php index 6e7f8d65..3c1a923b 100644 --- a/tests/Unit/Crypt/AES/TestCase.php +++ b/tests/Unit/Crypt/AES/TestCase.php @@ -11,7 +11,7 @@ abstract class Unit_Crypt_AES_TestCase extends PhpseclibTestCase { protected $engine; - private function checkEngine($aes) + private function _checkEngine($aes) { if ($aes->getEngine() != $this->engine) { $engine = 'internal'; @@ -78,7 +78,7 @@ abstract class Unit_Crypt_AES_TestCase extends PhpseclibTestCase $aes->setIV($iv); $aes->setKey($key); - $this->checkEngine($aes); + $this->_checkEngine($aes); $actual = ''; for ($i = 0, $strlen = strlen($plaintext); $i < $strlen; ++$i) { @@ -100,7 +100,7 @@ abstract class Unit_Crypt_AES_TestCase extends PhpseclibTestCase $aes->setPreferredEngine($this->engine); $aes->disablePadding(); $aes->setKey(pack('H*', '2b7e151628aed2a6abf7158809cf4f3c762e7160')); // 160-bit key. Valid in Rijndael. - //$this->checkEngine($aes); // should only work in internal mode + //$this->_checkEngine($aes); // should only work in internal mode $ciphertext = $aes->encrypt(pack('H*', '3243f6a8885a308d313198a2e0370734')); $this->assertEquals($ciphertext, pack('H*', '231d844639b31b412211cfe93712b880')); } @@ -116,7 +116,7 @@ abstract class Unit_Crypt_AES_TestCase extends PhpseclibTestCase $aes->setPreferredEngine($this->engine); $aes->disablePadding(); $aes->setKey(pack('H*', '2b7e151628aed2a6abf7158809cf4f3c762e7160')); // 160-bit key. AES should null pad to 192-bits - $this->checkEngine($aes); + $this->_checkEngine($aes); $ciphertext = $aes->encrypt(pack('H*', '3243f6a8885a308d313198a2e0370734')); $this->assertEquals($ciphertext, pack('H*', 'c109292b173f841b88e0ee49f13db8c0')); } @@ -135,10 +135,10 @@ abstract class Unit_Crypt_AES_TestCase extends PhpseclibTestCase ); $combos = array( - array(16), - array(17), - array(1, 16), - array(3, 6, 7), // (3 to test the openssl_encrypt call and the buffer creation, 6 to test the exclusive use of the buffer and 7 to test the buffer's exhaustion and recreation) + array(16), + array(17), + array(1, 16), + array(3, 6, 7), // (3 to test the openssl_encrypt call and the buffer creation, 6 to test the exclusive use of the buffer and 7 to test the buffer's exhaustion and recreation) array(15, 4), // (15 to test openssl_encrypt call and buffer creation and 4 to test something that spans multpile bloc array(3, 6, 10, 16), // this is why the strlen check in the buffer-only code was needed array(16, 16), // two full size blocks @@ -176,7 +176,7 @@ abstract class Unit_Crypt_AES_TestCase extends PhpseclibTestCase $aes->setKey($key); $aes->setIV($iv); - $this->checkEngine($aes); + $this->_checkEngine($aes); $str = ''; $result = ''; @@ -193,7 +193,7 @@ abstract class Unit_Crypt_AES_TestCase extends PhpseclibTestCase $aes->setKey($key); $aes->setIV($iv); - $this->checkEngine($aes); + $this->_checkEngine($aes); foreach ($test as $len) { $temp = str_repeat('d', $len); @@ -205,4 +205,4 @@ abstract class Unit_Crypt_AES_TestCase extends PhpseclibTestCase $this->assertSame(bin2hex($c1), bin2hex($c2)); } -} \ No newline at end of file +} diff --git a/tests/Unit/Crypt/DES.php b/tests/Unit/Crypt/DES.php index 3b6d5a4b..4d9e0aad 100644 --- a/tests/Unit/Crypt/DES.php +++ b/tests/Unit/Crypt/DES.php @@ -66,4 +66,4 @@ class Unit_Crypt_DES_TestCase extends PhpseclibTestCase self::markTestSkipped('Unable to initialize OpenSSL engine'); } } -} \ No newline at end of file +} diff --git a/tests/Unit/Crypt/RC2.php b/tests/Unit/Crypt/RC2.php index 545df9b5..7d61c33d 100644 --- a/tests/Unit/Crypt/RC2.php +++ b/tests/Unit/Crypt/RC2.php @@ -21,7 +21,7 @@ class Unit_Crypt_RC2_TestCase extends PhpseclibTestCase // admittedly, phpseclib is inconsistent in this regard. RC4 and Blowfish support arbitrary key lengths between a certain range, as well, // and they don't have any way to set the key length. but then again, neither do those algorithms have their own key expansion algorithm, // whereas RC2 does. and technically, AES / Rijndael (and even Twofish) don't support arbitrary key lengths - they support variable key - // lengths. so in some ways, i suppose this inconsistency somewhat makes sense, although the fact that Crypt_Twofish doesn't have a + // lengths. so in some ways, i suppose this inconsistency somewhat makes sense, although the fact that Crypt_Twofish doesn't have a // setKeyLength() function whereas Crypt_AES / Crypt_Rijndael do not is, itself, an inconsistency. // but that said, Crypt_RC2 is inconsistent in other ways: if you pass a 128-bit (16-byte) key to it via setKey() the key is not treated @@ -68,4 +68,4 @@ class Unit_Crypt_RC2_TestCase extends PhpseclibTestCase self::markTestSkipped('Unable to initialize OpenSSL engine'); } } -} \ No newline at end of file +} From f5f9c3d409cd388bf0e0014f8ffccf638f58be2d Mon Sep 17 00:00:00 2001 From: terrafrost Date: Sat, 13 Dec 2014 13:58:41 -0600 Subject: [PATCH 16/79] Crypt: replace CRYPT_MODE_INTERNAL/MCRYPT/OPENSSL with CRYPT_ENGINE_* --- phpseclib/Crypt/AES.php | 14 ------- phpseclib/Crypt/Base.php | 72 +++++++++++++++++------------------ phpseclib/Crypt/Blowfish.php | 2 +- phpseclib/Crypt/DES.php | 2 +- phpseclib/Crypt/RC2.php | 8 ++-- phpseclib/Crypt/RC4.php | 6 +-- phpseclib/Crypt/Rijndael.php | 6 +-- phpseclib/Crypt/TripleDES.php | 2 +- 8 files changed, 49 insertions(+), 63 deletions(-) diff --git a/phpseclib/Crypt/AES.php b/phpseclib/Crypt/AES.php index 36364398..3a3a49f5 100644 --- a/phpseclib/Crypt/AES.php +++ b/phpseclib/Crypt/AES.php @@ -111,20 +111,6 @@ define('CRYPT_AES_MODE_CFB', CRYPT_MODE_CFB); define('CRYPT_AES_MODE_OFB', CRYPT_MODE_OFB); /**#@-*/ -/**#@+ - * @access private - * @see Crypt_Base::Crypt_Base() - */ -/** - * Toggles the internal implementation - */ -define('CRYPT_AES_MODE_INTERNAL', CRYPT_MODE_INTERNAL); -/** - * Toggles the mcrypt implementation - */ -define('CRYPT_AES_MODE_MCRYPT', CRYPT_MODE_MCRYPT); -/**#@-*/ - /** * Pure-PHP implementation of AES. * diff --git a/phpseclib/Crypt/Base.php b/phpseclib/Crypt/Base.php index 693c74f9..952ba070 100644 --- a/phpseclib/Crypt/Base.php +++ b/phpseclib/Crypt/Base.php @@ -105,15 +105,15 @@ define('CRYPT_MODE_STREAM', 5); /** * Base value for the internal implementation $engine switch */ -define('CRYPT_MODE_INTERNAL', 1); +define('CRYPT_ENGINE_INTERNAL', 1); /** * Base value for the mcrypt implementation $engine switch */ -define('CRYPT_MODE_MCRYPT', 2); +define('CRYPT_ENGINE_MCRYPT', 2); /** * Base value for the OpenSSL implementation $engine switch */ -define('CRYPT_MODE_OPENSSL', 3); +define('CRYPT_ENGINE_OPENSSL', 3); /**#@-*/ /** @@ -278,7 +278,7 @@ class Crypt_Base * Optimizing value while CFB-encrypting * * Only relevant if $continuousBuffer enabled - * and $engine == CRYPT_MODE_MCRYPT + * and $engine == CRYPT_ENGINE_MCRYPT * * It's faster to re-init $enmcrypt if * $buffer bytes > $cfb_init_len than @@ -330,9 +330,9 @@ class Crypt_Base * which will be determined automatically on __construct() * * Currently available $engines are: - * - CRYPT_MODE_OPENSSL (very fast, php-extension: openssl, extension_loaded('openssl') required) - * - CRYPT_MODE_MCRYPT (fast, php-extension: mcrypt, extension_loaded('mcrypt') required) - * - CRYPT_MODE_INTERNAL (slower, pure php-engine, no php-extension required) + * - CRYPT_ENGINE_OPENSSL (very fast, php-extension: openssl, extension_loaded('openssl') required) + * - CRYPT_ENGINE_MCRYPT (fast, php-extension: mcrypt, extension_loaded('mcrypt') required) + * - CRYPT_ENGINE_INTERNAL (slower, pure php-engine, no php-extension required) * * @see Crypt_Base::_setEngine() * @see Crypt_Base::encrypt() @@ -355,7 +355,7 @@ class Crypt_Base /** * The mcrypt specific name of the cipher * - * Only used if $engine == CRYPT_MODE_MCRYPT + * Only used if $engine == CRYPT_ENGINE_MCRYPT * * @link http://www.php.net/mcrypt_module_open * @link http://www.php.net/mcrypt_list_algorithms @@ -368,7 +368,7 @@ class Crypt_Base /** * The openssl specific name of the cipher * - * Only used if $engine == CRYPT_MODE_OPENSSL + * Only used if $engine == CRYPT_ENGINE_OPENSSL * * @link http://www.php.net/openssl-get-cipher-methods * @var String @@ -433,7 +433,7 @@ class Crypt_Base * The name of the performance-optimized callback function * * Used by encrypt() / decrypt() - * only if $engine == CRYPT_MODE_INTERNAL + * only if $engine == CRYPT_ENGINE_INTERNAL * * @see Crypt_Base::encrypt() * @see Crypt_Base::decrypt() @@ -685,7 +685,7 @@ class Crypt_Base $plaintext = $this->_pad($plaintext); } - if ($this->engine === CRYPT_MODE_OPENSSL) { + if ($this->engine === CRYPT_ENGINE_OPENSSL) { if ($this->changed) { $this->_clearBuffers(); $this->changed = false; @@ -757,7 +757,7 @@ class Crypt_Base } } - if ($this->engine === CRYPT_MODE_MCRYPT) { + if ($this->engine === CRYPT_ENGINE_MCRYPT) { if ($this->changed) { $this->_setupMcrypt(); $this->changed = false; @@ -984,7 +984,7 @@ class Crypt_Base $ciphertext = str_pad($ciphertext, strlen($ciphertext) + ($this->block_size - strlen($ciphertext) % $this->block_size) % $this->block_size, chr(0)); } - if ($this->engine === CRYPT_MODE_OPENSSL) { + if ($this->engine === CRYPT_ENGINE_OPENSSL) { if ($this->changed) { $this->_clearBuffers(); $this->changed = false; @@ -1055,7 +1055,7 @@ class Crypt_Base return $this->paddable ? $this->_unpad($plaintext) : $plaintext; } - if ($this->engine === CRYPT_MODE_MCRYPT) { + if ($this->engine === CRYPT_ENGINE_MCRYPT) { $block_size = $this->block_size; if ($this->changed) { $this->_setupMcrypt(); @@ -1525,7 +1525,7 @@ class Crypt_Base function isValidEngine($engine) { switch ($engine) { - case CRYPT_MODE_OPENSSL: + case CRYPT_ENGINE_OPENSSL: $this->openssl_emulate_ctr = false; $result = $this->cipher_name_openssl && extension_loaded('openssl') && @@ -1556,11 +1556,11 @@ class Crypt_Base } } return false; - case CRYPT_MODE_MCRYPT: + case CRYPT_ENGINE_MCRYPT: return $this->cipher_name_mcrypt && extension_loaded('mcrypt') && in_array($this->cipher_name_mcrypt, mcrypt_list_algorithms()); - case CRYPT_MODE_INTERNAL: + case CRYPT_ENGINE_INTERNAL: return true; } } @@ -1570,11 +1570,11 @@ class Crypt_Base * * Currently, $engine could be: * - * - CRYPT_MODE_OPENSSL [very fast] + * - CRYPT_ENGINE_OPENSSL [very fast] * - * - CRYPT_MODE_MCRYPT [fast] + * - CRYPT_ENGINE_MCRYPT [fast] * - * - CRYPT_MODE_INTERNAL [slow] + * - CRYPT_ENGINE_INTERNAL [slow] * * If the preferred crypt engine is not available the fastest available one will be used * @@ -1585,13 +1585,13 @@ class Crypt_Base function setPreferredEngine($engine) { switch ($engine) { - //case CRYPT_MODE_OPENSSL: - case CRYPT_MODE_MCRYPT: - case CRYPT_MODE_INTERNAL: + //case CRYPT_ENGINE_OPENSSL: + case CRYPT_ENGINE_MCRYPT: + case CRYPT_ENGINE_INTERNAL: $this->preferredEngine = $engine; break; default: - $this->preferredEngine = CRYPT_MODE_OPENSSL; + $this->preferredEngine = CRYPT_ENGINE_OPENSSL; } $this->_setEngine(); @@ -1620,17 +1620,17 @@ class Crypt_Base case $this->isValidEngine($this->preferredEngine): $this->engine = $this->preferredEngine; break; - case $this->isValidEngine(CRYPT_MODE_OPENSSL): - $this->engine = CRYPT_MODE_OPENSSL; + case $this->isValidEngine(CRYPT_ENGINE_OPENSSL): + $this->engine = CRYPT_ENGINE_OPENSSL; break; - case $this->isValidEngine(CRYPT_MODE_MCRYPT): - $this->engine = CRYPT_MODE_MCRYPT; + case $this->isValidEngine(CRYPT_ENGINE_MCRYPT): + $this->engine = CRYPT_ENGINE_MCRYPT; break; default: - $this->engine = CRYPT_MODE_INTERNAL; + $this->engine = CRYPT_ENGINE_INTERNAL; } - if ($this->engine != CRYPT_MODE_MCRYPT && $this->enmcrypt) { + if ($this->engine != CRYPT_ENGINE_MCRYPT && $this->enmcrypt) { // Closing the current mcrypt resource(s). _mcryptSetup() will, if needed, // (re)open them with the module named in $this->cipher_name_mcrypt mcrypt_module_close($this->enmcrypt); @@ -1676,7 +1676,7 @@ class Crypt_Base /** * Setup the key (expansion) * - * Only used if $engine == CRYPT_MODE_INTERNAL + * Only used if $engine == CRYPT_ENGINE_INTERNAL * * @see Crypt_Base::_setup() * @access private @@ -1688,10 +1688,10 @@ class Crypt_Base } /** - * Setup the CRYPT_MODE_INTERNAL $engine + * Setup the CRYPT_ENGINE_INTERNAL $engine * * (re)init, if necessary, the internal cipher $engine and flush all $buffers - * Used (only) if $engine == CRYPT_MODE_INTERNAL + * Used (only) if $engine == CRYPT_ENGINE_INTERNAL * * _setup() will be called each time if $changed === true * typically this happens when using one or more of following public methods: @@ -1722,10 +1722,10 @@ class Crypt_Base } /** - * Setup the CRYPT_MODE_MCRYPT $engine + * Setup the CRYPT_ENGINE_MCRYPT $engine * * (re)init, if necessary, the (ext)mcrypt resources and flush all $buffers - * Used (only) if $engine = CRYPT_MODE_MCRYPT + * Used (only) if $engine = CRYPT_ENGINE_MCRYPT * * _setupMcrypt() will be called each time if $changed === true * typically this happens when using one or more of following public methods: @@ -1935,7 +1935,7 @@ class Crypt_Base * * _setupInlineCrypt() would be called only if: * - * - $engine == CRYPT_MODE_INTERNAL and + * - $engine == CRYPT_ENGINE_INTERNAL and * * - $use_inline_crypt === true * diff --git a/phpseclib/Crypt/Blowfish.php b/phpseclib/Crypt/Blowfish.php index 9b41cca3..a8788470 100644 --- a/phpseclib/Crypt/Blowfish.php +++ b/phpseclib/Crypt/Blowfish.php @@ -394,7 +394,7 @@ class Crypt_Blowfish extends Crypt_Base */ function isValidEngine($engine) { - if ($engine == CRYPT_MODE_OPENSSL) { + if ($engine == CRYPT_ENGINE_OPENSSL) { if (strlen($this->key) != 16) { return false; } diff --git a/phpseclib/Crypt/DES.php b/phpseclib/Crypt/DES.php index 395f9d30..792a3350 100644 --- a/phpseclib/Crypt/DES.php +++ b/phpseclib/Crypt/DES.php @@ -675,7 +675,7 @@ class Crypt_DES extends Crypt_Base */ function isValidEngine($engine) { - if ($engine == CRYPT_MODE_OPENSSL) { + if ($engine == CRYPT_ENGINE_OPENSSL) { $this->cipher_name_openssl_ecb = 'des-ecb'; $this->cipher_name_openssl = 'des-' . $this->_openssl_translate_mode(); } diff --git a/phpseclib/Crypt/RC2.php b/phpseclib/Crypt/RC2.php index f6857c7e..8fe34b68 100644 --- a/phpseclib/Crypt/RC2.php +++ b/phpseclib/Crypt/RC2.php @@ -366,7 +366,7 @@ class Crypt_RC2 extends Crypt_Base function isValidEngine($engine) { switch ($engine) { - case CRYPT_MODE_OPENSSL: + case CRYPT_ENGINE_OPENSSL: if ($this->current_key_length != 128 && strlen($this->orig_key) != 16) { return false; } @@ -464,7 +464,7 @@ class Crypt_RC2 extends Crypt_Base */ function encrypt($plaintext) { - if ($this->engine == CRYPT_MODE_OPENSSL) { + if ($this->engine == CRYPT_ENGINE_OPENSSL) { $temp = $this->key; $this->key = $this->orig_key; $result = parent::encrypt($plaintext); @@ -487,7 +487,7 @@ class Crypt_RC2 extends Crypt_Base */ function decrypt($ciphertext) { - if ($this->engine == CRYPT_MODE_OPENSSL) { + if ($this->engine == CRYPT_ENGINE_OPENSSL) { $temp = $this->key; $this->key = $this->orig_key; $result = parent::decrypt($ciphertext); @@ -589,7 +589,7 @@ class Crypt_RC2 extends Crypt_Base } /** - * Setup the CRYPT_MODE_MCRYPT $engine + * Setup the CRYPT_ENGINE_MCRYPT $engine * * @see Crypt_Base::_setupMcrypt() * @access private diff --git a/phpseclib/Crypt/RC4.php b/phpseclib/Crypt/RC4.php index 4c473a01..7d9e1f05 100644 --- a/phpseclib/Crypt/RC4.php +++ b/phpseclib/Crypt/RC4.php @@ -181,7 +181,7 @@ class Crypt_RC4 extends Crypt_Base function isValidEngine($engine) { switch ($engine) { - case CRYPT_MODE_OPENSSL: + case CRYPT_ENGINE_OPENSSL: switch (strlen($this->key)) { case 5: $this->cipher_name_openssl = 'rc4-40'; @@ -249,7 +249,7 @@ class Crypt_RC4 extends Crypt_Base */ function encrypt($plaintext) { - if ($this->engine == CRYPT_MODE_MCRYPT) { + if ($this->engine == CRYPT_ENGINE_MCRYPT) { return parent::encrypt($plaintext); } return $this->_crypt($plaintext, CRYPT_RC4_ENCRYPT); @@ -269,7 +269,7 @@ class Crypt_RC4 extends Crypt_Base */ function decrypt($ciphertext) { - if ($this->engine == CRYPT_MODE_MCRYPT) { + if ($this->engine == CRYPT_ENGINE_MCRYPT) { return parent::decrypt($ciphertext); } return $this->_crypt($ciphertext, CRYPT_RC4_DECRYPT); diff --git a/phpseclib/Crypt/Rijndael.php b/phpseclib/Crypt/Rijndael.php index ae34d615..be6b9a59 100644 --- a/phpseclib/Crypt/Rijndael.php +++ b/phpseclib/Crypt/Rijndael.php @@ -411,14 +411,14 @@ class Crypt_Rijndael extends Crypt_Base function isValidEngine($engine) { switch ($engine) { - case CRYPT_MODE_OPENSSL: + case CRYPT_ENGINE_OPENSSL: if ($this->block_size != 16) { return false; } $this->cipher_name_openssl_ecb = 'aes-' . ($this->key_size << 3) . '-ecb'; $this->cipher_name_openssl = 'aes-' . ($this->key_size << 3) . '-' . $this->_openssl_translate_mode(); break; - case CRYPT_MODE_MCRYPT: + case CRYPT_ENGINE_MCRYPT: $this->cipher_name_mcrypt = 'rijndael-' . ($this->block_size << 3); if ($this->key_size % 8) { // is it a 160/224-bit key? // mcrypt is not usable for them, only for 128/192/256-bit keys @@ -430,7 +430,7 @@ class Crypt_Rijndael extends Crypt_Base } /** - * Setup the CRYPT_MODE_MCRYPT $engine + * Setup the CRYPT_ENGINE_MCRYPT $engine * * @see Crypt_Base::_setupMcrypt() * @access private diff --git a/phpseclib/Crypt/TripleDES.php b/phpseclib/Crypt/TripleDES.php index c75000ac..5a3f23c2 100644 --- a/phpseclib/Crypt/TripleDES.php +++ b/phpseclib/Crypt/TripleDES.php @@ -230,7 +230,7 @@ class Crypt_TripleDES extends Crypt_DES */ function isValidEngine($engine) { - if ($engine == CRYPT_MODE_OPENSSL) { + if ($engine == CRYPT_ENGINE_OPENSSL) { $this->cipher_name_openssl_ecb = 'des-ede3'; $mode = $this->_openssl_translate_mode(); $this->cipher_name_openssl = $mode == 'ecb' ? 'des-ede3' : 'des-ede3-' . $mode; From 8d8c2693c529cbd78ddbb59f410bbd8065fa488a Mon Sep 17 00:00:00 2001 From: terrafrost Date: Sat, 13 Dec 2014 14:13:24 -0600 Subject: [PATCH 17/79] Crypt: rm @version stuff --- phpseclib/Crypt/AES.php | 1 - phpseclib/Crypt/Base.php | 1 - phpseclib/Crypt/Blowfish.php | 1 - phpseclib/Crypt/DES.php | 1 - phpseclib/Crypt/RC2.php | 1 - phpseclib/Crypt/RC4.php | 1 - phpseclib/Crypt/Rijndael.php | 1 - phpseclib/Crypt/TripleDES.php | 1 - phpseclib/Crypt/Twofish.php | 1 - 9 files changed, 9 deletions(-) diff --git a/phpseclib/Crypt/AES.php b/phpseclib/Crypt/AES.php index 3a3a49f5..ad66438c 100644 --- a/phpseclib/Crypt/AES.php +++ b/phpseclib/Crypt/AES.php @@ -116,7 +116,6 @@ define('CRYPT_AES_MODE_OFB', CRYPT_MODE_OFB); * * @package Crypt_AES * @author Jim Wigginton - * @version 0.1.1 * @access public */ class Crypt_AES extends Crypt_Rijndael diff --git a/phpseclib/Crypt/Base.php b/phpseclib/Crypt/Base.php index 952ba070..71b97d72 100644 --- a/phpseclib/Crypt/Base.php +++ b/phpseclib/Crypt/Base.php @@ -122,7 +122,6 @@ define('CRYPT_ENGINE_OPENSSL', 3); * @package Crypt_Base * @author Jim Wigginton * @author Hans-Juergen Petrich - * @version 1.0.2 * @access public */ class Crypt_Base diff --git a/phpseclib/Crypt/Blowfish.php b/phpseclib/Crypt/Blowfish.php index a8788470..49b2234f 100644 --- a/phpseclib/Crypt/Blowfish.php +++ b/phpseclib/Crypt/Blowfish.php @@ -107,7 +107,6 @@ define('CRYPT_BLOWFISH_MODE_OFB', CRYPT_MODE_OFB); * @package Crypt_Blowfish * @author Jim Wigginton * @author Hans-Juergen Petrich - * @version 1.0.1 * @access public */ class Crypt_Blowfish extends Crypt_Base diff --git a/phpseclib/Crypt/DES.php b/phpseclib/Crypt/DES.php index 792a3350..a2d72715 100644 --- a/phpseclib/Crypt/DES.php +++ b/phpseclib/Crypt/DES.php @@ -126,7 +126,6 @@ define('CRYPT_DES_MODE_OFB', CRYPT_MODE_OFB); * * @package Crypt_DES * @author Jim Wigginton - * @version 0.1.1 * @access public */ class Crypt_DES extends Crypt_Base diff --git a/phpseclib/Crypt/RC2.php b/phpseclib/Crypt/RC2.php index 8fe34b68..dc0c41d7 100644 --- a/phpseclib/Crypt/RC2.php +++ b/phpseclib/Crypt/RC2.php @@ -103,7 +103,6 @@ define('CRYPT_RC2_MODE_OFB', CRYPT_MODE_OFB); * Pure-PHP implementation of RC2. * * @package Crypt_RC2 - * @version 0.1.2 * @access public */ class Crypt_RC2 extends Crypt_Base diff --git a/phpseclib/Crypt/RC4.php b/phpseclib/Crypt/RC4.php index 7d9e1f05..2a271ec3 100644 --- a/phpseclib/Crypt/RC4.php +++ b/phpseclib/Crypt/RC4.php @@ -82,7 +82,6 @@ define('CRYPT_RC4_DECRYPT', 1); * * @package Crypt_RC4 * @author Jim Wigginton - * @version 0.1.1 * @access public */ class Crypt_RC4 extends Crypt_Base diff --git a/phpseclib/Crypt/Rijndael.php b/phpseclib/Crypt/Rijndael.php index be6b9a59..78cebb69 100644 --- a/phpseclib/Crypt/Rijndael.php +++ b/phpseclib/Crypt/Rijndael.php @@ -123,7 +123,6 @@ define('CRYPT_RIJNDAEL_MODE_OFB', CRYPT_MODE_OFB); * * @package Crypt_Rijndael * @author Jim Wigginton - * @version 0.1.1 * @access public */ class Crypt_Rijndael extends Crypt_Base diff --git a/phpseclib/Crypt/TripleDES.php b/phpseclib/Crypt/TripleDES.php index 5a3f23c2..2ea9baef 100644 --- a/phpseclib/Crypt/TripleDES.php +++ b/phpseclib/Crypt/TripleDES.php @@ -82,7 +82,6 @@ define('CRYPT_DES_MODE_CBC3', CRYPT_DES_MODE_CBC); * * @package Crypt_TripleDES * @author Jim Wigginton - * @version 0.1.1 * @access public */ class Crypt_TripleDES extends Crypt_DES diff --git a/phpseclib/Crypt/Twofish.php b/phpseclib/Crypt/Twofish.php index c99f3ad8..61aff9fe 100644 --- a/phpseclib/Crypt/Twofish.php +++ b/phpseclib/Crypt/Twofish.php @@ -107,7 +107,6 @@ define('CRYPT_TWOFISH_MODE_OFB', CRYPT_MODE_OFB); * @package Crypt_Twofish * @author Jim Wigginton * @author Hans-Juergen Petrich - * @version 1.0.1 * @access public */ class Crypt_Twofish extends Crypt_Base From 7e2d0147b69faf20a94291064e2110360ed947ba Mon Sep 17 00:00:00 2001 From: terrafrost Date: Sat, 13 Dec 2014 14:17:10 -0600 Subject: [PATCH 18/79] Tests: don't set CRYPT_MODE_CIPHER to CRYPT_MODE_MCRYPT --- tests/Functional/Net/SFTPLargeFileTest.php | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/tests/Functional/Net/SFTPLargeFileTest.php b/tests/Functional/Net/SFTPLargeFileTest.php index 1c78f496..965e1e93 100644 --- a/tests/Functional/Net/SFTPLargeFileTest.php +++ b/tests/Functional/Net/SFTPLargeFileTest.php @@ -15,17 +15,10 @@ class Functional_Net_SFTPLargeFileTest extends PhpseclibFunctionalTestCase static public function setUpBeforeClass() { - if (!extension_loaded('mcrypt')) { - self::markTestSkipped('This test depends on mcrypt for performance.'); + if (!extension_loaded('mcrypt') && !extension_loaded('openssl')) { + self::markTestSkipped('This test depends on mcrypt or openssl for performance.'); } parent::setUpBeforeClass(); - self::ensureConstant('CRYPT_AES_MODE', CRYPT_MODE_MCRYPT); - self::ensureConstant('CRYPT_BLOWFISH_MODE', CRYPT_MODE_MCRYPT); - self::ensureConstant('CRYPT_DES_MODE', CRYPT_MODE_MCRYPT); - self::ensureConstant('CRYPT_RC2_MODE', CRYPT_MODE_MCRYPT); - self::ensureConstant('CRYPT_RC4_MODE', CRYPT_MODE_MCRYPT); - self::ensureConstant('CRYPT_RIJNDAEL_MODE', CRYPT_MODE_MCRYPT); - self::ensureConstant('CRYPT_TWOFISH_MODE', CRYPT_MODE_MCRYPT); } public function setUp() From 7d31f924a8af9c6bae7d9b39597fc831600d895f Mon Sep 17 00:00:00 2001 From: terrafrost Date: Sat, 13 Dec 2014 14:20:25 -0600 Subject: [PATCH 19/79] Crypt/Base: clean up comments --- phpseclib/Crypt/Base.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/phpseclib/Crypt/Base.php b/phpseclib/Crypt/Base.php index 55edffcf..ab32ea15 100644 --- a/phpseclib/Crypt/Base.php +++ b/phpseclib/Crypt/Base.php @@ -100,7 +100,7 @@ define('CRYPT_MODE_STREAM', 5); /**#@+ * @access private * @see Crypt_Base::Crypt_Base() - * @internal This constants are for internal usage only + * @internal This constants are for internal use only */ /** * Base value for the internal implementation $engine switch @@ -532,7 +532,7 @@ class Crypt_Base * * @access public * @param String $iv - * @internal Could, but not must, extend by the child Crypt_* class + * @internal Can be overwritten by a sub class, but does not have to be */ function setIV($iv) { From 51c0deba45d30dc4a31f8f2ecbad2b493da8ad22 Mon Sep 17 00:00:00 2001 From: terrafrost Date: Sat, 13 Dec 2014 14:22:12 -0600 Subject: [PATCH 20/79] Crypt/Base: update one more comment --- phpseclib/Crypt/Base.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/phpseclib/Crypt/Base.php b/phpseclib/Crypt/Base.php index ab32ea15..192ecee4 100644 --- a/phpseclib/Crypt/Base.php +++ b/phpseclib/Crypt/Base.php @@ -56,7 +56,7 @@ * @access private * @see Crypt_Base::encrypt() * @see Crypt_Base::decrypt() - * @internal This constants are for internal usage only + * @internal This constants are for internal use only */ /** * Encrypt / decrypt using the Counter mode. From 8d40eb22efcd86ea74ce53cbe9c8937cc006b5b5 Mon Sep 17 00:00:00 2001 From: terrafrost Date: Sat, 13 Dec 2014 14:34:48 -0600 Subject: [PATCH 21/79] Tests: update unit tests to use CRYPT_ENGINE_* instead of CRYPT_MODE_* --- tests/Unit/Crypt/AES/InternalTest.php | 2 +- tests/Unit/Crypt/AES/McryptTest.php | 2 +- tests/Unit/Crypt/AES/OpenSSLTest.php | 2 +- tests/Unit/Crypt/DES.php | 20 ++++++++++---------- tests/Unit/Crypt/RC2.php | 10 +++++----- 5 files changed, 18 insertions(+), 18 deletions(-) diff --git a/tests/Unit/Crypt/AES/InternalTest.php b/tests/Unit/Crypt/AES/InternalTest.php index 8c1d1f37..75e89edf 100644 --- a/tests/Unit/Crypt/AES/InternalTest.php +++ b/tests/Unit/Crypt/AES/InternalTest.php @@ -9,6 +9,6 @@ class Unit_Crypt_AES_InternalTest extends Unit_Crypt_AES_TestCase { protected function setUp() { - $this->engine = CRYPT_MODE_INTERNAL; + $this->engine = CRYPT_ENGINE_INTERNAL; } } diff --git a/tests/Unit/Crypt/AES/McryptTest.php b/tests/Unit/Crypt/AES/McryptTest.php index 3dd1f9d1..41fa2041 100644 --- a/tests/Unit/Crypt/AES/McryptTest.php +++ b/tests/Unit/Crypt/AES/McryptTest.php @@ -9,6 +9,6 @@ class Unit_Crypt_AES_McryptTest extends Unit_Crypt_AES_TestCase { protected function setUp() { - $this->engine = CRYPT_MODE_MCRYPT; + $this->engine = CRYPT_ENGINE_MCRYPT; } } diff --git a/tests/Unit/Crypt/AES/OpenSSLTest.php b/tests/Unit/Crypt/AES/OpenSSLTest.php index ff950d08..ddb5de67 100644 --- a/tests/Unit/Crypt/AES/OpenSSLTest.php +++ b/tests/Unit/Crypt/AES/OpenSSLTest.php @@ -9,6 +9,6 @@ class Unit_Crypt_AES_OpenSSLTest extends Unit_Crypt_AES_TestCase { protected function setUp() { - $this->engine = CRYPT_MODE_OPENSSL; + $this->engine = CRYPT_ENGINE_OPENSSL; } } diff --git a/tests/Unit/Crypt/DES.php b/tests/Unit/Crypt/DES.php index 4d9e0aad..cf35fc6e 100644 --- a/tests/Unit/Crypt/DES.php +++ b/tests/Unit/Crypt/DES.php @@ -17,19 +17,19 @@ class Unit_Crypt_DES_TestCase extends PhpseclibTestCase $des->setKey('d'); $des->setIV('d'); - $des->setPreferredEngine(CRYPT_MODE_INTERNAL); + $des->setPreferredEngine(CRYPT_ENGINE_INTERNAL); $internal = $des->encrypt('d'); - $des->setPreferredEngine(CRYPT_MODE_MCRYPT); - if ($des->getEngine() == CRYPT_MODE_MCRYPT) { + $des->setPreferredEngine(CRYPT_ENGINE_MCRYPT); + if ($des->getEngine() == CRYPT_ENGINE_MCRYPT) { $mcrypt = $des->encrypt('d'); $this->assertEquals($internal, $mcrypt, 'Failed asserting that the internal and mcrypt engines produce identical results'); } else { self::markTestSkipped('Unable to initialize mcrypt engine'); } - $des->setPreferredEngine(CRYPT_MODE_OPENSSL); - if ($des->getEngine() == CRYPT_MODE_OPENSSL) { + $des->setPreferredEngine(CRYPT_ENGINE_OPENSSL); + if ($des->getEngine() == CRYPT_ENGINE_OPENSSL) { $openssl = $des->encrypt('d'); $this->assertEquals($internal, $openssl, 'Failed asserting that the internal and OpenSSL engines produce identical results'); } else { @@ -47,19 +47,19 @@ class Unit_Crypt_DES_TestCase extends PhpseclibTestCase //$des->setKey(); //$des->setIV(); - $des->setPreferredEngine(CRYPT_MODE_INTERNAL); + $des->setPreferredEngine(CRYPT_ENGINE_INTERNAL); $internal = $des->decrypt('d'); - $des->setPreferredEngine(CRYPT_MODE_MCRYPT); - if ($des->getEngine() == CRYPT_MODE_MCRYPT) { + $des->setPreferredEngine(CRYPT_ENGINE_MCRYPT); + if ($des->getEngine() == CRYPT_ENGINE_MCRYPT) { $mcrypt = $des->decrypt('d'); $this->assertEquals($internal, $mcrypt, 'Failed asserting that the internal and mcrypt engines produce identical results'); } else { self::markTestSkipped('Unable to initialize mcrypt engine'); } - $des->setPreferredEngine(CRYPT_MODE_OPENSSL); - if ($des->getEngine() == CRYPT_MODE_OPENSSL) { + $des->setPreferredEngine(CRYPT_ENGINE_OPENSSL); + if ($des->getEngine() == CRYPT_ENGINE_OPENSSL) { $openssl = $des->decrypt('d'); $this->assertEquals($internal, $openssl, 'Failed asserting that the internal and OpenSSL engines produce identical results'); } else { diff --git a/tests/Unit/Crypt/RC2.php b/tests/Unit/Crypt/RC2.php index 7d61c33d..6803aca3 100644 --- a/tests/Unit/Crypt/RC2.php +++ b/tests/Unit/Crypt/RC2.php @@ -49,19 +49,19 @@ class Unit_Crypt_RC2_TestCase extends PhpseclibTestCase $rc2->setKey(str_repeat('d', 16), 128); - $rc2->setPreferredEngine(CRYPT_MODE_INTERNAL); + $rc2->setPreferredEngine(CRYPT_ENGINE_INTERNAL); $internal = $rc2->encrypt('d'); - $rc2->setPreferredEngine(CRYPT_MODE_MCRYPT); - if ($rc2->getEngine() == CRYPT_MODE_MCRYPT) { + $rc2->setPreferredEngine(CRYPT_ENGINE_MCRYPT); + if ($rc2->getEngine() == CRYPT_ENGINE_MCRYPT) { $mcrypt = $rc2->encrypt('d'); $this->assertEquals($internal, $mcrypt, 'Failed asserting that the internal and mcrypt engines produce identical results'); } else { self::markTestSkipped('Unable to initialize mcrypt engine'); } - $rc2->setPreferredEngine(CRYPT_MODE_OPENSSL); - if ($rc2->getEngine() == CRYPT_MODE_OPENSSL) { + $rc2->setPreferredEngine(CRYPT_ENGINE_OPENSSL); + if ($rc2->getEngine() == CRYPT_ENGINE_OPENSSL) { $openssl = $rc2->encrypt('d'); $this->assertEquals($internal, $openssl, 'Failed asserting that the internal and OpenSSL engines produce identical results'); } else { From b1fdbd6bbda3b54276b08c02f1e91858d5b37673 Mon Sep 17 00:00:00 2001 From: terrafrost Date: Sat, 13 Dec 2014 14:42:58 -0600 Subject: [PATCH 22/79] Tests: CRYPT_MODE_* -> CRYPT_ENGINE_* in one more place --- tests/Unit/Crypt/AES/TestCase.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/Unit/Crypt/AES/TestCase.php b/tests/Unit/Crypt/AES/TestCase.php index 15909e47..a990eb1b 100644 --- a/tests/Unit/Crypt/AES/TestCase.php +++ b/tests/Unit/Crypt/AES/TestCase.php @@ -16,10 +16,10 @@ abstract class Unit_Crypt_AES_TestCase extends PhpseclibTestCase if ($aes->getEngine() != $this->engine) { $engine = 'internal'; switch ($this->engine) { - case CRYPT_MODE_OPENSSL: + case CRYPT_ENGINE_OPENSSL: $engine = 'OpenSSL'; break; - case CRYPT_MODE_MCRYPT: + case CRYPT_ENGINE_MCRYPT: $engine = 'mcrypt'; } self::markTestSkipped('Unable to initialize ' . $engine . ' engine'); From c8281dd4a37d9b731a2e274103e72b365f9f4568 Mon Sep 17 00:00:00 2001 From: terrafrost Date: Sat, 13 Dec 2014 15:00:38 -0600 Subject: [PATCH 23/79] Tests (DES): disable padding for decryption test When padding is enabled $des->decrypt() will return false with ciphertext's of invalid length. Which makes sense. Null padding doesn't work when padding is enabled because 0 isn't a valid PKCS7 padding character (has to be between 1 and the block_length, inclusive). --- tests/Unit/Crypt/DES.php | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/tests/Unit/Crypt/DES.php b/tests/Unit/Crypt/DES.php index cf35fc6e..56810bbe 100644 --- a/tests/Unit/Crypt/DES.php +++ b/tests/Unit/Crypt/DES.php @@ -18,12 +18,18 @@ class Unit_Crypt_DES_TestCase extends PhpseclibTestCase $des->setIV('d'); $des->setPreferredEngine(CRYPT_ENGINE_INTERNAL); + + $result = pack('H*', '3e7613642049af1e'); + $internal = $des->encrypt('d'); + if (!$this->assertEquals($result, $internal)) { + $this->assertEquals($result, $internal, 'Failed asserting that the internal engine produced the correct result'); + } $des->setPreferredEngine(CRYPT_ENGINE_MCRYPT); if ($des->getEngine() == CRYPT_ENGINE_MCRYPT) { $mcrypt = $des->encrypt('d'); - $this->assertEquals($internal, $mcrypt, 'Failed asserting that the internal and mcrypt engines produce identical results'); + $this->assertEquals($result, $mcrypt, 'Failed asserting that the mcrypt engine produced the correct result'); } else { self::markTestSkipped('Unable to initialize mcrypt engine'); } @@ -31,7 +37,7 @@ class Unit_Crypt_DES_TestCase extends PhpseclibTestCase $des->setPreferredEngine(CRYPT_ENGINE_OPENSSL); if ($des->getEngine() == CRYPT_ENGINE_OPENSSL) { $openssl = $des->encrypt('d'); - $this->assertEquals($internal, $openssl, 'Failed asserting that the internal and OpenSSL engines produce identical results'); + $this->assertEquals($result, $openssl, 'Failed asserting that the OpenSSL engine produced the correct result'); } else { self::markTestSkipped('Unable to initialize OpenSSL engine'); } @@ -43,6 +49,7 @@ class Unit_Crypt_DES_TestCase extends PhpseclibTestCase public function testDecryptPadding() { $des = new Crypt_DES(CRYPT_MODE_CBC); + $des->disablePadding(); // when the key and iv are not specified they should be null padded //$des->setKey(); //$des->setIV(); From 8f27aaa323f649290a7ebed57647c1af3394f787 Mon Sep 17 00:00:00 2001 From: terrafrost Date: Sat, 13 Dec 2014 15:10:47 -0600 Subject: [PATCH 24/79] Tests (DES): i didn't realize last commit included all the changes that it did not all of them were ready to go out. i just meant for it to include a one-line change. meh. --- tests/Unit/Crypt/DES.php | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/tests/Unit/Crypt/DES.php b/tests/Unit/Crypt/DES.php index 56810bbe..9ae77c03 100644 --- a/tests/Unit/Crypt/DES.php +++ b/tests/Unit/Crypt/DES.php @@ -22,9 +22,7 @@ class Unit_Crypt_DES_TestCase extends PhpseclibTestCase $result = pack('H*', '3e7613642049af1e'); $internal = $des->encrypt('d'); - if (!$this->assertEquals($result, $internal)) { - $this->assertEquals($result, $internal, 'Failed asserting that the internal engine produced the correct result'); - } + $this->assertEquals($result, $internal, 'Failed asserting that the internal engine produced the correct result'); $des->setPreferredEngine(CRYPT_ENGINE_MCRYPT); if ($des->getEngine() == CRYPT_ENGINE_MCRYPT) { @@ -57,10 +55,13 @@ class Unit_Crypt_DES_TestCase extends PhpseclibTestCase $des->setPreferredEngine(CRYPT_ENGINE_INTERNAL); $internal = $des->decrypt('d'); + $result = pack('H*', '36a86ebd0f9e048f'); + $this->assertEquals($result, $internal, 'Failed asserting that the internal engine produced the correct result'); + $des->setPreferredEngine(CRYPT_ENGINE_MCRYPT); if ($des->getEngine() == CRYPT_ENGINE_MCRYPT) { $mcrypt = $des->decrypt('d'); - $this->assertEquals($internal, $mcrypt, 'Failed asserting that the internal and mcrypt engines produce identical results'); + $this->assertEquals($result, $mcrypt, 'Failed asserting that the mcrypt engine produced the correct result'); } else { self::markTestSkipped('Unable to initialize mcrypt engine'); } @@ -68,7 +69,7 @@ class Unit_Crypt_DES_TestCase extends PhpseclibTestCase $des->setPreferredEngine(CRYPT_ENGINE_OPENSSL); if ($des->getEngine() == CRYPT_ENGINE_OPENSSL) { $openssl = $des->decrypt('d'); - $this->assertEquals($internal, $openssl, 'Failed asserting that the internal and OpenSSL engines produce identical results'); + $this->assertEquals($result, $openssl, 'Failed asserting that the OpenSSL engine produced the correct result'); } else { self::markTestSkipped('Unable to initialize OpenSSL engine'); } From 31af2b3ed31005aaeee58a3072836f74a8cb778a Mon Sep 17 00:00:00 2001 From: terrafrost Date: Sun, 14 Dec 2014 10:40:40 -0600 Subject: [PATCH 25/79] Crypt/Base: fix decryption for ECB / CBC on PHP < 5.4.0 --- phpseclib/Crypt/Base.php | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/phpseclib/Crypt/Base.php b/phpseclib/Crypt/Base.php index 192ecee4..9e38f5b2 100644 --- a/phpseclib/Crypt/Base.php +++ b/phpseclib/Crypt/Base.php @@ -990,10 +990,20 @@ class Crypt_Base } switch ($this->mode) { case CRYPT_MODE_STREAM: + $plaintext = openssl_decrypt($ciphertext, $this->cipher_name_openssl, $this->key, $this->openssl_options); + break; case CRYPT_MODE_ECB: + if (!defined('OPENSSL_RAW_DATA')) { + $padding = str_repeat(chr($this->block_size), $this->block_size); + $ciphetext.= openssl_encrypt($padding, $this->cipher_name_openssl_ecb, $this->key, true); + } $plaintext = openssl_decrypt($ciphertext, $this->cipher_name_openssl, $this->key, $this->openssl_options); break; case CRYPT_MODE_CBC: + if (!defined('OPENSSL_RAW_DATA')) { + $padding = str_repeat(chr($this->block_size), $this->block_size) ^ substr($ciphertext, -$block_size); + $plaintext.= openssl_encrypt($padding, $this->cipher_name_openssl_ecb, $this->key, true); + } $plaintext = openssl_decrypt($ciphertext, $this->cipher_name_openssl, $this->key, $this->openssl_options, $this->decryptIV); if ($this->continuousBuffer) { $this->decryptIV = substr($ciphertext, -$this->block_size); @@ -1528,7 +1538,8 @@ class Crypt_Base $this->openssl_emulate_ctr = false; $result = $this->cipher_name_openssl && extension_loaded('openssl') && - version_compare(PHP_VERSION, '5.3.0'); + // PHP 5.3.0 - 5.3.2 did not let you set IV's + version_compare(PHP_VERSION, '5.3.3', '>='); if (!$result) { return false; } From 4cc23b7006154ad162941af955316476b3c884d8 Mon Sep 17 00:00:00 2001 From: terrafrost Date: Sun, 14 Dec 2014 10:48:18 -0600 Subject: [PATCH 26/79] Crypt/Base: $block_size -> $this->block_size --- phpseclib/Crypt/Base.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/phpseclib/Crypt/Base.php b/phpseclib/Crypt/Base.php index 9e38f5b2..c2091387 100644 --- a/phpseclib/Crypt/Base.php +++ b/phpseclib/Crypt/Base.php @@ -1001,7 +1001,7 @@ class Crypt_Base break; case CRYPT_MODE_CBC: if (!defined('OPENSSL_RAW_DATA')) { - $padding = str_repeat(chr($this->block_size), $this->block_size) ^ substr($ciphertext, -$block_size); + $padding = str_repeat(chr($this->block_size), $this->block_size) ^ substr($ciphertext, -$this->block_size); $plaintext.= openssl_encrypt($padding, $this->cipher_name_openssl_ecb, $this->key, true); } $plaintext = openssl_decrypt($ciphertext, $this->cipher_name_openssl, $this->key, $this->openssl_options, $this->decryptIV); From d9adb6660965644afd78b4bbbd20266b89aa9484 Mon Sep 17 00:00:00 2001 From: terrafrost Date: Sun, 14 Dec 2014 11:03:12 -0600 Subject: [PATCH 27/79] Crypt/Base: fix typo --- phpseclib/Crypt/Base.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/phpseclib/Crypt/Base.php b/phpseclib/Crypt/Base.php index c2091387..79667a20 100644 --- a/phpseclib/Crypt/Base.php +++ b/phpseclib/Crypt/Base.php @@ -1002,7 +1002,7 @@ class Crypt_Base case CRYPT_MODE_CBC: if (!defined('OPENSSL_RAW_DATA')) { $padding = str_repeat(chr($this->block_size), $this->block_size) ^ substr($ciphertext, -$this->block_size); - $plaintext.= openssl_encrypt($padding, $this->cipher_name_openssl_ecb, $this->key, true); + $ciphertext.= openssl_encrypt($padding, $this->cipher_name_openssl_ecb, $this->key, true); } $plaintext = openssl_decrypt($ciphertext, $this->cipher_name_openssl, $this->key, $this->openssl_options, $this->decryptIV); if ($this->continuousBuffer) { From 5d0cb1cee9601889e0400ac69e3b19291ccf43db Mon Sep 17 00:00:00 2001 From: terrafrost Date: Sun, 14 Dec 2014 12:00:34 -0600 Subject: [PATCH 28/79] Crypt/Base: more fixes to pre 5.4.0 padding adjustments --- phpseclib/Crypt/Base.php | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/phpseclib/Crypt/Base.php b/phpseclib/Crypt/Base.php index 79667a20..17e8d110 100644 --- a/phpseclib/Crypt/Base.php +++ b/phpseclib/Crypt/Base.php @@ -994,15 +994,14 @@ class Crypt_Base break; case CRYPT_MODE_ECB: if (!defined('OPENSSL_RAW_DATA')) { - $padding = str_repeat(chr($this->block_size), $this->block_size); - $ciphetext.= openssl_encrypt($padding, $this->cipher_name_openssl_ecb, $this->key, true); + $ciphetext.= openssl_encrypt('', $this->cipher_name_openssl_ecb, $this->key, true); } $plaintext = openssl_decrypt($ciphertext, $this->cipher_name_openssl, $this->key, $this->openssl_options); break; case CRYPT_MODE_CBC: if (!defined('OPENSSL_RAW_DATA')) { $padding = str_repeat(chr($this->block_size), $this->block_size) ^ substr($ciphertext, -$this->block_size); - $ciphertext.= openssl_encrypt($padding, $this->cipher_name_openssl_ecb, $this->key, true); + $ciphertext.= substr(openssl_encrypt($padding, $this->cipher_name_openssl_ecb, $this->key, true), 0, $this->block_size); } $plaintext = openssl_decrypt($ciphertext, $this->cipher_name_openssl, $this->key, $this->openssl_options, $this->decryptIV); if ($this->continuousBuffer) { From baf65d3fefa2a0ab6d7c78e80a1b9a3d10bae480 Mon Sep 17 00:00:00 2001 From: terrafrost Date: Sat, 20 Dec 2014 11:14:08 -0600 Subject: [PATCH 29/79] Tests: small unit test updates --- tests/Unit/Crypt/AES/TestCase.php | 8 ++++---- tests/Unit/Crypt/RC2.php | 9 ++++++--- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/tests/Unit/Crypt/AES/TestCase.php b/tests/Unit/Crypt/AES/TestCase.php index a990eb1b..e885ae5c 100644 --- a/tests/Unit/Crypt/AES/TestCase.php +++ b/tests/Unit/Crypt/AES/TestCase.php @@ -135,10 +135,10 @@ abstract class Unit_Crypt_AES_TestCase extends PhpseclibTestCase ); $combos = array( - array(16), - array(17), - array(1, 16), - array(3, 6, 7), // (3 to test the openssl_encrypt call and the buffer creation, 6 to test the exclusive use of the buffer and 7 to test the buffer's exhaustion and recreation) + array(16), + array(17), + array(1, 16), + array(3, 6, 7), // (3 to test the openssl_encrypt call and the buffer creation, 6 to test the exclusive use of the buffer and 7 to test the buffer's exhaustion and recreation) array(15, 4), // (15 to test openssl_encrypt call and buffer creation and 4 to test something that spans multpile bloc array(3, 6, 10, 16), // this is why the strlen check in the buffer-only code was needed array(16, 16), // two full size blocks diff --git a/tests/Unit/Crypt/RC2.php b/tests/Unit/Crypt/RC2.php index 6803aca3..533239e3 100644 --- a/tests/Unit/Crypt/RC2.php +++ b/tests/Unit/Crypt/RC2.php @@ -33,7 +33,7 @@ class Unit_Crypt_RC2_TestCase extends PhpseclibTestCase // in contrast, to my knowledge, there is no technique for expanding a key less than 128 bits to 128 bits, via RC2 key expansion. the only // scenario in that regard is null padding. - // simple truncation is insufficient, since, quoting RFC2268, "the purpose of th key-expansion algorithm [in RC2] is to modify the key buffer + // simple truncation is insufficient, since, quoting RFC2268, "the purpose of the key-expansion algorithm [in RC2] is to modify the key buffer // so that each bit of the expanded key depends in a complicated way on every bit of the supplied input key". // now, to OpenSSL's credit, null padding is internally consistent with OpenSSL. OpenSSL only supports fixed length keys. For rc2, rc4 and @@ -52,10 +52,13 @@ class Unit_Crypt_RC2_TestCase extends PhpseclibTestCase $rc2->setPreferredEngine(CRYPT_ENGINE_INTERNAL); $internal = $rc2->encrypt('d'); + $result = pack('H*', 'e3b36057f4821346'); + $this->assertEquals($result, $internal, 'Failed asserting that the internal engine produced the correct result'); + $rc2->setPreferredEngine(CRYPT_ENGINE_MCRYPT); if ($rc2->getEngine() == CRYPT_ENGINE_MCRYPT) { $mcrypt = $rc2->encrypt('d'); - $this->assertEquals($internal, $mcrypt, 'Failed asserting that the internal and mcrypt engines produce identical results'); + $this->assertEquals($result, $mcrypt, 'Failed asserting that the mcrypt engine produced the correct result'); } else { self::markTestSkipped('Unable to initialize mcrypt engine'); } @@ -63,7 +66,7 @@ class Unit_Crypt_RC2_TestCase extends PhpseclibTestCase $rc2->setPreferredEngine(CRYPT_ENGINE_OPENSSL); if ($rc2->getEngine() == CRYPT_ENGINE_OPENSSL) { $openssl = $rc2->encrypt('d'); - $this->assertEquals($internal, $openssl, 'Failed asserting that the internal and OpenSSL engines produce identical results'); + $this->assertEquals($result, $openssl, 'Failed asserting that the OpenSSL engine produced the correct result'); } else { self::markTestSkipped('Unable to initialize OpenSSL engine'); } From f91c4ccf60be4cb3f0e85595bd52a1810cdec806 Mon Sep 17 00:00:00 2001 From: terrafrost Date: Sat, 20 Dec 2014 11:14:29 -0600 Subject: [PATCH 30/79] DES: apparently TripleDES extends DES this was not always the case: See https://github.com/phpseclib/phpseclib/commit/c4752cbeba6389e8abbc8ee8b8b1a066c2c1634a --- phpseclib/Crypt/DES.php | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/phpseclib/Crypt/DES.php b/phpseclib/Crypt/DES.php index 5b141d18..b274495b 100644 --- a/phpseclib/Crypt/DES.php +++ b/phpseclib/Crypt/DES.php @@ -674,9 +674,11 @@ class Crypt_DES extends Crypt_Base */ function isValidEngine($engine) { - if ($engine == CRYPT_ENGINE_OPENSSL) { - $this->cipher_name_openssl_ecb = 'des-ecb'; - $this->cipher_name_openssl = 'des-' . $this->_openssl_translate_mode(); + if ($this->key_size_max == 8) { + if ($engine == CRYPT_ENGINE_OPENSSL) { + $this->cipher_name_openssl_ecb = 'des-ecb'; + $this->cipher_name_openssl = 'des-' . $this->_openssl_translate_mode(); + } } return parent::isValidEngine($engine); From b703fbe12b4aa6330ada65aaf569ffb837866423 Mon Sep 17 00:00:00 2001 From: terrafrost Date: Sat, 20 Dec 2014 12:21:17 -0600 Subject: [PATCH 31/79] Tests: add RC4 unit tests --- tests/Unit/Crypt/RC4.php | 115 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 115 insertions(+) create mode 100644 tests/Unit/Crypt/RC4.php diff --git a/tests/Unit/Crypt/RC4.php b/tests/Unit/Crypt/RC4.php new file mode 100644 index 00000000..6bc8f0b1 --- /dev/null +++ b/tests/Unit/Crypt/RC4.php @@ -0,0 +1,115 @@ + + * @copyright 2014 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + */ + +require_once 'Crypt/RC4.php'; + +class Unit_Crypt_RC4_TestCase extends PhpseclibTestCase +{ + public function engineVectors() + { + $engines = array( + 'CRYPT_ENGINE_INTERNAL' => 'internal', + 'CRYPT_ENGINE_MCRYPT' => 'mcrypt', + 'CRYPT_ENGINE_OPENSSL' => 'OpenSSL', + ); + // tests from https://tools.ietf.org/html/rfc6229 + $tests = array( + array( + 'key' => pack('H*', '0102030405'), + 'output' => array( + array('offset' => 0, 'result' => 'b2396305f03dc027ccc3524a0a1118a8'), + array('offset' => 16, 'result' => '6982944f18fc82d589c403a47a0d0919'), + array('offset' => 240, 'result' => '28cb1132c96ce286421dcaadb8b69eae'), + array('offset' => 256, 'result' => '1cfcf62b03eddb641d77dfcf7f8d8c93'), + array('offset' => 496, 'result' => '42b7d0cdd918a8a33dd51781c81f4041'), + array('offset' => 512, 'result' => '6459844432a7da923cfb3eb4980661f6'), + array('offset' => 752, 'result' => 'ec10327bde2beefd18f9277680457e22'), + array('offset' => 768, 'result' => 'eb62638d4f0ba1fe9fca20e05bf8ff2b'), + array('offset' => 1008, 'result' => '45129048e6a0ed0b56b490338f078da5'), + array('offset' => 1024, 'result' => '30abbcc7c20b01609f23ee2d5f6bb7df'), + array('offset' => 1520, 'result' => '3294f744d8f9790507e70f62e5bbceea'), + array('offset' => 1536, 'result' => 'd8729db41882259bee4f825325f5a130'), + array('offset' => 2032, 'result' => '1eb14a0c13b3bf47fa2a0ba93ad45b8b'), + array('offset' => 2048, 'result' => 'cc582f8ba9f265e2b1be9112e975d2d7'), + array('offset' => 3056, 'result' => 'f2e30f9bd102ecbf75aaade9bc35c43c'), + array('offset' => 3072, 'result' => 'ec0e11c479dc329dc8da7968fe965681'), + array('offset' => 4080, 'result' => '068326a2118416d21f9d04b2cd1ca050'), + array('offset' => 4096, 'result' => 'ff25b58995996707e51fbdf08b34d875') + ) + ), + array( + 'key' => pack('H*', '01020304050607'), + 'output' => array( + array('offset' => 0, 'result' => '293f02d47f37c9b633f2af5285feb46b'), + array('offset' => 16, 'result' => 'e620f1390d19bd84e2e0fd752031afc1'), + array('offset' => 240, 'result' => '914f02531c9218810df60f67e338154c'), + array('offset' => 256, 'result' => 'd0fdb583073ce85ab83917740ec011d5'), + array('offset' => 496, 'result' => '75f81411e871cffa70b90c74c592e454'), + array('offset' => 512, 'result' => '0bb87202938dad609e87a5a1b079e5e4'), + array('offset' => 752, 'result' => 'c2911246b612e7e7b903dfeda1dad866'), + array('offset' => 768, 'result' => '32828f91502b6291368de8081de36fc2'), + array('offset' => 1008, 'result' => 'f3b9a7e3b297bf9ad804512f9063eff1'), + array('offset' => 1024, 'result' => '8ecb67a9ba1f55a5a067e2b026a3676f'), + array('offset' => 1520, 'result' => 'd2aa902bd42d0d7cfd340cd45810529f'), + array('offset' => 1536, 'result' => '78b272c96e42eab4c60bd914e39d06e3'), + array('offset' => 2032, 'result' => 'f4332fd31a079396ee3cee3f2a4ff049'), + array('offset' => 2048, 'result' => '05459781d41fda7f30c1be7e1246c623'), + array('offset' => 3056, 'result' => 'adfd3868b8e51485d5e610017e3dd609'), + array('offset' => 3072, 'result' => 'ad26581c0c5be45f4cea01db2f3805d5'), + array('offset' => 4080, 'result' => 'f3172ceffc3b3d997c85ccd5af1a950c'), + array('offset' => 4096, 'result' => 'e74b0b9731227fd37c0ec08a47ddd8b8') + ) + ), + array( + 'key' => pack('H*', '0102030405060708'), + 'output' => array( + array('offset' => 0, 'result' => '97ab8a1bf0afb96132f2f67258da15a8'), + array('offset' => 16, 'result' => '8263efdb45c4a18684ef87e6b19e5b09'), + array('offset' => 240, 'result' => '9636ebc9841926f4f7d1f362bddf6e18'), + array('offset' => 256, 'result' => 'd0a990ff2c05fef5b90373c9ff4b870a'), + array('offset' => 496, 'result' => '73239f1db7f41d80b643c0c52518ec63'), + array('offset' => 512, 'result' => '163b319923a6bdb4527c626126703c0f'), + array('offset' => 752, 'result' => '49d6c8af0f97144a87df21d91472f966'), + array('offset' => 768, 'result' => '44173a103b6616c5d5ad1cee40c863d0'), + array('offset' => 1008, 'result' => '273c9c4b27f322e4e716ef53a47de7a4'), + array('offset' => 1024, 'result' => 'c6d0e7b226259fa9023490b26167ad1d'), + array('offset' => 1520, 'result' => '1fe8986713f07c3d9ae1c163ff8cf9d3'), + array('offset' => 1536, 'result' => '8369e1a965610be887fbd0c79162aafb'), + array('offset' => 2032, 'result' => '0a0127abb44484b9fbef5abcae1b579f'), + array('offset' => 2048, 'result' => 'c2cdadc6402e8ee866e1f37bdb47e42c'), + array('offset' => 3056, 'result' => '26b51ea37df8e1d6f76fc3b66a7429b3'), + array('offset' => 3072, 'result' => 'bc7683205d4f443dc1f29dda3315c87b'), + array('offset' => 4080, 'result' => 'd5fa5a3469d29aaaf83d23589db8c85b'), + array('offset' => 4096, 'result' => '3fb46e2c8f0f068edce8cdcd7dfc5862') + ) + ) + ); + $result = array(); + // @codingStandardsIgnoreStart + foreach ($engines as $engine => $engineName) + foreach ($tests as $test) + foreach ($test['output'] as $output) + $result[] = array($engine, $engineName, $test['key'], $output['offset'], $output['result']); + // @codingStandardsIgnoreEnd + return $result; + } + + /** + * @dataProvider engineVectors + */ + public function testVectors($engine, $engineName, $key, $offset, $expected) + { + $rc4 = new Crypt_RC4(); + $rc4->setPreferredEngine($engine); + if ($rc4->getEngine() != $engine) { + self::markTestSkipped('Unable to initialize ' . $engineName . ' engine'); + } + $rc4->setKey(pack('H*', $key)); + $result = $rc4->encrypt(str_repeat("\0", $offset + 16)); + $this->assertEquals(bin2hex(substr($result, -16)), $expected, "Failed asserting that key $key yielded expected output at offset $offset in $engineName engine"); + } +} From 1e1615080be764afab71aece0cd8d6e683251f1d Mon Sep 17 00:00:00 2001 From: terrafrost Date: Sat, 20 Dec 2014 12:24:07 -0600 Subject: [PATCH 32/79] Tests/RC4: test updates --- tests/Unit/Crypt/RC4.php | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/tests/Unit/Crypt/RC4.php b/tests/Unit/Crypt/RC4.php index 6bc8f0b1..d7ce352c 100644 --- a/tests/Unit/Crypt/RC4.php +++ b/tests/Unit/Crypt/RC4.php @@ -19,7 +19,7 @@ class Unit_Crypt_RC4_TestCase extends PhpseclibTestCase // tests from https://tools.ietf.org/html/rfc6229 $tests = array( array( - 'key' => pack('H*', '0102030405'), + 'key' => pack('H*', '0102030405'), // 40-bit key 'output' => array( array('offset' => 0, 'result' => 'b2396305f03dc027ccc3524a0a1118a8'), array('offset' => 16, 'result' => '6982944f18fc82d589c403a47a0d0919'), @@ -42,7 +42,7 @@ class Unit_Crypt_RC4_TestCase extends PhpseclibTestCase ) ), array( - 'key' => pack('H*', '01020304050607'), + 'key' => pack('H*', '01020304050607'), // 56-bit key 'output' => array( array('offset' => 0, 'result' => '293f02d47f37c9b633f2af5285feb46b'), array('offset' => 16, 'result' => 'e620f1390d19bd84e2e0fd752031afc1'), @@ -65,7 +65,7 @@ class Unit_Crypt_RC4_TestCase extends PhpseclibTestCase ) ), array( - 'key' => pack('H*', '0102030405060708'), + 'key' => pack('H*', '0102030405060708'), // 64-bit key 'output' => array( array('offset' => 0, 'result' => '97ab8a1bf0afb96132f2f67258da15a8'), array('offset' => 16, 'result' => '8263efdb45c4a18684ef87e6b19e5b09'), @@ -105,10 +105,10 @@ class Unit_Crypt_RC4_TestCase extends PhpseclibTestCase { $rc4 = new Crypt_RC4(); $rc4->setPreferredEngine($engine); - if ($rc4->getEngine() != $engine) { - self::markTestSkipped('Unable to initialize ' . $engineName . ' engine'); - } $rc4->setKey(pack('H*', $key)); + if ($rc4->getEngine() != $engine) { + self::markTestSkipped('Unable to initialize ' . $engineName . ' engine for ' . (strlen($key) * 8) . '-bit key'); + } $result = $rc4->encrypt(str_repeat("\0", $offset + 16)); $this->assertEquals(bin2hex(substr($result, -16)), $expected, "Failed asserting that key $key yielded expected output at offset $offset in $engineName engine"); } From 31dcbc919c6a298c588614b483ddb325dfc34b50 Mon Sep 17 00:00:00 2001 From: terrafrost Date: Sat, 20 Dec 2014 12:47:47 -0600 Subject: [PATCH 33/79] Tests/RC4: add more RC4 test vectors --- tests/Unit/Crypt/RC4.php | 92 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 92 insertions(+) diff --git a/tests/Unit/Crypt/RC4.php b/tests/Unit/Crypt/RC4.php index d7ce352c..f23143fb 100644 --- a/tests/Unit/Crypt/RC4.php +++ b/tests/Unit/Crypt/RC4.php @@ -86,6 +86,98 @@ class Unit_Crypt_RC4_TestCase extends PhpseclibTestCase array('offset' => 4080, 'result' => 'd5fa5a3469d29aaaf83d23589db8c85b'), array('offset' => 4096, 'result' => '3fb46e2c8f0f068edce8cdcd7dfc5862') ) + ), + array( + 'key' => pack('H*', '0102030405060708090a'), // 80-bit key + 'output' => array( + array('offset' => 0, 'result' => 'ede3b04643e586cc907dc21851709902'), + array('offset' => 16, 'result' => '03516ba78f413beb223aa5d4d2df6711'), + array('offset' => 240, 'result' => '3cfd6cb58ee0fdde640176ad0000044d'), + array('offset' => 256, 'result' => '48532b21fb6079c9114c0ffd9c04a1ad'), + array('offset' => 496, 'result' => '3e8cea98017109979084b1ef92f99d86'), + array('offset' => 512, 'result' => 'e20fb49bdb337ee48b8d8dc0f4afeffe'), + array('offset' => 752, 'result' => '5c2521eacd7966f15e056544bea0d315'), + array('offset' => 768, 'result' => 'e067a7031931a246a6c3875d2f678acb'), + array('offset' => 1008, 'result' => 'a64f70af88ae56b6f87581c0e23e6b08'), + array('offset' => 1024, 'result' => 'f449031de312814ec6f319291f4a0516'), + array('offset' => 1520, 'result' => 'bdae85924b3cb1d0a2e33a30c6d79599'), + array('offset' => 1536, 'result' => '8a0feddbac865a09bcd127fb562ed60a'), + array('offset' => 2032, 'result' => 'b55a0a5b51a12a8be34899c3e047511a'), + array('offset' => 2048, 'result' => 'd9a09cea3ce75fe39698070317a71339'), + array('offset' => 3056, 'result' => '552225ed1177f44584ac8cfa6c4eb5fc'), + array('offset' => 3072, 'result' => '7e82cbabfc95381b080998442129c2f8'), + array('offset' => 4080, 'result' => '1f135ed14ce60a91369d2322bef25e3c'), + array('offset' => 4096, 'result' => '08b6be45124a43e2eb77953f84dc8553') + ) + ), + array( + 'key' => pack('H*', '0102030405060708090a0b0c0d0e0f10'), // 128-bit key + 'output' => array( + array('offset' => 0, 'result' => '9ac7cc9a609d1ef7b2932899cde41b97'), + array('offset' => 16, 'result' => '5248c4959014126a6e8a84f11d1a9e1c'), + array('offset' => 240, 'result' => '065902e4b620f6cc36c8589f66432f2b'), + array('offset' => 256, 'result' => 'd39d566bc6bce3010768151549f3873f'), + array('offset' => 496, 'result' => 'b6d1e6c4a5e4771cad79538df295fb11'), + array('offset' => 512, 'result' => 'c68c1d5c559a974123df1dbc52a43b89'), + array('offset' => 752, 'result' => 'c5ecf88de897fd57fed301701b82a259'), + array('offset' => 768, 'result' => 'eccbe13de1fcc91c11a0b26c0bc8fa4d'), + array('offset' => 1008, 'result' => 'e7a72574f8782ae26aabcf9ebcd66065'), + array('offset' => 1024, 'result' => 'bdf0324e6083dcc6d3cedd3ca8c53c16'), + array('offset' => 1520, 'result' => 'b40110c4190b5622a96116b0017ed297'), + array('offset' => 1536, 'result' => 'ffa0b514647ec04f6306b892ae661181'), + array('offset' => 2032, 'result' => 'd03d1bc03cd33d70dff9fa5d71963ebd'), + array('offset' => 2048, 'result' => '8a44126411eaa78bd51e8d87a8879bf5'), + array('offset' => 3056, 'result' => 'fabeb76028ade2d0e48722e46c4615a3'), + array('offset' => 3072, 'result' => 'c05d88abd50357f935a63c59ee537623'), + array('offset' => 4080, 'result' => 'ff38265c1642c1abe8d3c2fe5e572bf8'), + array('offset' => 4096, 'result' => 'a36a4c301ae8ac13610ccbc12256cacc') + ) + ), + array( + 'key' => pack('H*', '0102030405060708090a0b0c0d0e0f101112131415161718'), // 192-bit key + 'output' => array( + array('offset' => 0, 'result' => '0595e57fe5f0bb3c706edac8a4b2db11'), + array('offset' => 16, 'result' => 'dfde31344a1af769c74f070aee9e2326'), + array('offset' => 240, 'result' => 'b06b9b1e195d13d8f4a7995c4553ac05'), + array('offset' => 256, 'result' => '6bd2378ec341c9a42f37ba79f88a32ff'), + array('offset' => 496, 'result' => 'e70bce1df7645adb5d2c4130215c3522'), + array('offset' => 512, 'result' => '9a5730c7fcb4c9af51ffda89c7f1ad22'), + array('offset' => 752, 'result' => '0485055fd4f6f0d963ef5ab9a5476982'), + array('offset' => 768, 'result' => '591fc66bcda10e452b03d4551f6b62ac'), + array('offset' => 1008, 'result' => '2753cc83988afa3e1688a1d3b42c9a02'), + array('offset' => 1024, 'result' => '93610d523d1d3f0062b3c2a3bbc7c7f0'), + array('offset' => 1520, 'result' => '96c248610aadedfeaf8978c03de8205a'), + array('offset' => 1536, 'result' => '0e317b3d1c73b9e9a4688f296d133a19'), + array('offset' => 2032, 'result' => 'bdf0e6c3cca5b5b9d533b69c56ada120'), + array('offset' => 2048, 'result' => '88a218b6e2ece1e6246d44c759d19b10'), + array('offset' => 3056, 'result' => '6866397e95c140534f94263421006e40'), + array('offset' => 3072, 'result' => '32cb0a1e9542c6b3b8b398abc3b0f1d5'), + array('offset' => 4080, 'result' => '29a0b8aed54a132324c62e423f54b4c8'), + array('offset' => 4096, 'result' => '3cb0f3b5020a98b82af9fe154484a168') + ) + ), + array( + 'key' => pack('H*', '0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20'), // 256-bit key + 'output' => array( + array('offset' => 0, 'result' => 'eaa6bd25880bf93d3f5d1e4ca2611d91'), + array('offset' => 16, 'result' => 'cfa45c9f7e714b54bdfa80027cb14380'), + array('offset' => 240, 'result' => '114ae344ded71b35f2e60febad727fd8'), + array('offset' => 256, 'result' => '02e1e7056b0f623900496422943e97b6'), + array('offset' => 496, 'result' => '91cb93c787964e10d9527d999c6f936b'), + array('offset' => 512, 'result' => '49b18b42f8e8367cbeb5ef104ba1c7cd'), + array('offset' => 752, 'result' => '87084b3ba700bade955610672745b374'), + array('offset' => 768, 'result' => 'e7a7b9e9ec540d5ff43bdb12792d1b35'), + array('offset' => 1008, 'result' => 'c799b596738f6b018c76c74b1759bd90'), + array('offset' => 1024, 'result' => '7fec5bfd9f9b89ce6548309092d7e958'), + array('offset' => 1520, 'result' => '40f250b26d1f096a4afd4c340a588815'), + array('offset' => 1536, 'result' => '3e34135c79db010200767651cf263073'), + array('offset' => 2032, 'result' => 'f656abccf88dd827027b2ce917d464ec'), + array('offset' => 2048, 'result' => '18b62503bfbc077fbabb98f20d98ab34'), + array('offset' => 3056, 'result' => '8aed95ee5b0dcbfbef4eb21d3a3f52f9'), + array('offset' => 3072, 'result' => '625a1ab00ee39a5327346bddb01a9c18'), + array('offset' => 4080, 'result' => 'a13a7c79c7e119b5ab0296ab28c300b9'), + array('offset' => 4096, 'result' => 'f3e4c0a2e02d1d01f7f0a74618af2b48') + ) ) ); $result = array(); From 7c5e7a0a72ba1560e4e2b8ec9de60c026d8df5b9 Mon Sep 17 00:00:00 2001 From: terrafrost Date: Sat, 20 Dec 2014 13:17:15 -0600 Subject: [PATCH 34/79] Tests/RC4: engines weren't being set correctly --- tests/Unit/Crypt/RC4.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/Unit/Crypt/RC4.php b/tests/Unit/Crypt/RC4.php index f23143fb..47021810 100644 --- a/tests/Unit/Crypt/RC4.php +++ b/tests/Unit/Crypt/RC4.php @@ -12,9 +12,9 @@ class Unit_Crypt_RC4_TestCase extends PhpseclibTestCase public function engineVectors() { $engines = array( - 'CRYPT_ENGINE_INTERNAL' => 'internal', - 'CRYPT_ENGINE_MCRYPT' => 'mcrypt', - 'CRYPT_ENGINE_OPENSSL' => 'OpenSSL', + CRYPT_ENGINE_INTERNAL => 'internal', + CRYPT_ENGINE_MCRYPT => 'mcrypt', + CRYPT_ENGINE_OPENSSL => 'OpenSSL', ); // tests from https://tools.ietf.org/html/rfc6229 $tests = array( From 45a5c05da6303473fa2489fd41625e58d67605b6 Mon Sep 17 00:00:00 2001 From: terrafrost Date: Sun, 21 Dec 2014 09:54:44 -0600 Subject: [PATCH 35/79] Tests: rename tests so that they actually run --- tests/Unit/Crypt/{DES.php => DESTest.php} | 2 +- tests/Unit/Crypt/{RC2.php => RC2Test.php} | 2 +- tests/Unit/Crypt/{RC4.php => RC4Test.php} | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) rename tests/Unit/Crypt/{DES.php => DESTest.php} (98%) rename tests/Unit/Crypt/{RC2.php => RC2Test.php} (98%) rename tests/Unit/Crypt/{RC4.php => RC4Test.php} (99%) diff --git a/tests/Unit/Crypt/DES.php b/tests/Unit/Crypt/DESTest.php similarity index 98% rename from tests/Unit/Crypt/DES.php rename to tests/Unit/Crypt/DESTest.php index 9ae77c03..0d7009e6 100644 --- a/tests/Unit/Crypt/DES.php +++ b/tests/Unit/Crypt/DESTest.php @@ -9,7 +9,7 @@ require_once 'Crypt/DES.php'; // the AES tests establish the correctness of the modes of operation. this test is inteded to establish the consistency of // key and iv padding between the multiple engines -class Unit_Crypt_DES_TestCase extends PhpseclibTestCase +class Unit_Crypt_DESTest extends PhpseclibTestCase { public function testEncryptPadding() { diff --git a/tests/Unit/Crypt/RC2.php b/tests/Unit/Crypt/RC2Test.php similarity index 98% rename from tests/Unit/Crypt/RC2.php rename to tests/Unit/Crypt/RC2Test.php index 533239e3..fb70ce31 100644 --- a/tests/Unit/Crypt/RC2.php +++ b/tests/Unit/Crypt/RC2Test.php @@ -8,7 +8,7 @@ require_once 'Crypt/RC2.php'; // this test is just confirming RC2's key expansion -class Unit_Crypt_RC2_TestCase extends PhpseclibTestCase +class Unit_Crypt_RC2Test extends PhpseclibTestCase { public function testEncryptPadding() { diff --git a/tests/Unit/Crypt/RC4.php b/tests/Unit/Crypt/RC4Test.php similarity index 99% rename from tests/Unit/Crypt/RC4.php rename to tests/Unit/Crypt/RC4Test.php index 47021810..11809d72 100644 --- a/tests/Unit/Crypt/RC4.php +++ b/tests/Unit/Crypt/RC4Test.php @@ -7,7 +7,7 @@ require_once 'Crypt/RC4.php'; -class Unit_Crypt_RC4_TestCase extends PhpseclibTestCase +class Unit_Crypt_RC4Test extends PhpseclibTestCase { public function engineVectors() { From 432700db8f987956de301edfb399521576f67fa5 Mon Sep 17 00:00:00 2001 From: terrafrost Date: Sun, 21 Dec 2014 10:16:37 -0600 Subject: [PATCH 36/79] Tests/RC4: key is already packed --- tests/Unit/Crypt/RC4Test.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Unit/Crypt/RC4Test.php b/tests/Unit/Crypt/RC4Test.php index 11809d72..7613d3c8 100644 --- a/tests/Unit/Crypt/RC4Test.php +++ b/tests/Unit/Crypt/RC4Test.php @@ -197,7 +197,7 @@ class Unit_Crypt_RC4Test extends PhpseclibTestCase { $rc4 = new Crypt_RC4(); $rc4->setPreferredEngine($engine); - $rc4->setKey(pack('H*', $key)); + $rc4->setKey($key); if ($rc4->getEngine() != $engine) { self::markTestSkipped('Unable to initialize ' . $engineName . ' engine for ' . (strlen($key) * 8) . '-bit key'); } From f891410b3df898040a0729c567743aac41904900 Mon Sep 17 00:00:00 2001 From: terrafrost Date: Thu, 25 Dec 2014 03:09:37 -0600 Subject: [PATCH 37/79] add 3DES unit test --- tests/Unit/Crypt/TripleDESTest.php | 113 +++++++++++++++++++++++++++++ 1 file changed, 113 insertions(+) create mode 100644 tests/Unit/Crypt/TripleDESTest.php diff --git a/tests/Unit/Crypt/TripleDESTest.php b/tests/Unit/Crypt/TripleDESTest.php new file mode 100644 index 00000000..41d52864 --- /dev/null +++ b/tests/Unit/Crypt/TripleDESTest.php @@ -0,0 +1,113 @@ + + * @copyright 2014 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + */ + +require_once 'Crypt/TripleDES.php'; + +class Unit_Crypt_TripleDESTest extends PhpseclibTestCase +{ + public function engineVectors() + { + $engines = array( + CRYPT_ENGINE_INTERNAL => 'internal', + CRYPT_ENGINE_MCRYPT => 'mcrypt', + CRYPT_ENGINE_OPENSSL => 'OpenSSL', + ); + + // tests from http://csrc.nist.gov/publications/nistpubs/800-20/800-20.pdf#page=273 + $tests = array( + // Table A.1 + // key, plaintext, ciphertext + array(str_repeat("\x01", 24), pack('H*', '8000000000000000'), pack('H*', '95F8A5E5DD31D900')), + array(str_repeat("\x01", 24), pack('H*', '4000000000000000'), pack('H*', 'DD7F121CA5015619')), + array(str_repeat("\x01", 24), pack('H*', '2000000000000000'), pack('H*', '2E8653104F3834EA')), + array(str_repeat("\x01", 24), pack('H*', '1000000000000000'), pack('H*', '4BD388FF6CD81D4F')), + array(str_repeat("\x01", 24), pack('H*', '0800000000000000'), pack('H*', '20B9E767B2FB1456')), + array(str_repeat("\x01", 24), pack('H*', '0400000000000000'), pack('H*', '55579380D77138EF')), + array(str_repeat("\x01", 24), pack('H*', '0200000000000000'), pack('H*', '6CC5DEFAAF04512F')), + array(str_repeat("\x01", 24), pack('H*', '0100000000000000'), pack('H*', '0D9F279BA5D87260')), + array(str_repeat("\x01", 24), pack('H*', '0080000000000000'), pack('H*', 'D9031B0271BD5A0A')), + array(str_repeat("\x01", 24), pack('H*', '0040000000000000'), pack('H*', '424250B37C3DD951')), + array(str_repeat("\x01", 24), pack('H*', '0020000000000000'), pack('H*', 'B8061B7ECD9A21E5')), + array(str_repeat("\x01", 24), pack('H*', '0010000000000000'), pack('H*', 'F15D0F286B65BD28')), + array(str_repeat("\x01", 24), pack('H*', '0008000000000000'), pack('H*', 'ADD0CC8D6E5DEBA1')), + array(str_repeat("\x01", 24), pack('H*', '0004000000000000'), pack('H*', 'E6D5F82752AD63D1')), + array(str_repeat("\x01", 24), pack('H*', '0002000000000000'), pack('H*', 'ECBFE3BD3F591A5E')), + array(str_repeat("\x01", 24), pack('H*', '0001000000000000'), pack('H*', 'F356834379D165CD')), + array(str_repeat("\x01", 24), pack('H*', '0000800000000000'), pack('H*', '2B9F982F20037FA9')), + array(str_repeat("\x01", 24), pack('H*', '0000400000000000'), pack('H*', '889DE068A16F0BE6')), + array(str_repeat("\x01", 24), pack('H*', '0000200000000000'), pack('H*', 'E19E275D846A1298')), + array(str_repeat("\x01", 24), pack('H*', '0000100000000000'), pack('H*', '329A8ED523D71AEC')), + array(str_repeat("\x01", 24), pack('H*', '0000080000000000'), pack('H*', 'E7FCE22557D23C97')), + array(str_repeat("\x01", 24), pack('H*', '0000040000000000'), pack('H*', '12A9F5817FF2D65D')), + array(str_repeat("\x01", 24), pack('H*', '0000020000000000'), pack('H*', 'A484C3AD38DC9C19')), + array(str_repeat("\x01", 24), pack('H*', '0000010000000000'), pack('H*', 'FBE00A8A1EF8AD72')), + array(str_repeat("\x01", 24), pack('H*', '0000008000000000'), pack('H*', '750D079407521363')), + array(str_repeat("\x01", 24), pack('H*', '0000004000000000'), pack('H*', '64FEED9C724C2FAF')), + array(str_repeat("\x01", 24), pack('H*', '0000002000000000'), pack('H*', 'F02B263B328E2B60')), + array(str_repeat("\x01", 24), pack('H*', '0000001000000000'), pack('H*', '9D64555A9A10B852')), + array(str_repeat("\x01", 24), pack('H*', '0000000800000000'), pack('H*', 'D106FF0BED5255D7')), + array(str_repeat("\x01", 24), pack('H*', '0000000400000000'), pack('H*', 'E1652C6B138C64A5')), + array(str_repeat("\x01", 24), pack('H*', '0000000200000000'), pack('H*', 'E428581186EC8F46')), + array(str_repeat("\x01", 24), pack('H*', '0000000100000000'), pack('H*', 'AEB5F5EDE22D1A36')), + array(str_repeat("\x01", 24), pack('H*', '0000000080000000'), pack('H*', 'E943D7568AEC0C5C')), + array(str_repeat("\x01", 24), pack('H*', '0000000040000000'), pack('H*', 'DF98C8276F54B04B')), + array(str_repeat("\x01", 24), pack('H*', '0000000020000000'), pack('H*', 'B160E4680F6C696F')), + array(str_repeat("\x01", 24), pack('H*', '0000000010000000'), pack('H*', 'FA0752B07D9C4AB8')), + array(str_repeat("\x01", 24), pack('H*', '0000000008000000'), pack('H*', 'CA3A2B036DBC8502')), + array(str_repeat("\x01", 24), pack('H*', '0000000004000000'), pack('H*', '5E0905517BB59BCF')), + array(str_repeat("\x01", 24), pack('H*', '0000000002000000'), pack('H*', '814EEB3B91D90726')), + array(str_repeat("\x01", 24), pack('H*', '0000000001000000'), pack('H*', '4D49DB1532919C9F')), + array(str_repeat("\x01", 24), pack('H*', '0000000000800000'), pack('H*', '25EB5FC3F8CF0621')), + array(str_repeat("\x01", 24), pack('H*', '0000000000400000'), pack('H*', 'AB6A20C0620D1C6F')), + array(str_repeat("\x01", 24), pack('H*', '0000000000200000'), pack('H*', '79E90DBC98F92CCA')), + array(str_repeat("\x01", 24), pack('H*', '0000000000100000'), pack('H*', '866ECEDD8072BB0E')), + array(str_repeat("\x01", 24), pack('H*', '0000000000080000'), pack('H*', '8B54536F2F3E64A8')), + array(str_repeat("\x01", 24), pack('H*', '0000000000040000'), pack('H*', 'EA51D3975595B86B')), + array(str_repeat("\x01", 24), pack('H*', '0000000000020000'), pack('H*', 'CAFFC6AC4542DE31')), + array(str_repeat("\x01", 24), pack('H*', '0000000000010000'), pack('H*', '8DD45A2DDF90796C')), + array(str_repeat("\x01", 24), pack('H*', '0000000000008000'), pack('H*', '1029D55E880EC2D0')), + array(str_repeat("\x01", 24), pack('H*', '0000000000004000'), pack('H*', '5D86CB23639DBEA9')), + array(str_repeat("\x01", 24), pack('H*', '0000000000002000'), pack('H*', '1D1CA853AE7C0C5F')), + array(str_repeat("\x01", 24), pack('H*', '0000000000001000'), pack('H*', 'CE332329248F3228')), + array(str_repeat("\x01", 24), pack('H*', '0000000000000800'), pack('H*', '8405D1ABE24FB942')), + array(str_repeat("\x01", 24), pack('H*', '0000000000000400'), pack('H*', 'E643D78090CA4207')), + array(str_repeat("\x01", 24), pack('H*', '0000000000000200'), pack('H*', '48221B9937748A23')), + array(str_repeat("\x01", 24), pack('H*', '0000000000000100'), pack('H*', 'DD7C0BBD61FAFD54')), + array(str_repeat("\x01", 24), pack('H*', '0000000000000080'), pack('H*', '2FBC291A570DB5C4')), + array(str_repeat("\x01", 24), pack('H*', '0000000000000040'), pack('H*', 'E07C30D7E4E26E12')), + array(str_repeat("\x01", 24), pack('H*', '0000000000000020'), pack('H*', '0953E2258E8E90A1')), + array(str_repeat("\x01", 24), pack('H*', '0000000000000010'), pack('H*', '5B711BC4CEEBF2EE')), + array(str_repeat("\x01", 24), pack('H*', '0000000000000008'), pack('H*', 'CC083F1E6D9E85F6')), + array(str_repeat("\x01", 24), pack('H*', '0000000000000004'), pack('H*', 'D2FD8867D50D2DFE')), + array(str_repeat("\x01", 24), pack('H*', '0000000000000002'), pack('H*', '06E7EA22CE92708F')), + array(str_repeat("\x01", 24), pack('H*', '0000000000000001'), pack('H*', '166B40B44ABA4BD6')) + ); + $result = array(); + // @codingStandardsIgnoreStart + foreach ($engines as $engine => $engineName) + foreach ($tests as $test) + $result[] = array($engine, $test[0], $output[1], $output[2]); + // @codingStandardsIgnoreEnd + return $result; + } + + /** + * @dataProvider engineVectors + */ + public function testVectors($engine, $engineName, $key, $plaintext, $expected) + { + $des = new Crypt_TripleDES(); + if (!$des->isValidEngine($engine)) { + self::markTestSkipped('Unable to initialize ' . $engineName . ' engine'); + } + $des->setPreferredEngine($engine); + $des->setKey($key); + $result = $des->encrypt($plaintext); + $plaintext = bin2hex($plaintext); + $this->assertEquals($result, $expected, "Failed asserting that $plaintext yielded expected output in $engineName engine"); + } +} From 7ea7463855738dfe5aff047d6b5afb8546ddddf1 Mon Sep 17 00:00:00 2001 From: terrafrost Date: Thu, 25 Dec 2014 09:47:36 -0600 Subject: [PATCH 38/79] fix 3DES unit test --- tests/Unit/Crypt/TripleDESTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Unit/Crypt/TripleDESTest.php b/tests/Unit/Crypt/TripleDESTest.php index 41d52864..81d9e063 100644 --- a/tests/Unit/Crypt/TripleDESTest.php +++ b/tests/Unit/Crypt/TripleDESTest.php @@ -90,7 +90,7 @@ class Unit_Crypt_TripleDESTest extends PhpseclibTestCase // @codingStandardsIgnoreStart foreach ($engines as $engine => $engineName) foreach ($tests as $test) - $result[] = array($engine, $test[0], $output[1], $output[2]); + $result[] = array($engine, $test[0], $test[1], $test[2]); // @codingStandardsIgnoreEnd return $result; } From 1d2a85a319e653750a51d17a93d73e374b53a4e2 Mon Sep 17 00:00:00 2001 From: terrafrost Date: Thu, 25 Dec 2014 10:09:04 -0600 Subject: [PATCH 39/79] another fix for 3DES unit test --- tests/Unit/Crypt/TripleDESTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Unit/Crypt/TripleDESTest.php b/tests/Unit/Crypt/TripleDESTest.php index 81d9e063..bbcf0c88 100644 --- a/tests/Unit/Crypt/TripleDESTest.php +++ b/tests/Unit/Crypt/TripleDESTest.php @@ -90,7 +90,7 @@ class Unit_Crypt_TripleDESTest extends PhpseclibTestCase // @codingStandardsIgnoreStart foreach ($engines as $engine => $engineName) foreach ($tests as $test) - $result[] = array($engine, $test[0], $test[1], $test[2]); + $result[] = array($engine, $engineName, $test[0], $test[1], $test[2]); // @codingStandardsIgnoreEnd return $result; } From 09c03d0f757b755b6ac9e293d33f177c050fca76 Mon Sep 17 00:00:00 2001 From: terrafrost Date: Sun, 28 Dec 2014 23:15:45 -0600 Subject: [PATCH 40/79] Tests/DES: the expeted output of testDecryptPadding() was incorrect (the expected output can be obtained by setting the key and iv both to 'd') --- tests/Unit/Crypt/DESTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Unit/Crypt/DESTest.php b/tests/Unit/Crypt/DESTest.php index 0d7009e6..20ebf0e3 100644 --- a/tests/Unit/Crypt/DESTest.php +++ b/tests/Unit/Crypt/DESTest.php @@ -55,7 +55,7 @@ class Unit_Crypt_DESTest extends PhpseclibTestCase $des->setPreferredEngine(CRYPT_ENGINE_INTERNAL); $internal = $des->decrypt('d'); - $result = pack('H*', '36a86ebd0f9e048f'); + $result = pack('H*', '79b305d1ce555221'); $this->assertEquals($result, $internal, 'Failed asserting that the internal engine produced the correct result'); $des->setPreferredEngine(CRYPT_ENGINE_MCRYPT); From cf17141930a6c9e2fd8bbb21dae479806d262c5c Mon Sep 17 00:00:00 2001 From: terrafrost Date: Mon, 29 Dec 2014 10:25:31 -0600 Subject: [PATCH 41/79] Tests/TripleDES: disable padding --- tests/Unit/Crypt/TripleDESTest.php | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/Unit/Crypt/TripleDESTest.php b/tests/Unit/Crypt/TripleDESTest.php index bbcf0c88..8b37cbd7 100644 --- a/tests/Unit/Crypt/TripleDESTest.php +++ b/tests/Unit/Crypt/TripleDESTest.php @@ -106,6 +106,7 @@ class Unit_Crypt_TripleDESTest extends PhpseclibTestCase } $des->setPreferredEngine($engine); $des->setKey($key); + $des->disablePadding(); $result = $des->encrypt($plaintext); $plaintext = bin2hex($plaintext); $this->assertEquals($result, $expected, "Failed asserting that $plaintext yielded expected output in $engineName engine"); From 5a915391486ac96c7ef2f2f8ea9b0d80b3ade6c3 Mon Sep 17 00:00:00 2001 From: terrafrost Date: Mon, 29 Dec 2014 22:10:26 -0600 Subject: [PATCH 42/79] SSH2: rm unsupported algorithms if OpenSSL is being used --- phpseclib/Net/SSH2.php | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/phpseclib/Net/SSH2.php b/phpseclib/Net/SSH2.php index a02c57d6..53b110d8 100644 --- a/phpseclib/Net/SSH2.php +++ b/phpseclib/Net/SSH2.php @@ -1091,7 +1091,9 @@ class Net_SSH2 $identifier = 'SSH-2.0-phpseclib_0.3'; $ext = array(); - if (extension_loaded('mcrypt')) { + if (extension_loaded('openssl')) { + $ext[] = 'openssl'; + } elseif (extension_loaded('mcrypt')) { $ext[] = 'mcrypt'; } @@ -1164,6 +1166,14 @@ class Net_SSH2 //'none' // OPTIONAL no encryption; NOT RECOMMENDED ); + if (extension_loaded('openssl')) { + // OpenSSL does not support arcfour256 + $encryption_algorithms = array_diff( + $encryption_algorithms, + array('arcfour256') + ); + } + if (phpseclib_resolve_include_path('Crypt/RC4.php') === false) { $encryption_algorithms = array_diff( $encryption_algorithms, From 46f81c98ab841a89c430bf56d02cf4d91fee8469 Mon Sep 17 00:00:00 2001 From: terrafrost Date: Tue, 30 Dec 2014 00:27:27 -0600 Subject: [PATCH 43/79] Tests/SSH2: update testGenerateIdentifier test --- tests/Unit/Net/SSH2Test.php | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/tests/Unit/Net/SSH2Test.php b/tests/Unit/Net/SSH2Test.php index d166ae45..583422ad 100644 --- a/tests/Unit/Net/SSH2Test.php +++ b/tests/Unit/Net/SSH2Test.php @@ -41,9 +41,14 @@ class Unit_Net_SSH2Test extends PhpseclibTestCase $identifier = $this->createSSHMock()->_generate_identifier(); $this->assertStringStartsWith('SSH-2.0-phpseclib_0.3', $identifier); - if (extension_loaded('mcrypt')) { + if (extension_loaded('openssl')) { + $this->assertContains('openssl', $identifier); + $this->assertNotContains('mcrypt', $identifier); + } else if (extension_loaded('mcrypt') { + $this->assertNotContains('openssl', $identifier); $this->assertContains('mcrypt', $identifier); } else { + $this->assertNotContains('openssl', $identifier); $this->assertNotContains('mcrypt', $identifier); } From 162e2f26cf0d4ae522adc1777d4e8c2df1fa818c Mon Sep 17 00:00:00 2001 From: terrafrost Date: Tue, 30 Dec 2014 00:57:01 -0600 Subject: [PATCH 44/79] Tests/SSH2: syntax error --- tests/Unit/Net/SSH2Test.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Unit/Net/SSH2Test.php b/tests/Unit/Net/SSH2Test.php index 583422ad..7c3ff2e2 100644 --- a/tests/Unit/Net/SSH2Test.php +++ b/tests/Unit/Net/SSH2Test.php @@ -44,7 +44,7 @@ class Unit_Net_SSH2Test extends PhpseclibTestCase if (extension_loaded('openssl')) { $this->assertContains('openssl', $identifier); $this->assertNotContains('mcrypt', $identifier); - } else if (extension_loaded('mcrypt') { + } else if (extension_loaded('mcrypt')) { $this->assertNotContains('openssl', $identifier); $this->assertContains('mcrypt', $identifier); } else { From e3487c8adb4b3c79f10028f7dc174f81ce924427 Mon Sep 17 00:00:00 2001 From: terrafrost Date: Tue, 30 Dec 2014 23:33:12 -0600 Subject: [PATCH 45/79] RC4: use the parent encrypt / decrypt methods if openssl is being used --- phpseclib/Crypt/RC4.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/phpseclib/Crypt/RC4.php b/phpseclib/Crypt/RC4.php index e2883fe0..07827e99 100644 --- a/phpseclib/Crypt/RC4.php +++ b/phpseclib/Crypt/RC4.php @@ -248,7 +248,7 @@ class Crypt_RC4 extends Crypt_Base */ function encrypt($plaintext) { - if ($this->engine == CRYPT_ENGINE_MCRYPT) { + if ($this->engine != CRYPT_ENGINE_INTERNAL) { return parent::encrypt($plaintext); } return $this->_crypt($plaintext, CRYPT_RC4_ENCRYPT); @@ -268,7 +268,7 @@ class Crypt_RC4 extends Crypt_Base */ function decrypt($ciphertext) { - if ($this->engine == CRYPT_ENGINE_MCRYPT) { + if ($this->engine != CRYPT_ENGINE_INTERNAL) { return parent::decrypt($ciphertext); } return $this->_crypt($ciphertext, CRYPT_RC4_DECRYPT); From be168e262ffdddd5f7334f38dec13ebc73eee32e Mon Sep 17 00:00:00 2001 From: terrafrost Date: Wed, 31 Dec 2014 14:10:53 -0600 Subject: [PATCH 46/79] Crypt/Base: stream ciphers cannot be run in continuous mode with OpenSSL --- phpseclib/Crypt/Base.php | 7 +++++++ phpseclib/Net/SSH2.php | 7 ++++--- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/phpseclib/Crypt/Base.php b/phpseclib/Crypt/Base.php index 17e8d110..b0f21ed6 100644 --- a/phpseclib/Crypt/Base.php +++ b/phpseclib/Crypt/Base.php @@ -1498,6 +1498,8 @@ class Crypt_Base } $this->continuousBuffer = true; + + $this->_setEngine(); } /** @@ -1520,6 +1522,8 @@ class Crypt_Base $this->continuousBuffer = false; $this->changed = true; + + $this->_setEngine(); } /** @@ -1534,6 +1538,9 @@ class Crypt_Base { switch ($engine) { case CRYPT_ENGINE_OPENSSL: + if ($this->mode == CRYPT_MODE_STREAM && $this->continuousBuffer) { + return false; + } $this->openssl_emulate_ctr = false; $result = $this->cipher_name_openssl && extension_loaded('openssl') && diff --git a/phpseclib/Net/SSH2.php b/phpseclib/Net/SSH2.php index 53b110d8..4d230b14 100644 --- a/phpseclib/Net/SSH2.php +++ b/phpseclib/Net/SSH2.php @@ -1166,11 +1166,12 @@ class Net_SSH2 //'none' // OPTIONAL no encryption; NOT RECOMMENDED ); - if (extension_loaded('openssl')) { - // OpenSSL does not support arcfour256 + if (extension_loaded('openssl') && !extension_loaded('mcrypt')) { + // OpenSSL does not support arcfour256 in any capacity and arcfour128 / arcfour support is limited to + // instances that do not use continuous buffers $encryption_algorithms = array_diff( $encryption_algorithms, - array('arcfour256') + array('arcfour256', 'arcfour128', 'arcfour') ); } From f9451c826a3cd23bf0e429db4c21121f7ac9d83a Mon Sep 17 00:00:00 2001 From: terrafrost Date: Wed, 31 Dec 2014 15:00:54 -0600 Subject: [PATCH 47/79] Tests/AES: add testNonContinuousBufferBatteryCombos --- tests/Unit/Crypt/AES/TestCase.php | 43 +++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/tests/Unit/Crypt/AES/TestCase.php b/tests/Unit/Crypt/AES/TestCase.php index e885ae5c..0fd4add9 100644 --- a/tests/Unit/Crypt/AES/TestCase.php +++ b/tests/Unit/Crypt/AES/TestCase.php @@ -205,4 +205,47 @@ abstract class Unit_Crypt_AES_TestCase extends PhpseclibTestCase $this->assertSame(bin2hex($c1), bin2hex($c2)); } + + /** + * @dataProvider continuousBufferBatteryCombos + */ + // pretty much the same as testContinuousBufferBattery with the caveat that continuous mode is not enabled + public function testNonContinuousBufferBattery($op, $mode, $test) + { + $iv = str_repeat('x', 16); + $key = str_repeat('a', 16); + + $aes = new Crypt_AES(constant($mode)); + $aes->setPreferredEngine($this->engine); + $aes->setKey($key); + $aes->setIV($iv); + + $this->_checkEngine($aes); + + $str = ''; + $result = ''; + foreach ($test as $len) { + $temp = str_repeat('d', $len); + $str.= $temp; + } + + $c1 = $aes->$op($str); + + $aes = new Crypt_AES(constant($mode)); + $aes->setPreferredEngine($this->engine); + $aes->setKey($key); + $aes->setIV($iv); + + $this->_checkEngine($aes); + + foreach ($test as $len) { + $temp = str_repeat('d', $len); + $output = $aes->$op($temp); + $result.= $output; + } + + $c2 = $result; + + $this->assertNotSame(bin2hex($c1), bin2hex($c2)); + } } From 50a0ae7b6e4e20c9212608a04e073293df0ddfb9 Mon Sep 17 00:00:00 2001 From: terrafrost Date: Wed, 31 Dec 2014 15:15:15 -0600 Subject: [PATCH 48/79] Test/AES: don't test stuff with only one buffer --- tests/Unit/Crypt/AES/TestCase.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/Unit/Crypt/AES/TestCase.php b/tests/Unit/Crypt/AES/TestCase.php index 0fd4add9..c4bcc80c 100644 --- a/tests/Unit/Crypt/AES/TestCase.php +++ b/tests/Unit/Crypt/AES/TestCase.php @@ -212,6 +212,10 @@ abstract class Unit_Crypt_AES_TestCase extends PhpseclibTestCase // pretty much the same as testContinuousBufferBattery with the caveat that continuous mode is not enabled public function testNonContinuousBufferBattery($op, $mode, $test) { + if (count($test) == 1) { + return; + } + $iv = str_repeat('x', 16); $key = str_repeat('a', 16); From 9199e624b2578e1295ecf451e2d727e6209a8cf7 Mon Sep 17 00:00:00 2001 From: terrafrost Date: Wed, 31 Dec 2014 15:41:43 -0600 Subject: [PATCH 49/79] Tests/TripleDES: add more test vectors --- tests/Unit/Crypt/TripleDESTest.php | 49 ++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/tests/Unit/Crypt/TripleDESTest.php b/tests/Unit/Crypt/TripleDESTest.php index 8b37cbd7..2dc06ee9 100644 --- a/tests/Unit/Crypt/TripleDESTest.php +++ b/tests/Unit/Crypt/TripleDESTest.php @@ -111,4 +111,53 @@ class Unit_Crypt_TripleDESTest extends PhpseclibTestCase $plaintext = bin2hex($plaintext); $this->assertEquals($result, $expected, "Failed asserting that $plaintext yielded expected output in $engineName engine"); } + + public function engineIVVectors() + { + $engines = array( + CRYPT_ENGINE_INTERNAL => 'internal', + CRYPT_ENGINE_MCRYPT => 'mcrypt', + CRYPT_ENGINE_OPENSSL => 'OpenSSL', + ); + + // tests from http://csrc.nist.gov/groups/STM/cavp/documents/des/DESMMT.pdf + $tests = array( + // key, iv, plaintext, ciphertext + array( + pack('H*', '627f460e08104a10' . '43cd265d5840eaf1' . '313edf97df2a8a8c'), + pack('H*', '8e29f75ea77e5475'), + pack('H*', '326a494cd33fe756'), + pack('H*', 'b22b8d66de970692')), + array( + pack('H*', '37ae5ebf46dff2dc' . '0754b94f31cbb385' . '5e7fd36dc870bfae'), + pack('H*', '3d1de3cc132e3b65'), + pack('H*', '84401f78fe6c10876d8ea23094ea5309'), + pack('H*', '7b1f7c7e3b1c948ebd04a75ffba7d2f5')) + ); + $result = array(); + // @codingStandardsIgnoreStart + foreach ($engines as $engine => $engineName) + foreach ($tests as $test) + $result[] = array($engine, $engineName, $test[0], $test[1], $test[2]); + // @codingStandardsIgnoreEnd + return $result; + } + + /** + * @dataProvider engineIVVectors + */ + public function testVectorsWithIV($engine, $engineName, $key, $iv, $plaintext, $expected) + { + $des = new Crypt_TripleDES(); + if (!$des->isValidEngine($engine)) { + self::markTestSkipped('Unable to initialize ' . $engineName . ' engine'); + } + $des->setPreferredEngine($engine); + $des->setKey($key); + $des->setIV($iv); + $des->disablePadding(); + $result = $des->encrypt($plaintext); + $plaintext = bin2hex($plaintext); + $this->assertEquals($result, $expected, "Failed asserting that $plaintext yielded expected output in $engineName engine"); + } } From 805c99458ba7e0770ee20d57176178f2f0b6c179 Mon Sep 17 00:00:00 2001 From: terrafrost Date: Wed, 31 Dec 2014 19:18:57 -0600 Subject: [PATCH 50/79] Tests/TripleDES: fix data provider for new test vectors --- tests/Unit/Crypt/TripleDESTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Unit/Crypt/TripleDESTest.php b/tests/Unit/Crypt/TripleDESTest.php index 2dc06ee9..ba650996 100644 --- a/tests/Unit/Crypt/TripleDESTest.php +++ b/tests/Unit/Crypt/TripleDESTest.php @@ -138,7 +138,7 @@ class Unit_Crypt_TripleDESTest extends PhpseclibTestCase // @codingStandardsIgnoreStart foreach ($engines as $engine => $engineName) foreach ($tests as $test) - $result[] = array($engine, $engineName, $test[0], $test[1], $test[2]); + $result[] = array($engine, $engineName, $test[0], $test[1], $test[2], $test[3]); // @codingStandardsIgnoreEnd return $result; } From b831724e1adfb58b663f1a3d5acd05d0b279ce95 Mon Sep 17 00:00:00 2001 From: terrafrost Date: Wed, 31 Dec 2014 22:24:56 -0600 Subject: [PATCH 51/79] Crypt/Base: don't always treat CTR as being continuous w/ OpenSSL --- phpseclib/Crypt/Base.php | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/phpseclib/Crypt/Base.php b/phpseclib/Crypt/Base.php index b0f21ed6..3f2d8a20 100644 --- a/phpseclib/Crypt/Base.php +++ b/phpseclib/Crypt/Base.php @@ -1327,19 +1327,26 @@ class Crypt_Base if ($overflow) { $plaintext2 = $this->_string_pop($plaintext, $overflow); // ie. trim $plaintext to a multiple of $block_size and put rest of $plaintext in $plaintext2 $encrypted = openssl_encrypt($plaintext . str_repeat("\0", $block_size), $this->cipher_name_openssl, $key, $this->openssl_options, $encryptIV); - $encryptIV = $this->_string_pop($encrypted, $block_size); - $ciphertext.= $encrypted . ($plaintext2 ^ $encryptIV); - $buffer['ciphertext'] = substr($encryptIV, $overflow); + $temp = $this->_string_pop($encrypted, $block_size); + $ciphertext.= $encrypted . ($plaintext2 ^ $temp); + if ($this->continuousBuffer) { + $buffer['ciphertext'] = substr($temp, $overflow); + $encryptIV = $temp; + } } else if (!strlen($buffer['ciphertext'])) { $ciphertext.= openssl_encrypt($plaintext . str_repeat("\0", $block_size), $this->cipher_name_openssl, $key, $this->openssl_options, $encryptIV); - $encryptIV = $this->_string_pop($ciphertext, $block_size); + if ($this->continuousBuffer) { + $encryptIV = $this->_string_pop($ciphertext, $block_size); + } } - if (!defined('OPENSSL_RAW_DATA')) { - $encryptIV.= openssl_encrypt('', $this->cipher_name_openssl_ecb, $key, $this->openssl_options); - } - $encryptIV = openssl_decrypt($encryptIV, $this->cipher_name_openssl_ecb, $key, $this->openssl_options); - if ($overflow) { - $this->_increment_str($encryptIV); + if ($this->continuousBuffer) { + if (!defined('OPENSSL_RAW_DATA')) { + $encryptIV.= openssl_encrypt('', $this->cipher_name_openssl_ecb, $key, $this->openssl_options); + } + $encryptIV = openssl_decrypt($encryptIV, $this->cipher_name_openssl_ecb, $key, $this->openssl_options); + if ($overflow) { + $this->_increment_str($encryptIV); + } } return $ciphertext; From bb6689add35840ab554b84c2e8b73632a3b1f582 Mon Sep 17 00:00:00 2001 From: terrafrost Date: Wed, 31 Dec 2014 22:32:55 -0600 Subject: [PATCH 52/79] Tests/AES: use better error message --- tests/Unit/Crypt/AES/TestCase.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Unit/Crypt/AES/TestCase.php b/tests/Unit/Crypt/AES/TestCase.php index c4bcc80c..8bc8bc41 100644 --- a/tests/Unit/Crypt/AES/TestCase.php +++ b/tests/Unit/Crypt/AES/TestCase.php @@ -250,6 +250,6 @@ abstract class Unit_Crypt_AES_TestCase extends PhpseclibTestCase $c2 = $result; - $this->assertNotSame(bin2hex($c1), bin2hex($c2)); + $this->assertNotSame(bin2hex($c1), bin2hex($c2), "{$this->engine} produced identical results for '$op' in $mode with " . implode(',', $test)); } } From 289ef9a2b75468ccc38c34960422bc7c2207c658 Mon Sep 17 00:00:00 2001 From: terrafrost Date: Wed, 31 Dec 2014 22:46:16 -0600 Subject: [PATCH 53/79] Tests/AES: improve error message for continuous buffer test as well --- tests/Unit/Crypt/AES/TestCase.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Unit/Crypt/AES/TestCase.php b/tests/Unit/Crypt/AES/TestCase.php index 8bc8bc41..baa7d1e6 100644 --- a/tests/Unit/Crypt/AES/TestCase.php +++ b/tests/Unit/Crypt/AES/TestCase.php @@ -203,7 +203,7 @@ abstract class Unit_Crypt_AES_TestCase extends PhpseclibTestCase $c2 = $result; - $this->assertSame(bin2hex($c1), bin2hex($c2)); + $this->assertSame(bin2hex($c1), bin2hex($c2), "{$this->engine} produced different results for '$op' in $mode with " . implode(',', $test)); } /** From dffde1fffc89681aaef3dc1a250c126cea3de4d8 Mon Sep 17 00:00:00 2001 From: terrafrost Date: Wed, 31 Dec 2014 23:02:22 -0600 Subject: [PATCH 54/79] Tests/AES: rm last two commits - this info can already be derived --- tests/Unit/Crypt/AES/TestCase.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/Unit/Crypt/AES/TestCase.php b/tests/Unit/Crypt/AES/TestCase.php index baa7d1e6..c4bcc80c 100644 --- a/tests/Unit/Crypt/AES/TestCase.php +++ b/tests/Unit/Crypt/AES/TestCase.php @@ -203,7 +203,7 @@ abstract class Unit_Crypt_AES_TestCase extends PhpseclibTestCase $c2 = $result; - $this->assertSame(bin2hex($c1), bin2hex($c2), "{$this->engine} produced different results for '$op' in $mode with " . implode(',', $test)); + $this->assertSame(bin2hex($c1), bin2hex($c2)); } /** @@ -250,6 +250,6 @@ abstract class Unit_Crypt_AES_TestCase extends PhpseclibTestCase $c2 = $result; - $this->assertNotSame(bin2hex($c1), bin2hex($c2), "{$this->engine} produced identical results for '$op' in $mode with " . implode(',', $test)); + $this->assertNotSame(bin2hex($c1), bin2hex($c2)); } } From 7b58268d58b33fb4568894b70fdd96c4971cd652 Mon Sep 17 00:00:00 2001 From: terrafrost Date: Wed, 31 Dec 2014 23:38:55 -0600 Subject: [PATCH 55/79] Crypt/Base: fix bug with openssl non-continuous CTR mode --- phpseclib/Crypt/Base.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/phpseclib/Crypt/Base.php b/phpseclib/Crypt/Base.php index 3f2d8a20..49ad303a 100644 --- a/phpseclib/Crypt/Base.php +++ b/phpseclib/Crypt/Base.php @@ -1335,8 +1335,9 @@ class Crypt_Base } } else if (!strlen($buffer['ciphertext'])) { $ciphertext.= openssl_encrypt($plaintext . str_repeat("\0", $block_size), $this->cipher_name_openssl, $key, $this->openssl_options, $encryptIV); + $temp = $this->_string_pop($ciphertext, $block_size); if ($this->continuousBuffer) { - $encryptIV = $this->_string_pop($ciphertext, $block_size); + $encryptIV = $temp; } } if ($this->continuousBuffer) { From b24e7c3fc97dac5d121ac721fae59f2ff0de3cdf Mon Sep 17 00:00:00 2001 From: terrafrost Date: Thu, 1 Jan 2015 00:27:30 -0600 Subject: [PATCH 56/79] Crypt/Base: don't modify the IV when the mode isn't continuous for CFB --- phpseclib/Crypt/Base.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/phpseclib/Crypt/Base.php b/phpseclib/Crypt/Base.php index 49ad303a..4b56246e 100644 --- a/phpseclib/Crypt/Base.php +++ b/phpseclib/Crypt/Base.php @@ -711,7 +711,7 @@ class Crypt_Base $iv = &$this->encryptIV; $pos = &$this->enbuffer['pos']; } else { - $iv = &$this->encryptIV; + $iv = $this->encryptIV; $pos = 0; } $len = strlen($plaintext); From 4766973e6104ec7c32983a3718951125801c20ca Mon Sep 17 00:00:00 2001 From: terrafrost Date: Thu, 1 Jan 2015 23:56:01 -0600 Subject: [PATCH 57/79] Tests/AES: add official test vectors to test --- tests/Unit/Crypt/AES/TestCase.php | 73 +++++++++++++++++++++++++++++++ 1 file changed, 73 insertions(+) diff --git a/tests/Unit/Crypt/AES/TestCase.php b/tests/Unit/Crypt/AES/TestCase.php index c4bcc80c..2b71d94f 100644 --- a/tests/Unit/Crypt/AES/TestCase.php +++ b/tests/Unit/Crypt/AES/TestCase.php @@ -252,4 +252,77 @@ abstract class Unit_Crypt_AES_TestCase extends PhpseclibTestCase $this->assertNotSame(bin2hex($c1), bin2hex($c2)); } + + // from http://csrc.nist.gov/groups/STM/cavp/documents/aes/AESAVS.pdf#page=16 + public function testGFSBox128() + { + $aes = new Crypt_AES(); + + $aes->setKey(pack('H*', '00000000000000000000000000000000')); + $aes->setIV(pack('H*', '00000000000000000000000000000000')); + + $aes->setPreferredEngine($this->engine); + $this->_checkEngine($aes); + + $result = $aes->encrypt('f34481ec3cc627bacd5dc3fb08f273e6'); + $this->assertSame($result, '0336763e966d92595a567cc9ce537f5e'); + $result = $aes->encrypt('9798c4640bad75c7c3227db910174e72'); + $this->assertSame($result, 'a9a1631bf4996954ebc093957b234589'); + $result = $aes->encrypt('96ab5c2ff612d9dfaae8c31f30c42168'); + $this->assertSame($result, 'ff4f8391a6a40ca5b25d23bedd44a597'); + $result = $aes->encrypt('6a118a874519e64e9963798a503f1d35'); + $this->assertSame($result, 'dc43be40be0e53712f7e2bf5ca707209'); + $result = $aes->encrypt('cb9fceec81286ca3e989bd979b0cb284'); + $this->assertSame($result, '92beedab1895a94faa69b632e5cc47ce'); + $result = $aes->encrypt('b26aeb1874e47ca8358ff22378f09144'); + $this->assertSame($result, '459264f4798f6a78bacb89c15ed3d601'); + $result = $aes->encrypt('58c8e00b2631686d54eab84b91f0aca1'); + $this->assertSame($result, '08a4e2efec8a8e3312ca7460b9040bbf'); + } + + public function testGFSBox192() + { + $aes = new Crypt_AES(); + + $aes->setKey(pack('H*', '000000000000000000000000000000000000000000000000')); + $aes->setIV(pack('H*', '00000000000000000000000000000000')); + + $aes->setPreferredEngine($this->engine); + $this->_checkEngine($aes); + + $result = $aes->encrypt('1b077a6af4b7f98229de786d7516b639'); + $this->assertSame($result, '275cfc0413d8ccb70513c3859b1d0f72'); + $result = $aes->encrypt('9c2d8842e5f48f57648205d39a239af1'); + $this->assertSame($result, 'c9b8135ff1b5adc413dfd053b21bd96d'); + $result = $aes->encrypt('bff52510095f518ecca60af4205444bb'); + $this->assertSame($result, '4a3650c3371ce2eb35e389a171427440'); + $result = $aes->encrypt('51719783d3185a535bd75adc65071ce1'); + $this->assertSame($result, '4f354592ff7c8847d2d0870ca9481b7c'); + $result = $aes->encrypt('26aa49dcfe7629a8901a69a9914e6dfd'); + $this->assertSame($result, 'd5e08bf9a182e857cf40b3a36ee248cc'); + $result = $aes->encrypt('941a4773058224e1ef66d10e0a6ee782'); + $this->assertSame($result, '067cd9d3749207791841562507fa9626'); + } + + public function testGFSBox256() + { + $aes = new Crypt_AES(); + + $aes->setKey(pack('H*', '00000000000000000000000000000000' . '00000000000000000000000000000000')); + $aes->setIV(pack('H*', '00000000000000000000000000000000')); + + $aes->setPreferredEngine($this->engine); + $this->_checkEngine($aes); + + $result = $aes->encrypt('014730f80ac625fe84f026c60bfd547d'); + $this->assertSame($result, '5c9d844ed46f9885085e5d6a4f94c7d7'); + $result = $aes->encrypt('0b24af36193ce4665f2825d7b4749c98'); + $this->assertSame($result, 'a9ff75bd7cf6613d3731c77c3b6d0c04'); + $result = $aes->encrypt('761c1fe41a18acf20d241650611d90f1'); + $this->assertSame($result, '623a52fcea5d443e48d9181ab32c7421'); + $result = $aes->encrypt('8a560769d605868ad80d819bdba03771'); + $this->assertSame($result, '38f2c7ae10612415d27ca190d27da8b4'); + $result = $aes->encrypt('91fbef2d15a97816060bee1feaa49afe'); + $this->assertSame($result, '1bc704f1bce135ceb810341b216d7abe'); + } } From e75d94663ebbc7ffe9bb7ba7ad1ee633f3e4a2c8 Mon Sep 17 00:00:00 2001 From: terrafrost Date: Wed, 7 Jan 2015 21:14:02 -0600 Subject: [PATCH 58/79] Tests/AES: use bin2hex for result comparison --- tests/Unit/Crypt/AES/TestCase.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/Unit/Crypt/AES/TestCase.php b/tests/Unit/Crypt/AES/TestCase.php index 2b71d94f..114f1507 100644 --- a/tests/Unit/Crypt/AES/TestCase.php +++ b/tests/Unit/Crypt/AES/TestCase.php @@ -264,7 +264,7 @@ abstract class Unit_Crypt_AES_TestCase extends PhpseclibTestCase $aes->setPreferredEngine($this->engine); $this->_checkEngine($aes); - $result = $aes->encrypt('f34481ec3cc627bacd5dc3fb08f273e6'); + $result = bin2hex($aes->encrypt('f34481ec3cc627bacd5dc3fb08f273e6')); $this->assertSame($result, '0336763e966d92595a567cc9ce537f5e'); $result = $aes->encrypt('9798c4640bad75c7c3227db910174e72'); $this->assertSame($result, 'a9a1631bf4996954ebc093957b234589'); @@ -290,7 +290,7 @@ abstract class Unit_Crypt_AES_TestCase extends PhpseclibTestCase $aes->setPreferredEngine($this->engine); $this->_checkEngine($aes); - $result = $aes->encrypt('1b077a6af4b7f98229de786d7516b639'); + $result = bin2hex($aes->encrypt('1b077a6af4b7f98229de786d7516b639')); $this->assertSame($result, '275cfc0413d8ccb70513c3859b1d0f72'); $result = $aes->encrypt('9c2d8842e5f48f57648205d39a239af1'); $this->assertSame($result, 'c9b8135ff1b5adc413dfd053b21bd96d'); @@ -314,7 +314,7 @@ abstract class Unit_Crypt_AES_TestCase extends PhpseclibTestCase $aes->setPreferredEngine($this->engine); $this->_checkEngine($aes); - $result = $aes->encrypt('014730f80ac625fe84f026c60bfd547d'); + $result = bin2hex($aes->encrypt('014730f80ac625fe84f026c60bfd547d')); $this->assertSame($result, '5c9d844ed46f9885085e5d6a4f94c7d7'); $result = $aes->encrypt('0b24af36193ce4665f2825d7b4749c98'); $this->assertSame($result, 'a9ff75bd7cf6613d3731c77c3b6d0c04'); From b34a05887c76452d8f9befd026dbc389ed00a86b Mon Sep 17 00:00:00 2001 From: terrafrost Date: Wed, 7 Jan 2015 21:23:04 -0600 Subject: [PATCH 59/79] Tests: add Blowfish test --- tests/Unit/Crypt/BlowfishTest.php | 84 +++++++++++++++++++++++++++++++ 1 file changed, 84 insertions(+) create mode 100644 tests/Unit/Crypt/BlowfishTest.php diff --git a/tests/Unit/Crypt/BlowfishTest.php b/tests/Unit/Crypt/BlowfishTest.php new file mode 100644 index 00000000..ab091f0b --- /dev/null +++ b/tests/Unit/Crypt/BlowfishTest.php @@ -0,0 +1,84 @@ + + * @copyright MMXIII Andreas Fischer + * @license http://www.opensource.org/licenses/mit-license.html MIT License + */ + +require_once 'Crypt/Blowfish.php'; + +class Unit_Crypt_BlowfishTest extends PhpseclibTestCase +{ + public function engineVectors() + { + $engines = array( + CRYPT_ENGINE_INTERNAL => 'internal', + CRYPT_ENGINE_MCRYPT => 'mcrypt', + CRYPT_ENGINE_OPENSSL => 'OpenSSL', + ); + + // tests from https://www.schneier.com/code/vectors.txt + $tests = array( + // key, plaintext, ciphertext + array(pack('H*', '0000000000000000'), pack('H*', '0000000000000000'), pack('H*', '4EF997456198DD78')), + array(pack('H*', 'FFFFFFFFFFFFFFFF'), pack('H*', 'FFFFFFFFFFFFFFFF'), pack('H*', '51866FD5B85ECB8A')), + array(pack('H*', '3000000000000000'), pack('H*', '1000000000000001'), pack('H*', '7D856F9A613063F2')), + array(pack('H*', '1111111111111111'), pack('H*', '1111111111111111'), pack('H*', '2466DD878B963C9D')), + array(pack('H*', '0123456789ABCDEF'), pack('H*', '1111111111111111'), pack('H*', '61F9C3802281B096')), + array(pack('H*', '1111111111111111'), pack('H*', '0123456789ABCDEF'), pack('H*', '7D0CC630AFDA1EC7')), + array(pack('H*', '0000000000000000'), pack('H*', '0000000000000000'), pack('H*', '4EF997456198DD78')), + array(pack('H*', 'FEDCBA9876543210'), pack('H*', '0123456789ABCDEF'), pack('H*', '0ACEAB0FC6A0A28D')), + array(pack('H*', '7CA110454A1A6E57'), pack('H*', '01A1D6D039776742'), pack('H*', '59C68245EB05282B')), + array(pack('H*', '0131D9619DC1376E'), pack('H*', '5CD54CA83DEF57DA'), pack('H*', 'B1B8CC0B250F09A0')), + array(pack('H*', '07A1133E4A0B2686'), pack('H*', '0248D43806F67172'), pack('H*', '1730E5778BEA1DA4')), + array(pack('H*', '3849674C2602319E'), pack('H*', '51454B582DDF440A'), pack('H*', 'A25E7856CF2651EB')), + array(pack('H*', '04B915BA43FEB5B6'), pack('H*', '42FD443059577FA2'), pack('H*', '353882B109CE8F1A')), + array(pack('H*', '0113B970FD34F2CE'), pack('H*', '059B5E0851CF143A'), pack('H*', '48F4D0884C379918')), + array(pack('H*', '0170F175468FB5E6'), pack('H*', '0756D8E0774761D2'), pack('H*', '432193B78951FC98')), + array(pack('H*', '43297FAD38E373FE'), pack('H*', '762514B829BF486A'), pack('H*', '13F04154D69D1AE5')), + array(pack('H*', '07A7137045DA2A16'), pack('H*', '3BDD119049372802'), pack('H*', '2EEDDA93FFD39C79')), + array(pack('H*', '04689104C2FD3B2F'), pack('H*', '26955F6835AF609A'), pack('H*', 'D887E0393C2DA6E3')), + array(pack('H*', '37D06BB516CB7546'), pack('H*', '164D5E404F275232'), pack('H*', '5F99D04F5B163969')), + array(pack('H*', '1F08260D1AC2465E'), pack('H*', '6B056E18759F5CCA'), pack('H*', '4A057A3B24D3977B')), + array(pack('H*', '584023641ABA6176'), pack('H*', '004BD6EF09176062'), pack('H*', '452031C1E4FADA8E')), + array(pack('H*', '025816164629B007'), pack('H*', '480D39006EE762F2'), pack('H*', '7555AE39F59B87BD')), + array(pack('H*', '49793EBC79B3258F'), pack('H*', '437540C8698F3CFA'), pack('H*', '53C55F9CB49FC019')), + array(pack('H*', '4FB05E1515AB73A7'), pack('H*', '072D43A077075292'), pack('H*', '7A8E7BFA937E89A3')), + array(pack('H*', '49E95D6D4CA229BF'), pack('H*', '02FE55778117F12A'), pack('H*', 'CF9C5D7A4986ADB5')), + array(pack('H*', '018310DC409B26D6'), pack('H*', '1D9D5C5018F728C2'), pack('H*', 'D1ABB290658BC778')), + array(pack('H*', '1C587F1C13924FEF'), pack('H*', '305532286D6F295A'), pack('H*', '55CB3774D13EF201')), + array(pack('H*', '0101010101010101'), pack('H*', '0123456789ABCDEF'), pack('H*', 'FA34EC4847B268B2')), + array(pack('H*', '1F1F1F1F0E0E0E0E'), pack('H*', '0123456789ABCDEF'), pack('H*', 'A790795108EA3CAE')), + array(pack('H*', 'E0FEE0FEF1FEF1FE'), pack('H*', '0123456789ABCDEF'), pack('H*', 'C39E072D9FAC631D')), + array(pack('H*', '0000000000000000'), pack('H*', 'FFFFFFFFFFFFFFFF'), pack('H*', '014933E0CDAFF6E4')), + array(pack('H*', 'FFFFFFFFFFFFFFFF'), pack('H*', '0000000000000000'), pack('H*', 'F21E9A77B71C49BC')), + array(pack('H*', '0123456789ABCDEF'), pack('H*', '0000000000000000'), pack('H*', '245946885754369A')), + array(pack('H*', 'FEDCBA9876543210'), pack('H*', 'FFFFFFFFFFFFFFFF'), pack('H*', '6B5C5A9C5D9E0A5A')) + ); + $result = array(); + // @codingStandardsIgnoreStart + foreach ($engines as $engine => $engineName) + foreach ($tests as $test) + $result[] = array($engine, $engineName, $test[0], $test[1], $test[2]); + // @codingStandardsIgnoreEnd + return $result; + } + + /** + * @dataProvider engineVectors + */ + public function testVectors($engine, $engineName, $key, $plaintext, $expected) + { + $bf = new Crypt_Blowfish(); + $bf->setKey($key); + if (!$bf->isValidEngine($engine)) { + self::markTestSkipped('Unable to initialize ' . $engineName . ' engine'); + } + $bf->setPreferredEngine($engine); + $bf->disablePadding(); + $result = $bf->encrypt($plaintext); + $plaintext = bin2hex($plaintext); + $this->assertEquals($result, $expected, "Failed asserting that $plaintext yielded expected output in $engineName engine"); + } +} + From 8713e940010528cbfacac2275cbc5721085cef75 Mon Sep 17 00:00:00 2001 From: terrafrost Date: Wed, 7 Jan 2015 21:36:02 -0600 Subject: [PATCH 60/79] Tests/AES: disable padding --- tests/Unit/Crypt/AES/TestCase.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/Unit/Crypt/AES/TestCase.php b/tests/Unit/Crypt/AES/TestCase.php index 114f1507..36432092 100644 --- a/tests/Unit/Crypt/AES/TestCase.php +++ b/tests/Unit/Crypt/AES/TestCase.php @@ -260,6 +260,7 @@ abstract class Unit_Crypt_AES_TestCase extends PhpseclibTestCase $aes->setKey(pack('H*', '00000000000000000000000000000000')); $aes->setIV(pack('H*', '00000000000000000000000000000000')); + $aes->disablePadding(); $aes->setPreferredEngine($this->engine); $this->_checkEngine($aes); @@ -286,6 +287,7 @@ abstract class Unit_Crypt_AES_TestCase extends PhpseclibTestCase $aes->setKey(pack('H*', '000000000000000000000000000000000000000000000000')); $aes->setIV(pack('H*', '00000000000000000000000000000000')); + $aes->disablePadding(); $aes->setPreferredEngine($this->engine); $this->_checkEngine($aes); @@ -310,6 +312,7 @@ abstract class Unit_Crypt_AES_TestCase extends PhpseclibTestCase $aes->setKey(pack('H*', '00000000000000000000000000000000' . '00000000000000000000000000000000')); $aes->setIV(pack('H*', '00000000000000000000000000000000')); + $aes->disablePadding(); $aes->setPreferredEngine($this->engine); $this->_checkEngine($aes); From 3485242ef6cb175e6a5bc7055ceb105c5d147a5c Mon Sep 17 00:00:00 2001 From: terrafrost Date: Wed, 7 Jan 2015 22:55:35 -0600 Subject: [PATCH 61/79] Tests/AES: pack plaintext prior to encryption --- tests/Unit/Crypt/AES/TestCase.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/Unit/Crypt/AES/TestCase.php b/tests/Unit/Crypt/AES/TestCase.php index 36432092..fa59e606 100644 --- a/tests/Unit/Crypt/AES/TestCase.php +++ b/tests/Unit/Crypt/AES/TestCase.php @@ -265,7 +265,7 @@ abstract class Unit_Crypt_AES_TestCase extends PhpseclibTestCase $aes->setPreferredEngine($this->engine); $this->_checkEngine($aes); - $result = bin2hex($aes->encrypt('f34481ec3cc627bacd5dc3fb08f273e6')); + $result = bin2hex($aes->encrypt(pack('H*', 'f34481ec3cc627bacd5dc3fb08f273e6'))); $this->assertSame($result, '0336763e966d92595a567cc9ce537f5e'); $result = $aes->encrypt('9798c4640bad75c7c3227db910174e72'); $this->assertSame($result, 'a9a1631bf4996954ebc093957b234589'); @@ -292,7 +292,7 @@ abstract class Unit_Crypt_AES_TestCase extends PhpseclibTestCase $aes->setPreferredEngine($this->engine); $this->_checkEngine($aes); - $result = bin2hex($aes->encrypt('1b077a6af4b7f98229de786d7516b639')); + $result = bin2hex($aes->encrypt(pack('H*', '1b077a6af4b7f98229de786d7516b639'))); $this->assertSame($result, '275cfc0413d8ccb70513c3859b1d0f72'); $result = $aes->encrypt('9c2d8842e5f48f57648205d39a239af1'); $this->assertSame($result, 'c9b8135ff1b5adc413dfd053b21bd96d'); @@ -317,7 +317,7 @@ abstract class Unit_Crypt_AES_TestCase extends PhpseclibTestCase $aes->setPreferredEngine($this->engine); $this->_checkEngine($aes); - $result = bin2hex($aes->encrypt('014730f80ac625fe84f026c60bfd547d')); + $result = bin2hex($aes->encrypt(pack('H*', '014730f80ac625fe84f026c60bfd547d'))); $this->assertSame($result, '5c9d844ed46f9885085e5d6a4f94c7d7'); $result = $aes->encrypt('0b24af36193ce4665f2825d7b4749c98'); $this->assertSame($result, 'a9ff75bd7cf6613d3731c77c3b6d0c04'); From cd57289555c5308cf51253336a5ca16fc9542877 Mon Sep 17 00:00:00 2001 From: terrafrost Date: Wed, 14 Jan 2015 20:19:03 -0600 Subject: [PATCH 62/79] Tests/AES: attempt to fix failing unit test --- tests/Unit/Crypt/AES/TestCase.php | 35 +++++++++++++++++++++++-------- 1 file changed, 26 insertions(+), 9 deletions(-) diff --git a/tests/Unit/Crypt/AES/TestCase.php b/tests/Unit/Crypt/AES/TestCase.php index fa59e606..f7abb86d 100644 --- a/tests/Unit/Crypt/AES/TestCase.php +++ b/tests/Unit/Crypt/AES/TestCase.php @@ -18,9 +18,10 @@ abstract class Unit_Crypt_AES_TestCase extends PhpseclibTestCase switch ($this->engine) { case CRYPT_ENGINE_OPENSSL: $engine = 'OpenSSL'; - break; + return true; case CRYPT_ENGINE_MCRYPT: $engine = 'mcrypt'; + return true; } self::markTestSkipped('Unable to initialize ' . $engine . ' engine'); } @@ -78,7 +79,9 @@ abstract class Unit_Crypt_AES_TestCase extends PhpseclibTestCase $aes->setIV($iv); $aes->setKey($key); - $this->_checkEngine($aes); + if (!$this->_checkEngine($aes)) { + return; + } $actual = ''; for ($i = 0, $strlen = strlen($plaintext); $i < $strlen; ++$i) { @@ -116,7 +119,9 @@ abstract class Unit_Crypt_AES_TestCase extends PhpseclibTestCase $aes->setPreferredEngine($this->engine); $aes->disablePadding(); $aes->setKey(pack('H*', '2b7e151628aed2a6abf7158809cf4f3c762e7160')); // 160-bit key. AES should null pad to 192-bits - $this->_checkEngine($aes); + if (!$this->_checkEngine($aes)) { + return; + } $ciphertext = $aes->encrypt(pack('H*', '3243f6a8885a308d313198a2e0370734')); $this->assertEquals($ciphertext, pack('H*', 'c109292b173f841b88e0ee49f13db8c0')); } @@ -176,7 +181,9 @@ abstract class Unit_Crypt_AES_TestCase extends PhpseclibTestCase $aes->setKey($key); $aes->setIV($iv); - $this->_checkEngine($aes); + if (!$this->_checkEngine($aes)) { + return; + } $str = ''; $result = ''; @@ -193,7 +200,9 @@ abstract class Unit_Crypt_AES_TestCase extends PhpseclibTestCase $aes->setKey($key); $aes->setIV($iv); - $this->_checkEngine($aes); + if (!$this->_checkEngine($aes)) { + return; + } foreach ($test as $len) { $temp = str_repeat('d', $len); @@ -224,7 +233,9 @@ abstract class Unit_Crypt_AES_TestCase extends PhpseclibTestCase $aes->setKey($key); $aes->setIV($iv); - $this->_checkEngine($aes); + if (!$this->_checkEngine($aes)) { + return; + } $str = ''; $result = ''; @@ -263,7 +274,9 @@ abstract class Unit_Crypt_AES_TestCase extends PhpseclibTestCase $aes->disablePadding(); $aes->setPreferredEngine($this->engine); - $this->_checkEngine($aes); + if (!$this->_checkEngine($aes)) { + return; + } $result = bin2hex($aes->encrypt(pack('H*', 'f34481ec3cc627bacd5dc3fb08f273e6'))); $this->assertSame($result, '0336763e966d92595a567cc9ce537f5e'); @@ -290,7 +303,9 @@ abstract class Unit_Crypt_AES_TestCase extends PhpseclibTestCase $aes->disablePadding(); $aes->setPreferredEngine($this->engine); - $this->_checkEngine($aes); + if (!$this->_checkEngine($aes)) { + return; + } $result = bin2hex($aes->encrypt(pack('H*', '1b077a6af4b7f98229de786d7516b639'))); $this->assertSame($result, '275cfc0413d8ccb70513c3859b1d0f72'); @@ -315,7 +330,9 @@ abstract class Unit_Crypt_AES_TestCase extends PhpseclibTestCase $aes->disablePadding(); $aes->setPreferredEngine($this->engine); - $this->_checkEngine($aes); + if (!$this->_checkEngine($aes)) { + return; + } $result = bin2hex($aes->encrypt(pack('H*', '014730f80ac625fe84f026c60bfd547d'))); $this->assertSame($result, '5c9d844ed46f9885085e5d6a4f94c7d7'); From 569967de20d3fcab1a04a2776d1a36afd119a248 Mon Sep 17 00:00:00 2001 From: terrafrost Date: Wed, 14 Jan 2015 20:28:23 -0600 Subject: [PATCH 63/79] Tests/Blowfish: CS adjustments --- tests/Unit/Crypt/BlowfishTest.php | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/Unit/Crypt/BlowfishTest.php b/tests/Unit/Crypt/BlowfishTest.php index ab091f0b..162c4707 100644 --- a/tests/Unit/Crypt/BlowfishTest.php +++ b/tests/Unit/Crypt/BlowfishTest.php @@ -81,4 +81,3 @@ class Unit_Crypt_BlowfishTest extends PhpseclibTestCase $this->assertEquals($result, $expected, "Failed asserting that $plaintext yielded expected output in $engineName engine"); } } - From 7efc032d4bc721bcf71c11a1fb43e7a38f17316c Mon Sep 17 00:00:00 2001 From: terrafrost Date: Wed, 14 Jan 2015 21:05:34 -0600 Subject: [PATCH 64/79] Tests/AES: pass everything through bin2hex (i thought this was already being done..) --- tests/Unit/Crypt/AES/TestCase.php | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/tests/Unit/Crypt/AES/TestCase.php b/tests/Unit/Crypt/AES/TestCase.php index f7abb86d..e438a530 100644 --- a/tests/Unit/Crypt/AES/TestCase.php +++ b/tests/Unit/Crypt/AES/TestCase.php @@ -280,17 +280,17 @@ abstract class Unit_Crypt_AES_TestCase extends PhpseclibTestCase $result = bin2hex($aes->encrypt(pack('H*', 'f34481ec3cc627bacd5dc3fb08f273e6'))); $this->assertSame($result, '0336763e966d92595a567cc9ce537f5e'); - $result = $aes->encrypt('9798c4640bad75c7c3227db910174e72'); + $result = bin2hex($aes->encrypt('9798c4640bad75c7c3227db910174e72')); $this->assertSame($result, 'a9a1631bf4996954ebc093957b234589'); - $result = $aes->encrypt('96ab5c2ff612d9dfaae8c31f30c42168'); + $result = bin2hex($aes->encrypt('96ab5c2ff612d9dfaae8c31f30c42168')); $this->assertSame($result, 'ff4f8391a6a40ca5b25d23bedd44a597'); - $result = $aes->encrypt('6a118a874519e64e9963798a503f1d35'); + $result = bin2hex($aes->encrypt('6a118a874519e64e9963798a503f1d35')); $this->assertSame($result, 'dc43be40be0e53712f7e2bf5ca707209'); - $result = $aes->encrypt('cb9fceec81286ca3e989bd979b0cb284'); + $result = bin2hex($aes->encrypt('cb9fceec81286ca3e989bd979b0cb284')); $this->assertSame($result, '92beedab1895a94faa69b632e5cc47ce'); - $result = $aes->encrypt('b26aeb1874e47ca8358ff22378f09144'); + $result = bin2hex($aes->encrypt('b26aeb1874e47ca8358ff22378f09144')); $this->assertSame($result, '459264f4798f6a78bacb89c15ed3d601'); - $result = $aes->encrypt('58c8e00b2631686d54eab84b91f0aca1'); + $result = bin2hex($aes->encrypt('58c8e00b2631686d54eab84b91f0aca1')); $this->assertSame($result, '08a4e2efec8a8e3312ca7460b9040bbf'); } @@ -309,15 +309,15 @@ abstract class Unit_Crypt_AES_TestCase extends PhpseclibTestCase $result = bin2hex($aes->encrypt(pack('H*', '1b077a6af4b7f98229de786d7516b639'))); $this->assertSame($result, '275cfc0413d8ccb70513c3859b1d0f72'); - $result = $aes->encrypt('9c2d8842e5f48f57648205d39a239af1'); + $result = bin2hex($aes->encrypt('9c2d8842e5f48f57648205d39a239af1')); $this->assertSame($result, 'c9b8135ff1b5adc413dfd053b21bd96d'); - $result = $aes->encrypt('bff52510095f518ecca60af4205444bb'); + $result = bin2hex($aes->encrypt('bff52510095f518ecca60af4205444bb')); $this->assertSame($result, '4a3650c3371ce2eb35e389a171427440'); - $result = $aes->encrypt('51719783d3185a535bd75adc65071ce1'); + $result = bin2hex($aes->encrypt('51719783d3185a535bd75adc65071ce1')); $this->assertSame($result, '4f354592ff7c8847d2d0870ca9481b7c'); - $result = $aes->encrypt('26aa49dcfe7629a8901a69a9914e6dfd'); + $result = bin2hex($aes->encrypt('26aa49dcfe7629a8901a69a9914e6dfd')); $this->assertSame($result, 'd5e08bf9a182e857cf40b3a36ee248cc'); - $result = $aes->encrypt('941a4773058224e1ef66d10e0a6ee782'); + $result = bin2hex($aes->encrypt('941a4773058224e1ef66d10e0a6ee782')); $this->assertSame($result, '067cd9d3749207791841562507fa9626'); } @@ -336,13 +336,13 @@ abstract class Unit_Crypt_AES_TestCase extends PhpseclibTestCase $result = bin2hex($aes->encrypt(pack('H*', '014730f80ac625fe84f026c60bfd547d'))); $this->assertSame($result, '5c9d844ed46f9885085e5d6a4f94c7d7'); - $result = $aes->encrypt('0b24af36193ce4665f2825d7b4749c98'); + $result = bin2hex($aes->encrypt('0b24af36193ce4665f2825d7b4749c98')); $this->assertSame($result, 'a9ff75bd7cf6613d3731c77c3b6d0c04'); - $result = $aes->encrypt('761c1fe41a18acf20d241650611d90f1'); + $result = bin2hex($aes->encrypt('761c1fe41a18acf20d241650611d90f1')); $this->assertSame($result, '623a52fcea5d443e48d9181ab32c7421'); - $result = $aes->encrypt('8a560769d605868ad80d819bdba03771'); + $result = bin2hex($aes->encrypt('8a560769d605868ad80d819bdba03771')); $this->assertSame($result, '38f2c7ae10612415d27ca190d27da8b4'); - $result = $aes->encrypt('91fbef2d15a97816060bee1feaa49afe'); + $result = bin2hex($aes->encrypt('91fbef2d15a97816060bee1feaa49afe')); $this->assertSame($result, '1bc704f1bce135ceb810341b216d7abe'); } } From f1b41e2782f8c6218d63eafa473f9c464a2bc90f Mon Sep 17 00:00:00 2001 From: terrafrost Date: Wed, 14 Jan 2015 22:46:46 -0600 Subject: [PATCH 65/79] Tests/AES: pack everything --- tests/Unit/Crypt/AES/TestCase.php | 61 ++++++++++++------------------- 1 file changed, 23 insertions(+), 38 deletions(-) diff --git a/tests/Unit/Crypt/AES/TestCase.php b/tests/Unit/Crypt/AES/TestCase.php index e438a530..15ea5532 100644 --- a/tests/Unit/Crypt/AES/TestCase.php +++ b/tests/Unit/Crypt/AES/TestCase.php @@ -18,10 +18,9 @@ abstract class Unit_Crypt_AES_TestCase extends PhpseclibTestCase switch ($this->engine) { case CRYPT_ENGINE_OPENSSL: $engine = 'OpenSSL'; - return true; + break; case CRYPT_ENGINE_MCRYPT: $engine = 'mcrypt'; - return true; } self::markTestSkipped('Unable to initialize ' . $engine . ' engine'); } @@ -79,9 +78,7 @@ abstract class Unit_Crypt_AES_TestCase extends PhpseclibTestCase $aes->setIV($iv); $aes->setKey($key); - if (!$this->_checkEngine($aes)) { - return; - } + $this->_checkEngine($aes); $actual = ''; for ($i = 0, $strlen = strlen($plaintext); $i < $strlen; ++$i) { @@ -119,9 +116,7 @@ abstract class Unit_Crypt_AES_TestCase extends PhpseclibTestCase $aes->setPreferredEngine($this->engine); $aes->disablePadding(); $aes->setKey(pack('H*', '2b7e151628aed2a6abf7158809cf4f3c762e7160')); // 160-bit key. AES should null pad to 192-bits - if (!$this->_checkEngine($aes)) { - return; - } + $this->_checkEngine($aes); $ciphertext = $aes->encrypt(pack('H*', '3243f6a8885a308d313198a2e0370734')); $this->assertEquals($ciphertext, pack('H*', 'c109292b173f841b88e0ee49f13db8c0')); } @@ -181,9 +176,7 @@ abstract class Unit_Crypt_AES_TestCase extends PhpseclibTestCase $aes->setKey($key); $aes->setIV($iv); - if (!$this->_checkEngine($aes)) { - return; - } + $this->_checkEngine($aes); $str = ''; $result = ''; @@ -233,9 +226,7 @@ abstract class Unit_Crypt_AES_TestCase extends PhpseclibTestCase $aes->setKey($key); $aes->setIV($iv); - if (!$this->_checkEngine($aes)) { - return; - } + $this->_checkEngine($aes); $str = ''; $result = ''; @@ -274,23 +265,21 @@ abstract class Unit_Crypt_AES_TestCase extends PhpseclibTestCase $aes->disablePadding(); $aes->setPreferredEngine($this->engine); - if (!$this->_checkEngine($aes)) { - return; - } + $this->_checkEngine($aes); $result = bin2hex($aes->encrypt(pack('H*', 'f34481ec3cc627bacd5dc3fb08f273e6'))); $this->assertSame($result, '0336763e966d92595a567cc9ce537f5e'); - $result = bin2hex($aes->encrypt('9798c4640bad75c7c3227db910174e72')); + $result = bin2hex($aes->encrypt(pack('H*', '9798c4640bad75c7c3227db910174e72'))); $this->assertSame($result, 'a9a1631bf4996954ebc093957b234589'); - $result = bin2hex($aes->encrypt('96ab5c2ff612d9dfaae8c31f30c42168')); + $result = bin2hex($aes->encrypt(pack('H*', '96ab5c2ff612d9dfaae8c31f30c42168'))); $this->assertSame($result, 'ff4f8391a6a40ca5b25d23bedd44a597'); - $result = bin2hex($aes->encrypt('6a118a874519e64e9963798a503f1d35')); + $result = bin2hex($aes->encrypt(pack('H*', '6a118a874519e64e9963798a503f1d35'))); $this->assertSame($result, 'dc43be40be0e53712f7e2bf5ca707209'); - $result = bin2hex($aes->encrypt('cb9fceec81286ca3e989bd979b0cb284')); + $result = bin2hex($aes->encrypt(pack('H*', 'cb9fceec81286ca3e989bd979b0cb284'))); $this->assertSame($result, '92beedab1895a94faa69b632e5cc47ce'); - $result = bin2hex($aes->encrypt('b26aeb1874e47ca8358ff22378f09144')); + $result = bin2hex($aes->encrypt(pack('H*', 'b26aeb1874e47ca8358ff22378f09144'))); $this->assertSame($result, '459264f4798f6a78bacb89c15ed3d601'); - $result = bin2hex($aes->encrypt('58c8e00b2631686d54eab84b91f0aca1')); + $result = bin2hex($aes->encrypt(pack('H*', '58c8e00b2631686d54eab84b91f0aca1'))); $this->assertSame($result, '08a4e2efec8a8e3312ca7460b9040bbf'); } @@ -303,21 +292,19 @@ abstract class Unit_Crypt_AES_TestCase extends PhpseclibTestCase $aes->disablePadding(); $aes->setPreferredEngine($this->engine); - if (!$this->_checkEngine($aes)) { - return; - } + $this->_checkEngine($aes); $result = bin2hex($aes->encrypt(pack('H*', '1b077a6af4b7f98229de786d7516b639'))); $this->assertSame($result, '275cfc0413d8ccb70513c3859b1d0f72'); - $result = bin2hex($aes->encrypt('9c2d8842e5f48f57648205d39a239af1')); + $result = bin2hex($aes->encrypt(pack('H*', '9c2d8842e5f48f57648205d39a239af1'))); $this->assertSame($result, 'c9b8135ff1b5adc413dfd053b21bd96d'); - $result = bin2hex($aes->encrypt('bff52510095f518ecca60af4205444bb')); + $result = bin2hex($aes->encrypt(pack('H*', 'bff52510095f518ecca60af4205444bb'))); $this->assertSame($result, '4a3650c3371ce2eb35e389a171427440'); - $result = bin2hex($aes->encrypt('51719783d3185a535bd75adc65071ce1')); + $result = bin2hex($aes->encrypt(pack('H*', '51719783d3185a535bd75adc65071ce1'))); $this->assertSame($result, '4f354592ff7c8847d2d0870ca9481b7c'); - $result = bin2hex($aes->encrypt('26aa49dcfe7629a8901a69a9914e6dfd')); + $result = bin2hex($aes->encrypt(pack('H*', '26aa49dcfe7629a8901a69a9914e6dfd'))); $this->assertSame($result, 'd5e08bf9a182e857cf40b3a36ee248cc'); - $result = bin2hex($aes->encrypt('941a4773058224e1ef66d10e0a6ee782')); + $result = bin2hex($aes->encrypt(pack('H*', '941a4773058224e1ef66d10e0a6ee782'))); $this->assertSame($result, '067cd9d3749207791841562507fa9626'); } @@ -330,19 +317,17 @@ abstract class Unit_Crypt_AES_TestCase extends PhpseclibTestCase $aes->disablePadding(); $aes->setPreferredEngine($this->engine); - if (!$this->_checkEngine($aes)) { - return; - } + $this->_checkEngine($aes); $result = bin2hex($aes->encrypt(pack('H*', '014730f80ac625fe84f026c60bfd547d'))); $this->assertSame($result, '5c9d844ed46f9885085e5d6a4f94c7d7'); - $result = bin2hex($aes->encrypt('0b24af36193ce4665f2825d7b4749c98')); + $result = bin2hex($aes->encrypt(pack('H*', '0b24af36193ce4665f2825d7b4749c98'))); $this->assertSame($result, 'a9ff75bd7cf6613d3731c77c3b6d0c04'); - $result = bin2hex($aes->encrypt('761c1fe41a18acf20d241650611d90f1')); + $result = bin2hex($aes->encrypt(pack('H*', '761c1fe41a18acf20d241650611d90f1'))); $this->assertSame($result, '623a52fcea5d443e48d9181ab32c7421'); - $result = bin2hex($aes->encrypt('8a560769d605868ad80d819bdba03771')); + $result = bin2hex($aes->encrypt(pack('H*', '8a560769d605868ad80d819bdba03771'))); $this->assertSame($result, '38f2c7ae10612415d27ca190d27da8b4'); - $result = bin2hex($aes->encrypt('91fbef2d15a97816060bee1feaa49afe')); + $result = bin2hex($aes->encrypt(pack('H*', '91fbef2d15a97816060bee1feaa49afe'))); $this->assertSame($result, '1bc704f1bce135ceb810341b216d7abe'); } } From 0f01128e98ff41eca660d66bb76ce9e84f24d2e0 Mon Sep 17 00:00:00 2001 From: terrafrost Date: Fri, 16 Jan 2015 20:27:43 -0600 Subject: [PATCH 66/79] Tests/AES: change CRYPT_AES_MODE_* -> CRYPT_MODE_* --- tests/Unit/Crypt/AES/TestCase.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/Unit/Crypt/AES/TestCase.php b/tests/Unit/Crypt/AES/TestCase.php index 15ea5532..ad762369 100644 --- a/tests/Unit/Crypt/AES/TestCase.php +++ b/tests/Unit/Crypt/AES/TestCase.php @@ -34,9 +34,9 @@ abstract class Unit_Crypt_AES_TestCase extends PhpseclibTestCase public function continuousBufferCombos() { $modes = array( - 'CRYPT_AES_MODE_CTR', - 'CRYPT_AES_MODE_OFB', - 'CRYPT_AES_MODE_CFB', + 'CRYPT_MODE_CTR', + 'CRYPT_MODE_OFB', + 'CRYPT_MODE_CFB', ); $plaintexts = array( '', From e9470d1fc5c4ae1ce2af9deb1d2d18370b98c80c Mon Sep 17 00:00:00 2001 From: terrafrost Date: Sat, 17 Jan 2015 09:42:47 -0600 Subject: [PATCH 67/79] TripleDES: updates to accomodate inner chaining --- phpseclib/Crypt/TripleDES.php | 36 ++++++++++++++++++------------ tests/Unit/Crypt/TripleDESTest.php | 33 +++++++++++++++++++++------ 2 files changed, 48 insertions(+), 21 deletions(-) diff --git a/phpseclib/Crypt/TripleDES.php b/phpseclib/Crypt/TripleDES.php index 35819ba7..5e63f361 100644 --- a/phpseclib/Crypt/TripleDES.php +++ b/phpseclib/Crypt/TripleDES.php @@ -68,13 +68,21 @@ if (!class_exists('Crypt_DES')) { * * Inner chaining is used by SSH-1 and is generally considered to be less secure then outer chaining (CRYPT_DES_MODE_CBC3). */ +define('CRYPT_MODE_3CBC', -2); +/** + * BC version of the above. + */ define('CRYPT_DES_MODE_3CBC', -2); /** * Encrypt / decrypt using outer chaining * * Outer chaining is used by SSH-2 and when the mode is set to CRYPT_DES_MODE_CBC. */ -define('CRYPT_DES_MODE_CBC3', CRYPT_DES_MODE_CBC); +define('CRYPT_MODE_CBC3', CRYPT_MODE_CBC); +/** + * BC version of the above. + */ +define('CRYPT_DES_MODE_CBC3', CRYPT_MODE_CBC3); /**#@-*/ /** @@ -190,20 +198,20 @@ class Crypt_TripleDES extends Crypt_DES * @param optional Integer $mode * @access public */ - function Crypt_TripleDES($mode = CRYPT_DES_MODE_CBC) + function Crypt_TripleDES($mode = CRYPT_MODE_CBC) { switch ($mode) { // In case of CRYPT_DES_MODE_3CBC, we init as CRYPT_DES_MODE_CBC // and additional flag us internally as 3CBC case CRYPT_DES_MODE_3CBC: - parent::Crypt_Base(CRYPT_DES_MODE_CBC); + parent::Crypt_Base(CRYPT_MODE_CBC); $this->mode_3cbc = true; // This three $des'es will do the 3CBC work (if $key > 64bits) $this->des = array( - new Crypt_DES(CRYPT_DES_MODE_CBC), - new Crypt_DES(CRYPT_DES_MODE_CBC), - new Crypt_DES(CRYPT_DES_MODE_CBC), + new Crypt_DES(CRYPT_MODE_CBC), + new Crypt_DES(CRYPT_MODE_CBC), + new Crypt_DES(CRYPT_MODE_CBC), ); // we're going to be doing the padding, ourselves, so disable it in the Crypt_DES objects @@ -308,7 +316,7 @@ class Crypt_TripleDES extends Crypt_DES function encrypt($plaintext) { // parent::en/decrypt() is able to do all the work for all modes and keylengths, - // except for: CRYPT_DES_MODE_3CBC (inner chaining CBC) with a key > 64bits + // except for: CRYPT_MODE_3CBC (inner chaining CBC) with a key > 64bits // if the key is smaller then 8, do what we'd normally do if ($this->mode_3cbc && strlen($this->key) > 8) { @@ -455,19 +463,19 @@ class Crypt_TripleDES extends Crypt_DES * Sets the internal crypt engine * * @see Crypt_Base::Crypt_Base() - * @see Crypt_Base::setEngine() - * @param optional Integer $engine + * @see Crypt_Base::setPreferredEngine() + * @param Integer $engine * @access public * @return Integer */ - function setEngine($engine = CRYPT_DES_MODE_MCRYPT) + function setPreferredEngine($engine) { if ($this->mode_3cbc) { - $this->des[0]->setEngine($engine); - $this->des[1]->setEngine($engine); - $this->des[2]->setEngine($engine); + $this->des[0]->setPreferredEngine($engine); + $this->des[1]->setPreferredEngine($engine); + $this->des[2]->setPreferredEngine($engine); } - return parent::setEngine($engine); + return parent::setPreferredEngine($engine); } } diff --git a/tests/Unit/Crypt/TripleDESTest.php b/tests/Unit/Crypt/TripleDESTest.php index ba650996..d317f716 100644 --- a/tests/Unit/Crypt/TripleDESTest.php +++ b/tests/Unit/Crypt/TripleDESTest.php @@ -9,14 +9,14 @@ require_once 'Crypt/TripleDES.php'; class Unit_Crypt_TripleDESTest extends PhpseclibTestCase { + var $engines = array( + CRYPT_ENGINE_INTERNAL => 'internal', + CRYPT_ENGINE_MCRYPT => 'mcrypt', + CRYPT_ENGINE_OPENSSL => 'OpenSSL', + ); + public function engineVectors() { - $engines = array( - CRYPT_ENGINE_INTERNAL => 'internal', - CRYPT_ENGINE_MCRYPT => 'mcrypt', - CRYPT_ENGINE_OPENSSL => 'OpenSSL', - ); - // tests from http://csrc.nist.gov/publications/nistpubs/800-20/800-20.pdf#page=273 $tests = array( // Table A.1 @@ -88,7 +88,7 @@ class Unit_Crypt_TripleDESTest extends PhpseclibTestCase ); $result = array(); // @codingStandardsIgnoreStart - foreach ($engines as $engine => $engineName) + foreach ($this->engines as $engine => $engineName) foreach ($tests as $test) $result[] = array($engine, $engineName, $test[0], $test[1], $test[2]); // @codingStandardsIgnoreEnd @@ -160,4 +160,23 @@ class Unit_Crypt_TripleDESTest extends PhpseclibTestCase $plaintext = bin2hex($plaintext); $this->assertEquals($result, $expected, "Failed asserting that $plaintext yielded expected output in $engineName engine"); } + + public function testInnerChaining() + { + // regular CBC returns + // e089b6d84708c6bc80be6c2da82bd19a79ffe11f02933ac1 + $expected = 'e089b6d84708c6bc6f04c8971121603d7be2861efae0f3f5'; + + $des = new Crypt_TripleDES(CRYPT_DES_MODE_3CBC); + $des->setKey('abcdefghijklmnopqrstuvwx'); + + for ($this->engines as $engine->$engineName) { + $des->setPreferredEngine($engine); + if (!$des->isValidEngine($engine)) { + self::markTestSkipped('Unable to initialize ' . $engineName . ' engine'); + } + $result = bin2hex($des->encrypt(str_repeat('a', 16)); + $this->assertEquals($result, $expected, "Failed asserting inner chainin worked correctly in $engineName engine"); + } + } } From fb41f3492b931bc7c59ef9af32a93cc28b0d6797 Mon Sep 17 00:00:00 2001 From: terrafrost Date: Sat, 17 Jan 2015 09:56:32 -0600 Subject: [PATCH 68/79] Tests/TripleDES: fix syntax error --- tests/Unit/Crypt/TripleDESTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Unit/Crypt/TripleDESTest.php b/tests/Unit/Crypt/TripleDESTest.php index d317f716..d86115e1 100644 --- a/tests/Unit/Crypt/TripleDESTest.php +++ b/tests/Unit/Crypt/TripleDESTest.php @@ -170,7 +170,7 @@ class Unit_Crypt_TripleDESTest extends PhpseclibTestCase $des = new Crypt_TripleDES(CRYPT_DES_MODE_3CBC); $des->setKey('abcdefghijklmnopqrstuvwx'); - for ($this->engines as $engine->$engineName) { + foreach ($this->engines as $engine->$engineName) { $des->setPreferredEngine($engine); if (!$des->isValidEngine($engine)) { self::markTestSkipped('Unable to initialize ' . $engineName . ' engine'); From 1547ec497a7bfdd891325dcd6542dbe4607ca032 Mon Sep 17 00:00:00 2001 From: terrafrost Date: Sat, 17 Jan 2015 10:04:01 -0600 Subject: [PATCH 69/79] Tests/TripleDES: another syntax error --- tests/Unit/Crypt/TripleDESTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Unit/Crypt/TripleDESTest.php b/tests/Unit/Crypt/TripleDESTest.php index d86115e1..90762efa 100644 --- a/tests/Unit/Crypt/TripleDESTest.php +++ b/tests/Unit/Crypt/TripleDESTest.php @@ -175,7 +175,7 @@ class Unit_Crypt_TripleDESTest extends PhpseclibTestCase if (!$des->isValidEngine($engine)) { self::markTestSkipped('Unable to initialize ' . $engineName . ' engine'); } - $result = bin2hex($des->encrypt(str_repeat('a', 16)); + $result = bin2hex($des->encrypt(str_repeat('a', 16))); $this->assertEquals($result, $expected, "Failed asserting inner chainin worked correctly in $engineName engine"); } } From eaf2397cb6bc448400c1456a6ef666a83b036e33 Mon Sep 17 00:00:00 2001 From: terrafrost Date: Sat, 17 Jan 2015 10:17:23 -0600 Subject: [PATCH 70/79] Tests/TripleDES: fix one last error --- tests/Unit/Crypt/TripleDESTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Unit/Crypt/TripleDESTest.php b/tests/Unit/Crypt/TripleDESTest.php index 90762efa..6afb832f 100644 --- a/tests/Unit/Crypt/TripleDESTest.php +++ b/tests/Unit/Crypt/TripleDESTest.php @@ -170,7 +170,7 @@ class Unit_Crypt_TripleDESTest extends PhpseclibTestCase $des = new Crypt_TripleDES(CRYPT_DES_MODE_3CBC); $des->setKey('abcdefghijklmnopqrstuvwx'); - foreach ($this->engines as $engine->$engineName) { + foreach ($this->engines as $engine => $engineName) { $des->setPreferredEngine($engine); if (!$des->isValidEngine($engine)) { self::markTestSkipped('Unable to initialize ' . $engineName . ' engine'); From c90010297c43661eec72dd751d9621aac8e18054 Mon Sep 17 00:00:00 2001 From: terrafrost Date: Sat, 17 Jan 2015 10:33:12 -0600 Subject: [PATCH 71/79] Tests/TripleDES: CS adjustments --- tests/Unit/Crypt/TripleDESTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Unit/Crypt/TripleDESTest.php b/tests/Unit/Crypt/TripleDESTest.php index 6afb832f..a1b07f86 100644 --- a/tests/Unit/Crypt/TripleDESTest.php +++ b/tests/Unit/Crypt/TripleDESTest.php @@ -173,7 +173,7 @@ class Unit_Crypt_TripleDESTest extends PhpseclibTestCase foreach ($this->engines as $engine => $engineName) { $des->setPreferredEngine($engine); if (!$des->isValidEngine($engine)) { - self::markTestSkipped('Unable to initialize ' . $engineName . ' engine'); + self::markTestSkipped('Unable to initialize ' . $engineName . ' engine'); } $result = bin2hex($des->encrypt(str_repeat('a', 16))); $this->assertEquals($result, $expected, "Failed asserting inner chainin worked correctly in $engineName engine"); From b852e8c6cbb9ffcce08d538e8383bb37a6b5590f Mon Sep 17 00:00:00 2001 From: terrafrost Date: Mon, 19 Jan 2015 20:52:25 -0600 Subject: [PATCH 72/79] Tests: add twofish unit test --- tests/Unit/Crypt/TwofishTest.php | 72 ++++++++++++++++++++++++++++++++ 1 file changed, 72 insertions(+) create mode 100644 tests/Unit/Crypt/TwofishTest.php diff --git a/tests/Unit/Crypt/TwofishTest.php b/tests/Unit/Crypt/TwofishTest.php new file mode 100644 index 00000000..68f012de --- /dev/null +++ b/tests/Unit/Crypt/TwofishTest.php @@ -0,0 +1,72 @@ + + * @copyright MMXIII Andreas Fischer + * @license http://www.opensource.org/licenses/mit-license.html MIT License + */ + +require_once 'Crypt/Twofish.php'; + +class Unit_Crypt_TwofishTest extends PhpseclibTestCase +{ + public function testVectors() + { + $engines = array( + CRYPT_ENGINE_INTERNAL => 'internal', + CRYPT_ENGINE_MCRYPT => 'mcrypt', + CRYPT_ENGINE_OPENSSL => 'OpenSSL', + ); + + foreach ($engines as $engine=>$name) { + $tf = new Crypt_Twofish(); + + // tests from https://www.schneier.com/code/ecb_ival.txt + + // key size = 128 + $key = pack('H*', '00000000000000000000000000000000'); + $tf->setKey($key); + if (!$bf->isValidEngine($engine)) { + self::markTestSkipped('Unable to initialize ' . $name . ' engine'); + } + + $plaintext = pack('H*', '00000000000000000000000000000000'); + $ciphertext = $tf->encrypt($plaintext); + $expected = strtolower('9F589F5CF6122C32B6BFEC2F2AE8C35A'); + $this->assertEquals(bin2hex($ciphertext), $expected, "Failed asserting that $plaintext yielded expected output in $name engine"); + + $expected = bin2hex($plaintext); + $plaintext = bin2hex($tf->decrypt($ciphertext)); + $this->assertEquals($plaintext, $expected, "Failed asserting that $plaintext yielded expected output in $name engine"); + + // key size = 192 + $key = pack('H*', '0123456789ABCDEFFEDCBA98765432100011223344556677'); + $tf->setKey($key); + if (!$bf->isValidEngine($engine)) { + self::markTestSkipped('Unable to initialize ' . $name . ' engine'); + } + $plaintext = pack('H*', '00000000000000000000000000000000'); + $ciphertext = $tf->encrypt($plaintext); + $expected = strtolower('CFD1D2E5A9BE9CDF501F13B892BD2248'); + $this->assertEquals(bin2hex($ciphertext), $expected, "Failed asserting that $plaintext yielded expected output in $name engine"); + + $expected = bin2hex($plaintext); + $plaintext = bin2hex($tf->decrypt($ciphertext)); + $this->assertEquals($plaintext, $expected, "Failed asserting that $plaintext yielded expected output in $name engine"); + + // key size = 256 + $key = pack('H*', '0123456789ABCDEFFEDCBA987654321000112233445566778899AABBCCDDEEFF'); + $tf->setKey($key); + if (!$bf->isValidEngine($engine)) { + self::markTestSkipped('Unable to initialize ' . $name . ' engine'); + } + $plaintext = pack('H*', '00000000000000000000000000000000'); + $ciphertext = $tf->encrypt($plaintext); + $expected = strtolower('37527BE0052334B89F0CFCCAE87CFA20'); + $this->assertEquals(bin2hex($ciphertext), $expected, "Failed asserting that $plaintext yielded expected output in $name engine"); + + $expected = bin2hex($plaintext); + $plaintext = bin2hex($tf->decrypt($ciphertext)); + $this->assertEquals($plaintext, $expected, "Failed asserting that $plaintext yielded expected output in $name engine"); + } + } +} From 06d9f078302be47e08d1e984a38abe8766f4c99f Mon Sep 17 00:00:00 2001 From: terrafrost Date: Mon, 19 Jan 2015 21:19:12 -0600 Subject: [PATCH 73/79] Tests/Twofish: fix E_NOTICE --- tests/Unit/Crypt/TwofishTest.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/Unit/Crypt/TwofishTest.php b/tests/Unit/Crypt/TwofishTest.php index 68f012de..e6eed4de 100644 --- a/tests/Unit/Crypt/TwofishTest.php +++ b/tests/Unit/Crypt/TwofishTest.php @@ -25,7 +25,7 @@ class Unit_Crypt_TwofishTest extends PhpseclibTestCase // key size = 128 $key = pack('H*', '00000000000000000000000000000000'); $tf->setKey($key); - if (!$bf->isValidEngine($engine)) { + if (!$tf->isValidEngine($engine)) { self::markTestSkipped('Unable to initialize ' . $name . ' engine'); } @@ -41,7 +41,7 @@ class Unit_Crypt_TwofishTest extends PhpseclibTestCase // key size = 192 $key = pack('H*', '0123456789ABCDEFFEDCBA98765432100011223344556677'); $tf->setKey($key); - if (!$bf->isValidEngine($engine)) { + if (!$tf->isValidEngine($engine)) { self::markTestSkipped('Unable to initialize ' . $name . ' engine'); } $plaintext = pack('H*', '00000000000000000000000000000000'); @@ -56,7 +56,7 @@ class Unit_Crypt_TwofishTest extends PhpseclibTestCase // key size = 256 $key = pack('H*', '0123456789ABCDEFFEDCBA987654321000112233445566778899AABBCCDDEEFF'); $tf->setKey($key); - if (!$bf->isValidEngine($engine)) { + if (!$tf->isValidEngine($engine)) { self::markTestSkipped('Unable to initialize ' . $name . ' engine'); } $plaintext = pack('H*', '00000000000000000000000000000000'); From 808a460f152f2f8b7adf7dbf5c33855c5939b75a Mon Sep 17 00:00:00 2001 From: terrafrost Date: Mon, 19 Jan 2015 22:00:49 -0600 Subject: [PATCH 74/79] Tests/Twofish: disable padding --- tests/Unit/Crypt/TwofishTest.php | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/Unit/Crypt/TwofishTest.php b/tests/Unit/Crypt/TwofishTest.php index e6eed4de..26cc0e28 100644 --- a/tests/Unit/Crypt/TwofishTest.php +++ b/tests/Unit/Crypt/TwofishTest.php @@ -19,6 +19,7 @@ class Unit_Crypt_TwofishTest extends PhpseclibTestCase foreach ($engines as $engine=>$name) { $tf = new Crypt_Twofish(); + $tf->disablePadding(); // tests from https://www.schneier.com/code/ecb_ival.txt From 8b8d9ac42323d186aff3bf312f001f2b42d21248 Mon Sep 17 00:00:00 2001 From: terrafrost Date: Mon, 26 Jan 2015 19:24:48 -0600 Subject: [PATCH 75/79] Tests/RC2: add test vectors --- tests/Unit/Crypt/RC2Test.php | 46 +++++++++++++++++++++++++++++++++++- 1 file changed, 45 insertions(+), 1 deletion(-) diff --git a/tests/Unit/Crypt/RC2Test.php b/tests/Unit/Crypt/RC2Test.php index fb70ce31..adcb592d 100644 --- a/tests/Unit/Crypt/RC2Test.php +++ b/tests/Unit/Crypt/RC2Test.php @@ -7,9 +7,38 @@ require_once 'Crypt/RC2.php'; -// this test is just confirming RC2's key expansion class Unit_Crypt_RC2Test extends PhpseclibTestCase { + var $engines = array( + CRYPT_ENGINE_INTERNAL => 'internal', + CRYPT_ENGINE_MCRYPT => 'mcrypt', + CRYPT_ENGINE_OPENSSL => 'OpenSSL', + ); + + public function engineVectors() + { + // tests from https://tools.ietf.org/html/rfc2268#page-8 + $tests = array( + // key, effective key length, plaintext, ciphertext + array('0000000000000000', 63, '0000000000000000', 'ebb773f993278eff'), + array('ffffffffffffffff', 64, 'ffffffffffffffff', '278b27e42e2f0d49'), + array('3000000000000000', 64, '1000000000000001', '30649edf9be7d2c2'), + array('88', 64, '0000000000000000', '61a8a244adacccf0'), + array('88bca90e90875a', 64, '0000000000000000', '6ccf4308974c267f'), + array('88bca90e90875a7f0f79c384627bafb2', 64, '0000000000000000', '1a807d272bbe5db1'), + array('88bca90e90875a7f0f79c384627bafb2', 128, '0000000000000000', '2269552ab0f85ca6'), + array('88bca90e90875a7f0f79c384627bafb216f80a6f85920584c42fceb0 be255daf1e', 129, '0000000000000000', '5b78d3a43dfff1f1') + ); + $result = array(); + // @codingStandardsIgnoreStart + foreach ($this->engines as $engine => $engineName) + foreach ($tests as $test) + $result[] = array($engine, $engineName, $test[0], $test[1], $test[2], $test[3]); + // @codingStandardsIgnoreEnd + return $result; + } + + // this test is just confirming RC2's key expansion public function testEncryptPadding() { $rc2 = new Crypt_RC2(CRYPT_MODE_ECB); @@ -71,4 +100,19 @@ class Unit_Crypt_RC2Test extends PhpseclibTestCase self::markTestSkipped('Unable to initialize OpenSSL engine'); } } + + public function testVectors($engine, $engineName, $key, $keyLen, $plaintext, $ciphertext) + { + $rc2 = new Crypt_RC2(); + $rc2->disablePadding(); + $rc2->setKeyLength($keyLen); + $rc2->setKey(pack('H*', $key)); // could also do $rc2->setKey(pack('H*', $key), $keyLen) + if (!$rc2->isValidEngine($engine)) { + self::markTestSkipped('Unable to initialize ' . $engineName . ' engine'); + } + $rc2->setPreferredEngine($engine); + + $result = bin2hex($rc2->encrypt(pack('H*', $plaintext))); + $this->assertEquals($result, $ciphertext, "Failed asserting that $plaintext yielded expected output in $engineName engine"); + } } From a467c9e0bd76a87a45ac66cb521c039e1a9ca15c Mon Sep 17 00:00:00 2001 From: terrafrost Date: Mon, 26 Jan 2015 19:51:57 -0600 Subject: [PATCH 76/79] Tests/RC2: use data provider --- tests/Unit/Crypt/RC2Test.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/Unit/Crypt/RC2Test.php b/tests/Unit/Crypt/RC2Test.php index adcb592d..5d6afa7d 100644 --- a/tests/Unit/Crypt/RC2Test.php +++ b/tests/Unit/Crypt/RC2Test.php @@ -101,6 +101,9 @@ class Unit_Crypt_RC2Test extends PhpseclibTestCase } } + /** + * @dataProvider engineVectors + */ public function testVectors($engine, $engineName, $key, $keyLen, $plaintext, $ciphertext) { $rc2 = new Crypt_RC2(); From fbfc935a1e74ad0e0597c06aabc7d3797c716c78 Mon Sep 17 00:00:00 2001 From: terrafrost Date: Mon, 26 Jan 2015 20:06:01 -0600 Subject: [PATCH 77/79] Tests/RC2: rm space --- tests/Unit/Crypt/RC2Test.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Unit/Crypt/RC2Test.php b/tests/Unit/Crypt/RC2Test.php index 5d6afa7d..17c2e729 100644 --- a/tests/Unit/Crypt/RC2Test.php +++ b/tests/Unit/Crypt/RC2Test.php @@ -27,7 +27,7 @@ class Unit_Crypt_RC2Test extends PhpseclibTestCase array('88bca90e90875a', 64, '0000000000000000', '6ccf4308974c267f'), array('88bca90e90875a7f0f79c384627bafb2', 64, '0000000000000000', '1a807d272bbe5db1'), array('88bca90e90875a7f0f79c384627bafb2', 128, '0000000000000000', '2269552ab0f85ca6'), - array('88bca90e90875a7f0f79c384627bafb216f80a6f85920584c42fceb0 be255daf1e', 129, '0000000000000000', '5b78d3a43dfff1f1') + array('88bca90e90875a7f0f79c384627bafb216f80a6f85920584c42fceb0be255daf1e', 129, '0000000000000000', '5b78d3a43dfff1f1') ); $result = array(); // @codingStandardsIgnoreStart From e93dc8d272d2f8fec41eedb8386f702d8d8a9d49 Mon Sep 17 00:00:00 2001 From: terrafrost Date: Thu, 29 Jan 2015 23:19:34 -0600 Subject: [PATCH 78/79] RC2: OpenSSL is pretty restricted in where it can be used --- phpseclib/Crypt/RC2.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/phpseclib/Crypt/RC2.php b/phpseclib/Crypt/RC2.php index dc0c41d7..ce78fc50 100644 --- a/phpseclib/Crypt/RC2.php +++ b/phpseclib/Crypt/RC2.php @@ -366,7 +366,7 @@ class Crypt_RC2 extends Crypt_Base { switch ($engine) { case CRYPT_ENGINE_OPENSSL: - if ($this->current_key_length != 128 && strlen($this->orig_key) != 16) { + if ($this->current_key_length != 128 || strlen($this->orig_key) != 16) { return false; } $this->cipher_name_openssl_ecb = 'rc2-ecb'; From a95160cb4432d18491aa74f9663cba0476d45bbb Mon Sep 17 00:00:00 2001 From: terrafrost Date: Sat, 31 Jan 2015 19:11:32 -0600 Subject: [PATCH 79/79] Crypt/Base: fix issue with CBC mode encryption with continuous buffers --- phpseclib/Crypt/Base.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/phpseclib/Crypt/Base.php b/phpseclib/Crypt/Base.php index 4b56246e..272193fb 100644 --- a/phpseclib/Crypt/Base.php +++ b/phpseclib/Crypt/Base.php @@ -698,7 +698,7 @@ class Crypt_Base case CRYPT_MODE_CBC: $result = openssl_encrypt($plaintext, $this->cipher_name_openssl, $this->key, $this->openssl_options, $this->encryptIV); if ($this->continuousBuffer) { - $this->encryptIV = substr($ciphertext, -$this->block_size); + $this->encryptIV = substr($result, -$this->block_size); } return !defined('OPENSSL_RAW_DATA') ? substr($result, 0, -$this->block_size) : $result; case CRYPT_MODE_CTR: