diff options
| author | Simon Glass <sjg@chromium.org> | 2018-07-17 13:25:44 -0600 | 
|---|---|---|
| committer | Simon Glass <sjg@chromium.org> | 2018-08-01 16:30:48 -0600 | 
| commit | 0ef87aa332e024c94d07a897c9f595be37077de8 (patch) | |
| tree | e6ca145b3de1f8499c102d568218fa8ab3f34e50 | |
| parent | aeffc5e95627a788c328cb92f82ad9a38d792ed8 (diff) | |
binman: Add support for Chromium GBB
This entry contains a Google Binary Block, used to store keys and bitmaps
in a Chromium image.
Signed-off-by: Simon Glass <sjg@chromium.org>
| -rw-r--r-- | tools/binman/README.entries | 19 | ||||
| -rw-r--r-- | tools/binman/etype/gbb.py | 96 | ||||
| -rw-r--r-- | tools/binman/ftest.py | 56 | ||||
| -rw-r--r-- | tools/binman/test/71_gbb.dts | 31 | ||||
| -rw-r--r-- | tools/binman/test/72_gbb_too_small.dts | 10 | ||||
| -rw-r--r-- | tools/binman/test/73_gbb_no_size.dts | 9 | 
6 files changed, 221 insertions, 0 deletions
| diff --git a/tools/binman/README.entries b/tools/binman/README.entries index 6f09626b24b..41b70192c08 100644 --- a/tools/binman/README.entries +++ b/tools/binman/README.entries @@ -91,6 +91,25 @@ FMAP does not support this. +Entry: gbb: An entry which contains a Chromium OS Google Binary Block +--------------------------------------------------------------------- + +Properties / Entry arguments: +    - hardware-id: Hardware ID to use for this build (a string) +    - keydir: Directory containing the public keys to use +    - bmpblk: Filename containing images used by recovery + +Chromium OS uses a GBB to store various pieces of information, in particular +the root and recovery keys that are used to verify the boot process. Some +more details are here: + +    https://www.chromium.org/chromium-os/firmware-porting-guide/2-concepts + +but note that the page dates from 2013 so is quite out of date. See +README.chromium for how to obtain the required keys and tools. + + +  Entry: intel-cmc: Entry containing an Intel Chipset Micro Code (CMC) file  ------------------------------------------------------------------------- diff --git a/tools/binman/etype/gbb.py b/tools/binman/etype/gbb.py new file mode 100644 index 00000000000..8fe10f47135 --- /dev/null +++ b/tools/binman/etype/gbb.py @@ -0,0 +1,96 @@ +# SPDX-License-Identifier: GPL-2.0+ +# Copyright (c) 2018 Google, Inc +# Written by Simon Glass <sjg@chromium.org> +# + +# Support for a Chromium OS Google Binary Block, used to record read-only +# information mostly used by firmware. + +from collections import OrderedDict + +import command +from entry import Entry, EntryArg + +import fdt_util +import tools + +# Build GBB flags. +# (src/platform/vboot_reference/firmware/include/gbb_header.h) +gbb_flag_properties = { +  'dev-screen-short-delay': 0x1, +  'load-option-roms': 0x2, +  'enable-alternate-os': 0x4, +  'force-dev-switch-on': 0x8, +  'force-dev-boot-usb': 0x10, +  'disable-fw-rollback-check': 0x20, +  'enter-triggers-tonorm': 0x40, +  'force-dev-boot-legacy': 0x80, +  'faft-key-override': 0x100, +  'disable-ec-software-sync': 0x200, +  'default-dev-boot-legacy': 0x400, +  'disable-pd-software-sync': 0x800, +  'disable-lid-shutdown': 0x1000, +  'force-dev-boot-fastboot-full-cap': 0x2000, +  'enable-serial': 0x4000, +  'disable-dwmp': 0x8000, +} + + +class Entry_gbb(Entry): +    """An entry which contains a Chromium OS Google Binary Block + +    Properties / Entry arguments: +        - hardware-id: Hardware ID to use for this build (a string) +        - keydir: Directory containing the public keys to use +        - bmpblk: Filename containing images used by recovery + +    Chromium OS uses a GBB to store various pieces of information, in particular +    the root and recovery keys that are used to verify the boot process. Some +    more details are here: + +        https://www.chromium.org/chromium-os/firmware-porting-guide/2-concepts + +    but note that the page dates from 2013 so is quite out of date. See +    README.chromium for how to obtain the required keys and tools. +    """ +    def __init__(self, section, etype, node): +        Entry.__init__(self, section, etype, node) +        self.hardware_id, self.keydir, self.bmpblk = self.GetEntryArgsOrProps( +            [EntryArg('hardware-id', str), +             EntryArg('keydir', str), +             EntryArg('bmpblk', str)]) + +        # Read in the GBB flags from the config +        self.gbb_flags = 0 +        flags_node = node.FindNode('flags') +        if flags_node: +            for flag, value in gbb_flag_properties.iteritems(): +                if fdt_util.GetBool(flags_node, flag): +                    self.gbb_flags |= value + +    def ObtainContents(self): +        gbb = 'gbb.bin' +        fname = tools.GetOutputFilename(gbb) +        if not self.size: +            self.Raise('GBB must have a fixed size') +        gbb_size = self.size +        bmpfv_size = gbb_size - 0x2180 +        if bmpfv_size < 0: +            self.Raise('GBB is too small (minimum 0x2180 bytes)') +        sizes = [0x100, 0x1000, bmpfv_size, 0x1000] +        sizes = ['%#x' % size for size in sizes] +        keydir = tools.GetInputFilename(self.keydir) +        gbb_set_command = [ +            'gbb_utility', '-s', +            '--hwid=%s' % self.hardware_id, +            '--rootkey=%s/root_key.vbpubk' % keydir, +            '--recoverykey=%s/recovery_key.vbpubk' % keydir, +            '--flags=%d' % self.gbb_flags, +            '--bmpfv=%s' % tools.GetInputFilename(self.bmpblk), +            fname] + +        tools.Run('futility', 'gbb_utility', '-c', ','.join(sizes), fname) +        tools.Run('futility', *gbb_set_command) + +        self.SetContents(tools.ReadFile(fname)) +        return True diff --git a/tools/binman/ftest.py b/tools/binman/ftest.py index 4e467145d71..f15b215c608 100644 --- a/tools/binman/ftest.py +++ b/tools/binman/ftest.py @@ -47,6 +47,8 @@ TEXT_DATA             = 'text'  TEXT_DATA2            = 'text2'  TEXT_DATA3            = 'text3'  CROS_EC_RW_DATA       = 'ecrw' +GBB_DATA              = 'gbbd' +BMPBLK_DATA           = 'bmp'  class TestFunctional(unittest.TestCase): @@ -95,6 +97,8 @@ class TestFunctional(unittest.TestCase):          TestFunctional._MakeInputFile('vbt.bin', VBT_DATA)          TestFunctional._MakeInputFile('mrc.bin', MRC_DATA)          TestFunctional._MakeInputFile('ecrw.bin', CROS_EC_RW_DATA) +        TestFunctional._MakeInputDir('devkeys') +        TestFunctional._MakeInputFile('bmpblk.bin', BMPBLK_DATA)          self._output_setup = False          # ELF file with a '_dt_ucode_base_size' symbol @@ -288,6 +292,21 @@ class TestFunctional(unittest.TestCase):          return pathname      @classmethod +    def _MakeInputDir(self, dirname): +        """Create a new test input directory, creating directories as needed + +        Args: +            dirname: Directory name to create + +        Returns: +            Full pathname of directory created +        """ +        pathname = os.path.join(self._indir, dirname) +        if not os.path.exists(pathname): +            os.makedirs(pathname) +        return pathname + +    @classmethod      def TestFile(self, fname):          return os.path.join(self._binman_dir, 'test', fname) @@ -1248,6 +1267,43 @@ class TestFunctional(unittest.TestCase):          self.assertIn("'fill' entry must have a size property",                        str(e.exception)) +    def _HandleGbbCommand(self, pipe_list): +        """Fake calls to the futility utility""" +        if pipe_list[0][0] == 'futility': +            fname = pipe_list[0][-1] +            # Append our GBB data to the file, which will happen every time the +            # futility command is called. +            with open(fname, 'a') as fd: +                fd.write(GBB_DATA) +            return command.CommandResult() + +    def testGbb(self): +        """Test for the Chromium OS Google Binary Block""" +        command.test_result = self._HandleGbbCommand +        entry_args = { +            'keydir': 'devkeys', +            'bmpblk': 'bmpblk.bin', +        } +        data, _, _, _ = self._DoReadFileDtb('71_gbb.dts', entry_args=entry_args) + +        # Since futility +        expected = GBB_DATA + GBB_DATA + 8 * chr(0) + (0x2180 - 16) * chr(0) +        self.assertEqual(expected, data) + +    def testGbbTooSmall(self): +        """Test for the Chromium OS Google Binary Block being large enough""" +        with self.assertRaises(ValueError) as e: +            self._DoReadFileDtb('72_gbb_too_small.dts') +        self.assertIn("Node '/binman/gbb': GBB is too small", +                      str(e.exception)) + +    def testGbbNoSize(self): +        """Test for the Chromium OS Google Binary Block having a size""" +        with self.assertRaises(ValueError) as e: +            self._DoReadFileDtb('73_gbb_no_size.dts') +        self.assertIn("Node '/binman/gbb': GBB must have a fixed size", +                      str(e.exception)) +  if __name__ == "__main__":      unittest.main() diff --git a/tools/binman/test/71_gbb.dts b/tools/binman/test/71_gbb.dts new file mode 100644 index 00000000000..551756372af --- /dev/null +++ b/tools/binman/test/71_gbb.dts @@ -0,0 +1,31 @@ +// SPDX-License-Identifier: GPL-2.0+ +/dts-v1/; + +/ { +	#address-cells = <1>; +	#size-cells = <1>; + +	binman { +		gbb { +			size = <0x2180>; +			flags { +				dev-screen-short-delay; +				load-option-roms; +				enable-alternate-os; +				force-dev-switch-on; +				force-dev-boot-usb; +				disable-fw-rollback-check; +				enter-triggers-tonorm; +				force-dev-boot-legacy; +				faft-key-override; +				disable-ec-software-sync; +				default-dev-boot-legacy; +				disable-pd-software-sync; +				disable-lid-shutdown; +				force-dev-boot-fastboot-full-cap; +				enable-serial; +				disable-dwmp; +			}; +		}; +	}; +}; diff --git a/tools/binman/test/72_gbb_too_small.dts b/tools/binman/test/72_gbb_too_small.dts new file mode 100644 index 00000000000..c088f36a1d0 --- /dev/null +++ b/tools/binman/test/72_gbb_too_small.dts @@ -0,0 +1,10 @@ +// SPDX-License-Identifier: GPL-2.0+ +/dts-v1/; + +/ { +	binman { +		gbb { +			size = <0x200>; +		}; +	}; +}; diff --git a/tools/binman/test/73_gbb_no_size.dts b/tools/binman/test/73_gbb_no_size.dts new file mode 100644 index 00000000000..83be4037852 --- /dev/null +++ b/tools/binman/test/73_gbb_no_size.dts @@ -0,0 +1,9 @@ +// SPDX-License-Identifier: GPL-2.0+ +/dts-v1/; + +/ { +	binman { +		gbb { +		}; +	}; +}; | 
