mirror of
https://xff.cz/git/u-boot/
synced 2025-09-07 19:52:15 +02:00
Merge tag 'efi-2023-07-rc3' of https://source.denx.de/u-boot/custodians/u-boot-efi
Pull request efi-2023-07-rc3 Documentation: * update the description of signature algorithms UEFI: * fix unaligned access to GUID in HII database protocol * fix launching EFI binaries loaded via semihosting * fix filling of file path in loaded image protocol for non-block devices
This commit is contained in:
@@ -589,7 +589,7 @@ static efi_status_t bootefi_test_prepare
|
|||||||
if (!bootefi_device_path)
|
if (!bootefi_device_path)
|
||||||
return EFI_OUT_OF_RESOURCES;
|
return EFI_OUT_OF_RESOURCES;
|
||||||
|
|
||||||
bootefi_image_path = efi_dp_from_file(NULL, 0, path);
|
bootefi_image_path = efi_dp_from_file(NULL, path);
|
||||||
if (!bootefi_image_path) {
|
if (!bootefi_image_path) {
|
||||||
ret = EFI_OUT_OF_RESOURCES;
|
ret = EFI_OUT_OF_RESOURCES;
|
||||||
goto failure;
|
goto failure;
|
||||||
|
@@ -100,7 +100,7 @@ and development only and is not recommended for production devices.
|
|||||||
|
|
||||||
If CONFIG_OF_SEPARATE is defined, then it will be built and placed in
|
If CONFIG_OF_SEPARATE is defined, then it will be built and placed in
|
||||||
a u-boot.dtb file alongside u-boot-nodtb.bin with the combined result placed
|
a u-boot.dtb file alongside u-boot-nodtb.bin with the combined result placed
|
||||||
in u-boot.bin so you can still just flash u-boot,bin onto your board. If you are
|
in u-boot.bin so you can still just flash u-boot.bin onto your board. If you are
|
||||||
using CONFIG_SPL_FRAMEWORK, then u-boot.img will be built to include the device
|
using CONFIG_SPL_FRAMEWORK, then u-boot.img will be built to include the device
|
||||||
tree binary.
|
tree binary.
|
||||||
|
|
||||||
|
@@ -42,8 +42,8 @@ device.
|
|||||||
Algorithms
|
Algorithms
|
||||||
----------
|
----------
|
||||||
In principle any suitable algorithm can be used to sign and verify a hash.
|
In principle any suitable algorithm can be used to sign and verify a hash.
|
||||||
At present only one class of algorithms is supported: SHA1 hashing with RSA.
|
U-Boot supports a few hashing and verification algorithms. See below for
|
||||||
This works by hashing the image to produce a 20-byte hash.
|
details.
|
||||||
|
|
||||||
While it is acceptable to bring in large cryptographic libraries such as
|
While it is acceptable to bring in large cryptographic libraries such as
|
||||||
openssl on the host side (e.g. mkimage), it is not desirable for U-Boot.
|
openssl on the host side (e.g. mkimage), it is not desirable for U-Boot.
|
||||||
@@ -56,10 +56,10 @@ of data from the FDT and exponentiation mod n. Code size impact is a little
|
|||||||
under 5KB on Tegra Seaboard, for example.
|
under 5KB on Tegra Seaboard, for example.
|
||||||
|
|
||||||
It is relatively straightforward to add new algorithms if required. If
|
It is relatively straightforward to add new algorithms if required. If
|
||||||
another RSA variant is needed, then it can be added to the table in
|
another RSA variant is needed, then it can be added with the
|
||||||
image-sig.c. If another algorithm is needed (such as DSA) then it can be
|
U_BOOT_CRYPTO_ALGO() macro. If another algorithm is needed (such as DSA) then
|
||||||
placed alongside rsa.c, and its functions added to the table in image-sig.c
|
it can be placed in a directory alongside lib/rsa/, and its functions added
|
||||||
also.
|
using U_BOOT_CRYPTO_ALGO().
|
||||||
|
|
||||||
|
|
||||||
Creating an RSA key pair and certificate
|
Creating an RSA key pair and certificate
|
||||||
@@ -439,6 +439,7 @@ be enabled:
|
|||||||
|
|
||||||
CONFIG_FIT_SIGNATURE - enable signing and verification in FITs
|
CONFIG_FIT_SIGNATURE - enable signing and verification in FITs
|
||||||
CONFIG_RSA - enable RSA algorithm for signing
|
CONFIG_RSA - enable RSA algorithm for signing
|
||||||
|
CONFIG_ECDSA - enable ECDSA algorithm for signing
|
||||||
|
|
||||||
WARNING: When relying on signed FIT images with required signature check
|
WARNING: When relying on signed FIT images with required signature check
|
||||||
the legacy image format is default disabled by not defining
|
the legacy image format is default disabled by not defining
|
||||||
@@ -694,8 +695,6 @@ bootm.
|
|||||||
|
|
||||||
Possible Future Work
|
Possible Future Work
|
||||||
--------------------
|
--------------------
|
||||||
- Add support for other RSA/SHA variants, such as rsa4096,sha512.
|
|
||||||
- Other algorithms besides RSA
|
|
||||||
- More sandbox tests for failure modes
|
- More sandbox tests for failure modes
|
||||||
- Passwords for keys/certificates
|
- Passwords for keys/certificates
|
||||||
- Perhaps implement OAEP
|
- Perhaps implement OAEP
|
||||||
|
@@ -1170,7 +1170,33 @@ struct efi_key_descriptor {
|
|||||||
|
|
||||||
struct efi_hii_keyboard_layout {
|
struct efi_hii_keyboard_layout {
|
||||||
u16 layout_length;
|
u16 layout_length;
|
||||||
efi_guid_t guid;
|
/*
|
||||||
|
* The EFI spec defines this as efi_guid_t.
|
||||||
|
* clang and gcc both report alignment problems here.
|
||||||
|
* clang with -Wunaligned-access
|
||||||
|
* warning: field guid within 'struct efi_hii_keyboard_layout' is less
|
||||||
|
* aligned than 'efi_guid_t' and is usually due to
|
||||||
|
* 'struct efi_hii_keyboard_layout' being packed, which can lead to
|
||||||
|
* unaligned accesses
|
||||||
|
*
|
||||||
|
* GCC with -Wpacked-not-aligned -Waddress-of-packed-member
|
||||||
|
* 'efi_guid_t' offset 2 in 'struct efi_hii_keyboard_layout'
|
||||||
|
* isn't aligned to 4
|
||||||
|
*
|
||||||
|
* Removing the alignment from efi_guid_t is not an option, since
|
||||||
|
* it is also used in non-packed structs and that would break
|
||||||
|
* calculations with offsetof
|
||||||
|
*
|
||||||
|
* This is the only place we get a report for. That happens because
|
||||||
|
* all other declarations of efi_guid_t within a packed struct happens
|
||||||
|
* to be 4-byte aligned. i.e a u32, a u64 a 2 * u16 or any combination
|
||||||
|
* that ends up landing efi_guid_t on a 4byte boundary precedes.
|
||||||
|
*
|
||||||
|
* Replace this with a 1-byte aligned counterpart of b[16]. This is a
|
||||||
|
* packed struct so the memory placement of efi_guid_t should not change
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
u8 guid[16];
|
||||||
u32 layout_descriptor_string_offset;
|
u32 layout_descriptor_string_offset;
|
||||||
u8 descriptor_count;
|
u8 descriptor_count;
|
||||||
/* struct efi_key_descriptor descriptors[]; follows here */
|
/* struct efi_key_descriptor descriptors[]; follows here */
|
||||||
|
@@ -810,7 +810,7 @@ bool efi_dp_is_multi_instance(const struct efi_device_path *dp);
|
|||||||
struct efi_device_path *efi_dp_from_part(struct blk_desc *desc, int part);
|
struct efi_device_path *efi_dp_from_part(struct blk_desc *desc, int part);
|
||||||
/* Create a device node for a block device partition. */
|
/* Create a device node for a block device partition. */
|
||||||
struct efi_device_path *efi_dp_part_node(struct blk_desc *desc, int part);
|
struct efi_device_path *efi_dp_part_node(struct blk_desc *desc, int part);
|
||||||
struct efi_device_path *efi_dp_from_file(struct blk_desc *desc, int part,
|
struct efi_device_path *efi_dp_from_file(const struct efi_device_path *dp,
|
||||||
const char *path);
|
const char *path);
|
||||||
struct efi_device_path *efi_dp_from_eth(void);
|
struct efi_device_path *efi_dp_from_eth(void);
|
||||||
struct efi_device_path *efi_dp_from_mem(uint32_t mem_type,
|
struct efi_device_path *efi_dp_from_mem(uint32_t mem_type,
|
||||||
|
@@ -47,7 +47,7 @@ const efi_guid_t efi_guid_bootmenu_auto_generated =
|
|||||||
static
|
static
|
||||||
struct efi_device_path *expand_media_path(struct efi_device_path *device_path)
|
struct efi_device_path *expand_media_path(struct efi_device_path *device_path)
|
||||||
{
|
{
|
||||||
struct efi_device_path *dp, *rem, *full_path;
|
struct efi_device_path *rem, *full_path;
|
||||||
efi_handle_t handle;
|
efi_handle_t handle;
|
||||||
|
|
||||||
if (!device_path)
|
if (!device_path)
|
||||||
@@ -58,15 +58,12 @@ struct efi_device_path *expand_media_path(struct efi_device_path *device_path)
|
|||||||
* simple file system protocol, append a default file name to support
|
* simple file system protocol, append a default file name to support
|
||||||
* booting from removable media.
|
* booting from removable media.
|
||||||
*/
|
*/
|
||||||
dp = device_path;
|
handle = efi_dp_find_obj(device_path,
|
||||||
handle = efi_dp_find_obj(dp, &efi_simple_file_system_protocol_guid,
|
&efi_simple_file_system_protocol_guid, &rem);
|
||||||
&rem);
|
|
||||||
if (handle) {
|
if (handle) {
|
||||||
if (rem->type == DEVICE_PATH_TYPE_END) {
|
if (rem->type == DEVICE_PATH_TYPE_END) {
|
||||||
dp = efi_dp_from_file(NULL, 0,
|
full_path = efi_dp_from_file(device_path,
|
||||||
"/EFI/BOOT/" BOOTEFI_NAME);
|
"/EFI/BOOT/" BOOTEFI_NAME);
|
||||||
full_path = efi_dp_append(device_path, dp);
|
|
||||||
efi_free_pool(dp);
|
|
||||||
} else {
|
} else {
|
||||||
full_path = efi_dp_dup(device_path);
|
full_path = efi_dp_dup(device_path);
|
||||||
}
|
}
|
||||||
|
@@ -1002,59 +1002,45 @@ static void path_to_uefi(void *uefi, const char *src)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* efi_dp_from_file() - create device path for file
|
* efi_dp_from_file() - append file path node to device path.
|
||||||
*
|
*
|
||||||
* The function creates a device path from the block descriptor @desc and the
|
* @dp: device path or NULL
|
||||||
* partition number @part and appends a device path node created describing the
|
* @path: file path or NULL
|
||||||
* file path @path.
|
|
||||||
*
|
|
||||||
* If @desc is NULL, the device path will not contain nodes describing the
|
|
||||||
* partition.
|
|
||||||
* If @path is an empty string "", the device path will not contain a node
|
|
||||||
* for the file path.
|
|
||||||
*
|
|
||||||
* @desc: block device descriptor or NULL
|
|
||||||
* @part: partition number
|
|
||||||
* @path: file path on partition or ""
|
|
||||||
* Return: device path or NULL in case of an error
|
* Return: device path or NULL in case of an error
|
||||||
*/
|
*/
|
||||||
struct efi_device_path *efi_dp_from_file(struct blk_desc *desc, int part,
|
struct efi_device_path *efi_dp_from_file(const struct efi_device_path *dp,
|
||||||
const char *path)
|
const char *path)
|
||||||
{
|
{
|
||||||
struct efi_device_path_file_path *fp;
|
struct efi_device_path_file_path *fp;
|
||||||
void *buf, *start;
|
void *buf, *pos;
|
||||||
size_t dpsize = 0, fpsize;
|
size_t dpsize, fpsize;
|
||||||
|
|
||||||
if (desc)
|
|
||||||
dpsize = dp_part_size(desc, part);
|
|
||||||
|
|
||||||
|
dpsize = efi_dp_size(dp);
|
||||||
fpsize = sizeof(struct efi_device_path) +
|
fpsize = sizeof(struct efi_device_path) +
|
||||||
2 * (utf8_utf16_strlen(path) + 1);
|
2 * (utf8_utf16_strlen(path) + 1);
|
||||||
if (fpsize > U16_MAX)
|
if (fpsize > U16_MAX)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
dpsize += fpsize;
|
buf = efi_alloc(dpsize + fpsize + sizeof(END));
|
||||||
|
|
||||||
start = buf = efi_alloc(dpsize + sizeof(END));
|
|
||||||
if (!buf)
|
if (!buf)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
if (desc)
|
memcpy(buf, dp, dpsize);
|
||||||
buf = dp_part_fill(buf, desc, part);
|
pos = buf + dpsize;
|
||||||
|
|
||||||
/* add file-path: */
|
/* add file-path: */
|
||||||
if (*path) {
|
if (*path) {
|
||||||
fp = buf;
|
fp = pos;
|
||||||
fp->dp.type = DEVICE_PATH_TYPE_MEDIA_DEVICE;
|
fp->dp.type = DEVICE_PATH_TYPE_MEDIA_DEVICE;
|
||||||
fp->dp.sub_type = DEVICE_PATH_SUB_TYPE_FILE_PATH;
|
fp->dp.sub_type = DEVICE_PATH_SUB_TYPE_FILE_PATH;
|
||||||
fp->dp.length = (u16)fpsize;
|
fp->dp.length = (u16)fpsize;
|
||||||
path_to_uefi(fp->str, path);
|
path_to_uefi(fp->str, path);
|
||||||
buf += fpsize;
|
pos += fpsize;
|
||||||
}
|
}
|
||||||
|
|
||||||
*((struct efi_device_path *)buf) = END;
|
memcpy(pos, &END, sizeof(END));
|
||||||
|
|
||||||
return start;
|
return buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct efi_device_path *efi_dp_from_uart(void)
|
struct efi_device_path *efi_dp_from_uart(void)
|
||||||
@@ -1079,8 +1065,7 @@ struct efi_device_path *efi_dp_from_uart(void)
|
|||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_NETDEVICES
|
struct efi_device_path __maybe_unused *efi_dp_from_eth(void)
|
||||||
struct efi_device_path *efi_dp_from_eth(void)
|
|
||||||
{
|
{
|
||||||
void *buf, *start;
|
void *buf, *start;
|
||||||
unsigned dpsize = 0;
|
unsigned dpsize = 0;
|
||||||
@@ -1099,7 +1084,6 @@ struct efi_device_path *efi_dp_from_eth(void)
|
|||||||
|
|
||||||
return start;
|
return start;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Construct a device-path for memory-mapped image */
|
/* Construct a device-path for memory-mapped image */
|
||||||
struct efi_device_path *efi_dp_from_mem(uint32_t memory_type,
|
struct efi_device_path *efi_dp_from_mem(uint32_t memory_type,
|
||||||
@@ -1185,58 +1169,42 @@ efi_status_t efi_dp_from_name(const char *dev, const char *devnr,
|
|||||||
struct efi_device_path **file)
|
struct efi_device_path **file)
|
||||||
{
|
{
|
||||||
struct blk_desc *desc = NULL;
|
struct blk_desc *desc = NULL;
|
||||||
|
struct efi_device_path *dp;
|
||||||
struct disk_partition fs_partition;
|
struct disk_partition fs_partition;
|
||||||
size_t image_size;
|
size_t image_size;
|
||||||
void *image_addr;
|
void *image_addr;
|
||||||
int part = 0;
|
int part = 0;
|
||||||
char *filename;
|
|
||||||
char *s;
|
|
||||||
|
|
||||||
if (path && !file)
|
if (path && !file)
|
||||||
return EFI_INVALID_PARAMETER;
|
return EFI_INVALID_PARAMETER;
|
||||||
|
|
||||||
if (!strcmp(dev, "Net")) {
|
if (!strcmp(dev, "Mem") || !strcmp(dev, "hostfs")) {
|
||||||
#ifdef CONFIG_NETDEVICES
|
/* loadm command and semihosting */
|
||||||
if (device)
|
|
||||||
*device = efi_dp_from_eth();
|
|
||||||
#endif
|
|
||||||
} else if (!strcmp(dev, "Uart")) {
|
|
||||||
if (device)
|
|
||||||
*device = efi_dp_from_uart();
|
|
||||||
} else if (!strcmp(dev, "Mem")) {
|
|
||||||
efi_get_image_parameters(&image_addr, &image_size);
|
efi_get_image_parameters(&image_addr, &image_size);
|
||||||
|
|
||||||
if (device)
|
dp = efi_dp_from_mem(EFI_RESERVED_MEMORY_TYPE,
|
||||||
*device = efi_dp_from_mem(EFI_RESERVED_MEMORY_TYPE,
|
(uintptr_t)image_addr, image_size);
|
||||||
(uintptr_t)image_addr,
|
} else if (IS_ENABLED(CONFIG_NETDEVICES) && !strcmp(dev, "Net")) {
|
||||||
image_size);
|
dp = efi_dp_from_eth();
|
||||||
|
} else if (!strcmp(dev, "Uart")) {
|
||||||
|
dp = efi_dp_from_uart();
|
||||||
} else {
|
} else {
|
||||||
part = blk_get_device_part_str(dev, devnr, &desc, &fs_partition,
|
part = blk_get_device_part_str(dev, devnr, &desc, &fs_partition,
|
||||||
1);
|
1);
|
||||||
if (part < 0 || !desc)
|
if (part < 0 || !desc)
|
||||||
return EFI_INVALID_PARAMETER;
|
return EFI_INVALID_PARAMETER;
|
||||||
|
|
||||||
if (device)
|
dp = efi_dp_from_part(desc, part);
|
||||||
*device = efi_dp_from_part(desc, part);
|
|
||||||
}
|
}
|
||||||
|
if (device)
|
||||||
|
*device = dp;
|
||||||
|
|
||||||
if (!path)
|
if (!path)
|
||||||
return EFI_SUCCESS;
|
return EFI_SUCCESS;
|
||||||
|
|
||||||
filename = calloc(1, strlen(path) + 1);
|
*file = efi_dp_from_file(dp, path);
|
||||||
if (!filename)
|
|
||||||
return EFI_OUT_OF_RESOURCES;
|
|
||||||
|
|
||||||
sprintf(filename, "%s", path);
|
|
||||||
/* DOS style file path: */
|
|
||||||
s = filename;
|
|
||||||
while ((s = strchr(s, '/')))
|
|
||||||
*s++ = '\\';
|
|
||||||
*file = efi_dp_from_file(desc, part, filename);
|
|
||||||
free(filename);
|
|
||||||
|
|
||||||
if (!*file)
|
if (!*file)
|
||||||
return EFI_INVALID_PARAMETER;
|
return EFI_OUT_OF_RESOURCES;
|
||||||
|
|
||||||
return EFI_SUCCESS;
|
return EFI_SUCCESS;
|
||||||
}
|
}
|
||||||
|
@@ -216,6 +216,10 @@ efi_status_t EFIAPI efi_main(efi_handle_t handle,
|
|||||||
(con_out, u"Cannot open device path to text protocol\r\n");
|
(con_out, u"Cannot open device path to text protocol\r\n");
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
con_out->output_string(con_out, u"File path: ");
|
||||||
|
ret = print_device_path(loaded_image->file_path, device_path_to_text);
|
||||||
|
if (ret != EFI_SUCCESS)
|
||||||
|
goto out;
|
||||||
if (!loaded_image->device_handle) {
|
if (!loaded_image->device_handle) {
|
||||||
con_out->output_string
|
con_out->output_string
|
||||||
(con_out, u"Missing device handle\r\n");
|
(con_out, u"Missing device handle\r\n");
|
||||||
@@ -234,10 +238,6 @@ efi_status_t EFIAPI efi_main(efi_handle_t handle,
|
|||||||
ret = print_device_path(device_path, device_path_to_text);
|
ret = print_device_path(device_path, device_path_to_text);
|
||||||
if (ret != EFI_SUCCESS)
|
if (ret != EFI_SUCCESS)
|
||||||
goto out;
|
goto out;
|
||||||
con_out->output_string(con_out, u"File path: ");
|
|
||||||
ret = print_device_path(loaded_image->file_path, device_path_to_text);
|
|
||||||
if (ret != EFI_SUCCESS)
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
out:
|
out:
|
||||||
boottime->exit(handle, ret, 0, NULL);
|
boottime->exit(handle, ret, 0, NULL);
|
||||||
|
@@ -2,7 +2,7 @@ config FWU_MULTI_BANK_UPDATE
|
|||||||
bool "Enable FWU Multi Bank Update Feature"
|
bool "Enable FWU Multi Bank Update Feature"
|
||||||
depends on EFI_CAPSULE_ON_DISK
|
depends on EFI_CAPSULE_ON_DISK
|
||||||
select PARTITION_TYPE_GUID
|
select PARTITION_TYPE_GUID
|
||||||
select EFI_SETUP_EARLY
|
select FWU_MDATA
|
||||||
imply EFI_CAPSULE_ON_DISK_EARLY
|
imply EFI_CAPSULE_ON_DISK_EARLY
|
||||||
select EVENT
|
select EVENT
|
||||||
help
|
help
|
||||||
|
Reference in New Issue
Block a user