AHAB usage example¶
This example shows how to create a product that signs an NXP AHAB boot
container for an i.MX9 device with the SignSPSDK operation, and then signs a
container. It uses the reference python client and the UI.
The example is divided into the following stages:
- Getting an authentication token
- Adding the SRK certificate profile
- Creating the product
- Approving the product
- Getting the SRK table and SRK hash
- Building the signing payload
- Signing the AHAB container
- Downloading and verifying the signed container
This example uses elliptic-curve (EC) keys. For RSA keys, see the SPSDK signing page. The older CST-based AHAB signing is being phased out — see CST signing.
Authentication¶
In order to use the reference python client a valid JWT token is needed. How to obtain one is explained in more detail in the authentication chapter. New token must be requested if the current token expires. ( roughly 1 hour of validity)
(venv) $ az login --allow-no-subscriptions --only-show-error
A web browser has been opened at https://login.microsoftonline.com/organizations/oauth2/v2.0/authorize. Please continue the login in the web browser. If no web browser is available or if the web browser fails to open, use device code flow with `az login --use-device-code`.
(venv) $ az account get-access-token --resource api://<redacted>
{
"accessToken": "<redacted>",
"expiresOn": "2025-06-04 15:18:10.000000",
"tokenType": "Bearer"
}
(venv) $ export TOKEN=<redacted>
Add the SRK certificate profile¶
Token handling in these examples
The signing-tool commands below use -n test.ini — a config file created with config-init that references
a token_file rather than embedding a token, so no token appears on the command line. See Reference Client ›
Usage for how to create it and for the secure token-input forms (-t @file, -t @-).
An SPSDK product has four Super Root Key (SRK) certificates. Each one is a root certificate (there is no certificate authority above it) and they all use the same end-entity certificate profile. For EC keys this is a standard ECDSA end-entity profile; an example is given in (A)HAB End-Entity profile for ECDSA keys.
Add the profile and note the returned profile ID:
(venv) $ signing-tool -n test.ini profile \
add -F srk-endentity.yaml -N "AHAB SPSDK SRK Profile" -T END
{
"id": "b58d7902-5fec-4fa5-90b0-7b6c70a23d6f",
"profile_name": "AHAB SPSDK SRK Profile",
"profile_type": 1,
"profile_yaml": "<base64 of the profile yaml>"
}
Profile added. Profile ID: b58d7902-5fec-4fa5-90b0-7b6c70a23d6f
Create the product¶
The product has four SRK certificates and one SignSPSDK operation. Unlike the
CST-based AHAB product, it has no subordinate SGK key — SPSDK signs directly
with one of the four SRKs.
Use the SPSDK product template
and replace $ENDPROFILEID with the profile ID from the previous step. The four
SRK certificates are root certificates (certificateType: ROOT) that point at
the SRK profile, and the product carries the FusemapType (IMXAHAB) and
AHABDigest configuration items.
{
"name": "TEST for i.mx9",
"description": "AHAB SPSDK signing product",
"productType": "Production",
"enabled": true,
"caInfo": [
{ "CN": "SRK0", "description": "SRK for i.MX9 AHAB", "useCase": "HABCA", "profileID": "$ENDPROFILEID", "keyType": "ECDSAP521", "certificateType": "ROOT" },
{ "CN": "SRK1", "description": "SRK for i.MX9 AHAB", "useCase": "HABCA", "profileID": "$ENDPROFILEID", "keyType": "ECDSAP521", "certificateType": "ROOT" },
{ "CN": "SRK2", "description": "SRK for i.MX9 AHAB", "useCase": "HABCA", "profileID": "$ENDPROFILEID", "keyType": "ECDSAP521", "certificateType": "ROOT" },
{ "CN": "SRK3", "description": "SRK for i.MX9 AHAB", "useCase": "HABCA", "profileID": "$ENDPROFILEID", "keyType": "ECDSAP521", "certificateType": "ROOT" }
],
"productConfigItems": [
{ "name": "FusemapType", "value": "IMXAHAB" },
{ "name": "AHABDigest", "value": "sha256" }
],
"productOperations": [
{
"name": "AHAB SPSDK signing",
"description": "AHAB image signing via SPSDK",
"operationType": "SignSPSDK",
"approvalRule": {
"name": "Test rule",
"description": "Rule used for the TEST product",
"allowedGroups": ["$WRITERGROUP"],
"approvalGroups": ["$APPROVERGROUP"],
"blanketGroups": []
}
}
]
}
$WRITERGROUP and $APPROVERGROUP are the Microsoft Entra group object IDs that
are allowed to submit and to approve signing requests. More information about
rules is in approval rules.
Save the file as product.json and create the product:
(venv) $ signing-tool -n test.ini product add -T product.json
...
Product Add request sent. Request ID: 608fdff6-2a06-4186-8267-94a84e7da88c state: ApprovalRequired
This product generates four ECDSAP521 key pairs in the CloudHSM (one per SRK).
Approve the product¶
The product was approved using the GUI. Then the product ID and the operation ID were read with the python tool (state is 16 for a ready product).
- productID = 608fdff6-2a06-4186-8267-94a84e7da88c
- operation ID for the SignSPSDK operation = 42b5da24-d2fc-4776-8aa1-a9cf0acf734b
(venv) $ signing-tool -n test.ini product getall
{
"count": 1,
"items": [
{
"description": "AHAB SPSDK signing product",
"id": "608fdff6-2a06-4186-8267-94a84e7da88c",
"name": "TEST for i.mx9",
"state": 16
}
]
}
Getting the SRK table and SRK hash¶
During manufacturing the SRK table and SRK hash are needed (the SRK hash is fused into the device). Register a client that can read them, approve it from the UI, then fetch the values:
(venv) $ signing-tool -n test.ini client add -N Manufacturing -D "Get sensitive information" \
-K client.public -U "oid:<your-object-id>" -T ProductionPC -p 608fdff6-2a06-4186-8267-94a84e7da88c
Client Add request sent. state: ApprovalRequired
(venv) $ signing-tool -n test.ini secrets get \
-P 608fdff6-2a06-4186-8267-94a84e7da88c -C client.private -O /tmp/prod.json
SRKHASH written to: /tmp/prod.jsonSRKHASH
SRKTABLE written to: /tmp/prod.jsonSRKTABLE
Full secret payload written to: /tmp/prod.json
The oid: form above names a person. A manufacturing client driven by a CI
pipeline or a factory script authenticates as a service principal instead, so
register that one with -U "appid:<application-id>" - see
which identity form to register.
More info can be found from client usage.
Building the signing payload¶
The SignSPSDK operation takes a single compressed archive containing the image,
an SPSDK configuration file describing the chip and image, and a request.json
that names them.
request.json:
{ "mode": "ahab", "image": "imx9-container.bin", "config": "mimx9352-sign.yaml" }
The SPSDK configuration file (mimx9352-sign.yaml) is short — you only fill in
the chip- and build-specific fields, and the platform fills in everything to do
with keys and SRK security:
family: mimx9352
revision: latest
fuse_version: 0
sw_version: 0
See the SPSDK configuration file for which fields you own. Build the archive:
tar czf payload.tar.gz request.json mimx9352-sign.yaml imx9-container.bin
Name the three files explicitly, as above. tar czf payload.tar.gz . stores them
as ./request.json and so on, and the platform rejects any member whose name
carries a path separator.
Signing the AHAB container¶
Submit the archive with the SignSPSDK operation:
(venv) $ signing-tool -n test.ini imagesigning add SignSPSDK \
-P 608fdff6-2a06-4186-8267-94a84e7da88c \
--operid 42b5da24-d2fc-4776-8aa1-a9cf0acf734b \
-N TEST -D TEST -F payload.tar.gz
Request sent. Request ID: 91b9f3bf-fb75-4294-8826-df3fc13e7332, state: Created
By default SRK0 signs. To sign with a different SRK, add --signingKeyIndex
(0–3) to the command. See the
API specification ImageSigning POST endpoint for details.
Approve the signing request¶
The request was approved from the GUI.
Download the signed container¶
After approval the request is processed. When its state is 16 the signing is complete and the signed container can be downloaded:
(venv) $ signing-tool -n test.ini imagesigning get \
-I 91b9f3bf-fb75-4294-8826-df3fc13e7332 -O /tmp/signed.bin
Downloading signed binary to: /tmp/signed.bin
File Downloaded
Verifying the signed container¶
While testing, the signed image can be inspected with the NXP ahab_image_verifier
tool (part of the NXP CST package). This is for experimentation and debugging
only — for real verification follow NXP's secure-boot procedure (for example
ahab_status on the device).
$ ahab_image_verifier /tmp/signed.bin
Notice: ahab_image_verifier is intended solely for experimentation and debugging purposes.
File: /tmp/signed.bin
Container #0 - offset: 0x0
Header:
Tag: Container (0x87)
Flags: 0x1
SRK Set: OEM SRK
SRK Selection: SRK 0 is used
Number of Images: 1
...