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.txt does not exist, hab4_pki_tree.sh silently creates one itself, with the password set to the literal string test. 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.