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 <pete@akeo.ie> - 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
)