Merge pull request #1192 from eternalharvest/feature/aes_mode_cfb8

Add 'cfb8' cipher mode of operation support
This commit is contained in:
terrafrost 2017-10-10 05:41:25 -05:00 committed by GitHub
commit 37abd02cc9
2 changed files with 118 additions and 5 deletions

View File

@ -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) . $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);
}
}
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) . $ciphertext[$i];
}
if ($this->continuousBuffer) {
if ($len >= $block_size) {
$this->decryptIV = substr($ciphertext, -$block_size);
} else {
$this->decryptIV = substr($this->decryptIV, $len - $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,
];
@ -2493,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) . $_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) . $_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;

View File

@ -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(