You are not logged in.

#1 2025-05-29 22:54:15

Snowflake2
Member
Registered: 2025-05-27
Posts: 2

Unknown bzImage hash creates digest extending PCR 4 in TPM 2 eventlog

Hello,
I hope this is the right place to ask this question
I'm trying to understand and replicate the eventlog in order to predict the values in some PCR's when I change bootloader or UKI. I have most of it figured out but a particular digest PCR 4 is stumping me. I'm using efibootguard and it boots a UKI I created using systemd-stub with the following code

objcopy \
    --add-section .osrel=/etc/os-release --change-section-vma .osrel=0x20000 \
    --add-section .cmdline=<(echo "$CMDLINE") --change-section-vma .cmdline=0x30000 \
    --add-section .linux="$KERNEL" --change-section-vma .linux=0x2000000 \
    --add-section .initrd="$INITRD" --change-section-vma .initrd=0x3000000 \
    /usr/lib/systemd/boot/efi/linuxx64.efi.stub \
    "vmlinuz-linux.efi"

Looking only at PCR 4 and only the part that interests us gives us the following eventlog


- EventNum: 30
  PCRIndex: 4
  EventType: EV_EFI_ACTION
  DigestCount: 1
  Digests:
  - AlgorithmId: sha256
    Digest: "3d6772b4f84ed47595d72a2c4c5ffd15f5bb72c7507fe26f2aaee2c69d5633ba"
  EventSize: 40
  Event: |-
    Calling EFI Application from Boot Option
- EventNum: 35
  PCRIndex: 4
  EventType: EV_SEPARATOR
  DigestCount: 1
  Digests:
  - AlgorithmId: sha256
    Digest: "df3f619804a92fdb4057192dc43dd748ea778adc52bc498ce80524c014b81119"
  EventSize: 4
  Event: "00000000"
- EventNum: 40
  PCRIndex: 4
  EventType: EV_EFI_BOOT_SERVICES_APPLICATION
  DigestCount: 1
  Digests:
  - AlgorithmId: sha256
    Digest: "1c708c78b5ecc2c73b9f2bacbb86eb3e5b92816a860d0b732417eb96034307db"
  EventSize: 158
  Event:
    ImageLocationInMemory: 0x601b3018
    ImageLengthInMemory: 76534
    ImageLinkTimeAddress: 0x0
    LengthOfDevicePath: 126
    DevicePath: '02010c00d041030a0000000001010600000e0317100001000000002538b83104455a04012a0001000000000800000000000000f81f00000000003e0b87300c911949951f3fc8d59ed0ea020204042e004500460049005c0062006f006f0074005c0062006f006f0074007800360034002e0065006600690000007fff0400'
- EventNum: 41
  PCRIndex: 4
  EventType: EV_EFI_BOOT_SERVICES_APPLICATION
  DigestCount: 1
  Digests:
  - AlgorithmId: sha256
    Digest: "d36d6b468d295869a289bd50eb2879b003fee885c570eb21e66b965c4bf30c57"
  EventSize: 152
  Event:
    ImageLocationInMemory: 0x57df4018
    ImageLengthInMemory: 109086049
    ImageLinkTimeAddress: 0x0
    LengthOfDevicePath: 120
    DevicePath: '02010c00d041030a0000000001010600000e0317100001000000002538b83104455a04012a0002000000000020000000000000002000000000004c30f73395ecb14b93844706078bbc9d02020404280076006d006c0069006e0075007a002d006c0069006e00750078002e0065006600690000007fff0400'
--
- EventNum: 50
  PCRIndex: 4
  EventType: EV_EFI_BOOT_SERVICES_APPLICATION
  DigestCount: 1
  Digests:
  - AlgorithmId: sha256
    Digest: "e319440ccb3e7ff03c0326ed34244dbd3dbf1940dff6d966e06d23aa5ec5fa3b"
  EventSize: 56
  Event:
    ImageLocationInMemory: 0x49ddb000
    ImageLengthInMemory: 8193984
    ImageLinkTimeAddress: 0x0
    LengthOfDevicePath: 24
    DevicePath: '04031400f8d1c555cd04b5468a20e56cbb3052d07fff0400'

The digest I'm having problems with is the last one (EventNum 50). With the help of the EFI specs (TCG EFI Platform Specification page 25 ) that say "The measuring entity MUST measure normalized code for all EFI applications into PCR [4]"  as well as section 8.2.4 Measuring OS Boot Events of the TCG PC Client Platform Firmware Profile Specification, I was able to understand what is happening here (also using the ImageLengthInMemory and DevicePath):
EventNum 30 => mandatory EV_EFI_ACTION event, digest of "Calling EFI Application from Boot Option"
EventNum 35 => mandatory EV_SEPARATOR once boot device has been selected
EventNum 40 => measurement of efibootguard.efi
EventNum 41 => measurement of  vmlinuz-linux.efi (chosen by efibootguard)
EventNum 50 => measurement of the .linux section of the vmlinuz-linux.efi

Now unfortunately these last 3 measurements are not simply sha256 sums of what they measure (a consequence of the "normalized code" mentioned above I suspect). The way these measurements must be done is clearly defined for PE/COFF objects, using the 2008 Windows Authenticode Portable Executable Signature Format (I would provide a link but it's both a docx and not that relevant). Since both efi are PE/COFF, we can recreate the digest easily in python with the LIEF library and the following code

import lief
pe = lief.parse(efi_file_path)
print(pe.authentihash(lief.PE.ALGORITHMS.SHA_256).hex())

The problem is the last measurement (EventNum 50). The .linux of the UKI has is a bzImage (full output of file: Linux kernel x86 boot executable bzImage, version 6.1.0-35-amd64 (debian-kernel@lists.debian.org) #1 SMP PREEMPT_DYNAMIC Debian 6.1.137-1 (2025-05-07), RO-rootFS, swap_dev 0X7, Normal VGA). I have been unable to find how this hashing/ measurement is done in the case of a bzImage and also been unable to recreate the same digest from the given file.

You can download the 7.9MB .linux part of the UKI (extracted via objcopy -O binary --only-section=.linux ) here: https://www.swisstransfer.com/d/57ba04d … 3a3916723f (editted for a link that should last a month)

Below you have a more complete eventlog where you can see, amongst other things the UKI being measured into PCR 11 (events 42 to 49).

- EventNum: 30
  PCRIndex: 4
  EventType: EV_EFI_ACTION
  DigestCount: 1
  Digests:
  - AlgorithmId: sha256
    Digest: "3d6772b4f84ed47595d72a2c4c5ffd15f5bb72c7507fe26f2aaee2c69d5633ba"
  EventSize: 40
  Event: |-
    Calling EFI Application from Boot Option
- EventNum: 31
  PCRIndex: 0
  EventType: EV_SEPARATOR
  DigestCount: 1
  Digests:
  - AlgorithmId: sha256
    Digest: "df3f619804a92fdb4057192dc43dd748ea778adc52bc498ce80524c014b81119"
  EventSize: 4
  Event: "00000000"
- EventNum: 32
  PCRIndex: 1
  EventType: EV_SEPARATOR
  DigestCount: 1
  Digests:
  - AlgorithmId: sha256
    Digest: "df3f619804a92fdb4057192dc43dd748ea778adc52bc498ce80524c014b81119"
  EventSize: 4
  Event: "00000000"
- EventNum: 33
  PCRIndex: 2
  EventType: EV_SEPARATOR
  DigestCount: 1
  Digests:
  - AlgorithmId: sha256
    Digest: "df3f619804a92fdb4057192dc43dd748ea778adc52bc498ce80524c014b81119"
  EventSize: 4
  Event: "00000000"
- EventNum: 34
  PCRIndex: 3
  EventType: EV_SEPARATOR
  DigestCount: 1
  Digests:
  - AlgorithmId: sha256
    Digest: "df3f619804a92fdb4057192dc43dd748ea778adc52bc498ce80524c014b81119"
  EventSize: 4
  Event: "00000000"
- EventNum: 35
  PCRIndex: 4
  EventType: EV_SEPARATOR
  DigestCount: 1
  Digests:
  - AlgorithmId: sha256
    Digest: "df3f619804a92fdb4057192dc43dd748ea778adc52bc498ce80524c014b81119"
  EventSize: 4
  Event: "00000000"
- EventNum: 36
  PCRIndex: 5
  EventType: EV_SEPARATOR
  DigestCount: 1
  Digests:
  - AlgorithmId: sha256
    Digest: "df3f619804a92fdb4057192dc43dd748ea778adc52bc498ce80524c014b81119"
  EventSize: 4
  Event: "00000000"
- EventNum: 37
  PCRIndex: 6
  EventType: EV_SEPARATOR
  DigestCount: 1
  Digests:
  - AlgorithmId: sha256
    Digest: "df3f619804a92fdb4057192dc43dd748ea778adc52bc498ce80524c014b81119"
  EventSize: 4
  Event: "00000000"
- EventNum: 38
  PCRIndex: 1
  EventType: EV_EFI_HANDOFF_TABLES
  DigestCount: 1
  Digests:
  - AlgorithmId: sha256
    Digest: "a9936fe33a4349e10f203d07c546c57bedb1b98b56cb9d54e26566f69193a7d1"
  EventSize: 32
  Event: "0100000000000000312d9deb882dd3119a160090273fc14d0030536c00000000"
- EventNum: 39
  PCRIndex: 5
  EventType: EV_EFI_GPT_EVENT
  DigestCount: 1
  Digests:
  - AlgorithmId: sha256
    Digest: "cbe676d6255509d4cfab0ee6f8170b01706c4a734d16e878daf642c8c9876169"
  EventSize: 868
  Event: "4546492050415254000001005c0000006047f1b4000000000100000000000000af5277ee0000000022000000000000008e5277ee00000000d81d19d8af9e16419b47e82d7a9ad0d702000000000000008000000080000000444dfb09060000000000000028732ac11ff8d211ba4b00a0c93ec93b3e0b87300c911949951f3fc8d59ed0ea0008000000000000ffff1f000000000000000000000000007000720069006d0061007200790000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a2a0d0ebe5b9334487c068b6b72699c74c30f73395ecb14b93844706078bbc9d0000200000000000ffff3f000000000000000000000000007000720069006d0061007200790000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a2a0d0ebe5b9334487c068b6b72699c7411107ff40e1a74d9b7e152c9f0a64840000400000000000ffff5f000000000000000000000000007000720069006d0061007200790000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000af3dc60f838472478e793d69d8477de49455873b2f780f4e9e9f9478efc9c7c90000600000000000ffff9f060000000000000000000000007000720069006d0061007200790000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000af3dc60f838472478e793d69d8477de471bf3277bc88624ab901c0f8444498fe0000a00600000000ffffdf0c0000000000000000000000007000720069006d0061007200790000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000af3dc60f838472478e793d69d8477de4a5d75e4dc633894bba8ef76768d87f6e0000e00c00000000ff4f77ee0000000000000000000000007000720069006d0061007200790000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
- EventNum: 40
  PCRIndex: 4
  EventType: EV_EFI_BOOT_SERVICES_APPLICATION
  DigestCount: 1
  Digests:
  - AlgorithmId: sha256
    Digest: "1c708c78b5ecc2c73b9f2bacbb86eb3e5b92816a860d0b732417eb96034307db"
  EventSize: 158
  Event:
    ImageLocationInMemory: 0x601b3018
    ImageLengthInMemory: 76534
    ImageLinkTimeAddress: 0x0
    LengthOfDevicePath: 126
    DevicePath: '02010c00d041030a0000000001010600000e0317100001000000002538b83104455a04012a0001000000000800000000000000f81f00000000003e0b87300c911949951f3fc8d59ed0ea020204042e004500460049005c0062006f006f0074005c0062006f006f0074007800360034002e0065006600690000007fff0400'
- EventNum: 41
  PCRIndex: 4
  EventType: EV_EFI_BOOT_SERVICES_APPLICATION
  DigestCount: 1
  Digests:
  - AlgorithmId: sha256
    Digest: "d36d6b468d295869a289bd50eb2879b003fee885c570eb21e66b965c4bf30c57"
  EventSize: 152
  Event:
    ImageLocationInMemory: 0x57df4018
    ImageLengthInMemory: 109086049
    ImageLinkTimeAddress: 0x0
    LengthOfDevicePath: 120
    DevicePath: '02010c00d041030a0000000001010600000e0317100001000000002538b83104455a04012a0002000000000020000000000000002000000000004c30f73395ecb14b93844706078bbc9d02020404280076006d006c0069006e0075007a002d006c0069006e00750078002e0065006600690000007fff0400'
- EventNum: 42
  PCRIndex: 11
  EventType: EV_IPL
  DigestCount: 1
  Digests:
  - AlgorithmId: sha256
    Digest: "0da293e37ad5511c59be47993769aacb91b243f7d010288e118dc90e95aaef5a"
  EventSize: 14
  Event:
    String: |-
      ".\0l\0i\0n\0u\0x\0\0\0"
- EventNum: 43
  PCRIndex: 11
  EventType: EV_IPL
  DigestCount: 1
  Digests:
  - AlgorithmId: sha256
    Digest: "cf027b373e0b76776d4c8ee64959dcf25034a0809032b46430db34ed438cb03b"
  EventSize: 14
  Event:
    String: |-
      ".\0l\0i\0n\0u\0x\0\0\0"
- EventNum: 44
  PCRIndex: 11
  EventType: EV_IPL
  DigestCount: 1
  Digests:
  - AlgorithmId: sha256
    Digest: "3fb9e4e3cc810d4326b5c13cef18aee1f9df8c5f4f7f5b96665724fa3b846e08"
  EventSize: 14
  Event:
    String: |-
      ".\0o\0s\0r\0e\0l\0\0\0"
- EventNum: 45
  PCRIndex: 11
  EventType: EV_IPL
  DigestCount: 1
  Digests:
  - AlgorithmId: sha256
    Digest: "59a77b5f2666d9c85c489bd1911a6eebbd91ef22fe48b90a3b75f1b21f3844d4"
  EventSize: 14
  Event:
    String: |-
      ".\0o\0s\0r\0e\0l\0\0\0"
- EventNum: 46
  PCRIndex: 11
  EventType: EV_IPL
  DigestCount: 1
  Digests:
  - AlgorithmId: sha256
    Digest: "461203a89f23e36c3a4dc817f905b00484d2cf7e7d9376f13df91c41d84abe46"
  EventSize: 18
  Event:
    String: |-
      ".\0c\0m\0d\0l\0i\0n\0e\0\0\0"
- EventNum: 47
  PCRIndex: 11
  EventType: EV_IPL
  DigestCount: 1
  Digests:
  - AlgorithmId: sha256
    Digest: "59f2c6f6909a714d81128eb0a3a4a5fbfa31c617b369b9f430957cfec62cf485"
  EventSize: 18
  Event:
    String: |-
      ".\0c\0m\0d\0l\0i\0n\0e\0\0\0"
- EventNum: 48
  PCRIndex: 11
  EventType: EV_IPL
  DigestCount: 1
  Digests:
  - AlgorithmId: sha256
    Digest: "15ee37e75f1e8d42080e91fdbbd2560780918c81fe3687ae6d15c472bbdaac75"
  EventSize: 16
  Event:
    String: |-
      ".\0i\0n\0i\0t\0r\0d\0\0\0"
- EventNum: 49
  PCRIndex: 11
  EventType: EV_IPL
  DigestCount: 1
  Digests:
  - AlgorithmId: sha256
    Digest: "b61511a20e34ae815cf180ebdb3d22bc83339be1cc366a56325e72a9ef495892"
  EventSize: 16
  Event:
    String: |-
      ".\0i\0n\0i\0t\0r\0d\0\0\0"
- EventNum: 50
  PCRIndex: 4
  EventType: EV_EFI_BOOT_SERVICES_APPLICATION
  DigestCount: 1
  Digests:
  - AlgorithmId: sha256
    Digest: "e319440ccb3e7ff03c0326ed34244dbd3dbf1940dff6d966e06d23aa5ec5fa3b"
  EventSize: 56
  Event:
    ImageLocationInMemory: 0x49ddb000
    ImageLengthInMemory: 8193984
    ImageLinkTimeAddress: 0x0
    LengthOfDevicePath: 24
    DevicePath: '04031400f8d1c555cd04b5468a20e56cbb3052d07fff0400'
- EventNum: 51
  PCRIndex: 9
  EventType: EV_EVENT_TAG
  DigestCount: 1
  Digests:
  - AlgorithmId: sha256
    Digest: "8a1217382818e90a967c14115bb2534cce1515c70afb79f2868738a83a1fc08f"
  EventSize: 34
  Event: "ed223b8f1a0000004c4f414445445f494d4147453a3a4c6f61644f7074696f6e7300"
- EventNum: 52
  PCRIndex: 9
  EventType: EV_EVENT_TAG
  DigestCount: 1
  Digests:
  - AlgorithmId: sha256
    Digest: "b61511a20e34ae815cf180ebdb3d22bc83339be1cc366a56325e72a9ef495892"
  EventSize: 21
  Event: "ec223b8f0d0000004c696e757820696e6974726400"
- EventNum: 53
  PCRIndex: 5
  EventType: EV_EFI_ACTION
  DigestCount: 1
  Digests:
  - AlgorithmId: sha256
    Digest: "d8043d6b7b85ad358eb3b6ae6a873ab7ef23a26352c5dc4faa5aeedacf5eb41b"
  EventSize: 29
  Event: |-
    Exit Boot Services Invocation
- EventNum: 54
  PCRIndex: 5
  EventType: EV_EFI_ACTION
  DigestCount: 1
  Digests:
  - AlgorithmId: sha256
    Digest: "b54f7542cbd872a81a9d9dea839b2b8d747c7ebd5ea6615c40f42f44a6dbeba0"
  EventSize: 40
  Event: |-
    Exit Boot Services Returned with Success

Any help is much appreciated and I'm more then happy to give additional information

Last edited by Snowflake2 (2025-05-30 13:57:36)

Offline

#2 2026-01-26 04:40:55

kalamoo
Member
Registered: 2026-01-26
Posts: 2

Re: Unknown bzImage hash creates digest extending PCR 4 in TPM 2 eventlog

Hi, did you find a solution for it?

I'm running into a similar issue trying to reproduce an event's measurement in PCR[4]. I'm booting a VM via QEMU using edk2-ovmf (2024.02-2ubuntu0.7) and passing the bzImage via -kernel.

I cannot match the digest in the event log (see below, after being parsed by tpm2_eventlog). I’ve tried both a direct sha256 hash of the bzImage and using the LIEF Authenticode API, but neither matches the digest below.

- EventNum: 15
  PCRIndex: 4
  EventType: EV_EFI_BOOT_SERVICES_APPLICATION
  DigestCount: 1
  Digests:
  - AlgorithmId: sha256
    Digest: "2529b5ed9a550b358753d71dfcac1d7306e69a884ce4203d47200ce12c1b10d1"
  EventSize: 74
  Event:
    ImageLocationInMemory: 0x1bc84018
    ImageLengthInMemory: 12579328
    ImageLinkTimeAddress: 0x0
    LengthOfDevicePath: 42
    DevicePath: '0403140072f728144ab61e44b8c39ebdd7f893c7040412006b00650072006e0065006c0000007fff0400'

I suspect the Authenticode implementations (LIEF's and OVMF's) might differ because the Linux bzImage isn't a "standard" PE image compared to Windows binaries. In fact, LIEF throws the following three warnings when processing the bzImage:

The value of the SizeOfOptionalHeader in the PE header seems corrupted 0xa0
Unable to find the section associated with DEBUG_DIR
The parsing of delay imports has failed or is incomplete ('read_error')

Last edited by kalamoo (2026-02-05 14:35:56)

Offline

#3 2026-02-05 14:35:43

kalamoo
Member
Registered: 2026-01-26
Posts: 2

Re: Unknown bzImage hash creates digest extending PCR 4 in TPM 2 eventlog

Hi,

I figured out what cause the issue. It's not becuase how LIEF and OVMF calculate the authenticode hash value, in fact, both of them strictly follow the spec (for LIEF, I modified a bit in its source code an recompile it to let it support varied-length data directories like bzImage, see LIEF/tree/varied-data-dir-length ). It's because when the bzImage file is loaded, part of its content are modified on the fly.

I found this when I tried to debug the ovmf during boot process, and dump the content that will be measured. I found the dumped content differ from the original bzImage file by 12 bytes (shown below).

According to the Linux's real mode header doc , what changed are: bootloader's identifier, initramfs's info (addr and size), and cmd line's addr.

Since I'm booting a VM via QEMU using edk2-ovmf (re-built for debugging) and passing the bzImage via -kernel, I think it's QEMU who modifies these fields accordingly on the fly. After I changed only these 12 bytes on the original bzImage file, its authenticode hash matches with what I see in the event log (i.e., 2529...10d1).

This is the original bzImage's snippet:

00000200  eb 6a 48 64 72 53 0f 02  00 00 00 00 00 10 00 43  |.jHdrS.........C| 
00000210  00 01 00 80 00 00 10 00  00 00 00 00 00 00 00 00  |................|
00000220  00 00 00 00 e0 5b 00 00  00 00 00 00 ff ff ff 7f  |.....[..........|

This is the dumped content:

00000200  eb 6a 48 64 72 53 0f 02  00 00 00 00 00 10 00 43  |.jHdrS.........C|
00000210  b0 81 00 80 00 00 10 00  00 b0 d6 1e a0 c5 26 01  |..............&.| 
00000220  00 00 00 00 00 fe 00 00  00 00 02 00 ff ff ff 7f  |................| 

Last edited by kalamoo (2026-02-05 14:39:26)

Offline

Board footer

Powered by FluxBB