ZynqMp security features usage in u-boot



Introduction

Bootloader u-boot is modified to use ZynqMP hardware cryptographic engines to authenticate and/or decrypt and load the image for execution. Xilinx Linux Distrubution PetaLinux v2018.1 releases u-boot with the required modifications to support authenticated and/or encrypted image loading.

Info:

Secure image loading is not supported if the image spans multiple partitions.

Loading an Authenticated Image from u-boot

The following steps shows the process of creating and loading authenticated boot image and data partition.

  1. Generate RSA key pair using bootgen - Refer bootgen section of Zynq Ultrascale plus Security Features wiki page for bootgen command details.
  2. Generate SHA-3 hash of Primary Public Key (PPK) created in step 1 using bootgen - Refer bootgen section of Zynq Ultrascale plus Security Features wiki page for bootgen command details.
  3. Generate the authenticated boot image using bootgen and below bif template file.

    boot_img:
    {
       [auth_params] ppk_select = 1; spk_id = 0x01
       [pskfile]<path_to_primary_secure_key_file>
       [sskfile]<path_to_secondary_secure_key_file>
       [spk_select] spk_efuse
     
       [ bootloader,
         authentication = rsa
       ] <path_to_fsbl_elf_file>
     
       [pmufw_image] <path_to_pmu_file>
     
       [ destination_cpu = a5x-0,
         exception_level = el-3,
         trustzone,
         authentication = rsa
       ] <path_to_atf_elf_file>
     
       [ destination_cpu = a5x-0,
         exception_level = el-2,
         authentication = rsa
       ] <path_to_u_boot_elf_file>
    }
  4. Create a single partition image authenticated and encrypted using bootgen and the below bif file template. Note that if elf file is provided as input, make sure elf doesn't contain multiple loadable sections. 

    data_img:
    {
       [auth_params] ppk_select = 0; spk_id = 0x01
       [pskfile]<path_to_primary_secure_key_file>
       [sskfile]<path_to_secondary_secure_key_file>
       [spk_select] spk_efuse
        
       [ authentication = rsa,
       ] <path_to_image_file_to_be_authenticated>
    }
  5. Enable RSA authentication by setting “RSA_EN” eFUSEs. Refer Programming BBRAM and eFUSEs Application Note (XAPP1319) for eFUSE programming.
  6. Write SHA-3 hash of PPK created in step 2 to PPK0 hash eFUSEs.

    Caution:

    Once RSA authentication is enabled on ZynqMP SoC, only RSA authenticated image created using secret key of the key pair whose public key hash is stored in eFUSE.

  7. Load the boot image to any of the configured/selected boot device(SD/QSPI/NAND) and boot.

    Info:

    There is option for user to revoke PPK once by writing to PPK0_INVLD / PPK1_INVLD eFUSEs. eFUSE has provision of storing the hash of two PPKs. Refer Zynq UltraScale+ Device Technical Reference Manual (UG1085)Programming BBRAM and eFUSEs Application Note (XAPP1319) for further details.

  8. On u-boot command prompt, perform following steps to authenticate the partition.
    • Load image to be authenticated (image created in step 2) in DDR memory.
    • Execute below command to authenticate the image loaded in DDR memory

      zynqmp secure <single_partition_img_addr> <size_of_img>
      
      


      where,

      single_partition_img_addr :

      DDR memory address where data image is loaded

      size_of_img :

      size of data image in bytes

    • u-boot returns the start address of actual partition after successful authentication. In case of failure, it prints the error code.

    Info:

    • If RSA_EN eFSUE is programmed, authentication of the image is compulsory. Boot header authentication is not supported when eFUSE RSA enabled.
    • During development/testing phase, user can disable PPK hash and SPK_ID verification by enabling bh_auth_enable flag in bif file to skips PPK and SPKID verification


Loading an Encrypted Image from u-boot

 Device key usage for decryption is possible only when one of the below condition meets:

  1. When PMU Firmware running on system is built with trusted execution environment (secure_environment) variable of XilSecure library enabled.
  2. Boot image is authenticated

The following steps shows the process of creating and loading encrypted boot image and data partition. This example doesn't use the authentication feature.

  1. Generate the encrypted boot image using bootgen and below bif template file. Below example expects AES red key is stored in BBRAM. Refer bootgen section of Zynq Ultrascale plus Security Features wiki page for bootgen command details.

    boot_img:
    {
       [aeskeyfile]<path_to_red_aes_key_file>
       [keysrc_encryption] bbram_red_key
     
       [ bootloader,
         encryption=aes
       ] <path_to_fsbl_elf_file>
     
       [ pmufw_image,
         encryption=aes
       ] <path_to_pmufw_elf_file>
     
       [ destination_cpu = a5x-0,
         exception_level = el-3,
         trustzone,
         encryption=aes
       ] <path_to_atf_elf_file>
     
       [ destination_cpu = a5x-0,
         exception_level = el-2,
         encryption=aes
       ] <path_to_u_boot_elf_file>
    }
  2. Generate the encrypted data image using bootgen and below bif template file. Refer bootgen section of Zynq Ultrascale plus Security Features wiki page for bootgen command details.

    data_img:
    {
       [aeskeyfile]<path_to_aes_red_key_file>
       [keysrc_encryption] kup_key
     
       [ encryption = aes,
         blocks = 1024; 256(4),
         authentication = rsa,
         load  = 0xF0400000
       ] <path_to_data_file>
    }

    Users can also use the bbram_red_key to decrypt the image if authentication is enabled and in that case user should give [keysrc_encryption] tag value as bbram_red_key in above bif file while creating data image.

  3. Program BBRAM to store the AES red key used during the boot image creation in step 1.
  4. Load the boot image to any of the configured/selected boot device(SD/QSPI/NAND) and boot.
  5. On u-boot command prompt, perform following steps to decrypt the partition.
    • Load image to be authenticated (image created in step 2) in unused DDR memory.
    • Load AES Key used for encrypting data image in step 2 in unused DDR memory.
    • Execute below command at u-boot command prompt to decrypt the partition

      zynqmp secure <single_partition_img_addr> <size_of_img> <KUP_key>


      where,

      single_partition_img_addr :

      DDR memory address where data image is loaded

      size_of_img :

      size of data image in bytes

      KUP_Key :

      DDR memory address where KUP Key is stored (only if image uses KUP to provide decryption key)

    • u-boot returns the start address of actual partition after successful authentication. In case of failure, it prints the error code.


Loading an Authenticated and Encrypted image from u-boot

The following steps shows the process of creating and loading authenticated and encrypted boot image and data partition.

  1. Generate RSA key pair using bootgen.
  2. Generate SHA-3 hash of Primary Public Key (PPK) created in step 1 using bootgen.
  3. Generate the authenticated boot image using bootgen and below bif template file. Refer bootgen section of Zynq Ultrascale plus Security Features wiki page for bootgen command details.

    boot_img:
    {
       [auth_params] ppk_select = 1; spk_id = 0x01
       [pskfile]<path_to_primary_secure_key_file>
       [sskfile]<path_to_secondary_secure_key_file>
       [spk_select] spk_efuse
       [aeskeyfile]<path_to_red_aes_key_file>
     
       [ bootloader,
         authentication = rsa,
         encryption = aes
       ] <path_to_fsbl_elf_file>
     
       [pmufw_image] <path_to_pmu_file>
     
       [ destination_cpu = a5x-0,
         exception_level = el-3,
         trustzone,
         authentication = rsa,
         encryption = aes
       ] <path_to_atf_elf_file>
     
       [ destination_cpu = a5x-0,
         exception_level = el-2,
         authentication = rsa,
         encryption = aes
       ] <path_to_u_boot_elf_file>
    }
  4. Create a single partition image authenticated and encrypted using bootgen and the below bif file template. Note that if elf file is provided as input, make sure elf doesn't contain multiple loadable sections. Refer bootgen section of Zynq Ultrascale plus Security Features wiki page for bootgen command details.

    data_img:
    {
       [auth_params] ppk_select = 0; spk_id = 0x01
       [pskfile]<path_to_primary_secure_key_file>
       [sskfile]<path_to_secondary_secure_key_file>
       [spk_select] spk_efuse
        
       [ authentication = rsa,
       ] <path_to_image_file_to_be_authenticated>
    }
  5. Enable RSA authentication by setting “RSA_EN” eFUSEs. Refer Programming BBRAM and eFUSEs Application Note (XAPP1319) for eFUSE programming.
  6. Write SHA-3 hash of PPK created in step 2 to PPK0 hash eFUSEs.

    Caution:

    Once RSA authentication is enabled on ZynqMP SoC, only RSA authenticated image created using secret key of the key pair whose public key hash is stored in eFUSE.

  7. Program BBRAM to store the AES red key used during the boot image creation in step 1.
  8. Load the boot image to any of the configured/selected boot device(SD/QSPI/NAND) and boot.

    Info:

    There is option for user to revoke PPK once by writing to PPK0_INVLD / PPK1_INVLD eFUSEs. eFUSE has provision of storing the hash of two PPKs. Refer Zynq UltraScale+ Device Technical Reference Manual (UG1085)Programming BBRAM and eFUSEs Application Note (XAPP1319) for further details.

    • Load image to be authenticated (image created in step 2) in DDR memory.
    • Execute below command to authenticate the image loaded in DDR memory

      zynqmp secure <single_partition_img_addr> <size_of_img>


      where,

      single_partition_img_addr :

      DDR memory address where data image is loaded

      size_of_img :

      size of data image in bytes

    • u-boot returns the start address of actual partition after successful authentication. In case of failure, it prints the error code.

Info:

  • If RSA_EN eFSUE is programmed, authentication of the image is compulsory. Boot header authentication is not supported when eFUSE RSA enabled.
  • During development/testing phase, user can disable PPK hash and SPK_ID verification by enabling bh_auth_enable flag in bif file to skips PPK and SPKID verification


Loading Secure Bitstream Images from u-boot

Xilinx Linux Distrubution PetaLinux 2018.1 release u-boot that support loading secured bitstream from u-boot. Below command is added to u-boot to load the secured bitstream to FPGA.

fpga loads [dev] [addr] [size] [auth-loc(0/1/2)] [enc-key-sel(0/1/2)] [KUP_key_addr]


where,

dev :

Device number for future use. Now set it as 0

addr :

address where bitstream is loaded in memory

size :

size of the bitstream image loaded in memory

auth_loc :

location of image to be authenticated is located

0 = On-Chip Memory (OCM)

1 = DDR

2 = no authentication

enc_key_sel :

selection of the encryption key

0 = device key

1 = user key – KUP

2 = no encryption

kup_key_addr :

Address of memory where user key (KUP Key) is stored

User can use similar steps explained in earlier example of secure partition to create bitstream except user should not mention load address in bif file.

Note:

Authenticated and Encrypted bitstreams can be loaded using external DDR (where the DDR is trusted) or using internal OCM (where the external DDR is not trusted)

Aes encryption and decryption usage in u-boot

U-boot supports encryption and decryption using AES, below command is used for encrypt/decrypt a data blob

zynqmp aes srcaddr ivaddr len aesop keysrc dstaddr [keyaddr]

Where

srcaddr :

Encrypts or decrypts blob of data at source address

ivaddr :

Initilization Vector address of aes key

len :

len of the input data blob

aesop :

aesop value specifies the operation which can be

0 for decryption

1 for encryption

keysrc :

keysrc value specifies from which source key has to be used, it can be User/Device/PUF key.

0 for KUP(user key)

1 for DeviceKey

2 for PUF key

dstaddr :

Decrypted data is  copied into dstaddr

         keyaddr:KUP/PUF key addr

RSA public encryption and private decryption usage in u-boot

U-boot supports RSA authentication of data

zynqmp rsa srcaddr srclen mod exp rsaop

Where

srcaddr :

Data at source address

srclen :

Length of source must be key size(4096 bits)

mod :

Modulus (.bin)

exp :

private key exponent for RSA decryption(4096 bits) (.bin) /

public key exponent for RSA encryption(32 bits) (.bin)

rsaop :

0 for RSA Decryption

1 for RSA Encryption

SHA3 usage in u-boot

U-boot supports generating a HASH value for a given data. Below command generates sha3 hash value for data blob at srcaddr and puts 48 bytes hash value into srcaddr

zynqmp sha3 srcaddr srclen

Where

srcaddr :

source address

srclen :

Length of source

Table of content