top of page

Secure boot is not one feature, it’s a chain

Writer: Lauri Hokkanen
Lauri Hokkanen
3 days ago
5 min read

Ask for “secure boot” on a datasheet and you get a checkbox. Ask an engineer who has shipped it and you get a diagram with five or six boxes and an arrow between each. The checkbox describes the first box. The diagram is the feature.

Secure boot means that every piece of code the device runs was verified by the piece before it, all the way back to something that cannot be changed. That “all the way back” is the point. A chain with one unverified link is a chain that stops there; whatever follows runs on trust that nobody checked.

The links, on a typical Linux gateway

Take an application-class SoC running Linux, the kind found in gateways, chargers and industrial controllers. The example is an NXP i.MX 8M gateway, the part this post draws its experience from; other SoCs have the same shape with different names and details, and the differences are noted where they matter. The chain looks like this:

  1. Boot ROM. Code in silicon, written by the chip vendor, unchangeable. It loads the first stage from flash and verifies it against a trust anchor the manufacturer provisioned. On the i.MX 8M that anchor is a key hash in one-time-programmable fuses and the mechanism is HAB; newer i.MX 8 and i.MX 9 parts use AHAB, and other vendors have their own names and their own anchor storage, some of it rewritable. The shape is the same: provisioned anchor, signed first stage.

  2. First-stage loader and U-Boot. The ROM verifies the first-stage loader; on many designs that loader and U-Boot are signed together in one container. This is the first link the manufacturer signs, and the first key the manufacturer owns.

  3. The kernel. U-Boot verifies a FIT image, a container holding the kernel, the device tree and the initramfs, against a public key compiled into U-Boot’s own device tree. That key was put there at build time, and it is only trustworthy because the U-Boot that carries it was verified one step earlier.

  4. The trusted execution environment. OP-TEE, if present, is loaded and verified alongside the kernel, and it in turn verifies every trusted application it loads against its own key. Trusted applications are signed with a key that belongs to a different party again: often not the boot team but whoever owns the secure service.

  5. The root filesystem and beyond. From here the kernel takes over with dm-verity or a signed root filesystem, and the update mechanism takes over the question of what may replace any of the above.

  6. Application containers, where used. If applications ship as container images, the container runtime verifies each image’s signature against its own trust policy before it runs. That is one more link and one more key, and it belongs to the application team rather than the boot team; the boot chain never sees it.

Five links, six on a device that runs application containers, and the chip vendor supplies only the first. Every other link is something the manufacturer builds, signs, and holds a key for.

Where each key lives

Counting the links is easy. Counting the keys is where it gets interesting, because each link has its own verifier, and each verifier has its own idea of a trust anchor.

  • The ROM trusts a provisioned anchor. On the i.MX 8M that is one hash in fuses, and it covers a table of up to four super root keys, committed together when the fuses are burned. No certificate is involved. Whoever holds one of those private keys can sign a bootloader for every device carrying that hash.

  • U-Boot trusts a public key compiled into its device tree, again without a certificate. Changing that key means rebuilding U-Boot, and the new U-Boot must itself be signed with the root key before the ROM will run it. The kernel key cannot change without going through the root key.

  • OP-TEE trusts a key compiled into it for the trusted applications, distinct from everything above.

  • The update client trusts a certificate or a public key, depending on the update format, stored in a part of the filesystem that the boot chain has already verified.

  • The container runtime trusts the keys or certificates listed in its own policy, one per image publisher it accepts. The private keys belong to whoever builds the application images, usually a different team from the one that owns the boot chain.

A real product easily ends up with five or six private keys, and they are usually created at different times, by different people, with different tools: the root key during board bring-up, the kernel key when the Yocto build was set up, the trusted-application key when the TEE was integrated. Nobody designed the set. Each key was created when its link needed one, and it stayed wherever that tool put it.

The questions that follow

Once the keys are counted, three questions apply to every one of them, and they are the same three that run through this whole series.

Where is the key? A key hash in fuses is only as strong as the storage of the private key that matches it. If that key is a PEM file on a build server, the fuses protect a secret that lives in a file share.

Who is allowed to use it? The root key behind the fuses signs a bootloader once a year. The FIT key signs every kernel build. The two need different rules: the root key should require a second person’s approval, the kernel key must be usable by an unattended pipeline. If every key sits in one secret store under one policy, that policy has to be loose enough for the pipeline, and the root key inherits it.

Is there a record? When a signed build turns out to be bad, the useful question is not whether the signature is valid. It is who requested the signature, when, and what else the same key signed in the same period. A chain of trust that cannot answer that has verified integrity but told you nothing about accountability.

None of this requires a particular platform. It requires knowing the number of links, the number of keys, and having an answer for each key to those three questions. The secure boot feature on the datasheet is the first link. The other links, and every key behind them, are the manufacturer’s to build and to protect.

Do you know how many keys your boot chain actually has, and for each of them, where it is and who can use it? We would like to hear the number.

Further reading: the boot chain this post is drawn from, worked through end to end, docs.laavat.io/solutions/cra-ready-imx8m. For the individual links, the vendor documentation: U-Boot verified boot, OP-TEE trusted applications, dm-verity.

Comments


Commenting on this post isn't available anymore. Contact the site owner for more info.
bottom of page