Spartan UltraScale+ HSM Flow Support with Example - Spartan UltraScale+ HSM Flow Support with Example - 2026.1 English - UG1283

Bootgen User Guide (UG1283)

Document ID
UG1283
Release Date
2026-06-23
Version
2026.1 English

This flow allows creation of authenticated boot images without exposing private keys outside a Hardware Security Module (HSM). The process is split into three stages:

  • Stage 0: Produce hash artifacts (no private keys required)
  • Stage 1: Offline/HSM signing of produced hashes
  • Stage 2: Assemble final boot image using returned signatures

The build host only needs public keys. Private keys (PSK/SSK) remain in the HSM.

Stage 0 Output Format Differs by Device Model

Both files Bootgen writes during Stage 0 -- the SPK file (spk.) and each partition's hashblock file (.N.) -- use the same rule. The format differs depending on the Spartan UltraScale+ device model, and that in turn changes what the HSM has to do during Stage 1:

Note: If you are using lms-sha256, the file extensions are .sha256 instead of .shake256.
Table 1. Bootgen-Returned Data for Offline Signing (Stage 0 output)
Device Models Contents of spk.<ext> (SPK file) Contents of <partition>.N.<ext> (hashblock file) What the HSM must do in Stage 1
SU10P, SU25P, SU35P Pre-computed SHA3 hash of the SPK data, with PKCS-style padding (small, fixed-size). Pre-computed SHA3 hash of the partition's hashblock, with PKCS-style padding (small, fixed-size). Sign each supplied hash directly. The HSM treats each file as an opaque digest.
SU45P, SU60P, SU65P, SU100P, SU150P, SU200P The full SPK header followed by the raw SPK public key data (larger, variable-size -- NOT pre-hashed). The raw hashblock for that partition (larger, variable- size -- NOT pre-hashed). Treat each file as the message to be signed under the LMS scheme. The HSM is responsible for hashing as part of the LMS signature computation.
Why the difference exists

On SU10P, SU25P, and SU35P, the signing flow is "hash, then sign", and Bootgen performs the hashing on the build host before writing each Stage 0 file. On SU45P and above, the signing flow uses the LMS signature scheme, which by construction signs the input message itself -- so the HSM must see the raw data and perform the hashing internally. Using the wrong approach for your device model produces a signature that the boot ROM rejects, and boot authentication fails.

Action required

Match your HSM signing flow to the target device:

SU10P / SU25P / SU35P
Configure the HSM to accept a hash and sign it as-is (no additional digest). Apply this to both the SPK file and every partition hashblock file.
SU45P / SU60P / SU65P / SU100P / SU150P / SU200P
Configure the HSM to accept the raw data block and apply the LMS sign-with-internal-hash operation. Apply this to both the SPK file and every partition hashblock file.
Important: Using an SPK signing flow that does not match the target device model causes boot authentication to fail at boot time, even though Stage 2 image generation appears successful.

Stage 1 – HSM / Offline Signing

Performed entirely inside the secure environment.

Sign:

  • SPK hash file → produces spk.<ext>.sig
  • Hashblock hash or Hashblock → produces <partition>.N.<ext>.sig (N = partition index)

Example (single authenticated partition, SHAKE256):

Input to HSM:
  spk.shake256.sig    (hash blob)
  plm.0.shake256      (Hashblock hash or Hashblock)
HSM outputs:
  spk.shake256.sig        (now a signature)
  plm.0.shake256.sig      (Hashblock hash or Hashblock signature)

Ensure:

  • PSK signs SPK hash
  • SSK signs hashblock hash/ hashblock hash
  • File naming preserved exactly
  • Binary (raw) signature format returned

Stage 2 – Final Image Assembly

Recombines original inputs + returned signatures.

Command:

./bootgen -arch spartanup -image test_stage2.bif -w -o boot_new.bin -log trace

Example (corrected for SHAKE256):

new_bif:
{
    id_code = 0x04E88093
    extended_id_code = 0x01
    id = 0x2
    boot_config { smap_width = 32 }
    ppkfile = ../files/hss_keys/primary.lms.pub
    spkfile = ../files/hss_keys/secondary.lms.pub
    image {
        name = pmc_subsys
        id = 0x1c000001
        partition {
            id = 0x01
            type = bootloader
            authentication = lms-shake256
            presign = plm.0.shake256.sig
            spksignature = spk.shake256.sig
            file = ../files/plm.elf
        }
        partition {
            id = 0x09
            type = pmcdata, load = 0xf2000000
            file = ../files/pmc_data.cdo
        }
    }
}

(If you instead choose lms-sha256, change authentication plus all .shake256 to .sha256 and presign = plm.0.sha256.sig, spksignature = spk.sha256.sig.)

Output: boot_new.bin (fully authenticated boot image)

Bootgen validates:

  • Signature lengths/format
  • Algorithm consistency
  • Presence of required presign + spksignature

Common Issues

  1. presign file not found:
    • Cause: Wrong extension or missing index (.0.)
  2. spksignature mismatch:
    • Cause: SPK public key in Stage 2 differs from Stage 0
  3. Mixed algorithm/extension:
    • lms-shake256 must use .shake256, lms-sha256 must use .sha256

Best Practices

  • Keep Stage 0 in build pipeline; isolate Stage 1 (HSM) with audit logging
  • Verify returned signatures (size sanity) before Stage 2
  • Enforce consistent key sets between Stage 0 and Stage 2
  • Automate detection of extension/key mismatches (pre-flight script)

Notes on LMS/HSS

  • Single-level LMS (LMS Only) vs hierarchical HSS (multi-level) affects private key handling, not external file naming.
  • Hash/signature generation interfaces remain identical for the flow.