diff -r 34716fd837a4 -r be944660c56a wp/wp-includes/sodium_compat/src/Compat.php --- a/wp/wp-includes/sodium_compat/src/Compat.php Tue Dec 15 15:52:01 2020 +0100 +++ b/wp/wp-includes/sodium_compat/src/Compat.php Wed Sep 21 18:19:35 2022 +0200 @@ -44,6 +44,8 @@ */ public static $fastMult = false; + const LIBRARY_MAJOR_VERSION = 9; + const LIBRARY_MINOR_VERSION = 1; const LIBRARY_VERSION_MAJOR = 9; const LIBRARY_VERSION_MINOR = 1; const VERSION_STRING = 'polyfill-1.0.8'; @@ -78,6 +80,10 @@ const CRYPTO_BOX_MACBYTES = 16; const CRYPTO_BOX_NONCEBYTES = 24; const CRYPTO_BOX_SEEDBYTES = 32; + const CRYPTO_CORE_RISTRETTO255_BYTES = 32; + const CRYPTO_CORE_RISTRETTO255_SCALARBYTES = 32; + const CRYPTO_CORE_RISTRETTO255_HASHBYTES = 64; + const CRYPTO_CORE_RISTRETTO255_NONREDUCEDSCALARBYTES = 64; const CRYPTO_KDF_BYTES_MIN = 16; const CRYPTO_KDF_BYTES_MAX = 64; const CRYPTO_KDF_CONTEXTBYTES = 8; @@ -113,6 +119,8 @@ const CRYPTO_PWHASH_SCRYPTSALSA208SHA256_MEMLIMIT_SENSITIVE = 1073741824; const CRYPTO_SCALARMULT_BYTES = 32; const CRYPTO_SCALARMULT_SCALARBYTES = 32; + const CRYPTO_SCALARMULT_RISTRETTO255_BYTES = 32; + const CRYPTO_SCALARMULT_RISTRETTO255_SCALARBYTES = 32; const CRYPTO_SHORTHASH_BYTES = 8; const CRYPTO_SHORTHASH_KEYBYTES = 16; const CRYPTO_SECRETBOX_KEYBYTES = 32; @@ -133,6 +141,8 @@ const CRYPTO_SIGN_KEYPAIRBYTES = 96; const CRYPTO_STREAM_KEYBYTES = 32; const CRYPTO_STREAM_NONCEBYTES = 24; + const CRYPTO_STREAM_XCHACHA20_KEYBYTES = 32; + const CRYPTO_STREAM_XCHACHA20_NONCEBYTES = 24; /** * Add two numbers (little-endian unsigned), storing the value in the first @@ -725,7 +735,9 @@ ) { /* Type checks: */ ParagonIE_Sodium_Core_Util::declareScalarType($plaintext, 'string', 1); - ParagonIE_Sodium_Core_Util::declareScalarType($assocData, 'string', 2); + if (!is_null($assocData)) { + ParagonIE_Sodium_Core_Util::declareScalarType($assocData, 'string', 2); + } ParagonIE_Sodium_Core_Util::declareScalarType($nonce, 'string', 3); ParagonIE_Sodium_Core_Util::declareScalarType($key, 'string', 4); @@ -812,7 +824,11 @@ ) { /* Type checks: */ ParagonIE_Sodium_Core_Util::declareScalarType($ciphertext, 'string', 1); - ParagonIE_Sodium_Core_Util::declareScalarType($assocData, 'string', 2); + if (!is_null($assocData)) { + ParagonIE_Sodium_Core_Util::declareScalarType($assocData, 'string', 2); + } else { + $assocData = ''; + } ParagonIE_Sodium_Core_Util::declareScalarType($nonce, 'string', 3); ParagonIE_Sodium_Core_Util::declareScalarType($key, 'string', 4); @@ -883,7 +899,11 @@ ) { /* Type checks: */ ParagonIE_Sodium_Core_Util::declareScalarType($plaintext, 'string', 1); - ParagonIE_Sodium_Core_Util::declareScalarType($assocData, 'string', 2); + if (!is_null($assocData)) { + ParagonIE_Sodium_Core_Util::declareScalarType($assocData, 'string', 2); + } else { + $assocData = ''; + } ParagonIE_Sodium_Core_Util::declareScalarType($nonce, 'string', 3); ParagonIE_Sodium_Core_Util::declareScalarType($key, 'string', 4); @@ -1686,12 +1706,13 @@ * @param string $their_public * @param string $client_public * @param string $server_public + * @param bool $dontFallback * @return string * @throws SodiumException * @throws TypeError * @psalm-suppress MixedArgument */ - public static function crypto_kx($my_secret, $their_public, $client_public, $server_public) + public static function crypto_kx($my_secret, $their_public, $client_public, $server_public, $dontFallback = false) { /* Type checks: */ ParagonIE_Sodium_Core_Util::declareScalarType($my_secret, 'string', 1); @@ -1713,7 +1734,7 @@ throw new SodiumException('Argument 4 must be CRYPTO_BOX_PUBLICKEYBYTES long.'); } - if (self::useNewSodiumAPI()) { + if (self::useNewSodiumAPI() && !$dontFallback) { if (is_callable('sodium_crypto_kx')) { return (string) sodium_crypto_kx( $my_secret, @@ -3048,6 +3069,103 @@ return random_bytes(self::CRYPTO_STREAM_KEYBYTES); } + + /** + * Expand a key and nonce into a keystream of pseudorandom bytes. + * + * @param int $len Number of bytes desired + * @param string $nonce Number to be used Once; must be 24 bytes + * @param string $key XChaCha20 key + * @param bool $dontFallback + * @return string Pseudorandom stream that can be XORed with messages + * to provide encryption (but not authentication; see + * Poly1305 or crypto_auth() for that, which is not + * optional for security) + * @throws SodiumException + * @throws TypeError + * @psalm-suppress MixedArgument + */ + public static function crypto_stream_xchacha20($len, $nonce, $key, $dontFallback = false) + { + /* Type checks: */ + ParagonIE_Sodium_Core_Util::declareScalarType($len, 'int', 1); + ParagonIE_Sodium_Core_Util::declareScalarType($nonce, 'string', 2); + ParagonIE_Sodium_Core_Util::declareScalarType($key, 'string', 3); + + /* Input validation: */ + if (ParagonIE_Sodium_Core_Util::strlen($nonce) !== self::CRYPTO_STREAM_XCHACHA20_NONCEBYTES) { + throw new SodiumException('Argument 2 must be CRYPTO_SECRETBOX_XCHACHA20_NONCEBYTES long.'); + } + if (ParagonIE_Sodium_Core_Util::strlen($key) !== self::CRYPTO_STREAM_XCHACHA20_KEYBYTES) { + throw new SodiumException('Argument 3 must be CRYPTO_STREAM_XCHACHA20_KEYBYTES long.'); + } + + if (self::useNewSodiumAPI() && !$dontFallback) { + return sodium_crypto_stream_xchacha20($len, $nonce, $key); + } + if (PHP_INT_SIZE === 4) { + return ParagonIE_Sodium_Core32_XChaCha20::stream($len, $nonce, $key); + } + return ParagonIE_Sodium_Core_XChaCha20::stream($len, $nonce, $key); + } + + /** + * DANGER! UNAUTHENTICATED ENCRYPTION! + * + * Unless you are following expert advice, do not used this feature. + * + * Algorithm: XChaCha20 + * + * This DOES NOT provide ciphertext integrity. + * + * @param string $message Plaintext message + * @param string $nonce Number to be used Once; must be 24 bytes + * @param string $key Encryption key + * @return string Encrypted text which is vulnerable to chosen- + * ciphertext attacks unless you implement some + * other mitigation to the ciphertext (i.e. + * Encrypt then MAC) + * @param bool $dontFallback + * @throws SodiumException + * @throws TypeError + * @psalm-suppress MixedArgument + */ + public static function crypto_stream_xchacha20_xor($message, $nonce, $key, $dontFallback = false) + { + /* Type checks: */ + ParagonIE_Sodium_Core_Util::declareScalarType($message, 'string', 1); + ParagonIE_Sodium_Core_Util::declareScalarType($nonce, 'string', 2); + ParagonIE_Sodium_Core_Util::declareScalarType($key, 'string', 3); + + /* Input validation: */ + if (ParagonIE_Sodium_Core_Util::strlen($nonce) !== self::CRYPTO_STREAM_XCHACHA20_NONCEBYTES) { + throw new SodiumException('Argument 2 must be CRYPTO_SECRETBOX_XCHACHA20_NONCEBYTES long.'); + } + if (ParagonIE_Sodium_Core_Util::strlen($key) !== self::CRYPTO_STREAM_XCHACHA20_KEYBYTES) { + throw new SodiumException('Argument 3 must be CRYPTO_SECRETBOX_XCHACHA20_KEYBYTES long.'); + } + + if (self::useNewSodiumAPI() && !$dontFallback) { + return sodium_crypto_stream_xchacha20_xor($message, $nonce, $key); + } + if (PHP_INT_SIZE === 4) { + return ParagonIE_Sodium_Core32_XChaCha20::streamXorIc($message, $nonce, $key); + } + return ParagonIE_Sodium_Core_XChaCha20::streamXorIc($message, $nonce, $key); + } + + /** + * Return a secure random key for use with crypto_stream_xchacha20 + * + * @return string + * @throws Exception + * @throws Error + */ + public static function crypto_stream_xchacha20_keygen() + { + return random_bytes(self::CRYPTO_STREAM_XCHACHA20_KEYBYTES); + } + /** * Cache-timing-safe implementation of hex2bin(). * @@ -3113,19 +3231,33 @@ } /** + * @param string $str + * @return bool + * + * @throws SodiumException + */ + public static function is_zero($str) + { + $d = 0; + for ($i = 0; $i < 32; ++$i) { + $d |= ParagonIE_Sodium_Core_Util::chrToInt($str[$i]); + } + return ((($d - 1) >> 31) & 1) === 1; + } + + /** * The equivalent to the libsodium minor version we aim to be compatible * with (sans pwhash and memzero). * * @return int - * @psalm-suppress MixedInferredReturnType - * @psalm-suppress UndefinedFunction */ public static function library_version_major() { - if (self::useNewSodiumAPI()) { - return sodium_library_version_major(); + if (self::useNewSodiumAPI() && defined('SODIUM_LIBRARY_MAJOR_VERSION')) { + return SODIUM_LIBRARY_MAJOR_VERSION; } if (self::use_fallback('library_version_major')) { + /** @psalm-suppress UndefinedFunction */ return (int) call_user_func('\\Sodium\\library_version_major'); } return self::LIBRARY_VERSION_MAJOR; @@ -3136,15 +3268,14 @@ * with (sans pwhash and memzero). * * @return int - * @psalm-suppress MixedInferredReturnType - * @psalm-suppress UndefinedFunction */ public static function library_version_minor() { - if (self::useNewSodiumAPI()) { - return sodium_library_version_minor(); + if (self::useNewSodiumAPI() && defined('SODIUM_LIBRARY_MINOR_VERSION')) { + return SODIUM_LIBRARY_MINOR_VERSION; } if (self::use_fallback('library_version_minor')) { + /** @psalm-suppress UndefinedFunction */ return (int) call_user_func('\\Sodium\\library_version_minor'); } return self::LIBRARY_VERSION_MINOR; @@ -3452,6 +3583,232 @@ } /** + * @param string $p + * @param bool $dontFallback + * @return bool + * @throws SodiumException + */ + public static function ristretto255_is_valid_point($p, $dontFallback = false) + { + if (self::useNewSodiumAPI() && !$dontFallback) { + return sodium_crypto_core_ristretto255_is_valid_point($p); + } + try { + $r = ParagonIE_Sodium_Core_Ristretto255::ristretto255_frombytes($p); + return $r['res'] === 0 && + ParagonIE_Sodium_Core_Ristretto255::ristretto255_point_is_canonical($p) === 1; + } catch (SodiumException $ex) { + if ($ex->getMessage() === 'S is not canonical') { + return false; + } + throw $ex; + } + } + + /** + * @param string $p + * @param string $q + * @param bool $dontFallback + * @return string + * @throws SodiumException + */ + public static function ristretto255_add($p, $q, $dontFallback = false) + { + if (self::useNewSodiumAPI() && !$dontFallback) { + return sodium_crypto_core_ristretto255_add($p, $q); + } + return ParagonIE_Sodium_Core_Ristretto255::ristretto255_add($p, $q); + } + + /** + * @param string $p + * @param string $q + * @param bool $dontFallback + * @return string + * @throws SodiumException + */ + public static function ristretto255_sub($p, $q, $dontFallback = false) + { + if (self::useNewSodiumAPI() && !$dontFallback) { + return sodium_crypto_core_ristretto255_sub($p, $q); + } + return ParagonIE_Sodium_Core_Ristretto255::ristretto255_sub($p, $q); + } + + /** + * @param string $r + * @param bool $dontFallback + * @return string + * + * @throws SodiumException + */ + public static function ristretto255_from_hash($r, $dontFallback = false) + { + if (self::useNewSodiumAPI() && !$dontFallback) { + return sodium_crypto_core_ristretto255_from_hash($r); + } + return ParagonIE_Sodium_Core_Ristretto255::ristretto255_from_hash($r); + } + + /** + * @param bool $dontFallback + * @return string + * + * @throws SodiumException + */ + public static function ristretto255_random($dontFallback = false) + { + if (self::useNewSodiumAPI() && !$dontFallback) { + return sodium_crypto_core_ristretto255_random(); + } + return ParagonIE_Sodium_Core_Ristretto255::ristretto255_random(); + } + + /** + * @param bool $dontFallback + * @return string + * + * @throws SodiumException + */ + public static function ristretto255_scalar_random($dontFallback = false) + { + if (self::useNewSodiumAPI() && !$dontFallback) { + return sodium_crypto_core_ristretto255_scalar_random(); + } + return ParagonIE_Sodium_Core_Ristretto255::ristretto255_scalar_random(); + } + + /** + * @param string $s + * @param bool $dontFallback + * @return string + * @throws SodiumException + */ + public static function ristretto255_scalar_invert($s, $dontFallback = false) + { + if (self::useNewSodiumAPI() && !$dontFallback) { + return sodium_crypto_core_ristretto255_scalar_invert($s); + } + return ParagonIE_Sodium_Core_Ristretto255::ristretto255_scalar_invert($s); + } + /** + * @param string $s + * @param bool $dontFallback + * @return string + * @throws SodiumException + */ + public static function ristretto255_scalar_negate($s, $dontFallback = false) + { + if (self::useNewSodiumAPI() && !$dontFallback) { + return sodium_crypto_core_ristretto255_scalar_negate($s); + } + return ParagonIE_Sodium_Core_Ristretto255::ristretto255_scalar_negate($s); + } + + /** + * @param string $s + * @param bool $dontFallback + * @return string + * @throws SodiumException + */ + public static function ristretto255_scalar_complement($s, $dontFallback = false) + { + if (self::useNewSodiumAPI() && !$dontFallback) { + return sodium_crypto_core_ristretto255_scalar_complement($s); + } + return ParagonIE_Sodium_Core_Ristretto255::ristretto255_scalar_complement($s); + } + + /** + * @param string $x + * @param string $y + * @param bool $dontFallback + * @return string + * @throws SodiumException + */ + public static function ristretto255_scalar_add($x, $y, $dontFallback = false) + { + if (self::useNewSodiumAPI() && !$dontFallback) { + return sodium_crypto_core_ristretto255_scalar_add($x, $y); + } + return ParagonIE_Sodium_Core_Ristretto255::ristretto255_scalar_add($x, $y); + } + + /** + * @param string $x + * @param string $y + * @param bool $dontFallback + * @return string + * @throws SodiumException + */ + public static function ristretto255_scalar_sub($x, $y, $dontFallback = false) + { + if (self::useNewSodiumAPI() && !$dontFallback) { + return sodium_crypto_core_ristretto255_scalar_sub($x, $y); + } + return ParagonIE_Sodium_Core_Ristretto255::ristretto255_scalar_sub($x, $y); + } + + /** + * @param string $x + * @param string $y + * @param bool $dontFallback + * @return string + * @throws SodiumException + */ + public static function ristretto255_scalar_mul($x, $y, $dontFallback = false) + { + if (self::useNewSodiumAPI() && !$dontFallback) { + return sodium_crypto_core_ristretto255_scalar_mul($x, $y); + } + return ParagonIE_Sodium_Core_Ristretto255::ristretto255_scalar_mul($x, $y); + } + + /** + * @param string $n + * @param string $p + * @param bool $dontFallback + * @return string + * @throws SodiumException + */ + public static function scalarmult_ristretto255($n, $p, $dontFallback = false) + { + if (self::useNewSodiumAPI() && !$dontFallback) { + return sodium_crypto_scalarmult_ristretto255($n, $p); + } + return ParagonIE_Sodium_Core_Ristretto255::scalarmult_ristretto255($n, $p); + } + + /** + * @param string $n + * @param string $p + * @param bool $dontFallback + * @return string + * @throws SodiumException + */ + public static function scalarmult_ristretto255_base($n, $dontFallback = false) + { + if (self::useNewSodiumAPI() && !$dontFallback) { + return sodium_crypto_scalarmult_ristretto255_base($n); + } + return ParagonIE_Sodium_Core_Ristretto255::scalarmult_ristretto255_base($n); + } + + /** + * @param string $s + * @param bool $dontFallback + * @return string + * @throws SodiumException + */ + public static function ristretto255_scalar_reduce($s, $dontFallback = false) + { + if (self::useNewSodiumAPI() && !$dontFallback) { + return sodium_crypto_core_ristretto255_scalar_reduce($s); + } + return ParagonIE_Sodium_Core_Ristretto255::sc_reduce($s); + } + + /** * Runtime testing method for 32-bit platforms. * * Usage: If runtime_speed_test() returns FALSE, then our 32-bit @@ -3488,6 +3845,36 @@ } /** + * Add two numbers (little-endian unsigned), storing the value in the first + * parameter. + * + * This mutates $val. + * + * @param string $val + * @param string $addv + * @return void + * @throws SodiumException + */ + public static function sub(&$val, $addv) + { + $val_len = ParagonIE_Sodium_Core_Util::strlen($val); + $addv_len = ParagonIE_Sodium_Core_Util::strlen($addv); + if ($val_len !== $addv_len) { + throw new SodiumException('values must have the same length'); + } + $A = ParagonIE_Sodium_Core_Util::stringToIntArray($val); + $B = ParagonIE_Sodium_Core_Util::stringToIntArray($addv); + + $c = 0; + for ($i = 0; $i < $val_len; $i++) { + $c = ($A[$i] - $B[$i] - $c); + $A[$i] = ($c & 0xff); + $c = ($c >> 8) & 1; + } + $val = ParagonIE_Sodium_Core_Util::intArrayToString($A); + } + + /** * This emulates libsodium's version_string() function, except ours is * prefixed with 'polyfill-'. *