[RFC PATCH] binman: bintool: etype: Add support for ti-secure entry

Simon Glass sjg at chromium.org
Tue Feb 28 01:35:32 CET 2023


Hi Neha,

On Fri, 24 Feb 2023 at 05:03, Neha Malcom Francis <n-francis at ti.com> wrote:
>
> core-secdev-k3 is the TI security development package provided for K3
> platform devices. This tool helps sign bootloader images with the x509
> ceritificate header.
>
> Signed-off-by: Neha Malcom Francis <n-francis at ti.com>
> ---
> This patch depends on https://patchwork.ozlabs.org/project/uboot/patch/20230224115101.563729-1-n-francis@ti.com/
> and on ongoing development in https://git.ti.com/cgit/security-development-tools/core-secdev-k3
>
>  tools/binman/btool/tisecuretool.py            |  72 +++++++++++
>  tools/binman/etype/ti_secure.py               | 114 ++++++++++++++++++
>  tools/binman/ftest.py                         |  36 ++++++
>  tools/binman/test/278_ti_secure_rom.dts       |  11 ++
>  tools/binman/test/279_ti_secure.dts           |  11 ++
>  .../binman/test/280_ti_secure_nofilename.dts  |  10 ++
>  tools/binman/test/281_ti_secure_combined.dts  |  12 ++
>  7 files changed, 266 insertions(+)
>  create mode 100644 tools/binman/btool/tisecuretool.py
>  create mode 100644 tools/binman/etype/ti_secure.py
>  create mode 100644 tools/binman/test/278_ti_secure_rom.dts
>  create mode 100644 tools/binman/test/279_ti_secure.dts
>  create mode 100644 tools/binman/test/280_ti_secure_nofilename.dts
>  create mode 100644 tools/binman/test/281_ti_secure_combined.dts

Now that I see what you are doing, this it not quite the right way.

See this hack-up of how you can call the openssl thing. Basically you
should not have a shell script in the way, but instead make your
bintool do it.

https://github.com/sjg20/u-boot/commit/03c0d74f81106570b18d8e4fe7a3355bfeb0d5da#r100378804

I suppose we can have an openssl bintool that others build on top of?

Regards,
Simon


>
> diff --git a/tools/binman/btool/tisecuretool.py b/tools/binman/btool/tisecuretool.py
> new file mode 100644
> index 0000000000..5102bb1f7d
> --- /dev/null
> +++ b/tools/binman/btool/tisecuretool.py
> @@ -0,0 +1,72 @@
> +# SPDX-License-Identifier: GPL-2.0+
> +# Copyright (c) 2022 Texas Instruments Incorporated - https://www.ti.com/
> +# Written by Neha Malcom Francis <n-francis at ti.com>
> +#
> +"""Bintool implementation for TI security development tools
> +
> +tisecuretool helps add x509 certification for bootloader images for K3 platform devices
> +
> +Source code:
> +https://git.ti.com/cgit/security-development-tools/core-secdev-k3/"""
> +
> +import os
> +
> +from binman import bintool
> +from patman import tout
> +from patman import tools
> +
> +class Bintooltisecuretool(bintool.Bintool):
> +    """Signing tool for TI bootloaders"""
> +    name = 'tisecuretool'
> +    def __init__(self, name):
> +        super().__init__(name, 'TI secure tool')
> +
> +    def sign_binary_secure(self, fname, out_fname):
> +        """Create a signed binary
> +
> +        Args:
> +            fname (str): Filename to sign
> +            out_fname (str): Output filename
> +
> +        Returns:
> +            str: Tool output
> +            or None
> +        """
> +        tool_path = self.get_path()
> +        script_path = os.path.join(tool_path, 'scripts/secure-binary-image.sh')
> +        args = [
> +            'sh',
> +            script_path,
> +            fname,
> +            out_fname
> +            ]
> +        output = self.run_cmd(*args, add_name=False)
> +        return output
> +
> +    def sign_binary_rom(self, args):
> +        """Create a signed binary that is booted by ROM
> +
> +        Args:
> +            fname (str): Filename to sign
> +            out_fname (str): Output filename"""
> +        tool_path = self.get_path()
> +        script_path = os.path.join(tool_path, 'scripts/secure-rom-boot-image.sh')
> +        #args.insert(0, script_path)
> +        args.insert(0, script_path)
> +        output = self.run_cmd(*args, add_name=False)
> +        return output
> +
> +    def fetch(self, method):
> +        """Fetch handler for TI secure tool
> +
> +        This builds the tool from source
> +
> +        Returns:
> +            True if the file was fetched, None if a method other than FETCH_SOURCE
> +            was requested
> +        """
> +        if method != bintool.FETCH_SOURCE:
> +            return None
> +        result = self.fetch_from_git(
> +            'git://git.ti.com/security-development-tools/core-secdev-k3.git', 'tisecuretool')
> +        return result
> diff --git a/tools/binman/etype/ti_secure.py b/tools/binman/etype/ti_secure.py
> new file mode 100644
> index 0000000000..26f81ff8e8
> --- /dev/null
> +++ b/tools/binman/etype/ti_secure.py
> @@ -0,0 +1,114 @@
> +# SPDX-License-Identifier: GPL-2.0+
> +# Copyright (c) 2022 Texas Instruments Incorporated - https://www.ti.com/
> +# Written by Neha Malcom Francis <n-francis at ti.com>
> +#
> +# Entry-type module for signed binaries for TI K3 platform
> +#
> +
> +from binman.etype.blob import Entry_blob
> +from binman import bintool
> +
> +from dtoc import fdt_util
> +from patman import terminal
> +from patman import tools
> +from patman import tout
> +
> +class Entry_ti_secure(Entry_blob):
> +    """An entry which contains a signed x509 binary for signing TI
> +    General Purpose as well as High-Security devices.
> +
> +    Properties / Entry arguments:
> +       - filename: filename of binary file to be secured
> +
> +    Output files:
> +        - filename_x509 - output file generated by secure x509 signing script (which
> +            used as entry contents)
> +    """
> +    def __init__(self, section, etype, node):
> +        super().__init__(section, etype, node)
> +        self.filename = fdt_util.GetString(self._node, 'filename')
> +        self.core = fdt_util.GetString(self._node, 'core', 'secure')
> +        self.load_addr = fdt_util.GetInt(self._node, 'load', 0x41c00000)
> +        self.sw_rev = fdt_util.GetInt(self._node, 'sw-rev', 1)
> +        self.sysfw_cert = fdt_util.GetBool(self._node, 'sysfw-cert', False)
> +        self.secure = fdt_util.GetBool(self._node, 'secure', False)
> +        self.combined = fdt_util.GetBool(self._node, 'combined', False)
> +        self.split_dm = fdt_util.GetBool(self._node, 'split-dm', False)
> +        self.sysfw_filename = fdt_util.GetString(self._node, 'sysfw-filename')
> +        self.sysfw_load_addr = fdt_util.GetInt(self._node, 'sysfw-load', 0x40000)
> +        self.sysfw_data_filename = fdt_util.GetString(self._node, 'sysfw-data-filename')
> +        self.sysfw_data_load_addr = fdt_util.GetInt(self._node, 'sysfw-data-load', 0x7f000)
> +        self.sysfw_inner_cert = fdt_util.GetString(self._node, 'sysfw-inner-cert', "")
> +        self.dm_data_filename = fdt_util.GetString(self._node, 'dm-data-filename')
> +        self.dm_data_load_addr = fdt_util.GetInt(self._node, 'dm-data-load', 0x41c80000)
> +        self.sysfw_inner_cert_filename = fdt_util.GetString(self._node, 'sysfw-inner-cert-filename')
> +        self.toolpresent = False
> +        if not self.filename:
> +            self.Raise("ti_secure must have a 'filename' property")
> +
> +    def _SignBinarySecure(self):
> +        infilename = self.filename
> +        outfilename = infilename + '_signed'
> +
> +        data = self.tisecuretool.sign_binary_secure(infilename, outfilename)
> +
> +        if data is None:
> +            # Bintool is missing, create a zeroed binary
> +            self.record_missing_bintool(self.tisecuretool)
> +            return tools.get_bytes(0, 1024)
> +
> +        return tools.read_file(outfilename)
> +
> +    def _SignBinaryROM(self):
> +        input_fname = self.filename
> +        output_fname = input_fname + "_x509"
> +        if self.combined:
> +            args = [
> +                '-b', input_fname,
> +                '-l', hex(self.load_addr),
> +                '-s', self.sysfw_filename,
> +                '-m', hex(self.sysfw_load_addr),
> +                '-a', self.sysfw_inner_cert,
> +                '-d', self.sysfw_data_filename,
> +                '-n', hex(self.sysfw_data_load_addr),
> +                '-r', str(self.sw_rev),
> +                '-o', output_fname,
> +            ]
> +            if self.split_dm:
> +                args.extend(['-t', self.dm_data_filename, '-y', hex(self.dm_data_load_addr)])
> +        else:
> +            args = [
> +                '-a', self.core,
> +                '-b', input_fname,
> +                '-o', output_fname,
> +                '-l', hex(self.load_addr),
> +                '-r', str(self.sw_rev),
> +
> +            ]
> +            if self.sysfw_cert == True:
> +                args.insert(0, '-u')
> +
> +        out = self.tisecuretool.sign_binary_rom(args)
> +
> +        if out is None:
> +            # Bintool is missing, create a zeroed binary
> +            self.record_missing_bintool(self.tisecuretool)
> +            return tools.get_bytes(0, 1024)
> +
> +        return tools.read_file(output_fname)
> +
> +    def ProcessContents(self):
> +        if self.secure:
> +            data = self._SignBinarySecure()
> +        else:
> +            data = self._SignBinaryROM()
> +        return self.ProcessContentsUpdate(data)
> +
> +    def AddBintools(self, btools):
> +        #super().AddBintools(btools)
> +        col = terminal.Color()
> +        self.tisecuretool = self.AddBintool(btools, 'tisecuretool')
> +        out = self.tisecuretool.fetch_tool(bintool.FETCH_SOURCE, col, True)
> +        if out == bintool.FAIL:
> +            # Bintool is missing, record missing
> +            self.record_missing_bintool(self.tisecuretool)
> \ No newline at end of file
> diff --git a/tools/binman/ftest.py b/tools/binman/ftest.py
> index bf902341c5..72cce0ef02 100644
> --- a/tools/binman/ftest.py
> +++ b/tools/binman/ftest.py
> @@ -97,6 +97,7 @@ PRE_LOAD_MAGIC        = b'UBSH'
>  PRE_LOAD_VERSION      = 0x11223344.to_bytes(4, 'big')
>  PRE_LOAD_HDR_SIZE     = 0x00001000.to_bytes(4, 'big')
>  TI_BOARD_CONFIG_DATA  = b'\x00\x01'
> +TIX509DATA            = b'letsgo'
>
>  # Subdirectory of the input dir to use to put test FDTs
>  TEST_FDT_SUBDIR       = 'fdts'
> @@ -206,6 +207,7 @@ class TestFunctional(unittest.TestCase):
>          TestFunctional._MakeInputFile('bl2u.bin', ATF_BL2U_DATA)
>          TestFunctional._MakeInputFile('fw_dynamic.bin', OPENSBI_DATA)
>          TestFunctional._MakeInputFile('scp.bin', SCP_DATA)
> +        TestFunctional._MakeInputFile('to_sign.bin', TIX509DATA)
>
>          # Add a few .dtb files for testing
>          TestFunctional._MakeInputFile('%s/test-fdt1.dtb' % TEST_FDT_SUBDIR,
> @@ -6398,5 +6400,39 @@ fdt         fdtmap                Extract the devicetree blob from the fdtmap
>          configlen_noheader = TI_BOARD_CONFIG_DATA*4
>          self.assertGreater(data, configlen_noheader)
>
> +    def testTISecureROMImageMissingTool(self):
> +        """Test that a TI secure signed ROM booted image can be generated although tisecuretool is missing"""
> +        with test_util.capture_sys_output() as (_, stderr):
> +            data = self._DoTestFile('278_ti_secure_rom.dts',
> +                force_missing_bintools='tisecuretool')
> +        err = stderr.getvalue()
> +        self.assertRegex(err,
> +                         "Image 'image'.*missing bintools.*: tisecuretool")
> +
> +    def testTISecureImageMissingTool(self):
> +        """Test that a TI secure signed image can be generated although tisecuretool is missing"""
> +        with test_util.capture_sys_output() as (_, stderr):
> +            data = self._DoTestFile('279_ti_secure.dts',
> +                force_missing_bintools='tisecuretool')
> +        err = stderr.getvalue()
> +        self.assertRegex(err,
> +                         "Image 'image'.*missing bintools.*: tisecuretool")
> +
> +    def testTISecureNoFilename(self):
> +        """Test that a missing 'filename' property is detected"""
> +        with self.assertRaises(ValueError) as e:
> +            self._DoTestFile('280_ti_secure_nofilename.dts')
> +        self.assertIn("ti_secure must have a 'filename' property",
> +                      str(e.exception))
> +
> +    def testTISecureImageCombinedMissingTool(self):
> +        """Test that a TI secure signed image can be generated although tisecuretool is missing"""
> +        with test_util.capture_sys_output() as (_, stderr):
> +            data = self._DoTestFile('281_ti_secure_combined.dts',
> +                force_missing_bintools='tisecuretool')
> +        err = stderr.getvalue()
> +        self.assertRegex(err,
> +                         "Image 'image'.*missing bintools.*: tisecuretool")
> +
>  if __name__ == "__main__":
>      unittest.main()
> diff --git a/tools/binman/test/278_ti_secure_rom.dts b/tools/binman/test/278_ti_secure_rom.dts
> new file mode 100644
> index 0000000000..67a6a9de8d
> --- /dev/null
> +++ b/tools/binman/test/278_ti_secure_rom.dts
> @@ -0,0 +1,11 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +/dts-v1/;
> +
> +/ {
> +       binman {
> +                       ti-secure {
> +                               filename = "to_sign.bin";
> +                               sysfw-cert;
> +                       };
> +       };
> +};
> diff --git a/tools/binman/test/279_ti_secure.dts b/tools/binman/test/279_ti_secure.dts
> new file mode 100644
> index 0000000000..0e60984013
> --- /dev/null
> +++ b/tools/binman/test/279_ti_secure.dts
> @@ -0,0 +1,11 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +/dts-v1/;
> +
> +/ {
> +       binman {
> +                       ti-secure {
> +                               filename = "to_sign.bin";
> +                               secure;
> +                       };
> +       };
> +};
> diff --git a/tools/binman/test/280_ti_secure_nofilename.dts b/tools/binman/test/280_ti_secure_nofilename.dts
> new file mode 100644
> index 0000000000..928a50a499
> --- /dev/null
> +++ b/tools/binman/test/280_ti_secure_nofilename.dts
> @@ -0,0 +1,10 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +/dts-v1/;
> +
> +/ {
> +       binman {
> +                       ti-secure {
> +                               secure;
> +                       };
> +       };
> +};
> diff --git a/tools/binman/test/281_ti_secure_combined.dts b/tools/binman/test/281_ti_secure_combined.dts
> new file mode 100644
> index 0000000000..aadb5a4306
> --- /dev/null
> +++ b/tools/binman/test/281_ti_secure_combined.dts
> @@ -0,0 +1,12 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +/dts-v1/;
> +
> +/ {
> +       binman {
> +                       ti-secure {
> +                               filename = "to_sign.bin";
> +                               combined;
> +                               split-dm;
> +                       };
> +       };
> +};
> --
> 2.34.1
>


More information about the U-Boot mailing list