HSM Mode Steps - 2024.1 English

Vitis Unified Software Platform Documentation: Embedded Software Development (UG1400)

Document ID
UG1400
Release Date
2024-05-30
Version
2024.1 English

Stage 0: Generate SPK Hash

Generate hash for SSK1:
command : bootgen -arch versal -image stage0-SSK1.bif -generate_hashes -w on -log error
 
stage0_SSK1:
{
  spkfile = rsa-keys/SSK1.pub
}
Generate hash for SSK2:
command : bootgen -arch versal -image stage0-SSK2.bif -generate_hashes -w on -log error
 
stage0_SSK2:
{
  spkfile = rsa-keys/SSK2.pub
}
Generate hash for SSK3:
command : bootgen -arch versal -image stage0-SSK3.bif -generate_hashes -w on -log error
 
stage0_SSK3:
{
  spkfile = rsa-keys/SSK3.pub
}

Stage 1: Sign SPK hash

Sign the generated hashes:
openssl rsautl -raw -sign -inkey rsa-keys/PSK1.pem -in SSK1.pub.sha384 > SSK1.pub.sha384.sig
openssl rsautl -raw -sign -inkey rsa-keys/PSK2.pem -in SSK2.pub.sha384 > SSK2.pub.sha384.sig
openssl rsautl -raw -sign -inkey rsa-keys/PSK3.pem -in SSK3.pub.sha384 > SSK3.pub.sha384.sig

Stage 2: Encrypt Individual Partitions

Encrypt partition 1:
command : bootgen -arch versal -image stage2a.bif -o pmc_subsys_e.bin -w on -log error
 
stage2a:
{
 image
 {
  name = pmc_subsys, id = 0x1c000001
  partition
  {
   id = 0x01, type = bootloader,
   encryption=aes,
   keysrc = bbram_red_key,
   aeskeyfile = encr_keys/bbram_red_key.nky,
   dpacm_enable,
   file = images/gen_files/plm.elf
  }
  partition
  {
   id = 0x09, type = pmcdata,
   load = 0xf2000000,
   keysrc = bbram_red_key,
   aeskeyfile = encr_keys/pmcdata.nky
   dpacm_enable
   file = images/gen_files/pmc_data.cdo
  }
 }
}
Encrypt partition 2:
command : bootgen -arch versal -image stage2b-1.bif -o lpd_lpd_data_e.bin -w on -log error
 
stage2b_1:
{
 image
 {
  name = lpd, id = 0x4210002
  partition
  {
   id = 0x0C, type = cdo,
   encryption=aes, delay_auth,
   keysrc = bbram_red_key,
   aeskeyfile = encr_keys/key1.nky,
   dpacm_enable,
   file = images/gen_files/lpd_data.cdo
  }
 }
}
Encrypt partition 3:
command : bootgen -arch versal -image stage2b-2.bif -o lpd_psm_fw_e.bin -w on -log error
 
stage2b_2:
{
 image
 {
  name = lpd, id = 0x4210002
  partition
  {
   id = 0x0B, core = psm,
   encryption = aes, delay_auth,
   keysrc = bbram_red_key,
   aeskeyfile = encr_keys/key2.nky,
   dpacm_enable,
   file = images/static_files/psm_fw.elf
  }
 }
}
Encrypt partition 4:
command : bootgen -arch versal -image stage2c.bif -o fpd_e.bin -w on -log error
 
stage2c:
{
 image
 {
  name = fpd, id = 0x420c003
  partition
  {
   id = 0x08, type = cdo,
   encryption=aes, delay_auth,
   keysrc = bbram_red_key,
   aeskeyfile = encr_keys/key5.nky,
   dpacm_enable,
   file = images/gen_files/fpd_data.cdo
  }
 }
}
Encrypt partition 5
command : bootgen -arch versal -image stage2d.bif -o subsystem_e.bin -w on -log
error

stage2d:
{
 image
 {
  name = ss, id = 0x1c000033
  partition
  {
   id = 0x0D, type = cdo,
   encryption = aes,
   keysrc = bbram_red_key,
   aeskeyfile = encr_keys/key6.nky,
   dpacm_enable,
   file = images/gen_files/subsystem.cdo
  }
 }
}

Stage 3: Generate Boot Header Hash

command : bootgen -arch versal -image stage3.bif -generate_hashes -w on -log error
 
stage3:
{
    boot_config {bh_auth_enable}  
    image
    {
      name = pmc_subsys, id = 0x1c000001
      {
        type = bootimage,
        authentication=rsa,
        ppkfile = rsa-keys/PSK1.pub,
        spkfile = rsa-keys/SSK1.pub,
        spksignature = SSK1.pub.sha384.sig,
        file = pmc_subsys_e.bin
      }
    }
}

Stage 4: Sign Boot Header Hash

Sign the generated hashes:
openssl rsautl -raw -sign -inkey rsa-keys/SSK1.pem -in bootheader.sha384 > bootheader.sha384.sig

Stage 5: Generate Partition Hashes

command : bootgen -arch versal -image stage5.bif -generate_hashes -w on -log error
 
stage5:
{
    bhsignature = bootheader.sha384.sig
     
    image
    {
      name = pmc_subsys, id = 0x1c000001
      {
        type = bootimage,
        authentication=rsa,
        ppkfile = rsa-keys/PSK1.pub,
        spkfile = rsa-keys/SSK1.pub,
        spksignature = SSK1.pub.sha384.sig,
        file = pmc_subsys_e.bin
      }
    }
     
    image
    {
     name = lpd, id = 0x4210002
     partition
     {
      type = bootimage,
      authentication = rsa,
      ppkfile = rsa-keys/PSK3.pub,
      spkfile = rsa-keys/SSK3.pub,
      spksignature = SSK3.pub.sha384.sig,
      file = lpd_lpd_data_e.bin
     }
     partition
     {
      type = bootimage,
      authentication = rsa,
      ppkfile = rsa-keys/PSK1.pub,
      spkfile = rsa-keys/SSK1.pub,
      spksignature = SSK1.pub.sha384.sig,
      file = lpd_psm_fw_e.bin
     }
    }  
    
    image
    {
      id = 0x1c000000, name = fpd
      {
        type = bootimage,       
        authentication=rsa,
        ppkfile = rsa-keys/PSK3.pub,
        spkfile = rsa-keys/SSK3.pub,
        spksignature = SSK3.pub.sha384.sig,
        file = fpd_e.bin  
      }
    }
     
    image
    {
     id = 0x1c000033, name = ss
     {
       type = bootimage,
       authentication = rsa,
       ppkfile = rsa-keys/PSK2.pub,
       spkfile = rsa-keys/SSK2.pub,
       spksignature = SSK2.pub.sha384.sig,
       file = subsystem_e.bin
     }
    }
}

Stage 6: Sign Partition Hashes

openssl rsautl -raw -sign -inkey rsa-keys/SSK1.pem -in pmc_subsys_1.0.sha384 > pmc_subsys.0.sha384.sig
 
openssl rsautl -raw -sign -inkey rsa-keys/SSK3.pem -in lpd_12.0.sha384 > lpd.0.sha384.sig
openssl rsautl -raw -sign -inkey rsa-keys/SSK1.pem -in lpd_11.0.sha384 > psm.0.sha384.sig
openssl rsautl -raw -sign -inkey rsa-keys/SSK1.pem -in lpd_11.1.sha384 >psm.1.sha384.sig
openssl rsautl -raw -sign -inkey rsa-keys/SSK1.pem -in lpd_11.2.sha384 >psm.2.sha384.sig
openssl rsautl -raw -sign -inkey rsa-keys/SSK1.pem -in lpd_11.3.sha384 >psm.3.sha384.sig
openssl rsautl -raw -sign -inkey rsa-keys/SSK1.pem -in lpd_11.4.sha384 >psm.4.sha384.sig
 
openssl rsautl -raw -sign -inkey rsa-keys/SSK3.pem -in fpd_8.0.sha384 > fpd_data.cdo.0.sha384.sig
openssl rsautl -raw -sign -inkey rsa-keys/SSK2.pem -in ss_13.0.sha384 > ss.0.sha384.sig

Stage 7: Insert Partition Signatures into Authentication Certificates

Insert partition 1 signature:
command : bootgen -arch versal -image stage7a.bif -o pmc_subsys_e_ac.bin -w on -log error
 
stage7a:
{
    bhsignature = bootheader.sha384.sig
    boot_config {bh_auth_enable}
     
    image
    {
      name = pmc_subsys, id = 0x1c000001
      {
        type = bootimage,
        authentication=rsa,
        ppkfile = rsa-keys/PSK1.pub,
        spkfile = rsa-keys/SSK1.pub,
        spksignature = SSK1.pub.sha384.sig,
        presign = pmc_subsys.0.sha384.sig,
        file = pmc_subsys_e.bin
      }
    }
}
Insert partition 2 signature:
command : bootgen -arch versal -image stage7b-1.bif -o lpd_lpd_data_e_ac.bin -w on -log error
 
stage7b_1:
{  
    image
    {
     name = lpd, id = 0x4210002
     partition
     {
      type = bootimage,
      authentication = rsa,
      ppkfile = rsa-keys/PSK3.pub,
      spkfile = rsa-keys/SSK3.pub,
      spksignature = SSK3.pub.sha384.sig,
      presign = lpd.0.sha384.sig,
      file = lpd_lpd_data_e.bin
     }
    }  
}
Insert partition 3 signature:
command : bootgen -arch versal -image stage7b-2.bif -o lpd_psm_fw_e_ac.bin -w on -log error
 
stage7b_2:
{  
    image
    {
     name = lpd, id = 0x4210002
     partition
     {
      type = bootimage,
      authentication = rsa,
      ppkfile = rsa-keys/PSK1.pub,
      spkfile = rsa-keys/SSK1.pub,
      spksignature = SSK1.pub.sha384.sig,
      presign = psm.0.sha384.sig,
      file = lpd_psm_fw_e.bin
     }
    }  
}
Insert partition 4 signature:
command : bootgen -arch versal -image stage7c.bif -o fpd_e_ac.bin -w on -log error
 
stage7c:
{
    image
    {
      id = 0x1c000000, name = fpd
      { type = bootimage,       
        authentication=rsa,
        ppkfile = rsa-keys/PSK3.pub,
        spkfile = rsa-keys/SSK3.pub,
        spksignature = SSK3.pub.sha384.sig,
        presign = fpd_data.cdo.0.sha384.sig,
        file = fpd_e.bin  
      }
    }
}
Insert partition 5 signature:
command : bootgen -arch versal -image stage7d.bif -o subsystem_e_ac.bin -w on -log error
 
stage7d:
{
    image
    {
     id = 0x1c000033, name = ss
     { type = bootimage,
       authentication = rsa,
       ppkfile = rsa-keys/PSK2.pub,
       spkfile = rsa-keys/SSK2.pub,
       spksignature = SSK2.pub.sha384.sig,
       presign = ss.0.sha384.sig,
       file = subsystem_e.bin
     }
    }
}

Stage 8: Generate Image Header Table Hash

command : bootgen -arch versal -image stage8a.bif -generate_hashes -w on -log error
 
stage8a:
{
  id_code = 0x04ca8093
  extended_id_code = 0x01
  id = 0x2

  metaheader
  {
   authentication = rsa,
   ppkfile = rsa-keys/PSK2.pub,
   spkfile = rsa-keys/SSK2.pub,
   spksignature = SSK2.pub.sha384.sig,
   encryption=aes,
   keysrc = bbram_red_key,
   aeskeyfile = encr_keys/efuse_red_metaheader_key.nky,
   dpacm_enable,
   revoke_id = 0x00000002
  }
 
  image
  {
    {type = bootimage, file = pmc_subsys_e_ac.bin}
  }
   
  image
  {
    {type = bootimage, file = lpd_lpd_data_e_ac.bin}
    {type = bootimage, file = lpd_psm_fw_e_ac.bin}
  }
   
  image
  {
    {type = bootimage, file = fpd_e_ac.bin}
  }
   
  image
  {
    {type = bootimage, file = subsystem_e_ac.bin}
  }
}

Stage 9: Sign Image Header Table Hash

Sign the generated hashes:
openssl rsautl -raw -sign -inkey rsa-keys/SSK2.pem -in imageheadertable.sha384 > imageheadertable.sha384.sig

Stage 10: Generate Meta Header Hash

command : bootgen -arch versal -image stage8b.bif -generate_hashes -w on -log error
 
stage8b:
{
  headersignature = imageheadertable.sha384.sig
  id_code = 0x04ca8093
  extended_id_code = 0x01
  id = 0x2
     
  metaheader
  {
   authentication = rsa,
   ppkfile = rsa-keys/PSK2.pub,
   spkfile = rsa-keys/SSK2.pub,
   spksignature = SSK2.pub.sha384.sig,
   encryption=aes,
   keysrc = bbram_red_key,
   aeskeyfile = encr_keys/efuse_red_metaheader_key.nky,
   dpacm_enable
  }
 
  image
  {
    {type = bootimage, file = pmc_subsys_e_ac.bin}
  }
   
  image
  {
    {type = bootimage, file = lpd_lpd_data_e_ac.bin}
    {type = bootimage, file = lpd_psm_fw_e_ac.bin}
  }
   
  image
  {
    {type = bootimage, file = fpd_e_ac.bin}
  }
   
  image
  {
    {type = bootimage, file = subsystem_e_ac.bin}
  }
}

Stage 11: Sign Meta Header Hash

openssl rsautl -raw -sign -inkey rsa-keys/SSK2.pem -in MetaHeader.sha384 > metaheader.sha384.sig

Stage 12: Combine Partitions and Insert Header Signature

Build the complete PDI:

command : bootgen -arch versal -image stage10.bif -o final.bin -w on -log error
 
stage10:
{
  headersignature = imageheadertable.sha384.sig
  id_code = 0x04ca8093
  extended_id_code = 0x01
  id = 0x2

  metaheader
  {
   authentication = rsa,
   ppkfile = rsa-keys/PSK2.pub,
   spkfile = rsa-keys/SSK2.pub
   spksignature = SSK2.pub.sha384.sig,
   presign = metaheader.sha384.sig
   encryption=aes,
   keysrc = bbram_red_key,
   aeskeyfile = encr_keys/efuse_red_metaheader_key.nky,
   dpacm_enable
  }
 
  image
  {
    {type = bootimage, file = pmc_subsys_e_ac.bin}
  }
   
  image
  {
    {type = bootimage, file = lpd_lpd_data_e_ac.bin}
    {type = bootimage, file = lpd_psm_fw_e_ac.bin}
  }
   
  image
  {
    {type = bootimage, file = fpd_e_ac.bin}
  }
   
  image
  {
    {type = bootimage, file = subsystem_e_ac.bin}
  }
}
Note: If signing using ecdsa, below is an example for ecdsa-p384 using openssl.

Assuming secondary.pub.sha384 is a Bootgen generated hash for a given SPK, below is a script to generate Bootgen usable signature with a PSK, primary.pem.

#! /bin/bash
ecdsa-p384-sign() {
cp $2 $2.hash
truncate -s 48 $2.hash
openssl pkeyutl -sign -inkey $1 -pkeyopt digest:sha3-384 -out $2.der -in $2.hash
r=$(openssl asn1parse -in $2.der -inform DER | sed -n 2p | sed -n 's/.*INTEGER.*:\(.*\)/0000000000000000\1/p' | sed -n 's/.*\(.\{96\}\).*/\1/p')
s=$(openssl asn1parse -in $2.der -inform DER | sed -n 3p | sed -n 's/.*INTEGER.*:\(.*\)/0000000000000000\1/p' | sed -n 's/.*\(.\{96\}\).*/\1/p')
padding=$(head -c 832 /dev/zero | LC_ALL=C tr "\000" "00")
echo -n $r$s$padding > $3
}
ecdsa-p384-sign primary.pem secondary.pub.sha384 secondary.pub.sha384.sig