mirror of
https://github.com/WordPress/WordPress.git
synced 2024-09-27 06:42:56 +02:00
cb01bbf97b
This adds a pure PHP implementation of the cryptographic functions supported in PHP 7.2+. It provides the necessary backwards compatibility required to support signature verification and other security features going forward across all supported PHP versions. Props paragoninitiativeenterprises Fixes #45806. See #39309. Built from https://develop.svn.wordpress.org/trunk@44953 git-svn-id: http://core.svn.wordpress.org/trunk@44784 1a063a9b-81f0-0310-95a4-ce76da25c4cd
239 lines
6.5 KiB
PHP
239 lines
6.5 KiB
PHP
<?php
|
|
|
|
if (class_exists('ParagonIE_Sodium_Core32_SipHash', false)) {
|
|
return;
|
|
}
|
|
|
|
/**
|
|
* Class ParagonIE_SodiumCompat_Core32_SipHash
|
|
*
|
|
* Only uses 32-bit arithmetic, while the original SipHash used 64-bit integers
|
|
*/
|
|
class ParagonIE_Sodium_Core32_SipHash extends ParagonIE_Sodium_Core32_Util
|
|
{
|
|
/**
|
|
* @internal You should not use this directly from another application
|
|
*
|
|
* @param array<int, ParagonIE_Sodium_Core32_Int64> $v
|
|
* @return array<int, ParagonIE_Sodium_Core32_Int64>
|
|
*/
|
|
public static function sipRound(array $v)
|
|
{
|
|
# v0 += v1;
|
|
$v[0] = $v[0]->addInt64($v[1]);
|
|
|
|
# v1 = ROTL(v1, 13);
|
|
$v[1] = $v[1]->rotateLeft(13);
|
|
|
|
# v1 ^= v0;
|
|
$v[1] = $v[1]->xorInt64($v[0]);
|
|
|
|
# v0=ROTL(v0,32);
|
|
$v[0] = $v[0]->rotateLeft(32);
|
|
|
|
# v2 += v3;
|
|
$v[2] = $v[2]->addInt64($v[3]);
|
|
|
|
# v3=ROTL(v3,16);
|
|
$v[3] = $v[3]->rotateLeft(16);
|
|
|
|
# v3 ^= v2;
|
|
$v[3] = $v[3]->xorInt64($v[2]);
|
|
|
|
# v0 += v3;
|
|
$v[0] = $v[0]->addInt64($v[3]);
|
|
|
|
# v3=ROTL(v3,21);
|
|
$v[3] = $v[3]->rotateLeft(21);
|
|
|
|
# v3 ^= v0;
|
|
$v[3] = $v[3]->xorInt64($v[0]);
|
|
|
|
# v2 += v1;
|
|
$v[2] = $v[2]->addInt64($v[1]);
|
|
|
|
# v1=ROTL(v1,17);
|
|
$v[1] = $v[1]->rotateLeft(17);
|
|
|
|
# v1 ^= v2;
|
|
$v[1] = $v[1]->xorInt64($v[2]);
|
|
|
|
# v2=ROTL(v2,32)
|
|
$v[2] = $v[2]->rotateLeft(32);
|
|
|
|
return $v;
|
|
}
|
|
|
|
/**
|
|
* @internal You should not use this directly from another application
|
|
*
|
|
* @param string $in
|
|
* @param string $key
|
|
* @return string
|
|
* @throws SodiumException
|
|
* @throws TypeError
|
|
*/
|
|
public static function sipHash24($in, $key)
|
|
{
|
|
$inlen = self::strlen($in);
|
|
|
|
# /* "somepseudorandomlygeneratedbytes" */
|
|
# u64 v0 = 0x736f6d6570736575ULL;
|
|
# u64 v1 = 0x646f72616e646f6dULL;
|
|
# u64 v2 = 0x6c7967656e657261ULL;
|
|
# u64 v3 = 0x7465646279746573ULL;
|
|
$v = array(
|
|
new ParagonIE_Sodium_Core32_Int64(
|
|
array(0x736f, 0x6d65, 0x7073, 0x6575)
|
|
),
|
|
new ParagonIE_Sodium_Core32_Int64(
|
|
array(0x646f, 0x7261, 0x6e64, 0x6f6d)
|
|
),
|
|
new ParagonIE_Sodium_Core32_Int64(
|
|
array(0x6c79, 0x6765, 0x6e65, 0x7261)
|
|
),
|
|
new ParagonIE_Sodium_Core32_Int64(
|
|
array(0x7465, 0x6462, 0x7974, 0x6573)
|
|
)
|
|
);
|
|
|
|
# u64 k0 = LOAD64_LE( k );
|
|
# u64 k1 = LOAD64_LE( k + 8 );
|
|
$k = array(
|
|
ParagonIE_Sodium_Core32_Int64::fromReverseString(
|
|
self::substr($key, 0, 8)
|
|
),
|
|
ParagonIE_Sodium_Core32_Int64::fromReverseString(
|
|
self::substr($key, 8, 8)
|
|
)
|
|
);
|
|
|
|
# b = ( ( u64 )inlen ) << 56;
|
|
$b = new ParagonIE_Sodium_Core32_Int64(
|
|
array(($inlen << 8) & 0xffff, 0, 0, 0)
|
|
);
|
|
|
|
# v3 ^= k1;
|
|
$v[3] = $v[3]->xorInt64($k[1]);
|
|
# v2 ^= k0;
|
|
$v[2] = $v[2]->xorInt64($k[0]);
|
|
# v1 ^= k1;
|
|
$v[1] = $v[1]->xorInt64($k[1]);
|
|
# v0 ^= k0;
|
|
$v[0] = $v[0]->xorInt64($k[0]);
|
|
|
|
$left = $inlen;
|
|
# for ( ; in != end; in += 8 )
|
|
while ($left >= 8) {
|
|
# m = LOAD64_LE( in );
|
|
$m = ParagonIE_Sodium_Core32_Int64::fromReverseString(
|
|
self::substr($in, 0, 8)
|
|
);
|
|
|
|
# v3 ^= m;
|
|
$v[3] = $v[3]->xorInt64($m);
|
|
|
|
# SIPROUND;
|
|
# SIPROUND;
|
|
$v = self::sipRound($v);
|
|
$v = self::sipRound($v);
|
|
|
|
# v0 ^= m;
|
|
$v[0] = $v[0]->xorInt64($m);
|
|
|
|
$in = self::substr($in, 8);
|
|
$left -= 8;
|
|
}
|
|
|
|
# switch( left )
|
|
# {
|
|
# case 7: b |= ( ( u64 )in[ 6] ) << 48;
|
|
# case 6: b |= ( ( u64 )in[ 5] ) << 40;
|
|
# case 5: b |= ( ( u64 )in[ 4] ) << 32;
|
|
# case 4: b |= ( ( u64 )in[ 3] ) << 24;
|
|
# case 3: b |= ( ( u64 )in[ 2] ) << 16;
|
|
# case 2: b |= ( ( u64 )in[ 1] ) << 8;
|
|
# case 1: b |= ( ( u64 )in[ 0] ); break;
|
|
# case 0: break;
|
|
# }
|
|
switch ($left) {
|
|
case 7:
|
|
$b = $b->orInt64(
|
|
ParagonIE_Sodium_Core32_Int64::fromInts(
|
|
0, self::chrToInt($in[6]) << 16
|
|
)
|
|
);
|
|
case 6:
|
|
$b = $b->orInt64(
|
|
ParagonIE_Sodium_Core32_Int64::fromInts(
|
|
0, self::chrToInt($in[5]) << 8
|
|
)
|
|
);
|
|
case 5:
|
|
$b = $b->orInt64(
|
|
ParagonIE_Sodium_Core32_Int64::fromInts(
|
|
0, self::chrToInt($in[4])
|
|
)
|
|
);
|
|
case 4:
|
|
$b = $b->orInt64(
|
|
ParagonIE_Sodium_Core32_Int64::fromInts(
|
|
self::chrToInt($in[3]) << 24, 0
|
|
)
|
|
);
|
|
case 3:
|
|
$b = $b->orInt64(
|
|
ParagonIE_Sodium_Core32_Int64::fromInts(
|
|
self::chrToInt($in[2]) << 16, 0
|
|
)
|
|
);
|
|
case 2:
|
|
$b = $b->orInt64(
|
|
ParagonIE_Sodium_Core32_Int64::fromInts(
|
|
self::chrToInt($in[1]) << 8, 0
|
|
)
|
|
);
|
|
case 1:
|
|
$b = $b->orInt64(
|
|
ParagonIE_Sodium_Core32_Int64::fromInts(
|
|
self::chrToInt($in[0]), 0
|
|
)
|
|
);
|
|
case 0:
|
|
break;
|
|
}
|
|
|
|
# v3 ^= b;
|
|
$v[3] = $v[3]->xorInt64($b);
|
|
|
|
# SIPROUND;
|
|
# SIPROUND;
|
|
$v = self::sipRound($v);
|
|
$v = self::sipRound($v);
|
|
|
|
# v0 ^= b;
|
|
$v[0] = $v[0]->xorInt64($b);
|
|
|
|
// Flip the lower 8 bits of v2 which is ($v[4], $v[5]) in our implementation
|
|
# v2 ^= 0xff;
|
|
$v[2]->limbs[3] ^= 0xff;
|
|
|
|
# SIPROUND;
|
|
# SIPROUND;
|
|
# SIPROUND;
|
|
# SIPROUND;
|
|
$v = self::sipRound($v);
|
|
$v = self::sipRound($v);
|
|
$v = self::sipRound($v);
|
|
$v = self::sipRound($v);
|
|
|
|
# b = v0 ^ v1 ^ v2 ^ v3;
|
|
# STORE64_LE( out, b );
|
|
return $v[0]
|
|
->xorInt64($v[1])
|
|
->xorInt64($v[2])
|
|
->xorInt64($v[3])
|
|
->toReverseString();
|
|
}
|
|
}
|