Support vendor_db as logged by newer shim versions

Resolves: RHEL-8045

Signed-off-by: Sergio Correia <scorreia@redhat.com>
This commit is contained in:
Sergio Correia 2025-08-12 10:01:36 +01:00
parent 1f0f824cc1
commit 957c21f40b
No known key found for this signature in database
GPG Key ID: D0D219ED1F7E762C
3 changed files with 394 additions and 1 deletions

View File

@ -0,0 +1,29 @@
From d14e0a132cfedd081bffa7a990b9401d5e257cac Mon Sep 17 00:00:00 2001
From: Sergio Correia <scorreia@redhat.com>
Date: Fri, 8 Aug 2025 16:40:01 +0100
Subject: [PATCH 8/9] mb: support EV_EFI_HANDOFF_TABLES events on PCR1
Allow EV_EFI_HANDOFF_TABLES events on PCR1 alongside the existing
EV_EFI_HANDOFF_TABLES2 support to handle different firmware
implementations, in the example policy.
Signed-off-by: Sergio Correia <scorreia@redhat.com>
---
keylime/mba/elchecking/example.py | 1 +
1 file changed, 1 insertion(+)
diff --git a/keylime/mba/elchecking/example.py b/keylime/mba/elchecking/example.py
index 2c6f699..a3d918a 100644
--- a/keylime/mba/elchecking/example.py
+++ b/keylime/mba/elchecking/example.py
@@ -185,6 +185,7 @@ class Example(policies.Policy):
# We only expect one EV_NO_ACTION event at the start.
dispatcher.set((0, "EV_NO_ACTION"), tests.OnceTest(tests.AcceptAll()))
dispatcher.set((1, "EV_CPU_MICROCODE"), tests.OnceTest(tests.AcceptAll()))
+ dispatcher.set((1, "EV_EFI_HANDOFF_TABLES"), tests.OnceTest(tests.AcceptAll()))
dispatcher.set((1, "EV_EFI_HANDOFF_TABLES2"), tests.OnceTest(tests.AcceptAll()))
dispatcher.set((0, "EV_S_CRTM_VERSION"), events_final.get("s_crtms"))
dispatcher.set((0, "EV_EFI_PLATFORM_FIRMWARE_BLOB"), events_final.get("platform_firmware_blobs"))
--
2.47.3

View File

@ -0,0 +1,356 @@
From 607b97ac8d414cb57b1ca89925631d41bd7ac04c Mon Sep 17 00:00:00 2001
From: Sergio Correia <scorreia@redhat.com>
Date: Fri, 8 Aug 2025 16:41:54 +0100
Subject: [PATCH 9/9] mb: support vendor_db as logged by newer shim versions
- Updated example policy to properly handle different event structures
for vendor_db validation:
- KeySubsetMulti for EV_EFI_VARIABLE_DRIVER_CONFIG (has SignatureType field)
- SignatureSetMember for EV_EFI_VARIABLE_AUTHORITY (direct signature format)
- Added method to extract vendor_db from EV_EFI_VARIABLE_AUTHORITY events
in reference state generation (keylime-policy create measured-boot and
the legacy create_mb_refstate script)
- Made vendor_db optional for backward compatibility
This fixes attestation failures when vendor_db variables are present but
missing from reference states or validated with incorrect test types.
See: https://github.com/rhboot/shim/pull/728
Signed-off-by: Sergio Correia <scorreia@redhat.com>
---
keylime/mba/elchecking/example.py | 45 +++++++++
keylime/policy/create_mb_policy.py | 30 ++++++
scripts/create_mb_refstate | 30 ++++++
test/test_create_mb_policy.py | 142 +++++++++++++++++++++++++++++
4 files changed, 247 insertions(+)
diff --git a/keylime/mba/elchecking/example.py b/keylime/mba/elchecking/example.py
index a3d918a..5a933ac 100644
--- a/keylime/mba/elchecking/example.py
+++ b/keylime/mba/elchecking/example.py
@@ -21,6 +21,7 @@ from . import policies, tests
# kek - list of allowed KEK keys
# db - list of allowed db keys
# dbx - list of required dbx keys
+# vendor_db - list of allowed vendor_db keys (optional, for newer shim versions)
# mokdig - list of allowed digests of MoKList (PCR 14 EV_IPL)
# mokxdig - list of allowed digests of MoKListX (PCR 14 EV_IPL)
# kernels - list of allowed {
@@ -121,6 +122,10 @@ class Example(policies.Policy):
if req not in refstate:
raise Exception(f"refstate lacks {req}")
+ # vendor_db is optional for backward compatibility
+ if "vendor_db" not in refstate:
+ refstate["vendor_db"] = []
+
dispatcher = tests.Dispatcher(("PCRIndex", "EventType"))
vd_driver_config = tests.VariableDispatch()
vd_authority = tests.VariableDispatch()
@@ -268,6 +273,34 @@ class Example(policies.Policy):
"db",
db_test,
)
+ # Support vendor_db as logged by newer shim versions
+ # See: https://github.com/rhboot/shim/pull/728
+ if not has_secureboot and not refstate["vendor_db"]:
+ vendor_db_test = tests.OnceTest(tests.AcceptAll())
+ else:
+ vendor_db_test = tests.OnceTest(
+ tests.Or(
+ tests.KeySubsetMulti(
+ ["a159c0a5-e494-a74a-87b5-ab155c2bf072", "2616c4c1-4c50-9240-aca9-41f936934328"],
+ sigs_strip0x(refstate["vendor_db"]),
+ ),
+ tests.KeySubsetMulti(
+ ["a5c059a1-94e4-4aa7-87b5-ab155c2bf072", "c1c41626-504c-4092-aca9-41f936934328"],
+ sigs_strip0x(refstate["vendor_db"]),
+ ),
+ )
+ )
+
+ vd_driver_config.set(
+ "cbb219d7-3a3d-9645-a3bc-dad00e67656f",
+ "vendor_db",
+ vendor_db_test,
+ )
+ vd_driver_config.set(
+ "d719b2cb-3d3a-4596-a3bc-dad00e67656f",
+ "vendor_db",
+ vendor_db_test,
+ )
if not has_secureboot and not refstate["dbx"]:
dbx_test = tests.OnceTest(tests.AcceptAll())
@@ -295,6 +328,18 @@ class Example(policies.Policy):
vd_db_test = tests.OnceTest(tests.AcceptAll())
vd_authority.set("cbb219d7-3a3d-9645-a3bc-dad00e67656f", "db", vd_db_test)
vd_authority.set("d719b2cb-3d3a-4596-a3bc-dad00e67656f", "db", vd_db_test)
+ # Support vendor_db as logged by newer shim versions in EV_EFI_VARIABLE_AUTHORITY events
+ # See: https://github.com/rhboot/shim/pull/728
+ # EV_EFI_VARIABLE_AUTHORITY events have different structure than EV_EFI_VARIABLE_DRIVER_CONFIG
+ # They contain direct signature data without SignatureType field
+ if not has_secureboot and not refstate["vendor_db"]:
+ vendor_db_authority_test = tests.OnceTest(tests.AcceptAll())
+ else:
+ vendor_db_authority_test = tests.OnceTest(
+ tests.IterateTest(tests.SignatureSetMember(sigs_strip0x(refstate["vendor_db"])))
+ )
+ vd_authority.set("cbb219d7-3a3d-9645-a3bc-dad00e67656f", "vendor_db", vendor_db_authority_test)
+ vd_authority.set("d719b2cb-3d3a-4596-a3bc-dad00e67656f", "vendor_db", vendor_db_authority_test)
# Accept all SbatLevels of the Shim, because we already checked the hash of the Shim itself.
vd_sbat_level_test = tests.OnceTest(tests.AcceptAll())
vd_authority.set("50ab5d60-46e0-0043-abb6-3dd810dd8b23", "SbatLevel", vd_sbat_level_test)
diff --git a/keylime/policy/create_mb_policy.py b/keylime/policy/create_mb_policy.py
index 859e652..b2b48f7 100644
--- a/keylime/policy/create_mb_policy.py
+++ b/keylime/policy/create_mb_policy.py
@@ -93,6 +93,35 @@ def get_keys(events: List[Dict[str, Any]]) -> Dict[str, List[Any]]:
return out
+def get_vendor_db(events: List[Dict[str, Any]]) -> Dict[str, List[Any]]:
+ """Get vendor_db signatures from EV_EFI_VARIABLE_AUTHORITY events."""
+ out: Dict[str, List[Any]] = {"vendor_db": []}
+
+ for event in events:
+ if "EventType" not in event:
+ continue
+ if event["EventType"] != "EV_EFI_VARIABLE_AUTHORITY":
+ continue
+ if "Event" not in event or "UnicodeName" not in event["Event"]:
+ continue
+
+ event_name = event["Event"]["UnicodeName"].lower()
+ if event_name == "vendor_db":
+ data = None
+ if "VariableData" in event["Event"]:
+ data = event["Event"]["VariableData"]
+
+ if data is not None:
+ # VariableData for EV_EFI_VARIABLE_AUTHORITY is a list of signatures
+ for entry in data:
+ if "SignatureOwner" in entry and "SignatureData" in entry:
+ out["vendor_db"].append(
+ {"SignatureOwner": entry["SignatureOwner"], "SignatureData": f"0x{entry['SignatureData']}"}
+ )
+
+ return out
+
+
def get_kernel(events: List[Dict[str, Any]], secure_boot: bool) -> Dict[str, List[Dict[str, Any]]]:
"""Extract digest for Shim, Grub, Linux Kernel and initrd."""
out = []
@@ -259,6 +288,7 @@ def create_mb_refstate(args: argparse.Namespace) -> Optional[Dict[str, object]]:
}
],
**get_keys(events),
+ **get_vendor_db(events),
**get_mok(events),
**get_kernel(events, has_secureboot),
}
diff --git a/scripts/create_mb_refstate b/scripts/create_mb_refstate
index 23cafb9..c98e61d 100755
--- a/scripts/create_mb_refstate
+++ b/scripts/create_mb_refstate
@@ -78,6 +78,35 @@ def get_keys(events):
return out
+def get_vendor_db(events):
+ """Get vendor_db signatures from EV_EFI_VARIABLE_AUTHORITY events."""
+ out = {"vendor_db": []}
+
+ for event in events:
+ if "EventType" not in event:
+ continue
+ if event["EventType"] != "EV_EFI_VARIABLE_AUTHORITY":
+ continue
+ if "Event" not in event or "UnicodeName" not in event["Event"]:
+ continue
+
+ event_name = event["Event"]["UnicodeName"].lower()
+ if event_name == "vendor_db":
+ data = None
+ if "VariableData" in event["Event"]:
+ data = event["Event"]["VariableData"]
+
+ if data is not None:
+ # VariableData for EV_EFI_VARIABLE_AUTHORITY is a list of signatures
+ for entry in data:
+ if "SignatureOwner" in entry and "SignatureData" in entry:
+ out["vendor_db"].append(
+ {"SignatureOwner": entry["SignatureOwner"], "SignatureData": f"0x{entry['SignatureData']}"}
+ )
+
+ return out
+
+
def get_kernel(events, secure_boot):
"""
Extract digest for Shim, Grub, Linux Kernel and initrd.
@@ -197,6 +226,7 @@ def main():
}
],
**get_keys(events),
+ **get_vendor_db(events),
**get_mok(events),
**get_kernel(events, has_secureboot),
}
diff --git a/test/test_create_mb_policy.py b/test/test_create_mb_policy.py
index b00d8e7..cd32bda 100644
--- a/test/test_create_mb_policy.py
+++ b/test/test_create_mb_policy.py
@@ -364,6 +364,148 @@ class CreateMeasuredBootPolicy_Test(unittest.TestCase):
for c in test_cases:
self.assertDictEqual(create_mb_policy.get_mok(c["events"]), c["expected"])
+ def test_get_vendor_db(self):
+ test_cases = [
+ {"events": [], "expected": {"vendor_db": []}},
+ # No EV_EFI_VARIABLE_AUTHORITY events.
+ {
+ "events": [
+ {
+ "EventType": "EV_EFI_VARIABLE_DRIVER_CONFIG",
+ "Event": {"UnicodeName": "vendor_db", "VariableData": []},
+ }
+ ],
+ "expected": {"vendor_db": []},
+ },
+ # Good vendor_db event with EV_EFI_VARIABLE_AUTHORITY.
+ {
+ "events": [
+ {
+ "EventType": "EV_EFI_VARIABLE_AUTHORITY",
+ "Event": {
+ "UnicodeName": "vendor_db",
+ "VariableData": [
+ {
+ "SignatureOwner": "0223eddb-9079-4388-af77-2d65b1c35d3b",
+ "SignatureData": "sig-data-1",
+ }
+ ],
+ },
+ }
+ ],
+ "expected": {
+ "vendor_db": [
+ {"SignatureOwner": "0223eddb-9079-4388-af77-2d65b1c35d3b", "SignatureData": "0xsig-data-1"}
+ ]
+ },
+ },
+ # Multiple vendor_db signatures.
+ {
+ "events": [
+ {
+ "EventType": "EV_EFI_VARIABLE_AUTHORITY",
+ "Event": {
+ "UnicodeName": "vendor_db",
+ "VariableData": [
+ {
+ "SignatureOwner": "0223eddb-9079-4388-af77-2d65b1c35d3b",
+ "SignatureData": "sig-data-1",
+ },
+ {
+ "SignatureOwner": "77fa9abd-0359-4d32-bd60-28f4e78f784b",
+ "SignatureData": "sig-data-2",
+ },
+ ],
+ },
+ }
+ ],
+ "expected": {
+ "vendor_db": [
+ {"SignatureOwner": "0223eddb-9079-4388-af77-2d65b1c35d3b", "SignatureData": "0xsig-data-1"},
+ {"SignatureOwner": "77fa9abd-0359-4d32-bd60-28f4e78f784b", "SignatureData": "0xsig-data-2"},
+ ]
+ },
+ },
+ # Missing EventType.
+ {
+ "events": [
+ {
+ "Event": {
+ "UnicodeName": "vendor_db",
+ "VariableData": [
+ {
+ "SignatureOwner": "0223eddb-9079-4388-af77-2d65b1c35d3b",
+ "SignatureData": "sig-data-1",
+ }
+ ],
+ }
+ }
+ ],
+ "expected": {"vendor_db": []},
+ },
+ # Wrong EventType.
+ {
+ "events": [
+ {
+ "EventType": "EV_EFI_VARIABLE_DRIVER_CONFIG",
+ "Event": {
+ "UnicodeName": "vendor_db",
+ "VariableData": [
+ {
+ "SignatureOwner": "0223eddb-9079-4388-af77-2d65b1c35d3b",
+ "SignatureData": "sig-data-1",
+ }
+ ],
+ },
+ }
+ ],
+ "expected": {"vendor_db": []},
+ },
+ # Missing Event.
+ {
+ "events": [{"EventType": "EV_EFI_VARIABLE_AUTHORITY"}],
+ "expected": {"vendor_db": []},
+ },
+ # Missing UnicodeName.
+ {
+ "events": [
+ {
+ "EventType": "EV_EFI_VARIABLE_AUTHORITY",
+ "Event": {
+ "VariableData": [
+ {
+ "SignatureOwner": "0223eddb-9079-4388-af77-2d65b1c35d3b",
+ "SignatureData": "sig-data-1",
+ }
+ ]
+ },
+ }
+ ],
+ "expected": {"vendor_db": []},
+ },
+ # Wrong UnicodeName.
+ {
+ "events": [
+ {
+ "EventType": "EV_EFI_VARIABLE_AUTHORITY",
+ "Event": {
+ "UnicodeName": "db",
+ "VariableData": [
+ {
+ "SignatureOwner": "0223eddb-9079-4388-af77-2d65b1c35d3b",
+ "SignatureData": "sig-data-1",
+ }
+ ],
+ },
+ }
+ ],
+ "expected": {"vendor_db": []},
+ },
+ ]
+
+ for c in test_cases:
+ self.assertDictEqual(create_mb_policy.get_vendor_db(c["events"]), c["expected"])
+
def test_get_kernel(self):
test_cases = [
{"events": [], "secureboot": False, "expected": {}},
--
2.47.3

View File

@ -9,7 +9,7 @@
Name: keylime
Version: 7.12.1
Release: 8%{?dist}
Release: 9%{?dist}
Summary: Open source TPM software for Bootstrapping and Maintaining Trust
URL: https://github.com/keylime/keylime
@ -30,6 +30,10 @@ Patch: 0006-Revert-default-server_key_password-for-verifier-regi.patch
# Backported from https://github.com/keylime/keylime/pull/1782
Patch: 0007-fix_db_connection_leaks.patch
# Backported from https://github.com/keylime/keylime/pull/1791
Patch: 0008-mb-support-EV_EFI_HANDOFF_TABLES-events-on-PCR1.patch
Patch: 0009-mb-support-vendor_db-as-logged-by-newer-shim-version.patch
License: ASL 2.0 and MIT
BuildRequires: git-core
@ -423,6 +427,10 @@ fi
%license LICENSE
%changelog
* Tue Aug 11 2025 Sergio Correia <scorreia@redhat.com> - 7.12.1-9
- Support vendor_db as logged by newer shim versions
Resolves: RHEL-8045
* Fri Aug 08 2025 Anderson Toshiyuki Sasaki <ansasaki@redhat.com> - 7.12.1-8
- Fix DB connection leaks
Resolves: RHEL-108263