Embedded Systems · Embedded Tooling

Secure Debug Lifecycle: Authentication, Locked Ports, and Recovery

How a debug port is gated by device life-cycle state and certificates, what an open port exposes once keys are readable, and why the lock is one-way once the device ships.

A debug port that can halt the core and read any address is, from a security standpoint, a root credential. It bypasses every access control the software implements, because it does not go through the software. The response in silicon is a gate: the port exists, responds to identification, and refuses the operations that would expose protected state unless the device is in a state that permits them, or unless the tool proves it holds a key.

The threat the gate addresses

Consider a device with a secure boot chain: a boot ROM verifies the first-stage image against a public key stored in one-time programmable memory, and the application keeps its secrets in a region that only privileged code can read. An attacker with an open debug port does not need to defeat the verifier. They halt the core before the verification completes and read the key, or they attach after boot and read the secret region directly. Every layer of software protection is downstream of a hardware capability that ignores it.

The same capability is required for manufacturing test, for failure analysis, and for development. A device that cannot be debugged cannot be diagnosed, and a returned unit whose fault cannot be located cannot be improved. The design problem is therefore not to remove the port but to make its authority conditional, and to make the condition depend on state the attacker cannot forge.

Life-cycle states and the transitions between them

Silicon vendors implement this as a small state machine backed by one-time programmable bits. A typical set of states is: an open state in which the port is fully functional and no protection applies; a provisioning state in which the port is open but the device can be moved forward; a secured state in which the port is closed or requires authentication; and a terminal state in which the port is permanently disabled and the only recovery is a full erase.

Transitions are one-way in the direction that matters. Moving from open to secured is a write to a one-time field, often requiring a key or a signed command. Moving back requires either authentication with a key that only the owner holds, or a mass erase that destroys the protected content along with the protection. The mass erase path is what makes a locked device recoverable for a legitimate owner who has lost the key, at the cost of losing everything the device held.

The important property is that the state is readable before it is changed and that the tool reports it. A debugger that fails to attach with a generic error, when the actual condition is “this device is in the secured state and requires a certificate”, sends the user down a path of checking cables and clock settings. Reading the state out is a few register accesses through the same port that is refusing the rest.

Certificate-based authentication

The more flexible scheme replaces the binary open/closed condition with a challenge. The probe requests debug access; the device returns a challenge derived from a random number and its identity; the probe signs it with a private key and returns the signature along with a certificate chain that terminates in a public key the device trusts. The device verifies the chain, verifies the signature, and grants a permission set.

Two details determine whether this is secure. The first is that the challenge must be fresh. A device that accepts a recorded signature is replayable, and the attack is a matter of capturing one authorised session. The second is that the permission set must be narrow. Granting full access on any valid certificate means a certificate issued for a field-return diagnosis also grants access to the key storage. Real implementations bind the permission to the certificate — read-only memory access, or access excluding a defined protected range, or access that expires after a session.

The certificate also carries a lifetime. A certificate valid indefinitely is a key compromise waiting to happen, and revocation requires the device to check a list, which requires storage and an update path. Most schemes avoid revocation lists and instead rely on short validity windows plus the one-way life-cycle transition for the terminal case.

What the gate does not cover

Three classes of exposure survive a correctly implemented debug gate.

The first is the bus between the core and the memory. A probe that cannot use the debug port can still probe the external memory bus if the memory is external, and can read the contents directly with a logic analyser or a socket. Encryption of external memory contents, with keys held on-chip, is the countermeasure, and it moves the problem to key storage rather than eliminating it.

The second is power and timing. A device that checks its life-cycle state at boot and then grants access based on that check can be induced to skip the check by disturbing its supply or clock. A single voltage glitch at the right instruction can turn a failed comparison into a successful one. Countermeasures include redundant checks, checks at multiple points, randomised timing, and a reset on detected anomaly. None is absolute; the goal is to raise the cost above the value of what is protected.

The third is the debug path itself as an attack surface. A port that remains physically present and responds to identification is firmware running on the device, and firmware has bugs. A parser that handles authentication requests and mishandles a malformed length can be exploited without any key. The mitigation is to keep the authentication handler minimal and to disable the port entirely in the terminal state rather than leaving a handler that answers.

Development versus production

The practical difficulty is that development requires the open state and production requires the closed one, and the same firmware is used for both. The usual arrangement is a provisioning step that programs the life-cycle field and the owner key after the final test, with the transition irreversible.

That step has to be treated as part of the product, not as a script someone runs. If the transition can be triggered by the application itself — a command over a maintenance interface, for instance — then an attacker who reaches that interface can also trigger it, which is fine for the transition to secured but catastrophic if the same interface can reverse it. The key must never be readable from the device after provisioning, which means it is either write-only or derived from a physically unclonable function rather than stored.

The failure mode that matters in practice is a device locked before its firmware is known good. A unit that reaches the terminal state with a defective image has no recovery except the erase path, and if the erase path itself is disabled, the unit is scrap. Keeping a small window in which the device is provisioned but not yet locked, and locking only after a successful boot of the final image, is the sequencing that avoids this. That sequencing interacts with the image validity check described in in-circuit programming and flash algorithms: the bootloader must be able to distinguish a valid image from an interrupted write before the lock is applied, because after it there is no second chance.

Interaction with the rest of the toolchain

The gate changes what the tools can do, and the tools must reflect it rather than fail obscurely. A debugger that cannot halt the core should report the life-cycle state and the required certificate rather than a transport error, because the transport succeeded: the access port answered and refused. That distinction is only visible if the tool distinguishes a protocol fault from an authentication denial, which is a property of the access port’s status reporting described in debug ports and memory access.

Trace has the same exposure and the same treatment. An open trace port reveals the addresses a protected routine executes, which is enough to locate a comparison and its branch, and some implementations gate trace output on the same state as the debug port. Where trace is not gated, the addresses alone are a meaningful leak, and the assumption that trace is harmless because it carries no data is wrong.

The final consequence is for build artifacts. Symbol files and images carry the addresses and the structure of the protected code, and a debug session on a secured device still needs them to decode what little it is permitted to see. Their distribution is a separate decision from the device’s own protection, and the two are frequently inconsistent: a device locked correctly, with a symbol file published openly, discloses the layout the lock was meant to hide.

References

  1. Armv8-M Architecture Reference Manual — Arm Ltd, DDI 0553
  2. Arm Debug Interface Architecture Specification (ADIv5) — Arm Ltd, IHI 0031
  3. IEEE 1149.1-2013: Standard for Test Access Port and Boundary-Scan Architecture — IEEE