mirror of
https://github.com/phpseclib/phpseclib.git
synced 2024-09-26 14:19:02 +00:00
- removed setMCrypt from the Crypt_* objects (you can achieve the same effect by doing ini_set('mcrypt.algorithms_dir', $path))
- added support for CTR mode to the various Crypt_* objects git-svn-id: http://phpseclib.svn.sourceforge.net/svnroot/phpseclib/trunk@83 21d32557-59b3-4da0-833f-c5933fad653e
This commit is contained in:
parent
ea4fd863d4
commit
d77c85218d
@ -56,7 +56,7 @@
|
|||||||
* @author Jim Wigginton <terrafrost@php.net>
|
* @author Jim Wigginton <terrafrost@php.net>
|
||||||
* @copyright MMVIII Jim Wigginton
|
* @copyright MMVIII Jim Wigginton
|
||||||
* @license http://www.gnu.org/licenses/lgpl.txt
|
* @license http://www.gnu.org/licenses/lgpl.txt
|
||||||
* @version $Id: AES.php,v 1.6 2010-01-04 07:59:01 terrafrost Exp $
|
* @version $Id: AES.php,v 1.7 2010-02-09 06:10:25 terrafrost Exp $
|
||||||
* @link http://phpseclib.sourceforge.net
|
* @link http://phpseclib.sourceforge.net
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -70,6 +70,14 @@ require_once 'Rijndael.php';
|
|||||||
* @see Crypt_AES::encrypt()
|
* @see Crypt_AES::encrypt()
|
||||||
* @see Crypt_AES::decrypt()
|
* @see Crypt_AES::decrypt()
|
||||||
*/
|
*/
|
||||||
|
/**
|
||||||
|
* Encrypt / decrypt using the Counter mode.
|
||||||
|
*
|
||||||
|
* Set to -1 since that's what Crypt/Random.php uses to index the CTR mode.
|
||||||
|
*
|
||||||
|
* @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Counter_.28CTR.29
|
||||||
|
*/
|
||||||
|
define('CRYPT_AES_MODE_CTR', -1);
|
||||||
/**
|
/**
|
||||||
* Encrypt / decrypt using the Electronic Code Book mode.
|
* Encrypt / decrypt using the Electronic Code Book mode.
|
||||||
*
|
*
|
||||||
@ -108,13 +116,28 @@ define('CRYPT_AES_MODE_MCRYPT', 2);
|
|||||||
*/
|
*/
|
||||||
class Crypt_AES extends Crypt_Rijndael {
|
class Crypt_AES extends Crypt_Rijndael {
|
||||||
/**
|
/**
|
||||||
* MCrypt parameters
|
* mcrypt resource for encryption
|
||||||
*
|
*
|
||||||
* @see Crypt_AES::setMCrypt()
|
* The mcrypt resource can be recreated every time something needs to be created or it can be created just once.
|
||||||
* @var Array
|
* Since mcrypt operates in continuous mode, by default, it'll need to be recreated when in non-continuous mode.
|
||||||
|
*
|
||||||
|
* @see Crypt_AES::encrypt()
|
||||||
|
* @var String
|
||||||
* @access private
|
* @access private
|
||||||
*/
|
*/
|
||||||
var $mcrypt = array('', '');
|
var $enmcrypt;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* mcrypt resource for decryption
|
||||||
|
*
|
||||||
|
* 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()
|
||||||
|
* @var String
|
||||||
|
* @access private
|
||||||
|
*/
|
||||||
|
var $demcrypt;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Default Constructor.
|
* Default Constructor.
|
||||||
@ -147,6 +170,13 @@ class Crypt_AES extends Crypt_Rijndael {
|
|||||||
case CRYPT_AES_MODE_ECB:
|
case CRYPT_AES_MODE_ECB:
|
||||||
$this->mode = MCRYPT_MODE_ECB;
|
$this->mode = MCRYPT_MODE_ECB;
|
||||||
break;
|
break;
|
||||||
|
case CRYPT_AES_MODE_CTR:
|
||||||
|
// ctr doesn't have a constant associated with it even though it appears to be fairly widely
|
||||||
|
// supported. in lieu of knowing just how widely supported it is, i've, for now, opted not to
|
||||||
|
// include a compatibility layer. the layer has been implemented but, for now, is commented out.
|
||||||
|
$this->mode = 'ctr';
|
||||||
|
//$this->mode = in_array('ctr', mcrypt_list_modes()) ? 'ctr' : CRYPT_AES_MODE_CTR;
|
||||||
|
break;
|
||||||
case CRYPT_AES_MODE_CBC:
|
case CRYPT_AES_MODE_CBC:
|
||||||
default:
|
default:
|
||||||
$this->mode = MCRYPT_MODE_CBC;
|
$this->mode = MCRYPT_MODE_CBC;
|
||||||
@ -158,6 +188,9 @@ class Crypt_AES extends Crypt_Rijndael {
|
|||||||
case CRYPT_AES_MODE_ECB:
|
case CRYPT_AES_MODE_ECB:
|
||||||
$this->mode = CRYPT_RIJNDAEL_MODE_ECB;
|
$this->mode = CRYPT_RIJNDAEL_MODE_ECB;
|
||||||
break;
|
break;
|
||||||
|
case CRYPT_AES_MODE_CTR:
|
||||||
|
$this->mode = CRYPT_RIJNDAEL_MODE_CTR;
|
||||||
|
break;
|
||||||
case CRYPT_AES_MODE_CBC:
|
case CRYPT_AES_MODE_CBC:
|
||||||
default:
|
default:
|
||||||
$this->mode = CRYPT_RIJNDAEL_MODE_CBC;
|
$this->mode = CRYPT_RIJNDAEL_MODE_CBC;
|
||||||
@ -203,18 +236,26 @@ class Crypt_AES extends Crypt_Rijndael {
|
|||||||
{
|
{
|
||||||
if ( CRYPT_AES_MODE == CRYPT_AES_MODE_MCRYPT ) {
|
if ( CRYPT_AES_MODE == CRYPT_AES_MODE_MCRYPT ) {
|
||||||
$this->_mcryptSetup();
|
$this->_mcryptSetup();
|
||||||
$plaintext = $this->_pad($plaintext);
|
/*
|
||||||
|
if ($this->mode == CRYPT_AES_MODE_CTR) {
|
||||||
|
$iv = $this->encryptIV;
|
||||||
|
$xor = mcrypt_generic($this->enmcrypt, $this->_generate_xor(strlen($plaintext), $iv));
|
||||||
|
$ciphertext = $plaintext ^ $xor;
|
||||||
|
if ($this->continuousBuffer) {
|
||||||
|
$this->encryptIV = $iv;
|
||||||
|
}
|
||||||
|
return $ciphertext;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
$td = mcrypt_module_open(MCRYPT_RIJNDAEL_128, $this->mcrypt[0], $this->mode, $this->mcrypt[1]);
|
if ($this->mode != 'ctr') {
|
||||||
mcrypt_generic_init($td, $this->key, $this->encryptIV);
|
$plaintext = $this->_pad($plaintext);
|
||||||
|
}
|
||||||
|
|
||||||
$ciphertext = mcrypt_generic($td, $plaintext);
|
$ciphertext = mcrypt_generic($this->enmcrypt, $plaintext);
|
||||||
|
|
||||||
mcrypt_generic_deinit($td);
|
if (!$this->continuousBuffer) {
|
||||||
mcrypt_module_close($td);
|
mcrypt_generic_init($this->enmcrypt, $this->key, $this->iv);
|
||||||
|
|
||||||
if ($this->continuousBuffer) {
|
|
||||||
$this->encryptIV = substr($ciphertext, -16);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return $ciphertext;
|
return $ciphertext;
|
||||||
@ -234,46 +275,38 @@ class Crypt_AES extends Crypt_Rijndael {
|
|||||||
*/
|
*/
|
||||||
function decrypt($ciphertext)
|
function decrypt($ciphertext)
|
||||||
{
|
{
|
||||||
// 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));
|
|
||||||
|
|
||||||
if ( CRYPT_AES_MODE == CRYPT_AES_MODE_MCRYPT ) {
|
if ( CRYPT_AES_MODE == CRYPT_AES_MODE_MCRYPT ) {
|
||||||
$this->_mcryptSetup();
|
$this->_mcryptSetup();
|
||||||
|
/*
|
||||||
|
if ($this->mode == CRYPT_AES_MODE_CTR) {
|
||||||
|
$iv = $this->decryptIV;
|
||||||
|
$xor = mcrypt_generic($this->enmcrypt, $this->_generate_xor(strlen($ciphertext), $iv));
|
||||||
|
$plaintext = $ciphertext ^ $xor;
|
||||||
|
if ($this->continuousBuffer) {
|
||||||
|
$this->decryptIV = $iv;
|
||||||
|
}
|
||||||
|
return $plaintext;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
$td = mcrypt_module_open(MCRYPT_RIJNDAEL_128, $this->mcrypt[0], $this->mode, $this->mcrypt[1]);
|
if ($this->mode != 'ctr') {
|
||||||
mcrypt_generic_init($td, $this->key, $this->decryptIV);
|
// 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 = mdecrypt_generic($td, $ciphertext);
|
$ciphertext = str_pad($ciphertext, (strlen($ciphertext) + 15) & 0xFFFFFFF0, chr(0));
|
||||||
|
|
||||||
mcrypt_generic_deinit($td);
|
|
||||||
mcrypt_module_close($td);
|
|
||||||
|
|
||||||
if ($this->continuousBuffer) {
|
|
||||||
$this->decryptIV = substr($ciphertext, -16);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this->_unpad($plaintext);
|
$plaintext = mdecrypt_generic($this->demcrypt, $ciphertext);
|
||||||
|
|
||||||
|
if (!$this->continuousBuffer) {
|
||||||
|
mcrypt_generic_init($this->demcrypt, $this->key, $this->iv);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->mode != 'ctr' ? $this->_unpad($plaintext) : $plaintext;
|
||||||
}
|
}
|
||||||
|
|
||||||
return parent::decrypt($ciphertext);
|
return parent::decrypt($ciphertext);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets MCrypt parameters. (optional)
|
|
||||||
*
|
|
||||||
* If MCrypt is being used, empty strings will be used, unless otherwise specified.
|
|
||||||
*
|
|
||||||
* @link http://php.net/function.mcrypt-module-open#function.mcrypt-module-open
|
|
||||||
* @access public
|
|
||||||
* @param optional Integer $algorithm_directory
|
|
||||||
* @param optional Integer $mode_directory
|
|
||||||
*/
|
|
||||||
function setMCrypt($algorithm_directory = '', $mode_directory = '')
|
|
||||||
{
|
|
||||||
$this->mcrypt = array($algorithm_directory, $mode_directory);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Setup mcrypt
|
* Setup mcrypt
|
||||||
*
|
*
|
||||||
@ -315,6 +348,17 @@ class Crypt_AES extends Crypt_Rijndael {
|
|||||||
$this->key = substr($this->key, 0, $this->key_size);
|
$this->key = substr($this->key, 0, $this->key_size);
|
||||||
$this->encryptIV = $this->decryptIV = $this->iv = str_pad(substr($this->iv, 0, 16), 16, chr(0));
|
$this->encryptIV = $this->decryptIV = $this->iv = str_pad(substr($this->iv, 0, 16), 16, chr(0));
|
||||||
|
|
||||||
|
if (!isset($this->enmcrypt)) {
|
||||||
|
$mode = $this->mode;
|
||||||
|
//$mode = $this->mode == CRYPT_AES_MODE_CTR ? MCRYPT_MODE_ECB : $this->mode;
|
||||||
|
|
||||||
|
$this->demcrypt = mcrypt_module_open(MCRYPT_RIJNDAEL_128, '', $mode, '');
|
||||||
|
$this->enmcrypt = mcrypt_module_open(MCRYPT_RIJNDAEL_128, '', $mode, '');
|
||||||
|
} // else should mcrypt_generic_deinit be called?
|
||||||
|
|
||||||
|
mcrypt_generic_init($this->demcrypt, $this->key, $this->iv);
|
||||||
|
mcrypt_generic_init($this->enmcrypt, $this->key, $this->iv);
|
||||||
|
|
||||||
$this->changed = false;
|
$this->changed = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -53,7 +53,7 @@
|
|||||||
* @author Jim Wigginton <terrafrost@php.net>
|
* @author Jim Wigginton <terrafrost@php.net>
|
||||||
* @copyright MMVII Jim Wigginton
|
* @copyright MMVII Jim Wigginton
|
||||||
* @license http://www.gnu.org/licenses/lgpl.txt
|
* @license http://www.gnu.org/licenses/lgpl.txt
|
||||||
* @version $Id: DES.php,v 1.11 2010-01-04 07:59:01 terrafrost Exp $
|
* @version $Id: DES.php,v 1.12 2010-02-09 06:10:26 terrafrost Exp $
|
||||||
* @link http://phpseclib.sourceforge.net
|
* @link http://phpseclib.sourceforge.net
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -77,6 +77,14 @@ define('CRYPT_DES_DECRYPT', 1);
|
|||||||
* @see Crypt_DES::encrypt()
|
* @see Crypt_DES::encrypt()
|
||||||
* @see Crypt_DES::decrypt()
|
* @see Crypt_DES::decrypt()
|
||||||
*/
|
*/
|
||||||
|
/**
|
||||||
|
* Encrypt / decrypt using the Counter mode.
|
||||||
|
*
|
||||||
|
* Set to -1 since that's what Crypt/Random.php uses to index the CTR mode.
|
||||||
|
*
|
||||||
|
* @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Counter_.28CTR.29
|
||||||
|
*/
|
||||||
|
define('CRYPT_DES_MODE_CTR', -1);
|
||||||
/**
|
/**
|
||||||
* Encrypt / decrypt using the Electronic Code Book mode.
|
* Encrypt / decrypt using the Electronic Code Book mode.
|
||||||
*
|
*
|
||||||
@ -178,13 +186,38 @@ class Crypt_DES {
|
|||||||
var $decryptIV = "\0\0\0\0\0\0\0\0";
|
var $decryptIV = "\0\0\0\0\0\0\0\0";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* MCrypt parameters
|
* mcrypt resource for encryption
|
||||||
*
|
*
|
||||||
* @see Crypt_DES::setMCrypt()
|
* The mcrypt resource can be recreated every time something needs to be created or it can be created just once.
|
||||||
* @var Array
|
* Since mcrypt operates in continuous mode, by default, it'll need to be recreated when in non-continuous mode.
|
||||||
|
*
|
||||||
|
* @see Crypt_AES::encrypt()
|
||||||
|
* @var String
|
||||||
* @access private
|
* @access private
|
||||||
*/
|
*/
|
||||||
var $mcrypt = array('', '');
|
var $enmcrypt;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* mcrypt resource for decryption
|
||||||
|
*
|
||||||
|
* 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()
|
||||||
|
* @var String
|
||||||
|
* @access private
|
||||||
|
*/
|
||||||
|
var $demcrypt;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Does the (en|de)mcrypt resource need to be (re)initialized?
|
||||||
|
*
|
||||||
|
* @see setKey()
|
||||||
|
* @see setIV()
|
||||||
|
* @var Boolean
|
||||||
|
* @access private
|
||||||
|
*/
|
||||||
|
var $changed = true;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Default Constructor.
|
* Default Constructor.
|
||||||
@ -217,6 +250,10 @@ class Crypt_DES {
|
|||||||
case CRYPT_DES_MODE_ECB:
|
case CRYPT_DES_MODE_ECB:
|
||||||
$this->mode = MCRYPT_MODE_ECB;
|
$this->mode = MCRYPT_MODE_ECB;
|
||||||
break;
|
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_CBC:
|
case CRYPT_DES_MODE_CBC:
|
||||||
default:
|
default:
|
||||||
$this->mode = MCRYPT_MODE_CBC;
|
$this->mode = MCRYPT_MODE_CBC;
|
||||||
@ -226,6 +263,7 @@ class Crypt_DES {
|
|||||||
default:
|
default:
|
||||||
switch ($mode) {
|
switch ($mode) {
|
||||||
case CRYPT_DES_MODE_ECB:
|
case CRYPT_DES_MODE_ECB:
|
||||||
|
case CRYPT_DES_MODE_CTR:
|
||||||
case CRYPT_DES_MODE_CBC:
|
case CRYPT_DES_MODE_CBC:
|
||||||
$this->mode = $mode;
|
$this->mode = $mode;
|
||||||
break;
|
break;
|
||||||
@ -252,6 +290,7 @@ class Crypt_DES {
|
|||||||
function setKey($key)
|
function setKey($key)
|
||||||
{
|
{
|
||||||
$this->keys = ( CRYPT_DES_MODE == CRYPT_DES_MODE_MCRYPT ) ? substr($key, 0, 8) : $this->_prepareKey($key);
|
$this->keys = ( CRYPT_DES_MODE == CRYPT_DES_MODE_MCRYPT ) ? substr($key, 0, 8) : $this->_prepareKey($key);
|
||||||
|
$this->changed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -265,22 +304,46 @@ class Crypt_DES {
|
|||||||
*/
|
*/
|
||||||
function setIV($iv)
|
function setIV($iv)
|
||||||
{
|
{
|
||||||
$this->encryptIV = $this->decryptIV = $this->iv = str_pad(substr($iv, 0, 8), 8, chr(0));;
|
$this->encryptIV = $this->decryptIV = $this->iv = str_pad(substr($iv, 0, 8), 8, chr(0));
|
||||||
|
$this->changed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets MCrypt parameters. (optional)
|
* Generate CTR XOR encryption key
|
||||||
*
|
*
|
||||||
* If MCrypt is being used, empty strings will be used, unless otherwise specified.
|
* Encrypt the output of this and XOR it against the ciphertext / plaintext to get the
|
||||||
|
* plaintext / ciphertext in CTR mode.
|
||||||
*
|
*
|
||||||
* @link http://php.net/function.mcrypt-module-open#function.mcrypt-module-open
|
* @see Crypt_DES::decrypt()
|
||||||
|
* @see Crypt_DES::encrypt()
|
||||||
* @access public
|
* @access public
|
||||||
* @param optional Integer $algorithm_directory
|
* @param Integer $length
|
||||||
* @param optional Integer $mode_directory
|
* @param String $iv
|
||||||
*/
|
*/
|
||||||
function setMCrypt($algorithm_directory = '', $mode_directory = '')
|
function _generate_xor($length, &$iv)
|
||||||
{
|
{
|
||||||
$this->mcrypt = array($algorithm_directory, $mode_directory);
|
$xor = '';
|
||||||
|
$num_blocks = ($length + 7) >> 3;
|
||||||
|
for ($i = 0; $i < $num_blocks; $i++) {
|
||||||
|
$xor.= $iv;
|
||||||
|
for ($j = 4; $j <= 8; $j+=4) {
|
||||||
|
$temp = substr($iv, -$j, 4);
|
||||||
|
switch ($temp) {
|
||||||
|
case "\xFF\xFF\xFF\xFF":
|
||||||
|
$iv = substr_replace($iv, "\x00\x00\x00\x00", -$j, 4);
|
||||||
|
break;
|
||||||
|
case "\x7F\xFF\xFF\xFF":
|
||||||
|
$iv = substr_replace($iv, "\x80\x00\x00\x00", -$j, 4);
|
||||||
|
break 2;
|
||||||
|
default:
|
||||||
|
extract(unpack('Ncount', $temp));
|
||||||
|
$iv = substr_replace($iv, pack('N', $count + 1), -$j, 4);
|
||||||
|
break 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $xor;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -302,19 +365,23 @@ class Crypt_DES {
|
|||||||
*/
|
*/
|
||||||
function encrypt($plaintext)
|
function encrypt($plaintext)
|
||||||
{
|
{
|
||||||
$plaintext = $this->_pad($plaintext);
|
if ($this->mode != CRYPT_DES_MODE_CTR && $this->mode != 'ctr') {
|
||||||
|
$plaintext = $this->_pad($plaintext);
|
||||||
|
}
|
||||||
|
|
||||||
if ( CRYPT_DES_MODE == CRYPT_DES_MODE_MCRYPT ) {
|
if ( CRYPT_DES_MODE == CRYPT_DES_MODE_MCRYPT ) {
|
||||||
$td = mcrypt_module_open(MCRYPT_DES, $this->mcrypt[0], $this->mode, $this->mcrypt[1]);
|
if ($this->changed) {
|
||||||
mcrypt_generic_init($td, $this->keys, $this->encryptIV);
|
if (!isset($this->enmcrypt)) {
|
||||||
|
$this->enmcrypt = mcrypt_module_open(MCRYPT_DES, '', $this->mode, '');
|
||||||
|
}
|
||||||
|
mcrypt_generic_init($this->enmcrypt, $this->keys, $this->encryptIV);
|
||||||
|
$this->changed = false;
|
||||||
|
}
|
||||||
|
|
||||||
$ciphertext = mcrypt_generic($td, $plaintext);
|
$ciphertext = mcrypt_generic($this->enmcrypt, $plaintext);
|
||||||
|
|
||||||
mcrypt_generic_deinit($td);
|
if (!$this->continuousBuffer) {
|
||||||
mcrypt_module_close($td);
|
mcrypt_generic_init($this->enmcrypt, $this->keys, $this->encryptIV);
|
||||||
|
|
||||||
if ($this->continuousBuffer) {
|
|
||||||
$this->encryptIV = substr($ciphertext, -8);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return $ciphertext;
|
return $ciphertext;
|
||||||
@ -342,6 +409,17 @@ class Crypt_DES {
|
|||||||
if ($this->continuousBuffer) {
|
if ($this->continuousBuffer) {
|
||||||
$this->encryptIV = $xor;
|
$this->encryptIV = $xor;
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
|
case CRYPT_DES_MODE_CTR:
|
||||||
|
$xor = $this->encryptIV;
|
||||||
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return $ciphertext;
|
return $ciphertext;
|
||||||
@ -358,24 +436,28 @@ class Crypt_DES {
|
|||||||
*/
|
*/
|
||||||
function decrypt($ciphertext)
|
function decrypt($ciphertext)
|
||||||
{
|
{
|
||||||
// we pad with chr(0) since that's what mcrypt_generic does. to quote from http://php.net/function.mcrypt-generic :
|
if ($this->mode != CRYPT_DES_MODE_CTR && $this->mode != 'ctr') {
|
||||||
// "The data is padded with "\0" to make sure the length of the data is n * blocksize."
|
// we pad with chr(0) since that's what mcrypt_generic does. to quote from http://php.net/function.mcrypt-generic :
|
||||||
$ciphertext = str_pad($ciphertext, (strlen($ciphertext) + 7) & 0xFFFFFFF8, chr(0));
|
// "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 ( CRYPT_DES_MODE == CRYPT_DES_MODE_MCRYPT ) {
|
||||||
$td = mcrypt_module_open(MCRYPT_DES, $this->mcrypt[0], $this->mode, $this->mcrypt[1]);
|
if ($this->changed) {
|
||||||
mcrypt_generic_init($td, $this->keys, $this->decryptIV);
|
if (!isset($this->demcrypt)) {
|
||||||
|
$this->demcrypt = mcrypt_module_open(MCRYPT_DES, '', $this->mode, '');
|
||||||
$plaintext = mdecrypt_generic($td, $ciphertext);
|
}
|
||||||
|
mcrypt_generic_init($this->demcrypt, $this->keys, $this->decryptIV);
|
||||||
mcrypt_generic_deinit($td);
|
$this->changed = false;
|
||||||
mcrypt_module_close($td);
|
|
||||||
|
|
||||||
if ($this->continuousBuffer) {
|
|
||||||
$this->decryptIV = substr($ciphertext, -8);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this->_unpad($plaintext);
|
$plaintext = mdecrypt_generic($this->demcrypt, $ciphertext);
|
||||||
|
|
||||||
|
if (!$this->continuousBuffer) {
|
||||||
|
mcrypt_generic_init($this->demcrypt, $this->keys, $this->decryptIV);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->mode != 'ctr' ? $this->_unpad($plaintext) : $plaintext;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!is_array($this->keys)) {
|
if (!is_array($this->keys)) {
|
||||||
@ -399,9 +481,20 @@ class Crypt_DES {
|
|||||||
if ($this->continuousBuffer) {
|
if ($this->continuousBuffer) {
|
||||||
$this->decryptIV = $xor;
|
$this->decryptIV = $xor;
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
|
case CRYPT_DES_MODE_CTR:
|
||||||
|
$xor = $this->decryptIV;
|
||||||
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this->_unpad($plaintext);
|
return $this->mode != CRYPT_DES_MODE_CTR ? $this->_unpad($plaintext) : $plaintext;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -64,7 +64,7 @@
|
|||||||
* @author Jim Wigginton <terrafrost@php.net>
|
* @author Jim Wigginton <terrafrost@php.net>
|
||||||
* @copyright MMVIII Jim Wigginton
|
* @copyright MMVIII Jim Wigginton
|
||||||
* @license http://www.gnu.org/licenses/lgpl.txt
|
* @license http://www.gnu.org/licenses/lgpl.txt
|
||||||
* @version $Id: Rijndael.php,v 1.11 2010-01-23 17:36:49 terrafrost Exp $
|
* @version $Id: Rijndael.php,v 1.12 2010-02-09 06:10:26 terrafrost Exp $
|
||||||
* @link http://phpseclib.sourceforge.net
|
* @link http://phpseclib.sourceforge.net
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -73,6 +73,14 @@
|
|||||||
* @see Crypt_Rijndael::encrypt()
|
* @see Crypt_Rijndael::encrypt()
|
||||||
* @see Crypt_Rijndael::decrypt()
|
* @see Crypt_Rijndael::decrypt()
|
||||||
*/
|
*/
|
||||||
|
/**
|
||||||
|
* Encrypt / decrypt using the Counter mode.
|
||||||
|
*
|
||||||
|
* Set to -1 since that's what Crypt/Random.php uses to index the CTR mode.
|
||||||
|
*
|
||||||
|
* @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Counter_.28CTR.29
|
||||||
|
*/
|
||||||
|
define('CRYPT_RIJNDAEL_MODE_CTR', -1);
|
||||||
/**
|
/**
|
||||||
* Encrypt / decrypt using the Electronic Code Book mode.
|
* Encrypt / decrypt using the Electronic Code Book mode.
|
||||||
*
|
*
|
||||||
@ -363,6 +371,7 @@ class Crypt_Rijndael {
|
|||||||
switch ($mode) {
|
switch ($mode) {
|
||||||
case CRYPT_RIJNDAEL_MODE_ECB:
|
case CRYPT_RIJNDAEL_MODE_ECB:
|
||||||
case CRYPT_RIJNDAEL_MODE_CBC:
|
case CRYPT_RIJNDAEL_MODE_CBC:
|
||||||
|
case CRYPT_RIJNDAEL_MODE_CTR:
|
||||||
$this->mode = $mode;
|
$this->mode = $mode;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@ -542,6 +551,45 @@ class Crypt_Rijndael {
|
|||||||
$this->changed = true;
|
$this->changed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generate CTR XOR encryption key
|
||||||
|
*
|
||||||
|
* Encrypt the output of this and XOR it against the ciphertext / plaintext to get the
|
||||||
|
* plaintext / ciphertext in CTR mode.
|
||||||
|
*
|
||||||
|
* @see Crypt_Rijndael::decrypt()
|
||||||
|
* @see Crypt_Rijndael::encrypt()
|
||||||
|
* @access public
|
||||||
|
* @param Integer $length
|
||||||
|
* @param String $iv
|
||||||
|
*/
|
||||||
|
function _generate_xor($length, &$iv)
|
||||||
|
{
|
||||||
|
$xor = '';
|
||||||
|
$block_size = $this->block_size;
|
||||||
|
$num_blocks = floor(($length + ($block_size - 1)) / $block_size);
|
||||||
|
for ($i = 0; $i < $num_blocks; $i++) {
|
||||||
|
$xor.= $iv;
|
||||||
|
for ($j = 4; $j <= $block_size; $j+=4) {
|
||||||
|
$temp = substr($iv, -$j, 4);
|
||||||
|
switch ($temp) {
|
||||||
|
case "\xFF\xFF\xFF\xFF":
|
||||||
|
$iv = substr_replace($iv, "\x00\x00\x00\x00", -$j, 4);
|
||||||
|
break;
|
||||||
|
case "\x7F\xFF\xFF\xFF":
|
||||||
|
$iv = substr_replace($iv, "\x80\x00\x00\x00", -$j, 4);
|
||||||
|
break 2;
|
||||||
|
default:
|
||||||
|
extract(unpack('Ncount', $temp));
|
||||||
|
$iv = substr_replace($iv, pack('N', $count + 1), -$j, 4);
|
||||||
|
break 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $xor;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Encrypts a message.
|
* Encrypts a message.
|
||||||
*
|
*
|
||||||
@ -563,19 +611,22 @@ class Crypt_Rijndael {
|
|||||||
function encrypt($plaintext)
|
function encrypt($plaintext)
|
||||||
{
|
{
|
||||||
$this->_setup();
|
$this->_setup();
|
||||||
$plaintext = $this->_pad($plaintext);
|
if ($this->mode != CRYPT_RIJNDAEL_MODE_CTR) {
|
||||||
|
$plaintext = $this->_pad($plaintext);
|
||||||
|
}
|
||||||
|
|
||||||
|
$block_size = $this->block_size;
|
||||||
$ciphertext = '';
|
$ciphertext = '';
|
||||||
switch ($this->mode) {
|
switch ($this->mode) {
|
||||||
case CRYPT_RIJNDAEL_MODE_ECB:
|
case CRYPT_RIJNDAEL_MODE_ECB:
|
||||||
for ($i = 0; $i < strlen($plaintext); $i+=$this->block_size) {
|
for ($i = 0; $i < strlen($plaintext); $i+=$block_size) {
|
||||||
$ciphertext.= $this->_encryptBlock(substr($plaintext, $i, $this->block_size));
|
$ciphertext.= $this->_encryptBlock(substr($plaintext, $i, $block_size));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case CRYPT_RIJNDAEL_MODE_CBC:
|
case CRYPT_RIJNDAEL_MODE_CBC:
|
||||||
$xor = $this->encryptIV;
|
$xor = $this->encryptIV;
|
||||||
for ($i = 0; $i < strlen($plaintext); $i+=$this->block_size) {
|
for ($i = 0; $i < strlen($plaintext); $i+=$block_size) {
|
||||||
$block = substr($plaintext, $i, $this->block_size);
|
$block = substr($plaintext, $i, $block_size);
|
||||||
$block = $this->_encryptBlock($block ^ $xor);
|
$block = $this->_encryptBlock($block ^ $xor);
|
||||||
$xor = $block;
|
$xor = $block;
|
||||||
$ciphertext.= $block;
|
$ciphertext.= $block;
|
||||||
@ -583,6 +634,17 @@ class Crypt_Rijndael {
|
|||||||
if ($this->continuousBuffer) {
|
if ($this->continuousBuffer) {
|
||||||
$this->encryptIV = $xor;
|
$this->encryptIV = $xor;
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
|
case CRYPT_RIJNDAEL_MODE_CTR:
|
||||||
|
$xor = $this->encryptIV;
|
||||||
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return $ciphertext;
|
return $ciphertext;
|
||||||
@ -601,30 +663,45 @@ class Crypt_Rijndael {
|
|||||||
function decrypt($ciphertext)
|
function decrypt($ciphertext)
|
||||||
{
|
{
|
||||||
$this->_setup();
|
$this->_setup();
|
||||||
// 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));
|
|
||||||
|
|
||||||
|
if ($this->mode != CRYPT_RIJNDAEL_MODE_CTR) {
|
||||||
|
// 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;
|
||||||
$plaintext = '';
|
$plaintext = '';
|
||||||
switch ($this->mode) {
|
switch ($this->mode) {
|
||||||
case CRYPT_RIJNDAEL_MODE_ECB:
|
case CRYPT_RIJNDAEL_MODE_ECB:
|
||||||
for ($i = 0; $i < strlen($ciphertext); $i+=$this->block_size) {
|
for ($i = 0; $i < strlen($ciphertext); $i+=$block_size) {
|
||||||
$plaintext.= $this->_decryptBlock(substr($ciphertext, $i, $this->block_size));
|
$plaintext.= $this->_decryptBlock(substr($ciphertext, $i, $block_size));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case CRYPT_RIJNDAEL_MODE_CBC:
|
case CRYPT_RIJNDAEL_MODE_CBC:
|
||||||
$xor = $this->decryptIV;
|
$xor = $this->decryptIV;
|
||||||
for ($i = 0; $i < strlen($ciphertext); $i+=$this->block_size) {
|
for ($i = 0; $i < strlen($ciphertext); $i+=$block_size) {
|
||||||
$block = substr($ciphertext, $i, $this->block_size);
|
$block = substr($ciphertext, $i, $block_size);
|
||||||
$plaintext.= $this->_decryptBlock($block) ^ $xor;
|
$plaintext.= $this->_decryptBlock($block) ^ $xor;
|
||||||
$xor = $block;
|
$xor = $block;
|
||||||
}
|
}
|
||||||
if ($this->continuousBuffer) {
|
if ($this->continuousBuffer) {
|
||||||
$this->decryptIV = $xor;
|
$this->decryptIV = $xor;
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
|
case CRYPT_RIJNDAEL_MODE_CTR:
|
||||||
|
$xor = $this->decryptIV;
|
||||||
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this->_unpad($plaintext);
|
return $this->mode != CRYPT_RIJNDAEL_MODE_CTR ? $this->_unpad($plaintext) : $plaintext;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -47,7 +47,7 @@
|
|||||||
* @author Jim Wigginton <terrafrost@php.net>
|
* @author Jim Wigginton <terrafrost@php.net>
|
||||||
* @copyright MMVII Jim Wigginton
|
* @copyright MMVII Jim Wigginton
|
||||||
* @license http://www.gnu.org/licenses/lgpl.txt
|
* @license http://www.gnu.org/licenses/lgpl.txt
|
||||||
* @version $Id: TripleDES.php,v 1.11 2010-01-04 07:59:01 terrafrost Exp $
|
* @version $Id: TripleDES.php,v 1.12 2010-02-09 06:10:26 terrafrost Exp $
|
||||||
* @link http://phpseclib.sourceforge.net
|
* @link http://phpseclib.sourceforge.net
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -142,15 +142,6 @@ class Crypt_TripleDES {
|
|||||||
*/
|
*/
|
||||||
var $decryptIV = "\0\0\0\0\0\0\0\0";
|
var $decryptIV = "\0\0\0\0\0\0\0\0";
|
||||||
|
|
||||||
/**
|
|
||||||
* MCrypt parameters
|
|
||||||
*
|
|
||||||
* @see Crypt_TripleDES::setMCrypt()
|
|
||||||
* @var Array
|
|
||||||
* @access private
|
|
||||||
*/
|
|
||||||
var $mcrypt = array('', '');
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The Crypt_DES objects
|
* The Crypt_DES objects
|
||||||
*
|
*
|
||||||
@ -159,6 +150,40 @@ class Crypt_TripleDES {
|
|||||||
*/
|
*/
|
||||||
var $des;
|
var $des;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* mcrypt resource for encryption
|
||||||
|
*
|
||||||
|
* 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()
|
||||||
|
* @var String
|
||||||
|
* @access private
|
||||||
|
*/
|
||||||
|
var $enmcrypt;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* mcrypt resource for decryption
|
||||||
|
*
|
||||||
|
* 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()
|
||||||
|
* @var String
|
||||||
|
* @access private
|
||||||
|
*/
|
||||||
|
var $demcrypt;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Does the (en|de)mcrypt resource need to be (re)initialized?
|
||||||
|
*
|
||||||
|
* @see setKey()
|
||||||
|
* @see setIV()
|
||||||
|
* @var Boolean
|
||||||
|
* @access private
|
||||||
|
*/
|
||||||
|
var $changed = true;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Default Constructor.
|
* Default Constructor.
|
||||||
*
|
*
|
||||||
@ -204,7 +229,11 @@ class Crypt_TripleDES {
|
|||||||
case CRYPT_DES_MODE_MCRYPT:
|
case CRYPT_DES_MODE_MCRYPT:
|
||||||
switch ($mode) {
|
switch ($mode) {
|
||||||
case CRYPT_DES_MODE_ECB:
|
case CRYPT_DES_MODE_ECB:
|
||||||
$this->mode = MCRYPT_MODE_ECB; break;
|
$this->mode = MCRYPT_MODE_ECB;
|
||||||
|
break;
|
||||||
|
case CRYPT_DES_MODE_CTR:
|
||||||
|
$this->mode = 'ctr';
|
||||||
|
break;
|
||||||
case CRYPT_DES_MODE_CBC:
|
case CRYPT_DES_MODE_CBC:
|
||||||
default:
|
default:
|
||||||
$this->mode = MCRYPT_MODE_CBC;
|
$this->mode = MCRYPT_MODE_CBC;
|
||||||
@ -225,6 +254,7 @@ class Crypt_TripleDES {
|
|||||||
|
|
||||||
switch ($mode) {
|
switch ($mode) {
|
||||||
case CRYPT_DES_MODE_ECB:
|
case CRYPT_DES_MODE_ECB:
|
||||||
|
case CRYPT_DES_MODE_CTR:
|
||||||
case CRYPT_DES_MODE_CBC:
|
case CRYPT_DES_MODE_CBC:
|
||||||
$this->mode = $mode;
|
$this->mode = $mode;
|
||||||
break;
|
break;
|
||||||
@ -264,6 +294,7 @@ class Crypt_TripleDES {
|
|||||||
$this->des[1]->setKey(substr($key, 8, 8));
|
$this->des[1]->setKey(substr($key, 8, 8));
|
||||||
$this->des[2]->setKey(substr($key, 16, 8));
|
$this->des[2]->setKey(substr($key, 16, 8));
|
||||||
}
|
}
|
||||||
|
$this->changed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -283,26 +314,45 @@ class Crypt_TripleDES {
|
|||||||
$this->des[1]->setIV($iv);
|
$this->des[1]->setIV($iv);
|
||||||
$this->des[2]->setIV($iv);
|
$this->des[2]->setIV($iv);
|
||||||
}
|
}
|
||||||
|
$this->changed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets MCrypt parameters. (optional)
|
* Generate CTR XOR encryption key
|
||||||
*
|
*
|
||||||
* If MCrypt is being used, empty strings will be used, unless otherwise specified.
|
* Encrypt the output of this and XOR it against the ciphertext / plaintext to get the
|
||||||
|
* plaintext / ciphertext in CTR mode.
|
||||||
*
|
*
|
||||||
* @link http://php.net/function.mcrypt-module-open#function.mcrypt-module-open
|
* @see Crypt_DES::decrypt()
|
||||||
|
* @see Crypt_DES::encrypt()
|
||||||
* @access public
|
* @access public
|
||||||
* @param optional Integer $algorithm_directory
|
* @param Integer $length
|
||||||
* @param optional Integer $mode_directory
|
* @param String $iv
|
||||||
*/
|
*/
|
||||||
function setMCrypt($algorithm_directory = '', $mode_directory = '')
|
function _generate_xor($length, &$iv)
|
||||||
{
|
{
|
||||||
$this->mcrypt = array($algorithm_directory, $mode_directory);
|
$xor = '';
|
||||||
if ( $this->mode == CRYPT_DES_MODE_3CBC ) {
|
$num_blocks = ($length + 7) >> 3;
|
||||||
$this->des[0]->setMCrypt($algorithm_directory, $mode_directory);
|
for ($i = 0; $i < $num_blocks; $i++) {
|
||||||
$this->des[1]->setMCrypt($algorithm_directory, $mode_directory);
|
$xor.= $iv;
|
||||||
$this->des[2]->setMCrypt($algorithm_directory, $mode_directory);
|
for ($j = 4; $j <= 8; $j+=4) {
|
||||||
|
$temp = substr($iv, -$j, 4);
|
||||||
|
switch ($temp) {
|
||||||
|
case "\xFF\xFF\xFF\xFF":
|
||||||
|
$iv = substr_replace($iv, "\x00\x00\x00\x00", -$j, 4);
|
||||||
|
break;
|
||||||
|
case "\x7F\xFF\xFF\xFF":
|
||||||
|
$iv = substr_replace($iv, "\x80\x00\x00\x00", -$j, 4);
|
||||||
|
break 2;
|
||||||
|
default:
|
||||||
|
extract(unpack('Ncount', $temp));
|
||||||
|
$iv = substr_replace($iv, pack('N', $count + 1), -$j, 4);
|
||||||
|
break 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return $xor;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -313,7 +363,9 @@ class Crypt_TripleDES {
|
|||||||
*/
|
*/
|
||||||
function encrypt($plaintext)
|
function encrypt($plaintext)
|
||||||
{
|
{
|
||||||
$plaintext = $this->_pad($plaintext);
|
if ($this->mode != CRYPT_DES_MODE_CTR && $this->mode != 'ctr') {
|
||||||
|
$plaintext = $this->_pad($plaintext);
|
||||||
|
}
|
||||||
|
|
||||||
// if the key is smaller then 8, do what we'd normally do
|
// if the key is smaller then 8, do what we'd normally do
|
||||||
if ($this->mode == CRYPT_DES_MODE_3CBC && strlen($this->key) > 8) {
|
if ($this->mode == CRYPT_DES_MODE_3CBC && strlen($this->key) > 8) {
|
||||||
@ -323,16 +375,18 @@ class Crypt_TripleDES {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ( CRYPT_DES_MODE == CRYPT_DES_MODE_MCRYPT ) {
|
if ( CRYPT_DES_MODE == CRYPT_DES_MODE_MCRYPT ) {
|
||||||
$td = mcrypt_module_open(MCRYPT_3DES, $this->mcrypt[0], $this->mode, $this->mcrypt[1]);
|
if ($this->changed) {
|
||||||
mcrypt_generic_init($td, $this->key, $this->encryptIV);
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
$ciphertext = mcrypt_generic($td, $plaintext);
|
$ciphertext = mcrypt_generic($this->enmcrypt, $plaintext);
|
||||||
|
|
||||||
mcrypt_generic_deinit($td);
|
if (!$this->continuousBuffer) {
|
||||||
mcrypt_module_close($td);
|
mcrypt_generic_init($this->enmcrypt, $this->keys, $this->encryptIV);
|
||||||
|
|
||||||
if ($this->continuousBuffer) {
|
|
||||||
$this->encryptIV = substr($ciphertext, -8);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return $ciphertext;
|
return $ciphertext;
|
||||||
@ -374,6 +428,20 @@ class Crypt_TripleDES {
|
|||||||
if ($this->continuousBuffer) {
|
if ($this->continuousBuffer) {
|
||||||
$this->encryptIV = $xor;
|
$this->encryptIV = $xor;
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
|
case CRYPT_DES_MODE_CTR:
|
||||||
|
$xor = $this->encryptIV;
|
||||||
|
for ($i = 0; $i < strlen($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);
|
||||||
|
$ciphertext.= $block ^ $key;
|
||||||
|
}
|
||||||
|
if ($this->continuousBuffer) {
|
||||||
|
$this->encryptIV = $xor;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return $ciphertext;
|
return $ciphertext;
|
||||||
@ -398,19 +466,21 @@ class Crypt_TripleDES {
|
|||||||
$ciphertext = str_pad($ciphertext, (strlen($ciphertext) + 7) & 0xFFFFFFF8, chr(0));
|
$ciphertext = str_pad($ciphertext, (strlen($ciphertext) + 7) & 0xFFFFFFF8, chr(0));
|
||||||
|
|
||||||
if ( CRYPT_DES_MODE == CRYPT_DES_MODE_MCRYPT ) {
|
if ( CRYPT_DES_MODE == CRYPT_DES_MODE_MCRYPT ) {
|
||||||
$td = mcrypt_module_open(MCRYPT_3DES, $this->mcrypt[0], $this->mode, $this->mcrypt[1]);
|
if ($this->changed) {
|
||||||
mcrypt_generic_init($td, $this->key, $this->decryptIV);
|
if (!isset($this->demcrypt)) {
|
||||||
|
$this->demcrypt = mcrypt_module_open(MCRYPT_3DES, '', $this->mode, '');
|
||||||
$plaintext = mdecrypt_generic($td, $ciphertext);
|
}
|
||||||
|
mcrypt_generic_init($this->demcrypt, $this->key, $this->decryptIV);
|
||||||
mcrypt_generic_deinit($td);
|
$this->changed = false;
|
||||||
mcrypt_module_close($td);
|
|
||||||
|
|
||||||
if ($this->continuousBuffer) {
|
|
||||||
$this->decryptIV = substr($ciphertext, -8);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this->_unpad($plaintext);
|
$plaintext = mdecrypt_generic($this->demcrypt, $ciphertext);
|
||||||
|
|
||||||
|
if (!$this->continuousBuffer) {
|
||||||
|
mcrypt_generic_init($this->demcrypt, $this->keys, $this->decryptIV);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->mode != 'ctr' ? $this->_unpad($plaintext) : $plaintext;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strlen($this->key) <= 8) {
|
if (strlen($this->key) <= 8) {
|
||||||
@ -445,9 +515,23 @@ class Crypt_TripleDES {
|
|||||||
if ($this->continuousBuffer) {
|
if ($this->continuousBuffer) {
|
||||||
$this->decryptIV = $xor;
|
$this->decryptIV = $xor;
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
|
case CRYPT_DES_MODE_CTR:
|
||||||
|
$xor = $this->decryptIV;
|
||||||
|
for ($i = 0; $i < strlen($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);
|
||||||
|
$plaintext.= $block ^ $key;
|
||||||
|
}
|
||||||
|
if ($this->continuousBuffer) {
|
||||||
|
$this->decryptIV = $xor;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this->_unpad($plaintext);
|
return $this->mode != CRYPT_DES_MODE_CTR ? $this->_unpad($plaintext) : $plaintext;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -60,7 +60,7 @@
|
|||||||
* @author Jim Wigginton <terrafrost@php.net>
|
* @author Jim Wigginton <terrafrost@php.net>
|
||||||
* @copyright MMVII Jim Wigginton
|
* @copyright MMVII Jim Wigginton
|
||||||
* @license http://www.gnu.org/licenses/lgpl.txt
|
* @license http://www.gnu.org/licenses/lgpl.txt
|
||||||
* @version $Id: SSH2.php,v 1.34 2010-01-21 07:33:05 terrafrost Exp $
|
* @version $Id: SSH2.php,v 1.35 2010-02-09 06:10:26 terrafrost Exp $
|
||||||
* @link http://phpseclib.sourceforge.net
|
* @link http://phpseclib.sourceforge.net
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -674,10 +674,22 @@ class Net_SSH2 {
|
|||||||
);
|
);
|
||||||
|
|
||||||
static $encryption_algorithms = array(
|
static $encryption_algorithms = array(
|
||||||
'arcfour', // OPTIONAL the ARCFOUR stream cipher with a 128-bit key
|
|
||||||
'aes128-cbc', // RECOMMENDED AES with a 128-bit key
|
'aes128-cbc', // RECOMMENDED AES with a 128-bit key
|
||||||
'aes192-cbc', // OPTIONAL AES with a 192-bit key
|
'aes192-cbc', // OPTIONAL AES with a 192-bit key
|
||||||
'aes256-cbc', // OPTIONAL AES in CBC mode, with a 256-bit key
|
'aes256-cbc', // OPTIONAL AES in CBC mode, with a 256-bit key
|
||||||
|
|
||||||
|
// from <http://tools.ietf.org/html/rfc4344#section-4>:
|
||||||
|
'aes128-ctr', // RECOMMENDED AES (Rijndael) in SDCTR mode, with 128-bit key
|
||||||
|
'aes192-ctr', // RECOMMENDED AES with 192-bit key
|
||||||
|
'aes256-ctr', // RECOMMENDED AES with 256-bit key
|
||||||
|
'3des-ctr', // RECOMMENDED Three-key 3DES in SDCTR mode
|
||||||
|
|
||||||
|
// from <http://tools.ietf.org/html/rfc4345#section-4>:
|
||||||
|
// (commented out since i don't know of any ssh servers that support them and thus am unable to test them)
|
||||||
|
//'arcfour128',
|
||||||
|
//'arcfour256',
|
||||||
|
|
||||||
|
'arcfour', // OPTIONAL the ARCFOUR stream cipher with a 128-bit key
|
||||||
'3des-cbc', // REQUIRED three-key 3DES in CBC mode
|
'3des-cbc', // REQUIRED three-key 3DES in CBC mode
|
||||||
'none' // OPTIONAL no encryption; NOT RECOMMENDED
|
'none' // OPTIONAL no encryption; NOT RECOMMENDED
|
||||||
);
|
);
|
||||||
@ -777,20 +789,28 @@ class Net_SSH2 {
|
|||||||
$decrypt = $encryption_algorithms[$i];
|
$decrypt = $encryption_algorithms[$i];
|
||||||
switch ($decrypt) {
|
switch ($decrypt) {
|
||||||
case '3des-cbc':
|
case '3des-cbc':
|
||||||
|
case '3des-ctr':
|
||||||
$decryptKeyLength = 24; // eg. 192 / 8
|
$decryptKeyLength = 24; // eg. 192 / 8
|
||||||
break;
|
break;
|
||||||
case 'aes256-cbc':
|
case 'aes256-cbc':
|
||||||
|
case 'aes256-ctr':
|
||||||
$decryptKeyLength = 32; // eg. 256 / 8
|
$decryptKeyLength = 32; // eg. 256 / 8
|
||||||
break;
|
break;
|
||||||
case 'aes192-cbc':
|
case 'aes192-cbc':
|
||||||
|
case 'aes192-ctr':
|
||||||
$decryptKeyLength = 24; // eg. 192 / 8
|
$decryptKeyLength = 24; // eg. 192 / 8
|
||||||
break;
|
break;
|
||||||
case 'aes128-cbc':
|
case 'aes128-cbc':
|
||||||
|
case 'aes128-ctr':
|
||||||
$decryptKeyLength = 16; // eg. 128 / 8
|
$decryptKeyLength = 16; // eg. 128 / 8
|
||||||
break;
|
break;
|
||||||
case 'arcfour':
|
case 'arcfour':
|
||||||
|
case 'arcfour128':
|
||||||
$decryptKeyLength = 16; // eg. 128 / 8
|
$decryptKeyLength = 16; // eg. 128 / 8
|
||||||
break;
|
break;
|
||||||
|
case 'arcfour256':
|
||||||
|
$decryptKeyLength = 32; // eg. 128 / 8
|
||||||
|
break;
|
||||||
case 'none';
|
case 'none';
|
||||||
$decryptKeyLength = 0;
|
$decryptKeyLength = 0;
|
||||||
}
|
}
|
||||||
@ -804,20 +824,28 @@ class Net_SSH2 {
|
|||||||
$encrypt = $encryption_algorithms[$i];
|
$encrypt = $encryption_algorithms[$i];
|
||||||
switch ($encrypt) {
|
switch ($encrypt) {
|
||||||
case '3des-cbc':
|
case '3des-cbc':
|
||||||
|
case '3des-ctr':
|
||||||
$encryptKeyLength = 24;
|
$encryptKeyLength = 24;
|
||||||
break;
|
break;
|
||||||
case 'aes256-cbc':
|
case 'aes256-cbc':
|
||||||
|
case 'aes256-ctr':
|
||||||
$encryptKeyLength = 32;
|
$encryptKeyLength = 32;
|
||||||
break;
|
break;
|
||||||
case 'aes192-cbc':
|
case 'aes192-cbc':
|
||||||
|
case 'aes192-ctr':
|
||||||
$encryptKeyLength = 24;
|
$encryptKeyLength = 24;
|
||||||
break;
|
break;
|
||||||
case 'aes128-cbc':
|
case 'aes128-cbc':
|
||||||
|
case 'aes128-ctr':
|
||||||
$encryptKeyLength = 16;
|
$encryptKeyLength = 16;
|
||||||
break;
|
break;
|
||||||
case 'arcfour':
|
case 'arcfour':
|
||||||
|
case 'arcfour128':
|
||||||
$encryptKeyLength = 16;
|
$encryptKeyLength = 16;
|
||||||
break;
|
break;
|
||||||
|
case 'arcfour256':
|
||||||
|
$encryptKeyLength = 32;
|
||||||
|
break;
|
||||||
case 'none';
|
case 'none';
|
||||||
$encryptKeyLength = 0;
|
$encryptKeyLength = 0;
|
||||||
}
|
}
|
||||||
@ -1073,19 +1101,25 @@ class Net_SSH2 {
|
|||||||
$this->encrypt = new Crypt_TripleDES();
|
$this->encrypt = new Crypt_TripleDES();
|
||||||
// $this->encrypt_block_size = 64 / 8 == the default
|
// $this->encrypt_block_size = 64 / 8 == the default
|
||||||
break;
|
break;
|
||||||
|
case '3des-ctr':
|
||||||
|
$this->encrypt = new Crypt_TripleDES(CRYPT_DES_MODE_CTR);
|
||||||
|
// $this->encrypt_block_size = 64 / 8 == the default
|
||||||
|
break;
|
||||||
case 'aes256-cbc':
|
case 'aes256-cbc':
|
||||||
|
case 'aes192-cbc':
|
||||||
|
case 'aes128-cbc':
|
||||||
$this->encrypt = new Crypt_AES();
|
$this->encrypt = new Crypt_AES();
|
||||||
$this->encrypt_block_size = 16; // eg. 128 / 8
|
$this->encrypt_block_size = 16; // eg. 128 / 8
|
||||||
break;
|
break;
|
||||||
case 'aes192-cbc':
|
case 'aes256-ctr':
|
||||||
$this->encrypt = new Crypt_AES();
|
case 'aes192-ctr':
|
||||||
$this->encrypt_block_size = 16;
|
case 'aes128-ctr':
|
||||||
break;
|
$this->encrypt = new Crypt_AES(CRYPT_AES_MODE_CTR);
|
||||||
case 'aes128-cbc':
|
$this->encrypt_block_size = 16; // eg. 128 / 8
|
||||||
$this->encrypt = new Crypt_AES();
|
|
||||||
$this->encrypt_block_size = 16;
|
|
||||||
break;
|
break;
|
||||||
case 'arcfour':
|
case 'arcfour':
|
||||||
|
case 'arcfour128':
|
||||||
|
case 'arcfour256':
|
||||||
$this->encrypt = new Crypt_RC4();
|
$this->encrypt = new Crypt_RC4();
|
||||||
break;
|
break;
|
||||||
case 'none';
|
case 'none';
|
||||||
@ -1096,19 +1130,24 @@ class Net_SSH2 {
|
|||||||
case '3des-cbc':
|
case '3des-cbc':
|
||||||
$this->decrypt = new Crypt_TripleDES();
|
$this->decrypt = new Crypt_TripleDES();
|
||||||
break;
|
break;
|
||||||
|
case '3des-ctr':
|
||||||
|
$this->decrypt = new Crypt_TripleDES(CRYPT_DES_MODE_CTR);
|
||||||
|
break;
|
||||||
case 'aes256-cbc':
|
case 'aes256-cbc':
|
||||||
$this->decrypt = new Crypt_AES();
|
|
||||||
$this->decrypt_block_size = 16;
|
|
||||||
break;
|
|
||||||
case 'aes192-cbc':
|
case 'aes192-cbc':
|
||||||
$this->decrypt = new Crypt_AES();
|
|
||||||
$this->decrypt_block_size = 16;
|
|
||||||
break;
|
|
||||||
case 'aes128-cbc':
|
case 'aes128-cbc':
|
||||||
$this->decrypt = new Crypt_AES();
|
$this->decrypt = new Crypt_AES();
|
||||||
$this->decrypt_block_size = 16;
|
$this->decrypt_block_size = 16;
|
||||||
break;
|
break;
|
||||||
|
case 'aes256-ctr':
|
||||||
|
case 'aes192-ctr':
|
||||||
|
case 'aes128-ctr':
|
||||||
|
$this->decrypt = new Crypt_AES(CRYPT_AES_MODE_CTR);
|
||||||
|
$this->decrypt_block_size = 16;
|
||||||
|
break;
|
||||||
case 'arcfour':
|
case 'arcfour':
|
||||||
|
case 'arcfour128':
|
||||||
|
case 'arcfour256':
|
||||||
$this->decrypt = new Crypt_RC4();
|
$this->decrypt = new Crypt_RC4();
|
||||||
break;
|
break;
|
||||||
case 'none';
|
case 'none';
|
||||||
@ -1151,6 +1190,20 @@ class Net_SSH2 {
|
|||||||
$this->decrypt->setKey(substr($key, 0, $decryptKeyLength));
|
$this->decrypt->setKey(substr($key, 0, $decryptKeyLength));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* The "arcfour128" algorithm is the RC4 cipher, as described in
|
||||||
|
[SCHNEIER], using a 128-bit key. The first 1536 bytes of keystream
|
||||||
|
generated by the cipher MUST be discarded, and the first byte of the
|
||||||
|
first encrypted packet MUST be encrypted using the 1537th byte of
|
||||||
|
keystream.
|
||||||
|
|
||||||
|
-- http://tools.ietf.org/html/rfc4345#section-4 */
|
||||||
|
if ($encrypt == 'arcfour128' || $encrypt == 'arcfour256') {
|
||||||
|
$this->encrypt->encrypt(str_repeat("\0", 1536));
|
||||||
|
}
|
||||||
|
if ($decrypt == 'arcfour128' || $decrypt == 'arcfour256') {
|
||||||
|
$this->decrypt->decrypt(str_repeat("\0", 1536));
|
||||||
|
}
|
||||||
|
|
||||||
for ($i = 0; $i < count($mac_algorithms) && !in_array($mac_algorithms[$i], $this->mac_algorithms_client_to_server); $i++);
|
for ($i = 0; $i < count($mac_algorithms) && !in_array($mac_algorithms[$i], $this->mac_algorithms_client_to_server); $i++);
|
||||||
if ($i == count($mac_algorithms)) {
|
if ($i == count($mac_algorithms)) {
|
||||||
user_error('No compatible client to server message authentication algorithms found', E_USER_NOTICE);
|
user_error('No compatible client to server message authentication algorithms found', E_USER_NOTICE);
|
||||||
|
Loading…
Reference in New Issue
Block a user