WordPress.org

Make WordPress Core

Ticket #47186: 47186-update_sodium_compat_to_v1_9_3.patch

File 47186-update_sodium_compat_to_v1_9_3.patch, 11.8 KB (added by paragoninitiativeenterprises, 17 months ago)

Same as the previous patch, except this one also addresses a false positive type error when testing with Psalm and other static analysis tools.

  • wp-includes/sodium_compat/lib/php72compat.php

    IDEA additional info:
    Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
    <+>UTF-8
     
    250250    function sodium_crypto_aead_xchacha20poly1305_ietf_decrypt($message, $assocData, $nonce, $key)
    251251    {
    252252        try {
    253             return ParagonIE_Sodium_Compat::crypto_aead_xchacha20poly1305_ietf_decrypt($message, $assocData, $nonce, $key);
     253            return ParagonIE_Sodium_Compat::crypto_aead_xchacha20poly1305_ietf_decrypt($message, $assocData, $nonce, $key, true);
    254254        } catch (Error $ex) {
    255255            return false;
    256256        } catch (Exception $ex) {
     
    271271     */
    272272    function sodium_crypto_aead_xchacha20poly1305_ietf_encrypt($message, $assocData, $nonce, $key)
    273273    {
    274         return ParagonIE_Sodium_Compat::crypto_aead_xchacha20poly1305_ietf_encrypt($message, $assocData, $nonce, $key);
     274        return ParagonIE_Sodium_Compat::crypto_aead_xchacha20poly1305_ietf_encrypt($message, $assocData, $nonce, $key, true);
    275275    }
    276276}
    277277if (!is_callable('sodium_crypto_aead_xchacha20poly1305_ietf_keygen')) {
  • wp-includes/sodium_compat/src/Crypto.php

    IDEA additional info:
    Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
    <+>UTF-8
     
    819819     */
    820820    public static function keyExchange($my_sk, $their_pk, $client_pk, $server_pk)
    821821    {
    822         return self::generichash(
    823             self::scalarmult($my_sk, $their_pk) .
     822        return ParagonIE_Sodium_Compat::crypto_generichash(
     823            ParagonIE_Sodium_Compat::crypto_scalarmult($my_sk, $their_pk) .
    824824            $client_pk .
    825825            $server_pk
    826826        );
  • wp-includes/sodium_compat/src/Core32/Int64.php

    IDEA additional info:
    Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
    <+>UTF-8
     
    205205     */
    206206    public function mulInt($int = 0, $size = 0)
    207207    {
     208        if (ParagonIE_Sodium_Compat::$fastMult) {
     209            return $this->mulIntFast($int);
     210        }
    208211        ParagonIE_Sodium_Core32_Util::declareScalarType($int, 'int', 1);
    209212        ParagonIE_Sodium_Core32_Util::declareScalarType($size, 'int', 2);
    210213        /** @var int $int */
     
    268271            $a3 &= 0xffff;
    269272
    270273            $int >>= 1;
    271             $return->limbs[0] = $ret0;
    272             $return->limbs[1] = $ret1;
    273             $return->limbs[2] = $ret2;
    274             $return->limbs[3] = $ret3;
    275         }
     274        }
     275        $return->limbs[0] = $ret0;
     276        $return->limbs[1] = $ret1;
     277        $return->limbs[2] = $ret2;
     278        $return->limbs[3] = $ret3;
    276279        return $return;
    277280    }
    278281
     
    317320        );
    318321    }
    319322
     323    /**
     324     * @param array<int, int> $a
     325     * @param array<int, int> $b
     326     * @param int $baseLog2
     327     * @return array<int, int>
     328     */
     329    public function multiplyLong(array $a, array $b, $baseLog2 = 16)
     330    {
     331        $a_l = count($a);
     332        $b_l = count($b);
     333        /** @var array<int, int> $r */
     334        $r = array_fill(0, $a_l + $b_l + 1, 0);
     335        $base = 1 << $baseLog2;
     336        for ($i = 0; $i < $a_l; ++$i) {
     337            $a_i = $a[$i];
     338            for ($j = 0; $j < $a_l; ++$j) {
     339                $b_j = $b[$j];
     340                $product = ($a_i * $b_j) + $r[$i + $j];
     341                $carry = ($product >> $baseLog2 & 0xffff);
     342                $r[$i + $j] = ($product - (int) ($carry * $base)) & 0xffff;
     343                $r[$i + $j + 1] += $carry;
     344            }
     345        }
     346        return array_slice($r, 0, 5);
     347    }
     348
     349    /**
     350     * @param int $int
     351     * @return ParagonIE_Sodium_Core32_Int64
     352     */
     353    public function mulIntFast($int)
     354    {
     355        // Handle negative numbers
     356        $aNeg = ($this->limbs[0] >> 15) & 1;
     357        $bNeg = ($int >> 31) & 1;
     358        $a = array_reverse($this->limbs);
     359        $b = array(
     360            $int & 0xffff,
     361            ($int >> 16) & 0xffff,
     362            -$bNeg & 0xffff,
     363            -$bNeg & 0xffff
     364        );
     365        if ($aNeg) {
     366            for ($i = 0; $i < 4; ++$i) {
     367                $a[$i] = ($a[$i] ^ 0xffff) & 0xffff;
     368            }
     369            ++$a[0];
     370        }
     371        if ($bNeg) {
     372            for ($i = 0; $i < 4; ++$i) {
     373                $b[$i] = ($b[$i] ^ 0xffff) & 0xffff;
     374            }
     375            ++$b[0];
     376        }
     377        // Multiply
     378        $res = $this->multiplyLong($a, $b);
     379
     380        // Re-apply negation to results
     381        if ($aNeg !== $bNeg) {
     382            for ($i = 0; $i < 4; ++$i) {
     383                $res[$i] = (0xffff ^ $res[$i]) & 0xffff;
     384            }
     385            // Handle integer overflow
     386            $c = 1;
     387            for ($i = 0; $i < 4; ++$i) {
     388                $res[$i] += $c;
     389                $c = $res[$i] >> 16;
     390                $res[$i] &= 0xffff;
     391            }
     392        }
     393
     394        // Return our values
     395        $return = new ParagonIE_Sodium_Core32_Int64();
     396        $return->limbs = array(
     397            $res[3] & 0xffff,
     398            $res[2] & 0xffff,
     399            $res[1] & 0xffff,
     400            $res[0] & 0xffff
     401        );
     402        if (count($res) > 4) {
     403            $return->overflow = $res[4] & 0xffff;
     404        }
     405        $return->unsignedInt = $this->unsignedInt;
     406        return $return;
     407    }
     408
     409    /**
     410     * @param ParagonIE_Sodium_Core32_Int64 $right
     411     * @return ParagonIE_Sodium_Core32_Int64
     412     */
     413    public function mulInt64Fast(ParagonIE_Sodium_Core32_Int64 $right)
     414    {
     415        $aNeg = ($this->limbs[0] >> 15) & 1;
     416        $bNeg = ($right->limbs[0] >> 15) & 1;
     417
     418        $a = array_reverse($this->limbs);
     419        $b = array_reverse($right->limbs);
     420        if ($aNeg) {
     421            for ($i = 0; $i < 4; ++$i) {
     422                $a[$i] = ($a[$i] ^ 0xffff) & 0xffff;
     423            }
     424            ++$a[0];
     425        }
     426        if ($bNeg) {
     427            for ($i = 0; $i < 4; ++$i) {
     428                $b[$i] = ($b[$i] ^ 0xffff) & 0xffff;
     429            }
     430            ++$b[0];
     431        }
     432        $res = $this->multiplyLong($a, $b);
     433        if ($aNeg !== $bNeg) {
     434            if ($aNeg !== $bNeg) {
     435                for ($i = 0; $i < 4; ++$i) {
     436                    $res[$i] = ($res[$i] ^ 0xffff) & 0xffff;
     437                }
     438                $c = 1;
     439                for ($i = 0; $i < 4; ++$i) {
     440                    $res[$i] += $c;
     441                    $c = $res[$i] >> 16;
     442                    $res[$i] &= 0xffff;
     443                }
     444            }
     445        }
     446        $return = new ParagonIE_Sodium_Core32_Int64();
     447        $return->limbs = array(
     448            $res[3] & 0xffff,
     449            $res[2] & 0xffff,
     450            $res[1] & 0xffff,
     451            $res[0] & 0xffff
     452        );
     453        if (count($res) > 4) {
     454            $return->overflow = $res[4];
     455        }
     456        return $return;
     457    }
     458
    320459    /**
    321460     * @param ParagonIE_Sodium_Core32_Int64 $int
    322461     * @param int $size
     
    327466     */
    328467    public function mulInt64(ParagonIE_Sodium_Core32_Int64 $int, $size = 0)
    329468    {
     469        if (ParagonIE_Sodium_Compat::$fastMult) {
     470            return $this->mulInt64Fast($int);
     471        }
    330472        ParagonIE_Sodium_Core32_Util::declareScalarType($size, 'int', 2);
    331473        if (!$size) {
    332474            $size = 63;
  • wp-includes/sodium_compat/src/Compat.php

    IDEA additional info:
    Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
    <+>UTF-8
     
    669669     * This mode uses a 64-bit random nonce with a 64-bit counter.
    670670     * IETF mode uses a 96-bit random nonce with a 32-bit counter.
    671671     *
    672      * @param string $ciphertext Encrypted message (with Poly1305 MAC appended)
    673      * @param string $assocData Authenticated Associated Data (unencrypted)
    674      * @param string $nonce Number to be used only Once; must be 8 bytes
    675      * @param string $key Encryption key
     672     * @param string $ciphertext   Encrypted message (with Poly1305 MAC appended)
     673     * @param string $assocData    Authenticated Associated Data (unencrypted)
     674     * @param string $nonce        Number to be used only Once; must be 8 bytes
     675     * @param string $key          Encryption key
     676     * @param bool   $dontFallback Don't fallback to ext/sodium
    676677     *
    677678     * @return string            The original plaintext message
    678679     * @throws SodiumException
     
    683684        $ciphertext = '',
    684685        $assocData = '',
    685686        $nonce = '',
    686         $key = ''
     687        $key = '',
     688        $dontFallback = false
    687689    ) {
    688690        /* Type checks: */
    689691        ParagonIE_Sodium_Core_Util::declareScalarType($ciphertext, 'string', 1);
     
    701703        if (ParagonIE_Sodium_Core_Util::strlen($ciphertext) < self::CRYPTO_AEAD_XCHACHA20POLY1305_IETF_ABYTES) {
    702704            throw new SodiumException('Message must be at least CRYPTO_AEAD_XCHACHA20POLY1305_IETF_ABYTES long');
    703705        }
     706        if (self::useNewSodiumAPI() && !$dontFallback) {
     707            if (is_callable('sodium_crypto_aead_xchacha20poly1305_ietf_decrypt')) {
     708                return sodium_crypto_aead_xchacha20poly1305_ietf_decrypt(
     709                    $ciphertext,
     710                    $assocData,
     711                    $nonce,
     712                    $key
     713                );
     714            }
     715        }
    704716
    705717        if (PHP_INT_SIZE === 4) {
    706718            return ParagonIE_Sodium_Crypto32::aead_xchacha20poly1305_ietf_decrypt(
     
    727739     * This mode uses a 64-bit random nonce with a 64-bit counter.
    728740     * IETF mode uses a 96-bit random nonce with a 32-bit counter.
    729741     *
    730      * @param string $plaintext Message to be encrypted
    731      * @param string $assocData Authenticated Associated Data (unencrypted)
    732      * @param string $nonce Number to be used only Once; must be 8 bytes
    733      * @param string $key Encryption key
     742     * @param string $plaintext    Message to be encrypted
     743     * @param string $assocData    Authenticated Associated Data (unencrypted)
     744     * @param string $nonce        Number to be used only Once; must be 8 bytes
     745     * @param string $key          Encryption key
     746     * @param bool   $dontFallback Don't fallback to ext/sodium
    734747     *
    735748     * @return string           Ciphertext with a 16-byte Poly1305 message
    736749     *                          authentication code appended
     
    742755        $plaintext = '',
    743756        $assocData = '',
    744757        $nonce = '',
    745         $key = ''
     758        $key = '',
     759        $dontFallback = false
    746760    ) {
    747761        /* Type checks: */
    748762        ParagonIE_Sodium_Core_Util::declareScalarType($plaintext, 'string', 1);
     
    757771        if (ParagonIE_Sodium_Core_Util::strlen($key) !== self::CRYPTO_AEAD_XCHACHA20POLY1305_IETF_KEYBYTES) {
    758772            throw new SodiumException('Key must be CRYPTO_AEAD_XCHACHA20POLY1305_KEYBYTES long');
    759773        }
     774        if (self::useNewSodiumAPI() && !$dontFallback) {
     775            if (is_callable('sodium_crypto_aead_xchacha20poly1305_ietf_encrypt')) {
     776                return sodium_crypto_aead_xchacha20poly1305_ietf_encrypt(
     777                    $plaintext,
     778                    $assocData,
     779                    $nonce,
     780                    $key
     781                );
     782            }
     783        }
    760784
    761785        if (PHP_INT_SIZE === 4) {
    762786            return ParagonIE_Sodium_Crypto32::aead_xchacha20poly1305_ietf_encrypt(