diff options
Diffstat (limited to 'srcs/wordpress/wp-includes/sodium_compat/src')
61 files changed, 29756 insertions, 0 deletions
diff --git a/srcs/wordpress/wp-includes/sodium_compat/src/Compat.php b/srcs/wordpress/wp-includes/sodium_compat/src/Compat.php new file mode 100644 index 0000000..e49133f --- /dev/null +++ b/srcs/wordpress/wp-includes/sodium_compat/src/Compat.php @@ -0,0 +1,3560 @@ +<?php + +/** + * Libsodium compatibility layer + * + * This is the only class you should be interfacing with, as a user of + * sodium_compat. + * + * If the PHP extension for libsodium is installed, it will always use that + * instead of our implementations. You get better performance and stronger + * guarantees against side-channels that way. + * + * However, if your users don't have the PHP extension installed, we offer a + * compatible interface here. It will give you the correct results as if the + * PHP extension was installed. It won't be as fast, of course. + * + * CAUTION * CAUTION * CAUTION * CAUTION * CAUTION * CAUTION * CAUTION * CAUTION * + * * + * Until audited, this is probably not safe to use! DANGER WILL ROBINSON * + * * + * CAUTION * CAUTION * CAUTION * CAUTION * CAUTION * CAUTION * CAUTION * CAUTION * + */ + +if (class_exists('ParagonIE_Sodium_Compat', false)) { + return; +} + +class ParagonIE_Sodium_Compat +{ + /** + * This parameter prevents the use of the PECL extension. + * It should only be used for unit testing. + * + * @var bool + */ + public static $disableFallbackForUnitTests = false; + + /** + * Use fast multiplication rather than our constant-time multiplication + * implementation. Can be enabled at runtime. Only enable this if you + * are absolutely certain that there is no timing leak on your platform. + * + * @var bool + */ + public static $fastMult = false; + + const LIBRARY_VERSION_MAJOR = 9; + const LIBRARY_VERSION_MINOR = 1; + const VERSION_STRING = 'polyfill-1.0.8'; + + // From libsodium + const BASE64_VARIANT_ORIGINAL = 1; + const BASE64_VARIANT_ORIGINAL_NO_PADDING = 3; + const BASE64_VARIANT_URLSAFE = 5; + const BASE64_VARIANT_URLSAFE_NO_PADDING = 7; + const CRYPTO_AEAD_AES256GCM_KEYBYTES = 32; + const CRYPTO_AEAD_AES256GCM_NSECBYTES = 0; + const CRYPTO_AEAD_AES256GCM_NPUBBYTES = 12; + const CRYPTO_AEAD_AES256GCM_ABYTES = 16; + const CRYPTO_AEAD_CHACHA20POLY1305_KEYBYTES = 32; + const CRYPTO_AEAD_CHACHA20POLY1305_NSECBYTES = 0; + const CRYPTO_AEAD_CHACHA20POLY1305_NPUBBYTES = 8; + const CRYPTO_AEAD_CHACHA20POLY1305_ABYTES = 16; + const CRYPTO_AEAD_CHACHA20POLY1305_IETF_KEYBYTES = 32; + const CRYPTO_AEAD_CHACHA20POLY1305_IETF_NSECBYTES = 0; + const CRYPTO_AEAD_CHACHA20POLY1305_IETF_NPUBBYTES = 12; + const CRYPTO_AEAD_CHACHA20POLY1305_IETF_ABYTES = 16; + const CRYPTO_AEAD_XCHACHA20POLY1305_IETF_KEYBYTES = 32; + const CRYPTO_AEAD_XCHACHA20POLY1305_IETF_NSECBYTES = 0; + const CRYPTO_AEAD_XCHACHA20POLY1305_IETF_NPUBBYTES = 24; + const CRYPTO_AEAD_XCHACHA20POLY1305_IETF_ABYTES = 16; + const CRYPTO_AUTH_BYTES = 32; + const CRYPTO_AUTH_KEYBYTES = 32; + const CRYPTO_BOX_SEALBYTES = 16; + const CRYPTO_BOX_SECRETKEYBYTES = 32; + const CRYPTO_BOX_PUBLICKEYBYTES = 32; + const CRYPTO_BOX_KEYPAIRBYTES = 64; + const CRYPTO_BOX_MACBYTES = 16; + const CRYPTO_BOX_NONCEBYTES = 24; + const CRYPTO_BOX_SEEDBYTES = 32; + const CRYPTO_KDF_BYTES_MIN = 16; + const CRYPTO_KDF_BYTES_MAX = 64; + const CRYPTO_KDF_CONTEXTBYTES = 8; + const CRYPTO_KDF_KEYBYTES = 32; + const CRYPTO_KX_BYTES = 32; + const CRYPTO_KX_PRIMITIVE = 'x25519blake2b'; + const CRYPTO_KX_SEEDBYTES = 32; + const CRYPTO_KX_KEYPAIRBYTES = 64; + const CRYPTO_KX_PUBLICKEYBYTES = 32; + const CRYPTO_KX_SECRETKEYBYTES = 32; + const CRYPTO_KX_SESSIONKEYBYTES = 32; + const CRYPTO_GENERICHASH_BYTES = 32; + const CRYPTO_GENERICHASH_BYTES_MIN = 16; + const CRYPTO_GENERICHASH_BYTES_MAX = 64; + const CRYPTO_GENERICHASH_KEYBYTES = 32; + const CRYPTO_GENERICHASH_KEYBYTES_MIN = 16; + const CRYPTO_GENERICHASH_KEYBYTES_MAX = 64; + const CRYPTO_PWHASH_SALTBYTES = 16; + const CRYPTO_PWHASH_STRPREFIX = '$argon2id$'; + const CRYPTO_PWHASH_ALG_ARGON2I13 = 1; + const CRYPTO_PWHASH_ALG_ARGON2ID13 = 2; + const CRYPTO_PWHASH_MEMLIMIT_INTERACTIVE = 33554432; + const CRYPTO_PWHASH_OPSLIMIT_INTERACTIVE = 4; + const CRYPTO_PWHASH_MEMLIMIT_MODERATE = 134217728; + const CRYPTO_PWHASH_OPSLIMIT_MODERATE = 6; + const CRYPTO_PWHASH_MEMLIMIT_SENSITIVE = 536870912; + const CRYPTO_PWHASH_OPSLIMIT_SENSITIVE = 8; + const CRYPTO_PWHASH_SCRYPTSALSA208SHA256_SALTBYTES = 32; + const CRYPTO_PWHASH_SCRYPTSALSA208SHA256_STRPREFIX = '$7$'; + const CRYPTO_PWHASH_SCRYPTSALSA208SHA256_OPSLIMIT_INTERACTIVE = 534288; + const CRYPTO_PWHASH_SCRYPTSALSA208SHA256_MEMLIMIT_INTERACTIVE = 16777216; + const CRYPTO_PWHASH_SCRYPTSALSA208SHA256_OPSLIMIT_SENSITIVE = 33554432; + const CRYPTO_PWHASH_SCRYPTSALSA208SHA256_MEMLIMIT_SENSITIVE = 1073741824; + const CRYPTO_SCALARMULT_BYTES = 32; + const CRYPTO_SCALARMULT_SCALARBYTES = 32; + const CRYPTO_SHORTHASH_BYTES = 8; + const CRYPTO_SHORTHASH_KEYBYTES = 16; + const CRYPTO_SECRETBOX_KEYBYTES = 32; + const CRYPTO_SECRETBOX_MACBYTES = 16; + const CRYPTO_SECRETBOX_NONCEBYTES = 24; + const CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_ABYTES = 17; + const CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_HEADERBYTES = 24; + const CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_KEYBYTES = 32; + const CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_TAG_PUSH = 0; + const CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_TAG_PULL = 1; + const CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_TAG_REKEY = 2; + const CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_TAG_FINAL = 3; + const CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_MESSAGEBYTES_MAX = 0x3fffffff80; + const CRYPTO_SIGN_BYTES = 64; + const CRYPTO_SIGN_SEEDBYTES = 32; + const CRYPTO_SIGN_PUBLICKEYBYTES = 32; + const CRYPTO_SIGN_SECRETKEYBYTES = 64; + const CRYPTO_SIGN_KEYPAIRBYTES = 96; + const CRYPTO_STREAM_KEYBYTES = 32; + const CRYPTO_STREAM_NONCEBYTES = 24; + + /** + * 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 add(&$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]); + $A[$i] = ($c & 0xff); + $c >>= 8; + } + $val = ParagonIE_Sodium_Core_Util::intArrayToString($A); + } + + /** + * @param string $encoded + * @param int $variant + * @param string $ignore + * @return string + * @throws SodiumException + */ + public static function base642bin($encoded, $variant, $ignore = '') + { + /* Type checks: */ + ParagonIE_Sodium_Core_Util::declareScalarType($encoded, 'string', 1); + + /** @var string $encoded */ + $encoded = (string) $encoded; + if (ParagonIE_Sodium_Core_Util::strlen($encoded) === 0) { + return ''; + } + + // Just strip before decoding + if (!empty($ignore)) { + $encoded = str_replace($ignore, '', $encoded); + } + + try { + switch ($variant) { + case self::BASE64_VARIANT_ORIGINAL: + return ParagonIE_Sodium_Core_Base64_Original::decode($encoded, true); + case self::BASE64_VARIANT_ORIGINAL_NO_PADDING: + return ParagonIE_Sodium_Core_Base64_Original::decode($encoded, false); + case self::BASE64_VARIANT_URLSAFE: + return ParagonIE_Sodium_Core_Base64_UrlSafe::decode($encoded, true); + case self::BASE64_VARIANT_URLSAFE_NO_PADDING: + return ParagonIE_Sodium_Core_Base64_UrlSafe::decode($encoded, false); + default: + throw new SodiumException('invalid base64 variant identifier'); + } + } catch (Exception $ex) { + if ($ex instanceof SodiumException) { + throw $ex; + } + throw new SodiumException('invalid base64 string'); + } + } + + /** + * @param string $decoded + * @param int $variant + * @return string + * @throws SodiumException + */ + public static function bin2base64($decoded, $variant) + { + /* Type checks: */ + ParagonIE_Sodium_Core_Util::declareScalarType($decoded, 'string', 1); + /** @var string $decoded */ + $decoded = (string) $decoded; + if (ParagonIE_Sodium_Core_Util::strlen($decoded) === 0) { + return ''; + } + + switch ($variant) { + case self::BASE64_VARIANT_ORIGINAL: + return ParagonIE_Sodium_Core_Base64_Original::encode($decoded); + case self::BASE64_VARIANT_ORIGINAL_NO_PADDING: + return ParagonIE_Sodium_Core_Base64_Original::encodeUnpadded($decoded); + case self::BASE64_VARIANT_URLSAFE: + return ParagonIE_Sodium_Core_Base64_UrlSafe::encode($decoded); + case self::BASE64_VARIANT_URLSAFE_NO_PADDING: + return ParagonIE_Sodium_Core_Base64_UrlSafe::encodeUnpadded($decoded); + default: + throw new SodiumException('invalid base64 variant identifier'); + } + } + + /** + * Cache-timing-safe implementation of bin2hex(). + * + * @param string $string A string (probably raw binary) + * @return string A hexadecimal-encoded string + * @throws SodiumException + * @throws TypeError + * @psalm-suppress MixedArgument + */ + public static function bin2hex($string) + { + /* Type checks: */ + ParagonIE_Sodium_Core_Util::declareScalarType($string, 'string', 1); + + if (self::useNewSodiumAPI()) { + return (string) sodium_bin2hex($string); + } + if (self::use_fallback('bin2hex')) { + return (string) call_user_func('\\Sodium\\bin2hex', $string); + } + return ParagonIE_Sodium_Core_Util::bin2hex($string); + } + + /** + * Compare two strings, in constant-time. + * Compared to memcmp(), compare() is more useful for sorting. + * + * @param string $left The left operand; must be a string + * @param string $right The right operand; must be a string + * @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 + */ + public static function compare($left, $right) + { + /* Type checks: */ + ParagonIE_Sodium_Core_Util::declareScalarType($left, 'string', 1); + ParagonIE_Sodium_Core_Util::declareScalarType($right, 'string', 2); + + if (self::useNewSodiumAPI()) { + return (int) sodium_compare($left, $right); + } + if (self::use_fallback('compare')) { + return (int) call_user_func('\\Sodium\\compare', $left, $right); + } + return ParagonIE_Sodium_Core_Util::compare($left, $right); + } + + /** + * Is AES-256-GCM even available to use? + * + * @return bool + * @psalm-suppress UndefinedFunction + * @psalm-suppress MixedInferredReturnType + * @psalm-suppress MixedReturnStatement + */ + public static function crypto_aead_aes256gcm_is_available() + { + if (self::useNewSodiumAPI()) { + return sodium_crypto_aead_aes256gcm_is_available(); + } + if (self::use_fallback('crypto_aead_aes256gcm_is_available')) { + return call_user_func('\\Sodium\\crypto_aead_aes256gcm_is_available'); + } + if (PHP_VERSION_ID < 70100) { + // OpenSSL doesn't support AEAD before 7.1.0 + return false; + } + if (!is_callable('openssl_encrypt') || !is_callable('openssl_decrypt')) { + // OpenSSL isn't installed + return false; + } + return (bool) in_array('aes-256-gcm', openssl_get_cipher_methods()); + } + + /** + * Authenticated Encryption with Associated Data: Decryption + * + * Algorithm: + * AES-256-GCM + * + * 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 + * + * @return string|bool The original plaintext message + * @throws SodiumException + * @throws TypeError + * @psalm-suppress MixedArgument + * @psalm-suppress MixedInferredReturnType + * @psalm-suppress MixedReturnStatement + */ + public static function crypto_aead_aes256gcm_decrypt( + $ciphertext = '', + $assocData = '', + $nonce = '', + $key = '' + ) { + if (!self::crypto_aead_aes256gcm_is_available()) { + throw new SodiumException('AES-256-GCM is not available'); + } + ParagonIE_Sodium_Core_Util::declareScalarType($ciphertext, 'string', 1); + ParagonIE_Sodium_Core_Util::declareScalarType($assocData, 'string', 2); + ParagonIE_Sodium_Core_Util::declareScalarType($nonce, 'string', 3); + ParagonIE_Sodium_Core_Util::declareScalarType($key, 'string', 4); + + /* Input validation: */ + if (ParagonIE_Sodium_Core_Util::strlen($nonce) !== self::CRYPTO_AEAD_AES256GCM_NPUBBYTES) { + throw new SodiumException('Nonce must be CRYPTO_AEAD_AES256GCM_NPUBBYTES long'); + } + if (ParagonIE_Sodium_Core_Util::strlen($key) !== self::CRYPTO_AEAD_AES256GCM_KEYBYTES) { + throw new SodiumException('Key must be CRYPTO_AEAD_AES256GCM_KEYBYTES long'); + } + if (ParagonIE_Sodium_Core_Util::strlen($ciphertext) < self::CRYPTO_AEAD_AES256GCM_ABYTES) { + throw new SodiumException('Message must be at least CRYPTO_AEAD_AES256GCM_ABYTES long'); + } + if (!is_callable('openssl_decrypt')) { + throw new SodiumException('The OpenSSL extension is not installed, or openssl_decrypt() is not available'); + } + + /** @var string $ctext */ + $ctext = ParagonIE_Sodium_Core_Util::substr($ciphertext, 0, -self::CRYPTO_AEAD_AES256GCM_ABYTES); + /** @var string $authTag */ + $authTag = ParagonIE_Sodium_Core_Util::substr($ciphertext, -self::CRYPTO_AEAD_AES256GCM_ABYTES, 16); + return openssl_decrypt( + $ctext, + 'aes-256-gcm', + $key, + OPENSSL_RAW_DATA, + $nonce, + $authTag, + $assocData + ); + } + + /** + * Authenticated Encryption with Associated Data: Encryption + * + * Algorithm: + * AES-256-GCM + * + * @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 + * + * @return string Ciphertext with a 16-byte GCM message + * authentication code appended + * @throws SodiumException + * @throws TypeError + * @psalm-suppress MixedArgument + */ + public static function crypto_aead_aes256gcm_encrypt( + $plaintext = '', + $assocData = '', + $nonce = '', + $key = '' + ) { + if (!self::crypto_aead_aes256gcm_is_available()) { + throw new SodiumException('AES-256-GCM is not available'); + } + ParagonIE_Sodium_Core_Util::declareScalarType($plaintext, 'string', 1); + ParagonIE_Sodium_Core_Util::declareScalarType($assocData, 'string', 2); + ParagonIE_Sodium_Core_Util::declareScalarType($nonce, 'string', 3); + ParagonIE_Sodium_Core_Util::declareScalarType($key, 'string', 4); + |
