Issue #576 has been updated by Thierry Laurion.
Mate Kukri wrote in #note-4: > Dan Ran wrote in #note-3: > > Nicholas Chin wrote in #note-1: > > > I've looked through the code and this is what I've found so far: > > > > > > There are two basic functions for locking GPIO pads, `gpio_lock_pads()` > > > and `gpio_non_smm_lock_pad()`, both in > > > `soc/intel/common/block/gpio/gpio.c`. > > > > > > `gpio_lock_pads()` can only be called from SMM, and requires that > > > `SOC_INTEL_COMMON_BLOCK_SMM_LOCK_GPIO_PADS` is selected. There are two > > > possible code paths where this function is invoked: > > > - The finalize SMI handler > > > (`soc/intel/common/block/gpio/gpio.c:finalize()`), which calls > > > `soc_lock_gpios()`. This requires that the platform implement a > > > `soc_gpio_lock_config()` override to return which GPIOs should be locked, > > > which no platform implements. Thus, locking from the SMI handler does not > > > work even if `SOC_INTEL_COMMON_BLOCK_SMM_LOCK_GPIO_PADS` is selected. > > > - `soc/intel/common/block/gpio/gpio.c:gpio_lock_pad()`, which calls > > > `gpio_lock_pads()` if called from SMM code. This does not suffer from the > > > `soc_gpio_lock_config()` described above, but this is almost always > > > called from ramstage through the `gpio_configure_pads()` > > > > `gpio_configure_pad()` call stack. The one exception is > > > `mb/google/dedede`, which calls it from a mainboard SMI handler. It will > > > also call `gpio_lock_pads()` if > > > `SOC_INTEL_COMMON_BLOCK_SMM_LOCK_GPIO_PADS` is selected, even if called > > > from ramstage, but this will also fail to lock the pads as > > > `gpio_lock_pads()` checks that it is called from SMM. > > > > > > Thus, the SMM method doesn't work because essentially no platform > > > implements it. > > > > > > `gpio_non_smm_lock_pad()` is only called from `gpio_lock_pad()` if > > > outside of SMM (almost always true as mentioned above) and if > > > `SOC_INTEL_COMMON_BLOCK_SMM_LOCK_GPIO_PADS` is NOT selected. For this > > > function to perform the lock, either > > > `SOC_INTEL_COMMON_BLOCK_GPIO_LOCK_USING_PCR` or > > > `SOC_INTEL_COMMON_BLOCK_GPIO_LOCK_USING_SBI` must be selected, which > > > choose the method to access the GPIO registers in the Private > > > Configuration Space. The former uses the MMIO mapping of the registers > > > through SBREG, while the latter sends sideband messages through the P2SB > > > registers. Currently, only Alderlake onwards selects these configs, so > > > GPIO locking using this method is expected to be broken on all > > > `soc/intel` platforms prior to this that use the common GPIO code. > > > > > > The latter method was added in [commit > > > fe678cbd195d](https://review.coreboot.org/c/coreboot/+/60801) > > > ("soc/intel/common/gpio: Perform GPIO PAD lock outside SMM"). > > > [Commit 222852a26476](https://review.coreboot.org/c/coreboot/+/66113) > > > ("soc/intel/gpio: Update GPIO Lock configuration recommendation") seems > > > to suggest that platforms prior to Alderlake can only set the lock bits > > > using the SBI method, though I have yet to determine if this is true. The > > > datasheets seem to suggest that the PCR method should work, which I would > > > prefer as it consists of low overhead MMIO accesses. > > > > > > One other aspect that needs to be looked into is how the lockdown bits > > > are enforced. According to PCH datasheets, after a lock bit is changed > > > from 0 (unlocked) to 1 (locked), attempts to change it back to the > > > unlocked state will signal an SMI. This may imply that SMM is responsible > > > to change the bit back to 1, similar to how the old BIOS Lock Enable bit > > > in the BIOS Control register was intended to work when setting the BIOS > > > Write Enable bit. That method often led to security issues due to no SMI > > > handler being implemented to change the write enable bit back to disabled. > > > > > > > > Nicholas Chin wrote in #note-2: > > > Possible fix here: > > > https://review.coreboot.org/c/coreboot/+/90884 > > > https://review.coreboot.org/c/coreboot/+/90885 > > > > > > Still needs testing and verification, and extension to other affected > > > platforms. It seems that the SBI method doesn't work on Skylake, though > > > the PCR method does. > > > > > > > > Nicholas Chin wrote in #note-2: > > > Possible fix here: > > > https://review.coreboot.org/c/coreboot/+/90884 > > > https://review.coreboot.org/c/coreboot/+/90885 > > > > > > Still needs testing and verification, and extension to other affected > > > platforms. It seems that the SBI method doesn't work on Skylake, though > > > the PCR method does. > > > > What is the status of this issue? How can we expedite a fix? I bought a > > used T480 to flash heads onto it, only to find out that there is a massive > > vulnerability (this one) on the heads firmware that has to be fixed in > > coreboot first. Is there a way to patch this vuln for a T480 and put the > > code into heads as well? Sorry i sound dumb, i'm still a noob on all of > > this. > > > > If this cant be fixed, what can I do to secure my t480? When do you think > > this can be fixed and patched? > > This needs to be implemented by someone with motivation and access to the > actual hardware documentation, anything else is hope and prayers that the > lock really works, but who knows if it does. > > Lenovo's stock BIOS and most firmware from this era is also hopelessly > vulnerable and unfixed to this day. > > Mate Kukri Alder Lake P also vulnerable: https://github.com/linuxboot/heads/pull/2165#issuecomment-5138700385 ``` shell # TPM GPIO Reset Vulnerability test: mount USB stick rw, audit PLTRST# lock status mount-usb.sh --mode rw && tpm-gpio-detect 2>&1 | tee /media/tpm-gpio-detect.log # Assert PLTRST# via P2SB PCR write and check TPM PCRs tpm-gpio-assert 2>&1 | tee /media/tpm-gpio-assert.log echo "=== DETECT ===" && cat /media/user/public/tpm-gpio-detect.log && echo && echo "=== ASSERT ===" && cat /media/user/public/tpm-gpio-assert.log === DETECT === Found platform AlderLake P with PCH ADL-P PCH! P2SB SBREG_BAR = 0xfd000000 (platform-specific) --- PLTRST# Pad Lock Status --- GPIO Signal PADCFGLOCK PADCFGLOCKTX GPP_B13 PLTRST# 0x00000000 (UNLOCKED) 0x00000000 (UNLOCKED) <- UNLOCKED --- Pad Configuration --- DW0 (0x07d0) = 0x40000400, mode: NF1 (bits 13:10=0x1) NF1 mode -- mode transition CAN create PLTRST# reset edge --- eSPI Bus Pin Lock Status --- GPIO Signal PADCFGLOCK PADCFGLOCKTX GPP_A1 ESPI_IO0 0x00000000 (UNLOCKED) 0x00000000 (UNLOCKED) <- UNLOCKED GPP_A2 ESPI_IO1 0x00000000 (UNLOCKED) 0x00000000 (UNLOCKED) <- UNLOCKED GPP_A3 ESPI_IO2 0x00000000 (UNLOCKED) 0x00000000 (UNLOCKED) <- UNLOCKED GPP_A4 ESPI_IO3 0x00000000 (UNLOCKED) 0x00000000 (UNLOCKED) <- UNLOCKED GPP_A5 ESPI_CS# 0x00000000 (UNLOCKED) 0x00000000 (UNLOCKED) <- UNLOCKED GPP_A9 ESPI_CLK 0x00000000 (UNLOCKED) 0x00000000 (UNLOCKED) <- UNLOCKED GPP_A14 ESPI_RESET# 0x00000000 (UNLOCKED) 0x00000000 (UNLOCKED) <- UNLOCKED --- Vulnerability Classification --- TIER 1 -- CONFIRMED VULNERABLE: ADL-P mobile: NF1 mode confirmed, PLTRST# verified (TIER 1) Attack confirmed working by community testing. === RESULT: unlocked pins found (unlocked: 8) === === ASSERT === SBREG_BAR = 0xfd000000 (MEM) Found Alder Point P --- PADCFGLOCK Status (port 0x6e, offset 0x80) --- PADCFGLOCK = 0x00000000 (UNLOCKED, bit 13 clear) PADCFGLOCKTX = 0x00000000 (UNLOCKED, bit 13 clear) --- PCR State Before Assertion --- sha256: 0 : 0x0000000000000000000000000000000000000000000000000000000000000000 1 : 0x0000000000000000000000000000000000000000000000000000000000000000 2 : 0xC45991E14F0B09EBFCD96FF16EAD26D7F3596E3F24677F587ED93FE66F3A9D16 3 : 0x0000000000000000000000000000000000000000000000000000000000000000 4 : 0x51737C77C481AA22095B38D38FC9FD494B0FFA4EAE7D3AC238082083D0AFD614 5 : 0x5DCB5FCAF52F32ED2BDF8F7C5CBA01A54343D8356EB5E2B755B635F217F29EBB 6 : 0x0000000000000000000000000000000000000000000000000000000000000000 7 : 0x0000000000000000000000000000000000000000000000000000000000000000 8 : 0x0000000000000000000000000000000000000000000000000000000000000000 9 : 0x0000000000000000000000000000000000000000000000000000000000000000 10: 0x0000000000000000000000000000000000000000000000000000000000000000 11: 0x0000000000000000000000000000000000000000000000000000000000000000 12: 0x0000000000000000000000000000000000000000000000000000000000000000 13: 0x0000000000000000000000000000000000000000000000000000000000000000 14: 0x0000000000000000000000000000000000000000000000000000000000000000 15: 0x0000000000000000000000000000000000000000000000000000000000000000 16: 0x0000000000000000000000000000000000000000000000000000000000000000 17: 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF 18: 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF 19: 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF 20: 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF 21: 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF 22: 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF 23: 0x0000000000000000000000000000000000000000000000000000000000000000 --- TPM Session Preparation --- Running tpm2 shutdown -c to cleanly shut down TPM session *** WARNING: About to assert PLTRST# -- TPM may reboot (PCRs clear, NVRAM preserved) *** *** This test reboots the TPM (PCRs clear, NVRAM preserved). *** PCR port=0x6e offset=0x7d0 DW0 (original) = 0x40000400 DW1 (original) = 0x0003c025 --- Pad Mode Check --- Current mode: NF1 (DW0 bits 13:10 = 0x1) Mode transition possible: NF1 -> GPIO -> NF1 (creates PLTRST# reset edge) PLTRST# assertion CAN attempt mode transition reset DW0 (asserted) = 0x80000000 DW1 (asserted) = 0x00000025 DW1 partially locked (TX control bits) - does not prevent reset Registers restored Running tpm2 startup -c to reinitialize TPM --- PCR State After Assertion --- sha256: 0 : 0x0000000000000000000000000000000000000000000000000000000000000000 1 : 0x0000000000000000000000000000000000000000000000000000000000000000 2 : 0x0000000000000000000000000000000000000000000000000000000000000000 3 : 0x0000000000000000000000000000000000000000000000000000000000000000 4 : 0x0000000000000000000000000000000000000000000000000000000000000000 5 : 0x0000000000000000000000000000000000000000000000000000000000000000 6 : 0x0000000000000000000000000000000000000000000000000000000000000000 7 : 0x0000000000000000000000000000000000000000000000000000000000000000 8 : 0x0000000000000000000000000000000000000000000000000000000000000000 9 : 0x0000000000000000000000000000000000000000000000000000000000000000 10: 0x0000000000000000000000000000000000000000000000000000000000000000 11: 0x0000000000000000000000000000000000000000000000000000000000000000 12: 0x0000000000000000000000000000000000000000000000000000000000000000 13: 0x0000000000000000000000000000000000000000000000000000000000000000 14: 0x0000000000000000000000000000000000000000000000000000000000000000 15: 0x0000000000000000000000000000000000000000000000000000000000000000 16: 0x0000000000000000000000000000000000000000000000000000000000000000 17: 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF 18: 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF 19: 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF 20: 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF 21: 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF 22: 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF 23: 0x0000000000000000000000000000000000000000000000000000000000000000 === RESULT: PCRs cleared to zero -- TPM reboot confirmed via sha256 PCR read === --- Next Steps --- NF1->GPIO transition executed. Report results: https://github.com/tlaurion/tpm-gpio-fail/issues Include this log output. ``` ---------------------------------------- Bug #576: GPIO locking is broken on Kaby Lake and possibly other platforms https://ticket.coreboot.org/issues/576#change-2371 * Author: Mate Kukri * Status: New * Priority: Normal * Target version: none * Start date: 2025-01-30 ---------------------------------------- Many supported Kaby Lake boards (and possibly newer platforms as well) are vulnerable to [TPM GPIO reset attacks](https://mkukri.xyz/2024/06/01/tpm-gpio-fail.html). Trying to fix this by marking the affected GPIOs as locked in gpio.h and even also selecting `SOC_INTEL_COMMON_BLOCK_SMM_LOCK_GPIO_PADS` does not work. This was discovered last year and briefly discussed on #coreboot, but it came up again on the Heads matrix group in relation to supporting the TPM on the in-progress ThinkPad T480 port. -- You have received this notification because you have either subscribed to it, or are involved in it. To change your notification preferences, please click here: https://ticket.coreboot.org/my/account _______________________________________________ coreboot mailing list -- [email protected] To unsubscribe send an email to [email protected]

