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
diff --git a/arch/arm/mach-rockchip/board.c b/arch/arm/mach-rockchip/board.c
index 8a57b82..0fdf936 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 616842e..f16f2f1 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 c6b14be..eb7fcd6 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 8025965..d97945e 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 6e6e276..5e5a45e 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 3440402..1c100d6 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 7ac3457..925afe0 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 6bed2d7..687ccb5 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 c46764e..d2f2b59 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 de0e04f..fd660ec 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 86b7701..27aea2d 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 64ae2ad..32b7d04 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 2dd3080..d3713ce 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 24ddc8b..226646c 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 b1a03bd..580821a 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 d450b12..9448275 100644
--- a/doc/develop/uefi/uefi.rst
+++ b/doc/develop/uefi/uefi.rst
@@ -449,6 +449,33 @@
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 c3d0f21..a5545f7 100644
--- a/doc/mkeficapsule.1
+++ b/doc/mkeficapsule.1
@@ -10,6 +10,9 @@
.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 @@
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 @@
.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 e0767fc..96c6496 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 906b85b..21ac0c2 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 1149a3b..350cff0 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 02173de..4596b9d 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 34d9d53..14efe72 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 da59cb0..15587e9 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 d5af213..84640cf 100644
--- a/include/efi.h
+++ b/include/efi.h
@@ -74,7 +74,7 @@
* 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 77ec65e..c317613 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 54b986c..797b542 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 145fede..b747903 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 3e288e8..84d45ec 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
similarity index 90%
rename from include/uuid.h
rename to include/u-boot/uuid.h
index f5a9412..7f8414d 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 @@
/* 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_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 5f282ec..1dd4f27 100644
--- a/lib/Kconfig
+++ b/lib/Kconfig
@@ -73,6 +73,7 @@
config LIB_UUID
bool
+ select SHA1
config RANDOM_UUID
bool "GPT Random UUID generation"
@@ -1081,8 +1082,6 @@
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 6733809..5714acc 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 b95cabb..ecff5a5 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 c2b9bb7..81ed3e6 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 @@
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 88332c3..9b94a93 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 6ffefa9..e58b882 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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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"
- default y
- depends on RISCV
+config EFI_SCROLL_ON_CLEAR_SCREEN
+ bool "Avoid overwriting previous output on clear screen"
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.
+ 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
+ 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.
config EFI_HTTP_BOOT
bool "EFI HTTP Boot support"
@@ -514,5 +550,10 @@
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 589d399..a3aa2b8 100644
--- a/lib/efi_loader/efi_bootmgr.c
+++ b/lib/efi_loader/efi_bootmgr.c
@@ -380,14 +380,15 @@
}
/**
- * 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 @@
/* 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 @@
/* 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 @@
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 635088f..a4ea287 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 c944c10..cea50c7 100644
--- a/lib/efi_loader/efi_console.c
+++ b/lib/efi_loader/efi_console.c
@@ -181,7 +181,7 @@
}
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 0f68459..9de3b95 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 ba5aba0..6650c2b 100644
--- a/lib/efi_loader/efi_firmware.c
+++ b/lib/efi_loader/efi_firmware.c
@@ -246,6 +246,55 @@
}
/**
+ * 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 @@
{
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 @@
}
*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 e888c52..f3533f4 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 bd72822..586177d 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 c14203b..5547230 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 dfa2320..11b86ff 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 @@
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 @@
{ "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 @@
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 @@
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_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 @@
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 @@
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 @@
}
}
+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 @@
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 @@
);
#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 cfd1f19..e580286 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 9dfb507..512ab2e 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 eaeda2b..0388060 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 3e912fa..23c16bd 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 8fe65db..d00e956 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 @@
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 11bcdc2..a726c71 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 @@
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 f3a2dff..8a790405 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 @@
'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 @@
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 44a58ba..debbce8 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 @@
'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 83a10e1..439bd71 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 @@
'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 07850cc..3aebb5b 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 6a4280e..ee08a96 100644
--- a/tools/Makefile
+++ b/tools/Makefile
@@ -246,12 +246,12 @@
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 5941545..768e006 100644
--- a/tools/binman/etype/efi_capsule.py
+++ b/tools/binman/etype/efi_capsule.py
@@ -24,7 +24,7 @@
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 93f3d22..2577c00 100644
--- a/tools/binman/ftest.py
+++ b/tools/binman/ftest.py
@@ -125,7 +125,7 @@
# 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 6efd07d..97d0775 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 1b53151..49f5b78 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 @@
{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 @@
"\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 @@
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 @@
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 };
+ static char buf[37] = { 0 };
- for (i = 0; i < ARRAY_SIZE(seq); i++) {
- if (seq[i] == '-')
- putchar(seq[i]);
- else
- printf("%02X", guid->b[seq[i]]);
- }
-
- 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 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 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 @@
"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 @@
printf("mkeficapsule version %s\n", PLAIN_VERSION);
exit(EXIT_SUCCESS);
default:
- print_usage();
+ print_usage_mkeficapsule();
exit(EXIT_FAILURE);
}
}
@@ -1000,7 +1104,7 @@
((argc != optind + 1) ||
((capsule_type == CAPSULE_ACCEPT) && !guid) ||
((capsule_type == CAPSULE_REVERT) && guid)))) {
- print_usage();
+ print_usage_mkeficapsule();
exit(EXIT_FAILURE);
}