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.
Code signing does not encrypt firmware (encryption and signing are separate, often complementary, operations). It authenticates firmware. The process has three steps:
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.
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:
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.
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.
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.
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.
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:
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.
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.
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.
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.
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.
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.
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.