diff --git a/phpseclib/Crypt/Base.php b/phpseclib/Crypt/Base.php index fe15f2ae..bd295298 100644 --- a/phpseclib/Crypt/Base.php +++ b/phpseclib/Crypt/Base.php @@ -72,7 +72,8 @@ define('CRYPT_MODE_CFB', 3); */ define('CRYPT_MODE_OFB', 4); /** - * Streaming mode + * Encrypt / decrypt using streaming mode. + * */ define('CRYPT_MODE_STREAM', 5); /**#@-*/ @@ -97,7 +98,7 @@ define('CRYPT_MODE_MCRYPT', 2); * @author Jim Wigginton * @author Hans-Juergen Petrich * @version 1.0.0 - * @access internal + * @access public * @package Crypt_Base */ class Crypt_Base { @@ -140,7 +141,7 @@ class Crypt_Base { * A "sliding" Initialization Vector * * @see Crypt_Base::enableContinuousBuffer() - * @see Crypt_Base::clearBuffers() + * @see Crypt_Base::_clearBuffers() * @var String * @access private */ @@ -150,7 +151,7 @@ class Crypt_Base { * A "sliding" Initialization Vector * * @see Crypt_Base::enableContinuousBuffer() - * @see Crypt_Base::clearBuffers() + * @see Crypt_Base::_clearBuffers() * @var String * @access private */ @@ -169,7 +170,7 @@ class Crypt_Base { * Encryption buffer for CTR, OFB and CFB modes * * @see Crypt_Base::encrypt() - * @see Crypt_Base::clearBuffers() + * @see Crypt_Base::_clearBuffers() * @var Array * @access private */ @@ -179,7 +180,7 @@ class Crypt_Base { * Decryption buffer for CTR, OFB and CFB modes * * @see Crypt_Base::decrypt() - * @see Crypt_Base::clearBuffers() + * @see Crypt_Base::_clearBuffers() * @var Array * @access private */ @@ -382,7 +383,7 @@ class Crypt_Base { * * @see Crypt_Base::encrypt() * @see Crypt_Base::decrypt() - * @see Crypt_Base::inline_crypt_setup() + * @see Crypt_Base::_inlineCryptSetup() * @see Crypt_Base::$use_inline_crypt * @var Callback * @access private @@ -465,7 +466,7 @@ class Crypt_Base { } // Determining whether inline crypting can be used by the cipher - if ($this->use_inline_crypt !== false && function_exists('create_function') && is_callable('create_function')) { + if ($this->use_inline_crypt !== false && function_exists('create_function')) { $this->use_inline_crypt = true; } } @@ -715,15 +716,15 @@ 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->_generate_xor($block_size, $xor)); + $buffer['encrypted'].= $this->_encryptBlock($this->_generateXor($block_size, $xor)); } - $key = $this->_string_shift($buffer['encrypted'], $block_size); + $key = $this->_stringShift($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->_generate_xor($block_size, $xor)); + $key = $this->_encryptBlock($this->_generateXor($block_size, $xor)); $ciphertext.= $block ^ $key; } } @@ -785,7 +786,7 @@ class Crypt_Base { $xor = $this->_encryptBlock($xor); $buffer['xor'].= $xor; } - $key = $this->_string_shift($buffer['xor'], $block_size); + $key = $this->_stringShift($buffer['xor'], $block_size); $ciphertext.= $block ^ $key; } } else { @@ -929,15 +930,15 @@ 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->_generate_xor($block_size, $xor)); + $buffer['ciphertext'].= $this->_encryptBlock($this->_generateXor($block_size, $xor)); } - $key = $this->_string_shift($buffer['ciphertext'], $block_size); + $key = $this->_stringShift($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->_generate_xor($block_size, $xor)); + $key = $this->_encryptBlock($this->_generateXor($block_size, $xor)); $plaintext.= $block ^ $key; } } @@ -998,7 +999,7 @@ class Crypt_Base { $xor = $this->_encryptBlock($xor); $buffer['xor'].= $xor; } - $key = $this->_string_shift($buffer['xor'], $block_size); + $key = $this->_stringShift($buffer['xor'], $block_size); $plaintext.= $block ^ $key; } } else { @@ -1022,130 +1023,6 @@ class Crypt_Base { return $this->paddable ? $this->_unpad($plaintext) : $plaintext; } - /** - * Encrypts a block - * - * Note: Must extend by the child Crypt_* class - * - * @access private - * @param String $in - * @return String - */ - function _encryptBlock($in) - { - echo basename(dirname(__FILE__)) . '/' . basename(__FILE__) . ':' . __LINE__ . ' ' . ( version_compare(PHP_VERSION, '5.0.0', '>=') ? __METHOD__ : __FUNCTION__ ) . '() must extend by ' . get_class($this); - } - - /** - * Decrypts a block - * - * Note: Must extend by the child Crypt_* class - * - * @access private - * @param String $in - * @return String - */ - function _decryptBlock($in) - { - echo basename(dirname(__FILE__)) . '/' . basename(__FILE__) . ':' . __LINE__ . ' ' . ( version_compare(PHP_VERSION, '5.0.0', '>=') ? __METHOD__ : __FUNCTION__ ) . '() must extend by ' . get_class($this); - } - - /** - * Setup the CRYPT_MODE_INTERNAL $engine - * - * (re)init, if necessary, the internal cipher $engine and flush all $buffers - * Used (only) if $engine == CRYPT_MODE_INTERNAL - * - * _setup() will be called each time if $changed === true - * typically this happens when using one or more of following public methods: - * - setKey() - * - setIV() - * - disableContinuousBuffer() - * - First run of encrypt() / decrypt() with no init-settings - * - * Internally: _setup() will, if necessary always called before(!) en/decryption. - * - * Note: Could, but not must, extend by the child Crypt_* class - * - * @see setKey() - * @see setIV() - * @see disableContinuousBuffer() - * @access private - */ - function _setup() - { - $this->clearBuffers(); - $this->_setupKey(); - - if ($this->use_inline_crypt) { - $this->inline_crypt_setup(); - } - } - - /** - * Setup the CRYPT_MODE_MCRYPT $engine - * - * (re)init, if necessary, the (ext)mcrypt resources and flush all $buffers - * Used (only) if $engine = CRYPT_MODE_MCRYPT - * - * _mcryptSetup() will be called each time if $changed === true - * typically this happens when using one or more of following public methods: - * - setKey() - * - setIV() - * - disableContinuousBuffer() - * - First run of encrypt() / decrypt() - * - * Note: Could, but not must, extend by the child Crypt_* class - * - * @see setKey() - * @see setIV() - * @see disableContinuousBuffer() - * @access private - */ - function _mcryptSetup() - { - $this->clearBuffers(); - $this->enchanged = $this->dechanged = true; - - if (!isset($this->enmcrypt)) { - static $mcrypt_modes = array( - CRYPT_MODE_CTR => 'ctr', - CRYPT_MODE_ECB => MCRYPT_MODE_ECB, - CRYPT_MODE_CBC => MCRYPT_MODE_CBC, - CRYPT_MODE_CFB => 'ncfb', - CRYPT_MODE_OFB => MCRYPT_MODE_NOFB, - CRYPT_MODE_STREAM => MCRYPT_MODE_STREAM, - ); - - $this->demcrypt = mcrypt_module_open($this->cipher_name_mcrypt, '', $mcrypt_modes[$this->mode], ''); - $this->enmcrypt = mcrypt_module_open($this->cipher_name_mcrypt, '', $mcrypt_modes[$this->mode], ''); - - if ($this->mode == CRYPT_MODE_CFB) { - $this->ecb = mcrypt_module_open($this->cipher_name_mcrypt, '', MCRYPT_MODE_ECB, ''); - } - - } // else should mcrypt_generic_deinit be called? - - if ($this->mode == CRYPT_MODE_CFB) { - mcrypt_generic_init($this->ecb, $this->key, str_repeat("\0", $this->block_size)); - } - } - - /** - * Setup the key (expansion) - * - * Only used if $engine == CRYPT_MODE_INTERNAL - * - * Note: Must extend by the child Crypt_* class - * - * @see Crypt_Base::_setup() - * @access private - */ - function _setupKey() - { - echo basename(dirname(__FILE__)) . '/' . basename(__FILE__) . ':' . __LINE__ . ' ' . ( version_compare(PHP_VERSION, '5.0.0', '>=') ? __METHOD__ : __FUNCTION__ ) . '() must extend by ' . get_class($this); - } - /** * Pad "packets". * @@ -1177,60 +1054,6 @@ class Crypt_Base { $this->padding = false; } - /** - * Pads a string - * - * Pads a string using the RSA PKCS padding standards so that its length is a multiple of the blocksize. - * $this->block_size - (strlen($text) % $this->block_size) bytes are added, each of which is equal to - * chr($this->block_size - (strlen($text) % $this->block_size) - * - * If padding is disabled and $text is not a multiple of the blocksize, the string will be padded regardless - * and padding will, hence forth, be enabled. - * - * @see Crypt_Base::_unpad() - * @access private - */ - function _pad($text) - { - $length = strlen($text); - - if (!$this->padding) { - if ($length % $this->block_size == 0) { - return $text; - } else { - user_error("The plaintext's length ($length) is not a multiple of the block size ({$this->block_size})"); - $this->padding = true; - } - } - - $pad = $this->block_size - ($length % $this->block_size); - - return str_pad($text, $length + $pad, chr($pad)); - } - - /** - * Unpads a string. - * - * If padding is enabled and the reported padding length is invalid the encryption key will be assumed to be wrong - * and false will be returned. - * - * @see Crypt_Base::_pad() - * @access private - */ - function _unpad($text) - { - if (!$this->padding) { - return $text; - } - - $length = ord($text[strlen($text) - 1]); - - if (!$length || $length > $this->block_size) { - return false; - } - - return substr($text, 0, -$length); - } /** * Treat consecutive "packets" as if they are a continuous buffer. * @@ -1302,6 +1125,187 @@ class Crypt_Base { $this->changed = true; } + /** + * Encrypts a block + * + * Note: Must extend by the child Crypt_* class + * + * @access private + * @param String $in + * @return String + */ + function _encryptBlock($in) + { + echo basename(dirname(__FILE__)) . '/' . basename(__FILE__) . ':' . __LINE__ . ' ' . ( version_compare(PHP_VERSION, '5.0.0', '>=') ? __METHOD__ : __FUNCTION__ ) . '() must extend by ' . get_class($this); + } + + /** + * Decrypts a block + * + * Note: Must extend by the child Crypt_* class + * + * @access private + * @param String $in + * @return String + */ + function _decryptBlock($in) + { + echo basename(dirname(__FILE__)) . '/' . basename(__FILE__) . ':' . __LINE__ . ' ' . ( version_compare(PHP_VERSION, '5.0.0', '>=') ? __METHOD__ : __FUNCTION__ ) . '() must extend by ' . get_class($this); + } + + /** + * Setup the CRYPT_MODE_INTERNAL $engine + * + * (re)init, if necessary, the internal cipher $engine and flush all $buffers + * Used (only) if $engine == CRYPT_MODE_INTERNAL + * + * _setup() will be called each time if $changed === true + * typically this happens when using one or more of following public methods: + * - setKey() + * - setIV() + * - disableContinuousBuffer() + * - First run of encrypt() / decrypt() with no init-settings + * + * Internally: _setup() will, if necessary always called before(!) en/decryption. + * + * Note: Could, but not must, extend by the child Crypt_* class + * + * @see setKey() + * @see setIV() + * @see disableContinuousBuffer() + * @access private + */ + function _setup() + { + $this->_clearBuffers(); + $this->_setupKey(); + + if ($this->use_inline_crypt) { + $this->_inlineCryptSetup(); + } + } + + /** + * Setup the CRYPT_MODE_MCRYPT $engine + * + * (re)init, if necessary, the (ext)mcrypt resources and flush all $buffers + * Used (only) if $engine = CRYPT_MODE_MCRYPT + * + * _mcryptSetup() will be called each time if $changed === true + * typically this happens when using one or more of following public methods: + * - setKey() + * - setIV() + * - disableContinuousBuffer() + * - First run of encrypt() / decrypt() + * + * Note: Could, but not must, extend by the child Crypt_* class + * + * @see setKey() + * @see setIV() + * @see disableContinuousBuffer() + * @access private + */ + function _mcryptSetup() + { + $this->_clearBuffers(); + $this->enchanged = $this->dechanged = true; + + if (!isset($this->enmcrypt)) { + static $mcrypt_modes = array( + CRYPT_MODE_CTR => 'ctr', + CRYPT_MODE_ECB => MCRYPT_MODE_ECB, + CRYPT_MODE_CBC => MCRYPT_MODE_CBC, + CRYPT_MODE_CFB => 'ncfb', + CRYPT_MODE_OFB => MCRYPT_MODE_NOFB, + CRYPT_MODE_STREAM => MCRYPT_MODE_STREAM, + ); + + $this->demcrypt = mcrypt_module_open($this->cipher_name_mcrypt, '', $mcrypt_modes[$this->mode], ''); + $this->enmcrypt = mcrypt_module_open($this->cipher_name_mcrypt, '', $mcrypt_modes[$this->mode], ''); + + if ($this->mode == CRYPT_MODE_CFB) { + $this->ecb = mcrypt_module_open($this->cipher_name_mcrypt, '', MCRYPT_MODE_ECB, ''); + } + + } // else should mcrypt_generic_deinit be called? + + if ($this->mode == CRYPT_MODE_CFB) { + mcrypt_generic_init($this->ecb, $this->key, str_repeat("\0", $this->block_size)); + } + } + + /** + * Setup the key (expansion) + * + * Only used if $engine == CRYPT_MODE_INTERNAL + * + * Note: Must extend by the child Crypt_* class + * + * @see Crypt_Base::_setup() + * @access private + */ + function _setupKey() + { + echo basename(dirname(__FILE__)) . '/' . basename(__FILE__) . ':' . __LINE__ . ' ' . ( version_compare(PHP_VERSION, '5.0.0', '>=') ? __METHOD__ : __FUNCTION__ ) . '() must extend by ' . get_class($this); + } + + /** + * Pads a string + * + * Pads a string using the RSA PKCS padding standards so that its length is a multiple of the blocksize. + * $this->block_size - (strlen($text) % $this->block_size) bytes are added, each of which is equal to + * chr($this->block_size - (strlen($text) % $this->block_size) + * + * If padding is disabled and $text is not a multiple of the blocksize, the string will be padded regardless + * and padding will, hence forth, be enabled. + * + * @see Crypt_Base::_unpad() + * @param String $text + * @access private + */ + function _pad($text) + { + $length = strlen($text); + + if (!$this->padding) { + if ($length % $this->block_size == 0) { + return $text; + } else { + user_error("The plaintext's length ($length) is not a multiple of the block size ({$this->block_size})"); + $this->padding = true; + } + } + + $pad = $this->block_size - ($length % $this->block_size); + + return str_pad($text, $length + $pad, chr($pad)); + } + + /** + * Unpads a string. + * + * If padding is enabled and the reported padding length is invalid the encryption key will be assumed to be wrong + * and false will be returned. + * + * @see Crypt_Base::_pad() + * @param String $text + * @access private + */ + function _unpad($text) + { + if (!$this->padding) { + return $text; + } + + $length = ord($text[strlen($text) - 1]); + + if (!$length || $length > $this->block_size) { + return false; + } + + return substr($text, 0, -$length); + } + /** * Clears internal buffers * @@ -1312,9 +1316,8 @@ class Crypt_Base { * Note: Could, but not must, extend by the child Crypt_* class * * @access public - * @param String $iv */ - function clearBuffers() + function _clearBuffers() { $this->enbuffer = array('encrypted' => '', 'xor' => '', 'pos' => 0, 'enmcrypt_init' => true); $this->debuffer = array('ciphertext' => '', 'xor' => '', 'pos' => 0, 'demcrypt_init' => true); @@ -1334,7 +1337,7 @@ class Crypt_Base { * @return String * @access private */ - function _string_shift(&$string, $index = 1) + function _stringShift(&$string, $index = 1) { $substr = substr($string, 0, $index); $string = substr($string, $index); @@ -1353,7 +1356,7 @@ class Crypt_Base { * @param Integer $length * @param String $iv */ - function _generate_xor($length, &$iv) + function _generateXor($length, &$iv) { $xor = ''; $block_size = $this->block_size; @@ -1387,25 +1390,31 @@ class Crypt_Base { * in $this->inline_crypt * * Internally for phpseclib developers: - * inline_crypt_setup() would be called only if + * + * _inlineCryptSetup() would be called only if: + * * - $engine == CRYPT_MODE_INTERNAL and + * * - $use_inline_crypt === true + * * - each time on _setup(), after(!) _setupKey() * - * This ensures that inline_crypt_setup() has allways a + * + * This ensures that _inlineCryptSetup() has allways a * full ready2go initializated internal cipher $engine state * where, for example, the keys allready expanded, * keys/block_size calculated and such. * - * It is, each time if called, the responsibility of inline_crypt_setup(): + * It is, each time if called, the responsibility of _inlineCryptSetup(): + * * - to set $this->inline_crypt to a valid and fully working callback function * as a (faster) replacement for encrypt() / decrypt() * * - NOT to create unlimited callback functions (for memory reasons!) - * no matter how often inline_crypt_setup() would be called. At some + * no matter how often _inlineCryptSetup() would be called. At some * point of amount they must be generic re-useable. * - * - the code of inline_crypt_setup() it self, + * - the code of _inlineCryptSetup() it self, * and the generated callback code, * must be, in following order: * - 100% safe @@ -1414,23 +1423,23 @@ class Crypt_Base { * compatibility (down to php4) or fallback is provided * - readable/maintainable/understandable/commented and... not-cryptic-styled-code :-) * - >= 10% faster than encrypt()/decrypt() [which is, by the way, - * the reason for the existence of inline_crypt_setup() :-)] + * the reason for the existence of _inlineCryptSetup() :-)] * - memory-nice * - short (as good as possible) * - * Note: inline_crypt_setup() is using createInlineCryptFunction() to create the full callback function code. + * Note: _inlineCryptSetup() is using _createInlineCryptFunction() to create the full callback function code. * * Note: In case of using inline crypting, it must extend by the child Crypt_* class * * @see Crypt_Base::_setup() - * @see Crypt_Base::createInlineCryptFunction() + * @see Crypt_Base::_createInlineCryptFunction() * @see Crypt_Base::encrypt() * @see Crypt_Base::decrypt() * @access private */ - function inline_crypt_setup() + function _inlineCryptSetup() { - // If a Crypt_* class providing inline crypting it must extend inline_crypt_setup() + // If a Crypt_* class providing inline crypting it must extend _inlineCryptSetup() // 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 @@ -1446,15 +1455,22 @@ class Crypt_Base { * * Internally for phpseclib developers: * - * createInlineCryptFunction() - * a) merge the $cipher_code [setup'ed by inline_crypt_setup()] - * with the current [$this->]mode of operation code - * b) create the $inline function, which called by encrypt() / decrypt() - * as its replacement to speed up the en/decryption operations. - * c) return the name of the created $inline callback function - * d) used to speed up en/decryption + * _createInlineCryptFunction(): + * + * - merge the $cipher_code [setup'ed by _inlineCryptSetup()] + * with the current [$this->]mode of operation code + * + * - create the $inline function, which called by encrypt() / decrypt() + * as its replacement to speed up the en/decryption operations. + * + * - return the name of the created $inline callback function + * + * - used to speed up en/decryption + * + * * * The main reason why can speed up things [up to 50%] this way are: + * * - using variables more effective then regular. * (ie no use of expensive arrays but integers $k_0, $k_1 ... * or even, for example, the pure $key[] values hardcoded) @@ -1469,59 +1485,62 @@ class Crypt_Base { * The basic code architectur of the generated $inline en/decrypt() * lambda function, in pseudo php, is: * - * +-------------------------------------------------------------------------------------------------+ - * | callback $inline = create_function: | - * | lambda_function_0001_crypt_ECB($action, $text) | - * | { | - * | INSERT PHP CODE OF: | - * | $cipher_code['init_crypt']; // general init code. | - * | // ie: $sbox'es declarations used for | - * | // encrypt and decrypt'ing. | - * | | - * | switch ($action) { | - * | case 'encrypt': | - * | INSERT PHP CODE OF: | - * | $cipher_code['init_encrypt']; // encrypt sepcific init code. | - * | ie: specified $key or $box | - * | declarations for encrypt'ing. | - * | | - * | foreach ($ciphertext) { | - * | $in = $block_size of $ciphertext; | - * | | - * | INSERT PHP CODE OF: | - * | $cipher_code['encrypt_block']; // encrypt's (string) $in, which is always: | - * | // strlen($in) == $this->block_size | - * | // here comes the cipher algorithm in action | - * | // for encryption. | - * | | - * | $plaintext .= $in; | - * | } | - * | return $plaintext; | - * | | - * | case 'decrypt': | - * | INSERT PHP CODE OF: | - * | $cipher_code['init_decrypt']; // decrypt sepcific init code | - * | ie: specified $key or $box | - * | declarations for decrypt'ing. | - * | foreach ($plaintext) { | - * | $in = $block_size of $plaintext; | - * | | - * | INSERT PHP CODE OF: | - * | $cipher_code['decrypt_block']; // decrypt's (string) $in, which is always | - * | // strlen($in) == $this->block_size | - * | // here comes the cipher algorithm in action | - * | // for decryption. | - * | $ciphertext .= $in; | - * | } | - * | return $ciphertext; | - * | } | - * | } | - * +-------------------------------------------------------------------------------------------------+ + * + * +----------------------------------------------------------------------------------------------+ + * | callback $inline = create_function: | + * | lambda_function_0001_crypt_ECB($action, $text) | + * | { | + * | INSERT PHP CODE OF: | + * | $cipher_code['init_crypt']; // general init code. | + * | // ie: $sbox'es declarations used for | + * | // encrypt and decrypt'ing. | + * | | + * | switch ($action) { | + * | case 'encrypt': | + * | INSERT PHP CODE OF: | + * | $cipher_code['init_encrypt']; // encrypt sepcific init code. | + * | ie: specified $key or $box | + * | declarations for encrypt'ing. | + * | | + * | foreach ($ciphertext) { | + * | $in = $block_size of $ciphertext; | + * | | + * | INSERT PHP CODE OF: | + * | $cipher_code['encrypt_block']; // encrypt's (string) $in, which is always: | + * | // strlen($in) == $this->block_size | + * | // here comes the cipher algorithm in action | + * | // for encryption. | + * | | + * | $plaintext .= $in; | + * | } | + * | return $plaintext; | + * | | + * | case 'decrypt': | + * | INSERT PHP CODE OF: | + * | $cipher_code['init_decrypt']; // decrypt sepcific init code | + * | ie: specified $key or $box | + * | declarations for decrypt'ing. | + * | foreach ($plaintext) { | + * | $in = $block_size of $plaintext; | + * | | + * | INSERT PHP CODE OF: | + * | $cipher_code['decrypt_block']; // decrypt's (string) $in, which is always | + * | // strlen($in) == $this->block_size | + * | // here comes the cipher algorithm in action | + * | // for decryption. | + * | $ciphertext .= $in; | + * | } | + * | return $ciphertext; | + * | } | + * | } | + * +----------------------------------------------------------------------------------------------+ + * * - * See also the Crypt_*::inline_crypt_setup()'s for + * See also the Crypt_*::_inlineCryptSetup()'s for * productive inline $cipher_code's how they works. * * Structure of: + * * $cipher_code = array( * 'init_crypt' => (string) '', // optional * 'init_encrypt' => (string) '', // optional @@ -1529,15 +1548,16 @@ class Crypt_Base { * 'encrypt_block' => (string) '', // required * 'decrypt_block' => (string) '' // required * ); + * * - * @see Crypt_Base::inline_crypt_setup() + * @see Crypt_Base::_inlineCryptSetup() * @see Crypt_Base::encrypt() * @see Crypt_Base::decrypt() * @param Array $cipher_code * @access private * @return String (the name of the created callback function) */ - function createInlineCryptFunction($cipher_code) + function _createInlineCryptFunction($cipher_code) { $block_size = $this->block_size; @@ -1593,17 +1613,17 @@ class Crypt_Base { for ($i = 0; $i < $plaintext_len; $i+= '.$block_size.') { $block = substr($text, $i, '.$block_size.'); if (strlen($block) > strlen($buffer["encrypted"])) { - $in = $self->_generate_xor('.$block_size.', $xor); + $in = $self->_generateXor('.$block_size.', $xor); '.$encrypt_block.' $buffer["encrypted"].= $in; } - $key = $self->_string_shift($buffer["encrypted"], '.$block_size.'); + $key = $self->_stringShift($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->_generate_xor('.$block_size.', $xor); + $in = $self->_generateXor('.$block_size.', $xor); '.$encrypt_block.' $key = $in; $ciphertext.= $block ^ $key; @@ -1629,17 +1649,17 @@ 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->_generate_xor('.$block_size.', $xor); + $in = $self->_generateXor('.$block_size.', $xor); '.$encrypt_block.' $buffer["ciphertext"].= $in; } - $key = $self->_string_shift($buffer["ciphertext"], '.$block_size.'); + $key = $self->_stringShift($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->_generate_xor('.$block_size.', $xor); + $in = $self->_generateXor('.$block_size.', $xor); '.$encrypt_block.' $key = $in; $plaintext.= $block ^ $key; @@ -1770,7 +1790,7 @@ class Crypt_Base { $xor = $in; $buffer["xor"].= $xor; } - $key = $self->_string_shift($buffer["xor"], '.$block_size.'); + $key = $self->_stringShift($buffer["xor"], '.$block_size.'); $ciphertext.= $block ^ $key; } } else { @@ -1806,7 +1826,7 @@ class Crypt_Base { $xor = $in; $buffer["xor"].= $xor; } - $key = $self->_string_shift($buffer["xor"], '.$block_size.'); + $key = $self->_stringShift($buffer["xor"], '.$block_size.'); $plaintext.= $block ^ $key; } } else { @@ -1892,7 +1912,7 @@ class Crypt_Base { * Holds the lambda_functions table (classwide) * * Each name of the lambda function, created from - * inline_crypt_setup() && createInlineCryptFunction() + * _inlineCryptSetup() && _createInlineCryptFunction() * is stored, classwide (!), here for reusing. * * The string-based index of $function is a classwide @@ -1903,7 +1923,7 @@ class Crypt_Base { * @return Array * @access private */ - function &get_lambda_functions() + function &_getLambdaFunctions() { static $functions = array(); return $functions; diff --git a/phpseclib/Crypt/Blowfish.php b/phpseclib/Crypt/Blowfish.php index 035d548d..776b7804 100644 --- a/phpseclib/Crypt/Blowfish.php +++ b/phpseclib/Crypt/Blowfish.php @@ -552,12 +552,12 @@ class Crypt_Blowfish extends Crypt_Base { /** * Setup the performance-optimized function for de/encrypt() * - * @see Crypt_Base::inline_crypt_setup() + * @see Crypt_Base::_inlineCryptSetup() * @access private */ - function inline_crypt_setup() + function _inlineCryptSetup() { - $lambda_functions =& Crypt_Blowfish::get_lambda_functions(); + $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. // After that, we'll still create very fast optimized code but not the hi-ultimative code, for each $mode one. @@ -655,7 +655,7 @@ class Crypt_Blowfish extends Crypt_Base { ); '; - $lambda_functions[$code_hash] = $this->createInlineCryptFunction( + $lambda_functions[$code_hash] = $this->_createInlineCryptFunction( array( 'init_crypt' => $init_crypt, 'init_encrypt' => '', diff --git a/phpseclib/Crypt/DES.php b/phpseclib/Crypt/DES.php index 0bc17aa3..230fa56d 100644 --- a/phpseclib/Crypt/DES.php +++ b/phpseclib/Crypt/DES.php @@ -1368,12 +1368,12 @@ class Crypt_DES extends Crypt_Base { /** * Setup the performance-optimized function for de/encrypt() * - * @see Crypt_Base::inline_crypt_setup() + * @see Crypt_Base::_inlineCryptSetup() * @access private */ - function inline_crypt_setup() + function _inlineCryptSetup() { - $lambda_functions =& Crypt_DES::get_lambda_functions(); + $lambda_functions =& Crypt_DES::_getLambdaFunctions(); // Engine configuration for: // - DES ($des_rounds == 1) or @@ -1512,7 +1512,7 @@ class Crypt_DES extends Crypt_Base { } // Creates the inline-crypt function - $lambda_functions[$code_hash] = $this->createInlineCryptFunction( + $lambda_functions[$code_hash] = $this->_createInlineCryptFunction( array( 'init_crypt' => $init_crypt, 'init_encrypt' => $init_encrypt, diff --git a/phpseclib/Crypt/RC4.php b/phpseclib/Crypt/RC4.php index 57c6dc68..c7e0a0c4 100644 --- a/phpseclib/Crypt/RC4.php +++ b/phpseclib/Crypt/RC4.php @@ -184,51 +184,6 @@ class Crypt_RC4 extends Crypt_Base { parent::Crypt_Base(CRYPT_MODE_STREAM); } - /** - * Sets the key. - * - * Keys can be between 1 and 256 bytes long. If they are longer then 256 bytes, the first 256 bytes will - * be used. If no key is explicitly set, it'll be assumed to be a single null byte. - * - * @access public - * @see Crypt_Base::setKey() - * @param String $key - */ - function setKey($key) - { - parent::setKey(substr($key, 0, 256)); - } - - /** - * Setup the key (expansion) - * - * @see Crypt_Base::_setupKey() - * @access private - */ - function _setupKey() - { - $key = $this->key; - $keyLength = strlen($key); - $keyStream = array(); - for ($i = 0; $i < 256; $i++) { - $keyStream[$i] = $i; - } - $j = 0; - for ($i = 0; $i < 256; $i++) { - $j = ($j + $keyStream[$i] + ord($key[$i % $keyLength])) & 255; - $temp = $keyStream[$i]; - $keyStream[$i] = $keyStream[$j]; - $keyStream[$j] = $temp; - } - - $this->stream = array(); - $this->stream[CRYPT_RC4_DECRYPT] = $this->stream[CRYPT_RC4_ENCRYPT] = array( - 0, // index $i - 0, // index $j - $keyStream - ); - } - /** * Dummy function. * @@ -252,6 +207,21 @@ class Crypt_RC4 extends Crypt_Base { { } + /** + * Sets the key. + * + * Keys can be between 1 and 256 bytes long. If they are longer then 256 bytes, the first 256 bytes will + * be used. If no key is explicitly set, it'll be assumed to be a single null byte. + * + * @access public + * @see Crypt_Base::setKey() + * @param String $key + */ + function setKey($key) + { + parent::setKey(substr($key, 0, 256)); + } + /** * Encrypts a message. * @@ -289,6 +259,37 @@ class Crypt_RC4 extends Crypt_Base { return $this->_crypt($ciphertext, CRYPT_RC4_DECRYPT); } + + /** + * Setup the key (expansion) + * + * @see Crypt_Base::_setupKey() + * @access private + */ + function _setupKey() + { + $key = $this->key; + $keyLength = strlen($key); + $keyStream = array(); + for ($i = 0; $i < 256; $i++) { + $keyStream[$i] = $i; + } + $j = 0; + for ($i = 0; $i < 256; $i++) { + $j = ($j + $keyStream[$i] + ord($key[$i % $keyLength])) & 255; + $temp = $keyStream[$i]; + $keyStream[$i] = $keyStream[$j]; + $keyStream[$j] = $temp; + } + + $this->stream = array(); + $this->stream[CRYPT_RC4_DECRYPT] = $this->stream[CRYPT_RC4_ENCRYPT] = array( + 0, // index $i + 0, // index $j + $keyStream + ); + } + /** * Encrypts or decrypts a message. * diff --git a/phpseclib/Crypt/Rijndael.php b/phpseclib/Crypt/Rijndael.php index ca557ff0..6fec3a9d 100644 --- a/phpseclib/Crypt/Rijndael.php +++ b/phpseclib/Crypt/Rijndael.php @@ -1077,6 +1077,7 @@ class Crypt_Rijndael extends Crypt_Base { * Performs S-Box substitutions * * @access private + * @param Integer $word */ function _subWord($word) { @@ -1091,16 +1092,16 @@ class Crypt_Rijndael extends Crypt_Base { /** * Setup the performance-optimized function for de/encrypt() * - * @see Crypt_Base::inline_crypt_setup() + * @see Crypt_Base::_inlineCryptSetup() * @access private */ - function inline_crypt_setup() + function _inlineCryptSetup() { - // Note: inline_crypt_setup() will be called only if $this->changed === true + // Note: _inlineCryptSetup() will be called only if $this->changed === true // So here we are'nt under the same heavy timing-stress as we are in _de/encryptBlock() or de/encrypt(). // However...the here generated function- $code, stored as php callback in $this->inline_crypt, must work as fast as even possible. - $lambda_functions =& Crypt_Rijndael::get_lambda_functions(); + $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. @@ -1242,7 +1243,7 @@ class Crypt_Rijndael extends Crypt_Base { } $decrypt_block .= ');'; - $lambda_functions[$code_hash] = $this->createInlineCryptFunction( + $lambda_functions[$code_hash] = $this->_createInlineCryptFunction( array( 'init_crypt' => '', 'init_encrypt' => $init_encrypt, diff --git a/phpseclib/Crypt/TripleDES.php b/phpseclib/Crypt/TripleDES.php index c2a05802..2c507352 100644 --- a/phpseclib/Crypt/TripleDES.php +++ b/phpseclib/Crypt/TripleDES.php @@ -209,6 +209,26 @@ class Crypt_TripleDES extends Crypt_DES { } } + /** + * Sets the initialization vector. (optional) + * + * SetIV is not required when CRYPT_DES_MODE_ECB is being used. If not explictly set, it'll be assumed + * to be all zero's. + * + * @see Crypt_Base::setIV() + * @access public + * @param String $iv + */ + function setIV($iv) + { + parent::setIV($iv); + if ($this->mode_3cbc) { + $this->des[0]->setIV($iv); + $this->des[1]->setIV($iv); + $this->des[2]->setIV($iv); + } + } + /** * Sets the key. * @@ -248,61 +268,6 @@ class Crypt_TripleDES extends Crypt_DES { } } - /** - * Creates the key schedule - * - * @see Crypt_DES::_setupKey() - * @see Crypt_Base::_setupKey() - * @access private - */ - function _setupKey() - { - switch (true) { - // if $key <= 64bits we configure our internal pure-php cipher engine - // to act as regular [1]DES, not as 3DES. mcrypt.so::tripledes does the same. - case strlen($this->key) <= 8: - $this->des_rounds = 1; - break; - - // otherwise, if $key > 64bits, we configure our engine to work as 3DES. - default: - $this->des_rounds = 3; - - // (only) if 3CBC is used we have, of course, to setup the $des[0-2] keys also separately. - if ($this->mode_3cbc) { - $this->des[0]->_setupKey(); - $this->des[1]->_setupKey(); - $this->des[2]->_setupKey(); - - // because $des[0-2] will, now, do all the work we can return here - // not need unnecessary stress parent::_setupKey() with our, now unused, $key. - return; - } - } - // setup our key - parent::_setupKey(); - } - - /** - * Sets the initialization vector. (optional) - * - * SetIV is not required when CRYPT_DES_MODE_ECB is being used. If not explictly set, it'll be assumed - * to be all zero's. - * - * @see Crypt_Base::setIV() - * @access public - * @param String $iv - */ - function setIV($iv) - { - parent::setIV($iv); - if ($this->mode_3cbc) { - $this->des[0]->setIV($iv); - $this->des[1]->setIV($iv); - $this->des[2]->setIV($iv); - } - } - /** * Encrypts a message. * @@ -411,6 +376,41 @@ class Crypt_TripleDES extends Crypt_DES { $this->des[2]->disableContinuousBuffer(); } } + + /** + * Creates the key schedule + * + * @see Crypt_DES::_setupKey() + * @see Crypt_Base::_setupKey() + * @access private + */ + function _setupKey() + { + switch (true) { + // if $key <= 64bits we configure our internal pure-php cipher engine + // to act as regular [1]DES, not as 3DES. mcrypt.so::tripledes does the same. + case strlen($this->key) <= 8: + $this->des_rounds = 1; + break; + + // otherwise, if $key > 64bits, we configure our engine to work as 3DES. + default: + $this->des_rounds = 3; + + // (only) if 3CBC is used we have, of course, to setup the $des[0-2] keys also separately. + if ($this->mode_3cbc) { + $this->des[0]->_setupKey(); + $this->des[1]->_setupKey(); + $this->des[2]->_setupKey(); + + // because $des[0-2] will, now, do all the work we can return here + // not need unnecessary stress parent::_setupKey() with our, now unused, $key. + return; + } + } + // setup our key + parent::_setupKey(); + } } // vim: ts=4:sw=4:et: diff --git a/phpseclib/Crypt/Twofish.php b/phpseclib/Crypt/Twofish.php index 72803c28..7fc07f8b 100644 --- a/phpseclib/Crypt/Twofish.php +++ b/phpseclib/Crypt/Twofish.php @@ -531,8 +531,8 @@ class Crypt_Twofish extends Crypt_Base { switch (strlen($this->key)) { case 16: - list ($s7, $s6, $s5, $s4) = $this->mds_rem($le_longs[1], $le_longs[2]); - list ($s3, $s2, $s1, $s0) = $this->mds_rem($le_longs[3], $le_longs[4]); + list ($s7, $s6, $s5, $s4) = $this->_mdsrem($le_longs[1], $le_longs[2]); + list ($s3, $s2, $s1, $s0) = $this->_mdsrem($le_longs[3], $le_longs[4]); for ($i = 0, $j = 1; $i < 40; $i+= 2,$j+= 2) { $A = $m0[$q0[$q0[$i] ^ $key[ 9]] ^ $key[1]] ^ $m1[$q0[$q1[$i] ^ $key[10]] ^ $key[2]] ^ @@ -554,9 +554,9 @@ class Crypt_Twofish extends Crypt_Base { } break; case 24: - list ($sb, $sa, $s9, $s8) = $this->mds_rem($le_longs[1], $le_longs[2]); - list ($s7, $s6, $s5, $s4) = $this->mds_rem($le_longs[3], $le_longs[4]); - list ($s3, $s2, $s1, $s0) = $this->mds_rem($le_longs[5], $le_longs[6]); + list ($sb, $sa, $s9, $s8) = $this->_mdsrem($le_longs[1], $le_longs[2]); + list ($s7, $s6, $s5, $s4) = $this->_mdsrem($le_longs[3], $le_longs[4]); + list ($s3, $s2, $s1, $s0) = $this->_mdsrem($le_longs[5], $le_longs[6]); for ($i = 0, $j = 1; $i < 40; $i+= 2, $j+= 2) { $A = $m0[$q0[$q0[$q1[$i] ^ $key[17]] ^ $key[ 9]] ^ $key[1]] ^ $m1[$q0[$q1[$q1[$i] ^ $key[18]] ^ $key[10]] ^ $key[2]] ^ @@ -578,10 +578,10 @@ class Crypt_Twofish extends Crypt_Base { } break; default: // 32 - list ($sf, $se, $sd, $sc) = $this->mds_rem($le_longs[1], $le_longs[2]); - list ($sb, $sa, $s9, $s8) = $this->mds_rem($le_longs[3], $le_longs[4]); - list ($s7, $s6, $s5, $s4) = $this->mds_rem($le_longs[5], $le_longs[6]); - list ($s3, $s2, $s1, $s0) = $this->mds_rem($le_longs[7], $le_longs[8]); + list ($sf, $se, $sd, $sc) = $this->_mdsrem($le_longs[1], $le_longs[2]); + list ($sb, $sa, $s9, $s8) = $this->_mdsrem($le_longs[3], $le_longs[4]); + list ($s7, $s6, $s5, $s4) = $this->_mdsrem($le_longs[5], $le_longs[6]); + list ($s3, $s2, $s1, $s0) = $this->_mdsrem($le_longs[7], $le_longs[8]); for ($i = 0, $j = 1; $i < 40; $i+= 2, $j+= 2) { $A = $m0[$q0[$q0[$q1[$q1[$i] ^ $key[25]] ^ $key[17]] ^ $key[ 9]] ^ $key[1]] ^ $m1[$q0[$q1[$q1[$q0[$i] ^ $key[26]] ^ $key[18]] ^ $key[10]] ^ $key[2]] ^ @@ -611,14 +611,14 @@ class Crypt_Twofish extends Crypt_Base { } /** - * mds_rem function using by the twofish cipher algorithm + * _mdsrem function using by the twofish cipher algorithm * * @access private * @param String $A * @param String $B * @return Array */ - function mds_rem($A, $B) + function _mdsrem($A, $B) { // No gain by unrolling this loop. for ($i = 0; $i < 8; ++$i) { @@ -767,12 +767,12 @@ class Crypt_Twofish extends Crypt_Base { /** * Setup the performance-optimized function for de/encrypt() * - * @see Crypt_Base::inline_crypt_setup() + * @see Crypt_Base::_inlineCryptSetup() * @access private */ - function inline_crypt_setup() + function _inlineCryptSetup() { - $lambda_functions =& Crypt_Twofish::get_lambda_functions(); + $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. $gen_hi_opt_code = (bool)( count($lambda_functions) < 10 ); @@ -901,7 +901,7 @@ class Crypt_Twofish extends Crypt_Base { '.$K[3].' ^ $R1); '; - $lambda_functions[$code_hash] = $this->createInlineCryptFunction( + $lambda_functions[$code_hash] = $this->_createInlineCryptFunction( array( 'init_crypt' => $init_crypt, 'init_encrypt' => '',