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
This commit is contained in:
Tom Rini
2024-09-13 08:20:25 -06:00
59 changed files with 693 additions and 253 deletions

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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,
},

View File

@@ -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>

View File

@@ -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"

View File

@@ -1,5 +1,7 @@
menu "Boot options"
source "lib/efi_loader/Kconfig"
menu "Boot images"
config ANDROID_BOOT_IMAGE

View File

@@ -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;

View File

@@ -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)
{

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>
/*

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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

View File

@@ -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

View File

@@ -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>

2
env/sf.c vendored
View File

@@ -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>

View File

@@ -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"

View File

@@ -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 */

View File

@@ -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"

View File

@@ -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;

View File

@@ -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)));

View File

@@ -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>

View File

@@ -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>

View File

@@ -11,7 +11,7 @@
#define __RKMTD__
#include <part_efi.h>
#include <uuid.h>
#include <u-boot/uuid.h>
#define LBA 64 + 512 + 33

View File

@@ -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"

View File

@@ -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

View File

@@ -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

View File

@@ -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>

View File

@@ -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>

View File

@@ -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

View File

@@ -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>

View File

@@ -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"
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 @@ 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

View File

@@ -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;
}

View File

@@ -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>

View File

@@ -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);
/*

View File

@@ -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 */

View File

@@ -245,6 +245,55 @@ void efi_firmware_fill_version_info(struct efi_firmware_image_descriptor *image_
free(var_state);
}
/**
* 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
@@ -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;

View File

@@ -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>

View File

@@ -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.

View File

@@ -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>

View File

@@ -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 */

View File

@@ -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>

View File

@@ -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"

View File

@@ -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>

View File

@@ -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>

View File

@@ -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);

View File

@@ -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)

View File

@@ -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)

View File

@@ -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)

View File

@@ -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)

View File

@@ -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";
};
};
};

View File

@@ -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

View File

@@ -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]

View File

@@ -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

View File

@@ -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);

View File

@@ -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 };
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 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);
}