Re: Fit images and EFI_LOAD_FILE2_PROTOCOL

2020-10-04 Thread Cristian Ciocaltea
Hello Heinrich,

On Sat, Oct 03, 2020 at 10:51:24AM +0200, Heinrich Schuchardt wrote:
> Hello Ilias, hello Christian,
> 
> with commit ec80b4735a59 ("efi_loader: Implement FileLoad2 for initramfs
> loading") Ilias provided the possibility to specify a device path
> (CONFIG_EFI_INITRD_FILESPEC) from which an initial RAM disk can be
> served via the EFI_FILE_LOAD2_PROTOCOL.
> 
> Ard extended the Linux EFI stub to allow loading the initial RAM disk
> via the EFI_FILE_LOAD2_PROTOCOL with the utmost priority.

Thanks for sharing this information, I was not aware of the work
related to the EFI_FILE_LOAD2_PROTOCOL, neither in the Linux kernel
nor in U-Boot.

> With commit ecc7fdaa9ef1 ("bootm: Add a bootm command for type
> IH_OS_EFI") Cristian enabled signed FIT images that contain a device
> tree and a UEFI binary (enabled by CONFIG_BOOTM_EFI=y).
> 
> In the DTE calls we have discussed that it is unfortunate that we do not
> have a method to validate initial RAM images in the UEFI context.
> 
> To me it would look like a good path forward to combine the two ideas:
> 
> * Let the signed FIT image (of type IH_OS_EFI) contain a RAM disk
> * Pass location and size to the UEFI subsystem and serve them via
>   the EFI_FILE_LOAD2_PROTOCOL.
> 
> We could also extend the bootefi command to be callable as
> 
>bootefi $kernel_addr_r $ramdisk_addr_r:$filesize $fdt_addr_r
> 
> like the booti command to serve an initial RAM disk.
> 
> What are your thoughts?

I think having initial RAM disk support in UEFI FIT images would be a
great improvement.

For the moment I had to put on hold my experiments around bootefi and
verified boot scenarios, but I will do my best to resume this work in
the foreseeable future.

> Best regards
> 
> Heinrich

Kind regards,
Cristi


Re: [PATCH v2 1/1] travis-ci: Fix "ResourceWarning: unclosed file"

2020-06-24 Thread Cristian Ciocaltea
On Wed, Jun 24, 2020 at 02:30:24PM -0600, Stephen Warren wrote:
> On 12/30/19 9:41 AM, Stephen Warren wrote:
> > On 12/30/19 4:49 AM, Cristian Ciocaltea wrote:
> >> This patch gets rid of the warning messages like:
> >>
> >> uboot-test-hooks/py/travis-ci/travis_tftp.py:43: ResourceWarning:
> >> unclosed file <_io.BufferedReader name='.bm-work/qemu_arm/u-boot.bin'>
> >>
> >> Signed-off-by: Cristian Ciocaltea 
> >> ---
> >> Changes in v2:
> >> * The warning line number in the comment relies on Heinrich Schuchardt's
> >>    work 'travis-ci: provide env__efi_fit_tftp_file', but my initial patch
> >>    was based on the master version. Even though it is still applicable,
> >>    to avoid any confusion, I rebased it on Heinrich's latest patch (v2):
> >>       https://lists.denx.de/pipermail/u-boot/2019-December/395029.html
> > 
> > There's no need to rebase the patch for that kind of thing; the warning
> > is only a reference/example anyway, and the next time someone edits this
> > file after you, the line number will change again, and we can't go back
> > and edit this commit description to patch that up.
> > 
> >> diff --git a/py/travis-ci/travis_tftp.py b/py/travis-ci/travis_tftp.py
> > 
> >> +
> >> +    with open(file_full, 'rb') as fd:
> >> +    ret["crc32"] = hex(binascii.crc32(fd.read()) & 0x)[2:]
> > 
> > Nit: "f" for "file" rather than "fd" for "file descriptor" (usually an
> > integer) would have been a better variable name. No need to resend to
> > change this though.
> > 
> > Reviewed-by: Stephen Warren 
> 
> Oh, somehow I failed to realize that I needed to apply this. It's now
> applied.

Great, thanks!


Re: [PATCH v2 1/1] travis-ci: provide env__efi_fit_tftp_file

2019-12-31 Thread Cristian Ciocaltea
On Tue, Dec 31, 2019 at 12:42:36PM +0200, Cristian Ciocaltea wrote:
> On Mon, Dec 30, 2019 at 09:03:38PM +0100, Heinrich Schuchardt wrote:
> > On 12/30/19 8:32 PM, Stephen Warren wrote:
> > > On 12/30/19 12:05 PM, Heinrich Schuchardt wrote:
> > > > On 12/30/19 5:38 PM, Stephen Warren wrote:
> > > > > On 12/30/19 3:52 AM, Heinrich Schuchardt wrote:
> > > > > > Provide dictionary env__efi_fit_tftp_file describing the file used 
> > > > > > for
> > > > > > the
> > > > > > UEFI FIT image test.
> > > > > 
> > > > > > diff --git a/py/travis-ci/travis_tftp.py 
> > > > > > b/py/travis-ci/travis_tftp.py
> > > > > 
> > > > > > +def efifit2env(addr=None):
> > > > > > +    """Create dictionary describing file for EFI fit image test
> > > > > > +
> > > > > > +    @addr:  address used for loading the file as int (e.g.
> > > > > > 0x4040)
> > > > > > +    Return: dictionary describing the file with entries
> > > > > > +    * fn    - filename
> > > > > > +    * addr  - loading address, optional
> > > > > > +    * dn    - tftp directory
> > > > > > +    """
> > > > > > +    tftp_dir = os.environ['UBOOT_TRAVIS_BUILD_DIR']
> > > > > > +
> > > > > > +    ret = {
> > > > > > +    "fn": "test-efi-fit.img",
> > > > > 
> > > > > If this function were to exist, then the filename shouldn't be
> > > > > hard-coded; it should be a parameter.
> > > > > 
> > > > 
> > > > Hello Stephen,
> > > > 
> > > > thanks for reviewing.
> > > > 
> > > > This is the name of a generated file. It does not depend on the board.
> > > 
> > > What generates the file and when/why?
> > > 
> > > Generated files should generally be put into
> > > u_boot_console.config.persistent_data_dir, and presumably the name
> > > hard-coded into the test that uses it.
> > > 
> > 
> > Hello Stephen,
> > 
> > this is the test case:
> > 
> > https://lists.denx.de/pipermail/u-boot/2019-December/394957.html
> > test/py: Create a test for launching UEFI binaries from FIT images
> > 
> > The test can be run in different styles:
> > 
> > * A complete FIT image can be supplied. In this case the dictionary
> >   must contain a "size" entry.
> > * The test can generate a FIT image from lib/efi_loader/helloworld.efi.
> >   In this case no "size" entry shall be supplied. The "fn" field
> >   provides the name of the generated file. The file is generated in
> >   cons.config.build_dir. The "dn" field" describes the tFTP root
> >   directory to which the generated file is copied.
> 
> A small correction here: if the "size" entry is not provided in the
> dictionary, the test generates a FIT image using a hardcoded file
> name (test-efi-fit-helloworld.fit), so any "fn" entry provided in the
> dictionary is ignored in this case.
>  
> > The tFTP directory "dn" is only known in uboot-test-hooks.git.
> 
> Yes, and this is actually the only mandatory information to be
> provided in the dictionary when the test is supposed to generate the
> FIT image. We could get rid of this, too, if we make the assumption
> that the tFTP root directory is u_boot_console.config.build_dir by
> default.
> 
> > test/py/README.md says --persistent-data-dir is used for data that may
> > be re-used across test runs. Currently the FIT file is generated in
> > every run. In principal it could be reused. So Christian could consider
> > adjusting his patch.
> 
> Actually the FIT image file can be generated multiple times per test
> run, with different content, which is determined by various combinations
> of flags. E.g. for sandbox we have: enable/disable GZIP compression,
> enable/disable FDT usage. Each combination is used in a subtest, that
> (re)generates the corresponding FIT image.
> 
> To re-use the generated data we need to introduce additional complexity
> to handle FIT image identification for each subtest and to invalidate
> those images when they become out of sync with the parametrized input 
> data samples (ITS, FDT) used to generate their content.
> 
> > Best regards
> > 
> > Heinric

Re: [PATCH v2 1/1] travis-ci: provide env__efi_fit_tftp_file

2019-12-31 Thread Cristian Ciocaltea
On Mon, Dec 30, 2019 at 09:03:38PM +0100, Heinrich Schuchardt wrote:
> On 12/30/19 8:32 PM, Stephen Warren wrote:
> > On 12/30/19 12:05 PM, Heinrich Schuchardt wrote:
> > > On 12/30/19 5:38 PM, Stephen Warren wrote:
> > > > On 12/30/19 3:52 AM, Heinrich Schuchardt wrote:
> > > > > Provide dictionary env__efi_fit_tftp_file describing the file used for
> > > > > the
> > > > > UEFI FIT image test.
> > > > 
> > > > > diff --git a/py/travis-ci/travis_tftp.py b/py/travis-ci/travis_tftp.py
> > > > 
> > > > > +def efifit2env(addr=None):
> > > > > +    """Create dictionary describing file for EFI fit image test
> > > > > +
> > > > > +    @addr:  address used for loading the file as int (e.g.
> > > > > 0x4040)
> > > > > +    Return: dictionary describing the file with entries
> > > > > +    * fn    - filename
> > > > > +    * addr  - loading address, optional
> > > > > +    * dn    - tftp directory
> > > > > +    """
> > > > > +    tftp_dir = os.environ['UBOOT_TRAVIS_BUILD_DIR']
> > > > > +
> > > > > +    ret = {
> > > > > +    "fn": "test-efi-fit.img",
> > > > 
> > > > If this function were to exist, then the filename shouldn't be
> > > > hard-coded; it should be a parameter.
> > > > 
> > > 
> > > Hello Stephen,
> > > 
> > > thanks for reviewing.
> > > 
> > > This is the name of a generated file. It does not depend on the board.
> > 
> > What generates the file and when/why?
> > 
> > Generated files should generally be put into
> > u_boot_console.config.persistent_data_dir, and presumably the name
> > hard-coded into the test that uses it.
> > 
> 
> Hello Stephen,
> 
> this is the test case:
> 
> https://lists.denx.de/pipermail/u-boot/2019-December/394957.html
> test/py: Create a test for launching UEFI binaries from FIT images
> 
> The test can be run in different styles:
> 
> * A complete FIT image can be supplied. In this case the dictionary
>   must contain a "size" entry.
> * The test can generate a FIT image from lib/efi_loader/helloworld.efi.
>   In this case no "size" entry shall be supplied. The "fn" field
>   provides the name of the generated file. The file is generated in
>   cons.config.build_dir. The "dn" field" describes the tFTP root
>   directory to which the generated file is copied.

A small correction here: if the "size" entry is not provided in the
dictionary, the test generates a FIT image using a hardcoded file
name (test-efi-fit-helloworld.fit), so any "fn" entry provided in the
dictionary is ignored in this case.
 
> The tFTP directory "dn" is only known in uboot-test-hooks.git.

Yes, and this is actually the only mandatory information to be
provided in the dictionary when the test is supposed to generate the
FIT image. We could get rid of this, too, if we make the assumption
that the tFTP root directory is u_boot_console.config.build_dir by
default.

> test/py/README.md says --persistent-data-dir is used for data that may
> be re-used across test runs. Currently the FIT file is generated in
> every run. In principal it could be reused. So Christian could consider
> adjusting his patch.

Actually the FIT image file can be generated multiple times per test
run, with different content, which is determined by various combinations
of flags. E.g. for sandbox we have: enable/disable GZIP compression,
enable/disable FDT usage. Each combination is used in a subtest, that
(re)generates the corresponding FIT image.

To re-use the generated data we need to introduce additional complexity
to handle FIT image identification for each subtest and to invalidate
those images when they become out of sync with the parametrized input 
data samples (ITS, FDT) used to generate their content.

> Best regards
> 
> Heinrich


[PATCH v2 1/1] travis-ci: Fix "ResourceWarning: unclosed file"

2019-12-30 Thread Cristian Ciocaltea
This patch gets rid of the warning messages like:

uboot-test-hooks/py/travis-ci/travis_tftp.py:43: ResourceWarning:
unclosed file <_io.BufferedReader name='.bm-work/qemu_arm/u-boot.bin'>

Signed-off-by: Cristian Ciocaltea 
---
Changes in v2:
* The warning line number in the comment relies on Heinrich Schuchardt's
  work 'travis-ci: provide env__efi_fit_tftp_file', but my initial patch
  was based on the master version. Even though it is still applicable,
  to avoid any confusion, I rebased it on Heinrich's latest patch (v2):
  
  https://lists.denx.de/pipermail/u-boot/2019-December/395029.html

 py/travis-ci/travis_tftp.py | 5 -
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/py/travis-ci/travis_tftp.py b/py/travis-ci/travis_tftp.py
index 884823c..f9a44aa 100644
--- a/py/travis-ci/travis_tftp.py
+++ b/py/travis-ci/travis_tftp.py
@@ -40,8 +40,11 @@ def file2env(file_name, addr=None):
 ret = {
 "fn": file_name,
 "size": os.path.getsize(file_full),
-"crc32": hex(binascii.crc32(open(file_full, 'rb').read()) & 
0x)[2:],
 }
+
+with open(file_full, 'rb') as fd:
+ret["crc32"] = hex(binascii.crc32(fd.read()) & 0x)[2:]
+
 if addr is not None:
 ret['addr'] = addr
 
-- 
2.17.1



Re: [PATCH 1/1] travis-ci: provide env__efi_fit_tftp_file

2019-12-30 Thread Cristian Ciocaltea
On Sun, Dec 29, 2019 at 06:46:40PM +0100, Heinrich Schuchardt wrote:
> Provide dictionary env__efi_fit_tftp_file describing the file used for the
> UEFI FIT image test.
> 
> Cf. "test/py: Create a test for launching UEFI binaries from FIT images"
> https://lists.denx.de/pipermail/u-boot/2019-December/394516.html
> 
> Signed-off-by: Heinrich Schuchardt 
> ---
>  py/travis-ci/travis_tftp.py   | 20 +++
>  py/travis-ci/u_boot_boardenv_qemu_arm64_na.py |  1 +
>  py/travis-ci/u_boot_boardenv_qemu_arm_na.py   |  1 +
>  .../u_boot_boardenv_qemu_x86_64_na.py |  2 ++
>  py/travis-ci/u_boot_boardenv_qemu_x86_na.py   |  2 ++
>  .../u_boot_boardenv_vexpress_ca15_tc2_qemu.py |  1 +
>  .../u_boot_boardenv_vexpress_ca9x4_qemu.py|  1 +
>  7 files changed, 28 insertions(+)
> 
> diff --git a/py/travis-ci/travis_tftp.py b/py/travis-ci/travis_tftp.py
> index 4ea5c06..2ab7740 100644
> --- a/py/travis-ci/travis_tftp.py
> +++ b/py/travis-ci/travis_tftp.py
> @@ -1,6 +1,26 @@
>  import os
>  import binascii
> 
> +def efifit2env(addr=None):
> +"""Create dictionary describing file for UEFI FIT image test
> +
> +@addr:  address used for loading the file as int (e.g. 0x4040)
> +Return: dictionary describing the file with entries
> +* fn- filename
> +* addr  - loading address, optional
> +* dn- tftp directory
> +"""
> +tftp_dir = os.environ['UBOOT_TRAVIS_BUILD_DIR'] + "/"
> +
> +ret = {
> +"fn": "test-efi-fit.img",
> +"dn": "tftp_dir",

The quotes around tftp_dir should be removed to allow variable
evaluation:

  "dn": tftp_dir,

> +}
> +if addr is not None:
> +ret['addr'] = addr
> +
> +return ret
> +
>  def file2env(file_name, addr=None):
>  """Create dictionary describing file
> 
> diff --git a/py/travis-ci/u_boot_boardenv_qemu_arm64_na.py 
> b/py/travis-ci/u_boot_boardenv_qemu_arm64_na.py
> index 2986115..98ce873 100644
> --- a/py/travis-ci/u_boot_boardenv_qemu_arm64_na.py
> +++ b/py/travis-ci/u_boot_boardenv_qemu_arm64_na.py
> @@ -6,3 +6,4 @@ env__net_dhcp_server = True
>  env__net_tftp_readable_file = travis_tftp.file2env('u-boot.bin', 0x4040)
>  env__efi_loader_helloworld_file = 
> travis_tftp.file2env('lib/efi_loader/helloworld.efi', 0x4040)
>  env__efi_loader_grub_file = travis_tftp.file2env('grub_arm64.efi', 
> 0x4040)
> +env__efi_fit_tftp_file = travis_tftp.efifit2env(0x4040)
> diff --git a/py/travis-ci/u_boot_boardenv_qemu_arm_na.py 
> b/py/travis-ci/u_boot_boardenv_qemu_arm_na.py
> index 391e3c4..3dbedde 100644
> --- a/py/travis-ci/u_boot_boardenv_qemu_arm_na.py
> +++ b/py/travis-ci/u_boot_boardenv_qemu_arm_na.py
> @@ -6,3 +6,4 @@ env__net_dhcp_server = True
>  env__net_tftp_readable_file = travis_tftp.file2env('u-boot.bin', 0x4040)
>  env__efi_loader_helloworld_file = 
> travis_tftp.file2env('lib/efi_loader/helloworld.efi', 0x4040)
>  env__efi_loader_grub_file = travis_tftp.file2env('grub_arm.efi', 0x4040)
> +env__efi_fit_tftp_file = travis_tftp.efifit2env(0x4040)
> diff --git a/py/travis-ci/u_boot_boardenv_qemu_x86_64_na.py 
> b/py/travis-ci/u_boot_boardenv_qemu_x86_64_na.py
> index 6f7c593..2fe72c8 100644
> --- a/py/travis-ci/u_boot_boardenv_qemu_x86_64_na.py
> +++ b/py/travis-ci/u_boot_boardenv_qemu_x86_64_na.py
> @@ -8,3 +8,5 @@ env__efi_loader_helloworld_file = 
> travis_tftp.file2env('lib/efi_loader/helloworl
> 
>  env__efi_loader_check_smbios = True
>  env__efi_loader_grub_file = travis_tftp.file2env('grub_x64.efi')
> +
> +env__efi_fit_tftp_file = travis_tftp.efifit2env()
> diff --git a/py/travis-ci/u_boot_boardenv_qemu_x86_na.py 
> b/py/travis-ci/u_boot_boardenv_qemu_x86_na.py
> index 70dc0ae..62cc279 100644
> --- a/py/travis-ci/u_boot_boardenv_qemu_x86_na.py
> +++ b/py/travis-ci/u_boot_boardenv_qemu_x86_na.py
> @@ -8,3 +8,5 @@ env__efi_loader_helloworld_file = 
> travis_tftp.file2env('lib/efi_loader/helloworl
> 
>  env__efi_loader_check_smbios = True
>  env__efi_loader_grub_file = travis_tftp.file2env('grub_x86.efi')
> +
> +env__efi_fit_tftp_file = travis_tftp.efifit2env()
> diff --git a/py/travis-ci/u_boot_boardenv_vexpress_ca15_tc2_qemu.py 
> b/py/travis-ci/u_boot_boardenv_vexpress_ca15_tc2_qemu.py
> index 7437ae6..75f287c 100644
> --- a/py/travis-ci/u_boot_boardenv_vexpress_ca15_tc2_qemu.py
> +++ b/py/travis-ci/u_boot_boardenv_vexpress_ca15_tc2_qemu.py
> @@ -5,3 +5,4 @@ env__net_dhcp_server = True
>  env__net_tftp_readable_file = travis_tftp.file2env('u-boot')
>  env__efi_loader_helloworld_file = 
> travis_tftp.file2env('lib/efi_loader/helloworld.efi')
>  env__efi_loader_grub_file = travis_tftp.file2env('grub_arm.efi')
> +env__efi_fit_tftp_file = travis_tftp.efifit2env()
> diff --git a/py/travis-ci/u_boot_boardenv_vexpress_ca9x4_qemu.py 
> b/py/travis-ci/u_boot_boardenv_vexpress_ca9x4_qemu.py
> index 7437ae6..75f287c 100644
> --- a/py/travis-ci/u_boot_boardenv_vexpress_ca9x4_qemu.py
> +++ 

[PATCH v5 1/5] image: Add IH_OS_EFI for EFI chain-load boot

2019-12-29 Thread Cristian Ciocaltea
Add a new OS type to be used for chain-loading an EFI compatible
firmware or boot loader like GRUB2, possibly in a verified boot
scenario.

Bellow is sample ITS file that generates a FIT image supporting
secure boot. Please note the presence of 'os = "efi";' line, which
identifies the currently introduced OS type:

/ {
#address-cells = <1>;

images {
efi-grub {
description = "GRUB EFI";
data = /incbin/("bootarm.efi");
type = "kernel_noload";
arch = "arm";
os = "efi";
compression = "none";
load = <0x0>;
entry = <0x0>;
hash-1 {
algo = "sha256";
};
};
};

configurations {
default = "config-grub";
config-grub {
kernel = "efi-grub";
signature-1 {
    algo = "sha256,rsa2048";
sign-images = "kernel";
};
};
};
};

Signed-off-by: Cristian Ciocaltea 
Reviewed-by: Heinrich Schuchardt 
---
 common/image-fit.c | 3 ++-
 common/image.c | 1 +
 include/image.h| 1 +
 3 files changed, 4 insertions(+), 1 deletion(-)

diff --git a/common/image-fit.c b/common/image-fit.c
index c52f945120..231612ff5f 100644
--- a/common/image-fit.c
+++ b/common/image-fit.c
@@ -1926,7 +1926,8 @@ int fit_image_load(bootm_headers_t *images, ulong addr,
image_type == IH_TYPE_FPGA ||
fit_image_check_os(fit, noffset, IH_OS_LINUX) ||
fit_image_check_os(fit, noffset, IH_OS_U_BOOT) ||
-   fit_image_check_os(fit, noffset, IH_OS_OPENRTOS);
+   fit_image_check_os(fit, noffset, IH_OS_OPENRTOS) ||
+   fit_image_check_os(fit, noffset, IH_OS_EFI);
 
/*
 * If either of the checks fail, we should report an error, but
diff --git a/common/image.c b/common/image.c
index eb626dcac9..75d5dd944f 100644
--- a/common/image.c
+++ b/common/image.c
@@ -137,6 +137,7 @@ static const table_entry_t uimage_os[] = {
{   IH_OS_OPENRTOS, "openrtos", "OpenRTOS", },
 #endif
{   IH_OS_OPENSBI,  "opensbi",  "RISC-V OpenSBI",   },
+   {   IH_OS_EFI,  "efi",  "EFI Firmware" },
 
{   -1, "", "", },
 };
diff --git a/include/image.h b/include/image.h
index f4d2aaf53e..4a280b78e7 100644
--- a/include/image.h
+++ b/include/image.h
@@ -157,6 +157,7 @@ enum {
IH_OS_ARM_TRUSTED_FIRMWARE, /* ARM Trusted Firmware */
IH_OS_TEE,  /* Trusted Execution Environment */
IH_OS_OPENSBI,  /* RISC-V OpenSBI */
+   IH_OS_EFI,  /* EFI Firmware (e.g. GRUB2) */
 
IH_OS_COUNT,
 };
-- 
2.17.1



[PATCH v5 5/5] test/py: Create a test for launching UEFI binaries from FIT images

2019-12-29 Thread Cristian Ciocaltea
This test verifies the implementation of the 'bootm' extension that
handles UEFI binaries inside FIT images (enabled via CONFIG_BOOTM_EFI).

Signed-off-by: Cristian Ciocaltea 
---
 test/py/tests/test_efi_fit.py | 458 ++
 1 file changed, 458 insertions(+)
 create mode 100644 test/py/tests/test_efi_fit.py

diff --git a/test/py/tests/test_efi_fit.py b/test/py/tests/test_efi_fit.py
new file mode 100644
index 00..6986b2d35c
--- /dev/null
+++ b/test/py/tests/test_efi_fit.py
@@ -0,0 +1,458 @@
+# SPDX-License-Identifier: GPL-2.0
+# Copyright (c) 2019, Cristian Ciocaltea 
+#
+# Work based on:
+# - test_net.py
+# Copyright (c) 2016, NVIDIA CORPORATION. All rights reserved.
+# - test_fit.py
+# Copyright (c) 2013, Google Inc.
+#
+# Test launching UEFI binaries from FIT images.
+
+import os.path
+import pytest
+import u_boot_utils as util
+
+"""
+Note: This test relies on boardenv_* containing configuration values to define
+which network environment is available for testing. Without this, the parts
+that rely on network will be automatically skipped.
+
+For example:
+
+# Boolean indicating whether the Ethernet device is attached to USB, and hence
+# USB enumeration needs to be performed prior to network tests.
+# This variable may be omitted if its value is False.
+env__net_uses_usb = False
+
+# Boolean indicating whether the Ethernet device is attached to PCI, and hence
+# PCI enumeration needs to be performed prior to network tests.
+# This variable may be omitted if its value is False.
+env__net_uses_pci = True
+
+# True if a DHCP server is attached to the network, and should be tested.
+# If DHCP testing is not possible or desired, this variable may be omitted or
+# set to False.
+env__net_dhcp_server = True
+
+# A list of environment variables that should be set in order to configure a
+# static IP. If solely relying on DHCP, this variable may be omitted or set to
+# an empty list.
+env__net_static_env_vars = [
+('ipaddr', '10.0.0.100'),
+('netmask', '255.255.255.0'),
+('serverip', '10.0.0.1'),
+]
+
+# Details regarding a file that may be read from a TFTP server. This variable
+# may be omitted or set to None if TFTP testing is not possible or desired.
+# Additionally, when the 'size' is not available, the file will be generated
+# automatically in the TFTP root directory, as specified by the 'dn' field.
+env__efi_fit_tftp_file = {
+'fn': 'test-efi-fit.img',   # File path relative to TFTP root
+'size': 3831,   # File size
+'crc32': '9fa3f79c',# Checksum using CRC-32 algorithm, optional
+'addr': 0x4040, # Loading address, integer, optional
+'dn': 'tftp/root/dir',  # TFTP root directory path, optional
+}
+"""
+
+# Define the parametrized ITS data to be used for FIT images generation.
+its_data = '''
+/dts-v1/;
+
+/ {
+description = "EFI image with FDT blob";
+#address-cells = <1>;
+
+images {
+efi {
+description = "Test EFI";
+data = /incbin/("%(efi-bin)s");
+type = "%(kernel-type)s";
+arch = "%(sys-arch)s";
+os = "efi";
+compression = "%(efi-comp)s";
+load = <0x0>;
+entry = <0x0>;
+};
+fdt {
+description = "Test FDT";
+data = /incbin/("%(fdt-bin)s");
+type = "flat_dt";
+arch = "%(sys-arch)s";
+compression = "%(fdt-comp)s";
+};
+};
+
+configurations {
+default = "config-efi-fdt";
+config-efi-fdt {
+description = "EFI FIT w/ FDT";
+kernel = "efi";
+fdt = "fdt";
+};
+config-efi-nofdt {
+description = "EFI FIT w/o FDT";
+kernel = "efi";
+};
+};
+};
+'''
+
+# Define the parametrized FDT data to be used for DTB images generation.
+fdt_data = '''
+/dts-v1/;
+
+/ {
+#address-cells = <1>;
+#size-cells = <0>;
+
+model = "%(sys-arch)s %(fdt_type)s EFI FIT Boot Test";
+compatible = "%(sys-arch)s";
+
+reset@0 {
+compatible = "%(sys-arch)s,reset";
+reg = <0>;
+};
+};
+'''
+
+@pytest.mark.buildconfigspec('bootm_efi')
+@pytest.mark.buildconfigspec('cmd_bootefi_hello_compile')
+@pytest.mark.buildconfigspec('fit')
+@pytest.mark.notbuildconfigspec('generate_acpi_table')
+@pytest.mark.requiredtool('dtc')
+def test_efi_fit_launch(u_boot_console):
+"""Test handling of UEFI binaries inside FIT images.
+
+The tests are trying to launch U-Boot's helloworld.efi embedded into
+FIT images, in uncompressed or gzip compressed format.
+
+Additionally, a sample FDT blob is created and embed

[PATCH v5 4/5] doc: uefi.rst: Document launching UEFI binaries from FIT images

2019-12-29 Thread Cristian Ciocaltea
This patch adds a new section "Launching a UEFI binary from a FIT image"
documenting the usage of the CONFIG_BOOTM_EFI extension to bootm command
that offers a verified boot alternative for UEFI binaries such as GRUB2.

Signed-off-by: Cristian Ciocaltea 
Reviewed-by: Heinrich Schuchardt 
---
 doc/uefi/uefi.rst | 34 ++
 1 file changed, 34 insertions(+)

diff --git a/doc/uefi/uefi.rst b/doc/uefi/uefi.rst
index db942df694..a8fd886d6b 100644
--- a/doc/uefi/uefi.rst
+++ b/doc/uefi/uefi.rst
@@ -63,6 +63,40 @@ The environment variable 'bootargs' is passed as load 
options in the UEFI system
 table. The Linux kernel EFI stub uses the load options as command line
 arguments.
 
+Launching a UEFI binary from a FIT image
+
+
+A signed FIT image can be used to securely boot a UEFI image via the
+bootm command. This feature is available if U-Boot is configured with::
+
+CONFIG_BOOTM_EFI=y
+
+A sample configuration is provided as file doc/uImage.FIT/uefi.its.
+
+Below you find the output of an example session starting GRUB::
+
+=> load mmc 0:1 ${kernel_addr_r} image.fit
+4620426 bytes read in 83 ms (53.1 MiB/s)
+=> bootm ${kernel_addr_r}#config-grub-nofdt
+## Loading kernel from FIT Image at 4040 ...
+   Using 'config-grub-nofdt' configuration
+   Verifying Hash Integrity ... sha256,rsa2048:dev+ OK
+   Trying 'efi-grub' kernel subimage
+ Description:  GRUB EFI Firmware
+ Created:  2019-11-20   8:18:16 UTC
+ Type: Kernel Image (no loading done)
+ Compression:  uncompressed
+ Data Start:   0x404000d0
+ Data Size:450560 Bytes = 440 KiB
+ Hash algo:sha256
+ Hash value:   
4dbee00021112df618f58b3f7cf5e1595533d543094064b9ce991e8b054a9eec
+   Verifying Hash Integrity ... sha256+ OK
+   XIP Kernel Image (no loading done)
+## Transferring control to EFI (at address 404000d0) ...
+Welcome to GRUB!
+
+See doc/uImage.FIT/howto.txt for an introduction to FIT images.
+
 Executing the boot manager
 ~~
 
-- 
2.17.1



[PATCH v5 2/5] bootm: Add a bootm command for type IH_OS_EFI

2019-12-29 Thread Cristian Ciocaltea
Add support for booting EFI binaries contained in FIT images.
A typical usage scenario is chain-loading GRUB2 in a verified
boot environment.

Signed-off-by: Cristian Ciocaltea 
Reviewed-by: Heinrich Schuchardt 
---
 cmd/Kconfig   |  7 ++
 common/bootm_os.c | 56 +++
 2 files changed, 63 insertions(+)

diff --git a/cmd/Kconfig b/cmd/Kconfig
index 1e4cf146c5..4394bb8e51 100644
--- a/cmd/Kconfig
+++ b/cmd/Kconfig
@@ -251,6 +251,13 @@ config CMD_BOOTM
help
  Boot an application image from the memory.
 
+config BOOTM_EFI
+   bool "Support booting UEFI FIT images"
+   depends on CMD_BOOTEFI && CMD_BOOTM && FIT
+   default y
+   help
+ Support booting UEFI FIT images via the bootm command.
+
 config CMD_BOOTZ
bool "bootz"
help
diff --git a/common/bootm_os.c b/common/bootm_os.c
index d89ddc32b0..1d58462509 100644
--- a/common/bootm_os.c
+++ b/common/bootm_os.c
@@ -7,10 +7,12 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 
@@ -498,6 +500,57 @@ static int do_bootm_tee(int flag, int argc, char * const 
argv[],
 }
 #endif
 
+#ifdef CONFIG_BOOTM_EFI
+static int do_bootm_efi(int flag, int argc, char * const argv[],
+   bootm_headers_t *images)
+{
+   int ret;
+   efi_status_t efi_ret;
+   void *image_buf;
+
+   if (flag != BOOTM_STATE_OS_GO)
+   return 0;
+
+   /* Locate FDT, if provided */
+   ret = bootm_find_images(flag, argc, argv);
+   if (ret)
+   return ret;
+
+   /* Initialize EFI drivers */
+   efi_ret = efi_init_obj_list();
+   if (efi_ret != EFI_SUCCESS) {
+   printf("## Failed to initialize UEFI sub-system: r = %lu\n",
+  efi_ret & ~EFI_ERROR_MASK);
+   return 1;
+   }
+
+   /* Install device tree */
+   efi_ret = efi_install_fdt(images->ft_len
+ ? images->ft_addr : EFI_FDT_USE_INTERNAL);
+   if (efi_ret != EFI_SUCCESS) {
+   printf("## Failed to install device tree: r = %lu\n",
+  efi_ret & ~EFI_ERROR_MASK);
+   return 1;
+   }
+
+   /* Run EFI image */
+   printf("## Transferring control to EFI (at address %08lx) ...\n",
+  images->ep);
+   bootstage_mark(BOOTSTAGE_ID_RUN_OS);
+
+   image_buf = map_sysmem(images->ep, images->os.image_len);
+
+   efi_ret = efi_run_image(image_buf, images->os.image_len);
+   if (efi_ret != EFI_SUCCESS) {
+   printf("## Failed to run EFI image: r = %lu\n",
+  efi_ret & ~EFI_ERROR_MASK);
+   return 1;
+   }
+
+   return 0;
+}
+#endif
+
 static boot_os_fn *boot_os[] = {
[IH_OS_U_BOOT] = do_bootm_standalone,
 #ifdef CONFIG_BOOTM_LINUX
@@ -534,6 +587,9 @@ static boot_os_fn *boot_os[] = {
 #ifdef CONFIG_BOOTM_OPTEE
[IH_OS_TEE] = do_bootm_tee,
 #endif
+#ifdef CONFIG_BOOTM_EFI
+   [IH_OS_EFI] = do_bootm_efi,
+#endif
 };
 
 /* Allow for arch specific config before we boot */
-- 
2.17.1



[PATCH v5 0/5] Add support for booting EFI FIT images

2019-12-29 Thread Cristian Ciocaltea
Currently the only way to run an EFI binary like GRUB2 is via the
'bootefi' command, which cannot be used in a verified boot scenario.

The obvious solution to this limitation is to add support for
booting FIT images containing those EFI binaries.

The implementation relies on a new image type - IH_OS_EFI - which
can be created by using 'os = "efi"' inside an ITS file:

/ {
#address-cells = <1>;

images {
efi-grub {
description = "GRUB EFI";
data = /incbin/("bootarm.efi");
type = "kernel_noload";
arch = "arm";
os = "efi";
compression = "none";
load = <0x0>;
entry = <0x0>;
hash-1 {
algo = "sha256";
};
};
};

configurations {
default = "config-grub";
config-grub {
kernel = "efi-grub";
signature-1 {
algo = "sha256,rsa2048";
sign-images = "kernel";
};
};
};
};

The bootm command has been extended to handle the IH_OS_EFI images.
To enable this feature, a new configuration option has been added:
BOOTM_EFI

I tested the solution using the 'qemu_arm' board:

=> load scsi 0:1 ${kernel_addr_r} efi-image.fit
=> bootm ${kernel_addr_r}#config-grub

Changes in v5:
* Update the definition of BOOTM_EFI: move content right after
  CMD_BOOTM, improve description and help text, fix dependency
* Change the type of the 'addr' field inside 'env__efi_fit_tftp_file'
  dictionary from string to integer, currently tested on: sandbox,
  qemu_arm, qemu_arm64

Changes in v4:
* Extend the python test to also run on real hardware, currently
  tested on qemu_arm

Changes in v3:
* Rebase patches on Heinrich Schuchardt's patch series v3:
   efi_loader: prepare for FIT images
   https://lists.denx.de/pipermail/u-boot/2019-December/393677.html
   This fixes implicitly the sandbox issue 'phys_to_virt: Cannot map
   sandbox address' since efi_install_fdt() is now expecting a pointer
   to addressable memory instead of a physical address.
* Get rid of 'EFI/BOOT/' prefix used in ITS samples
* Add a python test to verify the implementation in sandbox environment

Changes in v2:
* Rebase patches on Heinrich Schuchardt's patch series:
   efi_loader: prepare for FIT images
   https://lists.denx.de/pipermail/u-boot/2019-December/393192.html
* Add sample configuration: doc/uImage.FIT/uefi.its
* Update uefi documentation: doc/uefi/uefi.rst

Cristian Ciocaltea (5):
  image: Add IH_OS_EFI for EFI chain-load boot
  bootm: Add a bootm command for type IH_OS_EFI
  doc: Add sample uefi.its image description file
  doc: uefi.rst: Document launching UEFI binaries from FIT images
  test/py: Create a test for launching UEFI binaries from FIT images

 cmd/Kconfig   |   7 +
 common/bootm_os.c |  56 +
 common/image-fit.c|   3 +-
 common/image.c|   1 +
 doc/uImage.FIT/uefi.its   |  67 +
 doc/uefi/uefi.rst |  34 +++
 include/image.h   |   1 +
 test/py/tests/test_efi_fit.py | 458 ++
 8 files changed, 626 insertions(+), 1 deletion(-)
 create mode 100644 doc/uImage.FIT/uefi.its
 create mode 100644 test/py/tests/test_efi_fit.py

-- 
2.17.1



[PATCH v5 3/5] doc: Add sample uefi.its image description file

2019-12-29 Thread Cristian Ciocaltea
This patch adds an example FIT image description file demonstrating
the usage of bootm command to securely launch UEFI binaries.

Signed-off-by: Cristian Ciocaltea 
Reviewed-by: Heinrich Schuchardt 
---
 doc/uImage.FIT/uefi.its | 67 +
 1 file changed, 67 insertions(+)
 create mode 100644 doc/uImage.FIT/uefi.its

diff --git a/doc/uImage.FIT/uefi.its b/doc/uImage.FIT/uefi.its
new file mode 100644
index 00..378ca4ed8d
--- /dev/null
+++ b/doc/uImage.FIT/uefi.its
@@ -0,0 +1,67 @@
+/*
+ * Example FIT image description file demonstrating the usage of the
+ * bootm command to launch UEFI binaries.
+ *
+ * Two boot configurations are available to enable booting GRUB2 on QEMU,
+ * the former uses a FDT blob contained in the FIT image, while the later
+ * relies on the FDT provided by the board emulator.
+ */
+
+/dts-v1/;
+
+/ {
+   description = "GRUB2 EFI and QEMU FDT blob";
+   #address-cells = <1>;
+
+   images {
+   efi-grub {
+   description = "GRUB EFI Firmware";
+   data = /incbin/("bootarm.efi");
+   type = "kernel_noload";
+   arch = "arm";
+   os = "efi";
+   compression = "none";
+   load = <0x0>;
+   entry = <0x0>;
+   hash-1 {
+   algo = "sha256";
+   };
+   };
+
+   fdt-qemu {
+   description = "QEMU DTB";
+   data = /incbin/("qemu-arm.dtb");
+   type = "flat_dt";
+   arch = "arm";
+   compression = "none";
+   hash-1 {
+   algo = "sha256";
+   };
+   };
+   };
+
+   configurations {
+   default = "config-grub-fdt";
+
+   config-grub-fdt {
+   description = "GRUB EFI Boot w/ FDT";
+   kernel = "efi-grub";
+   fdt = "fdt-qemu";
+   signature-1 {
+   algo = "sha256,rsa2048";
+   key-name-hint = "dev";
+   sign-images = "kernel", "fdt";
+   };
+   };
+
+   config-grub-nofdt {
+   description = "GRUB EFI Boot w/o FDT";
+   kernel = "efi-grub";
+   signature-1 {
+   algo = "sha256,rsa2048";
+   key-name-hint = "dev";
+   sign-images = "kernel";
+   };
+   };
+   };
+};
-- 
2.17.1



[PATCH v1 1/1] travis-ci: Fix "ResourceWarning: unclosed file"

2019-12-29 Thread Cristian Ciocaltea
This patch gets rid of the warning messages like:

uboot-test-hooks/py/travis-ci/travis_tftp.py:43: ResourceWarning:
unclosed file <_io.BufferedReader name='.bm-work/qemu_arm/u-boot.bin'>

Signed-off-by: Cristian Ciocaltea 
---
 py/travis-ci/travis_tftp.py | 5 -
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/py/travis-ci/travis_tftp.py b/py/travis-ci/travis_tftp.py
index 4ea5c06..3e1f11d 100644
--- a/py/travis-ci/travis_tftp.py
+++ b/py/travis-ci/travis_tftp.py
@@ -20,8 +20,11 @@ def file2env(file_name, addr=None):
 ret = {
 "fn": file_name,
 "size": os.path.getsize(file_full),
-"crc32": hex(binascii.crc32(open(file_full, 'rb').read()) & 
0x)[2:],
 }
+
+with open(file_full, 'rb') as fd:
+ret["crc32"] = hex(binascii.crc32(fd.read()) & 0x)[2:]
+
 if addr is not None:
 ret['addr'] = addr
 
-- 
2.17.1



Re: [PATCH v4 5/5] test/py: Create a test for launching UEFI binaries from FIT images

2019-12-29 Thread Cristian Ciocaltea
On Sun, Dec 29, 2019 at 08:11:10PM +0100, Heinrich Schuchardt wrote:
> On 12/29/19 7:39 PM, Cristian Ciocaltea wrote:
> > On Sun, Dec 29, 2019 at 11:22:08AM +0100, Heinrich Schuchardt wrote:
> > > On 12/24/19 5:05 PM, Cristian Ciocaltea wrote:
> > > > This test verifies the implementation of the 'bootm' extension that
> > > > handles UEFI binaries inside FIT images (enabled via CONFIG_BOOTM_EFI).
> > > > 
> > > > Signed-off-by: Cristian Ciocaltea 
> > > 
> > > Thanks a lot for devising this test.
> > > 
> > > ---
> > > 
> > > You are using variable env__efi_fit_tftp_file. To run the test on Gitlab
> > > and Travis CI a patch will be needed for:
> > > 
> > >   https://github.com/swarren/uboot-test-hooks.git
> > > 
> > > I hope
> > > 
> > > https://github.com/xypron/uboot-test-hooks/commit/20dcd721437dd5f7d7d3d235f7112246f43305d2
> > > 
> > > will do the job.
> > > 
> > > Once we have this applied we will have to adjust the config files for 
> > > QEMU.
> > > 
> > > ---
> > > 
> > > I have been trying to run the test on qemu_arm64_defconfig using the
> > > following lines in u_boot_boardenv_qemu_arm64.py:
> > > 
> > > env__efi_fit_tftp_file = {
> > >  "fn": "helloworld.efi",
> > >  "size": 4480,
> > >  "crc32": "19f9c0ab",
> > > }
> > > 
> > > I got an error:
> > > 
> > > test/py/tests/test_efi_fit.py:417: in launch_efi
> > >  addr = load_fit_from_host(fit) if is_sandbox else
> > > load_fit_from_tftp(fit)
> > > _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
> > >  addr = f.get('addr', None)
> > >  if not addr:
> > > >addr = u_boot_utils.find_ram_base(cons)
> > > E   NameError: name 'u_boot_utils' is not defined
> > > 
> > > 
> > > When I provided addr:
> > > 
> > > env__efi_fit_tftp_file = {
> > >  "fn": "helloworld.efi",
> > >  "size": 4480,
> > >  "crc32": "19f9c0ab",
> > >  "addr": 0x4040,
> > > }
> > > 
> > > I got the following error:
> > > 
> > > => tftpboot 1073741824 helloworld.efi
> > > TFTP error: trying to overwrite reserved memory...
> > > 
> > > I would have expected a command
> > > 
> > >   tftpboot 4040 helloworld.efi
> > > 
> > > to be issued.
> > > 
> > > Same error with bootm:
> > > 
> > > => bootm 1077936128#config-efi-nofdt
> > > "Synchronous Abort" handler, esr 0x9610
> > > elr: 0001c36c lr : 000140f4 (reloc)
> > > 
> > > Please, fix the lines indicated below and verify that you can actually
> > > execute this test on the QEMU platform.
> > 
> > Thank you for the detailed report!
> > 
> > Unfortunately I have only tested on qemu_arm and somehow I missed the
> > check of having the address computed by the test suite. It used to work
> > before I changed the address data type to string - the reason was to
> > allow for more flexibility, e.g. providing values like '$kernel_addr_r'
> > instead of just precomputed numbers.
> > 
> > I'm going to extend the tests on qemu_arm64 as well.
> > 
> > > 
> > > https://github.com/xypron/u-boot-build/tree/qemu-arm64/u-boot-test
> > > 
> > > contains the files I use to run Python tests on qemu_arm64_defconfig.
> > > 
> > > > ---
> > > >test/py/tests/test_efi_fit.py | 459 
> > > > ++
> > > >1 file changed, 459 insertions(+)
> > > >create mode 100644 test/py/tests/test_efi_fit.py
> > > > 
> > > > diff --git a/test/py/tests/test_efi_fit.py 
> > > > b/test/py/tests/test_efi_fit.py
> > > > new file mode 100644
> > > > index 00..e1f0e42694
> > > > --- /dev/null
> > > > +++ b/test/py/tests/test_efi_fit.py
> > > > @@ -0,0 +1,459 @@
> > > > +# SPDX-License-Identifier: GPL-2.0
> > > > +# Copyright (c) 2019, Cristian Ciocaltea 
> > > > +#
> > > > +# Work based on:
> > > > +# - test_net.py
> > > > +# Copyright (c) 2016, NVIDIA CORPORATI

Re: [PATCH v4 5/5] test/py: Create a test for launching UEFI binaries from FIT images

2019-12-29 Thread Cristian Ciocaltea
On Sun, Dec 29, 2019 at 11:22:08AM +0100, Heinrich Schuchardt wrote:
> On 12/24/19 5:05 PM, Cristian Ciocaltea wrote:
> > This test verifies the implementation of the 'bootm' extension that
> > handles UEFI binaries inside FIT images (enabled via CONFIG_BOOTM_EFI).
> > 
> > Signed-off-by: Cristian Ciocaltea 
> 
> Thanks a lot for devising this test.
> 
> ---
> 
> You are using variable env__efi_fit_tftp_file. To run the test on Gitlab
> and Travis CI a patch will be needed for:
> 
>   https://github.com/swarren/uboot-test-hooks.git
> 
> I hope
> 
> https://github.com/xypron/uboot-test-hooks/commit/20dcd721437dd5f7d7d3d235f7112246f43305d2
> 
> will do the job.
> 
> Once we have this applied we will have to adjust the config files for QEMU.
> 
> ---
> 
> I have been trying to run the test on qemu_arm64_defconfig using the
> following lines in u_boot_boardenv_qemu_arm64.py:
> 
> env__efi_fit_tftp_file = {
> "fn": "helloworld.efi",
> "size": 4480,
> "crc32": "19f9c0ab",
> }
> 
> I got an error:
> 
> test/py/tests/test_efi_fit.py:417: in launch_efi
> addr = load_fit_from_host(fit) if is_sandbox else
> load_fit_from_tftp(fit)
> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
> addr = f.get('addr', None)
> if not addr:
> >   addr = u_boot_utils.find_ram_base(cons)
> E   NameError: name 'u_boot_utils' is not defined
> 
> 
> When I provided addr:
> 
> env__efi_fit_tftp_file = {
> "fn": "helloworld.efi",
> "size": 4480,
> "crc32": "19f9c0ab",
> "addr": 0x4040,
> }
> 
> I got the following error:
> 
> => tftpboot 1073741824 helloworld.efi
> TFTP error: trying to overwrite reserved memory...
> 
> I would have expected a command
> 
>   tftpboot 4040 helloworld.efi
> 
> to be issued.
> 
> Same error with bootm:
> 
> => bootm 1077936128#config-efi-nofdt
> "Synchronous Abort" handler, esr 0x9610
> elr: 0001c36c lr : 000140f4 (reloc)
> 
> Please, fix the lines indicated below and verify that you can actually
> execute this test on the QEMU platform.

Thank you for the detailed report!

Unfortunately I have only tested on qemu_arm and somehow I missed the
check of having the address computed by the test suite. It used to work
before I changed the address data type to string - the reason was to
allow for more flexibility, e.g. providing values like '$kernel_addr_r'
instead of just precomputed numbers.

I'm going to extend the tests on qemu_arm64 as well.

> 
> https://github.com/xypron/u-boot-build/tree/qemu-arm64/u-boot-test
> 
> contains the files I use to run Python tests on qemu_arm64_defconfig.
> 
> > ---
> >   test/py/tests/test_efi_fit.py | 459 ++
> >   1 file changed, 459 insertions(+)
> >   create mode 100644 test/py/tests/test_efi_fit.py
> > 
> > diff --git a/test/py/tests/test_efi_fit.py b/test/py/tests/test_efi_fit.py
> > new file mode 100644
> > index 00..e1f0e42694
> > --- /dev/null
> > +++ b/test/py/tests/test_efi_fit.py
> > @@ -0,0 +1,459 @@
> > +# SPDX-License-Identifier: GPL-2.0
> > +# Copyright (c) 2019, Cristian Ciocaltea 
> > +#
> > +# Work based on:
> > +# - test_net.py
> > +# Copyright (c) 2016, NVIDIA CORPORATION. All rights reserved.
> > +# - test_fit.py
> > +# Copyright (c) 2013, Google Inc.
> > +#
> > +# Test launching UEFI binaries from FIT images.
> > +
> > +import os.path
> > +import pytest
> > +import u_boot_utils as util
> 
> "as util" causes an error if you use u_boot_utils.* below. Below I
> indicate the places to change.

Fixed, thanks.

> > +
> > +"""
> > +Note: This test relies on boardenv_* containing configuration values to 
> > define
> > +which network environment is available for testing. Without this, the parts
> > +that rely on network will be automatically skipped.
> > +
> > +For example:
> > +
> > +# Boolean indicating whether the Ethernet device is attached to USB, and 
> > hence
> > +# USB enumeration needs to be performed prior to network tests.
> > +# This variable may be omitted if its value is False.
> > +env__net_uses_usb = False
> > +
> > +# Boolean indicating whether the Ethernet device is attached to PCI, and 
> > hence
> > +# PCI enumeration needs to be performed prior to network tests.
> > +# This variable may be omitted if its value is False.
&

Re: [PATCH v4 2/5] bootm: Add a bootm command for type IH_OS_EFI

2019-12-29 Thread Cristian Ciocaltea
On Sun, Dec 29, 2019 at 11:56:01AM +0100, Heinrich Schuchardt wrote:
> On 12/29/19 11:34 AM, Heinrich Schuchardt wrote:
> > On 12/24/19 5:05 PM, Cristian Ciocaltea wrote:
> > > Add support for booting EFI binaries contained in FIT images.
> > > A typical usage scenario is chain-loading GRUB2 in a verified
> > > boot environment.
> > > 
> > > Signed-off-by: Cristian Ciocaltea 
> > > Reviewed-by: Heinrich Schuchardt 
> > > ---
> > >   cmd/Kconfig   |  7 ++
> > >   common/bootm_os.c | 56 +++
> > >   2 files changed, 63 insertions(+)
> > > 
> > > diff --git a/cmd/Kconfig b/cmd/Kconfig
> > > index 1e4cf146c5..87f2335a3c 100644
> > > --- a/cmd/Kconfig
> > > +++ b/cmd/Kconfig
> > > @@ -263,6 +263,13 @@ config CMD_BOOTI
> > >   help
> > >     Boot an AArch64 Linux Kernel image from memory.
> > > 
> > > +config BOOTM_EFI
> > > +    bool "Support booting EFI OS images"
> > 
> > Shouldn't this be "Support booting UEFI FIT images"?
> > 
> > > +    depends on CMD_BOOTEFI
> > 
> > depends on BOOTM
> 
> depends on CMD_BOOTM
> 
> The patch series compiles without CONFIG_FIT. But shouldn't this also be
> a dependency?

Indeed, thanks.

> If we place the definition directly after CMD_BOOTM, it will be indented
> so that it is evident that this is a sub-feature of CMD_BOOTM.
> 
> So how about the following?
> 
> config CMD_BOOTM
> bool "bootm"
> default y
> help
>   Boot an application image from the memory.
> 
> config BOOTM_EFI
> bool "Support booting UEFI FIT images"
> depends on CMD_BOOTEFI && CMD_BOOTM && FIT
> default y
> help
>   Support booting UEFI FIT images via the bootm command.

In this case, we should probably also move CMD_BOOTZ, CMD_BOOTI and
BOOTM_LINUX right after CMD_BOOTEFI_HELLO, since those commands do not
depend on CMD_BOOTM, while all BOOTM_* features, except BOOTM_LINUX,
depend exclusively on CMD_BOOTM.

> Best regards
> 
> Heinrich
> 
> > 
> > is missing here.
> > 
> > > +    default y
> > > +    help
> > > +  Support booting EFI images via the bootm command.
> > 
> > Should we say:
> > 
> > Support booting UEFI FIT images via the bootm command.
> > 
> > Best regards
> > 
> > Heinrich
> > 
> > > +
> > >   config BOOTM_LINUX
> > >   bool "Support booting Linux OS images"
> > >   depends on CMD_BOOTM || CMD_BOOTZ || CMD_BOOTI
> > > diff --git a/common/bootm_os.c b/common/bootm_os.c
> > > index d89ddc32b0..1d58462509 100644
> > > --- a/common/bootm_os.c
> > > +++ b/common/bootm_os.c
> > > @@ -7,10 +7,12 @@
> > >   #include 
> > >   #include 
> > >   #include 
> > > +#include 
> > >   #include 
> > >   #include 
> > >   #include 
> > >   #include 
> > > +#include 
> > >   #include 
> > >   #include 
> > > 
> > > @@ -498,6 +500,57 @@ static int do_bootm_tee(int flag, int argc, char
> > > * const argv[],
> > >   }
> > >   #endif
> > > 
> > > +#ifdef CONFIG_BOOTM_EFI
> > > +static int do_bootm_efi(int flag, int argc, char * const argv[],
> > > +    bootm_headers_t *images)
> > > +{
> > > +    int ret;
> > > +    efi_status_t efi_ret;
> > > +    void *image_buf;
> > > +
> > > +    if (flag != BOOTM_STATE_OS_GO)
> > > +    return 0;
> > > +
> > > +    /* Locate FDT, if provided */
> > > +    ret = bootm_find_images(flag, argc, argv);
> > > +    if (ret)
> > > +    return ret;
> > > +
> > > +    /* Initialize EFI drivers */
> > > +    efi_ret = efi_init_obj_list();
> > > +    if (efi_ret != EFI_SUCCESS) {
> > > +    printf("## Failed to initialize UEFI sub-system: r = %lu\n",
> > > +   efi_ret & ~EFI_ERROR_MASK);
> > > +    return 1;
> > > +    }
> > > +
> > > +    /* Install device tree */
> > > +    efi_ret = efi_install_fdt(images->ft_len
> > > +  ? images->ft_addr : EFI_FDT_USE_INTERNAL);
> > > +    if (efi_ret != EFI_SUCCESS) {
> > > +    printf("## Failed to install device tree: r = %lu\n",
> > > + 

Re: [PATCH v4 2/5] bootm: Add a bootm command for type IH_OS_EFI

2019-12-29 Thread Cristian Ciocaltea
On Sun, Dec 29, 2019 at 11:34:09AM +0100, Heinrich Schuchardt wrote:
> On 12/24/19 5:05 PM, Cristian Ciocaltea wrote:
> > Add support for booting EFI binaries contained in FIT images.
> > A typical usage scenario is chain-loading GRUB2 in a verified
> > boot environment.
> > 
> > Signed-off-by: Cristian Ciocaltea 
> > Reviewed-by: Heinrich Schuchardt 
> > ---
> >   cmd/Kconfig   |  7 ++
> >   common/bootm_os.c | 56 +++
> >   2 files changed, 63 insertions(+)
> > 
> > diff --git a/cmd/Kconfig b/cmd/Kconfig
> > index 1e4cf146c5..87f2335a3c 100644
> > --- a/cmd/Kconfig
> > +++ b/cmd/Kconfig
> > @@ -263,6 +263,13 @@ config CMD_BOOTI
> > help
> >   Boot an AArch64 Linux Kernel image from memory.
> > 
> > +config BOOTM_EFI
> > +   bool "Support booting EFI OS images"
> 
> Shouldn't this be "Support booting UEFI FIT images"?

Done.

> > +   depends on CMD_BOOTEFI
> 
> depends on BOOTM
> 
> is missing here.

Right, thanks. Added 'CMD_BOOTEFI && CMD_BOOTM'.

> > +   default y
> > +   help
> > + Support booting EFI images via the bootm command.
> 
> Should we say:
> 
> Support booting UEFI FIT images via the bootm command.

Done.

> Best regards
> 
> Heinrich
> 
> > +
> >   config BOOTM_LINUX
> > bool "Support booting Linux OS images"
> > depends on CMD_BOOTM || CMD_BOOTZ || CMD_BOOTI
> > diff --git a/common/bootm_os.c b/common/bootm_os.c
> > index d89ddc32b0..1d58462509 100644
> > --- a/common/bootm_os.c
> > +++ b/common/bootm_os.c
> > @@ -7,10 +7,12 @@
> >   #include 
> >   #include 
> >   #include 
> > +#include 
> >   #include 
> >   #include 
> >   #include 
> >   #include 
> > +#include 
> >   #include 
> >   #include 
> > 
> > @@ -498,6 +500,57 @@ static int do_bootm_tee(int flag, int argc, char * 
> > const argv[],
> >   }
> >   #endif
> > 
> > +#ifdef CONFIG_BOOTM_EFI
> > +static int do_bootm_efi(int flag, int argc, char * const argv[],
> > +   bootm_headers_t *images)
> > +{
> > +   int ret;
> > +   efi_status_t efi_ret;
> > +   void *image_buf;
> > +
> > +   if (flag != BOOTM_STATE_OS_GO)
> > +   return 0;
> > +
> > +   /* Locate FDT, if provided */
> > +   ret = bootm_find_images(flag, argc, argv);
> > +   if (ret)
> > +   return ret;
> > +
> > +   /* Initialize EFI drivers */
> > +   efi_ret = efi_init_obj_list();
> > +   if (efi_ret != EFI_SUCCESS) {
> > +   printf("## Failed to initialize UEFI sub-system: r = %lu\n",
> > +  efi_ret & ~EFI_ERROR_MASK);
> > +   return 1;
> > +   }
> > +
> > +   /* Install device tree */
> > +   efi_ret = efi_install_fdt(images->ft_len
> > + ? images->ft_addr : EFI_FDT_USE_INTERNAL);
> > +   if (efi_ret != EFI_SUCCESS) {
> > +   printf("## Failed to install device tree: r = %lu\n",
> > +  efi_ret & ~EFI_ERROR_MASK);
> > +   return 1;
> > +   }
> > +
> > +   /* Run EFI image */
> > +   printf("## Transferring control to EFI (at address %08lx) ...\n",
> > +  images->ep);
> > +   bootstage_mark(BOOTSTAGE_ID_RUN_OS);
> > +
> > +   image_buf = map_sysmem(images->ep, images->os.image_len);
> > +
> > +   efi_ret = efi_run_image(image_buf, images->os.image_len);
> > +   if (efi_ret != EFI_SUCCESS) {
> > +   printf("## Failed to run EFI image: r = %lu\n",
> > +  efi_ret & ~EFI_ERROR_MASK);
> > +   return 1;
> > +   }
> > +
> > +   return 0;
> > +}
> > +#endif
> > +
> >   static boot_os_fn *boot_os[] = {
> > [IH_OS_U_BOOT] = do_bootm_standalone,
> >   #ifdef CONFIG_BOOTM_LINUX
> > @@ -534,6 +587,9 @@ static boot_os_fn *boot_os[] = {
> >   #ifdef CONFIG_BOOTM_OPTEE
> > [IH_OS_TEE] = do_bootm_tee,
> >   #endif
> > +#ifdef CONFIG_BOOTM_EFI
> > +   [IH_OS_EFI] = do_bootm_efi,
> > +#endif
> >   };
> > 
> >   /* Allow for arch specific config before we boot */
> > 
> 


[PATCH v4 5/5] test/py: Create a test for launching UEFI binaries from FIT images

2019-12-24 Thread Cristian Ciocaltea
This test verifies the implementation of the 'bootm' extension that
handles UEFI binaries inside FIT images (enabled via CONFIG_BOOTM_EFI).

Signed-off-by: Cristian Ciocaltea 
---
 test/py/tests/test_efi_fit.py | 459 ++
 1 file changed, 459 insertions(+)
 create mode 100644 test/py/tests/test_efi_fit.py

diff --git a/test/py/tests/test_efi_fit.py b/test/py/tests/test_efi_fit.py
new file mode 100644
index 00..e1f0e42694
--- /dev/null
+++ b/test/py/tests/test_efi_fit.py
@@ -0,0 +1,459 @@
+# SPDX-License-Identifier: GPL-2.0
+# Copyright (c) 2019, Cristian Ciocaltea 
+#
+# Work based on:
+# - test_net.py
+# Copyright (c) 2016, NVIDIA CORPORATION. All rights reserved.
+# - test_fit.py
+# Copyright (c) 2013, Google Inc.
+#
+# Test launching UEFI binaries from FIT images.
+
+import os.path
+import pytest
+import u_boot_utils as util
+
+"""
+Note: This test relies on boardenv_* containing configuration values to define
+which network environment is available for testing. Without this, the parts
+that rely on network will be automatically skipped.
+
+For example:
+
+# Boolean indicating whether the Ethernet device is attached to USB, and hence
+# USB enumeration needs to be performed prior to network tests.
+# This variable may be omitted if its value is False.
+env__net_uses_usb = False
+
+# Boolean indicating whether the Ethernet device is attached to PCI, and hence
+# PCI enumeration needs to be performed prior to network tests.
+# This variable may be omitted if its value is False.
+env__net_uses_pci = True
+
+# True if a DHCP server is attached to the network, and should be tested.
+# If DHCP testing is not possible or desired, this variable may be omitted or
+# set to False.
+env__net_dhcp_server = True
+
+# A list of environment variables that should be set in order to configure a
+# static IP. If solely relying on DHCP, this variable may be omitted or set to
+# an empty list.
+env__net_static_env_vars = [
+('ipaddr', '10.0.0.100'),
+('netmask', '255.255.255.0'),
+('serverip', '10.0.0.1'),
+]
+
+# Details regarding a file that may be read from a TFTP server. This variable
+# may be omitted or set to None if TFTP testing is not possible or desired.
+# Additionally, when the 'size' is not available, the file will be generated
+# automatically in the TFTP root directory, as specified by the 'dn' field.
+env__efi_fit_tftp_file = {
+'fn': 'test-efi-fit.img',   # File path relative to TFTP root
+'size': 3831,   # File size
+'crc32': '9fa3f79c',# Checksum using CRC-32 algorithm, optional
+'addr': '$kernel_addr_r',   # Loading address, optional
+'dn': 'tftp/root/dir',  # TFTP root directory path, optional
+}
+"""
+
+# Define the parametrized ITS data to be used for FIT images generation.
+its_data = '''
+/dts-v1/;
+
+/ {
+description = "EFI image with FDT blob";
+#address-cells = <1>;
+
+images {
+efi {
+description = "Test EFI";
+data = /incbin/("%(efi-bin)s");
+type = "%(kernel-type)s";
+arch = "%(sys-arch)s";
+os = "efi";
+compression = "%(efi-comp)s";
+load = <0x0>;
+entry = <0x0>;
+};
+fdt {
+description = "Test FDT";
+data = /incbin/("%(fdt-bin)s");
+type = "flat_dt";
+arch = "%(sys-arch)s";
+compression = "%(fdt-comp)s";
+};
+};
+
+configurations {
+default = "config-efi-fdt";
+config-efi-fdt {
+description = "EFI FIT w/ FDT";
+kernel = "efi";
+fdt = "fdt";
+};
+config-efi-nofdt {
+description = "EFI FIT w/o FDT";
+kernel = "efi";
+};
+};
+};
+'''
+
+# Define the parametrized FDT data to be used for DTB images generation.
+fdt_data = '''
+/dts-v1/;
+
+/ {
+#address-cells = <1>;
+#size-cells = <0>;
+
+model = "%(sys-arch)s %(fdt_type)s EFI FIT Boot Test";
+compatible = "%(sys-arch)s";
+
+reset@0 {
+compatible = "%(sys-arch)s,reset";
+reg = <0>;
+};
+};
+'''
+
+@pytest.mark.buildconfigspec('bootm_efi')
+@pytest.mark.buildconfigspec('cmd_bootefi_hello_compile')
+@pytest.mark.buildconfigspec('fit')
+@pytest.mark.notbuildconfigspec('generate_acpi_table')
+@pytest.mark.requiredtool('dtc')
+def test_efi_fit_launch(u_boot_console):
+"""Test handling of UEFI binaries inside FIT images.
+
+The tests are trying to launch U-Boot's helloworld.efi embedded into
+FIT images, in uncompressed or gzip compressed format.
+
+Additionally, a sample FDT blob is created and embedded 

[PATCH v4 4/5] doc: uefi.rst: Document launching UEFI binaries from FIT images

2019-12-24 Thread Cristian Ciocaltea
This patch adds a new section "Launching a UEFI binary from a FIT image"
documenting the usage of the CONFIG_BOOTM_EFI extension to bootm command
that offers a verified boot alternative for UEFI binaries such as GRUB2.

Signed-off-by: Cristian Ciocaltea 
Reviewed-by: Heinrich Schuchardt 
---
 doc/uefi/uefi.rst | 34 ++
 1 file changed, 34 insertions(+)

diff --git a/doc/uefi/uefi.rst b/doc/uefi/uefi.rst
index db942df694..a8fd886d6b 100644
--- a/doc/uefi/uefi.rst
+++ b/doc/uefi/uefi.rst
@@ -63,6 +63,40 @@ The environment variable 'bootargs' is passed as load 
options in the UEFI system
 table. The Linux kernel EFI stub uses the load options as command line
 arguments.
 
+Launching a UEFI binary from a FIT image
+
+
+A signed FIT image can be used to securely boot a UEFI image via the
+bootm command. This feature is available if U-Boot is configured with::
+
+CONFIG_BOOTM_EFI=y
+
+A sample configuration is provided as file doc/uImage.FIT/uefi.its.
+
+Below you find the output of an example session starting GRUB::
+
+=> load mmc 0:1 ${kernel_addr_r} image.fit
+4620426 bytes read in 83 ms (53.1 MiB/s)
+=> bootm ${kernel_addr_r}#config-grub-nofdt
+## Loading kernel from FIT Image at 4040 ...
+   Using 'config-grub-nofdt' configuration
+   Verifying Hash Integrity ... sha256,rsa2048:dev+ OK
+   Trying 'efi-grub' kernel subimage
+ Description:  GRUB EFI Firmware
+ Created:  2019-11-20   8:18:16 UTC
+ Type: Kernel Image (no loading done)
+ Compression:  uncompressed
+ Data Start:   0x404000d0
+ Data Size:450560 Bytes = 440 KiB
+ Hash algo:sha256
+ Hash value:   
4dbee00021112df618f58b3f7cf5e1595533d543094064b9ce991e8b054a9eec
+   Verifying Hash Integrity ... sha256+ OK
+   XIP Kernel Image (no loading done)
+## Transferring control to EFI (at address 404000d0) ...
+Welcome to GRUB!
+
+See doc/uImage.FIT/howto.txt for an introduction to FIT images.
+
 Executing the boot manager
 ~~
 
-- 
2.17.1



[PATCH v4 3/5] doc: Add sample uefi.its image description file

2019-12-24 Thread Cristian Ciocaltea
This patch adds an example FIT image description file demonstrating
the usage of bootm command to securely launch UEFI binaries.

Signed-off-by: Cristian Ciocaltea 
Reviewed-by: Heinrich Schuchardt 
---
 doc/uImage.FIT/uefi.its | 67 +
 1 file changed, 67 insertions(+)
 create mode 100644 doc/uImage.FIT/uefi.its

diff --git a/doc/uImage.FIT/uefi.its b/doc/uImage.FIT/uefi.its
new file mode 100644
index 00..378ca4ed8d
--- /dev/null
+++ b/doc/uImage.FIT/uefi.its
@@ -0,0 +1,67 @@
+/*
+ * Example FIT image description file demonstrating the usage of the
+ * bootm command to launch UEFI binaries.
+ *
+ * Two boot configurations are available to enable booting GRUB2 on QEMU,
+ * the former uses a FDT blob contained in the FIT image, while the later
+ * relies on the FDT provided by the board emulator.
+ */
+
+/dts-v1/;
+
+/ {
+   description = "GRUB2 EFI and QEMU FDT blob";
+   #address-cells = <1>;
+
+   images {
+   efi-grub {
+   description = "GRUB EFI Firmware";
+   data = /incbin/("bootarm.efi");
+   type = "kernel_noload";
+   arch = "arm";
+   os = "efi";
+   compression = "none";
+   load = <0x0>;
+   entry = <0x0>;
+   hash-1 {
+   algo = "sha256";
+   };
+   };
+
+   fdt-qemu {
+   description = "QEMU DTB";
+   data = /incbin/("qemu-arm.dtb");
+   type = "flat_dt";
+   arch = "arm";
+   compression = "none";
+   hash-1 {
+   algo = "sha256";
+   };
+   };
+   };
+
+   configurations {
+   default = "config-grub-fdt";
+
+   config-grub-fdt {
+   description = "GRUB EFI Boot w/ FDT";
+   kernel = "efi-grub";
+   fdt = "fdt-qemu";
+   signature-1 {
+   algo = "sha256,rsa2048";
+   key-name-hint = "dev";
+   sign-images = "kernel", "fdt";
+   };
+   };
+
+   config-grub-nofdt {
+   description = "GRUB EFI Boot w/o FDT";
+   kernel = "efi-grub";
+   signature-1 {
+   algo = "sha256,rsa2048";
+   key-name-hint = "dev";
+   sign-images = "kernel";
+   };
+   };
+   };
+};
-- 
2.17.1



[PATCH v4 2/5] bootm: Add a bootm command for type IH_OS_EFI

2019-12-24 Thread Cristian Ciocaltea
Add support for booting EFI binaries contained in FIT images.
A typical usage scenario is chain-loading GRUB2 in a verified
boot environment.

Signed-off-by: Cristian Ciocaltea 
Reviewed-by: Heinrich Schuchardt 
---
 cmd/Kconfig   |  7 ++
 common/bootm_os.c | 56 +++
 2 files changed, 63 insertions(+)

diff --git a/cmd/Kconfig b/cmd/Kconfig
index 1e4cf146c5..87f2335a3c 100644
--- a/cmd/Kconfig
+++ b/cmd/Kconfig
@@ -263,6 +263,13 @@ config CMD_BOOTI
help
  Boot an AArch64 Linux Kernel image from memory.
 
+config BOOTM_EFI
+   bool "Support booting EFI OS images"
+   depends on CMD_BOOTEFI
+   default y
+   help
+ Support booting EFI images via the bootm command.
+
 config BOOTM_LINUX
bool "Support booting Linux OS images"
depends on CMD_BOOTM || CMD_BOOTZ || CMD_BOOTI
diff --git a/common/bootm_os.c b/common/bootm_os.c
index d89ddc32b0..1d58462509 100644
--- a/common/bootm_os.c
+++ b/common/bootm_os.c
@@ -7,10 +7,12 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 
@@ -498,6 +500,57 @@ static int do_bootm_tee(int flag, int argc, char * const 
argv[],
 }
 #endif
 
+#ifdef CONFIG_BOOTM_EFI
+static int do_bootm_efi(int flag, int argc, char * const argv[],
+   bootm_headers_t *images)
+{
+   int ret;
+   efi_status_t efi_ret;
+   void *image_buf;
+
+   if (flag != BOOTM_STATE_OS_GO)
+   return 0;
+
+   /* Locate FDT, if provided */
+   ret = bootm_find_images(flag, argc, argv);
+   if (ret)
+   return ret;
+
+   /* Initialize EFI drivers */
+   efi_ret = efi_init_obj_list();
+   if (efi_ret != EFI_SUCCESS) {
+   printf("## Failed to initialize UEFI sub-system: r = %lu\n",
+  efi_ret & ~EFI_ERROR_MASK);
+   return 1;
+   }
+
+   /* Install device tree */
+   efi_ret = efi_install_fdt(images->ft_len
+ ? images->ft_addr : EFI_FDT_USE_INTERNAL);
+   if (efi_ret != EFI_SUCCESS) {
+   printf("## Failed to install device tree: r = %lu\n",
+  efi_ret & ~EFI_ERROR_MASK);
+   return 1;
+   }
+
+   /* Run EFI image */
+   printf("## Transferring control to EFI (at address %08lx) ...\n",
+  images->ep);
+   bootstage_mark(BOOTSTAGE_ID_RUN_OS);
+
+   image_buf = map_sysmem(images->ep, images->os.image_len);
+
+   efi_ret = efi_run_image(image_buf, images->os.image_len);
+   if (efi_ret != EFI_SUCCESS) {
+   printf("## Failed to run EFI image: r = %lu\n",
+  efi_ret & ~EFI_ERROR_MASK);
+   return 1;
+   }
+
+   return 0;
+}
+#endif
+
 static boot_os_fn *boot_os[] = {
[IH_OS_U_BOOT] = do_bootm_standalone,
 #ifdef CONFIG_BOOTM_LINUX
@@ -534,6 +587,9 @@ static boot_os_fn *boot_os[] = {
 #ifdef CONFIG_BOOTM_OPTEE
[IH_OS_TEE] = do_bootm_tee,
 #endif
+#ifdef CONFIG_BOOTM_EFI
+   [IH_OS_EFI] = do_bootm_efi,
+#endif
 };
 
 /* Allow for arch specific config before we boot */
-- 
2.17.1



[PATCH v4 1/5] image: Add IH_OS_EFI for EFI chain-load boot

2019-12-24 Thread Cristian Ciocaltea
Add a new OS type to be used for chain-loading an EFI compatible
firmware or boot loader like GRUB2, possibly in a verified boot
scenario.

Bellow is sample ITS file that generates a FIT image supporting
secure boot. Please note the presence of 'os = "efi";' line, which
identifies the currently introduced OS type:

/ {
#address-cells = <1>;

images {
efi-grub {
description = "GRUB EFI";
data = /incbin/("bootarm.efi");
type = "kernel_noload";
arch = "arm";
os = "efi";
compression = "none";
load = <0x0>;
entry = <0x0>;
hash-1 {
algo = "sha256";
};
};
};

configurations {
default = "config-grub";
config-grub {
kernel = "efi-grub";
signature-1 {
    algo = "sha256,rsa2048";
sign-images = "kernel";
};
};
};
};

Signed-off-by: Cristian Ciocaltea 
Reviewed-by: Heinrich Schuchardt 
---
 common/image-fit.c | 3 ++-
 common/image.c | 1 +
 include/image.h| 1 +
 3 files changed, 4 insertions(+), 1 deletion(-)

diff --git a/common/image-fit.c b/common/image-fit.c
index c52f945120..231612ff5f 100644
--- a/common/image-fit.c
+++ b/common/image-fit.c
@@ -1926,7 +1926,8 @@ int fit_image_load(bootm_headers_t *images, ulong addr,
image_type == IH_TYPE_FPGA ||
fit_image_check_os(fit, noffset, IH_OS_LINUX) ||
fit_image_check_os(fit, noffset, IH_OS_U_BOOT) ||
-   fit_image_check_os(fit, noffset, IH_OS_OPENRTOS);
+   fit_image_check_os(fit, noffset, IH_OS_OPENRTOS) ||
+   fit_image_check_os(fit, noffset, IH_OS_EFI);
 
/*
 * If either of the checks fail, we should report an error, but
diff --git a/common/image.c b/common/image.c
index eb626dcac9..75d5dd944f 100644
--- a/common/image.c
+++ b/common/image.c
@@ -137,6 +137,7 @@ static const table_entry_t uimage_os[] = {
{   IH_OS_OPENRTOS, "openrtos", "OpenRTOS", },
 #endif
{   IH_OS_OPENSBI,  "opensbi",  "RISC-V OpenSBI",   },
+   {   IH_OS_EFI,  "efi",  "EFI Firmware" },
 
{   -1, "", "", },
 };
diff --git a/include/image.h b/include/image.h
index f4d2aaf53e..4a280b78e7 100644
--- a/include/image.h
+++ b/include/image.h
@@ -157,6 +157,7 @@ enum {
IH_OS_ARM_TRUSTED_FIRMWARE, /* ARM Trusted Firmware */
IH_OS_TEE,  /* Trusted Execution Environment */
IH_OS_OPENSBI,  /* RISC-V OpenSBI */
+   IH_OS_EFI,  /* EFI Firmware (e.g. GRUB2) */
 
IH_OS_COUNT,
 };
-- 
2.17.1



[PATCH v4 0/5] Add support for booting EFI FIT images

2019-12-24 Thread Cristian Ciocaltea
Currently the only way to run an EFI binary like GRUB2 is via the
'bootefi' command, which cannot be used in a verified boot scenario.

The obvious solution to this limitation is to add support for
booting FIT images containing those EFI binaries.

The implementation relies on a new image type - IH_OS_EFI - which
can be created by using 'os = "efi"' inside an ITS file:

/ {
#address-cells = <1>;

images {
efi-grub {
description = "GRUB EFI";
data = /incbin/("bootarm.efi");
type = "kernel_noload";
arch = "arm";
os = "efi";
compression = "none";
load = <0x0>;
entry = <0x0>;
hash-1 {
algo = "sha256";
};
};
};

configurations {
default = "config-grub";
config-grub {
kernel = "efi-grub";
signature-1 {
algo = "sha256,rsa2048";
sign-images = "kernel";
};
};
};
};

The bootm command has been extended to handle the IH_OS_EFI images.
To enable this feature, a new configuration option has been added:
BOOTM_EFI

I tested the solution using the 'qemu_arm' board:

=> load scsi 0:1 ${kernel_addr_r} efi-image.fit
=> bootm ${kernel_addr_r}#config-grub

Changes in v4:
* Extend the python test to also run on real hardware, currently
  tested on qemu_arm

Changes in v3:
* Rebase patches on Heinrich Schuchardt's patch series v3:
   efi_loader: prepare for FIT images
   https://lists.denx.de/pipermail/u-boot/2019-December/393677.html
   This fixes implicitly the sandbox issue 'phys_to_virt: Cannot map
   sandbox address' since efi_install_fdt() is now expecting a pointer
   to addressable memory instead of a physical address.
* Get rid of 'EFI/BOOT/' prefix used in ITS samples
* Add a python test to verify the implementation in sandbox environment

Changes in v2:
* Rebase patches on Heinrich Schuchardt's patch series:
   efi_loader: prepare for FIT images
   https://lists.denx.de/pipermail/u-boot/2019-December/393192.html
* Add sample configuration: doc/uImage.FIT/uefi.its
* Update uefi documentation: doc/uefi/uefi.rst

Cristian Ciocaltea (5):
  image: Add IH_OS_EFI for EFI chain-load boot
  bootm: Add a bootm command for type IH_OS_EFI
  doc: Add sample uefi.its image description file
  doc: uefi.rst: Document launching UEFI binaries from FIT images
  test/py: Create a test for launching UEFI binaries from FIT images

 cmd/Kconfig   |   7 +
 common/bootm_os.c |  56 +
 common/image-fit.c|   3 +-
 common/image.c|   1 +
 doc/uImage.FIT/uefi.its   |  67 +
 doc/uefi/uefi.rst |  34 +++
 include/image.h   |   1 +
 test/py/tests/test_efi_fit.py | 459 ++
 8 files changed, 627 insertions(+), 1 deletion(-)
 create mode 100644 doc/uImage.FIT/uefi.its
 create mode 100644 test/py/tests/test_efi_fit.py

-- 
2.17.1



[PATCH 1/1] test/py: Fix broken 'notbuildconfigspec' marker

2019-12-24 Thread Cristian Ciocaltea
Consider the following test sample:

@pytest.mark.buildconfigspec('fit')
@pytest.mark.notbuildconfigspec('generate_acpi_table')
def test_sample(u_boot_console):

Whatever the argument of the 'notbuildconfigspec' is,
the test ends up being skipped with the message:

('/uboot/test/py/conftest.py', 463,
 'Skipped: .config feature "fit" enabled')

Signed-off-by: Cristian Ciocaltea 
---
 test/py/conftest.py | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/test/py/conftest.py b/test/py/conftest.py
index bffee6b8a3..c7f361f7bf 100644
--- a/test/py/conftest.py
+++ b/test/py/conftest.py
@@ -457,7 +457,7 @@ def setup_buildconfigspec(item):
 option = options.args[0]
 if not ubconfig.buildconfig.get('config_' + option.lower(), None):
 pytest.skip('.config feature "%s" not enabled' % option.lower())
-for option in item.iter_markers('notbuildconfigspec'):
+for options in item.iter_markers('notbuildconfigspec'):
 option = options.args[0]
 if ubconfig.buildconfig.get('config_' + option.lower(), None):
 pytest.skip('.config feature "%s" enabled' % option.lower())
-- 
2.17.1



Re: [PATCH v3 5/5] test/py: Create a test for launching UEFI binaries from FIT images

2019-12-18 Thread Cristian Ciocaltea
On Wed, Dec 18, 2019 at 11:56:00AM +0100, Heinrich Schuchardt wrote:
> On 12/18/19 9:22 AM, Cristian Ciocaltea wrote:
> > > > +};
> > > > +};
> > > > +'''
> > > > +
> > > > +@pytest.mark.boardspec('sandbox')
> > > This test looks ok in principal. But why should we restrict it to the
> > > sandbox?
> > Let me see how this should work on real hardware, I'm going to test
> > on qemu for the moment.
> 
> Device trees cannot be used in conjunction with ACPI tables when booting
> via UEFI. Currently this concerns only x86 and x86_64 but Phytec is
> working on an arm64 board which shall provide an ACPI table. So you
> probably want to check CONFIG_GENERATE_ACPI_TABLE instead of the board
> type, e.g.
> 
> @pytest.mark.notbuildconfigspec('generate_acpi_table')

Thanks for the hint! 

For some strange reason, whatever I put in the 'notbuildconfigspec'
marker causes the test to be skipped:

[-] Section: test_efi_fit
TIME: NOW: 2019/12/18 17:33:14.976576
TIME: SINCE-PREV: 0:00:00.192132
TIME: SINCE-START: 0:00:00.192132
SKIPPED:
('[...]/uboot/test/py/conftest.py', 463, 'Skipped: .config feature "bootm_efi" 
enabled')

I don't really understand the connection to 'bootm_efi'. If I comment
out the 'bootm_efi' marker, the reported status becomes:

SKIPPED:
('[].../uboot/test/py/conftest.py', 463, 'Skipped: .config feature 
"cmd_bootefi_hello_compile" enabled')

So it seems 'notbuildconfigspec' gets its parameter from the first
active 'buildconfigspec' statement. This is my current test:

#@pytest.mark.buildconfigspec('bootm_efi')
@pytest.mark.buildconfigspec('cmd_bootefi_hello_compile')
#@pytest.mark.notbuildconfigspec('generate_acpi_table')
@pytest.mark.notbuildconfigspec('fake_item')
@pytest.mark.requiredtool('dtc')

> Best regards
> 
> Heinrich


Re: [PATCH v3 5/5] test/py: Create a test for launching UEFI binaries from FIT images

2019-12-18 Thread Cristian Ciocaltea
On Wed, Dec 18, 2019 at 11:06:48AM +0100, Heinrich Schuchardt wrote:
> On 12/18/19 9:22 AM, Cristian Ciocaltea wrote:
> > On Tue, Dec 17, 2019 at 10:08:31PM +0100, Heinrich Schuchardt wrote:
> > > On 12/17/19 8:47 AM, Cristian Ciocaltea wrote:
> > > > This test verifies the implementation of the 'bootm' extension that
> > > > handles UEFI binaries inside FIT images (enabled via CONFIG_BOOTM_EFI).
> > > > 
> > > > Signed-off-by: Cristian Ciocaltea 
> > > > ---
> > > >test/py/tests/test_efi_fit.py | 233 
> > > > ++
> > > >1 file changed, 233 insertions(+)
> > > >create mode 100644 test/py/tests/test_efi_fit.py
> > > > 
> > > > diff --git a/test/py/tests/test_efi_fit.py 
> > > > b/test/py/tests/test_efi_fit.py
> > > > new file mode 100644
> > > > index 00..52b415b198
> > > > --- /dev/null
> > > > +++ b/test/py/tests/test_efi_fit.py
> > > > @@ -0,0 +1,233 @@
> > > > +# SPDX-License-Identifier: GPL-2.0
> > > > +# Copyright (c) 2019, Cristian Ciocaltea 
> > > > +
> > > > +# Test launching UEFI binaries from FIT images.
> > > > +
> > > > +import os
> > > > +import pytest
> > > > +import u_boot_utils as util
> > > > +
> > > > +# Define the parametrized ITS data to be used for FIT image generation.
> > > > +its_data = '''
> > > > +/dts-v1/;
> > > > +
> > > > +/ {
> > > > +description = "EFI image with FDT blob";
> > > > +#address-cells = <1>;
> > > > +
> > > > +images {
> > > > +efi {
> > > > +description = "Sandbox EFI";
> > > > +data = /incbin/("%(efi-bin)s");
> > > > +type = "%(kernel-type)s";
> > > > +arch = "sandbox";
> > > > +os = "efi";
> > > > +compression = "%(efi-comp)s";
> > > > +load = <0x0>;
> > > > +entry = <0x0>;
> > > > +};
> > > > +fdt {
> > > > +description = "Sandbox FDT";
> > > > +data = /incbin/("%(fdt-bin)s");
> > > > +type = "flat_dt";
> > > > +arch = "sandbox";
> > > > +compression = "%(fdt-comp)s";
> > > > +};
> > > > +};
> > > > +
> > > > +configurations {
> > > > +default = "config-efi-fdt";
> > > > +config-efi-fdt {
> > > > +description = "EFI FIT w/ FDT";
> > > > +kernel = "efi";
> > > > +fdt = "fdt";
> > > > +};
> > > > +config-efi-nofdt {
> > > > +description = "EFI FIT w/o FDT";
> > > > +kernel = "efi";
> > > > +};
> > > > +};
> > > > +};
> > > > +'''
> > > > +
> > > > +# Define the parametrized FDT data.
> > > > +fdt_data = '''
> > > > +/dts-v1/;
> > > > +
> > > > +/ {
> > > > +model = "Sandbox %(fdt_type) EFI FIT Boot Test ";
> > > > +compatible = "sandbox";
> > > > +
> > > > +reset@0 {
> > > > +compatible = "sandbox,reset";
> > > 
> > > This produces a warning:
> > > 
> > > +dtc ./test-efi-fit-sandbox-internal.dts -O dtb -o
> > > ./test-efi-fit-sandbox-internal.dtb
> > > ./test-efi-fit-sandbox-internal.dts:8.13-10.7: Warning
> > > (unit_address_vs_reg): /reset@0: node has a unit name, but no reg property
> > 
> > A similar sample is also used by test_fit.py and test_vboot.py, which
> > expose the same warning, that's why I initially ignored it.
> > If acceptable, I can suppress it via '-W no-unit_address_vs_reg'.
> 
> reset@0 includes a unit-address. So a reg property is expected. How about:
> 
> /dts-v1/;
> 
> / {
>   #address-cells = <1>;
>   #size-cells = <0>;
> 
>   model = "Sandbox %(fdt_type) EFI FIT Boot Test ";
>   compatible = "sandbox";
> 
>   

Re: [PATCH v3 2/5] bootm: Add a bootm command for type IH_OS_EFI

2019-12-18 Thread Cristian Ciocaltea
On Tue, Dec 17, 2019 at 09:34:44PM +0100, Heinrich Schuchardt wrote:
> On 12/17/19 8:46 AM, Cristian Ciocaltea wrote:
> > Add support for booting EFI binaries contained in FIT images.
> > A typical usage scenario is chain-loading GRUB2 in a verified
> > boot environment.
> > 
> > Signed-off-by: Cristian Ciocaltea 
> 
> You missed the current changes in common/bootm_os.c. I will rebase the
> patch.

Right, sorry. I have already rebased the patch and I will resubmit it
as soon as I finalize the changes on pytest.

Thanks!

> Reviewed-by: Heinrich Schuchardt 


Re: [PATCH v3 5/5] test/py: Create a test for launching UEFI binaries from FIT images

2019-12-18 Thread Cristian Ciocaltea
On Tue, Dec 17, 2019 at 10:08:31PM +0100, Heinrich Schuchardt wrote:
> On 12/17/19 8:47 AM, Cristian Ciocaltea wrote:
> > This test verifies the implementation of the 'bootm' extension that
> > handles UEFI binaries inside FIT images (enabled via CONFIG_BOOTM_EFI).
> > 
> > Signed-off-by: Cristian Ciocaltea 
> > ---
> >   test/py/tests/test_efi_fit.py | 233 ++
> >   1 file changed, 233 insertions(+)
> >   create mode 100644 test/py/tests/test_efi_fit.py
> > 
> > diff --git a/test/py/tests/test_efi_fit.py b/test/py/tests/test_efi_fit.py
> > new file mode 100644
> > index 00..52b415b198
> > --- /dev/null
> > +++ b/test/py/tests/test_efi_fit.py
> > @@ -0,0 +1,233 @@
> > +# SPDX-License-Identifier: GPL-2.0
> > +# Copyright (c) 2019, Cristian Ciocaltea 
> > +
> > +# Test launching UEFI binaries from FIT images.
> > +
> > +import os
> > +import pytest
> > +import u_boot_utils as util
> > +
> > +# Define the parametrized ITS data to be used for FIT image generation.
> > +its_data = '''
> > +/dts-v1/;
> > +
> > +/ {
> > +description = "EFI image with FDT blob";
> > +#address-cells = <1>;
> > +
> > +images {
> > +efi {
> > +description = "Sandbox EFI";
> > +data = /incbin/("%(efi-bin)s");
> > +type = "%(kernel-type)s";
> > +arch = "sandbox";
> > +os = "efi";
> > +compression = "%(efi-comp)s";
> > +load = <0x0>;
> > +entry = <0x0>;
> > +};
> > +fdt {
> > +description = "Sandbox FDT";
> > +data = /incbin/("%(fdt-bin)s");
> > +type = "flat_dt";
> > +arch = "sandbox";
> > +compression = "%(fdt-comp)s";
> > +};
> > +};
> > +
> > +configurations {
> > +default = "config-efi-fdt";
> > +config-efi-fdt {
> > +description = "EFI FIT w/ FDT";
> > +kernel = "efi";
> > +fdt = "fdt";
> > +};
> > +config-efi-nofdt {
> > +description = "EFI FIT w/o FDT";
> > +kernel = "efi";
> > +};
> > +};
> > +};
> > +'''
> > +
> > +# Define the parametrized FDT data.
> > +fdt_data = '''
> > +/dts-v1/;
> > +
> > +/ {
> > +model = "Sandbox %(fdt_type) EFI FIT Boot Test ";
> > +compatible = "sandbox";
> > +
> > +reset@0 {
> > +compatible = "sandbox,reset";
> 
> This produces a warning:
> 
> +dtc ./test-efi-fit-sandbox-internal.dts -O dtb -o
> ./test-efi-fit-sandbox-internal.dtb
> ./test-efi-fit-sandbox-internal.dts:8.13-10.7: Warning
> (unit_address_vs_reg): /reset@0: node has a unit name, but no reg property

A similar sample is also used by test_fit.py and test_vboot.py, which
expose the same warning, that's why I initially ignored it.
If acceptable, I can suppress it via '-W no-unit_address_vs_reg'.

> > +};
> > +};
> > +'''
> > +
> > +@pytest.mark.boardspec('sandbox')
> 
> This test looks ok in principal. But why should we restrict it to the
> sandbox?

Let me see how this should work on real hardware, I'm going to test
on qemu for the moment.

> Best regards
> 
> Heinrich
> 
> > +@pytest.mark.buildconfigspec('bootm_efi')
> > +@pytest.mark.buildconfigspec('cmd_bootefi_hello_compile')
> > +@pytest.mark.requiredtool('dtc')
> > +def test_efi_fit(u_boot_console):
> > +"""Test handling of UEFI binaries inside FIT images.
> > +
> > +The tests are trying to launch U-Boot's helloworld.efi embedded into
> > +FIT images, in uncompressed or gzip compressed format.
> > +
> > +Additionally, a sample FDT blob is created and embedded into the above
> > +mentioned FIT images, in uncompressed or gzip compressed format.
> > +
> > +The following test cases are currently defined and enabled:
> > +- Launch uncompressed FIT EFI & FIT FDT
> > +- Launch compressed FIT EFI & FIT FDT
> > +- Launch uncompressed FIT EFI & internal FDT
> > +- Launch compressed FIT EFI & internal FDT
> > +"""
> > +
> > +def make_fpath(fname):
> 

[PATCH v3 5/5] test/py: Create a test for launching UEFI binaries from FIT images

2019-12-16 Thread Cristian Ciocaltea
This test verifies the implementation of the 'bootm' extension that
handles UEFI binaries inside FIT images (enabled via CONFIG_BOOTM_EFI).

Signed-off-by: Cristian Ciocaltea 
---
 test/py/tests/test_efi_fit.py | 233 ++
 1 file changed, 233 insertions(+)
 create mode 100644 test/py/tests/test_efi_fit.py

diff --git a/test/py/tests/test_efi_fit.py b/test/py/tests/test_efi_fit.py
new file mode 100644
index 00..52b415b198
--- /dev/null
+++ b/test/py/tests/test_efi_fit.py
@@ -0,0 +1,233 @@
+# SPDX-License-Identifier: GPL-2.0
+# Copyright (c) 2019, Cristian Ciocaltea 
+
+# Test launching UEFI binaries from FIT images.
+
+import os
+import pytest
+import u_boot_utils as util
+
+# Define the parametrized ITS data to be used for FIT image generation.
+its_data = '''
+/dts-v1/;
+
+/ {
+description = "EFI image with FDT blob";
+#address-cells = <1>;
+
+images {
+efi {
+description = "Sandbox EFI";
+data = /incbin/("%(efi-bin)s");
+type = "%(kernel-type)s";
+arch = "sandbox";
+os = "efi";
+compression = "%(efi-comp)s";
+load = <0x0>;
+entry = <0x0>;
+};
+fdt {
+description = "Sandbox FDT";
+data = /incbin/("%(fdt-bin)s");
+type = "flat_dt";
+arch = "sandbox";
+compression = "%(fdt-comp)s";
+};
+};
+
+configurations {
+default = "config-efi-fdt";
+config-efi-fdt {
+description = "EFI FIT w/ FDT";
+kernel = "efi";
+fdt = "fdt";
+};
+config-efi-nofdt {
+description = "EFI FIT w/o FDT";
+kernel = "efi";
+};
+};
+};
+'''
+
+# Define the parametrized FDT data.
+fdt_data = '''
+/dts-v1/;
+
+/ {
+model = "Sandbox %(fdt_type) EFI FIT Boot Test ";
+compatible = "sandbox";
+
+reset@0 {
+compatible = "sandbox,reset";
+};
+};
+'''
+
+@pytest.mark.boardspec('sandbox')
+@pytest.mark.buildconfigspec('bootm_efi')
+@pytest.mark.buildconfigspec('cmd_bootefi_hello_compile')
+@pytest.mark.requiredtool('dtc')
+def test_efi_fit(u_boot_console):
+"""Test handling of UEFI binaries inside FIT images.
+
+The tests are trying to launch U-Boot's helloworld.efi embedded into
+FIT images, in uncompressed or gzip compressed format.
+
+Additionally, a sample FDT blob is created and embedded into the above
+mentioned FIT images, in uncompressed or gzip compressed format.
+
+The following test cases are currently defined and enabled:
+- Launch uncompressed FIT EFI & FIT FDT
+- Launch compressed FIT EFI & FIT FDT
+- Launch uncompressed FIT EFI & internal FDT
+- Launch compressed FIT EFI & internal FDT
+"""
+
+def make_fpath(fname):
+"""Compute the path of a given (temporary) file.
+
+Args:
+fname: The name of a file within U-Boot build dir.
+Return:
+The computed file path.
+"""
+return os.path.join(u_boot_console.config.build_dir, fname)
+
+def make_efi(fname, comp):
+"""Create an UEFI binary.
+
+This simply copies lib/efi_loader/helloworld.efi into U-Boot
+build dir and, optionally, compresses the file using gzip.
+
+Args:
+fname: The target file name within U-Boot build dir.
+comp: Flag to enable gzip compression.
+Return:
+The path of the created file.
+"""
+bin_path = make_fpath(fname)
+os.system('cp %s %s' % (make_fpath('lib/efi_loader/helloworld.efi'), 
bin_path))
+if comp:
+util.run_and_log(u_boot_console, ['gzip', '-f', bin_path])
+bin_path += '.gz'
+return bin_path
+
+def make_dtb(fdt_type, comp):
+"""Create a sample DTB file.
+
+Creates a DTS file and compiles it to a DTB.
+
+Args:
+fdt_type: The type of the FDT, i.e. internal, user.
+comp: Flag to enable gzip compression.
+Returns:
+The path of the created file.
+"""
+dts = make_fpath('test-efi-fit-sandbox-%s.dts' % fdt_type)
+dtb = make_fpath('test-efi-fit-sandbox-%s.dtb' % fdt_type)
+with open(dts, 'w') as fd:
+fd.write(fdt_data)
+util.run_and_log(u_boot_console, ['dtc', dts, '-O', 'dtb', '-o', dtb])
+if comp:
+util.run_and_log(u_boot_console, ['gzip', '-f', dtb])
+dtb += '.gz'
+return dtb
+
+def make_fit(efi_comp, fdt_comp):
+"

[PATCH v3 4/5] doc: uefi.rst: Document launching UEFI binaries from FIT images

2019-12-16 Thread Cristian Ciocaltea
This patch adds a new section "Launching a UEFI binary from a FIT image"
documenting the usage of the CONFIG_BOOTM_EFI extension to bootm command
that offers a verified boot alternative for UEFI binaries such as GRUB2.

Signed-off-by: Cristian Ciocaltea 
Reviewed-by: Heinrich Schuchardt 
---
 doc/uefi/uefi.rst | 34 ++
 1 file changed, 34 insertions(+)

diff --git a/doc/uefi/uefi.rst b/doc/uefi/uefi.rst
index db942df694..a8fd886d6b 100644
--- a/doc/uefi/uefi.rst
+++ b/doc/uefi/uefi.rst
@@ -63,6 +63,40 @@ The environment variable 'bootargs' is passed as load 
options in the UEFI system
 table. The Linux kernel EFI stub uses the load options as command line
 arguments.
 
+Launching a UEFI binary from a FIT image
+
+
+A signed FIT image can be used to securely boot a UEFI image via the
+bootm command. This feature is available if U-Boot is configured with::
+
+CONFIG_BOOTM_EFI=y
+
+A sample configuration is provided as file doc/uImage.FIT/uefi.its.
+
+Below you find the output of an example session starting GRUB::
+
+=> load mmc 0:1 ${kernel_addr_r} image.fit
+4620426 bytes read in 83 ms (53.1 MiB/s)
+=> bootm ${kernel_addr_r}#config-grub-nofdt
+## Loading kernel from FIT Image at 4040 ...
+   Using 'config-grub-nofdt' configuration
+   Verifying Hash Integrity ... sha256,rsa2048:dev+ OK
+   Trying 'efi-grub' kernel subimage
+ Description:  GRUB EFI Firmware
+ Created:  2019-11-20   8:18:16 UTC
+ Type: Kernel Image (no loading done)
+ Compression:  uncompressed
+ Data Start:   0x404000d0
+ Data Size:450560 Bytes = 440 KiB
+ Hash algo:sha256
+ Hash value:   
4dbee00021112df618f58b3f7cf5e1595533d543094064b9ce991e8b054a9eec
+   Verifying Hash Integrity ... sha256+ OK
+   XIP Kernel Image (no loading done)
+## Transferring control to EFI (at address 404000d0) ...
+Welcome to GRUB!
+
+See doc/uImage.FIT/howto.txt for an introduction to FIT images.
+
 Executing the boot manager
 ~~
 
-- 
2.17.1



[PATCH v3 0/5] Add support for booting EFI FIT images

2019-12-16 Thread Cristian Ciocaltea
Currently the only way to run an EFI binary like GRUB2 is via the
'bootefi' command, which cannot be used in a verified boot scenario.

The obvious solution to this limitation is to add support for
booting FIT images containing those EFI binaries.

The implementation relies on a new image type - IH_OS_EFI - which
can be created by using 'os = "efi"' inside an ITS file:

/ {
#address-cells = <1>;

images {
efi-grub {
description = "GRUB EFI";
data = /incbin/("bootarm.efi");
type = "kernel_noload";
arch = "arm";
os = "efi";
compression = "none";
load = <0x0>;
entry = <0x0>;
hash-1 {
algo = "sha256";
};
};
};

configurations {
default = "config-grub";
config-grub {
kernel = "efi-grub";
signature-1 {
algo = "sha256,rsa2048";
sign-images = "kernel";
};
};
};
};

The bootm command has been extended to handle the IH_OS_EFI images.
To enable this feature, a new configuration option has been added:
BOOTM_EFI

I tested the solution using the 'qemu_arm' board:

=> load scsi 0:1 ${kernel_addr_r} efi-image.fit
=> bootm ${kernel_addr_r}#config-grub

Changes in v3:
* Rebase patches on Heinrich Schuchardt's patch series v3:
   efi_loader: prepare for FIT images
   https://lists.denx.de/pipermail/u-boot/2019-December/393677.html
   This fixes implicitly the sandbox issue 'phys_to_virt: Cannot map
   sandbox address' since efi_install_fdt() is now expecting a pointer
   to addressable memory instead of a physical address.
* Get rid of 'EFI/BOOT/' prefix used in ITS samples
* Add a python test to verify the implementation in sandbox environment

Changes in v2:
* Rebase patches on Heinrich Schuchardt's patch series:
   efi_loader: prepare for FIT images
   https://lists.denx.de/pipermail/u-boot/2019-December/393192.html
* Add sample configuration: doc/uImage.FIT/uefi.its
* Update uefi documentation: doc/uefi/uefi.rst

Cristian Ciocaltea (5):
  image: Add IH_OS_EFI for EFI chain-load boot
  bootm: Add a bootm command for type IH_OS_EFI
  doc: Add sample uefi.its image description file
  doc: uefi.rst: Document launching UEFI binaries from FIT images
  test/py: Create a test for launching UEFI binaries from FIT images

 cmd/Kconfig   |   7 +
 common/bootm_os.c |  56 
 common/image-fit.c|   3 +-
 common/image.c|   1 +
 doc/uImage.FIT/uefi.its   |  67 ++
 doc/uefi/uefi.rst |  34 +
 include/image.h   |   1 +
 test/py/tests/test_efi_fit.py | 233 ++
 8 files changed, 401 insertions(+), 1 deletion(-)
 create mode 100644 doc/uImage.FIT/uefi.its
 create mode 100644 test/py/tests/test_efi_fit.py

-- 
2.17.1



[PATCH v3 1/5] image: Add IH_OS_EFI for EFI chain-load boot

2019-12-16 Thread Cristian Ciocaltea
Add a new OS type to be used for chain-loading an EFI compatible
firmware or boot loader like GRUB2, possibly in a verified boot
scenario.

Bellow is sample ITS file that generates a FIT image supporting
secure boot. Please note the presence of 'os = "efi";' line, which
identifies the currently introduced OS type:

/ {
#address-cells = <1>;

images {
efi-grub {
description = "GRUB EFI";
data = /incbin/("bootarm.efi");
type = "kernel_noload";
arch = "arm";
os = "efi";
compression = "none";
load = <0x0>;
entry = <0x0>;
hash-1 {
algo = "sha256";
};
};
};

configurations {
default = "config-grub";
config-grub {
kernel = "efi-grub";
signature-1 {
    algo = "sha256,rsa2048";
sign-images = "kernel";
};
};
};
};

Signed-off-by: Cristian Ciocaltea 
---
 common/image-fit.c | 3 ++-
 common/image.c | 1 +
 include/image.h| 1 +
 3 files changed, 4 insertions(+), 1 deletion(-)

diff --git a/common/image-fit.c b/common/image-fit.c
index 5c63c769de..19e313bf41 100644
--- a/common/image-fit.c
+++ b/common/image-fit.c
@@ -1925,7 +1925,8 @@ int fit_image_load(bootm_headers_t *images, ulong addr,
image_type == IH_TYPE_FPGA ||
fit_image_check_os(fit, noffset, IH_OS_LINUX) ||
fit_image_check_os(fit, noffset, IH_OS_U_BOOT) ||
-   fit_image_check_os(fit, noffset, IH_OS_OPENRTOS);
+   fit_image_check_os(fit, noffset, IH_OS_OPENRTOS) ||
+   fit_image_check_os(fit, noffset, IH_OS_EFI);
 
/*
 * If either of the checks fail, we should report an error, but
diff --git a/common/image.c b/common/image.c
index f17fa40c49..2e0e2b0e7f 100644
--- a/common/image.c
+++ b/common/image.c
@@ -134,6 +134,7 @@ static const table_entry_t uimage_os[] = {
{   IH_OS_OPENRTOS, "openrtos", "OpenRTOS", },
 #endif
{   IH_OS_OPENSBI,  "opensbi",  "RISC-V OpenSBI",   },
+   {   IH_OS_EFI,  "efi",  "EFI Firmware" },
 
{   -1, "", "", },
 };
diff --git a/include/image.h b/include/image.h
index f4d2aaf53e..4a280b78e7 100644
--- a/include/image.h
+++ b/include/image.h
@@ -157,6 +157,7 @@ enum {
IH_OS_ARM_TRUSTED_FIRMWARE, /* ARM Trusted Firmware */
IH_OS_TEE,  /* Trusted Execution Environment */
IH_OS_OPENSBI,  /* RISC-V OpenSBI */
+   IH_OS_EFI,  /* EFI Firmware (e.g. GRUB2) */
 
IH_OS_COUNT,
 };
-- 
2.17.1



[PATCH v3 3/5] doc: Add sample uefi.its image description file

2019-12-16 Thread Cristian Ciocaltea
This patch adds an example FIT image description file demonstrating
the usage of bootm command to securely launch UEFI binaries.

Signed-off-by: Cristian Ciocaltea 
Reviewed-by: Heinrich Schuchardt 
---
 doc/uImage.FIT/uefi.its | 67 +
 1 file changed, 67 insertions(+)
 create mode 100644 doc/uImage.FIT/uefi.its

diff --git a/doc/uImage.FIT/uefi.its b/doc/uImage.FIT/uefi.its
new file mode 100644
index 00..378ca4ed8d
--- /dev/null
+++ b/doc/uImage.FIT/uefi.its
@@ -0,0 +1,67 @@
+/*
+ * Example FIT image description file demonstrating the usage of the
+ * bootm command to launch UEFI binaries.
+ *
+ * Two boot configurations are available to enable booting GRUB2 on QEMU,
+ * the former uses a FDT blob contained in the FIT image, while the later
+ * relies on the FDT provided by the board emulator.
+ */
+
+/dts-v1/;
+
+/ {
+   description = "GRUB2 EFI and QEMU FDT blob";
+   #address-cells = <1>;
+
+   images {
+   efi-grub {
+   description = "GRUB EFI Firmware";
+   data = /incbin/("bootarm.efi");
+   type = "kernel_noload";
+   arch = "arm";
+   os = "efi";
+   compression = "none";
+   load = <0x0>;
+   entry = <0x0>;
+   hash-1 {
+   algo = "sha256";
+   };
+   };
+
+   fdt-qemu {
+   description = "QEMU DTB";
+   data = /incbin/("qemu-arm.dtb");
+   type = "flat_dt";
+   arch = "arm";
+   compression = "none";
+   hash-1 {
+   algo = "sha256";
+   };
+   };
+   };
+
+   configurations {
+   default = "config-grub-fdt";
+
+   config-grub-fdt {
+   description = "GRUB EFI Boot w/ FDT";
+   kernel = "efi-grub";
+   fdt = "fdt-qemu";
+   signature-1 {
+   algo = "sha256,rsa2048";
+   key-name-hint = "dev";
+   sign-images = "kernel", "fdt";
+   };
+   };
+
+   config-grub-nofdt {
+   description = "GRUB EFI Boot w/o FDT";
+   kernel = "efi-grub";
+   signature-1 {
+   algo = "sha256,rsa2048";
+   key-name-hint = "dev";
+   sign-images = "kernel";
+   };
+   };
+   };
+};
-- 
2.17.1



[PATCH v3 2/5] bootm: Add a bootm command for type IH_OS_EFI

2019-12-16 Thread Cristian Ciocaltea
Add support for booting EFI binaries contained in FIT images.
A typical usage scenario is chain-loading GRUB2 in a verified
boot environment.

Signed-off-by: Cristian Ciocaltea 
---
 cmd/Kconfig   |  7 ++
 common/bootm_os.c | 56 +++
 2 files changed, 63 insertions(+)

diff --git a/cmd/Kconfig b/cmd/Kconfig
index cf982ff65e..39fa87082d 100644
--- a/cmd/Kconfig
+++ b/cmd/Kconfig
@@ -263,6 +263,13 @@ config CMD_BOOTI
help
  Boot an AArch64 Linux Kernel image from memory.
 
+config BOOTM_EFI
+   bool "Support booting EFI OS images"
+   depends on CMD_BOOTEFI
+   default y
+   help
+ Support booting EFI images via the bootm command.
+
 config BOOTM_LINUX
bool "Support booting Linux OS images"
depends on CMD_BOOTM || CMD_BOOTZ || CMD_BOOTI
diff --git a/common/bootm_os.c b/common/bootm_os.c
index 6fb7d658da..96792430da 100644
--- a/common/bootm_os.c
+++ b/common/bootm_os.c
@@ -6,10 +6,12 @@
 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 
@@ -462,6 +464,57 @@ static int do_bootm_tee(int flag, int argc, char * const 
argv[],
 }
 #endif
 
+#ifdef CONFIG_BOOTM_EFI
+static int do_bootm_efi(int flag, int argc, char * const argv[],
+   bootm_headers_t *images)
+{
+   int ret;
+   efi_status_t efi_ret;
+   void *image_buf;
+
+   if (flag != BOOTM_STATE_OS_GO)
+   return 0;
+
+   /* Locate FDT, if provided */
+   ret = bootm_find_images(flag, argc, argv);
+   if (ret)
+   return ret;
+
+   /* Initialize EFI drivers */
+   efi_ret = efi_init_obj_list();
+   if (efi_ret != EFI_SUCCESS) {
+   printf("## Failed to initialize UEFI sub-system: r = %lu\n",
+  efi_ret & ~EFI_ERROR_MASK);
+   return 1;
+   }
+
+   /* Install device tree */
+   efi_ret = efi_install_fdt(images->ft_len
+ ? images->ft_addr : EFI_FDT_USE_INTERNAL);
+   if (efi_ret != EFI_SUCCESS) {
+   printf("## Failed to install device tree: r = %lu\n",
+  efi_ret & ~EFI_ERROR_MASK);
+   return 1;
+   }
+
+   /* Run EFI image */
+   printf("## Transferring control to EFI (at address %08lx) ...\n",
+  images->ep);
+   bootstage_mark(BOOTSTAGE_ID_RUN_OS);
+
+   image_buf = map_sysmem(images->ep, images->os.image_len);
+
+   efi_ret = efi_run_image(image_buf, images->os.image_len);
+   if (efi_ret != EFI_SUCCESS) {
+   printf("## Failed to run EFI image: r = %lu\n",
+  efi_ret & ~EFI_ERROR_MASK);
+   return 1;
+   }
+
+   return 0;
+}
+#endif
+
 static boot_os_fn *boot_os[] = {
[IH_OS_U_BOOT] = do_bootm_standalone,
 #ifdef CONFIG_BOOTM_LINUX
@@ -498,6 +551,9 @@ static boot_os_fn *boot_os[] = {
 #ifdef CONFIG_BOOTM_OPTEE
[IH_OS_TEE] = do_bootm_tee,
 #endif
+#ifdef CONFIG_BOOTM_EFI
+   [IH_OS_EFI] = do_bootm_efi,
+#endif
 };
 
 /* Allow for arch specific config before we boot */
-- 
2.17.1



Re: [PATCH v2 2/4] bootm: Add a bootm command for type IH_OS_EFI

2019-12-11 Thread Cristian Ciocaltea
On Wed, Dec 11, 2019 at 10:57:48AM +0100, Heinrich Schuchardt wrote:
> On 12/11/19 9:54 AM, Cristian Ciocaltea wrote:
> > On Tue, Dec 10, 2019 at 08:32:17PM +0100, Heinrich Schuchardt wrote:
> > > On 12/10/19 9:56 AM, Cristian Ciocaltea wrote:
> > > > Add support for booting EFI binaries contained in FIT images.
> > > > A typical usage scenario is chain-loading GRUB2 in a verified
> > > > boot environment.
> > > > 
> > > > Signed-off-by: Cristian Ciocaltea
> > > 
> > > Reading through the code it looks good. What I really need to do is
> > > analyze the address usage on the sandbox. To me it is unclear if
> > > images->fdt_addr is a physical address or an address in the address
> > > space of the sandbox.
> > > 
> > > Did you test this on the sandbox? You can use
> > > lib/efi_loader/helloworld.efi as a binary and the 'host load hostfs'
> > > command for loading the FIT image.
> > 
> > I only tested on qemu, I've never used the sandbox, so it's a good
> > opportunity to give it a try.
> > 
> > > Shouldn't we add booting a UEFI FIT image to the Python test in
> > > test/py/tests/test_fit.py?
> > 
> > Unfortunately I'm not familiar with the testing framework (including
> > Python scripting), but I'll do my best to add such a test.
> > 
> > > doc/uImage.FIT/signature.txt describes that several properties of the
> > > RSA public key should be stored in the control device tree.
> > > Unfortunately no example is supplied in which format they should be
> > > stored. Could you send me an example, please.
> > > 
> > > I found the following
> > > 
> > > https://github.com/bn121rajesh/ipython-notebooks/blob/master/BehindTheScene/RSAPublicKeyParamsUBoot/rsa_public_key_params_uboot.ipynb
> > > 
> > > Is this an accurate description? Or how do you get the parameters from
> > > your RSA public key?
> > 
> > My test scenario involves the following steps:
> > 
> > 1. Create a public/private key pair
> > $ openssl genpkey -algorithm RSA -out ${DEV_KEY} \
> >  -pkeyopt rsa_keygen_bits:2048 -pkeyopt rsa_keygen_pubexp:65537
> > 
> > 2. Create a certificate containing the public key
> > $ openssl req -batch -new -x509 -key ${DEV_KEY} -out ${DEV_CRT}
> > 
> > 3. Dump QEMU virt board DTB
> > $ qemu-system-arm -nographic -M virt,dumpdtb=${BOARD_DTB} \
> >  -cpu cortex-a15 -smp 1 -m 512 -bios u-boot.bin [...]
> > 
> > 4. Create (unsigned) FIT image and put the public key into DTB, with
> > the 'required' property set, telling U-Boot that this key MUST be
> > verified for the image to be valid
> > $ mkimage -f ${FIT_ITS} -K ${BOARD_DTB} -k ${KEYS_DIR} -r ${FIT_IMG}
> > 
> > 5. Sign the FIT image
> > $ fit_check_sign -f ${FIT_IMG} -k ${BOARD_DTB}
> > 
> > 6. Run QEMU supplying the DTB containing the public key and the
> > u-boot binary built with CONFIG_OF_BOARD
> > $ qemu-system-arm -nographic \
> >  -M virt -cpu cortex-a15 -smp 1 -m 512 -bios u-boot.bin \
> >  -dtb ${BOARD_DTB} [...]
> > 
> > This is what I get after booting QEMU with the command above:
> > 
> > => fdt addr $fdtcontroladdr
> > => fdt print
> > / {
> >  [...]
> > signature {
> > key-dev {
> > required = "conf";
> > algo = "sha256,rsa2048";
> > rsa,r-squared = * 0x5ef05188 [0x0100];
> > rsa,modulus = * 0x5ef05294 [0x0100];
> > rsa,exponent = <0x 0x00010001>;
> > rsa,n0-inverse = <0x649cd557>;
> > rsa,num-bits = <0x0800>;
> > key-name-hint = "dev";
> > };
> > };
> >  [...]
> 
> See my patch
> 
> doc: fitImage: example of a signature node
> https://lists.denx.de/pipermail/u-boot/2019-December/393613.html
> 
> ---
> 
> Booting of the sandbox fails due to an incorrect address passed for the
> device tree:
> 
> => host load hostfs - $kernel_addr_r image.fit
> 26558 bytes read in 0 ms
> => bootm ${kernel_addr_r}#config-grub-fdt
> ## Loading kernel from FIT Image at 0100 ...
>Using 'config-grub-fdt' configuration
>Verifying Hash Integrity ... OK
>Trying 'helloworld' kernel subimage
>  Description:  Hello World
>  Created:  2019-12-11   9:19:22 UTC
>  Type:  

Re: [PATCH v2 2/4] bootm: Add a bootm command for type IH_OS_EFI

2019-12-11 Thread Cristian Ciocaltea
On Wed, Dec 11, 2019 at 11:13:28AM +0100, Heinrich Schuchardt wrote:
> On 12/11/19 9:54 AM, Cristian Ciocaltea wrote:
> > 1. Create a public/private key pair
> > $ openssl genpkey -algorithm RSA -out ${DEV_KEY} \
> >  -pkeyopt rsa_keygen_bits:2048 -pkeyopt rsa_keygen_pubexp:65537
> > 
> > 2. Create a certificate containing the public key
> > $ openssl req -batch -new -x509 -key ${DEV_KEY} -out ${DEV_CRT}
> > 
> > 3. Dump QEMU virt board DTB
> > $ qemu-system-arm -nographic -M virt,dumpdtb=${BOARD_DTB} \
> >  -cpu cortex-a15 -smp 1 -m 512 -bios u-boot.bin [...]
> > 
> > 4. Create (unsigned) FIT image and put the public key into DTB, with
> > the 'required' property set, telling U-Boot that this key MUST be
> > verified for the image to be valid
> > $ mkimage -f ${FIT_ITS} -K ${BOARD_DTB} -k ${KEYS_DIR} -r ${FIT_IMG}
> > 
> > 5. Sign the FIT image
> > $ fit_check_sign -f ${FIT_IMG} -k ${BOARD_DTB}
> 
> Thanks for the description
> 
> tools/fit_check_sign does not change any file. The signature is added in
> step 4.

You are right, I've taken the commands from a script I use to automate
the whole procedure and I've just missed the verification step.

> What seems to be missing in the U-Boot build system is the capability to
> specify a public key in the configuation file to automatically include
> the public key in the generated dtbs similar to Linux's
> CONFIG_SYSTEM_TRUSTED_KEYS.

That would be a nice addition. Currently it is only possible to pass
the 'EXT_DTB' parameter to 'make' in order to provide the path to an
external DTB file to be put in the U-Boot image.

> Best regards
> 
> Heinrich
> 
> > 
> > 6. Run QEMU supplying the DTB containing the public key and the
> > u-boot binary built with CONFIG_OF_BOARD
> > $ qemu-system-arm -nographic \
> >  -M virt -cpu cortex-a15 -smp 1 -m 512 -bios u-boot.bin \
> >  -dtb ${BOARD_DTB} [...]
> 


Re: [PATCH v2 1/4] image: Add IH_OS_EFI for EFI chain-load boot

2019-12-11 Thread Cristian Ciocaltea
On Tue, Dec 10, 2019 at 10:49:09PM +, Peter Robinson wrote:
> On Tue, Dec 10, 2019 at 6:30 PM Heinrich Schuchardt  
> wrote:
> >
> > On 12/10/19 9:56 AM, Cristian Ciocaltea wrote:
> > > Add a new OS type to be used for chain-loading an EFI compatible
> > > firmware or boot loader like GRUB2, possibly in a verified boot
> > > scenario.
> > >
> > > Bellow is sample ITS file that generates a FIT image supporting
> > > secure boot. Please note the presence of 'os = "efi";' line, which
> > > identifies the currently introduced OS type:
> > >
> > > / {
> > >  #address-cells = <1>;
> > >
> > >  images {
> > >  efi-grub {
> > >  description = "GRUB EFI";
> > >  data = /incbin/("EFI/BOOT/bootarm.efi");
> >
> > According to UEFI Spec 2.8 the default file name for 32 bit ARM is
> > BOOTARM.EFI. But GRUB calls the file grubarm.efi.
> 
> In Linux the boot.efi file is provided by shim [1] and used for
> secure boot etc, I believe the default is also the fall back boot
> method. I'm unaware of shim currently being built for armv7.
> 
> [1] https://github.com/rhboot/shim/
> 
> > So shouldn't we use grubarm.efi here as filename?

My build platform relies on buildroot and that is the default path
where the GRUB EFI binary is deployed. I don't know the reasons behind,
but most probably they are related to portability/compatibility,
as Peter already pointed out.

> > You use EFI/BOOT as directory name. I think this path does not add
> > benefit to the example. The other *.its files also come without any
> > specific path.

Totally agree, I will remove the directory path.

> > Best regards
> >
> > Heinrich
> >
> > >  type = "kernel_noload";
> > >  arch = "arm";
> > >  os = "efi";
> > >  compression = "none";
> > >  load = <0x0>;
> > >  entry = <0x0>;
> > >  hash-1 {
> > >  algo = "sha256";
> > >  };
> > >  };
> > >  };
> > >
> > >  configurations {
> > >  default = "config-grub";
> > >  config-grub {
> > >  kernel = "efi-grub";
> > >  signature-1 {
> > >  algo = "sha256,rsa2048";
> > >  sign-images = "kernel";
> > >  };
> > >  };
> > >  };
> > > };
> > >
> > > Signed-off-by: Cristian Ciocaltea 
> > > ---
> > >   common/image-fit.c | 3 ++-
> > >   common/image.c | 1 +
> > >   include/image.h| 1 +
> > >   3 files changed, 4 insertions(+), 1 deletion(-)
> > >
> > > diff --git a/common/image-fit.c b/common/image-fit.c
> > > index 5c63c769de..19e313bf41 100644
> > > --- a/common/image-fit.c
> > > +++ b/common/image-fit.c
> > > @@ -1925,7 +1925,8 @@ int fit_image_load(bootm_headers_t *images, ulong 
> > > addr,
> > >   image_type == IH_TYPE_FPGA ||
> > >   fit_image_check_os(fit, noffset, IH_OS_LINUX) ||
> > >   fit_image_check_os(fit, noffset, IH_OS_U_BOOT) ||
> > > - fit_image_check_os(fit, noffset, IH_OS_OPENRTOS);
> > > + fit_image_check_os(fit, noffset, IH_OS_OPENRTOS) ||
> > > + fit_image_check_os(fit, noffset, IH_OS_EFI);
> > >
> > >   /*
> > >* If either of the checks fail, we should report an error, but
> > > diff --git a/common/image.c b/common/image.c
> > > index f17fa40c49..2e0e2b0e7f 100644
> > > --- a/common/image.c
> > > +++ b/common/image.c
> > > @@ -134,6 +134,7 @@ static const table_entry_t uimage_os[] = {
> > >   {   IH_OS_OPENRTOS, "openrtos", "OpenRTOS", },
> > >   #endif
> > >   {   IH_OS_OPENSBI,  "opensbi",  "RISC-V OpenSBI",   },
> > > + {   IH_OS_EFI,  "efi",  "EFI Firmware" },
> > >
> > >   {   -1, "", "", },
> > >   };
> > > diff --git a/include/image.h b/include/image.h
> > > index f4d2aaf53e..4a280b78e7 100644
> > > --- a/include/image.h
> > > +++ b/include/image.h
> > > @@ -157,6 +157,7 @@ enum {
> > >   IH_OS_ARM_TRUSTED_FIRMWARE, /* ARM Trusted Firmware */
> > >   IH_OS_TEE,  /* Trusted Execution Environment */
> > >   IH_OS_OPENSBI,  /* RISC-V OpenSBI */
> > > + IH_OS_EFI,  /* EFI Firmware (e.g. GRUB2) */
> > >
> > >   IH_OS_COUNT,
> > >   };
> > >
> >


Re: [PATCH v2 2/4] bootm: Add a bootm command for type IH_OS_EFI

2019-12-11 Thread Cristian Ciocaltea
On Tue, Dec 10, 2019 at 08:32:17PM +0100, Heinrich Schuchardt wrote:
> On 12/10/19 9:56 AM, Cristian Ciocaltea wrote:
> > Add support for booting EFI binaries contained in FIT images.
> > A typical usage scenario is chain-loading GRUB2 in a verified
> > boot environment.
> > 
> > Signed-off-by: Cristian Ciocaltea
> 
> Reading through the code it looks good. What I really need to do is
> analyze the address usage on the sandbox. To me it is unclear if
> images->fdt_addr is a physical address or an address in the address
> space of the sandbox.
> 
> Did you test this on the sandbox? You can use
> lib/efi_loader/helloworld.efi as a binary and the 'host load hostfs'
> command for loading the FIT image.

I only tested on qemu, I've never used the sandbox, so it's a good
opportunity to give it a try.

> Shouldn't we add booting a UEFI FIT image to the Python test in
> test/py/tests/test_fit.py?

Unfortunately I'm not familiar with the testing framework (including
Python scripting), but I'll do my best to add such a test.

> doc/uImage.FIT/signature.txt describes that several properties of the
> RSA public key should be stored in the control device tree.
> Unfortunately no example is supplied in which format they should be
> stored. Could you send me an example, please.
> 
> I found the following
> 
> https://github.com/bn121rajesh/ipython-notebooks/blob/master/BehindTheScene/RSAPublicKeyParamsUBoot/rsa_public_key_params_uboot.ipynb
> 
> Is this an accurate description? Or how do you get the parameters from
> your RSA public key?

My test scenario involves the following steps:

1. Create a public/private key pair
$ openssl genpkey -algorithm RSA -out ${DEV_KEY} \
-pkeyopt rsa_keygen_bits:2048 -pkeyopt rsa_keygen_pubexp:65537

2. Create a certificate containing the public key
$ openssl req -batch -new -x509 -key ${DEV_KEY} -out ${DEV_CRT}

3. Dump QEMU virt board DTB
$ qemu-system-arm -nographic -M virt,dumpdtb=${BOARD_DTB} \
-cpu cortex-a15 -smp 1 -m 512 -bios u-boot.bin [...]

4. Create (unsigned) FIT image and put the public key into DTB, with
   the 'required' property set, telling U-Boot that this key MUST be
   verified for the image to be valid
$ mkimage -f ${FIT_ITS} -K ${BOARD_DTB} -k ${KEYS_DIR} -r ${FIT_IMG}

5. Sign the FIT image
$ fit_check_sign -f ${FIT_IMG} -k ${BOARD_DTB}

6. Run QEMU supplying the DTB containing the public key and the
   u-boot binary built with CONFIG_OF_BOARD
$ qemu-system-arm -nographic \
-M virt -cpu cortex-a15 -smp 1 -m 512 -bios u-boot.bin \
-dtb ${BOARD_DTB} [...]

This is what I get after booting QEMU with the command above:

=> fdt addr $fdtcontroladdr
=> fdt print
/ {
[...]
signature {
key-dev {
required = "conf";
algo = "sha256,rsa2048";
rsa,r-squared = * 0x5ef05188 [0x0100];
rsa,modulus = * 0x5ef05294 [0x0100];
rsa,exponent = <0x 0x00010001>;
rsa,n0-inverse = <0x649cd557>;
rsa,num-bits = <0x0800>;
key-name-hint = "dev";
};
};
[...]

> Best regards
> 
> Heinrich


[PATCH v2 4/4] doc: uefi.rst: Document launching UEFI binaries from FIT images

2019-12-10 Thread Cristian Ciocaltea
This patch adds a new section "Launching a UEFI binary from a FIT image"
documenting the usage of the CONFIG_BOOTM_EFI extension to bootm command
that offers a secure boot alternative for UEFI binaries such as GRUB2.

Signed-off-by: Cristian Ciocaltea 
---
 doc/uefi/uefi.rst | 34 ++
 1 file changed, 34 insertions(+)

diff --git a/doc/uefi/uefi.rst b/doc/uefi/uefi.rst
index db942df694..a8fd886d6b 100644
--- a/doc/uefi/uefi.rst
+++ b/doc/uefi/uefi.rst
@@ -63,6 +63,40 @@ The environment variable 'bootargs' is passed as load 
options in the UEFI system
 table. The Linux kernel EFI stub uses the load options as command line
 arguments.
 
+Launching a UEFI binary from a FIT image
+
+
+A signed FIT image can be used to securely boot a UEFI image via the
+bootm command. This feature is available if U-Boot is configured with::
+
+CONFIG_BOOTM_EFI=y
+
+A sample configuration is provided as file doc/uImage.FIT/uefi.its.
+
+Below you find the output of an example session starting GRUB::
+
+=> load mmc 0:1 ${kernel_addr_r} image.fit
+4620426 bytes read in 83 ms (53.1 MiB/s)
+=> bootm ${kernel_addr_r}#config-grub-nofdt
+## Loading kernel from FIT Image at 4040 ...
+   Using 'config-grub-nofdt' configuration
+   Verifying Hash Integrity ... sha256,rsa2048:dev+ OK
+   Trying 'efi-grub' kernel subimage
+ Description:  GRUB EFI Firmware
+ Created:  2019-11-20   8:18:16 UTC
+ Type: Kernel Image (no loading done)
+ Compression:  uncompressed
+ Data Start:   0x404000d0
+ Data Size:450560 Bytes = 440 KiB
+ Hash algo:sha256
+ Hash value:   
4dbee00021112df618f58b3f7cf5e1595533d543094064b9ce991e8b054a9eec
+   Verifying Hash Integrity ... sha256+ OK
+   XIP Kernel Image (no loading done)
+## Transferring control to EFI (at address 404000d0) ...
+Welcome to GRUB!
+
+See doc/uImage.FIT/howto.txt for an introduction to FIT images.
+
 Executing the boot manager
 ~~
 
-- 
2.17.1



[PATCH v2 3/4] doc: Add sample uefi.its image description file

2019-12-10 Thread Cristian Ciocaltea
This patch adds an example FIT image description file demonstrating
the usage of bootm command to securely launch UEFI binaries.

Signed-off-by: Cristian Ciocaltea 
---
 doc/uImage.FIT/uefi.its | 67 +
 1 file changed, 67 insertions(+)
 create mode 100644 doc/uImage.FIT/uefi.its

diff --git a/doc/uImage.FIT/uefi.its b/doc/uImage.FIT/uefi.its
new file mode 100644
index 00..e336ad938d
--- /dev/null
+++ b/doc/uImage.FIT/uefi.its
@@ -0,0 +1,67 @@
+/*
+ * Example FIT image description file demonstrating the usage of
+ * bootm command to launch UEFI binaries.
+ *
+ * Two boot configurations are available to enable booting GRUB2 on QEMU,
+ * the former uses a FDT blob contained in the FIT image, while the later
+ * relies on the FDT provided by the board emulator.
+ */
+
+/dts-v1/;
+
+/ {
+   description = "GRUB2 EFI and QEMU FDT blob";
+   #address-cells = <1>;
+
+   images {
+   efi-grub {
+   description = "GRUB EFI Firmware";
+   data = /incbin/("efi-part/EFI/BOOT/bootarm.efi");
+   type = "kernel_noload";
+   arch = "arm";
+   os = "efi";
+   compression = "none";
+   load = <0x0>;
+   entry = <0x0>;
+   hash-1 {
+   algo = "sha256";
+   };
+   };
+
+   fdt-qemu {
+   description = "QEMU DTB";
+   data = /incbin/("qemu-arm.dtb");
+   type = "flat_dt";
+   arch = "arm";
+   compression = "none";
+   hash-1 {
+   algo = "sha256";
+   };
+   };
+   };
+
+   configurations {
+   default = "config-grub-fdt";
+
+   config-grub-fdt {
+   description = "GRUB EFI Boot with FDT";
+   kernel = "efi-grub";
+   fdt = "fdt-qemu";
+   signature-1 {
+   algo = "sha256,rsa2048";
+   key-name-hint = "dev";
+   sign-images = "kernel", "fdt";
+   };
+   };
+
+   config-grub-nofdt {
+   description = "GRUB EFI Boot w/o FDT";
+   kernel = "efi-grub";
+   signature-1 {
+   algo = "sha256,rsa2048";
+   key-name-hint = "dev";
+   sign-images = "kernel";
+   };
+   };
+   };
+};
-- 
2.17.1



[PATCH v2 2/4] bootm: Add a bootm command for type IH_OS_EFI

2019-12-10 Thread Cristian Ciocaltea
Add support for booting EFI binaries contained in FIT images.
A typical usage scenario is chain-loading GRUB2 in a verified
boot environment.

Signed-off-by: Cristian Ciocaltea 
---
 cmd/Kconfig   |  7 ++
 common/bootm_os.c | 61 +++
 2 files changed, 68 insertions(+)

diff --git a/cmd/Kconfig b/cmd/Kconfig
index cf982ff65e..39fa87082d 100644
--- a/cmd/Kconfig
+++ b/cmd/Kconfig
@@ -263,6 +263,13 @@ config CMD_BOOTI
help
  Boot an AArch64 Linux Kernel image from memory.
 
+config BOOTM_EFI
+   bool "Support booting EFI OS images"
+   depends on CMD_BOOTEFI
+   default y
+   help
+ Support booting EFI images via the bootm command.
+
 config BOOTM_LINUX
bool "Support booting Linux OS images"
depends on CMD_BOOTM || CMD_BOOTZ || CMD_BOOTI
diff --git a/common/bootm_os.c b/common/bootm_os.c
index 6fb7d658da..7aa76052b9 100644
--- a/common/bootm_os.c
+++ b/common/bootm_os.c
@@ -6,10 +6,12 @@
 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 
@@ -462,6 +464,62 @@ static int do_bootm_tee(int flag, int argc, char * const 
argv[],
 }
 #endif
 
+#ifdef CONFIG_BOOTM_EFI
+static int do_bootm_efi(int flag, int argc, char * const argv[],
+   bootm_headers_t *images)
+{
+   int ret;
+   efi_status_t efi_ret;
+   uintptr_t fdt_addr;
+   void *image_buf;
+
+   if (flag != BOOTM_STATE_OS_GO)
+   return 0;
+
+   /* Locate EFI binary and FDT, if provided */
+   ret = bootm_find_images(flag, argc, argv);
+   if (ret)
+   return ret;
+
+   /* Initialize EFI drivers */
+   efi_ret = efi_init_obj_list();
+   if (efi_ret != EFI_SUCCESS) {
+   printf("## Error: Cannot initialize UEFI sub-system, r = %lu\n",
+  efi_ret & ~EFI_ERROR_MASK);
+   return 1;
+   }
+
+   /* Install device tree */
+   if (images->ft_len)
+   fdt_addr = (uintptr_t)images->ft_addr;
+   else
+   fdt_addr = EFI_FDT_USE_INTERNAL;
+
+   efi_ret = efi_install_fdt(fdt_addr);
+   if (efi_ret != EFI_SUCCESS) {
+   printf("## Error: Cannot install device tree, r = %lu\n",
+  efi_ret & ~EFI_ERROR_MASK);
+   return 1;
+   }
+
+   /* Run EFI image */
+   printf("## Transferring control to EFI (at address %08lx) ...\n",
+  images->ep);
+   bootstage_mark(BOOTSTAGE_ID_RUN_OS);
+
+   image_buf = map_sysmem(images->ep, images->os.image_len);
+
+   efi_ret = efi_run_image(image_buf, images->os.image_len);
+   if (efi_ret != EFI_SUCCESS) {
+   printf("## Error: Cannot run EFI image, r = %lu\n",
+  efi_ret & ~EFI_ERROR_MASK);
+   return 1;
+   }
+
+   return 0;
+}
+#endif
+
 static boot_os_fn *boot_os[] = {
[IH_OS_U_BOOT] = do_bootm_standalone,
 #ifdef CONFIG_BOOTM_LINUX
@@ -498,6 +556,9 @@ static boot_os_fn *boot_os[] = {
 #ifdef CONFIG_BOOTM_OPTEE
[IH_OS_TEE] = do_bootm_tee,
 #endif
+#ifdef CONFIG_BOOTM_EFI
+   [IH_OS_EFI] = do_bootm_efi,
+#endif
 };
 
 /* Allow for arch specific config before we boot */
-- 
2.17.1



[PATCH v2 0/4] Add support for booting EFI FIT images

2019-12-10 Thread Cristian Ciocaltea
Currently the only way to run an EFI binary like GRUB2 is via the
'bootefi' command, which cannot be used in a verified boot scenario.

The obvious solution to this limitation is to add support for
booting FIT images containing those EFI binaries.

The implementation relies on a new image type - IH_OS_EFI - which
can be created by using 'os = "efi"' inside an ITS file:

/ {
#address-cells = <1>;

images {
efi-grub {
description = "GRUB EFI";
data = /incbin/("EFI/BOOT/bootarm.efi");
type = "kernel_noload";
arch = "arm";
os = "efi";
compression = "none";
load = <0x0>;
entry = <0x0>;
hash-1 {
algo = "sha256";
};
};
};

configurations {
default = "config-grub";
config-grub {
kernel = "efi-grub";
signature-1 {
algo = "sha256,rsa2048";
sign-images = "kernel";
};
};
};
};

The bootm command has been extended to handle the IH_OS_EFI images.
To enable this feature, a new configuration option has been added:
BOOTM_EFI

I tested the solution using the 'qemu_arm' board:

=> load scsi 0:1 ${kernel_addr_r} efi-image.fit
=> bootm ${kernel_addr_r}#config-grub

Changes since v1:
 * Rebase patches on Heinrich Schuchardt's patch series:
   efi_loader: prepare for FIT images
   https://lists.denx.de/pipermail/u-boot/2019-December/393192.html
 * Add sample configuration: doc/uImage.FIT/uefi.its
 * Update uefi documentation: doc/uefi/uefi.rst

Cristian Ciocaltea (4):
  image: Add IH_OS_EFI for EFI chain-load boot
  bootm: Add a bootm command for type IH_OS_EFI
  doc: Add sample uefi.its image description file
  doc: uefi.rst: Document launching UEFI binaries from FIT images

 cmd/Kconfig |  7 +
 common/bootm_os.c   | 61 +
 common/image-fit.c  |  3 +-
 common/image.c  |  1 +
 doc/uImage.FIT/uefi.its | 67 +
 doc/uefi/uefi.rst   | 34 +
 include/image.h |  1 +
 7 files changed, 173 insertions(+), 1 deletion(-)
 create mode 100644 doc/uImage.FIT/uefi.its

-- 
2.17.1



[PATCH v2 1/4] image: Add IH_OS_EFI for EFI chain-load boot

2019-12-10 Thread Cristian Ciocaltea
Add a new OS type to be used for chain-loading an EFI compatible
firmware or boot loader like GRUB2, possibly in a verified boot
scenario.

Bellow is sample ITS file that generates a FIT image supporting
secure boot. Please note the presence of 'os = "efi";' line, which
identifies the currently introduced OS type:

/ {
#address-cells = <1>;

images {
efi-grub {
description = "GRUB EFI";
data = /incbin/("EFI/BOOT/bootarm.efi");
type = "kernel_noload";
arch = "arm";
os = "efi";
compression = "none";
load = <0x0>;
entry = <0x0>;
hash-1 {
algo = "sha256";
};
};
};

configurations {
default = "config-grub";
config-grub {
kernel = "efi-grub";
signature-1 {
    algo = "sha256,rsa2048";
sign-images = "kernel";
};
};
};
};

Signed-off-by: Cristian Ciocaltea 
---
 common/image-fit.c | 3 ++-
 common/image.c | 1 +
 include/image.h| 1 +
 3 files changed, 4 insertions(+), 1 deletion(-)

diff --git a/common/image-fit.c b/common/image-fit.c
index 5c63c769de..19e313bf41 100644
--- a/common/image-fit.c
+++ b/common/image-fit.c
@@ -1925,7 +1925,8 @@ int fit_image_load(bootm_headers_t *images, ulong addr,
image_type == IH_TYPE_FPGA ||
fit_image_check_os(fit, noffset, IH_OS_LINUX) ||
fit_image_check_os(fit, noffset, IH_OS_U_BOOT) ||
-   fit_image_check_os(fit, noffset, IH_OS_OPENRTOS);
+   fit_image_check_os(fit, noffset, IH_OS_OPENRTOS) ||
+   fit_image_check_os(fit, noffset, IH_OS_EFI);
 
/*
 * If either of the checks fail, we should report an error, but
diff --git a/common/image.c b/common/image.c
index f17fa40c49..2e0e2b0e7f 100644
--- a/common/image.c
+++ b/common/image.c
@@ -134,6 +134,7 @@ static const table_entry_t uimage_os[] = {
{   IH_OS_OPENRTOS, "openrtos", "OpenRTOS", },
 #endif
{   IH_OS_OPENSBI,  "opensbi",  "RISC-V OpenSBI",   },
+   {   IH_OS_EFI,  "efi",  "EFI Firmware" },
 
{   -1, "", "", },
 };
diff --git a/include/image.h b/include/image.h
index f4d2aaf53e..4a280b78e7 100644
--- a/include/image.h
+++ b/include/image.h
@@ -157,6 +157,7 @@ enum {
IH_OS_ARM_TRUSTED_FIRMWARE, /* ARM Trusted Firmware */
IH_OS_TEE,  /* Trusted Execution Environment */
IH_OS_OPENSBI,  /* RISC-V OpenSBI */
+   IH_OS_EFI,  /* EFI Firmware (e.g. GRUB2) */
 
IH_OS_COUNT,
 };
-- 
2.17.1



Re: [U-Boot] [PATCH 0/2] Add support for booting EFI FIT images

2019-12-09 Thread Cristian Ciocaltea
On Sun, Dec 08, 2019 at 01:25:27AM +0100, Heinrich Schuchardt wrote:
> On 11/28/19 8:20 AM, Heinrich Schuchardt wrote:
> > On 11/27/19 8:45 PM, Cristian Ciocaltea wrote:
> > > On Tue, Nov 26, 2019 at 07:31:39PM +0100, Heinrich Schuchardt wrote:
> > > > On 11/24/19 9:11 PM, Cristian Ciocaltea wrote:
> > > > > Currently the only way to run an EFI binary like GRUB2 is via the
> > > > > 'bootefi' command, which cannot be used in a verified boot scenario.
> > > > > 
> > > > > The obvious solution to this limitation is to add support for
> > > > > booting FIT images containing those EFI binaries.
> > > > > 
> > > > > The implementation relies on a new image type - IH_OS_EFI - which
> > > > > can be created by using 'os = "efi"' inside an ITS file:
> > > > > 
> > > > > / {
> > > > >   #address-cells = <1>;
> > > > > 
> > > > >   images {
> > > > >   efi-grub {
> > > > >   description = "GRUB EFI";
> > > > >   data = /incbin/("EFI/BOOT/bootarm.efi");
> > > > >   type = "kernel_noload";
> > > > >   arch = "arm";
> > > > >   os = "efi";
> > > > >   compression = "none";
> > > > >   load = <0x0>;
> > > > >   entry = <0x0>;
> > > > >   hash-1 {
> > > > >   algo = "sha256";
> > > > >   };
> > > > >   };
> > > > >   };
> > > > > 
> > > > >   configurations {
> > > > >   default = "config-grub";
> > > > >   config-grub {
> > > > >   kernel = "efi-grub";
> > > > >   signature-1 {
> > > > >   algo = "sha256,rsa2048";
> > > > >   sign-images = "kernel";
> > > > >   };
> > > > >   };
> > > > >   };
> > > > > };
> > > > > 
> > > > > The bootm command has been extended to handle the IH_OS_EFI images.
> > > > > To enable this feature, a new configuration option has been added:
> > > > > BOOTM_EFI
> > > > > 
> > > > > I tested the solution using the 'qemu_arm' board:
> > > > > 
> > > > > => load scsi 0:1 ${kernel_addr_r} efi-image.fit
> > > > > => bootm ${kernel_addr_r}#config-grub
> > > > 
> > > > Thanks a lot for the patch series which makes good sense to me.
> > > > 
> > > > I think we should pass addresses and not strings to cmd/bootefi.c. This
> > > > will need a bit of refactoring as already addressed in a comment to
> > > > patch 2/2.
> > > > 
> > > > Additionally the documentation in doc/uefi/u-boot_on_efi.rst and
> > > > doc/uImage.FIT/howto.txt should be updated.
> > > > 
> > > > I cc the contributors given by
> > > > scripts/get_maintainer.pl -f common/bootm_os.c
> > > > 
> > > > Best regards
> > > > 
> > > > Heinrich
> > > > 
> > > 
> > > Thanks for the feedback, Heinrich!
> > > 
> > > Instead of creating new function(s), I think we could simply extend
> > >    int do_bootefi_image(const char *image_opt)
> > > with a new parameter to hold the fdt address and move here the call
> > > to 'efi_install_fdt()', which is now performed by 'do_bootefi()'.
> > 
> > efi_install_fdt() has to be called for the 'bootefi bootmgr' command too
> > so the refactoring is a bit more complicated. I have started on that.
> > 
> > The first step is to change efi_install_fdt() to expect the argument as
> > address instead of a string.
> > 
> > https://github.com/xypron/u-boot-patches/blob/efi-next/0001-efi_loader-pass-address-to-efi_install_fdt.patch
> > 
> > 
> > fdt_addr==NULL indicates no device tree supplied by user.
> > 
> > Best regards
> > 
> > Heinrich
> > 
> > > 
> > > However, I'm not sure about changing the data types, i.e. from
> > > 'char *' to ulong, for the following reasons:
> > > 1. image

Re: [U-Boot] [PATCH 0/2] Add support for booting EFI FIT images

2019-11-27 Thread Cristian Ciocaltea
On Tue, Nov 26, 2019 at 07:31:39PM +0100, Heinrich Schuchardt wrote:
> On 11/24/19 9:11 PM, Cristian Ciocaltea wrote:
> > Currently the only way to run an EFI binary like GRUB2 is via the
> > 'bootefi' command, which cannot be used in a verified boot scenario.
> > 
> > The obvious solution to this limitation is to add support for
> > booting FIT images containing those EFI binaries.
> > 
> > The implementation relies on a new image type - IH_OS_EFI - which
> > can be created by using 'os = "efi"' inside an ITS file:
> > 
> > / {
> >  #address-cells = <1>;
> > 
> >  images {
> >  efi-grub {
> >  description = "GRUB EFI";
> >  data = /incbin/("EFI/BOOT/bootarm.efi");
> >  type = "kernel_noload";
> >  arch = "arm";
> >  os = "efi";
> >  compression = "none";
> >  load = <0x0>;
> >  entry = <0x0>;
> >  hash-1 {
> >  algo = "sha256";
> >  };
> >  };
> >  };
> > 
> >  configurations {
> >  default = "config-grub";
> >  config-grub {
> >  kernel = "efi-grub";
> >  signature-1 {
> >  algo = "sha256,rsa2048";
> >  sign-images = "kernel";
> >  };
> >  };
> >  };
> > };
> > 
> > The bootm command has been extended to handle the IH_OS_EFI images.
> > To enable this feature, a new configuration option has been added:
> > BOOTM_EFI
> > 
> > I tested the solution using the 'qemu_arm' board:
> > 
> > => load scsi 0:1 ${kernel_addr_r} efi-image.fit
> > => bootm ${kernel_addr_r}#config-grub
> 
> Thanks a lot for the patch series which makes good sense to me.
> 
> I think we should pass addresses and not strings to cmd/bootefi.c. This
> will need a bit of refactoring as already addressed in a comment to
> patch 2/2.
> 
> Additionally the documentation in doc/uefi/u-boot_on_efi.rst and
> doc/uImage.FIT/howto.txt should be updated.
> 
> I cc the contributors given by
> scripts/get_maintainer.pl -f common/bootm_os.c
> 
> Best regards
> 
> Heinrich
> 

Thanks for the feedback, Heinrich!

Instead of creating new function(s), I think we could simply extend
  int do_bootefi_image(const char *image_opt)
with a new parameter to hold the fdt address and move here the call
to 'efi_install_fdt()', which is now performed by 'do_bootefi()'.

However, I'm not sure about changing the data types, i.e. from
'char *' to ulong, for the following reasons:
1. image_opt may have a different meaning in addition to efi address
2. fdt address may not be provided, so we need somehow to detect an
invalid value

Kind regards,
Cristian

> > 
> > 
> > Cristian Ciocaltea (2):
> >image: Add IH_OS_EFI for EFI chain-load boot
> >bootm: Add a bootm command for type IH_OS_EFI
> > 
> >   cmd/Kconfig|  9 -
> >   cmd/bootefi.c  |  2 +-
> >   common/bootm_os.c  | 44 
> >   common/image-fit.c |  3 ++-
> >   common/image.c |  1 +
> >   include/bootm.h|  2 ++
> >   include/image.h|  1 +
> >   7 files changed, 59 insertions(+), 3 deletions(-)
> > 
> 
___
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot


[U-Boot] [PATCH 1/1] buildman: Improve [make-flags] section parser to allow quoted strings

2019-11-24 Thread Cristian Ciocaltea
The parser responsible for the '[make-flags]' section in
the '.buildman' settings file is currently not able to
handle quoted strings, as given in the sample bellow:

[make-flags]
qemu_arm=HOSTCC="cc -isystem /add/include" HOSTLDFLAGS="-L/add/lib"

This patch replaces the simple string splitter based on the 
delimiter with a regex tokenizer that preserves spaces inside double
quoted strings.

Signed-off-by: Cristian Ciocaltea 
---
 tools/buildman/toolchain.py | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/tools/buildman/toolchain.py b/tools/buildman/toolchain.py
index cc26e2ede5..086a4d47cd 100644
--- a/tools/buildman/toolchain.py
+++ b/tools/buildman/toolchain.py
@@ -435,9 +435,10 @@ class Toolchains:
 self._make_flags['target'] = board.target
 arg_str = self.ResolveReferences(self._make_flags,
self._make_flags.get(board.target, ''))
-args = arg_str.split(' ')
+args = re.findall("(?:\".*?\"|\S)+", arg_str)
 i = 0
 while i < len(args):
+args[i] = args[i].replace('"', '')
 if not args[i]:
 del args[i]
 else:
-- 
2.17.1

___
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot


[U-Boot] [PATCH 1/2] image: Add IH_OS_EFI for EFI chain-load boot

2019-11-24 Thread Cristian Ciocaltea
Add a new OS type to be used for chain-loading an EFI compatible
firmware or boot loader like GRUB2, possibly in a verified boot
scenario.

Bellow is sample ITS file that generates a FIT image supporting
secure boot. Please note the presence of 'os = "efi";' line, which
identifies the currently introduced OS type:

/ {
#address-cells = <1>;

images {
efi-grub {
description = "GRUB EFI";
data = /incbin/("EFI/BOOT/bootarm.efi");
type = "kernel_noload";
arch = "arm";
os = "efi";
compression = "none";
load = <0x0>;
entry = <0x0>;
hash-1 {
algo = "sha256";
};
};
};

configurations {
default = "config-grub";
config-grub {
kernel = "efi-grub";
signature-1 {
    algo = "sha256,rsa2048";
sign-images = "kernel";
};
};
};
};

Signed-off-by: Cristian Ciocaltea 
---
 common/image-fit.c | 3 ++-
 common/image.c | 1 +
 include/image.h| 1 +
 3 files changed, 4 insertions(+), 1 deletion(-)

diff --git a/common/image-fit.c b/common/image-fit.c
index 5c63c769de..19e313bf41 100644
--- a/common/image-fit.c
+++ b/common/image-fit.c
@@ -1925,7 +1925,8 @@ int fit_image_load(bootm_headers_t *images, ulong addr,
image_type == IH_TYPE_FPGA ||
fit_image_check_os(fit, noffset, IH_OS_LINUX) ||
fit_image_check_os(fit, noffset, IH_OS_U_BOOT) ||
-   fit_image_check_os(fit, noffset, IH_OS_OPENRTOS);
+   fit_image_check_os(fit, noffset, IH_OS_OPENRTOS) ||
+   fit_image_check_os(fit, noffset, IH_OS_EFI);
 
/*
 * If either of the checks fail, we should report an error, but
diff --git a/common/image.c b/common/image.c
index f17fa40c49..2e0e2b0e7f 100644
--- a/common/image.c
+++ b/common/image.c
@@ -134,6 +134,7 @@ static const table_entry_t uimage_os[] = {
{   IH_OS_OPENRTOS, "openrtos", "OpenRTOS", },
 #endif
{   IH_OS_OPENSBI,  "opensbi",  "RISC-V OpenSBI",   },
+   {   IH_OS_EFI,  "efi",  "EFI Firmware" },
 
{   -1, "", "", },
 };
diff --git a/include/image.h b/include/image.h
index f4d2aaf53e..4a280b78e7 100644
--- a/include/image.h
+++ b/include/image.h
@@ -157,6 +157,7 @@ enum {
IH_OS_ARM_TRUSTED_FIRMWARE, /* ARM Trusted Firmware */
IH_OS_TEE,  /* Trusted Execution Environment */
IH_OS_OPENSBI,  /* RISC-V OpenSBI */
+   IH_OS_EFI,  /* EFI Firmware (e.g. GRUB2) */
 
IH_OS_COUNT,
 };
-- 
2.17.1

___
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot


[U-Boot] [PATCH 0/2] Add support for booting EFI FIT images

2019-11-24 Thread Cristian Ciocaltea
Currently the only way to run an EFI binary like GRUB2 is via the
'bootefi' command, which cannot be used in a verified boot scenario.

The obvious solution to this limitation is to add support for
booting FIT images containing those EFI binaries.

The implementation relies on a new image type - IH_OS_EFI - which
can be created by using 'os = "efi"' inside an ITS file:

/ {
#address-cells = <1>;

images {
efi-grub {
description = "GRUB EFI";
data = /incbin/("EFI/BOOT/bootarm.efi");
type = "kernel_noload";
arch = "arm";
os = "efi";
compression = "none";
load = <0x0>;
entry = <0x0>;
hash-1 {
algo = "sha256";
};
};
};

configurations {
default = "config-grub";
config-grub {
kernel = "efi-grub";
signature-1 {
algo = "sha256,rsa2048";
sign-images = "kernel";
};
};
};
};

The bootm command has been extended to handle the IH_OS_EFI images.
To enable this feature, a new configuration option has been added:
BOOTM_EFI

I tested the solution using the 'qemu_arm' board:

=> load scsi 0:1 ${kernel_addr_r} efi-image.fit
=> bootm ${kernel_addr_r}#config-grub


Cristian Ciocaltea (2):
  image: Add IH_OS_EFI for EFI chain-load boot
  bootm: Add a bootm command for type IH_OS_EFI

 cmd/Kconfig|  9 -
 cmd/bootefi.c  |  2 +-
 common/bootm_os.c  | 44 
 common/image-fit.c |  3 ++-
 common/image.c |  1 +
 include/bootm.h|  2 ++
 include/image.h|  1 +
 7 files changed, 59 insertions(+), 3 deletions(-)

-- 
2.17.1

___
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot


[U-Boot] [PATCH 2/2] bootm: Add a bootm command for type IH_OS_EFI

2019-11-24 Thread Cristian Ciocaltea
Add support for booting EFI binaries contained in FIT images.
A typical usage scenario is chain-loading GRUB2 in a verified
boot environment.

Signed-off-by: Cristian Ciocaltea 
---
 cmd/Kconfig   |  9 -
 cmd/bootefi.c |  2 +-
 common/bootm_os.c | 44 
 include/bootm.h   |  2 ++
 4 files changed, 55 insertions(+), 2 deletions(-)

diff --git a/cmd/Kconfig b/cmd/Kconfig
index cf982ff65e..1bec840f5a 100644
--- a/cmd/Kconfig
+++ b/cmd/Kconfig
@@ -263,6 +263,13 @@ config CMD_BOOTI
help
  Boot an AArch64 Linux Kernel image from memory.
 
+config BOOTM_EFI
+   bool "Support booting EFI OS images"
+   depends on CMD_BOOTEFI
+   default y
+   help
+ Support booting EFI images via the bootm command.
+
 config BOOTM_LINUX
bool "Support booting Linux OS images"
depends on CMD_BOOTM || CMD_BOOTZ || CMD_BOOTI
@@ -316,7 +323,7 @@ config CMD_BOOTEFI
depends on EFI_LOADER
default y
help
- Boot an EFI image from memory.
+ Boot an EFI binary from memory.
 
 config CMD_BOOTEFI_HELLO_COMPILE
bool "Compile a standard EFI hello world binary for testing"
diff --git a/cmd/bootefi.c b/cmd/bootefi.c
index f613cce7e2..f25d639dfe 100644
--- a/cmd/bootefi.c
+++ b/cmd/bootefi.c
@@ -553,7 +553,7 @@ static int do_efi_selftest(void)
  * @argv:  command line arguments
  * Return: status code
  */
-static int do_bootefi(cmd_tbl_t *cmdtp, int flag, int argc, char * const 
argv[])
+int do_bootefi(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 {
efi_status_t ret;
 
diff --git a/common/bootm_os.c b/common/bootm_os.c
index 6fb7d658da..706151913a 100644
--- a/common/bootm_os.c
+++ b/common/bootm_os.c
@@ -462,6 +462,47 @@ static int do_bootm_tee(int flag, int argc, char * const 
argv[],
 }
 #endif
 
+#ifdef CONFIG_BOOTM_EFI
+static int do_bootm_efi(int flag, int argc, char * const argv[],
+   bootm_headers_t *images)
+{
+   int ret;
+   int local_argc = 2;
+   char *local_args[3];
+   char str_efi_addr[16];
+   char str_fdt_addr[16];
+
+   if (flag != BOOTM_STATE_OS_GO)
+   return 0;
+
+   /* Locate FDT etc */
+   ret = bootm_find_images(flag, argc, argv);
+   if (ret)
+   return ret;
+
+   printf("## Transferring control to EFI (at address %08lx) ...\n",
+  images->ep);
+   bootstage_mark(BOOTSTAGE_ID_RUN_OS);
+
+   local_args[0] = argv[0];
+
+   /* Write efi addr into string */
+   sprintf(str_efi_addr, "%lx", images->ep);
+   /* and provide it via the arguments */
+   local_args[1] = str_efi_addr;
+
+   if (images->ft_len) {
+   /* Write fdt addr into string */
+   sprintf(str_fdt_addr, "%lx", (unsigned long)images->ft_addr);
+   /* and provide it via the arguments */
+   local_args[2] = str_fdt_addr;
+   local_argc = 3;
+   }
+
+   return do_bootefi(NULL, 0, local_argc, local_args);
+}
+#endif
+
 static boot_os_fn *boot_os[] = {
[IH_OS_U_BOOT] = do_bootm_standalone,
 #ifdef CONFIG_BOOTM_LINUX
@@ -498,6 +539,9 @@ static boot_os_fn *boot_os[] = {
 #ifdef CONFIG_BOOTM_OPTEE
[IH_OS_TEE] = do_bootm_tee,
 #endif
+#ifdef CONFIG_BOOTM_EFI
+   [IH_OS_EFI] = do_bootm_efi,
+#endif
 };
 
 /* Allow for arch specific config before we boot */
diff --git a/include/bootm.h b/include/bootm.h
index edeeacb0df..a0da86dc32 100644
--- a/include/bootm.h
+++ b/include/bootm.h
@@ -37,7 +37,9 @@ typedef int boot_os_fn(int flag, int argc, char * const 
argv[],
 extern boot_os_fn do_bootm_linux;
 extern boot_os_fn do_bootm_vxworks;
 
+int do_bootefi(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]);
 int do_bootelf(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]);
+
 void lynxkdi_boot(image_header_t *hdr);
 
 boot_os_fn *bootm_os_get_boot_func(int os);
-- 
2.17.1

___
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot


[U-Boot] [PATCH] api: storage: Add the missing write operation support

2019-01-11 Thread Cristian Ciocaltea
API_dev_write(va_list ap) is currently lacking the write support
to storage devices because, historically, those devices did not
implement block_write()

The solution has been tested by loading and booting a (patched)
GRUB instance in a QEMU vexpress-a9 environment. The disk write
operations were triggered with GRUB's save_env command.

Signed-off-by: Cristian Ciocaltea 
---

 api/api.c | 59 ++-
 api/api_private.h |  1 +
 api/api_storage.c | 24 +++
 3 files changed, 63 insertions(+), 21 deletions(-)

diff --git a/api/api.c b/api/api.c
index 9f03f1a35b..f7cfcc9ebc 100644
--- a/api/api.c
+++ b/api/api.c
@@ -294,27 +294,31 @@ static int API_dev_close(va_list ap)
 
 
 /*
- * Notice: this is for sending network packets only, as U-Boot does not
- * support writing to storage at the moment (12.2007)
- *
  * pseudo signature:
  *
  * int API_dev_write(
  * struct device_info *di,
  * void *buf,
- * int *len
+ * int *len,
+ * unsigned long *start
  * )
  *
  * buf:ptr to buffer from where to get the data to send
  *
- * len: length of packet to be sent (in bytes)
+ * len: ptr to length to be read
+ *  - network: len of packet to be sent (in bytes)
+ *  - storage: # of blocks to write (can vary in size depending on define)
  *
+ * start: ptr to start block (only used for storage devices, ignored for
+ *network)
  */
 static int API_dev_write(va_list ap)
 {
struct device_info *di;
void *buf;
-   int *len;
+   lbasize_t *len_stor, act_len_stor;
+   lbastart_t *start;
+   int *len_net;
int err = 0;
 
/* 1. arg is ptr to the device_info struct */
@@ -332,23 +336,36 @@ static int API_dev_write(va_list ap)
if (buf == NULL)
return API_EINVAL;
 
-   /* 3. arg is length of buffer */
-   len = (int *)va_arg(ap, uintptr_t);
-   if (len == NULL)
-   return API_EINVAL;
-   if (*len <= 0)
-   return API_EINVAL;
+   if (di->type & DEV_TYP_STOR) {
+   /* 3. arg - ptr to var with # of blocks to write */
+   len_stor = (lbasize_t *)va_arg(ap, uintptr_t);
+   if (!len_stor)
+   return API_EINVAL;
+   if (*len_stor <= 0)
+   return API_EINVAL;
 
-   if (di->type & DEV_TYP_STOR)
-   /*
-* write to storage is currently not supported by U-Boot:
-* no storage device implements block_write() method
-*/
-   return API_ENODEV;
+   /* 4. arg - ptr to var with start block */
+   start = (lbastart_t *)va_arg(ap, uintptr_t);
 
-   else if (di->type & DEV_TYP_NET)
-   err = dev_write_net(di->cookie, buf, *len);
-   else
+   act_len_stor = dev_write_stor(di->cookie, buf, *len_stor, 
*start);
+   if (act_len_stor != *len_stor) {
+   debugf("write @ %llu: done %llu out of %llu blocks",
+  (uint64_t)blk, (uint64_t)act_len_stor,
+  (uint64_t)len_stor);
+   return API_EIO;
+   }
+
+   } else if (di->type & DEV_TYP_NET) {
+   /* 3. arg points to the var with length of packet to write */
+   len_net = (int *)va_arg(ap, uintptr_t);
+   if (!len_net)
+   return API_EINVAL;
+   if (*len_net <= 0)
+   return API_EINVAL;
+
+   err = dev_write_net(di->cookie, buf, *len_net);
+
+   } else
err = API_ENODEV;
 
return err;
diff --git a/api/api_private.h b/api/api_private.h
index 8d97ca95a2..07fd50ad3a 100644
--- a/api/api_private.h
+++ b/api/api_private.h
@@ -22,6 +22,7 @@ int   dev_close_stor(void *);
 intdev_close_net(void *);
 
 lbasize_t  dev_read_stor(void *, void *, lbasize_t, lbastart_t);
+lbasize_t  dev_write_stor(void *, void *, lbasize_t, lbastart_t);
 intdev_read_net(void *, void *, int);
 intdev_write_net(void *, void *, int);
 
diff --git a/api/api_storage.c b/api/api_storage.c
index 2b90c18aae..7ae03ac230 100644
--- a/api/api_storage.c
+++ b/api/api_storage.c
@@ -349,3 +349,27 @@ lbasize_t dev_read_stor(void *cookie, void *buf, lbasize_t 
len, lbastart_t start
return dd->block_read(dd, start, len, buf);
 #endif /* defined(CONFIG_BLK) */
 }
+
+
+lbasize_t dev_write_stor(void *cookie, void *buf, lbasize_t len, lbastart_t 
start)
+{
+   struct blk_desc *dd = (struct blk_desc *)cookie;
+   int type = dev_stor_type(dd);
+
+   if (type == ENUM_MAX)
+   return 0;
+
+   if (!dev_stor_is_valid(type, dd))
+   return 0;
+
+#ifdef CONFIG_BLK
+   return blk_dwrite(dd, start, len, buf);
+#else
+   if (dd->block_write 

[U-Boot] [PATCH] api: storage: Fix enumeration of storage devices

2018-12-18 Thread Cristian Ciocaltea
dev_stor_get() is not able to find the next available device in the current
storage group when the previous enumerated device belongs to a different
group or class (e.g. network).

The root cause is the device group iterator not being reset after an
unsuccessful search for the last returned device so that the following
search for the next available device will start from beginning.

The issue has been identified by loading and booting GRUB in a QEMU
vexpress-a9 environment.

Signed-off-by: Cristian Ciocaltea 
---

 api/api_storage.c | 5 +
 1 file changed, 5 insertions(+)

diff --git a/api/api_storage.c b/api/api_storage.c
index 8aeeda2715..2b90c18aae 100644
--- a/api/api_storage.c
+++ b/api/api_storage.c
@@ -99,6 +99,7 @@ static int dev_stor_get(int type, int *more, struct 
device_info *di)
 {
struct blk_desc *dd;
int found = 0;
+   int found_last = 0;
int i = 0;
 
/* Wasn't configured for this type, return 0 directly */
@@ -111,9 +112,13 @@ static int dev_stor_get(int type, int *more, struct 
device_info *di)
if (di->cookie ==
(void *)blk_get_dev(specs[type].name, i)) {
i += 1;
+   found_last = 1;
break;
}
}
+
+   if (!found_last)
+   i = 0;
}
 
for (; i < specs[type].max_dev; i++) {
-- 
2.17.1

___
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot