From 8604e327a36d2c903f933526f6c7e55c312b01fe Mon Sep 17 00:00:00 2001 From: Takuya Sawada Date: Wed, 4 Oct 2017 19:30:53 +0900 Subject: [PATCH] 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, ];