UPGRADE YOUR BROWSER

We have detected your current browser version is not the latest one. Xilinx.com uses the latest web technologies to bring you the best online experience possible. Please upgrade to a Xilinx.com supported browser:Chrome, Firefox, Internet Explorer 11, Safari. Thank you!

cancel
Showing results for 
Search instead for 
Did you mean: 
692 Views
Registered: ‎10-30-2018

ZynqMP U-boot v2018.3 fails to load encrypted bitstream

Jump to solution

I'm having problems loading an encrypted FPGA bitstream on the ZynqMP platform (ZCU102) using U-boot. I have an encrypted-only boot image (no authentication) and an encrypted only bitstream (no authentication).

I am able to boot to U-boot and load the encrypted bitstream into memory, but the fpga loads command fails when using the user key.

The contents of by bif for my boot image are as follows:

encrypted_image:
{
[keysrc_encryption] bbram_red_key
[
bootloader,
destination_cpu = a53-0,
encryption = aes,
aeskeyfile = generated_aes.nky
] a53_fsbl.elf

[
destination_cpu = pmu,
encryption = aes
] pmu_fw.elf

[
destination_cpu = a53-0,
exception_level = el-3,
trustzone,
encryption = aes
] bl31.elf

[
destination_cpu = a53-0,
exception_level = el-2,
encryption = aes
] u-boot.elf

[
destination_cpu = r5-0,
encryption = aes
] r5_hello.elf
}

The BOOT.bin is generated w/ the command "bootgen -w on -image boot.bif -arch zynqmp -o BOOT.bin"

My bitstream is encrypted using bootgen as well with "bootgen -arch zynqmp -process_bitstream bin -w on" with the following BIF.

data_image:
{
[keysrc_encryption] kup_key
[
aeskeyfile = fpga_aes.nky,
encryption = aes
] fpga_top.bit
}

The bitstream key file contains the following

Device xczu9eq;
Key 0 E749A7BEB5EA19E476FE9806B570C2FDC8E8C54A5DAA1E1FFE3DA8AD1EC2B574;
IV 0 FBDAECC06C7AB733762283CC;

And I've generated a binary keyfile (as well as the IV) from this nky file.

$ xxd fpga_key.txt
00000000: 4537 3439 4137 4245 4235 4541 3139 4534 E749A7BEB5EA19E4
00000010: 3736 4645 3938 3036 4235 3730 4332 4644 76FE9806B570C2FD
00000020: 4338 4538 4335 3441 3544 4141 3145 3146 C8E8C54A5DAA1E1F
00000030: 4645 3344 4138 4144 3145 4332 4235 3734 FE3DA8AD1EC2B574

$ xxd fpga_iv.txt
00000000: 4642 4441 4543 4330 3643 3741 4237 3333 FBDAECC06C7AB733
00000010: 3736 3232 3833 4343

In U-Boot I use the following commands to load the encrypted bitstream and the key file from SD card

ZynqMP> fatload mmc 0 2000000 fpga_key.txt
reading fpga_key.txt
64 bytes read in 9 ms (6.8 KiB/s)
ZynqMP> fatload mmc 0 100000 fpga_top.bit.bin
reading fpga_top.bit.bin
26510908 bytes read in 1733 ms (14.6 MiB/s)
ZynqMP> setenv fpga_size $filesize
ZynqMP> fpga loads 0 100000 $fpga_size 2 1 2000000
PL FPGA LOAD fail

The failure returns almost instantly, which differs from when I attempt to decrypt the image into memory using the `zynqmp aes` command

Using the IV binary file as well...

ZynqMP> fatload mmc 0 2100000 fpga_iv.txt
reading fpga_iv.txt
24 bytes read in 8 ms (2.9 KiB/s)
ZynqMP> zynqmp aes 100000 2100000 $fpga_size 0 1 3000000 2000000
Failed: AES op status:0x0, errcode:0x1

The key values can be confirmed in U-Boot as well

ZynqMP> base 2000000
Base Address: 0x02000000
ZynqMP> md 0 11
02000000: 39343745 45423741 41453542 34453931 E749A7BEB5EA19E4
02000010: 45463637 36303839 30373542 44463243 76FE9806B570C2FD
02000020: 38453843 41343543 41414435 46314531 C8E8C54A5DAA1E1F
02000030: 44334546 44413841 32434531 34373542 FE3DA8AD1EC2B574
02000040: 00000000 ....
ZynqMP> base 2100000
Base Address: 0x02100000
ZynqMP> md 0 7
02100000: 41444246 30434345 41374336 33333742 FBDAECC06C7AB733
02100010: 32323637 43433338 00000000 762283CC....

This operation failure takes a few seconds to return in contrast with the near instant behavior of `fpga loads` command.

I understand the using the device key is also possible, but currently the boot image is not authenticated and it was documented that this is a prerequisite. Ultimately our application would be using a User key.

Additionally I've attempted with and without patches as referenced in this other Community post, https://forums.xilinx.com/t5/Embedded-Linux/Loading-an-encrypted-bitstream-in-u-boot/m-p/954347

The U-boot and ATF is souced from the Xilinx Github repositories and built from the 2018.3 release tag. The FSBL, PMU FW, and other components are built from the 2018.3 XSDK.

What part of this process is failing? The bitstream is confirmed to be valid as I can load an unencrypted version of it using `fpga loadb`

0 Kudos
1 Solution

Accepted Solutions
Highlighted
549 Views
Registered: ‎10-30-2018

Re: ZynqMP U-boot v2018.3 fails to load encrypted bitstream

Jump to solution

Revisiting the article gave me a clue on one thing I hadn't tried.

The correct answer is process the bitstream in Bootgen without the "-process_bitstream" command option. This seems to be only for turing a .bit to a .bin.

As I wrote in my previous post, the correct command is

$ bootgen -w on -arch zynqmp -image fpga.bif -o fpga.bin

If you allow bootgen to generate your key file, Key 0 is the user key to supply for the fpga loads command.

In U-boot

ZynqMP> fatload mmc 0 10000000 fpga.bin
reading fpga.bin
26521148 bytes read in 1724 ms (14.7 MiB/s)
ZynqMP> setenv fpga_size $filesize
ZynqMP> fatload mmc 0 100000 fpga_key.txt
reading fpga_key.txt
64 bytes read in 9 ms (6.8 KiB/s)
ZynqMP> fpga loads 0 10000000 $fpga_size 2 1 100000
Bitstream successfully loaded

In memory, the User key should be the 64-byte plain text representation of the key, not the actual binary. So for the following .nky contents

Device       xczu9eg;

Key 0        32DDE1582685FBCF55A4998FFAE682A9E1B8C474B19BF9DD3B51045EEC565D9E;
IV 0         EB790DB63AA942FAB2ACE966;

Key 1        A4DD4375C14C148B8F9871C18BE4F1C11D2428EAE34FBE000102A7518927AEFA;
IV 1         60B5842EE57BB5CD73078D06;

The key should appear in memory as follows

ZynqMP> md 0 10
00100000: 44443233 38353145 35383632 46434246    32DDE1582685FBCF
00100010: 34413535 46383939 36454146 39413238    55A4998FFAE682A9
00100020: 38423145 34373443 42393142 44443946    E1B8C474B19BF9DD
00100030: 31354233 45353430 36354345 45394435    3B51045EEC565D9E

One answer that could still be answered for me is where does the IV used to decrypt the bitstream come from?

View solution in original post

0 Kudos
10 Replies
Xilinx Employee
Xilinx Employee
586 Views
Registered: ‎10-11-2011

Re: ZynqMP U-boot v2018.3 fails to load encrypted bitstream

Jump to solution

Have you seen this https://xilinx-wiki.atlassian.net/wiki/spaces/A/pages/18841728/Authentication+and+Decryption+in+Zynq+U-Boot ?

 

-------------------------------------------------------------------------
Don’t forget to reply, kudo, and accept as solution.
-------------------------------------------------------------------------
0 Kudos
576 Views
Registered: ‎10-30-2018

Re: ZynqMP U-boot v2018.3 fails to load encrypted bitstream

Jump to solution

This is for the ZynqMP, not the Zynq. I have exhaustively read the equivalent article for the ZynqMP on the Wiki at https://xilinx-wiki.atlassian.net/wiki/spaces/A/pages/18842015/Authentication+and+Decryption+in+ZynqMP+u-boot.

0 Kudos
Xilinx Employee
Xilinx Employee
568 Views
Registered: ‎10-11-2011

Re: ZynqMP U-boot v2018.3 fails to load encrypted bitstream

Jump to solution

Sorry about the wrong link but what you pointed to is applicable only for 2017.1 and 2017.2.

This is a better link for 2018.3:

https://xilinx-wiki.atlassian.net/wiki/spaces/A/pages/18842432/Loading+authenticated+and+or+encrypted+image+partitions+from+u-boot#Loadingauthenticatedand/orencryptedimagepartitionsfromu-boot-LoadingSecureBitstreamImagesfromu-boot

 

-------------------------------------------------------------------------
Don’t forget to reply, kudo, and accept as solution.
-------------------------------------------------------------------------
0 Kudos
559 Views
Registered: ‎10-30-2018

Re: ZynqMP U-boot v2018.3 fails to load encrypted bitstream

Jump to solution

I have seen this as well and am following it's example. My original post shows the contents of my keyfile, BIF file, the Bootgen command I used to process the bitstream, and the commands entered in U-Boot.

What is the correct Bootgen command to package the bitstream such that `fpga loads` can process it?

If I allow Bootgen to generate a keyfile for this package using the command

$ bootgen -w on -image fpga.bif -o fpga.bin -arch zynqmp -log trace -p xczu9eg

The keyfile that is produced contains 2 key pairs.

Which key is to be used by the `fpga loads` command? What format does `fpga loads` expected the key to be in in-memory? Should it be 32-bytes of binary or 64-bytes of hex representative of the binary key? Do I need to worry about endianness?

0 Kudos
Highlighted
550 Views
Registered: ‎10-30-2018

Re: ZynqMP U-boot v2018.3 fails to load encrypted bitstream

Jump to solution

Revisiting the article gave me a clue on one thing I hadn't tried.

The correct answer is process the bitstream in Bootgen without the "-process_bitstream" command option. This seems to be only for turing a .bit to a .bin.

As I wrote in my previous post, the correct command is

$ bootgen -w on -arch zynqmp -image fpga.bif -o fpga.bin

If you allow bootgen to generate your key file, Key 0 is the user key to supply for the fpga loads command.

In U-boot

ZynqMP> fatload mmc 0 10000000 fpga.bin
reading fpga.bin
26521148 bytes read in 1724 ms (14.7 MiB/s)
ZynqMP> setenv fpga_size $filesize
ZynqMP> fatload mmc 0 100000 fpga_key.txt
reading fpga_key.txt
64 bytes read in 9 ms (6.8 KiB/s)
ZynqMP> fpga loads 0 10000000 $fpga_size 2 1 100000
Bitstream successfully loaded

In memory, the User key should be the 64-byte plain text representation of the key, not the actual binary. So for the following .nky contents

Device       xczu9eg;

Key 0        32DDE1582685FBCF55A4998FFAE682A9E1B8C474B19BF9DD3B51045EEC565D9E;
IV 0         EB790DB63AA942FAB2ACE966;

Key 1        A4DD4375C14C148B8F9871C18BE4F1C11D2428EAE34FBE000102A7518927AEFA;
IV 1         60B5842EE57BB5CD73078D06;

The key should appear in memory as follows

ZynqMP> md 0 10
00100000: 44443233 38353145 35383632 46434246    32DDE1582685FBCF
00100010: 34413535 46383939 36454146 39413238    55A4998FFAE682A9
00100020: 38423145 34373443 42393142 44443946    E1B8C474B19BF9DD
00100030: 31354233 45353430 36354345 45394435    3B51045EEC565D9E

One answer that could still be answered for me is where does the IV used to decrypt the bitstream come from?

View solution in original post

0 Kudos
Xilinx Employee
Xilinx Employee
393 Views
Registered: ‎10-11-2011

Re: ZynqMP U-boot v2018.3 fails to load encrypted bitstream

Jump to solution

From UG1283 (2019.2) Bootgen User Guide page 29.

Zynq UltraScale+ MPSoC Secure Header

When you choose to encrypt a partition, Bootgen appends the secure header to that partition. The secure header, contains the key/iv used to encrypt the actual partition. This header in-turn is encrypted using the device key and iv. The Zynq UltraScale+ Secure header is shown in the following table.

-------------------------------------------------------------------------
Don’t forget to reply, kudo, and accept as solution.
-------------------------------------------------------------------------
0 Kudos
Observer jwoeber
Observer
363 Views
Registered: ‎04-04-2019

Re: ZynqMP U-boot v2018.3 fails to load encrypted bitstream

Jump to solution

Hi,

thank you for your detailed description. I tried following it ( although with BootGen, U-Boot, FSBL .... all at Version 2018.2 ) but I still got the PL FPGA LOAD fail return. Did you have to set any fuses for this to work?

BTW could this scheme be cracked by using another unencrypted Boot.BIN where the Device Key is left in the AES-GCM decryption unit and is used to decrypt the encrypted Boot.BIN which contains the Key for the FPGA?

 

Edit: Typo

 

MfG

Johannes

0 Kudos
354 Views
Registered: ‎10-30-2018

Re: ZynqMP U-boot v2018.3 fails to load encrypted bitstream

Jump to solution

I did not need to set any eFuse for this configuration, as my normal boot image is not encrypted, just the bitstream being loaded by U-Boot.

Your error message implies that the decryption part of the operation was successful, which was what I was having issues with. Are you encrypting a .bit file or is it a .bin that has been converted and had the bitstream header removed? The `fpga loads` only works when the file packaged by Bootgen is a .bit file. See the BIF in my original post.

My configuration isn't intended to be secure, we're just working through usage of the tools with the AES key for the bitstream being stored in plaintext on the SD card. I believe the scenario you are proposing could be prevented by setting the ENC_ONLY eFUSE, which would prevent loading unencrypted boot images, or by using authentication.

 

Observer jwoeber
Observer
343 Views
Registered: ‎04-04-2019

Re: ZynqMP U-boot v2018.3 fails to load encrypted bitstream

Jump to solution

Hi,

thanks for the quick response. I encrypt a valid .bit file ( was able to load it via fpga loadb ) with bootgen. And I get the same error response if I use a bogus key so it could still be an decryption error.

And I think too that that setting ENC_ONLY should make this sheme secure in the sense that nobody can run anything on it without the symmetrical Key which means ( barring some high end attacks ) that anything encoded into the Uboot code ( like a key for FPGA decryption ) should be more or less secure.

MfG

Johannes

0 Kudos
Observer jwoeber
Observer
295 Views
Registered: ‎04-04-2019

Re: ZynqMP U-boot v2018.3 fails to load encrypted bitstream

Jump to solution

Hi, the PMUFW was not configured correctly to load secure bitstreams in my case. I had to add

#define XFPGA_SECURE_MODE

to the xfpga_config.h file. Now it works for me.

Thanks for your help.

 

MfG

Johannes