Blog

Code Signing for Embedded Firmware: A Complete Guide for Automotive and Embedded Systems Engineers

July 28, 2026

Every electronic control unit (ECU) on the road today runs firmware that can be updated in the field — over CAN, over UDS, or increasingly over the air. That capability is a huge win for maintenance and feature delivery. It is also the single easiest door for an attacker to walk through, because a flash bootloader that will accept any image will just as happily accept a malicious one.

Code signing closes to that door. It is the mechanism that lets an ECU cryptographically verify that a firmware image was produced by a trusted source and has not been altered since. For any embedded system that supports field-programmable updates — automotive, industrial, medical, aerospace, or military — code signing has moved from "nice to have" to a baseline requirement, driven by standards like UNECE R156, ISO/SAE 21434, and IEC 62443.

This guide covers what code signing does at the protocol level, how it fits into a secure boot chain, the tradeoffs between signing algorithms and key management approaches, and how it gets implemented in a real-time flash bootloader.

What Code Signing Actually Does

Code signing does not encrypt firmware (encryption and signing are separate, often complementary, operations). It authenticates firmware. The process has three steps:

  • Hash The firmware image is run through a cryptographic hash function (typically SHA-256 or SHA-384) to produce a fixed-length digest.
  • Sign The digest is encrypted with the firmware vendor's private key, producing a digital signature. This private key never leaves the vendor's build environment or HSM.
  • Verify The ECU's bootloader holds the corresponding public key. On receipt of a new image, the bootloader re-hashes the received firmware, decrypts the received signature using the public key, and compares the two hashes. A match proves two things at once: the image came from the holder of the private key, and it was not modified in transit or storage.

If the hashes don't match, the bootloader rejects the image and refuses to boot it — typically falling back to the previously known-good image or a minimal recovery mode.

Why Embedded Firmware Needs This

Unsigned firmware update paths have been the root cause of real-world attacks and recalls across the automotive and industrial space. The risk profile for embedded devices differs from general IT software in a few important ways:

  • Field-programmability is mandatory. Nearly every ECU shipped today supports reflashing over UDS, LIN, J1939, UDS or OTA. That update channel is the attack surface.
  • Physical access is common. Diagnostic connectors (OBD-II, J1939 service ports) are standardized and easy to reach, unlike a locked-down data center.
  • Consequences are physical. A compromised infotainment unit is bad; a compromised braking or engine control module is a safety issue, not just a data breach.
  • Long service life. Vehicles and industrial equipment stay in service for 10-20+ years, so a signing scheme has to account for key rotation and algorithm migration over a much longer horizon than typical IT systems.

Regulatory pressure has caught up with this reality. UNECE R156 requires an auditable software update management system for any vehicle type approved in UNECE member markets, and ISO/SAE 21434 treats firmware authenticity as a core cybersecurity control across the vehicle development lifecycle.

Code Signing vs. Secure Boot: Where One Ends and the Other Begins

These terms get used interchangeably, but they solve different problems:

Aspect Code Signing Secure Boot
Primary question answered Is this new firmware image authentic? Is the firmware currently on this device authentic?
When it runs At the update/flash stage, before writing new firmware At every power-on/reset, before executing existing firmware
Root of trust needed Public key stored in bootloader Public key stored in immutable boot ROM or OTP fuses
Protects against Malicious or corrupted update images Firmware tampered with after it's already on the device (e.g., via JTAG or flash reprogramming)
Typical failure response Reject the update, keep running current firmware Halt boot, enter recovery mode, or roll back to a known-good slot

In practice, a robust design uses both: code signing gates what gets written to flash, and secure boot verifies what gets executed from flash every time the device starts. Together they form a chain of trust that starts at an immutable hardware root (boot ROM or a secure element) and extends link by link through the bootloader, application firmware, and any subsequent update payloads.

Signing Algorithms: RSA vs. ECDSA

The two dominant choices for embedded code signing are RSA and Elliptic Curve Digital Signature Algorithm (ECDSA).

Aspect RSA (2048/3072-bit) ECDSA (P-256/P-384)
Signature size Larger (256-384 bytes) Smaller (64-96 bytes)
Key size for equivalent security Larger (3072-bit ≈ 128-bit security) Smaller (256-bit ≈ 128-bit security)
Verification speed on constrained MCUs Slower, more flash/RAM for math libraries Faster, smaller code footprint
Signing speed Slower Faster
Hardware crypto accelerator support Common in higher-end automotive MCUs Increasingly common, especially newer parts
Best fit Legacy toolchains, systems where signature size doesn't matter Resource-constrained MCUs, OTA payloads where every byte counts

For most new automotive and industrial designs with limited flash and RAM, ECDSA (P-256 at minimum) is the more practical choice because verification — the operation that runs on the constrained target — is both faster and lighter than RSA verification. RSA remains common where an existing toolchain or OEM specification already mandates it.

Where the Keys Live: Key Management Approaches

The signing scheme is only as strong as the protection around the private key and the storage of the public key on device.

Aspect Software Keystore Hardware Security Module (HSM) Secure Element / TPM on ECU
Private key location Build server file/env variable Dedicated tamper-resistant hardware at the OEM/Tier 1 N/A — this protects the public key/root of trust on the device
Attack surface High — key can be exfiltrated from a compromised build machine Very low — key never leaves the HSM boundary N/A
Typical use Prototyping, low-volume, non-safety-critical projects Production signing for shipped automotive/industrial firmware Storing the public key and boot-time verification logic immutably on the ECU
Compliance fit Generally insufficient for ISO 21434 / Meets production security expectations Required for a genuine hardware root of trust
UNECE R156 production programs
Cost/complexity Low Higher — dedicated hardware, access controls, audit logging Adds BOM cost per unit, but often already present (crypto-capable MCU)

A production signing pipeline should keep the private key exclusively inside an HSM, with signing requests issued through an authenticated build pipeline — never a developer laptop, a shared network drive, or a CI variable in plaintext.

Implementing Code Signing in a Flash Bootloader

For an ECU, the verification logic lives in the bootloader — the first-stage code that decides whether a new or existing application image is trustworthy before jumping to it. A typical signed-update flow looks like this:

  • Image packaging. The build system compiles the application, computes the hash, signs it with the private key (via HSM), and appends the signature plus a version/metadata header to the binary.
  • Transport. The signed image is transferred to the ECU — commonly via UDS (ISO 14229) request download/transfer data services over CAN, LIN, or Ethernet, or via an OTA channel for telematics-connected vehicles.
  • Staging. The bootloader writes the incoming image to a staging area or inactive flash bank (A/B partitioning is common) rather than overwriting the running application directly.
  • Verification. Before marking the staged image valid, the bootloader hashes it and verifies the signature against the stored public key.
  • Commit or reject. On success, the bootloader updates a valid-image flag or bank-select pointer and reboots into the new image. On failure, the staged image is discarded, the flag is never set, and the ECU continues running the last known-good firmware.
  • Rollback protection. A monotonic version counter (often in OTP or secure NVM) prevents an attacker from "downgrading" to an older, vulnerable signed image that still carries a valid signature.

Because this verification work happens during the update window — not in the real-time control loop — it does not affect the deterministic timing behavior of the running application. A well-designed bootloader keeps the crypto verification path isolated from the hard real-time protocol stack (J1939, CAN, LIN, UDS) that runs once the application is live.

Common Pitfalls

  • Verifying only at flash time, not at boot time. Without secure boot layered on top, firmware can still be tampered with directly in flash after a valid update.
  • No rollback/anti-rollback protection. A validly signed but outdated image can be replayed to reintroduce a fixed vulnerability.
  • Storing the public key in mutable memory. If the public key itself can be overwritten, the whole scheme is defeated — it needs to live in OTP, fuses, or a protected boot ROM region.
  • Treating encryption as a substitute for signing. Encrypting an image protects confidentiality (useful for protecting IP), but by itself does not prove authenticity or integrity.
  • Single key, no rotation plan. Given 10-20 year vehicle service life, a signing scheme needs a defined path for key rotation and algorithm migration (e.g., moving from RSA-2048 to ECDSA P-384) without bricking fielded units.

How Simma Software Fits In

Simma Software's flash bootloaders and protocol stacks — built for UDS, J1939, CAN, CANopen, LIN, and the full range of automotive and industrial transport layers — are designed with secure, field-programmable updates in mind. Our stacks are written in 100% ANSI C with a stable, vendor-independent hardware API (can_tx(), can_rx(), nv_write(), nv_read(), and similar), which makes it straightforward to integrate signature verification into the update path without disturbing the deterministic, hard real-time behavior our stacks are known for — typically ~2% CPU utilization while sustaining ~8,000 CAN frames/sec.

That efficiency matters directly for code signing: verification and hashing routines add CPU and flash overhead, and a protocol stack that already runs lean leaves more headroom for the crypto operations a secure bootloader needs, without pushing a resource-constrained MCU past its limits.

Frequently Asked Questions

Is code signing required by law for automotive ECUs?

UNECE R156 requires vehicle manufacturers approved in UNECE markets to operate an auditable software update management system, which in practice necessitates cryptographic authentication of firmware updates. ISO/SAE 21434 similarly treats firmware integrity as a core cybersecurity requirement across the development lifecycle, though the specific implementation (signing scheme, key management) is left to the manufacturer.

Does code signing slow down firmware updates?

The added overhead is the hash and signature verification step, which on a modern automotive-grade MCU typically adds milliseconds, not a meaningfully perceptible delay to the overall reflash process, which is otherwise dominated by data transfer time over CAN or UDS.

Can code signing be added to an existing, unsigned bootloader?

Yes, but it requires bootloader changes: adding verification logic, defining a signature/metadata format appended to the image, provisioning a public key into protected memory on already-fielded devices (or via a one-time signed update), and updating the build pipeline to sign outputs. It's easier to design in from the start than to retrofit across a large fielded population.

What's the difference between code signing and firmware encryption?

Signing proves authenticity and integrity (who sent it, and was it altered). Encryption protects confidentiality (preventing reverse engineering or IP theft). Many production systems use both: encrypt the image for IP protection, then sign it for authenticity.

Do I need an HSM for a low-volume or prototype project?

Not necessarily at the prototype stage, but any project heading toward production — especially one that needs to meet OEM cybersecurity requirements or ISO 21434 — should plan the migration to HSM-backed signing early, since retrofitting key management practices after a program is already in production is significantly more disruptive.