security: Add common boot media write protection

Introduce boot media protection settings and use the existing
boot_device_wp_region() function to apply settings on all
platforms that supports it yet.

Also remove the Intel southbridge code, which is now obsolete.
Every platform locks the SPIBAR in a different stage.
For align up with the common mrc cache driver and lock after it has been
written to.

Tested on Supermicro X11SSH-TF. The whole address space is write-protected.

Change-Id: Iceb3ecf0bde5cec562bc62d1d5c79da35305d183
Signed-off-by: Patrick Rudolph <patrick.rudolph@9elements.com>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/32704
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Philipp Deppenwiese <zaolin.daisuki@gmail.com>
Reviewed-by: Julius Werner <jwerner@chromium.org>
This commit is contained in:
Patrick Rudolph 2019-12-03 19:43:06 +01:00 committed by Philipp Deppenwiese
parent 7bcd9a1d91
commit 78feacc440
8 changed files with 135 additions and 49 deletions

View File

@ -62,4 +62,12 @@ int boot_device_wp_region(const struct region_device *rd,
**/
void boot_device_init(void);
/*
* Restrict read/write access to the bootmedia using platform defined rules.
*/
#if CONFIG(BOOTMEDIA_LOCK_NONE)
static inline void boot_device_security_lockdown(void) {}
#else
void boot_device_security_lockdown(void);
#endif
#endif /* _BOOT_DEVICE_H_ */

View File

@ -15,3 +15,4 @@ source "src/security/vboot/Kconfig"
source "src/security/tpm/Kconfig"
source "src/security/memory/Kconfig"
source "src/security/intel/Kconfig"
source "src/security/lockdown/Kconfig"

View File

@ -2,3 +2,4 @@ subdirs-y += vboot
subdirs-y += tpm
subdirs-y += memory
subdirs-y += intel
subdirs-y += lockdown

View File

@ -0,0 +1,62 @@
choice
prompt "Boot media protection mechanism"
default BOOTMEDIA_LOCK_NONE
config BOOTMEDIA_LOCK_NONE
bool "Don't lock boot media sections"
config BOOTMEDIA_LOCK_CONTROLLER
bool "Lock boot media using the controller"
help
Select this if you want the controller to lock specific regions.
This only works on some platforms, please check the code or boot log.
On Intel platforms for e.g. this will make use of the SPIBAR PRRs.
config BOOTMEDIA_LOCK_CHIP
bool "Lock boot media using the chip"
help
Select this if you want the chip to lock specific regions.
This only works on some chips, please check the code or boot log.
endchoice
choice
prompt "Boot media protected regions"
depends on !BOOTMEDIA_LOCK_NONE
default BOOTMEDIA_LOCK_WHOLE_RO
config BOOTMEDIA_LOCK_WHOLE_RO
bool "Write-protect the whole boot medium"
help
Select this if you want to write-protect the whole firmware boot
medium.
The locking will take place during the chipset lockdown.
Chipset lockdown is platform specific und might be done unconditionally,
when INTEL_CHIPSET_LOCKDOWN is set or has to be triggered later
(e.g. by the payload or the OS).
NOTE: If you trigger the chipset lockdown unconditionally,
you won't be able to write to the whole flash chip using the
internal controller any more.
config BOOTMEDIA_LOCK_WHOLE_NO_ACCESS
depends on BOOTMEDIA_LOCK_CONTROLLER
bool "Read- and write-protect the whole boot medium"
help
Select this if you want to protect the firmware boot medium against
all further accesses. On platforms that memory map a part of the
boot medium the corresponding region is still readable.
The locking will take place during the chipset lockdown.
Chipset lockdown is platform specific und might be done unconditionally,
when INTEL_CHIPSET_LOCKDOWN is set or has to be triggered later
(e.g. by the payload or the OS).
NOTE: If you trigger the chipset lockdown unconditionally,
you won't be able to write to the whole flash chip using the
internal controller any more.
endchoice

View File

@ -0,0 +1,6 @@
## SPDX-License-Identifier: GPL-2.0-or-later
## This file is part of the coreboot project.
ifneq ($(CONFIG_BOOTMEDIA_LOCK_NONE),y)
ramstage-y += lockdown.c
endif

View File

@ -0,0 +1,57 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
/* This file is part of the coreboot project. */
#include <boot_device.h>
#include <commonlib/region.h>
#include <console/console.h>
#include <bootstate.h>
/*
* Enables read- /write protection of the bootmedia.
*/
void boot_device_security_lockdown(void)
{
const struct region_device *rdev;
enum bootdev_prot_type lock_type;
printk(BIOS_DEBUG, "BM-LOCKDOWN: Enabling boot media protection scheme ");
if (CONFIG(BOOTMEDIA_LOCK_CONTROLLER)) {
if (CONFIG(BOOTMEDIA_LOCK_WHOLE_RO)) {
printk(BIOS_DEBUG, "'readonly'");
lock_type = CTRLR_WP;
} else if (CONFIG(BOOTMEDIA_LOCK_WHOLE_NO_ACCESS)) {
printk(BIOS_DEBUG, "'no access'");
lock_type = CTRLR_RWP;
}
printk(BIOS_DEBUG, "using CTRL...\n");
} else {
if (CONFIG(BOOTMEDIA_LOCK_WHOLE_RO)) {
printk(BIOS_DEBUG, "'readonly'");
lock_type = MEDIA_WP;
}
printk(BIOS_DEBUG, "using flash chip...\n");
}
rdev = boot_device_ro();
if (boot_device_wp_region(rdev, lock_type) >= 0)
printk(BIOS_INFO, "BM-LOCKDOWN: Enabled bootmedia protection\n");
else
printk(BIOS_ERR, "BM-LOCKDOWN: Failed to enable bootmedia protection\n");
}
static void lock(void *unused)
{
boot_device_security_lockdown();
}
/*
* Keep in sync with mrc_cache.c
*/
#if CONFIG(MRC_WRITE_NV_LATE)
BOOT_STATE_INIT_ENTRY(BS_OS_RESUME_CHECK, BS_ON_EXIT, lock, NULL);
#else
BOOT_STATE_INIT_ENTRY(BS_DEV_RESOURCES, BS_ON_ENTRY, lock, NULL);
#endif

View File

@ -97,42 +97,3 @@ config INTEL_CHIPSET_LOCKDOWN
config SOUTHBRIDGE_INTEL_COMMON_WATCHDOG
bool
depends on SOUTHBRIDGE_INTEL_COMMON_PMBASE
if SOUTHBRIDGE_INTEL_COMMON_FINALIZE
choice
prompt "Flash locking during chipset lockdown"
default LOCK_SPI_FLASH_NONE
config LOCK_SPI_FLASH_NONE
bool "Don't lock flash sections"
config LOCK_SPI_FLASH_RO
bool "Write-protect all flash sections"
help
Select this if you want to write-protect the whole firmware flash
chip. The locking will take place during the chipset lockdown, which
is either triggered by coreboot (when INTEL_CHIPSET_LOCKDOWN is set)
or has to be triggered later (e.g. by the payload or the OS).
NOTE: If you trigger the chipset lockdown unconditionally,
you won't be able to write to the flash chip using the
internal programmer any more.
config LOCK_SPI_FLASH_NO_ACCESS
bool "Write-protect all flash sections and read-protect non-BIOS sections"
help
Select this if you want to protect the firmware flash against all
further accesses (with the exception of the memory mapped BIOS re-
gion which is always readable). The locking will take place during
the chipset lockdown, which is either triggered by coreboot (when
INTEL_CHIPSET_LOCKDOWN is set) or has to be triggered later (e.g.
by the payload or the OS).
NOTE: If you trigger the chipset lockdown unconditionally,
you won't be able to write to the flash chip using the
internal programmer any more.
endchoice
endif

View File

@ -15,16 +15,6 @@ void intel_pch_finalize_smm(void)
{
const pci_devfn_t lpc_dev = PCI_DEV(0, 0x1f, 0);
if (CONFIG(LOCK_SPI_FLASH_RO) ||
CONFIG(LOCK_SPI_FLASH_NO_ACCESS)) {
int i;
u32 lockmask = 1UL << 31;
if (CONFIG(LOCK_SPI_FLASH_NO_ACCESS))
lockmask |= 1 << 15;
for (i = 0; i < 20; i += 4)
RCBA32(0x3874 + i) = RCBA32(0x3854 + i) | lockmask;
}
/* Lock SPIBAR */
RCBA32_OR(0x3804, (1 << 15));