diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/efi_loader/efi_boottime.c | 1 | ||||
-rw-r--r-- | lib/efi_loader/efi_capsule.c | 73 | ||||
-rw-r--r-- | lib/efi_loader/efi_smbios.c | 15 | ||||
-rw-r--r-- | lib/smbios.c | 27 |
4 files changed, 92 insertions, 24 deletions
diff --git a/lib/efi_loader/efi_boottime.c b/lib/efi_loader/efi_boottime.c index f6d5ba05e34..0b98e918137 100644 --- a/lib/efi_loader/efi_boottime.c +++ b/lib/efi_loader/efi_boottime.c @@ -20,6 +20,7 @@ #include <usb.h> #include <watchdog.h> #include <asm/global_data.h> +#include <asm/setjmp.h> #include <linux/libfdt_env.h> DECLARE_GLOBAL_DATA_PTR; diff --git a/lib/efi_loader/efi_capsule.c b/lib/efi_loader/efi_capsule.c index f9b0ef591cc..26990bc2df4 100644 --- a/lib/efi_loader/efi_capsule.c +++ b/lib/efi_loader/efi_capsule.c @@ -218,10 +218,40 @@ skip: return NULL; } -#if defined(CONFIG_EFI_CAPSULE_AUTHENTICATE) +/** + * efi_remove_auth_hdr - remove authentication data from image + * @image: Pointer to pointer to Image + * @image_size: Pointer to Image size + * + * Remove the authentication data from image if possible. + * Update @image and @image_size. + * + * Return: status code + */ +static efi_status_t efi_remove_auth_hdr(void **image, efi_uintn_t *image_size) +{ + struct efi_firmware_image_authentication *auth_hdr; + efi_status_t ret = EFI_INVALID_PARAMETER; + + auth_hdr = (struct efi_firmware_image_authentication *)*image; + if (*image_size < sizeof(*auth_hdr)) + goto out; + + if (auth_hdr->auth_info.hdr.dwLength <= + offsetof(struct win_certificate_uefi_guid, cert_data)) + goto out; + + *image = (uint8_t *)*image + sizeof(auth_hdr->monotonic_count) + + auth_hdr->auth_info.hdr.dwLength; + *image_size = *image_size - auth_hdr->auth_info.hdr.dwLength - + sizeof(auth_hdr->monotonic_count); + + ret = EFI_SUCCESS; +out: + return ret; +} -const efi_guid_t efi_guid_capsule_root_cert_guid = - EFI_FIRMWARE_MANAGEMENT_CAPSULE_ID_GUID; +#if defined(CONFIG_EFI_CAPSULE_AUTHENTICATE) static int efi_get_public_key_data(void **pkey, efi_uintn_t *pkey_len) { @@ -257,21 +287,15 @@ efi_status_t efi_capsule_authenticate(const void *capsule, efi_uintn_t capsule_s if (capsule == NULL || capsule_size == 0) goto out; - auth_hdr = (struct efi_firmware_image_authentication *)capsule; - if (capsule_size < sizeof(*auth_hdr)) - goto out; - - if (auth_hdr->auth_info.hdr.dwLength <= - offsetof(struct win_certificate_uefi_guid, cert_data)) + *image = (uint8_t *)capsule; + *image_size = capsule_size; + if (efi_remove_auth_hdr(image, image_size) != EFI_SUCCESS) goto out; + auth_hdr = (struct efi_firmware_image_authentication *)capsule; if (guidcmp(&auth_hdr->auth_info.cert_type, &efi_guid_cert_type_pkcs7)) goto out; - *image = (uint8_t *)capsule + sizeof(auth_hdr->monotonic_count) + - auth_hdr->auth_info.hdr.dwLength; - *image_size = capsule_size - auth_hdr->auth_info.hdr.dwLength - - sizeof(auth_hdr->monotonic_count); memcpy(&monotonic_count, &auth_hdr->monotonic_count, sizeof(monotonic_count)); @@ -351,7 +375,7 @@ static efi_status_t efi_capsule_update_firmware( { struct efi_firmware_management_capsule_header *capsule; struct efi_firmware_management_capsule_image_header *image; - size_t capsule_size; + size_t capsule_size, image_binary_size; void *image_binary, *vendor_code; efi_handle_t *handles; efi_uintn_t no_handles; @@ -413,13 +437,30 @@ static efi_status_t efi_capsule_update_firmware( } /* do update */ + if (IS_ENABLED(CONFIG_EFI_CAPSULE_AUTHENTICATE) && + !(image->image_capsule_support & + CAPSULE_SUPPORT_AUTHENTICATION)) { + /* no signature */ + ret = EFI_SECURITY_VIOLATION; + goto out; + } + image_binary = (void *)image + sizeof(*image); - vendor_code = image_binary + image->update_image_size; + image_binary_size = image->update_image_size; + vendor_code = image_binary + image_binary_size; + if (!IS_ENABLED(CONFIG_EFI_CAPSULE_AUTHENTICATE) && + (image->image_capsule_support & + CAPSULE_SUPPORT_AUTHENTICATION)) { + ret = efi_remove_auth_hdr(&image_binary, + &image_binary_size); + if (ret != EFI_SUCCESS) + goto out; + } abort_reason = NULL; ret = EFI_CALL(fmp->set_image(fmp, image->update_image_index, image_binary, - image->update_image_size, + image_binary_size, vendor_code, NULL, &abort_reason)); if (ret != EFI_SUCCESS) { diff --git a/lib/efi_loader/efi_smbios.c b/lib/efi_loader/efi_smbios.c index 719d3e8880a..2eb4cb1c1af 100644 --- a/lib/efi_loader/efi_smbios.c +++ b/lib/efi_loader/efi_smbios.c @@ -5,6 +5,8 @@ * Copyright (c) 2016 Alexander Graf */ +#define LOG_CATEGORY LOGC_EFI + #include <common.h> #include <efi_loader.h> #include <log.h> @@ -43,14 +45,13 @@ efi_status_t efi_smbios_register(void) * Generate SMBIOS tables - we know that efi_allocate_pages() returns * a 4k-aligned address, so it is safe to assume that * write_smbios_table() will write the table at that address. - * - * Note that on sandbox, efi_allocate_pages() unfortunately returns a - * pointer even though it uses a uint64_t type. Convert it. */ assert(!(dmi_addr & 0xf)); dmi = (void *)(uintptr_t)dmi_addr; - write_smbios_table(map_to_sysmem(dmi)); - - /* And expose them to our EFI payload */ - return efi_install_configuration_table(&smbios_guid, dmi); + if (write_smbios_table(map_to_sysmem(dmi))) + /* Install SMBIOS information as configuration table */ + return efi_install_configuration_table(&smbios_guid, dmi); + efi_free_pages(dmi_addr, 1); + log_err("Cannot create SMBIOS table\n"); + return EFI_SUCCESS; } diff --git a/lib/smbios.c b/lib/smbios.c index b52e125eeb1..d7f4999e8b2 100644 --- a/lib/smbios.c +++ b/lib/smbios.c @@ -8,6 +8,7 @@ #include <common.h> #include <dm.h> #include <env.h> +#include <linux/stringify.h> #include <mapmem.h> #include <smbios.h> #include <sysinfo.h> @@ -18,6 +19,28 @@ #include <dm/uclass-internal.h> #endif +/* Safeguard for checking that U_BOOT_VERSION_NUM macros are compatible with U_BOOT_DMI */ +#if U_BOOT_VERSION_NUM < 2000 || U_BOOT_VERSION_NUM > 2099 || \ + U_BOOT_VERSION_NUM_PATCH < 1 || U_BOOT_VERSION_NUM_PATCH > 12 +#error U_BOOT_VERSION_NUM macros are not compatible with DMI, fix U_BOOT_DMI macros +#endif + +/* + * U_BOOT_DMI_DATE contains BIOS Release Date in format mm/dd/yyyy. + * BIOS Release Date is calculated from U-Boot version and fixed day 01. + * So for U-Boot version 2021.04 it is calculated as "04/01/2021". + * BIOS Release Date should contain date when code was released + * and not when it was built or compiled. + */ +#if U_BOOT_VERSION_NUM_PATCH < 10 +#define U_BOOT_DMI_MONTH "0" __stringify(U_BOOT_VERSION_NUM_PATCH) +#else +#define U_BOOT_DMI_MONTH __stringify(U_BOOT_VERSION_NUM_PATCH) +#endif +#define U_BOOT_DMI_DAY "01" +#define U_BOOT_DMI_YEAR __stringify(U_BOOT_VERSION_NUM) +#define U_BOOT_DMI_DATE U_BOOT_DMI_MONTH "/" U_BOOT_DMI_DAY "/" U_BOOT_DMI_YEAR + DECLARE_GLOBAL_DATA_PTR; /** @@ -507,7 +530,8 @@ ulong write_smbios_table(ulong addr) */ printf("WARNING: SMBIOS table_address overflow %llx\n", (unsigned long long)table_addr); - table_addr = 0; + addr = 0; + goto out; } se->struct_table_address = table_addr; @@ -518,6 +542,7 @@ ulong write_smbios_table(ulong addr) isize = sizeof(struct smbios_entry) - SMBIOS_INTERMEDIATE_OFFSET; se->intermediate_checksum = table_compute_checksum(istart, isize); se->checksum = table_compute_checksum(se, sizeof(struct smbios_entry)); +out: unmap_sysmem(se); return addr; |