CVE-2023-3674 (published 2023-07-19T19:15Z)

A flaw was found in the keylime attestation verifier, which fails to flag a device's submitted TPM quote as faulty when the quote's signature does not validate for some reason. Instead, it will only emit an error in the log without flagging the device as untrusted.

CVSS v3 base score: 2.8, LOW (CVSS:3.1/AV:L/AC:L/PR:L/UI:R/S:U/C:N/I:L/A:N)

Weakness information:
cwe_id: NVD-CWE-Other
cwe_name: Other
description: NVD is only using a subset of CWE for mapping instead of the entire CWE, and the weakness type is not covered by that subset.
extended_description: Insufficient Information

Fix information:
repo_url: https://github.com/keylime/keylime
commit_details: repo_url: https://github.com/keylime/keylime
author: Stefan Berger
author_date: 2023-07-11 18:03:28-04:00
msg: tpm_util: Replace a logger.error with an Exception in case of invalid signature

This fixes a possibly severe issue in 7.2.5 & 7.3.0.

Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
repository: repo_url: https://github.com/keylime/keylime
repo_name: keylime/keylime
description: A CNCF Project to Bootstrap & Maintain Trust on the Edge / Cloud and IoT
repo_language: Python
owner: keylime
file_changes: filename: tpm_util.py
change_type: ModificationType.MODIFY
diff: @@ -3,7 +3,6 @@ import string
 import struct
 from typing import Any, Dict, List, Optional, Tuple, Union
 
-from cryptography.exceptions import InvalidSignature
 from cryptography.hazmat import backends
 from cryptography.hazmat.primitives import hashes, hmac, serialization
 from cryptography.hazmat.primitives.asymmetric import ec, padding
@@ -155,10 +154,7 @@ def checkquote(
     digest.update(quoteblob)
     quote_digest = digest.finalize()
 
-    try:
-        verify(pubkey, signature, quote_digest, hashfunc)
-    except InvalidSignature:
-        logger.error("Invalid quote signature!")
+    verify(pubkey, signature, quote_digest, hashfunc)
 
     # Check that reported nonce is expected one
     retDict = tpm2_objects.unmarshal_tpms_attest(quoteblob)

programming_language: Python
filename: tpm_util_test.py
change_type: ModificationType.MODIFY
diff: @@ -2,6 +2,7 @@ import base64
 import unittest
 from unittest import mock
 
+from cryptography.exceptions import InvalidSignature
 from cryptography.hazmat.primitives.asymmetric.ec import (
     SECP256R1,
     EllipticCurve,
@@ -60,6 +61,26 @@ class TestTpmUtil(unittest.TestCase):
         except Exception as e:
             self.fail(f"checkquote failed with {e}")
 
+        # test bad input
+        bad_quoteblob = bytearray(quoteblob)
+        bad_quoteblob[5] ^= 0x1
+        with self.assertRaises(InvalidSignature):
+            checkquote(aikblob, nonce, sigblob, bad_quoteblob, pcrblob, "sha256")
+
+        l = list(nonce)
+        l[0] = "a"
+        bad_nonce = "".join(l)
+        with self.assertRaises(Exception):
+            checkquote(aikblob, bad_nonce, sigblob, quoteblob, pcrblob, "sha256")
+
+        bad_pcrblob = bytearray(pcrblob)
+        bad_pcrblob[5] ^= 0x1
+        with self.assertRaises(Exception):
+            checkquote(aikblob, nonce, sigblob, quoteblob, bad_pcrblob, "sha256")
+
+        with self.assertRaises(ValueError):
+            checkquote(aikblob, nonce, sigblob, quoteblob, pcrblob, "sha1")
+
     @staticmethod
     def not_random(numbytes: int) -> bytes:
         return b"\x12" * numbytes

programming_language: Python