From 28fffb1d8d1ca5e4152fe888f4e7bf168519c9b2 Mon Sep 17 00:00:00 2001 From: Jeremi Piotrowski Date: Thu, 19 Feb 2026 11:54:55 +0100 Subject: [PATCH] build_library: pcr: simplify authenticode hash computation --- build_library/precompute_pcr.py | 91 +++++---------------------------- 1 file changed, 12 insertions(+), 79 deletions(-) diff --git a/build_library/precompute_pcr.py b/build_library/precompute_pcr.py index 5ee17cb072..f9617b71c2 100755 --- a/build_library/precompute_pcr.py +++ b/build_library/precompute_pcr.py @@ -50,95 +50,28 @@ PCR measurement details (SHA-256): import argparse import hashlib import json -import struct +import subprocess import sys # --------------------------------------------------------------------------- -# PE Authenticode hash (Microsoft spec: Windows Authenticode PE Signature) +# PE Authenticode hash via pesign(1) # Used by UEFI firmware to measure EFI binaries into PCR 4. # --------------------------------------------------------------------------- def pe_authenticode_hash(filepath, hash_algo='sha256'): - """Compute the PE Authenticode hash of an EFI binary. + """Compute the PE Authenticode hash of an EFI binary using pesign(1). - This hashes the PE file contents excluding the CheckSum field, - the Certificate Table directory entry, and the Certificate Table data, - matching UEFI firmware behavior for EV_EFI_BOOT_SERVICES_APPLICATION. + This invokes 'pesign --hash' which computes the hash per the + Microsoft PE Authenticode spec (excluding CheckSum, Certificate Table + directory entry, and Certificate Table data), matching UEFI firmware + behavior for EV_EFI_BOOT_SERVICES_APPLICATION measurements. """ - with open(filepath, 'rb') as f: - data = f.read() - - # DOS header: e_lfanew at offset 0x3c gives PE signature offset - pe_offset = struct.unpack_from(' 0: - sections.append((raw_ptr, raw_size)) - sections.sort(key=lambda s: s[0]) - - sum_of_bytes_hashed = size_of_headers - for ptr, size in sections: - h.update(data[ptr:ptr + size]) - sum_of_bytes_hashed += size - - # 7. Hash any extra data between sections and certificate table - file_size = len(data) - extra_end = file_size - if cert_table_size > 0: - extra_end = cert_table_va - if sum_of_bytes_hashed < extra_end: - h.update(data[sum_of_bytes_hashed:extra_end]) - - return h.hexdigest() + result = subprocess.run( + ['pesign', '-h', '-i', filepath, '-d', hash_algo], + capture_output=True, text=True, check=True) + # Output format: "hash: \n" + return result.stdout.strip().split(': ', 1)[1] # ---------------------------------------------------------------------------