Safeguard
Supply Chain Security•

SPI Flash Write Protection Explained: How Firmware Chips Are Locked

SPI flash write protection locks firmware with chip bits, a WP# pin, chipset locks and a root of trust. Learn how each layer works and how to check yours.

Safeguard Security Team
45 min read

SPI flash write protection is the set of locks that stop software from rewriting the small chip that holds a computer's boot firmware. It works in layers: protect bits and a WP# pin on the flash chip itself, lock bits and protected ranges in the chipset's flash controller, and a hardware root of trust that verifies what the chip contains before it runs. On Linux you can check most of it without writing anything, using fwupdmgr security, flashrom's --wp-status and chipsec's SPI modules.

This guide goes one level deeper than our posts on coreboot and verified boot, firmware updates with fwupd and LVFS and how motherboards evolved from BIOS to UEFI, TPM and BMC. Every register name, version and date below comes from NIST, fwupd, flashrom, chipsec, Linux kernel, coreboot, ChromeOS, CERT/CC and AMD documents listed at the end. This post explains how protection works and how to read its status, not how to get around it; the walkthrough commands are read only except one clearly marked vendor firmware update.

Key takeaways

  • The SPI flash is a small serial NOR chip that holds the boot firmware and more: on Intel style systems a flash descriptor, a BIOS region with the UEFI variables (NVRAM), a management engine region and others.
  • The chip has its own protection: block protect bits mark address ranges read only, and a status register protect bit combined with the WP# pin freezes those settings in hardware.
  • On x86, the chipset's SPI controller adds a second layer: BIOS Write Enable (BIOSWE), BIOS Lock Enable (BLE), SMM BIOS Write Protect (SMM_BWP), five Protected Range registers (PR0 to PR4), the FLOCKDN lockdown bit and per region access permissions in the flash descriptor.
  • NIST SP 800-147 (April 2011) requires signed BIOS updates verified by a Root of Trust for Update, flash integrity protection and no way to bypass the update path. NIST SP 800-193 (May 2018) extends this to protection, detection and recovery for all platform firmware.
  • Processor rooted boot verification, coreboot's vboot and Chromebook hardware write protect build on flash protection: a read only region holds the code and keys that verify everything else, and keeping it read only makes the system recoverable.
  • Real failures fall into a few classes: locks the firmware never set, a 2015 race that SMM_BWP fixed, flaws in System Management Mode, NVRAM left outside protected ranges, and physical access with a programmer clip.
  • fwupd puts the Intel SPI checks at HSI:1, the most basic level. Fail them and any root user can write persistent code into firmware.

What is the SPI flash chip, and what lives on it?

Almost every PC, server, router and single board computer boots from a small serial NOR flash chip on the Serial Peripheral Interface (SPI) bus. NIST SP 800-193 says that in most modern platforms the host boot firmware, BIOS or UEFI, is held in a SPI flash device. Code there runs before the operating system and Secure Boot, and survives a disk wipe and reinstall, which makes it the place an attacker most wants to write.

The regions on an Intel style flash

On Intel platforms the chip is divided into regions described by the Intel Flash Descriptor (IFD). The coreboot documentation for flash layouts lists the regions and their conventional names:

IFD region indexRegioncoreboot FMAP nameNotes from the coreboot docs
0Flash DescriptorSI_DESCAlways the top 4 KiB of flash
1BIOSSI_BIOSThe region that holds coreboot or the UEFI firmware
2Intel MESI_MEFirmware for the management engine
3Gigabit EthernetSI_GBENetwork controller configuration
4Platform DataSI_PDRPlatform specific data
8EC FirmwareSI_ECMost ChromeOS devices keep EC firmware in the BIOS region instead

The descriptor sets region boundaries and the permissions that decide which controller may read or write each region. Software that can rewrite it can rewrite those rules, so fwupd and chipsec both treat a writable descriptor as a failure.

Many Arm boards, routers and embedded devices have no IFD; they put a bootloader at a fixed offset. The chip level protections below apply to them too; the chipset section is x86 specific.

NVRAM variables and critical data

A UEFI image also contains a variable store, often called NVRAM, holding boot order, setup options and the Secure Boot keys (PK, KEK, db, dbx). NIST SP 800-193 calls this "critical data" and gives it its own protection, detection and recovery guidelines.

This is the central tension of SPI write protection. Code regions can be locked hard because they change only during an authenticated update. The variable store must stay writable at runtime, which is why NIST SP 800-147 excludes configuration data from its integrity rules. On x86 the usual answer is to route variable writes through System Management Mode (SMM). chipsec's bios_wp documentation notes what happens when that goes wrong: where certain BIOS data was not protected, malware could write the Platform Key on flash and turn Secure Boot off.

How the chip is read and written

A SPI NOR chip takes a one byte opcode, an address and data. The kernel's SPI NOR documentation lists opcodes such as 0x03 (read), 0x0b (fast read) and 0x02 (page program). Writing can only clear bits, so changing data means erasing a block, typically 4 KiB or larger, and programming it again.

To learn a chip's size and modes, software reads its Serial Flash Discoverable Parameter (SFDP) tables. The kernel documentation states that most SPI NOR flashes comply with JEDEC JESD216 SFDP, "a standard set of internal read-only parameter tables". It also says drivers still need explicit entries for settings SFDP does not cover, giving block protection as the example. SFDP is discovery, not protection, which is why flashrom carries its own per chip knowledge of write protection.

There are two ways to reach the chip:

PathHow it worksWhat controls it
In system, through the chipsetSoftware on the host CPU asks the platform's SPI controller to issue commands. On Linux, the spi-intel driver or flashrom's internal programmer do this.Chipset lock bits, protected ranges, descriptor permissions, SMM, and the chip's own protect bits
External programmerA clip or socket connects the chip to a separate device while the board is powered off.Only the chip's own protection and physical access to the board

The Linux kernel's spi-intel documentation is blunt about the in system path. It says the driver exposes the flash read only by default, makes the whole MTD device read only if it finds protection bits set and locked, and warns that overwriting the BIOS image "might render the machine unbootable" and require special equipment to revive. That default is a good one, and it is one of several reasons a stock Linux install cannot casually rewrite firmware.

What protections exist on the chip itself?

The first layer of protection lives inside the flash chip. It applies no matter which controller talks to the chip, which is why it is the last line of defence against an external programmer as well as software.

Block protect bits in the status register

Every SPI NOR chip has one or more status registers. Alongside busy and write enable latch bits, most parts have block protect bits, usually named BP0, BP1, BP2 and sometimes more, plus modifier bits that select whether the range counts from the top or the bottom of the chip. The ChromeOS write protection reference describes the role in one line: the block protect bits "mask the regions within the SPI flash data address space" so that writes and erases to those regions can be controlled.

The ranges are coarse and fixed by the chip design. flashrom's partial write protection guide shows a real list from a 16 MB part: lower or upper 1/4096, 1/2048, 1/1024 and so on up to halves and the whole chip. You choose the smallest supported range that covers what you need. The same guide notes that some chips allow finer sector based control, but that flashrom did not support it as of September 2023. Coarse ranges have a practical consequence covered later: what you protect has to line up with how the firmware image is laid out.

The WP# pin and status register protection

Block protect bits alone are soft. Any software that can send a "write status register" command can clear them. The second piece is the status register protect bit (called SRWD, SRP or SRP0 depending on the vendor) working together with the chip's write protect pin, WP#.

The ChromeOS reference spells out the rule: hardware protection mode requires SRWD set to 1 and the WP# pin asserted low. In that mode the chip no longer accepts the Write Status Register instruction, and SRWD and the block protect bits become read only. flashrom's manual describes the same behaviour from the tool's side: once status register protection is enabled, operations that change the status registers can only be performed if the chip's WP# pin is at an inactive level.

Software chooses the protected range; a pin decides whether that choice can change. flashrom's guide on firmware updates and write protection notes that the pin's job is to lock the state of software protection, so changing the pin alone does not unprotect anything, it only makes protection changeable. The kernel's SPI NOR documentation warns that with WP# tied low and the protect bit set, the flash "will be permanently locked" from software's view. Whether the board ties WP# to ground, a jumper, a screw or a security chip sets the ceiling for chip level protection.

Some chips keep protect bits in non volatile cells; others reset them at power on. The kernel's flash parameter dump shows a SWP_IS_VOLATILE flag for this. Volatile protection must be re engaged by firmware on every boot before untrusted code runs.

One time programmable areas and replay protected counters

Many serial flash parts also have small one time programmable (OTP) security registers that can be written once and locked, used for things like serial numbers. Their size and behaviour vary by part, so the chip's datasheet is the reference.

A newer feature is the Replay Protected Monotonic Counter (RPMC). Current flashrom manuals list options to read RPMC status, write a root key and read or increment counters. fwupd's "AMD SPI Replay protections" check describes the purpose: counters that let the platform detect replay attacks, such as an older but validly signed image put back on the chip.

Limits of chip level protection

Ranges are fixed fractions of the chip that rarely match firmware layouts, the chip has no idea which controller is asking, and locking more makes updates harder. flashrom's guide warns that a locked old boot block can make a later partial update unbootable.

What protections does the chipset add on x86?

On x86 PCs the host CPU never talks to the flash directly. It goes through the SPI controller in the Platform Controller Hub (PCH) or SoC. That controller enforces a second, richer set of protections. We describe them from the register names in fwupd's HSI specification, the chipsec module source, and Intel's own guidance as quoted in the CERT/CC vulnerability note; register layouts differ by chipset generation, and Intel's datasheets are the authority for any specific platform.

BIOS Control: BIOSWE, BLE and SMM_BWP

Three bits in the BIOS Control register form the classic Intel lock. The chipsec bios_wp module and fwupd describe them consistently:

  • BIOS Write Enable (BIOSWE), also called BIOS Write Protect Disable. When set, the BIOS region can be written. fwupd's rule: the bit must be clear, "otherwise userspace can write to the SPI chip".
  • BIOS Lock Enable (BLE). When set, any attempt to set BIOSWE raises a System Management Interrupt (SMI), and the SMI handler decides whether to allow the write.
  • SMM BIOS Write Protect (SMM_BWP), also called EISS on some chipsets. When set, writes to the BIOS region are honoured only while all processors are in SMM. fwupd's wording: it must be set "to make the BIOS region non-writable unless all processors are in system management mode".

Together these move firmware write decisions into SMM, which is how a signed capsule update can write flash while a root user cannot.

Protected Range registers and FLOCKDN

The SPI controller also has Protected Range registers, PR0 to PR4 in the chipsec source. Each has a base, a limit and enable bits for read protection (RPE) and write protection (WPE). Protected ranges are enforced by the controller for every access from the host, including from SMM, so they are stronger than the SMM path for anything that should never change outside an update.

The catch, in chipsec's own words, is that protected ranges are often used "only to protect part of the BIOS region (usually the boot block)", leaving other important data such as NVRAM exposed. chipsec's bios_wp module passes only if SMM based protection is correctly configured or the protected ranges cover the entire BIOS region.

The lockdown bit FLOCKDN, in the Hardware Sequencing Flash Status register, locks the controller configuration including the protected ranges "until reset", according to chipsec's spi_lock module. fwupd's "Read-only SPI Descriptor" check also requires FLOCKDN so that configuration registers in the SPI BAR cannot be changed.

Flash descriptor access permissions

The flash descriptor holds a master access section: for each requester (host CPU, management engine, network controller and others on newer chipsets), which regions it may read and which it may write. chipsec reads these through the FRAP register fields BRRA (BIOS region read access) and BRWA (BIOS region write access). Its spi_desc module checks that software cannot write the descriptor itself, and its spi_access module reports the permissions the descriptor grants. chipsec's docs say a writable descriptor is "often used for debugging" but should not exist on production systems.

There is also a hardware override. The Flash Descriptor Override Pin Strap, reported as HSFS.FDOPSS, tells the controller to ignore descriptor permissions. chipsec's spi_fdopss module notes that on some systems this strap "may be routed to a jumper on the motherboard". It exists for manufacturing and recovery, and it should not be asserted on a machine in service.

Management engine manufacturing mode

fwupd's HSI specification includes a check named org.fwupd.hsi.Mei.ManufacturingMode, and chipsec has a me_mfg_mode module. Both look for a management engine that is still in the mode used on the factory line, where many locks are not yet final. This is a direct example of the "bits left unlocked by the factory" class covered below.

AMD platforms

AMD systems use a different controller and different names, and the chipsec SPI modules above are Intel specific. fwupd's HSI specification has AMD specific checks: org.fwupd.hsi.Amd.SpiWriteProtection ("SOCs may enforce control of the SPI bus to prevent writes other than by verified entities", needed for HSI:2), org.fwupd.hsi.Amd.SpiReplayProtection (needed for HSI:3), org.fwupd.hsi.Amd.PlatformSecureBoot and org.fwupd.hsi.Amd.RollbackProtection. Each says the end user cannot fix a failure directly and should contact the OEM for a firmware update. chipsec also contains a module named rom_armor; we did not review its documentation, so we do not describe it here.

Why the order of locking matters

Firmware sets these locks during boot, so timing is security. NIST SP 800-193 says integrity protections must be always on "or must be engaged prior to execution of code outside of the CTU", the chain of trust for update. Locks set after an option ROM or shell has run leave a window, and the S3 resume path must reapply them, which is why chipsec has a uefi.s3bootscript module.

What do NIST SP 800-147 and SP 800-193 require?

These two publications are the closest thing to a common rulebook for flash protection. We confirmed both dates on NIST's publication pages: SP 800-147, BIOS Protection Guidelines, was published in April 2011, and SP 800-193, Platform Firmware Resiliency Guidelines, in May 2018.

SP 800-147: authenticated update, integrity, non bypassability

SP 800-147 is written for PC client BIOS and has four core requirements in section 3.1:

  1. BIOS update authentication. A Root of Trust for Update (RTU) verifies signed images, using an approved FIPS 186-3 algorithm with at least 112 bits of security strength. It "should prevent the unauthorized rollback" to an older version with a known weakness.
  2. Secure local update (optional). Unsigned updates only with physical presence, for the first image or recovery.
  3. Integrity protection. Flash protected by a mechanism "that cannot be overridden outside of an authenticated BIOS update", preferably enforced in hardware.
  4. Non bypassability. No DMA or on board microcontroller may write firmware outside the authenticated path.

The chipset locks map onto these almost one for one: SMM_BWP and BLE make the SMM update path exclusive, protected ranges and FLOCKDN give hardware integrity, and descriptor permissions stop other controllers from bypassing the host.

SP 800-193: protection, detection, recovery

SP 800-193 widens the scope from the BIOS to every platform device with firmware, and adds two principles to protection: detection and recovery. It defines three roots of trust (for update, for detection and for recovery) and three platform properties:

  • Protected: all critical platform devices meet the protection guidelines.
  • Recoverable: all critical devices can detect corruption and recover from it.
  • Resilient: all critical devices meet all the guidelines.

It moves to FIPS 186-4, requires verification "prior to the non-volatile storage completion of the update process", and names bypass paths to close, including "development or diagnostic interfaces that allow access to flash regions", DMA and rowhammer.

RequirementSP 800-147 (2011)SP 800-193 (2018)
ScopePC client system BIOSAll platform firmware and critical data
Signed updatesYes, FIPS 186-3, at least 112 bit strengthYes, FIPS 186-4, at least 112 bit strength, verified before the update is committed
RollbackShould prevent unauthorized rollbackCarried forward through the update guidelines
Physical presence updateOptional secure local updateOptional secure local update
Integrity protection of flashHardware enforced, not overridable outside an updateMust be engaged before code outside the chain of trust runs
Detection of corruptionNot a core requirementRequired for Recoverable and Resilient platforms
RecoveryRecovery must use authenticated update or secure local updateA root of trust for recovery restores code and critical data
Critical data such as NVRAMExcluded from the integrity rulesExplicitly protected, detected and recovered

How do hardware roots of trust and verified boot build on flash protection?

Write protection answers "can this be changed?". A root of trust answers "is what I am about to run the right code?". Each makes the other stronger. If the root of trust verifies everything, a write that slips through is detected at the next boot. If the root of trust's own code and keys sit in a write protected region, an attacker cannot simply replace the verifier.

Processor rooted boot verification

On many current PCs the CPU verifies the first firmware code before running it. fwupd's HSI specification describes Intel's feature as one that "prevents the machine from running firmware images not released by the system manufacturer", using keys fused into the processor to verify Authenticated Code Modules in the SPI flash, and describes AMD Platform Secure Boot in the same terms. Failures resolve only through the OEM, because these settings are fused by the manufacturer. This layer turns a successful flash write into a failed boot rather than a persistent implant, as long as the verified region covers the code that matters.

coreboot vboot: a read only root and A/B updates

coreboot's verified boot documentation explains the design in practical terms. With vboot, the root of trust "is basically the read-only portion of the SPI flash". The firmware is protected using the chip's WP# pin plus write protect bits in the status register set during manufacturing, and on x86 the protected area is "typically 1/4th of the SPI flash part size". Without a hardware change to the board, that portion keeps its manufactured state for the system's lifetime.

The layout has four parts:

SectionWhat it holdsWritable in the field?
Read only sectionBoot block, verstage and recovery firmware in a coreboot file systemNo, hardware write protected
GBB (Google Binary Blob) areaInside the read only section; holds a 4096 or 8192 bit RSA root public keyNo
Read/write section ASigning key, signature and most firmware (romstage, ramstage, payload, microcode, silicon init)Yes, through updates
Read/write section BA second copy of the sameYes, through updates

Updates write whichever read/write section is not in the "successfully booted" state. If the new section fails to boot, vboot falls back to the other one, and if neither verifies, it enters recovery mode from the read only section. The documentation's conclusion is the point of the whole design: as long as SPI write protection is in place "the system is always recoverable". vboot also records measurements in the TPM, which connects flash protection to measured boot and remote attestation. Our post on secure boot, trusted boot and measured boot covers that link.

Chromebooks: screws, switches and a security chip

The ChromeOS write protection reference says the RO firmware runs first, verifies the next stage, and is guaranteed by the WP signal: even if ChromeOS were fully compromised, "any RO firmware write attempts from code running on the CPU would be stopped by the flash chip itself". Older Chromebooks controlled the signal with a screw inside the case. Newer ones route it through a security chip running Cr50 firmware, which can be configured so only device owners can disable protection. The stated goal is that disabling protection needs extended physical access, while owners stay free to run their own firmware.

ChromeOS also separates hardware and software write protection: a device can ship with the pin asserted but software protection off, enabling it later, for example after moving from development to production signing keys. The embedded controller has its own protection driven by the same signal. See our post on ChromeOS release history and verified boot.

A root of trust does not make the rest of the flash safe to leave writable. NVRAM usually sits outside the verified region, so if the OS can write it, Secure Boot keys can change even when every byte of code is verified.

What breaks protection in practice?

The attack classes below are described conceptually, with the fix and the lesson for each. We do not give steps to reproduce any of them.

Locks the firmware never set

The simplest failure is that the locks exist in hardware but nobody turned them on. A CERT/CC note from 31 March 2017, VU#507496, describes UEFI firmware for two mini PC models that failed to set the BIOSWE, BLE, SMM_BWP and PRx bits, and whose firmware images were not signed and were served over plain HTTP without a checksum. The note says this was a vulnerable implementation of a reference design that did not appear to be affected by default. In other words, the platform could protect itself; the shipped configuration did not.

Related cases are descriptor regions left writable for debugging, the descriptor override strap left asserted, and management engine manufacturing mode left on. fwupd's HSI checks for all of these sit at the lowest levels precisely because they are configuration mistakes rather than deep design flaws.

Fix and lesson. Firmware updates from the manufacturer that set the locks during boot. For buyers and fleet owners, measure rather than assume: fwupd's specification says HSI only measures protections "that can be verified by the end user" without extra hardware or turning off security layers.

The race between write enable and the SMI handler

BLE was designed so that setting BIOSWE raises an SMI, and the SMI handler clears BIOSWE if the write is not allowed. CERT/CC note VU#766164, released 5 January 2015, describes a race condition in chipsets that rely solely on BIOSWE and BLE: writes could occur in the short window between setting BIOSWE and the SMI handler clearing it. The note says the impact included writing code to platform firmware and, where the UEFI variable region relied on the same lock, bypassing UEFI Secure Boot.

Fix and lesson. Intel's statement quoted in the note says the issue is mitigated by setting SMM_BWP along with BLE and clearing BIOSWE, because SMM_BWP requires the processor to be in SMM for BIOS writes to be honoured. The general lesson is that an interrupt based "undo" is weaker than a rule enforced on every access. chipsec's bios_wp module now treats a missing SMM_BWP as a failure for this reason.

Flaws in System Management Mode itself

Once SMM is the gatekeeper for flash writes, a bug in SMM code or SMM configuration becomes a flash protection bug. CERT/CC note VU#434994 covers multiple race conditions due to time of check to time of use flaws in various UEFI implementations. AMD security bulletin AMD-SB-7014, "SMM Lock Bypass", describes CVE-2023-31315: improper validation in a model specific register could let a program with ring 0 access modify SMM configuration while the SMI lock is enabled. AMD rates it High with a CVSS score of 7.5, and its mitigation table lists platform initialization firmware releases dated in 2024, delivered to OEMs as BIOS updates. fwupd's HSI specification checks AMD SMM lockdown and reports not-valid on systems vulnerable to the issue it calls Sinkclose.

Fix and lesson. These are fixed by firmware updates from the OEM, sometimes alongside microcode. The lesson is that SMM is part of your firmware's trusted computing base and needs the same patch discipline as the operating system kernel. Our post on CPU microcode updates covers the related microcode path.

Protected ranges that leave data exposed

chipsec's documentation notes that protected ranges are often used only for the boot block, leaving NVRAM and other data writable through whatever SMM allows. If SMM protection is misconfigured or buggy, that data is open. The cited 2013 research on a software bypass of Windows 8 Secure Boot, referenced in chipsec's source, is an example: where certain BIOS data was not protected, malicious code could alter the Platform Key on flash.

Fix and lesson. Protect all code with hardware enforced ranges, keep SMM based protection for the variable store, and verify Secure Boot state from a measured boot log rather than trusting the variables alone.

Physical access with a programmer clip

With the board powered off, an external programmer clipped onto the chip bypasses the chipset entirely. Only the chip's own protection and a root of trust that verifies flash at boot stand in the way. NIST's secure local update path is built around physical presence, and ChromeOS aims to make disabling protection need extended physical access rather than make it impossible.

Fix and lesson. Processor rooted verification turns tampering into a failed or detected boot, measured boot lets a fleet detect changes, and physical controls matter for high risk machines.

Timeline

DateEventSource
April 2011NIST publishes SP 800-147, BIOS Protection GuidelinesNIST CSRC
2013Research on a software bypass of Windows 8 Secure Boot through unprotected BIOS data, later cited by chipsecchipsec bios_wp source
March 2014First chipsec release, announced at CanSecWest 2014chipsec README
5 January 2015CERT/CC VU#766164: race condition in the BIOSWE and BLE lock; mitigation is SMM_BWPCERT/CC
31 March 2017CERT/CC VU#507496: firmware failing to set BIOSWE, BLE, SMM_BWP and PRx, with unsigned imagesCERT/CC
May 2018NIST publishes SP 800-193, Platform Firmware Resiliency GuidelinesNIST CSRC
fwupd 1.5.0First HSI SPI checks: BIOSWE, BLE and SMM_BWP at HSI:1fwupd HSI specification
fwupd 1.6.0Read only SPI descriptor check at HSI:1fwupd HSI specification
fwupd 1.8.4fwupdmgr security gives per failure recommendationsfwupd HSI specification
2024AMD-SB-7014, SMM Lock Bypass (CVE-2023-31315); fixes delivered as OEM BIOS updatesAMD

How do chip, chipset and platform protections compare?

LayerExamplesWhat it stopsWhat it does not stopWho configures it
Chip levelBlock protect bits, status register protect bit, WP# pin, volatile or non volatile protect bits, OTP areasWrites to protected ranges from any controller and, with WP# asserted, from an external programmer that leaves the pin assertedWrites to unprotected ranges; anyone who can change the pin stateBoard designer (pin wiring), firmware or factory (bits)
Chipset level (x86)BIOSWE, BLE, SMM_BWP, PR0 to PR4, FLOCKDN, descriptor permissions, FDOPSS strapWrites from the OS, drivers and other on board controllers outside the firmware's update pathExternal programmers; bugs in SMM; locks the firmware never setFirmware at every boot, locked until reset
Platform root of trustProcessor rooted boot verification, coreboot vboot, Chromebook RO firmware with Cr50Running unverified firmware code after any write, including physical onesUnverified data such as NVRAM if not covered; a compromised signing keyOEM at manufacturing (fuses, keys)
Detection and recovery (SP 800-193)Measured boot into a TPM, A/B firmware slots, recovery firmware, dual flash chipsPermanent loss of a working platform after corruptionThe initial compromiseOEM design, owner policy

How to check SPI flash protection on Linux, step by step

Everything in Steps 1 to 6 reads state; nothing writes the flash. Step 7 is the only write, and it uses the vendor's signed firmware through fwupd.

Warning. Do not run flash write, erase, --wp-disable or --wp-range commands while following this guide, and do not unbind the kernel's SPI driver to "get better access". flashrom's own manual notes that unbinding the driver "gives up the protections the kernel driver enforces". A bad write can leave a machine unbootable and may need an external programmer to recover. If you are investigating a machine you suspect is compromised, collect results and hand the device to your incident response team instead of experimenting on it.

Step 1: get the fwupd Host Security ID report

fwupd's HSI report is the friendliest starting point. It reads the same chipset bits as the specialist tools, explains failures, and works without turning off Secure Boot.

# Confirm fwupd is installed and recent enough (1.8.4 or later gives recommendations)
fwupdmgr --version

# Print the Host Security ID and every attribute
fwupdmgr security

Look for the SPI and boot verification attributes. On Intel systems the four SPI checks below are all HSI:1 requirements, according to the specification:

AttributePassing resultWhat a failure means
org.fwupd.hsi.Spi.Bioswenot-enabledBIOS write enable is on; firmware can be written from userspace
org.fwupd.hsi.Spi.BleenabledBIOS Lock Enable is off; BIOSWE can easily be set
org.fwupd.hsi.Spi.SmmBwpenabledBIOS region writable outside SMM
org.fwupd.hsi.Spi.DescriptorlockedDescriptor writable (not-valid) or SPI BAR not locked (not-locked)
org.fwupd.hsi.IntelBootguard.*enabled, verified, policy and OTP setProcessor rooted verification not fully set up
org.fwupd.hsi.Mei.ManufacturingModelockedManagement engine still in manufacturing mode
org.fwupd.hsi.Amd.SpiWriteProtectionenabledSPI bus writes not restricted to verified entities (HSI:2)
org.fwupd.hsi.Amd.SpiReplayProtectionenabledNo replay protected counters (HSI:3)
org.fwupd.hsi.Amd.PlatformSecureBootenabledProcessor rooted verification not set up

HSI:0 means a system that "can easily be modified from userspace"; HSI:1 is basic; HSI:2 adds protection against local attackers; HSI:3 adds out of band protection; HSI:4 adds encryption and execution protection; HSI:5 has no tests yet. A ! suffix flags a runtime problem such as Secure Boot off. The specification suggests HSI:3 or higher for PCs with confidential documents. For SMM_BWP failures fwupd says to turn off CSM boot and enable Secure Boot; for most other SPI failures, contact the OEM for a firmware update.

Step 2: find out which flash device and driver you have

# Is the kernel's MTD layer exposing the firmware flash?
cat /proc/mtd

# Which driver owns the SPI controller? (look for spi-intel or similar)
lspci -k | grep -i -A3 'spi\|serial bus'

# On boards whose SPI NOR is handled by the kernel's spi-nor framework
# (common on Arm and embedded systems), the chip identifies itself in sysfs.
# Check that the path exists before reading it.
ls /sys/bus/spi/devices/ 2>/dev/null
cat /sys/bus/spi/devices/spi0.0/spi-nor/partname 2>/dev/null
cat /sys/bus/spi/devices/spi0.0/spi-nor/jedec_id 2>/dev/null
cat /sys/bus/spi/devices/spi0.0/spi-nor/manufacturer 2>/dev/null

These sysfs files are the ones the kernel's SPI NOR documentation uses. On an Intel PC you more often see one MTD device named BIOS, read only unless the kernel was booted with spi_intel.writeable=1.

# Confirm the firmware flash is not exposed writable by the kernel
grep -o 'spi_intel.writeable=[0-9]' /proc/cmdline || echo "spi_intel.writeable not set (default read only)"

On embedded Linux systems where the firmware flash is an MTD device, mtd-utils can report the chip's lock state without changing it. Confirm the device first, because /dev/mtd0 on one board may be a different chip on another:

# Device check: make sure you are looking at the right MTD partition
cat /proc/mtd
# Read only query of lock state (the -i flag only reports)
sudo flash_lock -i /dev/mtd0

Step 3: read the chip's write protection with flashrom

flashrom can report the chip's status register protection and protected range. Write protection support was added in flashrom 1.3.0, according to its partial write protection guide.

flashrom --version

# Identify the chip without reading the whole flash
sudo flashrom --programmer internal --flash-name
sudo flashrom --programmer internal --flash-size

# Read only: current protection mode and range
sudo flashrom --programmer internal --wp-status

# Read only: the ranges this chip supports
sudo flashrom --programmer internal --wp-list

You will see one of three outcomes:

  • A Protection range and Protection mode line. Mode disabled with range none means the chip protects nothing and you rely on the chipset and root of trust.
  • WP operations are not implemented for this chip: flashrom does not know this chip's protection layout.
  • Chip write protection unavailable. The manual explains that when the kernel's spi-intel driver owns the controller, flashrom uses the MTD device, where "protected range handling and chip write protection are unavailable". That is normal, not a reason to unbind the driver.

Optionally, take a read only backup for reference. Locked regions such as the management engine region may not be readable from the host.

# Read only backup of the readable flash contents, then record a hash
sudo flashrom --programmer internal --read firmware-backup.bin
sha256sum firmware-backup.bin

Store the backup and its hash off the machine. Do not write it back with flashrom unless you are recovering a bricked board on a bench, and even then follow the board maker's recovery process first.

Step 4: run chipsec's SPI modules on a test machine

chipsec is the most detailed open source tool for chipset configuration checks. It runs on Windows, Linux and the UEFI shell. Two practical notes from its documentation and fwupd's:

  • The chipsec2 branch is now the default. Its README says the chipsec1 branch is needed for older Intel platforms: client platforms before 12th Gen Core and servers before 3rd Gen Xeon Scalable.
  • fwupd's HSI specification notes that running chipsec usually means turning off UEFI Secure Boot and allowing third party unsigned kernel modules. For that reason, run it on a dedicated test unit of the same model, or a machine you can re enable Secure Boot on afterwards, not on a production endpoint. chipsec's README also says it is security testing software to use at your own risk and asks you to read its WARNING.txt first.
# On a test unit, from a chipsec checkout or package, run the SPI checks one at a time
sudo chipsec_main -m common.bios_wp      # BIOSWE, BLE, SMM_BWP and PR0..PR4 coverage
sudo chipsec_main -m common.spi_lock     # FLOCKDN: controller configuration locked until reset
sudo chipsec_main -m common.spi_desc     # descriptor not writable by the host (FRAP.BRWA)
sudo chipsec_main -m common.spi_access   # region access permissions in the descriptor
sudo chipsec_main -m common.spi_fdopss   # descriptor override strap not asserted
sudo chipsec_main -m common.me_mfg_mode  # management engine not in manufacturing mode

Each module prints PASSED, FAILED or a warning with the register values it read. spi_access notes that some platforms "may use alternate means of protecting these regions", so treat its output as a prompt to investigate rather than a verdict.

Step 5: check ChromeOS devices

On Chromebooks in developer mode, the ChromeOS reference gives three read only checks:

# Hardware write protect switch: 1 means enabled
crossystem | grep wpsw

# Application processor flash: software write protect and protected range
futility flash --wp-status

# Embedded controller flash protection
ectool flashprotect

The reference notes that the protection range is independent of the software write protect status. If software protection is off, the range can still be changed, even if it currently looks correct.

Step 6: apply the vendor's firmware update

Most failures above are fixed by the manufacturer's firmware. On Linux, fwupd installs signed updates published by vendors to the Linux Vendor Firmware Service, using the authenticated update path that SP 800-147 describes. This is a firmware write, so check the device first and make sure you have power.

Warning. A firmware update writes flash. Plug the machine into mains power, close other work, and confirm the device ID matches the system firmware you intend to update before you run fwupdmgr update.

# Device check: list devices and confirm the system firmware entry and its current version
fwupdmgr get-devices

# Refresh metadata and see what is available
fwupdmgr refresh
fwupdmgr get-updates

# Apply updates; fwupd asks for confirmation and usually needs a reboot
fwupdmgr update

# After the reboot, re-run the report and compare
fwupdmgr security

If no update is available and your model fails HSI:1 checks, raise it with the manufacturer, quoting the attribute names. Our fwupd and LVFS post covers how capsule updates work in detail.

For a fleet, record the HSI level and failing attributes per model and firmware version. One failing unit suggests a different firmware version or setting; every unit failing means a firmware design issue that only a vendor update fixes.

Common mistakes

  • Treating write protection as one switch. Chip bits, the WP# pin, chipset locks, SMM and a root of trust each cover different attackers. Passing one says little about the others.
  • Assuming a modern machine ships locked. CERT/CC notes show shipped firmware that never set the basic locks. Measure with fwupdmgr security instead of trusting a datasheet or a marketing page.
  • Protecting only the boot block. chipsec warns that protected ranges often cover only the boot block, leaving NVRAM exposed through whatever SMM allows. Secure Boot keys live there.
  • Locking too late. SP 800-193 requires protections to be engaged before code outside the chain of trust runs. Locks set after option ROMs or a shell run leave a window.
  • Running chipsec on production endpoints. It may require turning off Secure Boot and loading unsigned kernel modules. Use a test unit of the same model.
  • Unbinding the kernel SPI driver to make tools work. flashrom's manual warns this gives up the kernel's protections. Partial results are better than an exposed controller.
  • Leaving spi_intel.writeable=1 on a kernel command line after a one time maintenance task.
  • Ignoring rollback. Old firmware with a known flaw is still validly signed. SP 800-147 says updates should prevent unauthorized rollback.
  • Forgetting the embedded controller and other devices with their own flash, which SP 800-193 lists as platform devices.
  • Not keeping a recovery path. Protection without a known good image turns a failed update into a dead machine.

FAQ

How do I check if my BIOS is write protected on Linux?

Run fwupdmgr security and look at the Spi.Bioswe, Spi.Ble, Spi.SmmBwp and Spi.Descriptor attributes on Intel systems, or the AMD SPI attributes on AMD systems. For the chip's own protection, run sudo flashrom --programmer internal --wp-status. Both commands only read state.

What is the WP# pin on a SPI flash chip?

It is the chip's hardware write protect input. When the status register protect bit is set and WP# is held low, the chip refuses to change its status register, which freezes the block protect bits and therefore the protected range. How the pin is wired (tied low, to a jumper, a screw or a security chip) decides how strong chip level protection is.

What are BIOSWE, BLE and SMM_BWP?

They are bits in the Intel chipset's BIOS Control register. BIOSWE allows writes to the BIOS region when set and should be clear. BLE makes any attempt to set BIOSWE raise an SMI so firmware can refuse it. SMM_BWP makes BIOS region writes work only while the CPU is in System Management Mode, which closes the race described in CERT/CC VU#766164.

What is a good HSI score in fwupd?

The fwupd specification describes HSI:1 as the most basic level and suggests HSI:3 or higher for PCs with confidential documents. HSI:0 means the firmware can easily be modified from userspace. HSI:5 cannot be reached yet because no tests exist for it.

Can malware write to the SPI flash?

On a correctly configured platform, malware with root access should not be able to write firmware code regions, because the chipset only allows writes through the firmware's authenticated update path in SMM. Where locks are missing, SMM has a bug, or data regions are unprotected, it can. That is why fwupd places the SPI lock checks at HSI:1.

Does Secure Boot protect the SPI flash?

No. UEFI Secure Boot verifies bootloaders and drivers that firmware loads, but it relies on the firmware and its variable store being intact. Flash write protection and processor rooted boot verification protect the firmware that enforces Secure Boot. CERT/CC VU#766164 notes that a bypass of the flash lock could also bypass Secure Boot where the variable region relied on that lock.

What does NIST SP 800-147 require?

It requires BIOS updates to be signed and verified by a Root of Trust for Update, using an approved algorithm with at least 112 bits of security strength; an optional secure local update that requires physical presence; hardware enforced integrity protection of flash; and no way to bypass the authenticated update path. It was published in April 2011.

What is the difference between NIST SP 800-147 and SP 800-193?

SP 800-147 (2011) covers protecting PC BIOS from unauthorized modification. SP 800-193 (2018) covers all platform firmware and critical data and adds detection of corruption and recovery to a known good state, defining Protected, Recoverable and Resilient platforms.

Where Safeguard fits

Safeguard does not scan firmware, read SPI flash, check chipset registers or produce a hardware bill of materials, and it does not replace fwupd, chipsec or flashrom for the checks above. Its fit here is indirect and sits around the software you build. The tools that report HSI scores, the scripts that collect fwupd output across a fleet, the open firmware builds some teams maintain, and the provisioning images for the machines you are hardening are all ordinary software projects with open source dependencies. Safeguard scans those repositories, container images and SBOM files for known vulnerabilities, shows which projects contain a given component and version, applies policies and gates, and can open fix pull requests when a fixed version exists.

Firmware hardening is only as good as the software pipeline around it: the inventory tool that records HSI results, the image that reinstalls a machine after a firmware recovery, and the build of coreboot or a payload pulled from public repositories all bring in open source components that need the same patch discipline. The section below describes how Safeguard closes the gap between a published fix and the software you ship, for the dependencies and images you build yourself.

Fix it without waiting for upstream

Whatever the vulnerability, most of the risk sits in two gaps. The first is the time between a fix being published and that fix actually running in your production builds. The second, and worse, is the time before any fix exists at all, while a maintainer works out a patch and a release schedule. Waiting through both gaps is a habit, not a requirement. Safeguard gives teams three ways to close them.

1. Autonomous remediation: pull requests, not tickets

When a fixed version exists, Safeguard's Griffin models open a tested, policy gated pull request that moves the affected dependency to the safe version. You can run it on one repository or in bulk across every project that carries the vulnerable version. Remediation covers eight categories, including dependencies, licenses, security posture and findings. Reachability analysis ranks the vulnerable code paths your application actually calls first, so the first pull requests you merge are the ones that matter most. Autonomous remediation ships switched off, with every category set to Manual, so your team decides how much runs on its own and what still needs a human approval.

2. Gold Open Source: the safe version in seconds, free

gold.safeguard.sh is free and needs no login. Search any CVE or package to see affected and fixed versions, CVSS, EPSS, CISA KEV status and a recommended safe version, or use the "Am I affected?" checker. The same data is available through a free read API, README status badges and RSS threat feeds. The safeguard-sh/gold-scan-action GitHub Action can fail a build on a known exploited vulnerability, on any known vulnerability, or never, so a version you have just removed cannot quietly come back in next week's merge.

3. Gold Registry: start from components that are already fixed

registry.safeguard.sh provides hardened, drop in replacements for upstream packages and container images. Every Gold artifact is held continuously to zero exploitable critical or high CVEs, zero malware and a completed license check, with SLSA L3 or higher provenance, a Sigstore signature and a public evidence page you can hand to an auditor. An artifact loses its Gold badge if it regresses. Teams can point their own package directory at the registry so hardened equivalents resolve without changing how developers install anything.

When upstream has no fix yet, or will not ship one, Safeguard first works to get the fix accepted upstream. If the issue is severe or upstream will not move, Safeguard builds a fork, fixes the vulnerability there and publishes a hardened Gold build, so you are not stuck on a maintainer's release schedule. You can also request a hardened, compatibility tested build of a specific package. This fork and patch flow is in early access today, so ask which packages it covers before you plan around it.

Your situationWhat to use
A fixed version existsAutonomous remediation opens the upgrade pull request; Gold Open Source confirms the safe version
You need to know today whether you are affectedGold Open Source lookup and "Am I affected?" checker, free and without login
You want vulnerable versions to stop shippingThe Gold scan GitHub Action in CI, plus Safeguard policies and gates
Upstream has no fix yet, or will not ship oneA custom Gold request; fork and patch (early access)
You want to start clean on new projectsPull hardened components and images from Gold Registry

One honest limit: when the vulnerable code lives in a vendor appliance, a hosted service or an operating system runtime you do not build yourself, the fix still has to come from that vendor or distribution. The steps above apply to the open source dependencies and container images you build and ship, which is where most teams carry the largest and least tracked share of their exposure.

See how Safeguard would help

The demos below show Safeguard on ordinary software projects, not on firmware or flash chips. They apply to the repositories around firmware hardening: fleet scripts that collect fwupdmgr security output, inventory services that store HSI results, and the images used to rebuild machines.

The first demo is a real Safeguard CLI session. After install, safeguard opens the interactive terminal, you ask it to fix the lodash CVE in a repository, and it reads the finding and advisory, asks before each command, edits package.json to lodash 4.17.21, runs npm install and npm test with your approval, prints a summary and pushes nothing. It ends with /permissions, /model and /scan. The same ask, approve and test loop suits a fleet tooling repository, where nobody should change code that runs on every machine without review.

Click through it at your own pace, or open it full screen.

Firmware test benches and image build hosts are often on restricted networks. The local runner demo shows how to set up the runner on your own machine, approve it with its device code, and then scan from the terminal. A runner on a build host can scan the provisioning image tree and the containers stored there without sending them elsewhere.

Click through it at your own pace, or open it full screen.

If your team uses Claude, the third demo shows how to connect Claude to the Safeguard MCP server with OAuth and choose which tools Claude can use. An engineer can then ask about known vulnerabilities in the projects that hold your fleet and provisioning tooling, using only the tools you allowed.

Click through it at your own pace, or open it full screen.

To try it on your own repositories, download Safeguard and follow the CLI documentation.

Quick check

fwupd reports Spi.Ble as enabled and Spi.Bioswe as not-enabled, but Spi.SmmBwp fails. Is the BIOS region protected?

Only partly. BLE makes an attempt to set BIOSWE raise an SMI, but without SMM_BWP the platform depends on that SMI handler winning a race, the weakness CERT/CC described in VU#766164 in 2015. fwupd's suggested resolution is to turn off CSM boot and enable Secure Boot in the firmware setup, then re-run fwupdmgr security. If it still fails, ask the manufacturer for a firmware update.

flashrom --wp-status says protection is disabled on an Intel laptop that passes every fwupd HSI:1 check. Is the laptop exposed?

Not necessarily. Many PCs do not use chip level protection and instead rely on chipset locks (BIOSWE, BLE, SMM_BWP, protected ranges, FLOCKDN) and processor rooted boot verification. Those stop software attacks. Chip level protection with the WP# pin asserted matters mainly against external programmers, where boot verification and physical controls are the other defences.

Sources

Last reviewed: 24 October 2026. Firmware locks, tool options and HSI attributes change between platform generations and releases; check your manufacturer's firmware notes and the current fwupd, flashrom and chipsec documentation before acting.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.

Self-healing security runs on Safeguard.

Your first fix PR is minutes away.

No sales call required, even your agent can complete the purchase over MCP.