From 3360d50bc206d365ec4cfee218108882d789f27d Mon Sep 17 00:00:00 2001 From: Alex Shiels Date: Fri, 17 May 2019 10:57:19 +0000 Subject: [PATCH] Upgrade/Install: Update sodium_compat to v1.10.0. This adds a runtime_speed_test() method for estimating if the 32-bit implementation is fast enough for expensive computations. Props paragoninitiativeenterprises. See #47186. git-svn-id: https://develop.svn.wordpress.org/trunk@45344 602fd350-edb4-49c9-b593-d223f7449a82 --- src/wp-includes/sodium_compat/LICENSE | 4 +- src/wp-includes/sodium_compat/composer.json | 2 +- .../sodium_compat/lib/php72compat.php | 16 +- .../sodium_compat/lib/sodium_compat.php | 41 ++--- .../sodium_compat/namespaced/Core/Salsa20.php | 4 +- .../namespaced/Core/Xsalsa20.php | 2 +- src/wp-includes/sodium_compat/src/Compat.php | 103 +++++++++--- .../sodium_compat/src/Core/BLAKE2b.php | 3 +- .../sodium_compat/src/Core/ChaCha20/Ctx.php | 7 +- .../sodium_compat/src/Core/Curve25519/Fe.php | 24 +-- .../sodium_compat/src/Core/Util.php | 2 +- .../sodium_compat/src/Core32/BLAKE2b.php | 2 +- .../sodium_compat/src/Core32/ChaCha20/Ctx.php | 6 +- .../sodium_compat/src/Core32/Int32.php | 138 +++++++++++++++- .../sodium_compat/src/Core32/Int64.php | 155 +++++++++++++++++- .../sodium_compat/src/Core32/X25519.php | 12 +- src/wp-includes/sodium_compat/src/Crypto.php | 4 +- src/wp-includes/sodium_compat/src/File.php | 10 +- 18 files changed, 427 insertions(+), 108 deletions(-) diff --git a/src/wp-includes/sodium_compat/LICENSE b/src/wp-includes/sodium_compat/LICENSE index ce41e508c0..532a3cf527 100644 --- a/src/wp-includes/sodium_compat/LICENSE +++ b/src/wp-includes/sodium_compat/LICENSE @@ -1,10 +1,10 @@ /* * ISC License * - * Copyright (c) 2016-2019 + * Copyright (c) 2016-2018 * Paragon Initiative Enterprises * - * Copyright (c) 2013-2019 + * Copyright (c) 2013-2018 * Frank Denis * * Permission to use, copy, modify, and/or distribute this software for any diff --git a/src/wp-includes/sodium_compat/composer.json b/src/wp-includes/sodium_compat/composer.json index 075b8b3040..b69808d922 100644 --- a/src/wp-includes/sodium_compat/composer.json +++ b/src/wp-includes/sodium_compat/composer.json @@ -50,7 +50,7 @@ "files": ["autoload.php"] }, "require": { - "php": "^5.2.4|^5.3|^5.4|^5.5|^5.6|^7", + "php": "^5.2.4|^5.3|^5.4|^5.5|^5.6|^7|^8", "paragonie/random_compat": ">=1" }, "require-dev": { diff --git a/src/wp-includes/sodium_compat/lib/php72compat.php b/src/wp-includes/sodium_compat/lib/php72compat.php index 9cc53ed8d5..3074af3a68 100644 --- a/src/wp-includes/sodium_compat/lib/php72compat.php +++ b/src/wp-includes/sodium_compat/lib/php72compat.php @@ -107,7 +107,7 @@ if (!is_callable('sodium_crypto_aead_aes256gcm_decrypt')) { * @param string $assocData * @param string $nonce * @param string $key - * @return string + * @return string|bool */ function sodium_crypto_aead_aes256gcm_decrypt($message, $assocData, $nonce, $key) { @@ -153,7 +153,7 @@ if (!is_callable('sodium_crypto_aead_chacha20poly1305_decrypt')) { * @param string $assocData * @param string $nonce * @param string $key - * @return string + * @return string|bool */ function sodium_crypto_aead_chacha20poly1305_decrypt($message, $assocData, $nonce, $key) { @@ -199,7 +199,7 @@ if (!is_callable('sodium_crypto_aead_chacha20poly1305_ietf_decrypt')) { * @param string $assocData * @param string $nonce * @param string $key - * @return string + * @return string|bool */ function sodium_crypto_aead_chacha20poly1305_ietf_decrypt($message, $assocData, $nonce, $key) { @@ -245,12 +245,12 @@ if (!is_callable('sodium_crypto_aead_xchacha20poly1305_ietf_decrypt')) { * @param string $assocData * @param string $nonce * @param string $key - * @return string + * @return string|bool */ function sodium_crypto_aead_xchacha20poly1305_ietf_decrypt($message, $assocData, $nonce, $key) { try { - return ParagonIE_Sodium_Compat::crypto_aead_xchacha20poly1305_ietf_decrypt($message, $assocData, $nonce, $key); + return ParagonIE_Sodium_Compat::crypto_aead_xchacha20poly1305_ietf_decrypt($message, $assocData, $nonce, $key, true); } catch (Error $ex) { return false; } catch (Exception $ex) { @@ -271,7 +271,7 @@ if (!is_callable('sodium_crypto_aead_xchacha20poly1305_ietf_encrypt')) { */ function sodium_crypto_aead_xchacha20poly1305_ietf_encrypt($message, $assocData, $nonce, $key) { - return ParagonIE_Sodium_Compat::crypto_aead_xchacha20poly1305_ietf_encrypt($message, $assocData, $nonce, $key); + return ParagonIE_Sodium_Compat::crypto_aead_xchacha20poly1305_ietf_encrypt($message, $assocData, $nonce, $key, true); } } if (!is_callable('sodium_crypto_aead_xchacha20poly1305_ietf_keygen')) { @@ -952,7 +952,7 @@ if (!is_callable('sodium_hex2bin')) { if (!is_callable('sodium_increment')) { /** * @see ParagonIE_Sodium_Compat::increment() - * @param &string $string + * @param string $string * @return void * @throws SodiumException * @throws TypeError @@ -1009,7 +1009,7 @@ if (!is_callable('sodium_memcmp')) { if (!is_callable('sodium_memzero')) { /** * @see ParagonIE_Sodium_Compat::memzero() - * @param string &$str + * @param string $str * @return void * @throws SodiumException * @throws TypeError diff --git a/src/wp-includes/sodium_compat/lib/sodium_compat.php b/src/wp-includes/sodium_compat/lib/sodium_compat.php index 1799bb57e3..ec5e5b5b51 100644 --- a/src/wp-includes/sodium_compat/lib/sodium_compat.php +++ b/src/wp-includes/sodium_compat/lib/sodium_compat.php @@ -45,16 +45,14 @@ if (!is_callable('\\Sodium\\crypto_aead_aes256gcm_decrypt')) { * @param string $nonce * @param string $key * @return string|bool - * @throws \SodiumException - * @throws \TypeError */ function crypto_aead_aes256gcm_decrypt($message, $assocData, $nonce, $key) { try { return ParagonIE_Sodium_Compat::crypto_aead_aes256gcm_decrypt($message, $assocData, $nonce, $key); - } catch (Error $ex) { + } catch (\TypeError $ex) { return false; - } catch (Exception $ex) { + } catch (\SodiumException $ex) { return false; } } @@ -93,16 +91,14 @@ if (!is_callable('\\Sodium\\crypto_aead_chacha20poly1305_decrypt')) { * @param string $nonce * @param string $key * @return string|bool - * @throws \SodiumException - * @throws \TypeError */ function crypto_aead_chacha20poly1305_decrypt($message, $assocData, $nonce, $key) { try { return ParagonIE_Sodium_Compat::crypto_aead_chacha20poly1305_decrypt($message, $assocData, $nonce, $key); - } catch (Error $ex) { + } catch (\TypeError $ex) { return false; - } catch (Exception $ex) { + } catch (\SodiumException $ex) { return false; } } @@ -131,16 +127,14 @@ if (!is_callable('\\Sodium\\crypto_aead_chacha20poly1305_ietf_decrypt')) { * @param string $nonce * @param string $key * @return string|bool - * @throws \SodiumException - * @throws \TypeError */ function crypto_aead_chacha20poly1305_ietf_decrypt($message, $assocData, $nonce, $key) { try { return ParagonIE_Sodium_Compat::crypto_aead_chacha20poly1305_ietf_decrypt($message, $assocData, $nonce, $key); - } catch (Error $ex) { + } catch (\TypeError $ex) { return false; - } catch (Exception $ex) { + } catch (\SodiumException $ex) { return false; } } @@ -238,16 +232,14 @@ if (!is_callable('\\Sodium\\crypto_box_open')) { * @param string $nonce * @param string $kp * @return string|bool - * @throws \SodiumException - * @throws \TypeError */ function crypto_box_open($message, $nonce, $kp) { try { return ParagonIE_Sodium_Compat::crypto_box_open($message, $nonce, $kp); - } catch (Error $ex) { + } catch (\TypeError $ex) { return false; - } catch (Exception $ex) { + } catch (\SodiumException $ex) { return false; } } @@ -298,15 +290,14 @@ if (!is_callable('\\Sodium\\crypto_box_seal_open')) { * @param string $message * @param string $kp * @return string|bool - * @throws \TypeError */ function crypto_box_seal_open($message, $kp) { try { return ParagonIE_Sodium_Compat::crypto_box_seal_open($message, $kp); - } catch (\Error $ex) { + } catch (\TypeError $ex) { return false; - } catch (\Exception $ex) { + } catch (\SodiumException $ex) { return false; } } @@ -543,16 +534,14 @@ if (!is_callable('\\Sodium\\crypto_secretbox_open')) { * @param string $nonce * @param string $key * @return string|bool - * @throws \SodiumException - * @throws \TypeError */ function crypto_secretbox_open($message, $nonce, $key) { try { return ParagonIE_Sodium_Compat::crypto_secretbox_open($message, $nonce, $key); - } catch (Error $ex) { + } catch (\TypeError $ex) { return false; - } catch (Exception $ex) { + } catch (\SodiumException $ex) { return false; } } @@ -622,9 +611,9 @@ if (!is_callable('\\Sodium\\crypto_sign_open')) { { try { return ParagonIE_Sodium_Compat::crypto_sign_open($signedMessage, $pk); - } catch (\Error $ex) { + } catch (\TypeError $ex) { return false; - } catch (\Exception $ex) { + } catch (\SodiumException $ex) { return false; } } @@ -810,7 +799,7 @@ if (!is_callable('\\Sodium\\randombytes_uniform')) { * @see ParagonIE_Sodium_Compat::randombytes_uniform() * @param int $upperLimit * @return int - * @throws \Exception + * @throws \SodiumException * @throws \Error */ function randombytes_uniform($upperLimit) diff --git a/src/wp-includes/sodium_compat/namespaced/Core/Salsa20.php b/src/wp-includes/sodium_compat/namespaced/Core/Salsa20.php index ac83f73967..a6112398de 100644 --- a/src/wp-includes/sodium_compat/namespaced/Core/Salsa20.php +++ b/src/wp-includes/sodium_compat/namespaced/Core/Salsa20.php @@ -1,7 +1,7 @@ 0 if the right operand is less than the left + * @return int If < 0 if the left operand is less than the right + * If = 0 if both strings are equal + * If > 0 if the right operand is less than the left * @throws SodiumException * @throws TypeError * @psalm-suppress MixedArgument @@ -669,12 +669,13 @@ class ParagonIE_Sodium_Compat * This mode uses a 64-bit random nonce with a 64-bit counter. * IETF mode uses a 96-bit random nonce with a 32-bit counter. * - * @param string $ciphertext Encrypted message (with Poly1305 MAC appended) - * @param string $assocData Authenticated Associated Data (unencrypted) - * @param string $nonce Number to be used only Once; must be 8 bytes - * @param string $key Encryption key + * @param string $ciphertext Encrypted message (with Poly1305 MAC appended) + * @param string $assocData Authenticated Associated Data (unencrypted) + * @param string $nonce Number to be used only Once; must be 8 bytes + * @param string $key Encryption key + * @param bool $dontFallback Don't fallback to ext/sodium * - * @return string The original plaintext message + * @return string|bool The original plaintext message * @throws SodiumException * @throws TypeError * @psalm-suppress MixedArgument @@ -683,7 +684,8 @@ class ParagonIE_Sodium_Compat $ciphertext = '', $assocData = '', $nonce = '', - $key = '' + $key = '', + $dontFallback = false ) { /* Type checks: */ ParagonIE_Sodium_Core_Util::declareScalarType($ciphertext, 'string', 1); @@ -701,6 +703,16 @@ class ParagonIE_Sodium_Compat if (ParagonIE_Sodium_Core_Util::strlen($ciphertext) < self::CRYPTO_AEAD_XCHACHA20POLY1305_IETF_ABYTES) { throw new SodiumException('Message must be at least CRYPTO_AEAD_XCHACHA20POLY1305_IETF_ABYTES long'); } + if (self::useNewSodiumAPI() && !$dontFallback) { + if (is_callable('sodium_crypto_aead_xchacha20poly1305_ietf_decrypt')) { + return sodium_crypto_aead_xchacha20poly1305_ietf_decrypt( + $ciphertext, + $assocData, + $nonce, + $key + ); + } + } if (PHP_INT_SIZE === 4) { return ParagonIE_Sodium_Crypto32::aead_xchacha20poly1305_ietf_decrypt( @@ -727,10 +739,11 @@ class ParagonIE_Sodium_Compat * This mode uses a 64-bit random nonce with a 64-bit counter. * IETF mode uses a 96-bit random nonce with a 32-bit counter. * - * @param string $plaintext Message to be encrypted - * @param string $assocData Authenticated Associated Data (unencrypted) - * @param string $nonce Number to be used only Once; must be 8 bytes - * @param string $key Encryption key + * @param string $plaintext Message to be encrypted + * @param string $assocData Authenticated Associated Data (unencrypted) + * @param string $nonce Number to be used only Once; must be 8 bytes + * @param string $key Encryption key + * @param bool $dontFallback Don't fallback to ext/sodium * * @return string Ciphertext with a 16-byte Poly1305 message * authentication code appended @@ -742,7 +755,8 @@ class ParagonIE_Sodium_Compat $plaintext = '', $assocData = '', $nonce = '', - $key = '' + $key = '', + $dontFallback = false ) { /* Type checks: */ ParagonIE_Sodium_Core_Util::declareScalarType($plaintext, 'string', 1); @@ -757,6 +771,16 @@ class ParagonIE_Sodium_Compat if (ParagonIE_Sodium_Core_Util::strlen($key) !== self::CRYPTO_AEAD_XCHACHA20POLY1305_IETF_KEYBYTES) { throw new SodiumException('Key must be CRYPTO_AEAD_XCHACHA20POLY1305_KEYBYTES long'); } + if (self::useNewSodiumAPI() && !$dontFallback) { + if (is_callable('sodium_crypto_aead_xchacha20poly1305_ietf_encrypt')) { + return sodium_crypto_aead_xchacha20poly1305_ietf_encrypt( + $plaintext, + $assocData, + $nonce, + $key + ); + } + } if (PHP_INT_SIZE === 4) { return ParagonIE_Sodium_Crypto32::aead_xchacha20poly1305_ietf_encrypt( @@ -1279,12 +1303,13 @@ class ParagonIE_Sodium_Compat /** * Get the final BLAKE2b hash output for a given context. * - * @param string &$ctx BLAKE2 hashing context. Generated by crypto_generichash_init(). - * @param int $length Hash output size. - * @return string Final BLAKE2b hash. + * @param string $ctx BLAKE2 hashing context. Generated by crypto_generichash_init(). + * @param int $length Hash output size. + * @return string Final BLAKE2b hash. * @throws SodiumException * @throws TypeError * @psalm-suppress MixedArgument + * @psalm-suppress ReferenceConstraintViolation */ public static function crypto_generichash_final(&$ctx, $length = self::CRYPTO_GENERICHASH_BYTES) { @@ -1357,13 +1382,15 @@ class ParagonIE_Sodium_Compat /** * Update a BLAKE2b hashing context with additional data. * - * @param string &$ctx BLAKE2 hashing context. Generated by crypto_generichash_init(). - * $ctx is passed by reference and gets updated in-place. + * @param string $ctx BLAKE2 hashing context. Generated by crypto_generichash_init(). + * $ctx is passed by reference and gets updated in-place. + * @param-out string $ctx * @param string $message The message to append to the existing hash state. * @return void * @throws SodiumException * @throws TypeError * @psalm-suppress MixedArgument + * @psalm-suppress ReferenceConstraintViolation */ public static function crypto_generichash_update(&$ctx, $message) { @@ -2610,6 +2637,7 @@ class ParagonIE_Sodium_Compat * native library for that. * * @param string|null $var + * @param-out string|null $var * * @return void * @throws SodiumException (Unless libsodium is installed) @@ -2622,6 +2650,7 @@ class ParagonIE_Sodium_Compat ParagonIE_Sodium_Core_Util::declareScalarType($var, 'string', 1); if (self::useNewSodiumAPI()) { + /** @psalm-suppress MixedArgument */ sodium_memzero($var); return; } @@ -2725,6 +2754,42 @@ class ParagonIE_Sodium_Compat return random_int(0, 65535); } + /** + * Runtime testing method for 32-bit platforms. + * + * Usage: If runtime_speed_test() returns FALSE, then our 32-bit + * implementation is to slow to use safely without risking timeouts. + * If this happens, install sodium from PECL to get acceptable + * performance. + * + * @param int $iterations Number of multiplications to attempt + * @param int $maxTimeout Milliseconds + * @return bool TRUE if we're fast enough, FALSE is not + * @throws SodiumException + */ + public static function runtime_speed_test($iterations, $maxTimeout) + { + if (self::polyfill_is_fast()) { + return true; + } + /** @var float $end */ + $end = 0.0; + /** @var float $start */ + $start = microtime(true); + /** @var ParagonIE_Sodium_Core32_Int64 $a */ + $a = ParagonIE_Sodium_Core32_Int64::fromInt(random_int(3, 1 << 16)); + for ($i = 0; $i < $iterations; ++$i) { + /** @var ParagonIE_Sodium_Core32_Int64 $b */ + $b = ParagonIE_Sodium_Core32_Int64::fromInt(random_int(3, 1 << 16)); + $a->mulInt64($b); + } + /** @var float $end */ + $end = microtime(true); + /** @var int $diff */ + $diff = (int) ceil(($end - $start) * 1000); + return $diff < $maxTimeout; + } + /** * This emulates libsodium's version_string() function, except ours is * prefixed with 'polyfill-'. diff --git a/src/wp-includes/sodium_compat/src/Core/BLAKE2b.php b/src/wp-includes/sodium_compat/src/Core/BLAKE2b.php index f0369df0c8..5d295ce615 100644 --- a/src/wp-includes/sodium_compat/src/Core/BLAKE2b.php +++ b/src/wp-includes/sodium_compat/src/Core/BLAKE2b.php @@ -256,6 +256,7 @@ abstract class ParagonIE_Sodium_Core_BLAKE2b extends ParagonIE_Sodium_Core_Util if (++$i > $maxLength) { return; } + /** @psalm-suppress MixedOperand */ $u[$uIdx] >>= 8; } } @@ -642,7 +643,7 @@ abstract class ParagonIE_Sodium_Core_BLAKE2b extends ParagonIE_Sodium_Core_Util /** * @internal You should not use this directly from another application * - * @param SplFixedArray[SplFixedArray] $ctx + * @param SplFixedArray $ctx * @return string * @throws TypeError * @psalm-suppress MixedArgument diff --git a/src/wp-includes/sodium_compat/src/Core/ChaCha20/Ctx.php b/src/wp-includes/sodium_compat/src/Core/ChaCha20/Ctx.php index b29ab90054..47a42b70de 100644 --- a/src/wp-includes/sodium_compat/src/Core/ChaCha20/Ctx.php +++ b/src/wp-includes/sodium_compat/src/Core/ChaCha20/Ctx.php @@ -83,9 +83,8 @@ class ParagonIE_Sodium_Core_ChaCha20_Ctx extends ParagonIE_Sodium_Core_Util impl /** * @internal You should not use this directly from another application * - * @param mixed $offset + * @param int $offset * @return bool - * @psalm-suppress MixedArrayOffset */ public function offsetExists($offset) { @@ -95,7 +94,7 @@ class ParagonIE_Sodium_Core_ChaCha20_Ctx extends ParagonIE_Sodium_Core_Util impl /** * @internal You should not use this directly from another application * - * @param mixed $offset + * @param int $offset * @return void * @psalm-suppress MixedArrayOffset */ @@ -107,7 +106,7 @@ class ParagonIE_Sodium_Core_ChaCha20_Ctx extends ParagonIE_Sodium_Core_Util impl /** * @internal You should not use this directly from another application * - * @param mixed $offset + * @param int $offset * @return mixed|null * @psalm-suppress MixedArrayOffset */ diff --git a/src/wp-includes/sodium_compat/src/Core/Curve25519/Fe.php b/src/wp-includes/sodium_compat/src/Core/Curve25519/Fe.php index 881e3695a1..64c489ae08 100644 --- a/src/wp-includes/sodium_compat/src/Core/Curve25519/Fe.php +++ b/src/wp-includes/sodium_compat/src/Core/Curve25519/Fe.php @@ -12,7 +12,7 @@ if (class_exists('ParagonIE_Sodium_Core_Curve25519_Fe', false)) { class ParagonIE_Sodium_Core_Curve25519_Fe implements ArrayAccess { /** - * @var array + * @var array */ protected $container = array(); @@ -24,7 +24,7 @@ class ParagonIE_Sodium_Core_Curve25519_Fe implements ArrayAccess /** * @internal You should not use this directly from another application * - * @param array $array + * @param array $array * @param bool $save_indexes * @return self */ @@ -37,6 +37,7 @@ class ParagonIE_Sodium_Core_Curve25519_Fe implements ArrayAccess $keys = range(0, $count - 1); } $array = array_values($array); + /** @var array $keys */ $obj = new ParagonIE_Sodium_Core_Curve25519_Fe(); if ($save_indexes) { @@ -54,8 +55,8 @@ class ParagonIE_Sodium_Core_Curve25519_Fe implements ArrayAccess /** * @internal You should not use this directly from another application * - * @param mixed $offset - * @param mixed $value + * @param int|null $offset + * @param int $value * @return void * @psalm-suppress MixedArrayOffset */ @@ -74,7 +75,7 @@ class ParagonIE_Sodium_Core_Curve25519_Fe implements ArrayAccess /** * @internal You should not use this directly from another application * - * @param mixed $offset + * @param int $offset * @return bool * @psalm-suppress MixedArrayOffset */ @@ -86,7 +87,7 @@ class ParagonIE_Sodium_Core_Curve25519_Fe implements ArrayAccess /** * @internal You should not use this directly from another application * - * @param mixed $offset + * @param int $offset * @return void * @psalm-suppress MixedArrayOffset */ @@ -98,15 +99,16 @@ class ParagonIE_Sodium_Core_Curve25519_Fe implements ArrayAccess /** * @internal You should not use this directly from another application * - * @param mixed $offset - * @return mixed|null + * @param int $offset + * @return int * @psalm-suppress MixedArrayOffset */ public function offsetGet($offset) { - return isset($this->container[$offset]) - ? $this->container[$offset] - : null; + if (!isset($this->container[$offset])) { + $this->container[$offset] = 0; + } + return (int) ($this->container[$offset]); } /** diff --git a/src/wp-includes/sodium_compat/src/Core/Util.php b/src/wp-includes/sodium_compat/src/Core/Util.php index 5caa3ffa32..a5808b191d 100644 --- a/src/wp-includes/sodium_compat/src/Core/Util.php +++ b/src/wp-includes/sodium_compat/src/Core/Util.php @@ -817,7 +817,7 @@ abstract class ParagonIE_Sodium_Core_Util } else { $sub = (string) substr($str, $start, $length); } - if (isset($sub)) { + if ($sub !== '') { return $sub; } return ''; diff --git a/src/wp-includes/sodium_compat/src/Core32/BLAKE2b.php b/src/wp-includes/sodium_compat/src/Core32/BLAKE2b.php index ee7f415d3a..f33b7b626e 100644 --- a/src/wp-includes/sodium_compat/src/Core32/BLAKE2b.php +++ b/src/wp-includes/sodium_compat/src/Core32/BLAKE2b.php @@ -574,7 +574,7 @@ abstract class ParagonIE_Sodium_Core32_BLAKE2b extends ParagonIE_Sodium_Core_Uti /** * @internal You should not use this directly from another application * - * @param SplFixedArray[SplFixedArray] $ctx + * @param SplFixedArray $ctx * @return string * @throws TypeError * @psalm-suppress MixedArgument diff --git a/src/wp-includes/sodium_compat/src/Core32/ChaCha20/Ctx.php b/src/wp-includes/sodium_compat/src/Core32/ChaCha20/Ctx.php index 996acf23e5..3f47d03b00 100644 --- a/src/wp-includes/sodium_compat/src/Core32/ChaCha20/Ctx.php +++ b/src/wp-includes/sodium_compat/src/Core32/ChaCha20/Ctx.php @@ -89,7 +89,7 @@ class ParagonIE_Sodium_Core32_ChaCha20_Ctx extends ParagonIE_Sodium_Core32_Util /** * @internal You should not use this directly from another application * - * @param mixed $offset + * @param int $offset * @return bool * @psalm-suppress MixedArrayOffset */ @@ -101,7 +101,7 @@ class ParagonIE_Sodium_Core32_ChaCha20_Ctx extends ParagonIE_Sodium_Core32_Util /** * @internal You should not use this directly from another application * - * @param mixed $offset + * @param int $offset * @return void * @psalm-suppress MixedArrayOffset */ @@ -113,7 +113,7 @@ class ParagonIE_Sodium_Core32_ChaCha20_Ctx extends ParagonIE_Sodium_Core32_Util /** * @internal You should not use this directly from another application * - * @param mixed $offset + * @param int $offset * @return mixed|null * @psalm-suppress MixedArrayOffset */ diff --git a/src/wp-includes/sodium_compat/src/Core32/Int32.php b/src/wp-includes/sodium_compat/src/Core32/Int32.php index 68c4b55f44..c3a17900a5 100644 --- a/src/wp-includes/sodium_compat/src/Core32/Int32.php +++ b/src/wp-includes/sodium_compat/src/Core32/Int32.php @@ -150,6 +150,136 @@ class ParagonIE_Sodium_Core32_Int32 ); } + /** + * @param array $a + * @param array $b + * @param int $baseLog2 + * @return array + */ + public function multiplyLong(array $a, array $b, $baseLog2 = 16) + { + $a_l = count($a); + $b_l = count($b); + /** @var array $r */ + $r = array_fill(0, $a_l + $b_l + 1, 0); + $base = 1 << $baseLog2; + for ($i = 0; $i < $a_l; ++$i) { + $a_i = $a[$i]; + for ($j = 0; $j < $a_l; ++$j) { + $b_j = $b[$j]; + $product = ($a_i * $b_j) + $r[$i + $j]; + $carry = ($product >> $baseLog2 & 0xffff); + $r[$i + $j] = ($product - (int) ($carry * $base)) & 0xffff; + $r[$i + $j + 1] += $carry; + } + } + return array_slice($r, 0, 5); + } + + /** + * @param int $int + * @return ParagonIE_Sodium_Core32_Int32 + */ + public function mulIntFast($int) + { + // Handle negative numbers + $aNeg = ($this->limbs[0] >> 15) & 1; + $bNeg = ($int >> 31) & 1; + $a = array_reverse($this->limbs); + $b = array( + $int & 0xffff, + ($int >> 16) & 0xffff + ); + if ($aNeg) { + for ($i = 0; $i < 2; ++$i) { + $a[$i] = ($a[$i] ^ 0xffff) & 0xffff; + } + ++$a[0]; + } + if ($bNeg) { + for ($i = 0; $i < 2; ++$i) { + $b[$i] = ($b[$i] ^ 0xffff) & 0xffff; + } + ++$b[0]; + } + // Multiply + $res = $this->multiplyLong($a, $b); + + // Re-apply negation to results + if ($aNeg !== $bNeg) { + for ($i = 0; $i < 2; ++$i) { + $res[$i] = (0xffff ^ $res[$i]) & 0xffff; + } + // Handle integer overflow + $c = 1; + for ($i = 0; $i < 2; ++$i) { + $res[$i] += $c; + $c = $res[$i] >> 16; + $res[$i] &= 0xffff; + } + } + + // Return our values + $return = new ParagonIE_Sodium_Core32_Int32(); + $return->limbs = array( + $res[1] & 0xffff, + $res[0] & 0xffff + ); + if (count($res) > 2) { + $return->overflow = $res[2] & 0xffff; + } + $return->unsignedInt = $this->unsignedInt; + return $return; + } + + /** + * @param ParagonIE_Sodium_Core32_Int32 $right + * @return ParagonIE_Sodium_Core32_Int32 + */ + public function mulInt32Fast(ParagonIE_Sodium_Core32_Int32 $right) + { + $aNeg = ($this->limbs[0] >> 15) & 1; + $bNeg = ($right->limbs[0] >> 15) & 1; + + $a = array_reverse($this->limbs); + $b = array_reverse($right->limbs); + if ($aNeg) { + for ($i = 0; $i < 2; ++$i) { + $a[$i] = ($a[$i] ^ 0xffff) & 0xffff; + } + ++$a[0]; + } + if ($bNeg) { + for ($i = 0; $i < 2; ++$i) { + $b[$i] = ($b[$i] ^ 0xffff) & 0xffff; + } + ++$b[0]; + } + $res = $this->multiplyLong($a, $b); + if ($aNeg !== $bNeg) { + if ($aNeg !== $bNeg) { + for ($i = 0; $i < 2; ++$i) { + $res[$i] = ($res[$i] ^ 0xffff) & 0xffff; + } + $c = 1; + for ($i = 0; $i < 2; ++$i) { + $res[$i] += $c; + $c = $res[$i] >> 16; + $res[$i] &= 0xffff; + } + } + } + $return = new ParagonIE_Sodium_Core32_Int32(); + $return->limbs = array( + $res[1] & 0xffff, + $res[0] & 0xffff + ); + if (count($res) > 2) { + $return->overflow = $res[2]; + } + return $return; + } + /** * @param int $int * @param int $size @@ -161,6 +291,9 @@ class ParagonIE_Sodium_Core32_Int32 { ParagonIE_Sodium_Core32_Util::declareScalarType($int, 'int', 1); ParagonIE_Sodium_Core32_Util::declareScalarType($size, 'int', 2); + if (ParagonIE_Sodium_Compat::$fastMult) { + return $this->mulIntFast((int) $int); + } /** @var int $int */ $int = (int) $int; /** @var int $size */ @@ -218,6 +351,9 @@ class ParagonIE_Sodium_Core32_Int32 public function mulInt32(ParagonIE_Sodium_Core32_Int32 $int, $size = 0) { ParagonIE_Sodium_Core32_Util::declareScalarType($size, 'int', 2); + if (ParagonIE_Sodium_Compat::$fastMult) { + return $this->mulInt32Fast($int); + } if (!$size) { $size = 31; } @@ -491,7 +627,7 @@ class ParagonIE_Sodium_Core32_Int32 /** @var int $c */ return $this->shiftLeft(-$c); } else { - if (is_null($c)) { + if (!is_int($c)) { throw new TypeError(); } /** @var int $c */ diff --git a/src/wp-includes/sodium_compat/src/Core32/Int64.php b/src/wp-includes/sodium_compat/src/Core32/Int64.php index cc7b69f86d..dd06a3fbeb 100644 --- a/src/wp-includes/sodium_compat/src/Core32/Int64.php +++ b/src/wp-includes/sodium_compat/src/Core32/Int64.php @@ -205,6 +205,9 @@ class ParagonIE_Sodium_Core32_Int64 */ public function mulInt($int = 0, $size = 0) { + if (ParagonIE_Sodium_Compat::$fastMult) { + return $this->mulIntFast($int); + } ParagonIE_Sodium_Core32_Util::declareScalarType($int, 'int', 1); ParagonIE_Sodium_Core32_Util::declareScalarType($size, 'int', 2); /** @var int $int */ @@ -268,11 +271,11 @@ class ParagonIE_Sodium_Core32_Int64 $a3 &= 0xffff; $int >>= 1; - $return->limbs[0] = $ret0; - $return->limbs[1] = $ret1; - $return->limbs[2] = $ret2; - $return->limbs[3] = $ret3; } + $return->limbs[0] = $ret0; + $return->limbs[1] = $ret1; + $return->limbs[2] = $ret2; + $return->limbs[3] = $ret3; return $return; } @@ -317,6 +320,142 @@ class ParagonIE_Sodium_Core32_Int64 ); } + /** + * @param array $a + * @param array $b + * @param int $baseLog2 + * @return array + */ + public function multiplyLong(array $a, array $b, $baseLog2 = 16) + { + $a_l = count($a); + $b_l = count($b); + /** @var array $r */ + $r = array_fill(0, $a_l + $b_l + 1, 0); + $base = 1 << $baseLog2; + for ($i = 0; $i < $a_l; ++$i) { + $a_i = $a[$i]; + for ($j = 0; $j < $a_l; ++$j) { + $b_j = $b[$j]; + $product = ($a_i * $b_j) + $r[$i + $j]; + $carry = ($product >> $baseLog2 & 0xffff); + $r[$i + $j] = ($product - (int) ($carry * $base)) & 0xffff; + $r[$i + $j + 1] += $carry; + } + } + return array_slice($r, 0, 5); + } + + /** + * @param int $int + * @return ParagonIE_Sodium_Core32_Int64 + */ + public function mulIntFast($int) + { + // Handle negative numbers + $aNeg = ($this->limbs[0] >> 15) & 1; + $bNeg = ($int >> 31) & 1; + $a = array_reverse($this->limbs); + $b = array( + $int & 0xffff, + ($int >> 16) & 0xffff, + -$bNeg & 0xffff, + -$bNeg & 0xffff + ); + if ($aNeg) { + for ($i = 0; $i < 4; ++$i) { + $a[$i] = ($a[$i] ^ 0xffff) & 0xffff; + } + ++$a[0]; + } + if ($bNeg) { + for ($i = 0; $i < 4; ++$i) { + $b[$i] = ($b[$i] ^ 0xffff) & 0xffff; + } + ++$b[0]; + } + // Multiply + $res = $this->multiplyLong($a, $b); + + // Re-apply negation to results + if ($aNeg !== $bNeg) { + for ($i = 0; $i < 4; ++$i) { + $res[$i] = (0xffff ^ $res[$i]) & 0xffff; + } + // Handle integer overflow + $c = 1; + for ($i = 0; $i < 4; ++$i) { + $res[$i] += $c; + $c = $res[$i] >> 16; + $res[$i] &= 0xffff; + } + } + + // Return our values + $return = new ParagonIE_Sodium_Core32_Int64(); + $return->limbs = array( + $res[3] & 0xffff, + $res[2] & 0xffff, + $res[1] & 0xffff, + $res[0] & 0xffff + ); + if (count($res) > 4) { + $return->overflow = $res[4] & 0xffff; + } + $return->unsignedInt = $this->unsignedInt; + return $return; + } + + /** + * @param ParagonIE_Sodium_Core32_Int64 $right + * @return ParagonIE_Sodium_Core32_Int64 + */ + public function mulInt64Fast(ParagonIE_Sodium_Core32_Int64 $right) + { + $aNeg = ($this->limbs[0] >> 15) & 1; + $bNeg = ($right->limbs[0] >> 15) & 1; + + $a = array_reverse($this->limbs); + $b = array_reverse($right->limbs); + if ($aNeg) { + for ($i = 0; $i < 4; ++$i) { + $a[$i] = ($a[$i] ^ 0xffff) & 0xffff; + } + ++$a[0]; + } + if ($bNeg) { + for ($i = 0; $i < 4; ++$i) { + $b[$i] = ($b[$i] ^ 0xffff) & 0xffff; + } + ++$b[0]; + } + $res = $this->multiplyLong($a, $b); + if ($aNeg !== $bNeg) { + if ($aNeg !== $bNeg) { + for ($i = 0; $i < 4; ++$i) { + $res[$i] = ($res[$i] ^ 0xffff) & 0xffff; + } + $c = 1; + for ($i = 0; $i < 4; ++$i) { + $res[$i] += $c; + $c = $res[$i] >> 16; + $res[$i] &= 0xffff; + } + } + } + $return = new ParagonIE_Sodium_Core32_Int64(); + $return->limbs = array( + $res[3] & 0xffff, + $res[2] & 0xffff, + $res[1] & 0xffff, + $res[0] & 0xffff + ); + if (count($res) > 4) { + $return->overflow = $res[4]; + } + return $return; + } + /** * @param ParagonIE_Sodium_Core32_Int64 $int * @param int $size @@ -327,6 +466,9 @@ class ParagonIE_Sodium_Core32_Int64 */ public function mulInt64(ParagonIE_Sodium_Core32_Int64 $int, $size = 0) { + if (ParagonIE_Sodium_Compat::$fastMult) { + return $this->mulInt64Fast($int); + } ParagonIE_Sodium_Core32_Util::declareScalarType($size, 'int', 2); if (!$size) { $size = 63; @@ -566,7 +708,7 @@ class ParagonIE_Sodium_Core32_Int64 /** @var int $c */ return $this->shiftRight(-$c); } else { - if (is_null($c)) { + if (!is_int($c)) { throw new TypeError(); } /** @var int $carry */ @@ -591,10 +733,11 @@ class ParagonIE_Sodium_Core32_Int64 public function shiftRight($c = 0) { ParagonIE_Sodium_Core32_Util::declareScalarType($c, 'int', 1); + $c = (int) $c; + /** @var int $c */ $return = new ParagonIE_Sodium_Core32_Int64(); $return->unsignedInt = $this->unsignedInt; $c &= 63; - /** @var int $c */ $negative = -(($this->limbs[0] >> 15) & 1); if ($c >= 16) { diff --git a/src/wp-includes/sodium_compat/src/Core32/X25519.php b/src/wp-includes/sodium_compat/src/Core32/X25519.php index fd4b056a81..3eb96900c5 100644 --- a/src/wp-includes/sodium_compat/src/Core32/X25519.php +++ b/src/wp-includes/sodium_compat/src/Core32/X25519.php @@ -102,58 +102,48 @@ abstract class ParagonIE_Sodium_Core32_X25519 extends ParagonIE_Sodium_Core32_Cu */ public static function fe_mul121666(ParagonIE_Sodium_Core32_Curve25519_Fe $f) { - /** @var array $h */ + /** @var array $h */ $h = array(); for ($i = 0; $i < 10; ++$i) { $h[$i] = $f[$i]->toInt64()->mulInt(121666, 17); } - /** @var ParagonIE_Sodium_Core32_Int32 $carry9 */ $carry9 = $h[9]->addInt(1 << 24)->shiftRight(25); $h[0] = $h[0]->addInt64($carry9->mulInt(19, 5)); $h[9] = $h[9]->subInt64($carry9->shiftLeft(25)); - /** @var ParagonIE_Sodium_Core32_Int32 $carry1 */ $carry1 = $h[1]->addInt(1 << 24)->shiftRight(25); $h[2] = $h[2]->addInt64($carry1); $h[1] = $h[1]->subInt64($carry1->shiftLeft(25)); - /** @var ParagonIE_Sodium_Core32_Int32 $carry3 */ $carry3 = $h[3]->addInt(1 << 24)->shiftRight(25); $h[4] = $h[4]->addInt64($carry3); $h[3] = $h[3]->subInt64($carry3->shiftLeft(25)); - /** @var ParagonIE_Sodium_Core32_Int32 $carry5 */ $carry5 = $h[5]->addInt(1 << 24)->shiftRight(25); $h[6] = $h[6]->addInt64($carry5); $h[5] = $h[5]->subInt64($carry5->shiftLeft(25)); - /** @var ParagonIE_Sodium_Core32_Int32 $carry7 */ $carry7 = $h[7]->addInt(1 << 24)->shiftRight(25); $h[8] = $h[8]->addInt64($carry7); $h[7] = $h[7]->subInt64($carry7->shiftLeft(25)); - /** @var ParagonIE_Sodium_Core32_Int32 $carry0 */ $carry0 = $h[0]->addInt(1 << 25)->shiftRight(26); $h[1] = $h[1]->addInt64($carry0); $h[0] = $h[0]->subInt64($carry0->shiftLeft(26)); - /** @var ParagonIE_Sodium_Core32_Int32 $carry2 */ $carry2 = $h[2]->addInt(1 << 25)->shiftRight(26); $h[3] = $h[3]->addInt64($carry2); $h[2] = $h[2]->subInt64($carry2->shiftLeft(26)); - /** @var ParagonIE_Sodium_Core32_Int32 $carry4 */ $carry4 = $h[4]->addInt(1 << 25)->shiftRight(26); $h[5] = $h[5]->addInt64($carry4); $h[4] = $h[4]->subInt64($carry4->shiftLeft(26)); - /** @var ParagonIE_Sodium_Core32_Int32 $carry6 */ $carry6 = $h[6]->addInt(1 << 25)->shiftRight(26); $h[7] = $h[7]->addInt64($carry6); $h[6] = $h[6]->subInt64($carry6->shiftLeft(26)); - /** @var ParagonIE_Sodium_Core32_Int32 $carry8 */ $carry8 = $h[8]->addInt(1 << 25)->shiftRight(26); $h[9] = $h[9]->addInt64($carry8); $h[8] = $h[8]->subInt64($carry8->shiftLeft(26)); diff --git a/src/wp-includes/sodium_compat/src/Crypto.php b/src/wp-includes/sodium_compat/src/Crypto.php index 3040763229..2e3383ff6f 100644 --- a/src/wp-includes/sodium_compat/src/Crypto.php +++ b/src/wp-includes/sodium_compat/src/Crypto.php @@ -819,8 +819,8 @@ abstract class ParagonIE_Sodium_Crypto */ public static function keyExchange($my_sk, $their_pk, $client_pk, $server_pk) { - return self::generichash( - self::scalarmult($my_sk, $their_pk) . + return ParagonIE_Sodium_Compat::crypto_generichash( + ParagonIE_Sodium_Compat::crypto_scalarmult($my_sk, $their_pk) . $client_pk . $server_pk ); diff --git a/src/wp-includes/sodium_compat/src/File.php b/src/wp-includes/sodium_compat/src/File.php index e675593c31..da6366b675 100644 --- a/src/wp-includes/sodium_compat/src/File.php +++ b/src/wp-includes/sodium_compat/src/File.php @@ -590,7 +590,6 @@ class ParagonIE_Sodium_File extends ParagonIE_Sodium_Core_Util $az[0] = self::intToChr(self::chrToInt($az[0]) & 248); $az[31] = self::intToChr((self::chrToInt($az[31]) & 63) | 64); - /** @var resource $hs */ $hs = hash_init('sha512'); hash_update($hs, self::substr($az, 32, 32)); /** @var resource $hs */ @@ -610,7 +609,6 @@ class ParagonIE_Sodium_File extends ParagonIE_Sodium_Core_Util ParagonIE_Sodium_Core_Ed25519::ge_scalarmult_base($nonce) ); - /** @var resource $hs */ $hs = hash_init('sha512'); hash_update($hs, self::substr($sig, 0, 32)); hash_update($hs, self::substr($pk, 0, 32)); @@ -719,7 +717,6 @@ class ParagonIE_Sodium_File extends ParagonIE_Sodium_Core_Util /** @var ParagonIE_Sodium_Core_Curve25519_Ge_P3 $A */ $A = ParagonIE_Sodium_Core_Ed25519::ge_frombytes_negate_vartime($publicKey); - /** @var resource $hs */ $hs = hash_init('sha512'); hash_update($hs, self::substr($sig, 0, 32)); hash_update($hs, self::substr($publicKey, 0, 32)); @@ -1079,7 +1076,7 @@ class ParagonIE_Sodium_File extends ParagonIE_Sodium_Core_Util * @param resource|object $hash * @param resource $fp * @param int $size - * @return mixed (resource on PHP < 7.2, object on PHP >= 7.2) + * @return resource|object Resource on PHP < 7.2, HashContext object on PHP >= 7.2 * @throws SodiumException * @throws TypeError * @psalm-suppress PossiblyInvalidArgument @@ -1095,12 +1092,12 @@ class ParagonIE_Sodium_File extends ParagonIE_Sodium_Core_Util if (!is_resource($hash)) { throw new TypeError('Argument 1 must be a resource, ' . gettype($hash) . ' given.'); } - } else { if (!is_object($hash)) { throw new TypeError('Argument 1 must be an object (PHP 7.2+), ' . gettype($hash) . ' given.'); } } + if (!is_resource($fp)) { throw new TypeError('Argument 2 must be a resource, ' . gettype($fp) . ' given.'); } @@ -1167,7 +1164,6 @@ class ParagonIE_Sodium_File extends ParagonIE_Sodium_Core_Util $az[0] = self::intToChr(self::chrToInt($az[0]) & 248); $az[31] = self::intToChr((self::chrToInt($az[31]) & 63) | 64); - /** @var resource $hs */ $hs = hash_init('sha512'); hash_update($hs, self::substr($az, 32, 32)); /** @var resource $hs */ @@ -1187,7 +1183,6 @@ class ParagonIE_Sodium_File extends ParagonIE_Sodium_Core_Util ParagonIE_Sodium_Core32_Ed25519::ge_scalarmult_base($nonce) ); - /** @var resource $hs */ $hs = hash_init('sha512'); hash_update($hs, self::substr($sig, 0, 32)); hash_update($hs, self::substr($pk, 0, 32)); @@ -1272,7 +1267,6 @@ class ParagonIE_Sodium_File extends ParagonIE_Sodium_Core_Util /** @var ParagonIE_Sodium_Core32_Curve25519_Ge_P3 $A */ $A = ParagonIE_Sodium_Core32_Ed25519::ge_frombytes_negate_vartime($publicKey); - /** @var resource $hs */ $hs = hash_init('sha512'); hash_update($hs, self::substr($sig, 0, 32)); hash_update($hs, self::substr($publicKey, 0, 32));