From ca76d3913faa5bfeceed5f0f1dd917066bceb44f Mon Sep 17 00:00:00 2001 From: terrafrost Date: Fri, 8 Mar 2019 07:27:04 -0600 Subject: [PATCH] RSA: protect against possible timing attacks during OAEP decryption --- phpseclib/Crypt/RSA.php | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/phpseclib/Crypt/RSA.php b/phpseclib/Crypt/RSA.php index c2fdc66d..3be36c88 100644 --- a/phpseclib/Crypt/RSA.php +++ b/phpseclib/Crypt/RSA.php @@ -2305,12 +2305,13 @@ class Crypt_RSA return false; } - $result = 0; + $result = "\0"; + $x^= $y; for ($i = 0; $i < strlen($x); $i++) { - $result |= ord($x[$i]) ^ ord($y[$i]); + $result|= $x[$i]; } - return $result == 0; + return $result === "\0"; } /** @@ -2517,19 +2518,26 @@ class Crypt_RSA $db = $maskedDB ^ $dbMask; $lHash2 = substr($db, 0, $this->hLen); $m = substr($db, $this->hLen); - if (!$this->_equals($lHash, $lHash2)) { - user_error('Decryption error'); - return false; + $hashesMatch = $this->_equals($lHash, $lHash2); + $leadingZeros = 1; + $patternMatch = 0; + $offset = 0; + for ($i = 0; $i < strlen($m); $i++) { + $patternMatch|= $leadingZeros & ($m[$i] === "\1"); + $leadingZeros&= $m[$i] === "\0"; + $offset+= $patternMatch ? 0 : 1; } - $m = ltrim($m, chr(0)); - if (ord($m[0]) != 1) { + + // we do & instead of && to avoid https://en.wikipedia.org/wiki/Short-circuit_evaluation + // to protect against timing attacks + if (!$hashesMatch & !$patternMatch) { user_error('Decryption error'); return false; } // Output the message M - return substr($m, 1); + return substr($m, $offset + 1); } /**