TripleDES: updates to accomodate inner chaining

This commit is contained in:
terrafrost 2015-01-17 09:42:47 -06:00
parent 0f01128e98
commit e9470d1fc5
2 changed files with 48 additions and 21 deletions

View File

@ -68,13 +68,21 @@ if (!class_exists('Crypt_DES')) {
* *
* Inner chaining is used by SSH-1 and is generally considered to be less secure then outer chaining (CRYPT_DES_MODE_CBC3). * 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); define('CRYPT_DES_MODE_3CBC', -2);
/** /**
* Encrypt / decrypt using outer chaining * Encrypt / decrypt using outer chaining
* *
* Outer chaining is used by SSH-2 and when the mode is set to CRYPT_DES_MODE_CBC. * Outer chaining is used by SSH-2 and when the mode is set to CRYPT_DES_MODE_CBC.
*/ */
define('CRYPT_DES_MODE_CBC3', CRYPT_DES_MODE_CBC); define('CRYPT_MODE_CBC3', CRYPT_MODE_CBC);
/**
* BC version of the above.
*/
define('CRYPT_DES_MODE_CBC3', CRYPT_MODE_CBC3);
/**#@-*/ /**#@-*/
/** /**
@ -190,20 +198,20 @@ class Crypt_TripleDES extends Crypt_DES
* @param optional Integer $mode * @param optional Integer $mode
* @access public * @access public
*/ */
function Crypt_TripleDES($mode = CRYPT_DES_MODE_CBC) function Crypt_TripleDES($mode = CRYPT_MODE_CBC)
{ {
switch ($mode) { switch ($mode) {
// In case of CRYPT_DES_MODE_3CBC, we init as CRYPT_DES_MODE_CBC // In case of CRYPT_DES_MODE_3CBC, we init as CRYPT_DES_MODE_CBC
// and additional flag us internally as 3CBC // and additional flag us internally as 3CBC
case CRYPT_DES_MODE_3CBC: case CRYPT_DES_MODE_3CBC:
parent::Crypt_Base(CRYPT_DES_MODE_CBC); parent::Crypt_Base(CRYPT_MODE_CBC);
$this->mode_3cbc = true; $this->mode_3cbc = true;
// This three $des'es will do the 3CBC work (if $key > 64bits) // This three $des'es will do the 3CBC work (if $key > 64bits)
$this->des = array( $this->des = array(
new Crypt_DES(CRYPT_DES_MODE_CBC), new Crypt_DES(CRYPT_MODE_CBC),
new Crypt_DES(CRYPT_DES_MODE_CBC), new Crypt_DES(CRYPT_MODE_CBC),
new Crypt_DES(CRYPT_DES_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 // we're going to be doing the padding, ourselves, so disable it in the Crypt_DES objects
@ -308,7 +316,7 @@ class Crypt_TripleDES extends Crypt_DES
function encrypt($plaintext) function encrypt($plaintext)
{ {
// parent::en/decrypt() is able to do all the work for all modes and keylengths, // 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 the key is smaller then 8, do what we'd normally do
if ($this->mode_3cbc && strlen($this->key) > 8) { if ($this->mode_3cbc && strlen($this->key) > 8) {
@ -455,19 +463,19 @@ class Crypt_TripleDES extends Crypt_DES
* Sets the internal crypt engine * Sets the internal crypt engine
* *
* @see Crypt_Base::Crypt_Base() * @see Crypt_Base::Crypt_Base()
* @see Crypt_Base::setEngine() * @see Crypt_Base::setPreferredEngine()
* @param optional Integer $engine * @param Integer $engine
* @access public * @access public
* @return Integer * @return Integer
*/ */
function setEngine($engine = CRYPT_DES_MODE_MCRYPT) function setPreferredEngine($engine)
{ {
if ($this->mode_3cbc) { if ($this->mode_3cbc) {
$this->des[0]->setEngine($engine); $this->des[0]->setPreferredEngine($engine);
$this->des[1]->setEngine($engine); $this->des[1]->setPreferredEngine($engine);
$this->des[2]->setEngine($engine); $this->des[2]->setPreferredEngine($engine);
} }
return parent::setEngine($engine); return parent::setPreferredEngine($engine);
} }
} }

View File

@ -9,14 +9,14 @@ require_once 'Crypt/TripleDES.php';
class Unit_Crypt_TripleDESTest extends PhpseclibTestCase class Unit_Crypt_TripleDESTest extends PhpseclibTestCase
{ {
var $engines = array(
CRYPT_ENGINE_INTERNAL => 'internal',
CRYPT_ENGINE_MCRYPT => 'mcrypt',
CRYPT_ENGINE_OPENSSL => 'OpenSSL',
);
public function engineVectors() public function engineVectors()
{ {
$engines = array(
CRYPT_ENGINE_INTERNAL => 'internal',
CRYPT_ENGINE_MCRYPT => 'mcrypt',
CRYPT_ENGINE_OPENSSL => 'OpenSSL',
);
// tests from http://csrc.nist.gov/publications/nistpubs/800-20/800-20.pdf#page=273 // tests from http://csrc.nist.gov/publications/nistpubs/800-20/800-20.pdf#page=273
$tests = array( $tests = array(
// Table A.1 // Table A.1
@ -88,7 +88,7 @@ class Unit_Crypt_TripleDESTest extends PhpseclibTestCase
); );
$result = array(); $result = array();
// @codingStandardsIgnoreStart // @codingStandardsIgnoreStart
foreach ($engines as $engine => $engineName) foreach ($this->engines as $engine => $engineName)
foreach ($tests as $test) foreach ($tests as $test)
$result[] = array($engine, $engineName, $test[0], $test[1], $test[2]); $result[] = array($engine, $engineName, $test[0], $test[1], $test[2]);
// @codingStandardsIgnoreEnd // @codingStandardsIgnoreEnd
@ -160,4 +160,23 @@ class Unit_Crypt_TripleDESTest extends PhpseclibTestCase
$plaintext = bin2hex($plaintext); $plaintext = bin2hex($plaintext);
$this->assertEquals($result, $expected, "Failed asserting that $plaintext yielded expected output in $engineName engine"); $this->assertEquals($result, $expected, "Failed asserting that $plaintext yielded expected output in $engineName engine");
} }
public function testInnerChaining()
{
// regular CBC returns
// e089b6d84708c6bc80be6c2da82bd19a79ffe11f02933ac1
$expected = 'e089b6d84708c6bc6f04c8971121603d7be2861efae0f3f5';
$des = new Crypt_TripleDES(CRYPT_DES_MODE_3CBC);
$des->setKey('abcdefghijklmnopqrstuvwx');
for ($this->engines as $engine->$engineName) {
$des->setPreferredEngine($engine);
if (!$des->isValidEngine($engine)) {
self::markTestSkipped('Unable to initialize ' . $engineName . ' engine');
}
$result = bin2hex($des->encrypt(str_repeat('a', 16));
$this->assertEquals($result, $expected, "Failed asserting inner chainin worked correctly in $engineName engine");
}
}
} }