diff --git a/src/security/lockdown/Kconfig b/src/security/lockdown/Kconfig index 8de7979904..95a768a148 100644 --- a/src/security/lockdown/Kconfig +++ b/src/security/lockdown/Kconfig @@ -73,6 +73,18 @@ config BOOTMEDIA_LOCK_WPRO_VBOOT_RO 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). +config BOOTMEDIA_LOCK_TOPSWAP + bool "Write-protect the COREBOOT & BOOTBLOCK regions" + depends on TOP_SWAP_REDUNDANCY + depends on BOOTMEDIA_LOCK_CONTROLLER + help + Select this if you want to write-protect the BOOTBLOCK and COREBOOT + (Slot A) regions as specified in the Top Swap FMAP. You will be able to + write to the TOPSWAP and COREBOOT_TS (Slot B) regions and set the + attempt_slot_b CMOS option to run updated firmware. The BOOTBLOCK and + COREBOOT regions will remain a read-only golden copy, which you can + then revert to by resetting CMOS. + endchoice config BOOTMEDIA_LOCK_IN_VERSTAGE diff --git a/src/security/lockdown/lockdown.c b/src/security/lockdown/lockdown.c index c2e2ac3501..6a75111f6b 100644 --- a/src/security/lockdown/lockdown.c +++ b/src/security/lockdown/lockdown.c @@ -27,6 +27,9 @@ void boot_device_security_lockdown(void) } else if (CONFIG(BOOTMEDIA_LOCK_WPRO_VBOOT_RO)) { printk(BIOS_DEBUG, "'WP_RO only'"); lock_type = CTRLR_WP; + } else if (CONFIG(BOOTMEDIA_LOCK_TOPSWAP)) { + printk(BIOS_DEBUG, "'COREBOOT + BOOTBLOCK'"); + lock_type = CTRLR_WP; } printk(BIOS_DEBUG, " using CTRL...\n"); } else { @@ -45,6 +48,11 @@ void boot_device_security_lockdown(void) printk(BIOS_ERR, "BM-LOCKDOWN: Could not find region 'WP_RO'\n"); else rdev = &dev; + } else if (CONFIG(BOOTMEDIA_LOCK_TOPSWAP)) { + if (fmap_locate_area_as_rdev("COREBOOT", &dev) < 0) + printk(BIOS_ERR, "BM-LOCKDOWN: Could not find region 'COREBOOT'\n"); + else + rdev = &dev; } else { rdev = boot_device_ro(); } @@ -53,6 +61,18 @@ void boot_device_security_lockdown(void) printk(BIOS_INFO, "BM-LOCKDOWN: Enabled bootmedia protection\n"); else printk(BIOS_ERR, "BM-LOCKDOWN: Failed to enable bootmedia protection\n"); + + if (CONFIG(BOOTMEDIA_LOCK_TOPSWAP)) { + /* + * Additionally set a protected range for the BOOTBLOCK region + */ + if (fmap_locate_area_as_rdev("BOOTBLOCK", &dev) < 0) + printk(BIOS_ERR, "BM-LOCKDOWN: Could not find region 'BOOTBLOCK'\n"); + else if (boot_device_wp_region(&dev, lock_type) >= 0) + printk(BIOS_INFO, "BM-LOCKDOWN: Enabled bootmedia protection for BOOTBLOCK\n"); + else + printk(BIOS_ERR, "BM-LOCKDOWN: Failed to enable bootmedia protection for BOOTBLOCK\n"); + } } static void lock(void *unused) diff --git a/src/soc/intel/common/Kconfig.common b/src/soc/intel/common/Kconfig.common index 964a564303..a1a2f39cfb 100644 --- a/src/soc/intel/common/Kconfig.common +++ b/src/soc/intel/common/Kconfig.common @@ -66,6 +66,20 @@ config INTEL_TOP_SWAP_OPTION_CONTROL option. Note that the option must be present in the board's cmos.layout. file. +config TOP_SWAP_REDUNDANCY + bool "Toggle the Intel Top Swap - based redundancy" + depends on HAVE_OPTION_TABLE && INTEL_HAS_TOP_SWAP + select INTEL_ADD_TOP_SWAP_BOOTBLOCK + select MAINBOARD_NEEDS_CMOS_OPTIONS + select INTEL_TOP_SWAP_SEPARATE_REGIONS + select INTEL_TOP_SWAP_OPTION_CONTROL + help + Toggle the Intel Top Swap based redundancy, where the BOOTBLOCK and COREBOOT + regions form a read-only golden copy and TOPSWAP and COREBOOT_TS are an + update partition. CMOS option "attempt_top_swap" decides which of the slots + gets booted, which means the platform can be reverted to the known-good copy + via CMOS reset. + endif config SOC_INTEL_COMMON