/spi-lockdown

Linux kernel module to protect PC firmware from modifications via SPI flash writes

Primary LanguageC

x86 SPI Lockdown Kernel Module

This module is meant to be used to prevent firmware modification as part of a SecureBoot authenticated execution environment. Where it is hardened such that there is no /dev/mem access or privileged IO available. (because if you have those things you can just do this from userspace)

These awesome slides give a full description of how this mechanism works.

Tested on amd64 debian, 3.16 kernel, and [ICH10R LPC Interface

With this miraculous technology you can:

  • set Flash Regions Access Permission Register to control which regions of flash memory can be read and written.
  • set Protected Ranges Registers to control which address ranges are read or write protected.

ALL FROM THE COMFORT OF RING 3!

But wait, there's more!

Tested on amd64 debian, 3.16 kernel, and ICH10R LPC Interface Controller

Installation and Usage

apt-get install linux-headers-$(uname -r)
git clone git@github.com:burritoaddict/spi-lockdown.git
cd spi-lockdown
make
insmod spi_lockdown.ko
sysctl -w dev.spi_lockdown.pr0=2415886336   # write protect entire
                                              region (0x8fff8000)
sysctl -w dev.spi_lockdown.flockdn=1        # prevent SPI protection
                                              modifications

Note: flockdn cannot be disabled after running sysctl without a 'reset'. On some systems that means waking from sleep

sysctl interfaces

  • dev.spi_lockdown.flockdn - FLOCKDN bit in Hardware Sequencing Flash Status Register
  • dev.spi_lockdown.frap - Flash Regions Access Permissions Register
  • dev.spi_lockdown.pr0 - Protected Range 0 Register
  • dev.spi_lockdown.pr1 - Protected Range 1 Register
  • dev.spi_lockdown.pr2 - Protected Range 2 Register
  • dev.spi_lockdown.pr3 - Protected Range 3 Register
  • dev.spi_lockdown.pr4 - Protected Range 4 Register

TODO

  • switch to use sysfs instead of sysctl
  • Review datasheets for all the chipsets dumped into lpc_chipsets to determine spibar calculation method... :(
  • Error handling and cleanup
  • Expose SPI protected memory ranges
  • Expose Flash Region Access Permissions Register
  • Expose Software Sequencing Flash Control Register
  • Expose flash descriptor region and mark unwritable
  • Re-write register values on wakeup from sleep?

References