diff --git a/.travis.yml b/.travis.yml index ff3b3497..9f4ca74c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -6,4 +6,4 @@ php: - 5.4 script: - - phpunit + - phpunit --verbose diff --git a/phpseclib/Crypt/Rijndael.php b/phpseclib/Crypt/Rijndael.php index d358fb47..ddd51415 100644 --- a/phpseclib/Crypt/Rijndael.php +++ b/phpseclib/Crypt/Rijndael.php @@ -387,7 +387,7 @@ class Crypt_Rijndael { * @var String * @access private */ - var $enbuffer = array('encrypted' => '', 'xor' => ''); + var $enbuffer = array('encrypted' => '', 'xor' => '', 'pos' => 0); /** * Decryption buffer for CTR, OFB and CFB modes @@ -396,7 +396,7 @@ class Crypt_Rijndael { * @var String * @access private */ - var $debuffer = array('ciphertext' => ''); + var $debuffer = array('ciphertext' => '', 'xor' => '', 'pos' => 0); /** * Default Constructor. @@ -763,42 +763,46 @@ class Crypt_Rijndael { } break; case CRYPT_RIJNDAEL_MODE_CFB: - if (strlen($buffer['xor'])) { - $ciphertext = $plaintext ^ $buffer['xor']; - $iv = $buffer['encrypted'] . $ciphertext; - $start = strlen($ciphertext); - $buffer['encrypted'].= $ciphertext; - $buffer['xor'] = substr($buffer['xor'], strlen($ciphertext)); - } else { - $ciphertext = ''; - $iv = $this->encryptIV; - $start = 0; - } + $iv = $this->encryptIV; + $pos = $this->continuousBuffer === true ? $buffer['pos'] : 0; + $len = strlen($plaintext); - for ($i = $start; $i < strlen($plaintext); $i+=$block_size) { - $block = substr($plaintext, $i, $block_size); - $xor = $this->_encryptBlock($iv); - $iv = $block ^ $xor; - if ($continuousBuffer && strlen($iv) != $block_size) { - $buffer = array( - 'encrypted' => $iv, - 'xor' => substr($xor, strlen($iv)) - ); + for ($i=0; $pos && $len; --$len, ++$i) + { + $iv[$pos] = $iv[$pos] ^ $plaintext[$i]; + $ciphertext .= $iv[$pos]; + $pos = ($pos+1) % $block_size; } - $ciphertext.= $iv; - } + for (; $len >= $block_size; $len-=$block_size, $i+=$block_size) + { + $iv = $this->_encryptBlock($iv) ^ substr($plaintext, $i, $block_size); + $ciphertext .= $iv; + } + if ($len) + { + $iv = $this->_encryptBlock($iv); + while ($len--) + { + $iv[$pos] = $iv[$pos] ^ $plaintext[$i]; + $ciphertext .= $iv[$pos]; - if ($this->continuousBuffer) { - $this->encryptIV = $iv; - } + ++$i; + ++$pos; + } + } + if($this->continuousBuffer) + { + $this->encryptIV = $iv; + $buffer['pos'] = $pos; + } break; case CRYPT_RIJNDAEL_MODE_OFB: $xor = $this->encryptIV; - if (strlen($buffer)) { + if (strlen($buffer['xor'])) { for ($i = 0; $i < strlen($plaintext); $i+=$block_size) { $xor = $this->_encryptBlock($xor); - $buffer.= $xor; - $key = $this->_string_shift($buffer, $block_size); + $buffer['xor'].= $xor; + $key = $this->_string_shift($buffer['xor'], $block_size); $ciphertext.= substr($plaintext, $i, $block_size) ^ $key; } } else { @@ -811,7 +815,7 @@ class Crypt_Rijndael { if ($this->continuousBuffer) { $this->encryptIV = $xor; if ($start = strlen($plaintext) % $block_size) { - $buffer = substr($key, $start) . $buffer; + $buffer['xor'] = substr($key, $start) . $buffer['xor']; } } } @@ -879,49 +883,56 @@ class Crypt_Rijndael { if ($this->continuousBuffer) { $this->decryptIV = $xor; if ($start = strlen($ciphertext) % $block_size) { - $buffer['ciphertext'] = substr($key, $start) . $buffer['encrypted']; + $buffer['ciphertext'] = substr($key, $start) . $buffer['ciphertext']; } } break; case CRYPT_RIJNDAEL_MODE_CFB: - if (strlen($buffer['ciphertext'])) { - $plaintext = $ciphertext ^ substr($this->decryptIV, strlen($buffer['ciphertext'])); - $buffer['ciphertext'].= substr($ciphertext, 0, strlen($plaintext)); - if (strlen($buffer['ciphertext']) != $block_size) { - $block = $this->decryptIV; - } else { - $block = $buffer['ciphertext']; - $xor = $this->_encryptBlock($buffer['ciphertext']); - $buffer['ciphertext'] = ''; - } - $start = strlen($plaintext); - } else { - $plaintext = ''; - $xor = $this->_encryptBlock($this->decryptIV); - $start = 0; - } + $iv = $this->decryptIV; + $pos = $this->continuousBuffer === true ? $buffer['pos'] : 0; + $len = strlen($ciphertext); - for ($i = $start; $i < strlen($ciphertext); $i+=$block_size) { - $block = substr($ciphertext, $i, $block_size); - $plaintext.= $block ^ $xor; - if ($continuousBuffer && strlen($block) != $block_size) { - $buffer['ciphertext'].= $block; - $block = $xor; - } else if (strlen($block) == $block_size) { - $xor = $this->_encryptBlock($block); + // cfb routines inspired by: http://cvs.openssl.org/fileview?f=openssl/crypto/modes/cfb128.c&v=1.3.2.2.2.1 + for ($i=0; $pos && $len; --$len, ++$i) + { + $plaintext .= $iv[$pos] ^ $ciphertext[$i]; + $iv[$pos] = $ciphertext[$i]; + $pos = ($pos+1) % $block_size; + } + + for (; $len >= $block_size; $len-=$block_size, $i+=$block_size) + { + $iv = $this->_encryptBlock($iv); + $cb = substr($ciphertext, $i, $block_size); + $plaintext .= $iv ^ $cb; + $iv = $cb; + } + + if ($len) + { + $iv = $this->_encryptBlock($iv); + while ($len--) + { + $plaintext .= $iv[$pos] ^ $ciphertext[$i]; + $iv[$pos] = $ciphertext[$i]; + + ++$i; + ++$pos; + } + } + if ($this->continuousBuffer) + { + $this->decryptIV = $iv; + $buffer['pos'] = $pos; } - } - if ($this->continuousBuffer) { - $this->decryptIV = $block; - } break; case CRYPT_RIJNDAEL_MODE_OFB: $xor = $this->decryptIV; - if (strlen($buffer)) { + if (strlen($buffer['xor'])) { for ($i = 0; $i < strlen($ciphertext); $i+=$block_size) { $xor = $this->_encryptBlock($xor); - $buffer.= $xor; - $key = $this->_string_shift($buffer, $block_size); + $buffer['xor'].= $xor; + $key = $this->_string_shift($buffer['xor'], $block_size); $plaintext.= substr($ciphertext, $i, $block_size) ^ $key; } } else { @@ -934,7 +945,7 @@ class Crypt_Rijndael { if ($this->continuousBuffer) { $this->decryptIV = $xor; if ($start = strlen($ciphertext) % $block_size) { - $buffer = substr($key, $start) . $buffer; + $buffer['xor'] = substr($key, $start) . $buffer['xor']; } } } @@ -1456,6 +1467,8 @@ class Crypt_Rijndael { $this->continuousBuffer = false; $this->encryptIV = $this->iv; $this->decryptIV = $this->iv; + $this->enbuffer = array('encrypted' => '', 'xor' => '', 'pos' => 0); + $this->debuffer = array('ciphertext' => '', 'xor' => '', 'pos' => 0); } /** @@ -1495,4 +1508,4 @@ class Crypt_Rijndael { } // vim: ts=4:sw=4:et: -// vim6: fdl=1: \ No newline at end of file +// vim6: fdl=1: diff --git a/tests/bootstrap.php b/tests/bootstrap.php index eb7136b8..13a8e81b 100644 --- a/tests/bootstrap.php +++ b/tests/bootstrap.php @@ -9,14 +9,34 @@ // class files of phpseclib require() other dependencies. set_include_path(implode(PATH_SEPARATOR, array( dirname(__FILE__) . '/../phpseclib/', + dirname(__FILE__) . '/', get_include_path(), ))); +function phpseclib_is_includable($suffix) +{ + foreach (explode(PATH_SEPARATOR, get_include_path()) as $prefix) + { + $ds = substr($prefix, -1) == DIRECTORY_SEPARATOR ? '' : DIRECTORY_SEPARATOR; + $file = $prefix . $ds . $suffix; + + if (file_exists($file)) + { + return true; + } + } + + return false; +} + function phpseclib_autoload($class) { $file = str_replace('_', '/', $class) . '.php'; - require $file; + if (phpseclib_is_includable($file)) + { + require $file; + } } spl_autoload_register('phpseclib_autoload');