PCR7 profile expects a `db` `EV_EFI_VARIABLE_AUTHORITY` measurement that some firmware never performs, making TPM unlock impossible
- Dominant language
- Go
- Stars
- 23
- Forks
- 29
- Avg merge
- 2d 8h
- Merged PRs (30d)
- 2
Description
## Summary
On an MSI MAG B850 TOMAHAWK MAX WIFI, Ubuntu Core 26 installs and seals successfully, but **every** subsequent boot fails to unlock and falls back to the recovery key.
The cause is a single measurement: secboot's generated PCR7 profile contains an `EV_EFI_VARIABLE_AUTHORITY` extend for the `db` entry that authorised shim. This firmware does not perform that measurement, so the predicted PCR7 value can never match the measured one.
secboot already tolerates other firmware variations in PCR7 (`WithAllowInsufficientDmaProtection`, and the user-mode/deployed-mode branch pair). This looks like the same class of problem, and a similar tolerance would make TPM-backed FDE usable on this hardware.
## Environment
| | |
|---|---|
| Board | MSI MAG B850 TOMAHAWK MAX WIFI (MS-7E62) |
| Firmware | 2.A62, 2026-06-29 (latest available) |
| TPM | AMD fTPM 2.0 |
| OS | Ubuntu Core 26, `ubuntu-core-26-amd64`, grade `signed` |
| snapd | 2.76.1 (also reproduced on 2.75.2) |
| Snaps | `pc-kernel` 3419, `pc` 227, `core26` 380 |
| Secure Boot | enabled; `SetupMode=0`, `AuditMode=0`, `DeployedMode=0` |
## Symptom
Installation completes, `sealed-keys` contains `tpm`, and `boot-chains` is written. The first real run-mode boot then fails:
```
snap-bootstrap: Error with keyslot "default": cannot recover keys from keyslot:
incompatible key data role params: invalid PCR policy data:
cannot complete authorization policy assertions:
the PCR policy is not authorized for the current configuration
snap-bootstrap: Error with keyslot "default-fallback":
snap-bootstrap: secboot_sb.go:390: successfully activated encrypted device
"/dev/disk/by-uuid/..." using a fallback activation method
```
This is fully reproducible: fresh install from a freshly written image, cleared TPM, and it fails on the very first run-mode boot. It is not a resealing regression.
## Analysis
### Measured PCR7 (from `/sys/kernel/security/tpm0/binary_bios_measurements`)
```
EV_EFI_VARIABLE_DRIVER_CONFIG ccfc4bb32888… SecureBoot
EV_EFI_VARIABLE_DRIVER_CONFIG 8b0b9e7f39a2… PK
EV_EFI_VARIABLE_DRIVER_CONFIG 38620385637c… KEK
EV_EFI_VARIABLE_DRIVER_CONFIG 79ed9f64ea63… db
EV_EFI_VARIABLE_DRIVER_CONFIG 7492b4f174ae… dbx
EV_SEPARATOR df3f619804a9…
EV_EFI_VARIABLE_AUTHORITY e8e9578f5951… SbatLevel
EV_EFI_VARIABLE_AUTHORITY 68bdff38e48c… MokListRT
```
Note there is **no** `EV_EFI_VARIABLE_AUTHORITY` for `db`. The firmware loads and verifies shim against `db`, but never records which entry authorised it. Per the TCG PC Client Platform Firmware Profile it should.
Resulting PCR7 (SHA-256), verified stable across more than ten boots:
```
C417ABAF8FC7D699F14CD98EB5580803FE9C6D53BE2E91FD2ECBA24EE576C699
```
PCR4 and PCR12 are likewise stable, and snapd's `boot-chains` matches the actual asset hashes and kernel command line.
### Profile generated by snapd (`SNAPD_DEBUG=1`, `secboot_tpm.go:974`)
```
Legacy PCR protection profile:
BranchPoint(
Branch 0 {
ExtendPCR(TPM_ALG_SHA256, 7, ccfc4bb3…) SecureBoot
ExtendPCR(TPM_ALG_SHA256, 7, 8b0b9e7f…) PK
ExtendPCR(TPM_ALG_SHA256, 7, 38620385…) KEK
ExtendPCR(TPM_ALG_SHA256, 7, 79ed9f64…) db
ExtendPCR(TPM_ALG_SHA256, 7, 7492b4f1…) dbx
ExtendPCR(TPM_ALG_SHA256, 7, df3f6198…) separator
BranchPoint(
Branch 0 {
ExtendPCR(TPM_ALG_SHA256, 7, 4d4a8e2c…) <-- never measured by this firmware
ExtendPCR(TPM_ALG_SHA256, 4, 98a7fb4d…) shim
ExtendPCR(TPM_ALG_SHA256, 7, e8e9578f…) SbatLevel
ExtendPCR(TPM_ALG_SHA256, 7, 68bdff38…) MokListRT
…
```
Every branch, including the deployed-mode and user-mode variants, contains that extra PCR7 extend.
### Identification of the extra digest
`4d4a8e2c74133bbdc01a16eaf2dbb5d575afeb36f5d8dfcf609ae043909e2ee9` is the SHA-256 of the `UEFI_VARIABLE_DATA` structure for variable `db` (`d719b2cb-3d3a-4596-a3bc-dad00e67656f`) carrying the full `EFI_SIGNATURE_DATA` of the **Microsoft Corporation Third Party Marketplace Root** entry, i.e. the CA that signs Ubuntu's shim. Verified by recomputation against the platform's actual `db` contents.
### Consequence
Replaying the profile's PCR7 extends:
```
predicted by snapd 43DFB710AA385DD81FA258FF0B66428B08CE12C2131A405BFF08309CC5964FBD
measured on device C417ABAF8FC7D699F14CD98EB5580803FE9C6D53BE2E91FD2ECBA24EE576C699
```
The two differ by exactly that one extend, which is why the policy is never authorised.
## Request
**Primarily:** would it be reasonable for the shim load handler to omit the `db` authority measurement when the platform demonstrably does not produce one, or to generate branches both with and without it, as is already done for user mode versus deployed mode?
**Secondarily:** a sanity check at seal time would help. PCR7 is largely independent of the boot mode here, and we measured the identical value (`C417ABAF…`) during the install-mode boot and during run-mode boots. Comparing the predicted PCR7 against the value the TPM actually holds, and warning when they differ, would turn a silent failure into an immediate one. As it stands the install seals a policy that provably can never be satisfied, reports success, and the problem only surfaces on the next boot, when a recovery key is already needed to get back in.
## Reproduction
1. Install Ubuntu Core 26 on the hardware above, with a cleared TPM and Secure Boot enabled
2. Installation succeeds and seals (`sealed-keys` = `tpm`)
3. Reboot into run mode
4. Unlock fails with the error above and falls back to the recovery key, on every boot
Contributor guide
Research direction
Start at secboot_tpm.go:974 and trace PCR7 profile construction, including the existing insufficient-DMA and user/deployed-mode branches. Compare the profile's db authority measurement with the reported firmware measurements and determine how the absent measurement should be represented. Done means TPM policy authorization can accommodate this firmware variation and sealing can identify a predicted PCR7 mismatch.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- go
- Domain
- security
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 48/100