From 3f1c76ce116a283850cde032711a7b76bcad69bb Mon Sep 17 00:00:00 2001 From: persmule Date: Wed, 17 Jan 2018 16:16:18 +0800 Subject: [PATCH] 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 --- Makefile | 1 + initrd/bin/generic-init | 11 +++++++++++ initrd/bin/lock_chip | 15 +++++++++++++++ modules/io386 | 28 ++++++++++++++++++++++++++++ 4 files changed, 55 insertions(+) create mode 100755 initrd/bin/lock_chip create mode 100644 modules/io386 diff --git a/Makefile b/Makefile index 33bb8901..85cda083 100644 --- a/Makefile +++ b/Makefile @@ -499,6 +499,7 @@ bin_modules-$(CONFIG_OPENSSL) += openssl bin_modules-$(CONFIG_TPM2_TOOLS) += tpm2-tools bin_modules-$(CONFIG_BASH) += bash bin_modules-$(CONFIG_POWERPC_UTILS) += powerpc-utils +bin_modules-$(CONFIG_IO386) += io386 $(foreach m, $(bin_modules-y), \ $(call map,initrd_bin_add,$(call bins,$m)) \ diff --git a/initrd/bin/generic-init b/initrd/bin/generic-init index 438f29d9..cd07049a 100755 --- a/initrd/bin/generic-init +++ b/initrd/bin/generic-init @@ -41,12 +41,18 @@ while true; do fi if [ "$totp_confirm" = "u" ]; then + if [ "$CONFIG_IO386" = y ]; then + lock_chip + fi exec /bin/usb-init continue fi if [ "$totp_confirm" = "m" ]; then # Try to select a kernel from the menu + if [ "$CONFIG_IO386" = y ]; then + lock_chip + fi mount_boot kexec-select-boot -m -b /boot -c "grub.cfg" continue @@ -54,11 +60,16 @@ while true; do if [ "$totp_confirm" = "y" -o -n "$totp_confirm" ]; then # Try to boot the default + if [ "$CONFIG_IO386" = y ]; then + lock_chip + fi mount_boot kexec-select-boot -b /boot -c "grub.cfg" \ || recovery "Failed default boot" fi + + done recovery "Something failed during boot" diff --git a/initrd/bin/lock_chip b/initrd/bin/lock_chip new file mode 100755 index 00000000..1331aebf --- /dev/null +++ b/initrd/bin/lock_chip @@ -0,0 +1,15 @@ +#!/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" +APM_CNT=0xb2 +FIN_CODE=0xcb +echo "Finalizing chipset" +io386 -o b -b x $APM_CNT $FIN_CODE diff --git a/modules/io386 b/modules/io386 new file mode 100644 index 00000000..6829c7ea --- /dev/null +++ b/modules/io386 @@ -0,0 +1,28 @@ +modules-$(CONFIG_IO386) += io386 + +io386_depends := $(musl_dep) + +io386_version := git +io386_repo := https://github.com/hardenedlinux/io386 +io386_dir := io386-$(io386_version) + +io386_target := \ + $(MAKE_JOBS) \ + $(CROSS_TOOLS) \ + SHARED=yes \ + PREFIX="/" \ + && \ + $(MAKE) \ + -C $(build)/$(io386_dir) \ + $(CROSS_TOOLS) \ + SHARED=yes \ + PREFIX="/" \ + DESTDIR="$(INSTALL)" \ + install \ + +io386_output := \ + io386 + +io386_libraries := + +io386_configure :=