Zynq Ultrascale+ MPSoC Secure bitstream programming from Linux

Table of content

Introduction

The ZynqMp Programmable Logic (PL) can be programmed either using First Stage Boot-loader (FSBL), U-Boot or through Linux. This page provides the details about programming the secure bitstream from Linux using FPGA manager.

Supported features for loading the secure bitstream from Linux are:

  • Encrypted full/partial bitstream loading with the user key.
  • Authenticated full/partial bitstream loading.
  • Authenticated and Encrypted full/partial bitstream loading.
  • Encrypted only Bitstream full/partial loading with the device key.

Unsupported features for loading the secure bitstream from Linux are:

  • Authentication of only headers. 

Architecture

Linux application sends the secure bitstream to Linux FPGA Manager framework to program the PL. With help of Xilinx FPGA driver FPGA Manager sends the bitstream to PMU firmware running on PMU securely via ARM Trusted Firmware(ATF). ARM Trusted Firmware uses IPI messaging service to request PMU firmware to perform bitstream load. With help of XilFPGA library, PMU firmware perform bitstream programming to PL. For authentication and/or encryption of secure bitstream, XilFPGA uses XilSecure library services.

U-boot communicates directly with PMU firmware via ATF for bitstream downloading.

Standalone application has direct access to low level libraries – XilSecure & XilFPGA. It can use PMU firmware services using IPI calls to program PL or can write application using XilFPGA and XilSecure library to directly program PL.

As the data provided in user space will be located in virtual space, linux driver before handing off to ATF converts the data buffers to physical address.

The below image shows the high level architecture of image loading via PMU firmware.


Prerequisites for bitstream loading from Linux

Build PMUFW

As shown in below image, modify BSP settings of xilsecure and xilfpga library using Xilinx Vivado Design Suite.

Enable secure_environment variable of xilsecure library, if encryption only bitstream is to be downloaded.

Enable secure_mode of xilfpga library, if secure bitstream is to be downloaded.

Build Linux bootable image with authentication

We will boot the ZynqMP system using the bootable image created below for all examples of loading different types of bitstream images from Linux.

  1. Generate RSA key pair using bootgen.
  2. Generate SHA-3 hash of Primary Public Key (PPK) created in step 1 using bootgen.
  3. We generated one secondary key (SSK) in step 1. If more SSK’s are required, repeat step 1 to create SSK keys.
  4. Generate the authenticated boot image using bootgen and the below bif file template.

  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.

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

Building Authenticated bitstream

Bitstream can be authenticated using OCM internal memory or by trusting external memory DDR, Xilinx recommends using OCM memory to authenticate the bitstream which is more secure. To authenticate bitstream using OCM, available OCM start address should be provided at BSP settings which is shown in highlighted second row of the above figure 2.

To authenticate bitstream using DDR no need to provide any start address XilFPGA authenticates the bitstream directly from source address(.bin) provided by user.

Generate the authenticated bitstream using bootgen and the below bif file template.

Use following bootgen command to create the image.

Building Encrypted bitstream

Bitstream can be encrypted either using device key or using user defined key in KUP register (KUP Key). Decryption of bitstream with Device key 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. Bitstream is authenticated.

There is no above restriction for using user defined key. 

Generate the encrypted bitstream using bootgen and the below bif file template.

Use following bootgen command to create the image.

Building Authenticated and Encrypted bitstream

Generate the authenticated and encrypted bitstream using bootgen and the below bif file template. Below example assumes that AES encryption key is stored to BBRAM. There are different options available for selecting key source. Refer Zynq Ultrascale plus Security Features # Advanced encryption standard - Galois/Counter Mode (AES-GCM) to find key source details. Note that Decryption of bitstream with Device key is possible only when authentication is enabled, but for KUP key authentication is not compulsory.

Use the following bootgen command to create the image.


Steps to load secure bitstream from Linux

Follow below steps to load secure bitstream from Linux.

  1. Create folder /lib/firmware if it does not exist using following command in Linux.

  2. Copy bitstream file (in .bin format) to be loaded to PL into folder /lib/firmware/.
  3. Select the type of bitstream to be loaded to PL using below command in Linux.

    where bitstream type can be selected from below table. 

    bitstream_type

    Usage

    0x01

    Partial bitstream

    0x02

    Authentication with image in DDR. Once bitstream is authenticated, it is either copied to PL or sent to AES crypto engine based on bitstream image type.

    0x04

    Authentication with image in OCM. During authentication of bitstream block, system stores hash of the bitstream block chunk during authentication. Once authentication is passed, during transfer of the bitstream block to PL or to AES engine, system revalidates hashes of chunk to make sure image not modified after authentication.

    0x08

    Decryption using user key (user key in KUP register)

    0x10

    Decryption using device key

    Note that above values can be ORed based on type of bitstream to be loaded. For example, if bitstream image is to be authenticated in OCM and decrypted using device key, the flag should be written with value 0x14 (0x04 OR 0x10).

  4. If user key to be used for bitstream decryption, the key should be stored in file and pushed using following command in Linux.

    For example,  

    User key 2584B3F7844A0A0AECD36F0E511DA724E38492277D71192462AFC6975936EED0 is stored in usr_key.txt file and this file is pushed to system using following command.

    echo usr_key.txt > /sys/class/fpga_manager/fpga0/key
  5. Now download the bitstream using following command in Linux.

    where bitstream_file_name is the name of file copied into folder /lib/firmware in step 2.


Table of content