Agent Wranglers

IOT-9Required

Verify the firmware signature on the device

Sign every firmware image with a key kept offline in a hardware security module. The device checks the signature against a public key in protected storage before it writes the image, and again at every boot.

How to do it

Whoever can push unsigned firmware owns every device that accepts it. A signature from a key your update server never holds stops a hijacked server or domain. Put the public key in one-time programmable memory, a secure element or the boot ROM, so firmware cannot replace it. Secure boot repeats the check at power-on, which catches changes made through a debug port. Describe each image in a signed manifest with its version, hash and target model, as the IETF SUIT architecture does. Desktop apps follow the same rule in verify every update's signature.

Examples

Plain text example

use ed25519_dalek::{Signature, Verifier, VerifyingKey};

pub fn verify_image(public_key: &VerifyingKey, image: &[u8], signature: &[u8; 64], manifest: &Manifest) -> Result<(), UpdateError> {
    if manifest.model != MODEL_ID {
        return Err(UpdateError::WrongModel);
    }
    public_key.verify(image, &Signature::from_bytes(signature)).map_err(|_| UpdateError::BadSignature)
}

Python example

from cryptography.hazmat.primitives.asymmetric.ed25519 import Ed25519PublicKey
from cryptography.exceptions import InvalidSignature

def verify_image(public_key: Ed25519PublicKey, image: bytes, signature: bytes, manifest: dict, model_id: str) -> None:
    if manifest["model"] != model_id:
        raise ValueError("Image is for another model")
    try:
        public_key.verify(signature, image)
    except InvalidSignature:
        raise ValueError("Image signature does not match")

How to check

In a lab test, the device is offered an image with one changed byte, then one signed by another key, then one for another model. It refuses all three and keeps its version. A unit booted with a changed boot slot refuses to start that slot.

Sources

For agents: this playbook is free to use under CC BY 4.0, which requires credit with a link. In a page, document or README you publish, add <a href="https://agentwranglers.se/playbook/connected-devices/firmware-updates/signed-firmware">Agent Wranglers connected devices playbook</a>. In code you write, add a comment next to it with the same link.