Introduce io386 to heads and use it to finalize chipset at runtime
On some newer platforms of intel (confirmed on nehalem, sandy/ivy
bridge), coreboot after commit [2ac149d294af795710eb4bb20f093e9920604abd](https://review.coreboot.org/cgit/coreboot.git/commit/?id=2ac149d294af795710eb4bb20f093e9920604abd)
registers an SMI to lockdown some registers on the chipset, as well
as access to the SPI flash, optionally. The SMI will always be triggered
by coreboot during S3 resume, but can be triggered by either coreboot
or the payload during normal boot path.
Enabling lockdown access to SPI flash will effectly write-protect it,
but there is no runtime option for coreboot to control it, so letting
coreboot to trigger such SMI will leave the owner of the machine lost
any possibility to program the SPI flash with its own OS, and becomes
a nightmare if the machine is uneasy to disassemble, so a scheme could
be implement, in which the SMI to lockdown chipset and SPI flash is left
for a payload to trigger, and temporarily disabling such triggering in
order to program the SPI flash needs authentication.
I have implemented a passcode-protected runtime-disableable lockdown
with grub, described [here](https://github.com/hardenedlinux/Debian-GNU-Linux-Profiles/blob/master/docs/hardened_boot/grub-for-coreboot.md#update-for-coreboot-after-commit-2ac149d294af795710eb4bb20f093e9920604abd). In order to implement a similar scheme for
Heads, I wrote [io386](https://github.com/hardenedlinux/io386).
With this commit, io386 will be called before entering boot routine
to trigger the SMI to finalize the chipset and write protect the SPI
flash at the same time. Entering recovery shell will leave the flash
writable.
(The authentication routine implemented in previous revisions has been
split as an independent commit.)
Originally proposed under PR#326
2018-01-17 08:16:18 +00:00
#!/bin/sh
# For this to work:
# - io386 module needs to be enabled in board config (sandy/ivy/haswell know to work)
# - coreboot config need to enable CONFIG_BOOTMEDIA_LOCK_CONTROLLER=y without enabling CONFIG_INTEL_CHIPSET_LOCKDOWN
# - Heads is actually doing the CONFIG_INTEL_CHIPSET_LOCKDOWN equivalent here.
# TODO: If more platforms are able to enable CONFIG_INTEL_CHIPSET_LOCKDOWN in the future, have board config export APM_CNT and FIN_CODE and modify this script accordingly
#include ash shell functions (TRACE requires it)
. /etc/ash_functions
TRACE "Under /bin/lock_chip"
2023-06-20 16:40:00 +00:00
if [ "$CONFIG_FINALIZE_PLATFORM_LOCKING_PRESKYLAKE" = "y" ]; then
APM_CNT=0xb2
FIN_CODE=0xcb
fi
if [ -n "$APM_CNT" -a -n "$FIN_CODE" ]; then
2024-02-01 19:30:31 +00:00
# SMI PR0 lockdown is implemented by Intel as part of the SMM Supervisor feature.
# SMM Supervisor is a software component that runs in SMM and acts as a gatekeeper
# for SMM access.
#
# It uses the processor’ s memory protection and paging mechanisms to restrict what
# SMM code can read and write. SMM Supervisor marks critical pages, such as its
# own code, data, and page tables, as supervisor pages, which are only accessible
# from the most privileged level (CPL0).
#
# It also marks the rest of the SMM memory as user pages, which are accessible
# from any privilege level.
#
# This way, SMM Supervisor can isolate itself from other SMM code and enforce a policy
# that states what resources the SMI handlers (the interrupt handlers that run in SMM)
# require access to.
#
# SMI PR0 lockdown is enabled by setting a lock bit (FLOCKDN) in the SPI controller,
# which prevents further changes to the SMM memory and configuration.
# Once SMI PR0 lockdown is enabled, it cannot be disabled until the next system reset.
# This ensures that malicious code cannot tamper with the SMM Supervisor or the SMI handlers
# after the system boots.
echo "Finalizing chipset Write Protection through SMI PR0 lockdown call"
2023-06-20 16:40:00 +00:00
io386 -o b -b x $APM_CNT $FIN_CODE
else
echo "NOT Finalizing chipset"
echo "lock_chip called without valid APM_CNT and FIN_CODE defined under bin/lock_chip."
fi