Skip to content

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

  1. Create product with needed signing operations.
    1. 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