Merge branch '1.0' into sftp-put-callback-for-1.0

This commit is contained in:
andrey012 2015-05-02 15:24:31 +03:00
commit f4a93c790f
37 changed files with 2529 additions and 1032 deletions

View File

@ -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

View File

@ -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)
*
@ -472,17 +481,17 @@ class Crypt_Blowfish extends Crypt_Base
$r = $in[2];
for ($i = 0; $i < 16; $i+= 2) {
$l^= $p[$i];
$r^= ($sb_0[$l >> 24 & 0xff] +
$sb_1[$l >> 16 & 0xff] ^
$sb_2[$l >> 8 & 0xff]) +
$sb_3[$l & 0xff];
$l^= $p[$i];
$r^= ($sb_0[$l >> 24 & 0xff] +
$sb_1[$l >> 16 & 0xff] ^
$sb_2[$l >> 8 & 0xff]) +
$sb_3[$l & 0xff];
$r^= $p[$i + 1];
$l^= ($sb_0[$r >> 24 & 0xff] +
$sb_1[$r >> 16 & 0xff] ^
$sb_2[$r >> 8 & 0xff]) +
$sb_3[$r & 0xff];
$r^= $p[$i + 1];
$l^= ($sb_0[$r >> 24 & 0xff] +
$sb_1[$r >> 16 & 0xff] ^
$sb_2[$r >> 8 & 0xff]) +
$sb_3[$r & 0xff];
}
return pack("N*", $r ^ $p[17], $l ^ $p[16]);
}
@ -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);
$gen_hi_opt_code = (bool)( count($lambda_functions) < 10 );
switch (true) {
case $gen_hi_opt_code:
$code_hash = md5(str_pad("Crypt_Blowfish, {$this->mode}, ", 32, "\0") . $this->key);
break;
default:
$code_hash = "Crypt_Blowfish, {$this->mode}";
// Generation of a 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])) {

View File

@ -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:
// For hi-optimized code, we create for each combination of
// $mode, $des_rounds and $this->key its own encrypt/decrypt function.
$code_hash = md5(str_pad("Crypt_DES, $des_rounds, {$this->mode}, ", 32, "\0") . $this->key);
break;
default:
// After max 10 hi-optimized functions, we create generic
// (still very fast.. but not ultra) functions for each $mode/$des_rounds
// Currently 2 * 5 generic functions will be then max. possible.
$code_hash = "Crypt_DES, $des_rounds, {$this->mode}";
$code_hash = "Crypt_DES, $des_rounds, {$this->mode}";
if ($gen_hi_opt_code) {
// For hi-optimized code, we create for each combination of
// $mode, $des_rounds and $this->key its own encrypt/decrypt function.
// After max 10 hi-optimized functions, we create generic
// (still very fast.. but not ultra) functions for each $mode/$des_rounds
// Currently 2 * 5 generic functions will be then max. possible.
$code_hash = str_pad($code_hash, 32) . $this->_hashInlineCryptFunction($this->key);
}
// Is there a re-usable $lambda_functions in there? If not, we have to create it.

View File

@ -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);
}
/**
@ -375,15 +407,18 @@ class Crypt_RC2 extends Crypt_Base
* @see Crypt_Base::setKey()
* @access public
* @param String $key
* @param Integer $t1 optional Effective key length in bits.
* @param Integer $t1 optional Effective key length in bits.
*/
function setKey($key, $t1 = 0)
{
$this->orig_key = $key;
if ($t1 <= 0) {
$t1 = $this->default_key_length;
} else if ($t1 > 1024) {
$t1 = 1024;
}
$this->current_key_length = $t1;
// Key byte count should be 1..128.
$key = strlen($key) ? substr($key, 0, 128) : "\x00";
$t = strlen($key);
@ -416,6 +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);

View File

@ -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

View File

@ -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);
}
}

View File

@ -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:
$code_hash = "Crypt_Twofish, {$this->mode}";
// Generation of a uniqe hash for our generated code
$code_hash = "Crypt_Twofish, {$this->mode}";
if ($gen_hi_opt_code) {
$code_hash = str_pad($code_hash, 32) . $this->_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;

View File

@ -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));
* ?>

View File

@ -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++;

View File

@ -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';
}
@ -1107,7 +1138,7 @@ class Net_SSH2
'arcfour256',
'arcfour128',
//'arcfour', // OPTIONAL the ARCFOUR stream cipher with a 128-bit key
//'arcfour', // OPTIONAL the ARCFOUR stream cipher with a 128-bit key
// CTR modes from <http://tools.ietf.org/html/rfc4344#section-4>:
'aes128-ctr', // RECOMMENDED AES (Rijndael) in SDCTR mode, with 128-bit key
@ -1135,9 +1166,18 @@ class Net_SSH2
'3des-ctr', // RECOMMENDED Three-key 3DES in SDCTR mode
'3des-cbc', // REQUIRED three-key 3DES in CBC mode
//'none' // OPTIONAL no encryption; NOT RECOMMENDED
//'none' // OPTIONAL no encryption; NOT RECOMMENDED
);
if (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();

View File

@ -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()
@ -51,10 +44,10 @@ class Functional_Net_SFTPLargeFileTest extends PhpseclibFunctionalTestCase
}
/**
* @group github298
* @group github455
* @group github457
*/
* @group github298
* @group github455
* @group github457
*/
public function testPutSizeLocalFile()
{
$tmp_filename = $this->createTempFile(128, 1024 * 1024);

View File

@ -36,8 +36,8 @@ class Functional_Net_SFTPUserStoryTest extends PhpseclibFunctionalTestCase
}
/**
* @depends testConstructor
*/
* @depends testConstructor
*/
public function testPasswordLogin($sftp)
{
$username = $this->getEnv('SSH_USERNAME');
@ -51,8 +51,8 @@ class Functional_Net_SFTPUserStoryTest extends PhpseclibFunctionalTestCase
}
/**
* @depends testPasswordLogin
*/
* @depends testPasswordLogin
*/
public function testPwdHome($sftp)
{
$this->assertEquals(
@ -65,8 +65,8 @@ class Functional_Net_SFTPUserStoryTest extends PhpseclibFunctionalTestCase
}
/**
* @depends testPwdHome
*/
* @depends testPwdHome
*/
public function testMkDirScratch($sftp)
{
$dirname = self::$scratchDir;
@ -87,8 +87,8 @@ class Functional_Net_SFTPUserStoryTest extends PhpseclibFunctionalTestCase
}
/**
* @depends testMkDirScratch
*/
* @depends testMkDirScratch
*/
public function testChDirScratch($sftp)
{
$this->assertTrue(
@ -120,8 +120,8 @@ class Functional_Net_SFTPUserStoryTest extends PhpseclibFunctionalTestCase
}
/**
* @depends testChDirScratch
*/
* @depends testChDirScratch
*/
public function testStatOnDir($sftp)
{
$this->assertNotSame(
@ -169,8 +169,8 @@ class Functional_Net_SFTPUserStoryTest extends PhpseclibFunctionalTestCase
/**
* @depends testStatOnDir
*/
* @depends testStatOnDir
*/
public function testPutSizeGetFile($sftp)
{
$this->assertTrue(
@ -194,8 +194,8 @@ class Functional_Net_SFTPUserStoryTest extends PhpseclibFunctionalTestCase
}
/**
* @depends testPutSizeGetFile
*/
* @depends testPutSizeGetFile
*/
public function testTouch($sftp)
{
$this->assertTrue(
@ -212,8 +212,8 @@ class Functional_Net_SFTPUserStoryTest extends PhpseclibFunctionalTestCase
}
/**
* @depends testTouch
*/
* @depends testTouch
*/
public function testTruncate($sftp)
{
$this->assertTrue(
@ -236,8 +236,8 @@ class Functional_Net_SFTPUserStoryTest extends PhpseclibFunctionalTestCase
}
/**
* @depends testTruncate
*/
* @depends testTruncate
*/
public function testChDirOnFile($sftp)
{
$this->assertFalse(
@ -249,8 +249,8 @@ class Functional_Net_SFTPUserStoryTest extends PhpseclibFunctionalTestCase
}
/**
* @depends testChDirOnFile
*/
* @depends testChDirOnFile
*/
public function testFileExistsIsFileIsDirFile($sftp)
{
$this->assertTrue(
@ -272,8 +272,8 @@ class Functional_Net_SFTPUserStoryTest extends PhpseclibFunctionalTestCase
}
/**
* @depends testFileExistsIsFileIsDirFile
*/
* @depends testFileExistsIsFileIsDirFile
*/
public function testFileExistsIsFileIsDirFileNonexistent($sftp)
{
$this->assertFalse(
@ -295,8 +295,8 @@ class Functional_Net_SFTPUserStoryTest extends PhpseclibFunctionalTestCase
}
/**
* @depends testFileExistsIsFileIsDirFileNonexistent
*/
* @depends testFileExistsIsFileIsDirFileNonexistent
*/
public function testSortOrder($sftp)
{
$this->assertTrue(
@ -347,8 +347,8 @@ class Functional_Net_SFTPUserStoryTest extends PhpseclibFunctionalTestCase
}
/**
* @depends testSortOrder
*/
* @depends testSortOrder
*/
public function testResourceXfer($sftp)
{
$fp = fopen('res.txt', 'w+');
@ -367,8 +367,8 @@ class Functional_Net_SFTPUserStoryTest extends PhpseclibFunctionalTestCase
}
/**
* @depends testResourceXfer
*/
* @depends testResourceXfer
*/
public function testSymlink($sftp)
{
$this->assertTrue(
@ -380,8 +380,8 @@ class Functional_Net_SFTPUserStoryTest extends PhpseclibFunctionalTestCase
}
/**
* @depends testSymlink
*/
* @depends testSymlink
*/
public function testReadlink($sftp)
{
$this->assertInternalType('string', $sftp->readlink('symlink'),
@ -392,10 +392,10 @@ class Functional_Net_SFTPUserStoryTest extends PhpseclibFunctionalTestCase
}
/**
* on older versions this would result in a fatal error
* @depends testReadlink
* @group github402
*/
* on older versions this would result in a fatal error
* @depends testReadlink
* @group github402
*/
public function testStatcacheFix($sftp)
{
// Name used for both directory and file.
@ -417,8 +417,8 @@ class Functional_Net_SFTPUserStoryTest extends PhpseclibFunctionalTestCase
}
/**
* @depends testStatcacheFix
*/
* @depends testStatcacheFix
*/
public function testChDirUpHome($sftp)
{
$this->assertTrue(
@ -436,8 +436,8 @@ class Functional_Net_SFTPUserStoryTest extends PhpseclibFunctionalTestCase
}
/**
* @depends testChDirUpHome
*/
* @depends testChDirUpHome
*/
public function testFileExistsIsFileIsDirDir($sftp)
{
$this->assertTrue(
@ -459,8 +459,8 @@ class Functional_Net_SFTPUserStoryTest extends PhpseclibFunctionalTestCase
}
/**
* @depends testFileExistsIsFileIsDirDir
*/
* @depends testFileExistsIsFileIsDirDir
*/
public function testTruncateLargeFile($sftp)
{
$filesize = (4 * 1024 + 16) * 1024 * 1024;
@ -473,8 +473,8 @@ class Functional_Net_SFTPUserStoryTest extends PhpseclibFunctionalTestCase
}
/**
* @depends testTruncateLargeFile
*/
* @depends testTruncateLargeFile
*/
public function testRmDirScratch($sftp)
{
$this->assertFalse(
@ -487,8 +487,8 @@ class Functional_Net_SFTPUserStoryTest extends PhpseclibFunctionalTestCase
}
/**
* @depends testRmDirScratch
*/
* @depends testRmDirScratch
*/
public function testDeleteRecursiveScratch($sftp)
{
$this->assertTrue(
@ -501,8 +501,8 @@ class Functional_Net_SFTPUserStoryTest extends PhpseclibFunctionalTestCase
}
/**
* @depends testDeleteRecursiveScratch
*/
* @depends testDeleteRecursiveScratch
*/
public function testRmDirScratchNonexistent($sftp)
{
$this->assertFalse(

View File

@ -21,10 +21,10 @@ class Functional_Net_SSH2Test extends PhpseclibFunctionalTestCase
}
/**
* @depends testConstructor
* @group github408
* @group github412
*/
* @depends testConstructor
* @group github408
* @group github412
*/
public function testPreLogin($ssh)
{
$this->assertFalse(
@ -51,8 +51,8 @@ class Functional_Net_SSH2Test extends PhpseclibFunctionalTestCase
}
/**
* @depends testPreLogin
*/
* @depends testPreLogin
*/
public function testPasswordLogin($ssh)
{
$username = $this->getEnv('SSH_USERNAME');
@ -66,9 +66,9 @@ class Functional_Net_SSH2Test extends PhpseclibFunctionalTestCase
}
/**
* @depends testPasswordLogin
* @group github280
*/
* @depends testPasswordLogin
* @group github280
*/
public function testExecWithMethodCallback($ssh)
{
$callbackObject = $this->getMock('stdClass', array('callbackMethod'));

View File

@ -33,11 +33,11 @@ abstract class PhpseclibFunctionalTestCase extends PhpseclibTestCase
}
/**
* @param string $variable
* @param string|null $message
*
* @return null
*/
* @param string $variable
* @param string|null $message
*
* @return null
*/
protected function requireEnv($variable, $message = null)
{
if ($this->_getEnv($variable) === false) {
@ -50,10 +50,10 @@ abstract class PhpseclibFunctionalTestCase extends PhpseclibTestCase
}
/**
* @param string $variable
*
* @return string
*/
* @param string $variable
*
* @return string
*/
protected function getEnv($variable)
{
$this->requireEnv($variable);

View File

@ -20,17 +20,17 @@ abstract class PhpseclibTestCase extends PHPUnit_Framework_TestCase
}
/**
* Creates a temporary file on the local filesystem and returns its path.
* The $number_of_writes and $bytes_per_write parameters can be used to
* write $number_of_writes * $bytes_per_write times the character 'a' to the
* temporary file. All files created using this method will be deleted from
* the filesystem on tearDown(), i.e. after each test method was run.
*
* @param int $number_of_writes
* @param int $bytes_per_write
*
* @return string
*/
* Creates a temporary file on the local filesystem and returns its path.
* The $number_of_writes and $bytes_per_write parameters can be used to
* write $number_of_writes * $bytes_per_write times the character 'a' to the
* temporary file. All files created using this method will be deleted from
* the filesystem on tearDown(), i.e. after each test method was run.
*
* @param int $number_of_writes
* @param int $bytes_per_write
*
* @return string
*/
protected function createTempFile($number_of_writes = 0, $bytes_per_write = 0)
{
$filename = tempnam(sys_get_temp_dir(), 'phpseclib-test-');
@ -48,11 +48,11 @@ abstract class PhpseclibTestCase extends PHPUnit_Framework_TestCase
}
/**
* @param string $constant
* @param mixed $expected
*
* @return null
*/
* @param string $constant
* @param mixed $expected
*
* @return null
*/
static protected function ensureConstant($constant, $expected)
{
if (defined($constant)) {
@ -82,10 +82,10 @@ abstract class PhpseclibTestCase extends PHPUnit_Framework_TestCase
}
/**
* @param string $filename
*
* @return null
*/
* @param string $filename
*
* @return null
*/
static protected function reRequireFile($filename)
{
if (function_exists('runkit_import')) {

View File

@ -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;
}
}

View File

@ -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;
}
}

View 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;
}
}

View File

@ -9,25 +9,34 @@ 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');
}
}
/**
* Produces all combinations of test values.
*
* @return array
*/
* Produces all combinations of test values.
*
* @return array
*/
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(
'',
@ -59,15 +68,18 @@ abstract class Unit_Crypt_AES_TestCase extends PhpseclibTestCase
}
/**
* @dataProvider continuousBufferCombos
*/
* @dataProvider continuousBufferCombos
*/
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]));
@ -77,31 +89,245 @@ abstract class Unit_Crypt_AES_TestCase extends PhpseclibTestCase
}
/**
* @group github451
*/
* @group github451
*/
public function testKeyPaddingRijndael()
{
// this test case is from the following URL:
// 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'));
}
/**
* @group github451
*/
* @group github451
*/
public function testKeyPaddingAES()
{
// 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');
}
}

View 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");
}
}

View 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');
}
}
}

View File

@ -13,8 +13,8 @@ class Unit_Crypt_Hash_MD5Test extends Unit_Crypt_Hash_TestCase
}
/**
* @dataProvider hashData()
*/
* @dataProvider hashData()
*/
public function testHash($message, $result)
{
$this->assertHashesTo($this->getInstance(), $message, $result);
@ -30,8 +30,8 @@ class Unit_Crypt_Hash_MD5Test extends Unit_Crypt_Hash_TestCase
}
/**
* @dataProvider hmacData()
*/
* @dataProvider hmacData()
*/
public function testHMAC($key, $message, $result)
{
$this->assertHMACsTo($this->getInstance(), $key, $message, $result);

View File

@ -13,8 +13,8 @@ class Unit_Crypt_Hash_SHA256Test extends Unit_Crypt_Hash_TestCase
}
/**
* @dataProvider hashData()
*/
* @dataProvider hashData()
*/
public function testHash($message, $result)
{
$this->assertHashesTo($this->getInstance(), $message, $result);
@ -39,8 +39,8 @@ class Unit_Crypt_Hash_SHA256Test extends Unit_Crypt_Hash_TestCase
}
/**
* @dataProvider hmacData()
*/
* @dataProvider hmacData()
*/
public function testHMAC($key, $message, $result)
{
$this->assertHMACsTo($this->getInstance(), $key, $message, $result);

View File

@ -13,16 +13,16 @@ class Unit_Crypt_Hash_SHA256_96Test extends Unit_Crypt_Hash_SHA256Test
}
/**
* @dataProvider hashData()
*/
* @dataProvider hashData()
*/
public function testHash($message, $longResult)
{
parent::testHash($message, substr($longResult, 0, 24));
}
/**
* @dataProvider hmacData()
*/
* @dataProvider hmacData()
*/
public function testHMAC($key, $message, $longResult)
{
parent::testHMAC($key, $message, substr($longResult, 0, 24));

View File

@ -13,8 +13,8 @@ class Unit_Crypt_Hash_SHA512Test extends Unit_Crypt_Hash_TestCase
}
/**
* @dataProvider hashData()
*/
* @dataProvider hashData()
*/
public function testHash($message, $result)
{
$this->assertHashesTo($this->getInstance(), $message, $result);
@ -39,8 +39,8 @@ class Unit_Crypt_Hash_SHA512Test extends Unit_Crypt_Hash_TestCase
}
/**
* @dataProvider hmacData()
*/
* @dataProvider hmacData()
*/
public function testHMAC($key, $message, $result)
{
$this->assertHMACsTo($this->getInstance(), $key, $message, $result);

View File

@ -13,16 +13,16 @@ class Unit_Crypt_Hash_SHA512_96Test extends Unit_Crypt_Hash_SHA512Test
}
/**
* @dataProvider hashData()
*/
* @dataProvider hashData()
*/
public function testHash($message, $longResult)
{
parent::testHash($message, substr($longResult, 0, 24));
}
/**
* @dataProvider hmacData()
*/
* @dataProvider hmacData()
*/
public function testHMAC($key, $message, $longResult)
{
parent::testHMAC($key, $message, substr($longResult, 0, 24));

View 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");
}
}

View 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");
}
}

View File

@ -261,10 +261,10 @@ Ao8eayMp6FcvNucIpUndo1X8dKMv3Y26ZQIDAQAB
}
/**
* make phpseclib generated XML keys be unsigned. this may need to be reverted
* if it is later learned that XML keys are, in fact, supposed to be signed
* @group github468
*/
* make phpseclib generated XML keys be unsigned. this may need to be reverted
* if it is later learned that XML keys are, in fact, supposed to be signed
* @group github468
*/
public function testUnsignedXML()
{
$rsa = new Crypt_RSA();
@ -282,8 +282,8 @@ Ao8eayMp6FcvNucIpUndo1X8dKMv3Y26ZQIDAQAB
}
/**
* @group github468
*/
* @group github468
*/
public function testSignedPKCS1()
{
$rsa = new Crypt_RSA();

View File

@ -27,9 +27,9 @@ class Unit_Crypt_RandomTest extends PhpseclibTestCase
}
/**
* Takes a set of random values of length 128 bits and asserts all taken
* values are unique.
*/
* Takes a set of random values of length 128 bits and asserts all taken
* values are unique.
*/
public function testStringUniqueness()
{
$values = array();

View 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");
}
}
}

View 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");
}
}
}

View File

@ -10,9 +10,9 @@ require_once 'File/ASN1.php';
class Unit_File_ASN1Test extends PhpseclibTestCase
{
/**
* on older versions of File_ASN1 this would yield a PHP Warning
* @group github275
*/
* on older versions of File_ASN1 this would yield a PHP Warning
* @group github275
*/
public function testAnyString()
{
$KDC_REP = array(
@ -83,9 +83,9 @@ class Unit_File_ASN1Test extends PhpseclibTestCase
}
/**
* on older versions of File_ASN1 this would produce a null instead of an array
* @group github275
*/
* on older versions of File_ASN1 this would produce a null instead of an array
* @group github275
*/
public function testIncorrectString()
{
$PA_DATA = array(
@ -235,8 +235,8 @@ class Unit_File_ASN1Test extends PhpseclibTestCase
}
/**
* older versions of File_ASN1 didn't handle indefinite length tags very well
*/
* older versions of File_ASN1 didn't handle indefinite length tags very well
*/
public function testIndefiniteLength()
{
$asn1 = new File_ASN1();
@ -270,8 +270,8 @@ class Unit_File_ASN1Test extends PhpseclibTestCase
}
/**
* @group github477
*/
* @group github477
*/
public function testContextSpecificNonConstructed()
{
$asn1 = new File_ASN1();
@ -280,8 +280,8 @@ class Unit_File_ASN1Test extends PhpseclibTestCase
}
/**
* @group github602
*/
* @group github602
*/
public function testEmptyContextTag()
{
$asn1 = new File_ASN1();

View File

@ -295,8 +295,8 @@ abstract class Unit_Math_BigInteger_TestCase extends PhpseclibTestCase
}
/**
* @group github279
*/
* @group github279
*/
public function testDiffieHellmanKeyAgreement()
{
if (getenv('TRAVIS') && PHP_VERSION === '5.3.3'

View File

@ -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);
}