Merge remote-tracking branch 'origin/petrich'

Conflicts:
	phpseclib/Crypt/AES.php
This commit is contained in:
terrafrost 2013-01-11 18:06:43 -06:00
commit 7c0926d94a

View File

@ -293,7 +293,6 @@ class Crypt_AES extends Crypt_Rijndael {
function encrypt($plaintext) function encrypt($plaintext)
{ {
if ( CRYPT_AES_MODE == CRYPT_AES_MODE_MCRYPT ) { if ( CRYPT_AES_MODE == CRYPT_AES_MODE_MCRYPT ) {
$changed = $this->changed;
$this->_mcryptSetup(); $this->_mcryptSetup();
/* /*
if ($this->mode == CRYPT_AES_MODE_CTR) { if ($this->mode == CRYPT_AES_MODE_CTR) {
@ -310,36 +309,43 @@ class Crypt_AES extends Crypt_Rijndael {
// using mcrypt's default handing of CFB the above would output two different things. using phpseclib's // using mcrypt's default handing of CFB the above would output two different things. using phpseclib's
// rewritten CFB implementation the above outputs the same thing twice. // rewritten CFB implementation the above outputs the same thing twice.
if ($this->mode == 'ncfb' && $this->continuousBuffer) { if ($this->mode == 'ncfb' && $this->continuousBuffer) {
if ($changed) { $iv = &$this->encryptIV;
$this->ecb = mcrypt_module_open(MCRYPT_RIJNDAEL_128, '', MCRYPT_MODE_ECB, ''); $pos = &$this->enbuffer['pos'];
mcrypt_generic_init($this->ecb, $this->key, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"); $len = strlen($plaintext);
} $ciphertext = '';
$i = 0;
$buffer = &$this->enbuffer['encrypted']; if ($pos) {
$orig_pos = $pos;
if (strlen($buffer)) { $max = 16 - $pos;
$ciphertext = $plaintext ^ substr($this->encryptIV, strlen($buffer)); if ($len >= $max) {
$buffer.= $ciphertext; $i = $max;
if (strlen($buffer) == 16) { $len-= $max;
$this->encryptIV = $buffer; $pos = 0;
$buffer = ''; } else {
mcrypt_generic_init($this->enmcrypt, $this->key, $this->encryptIV); $i = $len;
$pos+= $len;
$len = 0;
} }
$plaintext = substr($plaintext, strlen($ciphertext)); $ciphertext = substr($iv, $orig_pos) ^ $plaintext;
} else { $iv = substr_replace($iv, $ciphertext, $orig_pos, $i);
$ciphertext = ''; $this->enbuffer['enmcrypt_init'] = true;
} }
if ($len >= 16) {
$last_pos = strlen($plaintext) & 0xFFFFFFF0; if ($this->enbuffer['enmcrypt_init'] === true) {
if ($last_pos) { mcrypt_generic_init($this->enmcrypt, $this->key, $iv);
$ciphertext.= mcrypt_generic($this->enmcrypt, substr($plaintext, 0, $last_pos)); $this->enbuffer['enmcrypt_init'] = false;
$this->encryptIV = substr($ciphertext, -16); }
$ciphertext.= mcrypt_generic($this->enmcrypt, substr($plaintext, $i, $len - $len % 16));
$iv = substr($ciphertext, -16);
$i = strlen($ciphertext);
$len%= 16;
} }
if ($len) {
if (strlen($plaintext) & 0xF) { $iv = mcrypt_generic($this->ecb, $iv);
$this->encryptIV = mcrypt_generic($this->ecb, $this->encryptIV); $block = substr($iv, $pos) ^ substr($plaintext, $i);
$buffer = substr($plaintext, $last_pos) ^ $this->encryptIV; $iv = substr_replace($iv, $block, 0, $len);
$ciphertext.= $buffer; $ciphertext.= $block;
$pos = $len;
} }
return $ciphertext; return $ciphertext;
@ -373,7 +379,6 @@ class Crypt_AES extends Crypt_Rijndael {
function decrypt($ciphertext) function decrypt($ciphertext)
{ {
if ( CRYPT_AES_MODE == CRYPT_AES_MODE_MCRYPT ) { if ( CRYPT_AES_MODE == CRYPT_AES_MODE_MCRYPT ) {
$changed = $this->changed;
$this->_mcryptSetup(); $this->_mcryptSetup();
/* /*
if ($this->mode == CRYPT_AES_MODE_CTR) { if ($this->mode == CRYPT_AES_MODE_CTR) {
@ -387,37 +392,44 @@ class Crypt_AES extends Crypt_Rijndael {
} }
*/ */
if ($this->mode == 'ncfb' && $this->continuousBuffer) { if ($this->mode == 'ncfb' && $this->continuousBuffer) {
if ($changed) { $iv = &$this->decryptIV;
$this->ecb = mcrypt_module_open(MCRYPT_RIJNDAEL_128, '', MCRYPT_MODE_ECB, ''); $pos = &$this->debuffer['pos'];
mcrypt_generic_init($this->ecb, $this->key, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"); $len = strlen($ciphertext);
} $plaintext = '';
$i = 0;
$buffer = &$this->debuffer['ciphertext']; if ($pos) {
$orig_pos = $pos;
if (strlen($buffer)) { $max = 16 - $pos;
$plaintext = $ciphertext ^ substr($this->decryptIV, strlen($buffer)); if ($len >= $max) {
$i = $max;
$buffer.= substr($ciphertext, 0, strlen($plaintext)); $len-= $max;
if (strlen($buffer) == 16) { $pos = 0;
$this->decryptIV = $buffer; } else {
$buffer = ''; $i = $len;
mcrypt_generic_init($this->demcrypt, $this->key, $this->decryptIV); $pos+= $len;
$len = 0;
} }
$ciphertext = substr($ciphertext, strlen($plaintext)); // ie. $i = min($max, $len), $len-= $i, $pos+= $i, $pos%= $blocksize
} else { $plaintext = substr($iv, $orig_pos) ^ $ciphertext;
$plaintext = ''; $iv = substr_replace($iv, substr($ciphertext, 0, $i), $orig_pos, $i);
$this->debuffer['demcrypt_init'] = true;
} }
if ($len >= 16) {
$last_pos = strlen($ciphertext) & 0xFFFFFFF0; if ($this->debuffer['demcrypt_init'] === true) {
if ($last_pos) { mcrypt_generic_init($this->demcrypt, $this->key, $iv);
$plaintext.= mdecrypt_generic($this->demcrypt, substr($ciphertext, 0, $last_pos)); $this->debuffer['demcrypt_init'] = false;
$this->decryptIV = substr($ciphertext, $last_pos - 16, 16); }
$cb = substr($ciphertext, $i, $len - $len % 16);
$plaintext.= mdecrypt_generic($this->demcrypt, $cb);
$iv = substr($cb, -16);
$i = strlen($plaintext);
$len%= 16;
} }
if ($len) {
if (strlen($ciphertext) & 0xF) { $iv = mcrypt_generic($this->ecb, $iv);
$this->decryptIV = mcrypt_generic($this->ecb, $this->decryptIV); $plaintext.= substr($iv, $pos) ^ substr($ciphertext, $i);
$buffer = substr($ciphertext, $last_pos); $iv = substr_replace($iv, substr($ciphertext, $i, $len), 0, $len);
$plaintext.= $buffer ^ $this->decryptIV; $pos = $len;
} }
return $plaintext; return $plaintext;
@ -488,11 +500,20 @@ class Crypt_AES extends Crypt_Rijndael {
$this->demcrypt = mcrypt_module_open(MCRYPT_RIJNDAEL_128, '', $mode, ''); $this->demcrypt = mcrypt_module_open(MCRYPT_RIJNDAEL_128, '', $mode, '');
$this->enmcrypt = mcrypt_module_open(MCRYPT_RIJNDAEL_128, '', $mode, ''); $this->enmcrypt = mcrypt_module_open(MCRYPT_RIJNDAEL_128, '', $mode, '');
if ($mode == 'ncfb') {
$this->ecb = mcrypt_module_open(MCRYPT_RIJNDAEL_128, '', MCRYPT_MODE_ECB, '');
}
} // else should mcrypt_generic_deinit be called? } // else should mcrypt_generic_deinit be called?
mcrypt_generic_init($this->demcrypt, $this->key, $this->iv); mcrypt_generic_init($this->demcrypt, $this->key, $this->iv);
mcrypt_generic_init($this->enmcrypt, $this->key, $this->iv); mcrypt_generic_init($this->enmcrypt, $this->key, $this->iv);
if ($this->mode == 'ncfb') {
mcrypt_generic_init($this->ecb, $this->key, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0");
}
$this->changed = false; $this->changed = false;
} }
@ -608,6 +629,24 @@ class Crypt_AES extends Crypt_Rijndael {
return pack('N*', $state[0], $state[1], $state[2], $state[3]); return pack('N*', $state[0], $state[1], $state[2], $state[3]);
} }
/**
* Treat consecutive "packets" as if they are a continuous buffer.
*
* The default behavior.
*
* @see Crypt_Rijndael::disableContinuousBuffer()
* @access public
*/
function enableContinuousBuffer()
{
parent::enableContinuousBuffer();
if (CRYPT_AES_MODE == CRYPT_AES_MODE_MCRYPT) {
$this->enbuffer['enmcrypt_init'] = true;
$this->debuffer['demcrypt_init'] = true;
}
}
/** /**
* Treat consecutive packets as if they are a discontinuous buffer. * Treat consecutive packets as if they are a discontinuous buffer.
* *