About me
Blog
Europe/Berlin
--:--:--
Projects

Signed OTA Update Pipeline (ESP32 + STM32)

September 3, 2025
Fail-safe A/B updates with Ed25519 signatures, anti-rollback, and "verify-before-commit." Bring firmware updates to your IoT products – secure, reproducible, and CI-integrated. Our pipeline combines a canonical manifest, cryptographic signatures, and two-stage rollback mechanisms for ESP32 and STM32.
⚠️ Reference implementation for product teams and training. Adaptations to your hardware/toolchain are planned.

  • Security by design: Ed25519 signatures + SHA-256 integrity + anti-rollback.
  • Robustness: A/B slots, watchdog-friendly OTA writes, rollback on errors.
  • Transparency: Canonical manifest (verifiable, diffable); reproducible signing process.
  • DevEx: Python signer, verifier, CI workflow (GitHub Actions) – ready to use immediately.
  • Cross-target: ESP32 (ESP-IDF v5.x) & STM32 (bootloader skeleton) from a single toolkit.
Target audience: Embedded teams with security and update requirements (industrial/consumer/prototype → production). Duration (introduction): 2–5 days including customization + CI integration.
  • Canonical Manifest (JSON): device, version, slot, timestamp, image.sha256/size, meta.*
  • Signatures: Ed25519 over the canonicalized manifest body (stable sorting/separators)
  • Anti-rollback: Monotonic version check (NVS/Flash) + optional HW counter
  • A/B schema: Safe switching, self-test, commit only when healthy
  • CI-capable: Build → Sign → Artifact, key injection via secrets, release promotion
  • Extensible: SBOM (CycloneDX), release signatures (cosign), staged rollouts

  • Tooling ("signer/"): Keygen, signer, package builder (.ota ZIP with manifest.json + firmware.bin), verifier
  • ESP32 App: OTA flow (download/stream), versioning, NVS hook, rollback support via IDF bootloader
  • STM32 Bootloader: Slot selection, manifest/hash validation (Ed25519 verify as port/library), jump logic, rollback marker
  • CI Workflow: GitHub Actions template (build, sign, artifact upload)
  • Documentation: Threat model, test plan, integration guide

[CI Build]  ──(Artifacts)──>  [Signer]  ──( .ota Package )──>  [OTA Server/CDN]
                                                │
                                         (HTTPS, Auth)
                                                │
                                         [Device Fleet]
ESP32: Downloader → Verify(Signature+Hash) → Stream to OTA Partition → Reboot → Self-Test → Commit
STM32: Bootloader selects slot → Verify(Signature+Hash) → Jump → on errors Rollback/Alternate Slot

  • Authenticity & Integrity: Ed25519 over manifest; SHA-256 over image
  • "Verify-before-commit": No activation without fully verified data
  • Rollback resilience: A/B schema + monotonic version
  • Key hygiene: Offline root, short-lived CI keys, rotation & pinning of public keys
  • Supply chain: Optional SBOM + release signatures + reproducible builds

Json
{
  "body": {
    "device": "esp32|stm32",
    "version": "1.2.3",
    "slot": "ota_0|ota_1|app_a|app_b",
    "timestamp": "2025-09-03T12:00:00Z",
    "image": { "sha256": "…", "size": 524288 },
    "meta": { "min_bootloader": "1.0.0", "rollback_protected": true }
  },
  "signature": { "algo": "ed25519", "value": "BASE64_SIG" }
}
Canonicalization: JSON with stable sorting & compact separators; exactly the same bytes are signed/validated.
  • Partitions: factory, ota_0, ota_1
  • OTA stream via esp_https_ota
  • Pre-commit checks: manifest signature, image hash, version
  • Self-test after reboot; esp_ota_mark_app_valid_cancel_rollback()
  • Slots A/B + manifest header in reserved area
  • Verify (signature/hash) before jump
  • Rollback marker in backup SRAM/option bytes
  • Power-fail-safe switching

  1. Build (ESP32/STM32) → binary artifact
  2. Sign: signer.py generates .ota with manifest + signature
  3. Publish: Upload to OTA server/CDN, release via environment gate
  4. Deploy: Device downloads package (HTTPS), verifies manifest/hash, streams to target slot
  5. Commit: After self-tests → commit, otherwise rollback

Bash
# 1) Generate keys (offline)
cd signer && python -m venv .venv && source .venv/bin/activate
pip install -r requirements.txt
python generate_keys.py  # keys/ed25519_priv.pem + ed25519_pub.pem

# 2) Build ESP32
idf.py -C esp32 set-target esp32 && idf.py -C esp32 build

# 3) Sign package
python signer.py \
  --pubkey keys/ed25519_pub.pem \
  --privkey keys/ed25519_priv.pem \
  --device esp32 --version 1.0.0 --slot ota_0 \
  --image ../builds/esp32-app.bin \
  --out ../dist/esp32-app-1.0.0.ota

# 4) Verify package
python verify_package.py --pubkey keys/ed25519_pub.pem --package ../dist/esp32-app-1.0.0.ota
Notes:
  • Device-side Ed25519 verification integrated/ported as a lightweight library (e.g., TweetNaCl port).
  • Public key stored on the device (rotation via update possible).
  • Optional: NVS encryption (ESP32) & Secure Boot/TrustZone/TPM integration.

  • Unit: Signer/verifier (schema, canonicalization, round-trip), version logic
  • Integration (ESP32): Happy path, signature error, hash mismatch, rollback path
  • Integration (STM32): Slot matrix (A/B valid/invalid), brownout during update
  • HIL: Network interruptions, watchdog triggers, recovery scenarios

Basic • Reference repo (tooling, ESP32 app, STM32 bootloader, CI template, docs) • Remote onboarding (2h) Pro • Basic + production-grade integration (key management, TLS, SBOM, release signatures) • Rollout strategy (staging %, rings, device cohorts) Enterprise • Pro + hardware security (TPM/SE, Secure Boot), compliance documentation, pen test support Price: on request.
How much effort is the integration? ESP32: 1–3 days for proof of concept; STM32 depends on HAL/flash layout (3–7 days). Do we need Secure Boot? Recommended but not required – signature verification + anti-rollback are already included. Do you support key rotation? Yes. Public key pinning in the manifest; rotation via intermediate release. How do we validate releases? Through CI gates, SBOM, cosign signatures, and reproducible builds (optional).
Interested in a live demo or a pilot project? Inquire now: kontakt@buengener-software.de
Meta Title: Signed OTA Update Pipeline (ESP32 + STM32) – Secure A/B OTA for IoT Meta Description: Ed25519 signatures, anti-rollback, verify-before-commit, CI integration. Secure OTA for ESP32 & STM32 – as a reference implementation including tooling & documentation. JSON-LD (Service)
Html
<script type="application/ld+json">
  {
    "@context": "https://schema.org",
    "@type": "Service",
    "name": "Signed OTA Update Pipeline (ESP32 + STM32)",
    "provider": {
      "@type": "Organization",
      "name": "Büngener Software",
      "url": "https://buengener-software.de"
    },
    "areaServed": "EU",
    "serviceType": "Embedded OTA Security",
    "offers": {
      "@type": "Offer",
      "price": "0",
      "priceCurrency": "EUR",
      "availability": "https://schema.org/InStock"
    }
  }
</script>

  • v1.0 – Reference pipeline (tooling, ESP32/STM32, CI, docs)
MIT (for reference code; third-party libraries may differ).