Changeset 46858
- Timestamp:
- 12/09/2019 04:40:11 PM (5 years ago)
- Location:
- trunk/src/wp-includes/sodium_compat
- Files:
-
- 11 added
- 19 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/wp-includes/sodium_compat/LICENSE
r45344 r46858 2 2 * ISC License 3 3 * 4 * Copyright (c) 2016-201 84 * Copyright (c) 2016-2019 5 5 * Paragon Initiative Enterprises <security at paragonie dot com> 6 6 * 7 * Copyright (c) 2013-201 87 * Copyright (c) 2013-2019 8 8 * Frank Denis <j at pureftpd dot org> 9 9 * -
trunk/src/wp-includes/sodium_compat/autoload.php
r46586 r46858 44 44 require_once dirname(__FILE__) . '/lib/namespaced.php'; 45 45 require_once dirname(__FILE__) . '/lib/sodium_compat.php'; 46 } else { 47 require_once dirname(__FILE__) . '/src/PHP52/SplFixedArray.php'; 46 48 } 47 49 if (PHP_VERSION_ID < 70200 || !extension_loaded('sodium')) { 48 require_once dirname(__FILE__) . '/lib/php72compat.php'; 50 if (PHP_VERSION_ID >= 50300 && !defined('SODIUM_CRYPTO_SCALARMULT_BYTES')) { 51 require_once dirname(__FILE__) . '/lib/php72compat_const.php'; 52 } 53 if (PHP_VERSION_ID >= 70000) { 54 assert(class_exists('ParagonIE_Sodium_Compat'), 'Possible filesystem/autoloader bug?'); 55 } else { 56 assert(class_exists('ParagonIE_Sodium_Compat')); 57 } 58 require_once (dirname(__FILE__) . '/lib/php72compat.php'); 49 59 } -
trunk/src/wp-includes/sodium_compat/composer.json
r46587 r46858 55 55 }, 56 56 "require-dev": { 57 "phpunit/phpunit": "^3|^4|^5 "57 "phpunit/phpunit": "^3|^4|^5|^6|^7" 58 58 }, 59 59 "suggest": { -
trunk/src/wp-includes/sodium_compat/lib/constants.php
r46586 r46858 1 1 <?php 2 2 namespace Sodium; 3 4 require_once dirname(dirname(__FILE__)) . '/autoload.php'; 3 5 4 6 use ParagonIE_Sodium_Compat; -
trunk/src/wp-includes/sodium_compat/lib/namespaced.php
r46586 r46858 1 1 <?php 2 3 require_once dirname(dirname(__FILE__)) . '/autoload.php'; 2 4 3 5 if (PHP_VERSION_ID < 50300) { … … 37 39 // separators with directory separators in the relative class name, append 38 40 // with .php 39 $file = dirname( __DIR__) . '/namespaced/' . str_replace('\\', '/', $relative_class) . '.php';41 $file = dirname(dirname(__FILE__)) . '/namespaced/' . str_replace('\\', '/', $relative_class) . '.php'; 40 42 // if the file exists, require it 41 43 if (file_exists($file)) { -
trunk/src/wp-includes/sodium_compat/lib/php72compat.php
r46586 r46858 1 1 <?php 2 3 require_once dirname(dirname(__FILE__)) . '/autoload.php'; 2 4 3 5 /** … … 9 11 */ 10 12 foreach (array( 13 'BASE64_VARIANT_ORIGINAL', 14 'BASE64_VARIANT_ORIGINAL_NO_PADDING', 15 'BASE64_VARIANT_URLSAFE', 16 'BASE64_VARIANT_URLSAFE_NO_PADDING', 11 17 'CRYPTO_AEAD_CHACHA20POLY1305_KEYBYTES', 12 18 'CRYPTO_AEAD_CHACHA20POLY1305_NSECBYTES', … … 30 36 'CRYPTO_BOX_NONCEBYTES', 31 37 'CRYPTO_BOX_SEEDBYTES', 38 'CRYPTO_KDF_BYTES_MIN', 39 'CRYPTO_KDF_BYTES_MAX', 40 'CRYPTO_KDF_CONTEXTBYTES', 41 'CRYPTO_KDF_KEYBYTES', 32 42 'CRYPTO_KX_BYTES', 43 'CRYPTO_KX_KEYPAIRBYTES', 44 'CRYPTO_KX_PRIMITIVE', 33 45 'CRYPTO_KX_SEEDBYTES', 34 46 'CRYPTO_KX_PUBLICKEYBYTES', 35 47 'CRYPTO_KX_SECRETKEYBYTES', 48 'CRYPTO_KX_SESSIONKEYBYTES', 36 49 'CRYPTO_GENERICHASH_BYTES', 37 50 'CRYPTO_GENERICHASH_BYTES_MIN', … … 57 70 'CRYPTO_SECRETBOX_MACBYTES', 58 71 'CRYPTO_SECRETBOX_NONCEBYTES', 72 'CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_ABYTES', 73 'CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_HEADERBYTES', 74 'CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_KEYBYTES', 75 'CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_TAG_PUSH', 76 'CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_TAG_PULL', 77 'CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_TAG_REKEY', 78 'CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_TAG_FINAL', 79 'CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_MESSAGEBYTES_MAX', 59 80 'CRYPTO_SIGN_BYTES', 60 81 'CRYPTO_SIGN_SEEDBYTES', … … 69 90 ) as $constant 70 91 ) { 71 if (!defined("SODIUM_$constant") ) {92 if (!defined("SODIUM_$constant") && defined("ParagonIE_Sodium_Compat::$constant")) { 72 93 define("SODIUM_$constant", constant("ParagonIE_Sodium_Compat::$constant")); 73 94 } 74 95 } 75 96 if (!is_callable('sodium_add')) { 97 /** 98 * @see ParagonIE_Sodium_Compat::add() 99 * @param string $val 100 * @param string $addv 101 * @return void 102 * @throws SodiumException 103 */ 104 function sodium_add(&$val, $addv) 105 { 106 ParagonIE_Sodium_Compat::add($val, $addv); 107 } 108 } 109 if (!is_callable('sodium_base642bin')) { 110 /** 111 * @see ParagonIE_Sodium_Compat::bin2base64() 112 * @param string $string 113 * @param int $variant 114 * @param string $ignore 115 * @return string 116 * @throws SodiumException 117 * @throws TypeError 118 */ 119 function sodium_base642bin($string, $variant, $ignore ='') 120 { 121 return ParagonIE_Sodium_Compat::base642bin($string, $variant, $ignore); 122 } 123 } 124 if (!is_callable('sodium_bin2base64')) { 125 /** 126 * @see ParagonIE_Sodium_Compat::bin2base64() 127 * @param string $string 128 * @param int $variant 129 * @return string 130 * @throws SodiumException 131 * @throws TypeError 132 */ 133 function sodium_bin2base64($string, $variant) 134 { 135 return ParagonIE_Sodium_Compat::bin2base64($string, $variant); 136 } 137 } 76 138 if (!is_callable('sodium_bin2hex')) { 77 139 /** … … 187 249 * @see ParagonIE_Sodium_Compat::crypto_aead_chacha20poly1305_keygen() 188 250 * @return string 251 * @throws Exception 189 252 */ 190 253 function sodium_crypto_aead_chacha20poly1305_keygen() … … 233 296 * @see ParagonIE_Sodium_Compat::crypto_aead_chacha20poly1305_ietf_keygen() 234 297 * @return string 298 * @throws Exception 235 299 */ 236 300 function sodium_crypto_aead_chacha20poly1305_ietf_keygen() … … 279 343 * @see ParagonIE_Sodium_Compat::crypto_aead_xchacha20poly1305_ietf_keygen() 280 344 * @return string 345 * @throws Exception 281 346 */ 282 347 function sodium_crypto_aead_xchacha20poly1305_ietf_keygen() … … 303 368 * @see ParagonIE_Sodium_Compat::crypto_auth_keygen() 304 369 * @return string 370 * @throws Exception 305 371 */ 306 372 function sodium_crypto_auth_keygen() … … 517 583 * @see ParagonIE_Sodium_Compat::crypto_generichash_keygen() 518 584 * @return string 585 * @throws Exception 519 586 */ 520 587 function sodium_crypto_generichash_keygen() … … 535 602 { 536 603 ParagonIE_Sodium_Compat::crypto_generichash_update($ctx, $message); 604 } 605 } 606 if (!is_callable('sodium_crypto_kdf_keygen')) { 607 /** 608 * @see ParagonIE_Sodium_Compat::crypto_kdf_keygen() 609 * @return string 610 * @throws Exception 611 */ 612 function sodium_crypto_kdf_keygen() 613 { 614 return ParagonIE_Sodium_Compat::crypto_kdf_keygen(); 615 } 616 } 617 if (!is_callable('sodium_crypto_kdf_derive_from_key')) { 618 /** 619 * @see ParagonIE_Sodium_Compat::crypto_kdf_derive_from_key() 620 * @param int $subkey_len 621 * @param int $subkey_id 622 * @param string $context 623 * @param string $key 624 * @return string 625 * @throws Exception 626 */ 627 function sodium_crypto_kdf_derive_from_key($subkey_len, $subkey_id, $context, $key) 628 { 629 return ParagonIE_Sodium_Compat::crypto_kdf_derive_from_key( 630 $subkey_len, 631 $subkey_id, 632 $context, 633 $key 634 ); 537 635 } 538 636 } … … 556 654 $server_public 557 655 ); 656 } 657 } 658 if (!is_callable('sodium_crypto_kx_seed_keypair')) { 659 /** 660 * @param string $seed 661 * @return string 662 * @throws Exception 663 */ 664 function sodium_crypto_kx_seed_keypair($seed) 665 { 666 return ParagonIE_Sodium_Compat::crypto_kx_seed_keypair($seed); 667 } 668 } 669 if (!is_callable('sodium_crypto_kx_keypair')) { 670 /** 671 * @return string 672 * @throws Exception 673 */ 674 function sodium_crypto_kx_keypair() 675 { 676 return ParagonIE_Sodium_Compat::crypto_kx_keypair(); 677 } 678 } 679 if (!is_callable('sodium_crypto_kx_client_session_keys')) { 680 /** 681 * @param string $keypair 682 * @param string $serverPublicKey 683 * @return array{0: string, 1: string} 684 * @throws SodiumException 685 */ 686 function sodium_crypto_kx_client_session_keys($keypair, $serverPublicKey) 687 { 688 return ParagonIE_Sodium_Compat::crypto_kx_client_session_keys($keypair, $serverPublicKey); 689 } 690 } 691 if (!is_callable('sodium_crypto_kx_server_session_keys')) { 692 /** 693 * @param string $keypair 694 * @param string $clientPublicKey 695 * @return array{0: string, 1: string} 696 * @throws SodiumException 697 */ 698 function sodium_crypto_kx_server_session_keys($keypair, $clientPublicKey) 699 { 700 return ParagonIE_Sodium_Compat::crypto_kx_server_session_keys($keypair, $clientPublicKey); 701 } 702 } 703 if (!is_callable('sodium_crypto_kx_secretkey')) { 704 /** 705 * @param string $keypair 706 * @return string 707 * @throws Exception 708 */ 709 function sodium_crypto_kx_secretkey($keypair) 710 { 711 return ParagonIE_Sodium_Compat::crypto_kx_secretkey($keypair); 712 } 713 } 714 if (!is_callable('sodium_crypto_kx_publickey')) { 715 /** 716 * @param string $keypair 717 * @return string 718 * @throws Exception 719 */ 720 function sodium_crypto_kx_publickey($keypair) 721 { 722 return ParagonIE_Sodium_Compat::crypto_kx_publickey($keypair); 558 723 } 559 724 } … … 591 756 } 592 757 } 758 if (!is_callable('sodium_crypto_pwhash_str_needs_rehash')) { 759 /** 760 * @see ParagonIE_Sodium_Compat::crypto_pwhash_str_needs_rehash() 761 * @param string $hash 762 * @param int $opslimit 763 * @param int $memlimit 764 * @return bool 765 * 766 * @throws SodiumException 767 */ 768 function sodium_crypto_pwhash_str_needs_rehash($hash, $opslimit, $memlimit) 769 { 770 return ParagonIE_Sodium_Compat::crypto_pwhash_str_needs_rehash($hash, $opslimit, $memlimit); 771 } 772 } 593 773 if (!is_callable('sodium_crypto_pwhash_str_verify')) { 594 774 /** … … 697 877 * @see ParagonIE_Sodium_Compat::crypto_secretbox_keygen() 698 878 * @return string 879 * @throws Exception 699 880 */ 700 881 function sodium_crypto_secretbox_keygen() … … 722 903 } 723 904 } 905 if (!is_callable('sodium_crypto_secretstream_xchacha20poly1305_init_push')) { 906 /** 907 * @param string $key 908 * @return array<int, string> 909 * @throws SodiumException 910 */ 911 function sodium_crypto_secretstream_xchacha20poly1305_init_push($key) 912 { 913 return ParagonIE_Sodium_Compat::crypto_secretstream_xchacha20poly1305_init_push($key); 914 } 915 } 916 if (!is_callable('sodium_crypto_secretstream_xchacha20poly1305_push')) { 917 /** 918 * @param string $state 919 * @param string $msg 920 * @param string $aad 921 * @param int $tag 922 * @return string 923 * @throws SodiumException 924 */ 925 function sodium_crypto_secretstream_xchacha20poly1305_push(&$state, $msg, $aad = '', $tag = 0) 926 { 927 return ParagonIE_Sodium_Compat::crypto_secretstream_xchacha20poly1305_push($state, $msg, $aad, $tag); 928 } 929 } 930 if (!is_callable('sodium_crypto_secretstream_xchacha20poly1305_init_pull')) { 931 /** 932 * @param string $header 933 * @param string $key 934 * @return string 935 * @throws Exception 936 */ 937 function sodium_crypto_secretstream_xchacha20poly1305_init_pull($header, $key) 938 { 939 return ParagonIE_Sodium_Compat::crypto_secretstream_xchacha20poly1305_init_pull($header, $key); 940 } 941 } 942 if (!is_callable('sodium_crypto_secretstream_xchacha20poly1305_pull')) { 943 /** 944 * @param string $state 945 * @param string $cipher 946 * @param string $aad 947 * @return bool|array{0: string, 1: int} 948 * @throws SodiumException 949 */ 950 function sodium_crypto_secretstream_xchacha20poly1305_pull(&$state, $cipher, $aad = '') 951 { 952 return ParagonIE_Sodium_Compat::crypto_secretstream_xchacha20poly1305_pull($state, $cipher, $aad); 953 } 954 } 955 if (!is_callable('sodium_crypto_secretstream_xchacha20poly1305_rekey')) { 956 /** 957 * @param string $state 958 * @return void 959 * @throws SodiumException 960 */ 961 function sodium_crypto_secretstream_xchacha20poly1305_rekey(&$state) 962 { 963 ParagonIE_Sodium_Compat::crypto_secretstream_xchacha20poly1305_rekey($state); 964 } 965 } 966 if (!is_callable('sodium_crypto_secretstream_xchacha20poly1305_keygen')) { 967 /** 968 * @return string 969 * @throws Exception 970 */ 971 function sodium_crypto_secretstream_xchacha20poly1305_keygen() 972 { 973 return ParagonIE_Sodium_Compat::crypto_secretstream_xchacha20poly1305_keygen(); 974 } 975 } 724 976 if (!is_callable('sodium_crypto_shorthash')) { 725 977 /** … … 740 992 * @see ParagonIE_Sodium_Compat::crypto_shorthash_keygen() 741 993 * @return string 994 * @throws Exception 742 995 */ 743 996 function sodium_crypto_shorthash_keygen() … … 772 1025 { 773 1026 return ParagonIE_Sodium_Compat::crypto_sign_detached($message, $sk); 1027 } 1028 } 1029 if (!is_callable('sodium_crypto_sign_keypair_from_secretkey_and_publickey')) { 1030 /** 1031 * @see ParagonIE_Sodium_Compat::crypto_sign_keypair_from_secretkey_and_publickey() 1032 * @param string $sk 1033 * @param string $pk 1034 * @return string 1035 * @throws SodiumException 1036 * @throws TypeError 1037 */ 1038 function sodium_crypto_sign_keypair_from_secretkey_and_publickey($sk, $pk) 1039 { 1040 return ParagonIE_Sodium_Compat::crypto_sign_keypair_from_secretkey_and_publickey($sk, $pk); 774 1041 } 775 1042 } … … 916 1183 * @see ParagonIE_Sodium_Compat::crypto_stream_keygen() 917 1184 * @return string 1185 * @throws Exception 918 1186 */ 919 1187 function sodium_crypto_stream_keygen() … … 1020 1288 } 1021 1289 } 1290 if (!is_callable('sodium_pad')) { 1291 /** 1292 * @see ParagonIE_Sodium_Compat::pad() 1293 * @param string $unpadded 1294 * @param int $blockSize 1295 * @return int 1296 * @throws SodiumException 1297 * @throws TypeError 1298 */ 1299 function sodium_pad($unpadded, $blockSize) 1300 { 1301 return ParagonIE_Sodium_Compat::pad($unpadded, $blockSize, true); 1302 } 1303 } 1304 if (!is_callable('sodium_unpad')) { 1305 /** 1306 * @see ParagonIE_Sodium_Compat::pad() 1307 * @param string $padded 1308 * @param int $blockSize 1309 * @return int 1310 * @throws SodiumException 1311 * @throws TypeError 1312 */ 1313 function sodium_unpad($padded, $blockSize) 1314 { 1315 return ParagonIE_Sodium_Compat::unpad($padded, $blockSize, true); 1316 } 1317 } 1022 1318 if (!is_callable('sodium_randombytes_buf')) { 1023 1319 /** … … 1050 1346 * @see ParagonIE_Sodium_Compat::randombytes_random16() 1051 1347 * @return int 1348 * @throws Exception 1052 1349 */ 1053 1350 function sodium_randombytes_random16() -
trunk/src/wp-includes/sodium_compat/lib/sodium_compat.php
r46586 r46858 1 1 <?php 2 2 namespace Sodium; 3 4 require_once dirname(dirname(__FILE__)) . '/autoload.php'; 3 5 4 6 use ParagonIE_Sodium_Compat; -
trunk/src/wp-includes/sodium_compat/src/Compat.php
r46586 r46858 50 50 51 51 // From libsodium 52 const BASE64_VARIANT_ORIGINAL = 1; 53 const BASE64_VARIANT_ORIGINAL_NO_PADDING = 3; 54 const BASE64_VARIANT_URLSAFE = 5; 55 const BASE64_VARIANT_URLSAFE_NO_PADDING = 7; 52 56 const CRYPTO_AEAD_AES256GCM_KEYBYTES = 32; 53 57 const CRYPTO_AEAD_AES256GCM_NSECBYTES = 0; … … 75 79 const CRYPTO_BOX_NONCEBYTES = 24; 76 80 const CRYPTO_BOX_SEEDBYTES = 32; 81 const CRYPTO_KDF_BYTES_MIN = 16; 82 const CRYPTO_KDF_BYTES_MAX = 64; 83 const CRYPTO_KDF_CONTEXTBYTES = 8; 84 const CRYPTO_KDF_KEYBYTES = 32; 77 85 const CRYPTO_KX_BYTES = 32; 86 const CRYPTO_KX_PRIMITIVE = 'x25519blake2b'; 78 87 const CRYPTO_KX_SEEDBYTES = 32; 88 const CRYPTO_KX_KEYPAIRBYTES = 64; 79 89 const CRYPTO_KX_PUBLICKEYBYTES = 32; 80 90 const CRYPTO_KX_SECRETKEYBYTES = 32; 91 const CRYPTO_KX_SESSIONKEYBYTES = 32; 81 92 const CRYPTO_GENERICHASH_BYTES = 32; 82 93 const CRYPTO_GENERICHASH_BYTES_MIN = 16; … … 86 97 const CRYPTO_GENERICHASH_KEYBYTES_MAX = 64; 87 98 const CRYPTO_PWHASH_SALTBYTES = 16; 88 const CRYPTO_PWHASH_STRPREFIX = '$argon2i $';99 const CRYPTO_PWHASH_STRPREFIX = '$argon2id$'; 89 100 const CRYPTO_PWHASH_ALG_ARGON2I13 = 1; 90 101 const CRYPTO_PWHASH_ALG_ARGON2ID13 = 2; … … 108 119 const CRYPTO_SECRETBOX_MACBYTES = 16; 109 120 const CRYPTO_SECRETBOX_NONCEBYTES = 24; 121 const CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_ABYTES = 17; 122 const CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_HEADERBYTES = 24; 123 const CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_KEYBYTES = 32; 124 const CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_TAG_PUSH = 0; 125 const CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_TAG_PULL = 1; 126 const CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_TAG_REKEY = 2; 127 const CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_TAG_FINAL = 3; 128 const CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_MESSAGEBYTES_MAX = 0x3fffffff80; 110 129 const CRYPTO_SIGN_BYTES = 64; 111 130 const CRYPTO_SIGN_SEEDBYTES = 32; … … 115 134 const CRYPTO_STREAM_KEYBYTES = 32; 116 135 const CRYPTO_STREAM_NONCEBYTES = 24; 136 137 /** 138 * Add two numbers (little-endian unsigned), storing the value in the first 139 * parameter. 140 * 141 * This mutates $val. 142 * 143 * @param string $val 144 * @param string $addv 145 * @return void 146 * @throws SodiumException 147 */ 148 public static function add(&$val, $addv) 149 { 150 $val_len = ParagonIE_Sodium_Core_Util::strlen($val); 151 $addv_len = ParagonIE_Sodium_Core_Util::strlen($addv); 152 if ($val_len !== $addv_len) { 153 throw new SodiumException('values must have the same length'); 154 } 155 $A = ParagonIE_Sodium_Core_Util::stringToIntArray($val); 156 $B = ParagonIE_Sodium_Core_Util::stringToIntArray($addv); 157 158 $c = 0; 159 for ($i = 0; $i < $val_len; $i++) { 160 $c += ($A[$i] + $B[$i]); 161 $A[$i] = ($c & 0xff); 162 $c >>= 8; 163 } 164 $val = ParagonIE_Sodium_Core_Util::intArrayToString($A); 165 } 166 167 /** 168 * @param string $encoded 169 * @param int $variant 170 * @param string $ignore 171 * @return string 172 * @throws SodiumException 173 */ 174 public static function base642bin($encoded, $variant, $ignore = '') 175 { 176 /* Type checks: */ 177 ParagonIE_Sodium_Core_Util::declareScalarType($encoded, 'string', 1); 178 179 /** @var string $encoded */ 180 $encoded = (string) $encoded; 181 if (ParagonIE_Sodium_Core_Util::strlen($encoded) === 0) { 182 return ''; 183 } 184 185 // Just strip before decoding 186 if (!empty($ignore)) { 187 $encoded = str_replace($ignore, '', $encoded); 188 } 189 190 try { 191 switch ($variant) { 192 case self::BASE64_VARIANT_ORIGINAL: 193 return ParagonIE_Sodium_Core_Base64_Original::decode($encoded, true); 194 case self::BASE64_VARIANT_ORIGINAL_NO_PADDING: 195 return ParagonIE_Sodium_Core_Base64_Original::decode($encoded, false); 196 case self::BASE64_VARIANT_URLSAFE: 197 return ParagonIE_Sodium_Core_Base64_UrlSafe::decode($encoded, true); 198 case self::BASE64_VARIANT_URLSAFE_NO_PADDING: 199 return ParagonIE_Sodium_Core_Base64_UrlSafe::decode($encoded, false); 200 default: 201 throw new SodiumException('invalid base64 variant identifier'); 202 } 203 } catch (Exception $ex) { 204 if ($ex instanceof SodiumException) { 205 throw $ex; 206 } 207 throw new SodiumException('invalid base64 string'); 208 } 209 } 210 211 /** 212 * @param string $decoded 213 * @param int $variant 214 * @return string 215 * @throws SodiumException 216 */ 217 public static function bin2base64($decoded, $variant) 218 { 219 /* Type checks: */ 220 ParagonIE_Sodium_Core_Util::declareScalarType($decoded, 'string', 1); 221 /** @var string $decoded */ 222 $decoded = (string) $decoded; 223 if (ParagonIE_Sodium_Core_Util::strlen($decoded) === 0) { 224 return ''; 225 } 226 227 switch ($variant) { 228 case self::BASE64_VARIANT_ORIGINAL: 229 return ParagonIE_Sodium_Core_Base64_Original::encode($decoded); 230 case self::BASE64_VARIANT_ORIGINAL_NO_PADDING: 231 return ParagonIE_Sodium_Core_Base64_Original::encodeUnpadded($decoded); 232 case self::BASE64_VARIANT_URLSAFE: 233 return ParagonIE_Sodium_Core_Base64_UrlSafe::encode($decoded); 234 case self::BASE64_VARIANT_URLSAFE_NO_PADDING: 235 return ParagonIE_Sodium_Core_Base64_UrlSafe::encodeUnpadded($decoded); 236 default: 237 throw new SodiumException('invalid base64 variant identifier'); 238 } 239 } 117 240 118 241 /** … … 1311 1434 * @psalm-suppress MixedArgument 1312 1435 * @psalm-suppress ReferenceConstraintViolation 1436 * @psalm-suppress ConflictingReferenceConstraint 1313 1437 */ 1314 1438 public static function crypto_generichash_final(&$ctx, $length = self::CRYPTO_GENERICHASH_BYTES) … … 1324 1448 $func = '\\Sodium\\crypto_generichash_final'; 1325 1449 return (string) $func($ctx, $length); 1450 } 1451 if ($length < 1) { 1452 try { 1453 self::memzero($ctx); 1454 } catch (SodiumException $ex) { 1455 unset($ctx); 1456 } 1457 return ''; 1326 1458 } 1327 1459 if (PHP_INT_SIZE === 4) { … … 1381 1513 1382 1514 /** 1515 * Initialize a BLAKE2b hashing context, for use in a streaming interface. 1516 * 1517 * @param string|null $key If specified must be a string between 16 and 64 bytes 1518 * @param int $length The size of the desired hash output 1519 * @param string $salt Salt (up to 16 bytes) 1520 * @param string $personal Personalization string (up to 16 bytes) 1521 * @return string A BLAKE2 hashing context, encoded as a string 1522 * (To be 100% compatible with ext/libsodium) 1523 * @throws SodiumException 1524 * @throws TypeError 1525 * @psalm-suppress MixedArgument 1526 */ 1527 public static function crypto_generichash_init_salt_personal( 1528 $key = '', 1529 $length = self::CRYPTO_GENERICHASH_BYTES, 1530 $salt = '', 1531 $personal = '' 1532 ) { 1533 /* Type checks: */ 1534 if (is_null($key)) { 1535 $key = ''; 1536 } 1537 ParagonIE_Sodium_Core_Util::declareScalarType($key, 'string', 1); 1538 ParagonIE_Sodium_Core_Util::declareScalarType($length, 'int', 2); 1539 ParagonIE_Sodium_Core_Util::declareScalarType($salt, 'string', 3); 1540 ParagonIE_Sodium_Core_Util::declareScalarType($personal, 'string', 4); 1541 $salt = str_pad($salt, 16, "\0", STR_PAD_RIGHT); 1542 $personal = str_pad($personal, 16, "\0", STR_PAD_RIGHT); 1543 1544 /* Input validation: */ 1545 if (!empty($key)) { 1546 /* 1547 if (ParagonIE_Sodium_Core_Util::strlen($key) < self::CRYPTO_GENERICHASH_KEYBYTES_MIN) { 1548 throw new SodiumException('Unsupported key size. Must be at least CRYPTO_GENERICHASH_KEYBYTES_MIN bytes long.'); 1549 } 1550 */ 1551 if (ParagonIE_Sodium_Core_Util::strlen($key) > self::CRYPTO_GENERICHASH_KEYBYTES_MAX) { 1552 throw new SodiumException('Unsupported key size. Must be at most CRYPTO_GENERICHASH_KEYBYTES_MAX bytes long.'); 1553 } 1554 } 1555 if (PHP_INT_SIZE === 4) { 1556 return ParagonIE_Sodium_Crypto32::generichash_init_salt_personal($key, $length, $salt, $personal); 1557 } 1558 return ParagonIE_Sodium_Crypto::generichash_init_salt_personal($key, $length, $salt, $personal); 1559 } 1560 1561 /** 1383 1562 * Update a BLAKE2b hashing context with additional data. 1384 1563 * … … 1423 1602 { 1424 1603 return random_bytes(self::CRYPTO_GENERICHASH_KEYBYTES); 1604 } 1605 1606 /** 1607 * @param int $subkey_len 1608 * @param int $subkey_id 1609 * @param string $context 1610 * @param string $key 1611 * @return string 1612 * @throws SodiumException 1613 */ 1614 public static function crypto_kdf_derive_from_key( 1615 $subkey_len, 1616 $subkey_id, 1617 $context, 1618 $key 1619 ) { 1620 ParagonIE_Sodium_Core_Util::declareScalarType($subkey_len, 'int', 1); 1621 ParagonIE_Sodium_Core_Util::declareScalarType($subkey_id, 'int', 2); 1622 ParagonIE_Sodium_Core_Util::declareScalarType($context, 'string', 3); 1623 ParagonIE_Sodium_Core_Util::declareScalarType($key, 'string', 4); 1624 $subkey_id = (int) $subkey_id; 1625 $subkey_len = (int) $subkey_len; 1626 $context = (string) $context; 1627 $key = (string) $key; 1628 1629 if ($subkey_len < self::CRYPTO_KDF_BYTES_MIN) { 1630 throw new SodiumException('subkey cannot be smaller than SODIUM_CRYPTO_KDF_BYTES_MIN'); 1631 } 1632 if ($subkey_len > self::CRYPTO_KDF_BYTES_MAX) { 1633 throw new SodiumException('subkey cannot be larger than SODIUM_CRYPTO_KDF_BYTES_MAX'); 1634 } 1635 if ($subkey_id < 0) { 1636 throw new SodiumException('subkey_id cannot be negative'); 1637 } 1638 if (ParagonIE_Sodium_Core_Util::strlen($context) !== self::CRYPTO_KDF_CONTEXTBYTES) { 1639 throw new SodiumException('context should be SODIUM_CRYPTO_KDF_CONTEXTBYTES bytes'); 1640 } 1641 if (ParagonIE_Sodium_Core_Util::strlen($key) !== self::CRYPTO_KDF_KEYBYTES) { 1642 throw new SodiumException('key should be SODIUM_CRYPTO_KDF_KEYBYTES bytes'); 1643 } 1644 1645 $salt = ParagonIE_Sodium_Core_Util::store64_le($subkey_id); 1646 $state = self::crypto_generichash_init_salt_personal( 1647 $key, 1648 $subkey_len, 1649 $salt, 1650 $context 1651 ); 1652 return self::crypto_generichash_final($state, $subkey_len); 1653 } 1654 1655 /** 1656 * @return string 1657 * @throws Exception 1658 * @throws Error 1659 */ 1660 public static function crypto_kdf_keygen() 1661 { 1662 return random_bytes(self::CRYPTO_KDF_KEYBYTES); 1425 1663 } 1426 1664 … … 1512 1750 1513 1751 /** 1752 * @param string $seed 1753 * @return string 1754 * @throws SodiumException 1755 */ 1756 public static function crypto_kx_seed_keypair($seed) 1757 { 1758 ParagonIE_Sodium_Core_Util::declareScalarType($seed, 'string', 1); 1759 1760 $seed = (string) $seed; 1761 1762 if (ParagonIE_Sodium_Core_Util::strlen($seed) !== self::CRYPTO_KX_SEEDBYTES) { 1763 throw new SodiumException('seed must be SODIUM_CRYPTO_KX_SEEDBYTES bytes'); 1764 } 1765 1766 $sk = self::crypto_generichash($seed, '', self::CRYPTO_KX_SECRETKEYBYTES); 1767 $pk = self::crypto_scalarmult_base($sk); 1768 return $sk . $pk; 1769 } 1770 1771 /** 1772 * @return string 1773 * @throws Exception 1774 */ 1775 public static function crypto_kx_keypair() 1776 { 1777 $sk = self::randombytes_buf(self::CRYPTO_KX_SECRETKEYBYTES); 1778 $pk = self::crypto_scalarmult_base($sk); 1779 return $sk . $pk; 1780 } 1781 1782 /** 1783 * @param string $keypair 1784 * @param string $serverPublicKey 1785 * @return array{0: string, 1: string} 1786 * @throws SodiumException 1787 */ 1788 public static function crypto_kx_client_session_keys($keypair, $serverPublicKey) 1789 { 1790 ParagonIE_Sodium_Core_Util::declareScalarType($keypair, 'string', 1); 1791 ParagonIE_Sodium_Core_Util::declareScalarType($serverPublicKey, 'string', 2); 1792 1793 $keypair = (string) $keypair; 1794 $serverPublicKey = (string) $serverPublicKey; 1795 1796 if (ParagonIE_Sodium_Core_Util::strlen($keypair) !== self::CRYPTO_KX_KEYPAIRBYTES) { 1797 throw new SodiumException('keypair should be SODIUM_CRYPTO_KX_KEYPAIRBYTES bytes'); 1798 } 1799 if (ParagonIE_Sodium_Core_Util::strlen($serverPublicKey) !== self::CRYPTO_KX_PUBLICKEYBYTES) { 1800 throw new SodiumException('public keys must be SODIUM_CRYPTO_KX_PUBLICKEYBYTES bytes'); 1801 } 1802 1803 $sk = self::crypto_kx_secretkey($keypair); 1804 $pk = self::crypto_kx_publickey($keypair); 1805 $h = self::crypto_generichash_init(null, self::CRYPTO_KX_SESSIONKEYBYTES * 2); 1806 self::crypto_generichash_update($h, self::crypto_scalarmult($sk, $serverPublicKey)); 1807 self::crypto_generichash_update($h, $pk); 1808 self::crypto_generichash_update($h, $serverPublicKey); 1809 $sessionKeys = self::crypto_generichash_final($h, self::CRYPTO_KX_SESSIONKEYBYTES * 2); 1810 return array( 1811 ParagonIE_Sodium_Core_Util::substr( 1812 $sessionKeys, 1813 0, 1814 self::CRYPTO_KX_SESSIONKEYBYTES 1815 ), 1816 ParagonIE_Sodium_Core_Util::substr( 1817 $sessionKeys, 1818 self::CRYPTO_KX_SESSIONKEYBYTES, 1819 self::CRYPTO_KX_SESSIONKEYBYTES 1820 ) 1821 ); 1822 } 1823 1824 /** 1825 * @param string $keypair 1826 * @param string $clientPublicKey 1827 * @return array{0: string, 1: string} 1828 * @throws SodiumException 1829 */ 1830 public static function crypto_kx_server_session_keys($keypair, $clientPublicKey) 1831 { 1832 ParagonIE_Sodium_Core_Util::declareScalarType($keypair, 'string', 1); 1833 ParagonIE_Sodium_Core_Util::declareScalarType($clientPublicKey, 'string', 2); 1834 1835 $keypair = (string) $keypair; 1836 $clientPublicKey = (string) $clientPublicKey; 1837 1838 if (ParagonIE_Sodium_Core_Util::strlen($keypair) !== self::CRYPTO_KX_KEYPAIRBYTES) { 1839 throw new SodiumException('keypair should be SODIUM_CRYPTO_KX_KEYPAIRBYTES bytes'); 1840 } 1841 if (ParagonIE_Sodium_Core_Util::strlen($clientPublicKey) !== self::CRYPTO_KX_PUBLICKEYBYTES) { 1842 throw new SodiumException('public keys must be SODIUM_CRYPTO_KX_PUBLICKEYBYTES bytes'); 1843 } 1844 1845 $sk = self::crypto_kx_secretkey($keypair); 1846 $pk = self::crypto_kx_publickey($keypair); 1847 $h = self::crypto_generichash_init(null, self::CRYPTO_KX_SESSIONKEYBYTES * 2); 1848 self::crypto_generichash_update($h, self::crypto_scalarmult($sk, $clientPublicKey)); 1849 self::crypto_generichash_update($h, $clientPublicKey); 1850 self::crypto_generichash_update($h, $pk); 1851 $sessionKeys = self::crypto_generichash_final($h, self::CRYPTO_KX_SESSIONKEYBYTES * 2); 1852 return array( 1853 ParagonIE_Sodium_Core_Util::substr( 1854 $sessionKeys, 1855 self::CRYPTO_KX_SESSIONKEYBYTES, 1856 self::CRYPTO_KX_SESSIONKEYBYTES 1857 ), 1858 ParagonIE_Sodium_Core_Util::substr( 1859 $sessionKeys, 1860 0, 1861 self::CRYPTO_KX_SESSIONKEYBYTES 1862 ) 1863 ); 1864 } 1865 1866 /** 1867 * @param string $kp 1868 * @return string 1869 * @throws SodiumException 1870 */ 1871 public static function crypto_kx_secretkey($kp) 1872 { 1873 return ParagonIE_Sodium_Core_Util::substr( 1874 $kp, 1875 0, 1876 self::CRYPTO_KX_SECRETKEYBYTES 1877 ); 1878 } 1879 1880 /** 1881 * @param string $kp 1882 * @return string 1883 * @throws SodiumException 1884 */ 1885 public static function crypto_kx_publickey($kp) 1886 { 1887 return ParagonIE_Sodium_Core_Util::substr( 1888 $kp, 1889 self::CRYPTO_KX_SECRETKEYBYTES, 1890 self::CRYPTO_KX_PUBLICKEYBYTES 1891 ); 1892 } 1893 1894 /** 1514 1895 * @param int $outlen 1515 1896 * @param string $passwd … … 1591 1972 'This is not implemented, as it is not possible to implement Argon2i with acceptable performance in pure-PHP' 1592 1973 ); 1974 } 1975 1976 /** 1977 * Do we need to rehash this password? 1978 * 1979 * @param string $hash 1980 * @param int $opslimit 1981 * @param int $memlimit 1982 * @return bool 1983 * @throws SodiumException 1984 */ 1985 public static function crypto_pwhash_str_needs_rehash($hash, $opslimit, $memlimit) 1986 { 1987 ParagonIE_Sodium_Core_Util::declareScalarType($hash, 'string', 1); 1988 ParagonIE_Sodium_Core_Util::declareScalarType($opslimit, 'int', 2); 1989 ParagonIE_Sodium_Core_Util::declareScalarType($memlimit, 'int', 3); 1990 1991 // Just grab the first 4 pieces. 1992 $pieces = explode('$', (string) $hash); 1993 $prefix = implode('$', array_slice($pieces, 0, 4)); 1994 1995 // Rebuild the expected header. 1996 /** @var int $ops */ 1997 $ops = (int) $opslimit; 1998 /** @var int $mem */ 1999 $mem = (int) $memlimit >> 10; 2000 $encoded = self::CRYPTO_PWHASH_STRPREFIX . 'v=19$m=' . $mem . ',t=' . $ops . ',p=1'; 2001 2002 // Do they match? If so, we don't need to rehash, so return false. 2003 return !ParagonIE_Sodium_Core_Util::hashEquals($encoded, $prefix); 1593 2004 } 1594 2005 … … 1989 2400 1990 2401 /** 2402 * @param string $key 2403 * @return array<int, string> Returns a state and a header. 2404 * @throws Exception 2405 * @throws SodiumException 2406 */ 2407 public static function crypto_secretstream_xchacha20poly1305_init_push($key) 2408 { 2409 if (PHP_INT_SIZE === 4) { 2410 return ParagonIE_Sodium_Crypto32::secretstream_xchacha20poly1305_init_push($key); 2411 } 2412 return ParagonIE_Sodium_Crypto::secretstream_xchacha20poly1305_init_push($key); 2413 } 2414 2415 /** 2416 * @param string $header 2417 * @param string $key 2418 * @return string Returns a state. 2419 * @throws Exception 2420 */ 2421 public static function crypto_secretstream_xchacha20poly1305_init_pull($header, $key) 2422 { 2423 if (ParagonIE_Sodium_Core_Util::strlen($header) < self::CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_HEADERBYTES) { 2424 throw new SodiumException( 2425 'header size should be SODIUM_CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_HEADERBYTES bytes' 2426 ); 2427 } 2428 if (PHP_INT_SIZE === 4) { 2429 return ParagonIE_Sodium_Crypto32::secretstream_xchacha20poly1305_init_pull($key, $header); 2430 } 2431 return ParagonIE_Sodium_Crypto::secretstream_xchacha20poly1305_init_pull($key, $header); 2432 } 2433 2434 /** 2435 * @param string $state 2436 * @param string $msg 2437 * @param string $aad 2438 * @param int $tag 2439 * @return string 2440 * @throws SodiumException 2441 */ 2442 public static function crypto_secretstream_xchacha20poly1305_push(&$state, $msg, $aad = '', $tag = 0) 2443 { 2444 if (PHP_INT_SIZE === 4) { 2445 return ParagonIE_Sodium_Crypto32::secretstream_xchacha20poly1305_push( 2446 $state, 2447 $msg, 2448 $aad, 2449 $tag 2450 ); 2451 } 2452 return ParagonIE_Sodium_Crypto::secretstream_xchacha20poly1305_push( 2453 $state, 2454 $msg, 2455 $aad, 2456 $tag 2457 ); 2458 } 2459 2460 /** 2461 * @param string $state 2462 * @param string $msg 2463 * @param string $aad 2464 * @return bool|array{0: string, 1: int} 2465 * @throws SodiumException 2466 */ 2467 public static function crypto_secretstream_xchacha20poly1305_pull(&$state, $msg, $aad = '') 2468 { 2469 if (PHP_INT_SIZE === 4) { 2470 return ParagonIE_Sodium_Crypto32::secretstream_xchacha20poly1305_pull( 2471 $state, 2472 $msg, 2473 $aad 2474 ); 2475 } 2476 return ParagonIE_Sodium_Crypto::secretstream_xchacha20poly1305_pull( 2477 $state, 2478 $msg, 2479 $aad 2480 ); 2481 } 2482 2483 /** 2484 * @return string 2485 * @throws Exception 2486 */ 2487 public static function crypto_secretstream_xchacha20poly1305_keygen() 2488 { 2489 return random_bytes(self::CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_KEYBYTES); 2490 } 2491 2492 /** 2493 * @param string $state 2494 * @return void 2495 * @throws SodiumException 2496 */ 2497 public static function crypto_secretstream_xchacha20poly1305_rekey(&$state) 2498 { 2499 if (PHP_INT_SIZE === 4) { 2500 ParagonIE_Sodium_Crypto32::secretstream_xchacha20poly1305_rekey($state); 2501 } else { 2502 ParagonIE_Sodium_Crypto::secretstream_xchacha20poly1305_rekey($state); 2503 } 2504 } 2505 2506 /** 1991 2507 * Calculates a SipHash-2-4 hash of a message for a given key. 1992 2508 * … … 2135 2651 } 2136 2652 return ParagonIE_Sodium_Core_Ed25519::keypair(); 2653 } 2654 2655 /** 2656 * @param string $sk 2657 * @param string $pk 2658 * @return string 2659 * @throws SodiumException 2660 */ 2661 public static function crypto_sign_keypair_from_secretkey_and_publickey($sk, $pk) 2662 { 2663 ParagonIE_Sodium_Core_Util::declareScalarType($sk, 'string', 1); 2664 ParagonIE_Sodium_Core_Util::declareScalarType($pk, 'string', 1); 2665 $sk = (string) $sk; 2666 $pk = (string) $pk; 2667 2668 if (ParagonIE_Sodium_Core_Util::strlen($sk) !== self::CRYPTO_SIGN_SECRETKEYBYTES) { 2669 throw new SodiumException('secretkey should be SODIUM_CRYPTO_SIGN_SECRETKEYBYTES bytes'); 2670 } 2671 if (ParagonIE_Sodium_Core_Util::strlen($pk) !== self::CRYPTO_SIGN_PUBLICKEYBYTES) { 2672 throw new SodiumException('publickey should be SODIUM_CRYPTO_SIGN_PUBLICKEYBYTES bytes'); 2673 } 2674 2675 if (self::useNewSodiumAPI()) { 2676 return sodium_crypto_sign_keypair_from_secretkey_and_publickey($sk, $pk); 2677 } 2678 return $sk . $pk; 2137 2679 } 2138 2680 … … 2625 3167 ParagonIE_Sodium_Core_Util::declareScalarType($right, 'string', 2); 2626 3168 3169 if (self::useNewSodiumAPI()) { 3170 return sodium_memcmp($left, $right); 3171 } 2627 3172 if (self::use_fallback('memcmp')) { 2628 3173 return (int) call_user_func('\\Sodium\\memcmp', $left, $right); … … 2667 3212 'To fix this error, make sure libsodium is installed and the PHP extension is enabled.' 2668 3213 ); 3214 } 3215 3216 /** 3217 * @param string $unpadded 3218 * @param int $blockSize 3219 * @param bool $dontFallback 3220 * @return string 3221 * @throws SodiumException 3222 */ 3223 public static function pad($unpadded, $blockSize, $dontFallback = false) 3224 { 3225 /* Type checks: */ 3226 ParagonIE_Sodium_Core_Util::declareScalarType($unpadded, 'string', 1); 3227 ParagonIE_Sodium_Core_Util::declareScalarType($blockSize, 'int', 2); 3228 3229 $unpadded = (string) $unpadded; 3230 $blockSize = (int) $blockSize; 3231 3232 if (self::useNewSodiumAPI() && !$dontFallback) { 3233 return (string) sodium_pad($unpadded, $blockSize); 3234 } 3235 3236 if ($blockSize <= 0) { 3237 throw new SodiumException( 3238 'block size cannot be less than 1' 3239 ); 3240 } 3241 $unpadded_len = ParagonIE_Sodium_Core_Util::strlen($unpadded); 3242 $xpadlen = ($blockSize - 1); 3243 if (($blockSize & ($blockSize - 1)) === 0) { 3244 $xpadlen -= $unpadded_len & ($blockSize - 1); 3245 } else { 3246 $xpadlen -= $unpadded_len % $blockSize; 3247 } 3248 3249 $xpadded_len = $unpadded_len + $xpadlen; 3250 $padded = str_repeat("\0", $xpadded_len - 1); 3251 if ($unpadded_len > 0) { 3252 $st = 1; 3253 $i = 0; 3254 $k = $unpadded_len; 3255 for ($j = 0; $j <= $xpadded_len; ++$j) { 3256 $i = (int) $i; 3257 $k = (int) $k; 3258 $st = (int) $st; 3259 if ($j >= $unpadded_len) { 3260 $padded[$j] = "\0"; 3261 } else { 3262 $padded[$j] = $unpadded[$j]; 3263 } 3264 /** @var int $k */ 3265 $k -= $st; 3266 $st = (int) (~( 3267 ( 3268 ( 3269 ($k >> 48) 3270 | 3271 ($k >> 32) 3272 | 3273 ($k >> 16) 3274 | 3275 $k 3276 ) - 1 3277 ) >> 16 3278 ) 3279 ) & 1; 3280 $i += $st; 3281 } 3282 } 3283 3284 $mask = 0; 3285 $tail = $xpadded_len; 3286 for ($i = 0; $i < $blockSize; ++$i) { 3287 # barrier_mask = (unsigned char) 3288 # (((i ^ xpadlen) - 1U) >> ((sizeof(size_t) - 1U) * CHAR_BIT)); 3289 $barrier_mask = (($i ^ $xpadlen) -1) >> ((PHP_INT_SIZE << 3) - 1); 3290 # tail[-i] = (tail[-i] & mask) | (0x80 & barrier_mask); 3291 $padded[$tail - $i] = ParagonIE_Sodium_Core_Util::intToChr( 3292 (ParagonIE_Sodium_Core_Util::chrToInt($padded[$tail - $i]) & $mask) 3293 | 3294 (0x80 & $barrier_mask) 3295 ); 3296 # mask |= barrier_mask; 3297 $mask |= $barrier_mask; 3298 } 3299 return $padded; 3300 } 3301 3302 /** 3303 * @param string $padded 3304 * @param int $blockSize 3305 * @param bool $dontFallback 3306 * @return string 3307 * @throws SodiumException 3308 */ 3309 public static function unpad($padded, $blockSize, $dontFallback = false) 3310 { 3311 /* Type checks: */ 3312 ParagonIE_Sodium_Core_Util::declareScalarType($padded, 'string', 1); 3313 ParagonIE_Sodium_Core_Util::declareScalarType($blockSize, 'int', 2); 3314 3315 $padded = (string) $padded; 3316 $blockSize = (int) $blockSize; 3317 3318 if (self::useNewSodiumAPI() && !$dontFallback) { 3319 return (string) sodium_unpad($padded, $blockSize); 3320 } 3321 if ($blockSize <= 0) { 3322 throw new SodiumException('block size cannot be less than 1'); 3323 } 3324 $padded_len = ParagonIE_Sodium_Core_Util::strlen($padded); 3325 if ($padded_len < $blockSize) { 3326 throw new SodiumException('invalid padding'); 3327 } 3328 3329 # tail = &padded[padded_len - 1U]; 3330 $tail = $padded_len - 1; 3331 3332 $acc = 0; 3333 $valid = 0; 3334 $pad_len = 0; 3335 3336 $found = 0; 3337 for ($i = 0; $i < $blockSize; ++$i) { 3338 # c = tail[-i]; 3339 $c = ParagonIE_Sodium_Core_Util::chrToInt($padded[$tail - $i]); 3340 3341 # is_barrier = 3342 # (( (acc - 1U) & (pad_len - 1U) & ((c ^ 0x80) - 1U) ) >> 8) & 1U; 3343 $is_barrier = ( 3344 ( 3345 ($acc - 1) & ($pad_len - 1) & (($c ^ 80) - 1) 3346 ) >> 7 3347 ) & 1; 3348 $is_barrier &= ~$found; 3349 $found |= $is_barrier; 3350 3351 # acc |= c; 3352 $acc |= $c; 3353 3354 # pad_len |= i & (1U + ~is_barrier); 3355 $pad_len |= $i & (1 + ~$is_barrier); 3356 3357 # valid |= (unsigned char) is_barrier; 3358 $valid |= ($is_barrier & 0xff); 3359 } 3360 # unpadded_len = padded_len - 1U - pad_len; 3361 $unpadded_len = $padded_len - 1 - $pad_len; 3362 if ($valid !== 1) { 3363 throw new SodiumException('invalid padding'); 3364 } 3365 return ParagonIE_Sodium_Core_Util::substr($padded, 0, $unpadded_len); 2669 3366 } 2670 3367 -
trunk/src/wp-includes/sodium_compat/src/Core/BLAKE2b.php
r46586 r46858 89 89 $l = ($x[1] + $y[1]) & 0xffffffff; 90 90 return self::new64( 91 $x[0] + $y[0] + (91 (int) ($x[0] + $y[0] + ( 92 92 ($l < $x[1]) ? 1 : 0 93 ) ,94 $l93 )), 94 (int) $l 95 95 ); 96 96 } … … 133 133 } 134 134 return self::new64( 135 (int) ( $x[0] ^ $y[0]),136 (int) ( $x[1] ^ $y[1])135 (int) (($x[0] ^ $y[0]) & 0xffffffff), 136 (int) (($x[1] ^ $y[1]) & 0xffffffff) 137 137 ); 138 138 } … … 300 300 protected static function context() 301 301 { 302 $ctx = new SplFixedArray( 5);302 $ctx = new SplFixedArray(6); 303 303 $ctx[0] = new SplFixedArray(8); // h 304 304 $ctx[1] = new SplFixedArray(2); // t … … 306 306 $ctx[3] = new SplFixedArray(256); // buf 307 307 $ctx[4] = 0; // buflen 308 $ctx[5] = 0; // last_node (uint8_t) 308 309 309 310 for ($i = 8; $i--;) { … … 551 552 * @param SplFixedArray|null $key 552 553 * @param int $outlen 554 * @param SplFixedArray|null $salt 555 * @param SplFixedArray|null $personal 553 556 * @return SplFixedArray 554 557 * @throws SodiumException … … 560 563 * @psalm-suppress MixedArrayOffset 561 564 */ 562 public static function init($key = null, $outlen = 64) 563 { 565 public static function init( 566 $key = null, 567 $outlen = 64, 568 $salt = null, 569 $personal = null 570 ) { 564 571 self::pseudoConstructor(); 565 572 $klen = 0; … … 579 586 580 587 $p = new SplFixedArray(64); 588 // Zero our param buffer... 581 589 for ($i = 64; --$i;) { 582 590 $p[$i] = 0; … … 588 596 $p[3] = 1; // depth 589 597 598 if ($salt instanceof SplFixedArray) { 599 // salt: [32] through [47] 600 for ($i = 0; $i < 16; ++$i) { 601 $p[32 + $i] = (int) $salt[$i]; 602 } 603 } 604 if ($personal instanceof SplFixedArray) { 605 // personal: [48] through [63] 606 for ($i = 0; $i < 16; ++$i) { 607 $p[48 + $i] = (int) $personal[$i]; 608 } 609 } 610 590 611 $ctx[0][0] = self::xor64( 591 612 $ctx[0][0], 592 613 self::load64($p, 0) 593 614 ); 615 if ($salt instanceof SplFixedArray || $personal instanceof SplFixedArray) { 616 // We need to do what blake2b_init_param() does: 617 for ($i = 1; $i < 8; ++$i) { 618 $ctx[0][$i] = self::xor64( 619 $ctx[0][$i], 620 self::load64($p, $i << 3) 621 ); 622 } 623 } 594 624 595 625 if ($klen > 0 && $key instanceof SplFixedArray) { … … 602 632 } 603 633 self::update($ctx, $block, 128); 634 $ctx[4] = 128; 604 635 } 605 636 … … 694 725 )); 695 726 # uint8_t last_node; 696 return $str . "\x00";727 return $str . self::intToChr($ctx[5]) . str_repeat("\x00", 23); 697 728 } 698 729 … … 747 778 $ctx[3] = self::stringToSplFixedArray(self::substr($string, 96, 256)); 748 779 749 750 780 # uint8_t buf[2 * 128]; 751 781 $int = 0; -
trunk/src/wp-includes/sodium_compat/src/Core/Ed25519.php
r46586 r46858 277 277 throw new SodiumException('Signature is too short'); 278 278 } 279 if ( self::check_S_lt_L(self::substr($sig, 32, 32))) {279 if ((self::chrToInt($sig[63]) & 240) && self::check_S_lt_L(self::substr($sig, 32, 32))) { 280 280 throw new SodiumException('S < L - Invalid signature'); 281 281 } -
trunk/src/wp-includes/sodium_compat/src/Core/Poly1305/State.php
r46586 r46858 81 81 82 82 /** 83 * Zero internal buffer upon destruction 84 */ 85 public function __destruct() 86 { 87 $this->r[0] ^= $this->r[0]; 88 $this->r[1] ^= $this->r[1]; 89 $this->r[2] ^= $this->r[2]; 90 $this->r[3] ^= $this->r[3]; 91 $this->r[4] ^= $this->r[4]; 92 $this->h[0] ^= $this->h[0]; 93 $this->h[1] ^= $this->h[1]; 94 $this->h[2] ^= $this->h[2]; 95 $this->h[3] ^= $this->h[3]; 96 $this->h[4] ^= $this->h[4]; 97 $this->pad[0] ^= $this->pad[0]; 98 $this->pad[1] ^= $this->pad[1]; 99 $this->pad[2] ^= $this->pad[2]; 100 $this->pad[3] ^= $this->pad[3]; 101 $this->leftover = 0; 102 $this->final = true; 103 } 104 105 /** 83 106 * @internal You should not use this directly from another application 84 107 * … … 91 114 { 92 115 $bytes = self::strlen($message); 116 if ($bytes < 1) { 117 return $this; 118 } 93 119 94 120 /* handle leftover */ … … 112 138 113 139 $this->blocks( 114 s tatic::intArrayToString($this->buffer),140 self::intArrayToString($this->buffer), 115 141 ParagonIE_Sodium_Core_Poly1305::BLOCK_SIZE 116 142 ); … … 297 323 $this->blocks( 298 324 self::substr( 299 s tatic::intArrayToString($this->buffer),325 self::intArrayToString($this->buffer), 300 326 0, 301 327 ParagonIE_Sodium_Core_Poly1305::BLOCK_SIZE -
trunk/src/wp-includes/sodium_compat/src/Core/XChaCha20.php
r46586 r46858 40 40 * @internal You should not use this directly from another application 41 41 * 42 * @param int $len 43 * @param string $nonce 44 * @param string $key 45 * @return string 46 * @throws SodiumException 47 * @throws TypeError 48 */ 49 public static function ietfStream($len = 64, $nonce = '', $key = '') 50 { 51 if (self::strlen($nonce) !== 24) { 52 throw new SodiumException('Nonce must be 24 bytes long'); 53 } 54 return self::encryptBytes( 55 new ParagonIE_Sodium_Core_ChaCha20_IetfCtx( 56 self::hChaCha20( 57 self::substr($nonce, 0, 16), 58 $key 59 ), 60 "\x00\x00\x00\x00" . self::substr($nonce, 16, 8) 61 ), 62 str_repeat("\x00", $len) 63 ); 64 } 65 66 /** 67 * @internal You should not use this directly from another application 68 * 42 69 * @param string $message 43 70 * @param string $nonce … … 62 89 ); 63 90 } 91 92 /** 93 * @internal You should not use this directly from another application 94 * 95 * @param string $message 96 * @param string $nonce 97 * @param string $key 98 * @param string $ic 99 * @return string 100 * @throws SodiumException 101 * @throws TypeError 102 */ 103 public static function ietfStreamXorIc($message, $nonce = '', $key = '', $ic = '') 104 { 105 if (self::strlen($nonce) !== 24) { 106 throw new SodiumException('Nonce must be 24 bytes long'); 107 } 108 return self::encryptBytes( 109 new ParagonIE_Sodium_Core_ChaCha20_IetfCtx( 110 self::hChaCha20(self::substr($nonce, 0, 16), $key), 111 "\x00\x00\x00\x00" . self::substr($nonce, 16, 8), 112 $ic 113 ), 114 $message 115 ); 116 } 64 117 } -
trunk/src/wp-includes/sodium_compat/src/Core32/BLAKE2b.php
r46586 r46858 224 224 protected static function context() 225 225 { 226 $ctx = new SplFixedArray( 5);226 $ctx = new SplFixedArray(6); 227 227 $ctx[0] = new SplFixedArray(8); // h 228 228 $ctx[1] = new SplFixedArray(2); // t … … 230 230 $ctx[3] = new SplFixedArray(256); // buf 231 231 $ctx[4] = 0; // buflen 232 $ctx[5] = 0; // last_node (uint8_t) 232 233 233 234 for ($i = 8; $i--;) { … … 483 484 * @param SplFixedArray|null $key 484 485 * @param int $outlen 486 * @param SplFixedArray|null $salt 487 * @param SplFixedArray|null $personal 485 488 * @return SplFixedArray 486 489 * @throws SodiumException … … 492 495 * @psalm-suppress MixedMethodCall 493 496 */ 494 public static function init($key = null, $outlen = 64) 495 { 497 public static function init( 498 $key = null, 499 $outlen = 64, 500 $salt = null, 501 $personal = null 502 ) { 496 503 self::pseudoConstructor(); 497 504 $klen = 0; … … 511 518 512 519 $p = new SplFixedArray(64); 520 // Zero our param buffer... 513 521 for ($i = 64; --$i;) { 514 522 $p[$i] = 0; … … 520 528 $p[3] = 1; // depth 521 529 530 if ($salt instanceof SplFixedArray) { 531 // salt: [32] through [47] 532 for ($i = 0; $i < 16; ++$i) { 533 $p[32 + $i] = (int) $salt[$i]; 534 } 535 } 536 if ($personal instanceof SplFixedArray) { 537 // personal: [48] through [63] 538 for ($i = 0; $i < 16; ++$i) { 539 $p[48 + $i] = (int) $personal[$i]; 540 } 541 } 542 522 543 $ctx[0][0] = self::xor64( 523 544 $ctx[0][0], … … 525 546 ); 526 547 548 if ($salt instanceof SplFixedArray || $personal instanceof SplFixedArray) { 549 // We need to do what blake2b_init_param() does: 550 for ($i = 1; $i < 8; ++$i) { 551 $ctx[0][$i] = self::xor64( 552 $ctx[0][$i], 553 self::load64($p, $i << 3) 554 ); 555 } 556 } 557 527 558 if ($klen > 0 && $key instanceof SplFixedArray) { 528 559 $block = new SplFixedArray(128); … … 534 565 } 535 566 self::update($ctx, $block, 128); 567 $ctx[4] = 128; 536 568 } 537 569 … … 596 628 /** @var ParagonIE_Sodium_Core32_Int64 $ctxAi */ 597 629 $ctxAi = $ctxA[$i]; 598 $str .= $ctxAi->to String();630 $str .= $ctxAi->toReverseString(); 599 631 } 600 632 … … 609 641 $ctxA2 = $ctxA[1]; 610 642 611 $str .= $ctxA1->to String();612 $str .= $ctxA2->to String();643 $str .= $ctxA1->toReverseString(); 644 $str .= $ctxA2->toReverseString(); 613 645 } 614 646 … … 625 657 self::intToChr(($ctx4 >> 16) & 0xff), 626 658 self::intToChr(($ctx4 >> 24) & 0xff), 659 "\x00\x00\x00\x00" 660 /* 627 661 self::intToChr(($ctx4 >> 32) & 0xff), 628 662 self::intToChr(($ctx4 >> 40) & 0xff), 629 663 self::intToChr(($ctx4 >> 48) & 0xff), 630 664 self::intToChr(($ctx4 >> 56) & 0xff) 665 */ 631 666 )); 632 667 # uint8_t last_node; 633 return $str . "\x00";668 return $str . self::intToChr($ctx[5]) . str_repeat("\x00", 23); 634 669 } 635 670 … … 653 688 # uint64_t h[8]; 654 689 for ($i = 0; $i < 8; ++$i) { 655 $ctx[0][$i] = ParagonIE_Sodium_Core32_Int64::from String(690 $ctx[0][$i] = ParagonIE_Sodium_Core32_Int64::fromReverseString( 656 691 self::substr($string, (($i << 3) + 0), 8) 657 692 ); … … 661 696 # uint64_t f[2]; 662 697 for ($i = 1; $i < 3; ++$i) { 663 $ctx[$i][1] = ParagonIE_Sodium_Core32_Int64::from String(698 $ctx[$i][1] = ParagonIE_Sodium_Core32_Int64::fromReverseString( 664 699 self::substr($string, 72 + (($i - 1) << 4), 8) 665 700 ); 666 $ctx[$i][0] = ParagonIE_Sodium_Core32_Int64::from String(701 $ctx[$i][0] = ParagonIE_Sodium_Core32_Int64::fromReverseString( 667 702 self::substr($string, 64 + (($i - 1) << 4), 8) 668 703 ); … … 671 706 # uint8_t buf[2 * 128]; 672 707 $ctx[3] = self::stringToSplFixedArray(self::substr($string, 96, 256)); 673 674 708 675 709 # uint8_t buf[2 * 128]; -
trunk/src/wp-includes/sodium_compat/src/Core32/Ed25519.php
r46586 r46858 279 279 throw new SodiumException('Signature is too short'); 280 280 } 281 if ( self::check_S_lt_L(self::substr($sig, 32, 32))) {281 if ((self::chrToInt($sig[63]) & 240) && self::check_S_lt_L(self::substr($sig, 32, 32))) { 282 282 throw new SodiumException('S < L - Invalid signature'); 283 283 } -
trunk/src/wp-includes/sodium_compat/src/Core32/Poly1305/State.php
r46586 r46858 143 143 144 144 $this->blocks( 145 s tatic::intArrayToString($this->buffer),145 self::intArrayToString($this->buffer), 146 146 ParagonIE_Sodium_Core32_Poly1305::BLOCK_SIZE 147 147 ); … … 347 347 $this->blocks( 348 348 self::substr( 349 s tatic::intArrayToString($this->buffer),349 self::intArrayToString($this->buffer), 350 350 0, 351 351 ParagonIE_Sodium_Core32_Poly1305::BLOCK_SIZE -
trunk/src/wp-includes/sodium_compat/src/Core32/X25519.php
r46586 r46858 152 152 $h[$i] = $h[$i]->toInt32(); 153 153 } 154 /** @var array<int, ParagonIE_Sodium_Core32_Int32> $h */ 155 return ParagonIE_Sodium_Core32_Curve25519_Fe::fromArray($h); 154 /** @var array<int, ParagonIE_Sodium_Core32_Int32> $h2 */ 155 $h2 = $h; 156 return ParagonIE_Sodium_Core32_Curve25519_Fe::fromArray($h2); 156 157 } 157 158 -
trunk/src/wp-includes/sodium_compat/src/Crypto.php
r46586 r46858 779 779 780 780 /** 781 * Initialize a hashing context for BLAKE2b. 782 * 783 * @internal Do not use this directly. Use ParagonIE_Sodium_Compat. 784 * 785 * @param string $key 786 * @param int $outputLength 787 * @param string $salt 788 * @param string $personal 789 * @return string 790 * @throws RangeException 791 * @throws SodiumException 792 * @throws TypeError 793 */ 794 public static function generichash_init_salt_personal( 795 $key = '', 796 $outputLength = 32, 797 $salt = '', 798 $personal = '' 799 ) { 800 // This ensures that ParagonIE_Sodium_Core_BLAKE2b::$iv is initialized 801 ParagonIE_Sodium_Core_BLAKE2b::pseudoConstructor(); 802 803 $k = null; 804 if (!empty($key)) { 805 $k = ParagonIE_Sodium_Core_BLAKE2b::stringToSplFixedArray($key); 806 if ($k->count() > ParagonIE_Sodium_Core_BLAKE2b::KEYBYTES) { 807 throw new RangeException('Invalid key size'); 808 } 809 } 810 if (!empty($salt)) { 811 $s = ParagonIE_Sodium_Core_BLAKE2b::stringToSplFixedArray($salt); 812 } else { 813 $s = null; 814 } 815 if (!empty($salt)) { 816 $p = ParagonIE_Sodium_Core_BLAKE2b::stringToSplFixedArray($personal); 817 } else { 818 $p = null; 819 } 820 821 /** @var SplFixedArray $ctx */ 822 $ctx = ParagonIE_Sodium_Core_BLAKE2b::init($k, $outputLength, $s, $p); 823 824 return ParagonIE_Sodium_Core_BLAKE2b::contextToString($ctx); 825 } 826 827 /** 781 828 * Update a hashing context for BLAKE2b with $message 782 829 * … … 1187 1234 1188 1235 /** 1236 * @param string $key 1237 * @return array<int, string> Returns a state and a header. 1238 * @throws Exception 1239 * @throws SodiumException 1240 */ 1241 public static function secretstream_xchacha20poly1305_init_push($key) 1242 { 1243 # randombytes_buf(out, crypto_secretstream_xchacha20poly1305_HEADERBYTES); 1244 $out = random_bytes(24); 1245 1246 # crypto_core_hchacha20(state->k, out, k, NULL); 1247 $subkey = ParagonIE_Sodium_Core_HChaCha20::hChaCha20($out, $key); 1248 $state = new ParagonIE_Sodium_Core_SecretStream_State( 1249 $subkey, 1250 ParagonIE_Sodium_Core_Util::substr($out, 16, 8) . str_repeat("\0", 4) 1251 ); 1252 1253 # _crypto_secretstream_xchacha20poly1305_counter_reset(state); 1254 $state->counterReset(); 1255 1256 # memcpy(STATE_INONCE(state), out + crypto_core_hchacha20_INPUTBYTES, 1257 # crypto_secretstream_xchacha20poly1305_INONCEBYTES); 1258 # memset(state->_pad, 0, sizeof state->_pad); 1259 return array( 1260 $state->toString(), 1261 $out 1262 ); 1263 } 1264 1265 /** 1266 * @param string $key 1267 * @param string $header 1268 * @return string Returns a state. 1269 * @throws Exception 1270 */ 1271 public static function secretstream_xchacha20poly1305_init_pull($key, $header) 1272 { 1273 # crypto_core_hchacha20(state->k, in, k, NULL); 1274 $subkey = ParagonIE_Sodium_Core_HChaCha20::hChaCha20( 1275 ParagonIE_Sodium_Core_Util::substr($header, 0, 16), 1276 $key 1277 ); 1278 $state = new ParagonIE_Sodium_Core_SecretStream_State( 1279 $subkey, 1280 ParagonIE_Sodium_Core_Util::substr($header, 16) 1281 ); 1282 $state->counterReset(); 1283 # memcpy(STATE_INONCE(state), in + crypto_core_hchacha20_INPUTBYTES, 1284 # crypto_secretstream_xchacha20poly1305_INONCEBYTES); 1285 # memset(state->_pad, 0, sizeof state->_pad); 1286 # return 0; 1287 return $state->toString(); 1288 } 1289 1290 /** 1291 * @param string $state 1292 * @param string $msg 1293 * @param string $aad 1294 * @param int $tag 1295 * @return string 1296 * @throws SodiumException 1297 */ 1298 public static function secretstream_xchacha20poly1305_push(&$state, $msg, $aad = '', $tag = 0) 1299 { 1300 $st = ParagonIE_Sodium_Core_SecretStream_State::fromString($state); 1301 # crypto_onetimeauth_poly1305_state poly1305_state; 1302 # unsigned char block[64U]; 1303 # unsigned char slen[8U]; 1304 # unsigned char *c; 1305 # unsigned char *mac; 1306 1307 $msglen = ParagonIE_Sodium_Core_Util::strlen($msg); 1308 $aadlen = ParagonIE_Sodium_Core_Util::strlen($aad); 1309 1310 if ((($msglen + 63) >> 6) > 0xfffffffe) { 1311 throw new SodiumException( 1312 'message cannot be larger than SODIUM_CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_MESSAGEBYTES_MAX bytes' 1313 ); 1314 } 1315 1316 # if (outlen_p != NULL) { 1317 # *outlen_p = 0U; 1318 # } 1319 # if (mlen > crypto_secretstream_xchacha20poly1305_MESSAGEBYTES_MAX) { 1320 # sodium_misuse(); 1321 # } 1322 1323 # crypto_stream_chacha20_ietf(block, sizeof block, state->nonce, state->k); 1324 # crypto_onetimeauth_poly1305_init(&poly1305_state, block); 1325 # sodium_memzero(block, sizeof block); 1326 $auth = new ParagonIE_Sodium_Core_Poly1305_State( 1327 ParagonIE_Sodium_Core_ChaCha20::ietfStream(32, $st->getCombinedNonce(), $st->getKey()) 1328 ); 1329 1330 # crypto_onetimeauth_poly1305_update(&poly1305_state, ad, adlen); 1331 $auth->update($aad); 1332 1333 # crypto_onetimeauth_poly1305_update(&poly1305_state, _pad0, 1334 # (0x10 - adlen) & 0xf); 1335 $auth->update(str_repeat("\0", ((0x10 - $aadlen) & 0xf))); 1336 1337 # memset(block, 0, sizeof block); 1338 # block[0] = tag; 1339 # crypto_stream_chacha20_ietf_xor_ic(block, block, sizeof block, 1340 # state->nonce, 1U, state->k); 1341 $block = ParagonIE_Sodium_Core_ChaCha20::ietfStreamXorIc( 1342 ParagonIE_Sodium_Core_Util::intToChr($tag) . str_repeat("\0", 63), 1343 $st->getCombinedNonce(), 1344 $st->getKey(), 1345 ParagonIE_Sodium_Core_Util::store64_le(1) 1346 ); 1347 1348 # crypto_onetimeauth_poly1305_update(&poly1305_state, block, sizeof block); 1349 $auth->update($block); 1350 1351 # out[0] = block[0]; 1352 $out = $block[0]; 1353 # c = out + (sizeof tag); 1354 # crypto_stream_chacha20_ietf_xor_ic(c, m, mlen, state->nonce, 2U, state->k); 1355 $cipher = ParagonIE_Sodium_Core_ChaCha20::ietfStreamXorIc( 1356 $msg, 1357 $st->getCombinedNonce(), 1358 $st->getKey(), 1359 ParagonIE_Sodium_Core_Util::store64_le(2) 1360 ); 1361 1362 # crypto_onetimeauth_poly1305_update(&poly1305_state, c, mlen); 1363 $auth->update($cipher); 1364 1365 $out .= $cipher; 1366 unset($cipher); 1367 1368 # crypto_onetimeauth_poly1305_update 1369 # (&poly1305_state, _pad0, (0x10 - (sizeof block) + mlen) & 0xf); 1370 $auth->update(str_repeat("\0", ((0x10 - 64 + $msglen) & 0xf))); 1371 1372 # STORE64_LE(slen, (uint64_t) adlen); 1373 $slen = ParagonIE_Sodium_Core_Util::store64_le($aadlen); 1374 1375 # crypto_onetimeauth_poly1305_update(&poly1305_state, slen, sizeof slen); 1376 $auth->update($slen); 1377 1378 # STORE64_LE(slen, (sizeof block) + mlen); 1379 $slen = ParagonIE_Sodium_Core_Util::store64_le(64 + $msglen); 1380 1381 # crypto_onetimeauth_poly1305_update(&poly1305_state, slen, sizeof slen); 1382 $auth->update($slen); 1383 1384 # mac = c + mlen; 1385 # crypto_onetimeauth_poly1305_final(&poly1305_state, mac); 1386 $mac = $auth->finish(); 1387 $out .= $mac; 1388 1389 # sodium_memzero(&poly1305_state, sizeof poly1305_state); 1390 unset($auth); 1391 1392 1393 # XOR_BUF(STATE_INONCE(state), mac, 1394 # crypto_secretstream_xchacha20poly1305_INONCEBYTES); 1395 $st->xorNonce($mac); 1396 1397 # sodium_increment(STATE_COUNTER(state), 1398 # crypto_secretstream_xchacha20poly1305_COUNTERBYTES); 1399 $st->incrementCounter(); 1400 // Overwrite by reference: 1401 $state = $st->toString(); 1402 1403 /** @var bool $rekey */ 1404 $rekey = ($tag & ParagonIE_Sodium_Compat::CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_TAG_REKEY) !== 0; 1405 # if ((tag & crypto_secretstream_xchacha20poly1305_TAG_REKEY) != 0 || 1406 # sodium_is_zero(STATE_COUNTER(state), 1407 # crypto_secretstream_xchacha20poly1305_COUNTERBYTES)) { 1408 # crypto_secretstream_xchacha20poly1305_rekey(state); 1409 # } 1410 if ($rekey || $st->needsRekey()) { 1411 // DO REKEY 1412 self::secretstream_xchacha20poly1305_rekey($state); 1413 } 1414 # if (outlen_p != NULL) { 1415 # *outlen_p = crypto_secretstream_xchacha20poly1305_ABYTES + mlen; 1416 # } 1417 return $out; 1418 } 1419 1420 /** 1421 * @param string $state 1422 * @param string $cipher 1423 * @param string $aad 1424 * @return bool|array{0: string, 1: int} 1425 * @throws SodiumException 1426 */ 1427 public static function secretstream_xchacha20poly1305_pull(&$state, $cipher, $aad = '') 1428 { 1429 $st = ParagonIE_Sodium_Core_SecretStream_State::fromString($state); 1430 1431 $cipherlen = ParagonIE_Sodium_Core_Util::strlen($cipher); 1432 # mlen = inlen - crypto_secretstream_xchacha20poly1305_ABYTES; 1433 $msglen = $cipherlen - ParagonIE_Sodium_Compat::CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_ABYTES; 1434 $aadlen = ParagonIE_Sodium_Core_Util::strlen($aad); 1435 1436 # if (mlen > crypto_secretstream_xchacha20poly1305_MESSAGEBYTES_MAX) { 1437 # sodium_misuse(); 1438 # } 1439 if ((($msglen + 63) >> 6) > 0xfffffffe) { 1440 throw new SodiumException( 1441 'message cannot be larger than SODIUM_CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_MESSAGEBYTES_MAX bytes' 1442 ); 1443 } 1444 1445 # crypto_stream_chacha20_ietf(block, sizeof block, state->nonce, state->k); 1446 # crypto_onetimeauth_poly1305_init(&poly1305_state, block); 1447 # sodium_memzero(block, sizeof block); 1448 $auth = new ParagonIE_Sodium_Core_Poly1305_State( 1449 ParagonIE_Sodium_Core_ChaCha20::ietfStream(32, $st->getCombinedNonce(), $st->getKey()) 1450 ); 1451 1452 # crypto_onetimeauth_poly1305_update(&poly1305_state, ad, adlen); 1453 $auth->update($aad); 1454 1455 # crypto_onetimeauth_poly1305_update(&poly1305_state, _pad0, 1456 # (0x10 - adlen) & 0xf); 1457 $auth->update(str_repeat("\0", ((0x10 - $aadlen) & 0xf))); 1458 1459 1460 # memset(block, 0, sizeof block); 1461 # block[0] = in[0]; 1462 # crypto_stream_chacha20_ietf_xor_ic(block, block, sizeof block, 1463 # state->nonce, 1U, state->k); 1464 $block = ParagonIE_Sodium_Core_ChaCha20::ietfStreamXorIc( 1465 $cipher[0] . str_repeat("\0", 63), 1466 $st->getCombinedNonce(), 1467 $st->getKey(), 1468 ParagonIE_Sodium_Core_Util::store64_le(1) 1469 ); 1470 # tag = block[0]; 1471 # block[0] = in[0]; 1472 # crypto_onetimeauth_poly1305_update(&poly1305_state, block, sizeof block); 1473 $tag = ParagonIE_Sodium_Core_Util::chrToInt($block[0]); 1474 $block[0] = $cipher[0]; 1475 $auth->update($block); 1476 1477 1478 # c = in + (sizeof tag); 1479 # crypto_onetimeauth_poly1305_update(&poly1305_state, c, mlen); 1480 $auth->update(ParagonIE_Sodium_Core_Util::substr($cipher, 1, $msglen)); 1481 1482 # crypto_onetimeauth_poly1305_update 1483 # (&poly1305_state, _pad0, (0x10 - (sizeof block) + mlen) & 0xf); 1484 $auth->update(str_repeat("\0", ((0x10 - 64 + $msglen) & 0xf))); 1485 1486 # STORE64_LE(slen, (uint64_t) adlen); 1487 # crypto_onetimeauth_poly1305_update(&poly1305_state, slen, sizeof slen); 1488 $slen = ParagonIE_Sodium_Core_Util::store64_le($aadlen); 1489 $auth->update($slen); 1490 1491 # STORE64_LE(slen, (sizeof block) + mlen); 1492 # crypto_onetimeauth_poly1305_update(&poly1305_state, slen, sizeof slen); 1493 $slen = ParagonIE_Sodium_Core_Util::store64_le(64 + $msglen); 1494 $auth->update($slen); 1495 1496 # crypto_onetimeauth_poly1305_final(&poly1305_state, mac); 1497 # sodium_memzero(&poly1305_state, sizeof poly1305_state); 1498 $mac = $auth->finish(); 1499 1500 # stored_mac = c + mlen; 1501 # if (sodium_memcmp(mac, stored_mac, sizeof mac) != 0) { 1502 # sodium_memzero(mac, sizeof mac); 1503 # return -1; 1504 # } 1505 1506 $stored = ParagonIE_Sodium_Core_Util::substr($cipher, $msglen + 1, 16); 1507 if (!ParagonIE_Sodium_Core_Util::hashEquals($mac, $stored)) { 1508 return false; 1509 } 1510 1511 # crypto_stream_chacha20_ietf_xor_ic(m, c, mlen, state->nonce, 2U, state->k); 1512 $out = ParagonIE_Sodium_Core_ChaCha20::ietfStreamXorIc( 1513 ParagonIE_Sodium_Core_Util::substr($cipher, 1, $msglen), 1514 $st->getCombinedNonce(), 1515 $st->getKey(), 1516 ParagonIE_Sodium_Core_Util::store64_le(2) 1517 ); 1518 1519 # XOR_BUF(STATE_INONCE(state), mac, 1520 # crypto_secretstream_xchacha20poly1305_INONCEBYTES); 1521 $st->xorNonce($mac); 1522 1523 # sodium_increment(STATE_COUNTER(state), 1524 # crypto_secretstream_xchacha20poly1305_COUNTERBYTES); 1525 $st->incrementCounter(); 1526 1527 # if ((tag & crypto_secretstream_xchacha20poly1305_TAG_REKEY) != 0 || 1528 # sodium_is_zero(STATE_COUNTER(state), 1529 # crypto_secretstream_xchacha20poly1305_COUNTERBYTES)) { 1530 # crypto_secretstream_xchacha20poly1305_rekey(state); 1531 # } 1532 1533 // Overwrite by reference: 1534 $state = $st->toString(); 1535 1536 /** @var bool $rekey */ 1537 $rekey = ($tag & ParagonIE_Sodium_Compat::CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_TAG_REKEY) !== 0; 1538 if ($rekey || $st->needsRekey()) { 1539 // DO REKEY 1540 self::secretstream_xchacha20poly1305_rekey($state); 1541 } 1542 return array($out, $tag); 1543 } 1544 1545 /** 1546 * @param string $state 1547 * @return void 1548 * @throws SodiumException 1549 */ 1550 public static function secretstream_xchacha20poly1305_rekey(&$state) 1551 { 1552 $st = ParagonIE_Sodium_Core_SecretStream_State::fromString($state); 1553 # unsigned char new_key_and_inonce[crypto_stream_chacha20_ietf_KEYBYTES + 1554 # crypto_secretstream_xchacha20poly1305_INONCEBYTES]; 1555 # size_t i; 1556 # for (i = 0U; i < crypto_stream_chacha20_ietf_KEYBYTES; i++) { 1557 # new_key_and_inonce[i] = state->k[i]; 1558 # } 1559 $new_key_and_inonce = $st->getKey(); 1560 1561 # for (i = 0U; i < crypto_secretstream_xchacha20poly1305_INONCEBYTES; i++) { 1562 # new_key_and_inonce[crypto_stream_chacha20_ietf_KEYBYTES + i] = 1563 # STATE_INONCE(state)[i]; 1564 # } 1565 $new_key_and_inonce .= ParagonIE_Sodium_Core_Util::substR($st->getNonce(), 0, 8); 1566 1567 # crypto_stream_chacha20_ietf_xor(new_key_and_inonce, new_key_and_inonce, 1568 # sizeof new_key_and_inonce, 1569 # state->nonce, state->k); 1570 1571 $st->rekey(ParagonIE_Sodium_Core_ChaCha20::ietfStreamXorIc( 1572 $new_key_and_inonce, 1573 $st->getCombinedNonce(), 1574 $st->getKey(), 1575 ParagonIE_Sodium_Core_Util::store64_le(0) 1576 )); 1577 1578 # for (i = 0U; i < crypto_stream_chacha20_ietf_KEYBYTES; i++) { 1579 # state->k[i] = new_key_and_inonce[i]; 1580 # } 1581 # for (i = 0U; i < crypto_secretstream_xchacha20poly1305_INONCEBYTES; i++) { 1582 # STATE_INONCE(state)[i] = 1583 # new_key_and_inonce[crypto_stream_chacha20_ietf_KEYBYTES + i]; 1584 # } 1585 # _crypto_secretstream_xchacha20poly1305_counter_reset(state); 1586 $st->counterReset(); 1587 1588 $state = $st->toString(); 1589 } 1590 1591 /** 1189 1592 * Detached Ed25519 signature. 1190 1593 * -
trunk/src/wp-includes/sodium_compat/src/Crypto32.php
r46586 r46858 778 778 779 779 /** 780 * Initialize a hashing context for BLAKE2b. 781 * 782 * @internal Do not use this directly. Use ParagonIE_Sodium_Compat. 783 * 784 * @param string $key 785 * @param int $outputLength 786 * @param string $salt 787 * @param string $personal 788 * @return string 789 * @throws RangeException 790 * @throws SodiumException 791 * @throws TypeError 792 */ 793 public static function generichash_init_salt_personal( 794 $key = '', 795 $outputLength = 32, 796 $salt = '', 797 $personal = '' 798 ) { 799 // This ensures that ParagonIE_Sodium_Core32_BLAKE2b::$iv is initialized 800 ParagonIE_Sodium_Core32_BLAKE2b::pseudoConstructor(); 801 802 $k = null; 803 if (!empty($key)) { 804 $k = ParagonIE_Sodium_Core32_BLAKE2b::stringToSplFixedArray($key); 805 if ($k->count() > ParagonIE_Sodium_Core32_BLAKE2b::KEYBYTES) { 806 throw new RangeException('Invalid key size'); 807 } 808 } 809 if (!empty($salt)) { 810 $s = ParagonIE_Sodium_Core32_BLAKE2b::stringToSplFixedArray($salt); 811 } else { 812 $s = null; 813 } 814 if (!empty($salt)) { 815 $p = ParagonIE_Sodium_Core32_BLAKE2b::stringToSplFixedArray($personal); 816 } else { 817 $p = null; 818 } 819 820 /** @var SplFixedArray $ctx */ 821 $ctx = ParagonIE_Sodium_Core32_BLAKE2b::init($k, $outputLength, $s, $p); 822 823 return ParagonIE_Sodium_Core32_BLAKE2b::contextToString($ctx); 824 } 825 826 /** 780 827 * Update a hashing context for BLAKE2b with $message 781 828 * … … 1186 1233 1187 1234 /** 1235 * @param string $key 1236 * @return array<int, string> Returns a state and a header. 1237 * @throws Exception 1238 * @throws SodiumException 1239 */ 1240 public static function secretstream_xchacha20poly1305_init_push($key) 1241 { 1242 # randombytes_buf(out, crypto_secretstream_xchacha20poly1305_HEADERBYTES); 1243 $out = random_bytes(24); 1244 1245 # crypto_core_hchacha20(state->k, out, k, NULL); 1246 $subkey = ParagonIE_Sodium_Core32_HChaCha20::hChaCha20($out, $key); 1247 $state = new ParagonIE_Sodium_Core32_SecretStream_State( 1248 $subkey, 1249 ParagonIE_Sodium_Core32_Util::substr($out, 16, 8) . str_repeat("\0", 4) 1250 ); 1251 1252 # _crypto_secretstream_xchacha20poly1305_counter_reset(state); 1253 $state->counterReset(); 1254 1255 # memcpy(STATE_INONCE(state), out + crypto_core_hchacha20_INPUTBYTES, 1256 # crypto_secretstream_xchacha20poly1305_INONCEBYTES); 1257 # memset(state->_pad, 0, sizeof state->_pad); 1258 return array( 1259 $state->toString(), 1260 $out 1261 ); 1262 } 1263 1264 /** 1265 * @param string $key 1266 * @param string $header 1267 * @return string Returns a state. 1268 * @throws Exception 1269 */ 1270 public static function secretstream_xchacha20poly1305_init_pull($key, $header) 1271 { 1272 # crypto_core_hchacha20(state->k, in, k, NULL); 1273 $subkey = ParagonIE_Sodium_Core32_HChaCha20::hChaCha20( 1274 ParagonIE_Sodium_Core32_Util::substr($header, 0, 16), 1275 $key 1276 ); 1277 $state = new ParagonIE_Sodium_Core32_SecretStream_State( 1278 $subkey, 1279 ParagonIE_Sodium_Core32_Util::substr($header, 16) 1280 ); 1281 $state->counterReset(); 1282 # memcpy(STATE_INONCE(state), in + crypto_core_hchacha20_INPUTBYTES, 1283 # crypto_secretstream_xchacha20poly1305_INONCEBYTES); 1284 # memset(state->_pad, 0, sizeof state->_pad); 1285 # return 0; 1286 return $state->toString(); 1287 } 1288 1289 /** 1290 * @param string $state 1291 * @param string $msg 1292 * @param string $aad 1293 * @param int $tag 1294 * @return string 1295 * @throws SodiumException 1296 */ 1297 public static function secretstream_xchacha20poly1305_push(&$state, $msg, $aad = '', $tag = 0) 1298 { 1299 $st = ParagonIE_Sodium_Core32_SecretStream_State::fromString($state); 1300 # crypto_onetimeauth_poly1305_state poly1305_state; 1301 # unsigned char block[64U]; 1302 # unsigned char slen[8U]; 1303 # unsigned char *c; 1304 # unsigned char *mac; 1305 1306 $msglen = ParagonIE_Sodium_Core32_Util::strlen($msg); 1307 $aadlen = ParagonIE_Sodium_Core32_Util::strlen($aad); 1308 1309 if ((($msglen + 63) >> 6) > 0xfffffffe) { 1310 throw new SodiumException( 1311 'message cannot be larger than SODIUM_CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_MESSAGEBYTES_MAX bytes' 1312 ); 1313 } 1314 1315 # if (outlen_p != NULL) { 1316 # *outlen_p = 0U; 1317 # } 1318 # if (mlen > crypto_secretstream_xchacha20poly1305_MESSAGEBYTES_MAX) { 1319 # sodium_misuse(); 1320 # } 1321 1322 # crypto_stream_chacha20_ietf(block, sizeof block, state->nonce, state->k); 1323 # crypto_onetimeauth_poly1305_init(&poly1305_state, block); 1324 # sodium_memzero(block, sizeof block); 1325 $auth = new ParagonIE_Sodium_Core32_Poly1305_State( 1326 ParagonIE_Sodium_Core32_ChaCha20::ietfStream(32, $st->getCombinedNonce(), $st->getKey()) 1327 ); 1328 1329 # crypto_onetimeauth_poly1305_update(&poly1305_state, ad, adlen); 1330 $auth->update($aad); 1331 1332 # crypto_onetimeauth_poly1305_update(&poly1305_state, _pad0, 1333 # (0x10 - adlen) & 0xf); 1334 $auth->update(str_repeat("\0", ((0x10 - $aadlen) & 0xf))); 1335 1336 # memset(block, 0, sizeof block); 1337 # block[0] = tag; 1338 # crypto_stream_chacha20_ietf_xor_ic(block, block, sizeof block, 1339 # state->nonce, 1U, state->k); 1340 $block = ParagonIE_Sodium_Core32_ChaCha20::ietfStreamXorIc( 1341 ParagonIE_Sodium_Core32_Util::intToChr($tag) . str_repeat("\0", 63), 1342 $st->getCombinedNonce(), 1343 $st->getKey(), 1344 ParagonIE_Sodium_Core32_Util::store64_le(1) 1345 ); 1346 1347 # crypto_onetimeauth_poly1305_update(&poly1305_state, block, sizeof block); 1348 $auth->update($block); 1349 1350 # out[0] = block[0]; 1351 $out = $block[0]; 1352 # c = out + (sizeof tag); 1353 # crypto_stream_chacha20_ietf_xor_ic(c, m, mlen, state->nonce, 2U, state->k); 1354 $cipher = ParagonIE_Sodium_Core32_ChaCha20::ietfStreamXorIc( 1355 $msg, 1356 $st->getCombinedNonce(), 1357 $st->getKey(), 1358 ParagonIE_Sodium_Core32_Util::store64_le(2) 1359 ); 1360 1361 # crypto_onetimeauth_poly1305_update(&poly1305_state, c, mlen); 1362 $auth->update($cipher); 1363 1364 $out .= $cipher; 1365 unset($cipher); 1366 1367 # crypto_onetimeauth_poly1305_update 1368 # (&poly1305_state, _pad0, (0x10 - (sizeof block) + mlen) & 0xf); 1369 $auth->update(str_repeat("\0", ((0x10 - 64 + $msglen) & 0xf))); 1370 1371 # STORE64_LE(slen, (uint64_t) adlen); 1372 $slen = ParagonIE_Sodium_Core32_Util::store64_le($aadlen); 1373 1374 # crypto_onetimeauth_poly1305_update(&poly1305_state, slen, sizeof slen); 1375 $auth->update($slen); 1376 1377 # STORE64_LE(slen, (sizeof block) + mlen); 1378 $slen = ParagonIE_Sodium_Core32_Util::store64_le(64 + $msglen); 1379 1380 # crypto_onetimeauth_poly1305_update(&poly1305_state, slen, sizeof slen); 1381 $auth->update($slen); 1382 1383 # mac = c + mlen; 1384 # crypto_onetimeauth_poly1305_final(&poly1305_state, mac); 1385 $mac = $auth->finish(); 1386 $out .= $mac; 1387 1388 # sodium_memzero(&poly1305_state, sizeof poly1305_state); 1389 unset($auth); 1390 1391 1392 # XOR_BUF(STATE_INONCE(state), mac, 1393 # crypto_secretstream_xchacha20poly1305_INONCEBYTES); 1394 $st->xorNonce($mac); 1395 1396 # sodium_increment(STATE_COUNTER(state), 1397 # crypto_secretstream_xchacha20poly1305_COUNTERBYTES); 1398 $st->incrementCounter(); 1399 // Overwrite by reference: 1400 $state = $st->toString(); 1401 1402 /** @var bool $rekey */ 1403 $rekey = ($tag & ParagonIE_Sodium_Compat::CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_TAG_REKEY) !== 0; 1404 # if ((tag & crypto_secretstream_xchacha20poly1305_TAG_REKEY) != 0 || 1405 # sodium_is_zero(STATE_COUNTER(state), 1406 # crypto_secretstream_xchacha20poly1305_COUNTERBYTES)) { 1407 # crypto_secretstream_xchacha20poly1305_rekey(state); 1408 # } 1409 if ($rekey || $st->needsRekey()) { 1410 // DO REKEY 1411 self::secretstream_xchacha20poly1305_rekey($state); 1412 } 1413 # if (outlen_p != NULL) { 1414 # *outlen_p = crypto_secretstream_xchacha20poly1305_ABYTES + mlen; 1415 # } 1416 return $out; 1417 } 1418 1419 /** 1420 * @param string $state 1421 * @param string $cipher 1422 * @param string $aad 1423 * @return bool|array{0: string, 1: int} 1424 * @throws SodiumException 1425 */ 1426 public static function secretstream_xchacha20poly1305_pull(&$state, $cipher, $aad = '') 1427 { 1428 $st = ParagonIE_Sodium_Core32_SecretStream_State::fromString($state); 1429 1430 $cipherlen = ParagonIE_Sodium_Core32_Util::strlen($cipher); 1431 # mlen = inlen - crypto_secretstream_xchacha20poly1305_ABYTES; 1432 $msglen = $cipherlen - ParagonIE_Sodium_Compat::CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_ABYTES; 1433 $aadlen = ParagonIE_Sodium_Core32_Util::strlen($aad); 1434 1435 # if (mlen > crypto_secretstream_xchacha20poly1305_MESSAGEBYTES_MAX) { 1436 # sodium_misuse(); 1437 # } 1438 if ((($msglen + 63) >> 6) > 0xfffffffe) { 1439 throw new SodiumException( 1440 'message cannot be larger than SODIUM_CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_MESSAGEBYTES_MAX bytes' 1441 ); 1442 } 1443 1444 # crypto_stream_chacha20_ietf(block, sizeof block, state->nonce, state->k); 1445 # crypto_onetimeauth_poly1305_init(&poly1305_state, block); 1446 # sodium_memzero(block, sizeof block); 1447 $auth = new ParagonIE_Sodium_Core32_Poly1305_State( 1448 ParagonIE_Sodium_Core32_ChaCha20::ietfStream(32, $st->getCombinedNonce(), $st->getKey()) 1449 ); 1450 1451 # crypto_onetimeauth_poly1305_update(&poly1305_state, ad, adlen); 1452 $auth->update($aad); 1453 1454 # crypto_onetimeauth_poly1305_update(&poly1305_state, _pad0, 1455 # (0x10 - adlen) & 0xf); 1456 $auth->update(str_repeat("\0", ((0x10 - $aadlen) & 0xf))); 1457 1458 1459 # memset(block, 0, sizeof block); 1460 # block[0] = in[0]; 1461 # crypto_stream_chacha20_ietf_xor_ic(block, block, sizeof block, 1462 # state->nonce, 1U, state->k); 1463 $block = ParagonIE_Sodium_Core32_ChaCha20::ietfStreamXorIc( 1464 $cipher[0] . str_repeat("\0", 63), 1465 $st->getCombinedNonce(), 1466 $st->getKey(), 1467 ParagonIE_Sodium_Core32_Util::store64_le(1) 1468 ); 1469 # tag = block[0]; 1470 # block[0] = in[0]; 1471 # crypto_onetimeauth_poly1305_update(&poly1305_state, block, sizeof block); 1472 $tag = ParagonIE_Sodium_Core32_Util::chrToInt($block[0]); 1473 $block[0] = $cipher[0]; 1474 $auth->update($block); 1475 1476 1477 # c = in + (sizeof tag); 1478 # crypto_onetimeauth_poly1305_update(&poly1305_state, c, mlen); 1479 $auth->update(ParagonIE_Sodium_Core32_Util::substr($cipher, 1, $msglen)); 1480 1481 # crypto_onetimeauth_poly1305_update 1482 # (&poly1305_state, _pad0, (0x10 - (sizeof block) + mlen) & 0xf); 1483 $auth->update(str_repeat("\0", ((0x10 - 64 + $msglen) & 0xf))); 1484 1485 # STORE64_LE(slen, (uint64_t) adlen); 1486 # crypto_onetimeauth_poly1305_update(&poly1305_state, slen, sizeof slen); 1487 $slen = ParagonIE_Sodium_Core32_Util::store64_le($aadlen); 1488 $auth->update($slen); 1489 1490 # STORE64_LE(slen, (sizeof block) + mlen); 1491 # crypto_onetimeauth_poly1305_update(&poly1305_state, slen, sizeof slen); 1492 $slen = ParagonIE_Sodium_Core32_Util::store64_le(64 + $msglen); 1493 $auth->update($slen); 1494 1495 # crypto_onetimeauth_poly1305_final(&poly1305_state, mac); 1496 # sodium_memzero(&poly1305_state, sizeof poly1305_state); 1497 $mac = $auth->finish(); 1498 1499 # stored_mac = c + mlen; 1500 # if (sodium_memcmp(mac, stored_mac, sizeof mac) != 0) { 1501 # sodium_memzero(mac, sizeof mac); 1502 # return -1; 1503 # } 1504 1505 $stored = ParagonIE_Sodium_Core32_Util::substr($cipher, $msglen + 1, 16); 1506 if (!ParagonIE_Sodium_Core32_Util::hashEquals($mac, $stored)) { 1507 return false; 1508 } 1509 1510 # crypto_stream_chacha20_ietf_xor_ic(m, c, mlen, state->nonce, 2U, state->k); 1511 $out = ParagonIE_Sodium_Core32_ChaCha20::ietfStreamXorIc( 1512 ParagonIE_Sodium_Core32_Util::substr($cipher, 1, $msglen), 1513 $st->getCombinedNonce(), 1514 $st->getKey(), 1515 ParagonIE_Sodium_Core32_Util::store64_le(2) 1516 ); 1517 1518 # XOR_BUF(STATE_INONCE(state), mac, 1519 # crypto_secretstream_xchacha20poly1305_INONCEBYTES); 1520 $st->xorNonce($mac); 1521 1522 # sodium_increment(STATE_COUNTER(state), 1523 # crypto_secretstream_xchacha20poly1305_COUNTERBYTES); 1524 $st->incrementCounter(); 1525 1526 # if ((tag & crypto_secretstream_xchacha20poly1305_TAG_REKEY) != 0 || 1527 # sodium_is_zero(STATE_COUNTER(state), 1528 # crypto_secretstream_xchacha20poly1305_COUNTERBYTES)) { 1529 # crypto_secretstream_xchacha20poly1305_rekey(state); 1530 # } 1531 1532 // Overwrite by reference: 1533 $state = $st->toString(); 1534 1535 /** @var bool $rekey */ 1536 $rekey = ($tag & ParagonIE_Sodium_Compat::CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_TAG_REKEY) !== 0; 1537 if ($rekey || $st->needsRekey()) { 1538 // DO REKEY 1539 self::secretstream_xchacha20poly1305_rekey($state); 1540 } 1541 return array($out, $tag); 1542 } 1543 1544 /** 1545 * @param string $state 1546 * @return void 1547 * @throws SodiumException 1548 */ 1549 public static function secretstream_xchacha20poly1305_rekey(&$state) 1550 { 1551 $st = ParagonIE_Sodium_Core32_SecretStream_State::fromString($state); 1552 # unsigned char new_key_and_inonce[crypto_stream_chacha20_ietf_KEYBYTES + 1553 # crypto_secretstream_xchacha20poly1305_INONCEBYTES]; 1554 # size_t i; 1555 # for (i = 0U; i < crypto_stream_chacha20_ietf_KEYBYTES; i++) { 1556 # new_key_and_inonce[i] = state->k[i]; 1557 # } 1558 $new_key_and_inonce = $st->getKey(); 1559 1560 # for (i = 0U; i < crypto_secretstream_xchacha20poly1305_INONCEBYTES; i++) { 1561 # new_key_and_inonce[crypto_stream_chacha20_ietf_KEYBYTES + i] = 1562 # STATE_INONCE(state)[i]; 1563 # } 1564 $new_key_and_inonce .= ParagonIE_Sodium_Core32_Util::substR($st->getNonce(), 0, 8); 1565 1566 # crypto_stream_chacha20_ietf_xor(new_key_and_inonce, new_key_and_inonce, 1567 # sizeof new_key_and_inonce, 1568 # state->nonce, state->k); 1569 1570 $st->rekey(ParagonIE_Sodium_Core32_ChaCha20::ietfStreamXorIc( 1571 $new_key_and_inonce, 1572 $st->getCombinedNonce(), 1573 $st->getKey(), 1574 ParagonIE_Sodium_Core32_Util::store64_le(0) 1575 )); 1576 1577 # for (i = 0U; i < crypto_stream_chacha20_ietf_KEYBYTES; i++) { 1578 # state->k[i] = new_key_and_inonce[i]; 1579 # } 1580 # for (i = 0U; i < crypto_secretstream_xchacha20poly1305_INONCEBYTES; i++) { 1581 # STATE_INONCE(state)[i] = 1582 # new_key_and_inonce[crypto_stream_chacha20_ietf_KEYBYTES + i]; 1583 # } 1584 # _crypto_secretstream_xchacha20poly1305_counter_reset(state); 1585 $st->counterReset(); 1586 1587 $state = $st->toString(); 1588 } 1589 1590 /** 1188 1591 * Detached Ed25519 signature. 1189 1592 * -
trunk/src/wp-includes/sodium_compat/src/File.php
r46586 r46858 680 680 681 681 /* Security checks */ 682 if (ParagonIE_Sodium_Core_Ed25519::check_S_lt_L(self::substr($sig, 32, 32))) { 682 if ( 683 (ParagonIE_Sodium_Core_Ed25519::chrToInt($sig[63]) & 240) 684 && 685 ParagonIE_Sodium_Core_Ed25519::check_S_lt_L(self::substr($sig, 32, 32)) 686 ) { 683 687 throw new SodiumException('S < L - Invalid signature'); 684 688 } … … 842 846 throw new SodiumException('Could not read input file'); 843 847 } 844 $first32 = ftell($ifp);848 $first32 = self::ftell($ifp); 845 849 846 850 /** @var string $subkey */ … … 876 880 877 881 // Pre-write 16 blank bytes for the Poly1305 tag 878 $start = ftell($ofp);882 $start = self::ftell($ofp); 879 883 fwrite($ofp, str_repeat("\x00", 16)); 880 884 … … 927 931 $subkey = null; 928 932 } 929 $end = ftell($ofp);933 $end = self::ftell($ofp); 930 934 931 935 /* … … 1044 1048 ) { 1045 1049 /** @var int $pos */ 1046 $pos = ftell($ifp);1050 $pos = self::ftell($ifp); 1047 1051 1048 1052 /** @var int $iter */ … … 1107 1111 1108 1112 /** @var int $originalPosition */ 1109 $originalPosition = ftell($fp);1113 $originalPosition = self::ftell($fp); 1110 1114 1111 1115 // Move file pointer to beginning of file … … 1315 1319 throw new SodiumException('Could not read input file'); 1316 1320 } 1317 $first32 = ftell($ifp);1321 $first32 = self::ftell($ifp); 1318 1322 1319 1323 /** @var string $subkey */ … … 1349 1353 1350 1354 // Pre-write 16 blank bytes for the Poly1305 tag 1351 $start = ftell($ofp);1355 $start = self::ftell($ofp); 1352 1356 fwrite($ofp, str_repeat("\x00", 16)); 1353 1357 … … 1400 1404 $subkey = null; 1401 1405 } 1402 $end = ftell($ofp);1406 $end = self::ftell($ofp); 1403 1407 1404 1408 /* … … 1516 1520 ) { 1517 1521 /** @var int $pos */ 1518 $pos = ftell($ifp);1522 $pos = self::ftell($ifp); 1519 1523 1520 1524 /** @var int $iter */ … … 1541 1545 return $res; 1542 1546 } 1547 1548 /** 1549 * @param resource $resource 1550 * @return int 1551 * @throws SodiumException 1552 */ 1553 private static function ftell($resource) 1554 { 1555 $return = ftell($resource); 1556 if (!is_int($return)) { 1557 throw new SodiumException('ftell() returned false'); 1558 } 1559 return (int) $return; 1560 } 1543 1561 }
Note: See TracChangeset
for help on using the changeset viewer.