Merge branch 'cipher-revamp'

This commit is contained in:
terrafrost 2016-03-14 23:00:21 -05:00
commit 574d36fb7d
10 changed files with 36 additions and 17 deletions

View File

@ -65,6 +65,7 @@ class AES extends Rijndael
* *
* @see \phpseclib\Crypt\Rijndael::setBlockLength() * @see \phpseclib\Crypt\Rijndael::setBlockLength()
* @access public * @access public
* @param int $length
* @throws \BadMethodCallException anytime it's called * @throws \BadMethodCallException anytime it's called
*/ */
function setBlockLength($length) function setBlockLength($length)
@ -90,7 +91,7 @@ class AES extends Rijndael
case 256: case 256:
break; break;
default: default:
throw new \LengthException('Key of size ' . strlen($key) . ' not supported by this algorithm. Only keys of sizes 16, 24 or 32 supported'); throw new \LengthException('Key of size ' . $length . ' not supported by this algorithm. Only keys of sizes 128, 192 or 256 supported');
} }
parent::setKeyLength($length); parent::setKeyLength($length);
} }

View File

@ -793,7 +793,7 @@ abstract class Base
$this->changed = false; $this->changed = false;
} }
if ($this->enchanged) { if ($this->enchanged) {
mcrypt_generic_init($this->enmcrypt, $this->key, $this->encryptIV); mcrypt_generic_init($this->enmcrypt, $this->key, $this->_getIV($this->encryptIV));
$this->enchanged = false; $this->enchanged = false;
} }
@ -856,7 +856,7 @@ abstract class Base
$ciphertext = mcrypt_generic($this->enmcrypt, $plaintext); $ciphertext = mcrypt_generic($this->enmcrypt, $plaintext);
if (!$this->continuousBuffer) { if (!$this->continuousBuffer) {
mcrypt_generic_init($this->enmcrypt, $this->key, $this->encryptIV); mcrypt_generic_init($this->enmcrypt, $this->key, $this->_getIV($this->encryptIV));
} }
return $ciphertext; return $ciphertext;
@ -1010,8 +1010,8 @@ abstract class Base
*/ */
function decrypt($ciphertext) function decrypt($ciphertext)
{ {
if ($this->paddable) { if ($this->paddable && strlen($ciphertext) % $this->block_size) {
throw new \LengthException('The ciphertext length (' . strlen($ciphertext) . ') needs to be a multiple of the block size (' . $this->block_length . ')'); throw new \LengthException('The ciphertext length (' . strlen($ciphertext) . ') needs to be a multiple of the block size (' . $this->block_size . ')');
} }
if ($this->engine === self::ENGINE_OPENSSL) { if ($this->engine === self::ENGINE_OPENSSL) {
@ -1104,7 +1104,7 @@ abstract class Base
$this->changed = false; $this->changed = false;
} }
if ($this->dechanged) { if ($this->dechanged) {
mcrypt_generic_init($this->demcrypt, $this->key, $this->decryptIV); mcrypt_generic_init($this->demcrypt, $this->key, $this->_getIV($this->decryptIV));
$this->dechanged = false; $this->dechanged = false;
} }
@ -1149,7 +1149,7 @@ abstract class Base
$plaintext = mdecrypt_generic($this->demcrypt, $ciphertext); $plaintext = mdecrypt_generic($this->demcrypt, $ciphertext);
if (!$this->continuousBuffer) { if (!$this->continuousBuffer) {
mcrypt_generic_init($this->demcrypt, $this->key, $this->decryptIV); mcrypt_generic_init($this->demcrypt, $this->key, $this->_getIV($this->decryptIV));
} }
return $this->paddable ? $this->_unpad($plaintext) : $plaintext; return $this->paddable ? $this->_unpad($plaintext) : $plaintext;
@ -1286,6 +1286,22 @@ abstract class Base
return $this->paddable ? $this->_unpad($plaintext) : $plaintext; return $this->paddable ? $this->_unpad($plaintext) : $plaintext;
} }
/**
* Get the IV
*
* mcrypt requires an IV even if ECB is used
*
* @see self::encrypt()
* @see self::decrypt()
* @param string $iv
* @return string
* @access private
*/
function _getIV($iv)
{
return $this->mode == self::MODE_ECB ? str_repeat("\0", $this->block_size) : $iv;
}
/** /**
* OpenSSL CTR Processor * OpenSSL CTR Processor
* *

View File

@ -209,7 +209,7 @@ class RC4 extends Base
throw new \LengthException('Key size of ' . $length . ' bytes is not supported by RC4. Keys must be between 1 and 256 bytes long'); throw new \LengthException('Key size of ' . $length . ' bytes is not supported by RC4. Keys must be between 1 and 256 bytes long');
} }
parent::setKey($length); parent::setKey($key);
} }
/** /**

View File

@ -264,7 +264,7 @@ abstract class PKCS
return false; return false;
} }
$crypto = new DES(); $crypto = new DES(DES::MODE_CBC);
$crypto->setPassword($password, 'pbkdf1', 'md5', $salt, $iterationCount); $crypto->setPassword($password, 'pbkdf1', 'md5', $salt, $iterationCount);
$key = $crypto->decrypt($key); $key = $crypto->decrypt($key);
if ($key === false) { if ($key === false) {

View File

@ -107,7 +107,7 @@ class PKCS8 extends PKCS
$salt = Random::string(8); $salt = Random::string(8);
$iterationCount = 2048; $iterationCount = 2048;
$crypto = new DES(); $crypto = new DES(DES::MODE_CBC);
$crypto->setPassword($password, 'pbkdf1', 'md5', $salt, $iterationCount); $crypto->setPassword($password, 'pbkdf1', 'md5', $salt, $iterationCount);
$RSAPrivateKey = $crypto->encrypt($RSAPrivateKey); $RSAPrivateKey = $crypto->encrypt($RSAPrivateKey);

View File

@ -126,7 +126,7 @@ class PuTTY
switch ($encryption) { switch ($encryption) {
case 'aes256-cbc': case 'aes256-cbc':
$symkey = static::generateSymmetricKey($password, 32); $symkey = static::generateSymmetricKey($password, 32);
$crypto = new AES(); $crypto = new AES(AES::MODE_CBC);
} }
if ($encryption != 'none') { if ($encryption != 'none') {

View File

@ -275,7 +275,7 @@ class TripleDES extends DES
$this->changed = true; $this->changed = true;
$this->_setEngine(); $this->_setEngine();
if ($this->mode_3cbc && $length > 8) { if ($this->mode_3cbc) {
$this->des[0]->setKey(substr($key, 0, 8)); $this->des[0]->setKey(substr($key, 0, 8));
$this->des[1]->setKey(substr($key, 8, 8)); $this->des[1]->setKey(substr($key, 8, 8));
$this->des[2]->setKey(substr($key, 16, 8)); $this->des[2]->setKey(substr($key, 16, 8));

View File

@ -662,6 +662,7 @@ class SSH1
$this->crypto->disablePadding(); $this->crypto->disablePadding();
$this->crypto->enableContinuousBuffer(); $this->crypto->enableContinuousBuffer();
$this->crypto->setKey(substr($session_key, 0, 8)); $this->crypto->setKey(substr($session_key, 0, 8));
// "The iv (initialization vector) is initialized to all zeroes."
$this->crypto->setIV(str_repeat("\0", 8)); $this->crypto->setIV(str_repeat("\0", 8));
break; break;
case self::CIPHER_3DES: case self::CIPHER_3DES:
@ -669,6 +670,7 @@ class SSH1
$this->crypto->disablePadding(); $this->crypto->disablePadding();
$this->crypto->enableContinuousBuffer(); $this->crypto->enableContinuousBuffer();
$this->crypto->setKey(substr($session_key, 0, 24)); $this->crypto->setKey(substr($session_key, 0, 24));
// "All three initialization vectors are initialized to zero."
$this->crypto->setIV(str_repeat("\0", 8)); $this->crypto->setIV(str_repeat("\0", 8));
break; break;
//case self::CIPHER_RC4: //case self::CIPHER_RC4:

View File

@ -1815,26 +1815,26 @@ class SSH2
{ {
switch ($algorithm) { switch ($algorithm) {
case '3des-cbc': case '3des-cbc':
return new TripleDES(); return new TripleDES(Base::MODE_CBC);
case '3des-ctr': case '3des-ctr':
return new TripleDES(Base::MODE_CTR); return new TripleDES(Base::MODE_CTR);
case 'aes256-cbc': case 'aes256-cbc':
case 'aes192-cbc': case 'aes192-cbc':
case 'aes128-cbc': case 'aes128-cbc':
return new Rijndael(); return new Rijndael(Base::MODE_CBC);
case 'aes256-ctr': case 'aes256-ctr':
case 'aes192-ctr': case 'aes192-ctr':
case 'aes128-ctr': case 'aes128-ctr':
return new Rijndael(Base::MODE_CTR); return new Rijndael(Base::MODE_CTR);
case 'blowfish-cbc': case 'blowfish-cbc':
return new Blowfish(); return new Blowfish(Base::MODE_CBC);
case 'blowfish-ctr': case 'blowfish-ctr':
return new Blowfish(Base::MODE_CTR); return new Blowfish(Base::MODE_CTR);
case 'twofish128-cbc': case 'twofish128-cbc':
case 'twofish192-cbc': case 'twofish192-cbc':
case 'twofish256-cbc': case 'twofish256-cbc':
case 'twofish-cbc': case 'twofish-cbc':
return new Twofish(); return new Twofish(Base::MODE_CBC);
case 'twofish128-ctr': case 'twofish128-ctr':
case 'twofish192-ctr': case 'twofish192-ctr':
case 'twofish256-ctr': case 'twofish256-ctr':

View File

@ -388,7 +388,7 @@ abstract class Unit_Crypt_AES_TestCase extends PhpseclibTestCase
*/ */
public function testContinuousBuffer() public function testContinuousBuffer()
{ {
$aes = new AES(); $aes = new AES(AES::MODE_CBC);
$aes->disablePadding(); $aes->disablePadding();
$aes->enableContinuousBuffer(); $aes->enableContinuousBuffer();
$aes->setIV(pack('H*', '0457bdb4a6712986688349a29eb82535')); $aes->setIV(pack('H*', '0457bdb4a6712986688349a29eb82535'));