Skip to content

Commit 799b2d0

Browse files
Upgrade/Install: Update sodium_compat to v1.23.0.
The previous version of sodium_compat was overly permissible with `sodium_base642bin()` when the `*_NO_PADDING` variants were specified, which was not compatible with `ext-sodium`. This has been fixed in version 1.22.0. Version 1.23.0 includes some optimizations by replacing the array in the Curve25519 field element with 10 integer object properties instead. The result is a 7% to 12% speedup for the overall PHPUnit suite. References: * [https://github.com/paragonie/sodium_compat/releases/tag/v1.22.0 sodium_compat 1.22.0 release notes] * [https://github.com/paragonie/sodium_compat/releases/tag/v1.23.0 sodium_compat 1.23.0 release notes] * [paragonie/sodium_compat@v1.21.2...v1.23.0 Full list of changes in sodium_compat 1.23.0] Follow-up to [55699], [58752], [58753], [60787]. Props paragoninitiativeenterprises, SergeyBiryukov. Fixes #64079. git-svn-id: https://develop.svn.wordpress.org/trunk@60905 602fd350-edb4-49c9-b593-d223f7449a82
1 parent de3741f commit 799b2d0

File tree

16 files changed

+662
-392
lines changed

16 files changed

+662
-392
lines changed

src/wp-includes/sodium_compat/src/Compat.php

Lines changed: 29 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,9 @@
2525
return;
2626
}
2727

28+
/**
29+
* @api
30+
*/
2831
class ParagonIE_Sodium_Compat
2932
{
3033
/**
@@ -204,9 +207,6 @@ public static function base642bin(
204207

205208
/** @var string $encoded */
206209
$encoded = (string) $encoded;
207-
if (ParagonIE_Sodium_Core_Util::strlen($encoded) === 0) {
208-
return '';
209-
}
210210

211211
// Just strip before decoding
212212
if (!empty($ignore)) {
@@ -218,19 +218,19 @@ public static function base642bin(
218218
case self::BASE64_VARIANT_ORIGINAL:
219219
return ParagonIE_Sodium_Core_Base64_Original::decode($encoded, true);
220220
case self::BASE64_VARIANT_ORIGINAL_NO_PADDING:
221-
return ParagonIE_Sodium_Core_Base64_Original::decode($encoded, false);
221+
return ParagonIE_Sodium_Core_Base64_Original::decodeNoPadding($encoded);
222222
case self::BASE64_VARIANT_URLSAFE:
223223
return ParagonIE_Sodium_Core_Base64_UrlSafe::decode($encoded, true);
224224
case self::BASE64_VARIANT_URLSAFE_NO_PADDING:
225-
return ParagonIE_Sodium_Core_Base64_UrlSafe::decode($encoded, false);
225+
return ParagonIE_Sodium_Core_Base64_UrlSafe::decodeNoPadding($encoded);
226226
default:
227227
throw new SodiumException('invalid base64 variant identifier');
228228
}
229229
} catch (Exception $ex) {
230230
if ($ex instanceof SodiumException) {
231231
throw $ex;
232232
}
233-
throw new SodiumException('invalid base64 string');
233+
throw new SodiumException('invalid base64 string', 0, $ex);
234234
}
235235
}
236236

@@ -356,7 +356,7 @@ public static function crypto_aead_aegis128l_decrypt(
356356

357357
/* Input validation: */
358358
if (ParagonIE_Sodium_Core_Util::strlen($nonce) !== self::CRYPTO_AEAD_AEGIS128L_NPUBBYTES) {
359-
throw new SodiumException('Nonce must be CRYPTO_AEAD_AEGIS_128L_NPUBBYTES long');
359+
throw new SodiumException('Nonce must be CRYPTO_AEAD_AEGIS128L_NPUBBYTES long');
360360
}
361361
if (ParagonIE_Sodium_Core_Util::strlen($key) !== self::CRYPTO_AEAD_AEGIS128L_KEYBYTES) {
362362
throw new SodiumException('Key must be CRYPTO_AEAD_AEGIS128L_KEYBYTES long');
@@ -410,7 +410,7 @@ public static function crypto_aead_aegis128l_encrypt(
410410

411411
/* Input validation: */
412412
if (ParagonIE_Sodium_Core_Util::strlen($nonce) !== self::CRYPTO_AEAD_AEGIS128L_NPUBBYTES) {
413-
throw new SodiumException('Nonce must be CRYPTO_AEAD_AEGIS128L_KEYBYTES long');
413+
throw new SodiumException('Nonce must be CRYPTO_AEAD_AEGIS128L_NPUBBYTES long');
414414
}
415415
if (ParagonIE_Sodium_Core_Util::strlen($key) !== self::CRYPTO_AEAD_AEGIS128L_KEYBYTES) {
416416
throw new SodiumException('Key must be CRYPTO_AEAD_AEGIS128L_KEYBYTES long');
@@ -519,10 +519,10 @@ public static function crypto_aead_aegis256_encrypt(
519519

520520
/* Input validation: */
521521
if (ParagonIE_Sodium_Core_Util::strlen($nonce) !== self::CRYPTO_AEAD_AEGIS256_NPUBBYTES) {
522-
throw new SodiumException('Nonce must be CRYPTO_AEAD_AEGIS128L_KEYBYTES long');
522+
throw new SodiumException('Nonce must be CRYPTO_AEAD_AEGIS256_NPUBBYTES long');
523523
}
524524
if (ParagonIE_Sodium_Core_Util::strlen($key) !== self::CRYPTO_AEAD_AEGIS256_KEYBYTES) {
525-
throw new SodiumException('Key must be CRYPTO_AEAD_AEGIS128L_KEYBYTES long');
525+
throw new SodiumException('Key must be CRYPTO_AEAD_AEGIS256_KEYBYTES long');
526526
}
527527

528528
list($ct, $tag) = ParagonIE_Sodium_Core_AEGIS256::encrypt($plaintext, $assocData, $key, $nonce);
@@ -562,6 +562,9 @@ public static function crypto_aead_aes256gcm_is_available()
562562
// OpenSSL doesn't support AEAD before 7.1.0
563563
return false;
564564
}
565+
if (!extension_loaded('openssl')) {
566+
return false;
567+
}
565568
if (!is_callable('openssl_encrypt') || !is_callable('openssl_decrypt')) {
566569
// OpenSSL isn't installed
567570
return false;
@@ -615,6 +618,9 @@ public static function crypto_aead_aes256gcm_decrypt(
615618
if (ParagonIE_Sodium_Core_Util::strlen($ciphertext) < self::CRYPTO_AEAD_AES256GCM_ABYTES) {
616619
throw new SodiumException('Message must be at least CRYPTO_AEAD_AES256GCM_ABYTES long');
617620
}
621+
if (!extension_loaded('openssl')) {
622+
throw new SodiumException('The OpenSSL extension is not installed');
623+
}
618624
if (!is_callable('openssl_decrypt')) {
619625
throw new SodiumException('The OpenSSL extension is not installed, or openssl_decrypt() is not available');
620626
}
@@ -675,6 +681,9 @@ public static function crypto_aead_aes256gcm_encrypt(
675681
throw new SodiumException('Key must be CRYPTO_AEAD_AES256GCM_KEYBYTES long');
676682
}
677683

684+
if (!extension_loaded('openssl')) {
685+
throw new SodiumException('The OpenSSL extension is not installed');
686+
}
678687
if (!is_callable('openssl_encrypt')) {
679688
throw new SodiumException('The OpenSSL extension is not installed, or openssl_encrypt() is not available');
680689
}
@@ -823,10 +832,10 @@ public static function crypto_aead_chacha20poly1305_encrypt(
823832

824833
/* Input validation: */
825834
if (ParagonIE_Sodium_Core_Util::strlen($nonce) !== self::CRYPTO_AEAD_CHACHA20POLY1305_NPUBBYTES) {
826-
throw new SodiumException('Nonce must be CRYPTO_AEAD_CHACHA20POLY1305_NPUBBYTES long');
835+
throw new SodiumException('Nonce must be CRYPTO_AEAD_CHACHA20POLY1305_IETF_NPUBBYTES long');
827836
}
828837
if (ParagonIE_Sodium_Core_Util::strlen($key) !== self::CRYPTO_AEAD_CHACHA20POLY1305_KEYBYTES) {
829-
throw new SodiumException('Key must be CRYPTO_AEAD_CHACHA20POLY1305_KEYBYTES long');
838+
throw new SodiumException('Key must be CRYPTO_AEAD_CHACHA20POLY1305_IETF_KEYBYTES long');
830839
}
831840

832841
if (self::useNewSodiumAPI()) {
@@ -901,10 +910,10 @@ public static function crypto_aead_chacha20poly1305_ietf_decrypt(
901910
throw new SodiumException('Nonce must be CRYPTO_AEAD_CHACHA20POLY1305_IETF_NPUBBYTES long');
902911
}
903912
if (ParagonIE_Sodium_Core_Util::strlen($key) !== self::CRYPTO_AEAD_CHACHA20POLY1305_KEYBYTES) {
904-
throw new SodiumException('Key must be CRYPTO_AEAD_CHACHA20POLY1305_KEYBYTES long');
913+
throw new SodiumException('Key must be CRYPTO_AEAD_CHACHA20POLY1305_IETF_KEYBYTES long');
905914
}
906915
if (ParagonIE_Sodium_Core_Util::strlen($ciphertext) < self::CRYPTO_AEAD_CHACHA20POLY1305_ABYTES) {
907-
throw new SodiumException('Message must be at least CRYPTO_AEAD_CHACHA20POLY1305_ABYTES long');
916+
throw new SodiumException('Message must be at least CRYPTO_AEAD_CHACHA20POLY1305_IETF_ABYTES long');
908917
}
909918

910919
if (self::useNewSodiumAPI()) {
@@ -2781,6 +2790,9 @@ public static function crypto_secretbox_xchacha20poly1305_open(
27812790
if (ParagonIE_Sodium_Core_Util::strlen($key) !== self::CRYPTO_SECRETBOX_KEYBYTES) {
27822791
throw new SodiumException('Argument 3 must be CRYPTO_SECRETBOX_KEYBYTES long.');
27832792
}
2793+
if (ParagonIE_Sodium_Core_Util::strlen($ciphertext) < self::CRYPTO_SECRETBOX_MACBYTES) {
2794+
throw new SodiumException("Ciphertext must be at least CRYPTO_SECRETBOX_MACBYTES long");
2795+
}
27842796

27852797
if (PHP_INT_SIZE === 4) {
27862798
return ParagonIE_Sodium_Crypto32::secretbox_xchacha20poly1305_open($ciphertext, $nonce, $key);
@@ -3711,6 +3723,9 @@ public static function increment(
37113723
}
37123724

37133725
$len = ParagonIE_Sodium_Core_Util::strlen($var);
3726+
if ($len < 1) {
3727+
throw new SodiumException('Argument 1 cannot be empty');
3728+
}
37143729
$c = 1;
37153730
$copy = '';
37163731
for ($i = 0; $i < $len; ++$i) {

src/wp-includes/sodium_compat/src/Core/Base64/Original.php

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,32 @@ public static function decode($src, $strictPadding = false)
185185
}
186186
return $dest;
187187
}
188+
189+
/**
190+
* @param string $encodedString
191+
* @return string
192+
*/
193+
public static function decodeNoPadding(
194+
#[SensitiveParameter]
195+
$encodedString
196+
) {
197+
$srcLen = strlen($encodedString);
198+
if ($srcLen === 0) {
199+
return '';
200+
}
201+
if (($srcLen & 3) === 0) {
202+
// If $strLen is not zero, and it is divisible by 4, then it's at least 4.
203+
if ($encodedString[$srcLen - 1] === '=' || $encodedString[$srcLen - 2] === '=') {
204+
throw new InvalidArgumentException(
205+
"decodeNoPadding() doesn't tolerate padding"
206+
);
207+
}
208+
}
209+
return self::decode(
210+
$encodedString,
211+
true
212+
);
213+
}
188214
// COPY ParagonIE_Sodium_Core_Base64_Common ENDING HERE
189215

190216
/**

src/wp-includes/sodium_compat/src/Core/Base64/UrlSafe.php

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,33 @@ public static function decode($src, $strictPadding = false)
185185
}
186186
return $dest;
187187
}
188+
189+
/**
190+
* @param string $encodedString
191+
* @return string
192+
*/
193+
public static function decodeNoPadding(
194+
#[SensitiveParameter]
195+
$encodedString
196+
) {
197+
$srcLen = strlen($encodedString);
198+
if ($srcLen === 0) {
199+
return '';
200+
}
201+
if (($srcLen & 3) === 0) {
202+
// If $strLen is not zero, and it is divisible by 4, then it's at least 4.
203+
if ($encodedString[$srcLen - 1] === '=' || $encodedString[$srcLen - 2] === '=') {
204+
throw new InvalidArgumentException(
205+
"decodeNoPadding() doesn't tolerate padding"
206+
);
207+
}
208+
}
209+
return self::decode(
210+
$encodedString,
211+
true
212+
);
213+
}
214+
188215
// COPY ParagonIE_Sodium_Core_Base64_Common ENDING HERE
189216
/**
190217
* Uses bitwise operators instead of table-lookups to turn 6-bit integers

src/wp-includes/sodium_compat/src/Core/ChaCha20.php

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -329,7 +329,7 @@ public static function encryptBytes(
329329
* @throws SodiumException
330330
* @throws TypeError
331331
*/
332-
public static function stream($len = 64, $nonce = '', $key = '')
332+
public static function stream($len, $nonce, $key)
333333
{
334334
return self::encryptBytes(
335335
new ParagonIE_Sodium_Core_ChaCha20_Ctx($key, $nonce),
@@ -347,7 +347,7 @@ public static function stream($len = 64, $nonce = '', $key = '')
347347
* @throws SodiumException
348348
* @throws TypeError
349349
*/
350-
public static function ietfStream($len, $nonce = '', $key = '')
350+
public static function ietfStream($len, $nonce, $key)
351351
{
352352
return self::encryptBytes(
353353
new ParagonIE_Sodium_Core_ChaCha20_IetfCtx($key, $nonce),
@@ -366,7 +366,7 @@ public static function ietfStream($len, $nonce = '', $key = '')
366366
* @throws SodiumException
367367
* @throws TypeError
368368
*/
369-
public static function ietfStreamXorIc($message, $nonce = '', $key = '', $ic = '')
369+
public static function ietfStreamXorIc($message, $nonce, $key, $ic = '')
370370
{
371371
return self::encryptBytes(
372372
new ParagonIE_Sodium_Core_ChaCha20_IetfCtx($key, $nonce, $ic),
@@ -385,7 +385,7 @@ public static function ietfStreamXorIc($message, $nonce = '', $key = '', $ic = '
385385
* @throws SodiumException
386386
* @throws TypeError
387387
*/
388-
public static function streamXorIc($message, $nonce = '', $key = '', $ic = '')
388+
public static function streamXorIc($message, $nonce, $key, $ic = '')
389389
{
390390
return self::encryptBytes(
391391
new ParagonIE_Sodium_Core_ChaCha20_Ctx($key, $nonce, $ic),

src/wp-includes/sodium_compat/src/Core/ChaCha20/Ctx.php

Lines changed: 27 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -50,13 +50,9 @@ public function __construct($key = '', $iv = '', $counter = '')
5050
$this->container[10] = self::load_4(self::substr($key, 24, 4));
5151
$this->container[11] = self::load_4(self::substr($key, 28, 4));
5252

53-
if (empty($counter)) {
54-
$this->container[12] = 0;
55-
$this->container[13] = 0;
56-
} else {
57-
$this->container[12] = self::load_4(self::substr($counter, 0, 4));
58-
$this->container[13] = self::load_4(self::substr($counter, 4, 4));
59-
}
53+
$counter = $this->initCounter($counter);
54+
$this->container[12] = self::load_4(self::substr($counter, 0, 4));
55+
$this->container[13] = self::load_4(self::substr($counter, 4, 4));
6056
$this->container[14] = self::load_4(self::substr($iv, 0, 4));
6157
$this->container[15] = self::load_4(self::substr($iv, 4, 4));
6258
}
@@ -120,4 +116,28 @@ public function offsetGet($offset)
120116
? $this->container[$offset]
121117
: null;
122118
}
119+
120+
/**
121+
* Initialize (pad) a counter value.
122+
* @throws SodiumException
123+
*
124+
* @param string $ctr
125+
* @return string
126+
*/
127+
public function initCounter(
128+
#[SensitiveParameter]
129+
$ctr
130+
) {
131+
$len = self::strlen($ctr);
132+
if ($len === 0) {
133+
return str_repeat("\0", 8);
134+
}
135+
if ($len < 8) {
136+
return $ctr . str_repeat("\0", 8 - $len);
137+
}
138+
if ($len > 8) {
139+
throw new SodiumException("counter cannot be more than 8 bytes");
140+
}
141+
return $ctr;
142+
}
123143
}

src/wp-includes/sodium_compat/src/Core/ChaCha20/IetfCtx.php

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,11 +26,9 @@ public function __construct($key = '', $iv = '', $counter = '')
2626
if (self::strlen($iv) !== 12) {
2727
throw new InvalidArgumentException('ChaCha20 expects a 96-bit nonce in IETF mode.');
2828
}
29+
$counter = $this->initCounter($counter);
2930
parent::__construct($key, self::substr($iv, 0, 8), $counter);
30-
31-
if (!empty($counter)) {
32-
$this->container[12] = self::load_4(self::substr($counter, 0, 4));
33-
}
31+
$this->container[12] = self::load_4(self::substr($counter, 0, 4));
3432
$this->container[13] = self::load_4(self::substr($iv, 0, 4));
3533
$this->container[14] = self::load_4(self::substr($iv, 4, 4));
3634
$this->container[15] = self::load_4(self::substr($iv, 8, 4));

0 commit comments

Comments
 (0)