Generating HAB keys with NXP's Code Signing Tool (CST 4.0.1)
Getting CST, generating the thirteen-key HAB PKI tree with hab4_pki_tree.sh, and building the SRK table and its fuse hash with srktool. Including the thing that script does silently if you do not read it first: it invents a passphrase for you, and the passphrase is 'test'.
Part 2 was the theory — the CA, four SRKs, a CSF and IMG pair under each. This post generates them for real, with NXP's Code Signing Tool.
Nothing here touches the board. Everything below produces files on a build machine, and files can be deleted. The only irreversible thing in this post is the decision about where those files live.
Getting CST
It is not packaged. You download it from NXP behind a free account, and it arrives with a filename that tells you nothing:
tar -tzf IMX_CST_TOOL_NEW.tgz | head -3
cst-4.0.1/
cst-4.0.1/Software_Content_Register_CST.txt
cst-4.0.1/linux32/
Version 4.0.1. Anything 3.4.x or newer works for HABv4 on i.MX8M Plus; check, because the filename will not tell you.
What is inside that matters:
| Path | What it is |
|---|---|
keys/hab4_pki_tree.sh |
Generates the whole PKI tree |
keys/ |
Where the private keys land |
crts/ |
Where the public certificates land |
linux64/bin/srktool |
Builds the SRK table and its fuse hash |
linux64/bin/cst |
The signing tool itself — used in part 8 |
Where to extract it, and why it matters
~/projekti/compulab_gw/secure_boot_keys/cst-4.0.1/
A sibling of every project directory, and inside none of them. Never git added, never
committed, nothing from it in any repository's history — not even by accident, not even
briefly.
This is not fussiness. Git history is forever and it gets pushed. A private key that spends one commit in a repository has to be treated as compromised, and the recovery story from part 2 is "burn a revocation fuse", which is a thing you can do three times in the life of the board.
The passphrase, and the trap
Every private key the generator produces is password-protected, using a passphrase it reads from a file:
cd secure_boot_keys/cst-4.0.1/keys
printf '%s\n%s\n' 'your-chosen-passphrase' 'your-chosen-passphrase' > key_pass.txt
wc -l key_pass.txt # expect: 2
The same passphrase, twice, on two lines — the script uses the second as the confirmation prompt's answer, not as a different value.
Read the script before running it. If
key_pass.txtdoes not exist,hab4_pki_tree.shsilently creates one itself, with the password set to the literal stringtest. No prompt, no warning. I found this by reading its source rather than by discovering it later, and "later" here means after the SRK hash is burned into a chip.
Verify with wc -l, not cat. That file is exactly as sensitive as the keys it protects.
Generating the tree
cd secure_boot_keys/cst-4.0.1/keys
./hab4_pki_tree.sh -existing-ca n -kt rsa -kl 4096 -duration 20 -num-srk 4 -srk-ca y
Every choice is a flag rather than an interactive answer, which means the command is the documentation:
| Flag | Value | Why |
|---|---|---|
-existing-ca |
n |
A brand-new root — no prior CA to reuse |
-kt |
rsa |
Not the elliptic-curve option. RSA is far better documented for HAB, and this is not the place to be the first person debugging an edge case |
-kl |
4096 |
Key length |
-duration |
20 |
20 years. Irrelevant to security — see below |
-num-srk |
4 |
Four SRKs, which is the entire key-rotation story from part 2 |
-srk-ca |
y |
Let the SRKs certify keys beneath them, which the CSF/IMG pairs need |
It takes a while — thirteen 4096-bit RSA key pairs is real work — and produces exactly the
tree from part 2: one CA, four SRKs, and a CSF and IMG pair under each. Private halves in
keys/, public certificates in crts/, everything readable only by your own account.
The 20-year validity is irrelevant, and it is worth knowing why
The boot ROM, at the moment it checks a signature, has no concept of today's date. There is no real-time clock involved in that check at all.
Certificate expiry is an ordinary-PKI idea — your browser checking that a website's certificate has not run out. It does not apply to silicon verifying a signature at power-on. The duration exists only to keep the certificate tooling happy.
Building the SRK table and the fuse hash
The chip cannot store four public certificates. It stores one 256-bit fingerprint of a
table listing all four. srktool builds both:
cd secure_boot_keys/cst-4.0.1/crts
../linux64/bin/srktool -h 4 \
-t SRK_1_2_3_4_table.bin \
-e SRK_1_2_3_4_fuse.bin \
-d sha256 -c \
SRK1_sha256_4096_65537_v3_ca_crt.pem,SRK2_sha256_4096_65537_v3_ca_crt.pem,SRK3_sha256_4096_65537_v3_ca_crt.pem,SRK4_sha256_4096_65537_v3_ca_crt.pem \
-f 1
| Part | Meaning |
|---|---|
-h 4 |
Four SRKs in the table |
-t …table.bin |
The table — public, embedded in every signed image |
-e …fuse.bin |
The fuse hash — eight 32-bit words, the value that eventually gets burned |
-d sha256 |
Hash algorithm |
-c SRK1,SRK2,SRK3,SRK4 |
The four certificates, in order — SRK1 must stay SRK1 |
Order matters and is not checked for you. Swap two certificates and you get a valid table describing a different trust configuration than you think you have.
Check the fuse words with a second tool
Those eight words are the one value that becomes permanent. Before trusting them, read the same file with something that has nothing to do with CST:
hexdump -C SRK_1_2_3_4_fuse.bin
Two unrelated tools agreeing on the same bytes is a much better feeling than trusting one tool's own output, especially given where those bytes are going.
Write them down somewhere durable, outside the keys directory. If you ever need to confirm what a board was fused with, this is the reference you will compare against.
What exists now, and what does not
Thirteen key pairs, four certificates, an SRK table and a 32-byte hash. All of it is files on a disk and numbers on a terminal.
Nothing has been burned into any chip. That distinction is worth repeating to yourself throughout this phase, because the vocabulary — "fuse hash", "keys", "signing" — makes it feel more committal than it is. Generating keys and printing values is completely reversible: delete the directory and start again.
The next post is about backups, because before going anywhere near an irreversible step I wanted several independent, verified copies of absolutely everything — including these keys, whose loss after the device is closed means never being able to sign firmware for it again.