u-boot/tools/binman/btool/futility.py
Simon Glass 9d3a7a2e0b binman: Add a bintool implementation for futility
Add a Bintool for this, which is used to sign Chrome OS images and
build the Google Binary Block (GBB). It supports the features needed by
binman as well as fetching a binary from Google Drive. Building it from
source is possible but is left for another time, as it requires at least
one other library.

Signed-off-by: Simon Glass <sjg@chromium.org>
2022-01-25 12:36:11 -07:00

178 lines
6 KiB
Python

# 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