Skip to content

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
  ...