Skip to content

Commit

Permalink
Fix myriad bugs with PHP 8.1 on x86
Browse files Browse the repository at this point in the history
Related to #140, determined from local testing as per #140 (comment)
  • Loading branch information
paragonie-security committed Mar 23, 2022
1 parent f6550aa commit 87533e7
Show file tree
Hide file tree
Showing 14 changed files with 139 additions and 89 deletions.
12 changes: 12 additions & 0 deletions src/Core/BLAKE2b.php
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,9 @@ abstract class ParagonIE_Sodium_Core_BLAKE2b extends ParagonIE_Sodium_Core_Util
*/
public static function new64($high, $low)
{
if (PHP_INT_SIZE === 4) {
throw new SodiumException("Error, use 32-bit");
}
$i64 = new SplFixedArray(2);
$i64[0] = $high & 0xffffffff;
$i64[1] = $low & 0xffffffff;
Expand Down Expand Up @@ -86,6 +89,9 @@ protected static function to64($num)
*/
protected static function add64($x, $y)
{
if (PHP_INT_SIZE === 4) {
throw new SodiumException("Error, use 32-bit");
}
$l = ($x[1] + $y[1]) & 0xffffffff;
return self::new64(
(int) ($x[0] + $y[0] + (
Expand Down Expand Up @@ -119,6 +125,9 @@ protected static function add364($x, $y, $z)
*/
protected static function xor64(SplFixedArray $x, SplFixedArray $y)
{
if (PHP_INT_SIZE === 4) {
throw new SodiumException("Error, use 32-bit");
}
if (!is_numeric($x[0])) {
throw new SodiumException('x[0] is not an integer');
}
Expand Down Expand Up @@ -147,6 +156,9 @@ protected static function xor64(SplFixedArray $x, SplFixedArray $y)
*/
public static function rotr64($x, $c)
{
if (PHP_INT_SIZE === 4) {
throw new SodiumException("Error, use 32-bit");
}
if ($c >= 64) {
$c %= 64;
}
Expand Down
8 changes: 6 additions & 2 deletions src/Core/Util.php
Original file line number Diff line number Diff line change
Expand Up @@ -458,7 +458,7 @@ public static function load_4($string)
}
/** @var array<int, int> $unpacked */
$unpacked = unpack('V', $string);
return (int) ($unpacked[1] & 0xffffffff);
return (int) $unpacked[1];
}

/**
Expand Down Expand Up @@ -613,7 +613,11 @@ public static function numericTo64BitInteger($num)
{
$high = 0;
/** @var int $low */
$low = $num & 0xffffffff;
if (PHP_INT_SIZE === 4) {
$low = (int) $num;
} else {
$low = $num & 0xffffffff;
}

if ((+(abs($num))) >= 1) {
if ($num > 0) {
Expand Down
8 changes: 3 additions & 5 deletions src/Core32/Curve25519.php
Original file line number Diff line number Diff line change
Expand Up @@ -1838,8 +1838,8 @@ public static function equal($b, $c)
$c0 = $c & 0xffff;
$c1 = ($c >> 16) & 0xffff;

$d0 = (($b0 ^ $c0) - 1) >> 15;
$d1 = (($b1 ^ $c1) - 1) >> 15;
$d0 = (($b0 ^ $c0) - 1) >> 31;
$d1 = (($b1 ^ $c1) - 1) >> 31;
return ($d0 & $d1) & 1;
}

Expand All @@ -1857,7 +1857,6 @@ public static function negative($char)
return $char < 0 ? 1 : 0;
}
/** @var string $char */
/** @var int $x */
$x = self::chrToInt(self::substr($char, 0, 1));
return (int) ($x >> 31);
}
Expand Down Expand Up @@ -1963,15 +1962,14 @@ public static function ge_select($pos = 0, $b = 0)
}

$bnegative = self::negative($b);
/** @var int $babs */
$babs = $b - (((-$bnegative) & $b) << 1);

$t = self::ge_precomp_0();
for ($i = 0; $i < 8; ++$i) {
$t = self::cmov(
$t,
$base[$pos][$i],
self::equal($babs, $i + 1)
-self::equal($babs, $i + 1)
);
}
$minusT = new ParagonIE_Sodium_Core32_Curve25519_Ge_Precomp(
Expand Down
3 changes: 3 additions & 0 deletions src/Core32/Curve25519/Fe.php
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,9 @@ public static function fromArray($array, $save_indexes = null)
}
} else {
for ($i = 0; $i < $count; ++$i) {
if (!($array[$i] instanceof ParagonIE_Sodium_Core32_Int32)) {
throw new TypeError('Expected ParagonIE_Sodium_Core32_Int32');
}
$array[$i]->overflow = 0;
$obj->offsetSet($i, $array[$i]);
}
Expand Down
6 changes: 3 additions & 3 deletions src/Core32/Int64.php
Original file line number Diff line number Diff line change
Expand Up @@ -337,9 +337,9 @@ public function multiplyLong(array $a, array $b, $baseLog2 = 16)
$a_i = $a[$i];
for ($j = 0; $j < $a_l; ++$j) {
$b_j = $b[$j];
$product = ($a_i * $b_j) + $r[$i + $j];
$carry = ($product >> $baseLog2 & 0xffff);
$r[$i + $j] = ($product - (int) ($carry * $base)) & 0xffff;
$product = (($a_i * $b_j) + $r[$i + $j]);
$carry = (((int) $product >> $baseLog2) & 0xffff);
$r[$i + $j] = ((int) $product - (int) ($carry * $base)) & 0xffff;
$r[$i + $j + 1] += $carry;
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/Core32/Poly1305/State.php
Original file line number Diff line number Diff line change
Expand Up @@ -419,7 +419,7 @@ public function finish()
$g4 = $g4->mask($mask);

/** @var int $mask */
$mask = (~$mask) & 0xffffffff;
$mask = ~$mask;

$h0 = $h0->mask($mask)->orInt32($g0);
$h1 = $h1->mask($mask)->orInt32($g1);
Expand Down
71 changes: 62 additions & 9 deletions tests/unit/Blake2bTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -253,20 +253,38 @@ public function testGenericHashUpdate()
$hbufStr . $hbufStr
);

$exp = ParagonIE_Sodium_Core_BLAKE2b::init();
ParagonIE_Sodium_Core_BLAKE2b::update($exp, $hbuf, (1 << $h));
ParagonIE_Sodium_Core_BLAKE2b::update($exp, $hbuf, (1 << $h));
if (PHP_INT_SIZE === 4) {
$exp = ParagonIE_Sodium_Core32_BLAKE2b::init();
ParagonIE_Sodium_Core32_BLAKE2b::update($exp, $hbuf, (1 << $h));
ParagonIE_Sodium_Core32_BLAKE2b::update($exp, $hbuf, (1 << $h));

$ctx = ParagonIE_Sodium_Core32_BLAKE2b::init();
ParagonIE_Sodium_Core32_BLAKE2b::update($ctx, $buf, (1 << ($h + 1)));
} else {
$exp = ParagonIE_Sodium_Core_BLAKE2b::init();
ParagonIE_Sodium_Core_BLAKE2b::update($exp, $hbuf, (1 << $h));
ParagonIE_Sodium_Core_BLAKE2b::update($exp, $hbuf, (1 << $h));

$ctx = ParagonIE_Sodium_Core_BLAKE2b::init();
ParagonIE_Sodium_Core_BLAKE2b::update($ctx, $buf, (1 << ($h + 1)));
$ctx = ParagonIE_Sodium_Core_BLAKE2b::init();
ParagonIE_Sodium_Core_BLAKE2b::update($ctx, $buf, (1 << ($h + 1)));
}
for ($j = 0; $j < 5; ++$j) {
$this->assertEquals($exp[$j], $ctx[$j], 'element ' . $j);
}

$this->assertSame(
bin2hex(ParagonIE_Sodium_Core_BLAKE2b::contextToString($exp)),
bin2hex(ParagonIE_Sodium_Core_BLAKE2b::contextToString($ctx)),
'h = ' . $h);
if (PHP_INT_SIZE === 4) {
$this->assertSame(
bin2hex(ParagonIE_Sodium_Core32_BLAKE2b::contextToString($exp)),
bin2hex(ParagonIE_Sodium_Core32_BLAKE2b::contextToString($ctx)),
'h = ' . $h
);
} else {
$this->assertSame(
bin2hex(ParagonIE_Sodium_Core_BLAKE2b::contextToString($exp)),
bin2hex(ParagonIE_Sodium_Core_BLAKE2b::contextToString($ctx)),
'h = ' . $h
);
}
}
}

Expand All @@ -275,6 +293,9 @@ public function testGenericHashUpdate()
*/
public function testCounter()
{
if (PHP_INT_SIZE === 4) {
$this->markTestSkipped("Ignored in 32-bit");
}
$ctx = ParagonIE_Sodium_Core_BLAKE2b::init(null, 32);

ParagonIE_Sodium_Core_BLAKE2b::increment_counter($ctx, 1);
Expand All @@ -296,6 +317,38 @@ public function testCounter()
$this->assertEquals(1, $ctx[1][0][0]);
}

/**
* @covers ParagonIE_Sodium_Core32_BLAKE2b::increment_counter()
*/
public function testCounter32()
{
if (PHP_INT_SIZE === 8) {
$this->markTestSkipped("32-bit only");
}
$ctx = ParagonIE_Sodium_Core32_BLAKE2b::init(null, 32);

ParagonIE_Sodium_Core32_BLAKE2b::increment_counter($ctx, 1);
$this->assertEquals(1, $ctx[1][0]->toInt());
$this->assertEquals(0, $ctx[1][1]->toInt());

ParagonIE_Sodium_Core32_BLAKE2b::increment_counter($ctx, 1);
$this->assertEquals(2, $ctx[1][0]->toInt());
$this->assertEquals(0, $ctx[1][1]->toInt());

ParagonIE_Sodium_Core32_BLAKE2b::increment_counter($ctx, 1024);
$this->assertEquals(1026, $ctx[1][0]->toInt());
$this->assertEquals(0, $ctx[1][1]->toInt());

for ($i = 0; $i < 4; ++$i) {
ParagonIE_Sodium_Core32_BLAKE2b::increment_counter($ctx, 1 << 30);
}

/** @var ParagonIE_Sodium_Core32_Int64 $c */
$c = $ctx[1][0]->toArray();
$this->assertEquals(1026, $c[1]);
$this->assertEquals(1, $c[0]);
}

/**
* Make sure our 'context' string is consistent.
*
Expand Down
6 changes: 3 additions & 3 deletions tests/unit/CryptoTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -282,7 +282,7 @@ public function testCryptoBox32()
public function testCryptoBox()
{
if (PHP_INT_SIZE === 4) {
return;
$this->markTestSkipped('Ignored on 32-bit');
}
$nonce = str_repeat("\x00", 24);
$message = "Lorem ipsum dolor sit amet, consectetur adipiscing elit.";
Expand Down Expand Up @@ -459,6 +459,7 @@ public function testScalarmult()
);
}
}

/**
* @covers ParagonIE_Sodium_Crypto::sign_detached()
* @throws SodiumException
Expand All @@ -468,7 +469,6 @@ public function testSignDetached32()
{
if (PHP_INT_SIZE === 8) {
$this->markTestSkipped('Only 32-bit');
return;
}
$secret = ParagonIE_Sodium_Core_Util::hex2bin(
'fcdf31aae72e280cc760186d83e41be216fe1f2c7407dd393ad3a45a2fa501a4' .
Expand Down Expand Up @@ -497,7 +497,7 @@ public function testSignDetached32()
public function testSignDetached()
{
if (PHP_INT_SIZE === 4) {
return;
$this->markTestSkipped('Ignored on 32-bit');
}
$secret = ParagonIE_Sodium_Core_Util::hex2bin(
'fcdf31aae72e280cc760186d83e41be216fe1f2c7407dd393ad3a45a2fa501a4' .
Expand Down
Loading

0 comments on commit 87533e7

Please sign in to comment.