Skip to content

Commit

Permalink
Crypt/Base: use a custom error handler for mcrypt
Browse files Browse the repository at this point in the history
  • Loading branch information
terrafrost committed Mar 19, 2021
1 parent a45ccba commit e209db7
Showing 1 changed file with 45 additions and 21 deletions.
66 changes: 45 additions & 21 deletions phpseclib/Crypt/Base.php
Expand Up @@ -821,12 +821,13 @@ function encrypt($plaintext)
}

if ($this->engine === CRYPT_ENGINE_MCRYPT) {
set_error_handler(array($this, 'do_nothing'));
if ($this->changed) {
$this->_setupMcrypt();
$this->changed = false;
}
if ($this->enchanged) {
@mcrypt_generic_init($this->enmcrypt, $this->key, $this->encryptIV);
mcrypt_generic_init($this->enmcrypt, $this->key, $this->encryptIV);
$this->enchanged = false;
}

Expand Down Expand Up @@ -859,15 +860,15 @@ function encrypt($plaintext)
if ($len >= $block_size) {
if ($this->enbuffer['enmcrypt_init'] === false || $len > $this->cfb_init_len) {
if ($this->enbuffer['enmcrypt_init'] === true) {
@mcrypt_generic_init($this->enmcrypt, $this->key, $iv);
mcrypt_generic_init($this->enmcrypt, $this->key, $iv);
$this->enbuffer['enmcrypt_init'] = false;
}
$ciphertext.= @mcrypt_generic($this->enmcrypt, substr($plaintext, $i, $len - $len % $block_size));
$ciphertext.= mcrypt_generic($this->enmcrypt, substr($plaintext, $i, $len - $len % $block_size));
$iv = substr($ciphertext, -$block_size);
$len%= $block_size;
} else {
while ($len >= $block_size) {
$iv = @mcrypt_generic($this->ecb, $iv) ^ substr($plaintext, $i, $block_size);
$iv = mcrypt_generic($this->ecb, $iv) ^ substr($plaintext, $i, $block_size);
$ciphertext.= $iv;
$len-= $block_size;
$i+= $block_size;
Expand All @@ -876,22 +877,26 @@ function encrypt($plaintext)
}

if ($len) {
$iv = @mcrypt_generic($this->ecb, $iv);
$iv = mcrypt_generic($this->ecb, $iv);
$block = $iv ^ substr($plaintext, -$len);
$iv = substr_replace($iv, $block, 0, $len);
$ciphertext.= $block;
$pos = $len;
}

restore_error_handler();

return $ciphertext;
}

$ciphertext = @mcrypt_generic($this->enmcrypt, $plaintext);
$ciphertext = mcrypt_generic($this->enmcrypt, $plaintext);

if (!$this->continuousBuffer) {
@mcrypt_generic_init($this->enmcrypt, $this->key, $this->encryptIV);
mcrypt_generic_init($this->enmcrypt, $this->key, $this->encryptIV);
}

restore_error_handler();

return $ciphertext;
}

Expand Down Expand Up @@ -1132,13 +1137,14 @@ function decrypt($ciphertext)
}

if ($this->engine === CRYPT_ENGINE_MCRYPT) {
set_error_handler(array($this, 'do_nothing'));
$block_size = $this->block_size;
if ($this->changed) {
$this->_setupMcrypt();
$this->changed = false;
}
if ($this->dechanged) {
@mcrypt_generic_init($this->demcrypt, $this->key, $this->decryptIV);
mcrypt_generic_init($this->demcrypt, $this->key, $this->decryptIV);
$this->dechanged = false;
}

Expand Down Expand Up @@ -1166,26 +1172,30 @@ function decrypt($ciphertext)
}
if ($len >= $block_size) {
$cb = substr($ciphertext, $i, $len - $len % $block_size);
$plaintext.= @mcrypt_generic($this->ecb, $iv . $cb) ^ $cb;
$plaintext.= mcrypt_generic($this->ecb, $iv . $cb) ^ $cb;
$iv = substr($cb, -$block_size);
$len%= $block_size;
}
if ($len) {
$iv = @mcrypt_generic($this->ecb, $iv);
$iv = mcrypt_generic($this->ecb, $iv);
$plaintext.= $iv ^ substr($ciphertext, -$len);
$iv = substr_replace($iv, substr($ciphertext, -$len), 0, $len);
$pos = $len;
}

restore_error_handler();

return $plaintext;
}

$plaintext = @mdecrypt_generic($this->demcrypt, $ciphertext);
$plaintext = mdecrypt_generic($this->demcrypt, $ciphertext);

if (!$this->continuousBuffer) {
@mcrypt_generic_init($this->demcrypt, $this->key, $this->decryptIV);
mcrypt_generic_init($this->demcrypt, $this->key, $this->decryptIV);
}

restore_error_handler();

return $this->paddable ? $this->_unpad($plaintext) : $plaintext;
}

Expand Down Expand Up @@ -1643,9 +1653,12 @@ function isValidEngine($engine)
}
return false;
case CRYPT_ENGINE_MCRYPT:
return $this->cipher_name_mcrypt &&
set_error_handler(array($this, 'do_nothing'));
$result = $this->cipher_name_mcrypt &&
extension_loaded('mcrypt') &&
in_array($this->cipher_name_mcrypt, @mcrypt_list_algorithms());
in_array($this->cipher_name_mcrypt, mcrypt_list_algorithms());
restore_error_handler();
return $result;
case CRYPT_ENGINE_INTERNAL:
return true;
}
Expand Down Expand Up @@ -1722,17 +1735,19 @@ function _setEngine()
}

if ($this->engine != CRYPT_ENGINE_MCRYPT && $this->enmcrypt) {
set_error_handler(array($this, 'do_nothing'));
// Closing the current mcrypt resource(s). _mcryptSetup() will, if needed,
// (re)open them with the module named in $this->cipher_name_mcrypt
@mcrypt_module_close($this->enmcrypt);
@mcrypt_module_close($this->demcrypt);
mcrypt_module_close($this->enmcrypt);
mcrypt_module_close($this->demcrypt);
$this->enmcrypt = null;
$this->demcrypt = null;

if ($this->ecb) {
@mcrypt_module_close($this->ecb);
mcrypt_module_close($this->ecb);
$this->ecb = null;
}
restore_error_handler();
}

$this->changed = true;
Expand Down Expand Up @@ -1850,19 +1865,19 @@ function _setupMcrypt()
CRYPT_MODE_STREAM => MCRYPT_MODE_STREAM,
);

$this->demcrypt = @mcrypt_module_open($this->cipher_name_mcrypt, '', $mcrypt_modes[$this->mode], '');
$this->enmcrypt = @mcrypt_module_open($this->cipher_name_mcrypt, '', $mcrypt_modes[$this->mode], '');
$this->demcrypt = mcrypt_module_open($this->cipher_name_mcrypt, '', $mcrypt_modes[$this->mode], '');
$this->enmcrypt = mcrypt_module_open($this->cipher_name_mcrypt, '', $mcrypt_modes[$this->mode], '');

// we need the $ecb mcrypt resource (only) in MODE_CFB with enableContinuousBuffer()
// to workaround mcrypt's broken ncfb implementation in buffered mode
// see: {@link http://phpseclib.sourceforge.net/cfb-demo.phps}
if ($this->mode == CRYPT_MODE_CFB) {
$this->ecb = @mcrypt_module_open($this->cipher_name_mcrypt, '', MCRYPT_MODE_ECB, '');
$this->ecb = mcrypt_module_open($this->cipher_name_mcrypt, '', MCRYPT_MODE_ECB, '');
}
} // else should mcrypt_generic_deinit be called?
if ($this->mode == CRYPT_MODE_CFB) {
@mcrypt_generic_init($this->ecb, $this->key, str_repeat("\0", $this->block_size));
mcrypt_generic_init($this->ecb, $this->key, str_repeat("\0", $this->block_size));
}
}

Expand Down Expand Up @@ -2657,4 +2672,13 @@ function safe_intval_inline()
return $safeint . '((fmod(floor($temp / 0x80000000), 2) & 1) << 31))';
}
}

/**
* Dummy error handler to suppress mcrypt errors
*
* @access private
*/
function do_nothing()
{
}
}

0 comments on commit e209db7

Please sign in to comment.