diff mbox series

[12/14] efi_loader: Enable uefi capsule authentication

Message ID 20201126184110.30521-13-sughosh.ganu@linaro.org
State Superseded
Headers show
Series qemu: arm64: Add support for uefi capsule update on qemu arm64 platform | expand

Commit Message

Sughosh Ganu Nov. 26, 2020, 6:41 p.m. UTC
Add support for enabling uefi capsule authentication. 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_HAVE_CAPSULE_SUPPORT=y
CONFIG_EFI_CAPSULE_ON_DISK=y
CONFIG_EFI_CAPSULE_FIRMWARE_MANAGEMENT=y
CONFIG_EFI_CAPSULE_FIRMWARE=y
CONFIG_EFI_CAPSULE_FIRMWARE_RAW=y
CONFIG_EFI_CAPSULE_AUTHENTICATE=y

Signed-off-by: Sughosh Ganu <sughosh.ganu@linaro.org>

---
 lib/efi_loader/efi_firmware.c | 37 ++++++++++++++++++++++++++++++++++-
 1 file changed, 36 insertions(+), 1 deletion(-)

-- 
2.17.1

Comments

Heinrich Schuchardt Dec. 5, 2020, 10:47 a.m. UTC | #1
On 11/26/20 7:41 PM, Sughosh Ganu wrote:
> Add support for enabling uefi capsule authentication. 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_HAVE_CAPSULE_SUPPORT=y

> CONFIG_EFI_CAPSULE_ON_DISK=y

> CONFIG_EFI_CAPSULE_FIRMWARE_MANAGEMENT=y

> CONFIG_EFI_CAPSULE_FIRMWARE=y

> CONFIG_EFI_CAPSULE_FIRMWARE_RAW=y

> CONFIG_EFI_CAPSULE_AUTHENTICATE=y


Dear Takahiro, dear Sughosh,

could you, please, provide a documentation for capsule updates in /doc/uefi.

Best regards

Heinrich

>

> Signed-off-by: Sughosh Ganu <sughosh.ganu@linaro.org>

> ---

>   lib/efi_loader/efi_firmware.c | 37 ++++++++++++++++++++++++++++++++++-

>   1 file changed, 36 insertions(+), 1 deletion(-)

>

> diff --git a/lib/efi_loader/efi_firmware.c b/lib/efi_loader/efi_firmware.c

> index 6c97604d8b..5e17b2ab5a 100644

> --- a/lib/efi_loader/efi_firmware.c

> +++ b/lib/efi_loader/efi_firmware.c

> @@ -162,9 +162,16 @@ static efi_status_t efi_get_dfu_info(

>   		image_info[i].version_name = NULL; /* not supported */

>   		image_info[i].size = 0;

>   		image_info[i].attributes_supported =

> -				IMAGE_ATTRIBUTE_IMAGE_UPDATABLE;

> +			IMAGE_ATTRIBUTE_IMAGE_UPDATABLE |

> +			IMAGE_ATTRIBUTE_AUTHENTICATION_REQUIRED;

>   		image_info[i].attributes_setting =

>   				IMAGE_ATTRIBUTE_IMAGE_UPDATABLE;

> +

> +		/* Check if the capsule authentication is enabled */

> +		if (env_get("capsule_authentication_enabled"))

> +			image_info[0].attributes_setting |=

> +				IMAGE_ATTRIBUTE_AUTHENTICATION_REQUIRED;

> +

>   		image_info[i].lowest_supported_image_version = 0;

>   		image_info[i].last_attempt_version = 0;

>   		image_info[i].last_attempt_status = LAST_ATTEMPT_STATUS_SUCCESS;

> @@ -379,12 +386,40 @@ efi_status_t EFIAPI efi_firmware_raw_set_image(

>   	efi_status_t (*progress)(efi_uintn_t completion),

>   	u16 **abort_reason)

>   {

> +	void *capsule_payload;

> +	efi_status_t status;

> +	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);

>

>   	if (!image)

>   		return EFI_EXIT(EFI_INVALID_PARAMETER);

>

> +	/* 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");

> +			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");

> +	}

> +

>   	if (CONFIG_IS_ENABLED(EFI_CAPSULE_FMP_HEADER)) {

>   		/*

>   		 * When building the capsule with the scripts in

>
diff mbox series

Patch

diff --git a/lib/efi_loader/efi_firmware.c b/lib/efi_loader/efi_firmware.c
index 6c97604d8b..5e17b2ab5a 100644
--- a/lib/efi_loader/efi_firmware.c
+++ b/lib/efi_loader/efi_firmware.c
@@ -162,9 +162,16 @@  static efi_status_t efi_get_dfu_info(
 		image_info[i].version_name = NULL; /* not supported */
 		image_info[i].size = 0;
 		image_info[i].attributes_supported =
-				IMAGE_ATTRIBUTE_IMAGE_UPDATABLE;
+			IMAGE_ATTRIBUTE_IMAGE_UPDATABLE |
+			IMAGE_ATTRIBUTE_AUTHENTICATION_REQUIRED;
 		image_info[i].attributes_setting =
 				IMAGE_ATTRIBUTE_IMAGE_UPDATABLE;
+
+		/* Check if the capsule authentication is enabled */
+		if (env_get("capsule_authentication_enabled"))
+			image_info[0].attributes_setting |=
+				IMAGE_ATTRIBUTE_AUTHENTICATION_REQUIRED;
+
 		image_info[i].lowest_supported_image_version = 0;
 		image_info[i].last_attempt_version = 0;
 		image_info[i].last_attempt_status = LAST_ATTEMPT_STATUS_SUCCESS;
@@ -379,12 +386,40 @@  efi_status_t EFIAPI efi_firmware_raw_set_image(
 	efi_status_t (*progress)(efi_uintn_t completion),
 	u16 **abort_reason)
 {
+	void *capsule_payload;
+	efi_status_t status;
+	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);
 
 	if (!image)
 		return EFI_EXIT(EFI_INVALID_PARAMETER);
 
+	/* 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");
+			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");
+	}
+
 	if (CONFIG_IS_ENABLED(EFI_CAPSULE_FMP_HEADER)) {
 		/*
 		 * When building the capsule with the scripts in