1# SPDX-License-Identifier: GPL-2.0+ 2# Copyright 2022 Google LLC 3# 4"""Bintool implementation for futility 5 6futility (flash utility) is a tool for working with Chromium OS flash images. 7This implements just the features used by Binman. 8 9Documentation is at: 10 https://chromium.googlesource.com/chromiumos/platform/vboot/+/refs/heads/main/_vboot_reference/README 11 12Source code: 13 https://chromium.googlesource.com/chromiumos/platform/vboot/+/refs/heads/master/_vboot_reference/futility 14 15Here is the help: 16Usage: futility [options] COMMAND [args...] 17 18This is the unified firmware utility, which will eventually replace 19most of the distinct verified boot tools formerly produced by the 20vboot_reference package. 21 22When symlinked under the name of one of those previous tools, it should 23fully implement the original behavior. It can also be invoked directly 24as futility, followed by the original name as the first argument. 25 26Global options: 27 28 --vb1 Use only vboot v1.0 binary formats 29 --vb21 Use only vboot v2.1 binary formats 30 --debug Be noisy about what's going on 31 32The following commands are built-in: 33 34 bdb Common boot flow utility 35 create Create a keypair from an RSA .pem file 36 dump_fmap Display FMAP contents from a firmware image 37 dump_kernel_config Prints the kernel command line 38 gbb Manipulate the Google Binary Block (GBB) 39 gbb_utility Legacy name for `gbb` command 40 help Show a bit of help (you're looking at it) 41 load_fmap Replace the contents of specified FMAP areas 42 pcr Simulate a TPM PCR extension operation 43 show Display the content of various binary components 44 sign Sign / resign various binary components 45 update Update system firmware 46 validate_rec_mrc Validates content of Recovery MRC cache 47 vbutil_firmware Verified boot firmware utility 48 vbutil_kernel Creates, signs, and verifies the kernel partition 49 vbutil_key Wraps RSA keys with vboot headers 50 vbutil_keyblock Creates, signs, and verifies a keyblock 51 verify Verify the signatures of various binary components 52 version Show the futility source revision and build date 53""" 54 55from binman import bintool 56 57class Bintoolfutility(bintool.Bintool): 58 """Handles the 'futility' tool 59 60 futility (flash utility) is a tool for working with Chromium OS flash 61 images. This Bintool implements just the features used by Binman, related to 62 GBB creation and firmware signing. 63 64 A binary version of the tool can be fetched. 65 66 See `Chromium OS vboot documentation`_ for more information. 67 68 .. _`Chromium OS vboot documentation`: 69 https://chromium.googlesource.com/chromiumos/platform/vboot/+/refs/heads/main/_vboot_reference/README 70 """ 71 def __init__(self, name): 72 super().__init__(name, 'Chromium OS firmware utility', r'^(.*)$', 'version') 73 74 def gbb_create(self, fname, sizes): 75 """Create a new Google Binary Block 76 77 Args: 78 fname (str): Filename to write to 79 sizes (list of int): Sizes of each regions: 80 hwid_size, rootkey_size, bmpfv_size, recoverykey_size 81 82 Returns: 83 str: Tool output 84 """ 85 args = [ 86 'gbb_utility', 87 '-c', 88 ','.join(['%#x' % size for size in sizes]), 89 fname 90 ] 91 return self.run_cmd(*args) 92 93 # pylint: disable=R0913 94 def gbb_set(self, fname, hwid, rootkey, recoverykey, flags, bmpfv): 95 """Set the parameters in a Google Binary Block 96 97 Args: 98 fname (str): Filename to update 99 hwid (str): Hardware ID to use 100 rootkey (str): Filename of root key, e.g. 'root_key.vbpubk' 101 recoverykey (str): Filename of recovery key, 102 e.g. 'recovery_key.vbpubk' 103 flags (int): GBB flags to use 104 bmpfv (str): Filename of firmware bitmaps (bmpblk file) 105 106 Returns: 107 str: Tool output 108 """ 109 args = ['gbb_utility', 110 '-s', 111 f'--hwid={hwid}', 112 f'--rootkey={rootkey}', 113 f'--recoverykey={recoverykey}', 114 f'--flags={flags}', 115 f'--bmpfv={bmpfv}', 116 fname 117 ] 118 return self.run_cmd(*args) 119 120 def sign_firmware(self, vblock, keyblock, signprivate, version, firmware, 121 kernelkey, flags): 122 """Sign firmware to create a vblock file 123 124 Args: 125 vblock (str): Filename to write the vblock too 126 keyblock (str): Filename of keyblock file 127 signprivate (str): Filename of private key 128 version (int): Version number 129 firmware (str): Filename of firmware binary to sign 130 kernelkey (str): Filename of kernel key 131 flags (int): Preamble flags 132 133 Returns: 134 str: Tool output 135 """ 136 args = [ 137 'vbutil_firmware', 138 '--vblock', vblock, 139 '--keyblock', keyblock, 140 '--signprivate', signprivate, 141 '--version', version, 142 '--fv', firmware, 143 '--kernelkey', kernelkey, 144 '--flags', flags 145 ] 146 return self.run_cmd(*args) 147 148 def fetch(self, method): 149 """Fetch handler for futility 150 151 This installs futility using a binary download. 152 153 Args: 154 method (FETCH_...): Method to use 155 156 Returns: 157 True if the file was fetched, None if a method other than FETCH_BIN 158 was requested 159 160 Raises: 161 Valuerror: Fetching could not be completed 162 """ 163 if method != bintool.FETCH_BUILD: 164 return None 165 166 # The Chromium OS repo is here: 167 # https://chromium.googlesource.com/chromiumos/platform/vboot_reference/ 168 # 169 # Unfortunately this requires logging in and obtaining a line for the 170 # .gitcookies file. So use a mirror instead. 171 result = self.build_from_git( 172 'https://github.com/sjg20/vboot_reference.git', 173 ['all'], 174 'build/futility/futility', 175 flags=['USE_FLASHROM=0']) 176 return result 177