# BitLocker, the TPM and the UEFI boot chain

Tracing TPM key release, PCRs, PIN hashing, EFI update servicing and anti-rollback checks—and assessing the security boundaries of Windows' BitLocker boot chain.

Author: Berkan YILDIZ
Published: 2026-10-15
Tags: BitLocker, TPM 2.0, UEFI, Secure Boot, Windows internals, Reverse engineering
Canonical: <https://blog.berkan.fr/bitlocker-tpm-boot-chain>


BitLocker has to unlock the Windows volume before it can load the operating system from that volume. On a UEFI system, the code making that decision initially runs from an unencrypted EFI System Partition (ESP). The security boundary therefore depends on more than sector encryption: firmware authorizes boot code, measured boot records selected state, and a TPM policy controls when protected key material becomes available.

This article follows that boundary through Windows Boot Manager and the Windows OS loader. The interesting implementation details are the separation between the volume keys and the TPM object, the policy session preceding `TPM2_Unseal`, the use of PCR 11 to close the boot-time release window, and the in-memory keyring used by successive boot applications.

The firmware side of this chain starts earlier. [The TPM initialization analysis](/uefi-tpm-initialization) covers EDK II's device selection, startup, PCR banks and UEFI measurement services.

## Key findings

- **The sealed object picks its own hash.** The TPM 2.0 unseal path takes the policy session's hash and the PCR selection's bank from the object's `nameAlg`, not from a fixed SHA-256. [More](#loading-the-sealed-object-and-satisfying-its-policy)
- **The PIN is SHA-256 over UTF-16LE.** The typed PIN is hashed without its terminator into a 32-byte datum. Separately, the unseal callback truncates a SHA-256 to 20 bytes: an authorization size, not a SHA-1 PCR bank. [More](#pin-hashing-and-tpm-authorization)
- **The cap check returns 1 when the PCR is not capped.** `SipaCheckBitLockerPcrCapped` reports a bank still at zero; the cap then extends PCR 11 with a four-byte `EV_COMPACT_HASH` event, or PCR 22 when an environment flag is set. [More](#pcr-11-closes-the-unseal-window)
- **BCD options are hashed one by one.** The boot manager validates individual security-relevant options with SHA-256 rather than hashing the BCD store. [More](#bcd-validation-and-the-recipient-of-the-key)
- **Keys reach winload through boot option `0x15000042`.** It carries the physical address of a validated keyring, so the OS loader can use the cached keys without unsealing again. [More](#the-os-loader-inherits-usable-key-material)
- **The boot manager enforces an SVN floor of 7.0.** It shuts the machine down when `dbx` records a higher major version; with no matching record, the floor is zero. [More](#this-boot-manager-already-enforces-an-svn-floor)

None of these is a vulnerability. The last part of the article proposes hardening around updates, suspension and key lifetime.

## Targets and evidence

The binary analysis uses two x64 images:

| Image | File version | Size | Preferred image base |
| --- | --- | --- | --- |
| `bootmgfw.efi` | `10.0.26100.30215` | 2,830,240 bytes | `0x10000000` |
| `winload.efi` | `10.0.26100.8457` | 3,351,712 bytes | `0x180000000` |

```text Whole-file SHA-256 · sample identification
bootmgfw.efi
8c15458fa832863f51b9756cf6481c012e66c7f9be84574315a133c00a9e23af

winload.efi
e46cec4fe31d30a6433292a41d712528bbab3514f9c3506e8cdded56de2b1fe6
```

These are separate build snapshots, not a matched pair captured during one boot. Addresses below are **relative virtual addresses (RVAs)** in the named image. Function names are navigation aids from the analyzed databases; the findings rely on instructions, arguments and control flow.

Code listings are reduced reconstructions from assembly, with descriptive local names. Decompiler output was checked against disassembly: incorrect non-returning annotations on helper functions otherwise hid reachable code in several FVE routines. Everything here is static. No target machine's protector, TPM traffic or measured-boot log was captured, so the article describes the paths these binaries implement, not the configuration a given device uses. Configuration defaults come from Microsoft's documentation rather than from the samples, and the consequences described for tampering and updates were not reproduced on hardware. Update orchestration is described from Microsoft's servicing and protector-management contracts; the Windows Update engine and a live update transaction were not traced.

Firmware comparisons use [EDK II commit `02c1141a0e5b5c958630e81ac6ebb4b03c1e836f`][edk-revision]. Microsoft documentation supplies the supported configuration defaults; the TPM specification supplies command semantics. EDK II illustrates a reference firmware implementation, not the provenance of the Windows machine's firmware.

## The ESP is the first trust boundary

The ESP remains unencrypted. Firmware needs to read its FAT32 filesystem and load a boot application before the Windows volume has been unlocked. A typical Windows path places `bootmgfw.efi` and the BCD store under `\EFI\Microsoft\Boot` on that partition. The OS loader, normally `\Windows\System32\winload.efi`, resides on the Windows volume. Microsoft's [partition requirements][planning] describe this separation.

Three mechanisms cover different parts of the resulting exposure:

| Mechanism | Decision it makes |
| --- | --- |
| Secure Boot | Whether an EFI image is authorized to execute under the firmware's trust and revocation policy. |
| Measured boot | Which measured events have occurred, in which order, and into which PCR banks. |
| BitLocker TPM protector | Whether the TPM may release the secret needed by this protector in the current authorization and PCR state. |

An offline writer can still modify or delete ESP files. The intended result for an unauthorized executable is rejection by the boot trust chain; a changed selected measurement can instead prevent automatic key release. Deleting a required file can simply stop boot. None of these mechanisms supplies general filesystem write protection for FAT32.

![BitLocker boot trust and key flow. The unencrypted ESP supplies an authorized boot manager. Firmware measurements feed TPM policy. Successful authorization releases protector material used to recover the VMK and FVEK, allowing access to the encrypted Windows volume and a keyring handoff to winload.](/images/blog/bitlocker-tpm-boot-chain.svg)

This distinction matters when interpreting a tampering experiment. Being able to write a boot file does not mean modified code can run, and a boot that survives an unrelated ESP change does not mean every byte of the partition was authenticated.

## The TPM protects a key-release operation

BitLocker's key hierarchy separates bulk encryption from access to the encryption keys:

```text Conceptual key hierarchy · individual protector layouts vary
TPM policy + optional startup authentication
                |
                v
       TPM-protected secret / protector processing
                |
                v
       Volume Master Key (VMK)
                |
                v
       Full Volume Encryption Key (FVEK)
                |
                v
       Encrypted volume sectors
```

The FVEK handles volume data; the VMK protects the FVEK. Configured protectors provide different ways to obtain the VMK. Multiple protectors can coexist, including a recovery path independent of the TPM. Wrapped material is represented in the volume's metadata. This hierarchy is documented in Microsoft's [BitLocker key-management FAQ][key-management].

The TPM is therefore outside the ordinary sector read/write path. It authorizes release of a relatively small secret. Boot code can then build the cryptographic context needed to read the encrypted filesystem. How the sealed payload becomes the VMK depends on the protector's metadata format; the payload is not necessarily the VMK itself.

The metadata parser in this boot-manager sample makes that distinction concrete. `FveDatumGetVmk` at RVA `0x1D27B8` walks nested datums and dispatches according to their types. Its paths include key stretching, `FveDatumTpmEncBlobUnbox`, AES-CCM unboxing and composite-key processing. Enhanced-PIN, enhanced-crypto and PBKDF2-related metadata can send processing through `FveVmkInfoProcess` instead.

`FveDatumTpmEncBlobUnbox` at `0x1D50FC` extracts a TPM blob and optional input-key data, invokes the configured unseal callback, validates the returned datum within its returned length, and duplicates that datum for its caller.

Another concrete example is `FveDatumVmkCompositeKey` at `0x1DAA60`: it requires two 32-byte key data segments, XORs them, and creates the resulting key datum.

## From boot manager to TPM commands

Before boot services end, the Windows boot environment can use the TPM interface already exposed by firmware. In the inspected boot manager, `BlTpmpAcquireProtocol` at `0x19DC60` locates handles, opens the selected protocol, checks capabilities through its interface, and retains the protocol pointer.

For the TPM 2.0 protocol path, `BlTpmpTreeSubmitCommand` at `0x19E0BC` checks the interface type and buffer lengths, calls `EfiTreeSubmitCommand`, and reads the big-endian response size from the TPM response header. The Windows `Tree` naming here is part of its firmware-interface wrapper. Underneath this boundary, firmware's TPM driver owns the platform-specific transport described in the preceding article.

The FVE path reaches that command layer through a callback and a TPM-version dispatcher:

```text Observed bootmgfw call path · intervening metadata processing omitted
FveDatumGetVmk
  FveDatumTpmEncBlobUnbox
    configured unseal callback: FvebUnsealCallback
      FveHashData
      TpmApiUnseal
        TPM 1.2: Tpm12ApiUnsealEx
        TPM 2.0: TpmW8ApiUnsealEx
```

`FvebUnsealCallback` is at `0x539A4`; `TpmApiUnseal` is at `0x225D10`. The latter selects the TPM 1.2 or TPM 2.0 implementation from the established TPM type. The TPM 2.0 implementation is analyzed below.

### Loading the sealed object and satisfying its policy

`TpmW8ApiUnsealEx`, at boot-manager RVA `0x227BE8`, parses serialized blob components with length checks, reads the public area of persistent parent handle `0x81000001` (the storage root key Windows persists), and constructs a `TPM2_Load` request for the protected object. The object is represented by externally stored blobs loaded under a TPM parent; it need not occupy a dedicated persistent TPM handle itself.

The policy branch is visible in the assembly as command-object construction followed by `TPMW8_COMMAND::Execute` calls:

```text Reduced TPM 2.0 policy branch · error handling and cleanup omitted
ReadPublic(parent = 0x81000001)
Load(parent, privateBlob, publicBlob)

if object does not allow the userWithAuth authorization route:
    create policy session using object.nameAlg
    PolicyAuthValue(session)

    if the parsed PCR-digest component is present:
        selection.hash = object.nameAlg
        selection.bitmap = parsed three-byte PCR bitmap
        PolicyPCR(session, parsedPcrDigest, selection)

Unseal(loadedObject, authorizationSession)
FlushContext(loadedObject)
```

The branch tests `userWithAuth`, bit `0x40` in the object attributes. The parsed public area's hash-algorithm field is copied both to the policy session's hash setting and to the PCR selection in this implementation. `TPMW8T_PUBLIC::Deserialize` at `0x230030` establishes the public-field layout; `TPMW8_SESSION::Create` at `0x22BBC4` passes the selected hash into session creation.

The loaded object's fields flow into the commands themselves: the session hash comes from the object's public area, not from a fixed SHA-256.

The TPM's [`PolicyPCR` semantics][tpm-commands] bind the session policy to a selected PCR digest and selection. `PolicyAuthValue` adds an authorization-value requirement. At `Unseal`, the TPM enforces the object's authorization rules. Host-side code may compare measured values first to choose a binding or explain a failure, but those comparisons do not substitute for TPM enforcement.

Boot manager contains that diagnostic layer too. `FvebpGetKeyFromTpmPV2AuthData` at `0x58C8C` extracts binding information and compares final PCR values through `FveTpmLibDoFinalPcrValuesMatch`, before falling through to key acquisition or mismatch processing. A recovery diagnosis must distinguish these software checks from the TPM's command response.

## PCR selection: platform identity and boot phase

For **native UEFI**, Microsoft's documented default profiles are `{0, 2, 4, 11}`, or `{7, 11}` when usable Secure Boot/PCR 7 binding is available. An explicit policy can change the selection. [Native UEFI validation policy][pcr-profile]

| PCR | Relevant measured state | Role in the documented profiles |
| --- | --- | --- |
| 0 | Core firmware executable code | Included in `{0,2,4,11}`. |
| 2 | Extended or pluggable executable code | Included in `{0,2,4,11}`. |
| 4 | Boot-manager image measurements | Included in `{0,2,4,11}`. |
| 7 | Secure Boot policy and authority state | Included in `{7,11}`. |
| 11 | BitLocker access-control state | Included in both. |

PCR 7 represents a different trust decision from an exact boot-image digest. Firmware measures Secure Boot state and policy variables, then records relevant image-authorization events. EDK II's [`Tcg2Dxe` implementation][edk-pcr7] measures Secure Boot configuration and authority information; its variable handling includes `SecureBoot`, `PK`, `KEK`, `db` and `dbx`, with additional handling for `dbt` when present.

Binding to that policy can permit an authorized boot-image update without requiring the previous image's exact PCR 4 history. This is a policy-based acceptance boundary: the signer and revocation state become particularly important. Microsoft's [OEM guidance][oem-bitlocker] describes the expected PCR 7 sequence and the authority constraints used for BitLocker binding.

Secure Boot being enabled does not by itself prove that a protector uses PCR 7. Extra authority measurements or other incompatibilities in the boot sequence can make PCR 7 binding unavailable, leading to the other UEFI profile. Microsoft's [PCR 7 troubleshooting guidance][pcr7-troubleshooting] documents this case. A profile of `{0,2,4,11}` alone is therefore insufficient evidence that Secure Boot was disabled.

### PCR 5 describes partition metadata

EDK II's [`Tcg2MeasureGptTable` path][edk-image-measurements] emits an `EV_EFI_GPT_EVENT` into PCR 5. The event contains the GPT header and valid partition entries. This measures partition metadata rather than recursively hashing the ESP filesystem.

The same library directs EFI applications to PCR 4, and boot-service/runtime drivers to PCR 2, before calling `HashLogExtendEvent` with the PE/COFF image flag. These are separate measurement categories.

PCR 5 is absent from both documented default profiles above. Leaving it out does not weaken image authorization or the validation of who receives the key; those checks happen elsewhere.

## Which hash: distinguish the operations

There is no single BitLocker hash. The relevant algorithms operate on different inputs and establish different properties.

| Operation | Algorithm or selection in scope |
| --- | --- |
| Windows PCR-bank continuation | Windows prefers SHA-256; SHA-1 fallback remains documented when prerequisites are unmet. |
| A PCR extension | The hash associated with that PCR bank. |
| The observed TPM 2.0 policy branch | Session hash and selected bank taken from the sealed object's `nameAlg`. |
| The observed PIN-to-datum helper | SHA-256 over the PIN's UTF-16 code units, excluding the terminator. |
| The observed unseal callback's authentication transformation | SHA-256 of supplied authentication material, truncated to the first 20 bytes. |
| The observed boot-option validation entries | SHA-256 over the individual option's data. |
| EFI image measurement | Structured PE/COFF hashing using the configured measurement algorithms. |
| Software volume encryption | AES in the volume's configured mode; a cipher rather than a hash. |

### A bank and an index identify a PCR

A SHA-1 PCR holds a 20-byte digest; a SHA-256 PCR holds 32 bytes. `(SHA-1, PCR 7)` and `(SHA-256, PCR 7)` are different registers. A measurement generally has two hashing steps:

```text Measurement and extension · H is the selected bank's hash
eventDigest = H(measuredByteStream)
PCRnew      = H(PCRold || eventDigest)
```

For a sequence, each extension depends on the previous value. Replacing a log file does not undo the TPM's extensions. Replaying the digest records can reconstruct the expected PCR value, while interpreting the event data explains what the measuring component says it measured.

Windows checks active banks, firmware support and measurement-log coverage before choosing its continuation bank. It prefers SHA-256, with documented SHA-1 fallback, and continues its boot measurements in one bank while capping unused active banks. `TPMActivePCRBanks` and `TPMDigestAlgID` under `HKLM\SYSTEM\CurrentControlSet\Control\IntegrityServices` describe different things: an active-bank bitmap versus the selected algorithm identifier. [Windows PCR-bank behavior][pcr-banks]

A TPM 2.0 policy session has its own hash algorithm. Conceptually, that is distinct from the algorithm identifiers carried by its PCR selection. The inspected `TpmW8ApiUnsealEx` branch uses the same object-derived value for both, although TPM 2.0 allows them to differ.

### A PE measurement is not a whole-file hash

EDK II's [`MeasurePeImageAndExtend`][edk-pe-hash] excludes the PE checksum and Certificate Table directory entry, processes nonempty sections in raw-file order, and excludes certificate content through its remaining-data calculation. Its hash router feeds the selected byte ranges to the registered algorithms allowed by `PcdTpm2HashMask`, builds a digest list, and calls `Tpm2PcrExtend`. [Hash router][edk-hash-router]

The whole-file SHA-256 values at the top of this article identify samples. They are not interchangeable with a PE image measurement, an Authenticode image digest or a final PCR value. Microsoft's [PE signature documentation][pe-signatures] describes the signature-hashing distinction.

Secure Boot can authorize an image through a trusted certificate or an allowed image hash, subject to revocation rules. UEFI 2.11 requires SHA-256 support for these operations, which remain separate from PCR-bank selection. [UEFI cryptographic requirements][uefi-crypto]

The OS loader has another independent selection point. In the `winload.efi` sample, `ImgpGetHashAlgorithmForScenario` at `0x198058` selects scenario/policy-dependent values `0x8004` or `0x800C`, the [CryptoAPI identifiers][alg-id] for SHA-1 and SHA-256. `ImgpLoadPEImage` at `0x194334` reaches `ImgpValidateImageHash` at `0x196D3C`.

## PIN hashing and TPM authorization

The startup PIN is an additional authorization factor for a TPM protector. It is distinct from the Windows account sign-in credential and from the volume's bulk-encryption key. TPM authorization also brings dictionary-attack controls into the failed-attempt path; it is not merely an offline comparison of a short PIN hash. [BitLocker preboot authentication][countermeasures]

The analyzed boot manager provides two useful, separate observations.

First, `FvebpGetKeyWithPin` at `0x56210` obtains the PIN through the boot UI and calls `FveDatumFromPin` at `0x1D22BC`. That helper counts 16-bit code units up to the null terminator, hashes exactly twice that count in bytes with SymCrypt SHA-256, and creates a 32-byte key datum:

```c FveDatumFromPin · reduced reconstruction
characterCount = CountUtf16CodeUnitsUntilNull(pin);
pinDigest = SHA256(pin, characterCount * sizeof(uint16_t));
pinDatum = CreateKeyDatum(0x2004, pinDigest, 32);
```

On this x64 path the byte stream is UTF-16LE without the terminating zero. The helper marks the datum according to the PIN mode. The resulting datum then enters protector processing; the hash itself is not the disk-encryption key.

Second, `FvebUnsealCallback` calls `FveHashData` at `0x1D5274` with an output length of `0x14`. The helper uses SHA-256, then copies the smaller of the requested length and 32 bytes. Thus this callback obtains:

```text Observed authentication transformation
callbackAuth = SHA256(suppliedAuthenticationMaterial)[0:20]
```

The material supplied to this callback has already passed through metadata processing, so BitLocker does not simply send the first 20 bytes of SHA-256 of the typed PIN: enhanced and composite protectors add processing between the two steps. In the `winload.efi` snapshot, the matching `FveHashData` helper at `0x1F52B4` also uses SHA-256 with an output-length-limited copy.

Crucially, **20 bytes here does not identify a SHA-1 PCR bank**. It identifies the requested size of an authentication transformation. The policy hash, selected PCR bank and PIN processing have separate data flows.

## PCR 11 closes the unseal window

PCR 11 introduces a temporal boundary. A protector can be usable during an intended boot phase and become unusable through that same PCR policy after the boot environment advances the register. This limits later software's ability to repeat the early release operation merely by possessing the sealed blob.

Boot-manager `SipInitializePhase0` at `0x188B34` selects `BitlockerCapPCR` as follows:

```c Reduced PCR-index selection
BitlockerCapPCR = (BlpEnvironmentState & 2) ? 22 : 11;
```

The ordinary branch uses PCR 11; the environment-dependent alternate uses PCR 22. Which boot environment sets that bit was not determined.

`SipaCheckBitLockerPcrCapped` at `0x18ABD0` examines supported active-bank bits and reads the selected cap PCR for algorithm identifiers `0x0004` and `0x000B`: SHA-1 and SHA-256. Its return convention deserves attention: it returns **1 when a checked bank still contains an all-zero digest**, and 0 after the checks find no such zero digest. Reading the function name alone would invite the opposite interpretation.

`SipaLogBitLockerCap` at `0x1899D4` uses that result. When capping is needed, it passes the DWORD value `16` through `SipEarlyExtendBitLockerCap` at `0x18AB90`, with event type `12` (`EV_COMPACT_HASH`) and data length 4. The selected callback routes the operation through the boot measurement interface; `BlTpmTreeExtendWithWriteThrough` at `0x19E8A0` contains the firmware `HashLogExtendEvent` calls.

```text Observed SIP cap event · successful ordinary-PCR branch
eventType = 12
eventData = DWORD(16)          // four bytes: 10 00 00 00
destination = BitlockerCapPCR // ordinarily 11

HashLogExtendEvent(destination, eventData)
```

For a bank whose previous PCR value is zero, the ordinary raw-event measurement gives `H(zeros || H(10 00 00 00))`. PCR 11 is not assigned the integer 16; it takes the extended digest:

```text PCR 11 after the cap · previous value all zeros
SHA-256  H(event) = 097328e8c957de2428283954f6a1ee8ff7ad7def12e100a600178407f5decf24
         PCR 11   = 7366e3e017f2a466c909c2f4c2419b0a1587f07b3085218fc5790181786d6c4a
SHA-1    H(event) = 5497b0911b3f5772723def3b360a2e654327c19b
         PCR 11   = 11972de964d62675d4cb3234f7c1f1ea9bd7647e
```

A PCR 11 that already holds earlier measurements ends at a different value; only the zero-start case is reproducible from the event alone.

`FvebpEndTpmBindingEx` at `0x542B4` coordinates this with FVE state and error handling. It calls the SIP check/cap path and contains fallback capping logic, including an explicit `TpmApiExtendPCR20(..., 11, ...)` call. Capping is therefore not represented by one unconditional event on every possible path. SIP failures can also move the boot integrity machinery into an insecure state.

Microsoft's countermeasure description uses a simplified pre-release/post-release state model for PCR 11. The binary makes the mechanism explicit: **the register advances through extension**. This prevents subsequent reuse of a policy requiring the previous state; it does not erase a key already released into memory.

## BCD validation and the recipient of the key

The BCD store is data on the unencrypted boot partition. Its security treatment cannot be inferred from the fact that an EFI executable has a valid signature. The boot environment needs to validate security-relevant options and the code receiving access to the unlocked device.

The inspected boot manager has an explicit option-validation path. `FvebpCalculateDataHashes` at `0x53F48` allocates an array sized for selected boot-option entries. `FvebpHashOptions` at `0x53E80` walks those entries, including nested options, and calls `FveDatumValidationInfoDataEntry` at `0x1D0C10`. The latter stores the option identifier alongside a SHA-256 digest of that option's supplied data.

```text Observed validation entry · reduced field view
entry.kind     = 2
entry.optionId = bootOptionType
entry.digest   = SHA256(optionData, optionDataLength)
```

`FvebpValidateCodeIdentityOnUnlock` at `0x5349C` obtains the application path, retrieves device validation information, and distinguishes Secure Boot validation information from the alternate code-bound path. The latter calculates option hashes, finds the expected application entry, calls `FveDatumValidateCodeEx`, and can invoke key-revocation handling on validation failure.

The boot manager therefore validates individual options, not a hash of the whole BCD store, and it has more than one validation path. Microsoft's [BCD validation reference][bcd-validation] documents the policy-controlled option set and the relationship with Secure Boot enforcement.

`BlFveSecureBootUnlockBootDevice` at `0x53704` connects these pieces. After processing the relevant devices, it ensures a keyring exists, publishes the keyring's physical address as a boot option, and tests `FveKeyringIsCodeBound`. A code-bound ring triggers the identity-validation path described above.

## The OS loader inherits usable key material

The TPM need not repeat the initial unlock for every boot application. Both samples contain a boot-library keyring contract using integer option **`0x15000042`**.

In the boot manager, `BlFveSecureBootUnlockBootDevice` appends the physical keyring address with `BlAppendBootOptionInteger`. The OS-loader snapshot consumes the same identifier in `FvebpMapKeyRing` at `0x53C80`:

1. Read the physical address from option `0x15000042`.
2. Map an initial 4 KiB view and validate the keyring.
3. Obtain its declared full length and map the complete object.
4. Validate the complete ring and retain its virtual and physical addresses.

The OS loader's `FvebInitialize` at `0x4A25C` calls that mapping routine. Later, `FvebpGetKeyNoUI` at `0x4E878` tries `FveKeyringGetCachedVmkFvek`; a successful status branches to the key-use path. `FvebpUseKey` at `0x528D0` prepares cryptographic state and can cache VMK material through `FveKeyringCacheVmk`.

The kernel side of the handoff, the `fvevol.sys` runtime encryption path, is outside the binaries analyzed here.

The OS loader also continues image validation. Its `OslLoadImage` and boot-library image-loader paths reach the signing-scenario/hash-selection machinery described earlier. Unlocking the filesystem and authorizing its next executable are related but separate operations.

## What changes to the ESP actually imply

The observed boundaries produce more precise expectations than “BitLocker hashes the EFI partition.”

| Change or condition | Relevant boundary | Expected interpretation |
| --- | --- | --- |
| Altered boot-manager executable | Firmware image authorization; image measurement if selected | Rejection, or changed measured state affecting release, depends on authorization and protector policy. |
| Changed Secure Boot configuration or authority sequence | PCR 7 and firmware enforcement | Can change a PCR 7 binding or make it unavailable. |
| Changed security-relevant BCD option | Boot-option validation and applicable Secure Boot policy | Can fail validation even though the boot manager's own executable bytes are unchanged. |
| Changed GPT entries | PCR 5 measurement | Not automatically a mismatch for a protector selecting only the documented default PCRs. Other boot/device checks still apply. |
| Added unrelated ESP data file | Coverage of the components actually measured or validated | No general claim that the file enters a selected PCR or triggers recovery. |
| Deleted required boot file | Boot availability | Encryption does not restore the missing file or guarantee boot availability. |

PCR 7 binding delegates substantial trust to authorized executable policy. Signed code with a security flaw, stale revocations or compromised measuring firmware require analysis of that trust boundary; a matching PCR is not an independent proof that all code is vulnerability-free.

## Encryption state and protection state differ

The volume's encryption method is another independent parameter. Microsoft's current unconfigured software-encryption default is **XTS-AES 128**; policy and the volume's existing configuration can select a different supported method. [Cipher configuration][cipher-policy]

Suspension illustrates the distinction between encrypted sectors and protected key access: BitLocker can retain encrypted data while providing a clear-key route to the VMK for a maintenance interval. Recovery likewise uses a separate protector rather than forcing a failing TPM policy to succeed. [BitLocker FAQ][bitlocker-faq]

After successful authorization, useful key material must exist outside the TPM for software to read the volume. PCR 11 capping limits a later unseal; it cannot revoke an already available copy. The boot manager's own `FvebInitialize`, at boot-manager RVA `0x51248`, also calls `BlTcgFwSetMemoryOverwriteRequestBit` during TPM-backed initialization. That reset-attack mitigation addresses another part of the key lifetime. Microsoft's [countermeasure guidance][countermeasures] describes the Memory Overwrite Request mechanism and the different exposure of powered-off, hibernating and sleeping systems.

## How EFI updates avoid BitLocker recovery

Replacing an EFI file and changing a TPM release condition are different operations. Windows can update boot code without a recovery prompt when the existing protector still accepts the resulting boot, or when a managed transition makes the changed boot state acceptable. These cases have different security consequences.

Microsoft documents quality and feature updates as requiring no manual BitLocker preparation from the user. That is an orchestration contract; it does not mean protection stays active throughout. [BitLocker update FAQ][bitlocker-faq]

### Windows deploys new boot files to the readable system partition

During normal Windows operation, the OS volume is already unlocked and the boot environment is no longer executing the ESP's on-disk image. Authorized servicing code can replace files on that FAT32 partition. The TPM does not enforce filesystem write permissions on the ESP or need to approve each write.

Windows deployment distinguishes the installed Windows image from its boot-environment copies on the system partition. Microsoft's [`BCDBoot` contract][bcdboot] describes copying boot files from the Windows image to the system partition, creating or updating BCD, and managing UEFI boot entries. On UEFI that target is the ESP. Windows upgrades can therefore update the files firmware will load on the next boot.

Whether every monthly update goes through `BCDBoot`, and how each servicing path handles an interruption, would take a trace of the servicing components.

Updating a boot image also does not require re-encrypting the entire Windows volume. The sector cipher and FVEK can continue doing their existing work while the boot files and the conditions for obtaining usable key material are serviced.

### PCR 7 can preserve the release condition while PCR 4 changes

An EFI application update normally changes its image measurement and therefore its PCR 4 contribution. A `{7,11}` protector does not include PCR 4. Its relevant firmware boundary is Secure Boot policy and the measured authorization authority, combined with the intended PCR 11 release phase.

The EDK II reference separates these inputs explicitly: the image-measurement library processes PE/COFF bytes, while the [image-verification measurement hook][edk-authority-hook] records the authority used for authorization and suppresses repeated measurements of an already-recorded authority. This gives a concrete explanation of an update-compatible case:

```text Conditional example · identical policy and authority-event history
old boot-manager PE digest != new boot-manager PE digest
old PCR 4 history          != new PCR 4 history
old PCR 7 history          == new PCR 7 history

Protector selection: {7,11}
PCR 11 reaches the expected release phase on the new boot.
The existing TPM policy can still be satisfied.
```

This is a consequence of which byte streams and registers the policy covers. The new boot manager must still be authorized to execute. PCR 7 is not recomputed to pretend that the new executable has the old image digest, and a completed boot's PCRs are not edited in place to erase evidence of the update.

The equality above is conditional. A new signing authority, changed `db`/`dbx`, additional authority events or a different boot path can change PCR 7. Even two validly signed boot managers need not produce the same PCR 7 history. Conversely, an unchanged PCR 7 value does not identify one exact executable version.

With `{0,2,4,11}` or a custom profile including PCR 4, changing the boot-manager measurement affects a selected condition. That path needs an authorized binding/protection transition rather than relying on the PCR 7 compatibility case.

### A maintenance transition can refresh the binding

When protection is suspended, encrypted sectors remain encrypted, but a clear-key route makes the VMK obtainable without satisfying the normal protectors. The [`DisableKeyProtectors` API][disable-protectors] explicitly documents this exposure and supports a reboot-count parameter on OS volumes. Suspension changes access to the keys; it is not a special exception granted by `TPM2_Unseal` to a mismatched PCR digest.

The complementary [`EnableKeyProtectors` contract][enable-protectors] removes clear-key exposure and refreshes existing TPM-based protectors against the current startup services. That operation establishes an accepted baseline for later boots.

```text Conceptual maintenance path · exact servicing sequence varies
Protected state A
    authorize a managed protection transition
    deploy changed boot components / policy
    traverse the required maintenance boot(s)
    validate the intended resulting state B
    refresh TPM-based protection and remove the clear-key route
Protected state B
```

The explicit validation step is a security requirement for a sound transition. The management API's ability to baseline the current state does not independently prove that state is trustworthy; that decision belongs to the authorized updater and its verification policy.

Resume timing is configurable. The documented `Suspend-BitLocker` default is one restart when no count is supplied; a count of zero leaves suspension in place until resumed. [Suspension lifetime][suspend-protection]

### Trust-database changes require additional coordination

Changing a boot file under an existing authority is simpler than changing the authority itself. Secure Boot servicing can require an ordered transition between trusted certificates, new boot managers and revocation state. A newly signed boot manager must be trusted before firmware is asked to launch it; revoking the old authority can also make old installation or recovery media unusable. Microsoft's [CVE-2023-24932 mitigation guidance][bootmgr-revocations] documents these separate deployment concerns.

Windows has compatibility checks here. TPM-WMI **event 1032** records a Secure Boot update withheld because it would conflict with the current BitLocker configuration. It means the update was deferred, not installed. [Secure Boot update events][secureboot-update-events]

The servicing success markers are separate too: event **1799** reports application of the newer signed boot manager, while event **1042** reports the SVN update. One marker does not substitute for the other or for resumed BitLocker protection. [Boot-manager servicing events][bootmgr-revocations]

The outcome can be classified by the boundary involved:

| Update case | Why automatic unlock may continue | What can still fail |
| --- | --- | --- |
| New authorized EFI image; stable PCR 7 history; `{7,11}` selected | The changed image digest is outside the selected PCR set. | Image authorization, boot-path stability or other validation. |
| Changed image included by the selected profile | A managed transition refreshes accepted protection state. | Incomplete transition, unexpected measurement or protection left suspended. |
| New certificate or `db`/`dbx` state | Coordinated trust deployment and BitLocker rebinding can accept the new state. | Firmware compatibility, mixed authorities or stale reported measurements. |
| Old image now revoked or below its version floor | It is intended to be rejected. | Boot can stop before the BitLocker recovery interface is available. |

Recovery after an update remains possible. Microsoft describes firmware temporarily reporting stale Secure Boot values during resealing, causing a one-time recovery prompt, and mixed PXE/local-disk authority paths causing recurring prompts. [Secure Boot troubleshooting][secureboot-troubleshooting]

Therefore, absence of a recovery prompt does not prove that the image was unchanged, that its PCR measurement was ignored globally, or that the disk remained protected throughout maintenance. The protector selection, transition history and final protection status resolve those possibilities.

## This boot manager already enforces an SVN floor

Update compatibility creates a rollback question: an older image can remain correctly signed even after its security defects are known. The inspected build contains an explicit boot-manager Secure Version Number (SVN) mechanism in addition to ordinary image authorization.

| Boot-manager RVA | Function | Observed behavior |
| --- | --- | --- |
| `0x37670` | `EfiEntry` | Passes embedded SVN `0x00070000` and the boot-manager image identifier to `DbxSvnCheck`. |
| `0xBD1F8` | `DbxSvnIsSecureBootEnabled` | Requires `SecureBoot == 1` and `SetupMode == 0` for the enforcing branch. |
| `0xBCFBC` | `DbxFetchSvn` | Parses UEFI `dbx` signature lists, searches matching image-SVN records, and selects the highest matching packed version. |
| `0xBD2A0` | `DbxSvnCheck` | Rejects an embedded high 16-bit SVN component lower than the corresponding installed minimum. |
| `0x18ACF0` | `BlImgLoadBootApplication` | Retrieves a `BOOTMGRSECURITYVERSIONNUMBER` image resource and passes its value through the check. |

The principal comparison can be reduced to:

```c DbxSvnCheck · principal branch, parsing and error plumbing omitted
if (SecureBootEnabled && !SetupMode) {
    minimumSvn = FetchHighestMatchingSvnFromDbx(imageIdentifier);

    if (High16(imageSvn) < High16(minimumSvn)) {
        PrintVersionViolation();
        StallApproximatelyTenSeconds();
        ResetSystem(EfiResetShutdown, EFI_SECURITY_VIOLATION);
    }
}
```

The embedded constant is displayed as **7.0**. It is an SVN, not the Windows build number. The fetch logic chooses the highest full packed version, but the rejection branch compares only the high components: an image with the same major SVN and a lower minor one passes.

`BmMain` at `0x37840` contains another check when the entry path has not established `DbxSvnChecked`. The failure branch prints a security error and invokes firmware shutdown; it does not deliberately continue to an ordinary BitLocker recovery prompt.

Deployment is a separate condition. `EfiEntry` permits `EFI_NOT_FOUND` as well as success, and an available `dbx` without a matching SVN record leaves the fetched floor initialized to zero. The check only enforces a floor that has actually been deployed to `dbx`.

Microsoft's [servicing guidance][bootmgr-revocations] also describes the SVN self-revocation feature. A security assessment must examine the image, installed trust/revocation state and recovery-media readiness together, rather than treating “a security update is installed” as proof that every rollback defense has been deployed.

## Security assessment and improvement opportunities

The implementation solves an availability problem: exact boot-image binding is disruptive to legitimate updates, while authority-based acceptance can tolerate them. The resulting tradeoffs are security-relevant even when every component follows its documented contract. These are hardening proposals and verification targets.

### Make the complete update transaction observable

An installed update, a copied boot manager, an updated trust database, an enforced SVN floor and resumed BitLocker protection are distinct states. A single “update successful” result can hide which boundary actually completed.

A stronger status contract would tie these steps to one transaction identifier and report the staged and running image identity, intended authority, protector selection, suspension lifetime, deployed version floor and final protection result. Existing event and registry reporting should be correlated into that result, with failures distinguishing deferred work, firmware rejection, boot validation and TPM authorization.

Microsoft's Secure Boot servicing description already uses ordered, independently retried update steps and records their outcomes. The improvement is an end-to-end postcondition that also proves the intended key-protection state was restored. [Servicing orchestration][secureboot-troubleshooting]

### Reduce exposure during a clear-key maintenance window

Reboot-bounded suspension helps availability, but a reboot count is not a cryptographic statement that only one approved updater can recover the VMK. During a clear-key interval, strong AES and an uncompromised TPM do not restore the protection removed by that alternate access route.

The immediate engineering improvement is to minimize that interval, persist its reason and deadline, detect an interrupted transition, and verify resumed protection before declaring maintenance complete. An indefinite suspension should remain an explicit, visible maintenance state. Crash recovery must preserve data availability without silently converting a short exception into a long-lived clear-key baseline.

A more substantial design candidate is a **TPM-bound maintenance protector** accepting narrowly authorized successor states instead of a clear-key route. TPM 2.0 provides policy authorization mechanisms such as `PolicyAuthorize`; these can support signed approval of a PCR policy. BitLocker does not use it in the path traced here. [TPM policy commands][tpm-commands]

Such a design would also need volume/platform binding, an authenticated update authority, replay-resistant version constraints, controlled retirement of predecessor policies and recovery across interrupted boots. A signature alone would allow an old approved state to remain reusable. Exact future PCR values can also be difficult to predict across diverse firmware and boot paths. The cost and failure modes of policy-authority compromise must be weighed against the exposure of suspension.

### Treat freshness as an enforced state, not just a trusted signer

PCR 7 provides update compatibility precisely because many executable versions can share an accepted authority history. That property makes timely revocation and an enforced minimum version essential. A valid signature answers who authorized an image; it does not, by itself, establish that the image is sufficiently recent.

The observed SVN check is a useful existing defense. The improvement target is reliable floor deployment, coverage of all usable boot paths and explicit evidence that the floor is active. Recovery media and alternate boot installations need to advance with the enforcement state. Raising a floor without a compatible recovery path harms availability; retaining old approval indefinitely weakens rollback resistance.

The sample's missing-record behavior also makes an audit question concrete: does a device lack a matching record because deployment is pending, because the configuration does not support it, or because state was reset? A fleet-level result should distinguish those cases.

### Prove TPM response confidentiality separately from authorization

`PolicyAuthValue` and a successful command authorization do not alone establish confidentiality of the returned secret on a discrete TPM bus. TPM session parameter encryption and command/response authentication are different properties. The [TPM session-encryption architecture][tpm-session-encryption] specifies those mechanisms separately.

For a physical-attacker assessment, the relevant questions are whether the actual `Unseal` session encrypts the sensitive response parameter, how its secret is established, and what the transport/backend exposes. A useful hardening requirement is authenticated, confidential delivery appropriate to that backend, with a testable guarantee across supported discrete and firmware TPM implementations.

Whether this build's `Unseal` session encrypts its response remains open: settling it takes the session attributes traced through, or a captured command exchange.

### Specify and verify the keyring's lifetime

PCR 11 capping prevents reuse of an earlier release condition; usable keys inherited through the keyring remain outside the TPM. The observed header/length validation addresses object consistency. It does not establish the whole memory-access, copy and erasure contract.

A stronger, reviewable contract would enumerate which boot component owns each buffer, which successor can read it, when mappings are retired, and when all live and temporary copies are erased. The post-handoff attack surface should be tested across failures, recovery and alternate boot applications, alongside DMA and memory-isolation controls.

Some of the sampled cryptographic helpers already clear their working buffers; not every keyring cleanup path was traced.

These priorities preserve the useful separation between code authorization, measured state and key release. Adding every PCR to a protector or attempting to encrypt the entire ESP would not, by itself, solve authenticated update transitions, rollback freshness or post-release key exposure.

## Reconstructing a particular machine's boot

A binary supplies implementation paths. A machine-specific account additionally needs the protector's actual PCR selection, the chosen bank, firmware policy, the ordered measured-boot events and the relevant validation results.

The useful evidence relationships are:

| Evidence | Question it resolves |
| --- | --- |
| Image version, whole-file hash and RVA | Which exact implementation was inspected? |
| Protector type and PCR selection | Which release conditions were configured? |
| Active-bank bitmap and selected algorithm ID | Which banks exist, and which one Windows continued? |
| Ordered TCG event records and live PCR values | Does replay reproduce the relevant register state? |
| Secure Boot variables and authority events | Which policy and signer authorized the boot path? |
| Boot-manager validation result and TPM response | Did host validation fail, or did TPM authorization fail? |
| Keyring producer/consumer trace | Was usable material inherited rather than newly unsealed? |
| Servicing events and suspension/resumption history | Which update steps completed, and was normal protection restored? |
| Installed image-specific SVN records and the running image's SVN | Which version floor does this boot path actually enforce? |

The important result is a chain of constrained transitions: authorized boot code runs from the ESP, firmware and boot code extend selected state, TPM policy permits a protector operation during the intended phase, metadata processing yields usable volume keys, and trusted boot applications inherit the required context. Each transition has its own inputs and failure modes. The ESP's role is to host the readable beginning of that chain; its entire filesystem is not the unit of BitLocker encryption or measurement.

[edk-revision]: https://github.com/tianocore/edk2/commit/02c1141a0e5b5c958630e81ac6ebb4b03c1e836f
[planning]: https://learn.microsoft.com/en-us/windows/security/operating-system-security/data-protection/bitlocker/planning-guide#disk-configuration-considerations
[key-management]: https://learn.microsoft.com/en-us/windows/security/operating-system-security/data-protection/bitlocker/bitlocker-overview-and-requirements-faq#what-encryption-keys-are-used-in-bitlocker-how-do-they-work-together
[tpm-commands]: https://medias.cdn.trustedcomputinggroup.org/production/Trusted_Platform_Module_2_0_Library_Part_3_Commands_Version_185_pub_87a5c10230.pdf
[pcr-profile]: https://learn.microsoft.com/en-us/windows/security/operating-system-security/data-protection/bitlocker/configure#configure-tpm-platform-validation-profile-for-native-uefi-firmware-configurations
[edk-pcr7]: https://github.com/tianocore/edk2/blob/02c1141a0e5b5c958630e81ac6ebb4b03c1e836f/SecurityPkg/Tcg/Tcg2Dxe/Tcg2Dxe.c#L2704
[oem-bitlocker]: https://learn.microsoft.com/en-us/windows-hardware/design/device-experiences/oem-bitlocker
[pcr7-troubleshooting]: https://learn.microsoft.com/en-us/troubleshoot/windows-server/setup-upgrade-and-drivers/pcr7-configuration-binding-not-possible
[edk-image-measurements]: https://github.com/tianocore/edk2/blob/02c1141a0e5b5c958630e81ac6ebb4b03c1e836f/SecurityPkg/Library/DxeTpm2MeasureBootLib/DxeTpm2MeasureBootLib.c#L138
[pcr-banks]: https://learn.microsoft.com/en-us/windows/security/hardware-security/tpm/switch-pcr-banks-on-tpm-2-0-devices
[edk-pe-hash]: https://github.com/tianocore/edk2/blob/02c1141a0e5b5c958630e81ac6ebb4b03c1e836f/SecurityPkg/Tcg/Tcg2Dxe/MeasureBootPeCoff.c#L173
[edk-hash-router]: https://github.com/tianocore/edk2/blob/02c1141a0e5b5c958630e81ac6ebb4b03c1e836f/SecurityPkg/Library/HashLibBaseCryptoRouter/HashLibBaseCryptoRouterDxe.c#L274
[pe-signatures]: https://learn.microsoft.com/en-us/windows/win32/secbp/understanding-pe-signatures
[uefi-crypto]: https://uefi.org/specs/UEFI/2.11/02_Overview.html#cryptographic-algorithm-requirement
[alg-id]: https://learn.microsoft.com/en-us/windows/win32/seccrypto/alg-id
[countermeasures]: https://learn.microsoft.com/en-us/windows/security/operating-system-security/data-protection/bitlocker/countermeasures
[bcd-validation]: https://learn.microsoft.com/en-us/windows/security/operating-system-security/data-protection/bitlocker/bcd-settings-and-bitlocker
[cipher-policy]: https://learn.microsoft.com/en-us/windows/security/operating-system-security/data-protection/bitlocker/configure#choose-drive-encryption-method-and-cipher-strength
[bitlocker-faq]: https://learn.microsoft.com/en-us/windows/security/operating-system-security/data-protection/bitlocker/faq
[bcdboot]: https://learn.microsoft.com/en-us/windows-hardware/manufacture/desktop/bcdboot-command-line-options-techref-di?view=windows-11
[edk-authority-hook]: https://github.com/tianocore/edk2/blob/02c1141a0e5b5c958630e81ac6ebb4b03c1e836f/SecurityPkg/Library/DxeImageVerificationLib/Measurement.c#L280
[disable-protectors]: https://learn.microsoft.com/en-us/windows/win32/secprov/disablekeyprotectors-win32-encryptablevolume
[enable-protectors]: https://learn.microsoft.com/en-us/windows/win32/secprov/enablekeyprotectors-win32-encryptablevolume
[suspend-protection]: https://learn.microsoft.com/en-us/powershell/module/bitlocker/suspend-bitlocker?view=windowsserver2025-ps
[bootmgr-revocations]: https://support.microsoft.com/en-us/servicing/os/windows/2023/03/how-to-manage-the-windows-boot-manager-revocations-for-secure-boot-changes-associated-with-cve-2023
[secureboot-update-events]: https://support.microsoft.com/en-us/servicing/os/windows/2022/06/secure-boot-db-and-dbx-variable-update-events
[secureboot-troubleshooting]: https://support.microsoft.com/en-us/servicing/os/secure-boot/2026/03/secure-boot-troubleshooting-guide
[tpm-session-encryption]: https://medias.cdn.trustedcomputinggroup.org/production/Trusted_Platform_Module_2_0_Library_Part_1_Architecture_Version_185_pub_2a3392dc49.pdf#page=155

