mirror of
https://github.com/danog/phpseclib.git
synced 2024-12-11 16:49:42 +01:00
fix float to int conversions on 32-bit linux PHP < 5.3 installs
This commit is contained in:
parent
c27fd2e66f
commit
42fb96db16
@ -478,16 +478,14 @@ class Crypt_Blowfish extends Crypt_Base
|
|||||||
|
|
||||||
for ($i = 0; $i < 16; $i+= 2) {
|
for ($i = 0; $i < 16; $i+= 2) {
|
||||||
$l^= $p[$i];
|
$l^= $p[$i];
|
||||||
$r^= ($sb_0[$l >> 24 & 0xff] +
|
$r^= $this->safe_intval(($this->safe_intval($sb_0[$l >> 24 & 0xff] + $sb_1[$l >> 16 & 0xff]) ^
|
||||||
$sb_1[$l >> 16 & 0xff] ^
|
|
||||||
$sb_2[$l >> 8 & 0xff]) +
|
$sb_2[$l >> 8 & 0xff]) +
|
||||||
$sb_3[$l & 0xff];
|
$sb_3[$l & 0xff]);
|
||||||
|
|
||||||
$r^= $p[$i + 1];
|
$r^= $p[$i + 1];
|
||||||
$l^= ($sb_0[$r >> 24 & 0xff] +
|
$l^= $this->safe_intval(($this->safe_intval($sb_0[$r >> 24 & 0xff] + $sb_1[$r >> 16 & 0xff]) ^
|
||||||
$sb_1[$r >> 16 & 0xff] ^
|
|
||||||
$sb_2[$r >> 8 & 0xff]) +
|
$sb_2[$r >> 8 & 0xff]) +
|
||||||
$sb_3[$r & 0xff];
|
$sb_3[$r & 0xff]);
|
||||||
}
|
}
|
||||||
return pack("N*", $r ^ $p[17], $l ^ $p[16]);
|
return pack("N*", $r ^ $p[17], $l ^ $p[16]);
|
||||||
}
|
}
|
||||||
@ -513,16 +511,14 @@ class Crypt_Blowfish extends Crypt_Base
|
|||||||
|
|
||||||
for ($i = 17; $i > 2; $i-= 2) {
|
for ($i = 17; $i > 2; $i-= 2) {
|
||||||
$l^= $p[$i];
|
$l^= $p[$i];
|
||||||
$r^= ($sb_0[$l >> 24 & 0xff] +
|
$r^= $this->safe_intval(($this->safe_intval($sb_0[$l >> 24 & 0xff] + $sb_1[$l >> 16 & 0xff]) ^
|
||||||
$sb_1[$l >> 16 & 0xff] ^
|
|
||||||
$sb_2[$l >> 8 & 0xff]) +
|
$sb_2[$l >> 8 & 0xff]) +
|
||||||
$sb_3[$l & 0xff];
|
$sb_3[$l & 0xff]);
|
||||||
|
|
||||||
$r^= $p[$i - 1];
|
$r^= $p[$i - 1];
|
||||||
$l^= ($sb_0[$r >> 24 & 0xff] +
|
$l^= $this->safe_intval(($this->safe_intval($sb_0[$r >> 24 & 0xff] + $sb_1[$r >> 16 & 0xff]) ^
|
||||||
$sb_1[$r >> 16 & 0xff] ^
|
|
||||||
$sb_2[$r >> 8 & 0xff]) +
|
$sb_2[$r >> 8 & 0xff]) +
|
||||||
$sb_3[$r & 0xff];
|
$sb_3[$r & 0xff]);
|
||||||
}
|
}
|
||||||
return pack("N*", $r ^ $p[0], $l ^ $p[1]);
|
return pack("N*", $r ^ $p[0], $l ^ $p[1]);
|
||||||
}
|
}
|
||||||
@ -548,6 +544,18 @@ class Crypt_Blowfish extends Crypt_Base
|
|||||||
$code_hash = str_pad($code_hash, 32) . $this->_hashInlineCryptFunction($this->key);
|
$code_hash = str_pad($code_hash, 32) . $this->_hashInlineCryptFunction($this->key);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// on 32-bit linux systems with PHP < 5.3 float to integer conversion is bad
|
||||||
|
switch (true) {
|
||||||
|
case defined('PHP_INT_SIZE') && PHP_INT_SIZE == 8:
|
||||||
|
case version_compare(PHP_VERSION, '5.3.0') >= 0:
|
||||||
|
case (PHP_OS & "\xDF\xDF\xDF") === 'WIN':
|
||||||
|
$safeint = '%s';
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
$safeint = '(is_int($temp = %s) ? $temp : (fmod($temp, 0x80000000) & 0x7FFFFFFF) | ';
|
||||||
|
$safeint.= '((fmod(floor($temp / 0x80000000), 2) & 1) << 31))';
|
||||||
|
}
|
||||||
|
|
||||||
if (!isset($lambda_functions[$code_hash])) {
|
if (!isset($lambda_functions[$code_hash])) {
|
||||||
switch (true) {
|
switch (true) {
|
||||||
case $gen_hi_opt_code:
|
case $gen_hi_opt_code:
|
||||||
@ -583,16 +591,14 @@ class Crypt_Blowfish extends Crypt_Base
|
|||||||
for ($i = 0; $i < 16; $i+= 2) {
|
for ($i = 0; $i < 16; $i+= 2) {
|
||||||
$encrypt_block.= '
|
$encrypt_block.= '
|
||||||
$l^= ' . $p[$i] . ';
|
$l^= ' . $p[$i] . ';
|
||||||
$r^= ($sb_0[$l >> 24 & 0xff] +
|
$r^= ' . sprintf($safeint, '(' . sprintf($safeint, '$sb_0[$l >> 24 & 0xff] + $sb_1[$l >> 16 & 0xff]') . ' ^
|
||||||
$sb_1[$l >> 16 & 0xff] ^
|
|
||||||
$sb_2[$l >> 8 & 0xff]) +
|
$sb_2[$l >> 8 & 0xff]) +
|
||||||
$sb_3[$l & 0xff];
|
$sb_3[$l & 0xff]') . ';
|
||||||
|
|
||||||
$r^= ' . $p[$i + 1] . ';
|
$r^= ' . $p[$i + 1] . ';
|
||||||
$l^= ($sb_0[$r >> 24 & 0xff] +
|
$l^= ' . sprintf($safeint, '(' . sprintf($safeint, '$sb_0[$r >> 24 & 0xff] + $sb_1[$r >> 16 & 0xff]') . ' ^
|
||||||
$sb_1[$r >> 16 & 0xff] ^
|
|
||||||
$sb_2[$r >> 8 & 0xff]) +
|
$sb_2[$r >> 8 & 0xff]) +
|
||||||
$sb_3[$r & 0xff];
|
$sb_3[$r & 0xff]') . ';
|
||||||
';
|
';
|
||||||
}
|
}
|
||||||
$encrypt_block.= '
|
$encrypt_block.= '
|
||||||
@ -612,16 +618,14 @@ class Crypt_Blowfish extends Crypt_Base
|
|||||||
for ($i = 17; $i > 2; $i-= 2) {
|
for ($i = 17; $i > 2; $i-= 2) {
|
||||||
$decrypt_block.= '
|
$decrypt_block.= '
|
||||||
$l^= ' . $p[$i] . ';
|
$l^= ' . $p[$i] . ';
|
||||||
$r^= ($sb_0[$l >> 24 & 0xff] +
|
$r^= ' . sprintf($safeint, '(' . sprintf($safeint, '$sb_0[$l >> 24 & 0xff] + $sb_1[$l >> 16 & 0xff]') . ' ^
|
||||||
$sb_1[$l >> 16 & 0xff] ^
|
|
||||||
$sb_2[$l >> 8 & 0xff]) +
|
$sb_2[$l >> 8 & 0xff]) +
|
||||||
$sb_3[$l & 0xff];
|
$sb_3[$l & 0xff]') . ';
|
||||||
|
|
||||||
$r^= ' . $p[$i - 1] . ';
|
$r^= ' . $p[$i - 1] . ';
|
||||||
$l^= ($sb_0[$r >> 24 & 0xff] +
|
$l^= ' . sprintf($safeint, '(' . sprintf($safeint, '$sb_0[$r >> 24 & 0xff] + $sb_1[$r >> 16 & 0xff]') . ' ^
|
||||||
$sb_1[$r >> 16 & 0xff] ^
|
|
||||||
$sb_2[$r >> 8 & 0xff]) +
|
$sb_2[$r >> 8 & 0xff]) +
|
||||||
$sb_3[$r & 0xff];
|
$sb_3[$r & 0xff]') . ';
|
||||||
';
|
';
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -644,4 +648,24 @@ class Crypt_Blowfish extends Crypt_Base
|
|||||||
}
|
}
|
||||||
$this->inline_crypt = $lambda_functions[$code_hash];
|
$this->inline_crypt = $lambda_functions[$code_hash];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert float to int
|
||||||
|
*
|
||||||
|
* On 32-bit Linux installs running PHP < 5.3 converting floats to ints doesn't always work
|
||||||
|
*
|
||||||
|
* @access private
|
||||||
|
* @param string $x
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
function safe_intval($x)
|
||||||
|
{
|
||||||
|
// PHP 5.3, per http://php.net/releases/5_3_0.php, introduced "more consistent float rounding"
|
||||||
|
// PHP_OS & "\xDF\xDF\xDF" == strtoupper(substr(PHP_OS, 0, 3)), but a lot faster
|
||||||
|
if (is_int($x) || version_compare(PHP_VERSION, '5.3.0') >= 0 || (PHP_OS & "\xDF\xDF\xDF") === 'WIN') {
|
||||||
|
return $x;
|
||||||
|
}
|
||||||
|
return (fmod($x, 0x80000000) & 0x7FFFFFFF) |
|
||||||
|
((fmod(floor($x / 0x80000000), 2) & 1) << 31);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -820,7 +820,14 @@ class Crypt_Hash
|
|||||||
$result+= $argument < 0 ? ($argument & 0x7FFFFFFF) + 0x80000000 : $argument;
|
$result+= $argument < 0 ? ($argument & 0x7FFFFFFF) + 0x80000000 : $argument;
|
||||||
}
|
}
|
||||||
|
|
||||||
return fmod($result, $mod);
|
// PHP 5.3, per http://php.net/releases/5_3_0.php, introduced "more consistent float rounding"
|
||||||
|
// PHP_OS & "\xDF\xDF\xDF" == strtoupper(substr(PHP_OS, 0, 3)), but a lot faster
|
||||||
|
if (is_int($result) || version_compare(PHP_VERSION, '5.3.0') >= 0 || (PHP_OS & "\xDF\xDF\xDF") === 'WIN') {
|
||||||
|
return fmod($result, $mod);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (fmod($result, 0x80000000) & 0x7FFFFFFF) |
|
||||||
|
((fmod(floor($result / 0x80000000), 2) & 1) << 31);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Loading…
Reference in New Issue
Block a user