Xilinx Signing
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 SignXilinx 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.
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 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 authentication using a PPK hash burned into eFuses. The PPK hash is available from the product configuration as the EFusePPKBits field.
For production:
- The PPK hash (SHA-384) 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¶
Xilinx signing examples ($TOKEN contains the "regular" user token and $APPROVERTOKEN contains a token for a user that's in the approvers group):
(venv) $ signing-tool -c -t $TOKEN -a https://app.laavat.io/<CustomerName>/api/v1 imagesigning add SignXilinx \
-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 -c -t $APPROVERTOKEN -a https://app.laavat.io/<CustomerName>/api/v1 imagesigning approve \
-I a83081a6-1d3b-4117-a81b-0ebcfcf0669c
# Get the signed payload (boot.bin inside a tar.gz)
(venv) $ signing-tool -c -t $TOKEN -a https://app.laavat.io/<CustomerName>/api/v1 imagesigning get \
-I a83081a6-1d3b-4117-a81b-0ebcfcf0669c -O /tmp/signed-boot.tar.gz