CVE-2016-5430: Cryptographic Issues (CWE-310)
value: The RSA 1.5 algorithm implementation in the JOSE_JWE class in JWE.php in jose-php before 2.2.1 lacks the Random Filling protection mechanism, which makes it easier for remote attackers to obtain cleartext data via a Million Message Attack (MMA).
CWE description: Weaknesses in this category are related to the design and implementation of data confidentiality and integrity. Frequently these deal with the use of encoding techniques, encryption libraries, and hashing algorithms. The weaknesses in this category could lead to a degradation of the quality data if they are not addressed.
CVSS v3 base score: 5.3
Published: 2016-09-03T20:59Z
Repository: https://github.com/nov/jose-php
Language: PHP
Files changed: src/JOSE/JWE.php
Commit date: 2016-08-31 01:03:07 +0900
Commit message: one more hash_equals, and better CEK decryption error handling

Diff: diff --git a/src/JOSE/JWE.php b/src/JOSE/JWE.php
index 4bc1923..964d8ce 100644
--- a/src/JOSE/JWE.php
+++ b/src/JOSE/JWE.php
@@ -166,10 +166,12 @@ class JOSE_JWE extends JOSE_JWT {
             throw new JOSE_Exception_EncryptionFailed('Master key encryption failed');
         }
     }
 
     private function decryptContentEncryptionKey($private_key_or_secret) {
+        $this->generateContentEncryptionKey(null); # NOTE: run this always not to make timing difference
+        $fake_content_encryption_key = $this->content_encryption_key;
         switch ($this->header['alg']) {
             case 'RSA1_5':
                 $rsa = $this->rsa($private_key_or_secret, RSA::ENCRYPTION_PKCS1);
                 $this->content_encryption_key = $rsa->decrypt($this->jwe_encrypted_key);
                 break;
@@ -192,11 +194,11 @@ class JOSE_JWE extends JOSE_JWT {
         if (!$this->content_encryption_key) {
             # NOTE:
             #  Not to disclose timing difference between CEK decryption error and others.
             #  Mitigating Bleichenbacher Attack on PKCS#1 v1.5
             #  ref.) http://inaz2.hatenablog.com/entry/2016/01/26/222303
-            $this->generateContentEncryptionKey(null);
+            $this->content_encryption_key = $fake_content_encryption_key;
         }
     }
 
     private function deriveEncryptionAndMacKeys() {
         switch ($this->header['enc']) {
@@ -280,11 +282,11 @@ class JOSE_JWE extends JOSE_JWT {
             0, $sha_size / 2 / 8
         );
     }
 
     private function checkAuthenticationTag() {
-        if ($this->authentication_tag === $this->calculateAuthenticationTag()) {
+        if (hash_equals($this->authentication_tag, $this->calculateAuthenticationTag())) {
             return true;
         } else {
             throw new JOSE_Exception_UnexpectedAlgorithm('Invalid authentication tag');
         }
     }

Vulnerable code:             $this->generateContentEncryptionKey(null);
        if ($this->authentication_tag === $this->calculateAuthenticationTag()) {
Fixed code:         $this->generateContentEncryptionKey(null); # NOTE: run this always not to make timing difference
        $fake_content_encryption_key = $this->content_encryption_key;
            $this->content_encryption_key = $fake_content_encryption_key;
        if (hash_equals($this->authentication_tag, $this->calculateAuthenticationTag())) {