/*
 * 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;
	UINT64 Offset = 0;
	UINT64 ptn = 0;
	UINT64 part_size = 0;
	UINT32 PageSize = 0;
	UINT64 StartBlock = 0;
	UINT64 LastBlock = 0;
	UINT64 FullBlock = 0;
	UINT64 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*/
		UINT64 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%llx, ReadOffset 0x%llx, read_size 0x%llx\n",
		    StartBlock, StartPageReadOffset, StartPageReadSize);
		if (StartPageReadSize <= 0 || StartPageReadOffset >= PageSize ||
		    StartPageReadSize > PageSize - StartPageReadOffset ||
		    StartPageReadSize > NumBytes) {
			dprintf(CRITICAL,
			       "StartBlock 0x%llx, ReadOffset 0x%llx,"
				"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
		 */
		UINT64 LastPageReadOffset = 0;
		UINT64 ReadOffset2 = (LastBlock * PageSize);
		UINT64 LastPageReadSize = (Offset + NumBytes) - ReadOffset2;

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

		if (LastPageReadSize <= 0 || LastPageReadSize >= PageSize ||
		    LastPageReadSize > (NumBytes - *OutNumRead)) {
			dprintf(CRITICAL,
			       "LastBlock 0x%llx, ReadOffset 0x%llx, 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 */
		UINT64 FillPageReadSize = NumBytes - *OutNumRead;

		if ((FillPageReadSize % PageSize) != 0 ||
		    (NumBytes - StartPageReadSize) < FillPageReadSize) {
			dprintf(CRITICAL,
			       "FullBlock 0x%llx, 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%llx, 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);
	}
}
