aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorVincent Stehlé2022-05-31 09:55:34 +0200
committerHeinrich Schuchardt2022-06-04 08:43:55 +0200
commit8645aefc8b699f900d97cbadd55b7f492099c61e (patch)
tree8b9b58da4604290897131f8cb7fd70ab0ded7b3a /lib
parent82b3f4cb46ce8ef49b6b887233be0b409056d6c4 (diff)
efi: test/py: authenticate fit capsules
Add support for the authentication of UEFI capsules containing FIT images. The authentication code is moved out of the function handling raw images into a new function efi_firmware_capsule_authenticate(). The special case for the FMP header coming from edk2 tools is preserved. There is no functional change for capsules containing raw images. The python test for signed capsules with raw images is renamed with no functional change and a new test is added for signed capsules containing FIT images. This can be tested with sandbox64_defconfig or sandbox_flattree_defconfig, plus CONFIG_EFI_CAPSULE_AUTHENTICATE=y. Signed-off-by: Vincent Stehlé <vincent.stehle@arm.com> Cc: Heinrich Schuchardt <xypron.glpk@gmx.de>
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))