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:
committed by
Philipp Deppenwiese
parent
7bcd9a1d91
commit
78feacc440
@ -62,4 +62,12 @@ int boot_device_wp_region(const struct region_device *rd,
|
|||||||
**/
|
**/
|
||||||
void boot_device_init(void);
|
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_ */
|
#endif /* _BOOT_DEVICE_H_ */
|
||||||
|
@ -15,3 +15,4 @@ source "src/security/vboot/Kconfig"
|
|||||||
source "src/security/tpm/Kconfig"
|
source "src/security/tpm/Kconfig"
|
||||||
source "src/security/memory/Kconfig"
|
source "src/security/memory/Kconfig"
|
||||||
source "src/security/intel/Kconfig"
|
source "src/security/intel/Kconfig"
|
||||||
|
source "src/security/lockdown/Kconfig"
|
||||||
|
@ -2,3 +2,4 @@ subdirs-y += vboot
|
|||||||
subdirs-y += tpm
|
subdirs-y += tpm
|
||||||
subdirs-y += memory
|
subdirs-y += memory
|
||||||
subdirs-y += intel
|
subdirs-y += intel
|
||||||
|
subdirs-y += lockdown
|
||||||
|
62
src/security/lockdown/Kconfig
Normal file
62
src/security/lockdown/Kconfig
Normal 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
|
6
src/security/lockdown/Makefile.inc
Normal file
6
src/security/lockdown/Makefile.inc
Normal 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
|
57
src/security/lockdown/lockdown.c
Normal file
57
src/security/lockdown/lockdown.c
Normal 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
|
@ -97,42 +97,3 @@ config INTEL_CHIPSET_LOCKDOWN
|
|||||||
config SOUTHBRIDGE_INTEL_COMMON_WATCHDOG
|
config SOUTHBRIDGE_INTEL_COMMON_WATCHDOG
|
||||||
bool
|
bool
|
||||||
depends on SOUTHBRIDGE_INTEL_COMMON_PMBASE
|
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);
|
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 */
|
/* Lock SPIBAR */
|
||||||
RCBA32_OR(0x3804, (1 << 15));
|
RCBA32_OR(0x3804, (1 << 15));
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user