From 1bde98fc422e7d7803500947e74eaa86783ea82e Mon Sep 17 00:00:00 2001 From: terrafrost Date: Tue, 24 Jan 2017 07:04:59 -0600 Subject: [PATCH] Crypt: OpenSSL apparently supports variable size keys --- phpseclib/Crypt/Blowfish.php | 2 +- phpseclib/Crypt/RC4.php | 17 ++---------- tests/Unit/Crypt/BlowfishTest.php | 44 +++++++++++++++++++++++++++++++ tests/Unit/Crypt/RC4Test.php | 39 +++++++++++++++++++++++++++ 4 files changed, 86 insertions(+), 16 deletions(-) diff --git a/phpseclib/Crypt/Blowfish.php b/phpseclib/Crypt/Blowfish.php index e610209b..5be5ce3a 100644 --- a/phpseclib/Crypt/Blowfish.php +++ b/phpseclib/Crypt/Blowfish.php @@ -390,7 +390,7 @@ class Crypt_Blowfish extends Crypt_Base function isValidEngine($engine) { if ($engine == CRYPT_ENGINE_OPENSSL) { - if ($this->key_length != 16) { + if ($this->key_length < 16) { return false; } $this->cipher_name_openssl_ecb = 'bf-ecb'; diff --git a/phpseclib/Crypt/RC4.php b/phpseclib/Crypt/RC4.php index ce29e6af..62145548 100644 --- a/phpseclib/Crypt/RC4.php +++ b/phpseclib/Crypt/RC4.php @@ -189,21 +189,8 @@ class Crypt_RC4 extends Crypt_Base */ 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; - } + if ($engine == CRYPT_ENGINE_OPENSSL) { + $this->cipher_name_openssl = 'rc4-40'; } return parent::isValidEngine($engine); diff --git a/tests/Unit/Crypt/BlowfishTest.php b/tests/Unit/Crypt/BlowfishTest.php index 92553e25..87406c13 100644 --- a/tests/Unit/Crypt/BlowfishTest.php +++ b/tests/Unit/Crypt/BlowfishTest.php @@ -6,6 +6,7 @@ */ require_once 'Crypt/Blowfish.php'; +require_once 'Crypt/Random.php'; class Unit_Crypt_BlowfishTest extends PhpseclibTestCase { @@ -83,4 +84,47 @@ class Unit_Crypt_BlowfishTest extends PhpseclibTestCase $plaintext = bin2hex($plaintext); $this->assertEquals($result, $expected, "Failed asserting that $plaintext yielded expected output in $engineName engine"); } + + public function testKeySizes() + { + $objects = $engines = array(); + $temp = new Crypt_Blowfish(CRYPT_MODE_CTR); + $temp->setPreferredEngine(CRYPT_ENGINE_INTERNAL); + $objects[] = $temp; + $engines[] = 'internal'; + + if ($temp->isValidEngine(CRYPT_ENGINE_MCRYPT)) { + $temp = new Crypt_Blowfish(CRYPT_MODE_CTR); + $temp->setPreferredEngine(CRYPT_ENGINE_MCRYPT); + $objects[] = $temp; + $engines[] = 'mcrypt'; + } + + if ($temp->isValidEngine(CRYPT_ENGINE_OPENSSL)) { + $temp = new Crypt_Blowfish(CRYPT_MODE_CTR); + $temp->setPreferredEngine(CRYPT_ENGINE_OPENSSL); + $objects[] = $temp; + $engines[] = 'OpenSSL'; + } + + if (count($objects) < 2) { + self::markTestSkipped('Unable to initialize two or more engines'); + } + + for ($i = 0; $i < count($objects); $i++) { + $objects[$i]->setIV(str_repeat('x', $objects[$i]->getBlockLength() >> 3)); + } + + $plaintext = str_repeat('.', 100); + + for ($keyLen = 4; $keyLen <= 56; $keyLen++) { + $key = crypt_random_string($keyLen); + $objects[0]->setKey($key); + $ref = $objects[0]->encrypt($plaintext); + for ($i = 1; $i < count($objects); $i++) { + $objects[$i]->setKey($key); + $this->assertEquals($ref, $objects[$i]->encrypt($plaintext), "Failed asserting that {$engines[$i]} yields the same output as the internal engine with a key size of $keyLen"); + } + } + } } diff --git a/tests/Unit/Crypt/RC4Test.php b/tests/Unit/Crypt/RC4Test.php index a9c3ffdc..4ba34e3d 100644 --- a/tests/Unit/Crypt/RC4Test.php +++ b/tests/Unit/Crypt/RC4Test.php @@ -208,4 +208,43 @@ class Unit_Crypt_RC4Test extends PhpseclibTestCase $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"); } + + public function testKeySizes() + { + $objects = $engines = array(); + $temp = new Crypt_RC4(CRYPT_MODE_CTR); + $temp->setPreferredEngine(CRYPT_ENGINE_INTERNAL); + $objects[] = $temp; + $engines[] = 'internal'; + + if ($temp->isValidEngine(CRYPT_ENGINE_MCRYPT)) { + $temp = new Crypt_RC4(CRYPT_MODE_CTR); + $temp->setPreferredEngine(CRYPT_ENGINE_MCRYPT); + $objects[] = $temp; + $engines[] = 'mcrypt'; + } + + if ($temp->isValidEngine(CRYPT_ENGINE_OPENSSL)) { + $temp = new Crypt_RC4(CRYPT_MODE_CTR); + $temp->setPreferredEngine(CRYPT_ENGINE_OPENSSL); + $objects[] = $temp; + $engines[] = 'OpenSSL'; + } + + if (count($objects) < 2) { + self::markTestSkipped('Unable to initialize two or more engines'); + } + + $plaintext = str_repeat('.', 100); + + for ($keyLen = 5; $keyLen <= 256; $keyLen++) { + $key = crypt_random_string($keyLen); + $objects[0]->setKey($key); + $ref = $objects[0]->encrypt($plaintext); + for ($i = 1; $i < count($objects); $i++) { + $objects[$i]->setKey($key); + $this->assertEquals($ref, $objects[$i]->encrypt($plaintext), "Failed asserting that {$engines[$i]} yields the same output as the internal engine with a key size of $keyLen"); + } + } + } }