| # SPDX-License-Identifier: GPL-2.0+ |
| # Copyright 2022 Google LLC |
| # |
| """Bintool implementation for futility |
| |
| futility (flash utility) is a tool for working with Chromium OS flash images. |
| This implements just the features used by Binman. |
| |
| Documentation is at: |
| https://chromium.googlesource.com/chromiumos/platform/vboot/+/refs/heads/main/_vboot_reference/README |
| |
| Source code: |
| https://chromium.googlesource.com/chromiumos/platform/vboot/+/refs/heads/master/_vboot_reference/futility |
| |
| Here is the help: |
| Usage: futility [options] COMMAND [args...] |
| |
| This is the unified firmware utility, which will eventually replace |
| most of the distinct verified boot tools formerly produced by the |
| vboot_reference package. |
| |
| When symlinked under the name of one of those previous tools, it should |
| fully implement the original behavior. It can also be invoked directly |
| as futility, followed by the original name as the first argument. |
| |
| Global options: |
| |
| --vb1 Use only vboot v1.0 binary formats |
| --vb21 Use only vboot v2.1 binary formats |
| --debug Be noisy about what's going on |
| |
| The following commands are built-in: |
| |
| bdb Common boot flow utility |
| create Create a keypair from an RSA .pem file |
| dump_fmap Display FMAP contents from a firmware image |
| dump_kernel_config Prints the kernel command line |
| gbb Manipulate the Google Binary Block (GBB) |
| gbb_utility Legacy name for `gbb` command |
| help Show a bit of help (you're looking at it) |
| load_fmap Replace the contents of specified FMAP areas |
| pcr Simulate a TPM PCR extension operation |
| show Display the content of various binary components |
| sign Sign / resign various binary components |
| update Update system firmware |
| validate_rec_mrc Validates content of Recovery MRC cache |
| vbutil_firmware Verified boot firmware utility |
| vbutil_kernel Creates, signs, and verifies the kernel partition |
| vbutil_key Wraps RSA keys with vboot headers |
| vbutil_keyblock Creates, signs, and verifies a keyblock |
| verify Verify the signatures of various binary components |
| version Show the futility source revision and build date |
| """ |
| |
| from binman import bintool |
| |
| class Bintoolfutility(bintool.Bintool): |
| """Handles the 'futility' tool |
| |
| futility (flash utility) is a tool for working with Chromium OS flash |
| images. This Bintool implements just the features used by Binman, related to |
| GBB creation and firmware signing. |
| |
| A binary version of the tool can be fetched. |
| |
| See `Chromium OS vboot documentation`_ for more information. |
| |
| .. _`Chromium OS vboot documentation`: |
| https://chromium.googlesource.com/chromiumos/platform/vboot/+/refs/heads/main/_vboot_reference/README |
| """ |
| def __init__(self, name): |
| super().__init__(name, 'Chromium OS firmware utility') |
| |
| def gbb_create(self, fname, sizes): |
| """Create a new Google Binary Block |
| |
| Args: |
| fname (str): Filename to write to |
| sizes (list of int): Sizes of each regions: |
| hwid_size, rootkey_size, bmpfv_size, recoverykey_size |
| |
| Returns: |
| str: Tool output |
| """ |
| args = [ |
| 'gbb_utility', |
| '-c', |
| ','.join(['%#x' % size for size in sizes]), |
| fname |
| ] |
| return self.run_cmd(*args) |
| |
| # pylint: disable=R0913 |
| def gbb_set(self, fname, hwid, rootkey, recoverykey, flags, bmpfv): |
| """Set the parameters in a Google Binary Block |
| |
| Args: |
| fname (str): Filename to update |
| hwid (str): Hardware ID to use |
| rootkey (str): Filename of root key, e.g. 'root_key.vbpubk' |
| recoverykey (str): Filename of recovery key, |
| e.g. 'recovery_key.vbpubk' |
| flags (int): GBB flags to use |
| bmpfv (str): Filename of firmware bitmaps (bmpblk file) |
| |
| Returns: |
| str: Tool output |
| """ |
| args = ['gbb_utility', |
| '-s', |
| f'--hwid={hwid}', |
| f'--rootkey={rootkey}', |
| f'--recoverykey={recoverykey}', |
| f'--flags={flags}', |
| f'--bmpfv={bmpfv}', |
| fname |
| ] |
| return self.run_cmd(*args) |
| |
| def sign_firmware(self, vblock, keyblock, signprivate, version, firmware, |
| kernelkey, flags): |
| """Sign firmware to create a vblock file |
| |
| Args: |
| vblock (str): Filename to write the vblock too |
| keyblock (str): Filename of keyblock file |
| signprivate (str): Filename of private key |
| version (int): Version number |
| firmware (str): Filename of firmware binary to sign |
| kernelkey (str): Filename of kernel key |
| flags (int): Preamble flags |
| |
| Returns: |
| str: Tool output |
| """ |
| args = [ |
| 'vbutil_firmware', |
| '--vblock', vblock, |
| '--keyblock', keyblock, |
| '--signprivate', signprivate, |
| '--version', version, |
| '--fv', firmware, |
| '--kernelkey', kernelkey, |
| '--flags', flags |
| ] |
| return self.run_cmd(*args) |
| |
| def fetch(self, method): |
| """Fetch handler for futility |
| |
| This installs futility using a binary download. |
| |
| Args: |
| method (FETCH_...): Method to use |
| |
| Returns: |
| True if the file was fetched, None if a method other than FETCH_BIN |
| was requested |
| |
| Raises: |
| Valuerror: Fetching could not be completed |
| """ |
| if method != bintool.FETCH_BIN: |
| return None |
| fname, tmpdir = self.fetch_from_drive( |
| '1hdsInzsE4aJbmBeJ663kYgjOQyW1I-E0') |
| return fname, tmpdir |
| |
| def version(self): |
| """Version handler for futility |
| |
| Returns: |
| str: Version string for futility |
| """ |
| out = self.run_cmd('version').strip() |
| if not out: |
| return super().version() |
| return out |