mirror of
https://github.com/danog/phpseclib.git
synced 2025-01-22 04:51:19 +01:00
- added support for OFB and CFB modes (with the caveat that CFB mode isn't currently supported as a stream cipher)
- improvements to the fix to the bug Suby found - fixed bug whereby CTR mode gave different results in mcrypt and internal modes when the continuous buffer was enabled and the plaintext being encrypted wasn't a multiple of the block size - undid the fix for the bug f.dammassa found (thanks, j31!) git-svn-id: http://phpseclib.svn.sourceforge.net/svnroot/phpseclib/trunk@120 21d32557-59b3-4da0-833f-c5933fad653e
This commit is contained in:
parent
b3690e0fde
commit
202c3b64e9
@ -56,7 +56,7 @@
|
||||
* @author Jim Wigginton <terrafrost@php.net>
|
||||
* @copyright MMVIII Jim Wigginton
|
||||
* @license http://www.gnu.org/licenses/lgpl.txt
|
||||
* @version $Id: AES.php,v 1.7 2010-02-09 06:10:25 terrafrost Exp $
|
||||
* @version $Id: AES.php,v 1.8 2010-09-12 21:58:54 terrafrost Exp $
|
||||
* @link http://phpseclib.sourceforge.net
|
||||
*/
|
||||
|
||||
@ -90,6 +90,18 @@ define('CRYPT_AES_MODE_ECB', 1);
|
||||
* @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Cipher-block_chaining_.28CBC.29
|
||||
*/
|
||||
define('CRYPT_AES_MODE_CBC', 2);
|
||||
/**
|
||||
* Encrypt / decrypt using the Cipher Feedback mode.
|
||||
*
|
||||
* @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Cipher_feedback_.28CFB.29
|
||||
*/
|
||||
define('CRYPT_AES_MODE_CFB', 3);
|
||||
/**
|
||||
* Encrypt / decrypt using the Cipher Feedback mode.
|
||||
*
|
||||
* @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Output_feedback_.28OFB.29
|
||||
*/
|
||||
define('CRYPT_AES_MODE_OFB', 4);
|
||||
/**#@-*/
|
||||
|
||||
/**#@+
|
||||
@ -168,6 +180,7 @@ class Crypt_AES extends Crypt_Rijndael {
|
||||
case CRYPT_AES_MODE_MCRYPT:
|
||||
switch ($mode) {
|
||||
case CRYPT_AES_MODE_ECB:
|
||||
$this->paddable = true;
|
||||
$this->mode = MCRYPT_MODE_ECB;
|
||||
break;
|
||||
case CRYPT_AES_MODE_CTR:
|
||||
@ -177,8 +190,16 @@ class Crypt_AES extends Crypt_Rijndael {
|
||||
$this->mode = 'ctr';
|
||||
//$this->mode = in_array('ctr', mcrypt_list_modes()) ? 'ctr' : CRYPT_AES_MODE_CTR;
|
||||
break;
|
||||
case CRYPT_AES_MODE_CFB:
|
||||
$this->paddable = true;
|
||||
$this->mode = 'ncfb';
|
||||
break;
|
||||
case CRYPT_AES_MODE_OFB:
|
||||
$this->mode = MCRYPT_MODE_NOFB;
|
||||
break;
|
||||
case CRYPT_AES_MODE_CBC:
|
||||
default:
|
||||
$this->paddable = true;
|
||||
$this->mode = MCRYPT_MODE_CBC;
|
||||
}
|
||||
|
||||
@ -186,13 +207,22 @@ class Crypt_AES extends Crypt_Rijndael {
|
||||
default:
|
||||
switch ($mode) {
|
||||
case CRYPT_AES_MODE_ECB:
|
||||
$this->paddable = true;
|
||||
$this->mode = CRYPT_RIJNDAEL_MODE_ECB;
|
||||
break;
|
||||
case CRYPT_AES_MODE_CTR:
|
||||
$this->mode = CRYPT_RIJNDAEL_MODE_CTR;
|
||||
break;
|
||||
case CRYPT_AES_MODE_CFB:
|
||||
$this->paddable = true;
|
||||
$this->mode = CRYPT_RIJNDAEL_MODE_CFB;
|
||||
break;
|
||||
case CRYPT_AES_MODE_OFB:
|
||||
$this->mode = CRYPT_RIJNDAEL_MODE_OFB;
|
||||
break;
|
||||
case CRYPT_AES_MODE_CBC:
|
||||
default:
|
||||
$this->paddable = true;
|
||||
$this->mode = CRYPT_RIJNDAEL_MODE_CBC;
|
||||
}
|
||||
}
|
||||
@ -248,7 +278,7 @@ class Crypt_AES extends Crypt_Rijndael {
|
||||
}
|
||||
*/
|
||||
|
||||
if ($this->mode != 'ctr') {
|
||||
if ($this->paddable) {
|
||||
$plaintext = $this->_pad($plaintext);
|
||||
}
|
||||
|
||||
@ -289,7 +319,7 @@ class Crypt_AES extends Crypt_Rijndael {
|
||||
}
|
||||
*/
|
||||
|
||||
if ($this->mode != 'ctr') {
|
||||
if ($this->paddable) {
|
||||
// we pad with chr(0) since that's what mcrypt_generic does. to quote from http://php.net/function.mcrypt-generic :
|
||||
// "The data is padded with "\0" to make sure the length of the data is n * blocksize."
|
||||
$ciphertext = str_pad($ciphertext, (strlen($ciphertext) + 15) & 0xFFFFFFF0, chr(0));
|
||||
@ -301,7 +331,7 @@ class Crypt_AES extends Crypt_Rijndael {
|
||||
mcrypt_generic_init($this->demcrypt, $this->key, $this->iv);
|
||||
}
|
||||
|
||||
return $this->mode != 'ctr' ? $this->_unpad($plaintext) : $plaintext;
|
||||
return $this->paddable ? $this->_unpad($plaintext) : $plaintext;
|
||||
}
|
||||
|
||||
return parent::decrypt($ciphertext);
|
||||
|
@ -53,7 +53,7 @@
|
||||
* @author Jim Wigginton <terrafrost@php.net>
|
||||
* @copyright MMVII Jim Wigginton
|
||||
* @license http://www.gnu.org/licenses/lgpl.txt
|
||||
* @version $Id: DES.php,v 1.13 2010-08-08 05:06:38 terrafrost Exp $
|
||||
* @version $Id: DES.php,v 1.14 2010-09-12 21:58:54 terrafrost Exp $
|
||||
* @link http://phpseclib.sourceforge.net
|
||||
*/
|
||||
|
||||
@ -97,6 +97,18 @@ define('CRYPT_DES_MODE_ECB', 1);
|
||||
* @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Cipher-block_chaining_.28CBC.29
|
||||
*/
|
||||
define('CRYPT_DES_MODE_CBC', 2);
|
||||
/**
|
||||
* Encrypt / decrypt using the Cipher Feedback mode.
|
||||
*
|
||||
* @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Cipher_feedback_.28CFB.29
|
||||
*/
|
||||
define('CRYPT_DES_MODE_CFB', 3);
|
||||
/**
|
||||
* Encrypt / decrypt using the Cipher Feedback mode.
|
||||
*
|
||||
* @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Output_feedback_.28OFB.29
|
||||
*/
|
||||
define('CRYPT_DES_MODE_OFB', 4);
|
||||
/**#@-*/
|
||||
|
||||
/**#@+
|
||||
@ -191,7 +203,7 @@ class Crypt_DES {
|
||||
* The mcrypt resource can be recreated every time something needs to be created or it can be created just once.
|
||||
* Since mcrypt operates in continuous mode, by default, it'll need to be recreated when in non-continuous mode.
|
||||
*
|
||||
* @see Crypt_AES::encrypt()
|
||||
* @see Crypt_DES::encrypt()
|
||||
* @var String
|
||||
* @access private
|
||||
*/
|
||||
@ -203,7 +215,7 @@ class Crypt_DES {
|
||||
* The mcrypt resource can be recreated every time something needs to be created or it can be created just once.
|
||||
* Since mcrypt operates in continuous mode, by default, it'll need to be recreated when in non-continuous mode.
|
||||
*
|
||||
* @see Crypt_AES::decrypt()
|
||||
* @see Crypt_DES::decrypt()
|
||||
* @var String
|
||||
* @access private
|
||||
*/
|
||||
@ -212,8 +224,8 @@ class Crypt_DES {
|
||||
/**
|
||||
* Does the enmcrypt resource need to be (re)initialized?
|
||||
*
|
||||
* @see setKey()
|
||||
* @see setIV()
|
||||
* @see Crypt_DES::setKey()
|
||||
* @see Crypt_DES::setIV()
|
||||
* @var Boolean
|
||||
* @access private
|
||||
*/
|
||||
@ -222,13 +234,40 @@ class Crypt_DES {
|
||||
/**
|
||||
* Does the demcrypt resource need to be (re)initialized?
|
||||
*
|
||||
* @see setKey()
|
||||
* @see setIV()
|
||||
* @see Crypt_DES::setKey()
|
||||
* @see Crypt_DES::setIV()
|
||||
* @var Boolean
|
||||
* @access private
|
||||
*/
|
||||
var $dechanged = true;
|
||||
|
||||
/**
|
||||
* Is the mode one that is paddable?
|
||||
*
|
||||
* @see Crypt_DES::Crypt_DES()
|
||||
* @var Boolean
|
||||
* @access private
|
||||
*/
|
||||
var $paddable = false;
|
||||
|
||||
/**
|
||||
* Encryption buffer for CTR, OFB and CFB modes
|
||||
*
|
||||
* @see Crypt_DES::encrypt()
|
||||
* @var String
|
||||
* @access private
|
||||
*/
|
||||
var $enbuffer = '';
|
||||
|
||||
/**
|
||||
* Decryption buffer for CTR, OFB and CFB modes
|
||||
*
|
||||
* @see Crypt_DES::decrypt()
|
||||
* @var String
|
||||
* @access private
|
||||
*/
|
||||
var $debuffer = '';
|
||||
|
||||
/**
|
||||
* Default Constructor.
|
||||
*
|
||||
@ -258,14 +297,23 @@ class Crypt_DES {
|
||||
case CRYPT_DES_MODE_MCRYPT:
|
||||
switch ($mode) {
|
||||
case CRYPT_DES_MODE_ECB:
|
||||
$this->paddable = true;
|
||||
$this->mode = MCRYPT_MODE_ECB;
|
||||
break;
|
||||
case CRYPT_DES_MODE_CTR:
|
||||
$this->mode = 'ctr';
|
||||
//$this->mode = in_array('ctr', mcrypt_list_modes()) ? 'ctr' : CRYPT_DES_MODE_CTR;
|
||||
break;
|
||||
case CRYPT_DES_MODE_CFB:
|
||||
$this->paddable = true;
|
||||
$this->mode = 'ncfb';
|
||||
break;
|
||||
case CRYPT_DES_MODE_OFB:
|
||||
$this->mode = MCRYPT_MODE_NOFB;
|
||||
break;
|
||||
case CRYPT_DES_MODE_CBC:
|
||||
default:
|
||||
$this->paddable = true;
|
||||
$this->mode = MCRYPT_MODE_CBC;
|
||||
}
|
||||
|
||||
@ -273,11 +321,17 @@ class Crypt_DES {
|
||||
default:
|
||||
switch ($mode) {
|
||||
case CRYPT_DES_MODE_ECB:
|
||||
case CRYPT_DES_MODE_CFB:
|
||||
$this->paddable = true;
|
||||
$this->mode = $mode;
|
||||
break;
|
||||
case CRYPT_DES_MODE_CTR:
|
||||
case CRYPT_DES_MODE_CBC:
|
||||
case CRYPT_DES_MODE_OFB:
|
||||
$this->mode = $mode;
|
||||
break;
|
||||
default:
|
||||
$this->paddable = true;
|
||||
$this->mode = CRYPT_DES_MODE_CBC;
|
||||
}
|
||||
}
|
||||
@ -375,7 +429,7 @@ class Crypt_DES {
|
||||
*/
|
||||
function encrypt($plaintext)
|
||||
{
|
||||
if ($this->mode != CRYPT_DES_MODE_CTR && $this->mode != 'ctr') {
|
||||
if ($this->paddable) {
|
||||
$plaintext = $this->_pad($plaintext);
|
||||
}
|
||||
|
||||
@ -401,6 +455,7 @@ class Crypt_DES {
|
||||
$this->keys = $this->_prepareKey("\0\0\0\0\0\0\0\0");
|
||||
}
|
||||
|
||||
$buffer = &$this->enbuffer;
|
||||
$ciphertext = '';
|
||||
switch ($this->mode) {
|
||||
case CRYPT_DES_MODE_ECB:
|
||||
@ -422,13 +477,59 @@ class Crypt_DES {
|
||||
break;
|
||||
case CRYPT_DES_MODE_CTR:
|
||||
$xor = $this->encryptIV;
|
||||
if (strlen($buffer)) {
|
||||
for ($i = 0; $i < strlen($plaintext); $i+=8) {
|
||||
$block = substr($plaintext, $i, 8);
|
||||
$buffer.= $this->_processBlock($this->_generate_xor(8, $xor), CRYPT_DES_ENCRYPT);
|
||||
$key = $this->_string_shift($buffer, 8);
|
||||
$ciphertext.= $block ^ $key;
|
||||
}
|
||||
} else {
|
||||
for ($i = 0; $i < strlen($plaintext); $i+=8) {
|
||||
$block = substr($plaintext, $i, 8);
|
||||
$key = $this->_processBlock($this->_generate_xor(8, $xor), CRYPT_DES_ENCRYPT);
|
||||
$ciphertext.= $block ^ $key;
|
||||
}
|
||||
}
|
||||
if ($this->continuousBuffer) {
|
||||
$this->encryptIV = $xor;
|
||||
if ($start = strlen($plaintext) & 7) {
|
||||
$buffer = substr($key, $start) . $buffer;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case CRYPT_DES_MODE_CFB:
|
||||
$iv = $this->encryptIV;
|
||||
for ($i = 0; $i < strlen($plaintext); $i+=8) {
|
||||
$block = substr($plaintext, $i, 8);
|
||||
$iv = $block ^ $this->_processBlock($iv, CRYPT_DES_ENCRYPT);
|
||||
$ciphertext.= $iv;
|
||||
}
|
||||
if ($this->continuousBuffer) {
|
||||
$this->encryptIV = $iv;
|
||||
}
|
||||
break;
|
||||
case CRYPT_DES_MODE_OFB:
|
||||
$xor = $this->encryptIV;
|
||||
if (strlen($buffer)) {
|
||||
for ($i = 0; $i < strlen($plaintext); $i+=8) {
|
||||
$xor = $this->_processBlock($xor, CRYPT_DES_ENCRYPT);
|
||||
$buffer.= $xor;
|
||||
$key = $this->_string_shift($buffer, 8);
|
||||
$ciphertext.= substr($plaintext, $i, 8) ^ $key;
|
||||
}
|
||||
} else {
|
||||
for ($i = 0; $i < strlen($plaintext); $i+=8) {
|
||||
$xor = $this->_processBlock($xor, CRYPT_DES_ENCRYPT);
|
||||
$ciphertext.= substr($plaintext, $i, 8) ^ $xor;
|
||||
}
|
||||
$key = $xor;
|
||||
}
|
||||
if ($this->continuousBuffer) {
|
||||
$this->encryptIV = $xor;
|
||||
if ($start = strlen($plaintext) & 7) {
|
||||
$buffer = substr($key, $start) . $buffer;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -446,7 +547,7 @@ class Crypt_DES {
|
||||
*/
|
||||
function decrypt($ciphertext)
|
||||
{
|
||||
if ($this->mode != CRYPT_DES_MODE_CTR && $this->mode != 'ctr') {
|
||||
if ($this->paddable) {
|
||||
// we pad with chr(0) since that's what mcrypt_generic does. to quote from http://php.net/function.mcrypt-generic :
|
||||
// "The data is padded with "\0" to make sure the length of the data is n * blocksize."
|
||||
$ciphertext = str_pad($ciphertext, (strlen($ciphertext) + 7) & 0xFFFFFFF8, chr(0));
|
||||
@ -474,6 +575,7 @@ class Crypt_DES {
|
||||
$this->keys = $this->_prepareKey("\0\0\0\0\0\0\0\0");
|
||||
}
|
||||
|
||||
$buffer = &$this->debuffer;
|
||||
$plaintext = '';
|
||||
switch ($this->mode) {
|
||||
case CRYPT_DES_MODE_ECB:
|
||||
@ -494,17 +596,63 @@ class Crypt_DES {
|
||||
break;
|
||||
case CRYPT_DES_MODE_CTR:
|
||||
$xor = $this->decryptIV;
|
||||
if (strlen($buffer)) {
|
||||
for ($i = 0; $i < strlen($ciphertext); $i+=8) {
|
||||
$block = substr($ciphertext, $i, 8);
|
||||
$buffer.= $this->_processBlock($this->_generate_xor(8, $xor), CRYPT_DES_ENCRYPT);
|
||||
$key = $this->_string_shift($buffer, 8);
|
||||
$plaintext.= $block ^ $key;
|
||||
}
|
||||
} else {
|
||||
for ($i = 0; $i < strlen($ciphertext); $i+=8) {
|
||||
$block = substr($ciphertext, $i, 8);
|
||||
$key = $this->_processBlock($this->_generate_xor(8, $xor), CRYPT_DES_ENCRYPT);
|
||||
$plaintext.= $block ^ $key;
|
||||
}
|
||||
}
|
||||
if ($this->continuousBuffer) {
|
||||
$this->decryptIV = $xor;
|
||||
if ($start = strlen($ciphertext) % 8) {
|
||||
$buffer = substr($key, $start) . $buffer;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case CRYPT_DES_MODE_CFB:
|
||||
$xor = $this->_processBlock($this->decryptIV, CRYPT_DES_ENCRYPT);
|
||||
for ($i = 0; $i < strlen($ciphertext); $i+=8) {
|
||||
$block = substr($ciphertext, $i, 8);
|
||||
$plaintext.= $block ^ $xor;
|
||||
$xor = $this->_processBlock($block, CRYPT_DES_ENCRYPT);
|
||||
}
|
||||
if ($this->continuousBuffer) {
|
||||
$this->decryptIV = $xor;
|
||||
}
|
||||
break;
|
||||
case CRYPT_DES_MODE_OFB:
|
||||
$xor = $this->decryptIV;
|
||||
if (strlen($buffer)) {
|
||||
for ($i = 0; $i < strlen($ciphertext); $i+=8) {
|
||||
$xor = $this->_processBlock($xor, CRYPT_DES_ENCRYPT);
|
||||
$buffer.= $xor;
|
||||
$key = $this->_string_shift($buffer, 8);
|
||||
$plaintext.= substr($ciphertext, $i, 8) ^ $key;
|
||||
}
|
||||
} else {
|
||||
for ($i = 0; $i < strlen($ciphertext); $i+=8) {
|
||||
$xor = $this->_processBlock($xor, CRYPT_DES_ENCRYPT);
|
||||
$plaintext.= substr($ciphertext, $i, 8) ^ $xor;
|
||||
}
|
||||
$key = $xor;
|
||||
}
|
||||
if ($this->continuousBuffer) {
|
||||
$this->decryptIV = $xor;
|
||||
if ($start = strlen($ciphertext) % 8) {
|
||||
$buffer = substr($key, $start) . $buffer;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $this->mode != CRYPT_DES_MODE_CTR ? $this->_unpad($plaintext) : $plaintext;
|
||||
return $this->paddable ? $this->_unpad($plaintext) : $plaintext;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -949,6 +1097,23 @@ class Crypt_DES {
|
||||
|
||||
return $temp;
|
||||
}
|
||||
|
||||
/**
|
||||
* String Shift
|
||||
*
|
||||
* Inspired by array_shift
|
||||
*
|
||||
* @param String $string
|
||||
* @param optional Integer $index
|
||||
* @return String
|
||||
* @access private
|
||||
*/
|
||||
function _string_shift(&$string, $index = 1)
|
||||
{
|
||||
$substr = substr($string, 0, $index);
|
||||
$string = substr($string, $index);
|
||||
return $substr;
|
||||
}
|
||||
}
|
||||
|
||||
// vim: ts=4:sw=4:et:
|
||||
|
@ -62,7 +62,7 @@
|
||||
* @author Jim Wigginton <terrafrost@php.net>
|
||||
* @copyright MMIX Jim Wigginton
|
||||
* @license http://www.gnu.org/licenses/lgpl.txt
|
||||
* @version $Id: RSA.php,v 1.18 2010-09-05 03:04:29 terrafrost Exp $
|
||||
* @version $Id: RSA.php,v 1.19 2010-09-12 21:58:54 terrafrost Exp $
|
||||
* @link http://phpseclib.sourceforge.net
|
||||
*/
|
||||
|
||||
@ -784,6 +784,13 @@ class Crypt_RSA {
|
||||
}
|
||||
$symkey = substr($symkey, 0, 16);
|
||||
break;
|
||||
// CFB mode needs to work as a stream cipher for this to work
|
||||
//case 'DES-EDE3-CFB':
|
||||
// if (!class_exists('Crypt_TripleDES')) {
|
||||
// require_once('Crypt/TripleDES.php');
|
||||
// }
|
||||
// $crypto = new Crypt_TripleDES(CRYPT_DES_MODE_CFB);
|
||||
// break;
|
||||
case 'DES-EDE3-CBC':
|
||||
if (!class_exists('Crypt_TripleDES')) {
|
||||
require_once('Crypt/TripleDES.php');
|
||||
|
@ -64,7 +64,7 @@
|
||||
* @author Jim Wigginton <terrafrost@php.net>
|
||||
* @copyright MMVIII Jim Wigginton
|
||||
* @license http://www.gnu.org/licenses/lgpl.txt
|
||||
* @version $Id: Rijndael.php,v 1.12 2010-02-09 06:10:26 terrafrost Exp $
|
||||
* @version $Id: Rijndael.php,v 1.13 2010-09-12 21:58:54 terrafrost Exp $
|
||||
* @link http://phpseclib.sourceforge.net
|
||||
*/
|
||||
|
||||
@ -93,6 +93,18 @@ define('CRYPT_RIJNDAEL_MODE_ECB', 1);
|
||||
* @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Cipher-block_chaining_.28CBC.29
|
||||
*/
|
||||
define('CRYPT_RIJNDAEL_MODE_CBC', 2);
|
||||
/**
|
||||
* Encrypt / decrypt using the Cipher Feedback mode.
|
||||
*
|
||||
* @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Cipher_feedback_.28CFB.29
|
||||
*/
|
||||
define('CRYPT_RIJNDAEL_MODE_CFB', 3);
|
||||
/**
|
||||
* Encrypt / decrypt using the Cipher Feedback mode.
|
||||
*
|
||||
* @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Output_feedback_.28OFB.29
|
||||
*/
|
||||
define('CRYPT_RIJNDAEL_MODE_OFB', 4);
|
||||
/**#@-*/
|
||||
|
||||
/**#@+
|
||||
@ -356,6 +368,33 @@ class Crypt_Rijndael {
|
||||
*/
|
||||
var $dt3;
|
||||
|
||||
/**
|
||||
* Is the mode one that is paddable?
|
||||
*
|
||||
* @see Crypt_Rijndael::Crypt_Rijndael()
|
||||
* @var Boolean
|
||||
* @access private
|
||||
*/
|
||||
var $paddable = false;
|
||||
|
||||
/**
|
||||
* Encryption buffer for CTR, OFB and CFB modes
|
||||
*
|
||||
* @see Crypt_Rijndael::encrypt()
|
||||
* @var String
|
||||
* @access private
|
||||
*/
|
||||
var $enbuffer = '';
|
||||
|
||||
/**
|
||||
* Decryption buffer for CTR, OFB and CFB modes
|
||||
*
|
||||
* @see Crypt_Rijndael::decrypt()
|
||||
* @var String
|
||||
* @access private
|
||||
*/
|
||||
var $debuffer = '';
|
||||
|
||||
/**
|
||||
* Default Constructor.
|
||||
*
|
||||
@ -370,11 +409,17 @@ class Crypt_Rijndael {
|
||||
{
|
||||
switch ($mode) {
|
||||
case CRYPT_RIJNDAEL_MODE_ECB:
|
||||
case CRYPT_RIJNDAEL_MODE_CFB:
|
||||
$this->paddable = true;
|
||||
$this->mode = $mode;
|
||||
break;
|
||||
case CRYPT_RIJNDAEL_MODE_CBC:
|
||||
case CRYPT_RIJNDAEL_MODE_CTR:
|
||||
case CRYPT_RIJNDAEL_MODE_OFB:
|
||||
$this->mode = $mode;
|
||||
break;
|
||||
default:
|
||||
$this->paddable = true;
|
||||
$this->mode = CRYPT_RIJNDAEL_MODE_CBC;
|
||||
}
|
||||
|
||||
@ -611,11 +656,12 @@ class Crypt_Rijndael {
|
||||
function encrypt($plaintext)
|
||||
{
|
||||
$this->_setup();
|
||||
if ($this->mode != CRYPT_RIJNDAEL_MODE_CTR) {
|
||||
if ($this->paddable) {
|
||||
$plaintext = $this->_pad($plaintext);
|
||||
}
|
||||
|
||||
$block_size = $this->block_size;
|
||||
$buffer = &$this->enbuffer;
|
||||
$ciphertext = '';
|
||||
switch ($this->mode) {
|
||||
case CRYPT_RIJNDAEL_MODE_ECB:
|
||||
@ -637,13 +683,59 @@ class Crypt_Rijndael {
|
||||
break;
|
||||
case CRYPT_RIJNDAEL_MODE_CTR:
|
||||
$xor = $this->encryptIV;
|
||||
if (strlen($buffer)) {
|
||||
for ($i = 0; $i < strlen($plaintext); $i+=$block_size) {
|
||||
$block = substr($plaintext, $i, $block_size);
|
||||
$buffer.= $this->_encryptBlock($this->_generate_xor($block_size, $xor));
|
||||
$key = $this->_string_shift($buffer, $block_size);
|
||||
$ciphertext.= $block ^ $key;
|
||||
}
|
||||
} else {
|
||||
for ($i = 0; $i < strlen($plaintext); $i+=$block_size) {
|
||||
$block = substr($plaintext, $i, $block_size);
|
||||
$key = $this->_encryptBlock($this->_generate_xor($block_size, $xor));
|
||||
$ciphertext.= $block ^ $key;
|
||||
}
|
||||
}
|
||||
if ($this->continuousBuffer) {
|
||||
$this->encryptIV = $xor;
|
||||
if ($start = strlen($plaintext) % $block_size) {
|
||||
$buffer = substr($key, $start) . $buffer;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case CRYPT_RIJNDAEL_MODE_CFB:
|
||||
$iv = $this->encryptIV;
|
||||
for ($i = 0; $i < strlen($plaintext); $i+=$block_size) {
|
||||
$block = substr($plaintext, $i, $block_size);
|
||||
$iv = $block ^ $this->_encryptBlock($iv);
|
||||
$ciphertext.= $iv;
|
||||
}
|
||||
if ($this->continuousBuffer) {
|
||||
$this->encryptIV = $iv;
|
||||
}
|
||||
break;
|
||||
case CRYPT_RIJNDAEL_MODE_OFB:
|
||||
$xor = $this->encryptIV;
|
||||
if (strlen($buffer)) {
|
||||
for ($i = 0; $i < strlen($plaintext); $i+=$block_size) {
|
||||
$xor = $this->_encryptBlock($xor);
|
||||
$buffer.= $xor;
|
||||
$key = $this->_string_shift($buffer, $block_size);
|
||||
$ciphertext.= substr($plaintext, $i, $block_size) ^ $key;
|
||||
}
|
||||
} else {
|
||||
for ($i = 0; $i < strlen($plaintext); $i+=$block_size) {
|
||||
$xor = $this->_encryptBlock($xor);
|
||||
$ciphertext.= substr($plaintext, $i, $block_size) ^ $xor;
|
||||
}
|
||||
$key = $xor;
|
||||
}
|
||||
if ($this->continuousBuffer) {
|
||||
$this->encryptIV = $xor;
|
||||
if ($start = strlen($plaintext) % $block_size) {
|
||||
$buffer = substr($key, $start) . $buffer;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -664,13 +756,14 @@ class Crypt_Rijndael {
|
||||
{
|
||||
$this->_setup();
|
||||
|
||||
if ($this->mode != CRYPT_RIJNDAEL_MODE_CTR) {
|
||||
if ($this->paddable) {
|
||||
// we pad with chr(0) since that's what mcrypt_generic does. to quote from http://php.net/function.mcrypt-generic :
|
||||
// "The data is padded with "\0" to make sure the length of the data is n * blocksize."
|
||||
$ciphertext = str_pad($ciphertext, (strlen($ciphertext) + $this->block_size - 1) % $this->block_size, chr(0));
|
||||
}
|
||||
|
||||
$block_size = $this->block_size;
|
||||
$buffer = &$this->debuffer;
|
||||
$plaintext = '';
|
||||
switch ($this->mode) {
|
||||
case CRYPT_RIJNDAEL_MODE_ECB:
|
||||
@ -691,17 +784,63 @@ class Crypt_Rijndael {
|
||||
break;
|
||||
case CRYPT_RIJNDAEL_MODE_CTR:
|
||||
$xor = $this->decryptIV;
|
||||
if (strlen($buffer)) {
|
||||
for ($i = 0; $i < strlen($ciphertext); $i+=$block_size) {
|
||||
$block = substr($ciphertext, $i, $block_size);
|
||||
$buffer.= $this->_encryptBlock($this->_generate_xor($block_size, $xor));
|
||||
$key = $this->_string_shift($buffer, $block_size);
|
||||
$plaintext.= $block ^ $key;
|
||||
}
|
||||
} else {
|
||||
for ($i = 0; $i < strlen($ciphertext); $i+=$block_size) {
|
||||
$block = substr($ciphertext, $i, $block_size);
|
||||
$key = $this->_encryptBlock($this->_generate_xor($block_size, $xor));
|
||||
$plaintext.= $block ^ $key;
|
||||
}
|
||||
}
|
||||
if ($this->continuousBuffer) {
|
||||
$this->decryptIV = $xor;
|
||||
if ($start = strlen($ciphertext) % $block_size) {
|
||||
$buffer = substr($key, $start) . $buffer;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case CRYPT_RIJNDAEL_MODE_CFB:
|
||||
$iv = $this->_encryptBlock($this->decryptIV);
|
||||
for ($i = 0; $i < strlen($ciphertext); $i+=$block_size) {
|
||||
$block = substr($ciphertext, $i, $block_size);
|
||||
$plaintext.= $block ^ $iv;
|
||||
$iv = $this->_encryptBlock($block);
|
||||
}
|
||||
if ($this->continuousBuffer) {
|
||||
$this->decryptIV = $iv;
|
||||
}
|
||||
break;
|
||||
case CRYPT_RIJNDAEL_MODE_OFB:
|
||||
$xor = $this->decryptIV;
|
||||
if (strlen($buffer)) {
|
||||
for ($i = 0; $i < strlen($ciphertext); $i+=$block_size) {
|
||||
$xor = $this->_encryptBlock($xor);
|
||||
$buffer.= $xor;
|
||||
$key = $this->_string_shift($buffer, $block_size);
|
||||
$plaintext.= substr($ciphertext, $i, $block_size) ^ $key;
|
||||
}
|
||||
} else {
|
||||
for ($i = 0; $i < strlen($ciphertext); $i+=$block_size) {
|
||||
$xor = $this->_encryptBlock($xor);
|
||||
$plaintext.= substr($ciphertext, $i, $block_size) ^ $xor;
|
||||
}
|
||||
$key = $xor;
|
||||
}
|
||||
if ($this->continuousBuffer) {
|
||||
$this->decryptIV = $xor;
|
||||
if ($start = strlen($ciphertext) % $block_size) {
|
||||
$buffer = substr($key, $start) . $buffer;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $this->mode != CRYPT_RIJNDAEL_MODE_CTR ? $this->_unpad($plaintext) : $plaintext;
|
||||
return $this->paddable ? $this->_unpad($plaintext) : $plaintext;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -47,7 +47,7 @@
|
||||
* @author Jim Wigginton <terrafrost@php.net>
|
||||
* @copyright MMVII Jim Wigginton
|
||||
* @license http://www.gnu.org/licenses/lgpl.txt
|
||||
* @version $Id: TripleDES.php,v 1.14 2010-08-08 05:06:38 terrafrost Exp $
|
||||
* @version $Id: TripleDES.php,v 1.15 2010-09-12 21:58:54 terrafrost Exp $
|
||||
* @link http://phpseclib.sourceforge.net
|
||||
*/
|
||||
|
||||
@ -61,7 +61,7 @@ require_once('DES.php');
|
||||
*
|
||||
* Inner chaining is used by SSH-1 and is generally considered to be less secure then outer chaining (CRYPT_DES_MODE_CBC3).
|
||||
*/
|
||||
define('CRYPT_DES_MODE_3CBC', 3);
|
||||
define('CRYPT_DES_MODE_3CBC', -2);
|
||||
|
||||
/**
|
||||
* Encrypt / decrypt using outer chaining
|
||||
@ -156,7 +156,7 @@ class Crypt_TripleDES {
|
||||
* The mcrypt resource can be recreated every time something needs to be created or it can be created just once.
|
||||
* Since mcrypt operates in continuous mode, by default, it'll need to be recreated when in non-continuous mode.
|
||||
*
|
||||
* @see Crypt_AES::encrypt()
|
||||
* @see Crypt_TripleDES::encrypt()
|
||||
* @var String
|
||||
* @access private
|
||||
*/
|
||||
@ -168,21 +168,58 @@ class Crypt_TripleDES {
|
||||
* The mcrypt resource can be recreated every time something needs to be created or it can be created just once.
|
||||
* Since mcrypt operates in continuous mode, by default, it'll need to be recreated when in non-continuous mode.
|
||||
*
|
||||
* @see Crypt_AES::decrypt()
|
||||
* @see Crypt_TripleDES::decrypt()
|
||||
* @var String
|
||||
* @access private
|
||||
*/
|
||||
var $demcrypt;
|
||||
|
||||
/**
|
||||
* Does the (en|de)mcrypt resource need to be (re)initialized?
|
||||
* Does the enmcrypt resource need to be (re)initialized?
|
||||
*
|
||||
* @see setKey()
|
||||
* @see setIV()
|
||||
* @see Crypt_TripleDES::setKey()
|
||||
* @see Crypt_TripleDES::setIV()
|
||||
* @var Boolean
|
||||
* @access private
|
||||
*/
|
||||
var $changed = true;
|
||||
var $enchanged = true;
|
||||
|
||||
/**
|
||||
* Does the demcrypt resource need to be (re)initialized?
|
||||
*
|
||||
* @see Crypt_TripleDES::setKey()
|
||||
* @see Crypt_TripleDES::setIV()
|
||||
* @var Boolean
|
||||
* @access private
|
||||
*/
|
||||
var $dechanged = true;
|
||||
|
||||
/**
|
||||
* Is the mode one that is paddable?
|
||||
*
|
||||
* @see Crypt_TripleDES::Crypt_TripleDES()
|
||||
* @var Boolean
|
||||
* @access private
|
||||
*/
|
||||
var $paddable = false;
|
||||
|
||||
/**
|
||||
* Encryption buffer for CTR, OFB and CFB modes
|
||||
*
|
||||
* @see Crypt_TripleDES::encrypt()
|
||||
* @var String
|
||||
* @access private
|
||||
*/
|
||||
var $enbuffer = '';
|
||||
|
||||
/**
|
||||
* Decryption buffer for CTR, OFB and CFB modes
|
||||
*
|
||||
* @see Crypt_TripleDES::decrypt()
|
||||
* @var String
|
||||
* @access private
|
||||
*/
|
||||
var $debuffer = '';
|
||||
|
||||
/**
|
||||
* Default Constructor.
|
||||
@ -229,13 +266,22 @@ class Crypt_TripleDES {
|
||||
case CRYPT_DES_MODE_MCRYPT:
|
||||
switch ($mode) {
|
||||
case CRYPT_DES_MODE_ECB:
|
||||
$this->paddable = true;
|
||||
$this->mode = MCRYPT_MODE_ECB;
|
||||
break;
|
||||
case CRYPT_DES_MODE_CTR:
|
||||
$this->mode = 'ctr';
|
||||
break;
|
||||
case CRYPT_DES_MODE_CFB:
|
||||
$this->paddable = true;
|
||||
$this->mode = 'ncfb';
|
||||
break;
|
||||
case CRYPT_DES_MODE_OFB:
|
||||
$this->mode = MCRYPT_MODE_NOFB;
|
||||
break;
|
||||
case CRYPT_DES_MODE_CBC:
|
||||
default:
|
||||
$this->paddable = true;
|
||||
$this->mode = MCRYPT_MODE_CBC;
|
||||
}
|
||||
|
||||
@ -254,11 +300,17 @@ class Crypt_TripleDES {
|
||||
|
||||
switch ($mode) {
|
||||
case CRYPT_DES_MODE_ECB:
|
||||
case CRYPT_DES_MODE_CFB:
|
||||
$this->paddable = true;
|
||||
$this->mode = $mode;
|
||||
break;
|
||||
case CRYPT_DES_MODE_CTR:
|
||||
case CRYPT_DES_MODE_CBC:
|
||||
case CRYPT_DES_MODE_OFB:
|
||||
$this->mode = $mode;
|
||||
break;
|
||||
default:
|
||||
$this->paddable = true;
|
||||
$this->mode = CRYPT_DES_MODE_CBC;
|
||||
}
|
||||
}
|
||||
@ -294,7 +346,7 @@ class Crypt_TripleDES {
|
||||
$this->des[1]->setKey(substr($key, 8, 8));
|
||||
$this->des[2]->setKey(substr($key, 16, 8));
|
||||
}
|
||||
$this->changed = true;
|
||||
$this->enchanged = $this->dechanged = true;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -314,7 +366,7 @@ class Crypt_TripleDES {
|
||||
$this->des[1]->setIV($iv);
|
||||
$this->des[2]->setIV($iv);
|
||||
}
|
||||
$this->changed = true;
|
||||
$this->enchanged = $this->dechanged = true;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -323,9 +375,9 @@ class Crypt_TripleDES {
|
||||
* Encrypt the output of this and XOR it against the ciphertext / plaintext to get the
|
||||
* plaintext / ciphertext in CTR mode.
|
||||
*
|
||||
* @see Crypt_DES::decrypt()
|
||||
* @see Crypt_DES::encrypt()
|
||||
* @access public
|
||||
* @see Crypt_TripleDES::decrypt()
|
||||
* @see Crypt_TripleDES::encrypt()
|
||||
* @access private
|
||||
* @param Integer $length
|
||||
* @param String $iv
|
||||
*/
|
||||
@ -363,7 +415,7 @@ class Crypt_TripleDES {
|
||||
*/
|
||||
function encrypt($plaintext)
|
||||
{
|
||||
if ($this->mode != CRYPT_DES_MODE_CTR && $this->mode != 'ctr') {
|
||||
if ($this->paddable) {
|
||||
$plaintext = $this->_pad($plaintext);
|
||||
}
|
||||
|
||||
@ -375,12 +427,12 @@ class Crypt_TripleDES {
|
||||
}
|
||||
|
||||
if ( CRYPT_DES_MODE == CRYPT_DES_MODE_MCRYPT ) {
|
||||
if ($this->changed) {
|
||||
if ($this->enchanged) {
|
||||
if (!isset($this->enmcrypt)) {
|
||||
$this->enmcrypt = mcrypt_module_open(MCRYPT_3DES, '', $this->mode, '');
|
||||
}
|
||||
mcrypt_generic_init($this->enmcrypt, $this->key, $this->encryptIV);
|
||||
$this->changed = false;
|
||||
$this->enchanged = false;
|
||||
}
|
||||
|
||||
$ciphertext = mcrypt_generic($this->enmcrypt, $plaintext);
|
||||
@ -398,17 +450,20 @@ class Crypt_TripleDES {
|
||||
return $this->des[0]->encrypt($plaintext);
|
||||
}
|
||||
|
||||
// we pad with chr(0) since that's what mcrypt_generic does. to quote from http://php.net/function.mcrypt-generic :
|
||||
// "The data is padded with "\0" to make sure the length of the data is n * blocksize."
|
||||
$plaintext = str_pad($plaintext, ceil(strlen($plaintext) / 8) * 8, chr(0));
|
||||
|
||||
$des = $this->des;
|
||||
|
||||
$buffer = &$this->enbuffer;
|
||||
$ciphertext = '';
|
||||
switch ($this->mode) {
|
||||
case CRYPT_DES_MODE_ECB:
|
||||
for ($i = 0; $i < strlen($plaintext); $i+=8) {
|
||||
$block = substr($plaintext, $i, 8);
|
||||
// all of these _processBlock calls could, in theory, be put in a function - say Crypt_TripleDES::_ede_encrypt() or something.
|
||||
// only problem with that: it would slow encryption and decryption down. $this->des would have to be called every time that
|
||||
// function is called, instead of once for the whole string of text that's being encrypted, which would, in turn, make
|
||||
// encryption and decryption take more time, per this:
|
||||
//
|
||||
// http://blog.libssh2.org/index.php?/archives/21-Compiled-Variables.html
|
||||
$block = $des[0]->_processBlock($block, CRYPT_DES_ENCRYPT);
|
||||
$block = $des[1]->_processBlock($block, CRYPT_DES_DECRYPT);
|
||||
$block = $des[2]->_processBlock($block, CRYPT_DES_ENCRYPT);
|
||||
@ -431,16 +486,73 @@ class Crypt_TripleDES {
|
||||
break;
|
||||
case CRYPT_DES_MODE_CTR:
|
||||
$xor = $this->encryptIV;
|
||||
if (strlen($buffer)) {
|
||||
for ($i = 0; $i < strlen($plaintext); $i+=8) {
|
||||
$block = substr($plaintext, $i, 8);
|
||||
$key = $this->_generate_xor(8, $xor);
|
||||
$key = $des[0]->_processBlock($key, CRYPT_DES_ENCRYPT);
|
||||
$key = $des[1]->_processBlock($key, CRYPT_DES_DECRYPT);
|
||||
$key = $des[2]->_processBlock($key, CRYPT_DES_ENCRYPT);
|
||||
$block = substr($plaintext, $i, 8);
|
||||
$buffer.= $key;
|
||||
$key = $this->_string_shift($buffer, 8);
|
||||
$ciphertext.= $block ^ $key;
|
||||
}
|
||||
} else {
|
||||
for ($i = 0; $i < strlen($plaintext); $i+=8) {
|
||||
$block = substr($plaintext, $i, 8);
|
||||
$key = $this->_generate_xor(8, $xor);
|
||||
$key = $des[0]->_processBlock($key, CRYPT_DES_ENCRYPT);
|
||||
$key = $des[1]->_processBlock($key, CRYPT_DES_DECRYPT);
|
||||
$key = $des[2]->_processBlock($key, CRYPT_DES_ENCRYPT);
|
||||
$ciphertext.= $block ^ $key;
|
||||
}
|
||||
}
|
||||
if ($this->continuousBuffer) {
|
||||
$this->encryptIV = $xor;
|
||||
if ($start = strlen($plaintext) & 7) {
|
||||
$buffer = substr($key, $start) . $buffer;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case CRYPT_DES_MODE_CFB:
|
||||
$iv = $this->encryptIV;
|
||||
for ($i = 0; $i < strlen($plaintext); $i+=8) {
|
||||
$block = substr($plaintext, $i, 8);
|
||||
$iv = $des[0]->_processBlock($iv, CRYPT_DES_ENCRYPT);
|
||||
$iv = $des[1]->_processBlock($iv, CRYPT_DES_DECRYPT);
|
||||
$iv = $des[2]->_processBlock($iv, CRYPT_DES_ENCRYPT);
|
||||
$iv^= $block;
|
||||
$ciphertext.= $iv;
|
||||
}
|
||||
if ($this->continuousBuffer) {
|
||||
$this->encryptIV = $iv;
|
||||
}
|
||||
break;
|
||||
case CRYPT_DES_MODE_OFB:
|
||||
$xor = $this->encryptIV;
|
||||
if (strlen($buffer)) {
|
||||
for ($i = 0; $i < strlen($plaintext); $i+=8) {
|
||||
$xor = $des[0]->_processBlock($xor, CRYPT_DES_ENCRYPT);
|
||||
$xor = $des[1]->_processBlock($xor, CRYPT_DES_DECRYPT);
|
||||
$xor = $des[2]->_processBlock($xor, CRYPT_DES_ENCRYPT);
|
||||
$buffer.= $xor;
|
||||
$key = $this->_string_shift($buffer, 8);
|
||||
$ciphertext.= substr($plaintext, $i, 8) ^ $key;
|
||||
}
|
||||
} else {
|
||||
for ($i = 0; $i < strlen($plaintext); $i+=8) {
|
||||
$xor = $des[0]->_processBlock($xor, CRYPT_DES_ENCRYPT);
|
||||
$xor = $des[1]->_processBlock($xor, CRYPT_DES_DECRYPT);
|
||||
$xor = $des[2]->_processBlock($xor, CRYPT_DES_ENCRYPT);
|
||||
$ciphertext.= substr($plaintext, $i, 8) ^ $xor;
|
||||
}
|
||||
$key = $xor;
|
||||
}
|
||||
if ($this->continuousBuffer) {
|
||||
$this->encryptIV = $xor;
|
||||
if ($start = strlen($plaintext) & 7) {
|
||||
$buffer = substr($key, $start) . $buffer;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -461,17 +573,19 @@ class Crypt_TripleDES {
|
||||
return $this->_unpad($plaintext);
|
||||
}
|
||||
|
||||
if ($this->paddable) {
|
||||
// we pad with chr(0) since that's what mcrypt_generic does. to quote from http://php.net/function.mcrypt-generic :
|
||||
// "The data is padded with "\0" to make sure the length of the data is n * blocksize."
|
||||
$ciphertext = str_pad($ciphertext, (strlen($ciphertext) + 7) & 0xFFFFFFF8, chr(0));
|
||||
}
|
||||
|
||||
if ( CRYPT_DES_MODE == CRYPT_DES_MODE_MCRYPT ) {
|
||||
if ($this->changed) {
|
||||
if ($this->dechanged) {
|
||||
if (!isset($this->demcrypt)) {
|
||||
$this->demcrypt = mcrypt_module_open(MCRYPT_3DES, '', $this->mode, '');
|
||||
}
|
||||
mcrypt_generic_init($this->demcrypt, $this->key, $this->decryptIV);
|
||||
$this->changed = false;
|
||||
$this->dechanged = false;
|
||||
}
|
||||
|
||||
$plaintext = mdecrypt_generic($this->demcrypt, $ciphertext);
|
||||
@ -480,17 +594,18 @@ class Crypt_TripleDES {
|
||||
mcrypt_generic_init($this->demcrypt, $this->key, $this->decryptIV);
|
||||
}
|
||||
|
||||
return $this->mode != 'ctr' ? $this->_unpad($plaintext) : $plaintext;
|
||||
return $this->paddable ? $this->_unpad($plaintext) : $plaintext;
|
||||
}
|
||||
|
||||
if (strlen($this->key) <= 8) {
|
||||
$this->des[0]->mode = $this->mode;
|
||||
|
||||
return $this->_unpad($this->des[0]->decrypt($plaintext));
|
||||
$plaintext = $this->des[0]->decrypt($ciphertext);
|
||||
return $this->paddable ? $this->_unpad($plaintext) : $plaintext;
|
||||
}
|
||||
|
||||
$des = $this->des;
|
||||
|
||||
$buffer = &$this->enbuffer;
|
||||
$plaintext = '';
|
||||
switch ($this->mode) {
|
||||
case CRYPT_DES_MODE_ECB:
|
||||
@ -518,20 +633,77 @@ class Crypt_TripleDES {
|
||||
break;
|
||||
case CRYPT_DES_MODE_CTR:
|
||||
$xor = $this->decryptIV;
|
||||
if (strlen($buffer)) {
|
||||
for ($i = 0; $i < strlen($ciphertext); $i+=8) {
|
||||
$block = substr($ciphertext, $i, 8);
|
||||
$key = $this->_generate_xor(8, $xor);
|
||||
$key = $des[0]->_processBlock($key, CRYPT_DES_ENCRYPT);
|
||||
$key = $des[1]->_processBlock($key, CRYPT_DES_DECRYPT);
|
||||
$key = $des[2]->_processBlock($key, CRYPT_DES_ENCRYPT);
|
||||
$block = substr($ciphertext, $i, 8);
|
||||
$buffer.= $key;
|
||||
$key = $this->_string_shift($buffer, 8);
|
||||
$plaintext.= $block ^ $key;
|
||||
}
|
||||
} else {
|
||||
for ($i = 0; $i < strlen($ciphertext); $i+=8) {
|
||||
$block = substr($ciphertext, $i, 8);
|
||||
$key = $this->_generate_xor(8, $xor);
|
||||
$key = $des[0]->_processBlock($key, CRYPT_DES_ENCRYPT);
|
||||
$key = $des[1]->_processBlock($key, CRYPT_DES_DECRYPT);
|
||||
$key = $des[2]->_processBlock($key, CRYPT_DES_ENCRYPT);
|
||||
$plaintext.= $block ^ $key;
|
||||
}
|
||||
}
|
||||
if ($this->continuousBuffer) {
|
||||
$this->decryptIV = $xor;
|
||||
if ($start = strlen($plaintext) & 7) {
|
||||
$buffer = substr($key, $start) . $buffer;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case CRYPT_DES_MODE_CFB:
|
||||
$iv = $this->decryptIV;
|
||||
for ($i = 0; $i < strlen($ciphertext); $i+=8) {
|
||||
$block = substr($ciphertext, $i, 8);
|
||||
$iv = $des[0]->_processBlock($iv, CRYPT_DES_ENCRYPT);
|
||||
$iv = $des[1]->_processBlock($iv, CRYPT_DES_DECRYPT);
|
||||
$iv = $des[2]->_processBlock($iv, CRYPT_DES_ENCRYPT);
|
||||
$iv^= $block;
|
||||
$plaintext.= $iv;
|
||||
}
|
||||
if ($this->continuousBuffer) {
|
||||
$this->decryptIV = $iv;
|
||||
}
|
||||
break;
|
||||
case CRYPT_DES_MODE_OFB:
|
||||
$xor = $this->decryptIV;
|
||||
if (strlen($buffer)) {
|
||||
for ($i = 0; $i < strlen($ciphertext); $i+=8) {
|
||||
$xor = $des[0]->_processBlock($xor, CRYPT_DES_ENCRYPT);
|
||||
$xor = $des[1]->_processBlock($xor, CRYPT_DES_DECRYPT);
|
||||
$xor = $des[2]->_processBlock($xor, CRYPT_DES_ENCRYPT);
|
||||
$buffer.= $xor;
|
||||
$key = $this->_string_shift($buffer, 8);
|
||||
$plaintext.= substr($ciphertext, $i, 8) ^ $key;
|
||||
}
|
||||
} else {
|
||||
for ($i = 0; $i < strlen($ciphertext); $i+=8) {
|
||||
$xor = $des[0]->_processBlock($xor, CRYPT_DES_ENCRYPT);
|
||||
$xor = $des[1]->_processBlock($xor, CRYPT_DES_DECRYPT);
|
||||
$xor = $des[2]->_processBlock($xor, CRYPT_DES_ENCRYPT);
|
||||
$plaintext.= substr($ciphertext, $i, 8) ^ $xor;
|
||||
}
|
||||
$key = $xor;
|
||||
}
|
||||
if ($this->continuousBuffer) {
|
||||
$this->decryptIV = $xor;
|
||||
if ($start = strlen($ciphertext) & 7) {
|
||||
$buffer = substr($key, $start) . $buffer;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $this->mode != CRYPT_DES_MODE_CTR ? $this->_unpad($plaintext) : $plaintext;
|
||||
return $this->paddable ? $this->_unpad($plaintext) : $plaintext;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -684,6 +856,23 @@ class Crypt_TripleDES {
|
||||
|
||||
return substr($text, 0, -$length);
|
||||
}
|
||||
|
||||
/**
|
||||
* String Shift
|
||||
*
|
||||
* Inspired by array_shift
|
||||
*
|
||||
* @param String $string
|
||||
* @param optional Integer $index
|
||||
* @return String
|
||||
* @access private
|
||||
*/
|
||||
function _string_shift(&$string, $index = 1)
|
||||
{
|
||||
$substr = substr($string, 0, $index);
|
||||
$string = substr($string, $index);
|
||||
return $substr;
|
||||
}
|
||||
}
|
||||
|
||||
// vim: ts=4:sw=4:et:
|
||||
|
@ -60,7 +60,7 @@
|
||||
* @author Jim Wigginton <terrafrost@php.net>
|
||||
* @copyright MMVII Jim Wigginton
|
||||
* @license http://www.gnu.org/licenses/lgpl.txt
|
||||
* @version $Id: SSH2.php,v 1.50 2010-08-29 03:27:02 terrafrost Exp $
|
||||
* @version $Id: SSH2.php,v 1.51 2010-09-12 21:58:54 terrafrost Exp $
|
||||
* @link http://phpseclib.sourceforge.net
|
||||
*/
|
||||
|
||||
@ -563,23 +563,6 @@ class Net_SSH2 {
|
||||
*/
|
||||
var $signature_format = '';
|
||||
|
||||
/**
|
||||
* Key size fix
|
||||
*
|
||||
* Portable OpenSSH 4.4 and earlier use faulty key sizes for aes256-ctr, aes192-ctr and arcfour256.
|
||||
* These algorithms could be removed from $encryption_algorithms in Net_SSH2::_key_exchange() but we'll
|
||||
* adjust the key sizes instead to confirm that the version detection technique we're using is correct.
|
||||
* If it isn't correct than we'll get decryption / encryption errors. We wouldn't get any errors, in
|
||||
* contrast, if the algorithms were simply removed, and would never know if the version detection
|
||||
* technique we were using was correct.
|
||||
*
|
||||
* @link http://www.chiark.greenend.org.uk/~sgtatham/putty/wishlist/ssh2-aesctr-openssh
|
||||
* @see Net_SSH2::Net_SSH2()
|
||||
* @var Boolean
|
||||
* @access private
|
||||
*/
|
||||
var $adjust_key_fix = false;
|
||||
|
||||
/**
|
||||
* Default Constructor.
|
||||
*
|
||||
@ -725,8 +708,6 @@ class Net_SSH2 {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->adjust_key_fix = preg_match('#SSH-' . $matches[1] . '\-OpenSSH_([\d\.]+)#', $this->server_identifier, $matches) && $matches[1] < 4.6;
|
||||
|
||||
fputs($this->fsock, $this->identifier . "\r\n");
|
||||
|
||||
$response = $this->_get_binary_packet();
|
||||
@ -885,16 +866,12 @@ class Net_SSH2 {
|
||||
$decryptKeyLength = 24; // eg. 192 / 8
|
||||
break;
|
||||
case 'aes256-cbc':
|
||||
case 'aes256-ctr':
|
||||
$decryptKeyLength = 32; // eg. 256 / 8
|
||||
break;
|
||||
case 'aes256-ctr':
|
||||
$decryptKeyLength = !$this->adjust_key_fix ? 32 : 16;
|
||||
break;
|
||||
case 'aes192-cbc':
|
||||
$decryptKeyLength = 24;
|
||||
break;
|
||||
case 'aes192-ctr':
|
||||
$decryptKeyLength = !$this->adjust_key_fix ? 24 : 16;
|
||||
$decryptKeyLength = 24; // eg. 192 / 8
|
||||
break;
|
||||
case 'aes128-cbc':
|
||||
case 'aes128-ctr':
|
||||
@ -902,10 +879,10 @@ class Net_SSH2 {
|
||||
break;
|
||||
case 'arcfour':
|
||||
case 'arcfour128':
|
||||
$decryptKeyLength = 16;
|
||||
$decryptKeyLength = 16; // eg. 128 / 8
|
||||
break;
|
||||
case 'arcfour256':
|
||||
$decryptKeyLength = !$this->adjust_key_fix ? 32 : 16;
|
||||
$decryptKeyLength = 32; // eg. 128 / 8
|
||||
break;
|
||||
case 'none';
|
||||
$decryptKeyLength = 0;
|
||||
@ -924,16 +901,12 @@ class Net_SSH2 {
|
||||
$encryptKeyLength = 24;
|
||||
break;
|
||||
case 'aes256-cbc':
|
||||
case 'aes256-ctr':
|
||||
$encryptKeyLength = 32;
|
||||
break;
|
||||
case 'aes256-ctr':
|
||||
$encryptKeyLength = !$this->adjust_key_fix ? 32 : 16;
|
||||
break;
|
||||
case 'aes192-cbc':
|
||||
$encryptKeyLength = 24;
|
||||
break;
|
||||
case 'aes192-ctr':
|
||||
$encryptKeyLength = !$this->adjust_key_fix ? 24 : 16;
|
||||
$encryptKeyLength = 24;
|
||||
break;
|
||||
case 'aes128-cbc':
|
||||
case 'aes128-ctr':
|
||||
@ -944,7 +917,7 @@ class Net_SSH2 {
|
||||
$encryptKeyLength = 16;
|
||||
break;
|
||||
case 'arcfour256':
|
||||
$encryptKeyLength = !$this->adjust_key_fix ? 32 : 16;
|
||||
$encryptKeyLength = 32;
|
||||
break;
|
||||
case 'none';
|
||||
$encryptKeyLength = 0;
|
||||
|
Loading…
x
Reference in New Issue
Block a user