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]

Reply via email to