From eff0bb21c580f9360ff9a31fbe250c81427386eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hans-J=C3=BCrgen=20Petrich?= Date: Sun, 3 Mar 2013 17:26:41 +0700 Subject: [PATCH] 3DES/Rijndael/AES: Fix memory leak with CTR mode Related to: https://github.com/phpseclib/phpseclib/issues/77 --- phpseclib/Crypt/Rijndael.php | 24 ++++++++++++++++-------- phpseclib/Crypt/TripleDES.php | 24 ++++++++++++++---------- 2 files changed, 30 insertions(+), 18 deletions(-) diff --git a/phpseclib/Crypt/Rijndael.php b/phpseclib/Crypt/Rijndael.php index ef9726a2..682c8900 100644 --- a/phpseclib/Crypt/Rijndael.php +++ b/phpseclib/Crypt/Rijndael.php @@ -834,7 +834,9 @@ class Crypt_Rijndael { if (strlen($buffer['encrypted'])) { for ($i = 0; $i < strlen($plaintext); $i+=$block_size) { $block = substr($plaintext, $i, $block_size); - $buffer['encrypted'].= $this->_encryptBlock($this->_generate_xor($block_size, $xor)); + if (strlen($block) > strlen($buffer['encrypted'])) { + $buffer['encrypted'].= $this->_encryptBlock($this->_generate_xor($block_size, $xor)); + } $key = $this->_string_shift($buffer['encrypted'], $block_size); $ciphertext.= $block ^ $key; } @@ -971,7 +973,9 @@ class Crypt_Rijndael { if (strlen($buffer['ciphertext'])) { for ($i = 0; $i < strlen($ciphertext); $i+=$block_size) { $block = substr($ciphertext, $i, $block_size); - $buffer['ciphertext'].= $this->_encryptBlock($this->_generate_xor($block_size, $xor)); + if (strlen($block) > strlen($buffer['ciphertext'])) { + $buffer['ciphertext'].= $this->_encryptBlock($this->_generate_xor($block_size, $xor)); + } $key = $this->_string_shift($buffer['ciphertext'], $block_size); $plaintext.= $block ^ $key; } @@ -1794,9 +1798,11 @@ class Crypt_Rijndael { if (strlen($buffer["encrypted"])) { for ($i = 0; $i < $plaintext_len; $i+= '.$block_size.') { $block = substr($text, $i, '.$block_size.'); - $in = $self->_generate_xor('.$block_size.', $xor); - '.$_encryptBlock.' - $buffer["encrypted"].= $in; + if (strlen($block) > strlen($buffer["encrypted"])) { + $in = $self->_generate_xor('.$block_size.', $xor); + '.$_encryptBlock.' + $buffer["encrypted"].= $in; + } $key = $self->_string_shift($buffer["encrypted"], '.$block_size.'); $ciphertext.= $block ^ $key; } @@ -1828,9 +1834,11 @@ class Crypt_Rijndael { if (strlen($buffer["ciphertext"])) { for ($i = 0; $i < $ciphertext_len; $i+= '.$block_size.') { $block = substr($text, $i, '.$block_size.'); - $in = $self->_generate_xor('.$block_size.', $xor); - '.$_encryptBlock.' - $buffer["ciphertext"].= $in; + if (strlen($block) > strlen($buffer["ciphertext"])) { + $in = $self->_generate_xor('.$block_size.', $xor); + '.$_encryptBlock.' + $buffer["ciphertext"].= $in; + } $key = $self->_string_shift($buffer["ciphertext"], '.$block_size.'); $plaintext.= $block ^ $key; } diff --git a/phpseclib/Crypt/TripleDES.php b/phpseclib/Crypt/TripleDES.php index 3b4c8c36..476ff53c 100644 --- a/phpseclib/Crypt/TripleDES.php +++ b/phpseclib/Crypt/TripleDES.php @@ -605,11 +605,13 @@ class Crypt_TripleDES { if (strlen($buffer['encrypted'])) { for ($i = 0; $i < strlen($plaintext); $i+=8) { $block = substr($plaintext, $i, 8); - $key = $this->_generate_xor($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); - $buffer['encrypted'].= $key; + if (strlen($block) > strlen($buffer['encrypted'])) { + $key = $this->_generate_xor($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); + $buffer['encrypted'].= $key; + } $key = $this->_string_shift($buffer['encrypted'], 8); $ciphertext.= $block ^ $key; } @@ -809,11 +811,13 @@ class Crypt_TripleDES { if (strlen($buffer['ciphertext'])) { for ($i = 0; $i < strlen($ciphertext); $i+=8) { $block = substr($ciphertext, $i, 8); - $key = $this->_generate_xor($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); - $buffer['ciphertext'].= $key; + if (strlen($block) > strlen($buffer['ciphertext'])) { + $key = $this->_generate_xor($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); + $buffer['ciphertext'].= $key; + } $key = $this->_string_shift($buffer['ciphertext'], 8); $plaintext.= $block ^ $key; }