Skip to content

Vendor Authorized Boot (FPGA-First) Tutorial Example Design User Guide

Introduction

The Vendor Authorized Boot (VAB) design demonstrates an end-to-end authenticated boot flow, from device power on until the Linux kernel is loaded. There are two main components of this design - the Secure Device Manager (SDM) which authenticates the configuration bitstream and U-boot with the Vendor Authorized Boot (VAB) feature. This design is demonstrated on Agilex™ 7 FPGA F-Series Transceiver-SoC Development Kit (P-Tiles & E-Tile) but can also be easily ported to other boards.

This demo design requires the following: - QKY file to program virtual key for SDM authentication - Signed RBF file (configuration bitstream) that consists of Agilex™ 7 GHRD and U-boot FSBL - U-boot FSBL and SSBL with VAB features - Linux LTSI

Overview

The main purpose of a secure boot system is to ensure that the software running in the Hard Processor System (HPS) is trusted. Upon power up, a trusted first stage of boot will be executed - subsequent stages are only loaded and executed if it is authenticated by the current boot stage. In the Altera® Agilex™ 7 SoC FPGA devices, the Secure Device Manager (SDM) is the entry point for all configuration and booting scenarios. As such, the SDM is the root of trust and will be authenticating the configuration bitstream before any HPS software is being loaded. The SDM's Configuration Management Firmware (CMF) and HPS's First Stage Bootloader (FSBL) are validated as part of the signed configuration bitstream. If VAB is enabled in U-Boot, the FSBL will validate the Second Stage Bootloader (SSBL) and the SSBL will validate the Linux kernel.

Note: In this demo design, only the authentication feature of the SDM is being demonstrated. The SDM supports other security features such as bitstream encryption, Physically Unclonable Function (PUF) and many more.

Environment Setup

  1. Create the main directory of the design:
cd ~ 
mkdir agx7_vab && cd agx7_vab && export TOP_DIR=$(pwd) 
  1. Download and extract the Linaro toolchain. Then, configure your environment to access the Linaro cross compiler:
wget https://developer.arm.com/-/media/Files/downloads/gnu/11.2-2022.02/binrel/gcc-arm-11.2-2022.02-x86_64-aarch64-none-linux-gnu.tar.xz
tar xf gcc-arm-11.2-2022.02-x86_64-aarch64-none-linux-gnu.tar.xz
export PATH=`pwd`/gcc-arm-11.2-2022.02-x86_64-aarch64-none-linux-gnu/bin:$PATH
export ARCH=arm64
export CROSS_COMPILE=aarch64-none-linux-gnu-
rm -f gcc-arm-11.2-2022.02-x86_64-aarch64-none-linux-gnu.tar.xz
  1. Enable Quartus tools to be called from command line:
export QUARTUS_ROOTDIR=~/altera_pro/25.1/quartus/
export PATH=$QUARTUS_ROOTDIR/bin:$QUARTUS_ROOTDIR/linux64:$QUARTUS_ROOTDIR/../qsys/bin:$PATH

Building the System Image

Build Arm Trusted Firmware

cd $TOP_DIR
git clone https://github.com/altera-opensource/arm-trusted-firmware 
cd arm-trusted-firmware
git checkout -b socfpga_v2.12.0_vab origin/socfpga_v2.12.0
make realclean
make bl31 CROSS_COMPILE=aarch64-none-linux-gnu- PLAT=agilex DEPRECATED=1 HANDLE_EA_EL3_FIRST=1
cd ..

Build U-Boot

The VAB deconfig will add the Vendor Authorized Boot firmware to the FSBL and SSBL.

cd $TOP_DIR
git clone -b QPDS25.1_REL_GSRD_PR https://github.com/altera-opensource/u-boot-socfpga 
cd u-boot-socfpga 
export CROSS_COMPILE=aarch64-none-linux-gnu-; export ARCH=arm 
make clean && make mrproper 
make socfpga_agilex_vab_defconfig 
make -j 24 u-boot u-boot.img u-boot.dtb spl/u-boot-spl-dtb.hex 
cd .. 

Build Linux Kernel with Intel FGPA Crypto Service Support

cd $TOP_DIR
git clone -b QPDS25.1_REL_GSRD_PR https://github.com/altera-opensource/linux-socfpga 
cd linux-socfpga 
export CROSS_COMPILE=aarch64-none-linux-gnu-; export ARCH=arm64 
make clean 
make defconfig 
make menuconfig 
#(Browse and enable Cryptographic API > Hardware crypto devices > (*)Intel FPGA Crypto Service support) 
make -j 16 all && make dtbs && make -j 16 modules 
cd .. 

Generate Signature Chains

Create three signature chains (FPGA, SDM FW Cosigning, and HPS software). Create directories for the keys and signature chains.

mkdir -p privatekeys 
mkdir -p publickeys 
mkdir -p qky 
Start a Nios V command shell to have all Quartus tools in the PATH:
~/altera_pro/25.1/niosv/bin/niosv-shell

Generate Root Key

quartus_sign --family=agilex --operation=make_private_pem --curve=secp384r1 --no_passphrase privatekeys/root0.pem 
quartus_sign --family=agilex --operation=make_public_pem privatekeys/root0.pem publickeys/root0_public.pem 
quartus_sign --family=agilex --operation=make_root publickeys/root0_public.pem qky/root0.qky 

Generate Signing Keys

FPGA Signing

quartus_sign --family=agilex --operation=make_private_pem --curve=secp384r1 --no_passphrase privatekeys/sign0.pem 
quartus_sign --family=agilex --operation=make_public_pem privatekeys/sign0.pem publickeys/sign0_public.pem 
SDM Cosigning
quartus_sign --family=agilex --operation=make_private_pem --curve=secp384r1 --no_passphrase privatekeys/cosign0.pem 
quartus_sign --family=agilex --operation=make_public_pem privatekeys/cosign0.pem publickeys/cosign0_public.pem 
HPS Software
quartus_sign --family=agilex --operation=make_private_pem --curve=secp384r1 --no_passphrase privatekeys/software0.pem
quartus_sign --family=agilex --operation=make_public_pem privatekeys/software0.pem publickeys/software0_public.pem 
Generate Signature Chains: FPGA Signing - Cancel ID 1 – Permissions: FPGA/HPS/HPS Debug
quartus_sign --family=agilex --operation=append_key --previous_pem=privatekeys/root0.pem --previous_qky=qky/root0.qky --permission=14 --cancel=1 --input_pem=publickeys/sign0_public.pem qky/sign0_cancel1.qky 
SDM cosigning - cancel ID 2 – Permissions: SDM Firmware
quartus_sign --family=agilex --operation=append_key --previous_pem=privatekeys/root0.pem --previous_qky=qky/root0.qky --permission=0x1 --cancel=2 --input_pem=publickeys/cosign0_public.pem qky/cosign0_cancel2.qky 
HPS Software - cancel ID 3 – Permissions: HPS Firmware
quartus_sign --family=agilex --operation=append_key --previous_pem=privatekeys/root0.pem --previous_qky=qky/root0.qky --permission=0x80 --cancel=3 --input_pem=publickeys/software0_public.pem qky/software0_cancel3.qky 

Build the Hardware Design

Build the GHRD

Download the GHRD from GitHub, and build it using the commands below:

cd $TOP_FOLDER
wget https://github.com/altera-fpga/agilex7f-ed-gsrd/archive/refs/tags/QPDS25.1_REL_GSRD_PR.zip
unzip QPDS25.1_REL_GSRD_PR.zip
rm QPDS25.1_REL_GSRD_PR.zip
mv agilex7f-ed-gsrd-QPDS25.1_REL_GSRD_PR agilex7f-ed-gsrd
cd agilex7f-ed-gsrd
make agf014eb-si-devkit-oobe-baseline-all
cd ..

Enable Security Features: Authentication

For the FPGA configuration bitstream to be properly signed, enable the Quartus key File in the Quartus Project. - Open the GHRD project in Quartus. - From the Assignments Menu, navigate to Device > Device and Pin Options > Security. Under Quartus key file, browse and select qky/sign0_cancel1.qky. - Alternately, you can add the following assignment to the .qsf file: "set_global_assignment -name QKY_FILE "

Regenerate the sof by running the Assembler. - From the Processing menu, select Compilation Dashboard. In the Compilation Dashboard, select Assembler to regenerate the sof.

Generate and Sign FPGA and HPS RBF Files

Add FSBL bootloader to configuration bitstream.

cd $TOP_DIR
mkdir bitstreams 
cd bitstreams 
quartus_pfg -c ../agilex_soc_devkit_ghrd/output_files/ghrd_agfb014r24b2e2v.sof ghrd_agfb014r24b2e2v_hps.sof -o hps_path=../u-boot-socfpga/spl/u-boot-spl-dtb.hex 
Cosign the SDM firmware.
quartus_sign --family=agilex --operation=sign --qky=../qky/cosign0_cancel2.qky --pem=../privatekeys/cosign0.pem $QUARTUS_ROOTDIR/../devices/programmer/firmware/agilex.zip signed_agilex.zip 
Create Raw Binary File (rbf) with SDM Firmware included.
quartus_pfg -c -o fw_source=signed_agilex.zip ../agilex_soc_devkit_ghrd/output_files/ghrd_agfb014r24b2e2v_hps.sof \ 
-o sign_later=ON unsigned_bitstream.rbf 
Sign the rbf.
quartus_sign --family=agilex --operation=sign --qky=../qky/sign0_cancel1.qky --pem=../privatekeys/sign0.pem unsigned_bitstream.rbf signed_bitstream.rbf 
Create .jic for flash programmer. (Optional)
quartus_pfg -c signed_bitstream.rbf signed_flash.jic -o device=MT25QU128 -o flash_loader=AGFB014R24B -o mode=ASX4 

Prepare the Signed Images

Compile fcs_prepare

The VAB preparation tool is used along with quartus_sign to create a signed firmware image. The signing process perfoms the following: - The VAB preparation tool calculates the SHA384 hash of the firmware image and creates an unsigned certificate, named unsigned_cert.ccert. - The signing tool signs the unsigned certification using the appropriate signature chain and creates a signed certificate. - The VAB preparation tool will append the signed certificate and certificate length to the firmware image, creating a signed firmware image hps_image_signed.vab. - Create a FIT image of the individually signed firmware images.

cd $TOP_DIR
git clone https://github.com/altera-opensource/fcs_apps 
mv fcs_apps fcs_prepare 
cd fcs_prepare 
git checkout -b fcs_prepare_vab origin/fcs_prepare 
export CROSS_COMPILE=; export ARCH= 
make clean && make all 

Create Signed U-boot Image

A signed U-boot image will consist of three individually signed firmware images (bl31.bin, u-boot.dtb and u-boot-nodtb.bin) in a FIT image: Create a working directory for signing images

 cd $TOP_DIR
 mkdir signed_hps_images && cd signed_hps_images 
Create the certificate for bl31.bin
../fcs_prepare/fcs_prepare --hps_cert ../arm-trusted-firmware/build/agilex/release/bl31.bin -v 
quartus_sign --family=agilex --operation=SIGN --qky=../qky/software0_cancel3.qky --pem=../privatekeys/software0.pem ./unsigned_cert.ccert ./signed_cert_bl31.bin.ccert 
../fcs_prepare/fcs_prepare --finish ./signed_cert_bl31.bin.ccert --imagefile ../arm-trusted-firmware/build/agilex/release/bl31.bin 
mv hps_image_signed.vab ../u-boot-socfpga/signed-bl31.bin 
rm unsigned_cert.ccert 
Create the certificate for u-boot.dtb
../fcs_prepare/fcs_prepare --hps_cert ../u-boot-socfpga/u-boot.dtb -v 
quartus_sign --family=agilex --operation=SIGN --qky=../qky/software0_cancel3.qky --pem=../privatekeys/software0.pem ./unsigned_cert.ccert ./signed_cert_u-boot_pad.dtb.ccert 
../fcs_prepare/fcs_prepare --finish ./signed_cert_u-boot_pad.dtb.ccert --imagefile ../u-boot-socfpga/u-boot.dtb 
mv hps_image_signed.vab ../u-boot-socfpga/signed-u-boot.dtb 
rm unsigned_cert.ccert 
Create the certificate for u-boot-nodtb.bin
../fcs_prepare/fcs_prepare --hps_cert ../u-boot-socfpga/u-boot-nodtb.bin -v 
quartus_sign --family=agilex --operation=SIGN --qky=../qky/software0_cancel3.qky --pem=../privatekeys/software0.pem ./unsigned_cert.ccert ./signed_cert_u-boot-nodtb.bin.ccert 
../fcs_prepare/fcs_prepare --finish ./signed_cert_u-boot-nodtb.bin.ccert --imagefile ../u-boot-socfpga/u-boot-nodtb.bin 
mv hps_image_signed.vab ../u-boot-socfpga/signed-u-boot-nodtb.bin 
rm unsigned_cert.ccert 
Move into the U-Boot directory and run the FIT creation script
cd $TOP_DIR/u-boot-socfpga/ 
export CROSS_COMPILE=aarch64-none-linux-gnu-; export ARCH=arm64 
./tools/binman/binman build -u -d u-boot.dtb -O . -i u-boot  

Create Signed Linux Image

A signed Linux image will consist of two individually signed firmware images (Image and linux.dtb) in a FIT image: Move into the signed images working directory

cd $TOP_DIR/signed_hps_images 
Create the certificate for the Image.
../fcs_prepare/fcs_prepare --hps_cert ../linux-socfpga/arch/arm64/boot/Image -v 
quartus_sign --family=agilex --operation=SIGN --qky=../qky/software0_cancel3.qky --pem=../privatekeys/software0.pem ./unsigned_cert.ccert ./signed_cert_Image.ccert 
../fcs_prepare/fcs_prepare --finish ./signed_cert_Image.ccert --imagefile ../linux-socfpga/arch/arm64/boot/Image 
mv hps_image_signed.vab ../u-boot-socfpga/signed-Image 
rm unsigned_cert.ccert 
Create the certificate for linux.dtb.
../fcs_prepare/fcs_prepare --hps_cert ../linux-socfpga/arch/arm64/boot/dts/intel/socfpga_agilex_socdk.dtb -v 
quartus_sign --family=agilex --operation=SIGN --qky=../qky/software0_cancel3.qky --pem=../privatekeys/software0.pem ./unsigned_cert.ccert ./signed_cert_linux.dtb.ccert 
../fcs_prepare/fcs_prepare --finish ./signed_cert_linux.dtb.ccert --imagefile ../linux-socfpga/arch/arm64/boot/dts/intel/socfpga_agilex_socdk.dtb 
mv hps_image_signed.vab ../u-boot-socfpga/signed-linux.dtb 
rm unsigned_cert.ccert 
Move into the U-Boot directory and run the FIT creation script.
cd $TOP_DIR/u-boot-socfpga/ 
export CROSS_COMPILE=aarch64-none-linux-gnu-; export ARCH=arm64 
./tools/binman/binman build -u -d u-boot.dtb -O . -i kernel 

Create fcs_client (optional)

The FCS_Client is an application that will allow validation of firmware images from the linux kernel. This application interfaces the Intel FPGA Crypto Services drivers included with the linux build.

cd $TOP_DIR
git clone https://github.com/altera-opensource/fcs_apps 
mv fcs_apps fcs_client 
cd fcs_client 
git checkout -b fcs_client_vab origin/fcs_client 
export CROSS_COMPILE=aarch64-none-linux-gnu-; export ARCH=arm64 
make clean && make all  

Create Rootfs

Refer to Building Yocto Rootfs

cd $TOP_DIR
mkdir rootfs && cd rootfs 
git clone -b styhead https://git.yoctoproject.org/poky
git clone -b styhead https://git.yoctoproject.org/meta-intel-fpga
git clone -b styhead   https://github.com/openembedded/meta-openembedded
# work around issue
echo 'do_package_qa[noexec] = "1"' >> $(find meta-intel-fpga -name linux-socfpga_6.6.bb)
source poky/oe-init-build-env ./build
echo 'MACHINE = "agilex7_dk_si_agf014eb"' >> conf/local.conf
echo 'BBLAYERS += " ${TOPDIR}/../meta-intel-fpga "' >> conf/bblayers.conf
echo 'BBLAYERS += " ${TOPDIR}/../meta-openembedded/meta-oe "' >> conf/bblayers.conf  
echo 'CORE_IMAGE_EXTRA_INSTALL += "openssh gdbserver devmem2"' >> conf/local.conf
bitbake core-image-minimal

Create SD Card Image

cd $TOP_DIR
mkdir sd_card && cd sd_card 
wget https://releases.rocketboards.org/2020.11/gsrd/tools/make_sdimage_p3.py 
chmod +x make_sdimage_p3.py 
# remove mkfs.fat parameter which has some issues on Ubuntu 22.04
sed -i 's/\"\-F 32\",//g' make_sdimage_p3.py
Copy over U-boot and Linux
mkdir sdfs && cd sdfs 
cp ../../u-boot-socfpga/u-boot.itb . 
cp ../../u-boot-socfpga/kernel.itb . 
Copy over rootfs
mkdir rootfs && cd rootfs 
sudo tar xf ../../rootfs/build/tmp/deploy/images/agilex7_dk_si_agf014eb/core-image-minimal-agilex7_dk_si_agf014eb.rootfs.tar.gz
Copy fcs_client into rootfs (optional)
sudo mkdir home/root/tools 
sudo cp ../../fcs_client/fcs_client home/root/tools/fcs_client 
Copy signed images into rootfs to test fcs_client (optional). In this example, we copied over signed-bl31.bin.
sudo mkdir home/root/images 
sudo cp ../../u-boot-socfpga/signed-bl31.bin home/root/images/signed-bl31.bin 
Create the SD Card Image
cd $TOP_DIR/sd_card
sudo python3 make_sdimage_p3.py -f -P sdfs/*,num=1,format=fat32,size=50M -P rootfs/*,num=2,format=ext3,size=400M -s 512M -n sdcard_agilex_secure_boot.img 
cd .. 

Program the Board and Boot

Configure board for SDM to boot from JTAG: - SW1: 1:ON 2:ON 3:ON 4: OFF - All other switches are in the default position Insert the updated SD card into the slot on the OOBE HPS Daughtercard Connect to the board with a serial terminal with 115,200-8-N-1 settings Power up the board. Program and verify the virtual key using the following command. After this step, the device will no longer accept any unsigned bitstream or bitstream that has been signed with a different key until the device has received a power cycle.

quartus_pgm -c 1 -m jtag -o "pi;qky/root0.qky" 
Program the signed RBF file using the following command:
quartus_pgm -c 1 -m jtag -o "p;bitstreams/signed_bitstream.rbf" 
SDM will authenticate the bitstream and only allow configuration to proceed if the image is authenticated. Once RBF programming is done, you will be able to observe the U-boot boot messages at the serial terminal. The FSBL will verify the SSBL (in blue). The SSBL will then boot and verify the Linux kernel (in red).
U-Boot SPL 2021.04-14501-gbdc9a4409d (Jan 13 2022 - 17:20:53 -0600) 
Reset state: Cold 
MPU 1200000 kHz 
L4 Main 400000 kHz 
L4 sys free 100000 kHz 
L4 MP 200000 kHz 
L4 SP 100000 kHz 
SDMMC 50000 kHz 
DDR: 8192 MiB 
SDRAM-ECC: Initialized success with 1727 ms 
QSPI: Reference clock at 400000 kHz 
WDT: Started with servicing (10s timeout) 
Trying to boot from MMC1 
## Checking hash(es) for config conf … OK 
## Checking hash(es) for Image atf … crc32+ OK 
Image Authentication passed at address 0x0000000000001038 (40988 bytes) 
## Checking hash(es) for Image uboot … crc32+ OK 
Image Authentication passed at address 0x0000000000200014 (627496 bytes) 
## Checking hash(es) for Image fdt … crc32+ OK 
Image Authentication passed at address 0x0000000000299350 (18184 bytes) 
NOTICE: BL31: v2.5.0(release):QPDS21.1STD_REL_GSRD_PR 
NOTICE: BL31: Built : 17:05:32, Jan 13 2022 

U-Boot 2021.04-14501-gbdc9a4409d (Jan 13 2022 - 17:20:53 -0600)socfpga_agilex 
CPU: Intel FPGA SoCFPGA Platform (ARMv8 64bit Cortex-A53) 
Model: SoCFPGA Agilex SoCDK 
DRAM: 8 GiB 
WDT: Started with servicing (10s timeout) 
MMC: dwmmc0@ff808000: 0 
Loading Environment from MMC... *** Warning - bad CRC, using default environment 

In: serial0@ffc02000 
Out: serial0@ffc02000 
Err: serial0@ffc02000 
Net: 
Warning: ethernet@ff800000 (eth0) using random MAC address - 52:ec:38:d3:48:8e 
eth0: ethernet@ff800000 
Hit any key to stop autoboot: 0 
Failed to load 'u-boot.scr' 
31856470 bytes read in 1487 ms (20.4 MiB/s) 
## Loading kernel from FIT Image at 02000000 … 
 Using 'conf' configuration 
 Verifying Hash Integrity  OK 
 Trying 'kernel' kernel subimage 
 Description: Linux Kernel 
 Type: Kernel Image 
 Compression: uncompressed 
 Data Start: 0x020000bc 
 Data Size: 31837308 Bytes = 30.4 MiB 
 Architecture: AArch64 
 OS: Linux 
 Load Address: 0x04080000 
 Entry Point: 0x04080000 
 Hash algo: crc32 
 Hash value: 51c0a4d2 
 Verifying Hash Integrity  crc32+ OK 
Image Authentication passed at address 0x00000000020000bc (31836672 bytes) 
## Loading fdt from FIT Image at 02000000 … 
 Using 'conf' configuration 
 Verifying Hash Integrity  OK 
 Trying 'fdt' fdt subimage 
 Description: Linux DTB 
 Type: Flat Device Tree 
 Compression: uncompressed 
 Data Start: 0x03e5ce10 
 Data Size: 17304 Bytes = 16.9 KiB 
 Architecture: AArch64 
 Hash algo: crc32 
 Hash value: 57811f0f 
 Verifying Hash Integrity  crc32+ OK 
Image Authentication passed at address 0x0000000003e5ce10 (16668 bytes) 
 Booting using the fdt blob at 0x3e5ce10 
 Loading Kernel Image 
 Loading Device Tree to 000000007fa33000, end 000000007fa3a11b  OK 
SF: Detected mt25qu02g with page size 256 Bytes, erase size 4 KiB, total 256 MiB 
Enabling QSPI at Linux DTB... 
RSU: Firmware or flash content not supporting RSU 
RSU: Firmware or flash content not supporting RSU 
RSU: Firmware or flash content not supporting RSU 
RSU: Firmware or flash content not supporting RSU 

Starting kernel 
 

Using fcs_client

If included in your rootfs, you can verify signed firmware images using fcs_client. Enter username as 'root' (no password required) once booting is complete. In the below example, we are validating the signed_bl31.bin which we added to the rootfs. Return status '0x0' indicates validated firmware.

Poky (Yocto Project Reference Distro) 3.4.1 agilex /dev/ttyS0 
agilex login: root 
root@agilex:~# ./tools/fcs_client -V ./images/signed-bl31.bin -t 0 -v 
fcs_validate_request[481] filesize=41624 
fcs_validate_request[503] sz=41624, filesize=41624 
fcs_validate_request[516] Parsing Normal image 
fcs_validate_hps_image_buf[349] perform Hash Calculation 
Computed Hash 
0000: 0e 20 6f af 08 9c db b9 
0008: d6 25 71 1b fe 62 df 0d 
0010: 21 d6 c8 15 1f 7d 4c 32 
0018: c3 3e 53 c0 2c 5e 83 dc 
0020: 41 71 ff f5 2a 45 1c 4e 
0028: 24 67 8e 50 00 dd 10 34 
Certificate Hash 
0000: 0e 20 6f af 08 9c db b9 
0008: d6 25 71 1b fe 62 df 0d 
0010: 21 d6 c8 15 1f 7d 4c 32 
0018: c3 3e 53 c0 2c 5e 83 dc 
0020: 41 71 ff f5 2a 45 1c 4e 
0028: 24 67 8e 50 00 dd 10 34 
Hash matches so sending to SDM... 
VAB Certificate size is 636. 
ioctl size=636, address=0x0x1950f4ac 
ioctl return status=0x0 size=636 
root@agilex:~# 


Last update: October 2, 2025
Created: October 2, 2025
Ask in the Forum