Since I had the displeasure of fighting broken/quirky/limited UEFI Firmware implementations, as part of Mosby, and had to double check whether a signed Secure Boot authvar should be accepted as valid.
Usage ./authval.py <var.auth> where var.auth should start with PK, KEK, DB or DBX according to the variable you are trying to check (so that we automatically fill GUID and attributes for the signed payload). Also note that APPEND is assumed for all variables, except PK.
#!/bin/env python3 # authval.pl - A Python script to validate Secure Boot signed auth variables # Copyright 2026 Pete Batard <[email protected]> - GPL v3 or later import re import argparse import struct import uuid from datetime import datetime, timezone from cryptography import x509 from cryptography.hazmat.primitives import hashes from cryptography.hazmat.primitives.asymmetric import padding from asn1crypto import cms, x509 as asn1_x509 def guid_to_bytes(g): """Convert GUID string to EFI little-endian byte order""" u = uuid.UUID(g) return struct.pack("<IHH8s", u.time_low, u.time_mid, u.time_hi_version, u.bytes[8:]) def utf16le_no_null(s): return s.encode("utf-16le") def parse_authentication_2(data): efi_time = data[:16] cert_hdr = data[16:16+24] length, revision, cert_type = struct.unpack("<IHH", cert_hdr[:8]) cert_guid = uuid.UUID(bytes_le = cert_hdr[8:24]) cert_data = data[16+24:16+length] payload_offset = 16 + length payload = data[payload_offset:] return efi_time, cert_data, payload def build_signed_data(variable_name, vendor_guid, attributes, efi_time, variable_payload): buf = b"" buf += utf16le_no_null(variable_name) buf += guid_to_bytes(vendor_guid) buf += struct.pack("<I", attributes) buf += efi_time buf += variable_payload return buf def load_pkcs7_signed_data(pkcs7_der): try: ci = cms.ContentInfo.load(pkcs7_der) if ci['content_type'].native != 'signed_data': print(f"ERROR: PKCS#7 ContentType is set to '{ci['content_type'].native}'. UEFI specs requires 'signed_data'.") return None else: print("WARNING: PKCS#7 ContentType is set, but a longstanding EDK2 bug may lead some platforms to reject it!") print("For more on this, see https://github.com/tianocore/edk2/commit/37d3eb026a766b2405daae47e02094c2ec248646.") return ci['content'] except Exception: # Bare content. *NOT* actually specs-compliant (at least for UEFI v2.3.1), but due to # an implementation bug in EDK2's VerifyTimeBasedPayload(), became de-facto standard, # especially as Microsoft, who did notice the bug, but never bothered to report it to # the EDK2, *like the good UEFI Secure Boot stewards they are*, dropped ContentType # from all the DBX updates they published... sd = cms.SignedData.load(pkcs7_der) # Wrap it to normalize handling ci = cms.ContentInfo({ 'content_type': 'signed_data', 'content': sd }) return ci['content'] def validate_uefi_variable(variable_blob, variable_name, vendor_guid, attributes): efi_time, pkcs7, variable_payload = parse_authentication_2(variable_blob) signed_data = build_signed_data(variable_name, vendor_guid, attributes, efi_time, variable_payload) try: signed_data_obj = load_pkcs7_signed_data(pkcs7) signer = signed_data_obj['signer_infos'][0] except Exception: return # Extract signer certificate from embedded certs certs = [ cert.chosen for cert in signed_data_obj['certificates'] if isinstance(cert.chosen, asn1_x509.Certificate) ] # Match signer by serial number serial = signer['sid'].native['serial_number'] signer_cert = next(c for c in certs if c.serial_number == serial) # Load with cryptography cert = x509.load_der_x509_certificate(signer_cert.dump()) pubkey = cert.public_key() digest_algo = signer['digest_algorithm']['algorithm'].native msg = "ERROR: Signature is INVALID!" if digest_algo == 'sha256': hash_alg = hashes.SHA256() signature = signer['signature'].native try: pubkey.verify(signature, signed_data, padding.PKCS1v15(), hash_alg) msg = "Signature is valid" except Exception: pass else: msg = f"Signature uses invalid algorithm: {digest_algo}" print("Signer cert subject:", cert.subject) print("Signer cert issuer :", cert.issuer) print("Signer serial num :", cert.serial_number) print(msg) if __name__ == "__main__": ap = argparse.ArgumentParser() ap.add_argument("file", help="signed authvar") args = vars(ap.parse_args()) if re.search('PK', args['file'], re.IGNORECASE): var_guid = "8be4df61-93ca-11d2-aa0d-00e098032b8c" var_name = "PK" var_attr = 0x27 # NV_BS_RT_AT elif re.search('KEK', args['file'], re.IGNORECASE): var_guid = "8be4df61-93ca-11d2-aa0d-00e098032b8c" var_name = "KEK" var_attr = 0x67 # NV_BS_RT_AT_AP elif re.search('DBX', args['file'], re.IGNORECASE): var_guid = "d719b2cb-3d3a-4596-a3bc-dad00e67656f" var_name = "dbx" var_attr = 0x67 # NV_BS_RT_AT_AP elif re.search('DB', args['file'], re.IGNORECASE): var_guid = "d719b2cb-3d3a-4596-a3bc-dad00e67656f" var_name = "db" var_attr = 0x67 # NV_BS_RT_AT_AP else: print(f"'{args['file']}' is either missing a Secure Boot variable identifier (PK, KEK, DB, DBX)") print(f"in its name, or is not one of the Secure Boot variables we support for validation.") sys.exit(1) with open(args['file'], "rb") as f: variable_blob = f.read() print(f"Detected '{var_name}' - Using GUID: {var_guid} and ATTRS: {var_attr:#0x}") validate_uefi_variable( variable_blob=variable_blob, variable_name=var_name, vendor_guid=var_guid, attributes=var_attr )









