platform: msm_shared: Add changes as per AVB2.0 specs

As per the requirement of AVB2.0 current call flow aboot_init
is updated to make sure that device is booting with AVB2.0
enable.Fix kernel cmdline for recovery and add checks to verify
the boot image.

Change-Id: Icfb250eac71edf07ea6f6123ddd15c6aaaa1629f
diff --git a/include/err.h b/include/err.h
index 265c19c..b4e9c5a 100644
--- a/include/err.h
+++ b/include/err.h
@@ -51,5 +51,11 @@
 #define ERR_RECURSE_TOO_DEEP -23
 #define ERR_NOT_SUPPORTED -24
 #define ERR_TOO_BIG -25
+#define EIO 5      /* I/O error */
+#define ENOMEM 12  /* Out of memory */
+#define EACCES 13  /* Permission denied */
+#define ENODEV 19  /* No such device */
+#define EINVAL 22  /* Invalid argument */
+
 
 #endif
diff --git a/include/platform.h b/include/platform.h
index 55fd39e..f7a14cb 100644
--- a/include/platform.h
+++ b/include/platform.h
@@ -92,4 +92,7 @@
 bool platform_is_mdm9206();
 int is_vb_le_enabled();
 void* get_rpmb_snd_rcv_buff();
+int LoadImage(char *Pname, void **ImgBuf, uint32_t *ImgSzActual);
+void boot_verifier_init();
+uint32_t get_page_size();
 #endif
diff --git a/platform/msm_shared/avb/OEMPublicKey.h b/platform/msm_shared/avb/OEMPublicKey.h
new file mode 100644
index 0000000..6825696
--- /dev/null
+++ b/platform/msm_shared/avb/OEMPublicKey.h
@@ -0,0 +1,124 @@
+/* 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.
+*/
+#ifndef __OEM_PUBLIC_KEY_H__
+#define __OEM_PUBLIC_KEY_H__
+
+/**
+ * Internal builds use TestKeyRSA4096Public
+ * OEM should replace this Array with public key used to sign boot.img
+ * avbtool extract_public_key  --key KEY --output OUTPUT
+ */
+static const char OEMPublicKey[] = {
+    0x00, 0x00, 0x10, 0x00, 0x55, 0xd9, 0x04, 0xad, 0xd8, 0x04, 0xaf, 0xe3,
+    0xd3, 0x84, 0x6c, 0x7e, 0x0d, 0x89, 0x3d, 0xc2, 0x8c, 0xd3, 0x12, 0x55,
+    0xe9, 0x62, 0xc9, 0xf1, 0x0f, 0x5e, 0xcc, 0x16, 0x72, 0xab, 0x44, 0x7c,
+    0x2c, 0x65, 0x4a, 0x94, 0xb5, 0x16, 0x2b, 0x00, 0xbb, 0x06, 0xef, 0x13,
+    0x07, 0x53, 0x4c, 0xf9, 0x64, 0xb9, 0x28, 0x7a, 0x1b, 0x84, 0x98, 0x88,
+    0xd8, 0x67, 0xa4, 0x23, 0xf9, 0xa7, 0x4b, 0xdc, 0x4a, 0x0f, 0xf7, 0x3a,
+    0x18, 0xae, 0x54, 0xa8, 0x15, 0xfe, 0xb0, 0xad, 0xac, 0x35, 0xda, 0x3b,
+    0xad, 0x27, 0xbc, 0xaf, 0xe8, 0xd3, 0x2f, 0x37, 0x34, 0xd6, 0x51, 0x2b,
+    0x6c, 0x5a, 0x27, 0xd7, 0x96, 0x06, 0xaf, 0x6b, 0xb8, 0x80, 0xca, 0xfa,
+    0x30, 0xb4, 0xb1, 0x85, 0xb3, 0x4d, 0xaa, 0xaa, 0xc3, 0x16, 0x34, 0x1a,
+    0xb8, 0xe7, 0xc7, 0xfa, 0xf9, 0x09, 0x77, 0xab, 0x97, 0x93, 0xeb, 0x44,
+    0xae, 0xcf, 0x20, 0xbc, 0xf0, 0x80, 0x11, 0xdb, 0x23, 0x0c, 0x47, 0x71,
+    0xb9, 0x6d, 0xd6, 0x7b, 0x60, 0x47, 0x87, 0x16, 0x56, 0x93, 0xb7, 0xc2,
+    0x2a, 0x9a, 0xb0, 0x4c, 0x01, 0x0c, 0x30, 0xd8, 0x93, 0x87, 0xf0, 0xed,
+    0x6e, 0x8b, 0xbe, 0x30, 0x5b, 0xf6, 0xa6, 0xaf, 0xdd, 0x80, 0x7c, 0x45,
+    0x5e, 0x8f, 0x91, 0x93, 0x5e, 0x44, 0xfe, 0xb8, 0x82, 0x07, 0xee, 0x79,
+    0xca, 0xbf, 0x31, 0x73, 0x62, 0x58, 0xe3, 0xcd, 0xc4, 0xbc, 0xc2, 0x11,
+    0x1d, 0xa1, 0x4a, 0xbf, 0xfe, 0x27, 0x7d, 0xa1, 0xf6, 0x35, 0xa3, 0x5e,
+    0xca, 0xdc, 0x57, 0x2f, 0x3e, 0xf0, 0xc9, 0x5d, 0x86, 0x6a, 0xf8, 0xaf,
+    0x66, 0xa7, 0xed, 0xcd, 0xb8, 0xed, 0xa1, 0x5f, 0xba, 0x9b, 0x85, 0x1a,
+    0xd5, 0x09, 0xae, 0x94, 0x4e, 0x3b, 0xcf, 0xcb, 0x5c, 0xc9, 0x79, 0x80,
+    0xf7, 0xcc, 0xa6, 0x4a, 0xa8, 0x6a, 0xd8, 0xd3, 0x31, 0x11, 0xf9, 0xf6,
+    0x02, 0x63, 0x2a, 0x1a, 0x2d, 0xd1, 0x1a, 0x66, 0x1b, 0x16, 0x41, 0xbd,
+    0xbd, 0xf7, 0x4d, 0xc0, 0x4a, 0xe5, 0x27, 0x49, 0x5f, 0x7f, 0x58, 0xe3,
+    0x27, 0x2d, 0xe5, 0xc9, 0x66, 0x0e, 0x52, 0x38, 0x16, 0x38, 0xfb, 0x16,
+    0xeb, 0x53, 0x3f, 0xe6, 0xfd, 0xe9, 0xa2, 0x5e, 0x25, 0x59, 0xd8, 0x79,
+    0x45, 0xff, 0x03, 0x4c, 0x26, 0xa2, 0x00, 0x5a, 0x8e, 0xc2, 0x51, 0xa1,
+    0x15, 0xf9, 0x7b, 0xf4, 0x5c, 0x81, 0x9b, 0x18, 0x47, 0x35, 0xd8, 0x2d,
+    0x05, 0xe9, 0xad, 0x0f, 0x35, 0x74, 0x15, 0xa3, 0x8e, 0x8b, 0xcc, 0x27,
+    0xda, 0x7c, 0x5d, 0xe4, 0xfa, 0x04, 0xd3, 0x05, 0x0b, 0xba, 0x3a, 0xb2,
+    0x49, 0x45, 0x2f, 0x47, 0xc7, 0x0d, 0x41, 0x3f, 0x97, 0x80, 0x4d, 0x3f,
+    0xc1, 0xb5, 0xbb, 0x70, 0x5f, 0xa7, 0x37, 0xaf, 0x48, 0x22, 0x12, 0x45,
+    0x2e, 0xf5, 0x0f, 0x87, 0x92, 0xe2, 0x84, 0x01, 0xf9, 0x12, 0x0f, 0x14,
+    0x15, 0x24, 0xce, 0x89, 0x99, 0xee, 0xb9, 0xc4, 0x17, 0x70, 0x70, 0x15,
+    0xea, 0xbe, 0xc6, 0x6c, 0x1f, 0x62, 0xb3, 0xf4, 0x2d, 0x16, 0x87, 0xfb,
+    0x56, 0x1e, 0x45, 0xab, 0xae, 0x32, 0xe4, 0x5e, 0x91, 0xed, 0x53, 0x66,
+    0x5e, 0xbd, 0xed, 0xad, 0xe6, 0x12, 0x39, 0x0d, 0x83, 0xc9, 0xe8, 0x6b,
+    0x6c, 0x2d, 0xa5, 0xee, 0xc4, 0x5a, 0x66, 0xae, 0x8c, 0x97, 0xd7, 0x0d,
+    0x6c, 0x49, 0xc7, 0xf5, 0xc4, 0x92, 0x31, 0x8b, 0x09, 0xee, 0x33, 0xda,
+    0xa9, 0x37, 0xb6, 0x49, 0x18, 0xf8, 0x0e, 0x60, 0x45, 0xc8, 0x33, 0x91,
+    0xef, 0x20, 0x57, 0x10, 0xbe, 0x78, 0x2d, 0x83, 0x26, 0xd6, 0xca, 0x61,
+    0xf9, 0x2f, 0xe0, 0xbf, 0x05, 0x30, 0x52, 0x5a, 0x12, 0x1c, 0x00, 0xa7,
+    0x5d, 0xcc, 0x7c, 0x2e, 0xc5, 0x95, 0x8b, 0xa3, 0x3b, 0xf0, 0x43, 0x2e,
+    0x5e, 0xdd, 0x00, 0xdb, 0x0d, 0xb3, 0x37, 0x99, 0xa9, 0xcd, 0x9c, 0xb7,
+    0x43, 0xf7, 0x35, 0x44, 0x21, 0xc2, 0x82, 0x71, 0xab, 0x8d, 0xaa, 0xb4,
+    0x41, 0x11, 0xec, 0x1e, 0x8d, 0xfc, 0x14, 0x82, 0x92, 0x4e, 0x83, 0x6a,
+    0x0a, 0x6b, 0x35, 0x5e, 0x5d, 0xe9, 0x5c, 0xcc, 0x8c, 0xde, 0x39, 0xd1,
+    0x4a, 0x5b, 0x5f, 0x63, 0xa9, 0x64, 0xe0, 0x0a, 0xcb, 0x0b, 0xb8, 0x5a,
+    0x7c, 0xc3, 0x0b, 0xe6, 0xbe, 0xfe, 0x8b, 0x0f, 0x7d, 0x34, 0x8e, 0x02,
+    0x66, 0x74, 0x01, 0x6c, 0xca, 0x76, 0xac, 0x7c, 0x67, 0x08, 0x2f, 0x3f,
+    0x1a, 0xa6, 0x2c, 0x60, 0xb3, 0xff, 0xda, 0x8d, 0xb8, 0x12, 0x0c, 0x00,
+    0x7f, 0xcc, 0x50, 0xa1, 0x5c, 0x64, 0xa1, 0xe2, 0x5f, 0x32, 0x65, 0xc9,
+    0x9c, 0xbe, 0xd6, 0x0a, 0x13, 0x87, 0x3c, 0x2a, 0x45, 0x47, 0x0c, 0xca,
+    0x42, 0x82, 0xfa, 0x89, 0x65, 0xe7, 0x89, 0xb4, 0x8f, 0xf7, 0x1e, 0xe6,
+    0x23, 0xa5, 0xd0, 0x59, 0x37, 0x79, 0x92, 0xd7, 0xce, 0x3d, 0xfd, 0xe3,
+    0xa1, 0x0b, 0xcf, 0x6c, 0x85, 0xa0, 0x65, 0xf3, 0x5c, 0xc6, 0x4a, 0x63,
+    0x5f, 0x6e, 0x3a, 0x3a, 0x2a, 0x8b, 0x6a, 0xb6, 0x2f, 0xbb, 0xf8, 0xb2,
+    0x4b, 0x62, 0xbc, 0x1a, 0x91, 0x25, 0x66, 0xe3, 0x69, 0xca, 0x60, 0x49,
+    0x0b, 0xf6, 0x8a, 0xbe, 0x3e, 0x76, 0x53, 0xc2, 0x7a, 0xa8, 0x04, 0x17,
+    0x75, 0xf1, 0xf3, 0x03, 0x62, 0x1b, 0x85, 0xb2, 0xb0, 0xef, 0x80, 0x15,
+    0xb6, 0xd4, 0x4e, 0xdf, 0x71, 0xac, 0xdb, 0x2a, 0x04, 0xd4, 0xb4, 0x21,
+    0xba, 0x65, 0x56, 0x57, 0xe8, 0xfa, 0x84, 0xa2, 0x7d, 0x13, 0x0e, 0xaf,
+    0xd7, 0x9a, 0x58, 0x2a, 0xa3, 0x81, 0x84, 0x8d, 0x09, 0xa0, 0x6a, 0xc1,
+    0xbb, 0xd9, 0xf5, 0x86, 0xac, 0xbd, 0x75, 0x61, 0x09, 0xe6, 0x8c, 0x3d,
+    0x77, 0xb2, 0xed, 0x30, 0x20, 0xe4, 0x00, 0x1d, 0x97, 0xe8, 0xbf, 0xc7,
+    0x00, 0x1b, 0x21, 0xb1, 0x16, 0xe7, 0x41, 0x67, 0x2e, 0xec, 0x38, 0xbc,
+    0xe5, 0x1b, 0xb4, 0x06, 0x23, 0x31, 0x71, 0x1c, 0x49, 0xcd, 0x76, 0x4a,
+    0x76, 0x36, 0x8d, 0xa3, 0x89, 0x8b, 0x4a, 0x7a, 0xf4, 0x87, 0xc8, 0x15,
+    0x0f, 0x37, 0x39, 0xf6, 0x6d, 0x80, 0x19, 0xef, 0x5c, 0xa8, 0x66, 0xce,
+    0x1b, 0x16, 0x79, 0x21, 0xdf, 0xd7, 0x31, 0x30, 0xc4, 0x21, 0xdd, 0x34,
+    0x5b, 0xd2, 0x1a, 0x2b, 0x3e, 0x5d, 0xf7, 0xea, 0xca, 0x05, 0x8e, 0xb7,
+    0xcb, 0x49, 0x2e, 0xa0, 0xe3, 0xf4, 0xa7, 0x48, 0x19, 0x10, 0x9c, 0x04,
+    0xa7, 0xf4, 0x28, 0x74, 0xc8, 0x6f, 0x63, 0x20, 0x2b, 0x46, 0x24, 0x26,
+    0x19, 0x1d, 0xd1, 0x2c, 0x31, 0x6d, 0x5a, 0x29, 0xa2, 0x06, 0xa6, 0xb2,
+    0x41, 0xcc, 0x0a, 0x27, 0x96, 0x09, 0x96, 0xac, 0x47, 0x65, 0x78, 0x68,
+    0x51, 0x98, 0xd6, 0xd8, 0xa6, 0x2d, 0xa0, 0xcf, 0xec, 0xe2, 0x74, 0xf2,
+    0x82, 0xe3, 0x97, 0xd9, 0x7e, 0xd4, 0xf8, 0x0b, 0x70, 0x43, 0x3d, 0xb1,
+    0x7b, 0x97, 0x80, 0xd6, 0xcb, 0xd7, 0x19, 0xbc, 0x63, 0x0b, 0xfd, 0x4d,
+    0x88, 0xfe, 0x67, 0xac, 0xb8, 0xcc, 0x50, 0xb7, 0x68, 0xb3, 0x5b, 0xd6,
+    0x1e, 0x25, 0xfc, 0x5f, 0x3c, 0x8d, 0xb1, 0x33, 0x7c, 0xb3, 0x49, 0x01,
+    0x3f, 0x71, 0x55, 0x0e, 0x51, 0xba, 0x61, 0x26, 0xfa, 0xea, 0xe5, 0xb5,
+    0xe8, 0xaa, 0xcf, 0xcd, 0x96, 0x9f, 0xd6, 0xc1, 0x5f, 0x53, 0x91, 0xad,
+    0x05, 0xde, 0x20, 0xe7, 0x51, 0xda, 0x5b, 0x95, 0x67, 0xed, 0xf4, 0xee,
+    0x42, 0x65, 0x70, 0x13, 0x0b, 0x70, 0x14, 0x1c, 0xc9, 0xe0, 0x19, 0xca,
+    0x5f, 0xf5, 0x1d, 0x70, 0x4b, 0x6c, 0x06, 0x74, 0xec, 0xb5, 0x2e, 0x77,
+    0xe1, 0x74, 0xa1, 0xa3, 0x99, 0xa0, 0x85, 0x9e, 0xf1, 0xac, 0xd8, 0x7e};
+
+#endif /* __OEM_PUBLIC_KEY_H__ */
diff --git a/platform/msm_shared/avb/VerifiedBoot.c b/platform/msm_shared/avb/VerifiedBoot.c
new file mode 100644
index 0000000..ec455d3
--- /dev/null
+++ b/platform/msm_shared/avb/VerifiedBoot.c
@@ -0,0 +1,792 @@
+/* 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 "libavb/libavb.h"
+#include <malloc.h>
+
+#include <boot_verifier.h>
+#include <ab_partition_parser.h>
+#include <partition_parser.h>
+#include <recovery.h>
+#include <display_menu.h>
+#include <../../../app/aboot/mdtp.h>
+#include <platform/timer.h>
+#include "verifiedboot.h"
+#include <err.h>
+
+#ifndef DTB_PAD_SIZE
+#define DTB_PAD_SIZE            2048
+#endif
+#define INTERMEDIATE_DIGEST_LENGTH	64
+#define MAX_PART_NAME_SIZE		10
+
+#ifndef MDTP_SUPPORT
+int mdtp_activated(bool * activated)
+{
+	return 0;
+}
+void mdtp_fwlock_verify_lock(mdtp_ext_partition_verification_t *ext_partition)
+{
+	return;
+}
+#endif
+
+static const CHAR8 *VerifiedState = " androidboot.verifiedbootstate=";
+static const CHAR8 *KeymasterLoadState = " androidboot.keymaster=1";
+static const CHAR8 *Space = " ";
+#if !VERIFIED_BOOT_2
+static const CHAR8 *VerityMode = " androidboot.veritymode=";
+static struct verified_boot_verity_mode VbVm[] =
+{
+	{FALSE, "logging"},
+	{TRUE, "enforcing"},
+};
+#endif
+
+static struct verified_boot_state_name VbSn[] =
+{
+	{GREEN, "green"},
+	{ORANGE, "orange"},
+	{YELLOW, "yellow"},
+	{RED, "red"},
+};
+
+struct boolean_string
+{
+	BOOLEAN value;
+	CHAR8 *name;
+};
+
+static struct boolean_string BooleanString[] =
+{
+	{FALSE, "false"},
+	{TRUE, "true"}
+};
+
+
+typedef struct {
+	AvbOps *Ops;
+	AvbSlotVerifyData *SlotData;
+} VB2Data;
+
+UINT32 GetAVBVersion()
+{
+#if VERIFIED_BOOT_2
+	return 2;
+#elif VERIFIED_BOOT
+	return 1;
+#else
+	return 0;
+#endif
+}
+
+BOOLEAN VerifiedBootEnabled()
+{
+	return (GetAVBVersion() > NO_AVB);
+}
+
+static int GetCurrentSlotSuffix(Slot *CurrentSlot)
+{
+	if (!partition_multislot_is_supported())
+		return ERR_INVALID_ARGS;
+
+	strncpy(CurrentSlot->Suffix,
+			SUFFIX_SLOT(partition_find_active_slot()),
+			MAX_SLOT_SUFFIX_SZ);
+	return 0;
+}
+
+static int check_img_header(void *ImageHdrBuffer, uint32_t ImageHdrSize, uint32_t *imgsizeActual)
+{
+    /* These checks are already done before calling auth remove from here */
+#if VERIFIED_BOOT || VERIFIED_BOOT_2
+	boot_verifier_init();
+#endif
+	return 0;
+}
+
+static int GetActiveSlot(Slot *ActiveSlot)
+{
+	if (!partition_multislot_is_supported())
+		return ERR_INVALID_ARGS;
+	int idx = partition_find_active_slot();
+	if (idx != INVALID)
+	{
+		strncpy(ActiveSlot->Suffix,
+			SUFFIX_SLOT(partition_find_active_slot()),
+			MAX_SLOT_SUFFIX_SZ);
+		return 0;
+	}
+	return ERR_NOT_FOUND;
+}
+
+static int FindBootableSlot(Slot *BootableSlot)
+{
+   int Status = 0;
+
+   if (BootableSlot == NULL) {
+       dprintf(CRITICAL,"FindBootableSlot: input parameter invalid\n");
+       return -ERR_INVALID_ARGS;
+   }
+
+   Status = GetActiveSlot(BootableSlot);
+   if (Status != 0) {
+       /* clear bootable slot */
+       BootableSlot->Suffix[0] = '\0';
+   }
+   return Status;
+}
+
+bool IsSuffixEmpty(Slot *CheckSlot)
+{
+	if (CheckSlot == NULL) {
+		return TRUE;
+	}
+
+	if (strlen((char *)CheckSlot->Suffix) == 0) {
+		return TRUE;
+	}
+	return FALSE;
+}
+
+static int HandleActiveSlotUnbootable()
+{
+   int curr_slot;
+   curr_slot = partition_find_active_slot();
+   partition_deactivate_slot(curr_slot);
+   partition_find_boot_slot();
+
+   // should not reach here
+   return ERROR;
+}
+
+/*
+ * Returns length = 0 when there is failure.
+ */
+uint32_t GetSystemPath(char **SysPath)
+{
+	INT32 Index;
+	UINT32 Lun;
+	CHAR8 PartitionName[MAX_GPT_NAME_SIZE];
+	Slot CurSlot;
+	CHAR8 LunCharMapping[] = { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'};
+
+	if (GetCurrentSlotSuffix(&CurSlot))
+		return 0;
+
+	*SysPath = malloc(sizeof(char) * MAX_PATH_SIZE);
+	if (!*SysPath) {
+		dprintf(CRITICAL, "Failed to allocated memory for System path query\n");
+		return 0;
+	}
+
+	strncpy(PartitionName, "system", strlen("system") + 1);
+	strncat(PartitionName, CurSlot.Suffix, MAX_GPT_NAME_SIZE - 1);
+
+	Index = partition_get_index(PartitionName);
+	if (Index == INVALID_PTN || Index >= NUM_PARTITIONS) {
+		dprintf(CRITICAL, "System partition does not exit\n");
+		free(*SysPath);
+		return 0;
+	}
+
+	Lun = partition_get_lun(Index);
+	if (platform_boot_dev_isemmc()) {
+		snprintf(*SysPath, MAX_PATH_SIZE, " root=/dev/mmcblk0p%d",
+				Index + 1);
+	} else {
+		snprintf(*SysPath, MAX_PATH_SIZE, " root=/dev/sd%c%d",
+				LunCharMapping[Lun],
+				partition_get_index_in_lun(PartitionName, Lun));
+	}
+
+	dprintf(DEBUG, "System Path - %s \n", *SysPath);
+
+	return strlen(*SysPath);
+}
+
+static EFI_STATUS Appendvbcmdline(bootinfo *Info, const CHAR8 *Src)
+{
+	INT32 SrcLen = strlen(Src);
+	CHAR8 *Dst = (CHAR8 *)Info->vbcmdline + Info->vbcmdline_filled_len;
+
+	strlcat(Dst, Src, SrcLen);
+	Info->vbcmdline_filled_len += SrcLen;
+
+	return EFI_SUCCESS;
+}
+
+static EFI_STATUS AppendVBCommonCmdLine(bootinfo *Info)
+{
+	EFI_STATUS Status = EFI_SUCCESS;
+
+	if (GetAVBVersion() >= AVB_1) {
+		GUARD(Appendvbcmdline(Info, VerifiedState));
+		GUARD(Appendvbcmdline(Info, VbSn[Info->boot_state].name));
+	}
+	GUARD(Appendvbcmdline(Info, KeymasterLoadState));
+	GUARD(Appendvbcmdline(Info, Space));
+	return EFI_SUCCESS;
+}
+
+static EFI_STATUS VBCommonInit(bootinfo *Info)
+{
+	EFI_STATUS Status = EFI_SUCCESS;
+
+	Info->boot_state = RED;
+
+	// FIXME: Add boot call
+	/* allocate VB command line*/
+	Info->vbcmdline = malloc(2*DTB_PAD_SIZE);
+	if (Info->vbcmdline == NULL) {
+		dprintf(CRITICAL, "VB CmdLine allocation failed!\n");
+		Status = EFI_OUT_OF_RESOURCES;
+		return Status;
+	}
+	Info->vbcmdline_len = 2*DTB_PAD_SIZE;
+	Info->vbcmdline_filled_len = 0;
+	Info->vbcmdline[Info->vbcmdline_filled_len] = '\0';
+
+	return Status;
+}
+
+#if VERIFIED_BOOT_2
+/* Disable for VB 2.0 as this path is never taken */
+static EFI_STATUS LoadImageNoAuth(bootinfo *Info)
+{
+	return ERROR;
+}
+static EFI_STATUS load_image_and_authVB1(bootinfo *Info)
+{
+	return ERROR;
+}
+#else
+static EFI_STATUS LoadImageNoAuth(bootinfo *Info)
+{
+	EFI_STATUS Status = EFI_SUCCESS;
+
+	if (Info->images[0].image_buffer != NULL && Info->images[0].imgsize > 0) {
+		/* fastboot boot option image already loaded */
+		return Status;
+	}
+
+	Status = LoadImage(Info->pname, (VOID **)&(Info->images[0].image_buffer),
+	                   (UINT32 *)&(Info->images[0].imgsize));
+	if (Status != EFI_SUCCESS) {
+		dprintf(CRITICAL,
+		       "ERROR: Failed to load image from partition: %d\n", Status);
+		return EFI_LOAD_ERROR;
+	}
+	Info->num_loaded_images = 1;
+	Info->images[0].name = malloc(strlen(Info->pname) + 1);
+	strncpy(Info->images[0].name, Info->pname, strlen(Info->pname)); //FIXME
+	return Status;
+}
+
+static EFI_STATUS load_image_and_authVB1(bootinfo *Info)
+{
+	EFI_STATUS Status = EFI_SUCCESS;
+	CHAR8 StrPname[MAX_GPT_NAME_SIZE];
+	CHAR8 Pname[MAX_GPT_NAME_SIZE];
+	CHAR8 *SystemPath = NULL;
+	UINT32 SystemPathLen = 0;
+	device_info DevInfo_vb;
+
+	GUARD(VBCommonInit(Info));
+	GUARD(LoadImageNoAuth(Info));
+	boot_verifier_init();
+
+	// FIXME: INIT devinfo()
+	DevInfo_vb.is_unlocked = !is_device_locked();
+	DevInfo_vb.is_unlock_critical = !is_device_locked_critical();
+
+	strncpy(StrPname, "/", strlen("/"));
+	strncpy(Pname, Info->pname, strlen(Info->pname));
+	if (Info->multi_slot_boot) {
+		strncat(StrPname, Pname,
+	              strlen(Pname) - (MAX_SLOT_SUFFIX_SZ - 1));
+	} else {
+		strncat(StrPname, Pname, strlen(Pname));
+	}
+
+	Status = boot_verify_image((UINT8 *)Info->images[0].image_buffer,
+	                                Info->images[0].imgsize,
+					StrPname,
+	                                &Info->boot_state);
+	if (Status != EFI_SUCCESS || Info->boot_state == BOOT_STATE_MAX) {
+		dprintf(CRITICAL, "VBVerifyImage failed with: %d\n", Status);
+		return Status;
+	}
+
+	set_os_version((unsigned char *)Info->images[0].image_buffer);
+	if(!send_rot_command((uint32_t)DevInfo_vb.is_unlocked))
+		return EFI_LOAD_ERROR;
+
+	SystemPathLen = GetSystemPath(&SystemPath);
+	if (SystemPathLen == 0 || SystemPath == NULL) {
+		dprintf(CRITICAL, "GetSystemPath failed!\n");
+		return EFI_LOAD_ERROR;
+	}
+	GUARD(AppendVBCommonCmdLine(Info));
+	GUARD(Appendvbcmdline(Info, VerityMode));
+	GUARD(Appendvbcmdline(Info, VbVm[is_verity_enforcing()].name));
+	GUARD(Appendvbcmdline(Info, SystemPath));
+
+	Info->vb_data = NULL;
+	return Status;
+}
+#endif
+
+static BOOLEAN ResultShouldContinue(AvbSlotVerifyResult Result)
+{
+	switch (Result) {
+	case AVB_SLOT_VERIFY_RESULT_ERROR_OOM:
+	case AVB_SLOT_VERIFY_RESULT_ERROR_IO:
+	case AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_METADATA:
+	case AVB_SLOT_VERIFY_RESULT_ERROR_UNSUPPORTED_VERSION:
+        case AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_ARGUMENT:
+		return FALSE;
+
+	case AVB_SLOT_VERIFY_RESULT_OK:
+	case AVB_SLOT_VERIFY_RESULT_ERROR_VERIFICATION:
+	case AVB_SLOT_VERIFY_RESULT_ERROR_ROLLBACK_INDEX:
+	case AVB_SLOT_VERIFY_RESULT_ERROR_PUBLIC_KEY_REJECTED:
+		return TRUE;
+	}
+
+	return FALSE;
+}
+
+char *pname[] = {
+	"sbl1",
+	"rpm",
+	"tz",
+	"aboot",
+};
+
+static EFI_STATUS load_image_and_authVB2(bootinfo *Info)
+{
+	EFI_STATUS Status = EFI_SUCCESS;
+	AvbSlotVerifyResult Result;
+	AvbSlotVerifyData *SlotData = NULL;
+	VB2Data *VBData = NULL;
+	AvbOpsUserData *UserData = NULL;
+	AvbOps *Ops = NULL;
+	CHAR8 Pname[MAX_GPT_NAME_SIZE] = {0};
+	CHAR8 *SlotSuffix = NULL;
+	BOOLEAN AllowVerificationError = !is_device_locked();
+	BOOLEAN VerityEnforcing = is_verity_enforcing();
+	const CHAR8 *RequestedPartitionMission[] = {"boot", "dtbo", NULL};
+	const CHAR8 *RequestedPartitionRecovery[] = {"recovery", "dtbo", NULL};
+	const CHAR8 **RequestedPartition = NULL;
+	UINTN NumRequestedPartition = 0;
+	UINT32 ImageHdrSize = 0;
+	UINT32 imgsizeActual = 0;
+	VOID *image_buffer = NULL;
+	UINT32 imgsize = 0;
+        AvbSlotVerifyFlags VerifyFlags = AllowVerificationError ?
+           AVB_SLOT_VERIFY_FLAGS_ALLOW_VERIFICATION_ERROR :
+           AVB_SLOT_VERIFY_FLAGS_NONE;
+	AvbHashtreeErrorMode VerityFlags = AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE;
+	device_info DevInfo_vb;
+
+	Info->boot_state = RED;
+	GUARD(VBCommonInit(Info));
+
+	UserData = avb_calloc(sizeof(AvbOpsUserData));
+	if (UserData == NULL) {
+		dprintf(CRITICAL,
+		       "ERROR: Failed to allocate AvbOpsUserData\n");
+		Status = EFI_OUT_OF_RESOURCES;
+		goto out;
+	}
+
+	Ops = AvbOpsNew(UserData);
+	if (Ops == NULL) {
+		dprintf(CRITICAL, "ERROR: Failed to allocate AvbOps\n");
+		Status = EFI_OUT_OF_RESOURCES;
+		goto out;
+	}
+	if(Info->multi_slot_boot) {
+	strncpy(Pname, Info->pname, strlen(Info->pname));
+	if ((MAX_SLOT_SUFFIX_SZ + 1) > strlen(Pname)) {
+		dprintf(CRITICAL, "ERROR: Can not determine slot suffix\n");
+		Status = EFI_INVALID_PARAMETER;
+		goto out;
+	}
+	SlotSuffix = &Pname[strlen(Pname) - MAX_SLOT_SUFFIX_SZ + 1];
+	} else {
+		 SlotSuffix = "\0";
+	}
+
+	if(!Info->multi_slot_boot && Info->bootinto_recovery) {
+		RequestedPartition = RequestedPartitionRecovery;
+	NumRequestedPartition = ARRAY_SIZE (RequestedPartitionRecovery) - 1;
+	if (Info->num_loaded_images) {
+	/* fastboot boot option, skip Index 0, as boot image already
+	 * loaded */
+	RequestedPartition = &RequestedPartitionRecovery[1];
+	}
+	} else {
+	RequestedPartition = RequestedPartitionMission;
+        NumRequestedPartition = ARRAY_SIZE(RequestedPartitionMission) - 1;
+        if (Info->num_loaded_images) {
+                /* fastboot boot option, skip Index 0, as boot image already
+                 * loaded */
+                RequestedPartition = &RequestedPartitionMission[1];
+		}
+	}
+	if (Info->num_loaded_images) {
+		NumRequestedPartition--;
+	}
+
+	// FIXME: is this correct?
+	VerityFlags = VerityEnforcing ?
+				AVB_HASHTREE_ERROR_MODE_RESTART :
+				AVB_HASHTREE_ERROR_MODE_EIO;
+
+	Result = avb_slot_verify(Ops, RequestedPartition, SlotSuffix,
+				VerifyFlags, VerityFlags,
+				&SlotData);
+
+	if (AllowVerificationError && ResultShouldContinue(Result)) {
+		dprintf(CRITICAL, "State: Unlocked, AvbSlotVerify returned "
+		                    "%s, continue boot\n",
+		       avb_slot_verify_result_to_string(Result));
+	} else if (Result != AVB_SLOT_VERIFY_RESULT_OK) {
+		dprintf(CRITICAL,
+		       "ERROR: Device State %s, AvbSlotVerify returned %s\n",
+		       AllowVerificationError ? "Unlocked" : "Locked",
+		       avb_slot_verify_result_to_string(Result));
+		Status = EFI_LOAD_ERROR;
+		Info->boot_state = RED;
+		goto out;
+	}
+
+	for (UINTN ReqIndex = 0; ReqIndex < NumRequestedPartition; ReqIndex++) {
+		dprintf(DEBUG, "Requested Partition: %s\n",
+		       RequestedPartition[ReqIndex]);
+		for (UINTN loadedindex = 0;
+		     loadedindex < SlotData->num_loaded_partitions; loadedindex++) {
+			dprintf(DEBUG, "Loaded Partition: %s\n",
+			       SlotData->loaded_partitions[loadedindex].partition_name);
+			if (!strncmp((const char *)
+			            RequestedPartition[ReqIndex],
+			            SlotData->loaded_partitions[loadedindex].partition_name,
+			            strlen(SlotData->loaded_partitions[loadedindex]
+			                                .partition_name))) {
+				if (Info->num_loaded_images >= ARRAY_SIZE(Info->images)) {
+					dprintf(CRITICAL, "NumLoadedPartition"
+					                    "(%d) too large "
+					                    "max images(%d)\n",
+					       Info->num_loaded_images,
+					       ARRAY_SIZE(Info->images));
+					Status = EFI_LOAD_ERROR;
+					Info->boot_state = RED;
+					goto out;
+				}
+				Info->images[Info->num_loaded_images].name =
+				        SlotData->loaded_partitions[loadedindex].partition_name;
+				Info->images[Info->num_loaded_images].image_buffer =
+				        SlotData->loaded_partitions[loadedindex].data;
+				Info->images[Info->num_loaded_images].imgsize =
+				        SlotData->loaded_partitions[loadedindex].data_size;
+				Info->num_loaded_images++;
+				break;
+			}
+		}
+	}
+
+	if (Info->num_loaded_images < NumRequestedPartition) {
+		dprintf(CRITICAL, "ERROR: AvbSlotVerify slot data: num of loaded partitions %d, requested %lu\n",Info->num_loaded_images, NumRequestedPartition);
+		Status = EFI_LOAD_ERROR;
+		goto out;
+	}
+
+	dprintf(DEBUG, "Total loaded partition %d\n", Info->num_loaded_images);
+
+	VBData = (VB2Data *)avb_calloc(sizeof(VB2Data));
+	if (VBData == NULL) {
+		dprintf(CRITICAL, "ERROR: Failed to allocate VB2Data\n");
+		Status = EFI_OUT_OF_RESOURCES;
+		goto out;
+	}
+	VBData->Ops = Ops;
+	VBData->SlotData = SlotData;
+	Info->vb_data = (VOID *)VBData;
+
+	ImageHdrSize = get_page_size();
+	GUARD_OUT(getimage(Info, &image_buffer, &imgsize,(!Info->multi_slot_boot && Info->bootinto_recovery) ? "recovery" : "boot") );
+
+	Status = check_img_header(image_buffer, ImageHdrSize, &imgsizeActual);
+	if (Status != EFI_SUCCESS) {
+		dprintf(CRITICAL, "Invalid boot image header:%d\n", Status);
+		goto out;
+	}
+
+	if (imgsizeActual > imgsize) {
+		Status = EFI_BUFFER_TOO_SMALL;
+		dprintf(CRITICAL,
+		       "Boot size in vbmeta less than actual boot image size "
+		       "flash corresponding vbmeta.img\n");
+		goto out;
+	}
+	if (AllowVerificationError) {
+		Info->boot_state = ORANGE;
+	} else {
+		if (UserData->IsUserKey) {
+			Info->boot_state = YELLOW;
+		} else {
+			Info->boot_state = GREEN;
+		}
+	}
+
+	/* command line */
+	GUARD_OUT(AppendVBCommonCmdLine(Info));
+	GUARD_OUT(Appendvbcmdline(Info, SlotData->cmdline));
+	DevInfo_vb.is_unlocked = !is_device_locked();
+	set_os_version((unsigned char *)Info->images[0].image_buffer);
+	if(!send_rot_command((uint32_t)DevInfo_vb.is_unlocked))
+		return EFI_LOAD_ERROR;
+	dprintf(INFO, "VB2: Authenticate complete! boot state is: %s\n",
+	       VbSn[Info->boot_state].name);
+
+out:
+	if (Status != EFI_SUCCESS) {
+		if (SlotData != NULL) {
+			avb_slot_verify_data_free(SlotData);
+		}
+		if (Ops != NULL) {
+			AvbOpsFree(Ops);
+		}
+		if (UserData != NULL) {
+			avb_free(UserData);
+		}
+		if (VBData != NULL) {
+			avb_free(VBData);
+		}
+		Info->boot_state = RED;
+		if(Info->multi_slot_boot) {
+		HandleActiveSlotUnbootable();
+		/* HandleActiveSlotUnbootable should have swapped slots and
+		* reboot the device. If no bootable slot found, enter fastboot */
+			dprintf(CRITICAL, "No bootable slots found enter fastboot mode\n");
+		 } else {
+			dprintf(CRITICAL, "Non Multi-slot: Unbootable entering fastboot mode\n");
+		}
+
+		}
+
+	dprintf(CRITICAL, "VB2: boot state: %s(%d)\n",
+	       VbSn[Info->boot_state].name, Info->boot_state);
+	return Status;
+}
+
+static EFI_STATUS DisplayVerifiedBootScreen(bootinfo *Info)
+{
+	EFI_STATUS Status = EFI_SUCCESS;
+	CHAR8 ffbm_mode_string[FFBM_MODE_BUF_SIZE] = {'\0'};
+
+	if (GetAVBVersion() < AVB_1) {
+		return EFI_SUCCESS;
+	}
+
+	if (!strncmp(Info->pname, "boot", strlen("boot"))) {
+		Status = get_ffbm(ffbm_mode_string, FFBM_MODE_BUF_SIZE);
+		if (Status != EFI_SUCCESS) {
+			dprintf(DEBUG,
+			       "No Ffbm cookie found, ignore: %d\n", Status);
+			ffbm_mode_string[0] = '\0';
+		}
+	}
+
+	dprintf(DEBUG, "Boot State is : %d\n", Info->boot_state);
+	switch (Info->boot_state)
+        {
+		case RED:
+			display_bootverify_menu(DISPLAY_MENU_RED);
+			//if (Status != EFI_SUCCESS) {
+				dprintf(INFO, "Your device is corrupt. It can't be trusted and will not boot." \
+					"\nYour device will shutdown in 30s\n");
+			//}
+			udelay(30000000);
+			shutdown_device();
+			break;
+		case YELLOW:
+			display_bootverify_menu(DISPLAY_MENU_YELLOW);
+			//if (Status == EFI_SUCCESS) {
+				wait_for_users_action();
+			//} else {
+				dprintf(INFO, "Your device has loaded a different operating system." \
+					"\nWait for 5 seconds before proceeding\n");
+				udelay(5000000);
+			//}
+			break;
+		case ORANGE:
+			if (ffbm_mode_string[0] != '\0' && !target_build_variant_user()) {
+				dprintf(DEBUG, "Device will boot into FFBM mode\n");
+			} else {
+				//display_bootverify_menu(DISPLAY_MENU_ORANGE);
+				//if (Status == EFI_SUCCESS) {
+				//	wait_for_users_action();
+				//} else {
+					dprintf(INFO, "Device is unlocked, Skipping boot verification\n");
+					udelay(5000000);
+				//}
+			}
+			break;
+		default:
+			break;
+	}
+	return EFI_SUCCESS;
+}
+
+EFI_STATUS load_image_and_auth(bootinfo *Info)
+{
+	EFI_STATUS Status = EFI_SUCCESS;
+	BOOLEAN MdtpActive = FALSE;
+	UINT32 AVBVersion = NO_AVB;
+	mdtp_ext_partition_verification_t ext_partition;
+
+	if (Info == NULL) {
+		dprintf(CRITICAL, "Invalid parameter Info\n");
+		return EFI_INVALID_PARAMETER;
+	}
+
+	if (!Info->multi_slot_boot) {
+		if (Info->bootinto_recovery) {
+			dprintf(INFO, "Booting Into Recovery Mode\n");
+			strncpy(Info->pname, "recovery", strlen("recovery"));
+		} else {
+			dprintf(INFO, "Booting Into Mission Mode\n");
+			strncpy(Info->pname, "boot", strlen("boot"));
+		}
+	} else {
+		Slot CurrentSlot = {{0}};
+
+		GUARD(FindBootableSlot(&CurrentSlot));
+		if (IsSuffixEmpty(&CurrentSlot)) {
+			dprintf(CRITICAL, "No bootable slot\n");
+			return EFI_LOAD_ERROR;
+		}
+		strncpy(Info->pname, "boot", strlen("boot"));
+		strncat(Info->pname, CurrentSlot.Suffix, strlen(CurrentSlot.Suffix));
+	}
+
+	dprintf(DEBUG, "MultiSlot %s, partition name %s\n",
+	       BooleanString[Info->multi_slot_boot].name, Info->pname);
+
+	Status = mdtp_activated(&MdtpActive);
+	if (Status) {
+		dprintf(CRITICAL,
+			       "Failed to get activation state for MDTP, "
+			       "Status=%d."
+			       " Considering MDTP as active and continuing \n",
+			       Status);
+		if (Status != -1)
+			MdtpActive = TRUE;
+	}
+
+	AVBVersion = GetAVBVersion();
+	dprintf(DEBUG, "AVB version %d\n", AVBVersion);
+
+	/* Load and Authenticate */
+	switch (AVBVersion) {
+	case NO_AVB:
+		return LoadImageNoAuth(Info);
+		break;
+	case AVB_1:
+		Status = load_image_and_authVB1(Info);
+		break;
+	case AVB_2:
+		Status = load_image_and_authVB2(Info);
+		break;
+	default:
+		dprintf(CRITICAL, "Unsupported AVB version %d\n", AVBVersion);
+		Status = EFI_UNSUPPORTED;
+	}
+
+	// if MDTP is active Display Recovery UI
+	if (Status != EFI_SUCCESS && MdtpActive && !target_use_signed_kernel()) {
+		//FIXME: Hard coded to BOOT
+		ext_partition.partition = Info->bootinto_recovery ? MDTP_PARTITION_RECOVERY : MDTP_PARTITION_BOOT;
+		ext_partition.integrity_state = MDTP_PARTITION_STATE_UNSET;
+		ext_partition.page_size = get_page_size();
+		ext_partition.image_addr = (uint32)Info->images[0].image_buffer;
+		ext_partition.image_size = Info->images[0].imgsize;
+		ext_partition.sig_avail = FALSE;
+		mdtp_fwlock_verify_lock(&ext_partition);
+	}
+
+	if (!is_device_locked() && Status != EFI_SUCCESS) {
+		dprintf(CRITICAL, "load_image_and_auth failed %d\n", Status);
+		return Status;
+	}
+
+	DisplayVerifiedBootScreen(Info);
+
+	return Status;
+}
+
+#if VERIFIED_BOOT_2
+VOID free_verified_boot_resource(bootinfo *Info)
+{
+	dprintf(DEBUG, "free_verified_boot_resource\n");
+
+	if (Info == NULL) {
+		return;
+	}
+
+	VB2Data *VBData = Info->vb_data;
+	if (VBData != NULL) {
+		AvbOps *Ops = VBData->Ops;
+		if (Ops != NULL) {
+			if (Ops->user_data != NULL) {
+				avb_free(Ops->user_data);
+			}
+			AvbOpsFree(Ops);
+		}
+
+		AvbSlotVerifyData *SlotData = VBData->SlotData;
+		if (SlotData != NULL) {
+			avb_slot_verify_data_free(SlotData);
+		}
+		avb_free(VBData);
+	}
+
+	if (Info->vbcmdline != NULL) {
+		free(Info->vbcmdline);
+	}
+	return;
+}
+#else
+VOID free_verified_boot_resource(bootinfo *Info)
+{
+	return;
+}
+#endif
diff --git a/platform/msm_shared/avb/libavb/avb_ops.c b/platform/msm_shared/avb/libavb/avb_ops.c
new file mode 100644
index 0000000..97aa79b
--- /dev/null
+++ b/platform/msm_shared/avb/libavb/avb_ops.c
@@ -0,0 +1,572 @@
+/*
+ * 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;
+	UINT32 Offset = 0;
+	UINTN ptn = 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 (!strncmp(Partition,"boot",strlen("boot"))) {
+		/* API returns previously loaded Boot Image buffer address and size */
+		get_boot_image_info(Buffer, OutNumRead, "boot");
+		return AVB_IO_RESULT_OK;
+	}
+
+	index = partition_get_index(Partition);
+	ptn = partition_get_offset(index);
+
+	if (ReadOffset < 0) {
+		if ((-ReadOffset) > ptn) {
+			dprintf(CRITICAL,
+			       "Negative Offset outside range.\n");
+			Result = AVB_IO_RESULT_ERROR_RANGE_OUTSIDE_PARTITION;
+			goto out;
+		}
+		Offset = ptn - (-ReadOffset);
+		dprintf(DEBUG,
+		       "negative Offset (%lld) converted to (%u) \n", ReadOffset, Offset);
+	} else {
+		// check int64_t to UINT32 converstion?
+		Offset = ReadOffset;
+	}
+
+	if (Offset > ptn) {
+		dprintf(CRITICAL, "Offset outside range.\n");
+		Result = AVB_IO_RESULT_ERROR_RANGE_OUTSIDE_PARTITION;
+		goto out;
+	}
+
+	if (NumBytes > ptn - Offset) {
+		NumBytes = ptn - Offset;
+	}
+
+	dprintf(CRITICAL,
+	       "read from %s, 0x%x bytes at Offset 0x%x, partition size %lu\n",
+	       Partition, NumBytes, Offset, ptn);
+
+	/* |NumBytes| and or |Offset| can be unaligned to block size/page size.
+	 */
+	//PageSize = mmc_get_device_blocksize();
+	PageSize = get_page_size();
+	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%lx\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%lx outside range.\n",
+			       StartBlock, StartPageReadOffset, StartPageReadSize);
+			Result = AVB_IO_RESULT_ERROR_RANGE_OUTSIDE_PARTITION;
+			goto out;
+		}
+
+		Status = mmc_read(ptn, 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%lx\n",
+		       LastBlock, LastPageReadOffset, LastPageReadSize);
+
+		if (LastPageReadSize <= 0 || LastPageReadSize >= PageSize ||
+		    LastPageReadSize > (NumBytes - *OutNumRead)) {
+			dprintf(CRITICAL,
+			       "LastBlock 0x%x, ReadOffset 0x%x, read_size "
+			       "0x%lx 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%lx 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%lx outside range. StartPageReadSize %#lx PageSize %d ptn %#lx 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;
+
+	dprintf(DEBUG,
+	       "WriteRollbackIndex Location %zu, RollbackIndex %llu\n",
+	       RollbackIndexLocation, RollbackIndex);
+	/* Update rollback if the current slot is successful */
+	if (IsCurrentSlotSuccessful()) {
+		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;
+		}
+	} else {
+		dprintf(INFO, "Not updating rollback index as current "
+		                   "slot is not successful\n");
+	}
+	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);
+	}
+}
diff --git a/platform/msm_shared/avb/libavb/avb_ops.h b/platform/msm_shared/avb/libavb/avb_ops.h
index 2cf0f8a..15c7b22 100644
--- a/platform/msm_shared/avb/libavb/avb_ops.h
+++ b/platform/msm_shared/avb/libavb/avb_ops.h
@@ -63,6 +63,13 @@
 struct AvbOps;
 typedef struct AvbOps AvbOps;
 
+typedef struct {
+        uint32_t  Data1;
+        uint16_t  Data2;
+        uint16_t  Data3;
+        uint8_t   Data4[8];
+} EFI_GUID;
+
 /* Forward-declaration of operations in libavb_ab. */
 struct AvbABOps;
 
diff --git a/platform/msm_shared/avb/libavb/avb_sysdeps.h b/platform/msm_shared/avb/libavb/avb_sysdeps.h
index b7c5e8e..55e3e19 100644
--- a/platform/msm_shared/avb/libavb/avb_sysdeps.h
+++ b/platform/msm_shared/avb/libavb/avb_sysdeps.h
@@ -41,6 +41,7 @@
 #include <stddef.h>
 #include <stdint.h>
 #include <verifiedboot.h>
+#include <crypto_hash.h>
 
 /* If you don't have gcc or clang, these attribute macros may need to
  * be adjusted.
diff --git a/platform/msm_shared/avb/rules.mk b/platform/msm_shared/avb/rules.mk
new file mode 100644
index 0000000..6795e1d
--- /dev/null
+++ b/platform/msm_shared/avb/rules.mk
@@ -0,0 +1,25 @@
+LOCAL_DIR := $(GET_LOCAL_DIR)
+
+INCLUDES += -I$(LK_TOP_DIR)/include -I$(LK_TOP_DIR)/app/aboot -I$(LK_TOP_DIR)/platform/msm_shared -I$(LK_TOP_DIR)/platform/msm_shared/avb -I$(LK_TOP_DIR)/platform/msm_shared/include \
+
+CFLAGS += -DAVB_COMPILATION
+
+OBJS += $(LOCAL_DIR)/libavb/avb_chain_partition_descriptor.o \
+		$(LOCAL_DIR)/libavb/avb_crc32.o \
+		$(LOCAL_DIR)/libavb/avb_crypto.o \
+		$(LOCAL_DIR)/libavb/avb_descriptor.o \
+		$(LOCAL_DIR)/libavb/avb_footer.o \
+		$(LOCAL_DIR)/libavb/avb_hash_descriptor.o \
+		$(LOCAL_DIR)/libavb/avb_hashtree_descriptor.o \
+		$(LOCAL_DIR)/libavb/avb_kernel_cmdline_descriptor.o \
+		$(LOCAL_DIR)/libavb/avb_property_descriptor.o \
+		$(LOCAL_DIR)/libavb/avb_ops.o \
+		$(LOCAL_DIR)/libavb/avb_rsa.o \
+		$(LOCAL_DIR)/libavb/avb_sha256.o \
+		$(LOCAL_DIR)/libavb/avb_sha512.o \
+		$(LOCAL_DIR)/libavb/avb_slot_verify.o \
+		$(LOCAL_DIR)/libavb/avb_sysdeps_posix.o \
+		$(LOCAL_DIR)/libavb/avb_vbmeta_image.o \
+		$(LOCAL_DIR)/libavb/avb_util.o \
+		$(LOCAL_DIR)/libavb/avb_version.o \
+		$(LOCAL_DIR)/VerifiedBoot.o \
diff --git a/platform/msm_shared/display_menu.c b/platform/msm_shared/display_menu.c
index 8b74c9a..c9a58a8 100644
--- a/platform/msm_shared/display_menu.c
+++ b/platform/msm_shared/display_menu.c
@@ -78,7 +78,7 @@
 static bool is_thread_start = false;
 static struct select_msg_info msg_info;
 
-#if VERIFIED_BOOT
+#if VERIFIED_BOOT || VERIFIED_BOOT_2
 struct boot_verify_info {
 	int msg_type;
 	const char *warning_msg;
@@ -248,7 +248,7 @@
 	unlock_msg_info->info.option_index= 2;
 }
 
-#if VERIFIED_BOOT
+#if VERIFIED_BOOT || VERIFIED_BOOT_2
 /* msg_lock need to be holded when call this function. */
 void display_bootverify_menu_renew(struct select_msg_info *msg_info, int type)
 {
@@ -525,7 +525,7 @@
 	display_menu_thread_start(fastboot_menu_msg_info);
 }
 
-#if VERIFIED_BOOT
+#if VERIFIED_BOOT || VERIFIED_BOOT_2
 void display_bootverify_menu(int type)
 {
 	struct select_msg_info *bootverify_menu_msg_info;
diff --git a/platform/msm_shared/include/boot_device.h b/platform/msm_shared/include/boot_device.h
index 7d2451a..8fe4463 100644
--- a/platform/msm_shared/include/boot_device.h
+++ b/platform/msm_shared/include/boot_device.h
@@ -55,10 +55,40 @@
 };
 #endif
 
+#define MAX_NUMBER_OF_LOADED_IMAGES 32
+#ifndef MAX_GPT_NAME_SIZE
+#define MAX_GPT_NAME_SIZE 72
+#endif
+
+typedef struct {
+	char *name;
+	void *image_buffer;
+	uint32_t imgsize;
+} imagedata;
+
+typedef struct bootinfo {
+	int multi_slot_boot;
+	bool bootinto_recovery;
+	bool bootreason_alarm;
+	char pname[MAX_GPT_NAME_SIZE];
+	char bootable_slot[MAX_GPT_NAME_SIZE];
+	imagedata images[MAX_NUMBER_OF_LOADED_IMAGES];
+	uint32_t num_loaded_images;
+	uint32_t boot_state;
+	char *vbcmdline;
+	uint32_t vbcmdline_len;
+	uint32_t vbcmdline_filled_len;
+	void *vb_data;
+} bootinfo;
+
+int getimage(const bootinfo *Info, void **image_buffer, uint32_t *imgsize,
+                    char *imgname);
+
 void platform_read_boot_config();
 uint32_t platform_get_boot_dev();
 uint32_t platform_boot_dev_isemmc();
 void platform_boot_dev_cmdline(char *buf);
+int get_boot_image_info(void **image_buffer, uint32_t *imgsize,char *imgname);
 
 void *target_mmc_device();
 #endif
diff --git a/platform/msm_shared/include/verifiedboot.h b/platform/msm_shared/include/verifiedboot.h
new file mode 100644
index 0000000..9e16982
--- /dev/null
+++ b/platform/msm_shared/include/verifiedboot.h
@@ -0,0 +1,170 @@
+/* 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.
+*/
+
+#ifndef __VERIFIEDBOOT_H__
+#define __VERIFIEDBOOT_H__
+
+#include <stdlib.h>
+#include <stdint.h>
+#include <string.h>
+#include <sys/types.h>
+#include <mmc.h>
+#include <platform.h>
+#include <devinfo.h>
+#include <meta_format.h>
+#include <boot_device.h>
+#include <boot_verifier.h>
+#include <target.h>
+
+typedef enum {
+	NO_AVB	= 0,
+	AVB_1,
+	AVB_2,
+	AVB_LE
+} avb_versions;
+
+#define VB_SHA256_SIZE  32
+#define LE_BOOTIMG_SIG_SIZE 256
+#define abort() ASSERT(false);
+#define MAX_PATH_SIZE 64
+
+#define EFIERR(_a)		(-1 * (_a))
+
+#define EFI_SUCCESS               0
+#define EFI_LOAD_ERROR            EFIERR (1)
+#define EFI_INVALID_PARAMETER     EFIERR (2)
+#define EFI_UNSUPPORTED           EFIERR (3)
+#define EFI_BAD_BUFFER_SIZE       EFIERR (4)
+#define EFI_BUFFER_TOO_SMALL      EFIERR (5)
+#define EFI_NOT_READY             EFIERR (6)
+#define EFI_DEVICE_ERROR          EFIERR (7)
+#define EFI_WRITE_PROTECTED       EFIERR (8)
+#define EFI_OUT_OF_RESOURCES      EFIERR (9)
+#define EFI_VOLUME_CORRUPTED      EFIERR (10)
+#define EFI_VOLUME_FULL           EFIERR (11)
+#define EFI_NO_MEDIA              EFIERR (12)
+#define EFI_MEDIA_CHANGED         EFIERR (13)
+#define EFI_NOT_FOUND             EFIERR (14)
+#define EFI_ACCESS_DENIED         EFIERR (15)
+#define EFI_NO_RESPONSE           EFIERR (16)
+#define EFI_NO_MAPPING            EFIERR (17)
+#define EFI_TIMEOUT               EFIERR (18)
+#define EFI_NOT_STARTED           EFIERR (19)
+#define EFI_ALREADY_STARTED       EFIERR (20)
+#define EFI_ABORTED               EFIERR (21)
+#define EFI_ICMP_ERROR            EFIERR (22)
+
+#define EFI_TFTP_ERROR            EFIERR (23)
+#define EFI_PROTOCOL_ERROR        EFIERR (24)
+#define EFI_INCOMPATIBLE_VERSION  EFIERR (25)
+#define EFI_SECURITY_VIOLATION    EFIERR (26)
+#define EFI_CRC_ERROR             EFIERR (27)
+#define EFI_END_OF_MEDIA          EFIERR (28)
+#define EFI_END_OF_FILE           EFIERR (31)
+#define EFI_INVALID_LANGUAGE      EFIERR (32)
+
+#define EFI_WARN_UNKNOWN_GLYPH    EFIWARN (1)
+#define EFI_WARN_DELETE_FAILURE   EFIWARN (2)
+#define EFI_WARN_WRITE_FAILURE    EFIWARN (3)
+#define EFI_WARN_BUFFER_TOO_SMALL EFIWARN (4)
+
+typedef int       EFI_STATUS;
+typedef bool      BOOLEAN;
+typedef char      CHAR8;
+typedef int16_t   CHAR16;
+typedef void      VOID;
+typedef uint8_t   UINT8;
+typedef uint16_t  UINT16;
+typedef uint32_t  UINT32;
+typedef uint64_t  UINT64;
+typedef int16_t   INT16;
+typedef int32_t   INT32;
+typedef int64_t   INT64;
+typedef uintptr_t UINTN;
+
+typedef enum {
+	VB_UNDEFINED_HASH	= 0,
+	VB_SHA1,
+	VB_SHA256,
+	VB_UNSUPPORTED_HASH,
+	VB_RESERVED_HASH	= 0x7fffffff /* force to 32 bits */
+} vb_hash;
+
+#define GUARD(code)                                                            \
+    do {                                                                       \
+        Status = (code);                                                       \
+        if (Status != EFI_SUCCESS) {                                           \
+            dprintf(CRITICAL, "Err: line:%d %s() status: %d\n", __LINE__,      \
+                   __FUNCTION__, Status);                                      \
+            return Status;                                                     \
+        }                                                                      \
+    } while (0)
+
+#define GUARD_OUT(code)                                                        \
+    do {                                                                       \
+        Status = (code);                                                       \
+        if (Status != EFI_SUCCESS) {                                           \
+            dprintf(CRITICAL, "Err: line:%d %s() status: %d\n", __LINE__,      \
+                   __FUNCTION__, Status);                                      \
+            goto out;                                                          \
+        }                                                                      \
+    } while (0)
+
+/* forward declare bootinfo */
+typedef struct bootinfo bootinfo;
+
+BOOLEAN VerifiedBootEnabled();
+
+/**
+ * @return  0 - AVB disabled
+ *          1 - VB 1.0
+ *          2 - VB 2.0
+ *          3 - LE VB
+ */
+UINT32 GetAVBVersion();
+
+/**
+ * Authenticates and loads boot image in
+ * Info->Images on EFI_SUCCESS.
+ * Also provides Verified Boot command
+ * arguments (if any) in Info->vbcmdline
+ *
+ * @return EFI_STATUS
+ */
+int load_image_and_auth(bootinfo *Info);
+
+/**
+ *  Free resources/memory allocated by
+ *  verified boot, image_buffer, vbcmdline
+ *  VBData...
+ *
+ * @return VOID
+ */
+void free_verified_boot_resource(bootinfo *Info);
+
+#endif /* __VERIFIEDBOOT_H__ */
diff --git a/platform/msm_shared/rules.mk b/platform/msm_shared/rules.mk
index f8460ff..82c7d88 100755
--- a/platform/msm_shared/rules.mk
+++ b/platform/msm_shared/rules.mk
@@ -698,3 +698,8 @@
 ifeq ($(ENABLE_RPMB_SUPPORT), 1)
 include platform/msm_shared/rpmb/rules.mk
 endif
+
+ifeq ($(VERIFIED_BOOT_2), 1)
+OBJS += platform/msm_shared/boot_verifier.o
+endif
+include platform/msm_shared/avb/rules.mk