Skip to content

Instantly share code, notes, and snippets.

@ansiwen
Created September 4, 2023 16:42
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ansiwen/255174aa96d6dc34680d95957d9d6fe9 to your computer and use it in GitHub Desktop.
Save ansiwen/255174aa96d6dc34680d95957d9d6fe9 to your computer and use it in GitHub Desktop.
Enable BootGuard 1.0 on Prodive Hermes

Enable BootGuard 1.0 for PCR-0 measurement in Firmware on ProDrive Hermes Board

Operation

We are using BootGuard 1.0 in order to generate an Intel authorized Locality 3 PCR-0 measurement of the boot block, which is the self-measured root of trust for the PCR-2 measurements of Coreboot. That is, we are not using its verification feature, which would require to fuse the chip. Because there is no BootGuard profile without verification, we still have to use a dummy OEM Key for signing both the Key Manifest and the Boot Policy Manifest, so that we can get the PCR-0 measurement, but the OEM Key does not have to be kept secret. Because the Locality 3 measurement can only be done by Intel-signed ACMs, no adversary can reproduce the same PCR-0 measurements with any modification of the flash. (Hardware modifications are out of scope for the threat model.) The device key is sealed against both PCR-0 and PCR-2, and can't be accessed with any modified flash.

Requirements

For successful BooGuard startup and measurement into PCR-0 the following items are required:

  • Configured BootGuard profile 3 or 5 in the FPF (3 occurences)
  • OEM Key Hash stored in the FPF (3 occurences)
  • BootGuard Startup ACM in CBFS
    • Not included in the original Hermes FW, needs to be extracted (with UEFITool, e.g.) from another CSME firmware of a board with the same chipset C246, e.g. the Gigabyte C246-WU4.
  • Key Manifest signed by OEM Key stored in CBFS
  • Boot Policy Manifest stored in CBFS with
    • signed with key from Key Manifest
    • IBB section for the Coreboot boot block
    • IBB hash of the Coreboot boot block
    • IBB SE Flag 0x02: (Locality 3 Startup: Issue TPM Start-up from Locality 3)
  • FIT entries for:
    • Startup ACM
    • Key Manifest
    • Boot Policy Manifest

Manually Patching the Firmware

The Firmware can be manually patched with a hex editor. Open the original CSME firmware image (at the time of this writing POC6001198032R12-RP06.00-uefi-csme.swu) and find the $UEP section:

0000: 2455 4550 32a0 0000 0000 0000 0000 0000  $UEP2...........
                ^^^^ CRC16/AUG-CCITT of 0x8-0x208 in LE byte-order
0010: 0000 0000 0000 0000 0000 0000 0000 0000  ................
0020: 0000 0000 0000 0000 ffff cf0c 0fc0 00c0  ................
0030: c000 0000 ff0c 0000 0000 0000 0000 0000  ................
                ^^ enforcement bits (0xcc -> no enforcement)
0040: 0000 0000 0000 0000 80c0 4800 7900 0000  ..........H.y...
                          ^^^^^^^^^^^^^^ FPF bits
0050: 0000 0000 0000 0000 0000 0000 0000 0000  ................
0060: 0000 0000 0000 0000 0000 0000 0000 0000  ................
0070: 0000 0000 0000 0000 0000 0000 0000 0000  ................
0080: 0000 0000 0000 0000 0000 0000 0000 0000  ................
0090: 2ad7 1bd7 bfdd 3ae2 19f1 2904 157d 8e3f  *.....:...)..}.? < OEM Key Hash
00a0: 7faa a529 97ec 3e0f de35 4b67 a705 5a07  ...)..>..5Kg..Z. <
00b0: 0000 0000 0000 0000 0000 0000 0000 0000  ................
00c0: 0000 0000 0000 0000 0000 0000 0000 0000  ................
00d0: 0000 0000 0000 0000 0000 0000 0000 0000  ................
00e0: 0000 0000 80c0 4800 7900 0000 0000 0000  ......H.y.......
                ^^^^^^^^^^^^^^ FPF bits
00f0: 0000 0000 0000 0000 0000 0000 0000 0000  ................
0100: 0000 0000 0000 0000 0000 0000 0000 0000  ................
0110: 0000 0000 0000 0000 0000 0000 0000 0000  ................
0120: 2ad7 1bd7 bfdd 3ae2 19f1 2904 157d 8e3f  *.....:...)..}.? < OEM Key Hash
0130: 7faa a529 97ec 3e0f de35 4b67 a705 5a07  ...)..>..5Kg..Z. <
0140: 0000 0000 0000 0000 0000 0000 0000 0000  ................
0150: 0000 0000 0000 0000 0000 0000 0000 0000  ................
0160: 0000 0000 0000 0000 0000 0000 0000 0000  ................
0170: 0000 0000 80c0 4800 7900 0000 0000 0000  ......H.y.......
                ^^^^^^^^^^^^^^ FPF bits
0180: 0000 0000 0000 0000 0000 0000 0000 0000  ................
0190: 0000 0000 0000 0000 0000 0000 0000 0000  ................
01a0: 0000 0000 0000 0000 0000 0000 0000 0000  ................
01b0: 2ad7 1bd7 bfdd 3ae2 19f1 2904 157d 8e3f  *.....:...)..}.? < OEM Key Hash
01c0: 7faa a529 97ec 3e0f de35 4b67 a705 5a07  ...)..>..5Kg..Z. <
01d0: 0000 0000 0000 0000 0000 0000 0000 0000  ................
01e0: 0000 0000 0000 0000 0000 0000 0000 0000  ................
01f0: 0000 0000 0000 0000 0000 0000 0000 0000  ................
0200: 0000 0000 0000 0000 ffff ffff ffff ffff  ................

1. Set the BootGuard profile

The FPF Bits are located at offsets 0x48, 0xE4 and 0x174.

For BootGuard profile 5 the following values must be set:

  • Offset 0x34 to 0xFF (means: immediate shutdown on failure)
  • Of the FPF bits, byte 4 must be set to 0x79 (all three occurences). In detail:
    • Feature bits 0, 3, 4, 5 set
    • KM ID set to 0x1

For BootGuard profile 3 the following values must be set:

  • Offset 0x34 to 0xCC (means: ignore failure)
  • Of the FPF bits, byte 4 must be set to 0x78 (all three occurences). Difference to profile 5: FACB not set.

2. Store the OEM Key Hash

The hash of the dummy OEM Key must be stored at offsets 0x90, 0x120 and 0x1B0. If the OEM Key has been changed, you need to re-calculate the hash. The easiest way to do that is to use the bg-prov tool (see below):

$ ./bg-prov km-show km.bin

The last line then shows the Key Manifest Pubkey Hash

3. Update CRC-16

Then the CRC-16 (AUG-CCITT) of the bytes from offset 0x8 to 0x208 must be calculated and stored at offset 0x04.

For calculation you can use this website.

NOTE: It must be stored in little endian byte order, so a result of 0xA032 must be stored as 32A0.

Reverse-engineered meaning of the FPF bits:

[0] 0x80
[1] 0xc0
[2] bits:
 0:
 1:
 2: TXT
 3:
 4: ? (doesn't get measured, doesn't matter)
 5:
 6:
 7:
[3] 0x00
[4-5] bits:
 0: FACB (Force BootGuard ACM usage)
 1: CPU Debugging disabled
 2: BSP Init disabled
 3: Protect BIOS Environment
 4: Measured_Boot
 5: Verified_Boot
 6: KM ID (bit 0)
 7: KM ID (bit 1)
 0: KM ID (bit 2)
 1: KM ID (bit 3)
 2: S3 Opt Enabled: 0, Disabled: 1
 3:
 4:
 5:
 6:
 7:

Create FIT entries and KM/BPM

The easiest way to create the FIT entries and the signed KM and BPM is to use the unmerged patches from 9elements here: https://review.coreboot.org/c/coreboot/+/55729 in combination with the also unmerged version of the bg-prov tool from https://github.com/coreboot/9esec-security-tooling/tree/coreboot-CB55414

You need to create a dummy OEM key (RSA 2048bit) and set both CONFIG_INTEL_BG_KM_PRIV_KEY_FILE and CONFIG_INTEL_BG_BPM_PRIV_KEY_FILE to it.

CONFIG_INTEL_BIOSACM_FILE must be set to the BtG ACM. (See above)

Important: Bit 2 of CONFIG_INTEL_BG_IBB_FLAGS must be set, otherwise the TPM is not initialized with Locality 3, and the measurements could be spoofed by a compromised firmware.

Make sure that TPM_MEASURED_BOOT_INIT_BOOTBLOCK is enabled, so that there is no gap in the measurement chain.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment