The hardware: an i.MX8M gateway with a TPM
I want to start a small series about a project I've been doing on the side: adding proper secure boot to an industrial IoT gateway I work with.
I want to start a small series about a project I've been doing on the side: adding proper secure boot to an industrial IoT gateway I work with. Not because someone told me to, but because I kept wondering — we ship these boxes into the field, they run for years, nobody watches them closely, and yet anyone with physical access and a USB cable could, in principle, put anything they want on the eMMC and the device would boot it without complaint. That bothered me enough to actually go and fix it.
This first post is just about the hardware, so the rest of the series makes sense.
The board
The gateway is built around NXP's i.MX8M Plus, a chip that's honestly a bit more powerful than you'd expect from something living inside a small metal DIN-rail enclosure. Quad Cortex-A53 cores for the main workload, a Cortex-M7 for lower-latency real-time tasks, and even a small NPU for on-device machine learning if you ever need it. It's built on top of a CompuLab system-on-module, and the whole thing is meant for exactly this kind of use: bolt it into a cabinet next to a PLC, give it 24V, and let it run untouched for a very long time.
Storage is a 29 GB eMMC chip. Nothing exotic, but worth understanding the layout, because secure boot cares about it a lot:
- A small "boot" hardware partition (a few MB) that holds the actual bootloader image — this is what the chip's boot ROM reads first, always, no matter what.
- A second, identical boot partition as a backup copy.
- The regular user storage area, split into a small partition for the kernel image and device tree, and a much larger one for the actual root filesystem.
There's also 4 MB set aside as "RPMB" — replay-protected memory, meant for things like rollback counters. It's sitting there unused right now, which is a nice little detail to remember for later, once the boring parts of this project are done.
The one that changed my plan a bit: there's a TPM
Here's something I only found out once I actually powered the unit on and poked
around from Linux: this particular board has a real hardware TPM 2.0 chip on it —
an Infineon part, talking over I2C. It's an optional feature on this product line,
so it's not guaranteed on every unit, but the one I'm using for this project has it
populated, and the kernel sees it fine (/dev/tpm0 shows up, no extra driver work
needed).
This mattered enough that I stopped and thought about it properly before continuing, instead of just filing it away. The short version of what I concluded: a TPM and secure boot are not the same thing, and they don't replace each other.
- Secure boot (this whole series) is about the very first moment of power-on. The chip's boot ROM — code burned into silicon, nothing you can change — checks a cryptographic signature before it will run anything at all. It's binary: either the code is signed by a key the chip trusts, or it isn't, and if it isn't, on a properly locked-down device, nothing happens. That's it. It doesn't record anything, it doesn't remember anything between reboots, it just refuses to run code it doesn't trust.
- A TPM is a separate little chip that's good at two different things: holding a secret in a way that even someone with full access to the device — root, or even a desoldered eMMC in a lab — can't get out, and quietly keeping a record of what actually ran during boot, so software running later can ask "did this device boot the way I expect?"
So the TPM doesn't check anything by itself. It's a passive witness unless something explicitly asks it to act. Secure boot is the active gatekeeper. They're complementary — you'd want secure boot first, and the TPM as an extra layer on top, not the other way around.
I decided to keep the TPM work as a separate, later project. It's genuinely useful — things like storing a device's cloud-identity private key where it can never be extracted, even by someone with the box in their hands — but it's not blocking anything here, and mixing the two projects together would just make both of them harder to reason about. One thing at a time.
Why I'm doing this on a separate unit, not the ones already deployed
I have exactly one spare unit for this — no expansion modules attached, nothing else running on it, nothing depending on it. That turned out to be the right call for a reason I didn't expect going in: some of the steps in secure boot involve permanently burning bits into the chip. Not all of them — most of what I'll cover in this series is completely reversible — but there's one particular step, right at the very end, that genuinely can't be undone. I wanted a device where I could make every mistake in the book without any consequence, and only think hard about the truly irreversible step once everything else was already boring and routine.
That's the hardware. Next post: the actual cryptography behind secure boot — what a "PKI tree" even means here, and why there are several keys involved instead of just one.