From 7f51fe5c6db21592f7f2a914b2dab3f67e765d8b Mon Sep 17 00:00:00 2001 From: Lukas Funke Date: Thu, 3 Aug 2023 17:22:13 +0200 Subject: [PATCH] binman: btool: Add Xilinx Bootgen btool Add the Xilinx Bootgen as bintool. Xilinx Bootgen is used to create bootable SPL (FSBL in Xilinx terms) images for Zynq/ZynqMP devices. The btool creates a signed version of the SPL. Additionally to signing the key source for the decryption engine can be passend to the boot image. Signed-off-by: Lukas Funke --- tools/binman/bintools.rst | 2 +- tools/binman/btool/bootgen.py | 137 ++++++++++++++++++++++++++++++++++ 2 files changed, 138 insertions(+), 1 deletion(-) create mode 100644 tools/binman/btool/bootgen.py diff --git a/tools/binman/bintools.rst b/tools/binman/bintools.rst index 20ee24395a..1336f4d011 100644 --- a/tools/binman/bintools.rst +++ b/tools/binman/bintools.rst @@ -208,7 +208,7 @@ Using `fdt_add_pubkey` the key can be injected to the SPL independent of Bintool: bootgen: Sign ZynqMP FSBL image ---------------------------------------------- +---------------------------------------- This bintool supports running `bootgen` in order to sign a SPL for ZynqMP devices. diff --git a/tools/binman/btool/bootgen.py b/tools/binman/btool/bootgen.py new file mode 100644 index 0000000000..f2ca552dc2 --- /dev/null +++ b/tools/binman/btool/bootgen.py @@ -0,0 +1,137 @@ +# SPDX-License-Identifier: GPL-2.0+ +# Copyright (C) 2023 Weidmüller Interface GmbH & Co. KG +# Lukas Funke +# +"""Bintool implementation for bootgen + +bootgen allows creating bootable SPL for Zynq(MP) + +Documentation is available via: +https://www.xilinx.com/support/documents/sw_manuals/xilinx2022_1/ug1283-bootgen-user-guide.pdf + +Source code is available at: +https://github.com/Xilinx/bootgen + +""" + +from binman import bintool +from u_boot_pylib import tools + +# pylint: disable=C0103 +class Bintoolbootgen(bintool.Bintool): + """Generate bootable fsbl image for zynq/zynqmp + + This bintools supports running Xilinx "bootgen" in order + to generate a bootable, authenticated image form an SPL. + + """ + def __init__(self, name): + super().__init__(name, 'Xilinx Bootgen', + version_regex=r'^\*\*\*\*\*\* *Xilinx Bootgen *(.*)', + version_args='-help') + + # pylint: disable=R0913 + def sign(self, arch, spl_elf_fname, pmufw_elf_fname, + psk_fname, ssk_fname, fsbl_config, auth_params, keysrc_enc, + output_fname): + """Sign SPL elf file and bundle it with PMU firmware into an image + + The method bundels the SPL together with a 'Platform Management Unit' + (PMU)[1] firmware into a single bootable image. The image in turn is + signed with the provided 'secondary secret key' (ssk), which in turn is + signed with the 'primary secret key' (psk). In order to verify the + authenticity of the ppk, it's hash has to be fused into the device + itself. + + In Xilinx terms the SPL is usually called 'FSBL' + (First Stage Boot Loader). The jobs of the SPL and the FSBL are mostly + the same: load bitstream, bootstrap u-boot. + + Args: + arch (str): Xilinx SoC architecture. Currently only 'zynqmp' is + supported. + spl_elf_fname (str): Filename of SPL ELF file. The filename must end + with '.elf' in order for bootgen to recognized it as an ELF + file. Otherwise the start address field is missinterpreted. + pmufw_elf_fname (str): Filename PMU ELF firmware. + psk_fname (str): Filename of the primary secret key (psk). The psk + is a .pem file which holds the RSA private key used for signing + the secondary secret key. + ssk_fname (str): Filename of the secondary secret key. The ssk + is a .pem file which holds the RSA private key used for signing + the actual boot firmware. + fsbl_config (str): FSBL config options. A string list of fsbl config + options. Valid values according to [2] are: + "bh_auth_enable": Boot Header Authentication Enable: RSA + authentication of the bootimage is done + excluding the verification of PPK hash and SPK ID. This is + useful for debugging before bricking a device. + "auth_only": Boot image is only RSA signed. FSBL should not be + decrypted. See the + Zynq UltraScale+ Device Technical Reference Manual (UG1085) + for more information. + There are more options which relate to PUF (physical unclonable + functions). Please refer to Xilinx manuals for further info. + auth_params (str): Authentication parameter. A semicolon separated + list of authentication parameters. Valid values according to [3] + are: + "ppk_select=<0|1>" - Select which ppk to use + "spk_id=<32-bit spk id>" - Specifies which SPK can be + used or revoked, default is 0x0 + "spk_select=" - To differentiate spk and + user efuses. + "auth_header" - To authenticate headers when no partition + is authenticated. + keysrc_enc (str): This specifies the Key source for encryption. + Valid values according to [3] are: + "bbram_red_key" - RED key stored in BBRAM + "efuse_red_key" - RED key stored in eFUSE + "efuse_gry_key" - Grey (Obfuscated) Key stored in eFUSE. + "bh_gry_key" - Grey (Obfuscated) Key stored in boot header + "bh_blk_key" - Black Key stored in boot header + "efuse_blk_key" - Black Key stored in eFUSE + "kup_key" - User Key + + output_fname (str): Filename where bootgen should write the result + + Returns: + str: Bootgen output from stdout + + [1] https://xilinx-wiki.atlassian.net/wiki/spaces/A/pages/18841724/PMU+Firmware + [2] https://docs.xilinx.com/r/en-US/ug1283-bootgen-user-guide/fsbl_config + [3] https://docs.xilinx.com/r/en-US/ug1283-bootgen-user-guide/auth_params + [4] https://docs.xilinx.com/r/en-US/ug1283-bootgen-user-guide/keysrc_encryption + """ + + _fsbl_config = f"[fsbl_config] {fsbl_config}" if fsbl_config else "" + _auth_params = f"[auth_params] {auth_params}" if auth_params else "" + _keysrc_enc = f"[keysrc_encryption] {keysrc_enc}" if keysrc_enc else "" + + bif_template = f"""u_boot_spl_aes_rsa: {{ + [pskfile] {psk_fname} + [sskfile] {ssk_fname} + {_keysrc_enc} + {_fsbl_config} + {_auth_params} + [ bootloader, + authentication = rsa, + destination_cpu=a53-0] {spl_elf_fname} + [pmufw_image] {pmufw_elf_fname} + }}""" + args = ["-arch", arch] + + bif_fname = tools.get_output_filename('bootgen-in.sign.bif') + tools.write_file(bif_fname, bif_template, False) + args += ["-image", bif_fname, '-w', '-o', output_fname] + return self.run_cmd(*args) + + def fetch(self, method): + """Fetch bootgen from git""" + if method != bintool.FETCH_BUILD: + return None + + result = self.build_from_git( + 'https://github.com/Xilinx/bootgen', + 'all', + 'bootgen') + return result -- 2.39.5