NOTE: This page is applicable only for 2017.1 and 2017.2

Authentication and Decryption in ZynqMP u-boot


The authentication and decryption functionality in u-boot is divided into two.
1. Authentication or decryption for loading authenticated or encrypted bitstreams to PL.
2. Authentication and/or decryption of images other than PL bitstream.


Loading authenticated/encrypted PL bitstream at u-boot


At u-boot, the authentication/decryption of PL bitstream images is supported using new fpga command "fpga loads" which is described below.

fpga loads [dev] [address] [size] [key/sigaddr:size] [IV/PPKaddr:size] [secureimgtype]

Loads the secure bitstreams(authenticated/encrypted)image of [size] from [address] using key/signature(key for encrypted bitstreams and signature for authenticated bitstreams) from address with size :size and IV/PPK(IV is for encrypted and PPK is for authenticated) at address with size. The secure image type specifies whether it is authenticated/encrypted (1-auth, 0- encrypted) type of bitstream. Please note that as of now u-boot supports sha256 only for hashing

Procedure to create an encrypted bitstream at host

  1. create a bif file as shown in below example.
Example bif file contents:
all:
{
[aeskeyfile]key.nky
[encryption = aes]design_1_wrapper.bit
}
Here key.nky is the key file which contains AES key and IV and design_1_wrapper.bit is bit stream file to be encrypted.
  • Use bootgen as below to get an encrypted bitsream image
bootgen -image encrypt.bif -arch zynqmp -process_bitstream bin
  • The above command outputs an encrypted bitstream image with name design_1_wrapper.bit.bin

Loading of an encrypted bitstream image at u-boot


ZynqMP> load mmc 0 100000 design_1_wrapper.bit.bin
reading design_1_wrapper.bit.bin
26510908 bytes read in 1772 ms (14.3 MiB/s)
ZynqMP> load mmc 0 2000000 key.bin
reading key.bin
64 bytes read in 9 ms (6.8 KiB/s)
ZynqMP> load mmc 0 2100000 iv.bin
reading iv.bin
24 bytes read in 9 ms (2 KiB/s)
ZynqMP> fpga loads 0 100000 194863c 2000000:40 2100000:18 0
ZynqMP></span>
Above is an example on how to load authenticated bitstreams. Initially we load all the required files(design_1_wrapper.bit.bin, key.bin and iv.bin) at different addresses and then
use fpga loads command as shown above. '0' at the end specifies to load an encrypted bitstream

Procedure to create authenticated image and required files at host

1. Generating RSA private key, 4096 bit long modulus
openssl genrsa -out private-key.pem 4096
2. Generate the RSA public key pair using RSA private key
openssl pkey -in private-key.pem -out pubkey-key.pem -pubout
3. Generate Signature for the required Bit stream file ( design_1_wrapper.bit.bin)
openssl dgst -sha256 -sign private-key.pem -out signature.bin design_1_wrapper.bit.bin
4. Generate public-key.pem.bin from public-key.pem using below command and helper script.
command : pub-key.sh public-key.pem
helper script:

With the above command, we will get below files.
design_1_wrapper.bit.bin
pubkey-key.pem.bin
signature.bin

Loading of an authenticated bitstream image at u-boot

ZynqMP> fatload mmc 0 100000 design_1_wrapper.bit.bin
reading design_11_wrapper.bit.bin
26510780 bytes read in 1772 ms (14.3 MiB/s)
ZynqMP> fatload mmc 0 3000000 signature.bin
reading signature.bin
512 bytes read in 10 ms (49.8 KiB/s)
ZynqMP> fatload mmc 0 3100000 pubkey-key.pem.bin
reading pubkey-key.pem.bin
516 bytes read in 12 ms (42 KiB/s)
ZynqMP> fpga loads 0 100000 19485bc 3000000:200 3100000:204 1
ZynqMP> Loading.......................................................
........................................................................................................................................................e</span>
Above is an example on how to load authenticated bitstreams. Initially we load all the required files(design_1_wrapper.bit.bin, signature.bin and pubkey-key.pem.bin) at different addresses and then
use fpga loads command as shown above. '1' at the end specifies to load an authenticated bitstream.

Loading authenticated/encrypted Images at u-boot

Preparing encrypted Linux images at host

Below is the bootgen command and bif file content(example) to be used for creating encrypted images. This split option below creates all images separately with out partition headers. By this we can get encrypted Image.bin.bin and system.dtb.bin which are just encrypted. These images have to used at u-boot for decryption.
bootgen -image encrypt.bif -split bin -arch zynqmp -w

Bif File contents:
//arch = zynqmp; split = true; format = BIN
all:
{
     [aeskeyfile]key.nky
     [bootloader, encryption = aes] fsbl_zcu102_2017_1_0802.elf
     [encryption = aes]Image.bin
     [encryption = aes]system.dtb
}</span>
PS: For the split option to work there should be dummy boot loader in bif file and hence placed fsbl in bif file.
Preparing Key_IV file:
1.Concatenate the key and iv together(in sequence first copy key and then concatenate iv to it in a text and save it as bin. With this, we will get key_iv.bin

Decryption of encrypted Linux Images at u-boot:

  1. Copy the created Image.bin.bin and sytem.dtb.bin and key_iv.bin to DDR by any means(used SD commands in below example).
  2. Enter u-boot commands in below log sequence for decryption and boot Linux.
The command for decryption is as follows
aes dec <key_iv addess> <enrypted image addr> <dst adrr> <lenght of encrypted image> hw

Example u-boot log:
ZynqMP> fatload mmc 0 80000 image.bin.bin
reading image.bin.bin
29401728 bytes read in 1961 ms (14.3 MiB/s)
ZynqMP> fatload mmc 0 8000000 key_iv.bin
reading key_iv.bin
88 bytes read in 10 ms (7.8 KiB/s)
ZynqMP> aes dec 8000000 80000 0 1c0a280 hw
ZynqMP> fatload mmc 0 7000000 system.dtb.bin
reading system.dtb.bin
36760 bytes read in 20 ms (1.8 MiB/s)
ZynqMP> aes dec 8000000 7000000 0 8f98 hw
ZynqMP> booti 80000 - 7000000</span>
As of now, we are ignoring destination address and loading back the decrypted image to address of encrypted image mentioned.

Procedure to create authenticated Linux images and required files at host

As an example here are steps on how to create keys and signatures for linux images(image and system.dtb)
Keys and Signature generation at host:
  • Generate private key at host using openssl with below command
openssl genrsa -out private-key.pem 4096
  • Generate public key using private key generated with above command
openssl pkey -in private-key.pem -out pubkey-key.pem -pubout
  • Generate signature for Linux image using private key
openssl dgst -sha256 -sign private-key.pem -out signature_image.bin Image
  • Generate signature for dtb using private key
openssl dgst -sha256 -sign private-key.pem -out signature_dtb.bin system.dtb
  • The keys generated using above openssl command are in pem format. To convert the key to .bin format, use the attached script() and run as shown below.
./pub_key.sh pubkey-key.pem
This will output public key in bin format as pubkey-key.pem.bin

Authentication of Linux Images at u-boot:

Below is the u-boot command to authenticate images at u-boot.
Command: rsa key src len [hw]
help:

Authenticate a block of data $len bytes long at address $src using a key at address $key address $dst. The Key is a combination of signature of image to authenticate followed by public key to
be used for authentication. The optional hw flag specifies to used hardware engine if supports.

As mentioned in command help above, here are full details on how each argument should be.
key: Key is combination of signature followed by public key immediately. The signature should be of length 512 bytes and public key should be of length 516 bytes.
src: Src is address of authenticated image to where it was downloaded.
len: Len is the length of authenticated image in hex.
hw: Specifies it to use hardware engine for authentication if hardware supports. We support only hw.

Log:
ZynqMP> fatload mmc 0 7000000 system.dtb
reading system.dtb
36631 bytes read in 20 ms (1.8 MiB/s)
ZynqMP> fatload mmc 0 3000000 signature_dtb.bin
reading signature_dtb.bin
512 bytes read in 10 ms (10.8 KiB/s)
ZynqMP> fatload mmc 0 3000200 pubkey-key.pem.bin
reading pubkey-key.pem.bin
516 bytes read in 10 ms (10.8 KiB/s)
ZynqMP> rsa 3000000 7000000 8f17 hw
ZynqMP> fatload mmc 0 100000 Image
reading Image
29401600 bytes read in 1961 ms (14.3 MiB/s)
ZynqMP> fatload mmc 0 3000000 signature_image.bin
reading signature_image.bin
512 bytes read in 10 ms (10.8 KiB/s)
ZynqMP> rsa 3000000 100000 1c0a200 hw
ZynqMP> booti 100000 - 7000000</span>