Crypt/Base: add OFB8 as a new mode

This commit is contained in:
terrafrost 2022-01-28 14:39:16 -06:00
parent ef45ea7289
commit c8d379daa5
2 changed files with 115 additions and 5 deletions

View File

@ -79,7 +79,11 @@ abstract class Base
/** /**
* Encrypt / decrypt using the Cipher Feedback mode (8bit) * Encrypt / decrypt using the Cipher Feedback mode (8bit)
*/ */
const MODE_CFB8 = 38; const MODE_CFB8 = 6;
/**
* Encrypt / decrypt using the Output Feedback mode (8bit)
*/
const MODE_OFB8 = 7;
/** /**
* Encrypt / decrypt using the Output Feedback mode. * Encrypt / decrypt using the Output Feedback mode.
* *
@ -484,6 +488,7 @@ abstract class Base
case self::MODE_CTR: case self::MODE_CTR:
case self::MODE_CFB: case self::MODE_CFB:
case self::MODE_CFB8: case self::MODE_CFB8:
case self::MODE_OFB8:
case self::MODE_OFB: case self::MODE_OFB:
case self::MODE_STREAM: case self::MODE_STREAM:
$this->mode = $mode; $this->mode = $mode;
@ -773,8 +778,25 @@ abstract class Base
} }
} }
return $ciphertext; return $ciphertext;
case self::MODE_OFB8:
$ciphertext = '';
$len = strlen($plaintext);
$iv = $this->encryptIV;
for ($i = 0; $i < $len; ++$i) {
$xor = openssl_encrypt($iv, $this->cipher_name_openssl_ecb, $this->key, $this->openssl_options, $this->decryptIV);
$ciphertext.= $plaintext[$i] ^ $xor;
$iv = substr($iv, 1) . $xor[0];
}
if ($this->continuousBuffer) {
$this->encryptIV = $iv;
}
break;
case self::MODE_OFB: case self::MODE_OFB:
return $this->_openssl_ofb_process($plaintext, $this->encryptIV, $this->enbuffer); return $this->_openssl_ofb_process($plaintext, $this->encryptIV, $this->enbuffer);
case self::MODE_OFB8:
// OpenSSL has built in support for cfb8 but not ofb8
} }
} }
@ -959,12 +981,14 @@ abstract class Base
} }
break; break;
case self::MODE_CFB8: case self::MODE_CFB8:
// compared to regular CFB, which encrypts a block at a time,
// here, we're encrypting a byte at a time
$ciphertext = ''; $ciphertext = '';
$len = strlen($plaintext); $len = strlen($plaintext);
$iv = $this->encryptIV; $iv = $this->encryptIV;
for ($i = 0; $i < $len; ++$i) { for ($i = 0; $i < $len; ++$i) {
$ciphertext .= ($c = $plaintext[$i] ^ $this->_encryptBlock($iv)); $ciphertext.= ($c = $plaintext[$i] ^ $this->_encryptBlock($iv));
$iv = substr($iv, 1) . $c; $iv = substr($iv, 1) . $c;
} }
@ -976,6 +1000,21 @@ abstract class Base
} }
} }
break; break;
case self::MODE_OFB8:
$ciphertext = '';
$len = strlen($plaintext);
$iv = $this->encryptIV;
for ($i = 0; $i < $len; ++$i) {
$xor = $this->_encryptBlock($iv);
$ciphertext.= $plaintext[$i] ^ $xor;
$iv = substr($iv, 1) . $xor[0];
}
if ($this->continuousBuffer) {
$this->encryptIV = $iv;
}
break;
case self::MODE_OFB: case self::MODE_OFB:
$xor = $this->encryptIV; $xor = $this->encryptIV;
if (strlen($buffer['xor'])) { if (strlen($buffer['xor'])) {
@ -1116,6 +1155,21 @@ abstract class Base
} }
} }
break; break;
case self::MODE_OFB8:
$plaintext = '';
$len = strlen($ciphertext);
$iv = $this->decryptIV;
for ($i = 0; $i < $len; ++$i) {
$xor = openssl_encrypt($iv, $this->cipher_name_openssl_ecb, $this->key, $this->openssl_options, $this->decryptIV);
$plaintext.= $ciphertext[$i] ^ $xor;
$iv = substr($iv, 1) . $xor[0];
}
if ($this->continuousBuffer) {
$this->decryptIV = $iv;
}
break;
case self::MODE_OFB: case self::MODE_OFB:
$plaintext = $this->_openssl_ofb_process($ciphertext, $this->decryptIV, $this->debuffer); $plaintext = $this->_openssl_ofb_process($ciphertext, $this->decryptIV, $this->debuffer);
} }
@ -1290,7 +1344,7 @@ abstract class Base
$iv = $this->decryptIV; $iv = $this->decryptIV;
for ($i = 0; $i < $len; ++$i) { for ($i = 0; $i < $len; ++$i) {
$plaintext .= $ciphertext[$i] ^ $this->_encryptBlock($iv); $plaintext.= $ciphertext[$i] ^ $this->_encryptBlock($iv);
$iv = substr($iv, 1) . $ciphertext[$i]; $iv = substr($iv, 1) . $ciphertext[$i];
} }
@ -1302,6 +1356,21 @@ abstract class Base
} }
} }
break; break;
case self::MODE_OFB8:
$plaintext = '';
$len = strlen($ciphertext);
$iv = $this->decryptIV;
for ($i = 0; $i < $len; ++$i) {
$xor = $this->_encryptBlock($iv);
$plaintext.= $ciphertext[$i] ^ $xor;
$iv = substr($iv, 1) . $xor[0];
}
if ($this->continuousBuffer) {
$this->decryptIV = $iv;
}
break;
case self::MODE_OFB: case self::MODE_OFB:
$xor = $this->decryptIV; $xor = $this->decryptIV;
if (strlen($buffer['xor'])) { if (strlen($buffer['xor'])) {
@ -1864,6 +1933,7 @@ abstract class Base
self::MODE_CFB => 'ncfb', self::MODE_CFB => 'ncfb',
self::MODE_CFB8 => MCRYPT_MODE_CFB, self::MODE_CFB8 => MCRYPT_MODE_CFB,
self::MODE_OFB => MCRYPT_MODE_NOFB, self::MODE_OFB => MCRYPT_MODE_NOFB,
self::MODE_OFB8 => MCRYPT_MODE_OFB,
self::MODE_STREAM => MCRYPT_MODE_STREAM, self::MODE_STREAM => MCRYPT_MODE_STREAM,
); );
@ -2446,7 +2516,7 @@ abstract class Base
for ($_i = 0; $_i < $_len; ++$_i) { for ($_i = 0; $_i < $_len; ++$_i) {
$in = $_iv; $in = $_iv;
'.$encrypt_block.' '.$encrypt_block.'
$_ciphertext .= ($_c = $_text[$_i] ^ $in); $_ciphertext.= ($_c = $_text[$_i] ^ $in);
$_iv = substr($_iv, 1) . $_c; $_iv = substr($_iv, 1) . $_c;
} }
@ -2468,7 +2538,7 @@ abstract class Base
for ($_i = 0; $_i < $_len; ++$_i) { for ($_i = 0; $_i < $_len; ++$_i) {
$in = $_iv; $in = $_iv;
'.$encrypt_block.' '.$encrypt_block.'
$_plaintext .= $_text[$_i] ^ $in; $_plaintext.= $_text[$_i] ^ $in;
$_iv = substr($_iv, 1) . $_text[$_i]; $_iv = substr($_iv, 1) . $_text[$_i];
} }
@ -2480,6 +2550,44 @@ abstract class Base
} }
} }
return $_plaintext;
';
break;
case self::MODE_OFB8:
$encrypt = $init_encrypt . '
$_ciphertext = "";
$_len = strlen($_text);
$_iv = $self->encryptIV;
for ($_i = 0; $_i < $_len; ++$_i) {
$in = $_iv;
'.$encrypt_block.'
$_ciphertext.= $_text[$_i] ^ $in;
$_iv = substr($_iv, 1) . $in[0];
}
if ($self->continuousBuffer) {
$self->encryptIV = $_iv;
}
return $_ciphertext;
';
$decrypt = $init_encrypt . '
$_plaintext = "";
$_len = strlen($_text);
$_iv = $self->decryptIV;
for ($_i = 0; $_i < $_len; ++$_i) {
$in = $_iv;
'.$encrypt_block.'
$_plaintext.= $_text[$_i] ^ $in;
$_iv = substr($_iv, 1) . $in[0];
}
if ($self->continuousBuffer) {
$self->decryptIV = $_iv;
}
return $_plaintext; return $_plaintext;
'; ';
break; break;

View File

@ -40,6 +40,7 @@ abstract class Unit_Crypt_AES_TestCase extends PhpseclibTestCase
Base::MODE_OFB, Base::MODE_OFB,
Base::MODE_CFB, Base::MODE_CFB,
Base::MODE_CFB8, Base::MODE_CFB8,
Base::MODE_OFB8,
); );
$plaintexts = array( $plaintexts = array(
'', '',
@ -138,6 +139,7 @@ abstract class Unit_Crypt_AES_TestCase extends PhpseclibTestCase
Base::MODE_OFB, Base::MODE_OFB,
Base::MODE_CFB, Base::MODE_CFB,
Base::MODE_CFB8, Base::MODE_CFB8,
Base::MODE_OFB8,
); );
$combos = array( $combos = array(