diff mbox series

[v7,07/11] btool: mkeficapsule: Add a bintool for EFI capsule generation

Message ID 20230805113458.1430239-8-sughosh.ganu@linaro.org
State Superseded
Headers show
Series Integrate EFI capsule tasks into u-boot's build flow | expand

Commit Message

Sughosh Ganu Aug. 5, 2023, 11:34 a.m. UTC
Add a bintool for generating EFI capsules. This calls the mkeficapsule
tool which generates the capsules.

Signed-off-by: Sughosh Ganu <sughosh.ganu@linaro.org>
---
Changes since V6:
* Split the changes for mkeficapsule btool into a separate patch, as
  suggested by Simon Glass.
* Use the word commandline consistently, as suggested by Simon Glass.

 tools/binman/btool/mkeficapsule.py | 101 +++++++++++++++++++++++++++++
 1 file changed, 101 insertions(+)
 create mode 100644 tools/binman/btool/mkeficapsule.py

Comments

Simon Glass Aug. 5, 2023, 3:03 p.m. UTC | #1
Hi Sughosh,

On Sat, 5 Aug 2023 at 05:35, Sughosh Ganu <sughosh.ganu@linaro.org> wrote:
>
> Add a bintool for generating EFI capsules. This calls the mkeficapsule
> tool which generates the capsules.
>
> Signed-off-by: Sughosh Ganu <sughosh.ganu@linaro.org>
> ---
> Changes since V6:
> * Split the changes for mkeficapsule btool into a separate patch, as
>   suggested by Simon Glass.
> * Use the word commandline consistently, as suggested by Simon Glass.
>
>  tools/binman/btool/mkeficapsule.py | 101 +++++++++++++++++++++++++++++
>  1 file changed, 101 insertions(+)
>  create mode 100644 tools/binman/btool/mkeficapsule.py
>

Reviewed-by: Simon Glass <sjg@chromium.org>

> diff --git a/tools/binman/btool/mkeficapsule.py b/tools/binman/btool/mkeficapsule.py
> new file mode 100644
> index 0000000000..61179747ff
> --- /dev/null
> +++ b/tools/binman/btool/mkeficapsule.py
> @@ -0,0 +1,101 @@
> +# SPDX-License-Identifier: GPL-2.0+
> +# Copyright 2023 Linaro Limited
> +#
> +"""Bintool implementation for mkeficapsule tool
> +
> +mkeficapsule is a tool used for generating EFI capsules.
> +
> +The following are the commandline options to be provided
> +to the tool
> +Usage: mkeficapsule [options] <image blob> <output file>
> +Options:
> +       -g, --guid <guid string>    guid for image blob type
> +       -i, --index <index>         update image index
> +       -I, --instance <instance>   update hardware instance
> +       -v, --fw-version <version>  firmware version
> +       -p, --private-key <privkey file>  private key file
> +       -c, --certificate <cert file>     signer's certificate file
> +       -m, --monotonic-count <count>     monotonic count
> +       -d, --dump_sig              dump signature (*.p7)
> +       -A, --fw-accept  firmware accept capsule, requires GUID, no image blob
> +       -R, --fw-revert  firmware revert capsule, takes no GUID, no image blob
> +       -o, --capoemflag Capsule OEM Flag, an integer between 0x0000 and 0xffff
> +       -h, --help                  print a help message
> +"""
> +
> +from binman import bintool
> +
> +class Bintoolmkeficapsule(bintool.Bintool):
> +    """Handles the 'mkeficapsule' tool
> +
> +    This bintool is used for generating the EFI capsules. The
> +    capsule generation parameters can either be specified through
> +    commandline, or through a config file.
> +    """
> +    def __init__(self, name):
> +        super().__init__(name, 'mkeficapsule tool for generating capsules')
> +
> +    def generate_capsule(self, image_index, image_guid, hardware_instance,
> +                         payload, output_fname, priv_key, pub_key,
> +                         monotonic_count=0, version=0, oemflags=0):
> +        """Generate a capsule through commandline-provided parameters
> +
> +        Args:
> +            image_index (int): Unique number for identifying payload image
> +            image_guid (str): GUID used for identifying the image

I wonder what we can do about this, so that we don't have to speak in
GUIDs? Is there a registry somewhere of what all these things are? It
would be nice if you could provide a string like 'u-boot-sandbox' and
the capsule tool would know what that means.

> +            hardware_instance (int): Optional unique hardware instance of
> +            a device in the system. 0 if not being used
> +            payload (str): Path to the input payload image
> +            output_fname (str): Path to the output capsule file
> +            priv_key (str): Path to the private key
> +            pub_key(str): Path to the public key
> +            monotonic_count (int): Count used when signing an image
> +            version (int): Image version (Optional)
> +            oemflags (int): Optional 16 bit OEM flags
> +
> +        Returns:
> +            str: Tool output
> +        """
> +        args = [
> +            f'--index={image_index}',
> +            f'--guid={image_guid}',
> +            f'--instance={hardware_instance}'
> +        ]
> +
> +        if version:
> +            args += [f'--fw-version={version}']
> +        if oemflags:
> +            args += [f'--capoemflag={oemflags}']
> +        if priv_key and pub_key:
> +            args += [
> +                f'--monotonic-count={monotonic_count}',
> +                f'--private-key={priv_key}',
> +                f'--certificate={pub_key}'
> +            ]

It almost seems worth adding two methods in this class, one to build
with keys and one to not. Anyway, we can leave it for now.

> +
> +        args += [
> +            payload,
> +            output_fname
> +        ]
> +
> +        return self.run_cmd(*args)
> +
> +    def fetch(self, method):
> +        """Fetch handler for mkeficapsule
> +
> +        This builds the tool from source
> +
> +        Returns:
> +            tuple:
> +                str: Filename of fetched file to copy to a suitable directory
> +                str: Name of temp directory to remove, or None
> +        """
> +        if method != bintool.FETCH_BUILD:
> +            return None
> +
> +        cmd = ['tools-only_defconfig', 'tools']
> +        result = self.build_from_git(
> +            'https://source.denx.de/u-boot/u-boot.git',
> +            cmd,
> +            'tools/mkeficapsule')
> +        return result
> --
> 2.34.1
>

Regards,
Simon
Sughosh Ganu Aug. 5, 2023, 6:26 p.m. UTC | #2
hi Simon,

On Sat, 5 Aug 2023 at 20:34, Simon Glass <sjg@chromium.org> wrote:
>
> Hi Sughosh,
>
> On Sat, 5 Aug 2023 at 05:35, Sughosh Ganu <sughosh.ganu@linaro.org> wrote:
> >
> > Add a bintool for generating EFI capsules. This calls the mkeficapsule
> > tool which generates the capsules.
> >
> > Signed-off-by: Sughosh Ganu <sughosh.ganu@linaro.org>
> > ---
> > Changes since V6:
> > * Split the changes for mkeficapsule btool into a separate patch, as
> >   suggested by Simon Glass.
> > * Use the word commandline consistently, as suggested by Simon Glass.
> >
> >  tools/binman/btool/mkeficapsule.py | 101 +++++++++++++++++++++++++++++
> >  1 file changed, 101 insertions(+)
> >  create mode 100644 tools/binman/btool/mkeficapsule.py
> >
>
> Reviewed-by: Simon Glass <sjg@chromium.org>
>
> > diff --git a/tools/binman/btool/mkeficapsule.py b/tools/binman/btool/mkeficapsule.py
> > new file mode 100644
> > index 0000000000..61179747ff
> > --- /dev/null
> > +++ b/tools/binman/btool/mkeficapsule.py
> > @@ -0,0 +1,101 @@
> > +# SPDX-License-Identifier: GPL-2.0+
> > +# Copyright 2023 Linaro Limited
> > +#
> > +"""Bintool implementation for mkeficapsule tool
> > +
> > +mkeficapsule is a tool used for generating EFI capsules.
> > +
> > +The following are the commandline options to be provided
> > +to the tool
> > +Usage: mkeficapsule [options] <image blob> <output file>
> > +Options:
> > +       -g, --guid <guid string>    guid for image blob type
> > +       -i, --index <index>         update image index
> > +       -I, --instance <instance>   update hardware instance
> > +       -v, --fw-version <version>  firmware version
> > +       -p, --private-key <privkey file>  private key file
> > +       -c, --certificate <cert file>     signer's certificate file
> > +       -m, --monotonic-count <count>     monotonic count
> > +       -d, --dump_sig              dump signature (*.p7)
> > +       -A, --fw-accept  firmware accept capsule, requires GUID, no image blob
> > +       -R, --fw-revert  firmware revert capsule, takes no GUID, no image blob
> > +       -o, --capoemflag Capsule OEM Flag, an integer between 0x0000 and 0xffff
> > +       -h, --help                  print a help message
> > +"""
> > +
> > +from binman import bintool
> > +
> > +class Bintoolmkeficapsule(bintool.Bintool):
> > +    """Handles the 'mkeficapsule' tool
> > +
> > +    This bintool is used for generating the EFI capsules. The
> > +    capsule generation parameters can either be specified through
> > +    commandline, or through a config file.
> > +    """
> > +    def __init__(self, name):
> > +        super().__init__(name, 'mkeficapsule tool for generating capsules')
> > +
> > +    def generate_capsule(self, image_index, image_guid, hardware_instance,
> > +                         payload, output_fname, priv_key, pub_key,
> > +                         monotonic_count=0, version=0, oemflags=0):
> > +        """Generate a capsule through commandline-provided parameters
> > +
> > +        Args:
> > +            image_index (int): Unique number for identifying payload image
> > +            image_guid (str): GUID used for identifying the image
>
> I wonder what we can do about this, so that we don't have to speak in
> GUIDs? Is there a registry somewhere of what all these things are? It
> would be nice if you could provide a string like 'u-boot-sandbox' and
> the capsule tool would know what that means.

In the EFI world GUIDs are just identifiers used for uniquely
identifying resources, in this case, images on a given board. There is
no registry of these values, however there are certain resources which
do have truly unique value, e.g. EFI protocols, or standard disk
partitions -- these values are then defined in a specification, like
UEFI.

In this context though, these GUIDs simply serve in identifying an
image for a given board. Typically, the platform code would then
"declare" the images that are supported on that platform using their
associated GUID values. And these GUIDs which are part of the capsule
are then used for checking if the input image on the capsule is indeed
intended for that platform at the time of performing the update.

>
> > +            hardware_instance (int): Optional unique hardware instance of
> > +            a device in the system. 0 if not being used
> > +            payload (str): Path to the input payload image
> > +            output_fname (str): Path to the output capsule file
> > +            priv_key (str): Path to the private key
> > +            pub_key(str): Path to the public key
> > +            monotonic_count (int): Count used when signing an image
> > +            version (int): Image version (Optional)
> > +            oemflags (int): Optional 16 bit OEM flags
> > +
> > +        Returns:
> > +            str: Tool output
> > +        """
> > +        args = [
> > +            f'--index={image_index}',
> > +            f'--guid={image_guid}',
> > +            f'--instance={hardware_instance}'
> > +        ]
> > +
> > +        if version:
> > +            args += [f'--fw-version={version}']
> > +        if oemflags:
> > +            args += [f'--capoemflag={oemflags}']
> > +        if priv_key and pub_key:
> > +            args += [
> > +                f'--monotonic-count={monotonic_count}',
> > +                f'--private-key={priv_key}',
> > +                f'--certificate={pub_key}'
> > +            ]
>
> It almost seems worth adding two methods in this class, one to build
> with keys and one to not. Anyway, we can leave it for now.

I had them separate in my earlier versions, but clubbed them together.
I personally don't find this confusing.

-sughosh

>
> > +
> > +        args += [
> > +            payload,
> > +            output_fname
> > +        ]
> > +
> > +        return self.run_cmd(*args)
> > +
> > +    def fetch(self, method):
> > +        """Fetch handler for mkeficapsule
> > +
> > +        This builds the tool from source
> > +
> > +        Returns:
> > +            tuple:
> > +                str: Filename of fetched file to copy to a suitable directory
> > +                str: Name of temp directory to remove, or None
> > +        """
> > +        if method != bintool.FETCH_BUILD:
> > +            return None
> > +
> > +        cmd = ['tools-only_defconfig', 'tools']
> > +        result = self.build_from_git(
> > +            'https://source.denx.de/u-boot/u-boot.git',
> > +            cmd,
> > +            'tools/mkeficapsule')
> > +        return result
> > --
> > 2.34.1
> >
>
> Regards,
> Simon
diff mbox series

Patch

diff --git a/tools/binman/btool/mkeficapsule.py b/tools/binman/btool/mkeficapsule.py
new file mode 100644
index 0000000000..61179747ff
--- /dev/null
+++ b/tools/binman/btool/mkeficapsule.py
@@ -0,0 +1,101 @@ 
+# SPDX-License-Identifier: GPL-2.0+
+# Copyright 2023 Linaro Limited
+#
+"""Bintool implementation for mkeficapsule tool
+
+mkeficapsule is a tool used for generating EFI capsules.
+
+The following are the commandline options to be provided
+to the tool
+Usage: mkeficapsule [options] <image blob> <output file>
+Options:
+	-g, --guid <guid string>    guid for image blob type
+	-i, --index <index>         update image index
+	-I, --instance <instance>   update hardware instance
+	-v, --fw-version <version>  firmware version
+	-p, --private-key <privkey file>  private key file
+	-c, --certificate <cert file>     signer's certificate file
+	-m, --monotonic-count <count>     monotonic count
+	-d, --dump_sig              dump signature (*.p7)
+	-A, --fw-accept  firmware accept capsule, requires GUID, no image blob
+	-R, --fw-revert  firmware revert capsule, takes no GUID, no image blob
+	-o, --capoemflag Capsule OEM Flag, an integer between 0x0000 and 0xffff
+	-h, --help                  print a help message
+"""
+
+from binman import bintool
+
+class Bintoolmkeficapsule(bintool.Bintool):
+    """Handles the 'mkeficapsule' tool
+
+    This bintool is used for generating the EFI capsules. The
+    capsule generation parameters can either be specified through
+    commandline, or through a config file.
+    """
+    def __init__(self, name):
+        super().__init__(name, 'mkeficapsule tool for generating capsules')
+
+    def generate_capsule(self, image_index, image_guid, hardware_instance,
+                         payload, output_fname, priv_key, pub_key,
+                         monotonic_count=0, version=0, oemflags=0):
+        """Generate a capsule through commandline-provided parameters
+
+        Args:
+            image_index (int): Unique number for identifying payload image
+            image_guid (str): GUID used for identifying the image
+            hardware_instance (int): Optional unique hardware instance of
+            a device in the system. 0 if not being used
+            payload (str): Path to the input payload image
+            output_fname (str): Path to the output capsule file
+            priv_key (str): Path to the private key
+            pub_key(str): Path to the public key
+            monotonic_count (int): Count used when signing an image
+            version (int): Image version (Optional)
+            oemflags (int): Optional 16 bit OEM flags
+
+        Returns:
+            str: Tool output
+        """
+        args = [
+            f'--index={image_index}',
+            f'--guid={image_guid}',
+            f'--instance={hardware_instance}'
+        ]
+
+        if version:
+            args += [f'--fw-version={version}']
+        if oemflags:
+            args += [f'--capoemflag={oemflags}']
+        if priv_key and pub_key:
+            args += [
+                f'--monotonic-count={monotonic_count}',
+                f'--private-key={priv_key}',
+                f'--certificate={pub_key}'
+            ]
+
+        args += [
+            payload,
+            output_fname
+        ]
+
+        return self.run_cmd(*args)
+
+    def fetch(self, method):
+        """Fetch handler for mkeficapsule
+
+        This builds the tool from source
+
+        Returns:
+            tuple:
+                str: Filename of fetched file to copy to a suitable directory
+                str: Name of temp directory to remove, or None
+        """
+        if method != bintool.FETCH_BUILD:
+            return None
+
+        cmd = ['tools-only_defconfig', 'tools']
+        result = self.build_from_git(
+            'https://source.denx.de/u-boot/u-boot.git',
+            cmd,
+            'tools/mkeficapsule')
+        return result