Add support for uefi capsule authentication feature for the qemu arm64
platform. This feature is enabled by setting the environment variable
"capsule_authentication_enabled".

The following configs are needed for enabling uefi capsule update and
capsule authentication features on the platform.

CONFIG_EFI_CAPSULE_ON_DISK=y
CONFIG_EFI_FIRMWARE_MANAGEMENT_PROTOCOL=y
CONFIG_EFI_CAPSULE_AUTHENTICATE=y

Signed-off-by: Sughosh Ganu <sughosh.g...@linaro.org>
---
 board/emulation/qemu-arm/qemu_efi_fmp.c | 49 +++++++++++++++++++++----
 1 file changed, 41 insertions(+), 8 deletions(-)

diff --git a/board/emulation/qemu-arm/qemu_efi_fmp.c 
b/board/emulation/qemu-arm/qemu_efi_fmp.c
index 9baea94e6c..b58843f8fb 100644
--- a/board/emulation/qemu-arm/qemu_efi_fmp.c
+++ b/board/emulation/qemu-arm/qemu_efi_fmp.c
@@ -101,9 +101,15 @@ static efi_status_t EFIAPI qemu_arm64_fmp_get_image_info(
        image_info[0].size = 0;
 
        image_info[0].attributes_supported =
-               EFI_IMAGE_ATTRIBUTE_IMAGE_UPDATABLE;
+               EFI_IMAGE_ATTRIBUTE_IMAGE_UPDATABLE |
+               EFI_IMAGE_ATTRIBUTE_AUTHENTICATION_REQUIRED;
        image_info[0].attributes_setting = EFI_IMAGE_ATTRIBUTE_IMAGE_UPDATABLE;
 
+       /* Check if the capsule authentication is enabled */
+       if (env_get("capsule_authentication_enabled"))
+               image_info[0].attributes_setting |=
+                       EFI_IMAGE_ATTRIBUTE_AUTHENTICATION_REQUIRED;
+
        image_info[0].lowest_supported_image_version = 1;
        image_info[0].last_attempt_version = 0;
        image_info[0].last_attempt_status = LAST_ATTEMPT_STATUS_SUCCESS;
@@ -142,17 +148,12 @@ static efi_status_t EFIAPI qemu_arm64_fmp_set_image(
        long fd, ret;
        efi_status_t status = EFI_SUCCESS;
        char *mode = "w+b";
+       void *capsule_payload;
+       efi_uintn_t capsule_payload_size;
 
        EFI_ENTRY("%p %d %p %ld %p %p %p\n", this, image_index, image,
                  image_size, vendor_code, progress, abort_reason);
 
-       /*
-        * Put a hack here to offset the size of
-        * the FMP_PAYLOAD_HEADER that gets added
-        * by the GenerateCapsule script in edk2.
-        */
-       image += 0x10;
-       image_size -= 0x10;
 
        /* Do all the sanity checks first */
        if (!image) {
@@ -170,6 +171,38 @@ static efi_status_t EFIAPI qemu_arm64_fmp_set_image(
                goto back;
        }
 
+       /* Authenticate the capsule if authentication enabled */
+       if (IS_ENABLED(CONFIG_EFI_CAPSULE_AUTHENTICATE) &&
+           env_get("capsule_authentication_enabled")) {
+               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");
+                       goto back;
+               } else if (status != EFI_SUCCESS) {
+                       goto back;
+               }
+
+               debug("Capsule authentication successfull\n");
+               image = capsule_payload;
+               image_size = capsule_payload_size;
+       } else {
+               debug("Capsule authentication disabled. ");
+               debug("Updating capsule without authenticating.\n");
+       }
+
+       /*
+        * Put a hack here to offset the size of
+        * the FMP_PAYLOAD_HEADER that gets added
+        * by the GenerateCapsule script in edk2.
+        */
+       image += 0x10;
+       image_size -= 0x10;
+
        /* Do the update */
        fd = smh_open(UBOOT_FILE, mode);
        if (fd == -1) {
-- 
2.17.1

Reply via email to