// SPDX-License-Identifier: GPL-2.0+
/*
 * EFI Firmware management protocol
 *
 *  Copyright (c) 2020 Linaro Limited
 *			Author: AKASHI Takahiro
 */

#define LOG_CATEGORY LOGC_EFI

#include <charset.h>
#include <dfu.h>
#include <efi_loader.h>
#include <efi_variable.h>
#include <env.h>
#include <fwu.h>
#include <image.h>
#include <signatures.h>

#include <linux/list.h>

#define FMP_PAYLOAD_HDR_SIGNATURE	SIGNATURE_32('M', 'S', 'S', '1')

/**
 * struct fmp_payload_header - EDK2 header for the FMP payload
 *
 * This structure describes the header which is preprended to the
 * FMP payload by the edk2 capsule generation scripts.
 *
 * @signature:			Header signature used to identify the header
 * @header_size:		Size of the structure
 * @fw_version:			Firmware versions used
 * @lowest_supported_version:	Lowest supported version
 */
struct fmp_payload_header {
	u32 signature;
	u32 header_size;
	u32 fw_version;
	u32 lowest_supported_version;
};

/**
 * struct fmp_state - fmp firmware update state
 *
 * This structure describes the state of the firmware update
 * through FMP protocol.
 *
 * @fw_version:			Firmware versions used
 * @lowest_supported_version:	Lowest supported version
 * @last_attempt_version:	Last attempt version
 * @last_attempt_status:	Last attempt status
 */
struct fmp_state {
	u32 fw_version;
	u32 lowest_supported_version; /* not used */
	u32 last_attempt_version; /* not used */
	u32 last_attempt_status; /* not used */
};

/**
 * efi_firmware_get_image_type_id - get image_type_id
 * @image_index:	image index
 *
 * Return the image_type_id identified by the image index.
 *
 * Return:		pointer to the image_type_id, NULL if image_index is invalid
 */
static
efi_guid_t *efi_firmware_get_image_type_id(u8 image_index)
{
	int i;
	struct efi_fw_image *fw_array;

	fw_array = update_info.images;
	for (i = 0; i < update_info.num_images; i++) {
		if (fw_array[i].image_index == image_index)
			return &fw_array[i].image_type_id;
	}

	return NULL;
}

/* Place holder; not supported */
static
efi_status_t EFIAPI efi_firmware_get_image_unsupported(
	struct efi_firmware_management_protocol *this,
	u8 image_index,
	void *image,
	efi_uintn_t *image_size)
{
	EFI_ENTRY("%p %d %p %p\n", this, image_index, image, image_size);

	return EFI_EXIT(EFI_UNSUPPORTED);
}

/* Place holder; not supported */
static
efi_status_t EFIAPI efi_firmware_check_image_unsupported(
	struct efi_firmware_management_protocol *this,
	u8 image_index,
	const void *image,
	efi_uintn_t *image_size,
	u32 *image_updatable)
{
	EFI_ENTRY("%p %d %p %p %p\n", this, image_index, image, image_size,
		  image_updatable);

	return EFI_EXIT(EFI_UNSUPPORTED);
}

/* Place holder; not supported */
static
efi_status_t EFIAPI efi_firmware_get_package_info_unsupported(
	struct efi_firmware_management_protocol *this,
	u32 *package_version,
	u16 **package_version_name,
	u32 *package_version_name_maxlen,
	u64 *attributes_supported,
	u64 *attributes_setting)
{
	EFI_ENTRY("%p %p %p %p %p %p\n", this, package_version,
		  package_version_name, package_version_name_maxlen,
		  attributes_supported, attributes_setting);

	return EFI_EXIT(EFI_UNSUPPORTED);
}

/* Place holder; not supported */
static
efi_status_t EFIAPI efi_firmware_set_package_info_unsupported(
	struct efi_firmware_management_protocol *this,
	const void *image,
	efi_uintn_t *image_size,
	const void *vendor_code,
	u32 package_version,
	const u16 *package_version_name)
{
	EFI_ENTRY("%p %p %p %p %x %p\n", this, image, image_size, vendor_code,
		  package_version, package_version_name);

	return EFI_EXIT(EFI_UNSUPPORTED);
}

/**
 * efi_firmware_get_lsv_from_dtb - get lowest supported version from dtb
 * @image_index:	Image index
 * @image_type_id:	Image type id
 * @lsv:		Pointer to store the lowest supported version
 *
 * Read the firmware version information from dtb.
 */
static void efi_firmware_get_lsv_from_dtb(u8 image_index,
					  efi_guid_t *image_type_id, u32 *lsv)
{
	const void *fdt = gd->fdt_blob;
	const fdt32_t *val;
	const char *guid_str;
	int len, offset, index;
	int parent, ret;

	*lsv = 0;

	parent = fdt_subnode_offset(fdt, 0, "firmware-version");
	if (parent < 0)
		return;

	fdt_for_each_subnode(offset, fdt, parent) {
		efi_guid_t guid;

		guid_str = fdt_getprop(fdt, offset, "image-type-id", &len);
		if (!guid_str)
			continue;
		ret = uuid_str_to_bin(guid_str, guid.b, UUID_STR_FORMAT_GUID);
		if (ret < 0) {
			log_warning("Wrong image-type-id format.\n");
			continue;
		}

		val = fdt_getprop(fdt, offset, "image-index", &len);
		if (!val)
			continue;
		index = fdt32_to_cpu(*val);

		if (!guidcmp(&guid, image_type_id) && index == image_index) {
			val = fdt_getprop(fdt, offset,
					  "lowest-supported-version", &len);
			if (val)
				*lsv = fdt32_to_cpu(*val);
		}
	}
}

/**
 * efi_firmware_fill_version_info - fill the version information
 * @image_info:		Image information
 * @fw_array:		Pointer to size of new image
 *
 * Fill the version information into image_info strucrure.
 *
 */
static
void efi_firmware_fill_version_info(struct efi_firmware_image_descriptor *image_info,
				    struct efi_fw_image *fw_array)
{
	u16 varname[13]; /* u"FmpStateXXXX" */
	efi_status_t ret;
	efi_uintn_t size, expected_size;
	uint num_banks = 1;
	uint active_index = 0;
	struct fmp_state *var_state;

	efi_firmware_get_lsv_from_dtb(fw_array->image_index,
				      &fw_array->image_type_id,
				      &image_info->lowest_supported_image_version);

	image_info->version_name = NULL; /* not supported */
	image_info->last_attempt_version = 0;
	image_info->last_attempt_status = LAST_ATTEMPT_STATUS_SUCCESS;
	image_info->version = 0;

	/* get the fw_version */
	efi_create_indexed_name(varname, sizeof(varname), "FmpState",
				fw_array->image_index);
	if (IS_ENABLED(CONFIG_FWU_MULTI_BANK_UPDATE)) {
		ret = fwu_get_active_index(&active_index);
		if (ret)
			return;

		num_banks = CONFIG_FWU_NUM_BANKS;
	}

	size = num_banks * sizeof(*var_state);
	expected_size = size;
	var_state = calloc(1, size);
	if (!var_state)
		return;

	ret = efi_get_variable_int(varname, &fw_array->image_type_id,
				   NULL, &size, var_state, NULL);
	if (ret == EFI_SUCCESS && expected_size == size)
		image_info->version = var_state[active_index].fw_version;

	free(var_state);
}

/**
 * efi_gen_capsule_guids - generate GUIDs for the images
 *
 * Generate the image_type_id for each image in the update_info.images array
 * using the first compatible from the device tree and a salt
 * UUID defined at build time.
 *
 * Returns:		status code
 */
static efi_status_t efi_gen_capsule_guids(void)
{
	int ret, i;
	struct uuid namespace;
	const char *compatible; /* Full array including null bytes */
	struct efi_fw_image *fw_array;

	fw_array = update_info.images;
	/* Check if we need to run (there are images and we didn't already generate their IDs) */
	if (!update_info.num_images ||
	    memchr_inv(&fw_array[0].image_type_id, 0, sizeof(fw_array[0].image_type_id)))
		return EFI_SUCCESS;

	ret = uuid_str_to_bin(CONFIG_EFI_CAPSULE_NAMESPACE_GUID,
			      (unsigned char *)&namespace, UUID_STR_FORMAT_GUID);
	if (ret) {
		log_debug("%s: EFI_CAPSULE_NAMESPACE_GUID is invalid: %d\n", __func__, ret);
		return EFI_INVALID_PARAMETER;
	}

	compatible = ofnode_read_string(ofnode_root(), "compatible");
	if (!compatible) {
		log_debug("%s: model or compatible not defined\n", __func__);
		return EFI_INVALID_PARAMETER;
	}

	for (i = 0; i < update_info.num_images; i++) {
		if (!fw_array[i].fw_name) {
			log_err("fw_name is not defined. Not generating capsule GUIDs\n");
			return EFI_INVALID_PARAMETER;
		}
		gen_v5_guid(&namespace,
			    &fw_array[i].image_type_id,
			    compatible, strlen(compatible),
			    fw_array[i].fw_name, u16_strlen(fw_array[i].fw_name) * sizeof(uint16_t),
			    NULL);

		log_debug("Image %ls UUID %pUl\n", fw_array[i].fw_name,
			  &fw_array[i].image_type_id);
	}

	return EFI_SUCCESS;
}

/**
 * efi_fill_image_desc_array - populate image descriptor array
 * @image_info_size:		Size of @image_info
 * @image_info:			Image information
 * @descriptor_version:		Pointer to version number
 * @descriptor_count:		Image count
 * @descriptor_size:		Pointer to descriptor size
 * @package_version:		Package version
 * @package_version_name:	Package version's name
 *
 * Return information about the current firmware image in @image_info.
 * @image_info will consist of a number of descriptors.
 * Each descriptor will be created based on efi_fw_image array.
 *
 * Return		status code
 */
static efi_status_t efi_fill_image_desc_array(
	efi_uintn_t *image_info_size,
	struct efi_firmware_image_descriptor *image_info,
	u32 *descriptor_version,
	u8 *descriptor_count,
	efi_uintn_t *descriptor_size,
	u32 *package_version,
	u16 **package_version_name)
{
	size_t total_size;
	struct efi_fw_image *fw_array;
	int i, ret;

	total_size = sizeof(*image_info) * update_info.num_images;

	if (*image_info_size < total_size) {
		*image_info_size = total_size;

		return EFI_BUFFER_TOO_SMALL;
	}
	if (!image_info)
		return EFI_INVALID_PARAMETER;
	*image_info_size = total_size;

	ret = efi_gen_capsule_guids();
	if (ret != EFI_SUCCESS)
		return ret;

	fw_array = update_info.images;
	*descriptor_count = update_info.num_images;
	*descriptor_version = EFI_FIRMWARE_IMAGE_DESCRIPTOR_VERSION;
	*descriptor_size = sizeof(*image_info);
	*package_version = 0xffffffff; /* not supported */
	*package_version_name = NULL; /* not supported */

	for (i = 0; i < update_info.num_images; i++) {
		image_info[i].image_index = fw_array[i].image_index;
		image_info[i].image_type_id = fw_array[i].image_type_id;
		image_info[i].image_id = fw_array[i].image_index;
		image_info[i].image_id_name = fw_array[i].fw_name;

		efi_firmware_fill_version_info(&image_info[i], &fw_array[i]);

		image_info[i].size = 0;
		image_info[i].attributes_supported =
			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 (IS_ENABLED(CONFIG_EFI_CAPSULE_AUTHENTICATE))
			image_info[0].attributes_setting |=
				IMAGE_ATTRIBUTE_AUTHENTICATION_REQUIRED;

		image_info[i].hardware_instance = 1;
		image_info[i].dependencies = NULL;
	}

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

	*p_image = image;
	*p_image_size = image_size;
	return EFI_SUCCESS;
}

/**
 * efi_firmware_set_fmp_state_var - set FmpStateXXXX variable
 * @state:		Pointer to fmp state
 * @image_index:	image index
 *
 * Update the FmpStateXXXX variable with the firmware update state.
 *
 * Return:		status code
 */
static
efi_status_t efi_firmware_set_fmp_state_var(struct fmp_state *state, u8 image_index)
{
	u16 varname[13]; /* u"FmpStateXXXX" */
	efi_status_t ret;
	uint num_banks = 1;
	uint update_bank = 0;
	efi_uintn_t size;
	efi_guid_t *image_type_id;
	struct fmp_state *var_state;

	image_type_id = efi_firmware_get_image_type_id(image_index);
	if (!image_type_id)
		return EFI_INVALID_PARAMETER;

	efi_create_indexed_name(varname, sizeof(varname), "FmpState",
				image_index);

	if (IS_ENABLED(CONFIG_FWU_MULTI_BANK_UPDATE)) {
		ret = fwu_plat_get_update_index(&update_bank);
		if (ret)
			return EFI_INVALID_PARAMETER;

		num_banks = CONFIG_FWU_NUM_BANKS;
	}

	size = num_banks * sizeof(*var_state);
	var_state = malloc(size);
	if (!var_state)
		return EFI_OUT_OF_RESOURCES;

	/*
	 * GetVariable may fail, EFI_NOT_FOUND is returned if FmpState
	 * variable has not been set yet.
	 */
	ret = efi_get_variable_int(varname, image_type_id, NULL, &size,
				   var_state, NULL);
	if (ret != EFI_SUCCESS)
		memset(var_state, 0, num_banks * sizeof(*var_state));

	/*
	 * Only the fw_version is set here.
	 * lowest_supported_version in FmpState variable is ignored since
	 * it can be tampered if the file based EFI variable storage is used.
	 */
	var_state[update_bank].fw_version = state->fw_version;

	size = num_banks * sizeof(*var_state);
	ret = efi_set_variable_int(varname, image_type_id,
				   EFI_VARIABLE_READ_ONLY |
				   EFI_VARIABLE_NON_VOLATILE |
				   EFI_VARIABLE_BOOTSERVICE_ACCESS |
				   EFI_VARIABLE_RUNTIME_ACCESS,
				   size, var_state, false);

	free(var_state);

	return ret;
}

/**
 * efi_firmware_get_fw_version - get fw_version from FMP payload header
 * @p_image:		Pointer to new image
 * @p_image_size:	Pointer to size of new image
 * @state:		Pointer to fmp state
 *
 * Parse the FMP payload header and fill the fmp_state structure.
 * If no FMP payload header is found, fmp_state structure is not updated.
 *
 */
static void efi_firmware_get_fw_version(const void **p_image,
					efi_uintn_t *p_image_size,
					struct fmp_state *state)
{
	const struct fmp_payload_header *header;
	u32 fmp_hdr_signature = FMP_PAYLOAD_HDR_SIGNATURE;

	header = *p_image;
	if (header->signature == fmp_hdr_signature) {
		/* FMP header is inserted above the capsule payload */
		state->fw_version = header->fw_version;

		*p_image += header->header_size;
		*p_image_size -= header->header_size;
	}
}

/**
 * efi_firmware_verify_image - verify image
 * @p_image:		Pointer to new image
 * @p_image_size:	Pointer to size of new image
 * @image_index:	Image index
 * @state:		Pointer to fmp state
 *
 * Verify the capsule authentication and check if the fw_version
 * is equal or greater than the lowest supported version.
 *
 * Return:		status code
 */
static
efi_status_t efi_firmware_verify_image(const void **p_image,
				       efi_uintn_t *p_image_size,
				       u8 image_index,
				       struct fmp_state *state)
{
	u32 lsv;
	efi_status_t ret;
	efi_guid_t *image_type_id;

	ret = efi_firmware_capsule_authenticate(p_image, p_image_size);
	if (ret != EFI_SUCCESS)
		return ret;

	efi_firmware_get_fw_version(p_image, p_image_size, state);

	image_type_id = efi_firmware_get_image_type_id(image_index);
	if (!image_type_id)
		return EFI_INVALID_PARAMETER;

	efi_firmware_get_lsv_from_dtb(image_index, image_type_id, &lsv);
	if (state->fw_version < lsv) {
		log_err("Firmware version %u too low. Expecting >= %u. Aborting update\n",
			state->fw_version, lsv);
		return EFI_INVALID_PARAMETER;
	}

	return ret;
}

/**
 * efi_firmware_get_image_info - return information about the current
 *				     firmware image
 * @this:			Protocol instance
 * @image_info_size:		Size of @image_info
 * @image_info:			Image information
 * @descriptor_version:		Pointer to version number
 * @descriptor_count:		Pointer to number of descriptors
 * @descriptor_size:		Pointer to descriptor size
 * @package_version:		Package version
 * @package_version_name:	Package version's name
 *
 * Return information bout the current firmware image in @image_info.
 * @image_info will consist of a number of descriptors.
 * Each descriptor will be created based on "dfu_alt_info" variable.
 *
 * Return		status code
 */
static
efi_status_t EFIAPI efi_firmware_get_image_info(
	struct efi_firmware_management_protocol *this,
	efi_uintn_t *image_info_size,
	struct efi_firmware_image_descriptor *image_info,
	u32 *descriptor_version,
	u8 *descriptor_count,
	efi_uintn_t *descriptor_size,
	u32 *package_version,
	u16 **package_version_name)
{
	efi_status_t ret;

	EFI_ENTRY("%p %p %p %p %p %p %p %p\n", this,
		  image_info_size, image_info,
		  descriptor_version, descriptor_count, descriptor_size,
		  package_version, package_version_name);

	if (!image_info_size)
		return EFI_EXIT(EFI_INVALID_PARAMETER);

	if (*image_info_size &&
	    (!image_info || !descriptor_version || !descriptor_count ||
	     !descriptor_size || !package_version || !package_version_name))
		return EFI_EXIT(EFI_INVALID_PARAMETER);

	ret = efi_fill_image_desc_array(image_info_size, image_info,
					descriptor_version, descriptor_count,
					descriptor_size, package_version,
					package_version_name);

	return EFI_EXIT(ret);
}

#ifdef CONFIG_EFI_CAPSULE_FIRMWARE_FIT
/*
 * This FIRMWARE_MANAGEMENT_PROTOCOL driver provides a firmware update
 * method with existing FIT image format, and handles
 *   - multiple regions of firmware via DFU
 * but doesn't support
 *   - versioning of firmware image
 *   - package information
 */

/**
 * efi_firmware_fit_set_image - update the firmware image
 * @this:		Protocol instance
 * @image_index:	Image index number
 * @image:		New image
 * @image_size:		Size of new image
 * @vendor_code:	Vendor-specific update policy
 * @progress:		Function to report the progress of update
 * @abort_reason:	Pointer to string of abort reason
 *
 * Update the firmware to new image, using dfu. The new image should
 * have FIT image format commonly used in U-Boot.
 * @vendor_code, @progress and @abort_reason are not supported.
 *
 * Return:		status code
 */
static
efi_status_t EFIAPI efi_firmware_fit_set_image(
	struct efi_firmware_management_protocol *this,
	u8 image_index,
	const void *image,
	efi_uintn_t image_size,
	const void *vendor_code,
	efi_status_t (*progress)(efi_uintn_t completion),
	u16 **abort_reason)
{
	int ret;
	efi_status_t status;
	struct fmp_state state = { 0 };
	char *orig_dfu_env;
	void *img;

	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_verify_image(&image, &image_size, image_index,
					   &state);
	if (status != EFI_SUCCESS)
		return EFI_EXIT(status);

	orig_dfu_env = env_get("dfu_alt_info");
	if (orig_dfu_env) {
		orig_dfu_env = strdup(orig_dfu_env);
		if (!orig_dfu_env) {
			log_err("strdup() failed!\n");
			return EFI_EXIT(EFI_OUT_OF_RESOURCES);
		}
	}
	if (env_set("dfu_alt_info", update_info.dfu_string)) {
		log_err("Unable to set env variable \"dfu_alt_info\"!\n");
		free(orig_dfu_env);
		return EFI_EXIT(EFI_DEVICE_ERROR);
	}

	/* Make sure the update fitImage is properly aligned to 8-bytes */
	if (!IS_ALIGNED((uintptr_t)image, 8)) {
		img = memalign(8, image_size);
		if (!img)
			return EFI_EXIT(EFI_BAD_BUFFER_SIZE);
		memcpy(img, image, image_size);
	} else {
		img = (void *)image;
	}

	ret = fit_update(img);

	if (!IS_ALIGNED((uintptr_t)image, 8))
		free(img);

	if (env_set("dfu_alt_info", orig_dfu_env))
		log_warning("Unable to restore env variable \"dfu_alt_info\".  Further DFU operations may fail!\n");

	free(orig_dfu_env);

	if (ret)
		return EFI_EXIT(EFI_DEVICE_ERROR);

	efi_firmware_set_fmp_state_var(&state, image_index);

	return EFI_EXIT(EFI_SUCCESS);
}

const struct efi_firmware_management_protocol efi_fmp_fit = {
	.get_image_info = efi_firmware_get_image_info,
	.get_image = efi_firmware_get_image_unsupported,
	.set_image = efi_firmware_fit_set_image,
	.check_image = efi_firmware_check_image_unsupported,
	.get_package_info = efi_firmware_get_package_info_unsupported,
	.set_package_info = efi_firmware_set_package_info_unsupported,
};
#endif /* CONFIG_EFI_CAPSULE_FIRMWARE_FIT */

#ifdef CONFIG_EFI_CAPSULE_FIRMWARE_RAW
/*
 * This FIRMWARE_MANAGEMENT_PROTOCOL driver provides a firmware update
 * method with raw data.
 */

/**
 * efi_firmware_raw_set_image - update the firmware image
 * @this:		Protocol instance
 * @image_index:	Image index number
 * @image:		New image
 * @image_size:		Size of new image
 * @vendor_code:	Vendor-specific update policy
 * @progress:		Function to report the progress of update
 * @abort_reason:	Pointer to string of abort reason
 *
 * Update the firmware to new image, using dfu. The new image should
 * be a single raw image.
 * @vendor_code, @progress and @abort_reason are not supported.
 *
 * Return:		status code
 */
static
efi_status_t EFIAPI efi_firmware_raw_set_image(
	struct efi_firmware_management_protocol *this,
	u8 image_index,
	const void *image,
	efi_uintn_t image_size,
	const void *vendor_code,
	efi_status_t (*progress)(efi_uintn_t completion),
	u16 **abort_reason)
{
	int ret;
	u8 dfu_alt_num;
	efi_status_t status;
	struct fmp_state state = { 0 };
	char *orig_dfu_env;

	EFI_ENTRY("%p %d %p %zu %p %p %p\n", this, image_index, image,
		  image_size, vendor_code, progress, abort_reason);

	if (!image)
		return EFI_EXIT(EFI_INVALID_PARAMETER);

	status = efi_firmware_verify_image(&image, &image_size, image_index,
					   &state);
	if (status != EFI_SUCCESS)
		return EFI_EXIT(status);

	/*
	 * dfu_alt_num is assigned from 0 while image_index starts from 1.
	 * dfu_alt_num is calculated by (image_index - 1) when multi bank update
	 * is not used.
	 */
	dfu_alt_num = image_index - 1;
	if (IS_ENABLED(CONFIG_FWU_MULTI_BANK_UPDATE)) {
		/*
		 * Based on the value of update bank, derive the
		 * image index value.
		 */
		ret = fwu_get_dfu_alt_num(image_index, &dfu_alt_num);
		if (ret) {
			log_debug("Unable to get FWU image_index\n");
			return EFI_EXIT(EFI_DEVICE_ERROR);
		}
	}

	orig_dfu_env = env_get("dfu_alt_info");
	if (orig_dfu_env) {
		orig_dfu_env = strdup(orig_dfu_env);
		if (!orig_dfu_env) {
			log_err("strdup() failed!\n");
			return EFI_EXIT(EFI_OUT_OF_RESOURCES);
		}
	}
	if (env_set("dfu_alt_info", update_info.dfu_string)) {
		log_err("Unable to set env variable \"dfu_alt_info\"!\n");
		free(orig_dfu_env);
		return EFI_EXIT(EFI_DEVICE_ERROR);
	}

	ret = dfu_write_by_alt(dfu_alt_num, (void *)image, image_size,
			       NULL, NULL);

	if (env_set("dfu_alt_info", orig_dfu_env))
		log_warning("Unable to restore env variable \"dfu_alt_info\".  Further DFU operations may fail!\n");

	free(orig_dfu_env);

	if (ret)
		return EFI_EXIT(EFI_DEVICE_ERROR);

	efi_firmware_set_fmp_state_var(&state, image_index);

	return EFI_EXIT(EFI_SUCCESS);
}

const struct efi_firmware_management_protocol efi_fmp_raw = {
	.get_image_info = efi_firmware_get_image_info,
	.get_image = efi_firmware_get_image_unsupported,
	.set_image = efi_firmware_raw_set_image,
	.check_image = efi_firmware_check_image_unsupported,
	.get_package_info = efi_firmware_get_package_info_unsupported,
	.set_package_info = efi_firmware_set_package_info_unsupported,
};
#endif /* CONFIG_EFI_CAPSULE_FIRMWARE_RAW */
