[{"content":" A field note from a real embedded project — a Control Unit (CU) and Power Unit (PU) built on the NXP i.MX RT1062 (Cortex-M7 @ 600 MHz). This is the production / end-of-line story: how boards get flashed, fused, and provisioned once they leave engineering — and why each step is ordered the way it is. Written up so the reasoning is reusable next time someone has to take an RT10xx product to manufacturing.\nTL;DR Two stages, one rule: your keys never leave the building. The contract manufacturer (EMS) runs a key-free assembly test with an unsigned image. Final signed firmware, fuse burning, and per-device identity happen in-house. The RT1062 boots XIP from FlexSPI NOR, verified by HABv4. Provisioning is really about getting a signed (and optionally BEE/OTFAD-encrypted) image into NOR and burning the right OTP fuses in the right order. HAB fusing is a one-way ratchet with three positions: open → SRK-fused-but-open → closed. The whole sequence is designed around never closing HAB until a correctly-signed image has already booted on that exact board. All flashing is over USB (the RT1062 ROM Serial Downloader, driven by NXP SPSDK / MCUBootUtility). The only JTAG in the flow is for the TI C2000 co-processor on the PU. The device private key lives in an on-board Microchip ATECC608 secure element — generated inside the chip and never extractable, even at runtime. Certificates are public and live in a LittleFS data partition. Two separate roots of trust: the RT1062 (HAB + BEE/OTFAD) protects the firmware; the ATECC608 protects the device identity. Don\u0026rsquo;t conflate them. The problem: what \u0026ldquo;production\u0026rdquo; actually means for a secure MCU On the bench, flashing an i.MX RT1062 is trivial — attach a debug probe, drag in an ELF, run. In production, three new requirements appear at once:\nSecurity. The product needs secure boot (HAB) so only firmware signed by us runs, plus a per-device identity (serial, MAC, TLS certificate) that can\u0026rsquo;t be cloned. A contract manufacturer in the loop. An external EMS assembles the boards. They must be able to catch assembly defects — but must never hold our signing keys or PKI. Recoverability. Fuses are one-way (OTP). Get the order wrong and you brick boards permanently. We need a flow where a mistake is caught before the irreversible step. Those three pull in different directions. The design below is how we reconcile them.\nThe i.MX RT1062 boot \u0026amp; security model (the parts that matter here) The RT1062 has no internal flash. It boots eXecute-In-Place (XIP) from external FlexSPI NOR. The on-chip boot ROM:\nReads a FlexSPI configuration block and an Image Vector Table (IVT) at a fixed offset in NOR. Optionally decrypts the image on the fly via BEE/OTFAD using a device-unique key stored in OTP fuses. Optionally verifies the image against HABv4 — High Assurance Boot — using a hash of our public signing keys (the SRK hash) burned into fuses. Security state is governed by OTP (one-time-programmable) fuses. The three that dominate the production flow:\nFuse / field Effect Reversible? SRK_HASH The fingerprint of our public signing key set. Lets the ROM verify signatures. ❌ one-way SEC_CONFIG (\u0026ldquo;closed\u0026rdquo;) Switches HAB from audit (log failures, boot anyway) to enforce (reject unsigned/invalid images). ❌ one-way SDP_DISABLE Turns off the USB Serial Download recovery path entirely. ❌ one-way The key mental model: HAB is not a switch, it\u0026rsquo;s a ratchet with three positions.\nOpen — ROM runs any image. If a signature is present it\u0026rsquo;s checked but failures are only logged (audit mode). SRK-fused, still open — the SRK hash is burned, so the ROM can verify against our keys, but it still boots images that fail. This is the validation safety net. Closed — SEC_CONFIG blown. Signatures are enforced. An image that doesn\u0026rsquo;t verify against the fused SRK will not boot, and there\u0026rsquo;s no going back. Everything downstream is arranged so that we only ever move forward along this ratchet, and only after proving the next state is safe.\nTwo roots of trust: RT1062 for code, ATECC608 for identity The board carries a Microchip ATECC608 secure element on the RT1062\u0026rsquo;s I²C bus. This matters because the RT1062 alone cannot keep an asymmetric private key non-extractable — it has no CAAM and no public-key engine, so any software-generated key is exposed in RAM whenever it is used. The ATECC608 closes that gap.\nRoot of trust Protects Mechanism RT1062 HAB + BEE/OTFAD (OTPMK in fuses) The firmware — authenticity (HAB signature) and confidentiality (BEE-encrypted XIP) On-chip, fuse-rooted ATECC608 The device identity — ECC P-256 private key, ECDSA for TLS / mutual-auth Secure element; key generated and held inside, never exported The ATECC608 generates its identity keypair internally with the GenKey command and returns only the public key. The private key never crosses the I²C bus, never enters RT1062 RAM, and cannot be read out — even by fully-trusted code, even over JTAG.\nIdentity provisioning, zoomed in — the ATECC608\u0026rsquo;s own two-lock ratchet:\nsequenceDiagram autonumber participant ST as Python Station participant FW as RT1062 Firmware participant SE as ATECC608 participant CA as In-house CA / HSM ST-\u0026gt;\u0026gt;FW: provision identity FW-\u0026gt;\u0026gt;SE: Write config zone, slot 0 = ECC private key FW-\u0026gt;\u0026gt;SE: LOCK config zone (one-way) FW-\u0026gt;\u0026gt;SE: GenKey slot 0 Note over SE: private key created and sealed inside, never leaves the chip SE--\u0026gt;\u0026gt;FW: P-256 public key FW-\u0026gt;\u0026gt;FW: Assemble CSR (subject = serial + MAC) FW-\u0026gt;\u0026gt;SE: Sign CSR TBS hash SE--\u0026gt;\u0026gt;FW: ECDSA signature FW--\u0026gt;\u0026gt;ST: CSR ST-\u0026gt;\u0026gt;CA: CSR CA-\u0026gt;\u0026gt;CA: Sign with issuing CA key in HSM CA--\u0026gt;\u0026gt;ST: device.crt ST-\u0026gt;\u0026gt;FW: device.crt FW-\u0026gt;\u0026gt;SE: LOCK data zone (one-way) FW--\u0026gt;\u0026gt;ST: identity provisioned Why it matters at runtime — the private key never leaves the SE, even during a live handshake:\nsequenceDiagram autonumber participant Peer as TLS Peer / server participant FW as RT1062 Firmware participant SE as ATECC608 Peer-\u0026gt;\u0026gt;FW: TLS handshake challenge FW-\u0026gt;\u0026gt;SE: Sign handshake hash with device key Note over SE: signs INSIDE the SE, private key never exposed SE--\u0026gt;\u0026gt;FW: ECDSA signature FW-\u0026gt;\u0026gt;Peer: device cert + signature Peer-\u0026gt;\u0026gt;Peer: Verify against CA chain Note over Peer,FW: identity proven, key never left silicon The idea: split production into two stages The single most important decision is where the trust boundary sits. We put it between the EMS and ourselves:\nStage A — Assembly test Stage B — Provision \u0026amp; full test Where Contract manufacturer (EMS) In-house production line Goal Catch assembly / component defects Flash signed SW, fuse, provision identity, full test Firmware Unsigned, disposable test image Final signed (and BEE-encrypted) image Keys / PKI None All keys, HSM, and CA in-house only Board leaves as Open (no secrets) Provisioned, SRK-fused (→ closed at volume) Boards leave the EMS open, with no secrets on them. That\u0026rsquo;s what makes the split safe: the EMS can do everything they need with an unsigned image, because an open board runs unsigned images happily. Our signing keys and PKI never touch their floor.\nWhy not just let the EMS flash the final firmware? Because \u0026ldquo;final firmware\u0026rdquo; implies secure boot, which implies keys, which implies either shipping our private keys to a third party or building a signing service they call into. Both widen the attack surface for no benefit — the EMS\u0026rsquo;s real job is proving the copper is good, not the product is good.\nStage A — what the EMS actually tests The EMS test is a deliberately dumb manufacturing-defect filter. It answers one question: was this board assembled correctly? It flashes an unsigned, self-running test image to NOR (RT1062 over USB; the PU\u0026rsquo;s TI C2000 over JTAG). On power-up the board runs a GO/NO-GO self-test and reports over a UART/USB test channel plus a bed-of-nails fixture.\nCoverage (key-free): power rails \u0026amp; sequencing; RT1062 and C2000 boot; the TI↔NXP SPI link handshake; FlexSPI NOR + SDRAM read/write; peripheral presence (I²C ACK, RTC, SD-detect, Ethernet PHY IDs); connector / IO continuity.\nOut of scope at the EMS: anything needing keys or secure boot; application behaviour; and all calibration. Those belong to Stage B.\nStage B — the in-house provisioning sequence This is the heart of it. Every step is verified before the next one commits, and every irreversible (fuse) step comes after the check that proves it\u0026rsquo;s safe.\n1. Mass-erase NOR (remove EMS test image) 2. Load \u0026amp; boot the final SIGNED image while the board is still OPEN → confirm it runs → confirm HAB audit log is CLEAN (signature WOULD pass) ◀── proof before commit 3. Burn SRK_HASH (one-way) → reboot, re-verify signed image boots, HAB log clean vs fused SRK 4. Provision BEE/OTFAD device key into OTP (crypto root now exists) 5. ATECC608 provisioning (host-driven over I²C) → write + LOCK the config zone (one-way) → GenKey: keypair generated INSIDE the SE ◀── private key never leaves the chip → SE returns only the PUBLIC key → host builds a CSR; the SE signs it (ECDSA) → station relays CSR to in-house CA / HSM → device.crt → store device.crt in LittleFS → LOCK the data zone (one-way) 6. Write remaining identity serial, MAC(s), config, calibration → LittleFS 7. Flash the TI C2000 via JTAG + UniFlash CLI 8. Full functional test on the provisioned device 9. HAB close policy: first batch → leave OPEN + SRK-fused (recoverable) volume → SEC_CONFIG = closed (LAST fuse step, after test passes) 10. Print label, commit full genealogy record to the production DB Why this exact order Step 2 before step 3. We boot the signed image while still open and read the HAB audit log. If the signature is wrong, the log shows an audit event — and the board is still recoverable because HAB isn\u0026rsquo;t fused yet. We only burn the SRK hash once we\u0026rsquo;ve proven our own signature verifies. This one ordering choice eliminates the #1 production brick. Step 4 (BEE/OTFAD key) protects the firmware image, not the identity key. With the ATECC608 on board, the device private key does not rely on the OTPMK. The two roots of trust stay separate. The private key never exists outside the ATECC608. GenKey creates it inside the secure element; only a CSR (public) ever leaves. This is a stronger guarantee than any on-chip RT1062 mechanism can offer. Closing HAB is the last thing. For the first batch we leave boards open + SRK-fused (fully recoverable). Once proven end-to-end, we switch to always-close for volume. Where things are stored: certificate vs. private key Item Where In a filesystem? Private key Generated and held inside the ATECC608 ❌ never in flash or RAM — non-extractable, even at runtime Device certificate (public) NOR data partition, LittleFS (/identity/device.crt) ✅ yes — it\u0026rsquo;s public, a plain file is fine CA / chain certs (public) Firmware image or LittleFS Either The NOR layout: raw boot region + LittleFS data The RT1062 needs its bootable image at a fixed offset, XIP-executable, with an IVT — a filesystem there would break secure XIP boot. So the flash is split by purpose:\nFlexSPI NOR (32 MB — sized up for headroom) ├─ [XIP boot region] signed + BEE-encrypted firmware (RAW, fixed offset) ← common to all units ├─ [data partition] LittleFS: identity, cert, config, calibration ← per-device └─ [reserved / OTA] headroom / future A-B update slot We don\u0026rsquo;t deliver a monolithic per-unit image. The signed, BEE-encrypted bootable firmware is identical for all units; only the LittleFS identity partition is per-device, merged live on the station. That keeps one signature over one common firmware — no per-unit rebuild, no per-unit re-signing.\nTooling: USB for the NXP, JTAG only for the TI Is all the flashing over USB? For the NXP — yes. The boot ROM\u0026rsquo;s Serial Downloader (SDP) enumerates over USB, and NXP SPSDK drives everything through it: flashloader, NOR programming, fuse burns, signing, HAB close, and writing the data partition. The TI C2000 co-processor is flashed independently via JTAG + UniFlash CLI.\nCan I still reach the MCU over USB after fusing? State USB/SDP enumerates? Recover over USB? Open + SRK-fused (first batch) ✅ ✅ Full, free access HAB closed, SDP enabled (volume) ✅ ⚠️ Yes, but signed flashloader only Closed + SDP_DISABLE blown ❌ ❌ No USB path at all Closing HAB does not kill the USB downloader — it just makes the ROM refuse an unsigned flashloader. We deliberately leave SDP enabled even on closed volume units, so a signed-USB recovery/RMA door stays open. And because the image is BEE-encrypted, a readback over USB returns ciphertext — you can\u0026rsquo;t clone plaintext firmware off a provisioned unit.\nThe takeaways Design the trust boundary first. Deciding the EMS never holds keys shaped every other choice. Order fuses around recoverability, not convenience. Boot-and-verify while open before burning SRK; close HAB dead last. Separate code from identity from secrets. Raw signed firmware (HAB/BEE), LittleFS identity + public cert, private key sealed in the ATECC608. Anchor device identity in a secure element. The ATECC608 generates the private key inside itself and never releases it. USB is enough for the NXP. Reserve JTAG for the co-processor and keep a signed-USB recovery door open. Platform: NXP i.MX RT1062 (Cortex-M7 @ 600 MHz), FlexSPI NOR (32 MB), FreeRTOS + QP/C. Secure element: Microchip ATECC608. Co-processor: TI C2000. Tooling: NXP SPSDK / MCUBootUtility (USB SDP), TI UniFlash (JTAG), Microchip CryptoAuthLib / Trust Platform (I²C), LittleFS, HABv4, BEE/OTFAD.\nWant this kind of production-ready secure boot on your i.MX RT product? Let\u0026rsquo;s talk →\n","permalink":"https://hoanguyen.de/posts/provisioning-imx-rt1062-secure-boot/","summary":"A field note from a real i.MX RT1062 product: how boards get flashed, fused, and provisioned once they leave engineering — and why each step is ordered the way it is.","title":"Provisioning the i.MX RT1062 in Production: Secure Boot, Fusing, and a Two-Stage Flash Flow"},{"content":"I\u0026rsquo;m Hoa Nguyen, an embedded software architect based in Germany, specializing in secure firmware for NXP i.MX RT (Cortex-M7) crossover MCUs.\nOver 8+ years I\u0026rsquo;ve built safety- and security-critical embedded systems for the German automotive and industrial sector — including years at Bosch — working across the full stack that a real product needs: board bring-up, low-level drivers, RTOS architecture, secure boot, and end-of-line provisioning.\nMy recent work centers on taking i.MX RT-based control units from engineering into production: HABv4 secure boot, one-way fuse sequencing, secure-element device identity (ATECC608), encrypted XIP, and OTA update systems — the exact capabilities the EU Cyber Resilience Act now requires of connected products.\nHow I work I care about the reasoning behind engineering decisions, not just the code. Clients get firmware that is documented (arc42 / docs-as-code), maintainable, and built with production and certification in mind from day one — the process discipline you\u0026rsquo;d expect from an automotive background.\nToolbox C · C++ · NXP i.MX RT1062 / Cortex-M7 · FreeRTOS · QP/C · HABv4 secure boot · BEE/OTFAD · FlexSPI · MCUboot / signed OTA · ATECC608 · LittleFS · CMake · Ninja · LVGL · arc42 / AsciiDoc\nContact ✉️ Email: hoa@hoanguyen.de 💼 LinkedIn: linkedin.com/in/hoa-nguyen-embedded 💻 GitHub: github.com/hoanguyenasm Available for selected freelance and consulting engagements — remote, or on-site in the DACH region.\n","permalink":"https://hoanguyen.de/about/","summary":"8+ years of safety- and security-critical embedded engineering.","title":"About"},{"content":"I help device makers turn hardware into shippable, certifiable products on the NXP i.MX RT (Cortex-M7) platform. Below are the four areas I focus on — most engagements combine two or three.\n1 · i.MX RT firmware development \u0026amp; board bring-up The core work: getting a new board alive and a codebase into production shape.\nBoard bring-up: clocks, DDR/SDRAM, FlexSPI/QSPI NOR, boot configuration Low-level drivers: USDHC (SD/eMMC), FlexPWM, LCD/backlight, I²C/SPI/UART, Ethernet Board support packages, debugging, and performance tuning on Cortex-M7 Migrating bare-metal code onto a real RTOS 2 · Secure boot, provisioning \u0026amp; EU CRA readiness The premium work — and the one the EU Cyber Resilience Act now makes mandatory for connected products sold in the EU (incident reporting from Sept 2026, full compliance Dec 2027).\nHABv4 secure boot, SRK fusing, and a recoverable production fuse sequence BEE/OTFAD encrypted XIP; secure element identity (e.g. ATECC608) Signed OTA / firmware-update systems (A/B, rollback protection) SBOM generation and a CRA gap assessment for your device A two-stage production flow that keeps your signing keys in-house 3 · Firmware architecture \u0026amp; RTOS For teams whose firmware has outgrown its structure.\nEvent-driven architecture with QP/C active objects or FreeRTOS Refactoring \u0026ldquo;big-loop\u0026rdquo; firmware into testable, maintainable components Architecture documentation as code (arc42 / AsciiDoc) your auditors will accept 4 · Prototype → production For startups who prototyped on a Teensy 4.x (same i.MX RT1062 silicon) and now need a real product.\nFrom dev board to custom hardware Secure boot, real device identity, and production programming The path from \u0026ldquo;it works on my desk\u0026rdquo; to \u0026ldquo;it ships and passes certification\u0026rdquo; How we can work together Fixed-scope package — e.g. a CRA gap assessment or a secure-boot bring-up Hourly / day-rate consulting — remote, or on-site in the DACH region Architecture review \u0026amp; workshops — a focused deep-dive for your team Let\u0026rsquo;s talk: hoa@hoanguyen.de\n","permalink":"https://hoanguyen.de/services/","summary":"How I help device makers ship secure, certifiable firmware on NXP i.MX RT.","title":"Services"}]