* Base Class for all Crypt_* cipher classes
* Internally for phpseclib developers:
* If you plan to add a new cipher class, please note following rules:
* - The new Crypt_* cipher class should extend Crypt_Base
* - Following methods are then required to be overridden/overloaded:
* - All other methods are optional to be overridden/overloaded
* - Look at the source code of the current ciphers how they extend Crypt_Base
* and take one of them as a start up for the new cipher class.
* - Please read all the other comments/notes/hints here also for each class var/method
* LICENSE: Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* @author Jim Wigginton <terrafrost@php.net>
* @author Hans-Juergen Petrich <petrich@tronic-media.com>
* @copyright MMVII Jim Wigginton
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @link http://phpseclib.sourceforge.net
* @see Crypt_Base::encrypt()
* @see Crypt_Base::decrypt()
* Encrypt / decrypt using the Counter mode.
* Set to -1 since that's what Crypt/Random.php uses to index the CTR mode.
* @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Counter_.28CTR.29
define('CRYPT_MODE_CTR', -1);
* Encrypt / decrypt using the Electronic Code Book mode.
* @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Electronic_codebook_.28ECB.29
define('CRYPT_MODE_ECB', 1);
* Encrypt / decrypt using the Code Book Chaining mode.
* @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Cipher-block_chaining_.28CBC.29
define('CRYPT_MODE_CBC', 2);
* Encrypt / decrypt using the Cipher Feedback mode.
* @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Cipher_feedback_.28CFB.29
define('CRYPT_MODE_CFB', 3);
* Encrypt / decrypt using the Output Feedback mode.
* @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Output_feedback_.28OFB.29
define('CRYPT_MODE_OFB', 4);
* Encrypt / decrypt using streaming mode.
define('CRYPT_MODE_STREAM', 5);
* @see Crypt_Base::Crypt_Base()
* Base value for the internal implementation $engine switch
define('CRYPT_MODE_INTERNAL', 1);
* Base value for the mcrypt implementation $engine switch
define('CRYPT_MODE_MCRYPT', 2);
* Base Class for all Crypt_* cipher classes
* @author Jim Wigginton <terrafrost@php.net>
* @author Hans-Juergen Petrich <petrich@tronic-media.com>
* @see Crypt_Base::Crypt_Base()
* The Block Length of the block cipher
* @see Crypt_Base::setKey()
public $key = "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0";
* The Initialization Vector
* @see Crypt_Base::setIV()
* A "sliding" Initialization Vector
* @see Crypt_Base::enableContinuousBuffer()
* @see Crypt_Base::_clearBuffers()
* A "sliding" Initialization Vector
* @see Crypt_Base::enableContinuousBuffer()
* @see Crypt_Base::_clearBuffers()
* Continuous Buffer status
* @see Crypt_Base::enableContinuousBuffer()
public $continuousBuffer = false;
* Encryption buffer for CTR, OFB and CFB modes
* @see Crypt_Base::encrypt()
* @see Crypt_Base::_clearBuffers()
* Decryption buffer for CTR, OFB and CFB modes
* @see Crypt_Base::decrypt()
* @see Crypt_Base::_clearBuffers()
* mcrypt resource for encryption
* The mcrypt resource can be recreated every time something needs to be created or it can be created just once.
* Since mcrypt operates in continuous mode, by default, it'll need to be recreated when in non-continuous mode.
* @see Crypt_Base::encrypt()
* mcrypt resource for decryption
* The mcrypt resource can be recreated every time something needs to be created or it can be created just once.
* Since mcrypt operates in continuous mode, by default, it'll need to be recreated when in non-continuous mode.
* @see Crypt_Base::decrypt()
* Does the enmcrypt resource need to be (re)initialized?
* @see Crypt_Twofish::setKey()
* @see Crypt_Twofish::setIV()
public $enchanged = true;
* Does the demcrypt resource need to be (re)initialized?
* @see Crypt_Twofish::setKey()
* @see Crypt_Twofish::setIV()
public $dechanged = true;
* mcrypt resource for CFB mode
* mcrypt's CFB mode, in (and only in) buffered context,
* is broken, so phpseclib implements the CFB mode by it self,
* even when the mcrypt php extension is available.
* In order to do the CFB-mode work (fast) phpseclib
* use a separate ECB-mode mcrypt resource.
* @link http://phpseclib.sourceforge.net/cfb-demo.phps
* @see Crypt_Base::encrypt()
* @see Crypt_Base::decrypt()
* @see Crypt_Base::_setupMcrypt()
* Optimizing value while CFB-encrypting
* Only relevant if $continuousBuffer enabled
* and $engine == CRYPT_MODE_MCRYPT
* It's faster to re-init $enmcrypt if
* $buffer bytes > $cfb_init_len than
* using the $ecb resource furthermore.
* This value depends of the chosen cipher
* and the time it would be needed for it's
* initialization [by mcrypt_generic_init()]
* which, typically, depends on the complexity
* on its internaly Key-expanding algorithm.
* @see Crypt_Base::encrypt()
public $cfb_init_len = 600;
* Does internal cipher state need to be (re)initialized?
* @see disableContinuousBuffer()
* @see Crypt_Base::enablePadding()
* Is the mode one that is paddable?
* @see Crypt_Base::Crypt_Base()
public $paddable = false;
* Holds which crypt engine internaly should be use,
* which will be determined automatically on __construct()
* Currently available $engines are:
* - 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::encrypt()
* @see Crypt_Base::decrypt()
* The mcrypt specific name of the cipher
* Only used if $engine == CRYPT_MODE_MCRYPT
* @link http://www.php.net/mcrypt_module_open
* @link http://www.php.net/mcrypt_list_algorithms
* @see Crypt_Base::_setupMcrypt()
public $cipher_name_mcrypt;
* The default password key_size used by setPassword()
* @see Crypt_Base::setPassword()
public $password_key_size = 32;
* The default salt used by setPassword()
* @see Crypt_Base::setPassword()
public $password_default_salt = 'phpseclib/salt';
* The namespace used by the cipher for its constants.
* ie: AES.php is using CRYPT_AES_MODE_* for its constants
* so $const_namespace is AES
* DES.php is using CRYPT_DES_MODE_* for its constants
* so $const_namespace is DES... and so on
* All CRYPT_<$const_namespace>_MODE_* are aliases of
* the generic CRYPT_MODE_* constants, so both could be used
* $aes = new Crypt_AES(CRYPT_AES_MODE_CFB); // $aes will operate in cfb mode
* $aes = new Crypt_AES(CRYPT_MODE_CFB); // identical
* @see Crypt_Base::Crypt_Base()
* The name of the performance-optimized callback function
* Used by encrypt() / decrypt()
* only if $engine == CRYPT_MODE_INTERNAL
* @see Crypt_Base::encrypt()
* @see Crypt_Base::decrypt()
* @see Crypt_Base::_setupInlineCrypt()
* @see Crypt_Base::$use_inline_crypt
* Holds whether performance-optimized $inline_crypt() can/should be used.
* @see Crypt_Base::encrypt()
* @see Crypt_Base::decrypt()
* @see Crypt_Base::inline_crypt
public $use_inline_crypt;
* Determines whether or not the mcrypt extension should be used.
* (or the alias constants of the chosen cipher, for example for AES: CRYPT_AES_MODE_ECB or CRYPT_AES_MODE_CBC ...)
* If not explicitly set, CRYPT_MODE_CBC will be used.
* @param optional Integer $mode
public function __construct($mode = CRYPT_MODE_CBC)
$const_crypt_mode = 'CRYPT_'.$this->const_namespace.'_MODE';
// Determining the availibility of mcrypt support for the cipher
if (!defined($const_crypt_mode)) {
case extension_loaded('mcrypt') && in_array($this->cipher_name_mcrypt, mcrypt_list_algorithms()):
define($const_crypt_mode, CRYPT_MODE_MCRYPT);
define($const_crypt_mode, CRYPT_MODE_INTERNAL);
// Determining which internal $engine should be used.
// The fastes possible first.
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;
case constant($const_crypt_mode) == CRYPT_MODE_MCRYPT:
$this->engine = CRYPT_MODE_MCRYPT;
$this->engine = CRYPT_MODE_INTERNAL;
// $mode dependent settings
$this->mode = CRYPT_MODE_CBC;
// 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;
* Sets the initialization vector. (optional)