From 1168ba4d275a436253daeeb2b5e073bc8bafc4d5 Mon Sep 17 00:00:00 2001 From: terrafrost Date: Sun, 28 Aug 2022 09:53:46 -0500 Subject: [PATCH 1/2] backport 3.0's PHP 8.1 32-bit fixes --- phpseclib/Crypt/Base.php | 10 ++++++--- phpseclib/Crypt/Blowfish.php | 40 ++++++++++++++++++++++++++++++++++-- phpseclib/Crypt/DES.php | 4 ++-- phpseclib/Crypt/Rijndael.php | 39 ++++++++++++++++++++--------------- phpseclib/Crypt/Twofish.php | 36 ++++++++++++++++++++++++++++++++ 5 files changed, 105 insertions(+), 24 deletions(-) diff --git a/phpseclib/Crypt/Base.php b/phpseclib/Crypt/Base.php index 8033394c..83cab630 100644 --- a/phpseclib/Crypt/Base.php +++ b/phpseclib/Crypt/Base.php @@ -530,13 +530,17 @@ class Crypt_Base $this->use_inline_crypt = version_compare(PHP_VERSION, '5.3.0') >= 0 || function_exists('create_function'); } + if (!defined('PHP_INT_SIZE')) { + define('PHP_INT_SIZE', 4); + } + if (!defined('CRYPT_BASE_USE_REG_INTVAL')) { switch (true) { // PHP 5.3, per http://php.net/releases/5_3_0.php, introduced "more consistent float rounding" case version_compare(PHP_VERSION, '5.3.0') >= 0 && (php_uname('m') & "\xDF\xDF\xDF") != 'ARM': // PHP_OS & "\xDF\xDF\xDF" == strtoupper(substr(PHP_OS, 0, 3)), but a lot faster case (PHP_OS & "\xDF\xDF\xDF") === 'WIN': - case defined('PHP_INT_SIZE') && PHP_INT_SIZE == 8: + case PHP_INT_SIZE == 8: define('CRYPT_BASE_USE_REG_INTVAL', true); break; case (php_uname('m') & "\xDF\xDF\xDF") == 'ARM': @@ -2709,7 +2713,7 @@ class Crypt_Base */ function safe_intval($x) { - if (!CRYPT_BASE_USE_REG_INTVAL || is_int($x)) { + if (is_int($x)) { return $x; } return (fmod($x, 0x80000000) & 0x7FFFFFFF) | @@ -2725,7 +2729,7 @@ class Crypt_Base function safe_intval_inline() { if (CRYPT_BASE_USE_REG_INTVAL) { - return '%s'; + return PHP_INT_SIZE == 4 ? 'intval(%s)' : '%s'; } $safeint = '(is_int($temp = %s) ? $temp : (fmod($temp, 0x80000000) & 0x7FFFFFFF) | '; diff --git a/phpseclib/Crypt/Blowfish.php b/phpseclib/Crypt/Blowfish.php index 463cb7d6..c32bfa17 100644 --- a/phpseclib/Crypt/Blowfish.php +++ b/phpseclib/Crypt/Blowfish.php @@ -446,6 +446,41 @@ class Crypt_Blowfish extends Crypt_Base */ var $key_length = 16; + /** + * Default Constructor. + * + * Determines whether or not the mcrypt extension should be used. + * + * $mode could be: + * + * - CRYPT_MODE_ECB + * + * - CRYPT_MODE_CBC + * + * - CRYPT_MODE_CTR + * + * - CRYPT_MODE_CFB + * + * - CRYPT_MODE_OFB + * + * (or the alias constants of the chosen cipher, for example for AES: CRYPT_AES_MODE_ECB or CRYPT_AES_MODE_CBC ...) + * + * If not explicitly set, CRYPT_MODE_CBC will be used. + * + * @param int $mode + * @access public + */ + function __construct($mode = CRYPT_MODE_CBC) + { + parent::__construct($mode); + + $this->sbox0 = array_map('intval', $this->sbox0); + $this->sbox1 = array_map('intval', $this->sbox1); + $this->sbox2 = array_map('intval', $this->sbox2); + $this->sbox3 = array_map('intval', $this->sbox3); + $this->parray = array_map('intval', $this->parray); + } + /** * Sets the key length. * @@ -530,7 +565,7 @@ class Crypt_Blowfish extends Crypt_Base $j = 0; } } - $this->bctx['p'][] = $this->parray[$i] ^ $data; + $this->bctx['p'][] = $this->parray[$i] ^ intval($data); } // encrypt the zero-string, replace P1 and P2 with the encrypted data, @@ -601,7 +636,8 @@ class Crypt_Blowfish extends Crypt_Base */ function bcrypt_pbkdf($pass, $salt, $keylen, $rounds) { - if (!CRYPT_BASE_USE_REG_INTVAL) { + if (PHP_INT_SIZE == 4) { + user_error('bcrypt is far too slow to be practical on 32-bit versions of PHP'); return false; } diff --git a/phpseclib/Crypt/DES.php b/phpseclib/Crypt/DES.php index 4c574018..093657f6 100644 --- a/phpseclib/Crypt/DES.php +++ b/phpseclib/Crypt/DES.php @@ -1319,9 +1319,9 @@ class Crypt_DES extends Crypt_Base $pc2mapd3[($d >> 8) & 0xFF] | $pc2mapd4[ $d & 0xFF]; // Reorder: odd bytes/even bytes. Push the result in key schedule. - $val1 = ( $cp & 0xFF000000) | (($cp << 8) & 0x00FF0000) | + $val1 = ( $cp & intval(0xFF000000)) | (($cp << 8) & 0x00FF0000) | (($dp >> 16) & 0x0000FF00) | (($dp >> 8) & 0x000000FF); - $val2 = (($cp << 8) & 0xFF000000) | (($cp << 16) & 0x00FF0000) | + $val2 = (($cp << 8) & intval(0xFF000000)) | (($cp << 16) & 0x00FF0000) | (($dp >> 8) & 0x0000FF00) | ( $dp & 0x000000FF); $keys[$des_round][CRYPT_DES_ENCRYPT][ ] = $val1; $keys[$des_round][CRYPT_DES_DECRYPT][$ki - 1] = $val1; diff --git a/phpseclib/Crypt/Rijndael.php b/phpseclib/Crypt/Rijndael.php index 56bc4e9a..a8068b7b 100644 --- a/phpseclib/Crypt/Rijndael.php +++ b/phpseclib/Crypt/Rijndael.php @@ -454,7 +454,7 @@ class Crypt_Rijndael extends Crypt_Base $k = $c[2]; $l = $c[3]; while ($i < $Nb) { - $temp[$i] = ($state[$i] & 0xFF000000) ^ + $temp[$i] = ($state[$i] & intval(0xFF000000)) ^ ($state[$j] & 0x00FF0000) ^ ($state[$k] & 0x0000FF00) ^ ($state[$l] & 0x000000FF) ^ @@ -540,7 +540,7 @@ class Crypt_Rijndael extends Crypt_Base $l = $Nb - $c[3]; while ($i < $Nb) { - $word = ($state[$i] & 0xFF000000) | + $word = ($state[$i] & intval(0xFF000000)) | ($state[$j] & 0x00FF0000) | ($state[$k] & 0x0000FF00) | ($state[$l] & 0x000000FF); @@ -579,14 +579,19 @@ class Crypt_Rijndael extends Crypt_Base { // Each number in $rcon is equal to the previous number multiplied by two in Rijndael's finite field. // See http://en.wikipedia.org/wiki/Finite_field_arithmetic#Multiplicative_inverse - static $rcon = array(0, - 0x01000000, 0x02000000, 0x04000000, 0x08000000, 0x10000000, - 0x20000000, 0x40000000, 0x80000000, 0x1B000000, 0x36000000, - 0x6C000000, 0xD8000000, 0xAB000000, 0x4D000000, 0x9A000000, - 0x2F000000, 0x5E000000, 0xBC000000, 0x63000000, 0xC6000000, - 0x97000000, 0x35000000, 0x6A000000, 0xD4000000, 0xB3000000, - 0x7D000000, 0xFA000000, 0xEF000000, 0xC5000000, 0x91000000 - ); + static $rcon; + + if (!isset($rcon)) { + $rcon = array(0, + 0x01000000, 0x02000000, 0x04000000, 0x08000000, 0x10000000, + 0x20000000, 0x40000000, 0x80000000, 0x1B000000, 0x36000000, + 0x6C000000, 0xD8000000, 0xAB000000, 0x4D000000, 0x9A000000, + 0x2F000000, 0x5E000000, 0xBC000000, 0x63000000, 0xC6000000, + 0x97000000, 0x35000000, 0x6A000000, 0xD4000000, 0xB3000000, + 0x7D000000, 0xFA000000, 0xEF000000, 0xC5000000, 0x91000000 + ); + $rcon = array_map('intval', $rcon); + } if (isset($this->kl['key']) && $this->key === $this->kl['key'] && $this->key_length === $this->kl['key_length'] && $this->block_size === $this->kl['block_size']) { // already expanded @@ -625,7 +630,7 @@ class Crypt_Rijndael extends Crypt_Base // on a 32-bit machine, it's 32-bits, and on a 64-bit machine, it's 64-bits. on a 32-bit machine, // 0xFFFFFFFF << 8 == 0xFFFFFF00, but on a 64-bit machine, it equals 0xFFFFFFFF00. as such, doing 'and' // with 0xFFFFFFFF (or 0xFFFFFF00) on a 32-bit machine is unnecessary, but on a 64-bit machine, it is. - $temp = (($temp << 8) & 0xFFFFFF00) | (($temp >> 24) & 0x000000FF); // rotWord + $temp = (($temp << 8) & intval(0xFFFFFF00)) | (($temp >> 24) & 0x000000FF); // rotWord $temp = $this->_subWord($temp) ^ $rcon[$i / $this->Nk]; } elseif ($this->Nk > 6 && $i % $this->Nk == 4) { $temp = $this->_subWord($temp); @@ -755,9 +760,9 @@ class Crypt_Rijndael extends Crypt_Base )); foreach ($t3 as $t3i) { - $t0[] = (($t3i << 24) & 0xFF000000) | (($t3i >> 8) & 0x00FFFFFF); - $t1[] = (($t3i << 16) & 0xFFFF0000) | (($t3i >> 16) & 0x0000FFFF); - $t2[] = (($t3i << 8) & 0xFFFFFF00) | (($t3i >> 24) & 0x000000FF); + $t0[] = (($t3i << 24) & intval(0xFF000000)) | (($t3i >> 8) & 0x00FFFFFF); + $t1[] = (($t3i << 16) & intval(0xFFFF0000)) | (($t3i >> 16) & 0x0000FFFF); + $t2[] = (($t3i << 8) & intval(0xFFFFFF00)) | (($t3i >> 24) & 0x000000FF); } $tables = array( @@ -839,9 +844,9 @@ class Crypt_Rijndael extends Crypt_Base )); foreach ($dt3 as $dt3i) { - $dt0[] = (($dt3i << 24) & 0xFF000000) | (($dt3i >> 8) & 0x00FFFFFF); - $dt1[] = (($dt3i << 16) & 0xFFFF0000) | (($dt3i >> 16) & 0x0000FFFF); - $dt2[] = (($dt3i << 8) & 0xFFFFFF00) | (($dt3i >> 24) & 0x000000FF); + $dt0[] = (($dt3i << 24) & intval(0xFF000000)) | (($dt3i >> 8) & 0x00FFFFFF); + $dt1[] = (($dt3i << 16) & intval(0xFFFF0000)) | (($dt3i >> 16) & 0x0000FFFF); + $dt2[] = (($dt3i << 8) & intval(0xFFFFFF00)) | (($dt3i >> 24) & 0x000000FF); }; $tables = array( diff --git a/phpseclib/Crypt/Twofish.php b/phpseclib/Crypt/Twofish.php index f33cbdf8..69148ba0 100644 --- a/phpseclib/Crypt/Twofish.php +++ b/phpseclib/Crypt/Twofish.php @@ -441,6 +441,42 @@ class Crypt_Twofish extends Crypt_Base */ var $key_length = 16; + /** + * Default Constructor. + * + * Determines whether or not the mcrypt extension should be used. + * + * $mode could be: + * + * - CRYPT_MODE_ECB + * + * - CRYPT_MODE_CBC + * + * - CRYPT_MODE_CTR + * + * - CRYPT_MODE_CFB + * + * - CRYPT_MODE_OFB + * + * (or the alias constants of the chosen cipher, for example for AES: CRYPT_AES_MODE_ECB or CRYPT_AES_MODE_CBC ...) + * + * If not explicitly set, CRYPT_MODE_CBC will be used. + * + * @param int $mode + * @access public + */ + function __construct($mode = CRYPT_MODE_CBC) + { + parent::__construct($mode); + + $this->m0 = array_map('intval', $this->m0); + $this->m1 = array_map('intval', $this->m1); + $this->m2 = array_map('intval', $this->m2); + $this->m3 = array_map('intval', $this->m3); + $this->q0 = array_map('intval', $this->q0); + $this->q1 = array_map('intval', $this->q1); + } + /** * Sets the key length. * From 8dbb8667f1d2b814e86b2bd032495de7c0f617c3 Mon Sep 17 00:00:00 2001 From: terrafrost Date: Sun, 28 Aug 2022 11:03:15 -0500 Subject: [PATCH 2/2] fix bad merge --- phpseclib/Crypt/Blowfish.php | 2 +- phpseclib/Crypt/Twofish.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/phpseclib/Crypt/Blowfish.php b/phpseclib/Crypt/Blowfish.php index eca53aae..78e6367e 100644 --- a/phpseclib/Crypt/Blowfish.php +++ b/phpseclib/Crypt/Blowfish.php @@ -397,7 +397,7 @@ class Blowfish extends Base * @param int $mode * @access public */ - function __construct($mode = CRYPT_MODE_CBC) + function __construct($mode = self::MODE_CBC) { parent::__construct($mode); diff --git a/phpseclib/Crypt/Twofish.php b/phpseclib/Crypt/Twofish.php index 458b871c..1c020481 100644 --- a/phpseclib/Crypt/Twofish.php +++ b/phpseclib/Crypt/Twofish.php @@ -392,7 +392,7 @@ class Twofish extends Base * @param int $mode * @access public */ - function __construct($mode = CRYPT_MODE_CBC) + function __construct($mode = self::MODE_CBC) { parent::__construct($mode);