Xilinx Signing¶
Looking for the full Zynq UltraScale+ design?
This page documents the SignBootgenImage request and archive formats. For
the complete secure boot design — the product with its PSK and SSK key
operations, the PPK eFUSE values and which slot each one belongs to, and
verification before shipping — see
Building CRA-ready Zynq UltraScale+ MPSoC gateways.
In order to do Xilinx boot.bin signing for Zynq UltraScale+ MPSoC devices following actions/configurations are required
- Product is created with a configuration which supports Xilinx boot image signing.
- Product operation SignBootgenImage has been configured
Product configuration¶
- Create product with needed signing operations.
- Check product for product configuration details.
Input data for Xilinx signing¶
The input is a tar.gz archive containing a request.json descriptor and the binary component files referenced by it. The tar.gz payload must be base64-encoded before uploading to the platform.
Archive contents¶
The tar.gz archive must contain:
request.json: describes the boot image structure (generated from the Xilinx BIF file)- Binary component files (ELF and flat binary) referenced by
request.json
request.json format¶
The request.json describes the Zynq UltraScale+ boot image layout. It corresponds to the Xilinx Bootgen BIF (Boot Image Format) file, with authentication-related fields removed (the platform handles key management and RSA authentication).
Example request.json:
{
"arch": "zynqmp",
"ppk_select": 0,
"spk_id": 0,
"images": [{
"output": "boot.bin",
"fsbl_config": ["a53_x64"],
"items": [
{"filename": "pmufw.elf", "attributes": "pmufw_image"},
{"filename": "fsbl.elf", "attributes": "bootloader, destination_cpu=a53-0"},
{"filename": "mini.bit", "attributes": "destination_device=pl"},
{"filename": "bl31.elf", "attributes": "destination_cpu=a53-0, exception_level=el-3, trustzone"},
{"filename": "tee-pager_v2.bin", "attributes": "destination_cpu=a53-0, exception_level=el-1, trustzone, load=0x7e800000, startup=0x7e800000"},
{"filename": "u-boot.elf", "attributes": "destination_cpu=a53-0, exception_level=el-2"}
]
}]
}
Note
The attributes field corresponds to Xilinx Bootgen BIF attributes. Do not include pskfile, sskfile, or authentication attributes. The platform adds RSA authentication using its own PSK/SSK keys managed in the HSM.
Note
The platform supports different hash algorithms and key sizes. The values and component list shown above are examples. Configure them according to your product's requirements.
Key selection: ppk_select and spk_id¶
The PSK names carry AMD's PPK slot numbers:
arch |
ppk_select |
Key operation | eFUSE value (product secrets) |
|---|---|---|---|
zynqmp |
0 | BootgenPSK0 |
EFusePPK0Bits (PPK0 eFUSEs) |
zynqmp |
1 | BootgenPSK1 |
EFusePPK1Bits (PPK1 eFUSEs) |
zynq |
0 | BootgenPSK |
EFusePPKBits |
spk_id is the value the boot ROM compares with the 32-bit SPK_ID eFUSE, so it is written into every authentication certificate. eFUSE bits can only be set, so each SPK revocation burns one more bit, and each step uses its own SSK:
spk_id |
0 | 1 | 3 | 7 | 15 | 31 | 63 | 127 |
|---|---|---|---|---|---|---|---|---|
| SSK | BootgenSSK |
BootgenSSK2 |
BootgenSSK3 |
BootgenSSK4 |
BootgenSSK5 |
BootgenSSK6 |
BootgenSSK7 |
BootgenSSK8 |
Any other spk_id is refused. spk_id belongs at the top level of request.json; an spk_id inside an item's attributes is refused. zynq images use ppk_select 0 and spk_id 0. Only SignBootgenImage (signing) is supported.
Typical boot image components¶
A Zynq UltraScale+ boot image typically contains the following components:
| File | Description | Format |
|---|---|---|
pmufw.elf |
Platform Management Unit firmware | ELF |
fsbl.elf |
First Stage Boot Loader | ELF |
*.bit |
FPGA bitstream | Xilinx bitstream |
bl31.elf |
ARM Trusted Firmware (EL3) | ELF |
tee-pager*.bin |
OP-TEE secure OS (flat binary) | Raw binary |
u-boot.elf |
U-Boot bootloader | ELF |
Output¶
The platform returns a tar.gz archive (raw binary, not base64) containing boot.bin (filename is configured by 'output' field in request.json), the fully assembled and RSA-authenticated Zynq UltraScale+ boot image, as produced by Bootgen.
The archive also holds primary.pub (the PPK) and secondary.pub (the SPK). bootgen -efuseppkbits over primary.pub must give the eFUSE value from the product secrets for the ppk_select used.
The returned boot.bin:
- Is a valid ZynqMP boot image (boot ROM header at offset 0)
- Has RSA authentication on each component (equivalent to
[authentication=rsa]in the BIF) - Uses the product's PSK/SSK key pair for signing
Developer example: preparing a Xilinx boot image for signing¶
1. Start from the Bootgen BIF file¶
A typical Xilinx Bootgen BIF file (boot.bif) for a Zynq UltraScale+ design looks like:
the_ROM_image:
{
[fsbl_config] a53_x64
[pmufw_image] pmufw.elf
[bootloader, destination_cpu=a53-0,
authentication=rsa, pskfile=psk.pem, sskfile=ssk.pem] fsbl.elf
[destination_device=pl,
authentication=rsa, pskfile=psk.pem, sskfile=ssk.pem] mini.bit
[destination_cpu=a53-0, exception_level=el-3, trustzone,
authentication=rsa, pskfile=psk.pem, sskfile=ssk.pem] bl31.elf
[destination_cpu=a53-0, exception_level=el-1, trustzone,
load=0x7e800000, startup=0x7e800000,
authentication=rsa, pskfile=psk.pem, sskfile=ssk.pem] tee-pager_v2.bin
[destination_cpu=a53-0, exception_level=el-2,
authentication=rsa, pskfile=psk.pem, sskfile=ssk.pem] u-boot.elf
}
Warning
When building the request.json for the LAAVAT Platform, strip the authentication, pskfile, and sskfile attributes from each item. The platform handles key management and adds RSA authentication using its own keys stored in the HSM.
2. Generate request.json from the BIF¶
Convert the BIF to request.json by extracting the architecture, image items, and their attributes (without the authentication/key fields):
{
"arch": "zynqmp",
"ppk_select": 0,
"spk_id": 0,
"images": [{
"output": "boot.bin",
"fsbl_config": ["a53_x64"],
"items": [
{"filename": "pmufw.elf", "attributes": "pmufw_image"},
{"filename": "fsbl.elf", "attributes": "bootloader, destination_cpu=a53-0"},
{"filename": "mini.bit", "attributes": "destination_device=pl"},
{"filename": "bl31.elf", "attributes": "destination_cpu=a53-0, exception_level=el-3, trustzone"},
{"filename": "tee-pager_v2.bin", "attributes": "destination_cpu=a53-0, exception_level=el-1, trustzone, load=0x7e800000, startup=0x7e800000"},
{"filename": "u-boot.elf", "attributes": "destination_cpu=a53-0, exception_level=el-2"}
]
}]
}
3. Package the archive¶
Create a tar.gz archive containing request.json and all referenced binary files:
tar czf xilinx-payload.tar.gz request.json pmufw.elf fsbl.elf mini.bit bl31.elf tee-pager_v2.bin u-boot.elf
4. Submit to the LAAVAT Platform¶
The tar.gz is base64-encoded and uploaded via the standard image signing flow. See the usage example below.
PPK hash for eFuse programming¶
The boot ROM on the ZynqMP verifies boot.bin against the PPK hash burned into the PPK0 or PPK1 eFUSEs, chosen by ppk_select. The values are delivered with the product secrets as EFusePPK0Bits and EFusePPK1Bits (Zynq-7000: EFusePPKBits), see the table above.
For production:
- The PPK hash (SHA3-384 in AMD's Keccak form) must be programmed into the device eFuses during manufacturing
- The PPK hash is a one-time-programmable value. Once set, only boot images signed with the matching PPK can boot
For R&D/unfused devices, the bh_auth_enable BIF flag enables authentication without eFuses (for testing).
Example usage with reference client package: Xilinx signing¶
The examples below use two config files created with config-init: test.ini for the regular user and approver.ini for a user in the approvers group. Each config holds a token_file reference rather than a literal token, so no token appears on the command line. See Reference Client › Usage for how to create these configs and for the secure token-input forms (-t @file, -t @-).
(venv) $ signing-tool -n test.ini imagesigning add SignBootgenImage \
-N test -D test2 -P adcb30d8-f009-438e-b1b2-96f507b306cb --operid 4add90e9-ffb3-4708-9554-ed2e82e8fd71 -F xilinx-payload.tar.gz
# Approve the signing request
(venv) $ signing-tool -n approver.ini imagesigning approve \
-I a83081a6-1d3b-4117-a81b-0ebcfcf0669c
# Get the signed payload (a raw tar.gz: boot.bin, primary.pub, secondary.pub; --skipBase64 because it is not base64)
(venv) $ signing-tool -n test.ini imagesigning get \
-I a83081a6-1d3b-4117-a81b-0ebcfcf0669c -O /tmp/signed-boot.tar.gz --wait --skipBase64