--- /dev/null
+# 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,
+ '--fw', 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