From 8604e327a36d2c903f933526f6c7e55c312b01fe Mon Sep 17 00:00:00 2001 From: Takuya Sawada Date: Wed, 4 Oct 2017 19:30:53 +0900 Subject: [PATCH 1/5] SymmetricKey: add 'cfb8' cipher mode of operation support --- phpseclib/Crypt/Common/SymmetricKey.php | 75 +++++++++++++++++++++++-- 1 file changed, 70 insertions(+), 5 deletions(-) diff --git a/phpseclib/Crypt/Common/SymmetricKey.php b/phpseclib/Crypt/Common/SymmetricKey.php index 888a7e9b..23e2a639 100644 --- a/phpseclib/Crypt/Common/SymmetricKey.php +++ b/phpseclib/Crypt/Common/SymmetricKey.php @@ -80,6 +80,10 @@ abstract class SymmetricKey * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Cipher_feedback_.28CFB.29 */ const MODE_CFB = 3; + /** + * Encrypt / decrypt using the Cipher Feedback mode (8bit) + */ + const MODE_CFB8 = 38; /** * Encrypt / decrypt using the Output Feedback mode. * @@ -99,11 +103,12 @@ abstract class SymmetricKey * @see \phpseclib\Crypt\Common\SymmetricKey::__construct() */ const MODE_MAP = [ - 'ctr' => self::MODE_CTR, - 'ecb' => self::MODE_ECB, - 'cbc' => self::MODE_CBC, - 'cfb' => self::MODE_CFB, - 'ofb' => self::MODE_OFB, + 'ctr' => self::MODE_CTR, + 'ecb' => self::MODE_ECB, + 'cbc' => self::MODE_CBC, + 'cfb' => self::MODE_CFB, + 'cfb8' => self::MODE_CFB8, + 'ofb' => self::MODE_OFB, 'stream' => self::MODE_STREAM ]; @@ -504,6 +509,7 @@ abstract class SymmetricKey break; case self::MODE_CTR: case self::MODE_CFB: + case self::MODE_CFB8: case self::MODE_OFB: case self::MODE_STREAM: $this->paddable = false; @@ -925,6 +931,16 @@ abstract class SymmetricKey $iv = substr($ciphertext, -$this->block_size); } + return $ciphertext; + case self::MODE_CFB8: + $ciphertext = openssl_encrypt($plaintext, $this->cipher_name_openssl, $this->key, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING, $this->encryptIV); + if ($this->continuousBuffer) { + if (($len = strlen($ciphertext)) >= $this->block_size) { + $this->encryptIV = substr($ciphertext, -$this->block_size); + } else { + $this->encryptIV = substr($this->encryptIV, $len - $this->block_size) . substr($ciphertext, -$len); + } + } return $ciphertext; case self::MODE_OFB: return $this->openssl_ofb_process($plaintext, $this->encryptIV, $this->enbuffer); @@ -1105,6 +1121,24 @@ abstract class SymmetricKey $pos = $len; } break; + case self::MODE_CFB8: + $ciphertext = ''; + $len = strlen($plaintext); + $iv = $this->encryptIV; + + for ($i=0; $i < $len; ++$i) { + $ciphertext .= ($c = $plaintext[$i] ^ $this->encryptBlock($iv)); + $iv = substr($iv, 1, $this->block_size - 1) . $c; + } + + if ($this->continuousBuffer) { + if ($len >= $this->block_size) { + $this->encryptIV = substr($ciphertext, -$this->block_size); + } else { + $this->encryptIV = substr($this->encryptIV, $len - $this->block_size) . substr($ciphertext, -$len); + } + } + break; case self::MODE_OFB: $xor = $this->encryptIV; if (strlen($buffer['xor'])) { @@ -1225,6 +1259,16 @@ abstract class SymmetricKey $iv = substr($ciphertext, -$this->block_size); } break; + case self::MODE_CFB8: + $plaintext = openssl_decrypt($ciphertext, $this->cipher_name_openssl, $this->key, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING, $this->decryptIV); + if ($this->continuousBuffer) { + if (($len = strlen($ciphertext)) >= $this->block_size) { + $this->decryptIV = substr($ciphertext, -$this->block_size); + } else { + $this->decryptIV = substr($this->decryptIV, $len - $this->block_size) . substr($ciphertext, -$len); + } + } + break; case self::MODE_OFB: $plaintext = $this->openssl_ofb_process($ciphertext, $this->decryptIV, $this->debuffer); } @@ -1388,6 +1432,24 @@ abstract class SymmetricKey $pos = $len; } break; + case self::MODE_CFB8: + $plaintext = ''; + $len = strlen($ciphertext); + $iv = $this->decryptIV; + + for ($i=0; $i < $len; ++$i) { + $plaintext .= $ciphertext[$i] ^ $this->encryptBlock($iv); + $iv = substr($iv, 1, $this->block_size - 1) . $ciphertext[$i]; + } + + if ($this->continuousBuffer) { + if ($len >= $this->block_size) { + $this->decryptIV = substr($ciphertext, -$this->block_size); + } else { + $this->decryptIV = substr($this->decryptIV, $len - $this->block_size) . substr($ciphertext, -$len); + } + } + break; case self::MODE_OFB: $xor = $this->decryptIV; if (strlen($buffer['xor'])) { @@ -1598,6 +1660,8 @@ abstract class SymmetricKey return 'ctr'; case self::MODE_CFB: return 'cfb'; + case self::MODE_CFB8: + return 'cfb8'; case self::MODE_OFB: return 'ofb'; } @@ -1967,6 +2031,7 @@ abstract class SymmetricKey self::MODE_ECB => MCRYPT_MODE_ECB, self::MODE_CBC => MCRYPT_MODE_CBC, self::MODE_CFB => 'ncfb', + self::MODE_CFB8 => MCRYPT_MODE_CFB, self::MODE_OFB => MCRYPT_MODE_NOFB, self::MODE_STREAM => MCRYPT_MODE_STREAM, ]; From 7aa400745c90e03e9c79b702de536c5ba2b90f27 Mon Sep 17 00:00:00 2001 From: Takuya Sawada Date: Wed, 4 Oct 2017 19:33:34 +0900 Subject: [PATCH 2/5] SymmetricKey: add Eval engine implementation for 'cfb8' cipher mode of operation --- phpseclib/Crypt/Common/SymmetricKey.php | 46 +++++++++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/phpseclib/Crypt/Common/SymmetricKey.php b/phpseclib/Crypt/Common/SymmetricKey.php index 23e2a639..2dc2be24 100644 --- a/phpseclib/Crypt/Common/SymmetricKey.php +++ b/phpseclib/Crypt/Common/SymmetricKey.php @@ -2558,6 +2558,52 @@ abstract class SymmetricKey $_pos = $_len; } + return $_plaintext; + '; + break; + case self::MODE_CFB8: + $encrypt = $init_encrypt . ' + $_ciphertext = ""; + $_len = strlen($_text); + $_iv = $this->encryptIV; + + for ($_i = 0; $_i < $_len; ++$_i) { + $in = $_iv; + '.$encrypt_block.' + $_ciphertext .= ($_c = $_text[$_i] ^ $in); + $_iv = substr($_iv, 1, '.$block_size.' - 1) . $_c; + } + + if ($this->continuousBuffer) { + if ($_len >= '.$block_size.') { + $this->encryptIV = substr($_ciphertext, -'.$block_size.'); + } else { + $this->encryptIV = substr($this->encryptIV, $_len - '.$block_size.') . substr($_ciphertext, -$_len); + } + } + + return $_ciphertext; + '; + $decrypt = $init_encrypt . ' + $_plaintext = ""; + $_len = strlen($_text); + $_iv = $this->decryptIV; + + for ($_i = 0; $_i < $_len; ++$_i) { + $in = $_iv; + '.$encrypt_block.' + $_plaintext .= $_text[$_i] ^ $in; + $_iv = substr($_iv, 1, '.$block_size.' - 1) . $_text[$_i]; + } + + if ($this->continuousBuffer) { + if ($_len >= '.$block_size.') { + $this->decryptIV = substr($_text, -'.$block_size.'); + } else { + $this->decryptIV = substr($this->decryptIV, $_len - '.$block_size.') . substr($_text, -$_len); + } + } + return $_plaintext; '; break; From 18a5867e1638d1a5da450c182328cca6222eeec5 Mon Sep 17 00:00:00 2001 From: Takuya Sawada Date: Wed, 4 Oct 2017 19:32:29 +0900 Subject: [PATCH 3/5] Tests/AES: add newly added 'cfb8' cipher mode of operation for unit test --- tests/Unit/Crypt/AES/TestCase.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/Unit/Crypt/AES/TestCase.php b/tests/Unit/Crypt/AES/TestCase.php index ceef6a41..09458fd3 100644 --- a/tests/Unit/Crypt/AES/TestCase.php +++ b/tests/Unit/Crypt/AES/TestCase.php @@ -31,6 +31,7 @@ abstract class Unit_Crypt_AES_TestCase extends PhpseclibTestCase 'ctr', 'ofb', 'cfb', + 'cfb8' ); $plaintexts = array( '', @@ -131,6 +132,7 @@ abstract class Unit_Crypt_AES_TestCase extends PhpseclibTestCase 'ctr', 'ofb', 'cfb', + 'cfb8', ); $combos = array( From 65cbc60918a3ff4ac7e45809bf0c32c34bd6a98c Mon Sep 17 00:00:00 2001 From: Takuya Sawada Date: Tue, 10 Oct 2017 19:02:55 +0900 Subject: [PATCH 4/5] SymmetricKey: fix indent style to follows the PSR-2 codeing style --- phpseclib/Crypt/Common/SymmetricKey.php | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/phpseclib/Crypt/Common/SymmetricKey.php b/phpseclib/Crypt/Common/SymmetricKey.php index 2dc2be24..ee8b7a84 100644 --- a/phpseclib/Crypt/Common/SymmetricKey.php +++ b/phpseclib/Crypt/Common/SymmetricKey.php @@ -935,11 +935,11 @@ abstract class SymmetricKey case self::MODE_CFB8: $ciphertext = openssl_encrypt($plaintext, $this->cipher_name_openssl, $this->key, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING, $this->encryptIV); if ($this->continuousBuffer) { - if (($len = strlen($ciphertext)) >= $this->block_size) { - $this->encryptIV = substr($ciphertext, -$this->block_size); - } else { - $this->encryptIV = substr($this->encryptIV, $len - $this->block_size) . substr($ciphertext, -$len); - } + if (($len = strlen($ciphertext)) >= $this->block_size) { + $this->encryptIV = substr($ciphertext, -$this->block_size); + } else { + $this->encryptIV = substr($this->encryptIV, $len - $this->block_size) . substr($ciphertext, -$len); + } } return $ciphertext; case self::MODE_OFB: @@ -1126,7 +1126,7 @@ abstract class SymmetricKey $len = strlen($plaintext); $iv = $this->encryptIV; - for ($i=0; $i < $len; ++$i) { + for ($i = 0; $i < $len; ++$i) { $ciphertext .= ($c = $plaintext[$i] ^ $this->encryptBlock($iv)); $iv = substr($iv, 1, $this->block_size - 1) . $c; } @@ -1437,7 +1437,7 @@ abstract class SymmetricKey $len = strlen($ciphertext); $iv = $this->decryptIV; - for ($i=0; $i < $len; ++$i) { + for ($i = 0; $i < $len; ++$i) { $plaintext .= $ciphertext[$i] ^ $this->encryptBlock($iv); $iv = substr($iv, 1, $this->block_size - 1) . $ciphertext[$i]; } From 9e037309b91abf613203b2d3a8e79816c692c39f Mon Sep 17 00:00:00 2001 From: Takuya Sawada Date: Tue, 10 Oct 2017 19:06:14 +0900 Subject: [PATCH 5/5] SymmetricKey: refactor to simplify the code --- phpseclib/Crypt/Common/SymmetricKey.php | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/phpseclib/Crypt/Common/SymmetricKey.php b/phpseclib/Crypt/Common/SymmetricKey.php index ee8b7a84..ae0e96a3 100644 --- a/phpseclib/Crypt/Common/SymmetricKey.php +++ b/phpseclib/Crypt/Common/SymmetricKey.php @@ -1128,14 +1128,14 @@ abstract class SymmetricKey for ($i = 0; $i < $len; ++$i) { $ciphertext .= ($c = $plaintext[$i] ^ $this->encryptBlock($iv)); - $iv = substr($iv, 1, $this->block_size - 1) . $c; + $iv = substr($iv, 1) . $c; } if ($this->continuousBuffer) { - if ($len >= $this->block_size) { - $this->encryptIV = substr($ciphertext, -$this->block_size); + if ($len >= $block_size) { + $this->encryptIV = substr($ciphertext, -$block_size); } else { - $this->encryptIV = substr($this->encryptIV, $len - $this->block_size) . substr($ciphertext, -$len); + $this->encryptIV = substr($this->encryptIV, $len - $block_size) . substr($ciphertext, -$len); } } break; @@ -1439,14 +1439,14 @@ abstract class SymmetricKey for ($i = 0; $i < $len; ++$i) { $plaintext .= $ciphertext[$i] ^ $this->encryptBlock($iv); - $iv = substr($iv, 1, $this->block_size - 1) . $ciphertext[$i]; + $iv = substr($iv, 1) . $ciphertext[$i]; } if ($this->continuousBuffer) { - if ($len >= $this->block_size) { - $this->decryptIV = substr($ciphertext, -$this->block_size); + if ($len >= $block_size) { + $this->decryptIV = substr($ciphertext, -$block_size); } else { - $this->decryptIV = substr($this->decryptIV, $len - $this->block_size) . substr($ciphertext, -$len); + $this->decryptIV = substr($this->decryptIV, $len - $block_size) . substr($ciphertext, -$len); } } break; @@ -2571,7 +2571,7 @@ abstract class SymmetricKey $in = $_iv; '.$encrypt_block.' $_ciphertext .= ($_c = $_text[$_i] ^ $in); - $_iv = substr($_iv, 1, '.$block_size.' - 1) . $_c; + $_iv = substr($_iv, 1) . $_c; } if ($this->continuousBuffer) { @@ -2593,7 +2593,7 @@ abstract class SymmetricKey $in = $_iv; '.$encrypt_block.' $_plaintext .= $_text[$_i] ^ $in; - $_iv = substr($_iv, 1, '.$block_size.' - 1) . $_text[$_i]; + $_iv = substr($_iv, 1) . $_text[$_i]; } if ($this->continuousBuffer) {