1# SPDX-License-Identifier: GPL-2.0+ 2# Copyright (C) 2023 Weidm��ller Interface GmbH & Co. KG 3# Lukas Funke <lukas.funke@weidmueller.com> 4# 5"""Bintool implementation for bootgen 6 7bootgen allows creating bootable SPL for Zynq(MP) 8 9Documentation is available via: 10https://www.xilinx.com/support/documents/sw_manuals/xilinx2022_1/ug1283-bootgen-user-guide.pdf 11 12Source code is available at: 13https://github.com/Xilinx/bootgen 14 15""" 16 17from binman import bintool 18from u_boot_pylib import tools 19 20# pylint: disable=C0103 21class Bintoolbootgen(bintool.Bintool): 22 """Generate bootable fsbl image for zynq/zynqmp 23 24 This bintools supports running Xilinx "bootgen" in order 25 to generate a bootable, authenticated image form an SPL. 26 27 """ 28 def __init__(self, name): 29 super().__init__(name, 'Xilinx Bootgen', 30 version_regex=r'^\*\*\*\*\*\* *Xilinx Bootgen *(.*)', 31 version_args='-help') 32 33 # pylint: disable=R0913 34 def sign(self, arch, spl_elf_fname, pmufw_elf_fname, 35 psk_fname, ssk_fname, fsbl_config, auth_params, keysrc_enc, 36 output_fname): 37 """Sign SPL elf file and bundle it with PMU firmware into an image 38 39 The method bundels the SPL together with a 'Platform Management Unit' 40 (PMU)[1] firmware into a single bootable image. The image in turn is 41 signed with the provided 'secondary secret key' (ssk), which in turn is 42 signed with the 'primary secret key' (psk). In order to verify the 43 authenticity of the ppk, it's hash has to be fused into the device 44 itself. 45 46 In Xilinx terms the SPL is usually called 'FSBL' 47 (First Stage Boot Loader). The jobs of the SPL and the FSBL are mostly 48 the same: load bitstream, bootstrap u-boot. 49 50 Args: 51 arch (str): Xilinx SoC architecture. Currently only 'zynqmp' is 52 supported. 53 spl_elf_fname (str): Filename of SPL ELF file. The filename must end 54 with '.elf' in order for bootgen to recognized it as an ELF 55 file. Otherwise the start address field is missinterpreted. 56 pmufw_elf_fname (str): Filename PMU ELF firmware. 57 psk_fname (str): Filename of the primary secret key (psk). The psk 58 is a .pem file which holds the RSA private key used for signing 59 the secondary secret key. 60 ssk_fname (str): Filename of the secondary secret key. The ssk 61 is a .pem file which holds the RSA private key used for signing 62 the actual boot firmware. 63 fsbl_config (str): FSBL config options. A string list of fsbl config 64 options. Valid values according to [2] are: 65 "bh_auth_enable": Boot Header Authentication Enable: RSA 66 authentication of the bootimage is done 67 excluding the verification of PPK hash and SPK ID. This is 68 useful for debugging before bricking a device. 69 "auth_only": Boot image is only RSA signed. FSBL should not be 70 decrypted. See the 71 Zynq UltraScale+ Device Technical Reference Manual (UG1085) 72 for more information. 73 There are more options which relate to PUF (physical unclonable 74 functions). Please refer to Xilinx manuals for further info. 75 auth_params (str): Authentication parameter. A semicolon separated 76 list of authentication parameters. Valid values according to [3] 77 are: 78 "ppk_select=<0|1>" - Select which ppk to use 79 "spk_id=<32-bit spk id>" - Specifies which SPK can be 80 used or revoked, default is 0x0 81 "spk_select=<spk-efuse/user-efuse>" - To differentiate spk and 82 user efuses. 83 "auth_header" - To authenticate headers when no partition 84 is authenticated. 85 keysrc_enc (str): This specifies the Key source for encryption. 86 Valid values according to [3] are: 87 "bbram_red_key" - RED key stored in BBRAM 88 "efuse_red_key" - RED key stored in eFUSE 89 "efuse_gry_key" - Grey (Obfuscated) Key stored in eFUSE. 90 "bh_gry_key" - Grey (Obfuscated) Key stored in boot header 91 "bh_blk_key" - Black Key stored in boot header 92 "efuse_blk_key" - Black Key stored in eFUSE 93 "kup_key" - User Key 94 95 output_fname (str): Filename where bootgen should write the result 96 97 Returns: 98 str: Bootgen output from stdout 99 100 [1] https://xilinx-wiki.atlassian.net/wiki/spaces/A/pages/18841724/PMU+Firmware 101 [2] https://docs.xilinx.com/r/en-US/ug1283-bootgen-user-guide/fsbl_config 102 [3] https://docs.xilinx.com/r/en-US/ug1283-bootgen-user-guide/auth_params 103 [4] https://docs.xilinx.com/r/en-US/ug1283-bootgen-user-guide/keysrc_encryption 104 """ 105 106 _fsbl_config = f"[fsbl_config] {fsbl_config}" if fsbl_config else "" 107 _auth_params = f"[auth_params] {auth_params}" if auth_params else "" 108 _keysrc_enc = f"[keysrc_encryption] {keysrc_enc}" if keysrc_enc else "" 109 110 bif_template = f"""u_boot_spl_aes_rsa: {{ 111 [pskfile] {psk_fname} 112 [sskfile] {ssk_fname} 113 {_keysrc_enc} 114 {_fsbl_config} 115 {_auth_params} 116 [ bootloader, 117 authentication = rsa, 118 destination_cpu=a53-0] {spl_elf_fname} 119 [pmufw_image] {pmufw_elf_fname} 120 }}""" 121 args = ["-arch", arch] 122 123 bif_fname = tools.get_output_filename('bootgen-in.sign.bif') 124 tools.write_file(bif_fname, bif_template, False) 125 args += ["-image", bif_fname, '-w', '-o', output_fname] 126 return self.run_cmd(*args) 127 128 def fetch(self, method): 129 """Fetch bootgen from git""" 130 if method != bintool.FETCH_BUILD: 131 return None 132 133 result = self.build_from_git( 134 'https://github.com/Xilinx/bootgen', 135 ['all'], 136 'bootgen') 137 return result 138