aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/efi_loader/efi_firmware.c115
1 files changed, 73 insertions, 42 deletions
diff --git a/lib/efi_loader/efi_firmware.c b/lib/efi_loader/efi_firmware.c
index 9cdefab41fa..0ce6c1e34f0 100644
--- a/lib/efi_loader/efi_firmware.c
+++ b/lib/efi_loader/efi_firmware.c
@@ -177,6 +177,70 @@ static efi_status_t efi_fill_image_desc_array(
return EFI_SUCCESS;
}
+/**
+ * efi_firmware_capsule_authenticate - authenticate the capsule if enabled
+ * @p_image: Pointer to new image
+ * @p_image_size: Pointer to size of new image
+ *
+ * Authenticate the capsule if authentication is enabled.
+ * The image pointer and the image size are updated in case of success.
+ *
+ * Return: status code
+ */
+static
+efi_status_t efi_firmware_capsule_authenticate(const void **p_image,
+ efi_uintn_t *p_image_size)
+{
+ const void *image = *p_image;
+ efi_uintn_t image_size = *p_image_size;
+ u32 fmp_hdr_signature;
+ struct fmp_payload_header *header;
+ void *capsule_payload;
+ efi_status_t status;
+ efi_uintn_t capsule_payload_size;
+
+ if (IS_ENABLED(CONFIG_EFI_CAPSULE_AUTHENTICATE)) {
+ capsule_payload = NULL;
+ capsule_payload_size = 0;
+ status = efi_capsule_authenticate(image, image_size,
+ &capsule_payload,
+ &capsule_payload_size);
+
+ if (status == EFI_SECURITY_VIOLATION) {
+ printf("Capsule authentication check failed. Aborting update\n");
+ return status;
+ } else if (status != EFI_SUCCESS) {
+ return status;
+ }
+
+ debug("Capsule authentication successful\n");
+ image = capsule_payload;
+ image_size = capsule_payload_size;
+ } else {
+ debug("Capsule authentication disabled. ");
+ debug("Updating capsule without authenticating.\n");
+ }
+
+ fmp_hdr_signature = FMP_PAYLOAD_HDR_SIGNATURE;
+ header = (void *)image;
+
+ if (!memcmp(&header->signature, &fmp_hdr_signature,
+ sizeof(fmp_hdr_signature))) {
+ /*
+ * When building the capsule with the scripts in
+ * edk2, a FMP header is inserted above the capsule
+ * payload. Compensate for this header to get the
+ * actual payload that is to be updated.
+ */
+ image += header->header_size;
+ image_size -= header->header_size;
+ }
+
+ *p_image = image;
+ *p_image_size = image_size;
+ return EFI_SUCCESS;
+}
+
#ifdef CONFIG_EFI_CAPSULE_FIRMWARE_FIT
/*
* This FIRMWARE_MANAGEMENT_PROTOCOL driver provides a firmware update
@@ -265,12 +329,18 @@ efi_status_t EFIAPI efi_firmware_fit_set_image(
efi_status_t (*progress)(efi_uintn_t completion),
u16 **abort_reason)
{
+ efi_status_t status;
+
EFI_ENTRY("%p %d %p %zu %p %p %p\n", this, image_index, image,
image_size, vendor_code, progress, abort_reason);
if (!image || image_index != 1)
return EFI_EXIT(EFI_INVALID_PARAMETER);
+ status = efi_firmware_capsule_authenticate(&image, &image_size);
+ if (status != EFI_SUCCESS)
+ return EFI_EXIT(status);
+
if (fit_update(image))
return EFI_EXIT(EFI_DEVICE_ERROR);
@@ -371,11 +441,7 @@ efi_status_t EFIAPI efi_firmware_raw_set_image(
efi_status_t (*progress)(efi_uintn_t completion),
u16 **abort_reason)
{
- u32 fmp_hdr_signature;
- struct fmp_payload_header *header;
- void *capsule_payload;
efi_status_t status;
- efi_uintn_t capsule_payload_size;
EFI_ENTRY("%p %d %p %zu %p %p %p\n", this, image_index, image,
image_size, vendor_code, progress, abort_reason);
@@ -383,44 +449,9 @@ efi_status_t EFIAPI efi_firmware_raw_set_image(
if (!image)
return EFI_EXIT(EFI_INVALID_PARAMETER);
- /* Authenticate the capsule if authentication enabled */
- if (IS_ENABLED(CONFIG_EFI_CAPSULE_AUTHENTICATE)) {
- capsule_payload = NULL;
- capsule_payload_size = 0;
- status = efi_capsule_authenticate(image, image_size,
- &capsule_payload,
- &capsule_payload_size);
-
- if (status == EFI_SECURITY_VIOLATION) {
- printf("Capsule authentication check failed. Aborting update\n");
- return EFI_EXIT(status);
- } else if (status != EFI_SUCCESS) {
- return EFI_EXIT(status);
- }
-
- debug("Capsule authentication successfull\n");
- image = capsule_payload;
- image_size = capsule_payload_size;
- } else {
- debug("Capsule authentication disabled. ");
- debug("Updating capsule without authenticating.\n");
- }
-
- fmp_hdr_signature = FMP_PAYLOAD_HDR_SIGNATURE;
- header = (void *)image;
-
- if (!memcmp(&header->signature, &fmp_hdr_signature,
- sizeof(fmp_hdr_signature))) {
- /*
- * When building the capsule with the scripts in
- * edk2, a FMP header is inserted above the capsule
- * payload. Compensate for this header to get the
- * actual payload that is to be updated.
- */
- image += header->header_size;
- image_size -= header->header_size;
-
- }
+ status = efi_firmware_capsule_authenticate(&image, &image_size);
+ if (status != EFI_SUCCESS)
+ return EFI_EXIT(status);
if (dfu_write_by_alt(image_index - 1, (void *)image, image_size,
NULL, NULL))