mirror of
https://github.com/phpseclib/phpseclib.git
synced 2024-12-27 03:42:40 +00:00
Merge pull request #926 from terrafrost/iv-or-exception
Crypt/Base: throw an exception if an IV is required but not defined
This commit is contained in:
commit
e38cc4adb7
@ -150,7 +150,7 @@ abstract class Base
|
|||||||
* @var string
|
* @var string
|
||||||
* @access private
|
* @access private
|
||||||
*/
|
*/
|
||||||
var $iv;
|
var $iv = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A "sliding" Initialization Vector
|
* A "sliding" Initialization Vector
|
||||||
@ -500,10 +500,9 @@ abstract class Base
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the initialization vector. (optional)
|
* Sets the initialization vector.
|
||||||
*
|
*
|
||||||
* SetIV is not required when self::MODE_ECB (or ie for AES: \phpseclib\Crypt\AES::MODE_ECB) is being used. If not explicitly set, it'll be assumed
|
* setIV() is not required when self::MODE_ECB (or ie for AES: \phpseclib\Crypt\AES::MODE_ECB) is being used.
|
||||||
* to be all zero's.
|
|
||||||
*
|
*
|
||||||
* @access public
|
* @access public
|
||||||
* @param string $iv
|
* @param string $iv
|
||||||
@ -511,8 +510,10 @@ abstract class Base
|
|||||||
*/
|
*/
|
||||||
function setIV($iv)
|
function setIV($iv)
|
||||||
{
|
{
|
||||||
if ($this->mode == self::MODE_ECB) {
|
switch ($this->mode) {
|
||||||
return;
|
case self::MODE_ECB:
|
||||||
|
case self::MODE_STREAM:
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->iv = $iv;
|
$this->iv = $iv;
|
||||||
@ -1871,13 +1872,18 @@ abstract class Base
|
|||||||
* after disableContinuousBuffer() or on cipher $engine (re)init
|
* after disableContinuousBuffer() or on cipher $engine (re)init
|
||||||
* ie after setKey() or setIV()
|
* ie after setKey() or setIV()
|
||||||
*
|
*
|
||||||
* @access public
|
* @access private
|
||||||
* @internal Could, but not must, extend by the child Crypt_* class
|
* @internal Could, but not must, extend by the child Crypt_* class
|
||||||
|
* @throws \UnexpectedValueException when an IV is required but not defined
|
||||||
*/
|
*/
|
||||||
function _clearBuffers()
|
function _clearBuffers()
|
||||||
{
|
{
|
||||||
$this->enbuffer = $this->debuffer = array('ciphertext' => '', 'xor' => '', 'pos' => 0, 'enmcrypt_init' => true);
|
$this->enbuffer = $this->debuffer = array('ciphertext' => '', 'xor' => '', 'pos' => 0, 'enmcrypt_init' => true);
|
||||||
|
|
||||||
|
if ($this->iv === false && !in_array($this->mode, array(self::MODE_STREAM, self::MODE_ECB))) {
|
||||||
|
throw new \UnexpectedValueException('No IV has been defined');
|
||||||
|
}
|
||||||
|
|
||||||
// mcrypt's handling of invalid's $iv:
|
// mcrypt's handling of invalid's $iv:
|
||||||
// $this->encryptIV = $this->decryptIV = strlen($this->iv) == $this->block_size ? $this->iv : str_repeat("\0", $this->block_size);
|
// $this->encryptIV = $this->decryptIV = strlen($this->iv) == $this->block_size ? $this->iv : str_repeat("\0", $this->block_size);
|
||||||
$this->encryptIV = $this->decryptIV = str_pad(substr($this->iv, 0, $this->block_size), $this->block_size, "\0");
|
$this->encryptIV = $this->decryptIV = str_pad(substr($this->iv, 0, $this->block_size), $this->block_size, "\0");
|
||||||
|
@ -132,6 +132,7 @@ class PuTTY
|
|||||||
|
|
||||||
if ($encryption != 'none') {
|
if ($encryption != 'none') {
|
||||||
$crypto->setKey($symkey);
|
$crypto->setKey($symkey);
|
||||||
|
$crypto->setIV(str_repeat("\0", $crypto->getBlockLength() >> 3));
|
||||||
$crypto->disablePadding();
|
$crypto->disablePadding();
|
||||||
$private = $crypto->decrypt($private);
|
$private = $crypto->decrypt($private);
|
||||||
if ($private === false) {
|
if ($private === false) {
|
||||||
@ -263,6 +264,7 @@ class PuTTY
|
|||||||
$crypto = new AES();
|
$crypto = new AES();
|
||||||
|
|
||||||
$crypto->setKey(static::generateSymmetricKey($password, 32));
|
$crypto->setKey(static::generateSymmetricKey($password, 32));
|
||||||
|
$crypto->setIV(str_repeat("\0", $crypto->getBlockLength() >> 3));
|
||||||
$crypto->disablePadding();
|
$crypto->disablePadding();
|
||||||
$private = $crypto->encrypt($private);
|
$private = $crypto->encrypt($private);
|
||||||
$hashkey = 'putty-private-key-file-mac-key' . $password;
|
$hashkey = 'putty-private-key-file-mac-key' . $password;
|
||||||
|
@ -104,6 +104,7 @@ abstract class Unit_Crypt_AES_TestCase extends PhpseclibTestCase
|
|||||||
$aes->setPreferredEngine($this->engine);
|
$aes->setPreferredEngine($this->engine);
|
||||||
$aes->disablePadding();
|
$aes->disablePadding();
|
||||||
$aes->setKey(pack('H*', '2b7e151628aed2a6abf7158809cf4f3c762e7160')); // 160-bit key. Valid in Rijndael.
|
$aes->setKey(pack('H*', '2b7e151628aed2a6abf7158809cf4f3c762e7160')); // 160-bit key. Valid in Rijndael.
|
||||||
|
$aes->setIV(str_repeat("\0", 16));
|
||||||
//$this->_checkEngine($aes); // should only work in internal mode
|
//$this->_checkEngine($aes); // should only work in internal mode
|
||||||
$ciphertext = $aes->encrypt(pack('H*', '3243f6a8885a308d313198a2e0370734'));
|
$ciphertext = $aes->encrypt(pack('H*', '3243f6a8885a308d313198a2e0370734'));
|
||||||
$this->assertEquals($ciphertext, pack('H*', '231d844639b31b412211cfe93712b880'));
|
$this->assertEquals($ciphertext, pack('H*', '231d844639b31b412211cfe93712b880'));
|
||||||
@ -120,6 +121,7 @@ abstract class Unit_Crypt_AES_TestCase extends PhpseclibTestCase
|
|||||||
$aes->setPreferredEngine($this->engine);
|
$aes->setPreferredEngine($this->engine);
|
||||||
$aes->disablePadding();
|
$aes->disablePadding();
|
||||||
$aes->setKey(pack('H*', '2b7e151628aed2a6abf7158809cf4f3c762e7160')); // 160-bit key. AES should null pad to 192-bits
|
$aes->setKey(pack('H*', '2b7e151628aed2a6abf7158809cf4f3c762e7160')); // 160-bit key. AES should null pad to 192-bits
|
||||||
|
$aes->setIV(str_repeat("\0", 16));
|
||||||
$this->_checkEngine($aes);
|
$this->_checkEngine($aes);
|
||||||
$ciphertext = $aes->encrypt(pack('H*', '3243f6a8885a308d313198a2e0370734'));
|
$ciphertext = $aes->encrypt(pack('H*', '3243f6a8885a308d313198a2e0370734'));
|
||||||
$this->assertEquals($ciphertext, pack('H*', 'c109292b173f841b88e0ee49f13db8c0'));
|
$this->assertEquals($ciphertext, pack('H*', 'c109292b173f841b88e0ee49f13db8c0'));
|
||||||
@ -355,6 +357,7 @@ abstract class Unit_Crypt_AES_TestCase extends PhpseclibTestCase
|
|||||||
$aes = new AES();
|
$aes = new AES();
|
||||||
$aes->setKeyLength(128);
|
$aes->setKeyLength(128);
|
||||||
$aes->setKey(str_repeat('a', 24));
|
$aes->setKey(str_repeat('a', 24));
|
||||||
|
$aes->setIV(str_repeat("\0", 16));
|
||||||
$this->assertSame($aes->getKeyLength(), 128);
|
$this->assertSame($aes->getKeyLength(), 128);
|
||||||
$ciphertext = bin2hex($aes->encrypt('a'));
|
$ciphertext = bin2hex($aes->encrypt('a'));
|
||||||
$this->assertSame($ciphertext, '82b7b068dfc60ed2a46893b69fecd6c2');
|
$this->assertSame($ciphertext, '82b7b068dfc60ed2a46893b69fecd6c2');
|
||||||
@ -366,6 +369,7 @@ abstract class Unit_Crypt_AES_TestCase extends PhpseclibTestCase
|
|||||||
$aes = new AES();
|
$aes = new AES();
|
||||||
$aes->setKeyLength(256);
|
$aes->setKeyLength(256);
|
||||||
$aes->setKey(str_repeat('a', 16));
|
$aes->setKey(str_repeat('a', 16));
|
||||||
|
$aes->setIV(str_repeat("\0", 16));
|
||||||
$this->assertSame($aes->getKeyLength(), 256);
|
$this->assertSame($aes->getKeyLength(), 256);
|
||||||
$ciphertext = bin2hex($aes->encrypt('a'));
|
$ciphertext = bin2hex($aes->encrypt('a'));
|
||||||
$this->assertSame($ciphertext, 'fd4250c0d234aa7e1aa592820aa8406b');
|
$this->assertSame($ciphertext, 'fd4250c0d234aa7e1aa592820aa8406b');
|
||||||
|
@ -75,6 +75,7 @@ class Unit_Crypt_BlowfishTest extends PhpseclibTestCase
|
|||||||
{
|
{
|
||||||
$bf = new Blowfish();
|
$bf = new Blowfish();
|
||||||
$bf->setKey($key);
|
$bf->setKey($key);
|
||||||
|
$bf->setIV(str_repeat("\0", $bf->getBlockLength() >> 3));
|
||||||
if (!$bf->isValidEngine($engine)) {
|
if (!$bf->isValidEngine($engine)) {
|
||||||
self::markTestSkipped('Unable to initialize ' . $engineName . ' engine');
|
self::markTestSkipped('Unable to initialize ' . $engineName . ' engine');
|
||||||
}
|
}
|
||||||
|
@ -51,7 +51,7 @@ class Unit_Crypt_DESTest extends PhpseclibTestCase
|
|||||||
$des->disablePadding();
|
$des->disablePadding();
|
||||||
// when the key and iv are not specified they should be null padded
|
// when the key and iv are not specified they should be null padded
|
||||||
//$des->setKey();
|
//$des->setKey();
|
||||||
//$des->setIV();
|
$des->setIV('');
|
||||||
|
|
||||||
$des->setPreferredEngine(Base::ENGINE_INTERNAL);
|
$des->setPreferredEngine(Base::ENGINE_INTERNAL);
|
||||||
$internal = $des->decrypt('d');
|
$internal = $des->decrypt('d');
|
||||||
|
@ -114,6 +114,7 @@ class Unit_Crypt_RC2Test extends PhpseclibTestCase
|
|||||||
$rc2->disablePadding();
|
$rc2->disablePadding();
|
||||||
$rc2->setKeyLength($keyLen);
|
$rc2->setKeyLength($keyLen);
|
||||||
$rc2->setKey(pack('H*', $key)); // could also do $rc2->setKey(pack('H*', $key), $keyLen)
|
$rc2->setKey(pack('H*', $key)); // could also do $rc2->setKey(pack('H*', $key), $keyLen)
|
||||||
|
$rc2->setIV(str_repeat("\0", $rc2->getBlockLength() >> 3));
|
||||||
if (!$rc2->isValidEngine($engine)) {
|
if (!$rc2->isValidEngine($engine)) {
|
||||||
self::markTestSkipped('Unable to initialize ' . $engineName . ' engine');
|
self::markTestSkipped('Unable to initialize ' . $engineName . ' engine');
|
||||||
}
|
}
|
||||||
|
@ -110,6 +110,7 @@ class Unit_Crypt_TripleDESTest extends PhpseclibTestCase
|
|||||||
}
|
}
|
||||||
$des->setPreferredEngine($engine);
|
$des->setPreferredEngine($engine);
|
||||||
$des->setKey($key);
|
$des->setKey($key);
|
||||||
|
$des->setIV(str_repeat("\0", $des->getBlockLength() >> 3));
|
||||||
$des->disablePadding();
|
$des->disablePadding();
|
||||||
$result = $des->encrypt($plaintext);
|
$result = $des->encrypt($plaintext);
|
||||||
$plaintext = bin2hex($plaintext);
|
$plaintext = bin2hex($plaintext);
|
||||||
@ -176,6 +177,7 @@ class Unit_Crypt_TripleDESTest extends PhpseclibTestCase
|
|||||||
|
|
||||||
$des = new TripleDES(TripleDES::MODE_3CBC);
|
$des = new TripleDES(TripleDES::MODE_3CBC);
|
||||||
$des->setKey('abcdefghijklmnopqrstuvwx');
|
$des->setKey('abcdefghijklmnopqrstuvwx');
|
||||||
|
$des->setIV(str_repeat("\0", $des->getBlockLength() >> 3));
|
||||||
|
|
||||||
foreach ($this->engines as $engine => $engineName) {
|
foreach ($this->engines as $engine => $engineName) {
|
||||||
$des->setPreferredEngine($engine);
|
$des->setPreferredEngine($engine);
|
||||||
|
@ -20,6 +20,7 @@ class Unit_Crypt_TwofishTest extends PhpseclibTestCase
|
|||||||
|
|
||||||
foreach ($engines as $engine => $name) {
|
foreach ($engines as $engine => $name) {
|
||||||
$tf = new Twofish();
|
$tf = new Twofish();
|
||||||
|
$tf->setIV(str_repeat("\0", $tf->getBlockLength() >> 3));
|
||||||
$tf->disablePadding();
|
$tf->disablePadding();
|
||||||
|
|
||||||
// tests from https://www.schneier.com/code/ecb_ival.txt
|
// tests from https://www.schneier.com/code/ecb_ival.txt
|
||||||
|
Loading…
Reference in New Issue
Block a user