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:
parent
7bcd9a1d91
commit
78feacc440
|
@ -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_ */
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -2,3 +2,4 @@ subdirs-y += vboot
|
|||
subdirs-y += tpm
|
||||
subdirs-y += memory
|
||||
subdirs-y += intel
|
||||
subdirs-y += lockdown
|
||||
|
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
||||
|
|
|
@ -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));
|
||||
|
||||
|
|
Loading…
Reference in New Issue