/*
 * Copyright (C) 2017 The Android Open Source Project
 *
 * Permission is hereby granted, free of charge, to any person
 * obtaining a copy of this software and associated documentation
 * files (the "Software"), to deal in the Software without
 * restriction, including without limitation the rights to use, copy,
 * modify, merge, publish, distribute, sublicense, and/or sell copies
 * of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */

/* Copyright (c) 2018, The Linux Foundation. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 * * Redistributions of source code must retain the above copyright
 *  notice, this list of conditions and the following disclaimer.
 *  * Redistributions in binary form must reproduce the above
 * copyright notice, this list of conditions and the following
 * disclaimer in the documentation and/or other materials provided
 *  with the distribution.
 *   * Neither the name of The Linux Foundation nor the names of its
 * contributors may be used to endorse or promote products derived
 * from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

#include "../OEMPublicKey.h"
#include "avb_sysdeps.h"
#include "libavb.h"
#include <platform.h>
#include <err.h>
#include <ab_partition_parser.h>
#include <partition_parser.h>

struct partition_entry *PtnEntries;

bool IsCurrentSlotSuccessful()
{
   struct ab_slot_info slot_info[AB_SUPPORTED_SLOTS];
   int slot_idx =INVALID;

   slot_idx = partition_find_active_slot();
   if(slot_idx == INVALID)
   {
	   dprintf(CRITICAL,
	           "IsCurrentSlotSuccessful: no active slots found!\n");
	   return FALSE;
	}
   partition_fill_slot_meta(slot_info);
   if(!strncmp(slot_info[slot_idx].slot_is_succesful_rsp,"yes",strlen("yes")))
       return TRUE;

   return FALSE;
}

static struct partition_entry *Getpartition_entry(const char *Partition)
{
	int32_t Index = partition_get_index(Partition);
	struct partition_entry *partition_entries =
				partition_get_partition_entries();
	if (partition_entries == NULL) {
                dprintf(CRITICAL, "Getpartition_entry: No partition entry found\n");
                return NULL;
        }

	PtnEntries = partition_entries;

	if (Index == INVALID_PTN) {
		dprintf(CRITICAL, "Getpartition_entry: No partition entry for "
		           "%s, invalid index\n", Partition);
		return NULL;
	}
	return &PtnEntries[Index];
}

int get_unique_guid(const char *Partition, char *unique_guid)
{
        struct partition_entry *gp = Getpartition_entry(Partition);
	if(gp == NULL)
	{
		dprintf(CRITICAL, "Partition entry not found\n");
                return -1;

	}
        if (!unique_guid)
                return -1;

        memcpy(unique_guid, gp->unique_partition_guid, UNIQUE_PARTITION_GUID_SIZE);

        return 0;
}

static struct partition_entry *GetBootpartition_entry(Slot *BootSlot)
{
	int32_t Index = INVALID_PTN;
	struct partition_entry *partition_entries =
				partition_get_partition_entries();
	if( BootSlot == NULL)
        {
                dprintf(INFO, "No bootable slot found \n");
                return NULL;

        }
	if( partition_entries == NULL)
	{
		dprintf(INFO, "No partition entry found \n");
                return NULL;

	}
	PtnEntries = partition_entries;

	if (strncmp("_a", (const char *)BootSlot->Suffix, strlen((const char *)BootSlot->Suffix)) == 0) {
		Index = partition_get_index("boot_a");
	} else if (strncmp("_b", (const char *)BootSlot->Suffix, strlen((const char *)BootSlot->Suffix)) == 0) {
		Index = partition_get_index("boot_b");
	} else {
		dprintf(CRITICAL, "GetBootpartition_entry: No boot partition "
		                    "entry for slot %s\n", (char *)BootSlot->Suffix);
		return NULL;
	}

	if (Index == INVALID_PTN) {
		dprintf(CRITICAL,
		       "GetBootpartition_entry: No boot partition entry "
		       "for slot %s, invalid index\n", (char *)BootSlot->Suffix);
		return NULL;
	}
	return &PtnEntries[Index];
}

AvbIOResult AvbReadFromPartition(AvbOps *Ops, const char *Partition, int64_t ReadOffset,
                     size_t NumBytes, void *Buffer, size_t *OutNumRead)
{
	AvbIOResult Result = AVB_IO_RESULT_OK;
	EFI_STATUS Status = EFI_SUCCESS;
	VOID *Page = NULL;
	UINTN Offset = 0;
	UINTN ptn = 0;
	UINTN part_size = 0;
	UINT32 PageSize = 0;
	UINT32 StartBlock = 0;
	UINT32 LastBlock = 0;
	UINT32 FullBlock = 0;
	UINTN StartPageReadSize = 0;
	int index = INVALID_PTN;

	if (Partition == NULL || Buffer == NULL || OutNumRead == NULL || NumBytes <= 0) {
		dprintf(CRITICAL, "bad input paramaters\n");
		Result = AVB_IO_RESULT_ERROR_IO;
		goto out;
	}
	*OutNumRead = 0;

	if (!getimage(Buffer, OutNumRead, Partition)) {
		/* API returns previously loaded Images buffer address and size */
                dprintf(SPEW, "DEBUG: %s already loaded \n", Partition);
		return AVB_IO_RESULT_OK;
	}
	dprintf(SPEW, "Loading image %s\n", Partition);
	index = partition_get_index(Partition);
	ptn = partition_get_offset(index);
	part_size = partition_get_size(index);

	if (ReadOffset < 0) {
		if ((-ReadOffset) > (int64_t)part_size) {
			dprintf(CRITICAL,
			       "Negative Offset outside range.\n");
			Result = AVB_IO_RESULT_ERROR_RANGE_OUTSIDE_PARTITION;
			goto out;
		}
		Offset = part_size - (-ReadOffset);
		dprintf(DEBUG,
		       "negative Offset (%lld) converted to (0x%llx) \n", ReadOffset, Offset);
	} else {
		// check int64_t to UINT32 converstion?
		Offset = ReadOffset;
	}

	if (Offset > part_size) {
		dprintf(CRITICAL, "Offset outside range.\n");
		Result = AVB_IO_RESULT_ERROR_RANGE_OUTSIDE_PARTITION;
		goto out;
	}

	if (NumBytes > part_size - Offset) {
		NumBytes = part_size - Offset;
	}

	dprintf(CRITICAL,
	       "read from %s, 0x%x bytes at Offset 0x%llx, partition size %llu\n",
	       Partition, NumBytes, Offset, ptn);

	/* |NumBytes| and or |Offset| can be unaligned to block size.
	 */
	PageSize = mmc_get_device_blocksize();
	Page = avb_malloc(PageSize);
	if (Page == NULL) {
		dprintf(CRITICAL, "Allocate for partial read failed!");
		Result = AVB_IO_RESULT_ERROR_OOM;
		goto out;
	}

	StartBlock = Offset / PageSize;
	LastBlock = (NumBytes + Offset) / PageSize;
	FullBlock = StartBlock;
	StartPageReadSize = 0;

	if (Offset % PageSize != 0) {
		/* Offset not aligned to PageSize*/
		UINT32 StartPageReadOffset = Offset - (StartBlock * PageSize);

		if (StartBlock == LastBlock) {
			/* Offset & Offset + NumBytes are in same block */
			StartPageReadSize = NumBytes;
		} else {
			StartPageReadSize = PageSize - StartPageReadOffset;
			FullBlock++;
		}

		dprintf(DEBUG,
		       "StartBlock 0x%x, ReadOffset 0x%x, read_size 0x%llx\n",
		       StartBlock, StartPageReadOffset, StartPageReadSize);
		if (StartPageReadSize <= 0 || StartPageReadOffset >= PageSize ||
		    StartPageReadSize > PageSize - StartPageReadOffset ||
		    StartPageReadSize > NumBytes) {
			dprintf(CRITICAL,
			       "StartBlock 0x%x, ReadOffset 0x%x, read_size "
			       "0x%llx outside range.\n",
			       StartBlock, StartPageReadOffset, StartPageReadSize);
			Result = AVB_IO_RESULT_ERROR_RANGE_OUTSIDE_PARTITION;
			goto out;
		}

		Status = mmc_read(ptn + (StartBlock * PageSize), Page, PageSize);
		if (Status == EFI_SUCCESS) {
			avb_memcpy(Buffer, Page + StartPageReadOffset, StartPageReadSize);
			*OutNumRead += StartPageReadSize;
		} else {
			*OutNumRead = 0;
			dprintf(CRITICAL, "ReadBlocks failed %d\n", Status);
			goto out;
		}
	}

	if (*OutNumRead < NumBytes && (NumBytes + Offset) % PageSize != 0) {
		/* NumBytes + Offset not aligned to PageSize*/
		/* Offset for last block is always zero, start at Page boundary
		 */
		UINT32 LastPageReadOffset = 0;
		UINTN ReadOffset2 = (LastBlock * PageSize);
		UINTN LastPageReadSize = (Offset + NumBytes) - ReadOffset2;

		dprintf(DEBUG,
		       "LastBlock 0x%x, ReadOffset 0x%x, read_size 0x%llx\n",
		       LastBlock, LastPageReadOffset, LastPageReadSize);

		if (LastPageReadSize <= 0 || LastPageReadSize >= PageSize ||
		    LastPageReadSize > (NumBytes - *OutNumRead)) {
			dprintf(CRITICAL,
			       "LastBlock 0x%x, ReadOffset 0x%x, read_size "
			       "0x%llx outside range.\n",
			       LastBlock, LastPageReadOffset, LastPageReadSize);
			Result = AVB_IO_RESULT_ERROR_RANGE_OUTSIDE_PARTITION;
			goto out;
		}

		Status = mmc_read(ptn + ReadOffset2, Page, PageSize);
		if (Status == EFI_SUCCESS) {
			avb_memcpy(Buffer + (NumBytes - LastPageReadSize), Page,
			           LastPageReadSize);
			*OutNumRead += LastPageReadSize;
		} else {
			*OutNumRead = 0;
			dprintf(CRITICAL, "ReadBlocks failed %d\n", Status);
			goto out;
		}
	}

	if (*OutNumRead < NumBytes) {
		/* full block reads */
		UINTN FillPageReadSize = NumBytes - *OutNumRead;

		if ((FillPageReadSize % PageSize) != 0 ||
		    (NumBytes - StartPageReadSize) < FillPageReadSize) {
			dprintf(CRITICAL,
			       "FullBlock 0x%x, ReadOffset 0x%x, read_size "
			       "0x%llx outside range.\n",
			       FullBlock, 0, FillPageReadSize);
			Result = AVB_IO_RESULT_ERROR_RANGE_OUTSIDE_PARTITION;
			goto out;
		}
			dprintf(SPEW,
			       "FullBlock 0x%x, ReadOffset 0x%x, read_size "
			       "0x%llx outside range. StartPageReadSize %#llx PageSize %d ptn %#llx Buffer %p\n",
			       FullBlock, 0, FillPageReadSize, StartPageReadSize, PageSize, ptn, Buffer);
		Status = mmc_read(ptn + FullBlock * PageSize, Buffer + StartPageReadSize,
					FillPageReadSize);
		if (Status == EFI_SUCCESS) {
			*OutNumRead += FillPageReadSize;
		} else {
			*OutNumRead = 0;
			dprintf(CRITICAL, "ReadBlocks failed %d\n", Status);
			goto out;
		}
	}
out:
	if (Page != NULL) {
		avb_free(Page);
	}

	return Result;
}

AvbIOResult AvbWriteToPartition(AvbOps *Ops, const char *Partition, int64_t Offset,
                                size_t NumBytes, const void *Buffer)
{
	/* unsupported api */
	return AVB_IO_RESULT_ERROR_IO;
}

AvbIOResult
AvbValidateVbmetaPublicKey(AvbOps *Ops, const uint8_t *PublicKeyData,
                           size_t PublicKeyLength, const uint8_t *PublicKeyMetadata,
                           size_t PublicKeyMetadataLength, bool *OutIsTrusted)
{
	UINT8 *UserKeyBuffer = NULL;
	UINT32 UserKeyLength = 0;
	EFI_STATUS Status = EFI_SUCCESS;
	AvbOpsUserData *UserData = NULL;

	dprintf(DEBUG, "ValidateVbmetaPublicKey PublicKeyLength %d, "
	                      "PublicKeyMetadataLength %d\n",
	       PublicKeyLength, PublicKeyMetadataLength);

	if (Ops == NULL || OutIsTrusted == NULL || PublicKeyData == NULL) {
		dprintf(CRITICAL, "Invalid parameters\n");
		return AVB_IO_RESULT_ERROR_IO;
	}

	Status = get_userkey(&UserKeyBuffer, &UserKeyLength);
	if (Status != EFI_SUCCESS) {
		dprintf(CRITICAL, "get_userkey failed\n");
		return AVB_IO_RESULT_ERROR_IO;
	}

	UserData = (AvbOpsUserData *)Ops->user_data;
	UserData->IsUserKey = FALSE;

	if (PublicKeyLength == UserKeyLength &&
	    memcmp(PublicKeyData, UserKeyBuffer, PublicKeyLength) == 0) {
		*OutIsTrusted = true;
		UserData->IsUserKey = TRUE;
	} else if (PublicKeyLength == ARRAY_SIZE(OEMPublicKey) &&
	           memcmp(PublicKeyData, OEMPublicKey, PublicKeyLength) == 0) {
		*OutIsTrusted = true;
	} else {
		*OutIsTrusted = false;
		memset(UserData->PublicKey, 0, ARRAY_SIZE(UserData->PublicKey));
		UserData->PublicKeyLen = 0;
	}

	if (*OutIsTrusted == true) {
		if (PublicKeyLength > ARRAY_SIZE(UserData->PublicKey)) {
			dprintf(CRITICAL, "ValidateVbmetaPublicKey: "
			                    "public key length too large %d\n",
			       PublicKeyLength);
			return AVB_IO_RESULT_ERROR_OOM;
		}
		memcpy(UserData->PublicKey, PublicKeyData, PublicKeyLength);
		UserData->PublicKeyLen = PublicKeyLength;
	}
	dprintf(DEBUG,
	       "ValidateVbmetaPublicKey OutIsTrusted %d, UserKey %d\n",
	       *OutIsTrusted, UserData->IsUserKey);
	return AVB_IO_RESULT_OK;
}


AvbIOResult AvbReadRollbackIndex(AvbOps *Ops, size_t RollbackIndexLocation,
                                 uint64_t *OutRollbackIndex)
{

	EFI_STATUS Status = read_rollback_index(RollbackIndexLocation, OutRollbackIndex);

	if (Status != EFI_SUCCESS) {
		dprintf(CRITICAL, "ReadRollbackIndex failed! %d\n", Status);
		return AVB_IO_RESULT_ERROR_IO;
	}
	dprintf(DEBUG,
	       "ReadRollbackIndex Location %zu, RollbackIndex %llu\n",
	       RollbackIndexLocation, *OutRollbackIndex);
	return AVB_IO_RESULT_OK;
}

AvbIOResult
AvbWriteRollbackIndex(AvbOps *Ops, size_t RollbackIndexLocation, uint64_t RollbackIndex)
{
	EFI_STATUS Status = EFI_SUCCESS;
	BOOLEAN UpdateRollbackIndex = FALSE;
	AvbOpsUserData *UserData = NULL;

	dprintf(DEBUG,
	       "WriteRollbackIndex Location %zu, RollbackIndex %llu\n",
	       RollbackIndexLocation, RollbackIndex);

	UserData = (AvbOpsUserData *)Ops->user_data;
	if(UserData->IsMultiSlot) {
		/* Update rollback if the current slot is successful */
		if (IsCurrentSlotSuccessful()) {
			UpdateRollbackIndex = TRUE;
		} else {
			UpdateRollbackIndex = FALSE;
			dprintf(DEBUG, "Not updating rollback index as current "
					"slot is unbootable\n");
		}
	} else {
		/* When Multislot is disabled, always update*/
		UpdateRollbackIndex = TRUE;
	}

	if(UpdateRollbackIndex == TRUE) {
		dprintf(INFO,
		       "Updating rollback index %llu, for location %zu\n",
		       RollbackIndex, RollbackIndexLocation);
		Status = write_rollback_index(RollbackIndexLocation, RollbackIndex);
		if (Status != EFI_SUCCESS) {
			dprintf(CRITICAL, "ReadRollbackIndex failed! %d\n", Status);
			return AVB_IO_RESULT_ERROR_IO;
		}
	}
	return AVB_IO_RESULT_OK;
}

AvbIOResult AvbReadIsDeviceUnlocked(AvbOps *Ops, bool *OutIsUnlocked)
{
	if (OutIsUnlocked == NULL) {
		dprintf(CRITICAL, "bad input paramaters\n");
		return AVB_IO_RESULT_ERROR_IO;
	}
	*OutIsUnlocked = !is_device_locked();
	return AVB_IO_RESULT_OK;
}

static VOID GuidToHex(CHAR8 *Buf, EFI_GUID *Guid)
{
	CHAR8 HexDigits[17] = "0123456789abcdef";

	Buf[0] = HexDigits[(Guid->Data1 >> 28) & 0x0f];
	Buf[1] = HexDigits[(Guid->Data1 >> 24) & 0x0f];
	Buf[2] = HexDigits[(Guid->Data1 >> 20) & 0x0f];
	Buf[3] = HexDigits[(Guid->Data1 >> 16) & 0x0f];
	Buf[4] = HexDigits[(Guid->Data1 >> 12) & 0x0f];
	Buf[5] = HexDigits[(Guid->Data1 >> 8) & 0x0f];
	Buf[6] = HexDigits[(Guid->Data1 >> 4) & 0x0f];
	Buf[7] = HexDigits[(Guid->Data1 >> 0) & 0x0f];
	Buf[8] = '-';
	Buf[9] = HexDigits[(Guid->Data2 >> 12) & 0x0f];
	Buf[10] = HexDigits[(Guid->Data2 >> 8) & 0x0f];
	Buf[11] = HexDigits[(Guid->Data2 >> 4) & 0x0f];
	Buf[12] = HexDigits[(Guid->Data2 >> 0) & 0x0f];
	Buf[13] = '-';
	Buf[14] = HexDigits[(Guid->Data3 >> 12) & 0x0f];
	Buf[15] = HexDigits[(Guid->Data3 >> 8) & 0x0f];
	Buf[16] = HexDigits[(Guid->Data3 >> 4) & 0x0f];
	Buf[17] = HexDigits[(Guid->Data3 >> 0) & 0x0f];
	Buf[18] = '-';
	Buf[19] = HexDigits[(Guid->Data4[0] >> 4) & 0x0f];
	Buf[20] = HexDigits[(Guid->Data4[0] >> 0) & 0x0f];
	Buf[21] = HexDigits[(Guid->Data4[1] >> 4) & 0x0f];
	Buf[22] = HexDigits[(Guid->Data4[1] >> 0) & 0x0f];
	Buf[23] = '-';
	Buf[24] = HexDigits[(Guid->Data4[2] >> 4) & 0x0f];
	Buf[25] = HexDigits[(Guid->Data4[2] >> 0) & 0x0f];
	Buf[26] = HexDigits[(Guid->Data4[3] >> 4) & 0x0f];
	Buf[27] = HexDigits[(Guid->Data4[3] >> 0) & 0x0f];
	Buf[28] = HexDigits[(Guid->Data4[4] >> 4) & 0x0f];
	Buf[29] = HexDigits[(Guid->Data4[4] >> 0) & 0x0f];
	Buf[30] = HexDigits[(Guid->Data4[5] >> 4) & 0x0f];
	Buf[31] = HexDigits[(Guid->Data4[5] >> 0) & 0x0f];
	Buf[32] = HexDigits[(Guid->Data4[6] >> 4) & 0x0f];
	Buf[33] = HexDigits[(Guid->Data4[6] >> 0) & 0x0f];
	Buf[34] = HexDigits[(Guid->Data4[7] >> 4) & 0x0f];
	Buf[35] = HexDigits[(Guid->Data4[7] >> 0) & 0x0f];
	Buf[36] = '\0';
}

AvbIOResult AvbGetUniqueGuidForPartition(AvbOps *Ops, const char *PartitionName,
                                         char *GuidBuf, size_t GuidBufSize)
{
	EFI_STATUS Status = EFI_SUCCESS;
	char unique_partition_guid[UNIQUE_PARTITION_GUID_SIZE];
	CHAR16 UnicodePartition[MAX_GPT_NAME_SIZE] = {0};

	Status = get_unique_guid(PartitionName, unique_partition_guid);
	if (Status) {
		dprintf(CRITICAL,
		       "get_unique_guid: No partition entry for %s\n",
		       PartitionName);
		return AVB_IO_RESULT_ERROR_IO;
	}

	if ((strlen(PartitionName) + 1) > ARRAY_SIZE(UnicodePartition)) {
		dprintf(CRITICAL, "AvbGetUniqueGuidForPartition: Partition "
		                    "%s, name too large\n",
		       PartitionName);
		return AVB_IO_RESULT_ERROR_IO;
	}

	GuidToHex(GuidBuf, (EFI_GUID *)unique_partition_guid);
	dprintf(DEBUG, "%s uuid: %s\n", PartitionName, GuidBuf);

	return AVB_IO_RESULT_OK;
}

AvbIOResult AvbGetSizeOfPartition(AvbOps *Ops, const char *Partition, uint64_t *OutSizeNumBytes)
{
	AvbIOResult Result = AVB_IO_RESULT_OK;
	int index;

	if (Ops == NULL || Partition == NULL || OutSizeNumBytes == NULL) {
		dprintf(CRITICAL,
		       "AvbGetSizeOfPartition invalid parameter pointers\n");
		return AVB_IO_RESULT_ERROR_IO;
	}

	index = partition_get_index(Partition);
	*OutSizeNumBytes = (uint64_t)partition_get_size(index);
	if (*OutSizeNumBytes == 0)
		return AVB_IO_RESULT_ERROR_IO;

	return Result;
}

AvbOps *AvbOpsNew(VOID *UserData)
{
	AvbOps *Ops = avb_calloc(sizeof(AvbOps));
	if (Ops == NULL) {
		dprintf(CRITICAL, "Error allocating memory for AvbOps.\n");
		goto out;
	}

	Ops->user_data = UserData;
	Ops->read_from_partition = AvbReadFromPartition;
	Ops->write_to_partition = AvbWriteToPartition;
	Ops->validate_vbmeta_public_key = AvbValidateVbmetaPublicKey;
	Ops->read_rollback_index = AvbReadRollbackIndex;
	Ops->write_rollback_index = AvbWriteRollbackIndex;
	Ops->read_is_device_unlocked = AvbReadIsDeviceUnlocked;
	Ops->get_unique_guid_for_partition = AvbGetUniqueGuidForPartition;
	Ops->get_size_of_partition = AvbGetSizeOfPartition;

out:
	return Ops;
}

VOID AvbOpsFree(AvbOps *Ops)
{
	if (Ops != NULL) {
		avb_free(Ops);
	}
}
