Blowing Fuses: Locking Down a Production Device
Most secure microcontrollers have one-time-programmable fuses that permanently enable protections: locking debug ports, enabling secure boot, and anchoring keys. Blowing them is how a device goes from development to truly hardened, and forgetting to is one of the most common and most expensive misses I find.
The One-Way Switch
A fuse is a tiny element inside the chip that can be changed exactly once, from its blank state to a programmed one, and never back. That permanence is the entire point. A setting an attacker can flip back in software is not a security boundary, but a fuse, once blown, holds its decision against software, against a reset, and against the manufacturer.
Designers use fuses to make the most important protections sticky. The question for any device is not whether the chip has these fuses, almost all secure parts do, but whether anyone actually blew them before the unit shipped. The gap between the capability and the act is where most of the trouble lives.
What the Fuses Control
The fuses that matter gate the protections you most want enforced: disabling JTAG and SWD so the debug port cannot read memory, enforcing signature verification at boot so the chip refuses unsigned firmware, and locking a key or its hash so it cannot be altered. There are usually others too, like disabling a serial bootloader or a test mode. The common thread is that every one of them converts a software-configurable convenience into a hardware-enforced rule, and before they are blown, a determined attacker can often just turn the protection off.
Reading the Fuse State
The first thing I check on a unit is what state its fuses are actually in, which the vendor tool reports directly. On STM32, that means reading the option bytes and the readout-protection level over the debug interface.
# read the option bytes / protection level from a connected unit
STM32_Programmer_CLI -c port=SWD -ob displRead Out Protection: RDP : 0xAA (Level 0, no protection) nBOOT0 : 1 Write Protection : none # RDP 0xAA means debug and flash read are fully open
An RDP Level 0 reading on what is supposed to be a production unit is a finding on its own. It means the debug port can read flash, the firmware is exposed, and none of the chip’s protection was actually engaged. The tool just told you the door is open.
Why One-Time, and the Shipping Mistake
The value of a fuse comes precisely from the fact that it cannot be undone, even by someone with full access to the chip. A reversible setting invites an attacker to reverse it; a fuse removes that move entirely, which is what lets a downstream system trust that the protection is really on. That same permanence is what makes blowing them a decision to take seriously, since there is no second attempt and no recovery if you lock something you needed open.
Development boards run with fuses unblown so engineers can debug freely and reflash at will, which is correct for development. The danger is shipping production units in the same state, with full debug access and verification disabled, because no one added the fuse step to the manufacturing flow. This is rarely a knowledge problem, it is a process problem: the lock step was never made a required, verified stage, so units leave the line open and nobody notices until an assessment, or an attacker, reads the firmware straight off the debug port.
Audit a Production Unit like an Attacker
Confirming the lock happened means testing a finished unit the way an attacker would, not trusting the build paperwork. Try to read flash over the debug port; if it succeeds, the fuses were never blown, regardless of what the process document claims.
# attempt to read flash from a shipped unit; this should FAIL on a locked device
STM32_Programmer_CLI -c port=SWD -r32 0x08000000 0x100 fw_head.binError: Read operation failed (RDP active?) <- GOOD: protection engaged # vs. on an unlocked unit: # Reading 256 bytes... OK <- BAD: production unit is wide open
A read that fails with a protection error is the result you want on a shipped unit. A read that succeeds means the device is unlocked, the firmware is exposed, and the manufacturing process let an open unit through. The test takes a minute and it is the only way to be sure.
Anchor the Key, Not Just Debug
Fuses do more than disable debug, they anchor the root of trust by storing a public-key hash that the boot ROM checks every signature against. Once that hash is fused, the chip will only run firmware signed by the matching private key, which is what makes secure boot real rather than aspirational. A device that enabled secure boot in software but never fused the key hash is trusting a check it can be talked out of, and skipping that anchor quietly defeats the rest of the design.
Order of Operations, and Plan for Repair
Sequence matters because each step is permanent. Provision the keys and confirm the device boots its signed firmware before you lock anything; then enable secure boot and the key anchor, verify a signed image still runs and an unsigned one is refused, and only then blow the debug-disable fuse as the last step. Lock debug before you have confirmed the signed boot works and you have no way to diagnose the unit that will not start.
Because the operation is permanent, locking everything can strand a unit that later needs field diagnosis or a firmware recovery, so decide how legitimate access will work before you close the door: an authenticated debug unlock that requires a cryptographic challenge, or a signed recovery path that re-flashes authentic firmware without exposing raw debug. Designing the recovery story first, and proving it works on a locked unit, is what lets you commit to the lockdown with confidence instead of regret.
Verify the Lock Took
Blowing the fuse is not the end, confirming it took is. Read the fuse and protection state back after programming, and re-run the attacker’s read test, so the manufacturing record reflects a verified locked state rather than an assumption.
# after locking, confirm RDP advanced and debug read now fails
STM32_Programmer_CLI -c port=SWD -ob displ | grep RDPRDP : 0xBB (Level 1, flash read protected) # and the earlier read test now returns a protection error -> locked and verified
A protection level that advanced and a read test that now fails together prove the lock engaged on this specific unit. Recording that verification per batch, or per unit, is what turns we blow the fuses in production from a claim into something you can stand behind.
A Production Lock-Down Checklist
Before a device ships, a short checklist closes the gap, and every item is a yes-or-no question with a known way to check it:
- Keys provisioned, and the device boots its signed firmware
- Secure boot and the key anchor enabled
- An unsigned image is refused
- The recovery path works on a locked unit
- The debug-disable fuse blown, and verified by a failed read test
The Step That Gets Forgotten
The failure here is almost never ignorance of fuses, it is a manufacturing flow that never includes blowing them. The fix is process, not knowledge: make fuse programming a required, audited stage, sample finished units to confirm it happened, and treat an unlocked production unit as a line defect. The chips give you strong protection; a disciplined manufacturing step is what actually turns it on.
Where This Fits
Reviewing whether a product’s hardware protections were actually enabled at manufacturing, not just designed in, is a core part of a hardware penetration test and a pre-production security review. If you want your production lock-down audited on real shipped units, that is the kind of work we do at Berkner Tech.



