aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTom Rini <trini@konsulko.com>2024-09-13 08:20:25 -0600
committerTom Rini <trini@konsulko.com>2024-09-13 08:20:25 -0600
commit35394e1ea77ba0ad971d9115bd965a2403c0e031 (patch)
treec42dec5a1ecdcbae74a7b62603dadf874542ee68
parent9eb0d731d800b4fbc8e9ed0178fec0d6f201d911 (diff)
parent7de51622a2cf901e888d703a7bea33ad16645d3b (diff)
downloadu-boot-35394e1ea77ba0ad971d9115bd965a2403c0e031.tar.gz
Merge tag 'efi-next-20241024' of https://source.denx.de/u-boot/custodians/u-boot-efi into next
Pull request efi-next-20241024 UEFI: * Use generated UUIDs in UEFI capsules: - efi: define struct efi_guid - lib: uuid: add UUID v5 support - efi: add a helper to generate dynamic UUIDs - doc: uefi: document dynamic UUID generation - sandbox: switch to dynamic UUIDs - lib: uuid: supporting building as part of host tools - include: export uuid.h - tools: mkeficapsule: use u-boot UUID library - tools: mkeficapsule: support generating dynamic GUIDs - test: lib/uuid: add unit tests for dynamic UUIDs - test: lib/uuid: add tests for UUID version/variant bits * Minor code clean-up - shorten efi_bootmgr_release_uridp_resource() - rename efi_bootmgr_image_return_notify - return the correct error in efi_bootmgr_release_uridp() - Kconfig: clean up the efi configuration status - Use puts() in cout so that console recording works - Put back copyright message in helloworld.c
-rw-r--r--arch/arm/mach-rockchip/board.c2
-rw-r--r--board/cobra5272/flash.c2
-rw-r--r--board/gardena/smart-gateway-mt7688/board.c2
-rw-r--r--board/sandbox/sandbox.c16
-rw-r--r--board/socrates/socrates.c2
-rw-r--r--board/xilinx/common/board.c2
-rw-r--r--boot/Kconfig2
-rw-r--r--cmd/efi.c2
-rw-r--r--cmd/efi_common.c2
-rw-r--r--cmd/flash.c2
-rw-r--r--cmd/gpt.c2
-rw-r--r--cmd/nvedit_efi.c2
-rw-r--r--cmd/x86/hob.c2
-rw-r--r--common/flash.c2
-rw-r--r--disk/part_efi.c2
-rw-r--r--doc/develop/uefi/uefi.rst27
-rw-r--r--doc/mkeficapsule.123
-rw-r--r--drivers/firmware/arm-ffa/arm-ffa-uclass.c2
-rw-r--r--env/sf.c2
-rw-r--r--fs/btrfs/btrfs.c2
-rw-r--r--fs/btrfs/compat.h2
-rw-r--r--fs/btrfs/disk-io.c2
-rw-r--r--fs/ext4/ext4fs.c2
-rw-r--r--include/efi.h2
-rw-r--r--include/fwu.h2
-rw-r--r--include/part.h2
-rw-r--r--include/rkmtd.h2
-rw-r--r--include/sandbox_efi_capsule.h6
-rw-r--r--include/u-boot/uuid.h (renamed from include/uuid.h)21
-rw-r--r--lib/Kconfig3
-rw-r--r--lib/acpi/acpi_dp.c2
-rw-r--r--lib/acpi/acpigen.c2
-rw-r--r--lib/efi/Kconfig5
-rw-r--r--lib/efi/efi_app.c2
-rw-r--r--lib/efi_loader/Kconfig215
-rw-r--r--lib/efi_loader/efi_bootmgr.c28
-rw-r--r--lib/efi_loader/efi_capsule.c1
-rw-r--r--lib/efi_loader/efi_console.c2
-rw-r--r--lib/efi_loader/efi_device_path.c2
-rw-r--r--lib/efi_loader/efi_firmware.c55
-rw-r--r--lib/efi_loader/efi_variable.c2
-rw-r--r--lib/efi_loader/helloworld.c3
-rw-r--r--lib/fwu_updates/fwu_mtd.c2
-rw-r--r--lib/uuid.c103
-rw-r--r--lib/vsprintf.c2
-rw-r--r--net/bootp.c2
-rw-r--r--test/dm/acpi_dp.c2
-rw-r--r--test/dm/acpigen.c2
-rw-r--r--test/lib/uuid.c124
-rw-r--r--test/py/tests/test_efi_capsule/test_capsule_firmware_fit.py2
-rw-r--r--test/py/tests/test_efi_capsule/test_capsule_firmware_raw.py8
-rw-r--r--test/py/tests/test_efi_capsule/test_capsule_firmware_signed_fit.py2
-rw-r--r--test/py/tests/test_efi_capsule/test_capsule_firmware_signed_raw.py4
-rw-r--r--test/py/tests/test_efi_capsule/version.dtso6
-rw-r--r--tools/Makefile8
-rw-r--r--tools/binman/etype/efi_capsule.py2
-rw-r--r--tools/binman/ftest.py2
-rw-r--r--tools/eficapsule.h2
-rw-r--r--tools/mkeficapsule.c208
59 files changed, 692 insertions, 252 deletions
diff --git a/arch/arm/mach-rockchip/board.c b/arch/arm/mach-rockchip/board.c
index 8a57b8217ff..0fdf9365b41 100644
--- a/arch/arm/mach-rockchip/board.c
+++ b/arch/arm/mach-rockchip/board.c
@@ -25,7 +25,7 @@
#include <part.h>
#include <ram.h>
#include <syscon.h>
-#include <uuid.h>
+#include <u-boot/uuid.h>
#include <u-boot/crc.h>
#include <u-boot/sha256.h>
#include <asm/cache.h>
diff --git a/board/cobra5272/flash.c b/board/cobra5272/flash.c
index 616842e62f4..f16f2f1184f 100644
--- a/board/cobra5272/flash.c
+++ b/board/cobra5272/flash.c
@@ -11,7 +11,7 @@
#include <irq_func.h>
#include <stdio.h>
#include <time.h>
-#include <uuid.h>
+#include <u-boot/uuid.h>
#include <vsprintf.h>
#include <linux/delay.h>
#include <linux/string.h>
diff --git a/board/gardena/smart-gateway-mt7688/board.c b/board/gardena/smart-gateway-mt7688/board.c
index c6b14bed41f..eb7fcd630a1 100644
--- a/board/gardena/smart-gateway-mt7688/board.c
+++ b/board/gardena/smart-gateway-mt7688/board.c
@@ -16,7 +16,7 @@
#include <linux/delay.h>
#include <linux/stringify.h>
#include <u-boot/crc.h>
-#include <uuid.h>
+#include <u-boot/uuid.h>
#include <linux/ctype.h>
#include <linux/io.h>
diff --git a/board/sandbox/sandbox.c b/board/sandbox/sandbox.c
index 802596569c6..d97945e58fc 100644
--- a/board/sandbox/sandbox.c
+++ b/board/sandbox/sandbox.c
@@ -32,34 +32,18 @@
gd_t *gd;
#if IS_ENABLED(CONFIG_EFI_HAVE_CAPSULE_SUPPORT)
-/* GUIDs for capsule updatable firmware images */
-#define SANDBOX_UBOOT_IMAGE_GUID \
- EFI_GUID(0x09d7cf52, 0x0720, 0x4710, 0x91, 0xd1, \
- 0x08, 0x46, 0x9b, 0x7f, 0xe9, 0xc8)
-
-#define SANDBOX_UBOOT_ENV_IMAGE_GUID \
- EFI_GUID(0x5a7021f5, 0xfef2, 0x48b4, 0xaa, 0xba, \
- 0x83, 0x2e, 0x77, 0x74, 0x18, 0xc0)
-
-#define SANDBOX_FIT_IMAGE_GUID \
- EFI_GUID(0x3673b45d, 0x6a7c, 0x46f3, 0x9e, 0x60, \
- 0xad, 0xab, 0xb0, 0x3f, 0x79, 0x37)
-
struct efi_fw_image fw_images[] = {
#if defined(CONFIG_EFI_CAPSULE_FIRMWARE_RAW)
{
- .image_type_id = SANDBOX_UBOOT_IMAGE_GUID,
.fw_name = u"SANDBOX-UBOOT",
.image_index = 1,
},
{
- .image_type_id = SANDBOX_UBOOT_ENV_IMAGE_GUID,
.fw_name = u"SANDBOX-UBOOT-ENV",
.image_index = 2,
},
#elif defined(CONFIG_EFI_CAPSULE_FIRMWARE_FIT)
{
- .image_type_id = SANDBOX_FIT_IMAGE_GUID,
.fw_name = u"SANDBOX-FIT",
.image_index = 1,
},
diff --git a/board/socrates/socrates.c b/board/socrates/socrates.c
index 6e6e276cc74..5e5a45ee00d 100644
--- a/board/socrates/socrates.c
+++ b/board/socrates/socrates.c
@@ -15,7 +15,7 @@
#include <env.h>
#include <init.h>
#include <pci.h>
-#include <uuid.h>
+#include <u-boot/uuid.h>
#include <asm/global_data.h>
#include <asm/processor.h>
#include <asm/immap_85xx.h>
diff --git a/board/xilinx/common/board.c b/board/xilinx/common/board.c
index 3440402ab46..1c100d61589 100644
--- a/board/xilinx/common/board.c
+++ b/board/xilinx/common/board.c
@@ -30,7 +30,7 @@
#include <soc.h>
#include <linux/ctype.h>
#include <linux/kernel.h>
-#include <uuid.h>
+#include <u-boot/uuid.h>
#include "fru.h"
diff --git a/boot/Kconfig b/boot/Kconfig
index 7ac34574079..925afe06a19 100644
--- a/boot/Kconfig
+++ b/boot/Kconfig
@@ -1,5 +1,7 @@
menu "Boot options"
+source "lib/efi_loader/Kconfig"
+
menu "Boot images"
config ANDROID_BOOT_IMAGE
diff --git a/cmd/efi.c b/cmd/efi.c
index 6bed2d743ba..687ccb52042 100644
--- a/cmd/efi.c
+++ b/cmd/efi.c
@@ -11,7 +11,7 @@
#include <log.h>
#include <malloc.h>
#include <sort.h>
-#include <uuid.h>
+#include <u-boot/uuid.h>
#include <asm/global_data.h>
DECLARE_GLOBAL_DATA_PTR;
diff --git a/cmd/efi_common.c b/cmd/efi_common.c
index c46764e6eea..d2f2b59e9e3 100644
--- a/cmd/efi_common.c
+++ b/cmd/efi_common.c
@@ -8,7 +8,7 @@
#include <efi.h>
#include <efi_api.h>
-#include <uuid.h>
+#include <u-boot/uuid.h>
void efi_show_tables(struct efi_system_table *systab)
{
diff --git a/cmd/flash.c b/cmd/flash.c
index de0e04f09cf..fd660ec477c 100644
--- a/cmd/flash.c
+++ b/cmd/flash.c
@@ -10,7 +10,7 @@
#include <command.h>
#include <log.h>
#include <vsprintf.h>
-#include <uuid.h>
+#include <u-boot/uuid.h>
#if defined(CONFIG_CMD_MTDPARTS)
#include <jffs2/jffs2.h>
diff --git a/cmd/gpt.c b/cmd/gpt.c
index 86b7701886a..27aea2df197 100644
--- a/cmd/gpt.c
+++ b/cmd/gpt.c
@@ -19,7 +19,7 @@
#include <part_efi.h>
#include <part.h>
#include <exports.h>
-#include <uuid.h>
+#include <u-boot/uuid.h>
#include <linux/ctype.h>
#include <div64.h>
#include <memalign.h>
diff --git a/cmd/nvedit_efi.c b/cmd/nvedit_efi.c
index 64ae2ad2ce2..32b7d049074 100644
--- a/cmd/nvedit_efi.c
+++ b/cmd/nvedit_efi.c
@@ -15,7 +15,7 @@
#include <malloc.h>
#include <mapmem.h>
#include <rtc.h>
-#include <uuid.h>
+#include <u-boot/uuid.h>
#include <linux/kernel.h>
/*
diff --git a/cmd/x86/hob.c b/cmd/x86/hob.c
index 2dd30808bd1..d3713cef331 100644
--- a/cmd/x86/hob.c
+++ b/cmd/x86/hob.c
@@ -5,7 +5,7 @@
#include <command.h>
#include <efi.h>
-#include <uuid.h>
+#include <u-boot/uuid.h>
#include <asm/global_data.h>
#include <asm/hob.h>
#include <asm/fsp/fsp_hob.h>
diff --git a/common/flash.c b/common/flash.c
index 24ddc8bee72..226646c6868 100644
--- a/common/flash.c
+++ b/common/flash.c
@@ -8,7 +8,7 @@
#include <flash.h>
#include <log.h>
-#include <uuid.h>
+#include <u-boot/uuid.h>
#include <linux/string.h>
#include <mtd/cfi_flash.h>
diff --git a/disk/part_efi.c b/disk/part_efi.c
index b1a03bd165e..580821a6ee9 100644
--- a/disk/part_efi.c
+++ b/disk/part_efi.c
@@ -15,7 +15,7 @@
#include <blk.h>
#include <log.h>
#include <part.h>
-#include <uuid.h>
+#include <u-boot/uuid.h>
#include <asm/cache.h>
#include <asm/global_data.h>
#include <asm/unaligned.h>
diff --git a/doc/develop/uefi/uefi.rst b/doc/develop/uefi/uefi.rst
index d450b12bf80..94482758573 100644
--- a/doc/develop/uefi/uefi.rst
+++ b/doc/develop/uefi/uefi.rst
@@ -449,6 +449,33 @@ practice. Getting this information from the firmware itself is more
secure, assuming the firmware has been verified by a previous stage
boot loader.
+Dynamic Firmware Update GUIDs
+*****************************
+
+The image_type_id contains a GUID value which is specific to the image
+and board being updated, that is to say it should uniquely identify the
+board model (and revision if relevant) and image pair. Traditionally,
+these GUIDs are generated manually and hardcoded on a per-board basis,
+however this scheme makes it difficult to scale up to support many
+boards.
+
+To address this, v5 GUIDs can be used to generate board-specific GUIDs
+at runtime, based on the board's devicetree root compatible
+(e.g. "qcom,qrb5165-rb5").
+
+These strings are combined with the fw_image name to generate GUIDs for
+each image. Support for dynamic UUIDs can be enabled by generating a new
+namespace UUID and setting EFI_CAPSULE_NAMESPACE_GUID to it. Dynamic GUID
+generation is only enabled if the image_type_id property is unset for your
+firmware images, this is to avoid breaking existing boards with hardcoded
+GUIDs.
+
+The mkeficapsule tool can be used to determine the GUIDs for a particular
+board and image. It can be found in the tools directory.
+
+Firmware update images
+**********************
+
The firmware images structure defines the GUID values, image index
values and the name of the images that are to be updated through
the capsule update feature. These values are to be defined as part of
diff --git a/doc/mkeficapsule.1 b/doc/mkeficapsule.1
index c3d0f21488a..a5545f7898a 100644
--- a/doc/mkeficapsule.1
+++ b/doc/mkeficapsule.1
@@ -10,6 +10,9 @@ mkeficapsule \- Generate EFI capsule file for U-Boot
.B mkeficapsule
.RI [ options ] " " [ image-blob ] " " capsule-file
+.B mkeficapsule
+.RI guidgen " " [ GUID ] " " DTB " " IMAGE_NAME...
+
.SH "DESCRIPTION"
The
.B mkeficapsule
@@ -42,6 +45,10 @@ multiple binary blobs in a single capsule file.
This type of image file can be generated by
.BR mkimage .
+mkeficapsule can also be used to simulate the dynamic GUID generation used to
+identify firmware images in capsule updates by providing the namespace guid, dtb
+for the board, and a list of firmware images.
+
.SH "OPTIONS"
.TP
@@ -117,6 +124,22 @@ at every firmware update.
.B "-d\fR,\fB --dump_sig"
Dump signature data into *.p7 file
+.SH "GUIDGEN OPTIONS"
+
+.TP
+.B "[GUID]"
+The namespace/salt GUID, by default this is EFI_CAPSULE_NAMESPACE_GUID.
+The format is:
+ xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
+
+.TP
+.B DTB
+The device tree blob file for the board.
+
+.TP
+.B IMAGE_NAME...
+The names of the firmware images to generate GUIDs for.
+
.PP
.SH FILES
.TP
diff --git a/drivers/firmware/arm-ffa/arm-ffa-uclass.c b/drivers/firmware/arm-ffa/arm-ffa-uclass.c
index e0767fc7551..96c64964bb7 100644
--- a/drivers/firmware/arm-ffa/arm-ffa-uclass.c
+++ b/drivers/firmware/arm-ffa/arm-ffa-uclass.c
@@ -11,7 +11,7 @@
#include <log.h>
#include <malloc.h>
#include <string.h>
-#include <uuid.h>
+#include <u-boot/uuid.h>
#include <asm/global_data.h>
#include <dm/device-internal.h>
#include <dm/devres.h>
diff --git a/env/sf.c b/env/sf.c
index 906b85b0db4..21ac0c202e7 100644
--- a/env/sf.c
+++ b/env/sf.c
@@ -16,7 +16,7 @@
#include <spi_flash.h>
#include <search.h>
#include <errno.h>
-#include <uuid.h>
+#include <u-boot/uuid.h>
#include <asm/cache.h>
#include <asm/global_data.h>
#include <dm/device-internal.h>
diff --git a/fs/btrfs/btrfs.c b/fs/btrfs/btrfs.c
index 1149a3b2007..350cff0cbca 100644
--- a/fs/btrfs/btrfs.c
+++ b/fs/btrfs/btrfs.c
@@ -7,7 +7,7 @@
#include <config.h>
#include <malloc.h>
-#include <uuid.h>
+#include <u-boot/uuid.h>
#include <linux/time.h>
#include "btrfs.h"
#include "crypto/hash.h"
diff --git a/fs/btrfs/compat.h b/fs/btrfs/compat.h
index 02173dea5f4..4596b9d1dd3 100644
--- a/fs/btrfs/compat.h
+++ b/fs/btrfs/compat.h
@@ -5,7 +5,7 @@
#include <linux/errno.h>
#include <fs_internal.h>
-#include <uuid.h>
+#include <u-boot/uuid.h>
/* Provide a compatibility layer to make code syncing easier */
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
index 34d9d535121..14efe7218df 100644
--- a/fs/btrfs/disk-io.c
+++ b/fs/btrfs/disk-io.c
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: GPL-2.0+
#include <fs_internal.h>
#include <log.h>
-#include <uuid.h>
+#include <u-boot/uuid.h>
#include <memalign.h>
#include "kernel-shared/btrfs_tree.h"
#include "common/rbtree-utils.h"
diff --git a/fs/ext4/ext4fs.c b/fs/ext4/ext4fs.c
index da59cb008fc..15587e92e3e 100644
--- a/fs/ext4/ext4fs.c
+++ b/fs/ext4/ext4fs.c
@@ -27,7 +27,7 @@
#include <div64.h>
#include <malloc.h>
#include <part.h>
-#include <uuid.h>
+#include <u-boot/uuid.h>
int ext4fs_symlinknest;
struct ext_filesystem ext_fs;
diff --git a/include/efi.h b/include/efi.h
index d5af2139946..84640cf7b25 100644
--- a/include/efi.h
+++ b/include/efi.h
@@ -74,7 +74,7 @@ struct efi_device_path {
* struct { u32 a; u16; b; u16 c; u8 d[8]; }; which is 4-byte
* aligned.
*/
-typedef struct {
+typedef struct efi_guid {
u8 b[16];
} efi_guid_t __attribute__((aligned(4)));
diff --git a/include/fwu.h b/include/fwu.h
index 77ec65e6180..c317613eaaa 100644
--- a/include/fwu.h
+++ b/include/fwu.h
@@ -10,7 +10,7 @@
#include <efi.h>
#include <fwu_mdata.h>
#include <mtd.h>
-#include <uuid.h>
+#include <u-boot/uuid.h>
#include <linux/types.h>
diff --git a/include/part.h b/include/part.h
index 54b986cee63..797b542ef1f 100644
--- a/include/part.h
+++ b/include/part.h
@@ -8,7 +8,7 @@
#include <blk.h>
#include <ide.h>
-#include <uuid.h>
+#include <u-boot/uuid.h>
#include <linker_lists.h>
#include <linux/errno.h>
#include <linux/list.h>
diff --git a/include/rkmtd.h b/include/rkmtd.h
index 145fede6c84..b7479036b39 100644
--- a/include/rkmtd.h
+++ b/include/rkmtd.h
@@ -11,7 +11,7 @@
#define __RKMTD__
#include <part_efi.h>
-#include <uuid.h>
+#include <u-boot/uuid.h>
#define LBA 64 + 512 + 33
diff --git a/include/sandbox_efi_capsule.h b/include/sandbox_efi_capsule.h
index 3e288e8a84a..84d45ec5cfd 100644
--- a/include/sandbox_efi_capsule.h
+++ b/include/sandbox_efi_capsule.h
@@ -6,9 +6,9 @@
#if !defined(_SANDBOX_EFI_CAPSULE_H_)
#define _SANDBOX_EFI_CAPSULE_H_
-#define SANDBOX_UBOOT_IMAGE_GUID "09d7cf52-0720-4710-91d1-08469b7fe9c8"
-#define SANDBOX_UBOOT_ENV_IMAGE_GUID "5a7021f5-fef2-48b4-aaba-832e777418c0"
-#define SANDBOX_FIT_IMAGE_GUID "3673b45d-6a7c-46f3-9e60-adabb03f7937"
+#define SANDBOX_UBOOT_IMAGE_GUID "985f2937-7c2e-5e9a-8a5e-8e063312964b"
+#define SANDBOX_UBOOT_ENV_IMAGE_GUID "9e339473-c2eb-530a-a69b-0cd6bbbed40e"
+#define SANDBOX_FIT_IMAGE_GUID "46610520-469e-59dc-a8dd-c11832b877ea"
#define SANDBOX_INCORRECT_GUID "058b7d83-50d5-4c47-a195-60d86ad341c4"
#define UBOOT_FIT_IMAGE "u-boot_bin_env.itb"
diff --git a/include/uuid.h b/include/u-boot/uuid.h
index f5a941250f4..7f8414dc906 100644
--- a/include/uuid.h
+++ b/include/u-boot/uuid.h
@@ -11,6 +11,7 @@
#define __UUID_H__
#include <linux/bitops.h>
+#include <linux/kconfig.h>
/*
* UUID - Universally Unique IDentifier - 128 bits unique number.
@@ -46,8 +47,8 @@
* When converting to a binary UUID, le means the field should be converted
* to little endian and be means it should be converted to big endian.
*
- * UUID is also used as GUID (Globally Unique Identifier) with the same binary
- * format but it differs in string format like below.
+ * UUID is also used as GUID (Globally Unique Identifier) with the same format
+ * but with some fields stored in little endian.
*
* GUID:
* 0 9 14 19 24
@@ -69,8 +70,8 @@ struct uuid {
/* Bits of a bitmask specifying the output format for GUIDs */
#define UUID_STR_FORMAT_STD 0
-#define UUID_STR_FORMAT_GUID BIT(0)
-#define UUID_STR_UPPER_CASE BIT(1)
+#define UUID_STR_FORMAT_GUID 0x1
+#define UUID_STR_UPPER_CASE 0x2
/* Use UUID_STR_LEN + 1 for string space */
#define UUID_STR_LEN 36
@@ -143,6 +144,18 @@ void gen_rand_uuid(unsigned char *uuid_bin);
*/
void gen_rand_uuid_str(char *uuid_str, int str_format);
+struct efi_guid;
+
+/**
+ * gen_v5_guid() - generate little endian v5 GUID from namespace and other seed data.
+ *
+ * @namespace: pointer to UUID namespace salt
+ * @guid: pointer to allocated GUID output
+ * @...: NULL terminated list of seed data as pairs of pointers
+ * to data and their lengths
+ */
+void gen_v5_guid(const struct uuid *namespace, struct efi_guid *guid, ...);
+
/**
* uuid_str_to_le_bin() - Convert string UUID to little endian binary data.
* @uuid_str: pointer to UUID string
diff --git a/lib/Kconfig b/lib/Kconfig
index 5f282ecb543..1dd4f271595 100644
--- a/lib/Kconfig
+++ b/lib/Kconfig
@@ -73,6 +73,7 @@ config HAVE_PRIVATE_LIBGCC
config LIB_UUID
bool
+ select SHA1
config RANDOM_UUID
bool "GPT Random UUID generation"
@@ -1081,8 +1082,6 @@ config SMBIOS_PARSER
help
A simple parser for SMBIOS data.
-source "lib/efi/Kconfig"
-source "lib/efi_loader/Kconfig"
source "lib/optee/Kconfig"
config TEST_FDTDEC
diff --git a/lib/acpi/acpi_dp.c b/lib/acpi/acpi_dp.c
index 6733809986a..5714acce088 100644
--- a/lib/acpi/acpi_dp.c
+++ b/lib/acpi/acpi_dp.c
@@ -9,7 +9,7 @@
#include <dm.h>
#include <log.h>
#include <malloc.h>
-#include <uuid.h>
+#include <u-boot/uuid.h>
#include <acpi/acpigen.h>
#include <acpi/acpi_dp.h>
#include <dm/acpi.h>
diff --git a/lib/acpi/acpigen.c b/lib/acpi/acpigen.c
index b95cabb9149..ecff5a50d50 100644
--- a/lib/acpi/acpigen.c
+++ b/lib/acpi/acpigen.c
@@ -10,7 +10,7 @@
#include <dm.h>
#include <log.h>
-#include <uuid.h>
+#include <u-boot/uuid.h>
#include <acpi/acpigen.h>
#include <acpi/acpi_device.h>
#include <acpi/acpi_table.h>
diff --git a/lib/efi/Kconfig b/lib/efi/Kconfig
index c2b9bb73f71..81ed3e66b34 100644
--- a/lib/efi/Kconfig
+++ b/lib/efi/Kconfig
@@ -1,3 +1,6 @@
+menu "U-Boot as UEFI application"
+ depends on X86
+
config EFI
bool "Support running U-Boot from EFI"
depends on X86
@@ -72,3 +75,5 @@ config EFI_RAM_SIZE
use. U-Boot allocates this from EFI on start-up (along with a few
other smaller amounts) and it can never be increased after that.
It is used as the RAM size in with U-Boot.
+
+endmenu
diff --git a/lib/efi/efi_app.c b/lib/efi/efi_app.c
index 88332c3c910..9b94a93ee4f 100644
--- a/lib/efi/efi_app.c
+++ b/lib/efi/efi_app.c
@@ -17,7 +17,7 @@
#include <init.h>
#include <malloc.h>
#include <sysreset.h>
-#include <uuid.h>
+#include <u-boot/uuid.h>
#include <asm/global_data.h>
#include <linux/err.h>
#include <linux/types.h>
diff --git a/lib/efi_loader/Kconfig b/lib/efi_loader/Kconfig
index 6ffefa9103f..e58b8825605 100644
--- a/lib/efi_loader/Kconfig
+++ b/lib/efi_loader/Kconfig
@@ -1,3 +1,5 @@
+menu "UEFI Support"
+
config EFI_LOADER
bool "Support running UEFI applications"
depends on OF_LIBFDT && ( \
@@ -41,13 +43,58 @@ config EFI_BINARY_EXEC
You may enable CMD_BOOTEFI_BINARY so that you can use bootefi
command to do that.
-config EFI_BOOTMGR
- bool "UEFI Boot Manager"
+config EFI_SECURE_BOOT
+ bool "Enable EFI secure boot support"
+ depends on EFI_LOADER && FIT_SIGNATURE
+ select HASH
+ select SHA256
+ select RSA
+ select RSA_VERIFY_WITH_PKEY
+ select IMAGE_SIGN_INFO
+ select ASYMMETRIC_KEY_TYPE
+ select ASYMMETRIC_PUBLIC_KEY_SUBTYPE
+ select X509_CERTIFICATE_PARSER
+ select PKCS7_MESSAGE_PARSER
+ select PKCS7_VERIFY
+ select MSCODE_PARSER
+ select EFI_SIGNATURE_SUPPORT
+ help
+ Select this option to enable EFI secure boot support.
+ Once SecureBoot mode is enforced, any EFI binary can run only if
+ it is signed with a trusted key. To do that, you need to install,
+ at least, PK, KEK and db.
+
+config EFI_SIGNATURE_SUPPORT
+ bool
+
+menu "UEFI services"
+
+config EFI_GET_TIME
+ bool "GetTime() runtime service"
+ depends on DM_RTC
default y
help
- Select this option if you want to select the UEFI binary to be booted
- via UEFI variables Boot####, BootOrder, and BootNext. You should also
- normally enable CMD_BOOTEFI_BOOTMGR so that the command is available.
+ Provide the GetTime() runtime service at boottime. This service
+ can be used by an EFI application to read the real time clock.
+
+config EFI_SET_TIME
+ bool "SetTime() runtime service"
+ depends on EFI_GET_TIME
+ default y if ARCH_QEMU || SANDBOX
+ help
+ Provide the SetTime() runtime service at boottime. This service
+ can be used by an EFI application to adjust the real time clock.
+
+config EFI_HAVE_RUNTIME_RESET
+ # bool "Reset runtime service is available"
+ bool
+ default y
+ depends on ARCH_BCM283X || FSL_LAYERSCAPE || PSCI_RESET || \
+ SANDBOX || SYSRESET_SBI || SYSRESET_X86
+
+endmenu
+
+menu "UEFI Variables"
choice
prompt "Store for non-volatile UEFI variables"
@@ -172,30 +219,18 @@ config EFI_VAR_BUF_SIZE
Minimum 4096, default 131072
-config EFI_GET_TIME
- bool "GetTime() runtime service"
- depends on DM_RTC
- default y
+config EFI_PLATFORM_LANG_CODES
+ string "Language codes supported by firmware"
+ default "en-US"
help
- Provide the GetTime() runtime service at boottime. This service
- can be used by an EFI application to read the real time clock.
+ This value is used to initialize the PlatformLangCodes variable. Its
+ value is a semicolon (;) separated list of language codes in native
+ RFC 4646 format, e.g. "en-US;de-DE". The first language code is used
+ to initialize the PlatformLang variable.
-config EFI_SET_TIME
- bool "SetTime() runtime service"
- depends on EFI_GET_TIME
- default y if ARCH_QEMU || SANDBOX
- help
- Provide the SetTime() runtime service at boottime. This service
- can be used by an EFI application to adjust the real time clock.
+endmenu
-config EFI_SCROLL_ON_CLEAR_SCREEN
- bool "Avoid overwriting previous output on clear screen"
- help
- Instead of erasing the screen content when the console screen should
- be cleared, emit blank new lines so that previous output is scrolled
- out of sight rather than overwritten. On serial consoles this allows
- to capture complete boot logs (except for interactive menus etc.)
- and can ease debugging related issues.
+menu "Capsule support"
config EFI_HAVE_CAPSULE_SUPPORT
bool
@@ -237,6 +272,18 @@ config EFI_CAPSULE_ON_DISK_EARLY
executed as part of U-Boot initialisation so that they will
surely take place whatever is set to distro_bootcmd.
+config EFI_CAPSULE_NAMESPACE_GUID
+ string "Namespace for dynamic capsule GUIDs"
+ # v4 UUID as a default for upstream U-Boot boards
+ default "8c9f137e-91dc-427b-b2d6-b420faebaf2a"
+ depends on EFI_HAVE_CAPSULE_SUPPORT
+ help
+ Define the namespace or "salt" GUID used to generate the per-image
+ GUIDs. This should be a GUID in the standard 8-4-4-4-12 format.
+
+ Device vendors are expected to generate their own namespace GUID
+ to avoid conflicts with upstream/community images.
+
config EFI_CAPSULE_FIRMWARE
bool
@@ -309,6 +356,10 @@ config EFI_CAPSULE_CRT_FILE
embedded in the platform's device tree and used for capsule
authentication at the time of capsule update.
+endmenu
+
+menu "UEFI protocol support"
+
config EFI_DEVICE_PATH_TO_TEXT
bool "Device path to text protocol"
default y
@@ -362,39 +413,6 @@ config EFI_UNICODE_CAPITALIZATION
endif
-config EFI_LOADER_BOUNCE_BUFFER
- bool "EFI Applications use bounce buffers for DMA operations"
- help
- Some hardware does not support DMA to full 64bit addresses. For this
- hardware we can create a bounce buffer so that payloads don't have to
- worry about platform details.
-
-config EFI_PLATFORM_LANG_CODES
- string "Language codes supported by firmware"
- default "en-US"
- help
- This value is used to initialize the PlatformLangCodes variable. Its
- value is a semicolon (;) separated list of language codes in native
- RFC 4646 format, e.g. "en-US;de-DE". The first language code is used
- to initialize the PlatformLang variable.
-
-config EFI_HAVE_RUNTIME_RESET
- # bool "Reset runtime service is available"
- bool
- default y
- depends on ARCH_BCM283X || FSL_LAYERSCAPE || PSCI_RESET || \
- SANDBOX || SYSRESET_SBI || SYSRESET_X86
-
-config EFI_GRUB_ARM32_WORKAROUND
- bool "Workaround for GRUB on 32bit ARM"
- default n if ARCH_BCM283X || ARCH_SUNXI || ARCH_QEMU
- default y
- depends on ARM && !ARM64
- help
- GRUB prior to version 2.04 requires U-Boot to disable caches. This
- workaround currently is also needed on systems with caches that
- cannot be managed via CP15.
-
config EFI_RNG_PROTOCOL
bool "EFI_RNG_PROTOCOL support"
depends on DM_RNG
@@ -447,29 +465,36 @@ config EFI_LOAD_FILE2_INITRD
installed and Linux 5.7+ will ignore any initrd=<ramdisk> command line
argument.
-config EFI_SECURE_BOOT
- bool "Enable EFI secure boot support"
- depends on EFI_LOADER && FIT_SIGNATURE
- select HASH
- select SHA256
- select RSA
- select RSA_VERIFY_WITH_PKEY
- select IMAGE_SIGN_INFO
- select ASYMMETRIC_KEY_TYPE
- select ASYMMETRIC_PUBLIC_KEY_SUBTYPE
- select X509_CERTIFICATE_PARSER
- select PKCS7_MESSAGE_PARSER
- select PKCS7_VERIFY
- select MSCODE_PARSER
- select EFI_SIGNATURE_SUPPORT
+config EFI_RISCV_BOOT_PROTOCOL
+ bool "RISCV_EFI_BOOT_PROTOCOL support"
+ default y
+ depends on RISCV
help
- Select this option to enable EFI secure boot support.
- Once SecureBoot mode is enforced, any EFI binary can run only if
- it is signed with a trusted key. To do that, you need to install,
- at least, PK, KEK and db.
+ The EFI_RISCV_BOOT_PROTOCOL is used to transfer the boot hart ID
+ to the next boot stage. It should be enabled as it is meant to
+ replace the transfer via the device-tree. The latter is not
+ possible on systems using ACPI.
-config EFI_SIGNATURE_SUPPORT
- bool
+endmenu
+
+menu "Misc options"
+config EFI_LOADER_BOUNCE_BUFFER
+ bool "EFI Applications use bounce buffers for DMA operations"
+ depends on ARM64
+ help
+ Some hardware does not support DMA to full 64bit addresses. For this
+ hardware we can create a bounce buffer so that payloads don't have to
+ worry about platform details.
+
+config EFI_GRUB_ARM32_WORKAROUND
+ bool "Workaround for GRUB on 32bit ARM"
+ default n if ARCH_BCM283X || ARCH_SUNXI || ARCH_QEMU
+ default y
+ depends on ARM && !ARM64
+ help
+ GRUB prior to version 2.04 requires U-Boot to disable caches. This
+ workaround currently is also needed on systems with caches that
+ cannot be managed via CP15.
config EFI_ESRT
bool "Enable the UEFI ESRT generation"
@@ -496,15 +521,26 @@ config EFI_EBBR_2_1_CONFORMANCE
help
Enabling this option adds the EBBRv2.1 conformance entry to the ECPT UEFI table.
-config EFI_RISCV_BOOT_PROTOCOL
- bool "RISCV_EFI_BOOT_PROTOCOL support"
+config EFI_SCROLL_ON_CLEAR_SCREEN
+ bool "Avoid overwriting previous output on clear screen"
+ help
+ Instead of erasing the screen content when the console screen should
+ be cleared, emit blank new lines so that previous output is scrolled
+ out of sight rather than overwritten. On serial consoles this allows
+ to capture complete boot logs (except for interactive menus etc.)
+ and can ease debugging related issues.
+
+endmenu
+
+menu "EFI bootmanager"
+
+config EFI_BOOTMGR
+ bool "UEFI Boot Manager"
default y
- depends on RISCV
help
- The EFI_RISCV_BOOT_PROTOCOL is used to transfer the boot hart ID
- to the next boot stage. It should be enabled as it is meant to
- replace the transfer via the device-tree. The latter is not
- possible on systems using ACPI.
+ Select this option if you want to select the UEFI binary to be booted
+ via UEFI variables Boot####, BootOrder, and BootNext. You should also
+ normally enable CMD_BOOTEFI_BOOTMGR so that the command is available.
config EFI_HTTP_BOOT
bool "EFI HTTP Boot support"
@@ -514,5 +550,10 @@ config EFI_HTTP_BOOT
help
Enabling this option adds EFI HTTP Boot support. It allows to
directly boot from network.
+endmenu
endif
+
+source "lib/efi/Kconfig"
+
+endmenu
diff --git a/lib/efi_loader/efi_bootmgr.c b/lib/efi_loader/efi_bootmgr.c
index 589d3996b68..a3aa2b8d1b9 100644
--- a/lib/efi_loader/efi_bootmgr.c
+++ b/lib/efi_loader/efi_bootmgr.c
@@ -380,14 +380,15 @@ err:
}
/**
- * efi_bootmgr_release_uridp_resource() - cleanup uri device path resource
+ * efi_bootmgr_release_uridp() - cleanup uri device path resource
*
* @ctx: event context
* Return: status code
*/
-efi_status_t efi_bootmgr_release_uridp_resource(struct uridp_context *ctx)
+efi_status_t efi_bootmgr_release_uridp(struct uridp_context *ctx)
{
efi_status_t ret = EFI_SUCCESS;
+ efi_status_t ret2 = EFI_SUCCESS;
if (!ctx)
return ret;
@@ -407,32 +408,33 @@ efi_status_t efi_bootmgr_release_uridp_resource(struct uridp_context *ctx)
/* cleanup for PE-COFF image */
if (ctx->mem_handle) {
- ret = efi_uninstall_multiple_protocol_interfaces(
- ctx->mem_handle, &efi_guid_device_path, ctx->loaded_dp,
- NULL);
- if (ret != EFI_SUCCESS)
+ ret2 = efi_uninstall_multiple_protocol_interfaces(ctx->mem_handle,
+ &efi_guid_device_path,
+ ctx->loaded_dp,
+ NULL);
+ if (ret2 != EFI_SUCCESS)
log_err("Uninstall device_path protocol failed\n");
}
efi_free_pool(ctx->loaded_dp);
free(ctx);
- return ret;
+ return ret == EFI_SUCCESS ? ret2 : ret;
}
/**
- * efi_bootmgr_image_return_notify() - return to efibootmgr callback
+ * efi_bootmgr_http_return() - return to efibootmgr callback
*
* @event: the event for which this notification function is registered
* @context: event context
*/
-static void EFIAPI efi_bootmgr_image_return_notify(struct efi_event *event,
- void *context)
+static void EFIAPI efi_bootmgr_http_return(struct efi_event *event,
+ void *context)
{
efi_status_t ret;
EFI_ENTRY("%p, %p", event, context);
- ret = efi_bootmgr_release_uridp_resource(context);
+ ret = efi_bootmgr_release_uridp(context);
EFI_EXIT(ret);
}
@@ -533,7 +535,7 @@ static efi_status_t try_load_from_uri_path(struct efi_device_path_uri *uridp,
/* create event for cleanup when the image returns or error occurs */
ret = efi_create_event(EVT_NOTIFY_SIGNAL, TPL_CALLBACK,
- efi_bootmgr_image_return_notify, ctx,
+ efi_bootmgr_http_return, ctx,
&efi_guid_event_group_return_to_efibootmgr,
&event);
if (ret != EFI_SUCCESS) {
@@ -544,7 +546,7 @@ static efi_status_t try_load_from_uri_path(struct efi_device_path_uri *uridp,
return ret;
err:
- efi_bootmgr_release_uridp_resource(ctx);
+ efi_bootmgr_release_uridp(ctx);
return ret;
}
diff --git a/lib/efi_loader/efi_capsule.c b/lib/efi_loader/efi_capsule.c
index 635088f25a1..a4ea2873038 100644
--- a/lib/efi_loader/efi_capsule.c
+++ b/lib/efi_loader/efi_capsule.c
@@ -20,6 +20,7 @@
#include <sort.h>
#include <sysreset.h>
#include <asm/global_data.h>
+#include <u-boot/uuid.h>
#include <crypto/pkcs7.h>
#include <crypto/pkcs7_parser.h>
diff --git a/lib/efi_loader/efi_console.c b/lib/efi_loader/efi_console.c
index c944c10b216..cea50c748aa 100644
--- a/lib/efi_loader/efi_console.c
+++ b/lib/efi_loader/efi_console.c
@@ -181,7 +181,7 @@ static efi_status_t EFIAPI efi_cout_output_string(
}
pos = buf;
utf16_utf8_strcpy(&pos, string);
- fputs(stdout, buf);
+ puts(buf);
free(buf);
/*
diff --git a/lib/efi_loader/efi_device_path.c b/lib/efi_loader/efi_device_path.c
index 0f684590f22..9de3b95d073 100644
--- a/lib/efi_loader/efi_device_path.c
+++ b/lib/efi_loader/efi_device_path.c
@@ -17,7 +17,7 @@
#include <nvme.h>
#include <efi_loader.h>
#include <part.h>
-#include <uuid.h>
+#include <u-boot/uuid.h>
#include <asm-generic/unaligned.h>
#include <linux/compat.h> /* U16_MAX */
diff --git a/lib/efi_loader/efi_firmware.c b/lib/efi_loader/efi_firmware.c
index ba5aba098c0..6650c2b8071 100644
--- a/lib/efi_loader/efi_firmware.c
+++ b/lib/efi_loader/efi_firmware.c
@@ -246,6 +246,55 @@ void efi_firmware_fill_version_info(struct efi_firmware_image_descriptor *image_
}
/**
+ * efi_gen_capsule_guids - generate GUIDs for the images
+ *
+ * Generate the image_type_id for each image in the update_info.images array
+ * using the first compatible from the device tree and a salt
+ * UUID defined at build time.
+ *
+ * Returns: status code
+ */
+static efi_status_t efi_gen_capsule_guids(void)
+{
+ int ret, i;
+ struct uuid namespace;
+ const char *compatible; /* Full array including null bytes */
+ struct efi_fw_image *fw_array;
+
+ fw_array = update_info.images;
+ /* Check if we need to run (there are images and we didn't already generate their IDs) */
+ if (!update_info.num_images ||
+ memchr_inv(&fw_array[0].image_type_id, 0, sizeof(fw_array[0].image_type_id)))
+ return EFI_SUCCESS;
+
+ ret = uuid_str_to_bin(CONFIG_EFI_CAPSULE_NAMESPACE_GUID,
+ (unsigned char *)&namespace, UUID_STR_FORMAT_GUID);
+ if (ret) {
+ log_debug("%s: EFI_CAPSULE_NAMESPACE_GUID is invalid: %d\n", __func__, ret);
+ return EFI_INVALID_PARAMETER;
+ }
+
+ compatible = ofnode_read_string(ofnode_root(), "compatible");
+ if (!compatible) {
+ log_debug("%s: model or compatible not defined\n", __func__);
+ return EFI_INVALID_PARAMETER;
+ }
+
+ for (i = 0; i < update_info.num_images; i++) {
+ gen_v5_guid(&namespace,
+ &fw_array[i].image_type_id,
+ compatible, strlen(compatible),
+ fw_array[i].fw_name, u16_strlen(fw_array[i].fw_name) * sizeof(uint16_t),
+ NULL);
+
+ log_debug("Image %ls UUID %pUl\n", fw_array[i].fw_name,
+ &fw_array[i].image_type_id);
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
* efi_fill_image_desc_array - populate image descriptor array
* @image_info_size: Size of @image_info
* @image_info: Image information
@@ -272,7 +321,7 @@ static efi_status_t efi_fill_image_desc_array(
{
size_t total_size;
struct efi_fw_image *fw_array;
- int i;
+ int i, ret;
total_size = sizeof(*image_info) * update_info.num_images;
@@ -283,6 +332,10 @@ static efi_status_t efi_fill_image_desc_array(
}
*image_info_size = total_size;
+ ret = efi_gen_capsule_guids();
+ if (ret != EFI_SUCCESS)
+ return ret;
+
fw_array = update_info.images;
*descriptor_count = update_info.num_images;
*descriptor_version = EFI_FIRMWARE_IMAGE_DESCRIPTOR_VERSION;
diff --git a/lib/efi_loader/efi_variable.c b/lib/efi_loader/efi_variable.c
index e888c52efe3..f3533f4def3 100644
--- a/lib/efi_loader/efi_variable.c
+++ b/lib/efi_loader/efi_variable.c
@@ -16,7 +16,7 @@
#include <malloc.h>
#include <rtc.h>
#include <search.h>
-#include <uuid.h>
+#include <u-boot/uuid.h>
#include <crypto/pkcs7_parser.h>
#include <linux/compat.h>
#include <u-boot/crc.h>
diff --git a/lib/efi_loader/helloworld.c b/lib/efi_loader/helloworld.c
index bd72822c0b7..586177de0c8 100644
--- a/lib/efi_loader/helloworld.c
+++ b/lib/efi_loader/helloworld.c
@@ -2,6 +2,9 @@
/*
* Hello world EFI application
*
+ * Copyright (c) 2016 Google, Inc
+ * Written by Simon Glass <sjg@chromium.org>
+ *
* Copyright 2020, Heinrich Schuchardt <xypron.glpk@gmx.de>
*
* This test program is used to test the invocation of an EFI application.
diff --git a/lib/fwu_updates/fwu_mtd.c b/lib/fwu_updates/fwu_mtd.c
index c14203b9dd3..554723046f6 100644
--- a/lib/fwu_updates/fwu_mtd.c
+++ b/lib/fwu_updates/fwu_mtd.c
@@ -10,7 +10,7 @@
#include <log.h>
#include <malloc.h>
#include <mtd.h>
-#include <uuid.h>
+#include <u-boot/uuid.h>
#include <stdio.h>
#include <dm/ofnode.h>
diff --git a/lib/uuid.c b/lib/uuid.c
index dfa2320ba26..11b86ffb02e 100644
--- a/lib/uuid.c
+++ b/lib/uuid.c
@@ -7,21 +7,35 @@
* Abdellatif El Khlifi <abdellatif.elkhlifi@arm.com>
*/
-#define LOG_CATEGOT LOGC_CORE
-
+#ifndef USE_HOSTCC
#include <command.h>
#include <efi_api.h>
#include <env.h>
#include <rand.h>
#include <time.h>
-#include <uuid.h>
-#include <linux/ctype.h>
-#include <errno.h>
#include <asm/io.h>
#include <part_efi.h>
#include <malloc.h>
#include <dm/uclass.h>
#include <rng.h>
+#include <linux/ctype.h>
+#include <hexdump.h>
+#else
+#include <stdarg.h>
+#include <stdint.h>
+#include <eficapsule.h>
+#include <ctype.h>
+#endif
+#include <linux/types.h>
+#include <errno.h>
+#include <linux/kconfig.h>
+#include <u-boot/uuid.h>
+#include <u-boot/sha1.h>
+
+#ifdef USE_HOSTCC
+/* polyfill hextoul to avoid pulling in strto.c */
+#define hextoul(cp, endp) strtoul(cp, endp, 16)
+#endif
int uuid_str_valid(const char *uuid)
{
@@ -51,6 +65,7 @@ static const struct {
const char *string;
efi_guid_t guid;
} list_guid[] = {
+#ifndef USE_HOSTCC
#ifdef CONFIG_PARTITION_TYPE_GUID
{"system", PARTITION_SYSTEM_GUID},
{"mbr", LEGACY_MBR_PARTITION_GUID},
@@ -231,6 +246,7 @@ static const struct {
{ "EFI_MEM_STATUS_CODE_REC", EFI_MEM_STATUS_CODE_REC },
{ "EFI_GUID_EFI_ACPI1", EFI_GUID_EFI_ACPI1 },
#endif
+#endif /* !USE_HOSTCC */
};
int uuid_guid_get_bin(const char *guid_str, unsigned char *guid_bin)
@@ -266,7 +282,6 @@ int uuid_str_to_bin(const char *uuid_str, unsigned char *uuid_bin,
uint64_t tmp64;
if (!uuid_str_valid(uuid_str)) {
- log_debug("not valid\n");
#ifdef CONFIG_PARTITION_TYPE_GUID
if (!uuid_guid_get_bin(uuid_str, uuid_bin))
return 0;
@@ -297,7 +312,7 @@ int uuid_str_to_bin(const char *uuid_str, unsigned char *uuid_bin,
tmp16 = cpu_to_be16(hextoul(uuid_str + 19, NULL));
memcpy(uuid_bin + 8, &tmp16, 2);
- tmp64 = cpu_to_be64(simple_strtoull(uuid_str + 24, NULL, 16));
+ tmp64 = cpu_to_be64(hextoul(uuid_str + 24, NULL));
memcpy(uuid_bin + 10, (char *)&tmp64 + 2, 6);
return 0;
@@ -305,9 +320,9 @@ int uuid_str_to_bin(const char *uuid_str, unsigned char *uuid_bin,
int uuid_str_to_le_bin(const char *uuid_str, unsigned char *uuid_bin)
{
- u16 tmp16;
- u32 tmp32;
- u64 tmp64;
+ uint16_t tmp16;
+ uint32_t tmp32;
+ uint64_t tmp64;
if (!uuid_str_valid(uuid_str) || !uuid_bin)
return -EINVAL;
@@ -324,7 +339,7 @@ int uuid_str_to_le_bin(const char *uuid_str, unsigned char *uuid_bin)
tmp16 = cpu_to_le16(hextoul(uuid_str + 19, NULL));
memcpy(uuid_bin + 8, &tmp16, 2);
- tmp64 = cpu_to_le64(simple_strtoull(uuid_str + 24, NULL, 16));
+ tmp64 = cpu_to_le64(hextoul(uuid_str + 24, NULL));
memcpy(uuid_bin + 10, &tmp64, 6);
return 0;
@@ -333,11 +348,11 @@ int uuid_str_to_le_bin(const char *uuid_str, unsigned char *uuid_bin)
void uuid_bin_to_str(const unsigned char *uuid_bin, char *uuid_str,
int str_format)
{
- const u8 uuid_char_order[UUID_BIN_LEN] = {0, 1, 2, 3, 4, 5, 6, 7, 8,
+ const uint8_t uuid_char_order[UUID_BIN_LEN] = {0, 1, 2, 3, 4, 5, 6, 7, 8,
9, 10, 11, 12, 13, 14, 15};
- const u8 guid_char_order[UUID_BIN_LEN] = {3, 2, 1, 0, 5, 4, 7, 6, 8,
+ const uint8_t guid_char_order[UUID_BIN_LEN] = {3, 2, 1, 0, 5, 4, 7, 6, 8,
9, 10, 11, 12, 13, 14, 15};
- const u8 *char_order;
+ const uint8_t *char_order;
const char *format;
int i;
@@ -369,6 +384,57 @@ void uuid_bin_to_str(const unsigned char *uuid_bin, char *uuid_str,
}
}
+static void configure_uuid(struct uuid *uuid, unsigned char version)
+{
+ uint16_t tmp;
+
+ /* Configure variant/version bits */
+ tmp = be16_to_cpu(uuid->time_hi_and_version);
+ tmp = (tmp & ~UUID_VERSION_MASK) | (version << UUID_VERSION_SHIFT);
+ uuid->time_hi_and_version = cpu_to_be16(tmp);
+
+ uuid->clock_seq_hi_and_reserved &= ~UUID_VARIANT_MASK;
+ uuid->clock_seq_hi_and_reserved |= (UUID_VARIANT << UUID_VARIANT_SHIFT);
+}
+
+void gen_v5_guid(const struct uuid *namespace, struct efi_guid *guid, ...)
+{
+ sha1_context ctx;
+ va_list args;
+ const uint8_t *data;
+ uint32_t *tmp32;
+ uint16_t *tmp16;
+ uint8_t hash[SHA1_SUM_LEN];
+
+ sha1_starts(&ctx);
+ /* Hash the namespace UUID as salt */
+ sha1_update(&ctx, (unsigned char *)namespace, UUID_BIN_LEN);
+ va_start(args, guid);
+
+ while ((data = va_arg(args, const uint8_t *))) {
+ unsigned int len = va_arg(args, size_t);
+
+ sha1_update(&ctx, data, len);
+ }
+
+ va_end(args);
+ sha1_finish(&ctx, hash);
+
+ /* Truncate the hash into output UUID, it is already big endian */
+ memcpy(guid, hash, sizeof(*guid));
+
+ configure_uuid((struct uuid *)guid, 5);
+
+ /* Make little endian */
+ tmp32 = (uint32_t *)&guid->b[0];
+ *tmp32 = cpu_to_le32(be32_to_cpu(*tmp32));
+ tmp16 = (uint16_t *)&guid->b[4];
+ *tmp16 = cpu_to_le16(be16_to_cpu(*tmp16));
+ tmp16 = (uint16_t *)&guid->b[6];
+ *tmp16 = cpu_to_le16(be16_to_cpu(*tmp16));
+}
+
+#ifndef USE_HOSTCC
#if defined(CONFIG_RANDOM_UUID) || defined(CONFIG_CMD_UUID)
void gen_rand_uuid(unsigned char *uuid_bin)
{
@@ -395,13 +461,7 @@ void gen_rand_uuid(unsigned char *uuid_bin)
for (i = 0; i < 4; i++)
ptr[i] = rand();
- clrsetbits_be16(&uuid->time_hi_and_version,
- UUID_VERSION_MASK,
- UUID_VERSION << UUID_VERSION_SHIFT);
-
- clrsetbits_8(&uuid->clock_seq_hi_and_reserved,
- UUID_VARIANT_MASK,
- UUID_VARIANT << UUID_VARIANT_SHIFT);
+ configure_uuid(uuid, UUID_VERSION);
memcpy(uuid_bin, uuid, 16);
}
@@ -458,3 +518,4 @@ U_BOOT_CMD(guid, CONFIG_SYS_MAXARGS, 1, do_uuid,
);
#endif /* CONFIG_CMD_UUID */
#endif /* CONFIG_RANDOM_UUID || CONFIG_CMD_UUID */
+#endif /* !USE_HOSTCC */
diff --git a/lib/vsprintf.c b/lib/vsprintf.c
index cfd1f1914ed..e5802866632 100644
--- a/lib/vsprintf.c
+++ b/lib/vsprintf.c
@@ -18,7 +18,7 @@
#include <div64.h>
#include <hexdump.h>
#include <stdarg.h>
-#include <uuid.h>
+#include <u-boot/uuid.h>
#include <stdio.h>
#include <vsprintf.h>
#include <linux/ctype.h>
diff --git a/net/bootp.c b/net/bootp.c
index 9dfb50749b4..512ab2ed7c8 100644
--- a/net/bootp.c
+++ b/net/bootp.c
@@ -15,7 +15,7 @@
#include <log.h>
#include <net.h>
#include <rand.h>
-#include <uuid.h>
+#include <u-boot/uuid.h>
#include <linux/delay.h>
#include <net/tftp.h>
#include "bootp.h"
diff --git a/test/dm/acpi_dp.c b/test/dm/acpi_dp.c
index eaeda2b8a7a..038806004b5 100644
--- a/test/dm/acpi_dp.c
+++ b/test/dm/acpi_dp.c
@@ -7,7 +7,7 @@
*/
#include <dm.h>
-#include <uuid.h>
+#include <u-boot/uuid.h>
#include <acpi/acpigen.h>
#include <acpi/acpi_dp.h>
#include <asm/unaligned.h>
diff --git a/test/dm/acpigen.c b/test/dm/acpigen.c
index 3e912fadaef..23c16bd9866 100644
--- a/test/dm/acpigen.c
+++ b/test/dm/acpigen.c
@@ -9,7 +9,7 @@
#include <dm.h>
#include <irq.h>
#include <malloc.h>
-#include <uuid.h>
+#include <u-boot/uuid.h>
#include <acpi/acpigen.h>
#include <acpi/acpi_device.h>
#include <acpi/acpi_table.h>
diff --git a/test/lib/uuid.c b/test/lib/uuid.c
index 8fe65dbf78b..d00e9563a47 100644
--- a/test/lib/uuid.c
+++ b/test/lib/uuid.c
@@ -8,13 +8,18 @@
* Abdellatif El Khlifi <abdellatif.elkhlifi@arm.com>
*/
-#include <uuid.h>
+#include <charset.h>
+#include <u-boot/uuid.h>
#include <test/lib.h>
#include <test/test.h>
#include <test/ut.h>
+#include <efi.h>
+
/* test UUID */
#define TEST_SVC_UUID "ed32d533-4209-99e6-2d72-cdd998a79cc0"
+/* U-Boot default fw image namespace */
+#define DEFAULT_FW_IMAGE_NAMESPACE "8c9f137e-91dc-427b-b2d6-b420faebaf2a"
#define UUID_SIZE 16
@@ -37,3 +42,120 @@ static int lib_test_uuid_to_le(struct unit_test_state *uts)
return 0;
}
LIB_TEST(lib_test_uuid_to_le, 0);
+
+#if defined(CONFIG_RANDOM_UUID) || defined(CONFIG_CMD_UUID)
+/* Test UUID attribute bits (version, variant) */
+static int lib_test_uuid_bits(struct unit_test_state *uts)
+{
+ unsigned char uuid[16];
+ efi_guid_t guid;
+ int i;
+
+ /*
+ * Reduce the chance of a randomly generated UUID disguising
+ * a regression by testing multiple times.
+ */
+ for (i = 0; i < 5; i++) {
+ /* Test UUID v4 */
+ gen_rand_uuid((unsigned char *)&uuid);
+
+ printf("v4 UUID: %pUb\n", (efi_guid_t *)uuid);
+
+ /* version 4 */
+ ut_assert((uuid[6] & 0xf0) == 0x40);
+ /* variant 1 */
+ ut_assert((uuid[8] & UUID_VARIANT_MASK) == (UUID_VARIANT << UUID_VARIANT_SHIFT));
+
+ /* Test v5, use the v4 UUID as the namespace */
+ gen_v5_guid((struct uuid *)uuid,
+ &guid, "test", 4, NULL);
+
+ printf("v5 GUID: %pUl\n", (efi_guid_t *)uuid);
+
+ /* This is a GUID so bits 6 and 7 are swapped (little endian). Version 5 */
+ ut_assert((guid.b[7] & 0xf0) == 0x50);
+ /* variant 1 */
+ ut_assert((guid.b[8] & UUID_VARIANT_MASK) == (UUID_VARIANT << UUID_VARIANT_SHIFT));
+ }
+
+ return 0;
+}
+
+LIB_TEST(lib_test_uuid_bits, 0);
+#endif
+
+struct dynamic_uuid_test_data {
+ const char *compatible;
+ const u16 *images[4];
+ const char *expected_uuids[4];
+};
+
+static int lib_test_dynamic_uuid_case(struct unit_test_state *uts,
+ const struct dynamic_uuid_test_data *data)
+{
+ struct uuid namespace;
+ int j;
+
+ ut_assertok(uuid_str_to_bin(DEFAULT_FW_IMAGE_NAMESPACE, (unsigned char *)&namespace,
+ UUID_STR_FORMAT_GUID));
+
+ for (j = 0; data->images[j]; j++) {
+ const char *expected_uuid = data->expected_uuids[j];
+ const u16 *image = data->images[j];
+ efi_guid_t uuid;
+ char uuid_str[37];
+
+ gen_v5_guid(&namespace, &uuid,
+ data->compatible, strlen(data->compatible),
+ image, u16_strlen(image) * sizeof(uint16_t),
+ NULL);
+ uuid_bin_to_str((unsigned char *)&uuid, uuid_str, UUID_STR_FORMAT_GUID);
+
+ ut_asserteq_str(expected_uuid, uuid_str);
+ }
+
+ return 0;
+}
+
+static int lib_test_dynamic_uuid(struct unit_test_state *uts)
+{
+ int ret, i;
+ const struct dynamic_uuid_test_data test_data[] = {
+ {
+ .compatible = "sandbox",
+ .images = {
+ u"SANDBOX-UBOOT",
+ u"SANDBOX-UBOOT-ENV",
+ u"SANDBOX-FIT",
+ NULL,
+ },
+ .expected_uuids = {
+ "985f2937-7c2e-5e9a-8a5e-8e063312964b",
+ "9e339473-c2eb-530a-a69b-0cd6bbbed40e",
+ "46610520-469e-59dc-a8dd-c11832b877ea",
+ NULL,
+ }
+ },
+ {
+ .compatible = "qcom,qrb4210-rb2",
+ .images = {
+ u"QUALCOMM-UBOOT",
+ NULL,
+ },
+ .expected_uuids = {
+ "d5021fac-8dd0-5ed7-90c2-763c304aaf86",
+ NULL,
+ }
+ },
+ };
+
+ for (i = 0; i < ARRAY_SIZE(test_data); i++) {
+ ret = lib_test_dynamic_uuid_case(uts, &test_data[i]);
+ if (ret)
+ return ret;
+ }
+
+ return 0;
+}
+
+LIB_TEST(lib_test_dynamic_uuid, 0);
diff --git a/test/py/tests/test_efi_capsule/test_capsule_firmware_fit.py b/test/py/tests/test_efi_capsule/test_capsule_firmware_fit.py
index 11bcdc2bb29..a726c71c113 100644
--- a/test/py/tests/test_efi_capsule/test_capsule_firmware_fit.py
+++ b/test/py/tests/test_efi_capsule/test_capsule_firmware_fit.py
@@ -147,7 +147,7 @@ class TestEfiCapsuleFirmwareFit():
verify_content(u_boot_console, '150000', 'u-boot-env:Old')
else:
# ensure that SANDBOX_UBOOT_IMAGE_GUID is in the ESRT.
- assert '3673B45D-6A7C-46F3-9E60-ADABB03F7937' in ''.join(output)
+ assert '985F2937-7C2E-5E9A-8A5E-8E063312964B' in ''.join(output)
assert 'ESRT: fw_version=5' in ''.join(output)
assert 'ESRT: lowest_supported_fw_version=3' in ''.join(output)
diff --git a/test/py/tests/test_efi_capsule/test_capsule_firmware_raw.py b/test/py/tests/test_efi_capsule/test_capsule_firmware_raw.py
index f3a2dff5c2c..8a790405c7c 100644
--- a/test/py/tests/test_efi_capsule/test_capsule_firmware_raw.py
+++ b/test/py/tests/test_efi_capsule/test_capsule_firmware_raw.py
@@ -145,10 +145,10 @@ class TestEfiCapsuleFirmwareRaw:
'efidebug capsule esrt'])
# ensure that SANDBOX_UBOOT_ENV_IMAGE_GUID is in the ESRT.
- assert '5A7021F5-FEF2-48B4-AABA-832E777418C0' in ''.join(output)
+ assert '9E339473-C2EB-530A-A69B-0CD6BBBED40E' in ''.join(output)
# ensure that SANDBOX_UBOOT_IMAGE_GUID is in the ESRT.
- assert '09D7CF52-0720-4710-91D1-08469B7FE9C8' in ''.join(output)
+ assert '985F2937-7C2E-5E9A-8A5E-8E063312964B' in ''.join(output)
check_file_removed(u_boot_console, disk_img, capsule_files)
@@ -199,12 +199,12 @@ class TestEfiCapsuleFirmwareRaw:
verify_content(u_boot_console, '150000', 'u-boot-env:Old')
else:
# ensure that SANDBOX_UBOOT_IMAGE_GUID is in the ESRT.
- assert '09D7CF52-0720-4710-91D1-08469B7FE9C8' in ''.join(output)
+ assert '985F2937-7C2E-5E9A-8A5E-8E063312964B' in ''.join(output)
assert 'ESRT: fw_version=5' in ''.join(output)
assert 'ESRT: lowest_supported_fw_version=3' in ''.join(output)
# ensure that SANDBOX_UBOOT_ENV_IMAGE_GUID is in the ESRT.
- assert '5A7021F5-FEF2-48B4-AABA-832E777418C0' in ''.join(output)
+ assert '9E339473-C2EB-530A-A69B-0CD6BBBED40E' in ''.join(output)
assert 'ESRT: fw_version=10' in ''.join(output)
assert 'ESRT: lowest_supported_fw_version=7' in ''.join(output)
diff --git a/test/py/tests/test_efi_capsule/test_capsule_firmware_signed_fit.py b/test/py/tests/test_efi_capsule/test_capsule_firmware_signed_fit.py
index 44a58baa310..debbce8bdbd 100644
--- a/test/py/tests/test_efi_capsule/test_capsule_firmware_signed_fit.py
+++ b/test/py/tests/test_efi_capsule/test_capsule_firmware_signed_fit.py
@@ -157,7 +157,7 @@ class TestEfiCapsuleFirmwareSignedFit():
'efidebug capsule esrt'])
# ensure that SANDBOX_UBOOT_IMAGE_GUID is in the ESRT.
- assert '3673B45D-6A7C-46F3-9E60-ADABB03F7937' in ''.join(output)
+ assert '46610520-469E-59DC-A8DD-C11832B877EA' in ''.join(output)
assert 'ESRT: fw_version=5' in ''.join(output)
assert 'ESRT: lowest_supported_fw_version=3' in ''.join(output)
diff --git a/test/py/tests/test_efi_capsule/test_capsule_firmware_signed_raw.py b/test/py/tests/test_efi_capsule/test_capsule_firmware_signed_raw.py
index 83a10e160b8..439bd71b3a7 100644
--- a/test/py/tests/test_efi_capsule/test_capsule_firmware_signed_raw.py
+++ b/test/py/tests/test_efi_capsule/test_capsule_firmware_signed_raw.py
@@ -151,12 +151,12 @@ class TestEfiCapsuleFirmwareSignedRaw():
'efidebug capsule esrt'])
# ensure that SANDBOX_UBOOT_IMAGE_GUID is in the ESRT.
- assert '09D7CF52-0720-4710-91D1-08469B7FE9C8' in ''.join(output)
+ assert '985F2937-7C2E-5E9A-8A5E-8E063312964B' in ''.join(output)
assert 'ESRT: fw_version=5' in ''.join(output)
assert 'ESRT: lowest_supported_fw_version=3' in ''.join(output)
# ensure that SANDBOX_UBOOT_ENV_IMAGE_GUID is in the ESRT.
- assert '5A7021F5-FEF2-48B4-AABA-832E777418C0' in ''.join(output)
+ assert '9E339473-C2EB-530A-A69B-0CD6BBBED40E' in ''.join(output)
assert 'ESRT: fw_version=10' in ''.join(output)
assert 'ESRT: lowest_supported_fw_version=7' in ''.join(output)
diff --git a/test/py/tests/test_efi_capsule/version.dtso b/test/py/tests/test_efi_capsule/version.dtso
index 07850cc6064..3aebb5b64fb 100644
--- a/test/py/tests/test_efi_capsule/version.dtso
+++ b/test/py/tests/test_efi_capsule/version.dtso
@@ -8,17 +8,17 @@
image1 {
lowest-supported-version = <3>;
image-index = <1>;
- image-type-id = "09D7CF52-0720-4710-91D1-08469B7FE9C8";
+ image-type-id = "985F2937-7C2E-5E9A-8A5E-8E063312964B";
};
image2 {
lowest-supported-version = <7>;
image-index = <2>;
- image-type-id = "5A7021F5-FEF2-48B4-AABA-832E777418C0";
+ image-type-id = "9E339473-C2EB-530A-A69B-0CD6BBBED40E";
};
image3 {
lowest-supported-version = <3>;
image-index = <1>;
- image-type-id = "3673B45D-6A7C-46F3-9E60-ADABB03F7937";
+ image-type-id = "46610520-469E-59DC-A8DD-C11832B877EA";
};
};
};
diff --git a/tools/Makefile b/tools/Makefile
index 6a4280e3668..ee08a9675df 100644
--- a/tools/Makefile
+++ b/tools/Makefile
@@ -246,12 +246,12 @@ HOSTCFLAGS_asn1_compiler.o = -idirafter $(srctree)/include
HOSTCFLAGS_mkeficapsule.o += \
$(shell pkg-config --cflags gnutls 2> /dev/null || echo "")
-HOSTCFLAGS_mkeficapsule.o += \
- $(shell pkg-config --cflags uuid 2> /dev/null || echo "")
HOSTLDLIBS_mkeficapsule += \
$(shell pkg-config --libs gnutls 2> /dev/null || echo "-lgnutls")
-HOSTLDLIBS_mkeficapsule += \
- $(shell pkg-config --libs uuid 2> /dev/null || echo "-luuid")
+mkeficapsule-objs := generated/lib/uuid.o \
+ generated/lib/sha1.o \
+ $(LIBFDT_OBJS) \
+ mkeficapsule.o
hostprogs-$(CONFIG_TOOLS_MKEFICAPSULE) += mkeficapsule
mkfwumdata-objs := mkfwumdata.o generated/lib/crc32.o
diff --git a/tools/binman/etype/efi_capsule.py b/tools/binman/etype/efi_capsule.py
index 5941545d0b2..768e006dc50 100644
--- a/tools/binman/etype/efi_capsule.py
+++ b/tools/binman/etype/efi_capsule.py
@@ -24,7 +24,7 @@ def get_binman_test_guid(type_str):
The actual GUID value (str)
"""
TYPE_TO_GUID = {
- 'binman-test' : '09d7cf52-0720-4710-91d1-08469b7fe9c8'
+ 'binman-test' : '985f2937-7c2e-5e9a-8a5e-8e063312964b'
}
return TYPE_TO_GUID[type_str]
diff --git a/tools/binman/ftest.py b/tools/binman/ftest.py
index 93f3d22cf57..2577c0016c0 100644
--- a/tools/binman/ftest.py
+++ b/tools/binman/ftest.py
@@ -125,7 +125,7 @@ TEE_ADDR = 0x5678
# Firmware Management Protocol(FMP) GUID
FW_MGMT_GUID = '6dcbd5ed-e82d-4c44-bda1-7194199ad92a'
# Image GUID specified in the DTS
-CAPSULE_IMAGE_GUID = '09d7cf52-0720-4710-91d1-08469b7fe9c8'
+CAPSULE_IMAGE_GUID = '985F2937-7C2E-5E9A-8A5E-8E063312964B'
# Windows cert GUID
WIN_CERT_TYPE_EFI_GUID = '4aafd29d-68df-49ee-8aa9-347d375665a7'
# Empty capsule GUIDs
diff --git a/tools/eficapsule.h b/tools/eficapsule.h
index 6efd07d2eb6..97d077536d5 100644
--- a/tools/eficapsule.h
+++ b/tools/eficapsule.h
@@ -24,7 +24,7 @@
#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
-typedef struct {
+typedef struct efi_guid {
uint8_t b[16];
} efi_guid_t __aligned(8);
diff --git a/tools/mkeficapsule.c b/tools/mkeficapsule.c
index 1b53151d41a..49f5b7849e4 100644
--- a/tools/mkeficapsule.c
+++ b/tools/mkeficapsule.c
@@ -16,16 +16,20 @@
#include <sys/stat.h>
#include <sys/types.h>
-#include <uuid/uuid.h>
#include <gnutls/gnutls.h>
#include <gnutls/pkcs7.h>
#include <gnutls/abstract.h>
#include <version.h>
+#include <libfdt.h>
+#include <u-boot/uuid.h>
#include "eficapsule.h"
+// Matches CONFIG_EFI_CAPSULE_NAMESPACE_GUID
+#define DEFAULT_NAMESPACE_GUID "8c9f137e-91dc-427b-b2d6-b420faebaf2a"
+
static const char *tool_name = "mkeficapsule";
efi_guid_t efi_guid_fm_capsule = EFI_FIRMWARE_MANAGEMENT_CAPSULE_ID_GUID;
@@ -56,9 +60,20 @@ static struct option options[] = {
{NULL, 0, NULL, 0},
};
-static void print_usage(void)
+static void print_usage_guidgen(void)
{
- fprintf(stderr, "Usage: %s [options] <image blob> <output file>\n"
+ fprintf(stderr, "%s guidgen [GUID] DTB IMAGE_NAME...\n"
+ "Options:\n"
+
+ "\tGUID Namespace GUID (default: %s)\n"
+ "\tDTB Device Tree Blob\n"
+ "\tIMAGE_NAME... One or more names of fw_images to generate GUIDs for\n",
+ tool_name, DEFAULT_NAMESPACE_GUID);
+}
+
+static void print_usage_mkeficapsule(void)
+{
+ fprintf(stderr, "Usage:\n\n%s [options] <image blob> <output file>\n"
"Options:\n"
"\t-g, --guid <guid string> guid for image blob type\n"
@@ -74,8 +89,9 @@ static void print_usage(void)
"\t-o, --capoemflag Capsule OEM Flag, an integer between 0x0000 and 0xffff\n"
"\t-D, --dump-capsule dump the contents of the capsule headers\n"
"\t-V, --version show version number\n"
- "\t-h, --help print a help message\n",
+ "\t-h, --help print a help message\n\n",
tool_name);
+ print_usage_guidgen();
}
/**
@@ -578,37 +594,6 @@ err:
return ret;
}
-/**
- * convert_uuid_to_guid() - convert UUID to GUID
- * @buf: UUID binary
- *
- * UUID and GUID have the same data structure, but their binary
- * formats are different due to the endianness. See lib/uuid.c.
- * Since uuid_parse() can handle only UUID, this function must
- * be called to get correct data for GUID when parsing a string.
- *
- * The correct data will be returned in @buf.
- */
-void convert_uuid_to_guid(unsigned char *buf)
-{
- unsigned char c;
-
- c = buf[0];
- buf[0] = buf[3];
- buf[3] = c;
- c = buf[1];
- buf[1] = buf[2];
- buf[2] = c;
-
- c = buf[4];
- buf[4] = buf[5];
- buf[5] = c;
-
- c = buf[6];
- buf[6] = buf[7];
- buf[7] = c;
-}
-
static int create_empty_capsule(char *path, efi_guid_t *guid, bool fw_accept)
{
struct efi_capsule_header header = { 0 };
@@ -654,20 +639,10 @@ err:
static void print_guid(void *ptr)
{
- int i;
- efi_guid_t *guid = ptr;
- const uint8_t seq[] = {
- 3, 2, 1, 0, '-', 5, 4, '-', 7, 6,
- '-', 8, 9, '-', 10, 11, 12, 13, 14, 15 };
-
- for (i = 0; i < ARRAY_SIZE(seq); i++) {
- if (seq[i] == '-')
- putchar(seq[i]);
- else
- printf("%02X", guid->b[seq[i]]);
- }
+ static char buf[37] = { 0 };
- printf("\n");
+ uuid_bin_to_str(ptr, buf, UUID_STR_FORMAT_GUID | UUID_STR_UPPER_CASE);
+ printf("%s\n", buf);
}
static uint32_t dump_fmp_payload_header(
@@ -861,6 +836,129 @@ static void dump_capsule_contents(char *capsule_file)
}
}
+static struct fdt_header *load_dtb(const char *path)
+{
+ struct fdt_header *dtb;
+ ssize_t dtb_size;
+ FILE *f;
+
+ /* Open and parse DTB */
+ f = fopen(path, "r");
+ if (!f) {
+ fprintf(stderr, "Cannot open %s\n", path);
+ return NULL;
+ }
+
+ if (fseek(f, 0, SEEK_END)) {
+ fprintf(stderr, "Cannot seek to the end of %s: %s\n",
+ path, strerror(errno));
+ return NULL;
+ }
+
+ dtb_size = ftell(f);
+ if (dtb_size < 0) {
+ fprintf(stderr, "Cannot ftell %s: %s\n",
+ path, strerror(errno));
+ return NULL;
+ }
+
+ fseek(f, 0, SEEK_SET);
+
+ dtb = malloc(dtb_size);
+ if (!dtb) {
+ fprintf(stderr, "Can't allocated %ld\n", dtb_size);
+ return NULL;
+ }
+
+ if (fread(dtb, dtb_size, 1, f) != 1) {
+ fprintf(stderr, "Can't read %ld bytes from %s\n",
+ dtb_size, path);
+ free(dtb);
+ return NULL;
+ }
+
+ fclose(f);
+
+ return dtb;
+}
+
+#define MAX_IMAGE_NAME_LEN 128
+static int genguid(int argc, char **argv)
+{
+ int idx = 2, ret;
+ unsigned char namespace[16];
+ struct efi_guid image_type_id;
+ const char *dtb_path;
+ struct fdt_header *dtb;
+ const char *compatible;
+ int compatlen, namelen;
+ uint16_t fw_image[MAX_IMAGE_NAME_LEN];
+
+ if (argc < 2) {
+ fprintf(stderr, "Usage: ");
+ print_usage_guidgen();
+ return -1;
+ }
+
+ if (uuid_str_to_bin(argv[1], namespace, UUID_STR_FORMAT_GUID)) {
+ uuid_str_to_bin(DEFAULT_NAMESPACE_GUID, namespace, UUID_STR_FORMAT_GUID);
+ dtb_path = argv[1];
+ } else {
+ dtb_path = argv[2];
+ idx = 3;
+ }
+
+ if (idx == argc) {
+ fprintf(stderr, "Usage: ");
+ print_usage_guidgen();
+ return -1;
+ }
+
+ dtb = load_dtb(dtb_path);
+ if (!dtb)
+ return -1;
+
+ ret = fdt_check_header(dtb);
+ if (ret) {
+ fprintf(stderr, "Invalid DTB header: %d\n", ret);
+ return -1;
+ }
+
+ compatible = fdt_getprop(dtb, 0, "compatible", &compatlen);
+ if (!compatible) {
+ fprintf(stderr, "No compatible string found in DTB\n");
+ return -1;
+ }
+ if (strnlen(compatible, compatlen) >= compatlen) {
+ fprintf(stderr, "Compatible string not null-terminated\n");
+ return -1;
+ }
+
+ printf("Generating GUIDs for %s with namespace %s:\n",
+ compatible, DEFAULT_NAMESPACE_GUID);
+ for (; idx < argc; idx++) {
+ memset(fw_image, 0, sizeof(fw_image));
+ namelen = strlen(argv[idx]);
+ if (namelen > MAX_IMAGE_NAME_LEN) {
+ fprintf(stderr, "Image name too long: %s\n", argv[idx]);
+ return -1;
+ }
+
+ for (int i = 0; i < namelen; i++)
+ fw_image[i] = (uint16_t)argv[idx][i];
+
+ gen_v5_guid((struct uuid *)&namespace, &image_type_id,
+ compatible, strlen(compatible),
+ fw_image, namelen * sizeof(uint16_t),
+ NULL);
+
+ printf("%s: ", argv[idx]);
+ print_guid(&image_type_id);
+ }
+
+ return 0;
+}
+
/**
* main - main entry function of mkeficapsule
* @argc: Number of arguments
@@ -885,6 +983,13 @@ int main(int argc, char **argv)
int c, idx;
struct fmp_payload_header_params fmp_ph_params = { 0 };
+ /* Generate dynamic GUIDs */
+ if (argc > 1 && !strcmp(argv[1], "guidgen")) {
+ if (genguid(argc - 1, argv + 1))
+ exit(EXIT_FAILURE);
+ exit(EXIT_SUCCESS);
+ }
+
guid = NULL;
index = 0;
instance = 0;
@@ -907,11 +1012,10 @@ int main(int argc, char **argv)
"Image type already specified\n");
exit(EXIT_FAILURE);
}
- if (uuid_parse(optarg, uuid_buf)) {
+ if (uuid_str_to_bin(optarg, uuid_buf, UUID_STR_FORMAT_GUID)) {
fprintf(stderr, "Wrong guid format\n");
exit(EXIT_FAILURE);
}
- convert_uuid_to_guid(uuid_buf);
guid = (efi_guid_t *)uuid_buf;
break;
case 'i':
@@ -977,7 +1081,7 @@ int main(int argc, char **argv)
printf("mkeficapsule version %s\n", PLAIN_VERSION);
exit(EXIT_SUCCESS);
default:
- print_usage();
+ print_usage_mkeficapsule();
exit(EXIT_FAILURE);
}
}
@@ -1000,7 +1104,7 @@ int main(int argc, char **argv)
((argc != optind + 1) ||
((capsule_type == CAPSULE_ACCEPT) && !guid) ||
((capsule_type == CAPSULE_REVERT) && guid)))) {
- print_usage();
+ print_usage_mkeficapsule();
exit(EXIT_FAILURE);
}