summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/efi_loader/efi_boottime.c1
-rw-r--r--lib/efi_loader/efi_capsule.c73
-rw-r--r--lib/efi_loader/efi_smbios.c15
-rw-r--r--lib/smbios.c27
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;