mirror of
https://github.com/phpseclib/phpseclib.git
synced 2024-11-05 21:17:53 +00:00
Merge branch '1.0' into sftp-put-callback-for-1.0
This commit is contained in:
commit
f4a93c790f
@ -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()}
|
||||
@ -107,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.
|
||||
*
|
||||
@ -201,7 +191,7 @@ class Crypt_AES extends Crypt_Rijndael
|
||||
default:
|
||||
$this->key_size = 32;
|
||||
}
|
||||
$this->_setupEngine();
|
||||
$this->_setEngine();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -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.
|
||||
*
|
||||
@ -174,7 +160,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
|
||||
@ -340,7 +326,7 @@ class Crypt_Blowfish extends Crypt_Base
|
||||
/**
|
||||
* P-Array consists of 18 32-bit subkeys
|
||||
*
|
||||
* @var array $parray
|
||||
* @var array
|
||||
* @access private
|
||||
*/
|
||||
var $parray = array(
|
||||
@ -354,7 +340,7 @@ class Crypt_Blowfish extends Crypt_Base
|
||||
*
|
||||
* Holds the expanded key [p] and the key-depended s-boxes [sb]
|
||||
*
|
||||
* @var array $bctx
|
||||
* @var array
|
||||
* @access private
|
||||
*/
|
||||
var $bctx;
|
||||
@ -395,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::isValidEngine()
|
||||
* @param Integer $engine
|
||||
* @access public
|
||||
* @return Boolean
|
||||
*/
|
||||
function isValidEngine($engine)
|
||||
{
|
||||
if ($engine == CRYPT_ENGINE_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)
|
||||
*
|
||||
@ -519,7 +528,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]);
|
||||
}
|
||||
|
||||
@ -534,15 +542,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 );
|
||||
|
||||
switch (true) {
|
||||
case $gen_hi_opt_code:
|
||||
$code_hash = md5(str_pad("Crypt_Blowfish, {$this->mode}, ", 32, "\0") . $this->key);
|
||||
break;
|
||||
default:
|
||||
// Generation of a unique hash for our generated code
|
||||
$code_hash = "Crypt_Blowfish, {$this->mode}";
|
||||
if ($gen_hi_opt_code) {
|
||||
$code_hash = str_pad($code_hash, 32) . $this->_hashInlineCryptFunction($this->key);
|
||||
}
|
||||
|
||||
if (!isset($lambda_functions[$code_hash])) {
|
||||
|
@ -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.
|
||||
*
|
||||
@ -191,6 +177,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
|
||||
*
|
||||
@ -661,6 +662,28 @@ 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::isValidEngine()
|
||||
* @param Integer $engine
|
||||
* @access public
|
||||
* @return Boolean
|
||||
*/
|
||||
function isValidEngine($engine)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the key.
|
||||
*
|
||||
@ -1358,21 +1381,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:
|
||||
$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.
|
||||
$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 = str_pad($code_hash, 32) . $this->_hashInlineCryptFunction($this->key);
|
||||
}
|
||||
|
||||
// Is there a re-usable $lambda_functions in there? If not, we have to create it.
|
||||
|
@ -99,20 +99,6 @@ define('CRYPT_RC2_MODE_CFB', CRYPT_MODE_CFB);
|
||||
define('CRYPT_RC2_MODE_OFB', CRYPT_MODE_OFB);
|
||||
/**#@-*/
|
||||
|
||||
/**#@+
|
||||
* @access private
|
||||
* @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.
|
||||
*
|
||||
@ -138,7 +124,19 @@ class Crypt_RC2 extends Crypt_Base
|
||||
* @var String
|
||||
* @access private
|
||||
*/
|
||||
var $key = "\0";
|
||||
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()
|
||||
@ -189,6 +187,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
|
||||
*
|
||||
@ -341,7 +350,30 @@ class Crypt_RC2 extends Crypt_Base
|
||||
function Crypt_RC2($mode = CRYPT_RC2_MODE_CBC)
|
||||
{
|
||||
parent::Crypt_Base($mode);
|
||||
$this->setKey('');
|
||||
}
|
||||
|
||||
/**
|
||||
* 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_ENGINE_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);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -379,11 +411,14 @@ class Crypt_RC2 extends Crypt_Base
|
||||
*/
|
||||
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 +451,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_ENGINE_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_ENGINE_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
|
||||
*
|
||||
@ -506,6 +587,21 @@ class Crypt_RC2 extends Crypt_Base
|
||||
return pack('vvvv', $r0, $r1, $r2, $r3);
|
||||
}
|
||||
|
||||
/**
|
||||
* Setup the CRYPT_ENGINE_MCRYPT $engine
|
||||
*
|
||||
* @see Crypt_Base::_setupMcrypt()
|
||||
* @access private
|
||||
*/
|
||||
function _setupMcrypt()
|
||||
{
|
||||
if (!isset($this->key)) {
|
||||
$this->setKey('');
|
||||
}
|
||||
|
||||
parent::_setupMcrypt();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the key schedule
|
||||
*
|
||||
@ -514,6 +610,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);
|
||||
@ -536,14 +636,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->_hashInlineCryptFunction($this->key);
|
||||
}
|
||||
|
||||
// Is there a re-usable $lambda_functions in there?
|
||||
// If not, we have to create it.
|
||||
@ -551,6 +651,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);
|
||||
|
@ -69,20 +69,6 @@ if (!class_exists('Crypt_Base')) {
|
||||
include_once 'Base.php';
|
||||
}
|
||||
|
||||
/**#@+
|
||||
* @access private
|
||||
* @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()
|
||||
@ -181,6 +167,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_ENGINE_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.
|
||||
*
|
||||
@ -230,7 +248,7 @@ class Crypt_RC4 extends Crypt_Base
|
||||
*/
|
||||
function encrypt($plaintext)
|
||||
{
|
||||
if ($this->engine == CRYPT_MODE_MCRYPT) {
|
||||
if ($this->engine != CRYPT_ENGINE_INTERNAL) {
|
||||
return parent::encrypt($plaintext);
|
||||
}
|
||||
return $this->_crypt($plaintext, CRYPT_RC4_ENCRYPT);
|
||||
@ -250,7 +268,7 @@ class Crypt_RC4 extends Crypt_Base
|
||||
*/
|
||||
function decrypt($ciphertext)
|
||||
{
|
||||
if ($this->engine == CRYPT_MODE_MCRYPT) {
|
||||
if ($this->engine != CRYPT_ENGINE_INTERNAL) {
|
||||
return parent::decrypt($ciphertext);
|
||||
}
|
||||
return $this->_crypt($ciphertext, CRYPT_RC4_DECRYPT);
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -59,19 +59,31 @@ if (!class_exists('Crypt_DES')) {
|
||||
include_once 'DES.php';
|
||||
}
|
||||
|
||||
/**#@+
|
||||
* @access public
|
||||
* @see Crypt_TripleDES::Crypt_TripleDES()
|
||||
*/
|
||||
/**
|
||||
* Encrypt / decrypt using inner chaining
|
||||
*
|
||||
* 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);
|
||||
/**#@-*/
|
||||
|
||||
/**
|
||||
* Pure-PHP implementation of Triple DES.
|
||||
@ -186,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
|
||||
@ -213,6 +225,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_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;
|
||||
}
|
||||
|
||||
return parent::isValidEngine($engine);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the initialization vector. (optional)
|
||||
*
|
||||
@ -255,7 +288,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));
|
||||
}
|
||||
@ -283,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) {
|
||||
@ -425,4 +458,24 @@ class Crypt_TripleDES extends Crypt_DES
|
||||
// setup our key
|
||||
parent::_setupKey();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the internal crypt engine
|
||||
*
|
||||
* @see Crypt_Base::Crypt_Base()
|
||||
* @see Crypt_Base::setPreferredEngine()
|
||||
* @param Integer $engine
|
||||
* @access public
|
||||
* @return Integer
|
||||
*/
|
||||
function setPreferredEngine($engine)
|
||||
{
|
||||
if ($this->mode_3cbc) {
|
||||
$this->des[0]->setPreferredEngine($engine);
|
||||
$this->des[1]->setPreferredEngine($engine);
|
||||
$this->des[2]->setPreferredEngine($engine);
|
||||
}
|
||||
|
||||
return parent::setPreferredEngine($engine);
|
||||
}
|
||||
}
|
||||
|
@ -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.
|
||||
*
|
||||
@ -754,21 +740,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:
|
||||
// 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->_hashInlineCryptFunction($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) {
|
||||
@ -786,7 +770,6 @@ class Crypt_Twofish extends Crypt_Base
|
||||
for ($i = 0; $i < 40; ++$i) {
|
||||
$K[] = '$K_' . $i;
|
||||
}
|
||||
|
||||
$init_crypt = '
|
||||
$S0 = $self->S0;
|
||||
$S1 = $self->S1;
|
||||
|
@ -17,7 +17,7 @@
|
||||
* if (!$ssh->login('username', 'password')) {
|
||||
* exit('bad login');
|
||||
* }
|
||||
|
||||
*
|
||||
* $scp = new Net_SCP($ssh);
|
||||
* $scp->put('abcd', str_repeat('x', 1024*1024));
|
||||
* ?>
|
||||
|
@ -1793,11 +1793,12 @@ class Net_SFTP extends Net_SSH2
|
||||
* @param optional Integer $mode
|
||||
* @param optional Integer $start
|
||||
* @param optional Integer $local_start
|
||||
* @param optional callable|null $callback
|
||||
* @return Boolean
|
||||
* @access public
|
||||
* @internal ASCII mode for SFTPv4/5/6 can be supported by adding a new function - Net_SFTP::setMode().
|
||||
*/
|
||||
function put($remote_file, $data, $mode = NET_SFTP_STRING, $start = -1, $local_start = -1)
|
||||
function put($remote_file, $data, $mode = NET_SFTP_STRING, $start = -1, $local_start = -1, $callback = null)
|
||||
{
|
||||
if (!($this->bitmap & NET_SSH2_MASK_LOGIN)) {
|
||||
return false;
|
||||
@ -1911,6 +1912,9 @@ class Net_SFTP extends Net_SSH2
|
||||
return false;
|
||||
}
|
||||
$sent+= strlen($temp);
|
||||
if (is_callable($callback)) {
|
||||
call_user_func($callback, $sent);
|
||||
}
|
||||
|
||||
$i++;
|
||||
|
||||
|
@ -826,6 +826,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;
|
||||
|
||||
/**
|
||||
* A System_SSH_Agent for use in the SSH2 Agent Forwarding scenario
|
||||
*
|
||||
@ -860,6 +870,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',
|
||||
@ -935,6 +950,20 @@ class Net_SSH2
|
||||
$this->timeout = $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
|
||||
*
|
||||
@ -1065,7 +1094,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';
|
||||
}
|
||||
|
||||
@ -1138,6 +1169,15 @@ class Net_SSH2
|
||||
//'none' // OPTIONAL no encryption; NOT RECOMMENDED
|
||||
);
|
||||
|
||||
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', 'arcfour128', 'arcfour')
|
||||
);
|
||||
}
|
||||
|
||||
if (phpseclib_resolve_include_path('Crypt/RC4.php') === false) {
|
||||
$encryption_algorithms = array_diff(
|
||||
$encryption_algorithms,
|
||||
@ -1649,6 +1689,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();
|
||||
|
||||
@ -1666,6 +1709,9 @@ class Net_SSH2
|
||||
}
|
||||
|
||||
if ($this->decrypt) {
|
||||
if ($this->crypto_engine) {
|
||||
$this->decrypt->setEngine($this->crypto_engine);
|
||||
}
|
||||
$this->decrypt->enableContinuousBuffer();
|
||||
$this->decrypt->disablePadding();
|
||||
|
||||
|
@ -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()
|
||||
|
@ -7,11 +7,8 @@
|
||||
|
||||
class Unit_Crypt_AES_InternalTest extends Unit_Crypt_AES_TestCase
|
||||
{
|
||||
static public function setUpBeforeClass()
|
||||
protected function setUp()
|
||||
{
|
||||
parent::setUpBeforeClass();
|
||||
|
||||
self::ensureConstant('CRYPT_AES_MODE', CRYPT_AES_MODE_INTERNAL);
|
||||
self::ensureConstant('CRYPT_RIJNDAEL_MODE', CRYPT_RIJNDAEL_MODE_INTERNAL);
|
||||
$this->engine = CRYPT_ENGINE_INTERNAL;
|
||||
}
|
||||
}
|
||||
|
@ -7,15 +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.');
|
||||
}
|
||||
|
||||
parent::setUpBeforeClass();
|
||||
|
||||
self::ensureConstant('CRYPT_AES_MODE', CRYPT_AES_MODE_MCRYPT);
|
||||
self::ensureConstant('CRYPT_RIJNDAEL_MODE', CRYPT_RIJNDAEL_MODE_MCRYPT);
|
||||
$this->engine = CRYPT_ENGINE_MCRYPT;
|
||||
}
|
||||
}
|
||||
|
14
tests/Unit/Crypt/AES/OpenSSLTest.php
Normal file
14
tests/Unit/Crypt/AES/OpenSSLTest.php
Normal file
@ -0,0 +1,14 @@
|
||||
<?php
|
||||
/**
|
||||
* @author Andreas Fischer <bantu@phpbb.com>
|
||||
* @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_ENGINE_OPENSSL;
|
||||
}
|
||||
}
|
@ -9,12 +9,21 @@ require_once 'Crypt/AES.php';
|
||||
|
||||
abstract class Unit_Crypt_AES_TestCase extends PhpseclibTestCase
|
||||
{
|
||||
static public function setUpBeforeClass()
|
||||
{
|
||||
parent::setUpBeforeClass();
|
||||
protected $engine;
|
||||
|
||||
self::reRequireFile('Crypt/Rijndael.php');
|
||||
self::reRequireFile('Crypt/AES.php');
|
||||
private function _checkEngine($aes)
|
||||
{
|
||||
if ($aes->getEngine() != $this->engine) {
|
||||
$engine = 'internal';
|
||||
switch ($this->engine) {
|
||||
case CRYPT_ENGINE_OPENSSL:
|
||||
$engine = 'OpenSSL';
|
||||
break;
|
||||
case CRYPT_ENGINE_MCRYPT:
|
||||
$engine = 'mcrypt';
|
||||
}
|
||||
self::markTestSkipped('Unable to initialize ' . $engine . ' engine');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -25,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(
|
||||
'',
|
||||
@ -64,10 +73,13 @@ abstract class Unit_Crypt_AES_TestCase extends PhpseclibTestCase
|
||||
public function testEncryptDecryptWithContinuousBuffer($mode, $plaintext, $iv, $key)
|
||||
{
|
||||
$aes = new Crypt_AES(constant($mode));
|
||||
$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,8 +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->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'));
|
||||
}
|
||||
@ -99,9 +113,221 @@ abstract class Unit_Crypt_AES_TestCase extends PhpseclibTestCase
|
||||
// same as the above - just with a different ciphertext
|
||||
|
||||
$aes = new Crypt_AES();
|
||||
$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);
|
||||
|
||||
if (!$this->_checkEngine($aes)) {
|
||||
return;
|
||||
}
|
||||
|
||||
foreach ($test as $len) {
|
||||
$temp = str_repeat('d', $len);
|
||||
$output = $aes->$op($temp);
|
||||
$result.= $output;
|
||||
}
|
||||
|
||||
$c2 = $result;
|
||||
|
||||
$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)
|
||||
{
|
||||
if (count($test) == 1) {
|
||||
return;
|
||||
}
|
||||
|
||||
$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 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->disablePadding();
|
||||
|
||||
$aes->setPreferredEngine($this->engine);
|
||||
$this->_checkEngine($aes);
|
||||
|
||||
$result = bin2hex($aes->encrypt(pack('H*', 'f34481ec3cc627bacd5dc3fb08f273e6')));
|
||||
$this->assertSame($result, '0336763e966d92595a567cc9ce537f5e');
|
||||
$result = bin2hex($aes->encrypt(pack('H*', '9798c4640bad75c7c3227db910174e72')));
|
||||
$this->assertSame($result, 'a9a1631bf4996954ebc093957b234589');
|
||||
$result = bin2hex($aes->encrypt(pack('H*', '96ab5c2ff612d9dfaae8c31f30c42168')));
|
||||
$this->assertSame($result, 'ff4f8391a6a40ca5b25d23bedd44a597');
|
||||
$result = bin2hex($aes->encrypt(pack('H*', '6a118a874519e64e9963798a503f1d35')));
|
||||
$this->assertSame($result, 'dc43be40be0e53712f7e2bf5ca707209');
|
||||
$result = bin2hex($aes->encrypt(pack('H*', 'cb9fceec81286ca3e989bd979b0cb284')));
|
||||
$this->assertSame($result, '92beedab1895a94faa69b632e5cc47ce');
|
||||
$result = bin2hex($aes->encrypt(pack('H*', 'b26aeb1874e47ca8358ff22378f09144')));
|
||||
$this->assertSame($result, '459264f4798f6a78bacb89c15ed3d601');
|
||||
$result = bin2hex($aes->encrypt(pack('H*', '58c8e00b2631686d54eab84b91f0aca1')));
|
||||
$this->assertSame($result, '08a4e2efec8a8e3312ca7460b9040bbf');
|
||||
}
|
||||
|
||||
public function testGFSBox192()
|
||||
{
|
||||
$aes = new Crypt_AES();
|
||||
|
||||
$aes->setKey(pack('H*', '000000000000000000000000000000000000000000000000'));
|
||||
$aes->setIV(pack('H*', '00000000000000000000000000000000'));
|
||||
$aes->disablePadding();
|
||||
|
||||
$aes->setPreferredEngine($this->engine);
|
||||
$this->_checkEngine($aes);
|
||||
|
||||
$result = bin2hex($aes->encrypt(pack('H*', '1b077a6af4b7f98229de786d7516b639')));
|
||||
$this->assertSame($result, '275cfc0413d8ccb70513c3859b1d0f72');
|
||||
$result = bin2hex($aes->encrypt(pack('H*', '9c2d8842e5f48f57648205d39a239af1')));
|
||||
$this->assertSame($result, 'c9b8135ff1b5adc413dfd053b21bd96d');
|
||||
$result = bin2hex($aes->encrypt(pack('H*', 'bff52510095f518ecca60af4205444bb')));
|
||||
$this->assertSame($result, '4a3650c3371ce2eb35e389a171427440');
|
||||
$result = bin2hex($aes->encrypt(pack('H*', '51719783d3185a535bd75adc65071ce1')));
|
||||
$this->assertSame($result, '4f354592ff7c8847d2d0870ca9481b7c');
|
||||
$result = bin2hex($aes->encrypt(pack('H*', '26aa49dcfe7629a8901a69a9914e6dfd')));
|
||||
$this->assertSame($result, 'd5e08bf9a182e857cf40b3a36ee248cc');
|
||||
$result = bin2hex($aes->encrypt(pack('H*', '941a4773058224e1ef66d10e0a6ee782')));
|
||||
$this->assertSame($result, '067cd9d3749207791841562507fa9626');
|
||||
}
|
||||
|
||||
public function testGFSBox256()
|
||||
{
|
||||
$aes = new Crypt_AES();
|
||||
|
||||
$aes->setKey(pack('H*', '00000000000000000000000000000000' . '00000000000000000000000000000000'));
|
||||
$aes->setIV(pack('H*', '00000000000000000000000000000000'));
|
||||
$aes->disablePadding();
|
||||
|
||||
$aes->setPreferredEngine($this->engine);
|
||||
$this->_checkEngine($aes);
|
||||
|
||||
$result = bin2hex($aes->encrypt(pack('H*', '014730f80ac625fe84f026c60bfd547d')));
|
||||
$this->assertSame($result, '5c9d844ed46f9885085e5d6a4f94c7d7');
|
||||
$result = bin2hex($aes->encrypt(pack('H*', '0b24af36193ce4665f2825d7b4749c98')));
|
||||
$this->assertSame($result, 'a9ff75bd7cf6613d3731c77c3b6d0c04');
|
||||
$result = bin2hex($aes->encrypt(pack('H*', '761c1fe41a18acf20d241650611d90f1')));
|
||||
$this->assertSame($result, '623a52fcea5d443e48d9181ab32c7421');
|
||||
$result = bin2hex($aes->encrypt(pack('H*', '8a560769d605868ad80d819bdba03771')));
|
||||
$this->assertSame($result, '38f2c7ae10612415d27ca190d27da8b4');
|
||||
$result = bin2hex($aes->encrypt(pack('H*', '91fbef2d15a97816060bee1feaa49afe')));
|
||||
$this->assertSame($result, '1bc704f1bce135ceb810341b216d7abe');
|
||||
}
|
||||
}
|
||||
|
83
tests/Unit/Crypt/BlowfishTest.php
Normal file
83
tests/Unit/Crypt/BlowfishTest.php
Normal file
@ -0,0 +1,83 @@
|
||||
<?php
|
||||
/**
|
||||
* @author Andreas Fischer <bantu@phpbb.com>
|
||||
* @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");
|
||||
}
|
||||
}
|
77
tests/Unit/Crypt/DESTest.php
Normal file
77
tests/Unit/Crypt/DESTest.php
Normal file
@ -0,0 +1,77 @@
|
||||
<?php
|
||||
/**
|
||||
* @author Andreas Fischer <bantu@phpbb.com>
|
||||
* @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_DESTest extends PhpseclibTestCase
|
||||
{
|
||||
public function testEncryptPadding()
|
||||
{
|
||||
$des = new Crypt_DES(CRYPT_MODE_CBC);
|
||||
$des->setKey('d');
|
||||
$des->setIV('d');
|
||||
|
||||
$des->setPreferredEngine(CRYPT_ENGINE_INTERNAL);
|
||||
|
||||
$result = pack('H*', '3e7613642049af1e');
|
||||
|
||||
$internal = $des->encrypt('d');
|
||||
$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($result, $mcrypt, 'Failed asserting that the mcrypt engine produced the correct result');
|
||||
} else {
|
||||
self::markTestSkipped('Unable to initialize mcrypt engine');
|
||||
}
|
||||
|
||||
$des->setPreferredEngine(CRYPT_ENGINE_OPENSSL);
|
||||
if ($des->getEngine() == CRYPT_ENGINE_OPENSSL) {
|
||||
$openssl = $des->encrypt('d');
|
||||
$this->assertEquals($result, $openssl, 'Failed asserting that the OpenSSL engine produced the correct result');
|
||||
} 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);
|
||||
$des->disablePadding();
|
||||
// when the key and iv are not specified they should be null padded
|
||||
//$des->setKey();
|
||||
//$des->setIV();
|
||||
|
||||
$des->setPreferredEngine(CRYPT_ENGINE_INTERNAL);
|
||||
$internal = $des->decrypt('d');
|
||||
|
||||
$result = pack('H*', '79b305d1ce555221');
|
||||
$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($result, $mcrypt, 'Failed asserting that the mcrypt engine produced the correct result');
|
||||
} else {
|
||||
self::markTestSkipped('Unable to initialize mcrypt engine');
|
||||
}
|
||||
|
||||
$des->setPreferredEngine(CRYPT_ENGINE_OPENSSL);
|
||||
if ($des->getEngine() == CRYPT_ENGINE_OPENSSL) {
|
||||
$openssl = $des->decrypt('d');
|
||||
$this->assertEquals($result, $openssl, 'Failed asserting that the OpenSSL engine produced the correct result');
|
||||
} else {
|
||||
self::markTestSkipped('Unable to initialize OpenSSL engine');
|
||||
}
|
||||
}
|
||||
}
|
121
tests/Unit/Crypt/RC2Test.php
Normal file
121
tests/Unit/Crypt/RC2Test.php
Normal file
@ -0,0 +1,121 @@
|
||||
<?php
|
||||
/**
|
||||
* @author Andreas Fischer <bantu@phpbb.com>
|
||||
* @copyright MMXIII Andreas Fischer
|
||||
* @license http://www.opensource.org/licenses/mit-license.html MIT License
|
||||
*/
|
||||
|
||||
require_once 'Crypt/RC2.php';
|
||||
|
||||
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('88bca90e90875a7f0f79c384627bafb216f80a6f85920584c42fceb0be255daf1e', 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);
|
||||
|
||||
// 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 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
|
||||
// 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_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($result, $mcrypt, 'Failed asserting that the mcrypt engine produced the correct result');
|
||||
} else {
|
||||
self::markTestSkipped('Unable to initialize mcrypt engine');
|
||||
}
|
||||
|
||||
$rc2->setPreferredEngine(CRYPT_ENGINE_OPENSSL);
|
||||
if ($rc2->getEngine() == CRYPT_ENGINE_OPENSSL) {
|
||||
$openssl = $rc2->encrypt('d');
|
||||
$this->assertEquals($result, $openssl, 'Failed asserting that the OpenSSL engine produced the correct result');
|
||||
} else {
|
||||
self::markTestSkipped('Unable to initialize OpenSSL engine');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider engineVectors
|
||||
*/
|
||||
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");
|
||||
}
|
||||
}
|
207
tests/Unit/Crypt/RC4Test.php
Normal file
207
tests/Unit/Crypt/RC4Test.php
Normal file
@ -0,0 +1,207 @@
|
||||
<?php
|
||||
/**
|
||||
* @author Jim Wigginton <terrafrost@php.net>
|
||||
* @copyright 2014 Jim Wigginton
|
||||
* @license http://www.opensource.org/licenses/mit-license.html MIT License
|
||||
*/
|
||||
|
||||
require_once 'Crypt/RC4.php';
|
||||
|
||||
class Unit_Crypt_RC4Test 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'), // 40-bit key
|
||||
'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'), // 56-bit key
|
||||
'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'), // 64-bit key
|
||||
'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')
|
||||
)
|
||||
),
|
||||
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();
|
||||
// @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);
|
||||
$rc4->setKey($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");
|
||||
}
|
||||
}
|
182
tests/Unit/Crypt/TripleDESTest.php
Normal file
182
tests/Unit/Crypt/TripleDESTest.php
Normal file
@ -0,0 +1,182 @@
|
||||
<?php
|
||||
/**
|
||||
* @author Jim Wigginton <terrafrost@php.net>
|
||||
* @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
|
||||
{
|
||||
var $engines = array(
|
||||
CRYPT_ENGINE_INTERNAL => 'internal',
|
||||
CRYPT_ENGINE_MCRYPT => 'mcrypt',
|
||||
CRYPT_ENGINE_OPENSSL => 'OpenSSL',
|
||||
);
|
||||
|
||||
public function engineVectors()
|
||||
{
|
||||
// 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 ($this->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)
|
||||
{
|
||||
$des = new Crypt_TripleDES();
|
||||
if (!$des->isValidEngine($engine)) {
|
||||
self::markTestSkipped('Unable to initialize ' . $engineName . ' engine');
|
||||
}
|
||||
$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");
|
||||
}
|
||||
|
||||
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], $test[3]);
|
||||
// @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");
|
||||
}
|
||||
|
||||
public function testInnerChaining()
|
||||
{
|
||||
// regular CBC returns
|
||||
// e089b6d84708c6bc80be6c2da82bd19a79ffe11f02933ac1
|
||||
$expected = 'e089b6d84708c6bc6f04c8971121603d7be2861efae0f3f5';
|
||||
|
||||
$des = new Crypt_TripleDES(CRYPT_DES_MODE_3CBC);
|
||||
$des->setKey('abcdefghijklmnopqrstuvwx');
|
||||
|
||||
foreach ($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");
|
||||
}
|
||||
}
|
||||
}
|
73
tests/Unit/Crypt/TwofishTest.php
Normal file
73
tests/Unit/Crypt/TwofishTest.php
Normal file
@ -0,0 +1,73 @@
|
||||
<?php
|
||||
/**
|
||||
* @author Andreas Fischer <bantu@phpbb.com>
|
||||
* @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();
|
||||
$tf->disablePadding();
|
||||
|
||||
// tests from https://www.schneier.com/code/ecb_ival.txt
|
||||
|
||||
// key size = 128
|
||||
$key = pack('H*', '00000000000000000000000000000000');
|
||||
$tf->setKey($key);
|
||||
if (!$tf->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 (!$tf->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 (!$tf->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");
|
||||
}
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user