Merge "msm-shared: scm: Properly init SCM command struct on alloc"
diff --git a/AndroidBoot.mk b/AndroidBoot.mk
index 5b1c348..2ebb180 100644
--- a/AndroidBoot.mk
+++ b/AndroidBoot.mk
@@ -13,12 +13,38 @@
   SIGNED_KERNEL := SIGNED_KERNEL=0
 endif
 
-ifeq ($(call is-board-platform,msm8660),true)
+ifeq ($(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_SUPPORTS_VERITY),true)
+  VERIFIED_BOOT := VERIFIED_BOOT=1
+else
+  VERIFIED_BOOT := VERIFIED_BOOT=0
+endif
+
+ifeq ($(TARGET_BUILD_VARIANT),user)
+  BUILD_VARIANT := USER_BUILD_VARIANT=true
+endif
+
+ifneq ($(TARGET_BUILD_VARIANT),user)
+  DEVICE_STATUS := DEFAULT_UNLOCK=true
+endif
+
+ifeq ($(TARGET_BOARD_PLATFORM),msm8660)
   BOOTLOADER_PLATFORM := msm8660_surf
 else
   BOOTLOADER_PLATFORM := $(TARGET_BOARD_PLATFORM)
 endif
 
+ABOOT_OUT := $(TARGET_OUT_INTERMEDIATES)/ABOOT_OBJ
+$(ABOOT_OUT):
+	$(hide) mkdir -p $(ABOOT_OUT)
+
+ABOOT_CLEAN:
+	$(hide) rm -f $(TARGET_ABOOT_ELF)
+
+# ELF binary for ABOOT
+TARGET_ABOOT_ELF := $(PRODUCT_OUT)/aboot.elf
+$(TARGET_ABOOT_ELF): ABOOT_CLEAN | $(ABOOT_OUT)
+	$(MAKE) -C bootable/bootloader/lk TOOLCHAIN_PREFIX=$(CROSS_COMPILE) BOOTLOADER_OUT=../../../$(ABOOT_OUT) $(BOOTLOADER_PLATFORM) $(EMMC_BOOT) $(SIGNED_KERNEL) $(VERIFIED_BOOT) $(DEVICE_STATUS)
+
 # NAND variant output
 TARGET_NAND_BOOTLOADER := $(PRODUCT_OUT)/appsboot.mbn
 NAND_BOOTLOADER_OUT := $(TARGET_OUT_INTERMEDIATES)/NAND_BOOTLOADER_OBJ
@@ -45,8 +71,8 @@
 	$(MAKE) -C bootable/bootloader/lk TOOLCHAIN_PREFIX=$(CROSS_COMPILE) BOOTLOADER_OUT=../../../$(NAND_BOOTLOADER_OUT) $(BOOTLOADER_PLATFORM) $(SIGNED_KERNEL)
 
 # Top level for eMMC variant targets
-$(TARGET_EMMC_BOOTLOADER): emmc_appsbootldr_clean | $(EMMC_BOOTLOADER_OUT)
-	$(MAKE) -C bootable/bootloader/lk TOOLCHAIN_PREFIX=$(CROSS_COMPILE) BOOTLOADER_OUT=../../../$(EMMC_BOOTLOADER_OUT) $(BOOTLOADER_PLATFORM) EMMC_BOOT=1 $(SIGNED_KERNEL)
+$(TARGET_EMMC_BOOTLOADER): emmc_appsbootldr_clean | $(EMMC_BOOTLOADER_OUT) $(INSTALLED_KEYSTOREIMAGE_TARGET)
+	$(MAKE) -C bootable/bootloader/lk TOOLCHAIN_PREFIX=$(CROSS_COMPILE) BOOTLOADER_OUT=../../../$(EMMC_BOOTLOADER_OUT) $(BOOTLOADER_PLATFORM) EMMC_BOOT=1 $(SIGNED_KERNEL) $(VERIFIED_BOOT) $(DEVICE_STATUS)
 
 # Keep build NAND & eMMC as default for targets still using TARGET_BOOTLOADER
 TARGET_BOOTLOADER := $(PRODUCT_OUT)/EMMCBOOT.MBN
diff --git a/app/aboot/aboot.c b/app/aboot/aboot.c
index 389f6e4..fa80f28 100755
--- a/app/aboot/aboot.c
+++ b/app/aboot/aboot.c
@@ -68,6 +68,11 @@
 #include "board.h"
 #include "scm.h"
 
+#if VERIFIED_BOOT
+#include "boot_verifier.h"
+#include "secapp_loader.h"
+#endif
+
 extern  bool target_use_signed_kernel(void);
 extern void platform_uninit(void);
 extern void target_uninit(void);
@@ -101,6 +106,12 @@
 #define RECOVERY_MODE   0x77665502
 #define FASTBOOT_MODE   0x77665500
 
+#if VERIFIED_BOOT
+#define DM_VERITY_LOGGING    0x77665508
+#define DM_VERITY_ENFORCING  0x77665509
+#define DM_VERITY_KEYSCLEAR  0x7766550A
+#endif
+
 /* make 4096 as default size to ensure EFS,EXT4's erasing */
 #define DEFAULT_ERASE_SIZE  4096
 #define MAX_PANEL_BUF_SIZE 128
@@ -126,6 +137,26 @@
 static const char *baseband_dsda2   = " androidboot.baseband=dsda2";
 static const char *baseband_sglte2  = " androidboot.baseband=sglte2";
 
+#if VERIFIED_BOOT
+static const char *verity_mode = " androidboot.veritymode=";
+static const char *verified_state= " androidboot.verifiedbootstate=";
+
+//indexed based on enum values, green is 0 by default
+
+struct verified_boot_verity_mode vbvm[] =
+{
+	{false, "logging"},
+	{true, "enforcing"},
+};
+struct verified_boot_state_name vbsn[] =
+{
+	{GREEN, "green"},
+	{ORANGE, "orange"},
+	{YELLOW,"yellow"},
+	{RED,"red" },
+};
+#endif
+
 static unsigned page_size = 0;
 static unsigned page_mask = 0;
 static char ffbm_mode_string[FFBM_MODE_BUF_SIZE];
@@ -134,7 +165,11 @@
 /* Assuming unauthorized kernel image by default */
 static int auth_kernel_img = 0;
 
+#if VERIFIED_BOOT
+static device_info device = {DEVICE_MAGIC, 0, 0, 0, 0, 1};
+#else
 static device_info device = {DEVICE_MAGIC, 0, 0, 0, 0};
+#endif
 
 struct atag_ptbl_entry
 {
@@ -209,6 +244,10 @@
 	unsigned char *cmdline_final = NULL;
 	int pause_at_bootup = 0;
 	bool gpt_exists = partition_gpt_exists();
+#if VERIFIED_BOOT
+    uint32_t boot_state = boot_verify_get_state();
+#endif
+
 
 	if (cmdline && cmdline[0]) {
 		cmdline_len = strlen(cmdline);
@@ -221,6 +260,12 @@
 	cmdline_len += strlen(usb_sn_cmdline);
 	cmdline_len += strlen(sn_buf);
 
+#if VERIFIED_BOOT
+	cmdline_len += strlen(verified_state) + strlen(vbsn[boot_state].name);
+	cmdline_len += strlen(verity_mode) + strlen(vbvm[device.verity_mode].name);
+#endif
+
+
 	if (boot_into_recovery && gpt_exists)
 		cmdline_len += strlen(secondary_gpt_enable);
 
@@ -303,7 +348,22 @@
 			have_cmdline = 1;
 			while ((*dst++ = *src++));
 		}
+#if VERIFIED_BOOT
+		src = verified_state;
+		if(have_cmdline) --dst;
+		have_cmdline = 1;
+		while ((*dst++ = *src++));
+		src = vbsn[boot_state].name;
+		if(have_cmdline) --dst;
+		while ((*dst++ = *src++));
 
+		src = verity_mode;
+		if(have_cmdline) --dst;
+		while ((*dst++ = *src++));
+		src = vbvm[device.verity_mode].name;
+		if(have_cmdline) -- dst;
+		while ((*dst++ = *src++));
+#endif
 		src = usb_sn_cmdline;
 		if (have_cmdline) --dst;
 		have_cmdline = 1;
@@ -585,17 +645,36 @@
 static void verify_signed_bootimg(uint32_t bootimg_addr, uint32_t bootimg_size)
 {
 	int ret;
+#if !VERIFIED_BOOT
+#if IMAGE_VERIF_ALGO_SHA1
+	uint32_t auth_algo = CRYPTO_AUTH_ALG_SHA1;
+#else
+	uint32_t auth_algo = CRYPTO_AUTH_ALG_SHA256;
+#endif
+#endif
 
 	/* Assume device is rooted at this time. */
 	device.is_tampered = 1;
 
 	dprintf(INFO, "Authenticating boot image (%d): start\n", bootimg_size);
-
+#if VERIFIED_BOOT
+	if(boot_into_recovery)
+	{
+		ret = boot_verify_image((unsigned char *)bootimg_addr,
+				bootimg_size, "/recovery");
+	}
+	else
+	{
+		ret = boot_verify_image((unsigned char *)bootimg_addr,
+				bootimg_size, "/boot");
+	}
+	boot_verify_print_state();
+#else
 	ret = image_verify((unsigned char *)bootimg_addr,
 					   (unsigned char *)(bootimg_addr + bootimg_size),
 					   bootimg_size,
 					   CRYPTO_AUTH_ALG_SHA256);
-
+#endif
 	dprintf(INFO, "Authenticating boot image: done return value = %d\n", ret);
 
 	if (ret)
@@ -607,7 +686,24 @@
 #if USE_PCOM_SECBOOT
 	set_tamper_flag(device.is_tampered);
 #endif
-
+#if VERIFIED_BOOT
+	switch(boot_verify_get_state())
+	{
+		case RED:
+				dprintf(CRITICAL,
+						"Your device has failed verification and may not work properly.\nWait for 5 seconds before proceeding\n");
+				mdelay(5000);
+				break;
+		case YELLOW:
+				dprintf(CRITICAL,
+						"Your device has loaded a different operating system.\nWait for 5 seconds before proceeding\n");
+				mdelay(5000);
+				break;
+		default:
+				break;
+	}
+#endif
+#if !VERIFIED_BOOT
 	if(device.is_tampered)
 	{
 		write_device_info_mmc(&device);
@@ -619,6 +715,7 @@
 		ASSERT(0);
 	#endif
 	}
+#endif
 }
 
 static bool check_format_bit()
@@ -663,6 +760,27 @@
 	free(buf);
 	return ret;
 }
+#if VERIFIED_BOOT
+void boot_verifier_init()
+{
+	uint32_t boot_state;
+	/* Check if device unlock */
+	if(device.is_unlocked)
+	{
+		boot_verify_send_event(DEV_UNLOCK);
+		boot_verify_print_state();
+		dprintf(CRITICAL, "Device is unlocked! Skipping verification...\n");
+		return;
+	}
+	else
+	{
+		boot_verify_send_event(BOOT_INIT);
+	}
+
+	/* Initialize keystore */
+	boot_state = boot_verify_keystore_init();
+}
+#endif
 
 int boot_linux_from_mmc(void)
 {
@@ -769,6 +887,11 @@
 	}
 #endif
 
+#if VERIFIED_BOOT
+	boot_verifier_init();
+#endif
+
+
 	/* Authenticate Kernel */
 	dprintf(INFO, "use_signed_kernel=%d, is_unlocked=%d, is_tampered=%d.\n",
 		(int) target_use_signed_kernel(),
@@ -985,6 +1108,19 @@
 		}
 		#endif
 	}
+#if VERIFIED_BOOT
+	if(boot_verify_get_state() == ORANGE)
+	{
+		dprintf(CRITICAL,
+				"Your device has been unlocked and can't be trusted.\nWait for 5 seconds before proceeding\n");
+		mdelay(5000);
+	}
+
+	// send root of trust
+	if(!send_rot_command((uint32_t)device.is_unlocked))
+		ASSERT(0);
+#endif
+
 
 	if (boot_into_recovery && !device.is_unlocked && !device.is_tampered)
 		target_load_ssd_keystore();
@@ -1311,7 +1447,9 @@
 		info->is_unlocked = 0;
 		info->is_tampered = 0;
 		info->charger_screen_enabled = 0;
-
+#if VERIFIED_BOOT
+		info->verity_mode = 1;
+#endif
 		write_device_info_mmc(info);
 	}
 	memcpy(dev, info, sizeof(device_info));
@@ -1664,11 +1802,25 @@
 		return;
 	}
 #endif
+#if VERIFIED_BOOT
+	if(!(strncmp(arg, "userdata", 8)))
+		if(send_delete_keys_to_tz())
+			ASSERT(0);
+#endif
 	fastboot_okay("");
 }
 
 void cmd_erase(const char *arg, void *data, unsigned sz)
 {
+
+#if VERIFIED_BOOT
+	if(!device.is_unlocked)
+	{
+		fastboot_fail("device is locked. Cannot erase");
+		return;
+	}
+#endif
+
 	if(target_is_emmc_boot())
 		cmd_erase_mmc(arg, data, sz);
 	else
@@ -1973,11 +2125,29 @@
 	}
 #endif /* SSD_ENABLE */
 
+#if VERIFIED_BOOT
+	if(!device.is_unlocked)
+	{
+		fastboot_fail("device is locked. Cannot flash images");
+		return;
+	}
+#endif
+
 	sparse_header = (sparse_header_t *) data;
 	if (sparse_header->magic != SPARSE_HEADER_MAGIC)
 		cmd_flash_mmc_img(arg, data, sz);
 	else
 		cmd_flash_mmc_sparse_img(arg, data, sz);
+
+#if VERIFIED_BOOT
+	if((!strncmp(arg, "system", 6)) && !device.verity_mode)
+	{
+		// reset dm_verity mode to enforcing
+		device.verity_mode = 1;
+		write_device_info(&device);
+	}
+#endif
+
 	return;
 }
 
@@ -2089,12 +2259,35 @@
 	fastboot_okay("");
 }
 
+void cmd_oem_lock(const char *arg, void *data, unsigned sz)
+{
+	struct recovery_message msg;
+	if(device.is_unlocked)
+	{
+		device.is_unlocked = 0;
+		write_device_info(&device);
+		// upon oem lock, reboot to recovery to wipe user data
+		snprintf(msg.recovery, sizeof(msg.recovery), "recovery\n--wipe_data");
+		write_misc(0, &msg, sizeof(msg));
+		fastboot_okay("");
+		reboot_device(RECOVERY_MODE);
+	}
+	fastboot_okay("");
+}
+
+
 void cmd_oem_unlock(const char *arg, void *data, unsigned sz)
 {
 	if(!device.is_unlocked)
 	{
 		device.is_unlocked = 1;
 		write_device_info(&device);
+		struct recovery_message msg;
+		snprintf(msg.recovery, sizeof(msg.recovery), "recovery\n--wipe_data");
+		write_misc(0, &msg, sizeof(msg));
+
+		fastboot_okay("");
+		reboot_device(RECOVERY_MODE);
 	}
 	fastboot_okay("");
 }
@@ -2318,6 +2511,7 @@
 											{"reboot", cmd_reboot},
 											{"reboot-bootloader", cmd_reboot_bootloader},
 											{"oem unlock", cmd_oem_unlock},
+											{"oem lock", cmd_oem_lock},
 											{"oem device-info", cmd_oem_devinfo},
 											{"preflash", cmd_preflash},
 											{"oem enable-charger-screen", cmd_oem_enable_charger_screen},
@@ -2426,6 +2620,17 @@
 		boot_into_recovery = 1;
 	} else if(reboot_mode == FASTBOOT_MODE) {
 		boot_into_fastboot = true;
+#if VERIFIED_BOOT
+	} else if(reboot_mode == DM_VERITY_ENFORCING) {
+		device.verity_mode = 1;
+		write_device_info(&device);
+	} else if(reboot_mode == DM_VERITY_LOGGING) {
+		device.verity_mode = 0;
+		write_device_info(&device);
+	} else if(reboot_mode == DM_VERITY_KEYSCLEAR) {
+		if(send_delete_keys_to_tz())
+			ASSERT(0);
+#endif
 	}
 
 	if (!boot_into_fastboot)
diff --git a/app/aboot/devinfo.h b/app/aboot/devinfo.h
index a0d8743..108f252 100644
--- a/app/aboot/devinfo.h
+++ b/app/aboot/devinfo.h
@@ -43,6 +43,7 @@
 	bool is_tampered;
 	bool charger_screen_enabled;
 	char display_panel[MAX_PANEL_ID_LEN];
+	bool verity_mode; // 1 = enforcing, 0 = logging
 };
 
 #endif
diff --git a/app/rpmbtests/qseecom_lk_test.c b/app/rpmbtests/qseecom_lk_test.c
new file mode 100644
index 0000000..0bfcb9b
--- /dev/null
+++ b/app/rpmbtests/qseecom_lk_test.c
@@ -0,0 +1,358 @@
+/* Copyright (c) 2015, 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 <partition_parser.h>
+#include <qseecom_lk.h>
+#include <scm.h>
+
+//#include "qseecom_legacy.h"
+#include "qseecom_lk_api.h"
+#include <debug.h>
+#include <kernel/mutex.h>
+#include <malloc.h>
+#include <stdlib.h>
+#include <arch/defines.h>
+#include <string.h>
+
+/* commands supported from sample client */
+#define CLIENT_CMD0_GET_VERSION             0
+#define CLIENT_CMD1_BASIC_DATA              1
+#define CLIENT_CMD2_REGISTER_SB_PTR         2
+#define CLIENT_CMD3_RUN_CRYTPO_TEST         3
+#define CLIENT_CMD4_RUN_CRYTPO_PERF         4
+#define CLIENT_CMD5_RUN_SFS_TEST            5
+#define CLIENT_CMD6_RUN_BUF_ALIGNMENT_TEST  6
+#define CLIENT_CMD7_RUN_CRYPTO_RSA_TEST     7
+#define CLIENT_CMD8_RUN_RSA_PERF_TEST       8
+#define CLIENT_CMD9_RUN_CMNLIB_TEST         9
+#define CLIENT_CMD10_RUN_CORE_TEST          10
+#define CLIENT_CMD11_RUN_SECURECHANNEL_TEST 11
+#define CLIENT_CMD12_RUN_SERVICES_TEST      12
+#define CLIENT_CMD13_RUN_MISC_TEST          13
+#define CLIENT_CMD17_RUN_STORAGE_TEST       17
+#define CLIENT_APPSBL_QSEECOM_RUN_LISTENER_FRAMEWORK_TEST_1       50
+
+#define __64KB__ 0x10000
+#define __32KB__ 0x8000
+#define __16KB__ 0x4000
+#define __8KB__ 0x2000
+#define __4KB__ 0x1000
+#define __2KB__ 0x800
+#define __1KB__ 0x400
+
+#define LISTENER_TEST_SERVICE			0x100
+
+struct qsc_send_cmd {
+     unsigned int cmd_id;
+     unsigned int data;
+     unsigned int data2;
+     unsigned int len;
+     unsigned int start_pkt;
+     unsigned int end_pkt;
+     unsigned int test_buf_size;
+};
+
+struct qsc_send_cmd_rsp {
+  unsigned int data;
+  int status;
+};
+
+
+int listener_test_cmd_handler (void* buf, uint32_t size)
+{
+	uint32 *req = 0;
+	uint32 rsp = 0;
+
+	if ((!buf) || (size < 4)) {
+		dprintf(CRITICAL, "Invalid listener cmd handler inputs\n");
+		return -1;
+	}
+
+	req = (uint32 *)buf;
+	if (*req == (100 * 100)) {
+		dprintf(CRITICAL, "Listener Success\n");
+		rsp = *req * 100;
+		dprintf(CRITICAL, "rsp = %u\n", rsp);
+		memcpy (buf, &rsp, sizeof(uint32));
+		return 0;
+	} else {
+		dprintf(CRITICAL, "Listener Failure, req:%u\n", *req);
+		rsp = 0;
+		memcpy (buf, &rsp, sizeof(uint32));
+		return 0;
+	}
+}
+
+static struct qseecom_listener_services listeners[] = {
+		{
+			.service_name = "Listener Test service",
+			.id = LISTENER_TEST_SERVICE,
+			.sb_size = (20 * 1024),
+			.service_cmd_handler = listener_test_cmd_handler,
+		},
+};
+
+int qsc_run_get_version(char *appname, uint32_t iterations)
+{
+	struct qsc_send_cmd send_cmd;
+	struct qsc_send_cmd_rsp msgrsp={0};	/* response data sent from QSEE */
+	uint32_t i = 0, ret = 0, err = -1;
+
+	dprintf(CRITICAL, "%s:Get_version\n", __func__);
+
+	dprintf(CRITICAL, "(This may take a few minutes please wait....)\n");
+	/* Start the application */
+	for  (i = 0;  i < iterations;  i++) {
+		dprintf(CRITICAL, "iteration %d\n", i);
+		ret = qseecom_start_app(appname);
+		if (ret <= 0) {
+			dprintf(CRITICAL, "Start app: fail: ret:%d\n", ret);
+			err = -1;
+			goto err_ret;
+		}
+		dprintf(CRITICAL, "apphandle %u\n", ret);
+		ret = qseecom_start_app(appname);
+		if (ret <= 0) {
+			dprintf(CRITICAL, "Start app: fail: ret:%d\n", ret);
+			err = -1;
+			goto err_ret_shutdown;
+		}
+		dprintf(CRITICAL, "apphandle %u\n", ret);
+		send_cmd.cmd_id = CLIENT_CMD0_GET_VERSION;
+		err = qseecom_send_command(ret, &send_cmd, sizeof(struct qsc_send_cmd), &msgrsp, sizeof(struct qsc_send_cmd_rsp));
+		if (err) {
+			dprintf(CRITICAL, "Send app: fail\n");
+			goto err_ret_shutdown;
+		}
+		dprintf(ALWAYS, "The version of %s is: %u\n", appname, msgrsp.data);
+		/* Shutdown the application */
+		dprintf(ALWAYS, "Shutting down %s\n", appname);
+		err = qseecom_shutdown_app(ret);
+		if (err) {
+			dprintf(CRITICAL, "Failed to shutdown app: %d\n",err);
+			goto err_ret;
+		}
+		dprintf(ALWAYS, "Shutting down %s\n", appname);
+		err = qseecom_shutdown_app(ret);
+		if (err) {
+			dprintf(CRITICAL, "Failed to shutdown app: %d\n",err);
+			goto err_ret;
+		}
+
+    }
+err_ret_shutdown:
+	if (err) {
+		if (qseecom_shutdown_app(ret))
+			dprintf(CRITICAL, "Failed to shutdown app: %d\n",err);
+	}
+err_ret:
+	if (err)
+		dprintf(CRITICAL, "Test %u failed with error %d, shutting down %s\n", CLIENT_CMD0_GET_VERSION, err, appname);
+	else
+		dprintf(CRITICAL, "Test %u passed for iterations %u executing %s\n", CLIENT_CMD0_GET_VERSION, iterations, appname);
+	return err;
+}
+
+
+int qsc_run_start_stop_app_basic_test(char *appname, uint32_t iterations)
+{
+	uint32_t i = 0;
+	int ret = 0;			/* return value */
+	int err = 0;			/* return value */
+	struct qsc_send_cmd send_cmd = {0};
+	struct qsc_send_cmd_rsp msgrsp={0};	/* response data sent from QSEE */
+
+	dprintf(CRITICAL, "%s:Basic_start_stop_test\n", __func__);
+
+	dprintf(CRITICAL, "(This may take a few minutes please wait....)\n");
+	/* Start the application */
+    for  (i = 0;  i < iterations;  i++) {
+		dprintf(CRITICAL, "iteration %d\n", i);
+		ret = qseecom_start_app(appname);
+		if (ret <= 0) {
+			dprintf(CRITICAL, "Start app: fail: ret:%d\n", ret);
+			err = -1;
+			goto err_ret;
+		}
+		/* Send data using send command to QSEE application */
+		send_cmd.cmd_id = CLIENT_CMD1_BASIC_DATA;
+		send_cmd.start_pkt = 0;
+		send_cmd.end_pkt = 0;
+		send_cmd.test_buf_size = 0;
+		send_cmd.data = 100;
+		err = qseecom_send_command(ret, &send_cmd, sizeof(struct qsc_send_cmd), &msgrsp, sizeof(struct qsc_send_cmd_rsp));
+		if (err) {
+			dprintf(CRITICAL, "Send app: fail\n");
+			goto err_ret_shutdown;
+		}
+		if (((msgrsp.data)/100) != 10) {
+			dprintf(CRITICAL, "App Comm Error:%u\n", msgrsp.data);
+			err = -1;
+			goto err_ret_shutdown;
+		}
+		dprintf(CRITICAL, "msg.rsp:%u\n", msgrsp.data);
+		/* Shutdown the application */
+		err = qseecom_shutdown_app(ret);
+		if (err) {
+			dprintf(CRITICAL, "Failed to shutdown app: %d\n",err);
+			goto err_ret;
+		}
+    }
+err_ret_shutdown:
+    if (err) {
+		if (qseecom_shutdown_app(ret))
+			dprintf(CRITICAL, "Failed to shutdown app: %d\n",err);
+    }
+err_ret:
+	if (err)
+		dprintf(CRITICAL, "Test %u failed with error %d, shutting down %s\n", CLIENT_CMD0_GET_VERSION, err, appname);
+	else
+		dprintf(CRITICAL, "Test %u passed for iterations %u executing %s\n", CLIENT_CMD0_GET_VERSION, iterations, appname);
+		return err;
+}
+
+
+
+int qsc_run_start_stop_app_listener_test(char *appname, uint32_t iterations)
+{
+	uint32_t i = 0;
+	int ret = 0;			/* return value */
+	int err = 0;			/* return value */
+	struct qsc_send_cmd send_cmd;
+	struct qsc_send_cmd_rsp msgrsp={0};	/* response data sent from QSEE */
+
+	dprintf(CRITICAL, "%s:qsc_run_start_stop_app_listener_test\n", __func__);
+
+	dprintf(CRITICAL, "(This may take a few minutes please wait....)\n");
+
+	ret = qseecom_register_listener(&listeners[0]);
+	if (ret < 0) {
+		dprintf(CRITICAL, "Reg Listener: fail: ret:%d\n", ret);
+		err = -1;
+		goto err_ret;
+	}
+	/* Start the application */
+    for  (i = 0;  i < iterations;  i++) {
+		dprintf(CRITICAL, "iteration %d\n", i);
+		ret = qseecom_start_app(appname);
+		if (ret <= 0) {
+			dprintf(CRITICAL, "Start app: fail: ret:%d\n", ret);
+			err = -1;
+			goto err_dereg;
+		}
+		/* Send data using send command to QSEE application */
+		send_cmd.cmd_id = CLIENT_APPSBL_QSEECOM_RUN_LISTENER_FRAMEWORK_TEST_1;
+		send_cmd.start_pkt = 0;
+		send_cmd.end_pkt = 0;
+		send_cmd.test_buf_size = 0;
+		send_cmd.data = 100;
+		err = qseecom_send_command(ret, &send_cmd, sizeof(struct qsc_send_cmd), &msgrsp, sizeof(struct qsc_send_cmd_rsp));
+		if (err) {
+			dprintf(CRITICAL, "Send app: fail\n");
+			goto err_ret_shutdown;
+		}
+		if (((msgrsp.data)/100) != 10) {
+			dprintf(CRITICAL, "App Comm Error:%u Status:%d\n", msgrsp.data, msgrsp.status);
+			err = -1;
+			goto err_ret_shutdown;
+		}
+		/* Shutdown the application */
+		err = qseecom_shutdown_app(ret);
+		if (err) {
+			dprintf(CRITICAL, "Failed to shutdown app: %d\n",err);
+			goto err_dereg;
+		}
+    }
+
+err_ret_shutdown:
+	if (err) {
+	   	if (qseecom_shutdown_app(ret))
+	   		dprintf(CRITICAL, "Failed to shutdown app: %d\n",err);
+	}
+err_dereg:
+	ret = qseecom_deregister_listener(listeners[0].id);
+	if (ret < 0) {
+		dprintf(CRITICAL, "DeReg Listener: fail: ret:%d\n", ret);
+		err = -1;
+	}
+err_ret:
+	if (err)
+		dprintf(CRITICAL, "Test %u failed with error %d, shutting down %s\n", CLIENT_CMD0_GET_VERSION, err, appname);
+	else
+		dprintf(CRITICAL, "Test %u passed for iterations %u executing %s\n", CLIENT_CMD0_GET_VERSION, iterations, appname);
+	return err;
+}
+
+int qseecom_test_cmd_handler(const char *arg) {
+	char *token = NULL;
+	char * appname = NULL;
+	uint32_t test = 0;
+	uint32_t iterations = 0;
+
+	token = strtok((char *)arg, " ");
+	if (!token) {
+		dprintf(CRITICAL, "Appname not provided, error\n");
+		return -1;
+	}
+	appname = token;
+
+	token = strtok(NULL, " ");
+	if (!token) {
+		dprintf(CRITICAL, "Test not provided, error\n");
+		return -1;
+	}
+	test = atoi(token);
+
+	token = strtok(NULL, " ");
+	if (token)
+		iterations = atoi(token);
+	else
+		dprintf(CRITICAL, "iterations not provided\n");
+
+	switch (test) {
+		case CLIENT_CMD0_GET_VERSION:
+		{
+			qsc_run_get_version(appname, iterations);
+			break;
+		}
+		case CLIENT_CMD1_BASIC_DATA:
+		{
+			qsc_run_start_stop_app_basic_test(appname, iterations);
+			break;
+		}
+
+		case CLIENT_APPSBL_QSEECOM_RUN_LISTENER_FRAMEWORK_TEST_1:
+		{
+			qsc_run_start_stop_app_listener_test(appname, iterations);
+			break;
+		}
+	}
+	dprintf(CRITICAL, "test:%u iterations:%u\n", test, iterations);
+	return 0;
+}
+
diff --git a/include/dev/gpio.h b/include/dev/gpio.h
index 6e1bce8..50386e9 100644
--- a/include/dev/gpio.h
+++ b/include/dev/gpio.h
@@ -2,6 +2,8 @@
  * Copyright (c) 2008, Google Inc.
  * All rights reserved.
  *
+ * Copyright (c) 2014 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:
@@ -26,6 +28,8 @@
  * SUCH DAMAGE.
  */
 
+#include <platform/gpio.h>
+
 #ifndef __DEV_GPIO_H
 #define __DEV_GPIO_H
 
diff --git a/include/km_main.h b/include/km_main.h
new file mode 100644
index 0000000..42920d1
--- /dev/null
+++ b/include/km_main.h
@@ -0,0 +1,166 @@
+/*
+ * Copyright (c) 2015, 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 KM_MAIN_H
+#define KM_MAIN_H
+
+#include <sys/types.h>
+/**
+ * Commands supported
+ */
+#define KEYMASTER_CMD_ID  0x100UL
+#define KEYMASTER_UTILS_CMD_ID  0x200UL
+
+#define UINT32_MAX  (0xffffffff)
+
+typedef enum {
+    /*
+     * List the commands supportedin by the hardware.
+     */
+    KEYMASTER_GET_SUPPORTED_ALGORITHMS		= (KEYMASTER_CMD_ID + 1UL),
+    KEYMASTER_GET_SUPPORTED_BLOCK_MODES		= (KEYMASTER_CMD_ID + 2UL),
+    KEYMASTER_GET_SUPPORTED_PADDING_MODES	= (KEYMASTER_CMD_ID + 3UL),
+    KEYMASTER_GET_SUPPORTED_DIGESTS			= (KEYMASTER_CMD_ID + 4UL),
+    KEYMASTER_GET_SUPPORTED_IMPORT_FORMATS	= (KEYMASTER_CMD_ID + 5UL),
+    KEYMASTER_GET_SUPPORTED_EXPORT_FORMATS	= (KEYMASTER_CMD_ID + 6UL),
+    KEYMASTER_ADD_RNG_ENTROPY				= (KEYMASTER_CMD_ID + 7UL),
+    KEYMASTER_GENERATE_KEY					= (KEYMASTER_CMD_ID + 8UL),
+    KEYMASTER_GET_KEY_CHARACTERISTICS		= (KEYMASTER_CMD_ID + 9UL),
+    KEYMASTER_RESCOPE						= (KEYMASTER_CMD_ID + 10UL),
+    KEYMASTER_IMPORT_KEY					= (KEYMASTER_CMD_ID + 11UL),
+    KEYMASTER_EXPORT_KEY					= (KEYMASTER_CMD_ID + 12UL),
+    KEYMASTER_DELETE_KEY					= (KEYMASTER_CMD_ID + 13UL),
+    KEYMASTER_DELETE_ALL_KEYS				= (KEYMASTER_CMD_ID + 14UL),
+    KEYMASTER_BEGIN							= (KEYMASTER_CMD_ID + 15UL),
+    KEYMASTER_GET_OUTPUT_SIZE				= (KEYMASTER_CMD_ID + 16UL),
+    KEYMASTER_UPDATE						= (KEYMASTER_CMD_ID + 17UL),
+    KEYMASTER_FINISH						= (KEYMASTER_CMD_ID + 18UL),
+    KEYMASTER_ABORT							= (KEYMASTER_CMD_ID + 19UL),
+
+    KEYMASTER_SET_ROT						= (KEYMASTER_UTILS_CMD_ID + 1UL),
+    KEYMASTER_READ_LK_DEVICE_STATE			= (KEYMASTER_UTILS_CMD_ID + 2UL),
+    KEYMASTER_WRITE_LK_DEVICE_STATE			= (KEYMASTER_UTILS_CMD_ID + 3UL),
+    KEYMASTER_MILESTONE_CALL				= (KEYMASTER_UTILS_CMD_ID + 4UL),
+
+    KEYMASTER_LAST_CMD_ENTRY				= (int)0xFFFFFFFFULL
+} keymaster_cmd_t;
+
+
+/*
+ * Utils Api struct
+ */
+/**
+  @brief
+    Data structure
+
+  @param[in]   cmd_id      Requested command
+  @param[in]   rot_ofset   Offset from the top of the struct.
+  @param[in]   rot_size    Size of the ROT
+*/
+typedef struct _km_set_rot_req_t {
+	uint32 cmd_id;
+	uint32 rot_ofset;
+	uint32 rot_size;
+}__attribute__ ((packed)) km_set_rot_req_t;
+
+/**
+  @brief
+    Data structure
+
+  @param[out]   status      Status of the request
+*/
+typedef struct _km_set_rot_rsp_t {
+	int status;
+}__attribute__ ((packed)) km_set_rot_rsp_t;
+
+/**
+  @brief
+    Data structure
+
+  @param[in]   cmd_id      Requested command
+  @param[in]   data        information (could be data or a pointer to the memory that holds the data
+  @param[in]   len         if data is ptr to some buffer, len indicates length of the buffer
+*/
+typedef struct send_cmd{
+	uint32 cmd_id;
+	uint32 data;
+	uint32 len;
+} __attribute__ ((packed)) send_cmd_t;
+
+/*
+typedef struct send_cmd_rsp{
+	uint32 cmd_id;
+	uint32 data;
+	int32 status;
+}  __attribute__ ((packed)) send_cmd_rsp_t; */
+
+/**
+  @brief
+    Data structure
+
+  @param[in]   cmd_id      Requested command
+*/
+typedef struct _km_set_milestone_req_t {
+	uint32 cmd_id;
+}__attribute__ ((packed)) km_set_milestone_req_t;
+
+/**
+  @brief
+    Data structure
+
+  @param[out]   status      Status of the request
+*/
+typedef struct _km_set_milestone_rsp_t {
+	int status;
+}__attribute__ ((packed)) km_set_milestone_rsp_t;
+
+/*
+ * Structures for delete_all cmd
+ */
+/*
+  @brief
+  Data structure
+
+  @param[in]  cmd_id              Requested command
+*/
+typedef struct _key_op_delete_all_req_t {
+	uint32 cmd_id;
+}__attribute__ ((packed)) key_op_delete_all_req_t;
+
+/*
+  @brief
+  Data structure
+
+  @param[out]   status             Status of the request
+*/
+typedef struct _key_op_delete_all_rsp_t {
+	int status;
+}__attribute__ ((packed)) key_op_delete_all_rsp_t;
+
+#endif /* KM_MAIN_H */
diff --git a/include/platform.h b/include/platform.h
index aa63431..58e0d32 100644
--- a/include/platform.h
+++ b/include/platform.h
@@ -1,6 +1,8 @@
 /*
  * Copyright (c) 2008 Travis Geiselbrecht
  *
+ * Copyright (c) 2014, The Linux Foundation. All rights reserved.
+ *
  * 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,
@@ -42,6 +44,7 @@
 void platform_init_mmu_mappings(void);
 addr_t platform_get_virt_to_phys_mapping(addr_t virt_addr);
 addr_t platform_get_phys_to_virt_mapping(addr_t phys_addr);
+addr_t get_bs_info_addr(void);
 
 void display_init(void);
 void display_shutdown(void);
@@ -53,5 +56,8 @@
 void platform_uninit_timer(void);
 void reboot_device(unsigned);
 int set_download_mode(enum dload_mode mode);
-
+uint32_t platform_get_sclk_count(void);
+void clock_config_cdc(uint32_t interface);
+int platform_is_msm8939();
+uint32_t platform_get_smem_base_addr();
 #endif
diff --git a/include/stdio.h b/include/stdio.h
index ebabfca..5052636 100644
--- a/include/stdio.h
+++ b/include/stdio.h
@@ -4,9 +4,21 @@
 #include <debug.h>
 #include <printf.h>
 
+typedef struct {
+	char *fpos; /* Current position of file pointer (absolute address) */
+	void *base; /* Pointer to the base of the file */
+	unsigned short handle; /* File handle */
+	short flags; /* Flags (see FileFlags) */
+	short unget; /* 1-byte buffer for ungetc (b15=1 if non-empty) */
+	unsigned long alloc; /* Number of currently allocated bytes for the file */
+	unsigned short buffincrement; /* Number of bytes allocated at once */
+} FILE;
+
 void putc(char c);
 int puts(const char *str);
 int getc(char *c); // XXX not really getc
+size_t fwrite(const void *buf, size_t size, size_t count, FILE *stream);
+int sscanf(const char *str, const char *format, ...);
 
 #endif
 
diff --git a/include/stdlib.h b/include/stdlib.h
index 5c5145a..4db77fa 100644
--- a/include/stdlib.h
+++ b/include/stdlib.h
@@ -1,7 +1,7 @@
 /*
  * Copyright (c) 2008 Travis Geiselbrecht
  *
- * Copyright (c) 2013, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013, 2014 The Linux Foundation. All rights reserved.
  *
  * Permission is hereby granted, free of charge, to any person obtaining
  * a copy of this software and associated documentation files
@@ -39,6 +39,9 @@
 long atol(const char *num);
 unsigned long atoul(const char *num);
 int itoa(int num, unsigned char* str, int len, int base);
+long int strtol(const char *nptr, char **endptr, int base);
+char *getenv(const char *atypeofinformation);
+void qsort(void *buf, size_t num, size_t size, int (*compare) (const void *, const void *));
 
 #define MIN(a, b) (((a) < (b)) ? (a) : (b))
 #define MAX(a, b) (((a) > (b)) ? (a) : (b))
diff --git a/include/target.h b/include/target.h
index dfd5521..7e06f28 100644
--- a/include/target.h
+++ b/include/target.h
@@ -25,6 +25,15 @@
 #ifndef __TARGET_H
 #define __TARGET_H
 
+/* Target helper functions exposed to USB driver */
+typedef struct {
+	void (*mux_config) ();
+	void (*phy_reset) ();
+	void (*phy_init) ();
+	void (*clock_init) ();
+	uint8_t vbus_override;
+} target_usb_iface_t;
+
 /* super early platform initialization, before almost everything */
 void target_early_init(void);
 
@@ -53,4 +62,16 @@
 bool target_display_panel_node(char *pbuf, uint16_t buf_size);
 void target_display_init(const char *panel_name);
 void target_display_shutdown(void);
+bool target_build_variant_user();
+uint32_t target_hw_interposer();
+uint32_t target_override_pll();
+uint32_t target_ddr_cfg_val();
+void target_usb_init(void);
+void target_usb_stop(void);
+uint32_t target_get_hlos_subtype(void);
+void shutdown_device();
+bool target_warm_boot(void);
+bool target_use_signed_kernel(void);
+int _emmc_recovery_init(void);
+void ulpi_write(unsigned val, unsigned reg);
 #endif
diff --git a/lib/debug/debug.c b/lib/debug/debug.c
index 84d0678..afb2443 100644
--- a/lib/debug/debug.c
+++ b/lib/debug/debug.c
@@ -35,11 +35,15 @@
 #include <kernel/thread.h>
 #include <kernel/timer.h>
 #include <rand.h>
+#if ARCH_ARM
+#include <arch/arm.h>
+#endif
 
 void __attribute__ ((noreturn))
 __stack_chk_fail (void)
 {
 	panic("stack smashing detected.");
+	for(;;);
 }
 
 void spin(uint32_t usecs)
@@ -83,7 +87,7 @@
 	char ts_buf[13];
 	int err;
 
-	snprintf(ts_buf, sizeof(ts_buf), "[%u] ", current_time());
+	snprintf(ts_buf, sizeof(ts_buf), "[%u] ",(unsigned int)current_time());
 	dputs(ALWAYS, ts_buf);
 
 	va_list ap;
diff --git a/lib/libc/string/memscpy.c b/lib/libc/string/memscpy.c
new file mode 100644
index 0000000..3dd4d6b
--- /dev/null
+++ b/lib/libc/string/memscpy.c
@@ -0,0 +1,37 @@
+/* Copyright (c) 2015, 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 Fundation, Inc. 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 <string.h>
+
+size_t memscpy(void *dest, size_t dst_size, const void *src, size_t src_size)
+{
+	size_t copy_size = dst_size < src_size ? dst_size : src_size;
+	memcpy(dest, src, copy_size);
+	return copy_size;
+}
diff --git a/lib/libc/string/rules.mk b/lib/libc/string/rules.mk
index fc1ceb2..97a5db8 100644
--- a/lib/libc/string/rules.mk
+++ b/lib/libc/string/rules.mk
@@ -8,6 +8,7 @@
 	memcpy \
 	memmove \
 	memset \
+	memscpy \
 	strcat \
 	strchr \
 	strcmp \
diff --git a/lib/libfdt/fdt.c b/lib/libfdt/fdt.c
index 3267a1c..c43b83e 100644
--- a/lib/libfdt/fdt.c
+++ b/lib/libfdt/fdt.c
@@ -91,7 +91,7 @@
 	const char *p;
 
 	if (fdt_version(fdt) >= 0x11)
-		if (((offset + len) < offset)
+		if (((int)(offset + len) < offset)
 		    || ((offset + len) > fdt_size_dt_struct(fdt)))
 			return NULL;
 
@@ -226,7 +226,7 @@
 {
 	FDT_CHECK_HEADER(fdt);
 
-	if (fdt_totalsize(fdt) > bufsize)
+	if (fdt_totalsize(fdt) > (uint32_t)bufsize)
 		return -FDT_ERR_NOSPACE;
 
 	memmove(buf, fdt, fdt_totalsize(fdt));
diff --git a/lib/libfdt/fdt_ro.c b/lib/libfdt/fdt_ro.c
index 02b6d68..1e6b2e7 100644
--- a/lib/libfdt/fdt_ro.c
+++ b/lib/libfdt/fdt_ro.c
@@ -85,7 +85,7 @@
 {
 	const char *p = fdt_string(fdt, stroffset);
 
-	return (strlen(p) == len) && (memcmp(p, s, len) == 0);
+	return (strlen(p) == (size_t)len) && (memcmp(p, s, len) == 0);
 }
 
 int fdt_get_mem_rsv(const void *fdt, int n, uint64_t *address, uint64_t *size)
@@ -494,7 +494,7 @@
 {
 	int offset;
 
-	if ((phandle == 0) || (phandle == -1))
+	if ((phandle == 0))
 		return -FDT_ERR_BADPHANDLE;
 
 	FDT_CHECK_HEADER(fdt);
diff --git a/lib/libfdt/fdt_strerror.c b/lib/libfdt/fdt_strerror.c
index e6c3cee..f1ce5ad 100644
--- a/lib/libfdt/fdt_strerror.c
+++ b/lib/libfdt/fdt_strerror.c
@@ -85,7 +85,7 @@
 		return "<valid offset/length>";
 	else if (errval == 0)
 		return "<no error>";
-	else if (errval > -FDT_ERRTABSIZE) {
+	else if (errval > (int) -FDT_ERRTABSIZE) {
 		const char *s = fdt_errtable[-errval].str;
 
 		if (s)
diff --git a/lib/libfdt/fdt_sw.c b/lib/libfdt/fdt_sw.c
index 55ebebf..c8d998c 100644
--- a/lib/libfdt/fdt_sw.c
+++ b/lib/libfdt/fdt_sw.c
@@ -78,7 +78,7 @@
 	spaceleft = fdt_totalsize(fdt) - fdt_off_dt_struct(fdt)
 		- fdt_size_dt_strings(fdt);
 
-	if ((offset + len < offset) || (offset + len > spaceleft))
+	if (((int)(offset + len) < offset) || ((int)(offset + len) > spaceleft))
 		return NULL;
 
 	fdt_set_size_dt_struct(fdt, offset + len);
@@ -89,7 +89,7 @@
 {
 	void *fdt = buf;
 
-	if (bufsize < sizeof(struct fdt_header))
+	if (bufsize < (int)sizeof(struct fdt_header))
 		return -FDT_ERR_NOSPACE;
 
 	memset(buf, 0, bufsize);
@@ -180,7 +180,7 @@
 	/* Add it */
 	offset = -strtabsize - len;
 	struct_top = fdt_off_dt_struct(fdt) + fdt_size_dt_struct(fdt);
-	if (fdt_totalsize(fdt) + offset < struct_top)
+	if ((int)(fdt_totalsize(fdt) + offset) < struct_top)
 		return 0; /* no more room :( */
 
 	memcpy(strtab + offset, s, len);
diff --git a/lib/openssl/crypto/asn1/a_int.c b/lib/openssl/crypto/asn1/a_int.c
index c6fd204..3348b87 100644
--- a/lib/openssl/crypto/asn1/a_int.c
+++ b/lib/openssl/crypto/asn1/a_int.c
@@ -273,7 +273,7 @@
 	{
 	ASN1_INTEGER *ret=NULL;
 	const unsigned char *p;
-	unsigned char *to,*s;
+	unsigned char *s;
 	long len;
 	int inf,tag,xclass;
 	int i;
@@ -308,7 +308,6 @@
 		i=ERR_R_MALLOC_FAILURE;
 		goto err;
 		}
-	to=s;
 	ret->type=V_ASN1_INTEGER;
 	if(len) {
 		if ((*p == 0) && (len != 1))
diff --git a/lib/openssl/crypto/asn1/a_strnid.c b/lib/openssl/crypto/asn1/a_strnid.c
index 753021a..f0af42f 100644
--- a/lib/openssl/crypto/asn1/a_strnid.c
+++ b/lib/openssl/crypto/asn1/a_strnid.c
@@ -57,10 +57,12 @@
  */
 
 #include <stdio.h>
+#include <stdlib.h>
 #include <ctype.h>
 #include "cryptlib.h"
 #include <openssl/asn1.h>
 #include <openssl/objects.h>
+#include "../../e_os.h"
 
 
 static STACK_OF(ASN1_STRING_TABLE) *stable = NULL;
diff --git a/lib/openssl/crypto/asn1/ameth_lib.c b/lib/openssl/crypto/asn1/ameth_lib.c
index c52f9c9..5565ba4 100644
--- a/lib/openssl/crypto/asn1/ameth_lib.c
+++ b/lib/openssl/crypto/asn1/ameth_lib.c
@@ -59,6 +59,7 @@
 #include "cryptlib.h"
 #include <openssl/asn1t.h>
 #include <openssl/x509.h>
+#include <string.h>
 #ifndef OPENSSL_NO_ENGINE
 #include <openssl/engine.h>
 #endif
diff --git a/lib/openssl/crypto/asn1/n_pkey.c b/lib/openssl/crypto/asn1/n_pkey.c
index 60bc437..e7d0439 100644
--- a/lib/openssl/crypto/asn1/n_pkey.c
+++ b/lib/openssl/crypto/asn1/n_pkey.c
@@ -242,7 +242,7 @@
 		 int sgckey)
 	{
 	RSA *ret=NULL;
-	const unsigned char *p, *kp;
+	const unsigned char *p;
 	NETSCAPE_ENCRYPTED_PKEY *enckey = NULL;
 
 	p = *pp;
@@ -265,7 +265,6 @@
 		ASN1err(ASN1_F_D2I_RSA_NET,ASN1_R_UNSUPPORTED_ENCRYPTION_ALGORITHM);
 		goto err;
 	}
-	kp = enckey->enckey->digest->data;
 	if (cb == NULL)
 		cb=EVP_read_pw_string;
 	if ((ret=d2i_RSA_NET_2(a, enckey->enckey->digest,cb, sgckey)) == NULL) goto err;
diff --git a/lib/openssl/crypto/asn1/t_crl.c b/lib/openssl/crypto/asn1/t_crl.c
index bdb244c..ee5a687 100644
--- a/lib/openssl/crypto/asn1/t_crl.c
+++ b/lib/openssl/crypto/asn1/t_crl.c
@@ -87,7 +87,7 @@
 	STACK_OF(X509_REVOKED) *rev;
 	X509_REVOKED *r;
 	long l;
-	int i, n;
+	int i;
 	char *p;
 
 	BIO_printf(out, "Certificate Revocation List (CRL):\n");
@@ -107,7 +107,6 @@
 	else BIO_printf(out,"NONE");
 	BIO_printf(out,"\n");
 
-	n=X509_CRL_get_ext_count(x);
 	X509V3_extensions_print(out, "CRL extensions",
 						x->crl->extensions, 0, 8);
 
diff --git a/lib/openssl/crypto/asn1/tasn_dec.c b/lib/openssl/crypto/asn1/tasn_dec.c
index 3bee439..87d7dfd 100644
--- a/lib/openssl/crypto/asn1/tasn_dec.c
+++ b/lib/openssl/crypto/asn1/tasn_dec.c
@@ -168,7 +168,7 @@
 	int i;
 	int otag;
 	int ret = 0;
-	ASN1_VALUE *pchval, **pchptr, *ptmpval;
+	ASN1_VALUE **pchptr, *ptmpval;
 	if (!pval)
 		return 0;
 	if (aux && aux->asn1_cb)
@@ -319,7 +319,6 @@
 			goto err;
 			}
 		/* CHOICE type, try each possibility in turn */
-		pchval = NULL;
 		p = *in;
 		for (i = 0, tt=it->templates; i < it->tcount; i++, tt++)
 			{
diff --git a/lib/openssl/crypto/asn1/x_bignum.c b/lib/openssl/crypto/asn1/x_bignum.c
index 9cf3204..827d7af 100644
--- a/lib/openssl/crypto/asn1/x_bignum.c
+++ b/lib/openssl/crypto/asn1/x_bignum.c
@@ -81,7 +81,8 @@
 	bn_free,
 	0,
 	bn_c2i,
-	bn_i2c
+	bn_i2c,
+	NULL
 };
 
 ASN1_ITEM_start(BIGNUM)
diff --git a/lib/openssl/crypto/bn/bn_mul.c b/lib/openssl/crypto/bn/bn_mul.c
index a0e9ec3..ce7ca1d 100644
--- a/lib/openssl/crypto/bn/bn_mul.c
+++ b/lib/openssl/crypto/bn/bn_mul.c
@@ -551,7 +551,7 @@
 	     int tna, int tnb, BN_ULONG *t)
 	{
 	int i,j,n2=n*2;
-	int c1,c2,neg,zero;
+	int c1,c2,neg;
 	BN_ULONG ln,lo,*p;
 
 # ifdef BN_COUNT
@@ -567,7 +567,7 @@
 	/* r=(a[0]-a[1])*(b[1]-b[0]) */
 	c1=bn_cmp_part_words(a,&(a[n]),tna,n-tna);
 	c2=bn_cmp_part_words(&(b[n]),b,tnb,tnb-n);
-	zero=neg=0;
+	neg=0;
 	switch (c1*3+c2)
 		{
 	case -4:
@@ -575,8 +575,6 @@
 		bn_sub_part_words(&(t[n]),b,      &(b[n]),tnb,n-tnb); /* - */
 		break;
 	case -3:
-		zero=1;
-		/* break; */
 	case -2:
 		bn_sub_part_words(t,      &(a[n]),a,      tna,tna-n); /* - */
 		bn_sub_part_words(&(t[n]),&(b[n]),b,      tnb,tnb-n); /* + */
@@ -585,16 +583,12 @@
 	case -1:
 	case 0:
 	case 1:
-		zero=1;
-		/* break; */
 	case 2:
 		bn_sub_part_words(t,      a,      &(a[n]),tna,n-tna); /* + */
 		bn_sub_part_words(&(t[n]),b,      &(b[n]),tnb,n-tnb); /* - */
 		neg=1;
 		break;
 	case 3:
-		zero=1;
-		/* break; */
 	case 4:
 		bn_sub_part_words(t,      a,      &(a[n]),tna,n-tna);
 		bn_sub_part_words(&(t[n]),&(b[n]),b,      tnb,tnb-n);
@@ -1012,7 +1006,6 @@
 		{
 		if (i >= -1 && i <= 1)
 			{
-			int sav_j =0;
 			/* Find out the power of two lower or equal
 			   to the longest of the two numbers */
 			if (i >= 0)
@@ -1023,7 +1016,6 @@
 				{
 				j = BN_num_bits_word((BN_ULONG)bl);
 				}
-			sav_j = j;
 			j = 1<<(j-1);
 			assert(j <= al || j <= bl);
 			k = j+j;
diff --git a/lib/openssl/crypto/conf/conf_api.c b/lib/openssl/crypto/conf/conf_api.c
index d39503c..586b03c 100644
--- a/lib/openssl/crypto/conf/conf_api.c
+++ b/lib/openssl/crypto/conf/conf_api.c
@@ -65,6 +65,7 @@
 
 #include <assert.h>
 #include <string.h>
+#include <stdlib.h>
 #include <openssl/conf.h>
 #include <openssl/conf_api.h>
 #include <openssl/e_os.h>
diff --git a/lib/openssl/crypto/conf/conf_def.c b/lib/openssl/crypto/conf/conf_def.c
index 0b571b0..5e8506c 100644
--- a/lib/openssl/crypto/conf/conf_def.c
+++ b/lib/openssl/crypto/conf/conf_def.c
@@ -68,6 +68,7 @@
 #include "conf_def.h"
 #include <openssl/buffer.h>
 #include <openssl/err.h>
+#include <bio.h>
 
 static char *eat_ws(CONF *conf, char *p);
 static char *eat_alpha_numeric(CONF *conf, char *p);
@@ -187,9 +188,9 @@
 	BIO *in=NULL;
 
 #ifdef OPENSSL_SYS_VMS
-	in=BIO_new_file(name, "r");
+	in= (BIO *)BIO_new_file(name, "r");
 #else
-	in=BIO_new_file(name, "rb");
+	in= (BIO *)BIO_new_file(name, "rb");
 #endif
 	if (in == NULL)
 		{
@@ -213,13 +214,12 @@
 	int bufnum=0,i,ii;
 	BUF_MEM *buff=NULL;
 	char *s,*p,*end;
-	int again,n;
+	int again;
 	long eline=0;
 	char btmp[DECIMAL_SIZE(eline)+1];
 	CONF_VALUE *v=NULL,*tv;
 	CONF_VALUE *sv=NULL;
 	char *section=NULL,*buf;
-	STACK_OF(CONF_VALUE) *section_sk=NULL,*ts;
 	char *start,*psection,*pname;
 	void *h = (void *)(conf->data);
 
@@ -250,8 +250,6 @@
 					CONF_R_UNABLE_TO_CREATE_NEW_SECTION);
 		goto err;
 		}
-	section_sk=(STACK_OF(CONF_VALUE) *)sv->value;
-
 	bufnum=0;
 	again=0;
 	for (;;)
@@ -309,7 +307,6 @@
 		buf=buff->data;
 
 		clear_comments(conf, buf);
-		n=strlen(buf);
 		s=eat_ws(conf, buf);
 		if (IS_EOF(conf,*s)) continue; /* blank line */
 		if (*s == '[')
@@ -343,7 +340,6 @@
 					CONF_R_UNABLE_TO_CREATE_NEW_SECTION);
 				goto err;
 				}
-			section_sk=(STACK_OF(CONF_VALUE) *)sv->value;
 			continue;
 			}
 		else
@@ -406,12 +402,10 @@
 					   CONF_R_UNABLE_TO_CREATE_NEW_SECTION);
 					goto err;
 					}
-				ts=(STACK_OF(CONF_VALUE) *)tv->value;
 				}
 			else
 				{
 				tv=sv;
-				ts=section_sk;
 				}
 #if 1
 			if (_CONF_add_string(conf, tv, v) == 0)
@@ -465,9 +459,6 @@
 
 static void clear_comments(CONF *conf, char *p)
 	{
-	char *to;
-
-	to=p;
 	for (;;)
 		{
 		if (IS_FCOMMENT(conf,*p))
diff --git a/lib/openssl/crypto/conf/conf_lib.c b/lib/openssl/crypto/conf/conf_lib.c
index 54046de..a82c838 100644
--- a/lib/openssl/crypto/conf/conf_lib.c
+++ b/lib/openssl/crypto/conf/conf_lib.c
@@ -62,6 +62,7 @@
 #include <openssl/conf.h>
 #include <openssl/conf_api.h>
 #include <openssl/lhash.h>
+#include <bio.h>
 
 const char CONF_version[]="CONF" OPENSSL_VERSION_PTEXT;
 
@@ -94,9 +95,9 @@
 	BIO *in=NULL;
 
 #ifdef OPENSSL_SYS_VMS
-	in=BIO_new_file(file, "r");
+	in= (BIO *)BIO_new_file(file, "r");
 #else
-	in=BIO_new_file(file, "rb");
+	in= (BIO *)BIO_new_file(file, "rb");
 #endif
 	if (in == NULL)
 		{
diff --git a/lib/openssl/crypto/err/err.c b/lib/openssl/crypto/err/err.c
index 6237c1b..bd0d402 100644
--- a/lib/openssl/crypto/err/err.c
+++ b/lib/openssl/crypto/err/err.c
@@ -713,7 +713,7 @@
 	 * anyways for now.
 	 */
 #ifdef LK_NO_ERR_STATE
-	return
+	return;
 #endif
 
 #ifdef _OSD_POSIX
diff --git a/lib/openssl/crypto/evp/encode.c b/lib/openssl/crypto/evp/encode.c
index b42c747..28546a8 100644
--- a/lib/openssl/crypto/evp/encode.c
+++ b/lib/openssl/crypto/evp/encode.c
@@ -235,7 +235,7 @@
 int EVP_DecodeUpdate(EVP_ENCODE_CTX *ctx, unsigned char *out, int *outl,
 	     const unsigned char *in, int inl)
 	{
-	int seof= -1,eof=0,rv= -1,ret=0,i,v,tmp,n,ln,tmp2,exp_nl;
+	int seof= -1,eof=0,rv= -1,ret=0,i,v,tmp,n,ln,exp_nl;
 	unsigned char *d;
 
 	n=ctx->num;
@@ -319,7 +319,6 @@
 			 * lines.  We process the line and then need to
 			 * accept the '\n' */
 			if ((v != B64_EOF) && (n >= 64)) exp_nl=1;
-			tmp2=v;
 			if (n > 0)
 				{
 				v=EVP_DecodeBlock(out,d,n);
diff --git a/lib/openssl/crypto/evp/m_dss.c b/lib/openssl/crypto/evp/m_dss.c
index 48c2689..7bcc274 100644
--- a/lib/openssl/crypto/evp/m_dss.c
+++ b/lib/openssl/crypto/evp/m_dss.c
@@ -90,6 +90,7 @@
 	EVP_PKEY_DSA_method,
 	SHA_CBLOCK,
 	sizeof(EVP_MD *)+sizeof(SHA_CTX),
+	NULL
 	};
 
 const EVP_MD *EVP_dss(void)
diff --git a/lib/openssl/crypto/evp/m_dss1.c b/lib/openssl/crypto/evp/m_dss1.c
index 4f03fb7..40460b7 100644
--- a/lib/openssl/crypto/evp/m_dss1.c
+++ b/lib/openssl/crypto/evp/m_dss1.c
@@ -91,6 +91,7 @@
 	EVP_PKEY_DSA_method,
 	SHA_CBLOCK,
 	sizeof(EVP_MD *)+sizeof(SHA_CTX),
+	NULL
 	};
 
 const EVP_MD *EVP_dss1(void)
diff --git a/lib/openssl/crypto/evp/m_null.c b/lib/openssl/crypto/evp/m_null.c
index cb07216..b6e6d76 100644
--- a/lib/openssl/crypto/evp/m_null.c
+++ b/lib/openssl/crypto/evp/m_null.c
@@ -85,6 +85,7 @@
 	EVP_PKEY_NULL_method,
 	0,
 	sizeof(EVP_MD *),
+	NULL
 	};
 
 const EVP_MD *EVP_md_null(void)
diff --git a/lib/openssl/crypto/evp/m_ripemd.c b/lib/openssl/crypto/evp/m_ripemd.c
index a1d60ee..fb639d1 100644
--- a/lib/openssl/crypto/evp/m_ripemd.c
+++ b/lib/openssl/crypto/evp/m_ripemd.c
@@ -92,6 +92,7 @@
 	EVP_PKEY_RSA_method,
 	RIPEMD160_CBLOCK,
 	sizeof(EVP_MD *)+sizeof(RIPEMD160_CTX),
+	NULL
 	};
 
 const EVP_MD *EVP_ripemd160(void)
diff --git a/lib/openssl/crypto/evp/m_sha1.c b/lib/openssl/crypto/evp/m_sha1.c
index 9a2790f..bd8c5e3 100644
--- a/lib/openssl/crypto/evp/m_sha1.c
+++ b/lib/openssl/crypto/evp/m_sha1.c
@@ -91,6 +91,7 @@
 	EVP_PKEY_RSA_method,
 	SHA_CBLOCK,
 	sizeof(EVP_MD *)+sizeof(SHA_CTX),
+	NULL
 	};
 
 const EVP_MD *EVP_sha1(void)
@@ -128,6 +129,7 @@
 	EVP_PKEY_RSA_method,
 	SHA256_CBLOCK,
 	sizeof(EVP_MD *)+sizeof(SHA256_CTX),
+	NULL
 	};
 
 const EVP_MD *EVP_sha224(void)
@@ -147,6 +149,7 @@
 	EVP_PKEY_RSA_method,
 	SHA256_CBLOCK,
 	sizeof(EVP_MD *)+sizeof(SHA256_CTX),
+	NULL
 	};
 
 const EVP_MD *EVP_sha256(void)
@@ -178,6 +181,7 @@
 	EVP_PKEY_RSA_method,
 	SHA512_CBLOCK,
 	sizeof(EVP_MD *)+sizeof(SHA512_CTX),
+	NULL
 	};
 
 const EVP_MD *EVP_sha384(void)
@@ -197,6 +201,7 @@
 	EVP_PKEY_RSA_method,
 	SHA512_CBLOCK,
 	sizeof(EVP_MD *)+sizeof(SHA512_CTX),
+	NULL
 	};
 
 const EVP_MD *EVP_sha512(void)
diff --git a/lib/openssl/crypto/md32_common.h b/lib/openssl/crypto/md32_common.h
index 1cb7839..40f5055 100644
--- a/lib/openssl/crypto/md32_common.h
+++ b/lib/openssl/crypto/md32_common.h
@@ -225,15 +225,13 @@
 #define HOST_c2l(c,l)	(l =(((unsigned long)(*((c)++)))<<24),		\
 			 l|=(((unsigned long)(*((c)++)))<<16),		\
 			 l|=(((unsigned long)(*((c)++)))<< 8),		\
-			 l|=(((unsigned long)(*((c)++)))    ),		\
-			 l)
+			 l|=(((unsigned long)(*((c)++)))    ))
 #endif
 #ifndef HOST_l2c
 #define HOST_l2c(l,c)	(*((c)++)=(unsigned char)(((l)>>24)&0xff),	\
 			 *((c)++)=(unsigned char)(((l)>>16)&0xff),	\
 			 *((c)++)=(unsigned char)(((l)>> 8)&0xff),	\
-			 *((c)++)=(unsigned char)(((l)    )&0xff),	\
-			 l)
+			 *((c)++)=(unsigned char)(((l)    )&0xff))
 #endif
 
 #elif defined(DATA_ORDER_IS_LITTLE_ENDIAN)
@@ -262,15 +260,13 @@
 #define HOST_c2l(c,l)	(l =(((unsigned long)(*((c)++)))    ),		\
 			 l|=(((unsigned long)(*((c)++)))<< 8),		\
 			 l|=(((unsigned long)(*((c)++)))<<16),		\
-			 l|=(((unsigned long)(*((c)++)))<<24),		\
-			 l)
+			 l|=(((unsigned long)(*((c)++)))<<24))
 #endif
 #ifndef HOST_l2c
 #define HOST_l2c(l,c)	(*((c)++)=(unsigned char)(((l)    )&0xff),	\
 			 *((c)++)=(unsigned char)(((l)>> 8)&0xff),	\
 			 *((c)++)=(unsigned char)(((l)>>16)&0xff),	\
-			 *((c)++)=(unsigned char)(((l)>>24)&0xff),	\
-			 l)
+			 *((c)++)=(unsigned char)(((l)>>24)&0xff))
 #endif
 
 #endif
diff --git a/lib/openssl/crypto/mem_dbg.c b/lib/openssl/crypto/mem_dbg.c
index 9a07537..236431e 100644
--- a/lib/openssl/crypto/mem_dbg.c
+++ b/lib/openssl/crypto/mem_dbg.c
@@ -537,7 +537,11 @@
 				m->addr, m->num);
 #endif
 			if (options & V_CRYPTO_MDEBUG_TIME)
+#ifndef LK_NO_TIME
 				m->time=time(NULL);
+#else
+				m->time=0;
+#endif
 			else
 				m->time=0;
 
@@ -753,6 +757,10 @@
 		}
 #endif
 	}
+#else
+static void print_leak_doall_arg(const MEM *m, MEM_LEAK *l)
+{
+}
 #endif
 
 static IMPLEMENT_LHASH_DOALL_ARG_FN(print_leak, const MEM, MEM_LEAK)
diff --git a/lib/openssl/crypto/modes/cbc128.c b/lib/openssl/crypto/modes/cbc128.c
index 8f8bd56..af2d93a 100644
--- a/lib/openssl/crypto/modes/cbc128.c
+++ b/lib/openssl/crypto/modes/cbc128.c
@@ -176,7 +176,7 @@
 				for(n=0; n<16; n+=sizeof(size_t)) {
 					c = *(size_t *)(in+n);
 					*(size_t *)(out+n) =
-					*(size_t *)(tmp.c+n) ^ *(size_t *)(ivec+n);
+					*(tmp.c+n) ^ *(size_t *)(ivec+n);
 					*(size_t *)(ivec+n) = c;
 				}
 				len -= 16;
diff --git a/lib/openssl/crypto/pkcs7/pk7_doit.c b/lib/openssl/crypto/pkcs7/pk7_doit.c
index 451de84..3bf1a36 100644
--- a/lib/openssl/crypto/pkcs7/pk7_doit.c
+++ b/lib/openssl/crypto/pkcs7/pk7_doit.c
@@ -422,7 +422,6 @@
 	X509_ALGOR *enc_alg=NULL;
 	STACK_OF(X509_ALGOR) *md_sk=NULL;
 	STACK_OF(PKCS7_RECIP_INFO) *rsk=NULL;
-	X509_ALGOR *xalg=NULL;
 	PKCS7_RECIP_INFO *ri=NULL;
 
 	i=OBJ_obj2nid(p7->type);
@@ -445,7 +444,6 @@
 			PKCS7err(PKCS7_F_PKCS7_DATADECODE,PKCS7_R_UNSUPPORTED_CIPHER_TYPE);
 			goto err;
 			}
-		xalg=p7->d.signed_and_enveloped->enc_data->algorithm;
 		break;
 	case NID_pkcs7_enveloped:
 		rsk=p7->d.enveloped->recipientinfo;
@@ -457,7 +455,6 @@
 			PKCS7err(PKCS7_F_PKCS7_DATADECODE,PKCS7_R_UNSUPPORTED_CIPHER_TYPE);
 			goto err;
 			}
-		xalg=p7->d.enveloped->enc_data->algorithm;
 		break;
 	default:
 		PKCS7err(PKCS7_F_PKCS7_DATADECODE,PKCS7_R_UNSUPPORTED_CONTENT_TYPE);
diff --git a/lib/openssl/crypto/pkcs7/pk7_lib.c b/lib/openssl/crypto/pkcs7/pk7_lib.c
index 3ca0952..d411269 100644
--- a/lib/openssl/crypto/pkcs7/pk7_lib.c
+++ b/lib/openssl/crypto/pkcs7/pk7_lib.c
@@ -591,7 +591,6 @@
 int PKCS7_set_cipher(PKCS7 *p7, const EVP_CIPHER *cipher)
 	{
 	int i;
-	ASN1_OBJECT *objtmp;
 	PKCS7_ENC_CONTENT *ec;
 
 	i=OBJ_obj2nid(p7->type);
@@ -614,7 +613,6 @@
 		PKCS7err(PKCS7_F_PKCS7_SET_CIPHER,PKCS7_R_CIPHER_HAS_NO_OBJECT_IDENTIFIER);
 		return(0);
 	}
-	objtmp = OBJ_nid2obj(i);
 
 	ec->cipher = cipher;
 	return 1;
diff --git a/lib/openssl/crypto/rsa/rsa_ameth.c b/lib/openssl/crypto/rsa/rsa_ameth.c
index 033e2b6..806c263 100644
--- a/lib/openssl/crypto/rsa/rsa_ameth.c
+++ b/lib/openssl/crypto/rsa/rsa_ameth.c
@@ -352,6 +352,27 @@
 		{
 		EVP_PKEY_RSA2,
 		EVP_PKEY_RSA,
-		ASN1_PKEY_ALIAS
+		ASN1_PKEY_ALIAS,
+		NULL,
+		NULL,
+		NULL,
+		NULL,
+		NULL,
+		NULL,
+		NULL,
+		NULL,
+		NULL,
+		NULL,
+		NULL,
+		NULL,
+		NULL,
+		NULL,
+		NULL,
+		NULL,
+		NULL,
+		NULL,
+		NULL,
+		NULL,
+		NULL
 		}
 	};
diff --git a/lib/openssl/crypto/rules.mk b/lib/openssl/crypto/rules.mk
index ff710c4..63c4d0f 100644
--- a/lib/openssl/crypto/rules.mk
+++ b/lib/openssl/crypto/rules.mk
@@ -13,7 +13,8 @@
 			-I$(LOCAL_DIR)/x509 \
 			-I$(LOCAL_DIR)/../.. \
 			-I$(LOCAL_DIR)/../include \
-			-I$(LOCAL_DIR)/../include/openssl
+			-I$(LOCAL_DIR)/../include/openssl \
+			-I$(LOCAL_DIR)/../../openssl
 
 OBJS +=  $(LOCAL_DIR)/bn/asm/armv4-mont.o
 
@@ -102,6 +103,7 @@
 	$(LOCAL_DIR)/asn1/x_pkey.o \
 	$(LOCAL_DIR)/asn1/x_pubkey.o \
 	$(LOCAL_DIR)/asn1/x_req.o \
+	$(LOCAL_DIR)/asn1/x_sig.o \
 	$(LOCAL_DIR)/asn1/x_spki.o \
 	$(LOCAL_DIR)/asn1/x_val.o \
 	$(LOCAL_DIR)/asn1/x_x509.o \
@@ -489,6 +491,5 @@
 Files_removed_error_during_link := \
 	$(LOCAL_DIR)/rsa/rsa_oaep.o \
 	$(LOCAL_DIR)/rsa/rsa_ssl.o \
-	$(LOCAL_DIR)/asn1/x_sig.o \
 	$(LOCAL_DIR)/bn/bn_rand.o \
 	$(LOCAL_DIR)/asn1/t_pkey.o
diff --git a/lib/openssl/crypto/x509/x509_vfy.c b/lib/openssl/crypto/x509/x509_vfy.c
index 16baf47..67a3051 100644
--- a/lib/openssl/crypto/x509/x509_vfy.c
+++ b/lib/openssl/crypto/x509/x509_vfy.c
@@ -155,7 +155,6 @@
 int X509_verify_cert(X509_STORE_CTX *ctx)
 	{
 	X509 *x,*xtmp,*chain_ss=NULL;
-	X509_NAME *xn;
 	int bad_chain = 0;
 	X509_VERIFY_PARAM *param = ctx->param;
 	int depth,i,ok=0;
@@ -207,7 +206,6 @@
 		                         */
 
 		/* If we are self signed, we break */
-		xn=X509_get_issuer_name(x);
 		if (ctx->check_issued(ctx, x,x)) break;
 
 		/* If we were passed a cert chain, use it first */
@@ -244,7 +242,6 @@
 
 	i=sk_X509_num(ctx->chain);
 	x=sk_X509_value(ctx->chain,i-1);
-	xn = X509_get_subject_name(x);
 	if (ctx->check_issued(ctx, x, x))
 		{
 		/* we have a self signed certificate */
@@ -293,7 +290,6 @@
 		if (depth < num) break;
 
 		/* If we are self signed, we break */
-		xn=X509_get_issuer_name(x);
 		if (ctx->check_issued(ctx,x,x)) break;
 
 		ok = ctx->get_issuer(&xtmp, ctx, x);
@@ -311,8 +307,6 @@
 		num++;
 		}
 
-	/* we now have our chain, lets check it... */
-	xn=X509_get_issuer_name(x);
 
 	/* Is last certificate looked up self signed? */
 	if (!ctx->check_issued(ctx,x,x))
diff --git a/lib/openssl/crypto/x509v3/pcy_tree.c b/lib/openssl/crypto/x509v3/pcy_tree.c
index 92f6b24..04e3d59 100644
--- a/lib/openssl/crypto/x509v3/pcy_tree.c
+++ b/lib/openssl/crypto/x509v3/pcy_tree.c
@@ -341,9 +341,7 @@
 				const X509_POLICY_CACHE *cache)
 	{
 	int i;
-	X509_POLICY_LEVEL *last;
 	X509_POLICY_DATA *data;
-	last = curr - 1;
 	for (i = 0; i < sk_X509_POLICY_DATA_num(cache->data); i++)
 		{
 		data = sk_X509_POLICY_DATA_value(cache->data, i);
diff --git a/lib/openssl/crypto/x509v3/v3_ncons.c b/lib/openssl/crypto/x509v3/v3_ncons.c
index ec200ba..d7e9c4c 100644
--- a/lib/openssl/crypto/x509v3/v3_ncons.c
+++ b/lib/openssl/crypto/x509v3/v3_ncons.c
@@ -62,6 +62,7 @@
 #include <openssl/asn1t.h>
 #include <openssl/conf.h>
 #include <openssl/x509v3.h>
+#include <e_os.h>
 
 static void *v2i_NAME_CONSTRAINTS(const X509V3_EXT_METHOD *method,
 				  X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval);
diff --git a/lib/openssl/crypto/x509v3/v3_utl.c b/lib/openssl/crypto/x509v3/v3_utl.c
index e030234..87cfceb 100644
--- a/lib/openssl/crypto/x509v3/v3_utl.c
+++ b/lib/openssl/crypto/x509v3/v3_utl.c
@@ -365,7 +365,7 @@
 	char *tmp, *q;
 	const unsigned char *p;
 	int i;
-	const static char hexdig[] = "0123456789ABCDEF";
+	static const char hexdig[] = "0123456789ABCDEF";
 	if(!buffer || !len) return NULL;
 	if(!(tmp = OPENSSL_malloc(len * 3 + 1))) {
 		X509V3err(X509V3_F_HEX_TO_STRING,ERR_R_MALLOC_FAILURE);
diff --git a/lib/openssl/e_os.h b/lib/openssl/e_os.h
index f527ae9..26f9bac 100644
--- a/lib/openssl/e_os.h
+++ b/lib/openssl/e_os.h
@@ -62,6 +62,7 @@
 #include <openssl/opensslconf.h>
 
 #include <openssl/e_os2.h>
+#include <stdlib.h>
 /* <openssl/e_os2.h> contains what we can justify to make visible
  * to the outside; this file e_os.h is not part of the exported
  * interface. */
@@ -645,7 +646,7 @@
 #  endif
 #endif
 
-#if defined(sun) && !defined(__svr4__) && !defined(__SVR4)
+#if defined(OPENSSL_LK) || defined(sun) && !defined(__svr4__) && !defined(__SVR4)
   /* include headers first, so our defines don't break it */
 #include <stdlib.h>
 #include <string.h>
@@ -679,9 +680,9 @@
 #define IRIX_CC_BUG	/* CDS++ up to V2.0Bsomething suffered from the same bug.*/
 #endif
 
-#if defined(OPENSSL_SYS_WINDOWS)
-#  define strcasecmp _stricmp
-#  define strncasecmp _strnicmp
+#if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_LK)
+#  define strcasecmp strcmp
+#  define strncasecmp strnicmp
 #elif defined(OPENSSL_SYS_VMS)
 /* VMS below version 7.0 doesn't have strcasecmp() */
 #  include "o_str.h"
diff --git a/lib/openssl/include/openssl/bio.h b/lib/openssl/include/openssl/bio.h
index 152802f..f7eac3e 100644
--- a/lib/openssl/include/openssl/bio.h
+++ b/lib/openssl/include/openssl/bio.h
@@ -61,7 +61,7 @@
 
 #include <openssl/e_os2.h>
 
-#ifndef OPENSSL_NO_FP_API
+#if !defined(OPENSSL_NO_FP_API)|| defined(OPENSSL_LK)
 # include <stdio.h>
 #endif
 #include <stdarg.h>
@@ -564,7 +564,7 @@
 int BIO_asn1_get_suffix(BIO *b, asn1_ps_func **psuffix,
 					asn1_ps_func **psuffix_free);
 
-# ifndef OPENSSL_NO_FP_API
+# if !(defined(OPENSSL_NO_FP_API)) || defined(OPENSSL_LK)
 BIO_METHOD *BIO_s_file(void );
 BIO *BIO_new_file(const char *filename, const char *mode);
 BIO *BIO_new_fp(FILE *stream, int close_flag);
diff --git a/makefile b/makefile
index 4f8f53e..6532fce 100644
--- a/makefile
+++ b/makefile
@@ -95,6 +95,14 @@
 # Useful for header files that may be included by one or more source files.
 SRCDEPS := $(CONFIGHEADER)
 
+ifeq ($(VERIFIED_BOOT),1)
+  DEFINES += VERIFIED_BOOT=1
+  DEFINES += _SIGNED_KERNEL=1
+  ifeq ($(DEFAULT_UNLOCK),true)
+    DEFINES += DEFAULT_UNLOCK=1
+  endif
+endif
+
 # these need to be filled out by the project/target/platform rules.mk files
 TARGET :=
 PLATFORM :=
diff --git a/platform/init.c b/platform/init.c
index 5001373..89381cf 100644
--- a/platform/init.c
+++ b/platform/init.c
@@ -1,6 +1,8 @@
 /*
  * Copyright (c) 2008 Travis Geiselbrecht
  *
+ * Copyright (c) 2014, The Linux Foundation. All rights reserved.
+ *
  * 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,
@@ -24,6 +26,7 @@
 #include <debug.h>
 #include <platform.h>
 #include <boot_stats.h>
+#include <platform/iomap.h>
 
 /*
  * default implementations of these routines, if the platform code
@@ -94,7 +97,7 @@
 
 __WEAK addr_t get_bs_info_addr()
 {
-	return NULL;
+	return 0;
 }
 
 __WEAK uint32_t platform_get_sclk_count(void)
@@ -102,6 +105,12 @@
 	return 0;
 }
 
-__WEAK void clock_config_cdc(uint8_t slot)
+__WEAK void clock_config_cdc(uint32_t slot)
 {
+
+}
+
+__WEAK uint32_t platform_get_smem_base_addr()
+{
+	return (uint32_t)MSM_SHARED_BASE;
 }
diff --git a/platform/msm8226/include/platform/iomap.h b/platform/msm8226/include/platform/iomap.h
index 5b537e8..96fd8f9 100644
--- a/platform/msm8226/include/platform/iomap.h
+++ b/platform/msm8226/include/platform/iomap.h
@@ -35,6 +35,7 @@
 #define SDRAM_START_ADDR            0x00000000
 
 #define MSM_SHARED_BASE             0x0FA00000
+#define MSM_DYNAMIC_SHARED_BASE     0xFE802FF8
 
 #define APPS_SS_BASE                0xF9000000
 
@@ -208,4 +209,15 @@
 #define VIDEO_MODE_CTRL             0x010
 #define HS_TIMER_CTRL               0x0BC
 
+/* RPMB send receive buffer needs to be mapped
+*  * as device memory, define the start address
+*  * and size in MB
+*/
+#define RPMB_SND_RCV_BUF            0x10100000
+#define RPMB_SND_RCV_BUF_SZ         0x1
+
+/* QSEECOM: Secure app region notification */
+#define APP_REGION_ADDR 0xd980000
+#define APP_REGION_SIZE 0x200000
+
 #endif
diff --git a/platform/msm8226/platform.c b/platform/msm8226/platform.c
index 3a25699..c316ab3 100644
--- a/platform/msm8226/platform.c
+++ b/platform/msm8226/platform.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2014, 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
@@ -54,6 +54,7 @@
 /*       Physical addr,    Virtual addr,    Size (in MB),    Flags */
 	{    MEMBASE,          MEMBASE,        (MEMSIZE / MB),   LK_MEMORY},
 	{    MSM_IOMAP_BASE,   MSM_IOMAP_BASE,  MSM_IOMAP_SIZE,  IOMAP_MEMORY},
+    {    RPMB_SND_RCV_BUF,  RPMB_SND_RCV_BUF, RPMB_SND_RCV_BUF_SZ, IOMAP_MEMORY},
 };
 
 static struct smem_ram_ptable ram_ptable;
@@ -141,3 +142,8 @@
 		}
 	}
 }
+
+uint32_t platform_get_smem_base_addr()
+{
+	return (uint32_t)(readl(MSM_DYNAMIC_SHARED_BASE));
+}
diff --git a/platform/msm_shared/boot_verifier.c b/platform/msm_shared/boot_verifier.c
new file mode 100644
index 0000000..43b12fa
--- /dev/null
+++ b/platform/msm_shared/boot_verifier.c
@@ -0,0 +1,623 @@
+/*
+ * Copyright (c) 2014-2015, 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 <stdlib.h>
+#include <stdint.h>
+#include <crypto_hash.h>
+#include <boot_verifier.h>
+#include <image_verify.h>
+#include <mmc.h>
+#include <oem_keystore.h>
+#include <openssl/asn1t.h>
+#include <openssl/x509.h>
+#include <partition_parser.h>
+#include <rsa.h>
+#include <string.h>
+#include <openssl/err.h>
+#include <qseecom_lk_api.h>
+#include <secapp_loader.h>
+#include <target.h>
+
+#define ASN1_ENCODED_SHA256_SIZE 0x33
+#define ASN1_ENCODED_SHA256_OFFSET 0x13
+
+static KEYSTORE *oem_keystore;
+static KEYSTORE *user_keystore;
+static uint32_t dev_boot_state = RED;
+char KEYSTORE_PTN_NAME[] = "keystore";
+RSA *rsa_from_cert = NULL;
+unsigned char fp[EVP_MAX_MD_SIZE];
+uint32_t fp_size;
+
+ASN1_SEQUENCE(AUTH_ATTR) ={
+	ASN1_SIMPLE(AUTH_ATTR, target, ASN1_PRINTABLESTRING),
+	ASN1_SIMPLE(AUTH_ATTR, len, ASN1_INTEGER)
+} ASN1_SEQUENCE_END(AUTH_ATTR)
+IMPLEMENT_ASN1_FUNCTIONS(AUTH_ATTR)
+
+	ASN1_SEQUENCE(VERIFIED_BOOT_SIG) = {
+		ASN1_SIMPLE(VERIFIED_BOOT_SIG, version, ASN1_INTEGER),
+		ASN1_SIMPLE(VERIFIED_BOOT_SIG, certificate, X509),
+		ASN1_SIMPLE(VERIFIED_BOOT_SIG, algor, X509_ALGOR),
+		ASN1_SIMPLE(VERIFIED_BOOT_SIG, auth_attr, AUTH_ATTR),
+		ASN1_SIMPLE(VERIFIED_BOOT_SIG, sig, ASN1_OCTET_STRING)
+	} ASN1_SEQUENCE_END(VERIFIED_BOOT_SIG)
+IMPLEMENT_ASN1_FUNCTIONS(VERIFIED_BOOT_SIG)
+
+	ASN1_SEQUENCE(KEY) = {
+		ASN1_SIMPLE(KEY, algorithm_id, X509_ALGOR),
+		ASN1_SIMPLE(KEY, key_material, RSAPublicKey)
+	}ASN1_SEQUENCE_END(KEY)
+IMPLEMENT_ASN1_FUNCTIONS(KEY);
+
+ASN1_SEQUENCE(KEYBAG) = {
+	ASN1_SIMPLE(KEYBAG, mykey, KEY)
+}ASN1_SEQUENCE_END(KEYBAG)
+IMPLEMENT_ASN1_FUNCTIONS(KEYBAG)
+
+	ASN1_SEQUENCE(KEYSTORE_INNER) = {
+		ASN1_SIMPLE(KEYSTORE_INNER, version, ASN1_INTEGER),
+		ASN1_SIMPLE(KEYSTORE_INNER, mykeybag, KEYBAG)
+	} ASN1_SEQUENCE_END(KEYSTORE_INNER)
+IMPLEMENT_ASN1_FUNCTIONS(KEYSTORE_INNER)
+
+	ASN1_SEQUENCE(KEYSTORE) = {
+		ASN1_SIMPLE(KEYSTORE, version, ASN1_INTEGER),
+		ASN1_SIMPLE(KEYSTORE, mykeybag, KEYBAG),
+		ASN1_SIMPLE(KEYSTORE, sig, VERIFIED_BOOT_SIG)
+	} ASN1_SEQUENCE_END(KEYSTORE)
+IMPLEMENT_ASN1_FUNCTIONS(KEYSTORE)
+
+static uint32_t read_der_message_length(unsigned char* input)
+{
+	uint32_t len = 0;
+	int pos = 0;
+	uint8_t len_bytes = 1;
+
+	/* Check if input starts with Sequence id (0X30) */
+	if(input[pos] != 0x30)
+		return len;
+	pos++;
+
+	/* A length of 0xAABBCCDD in DER encoded messages would be sequence of
+	   following octets 0xAA, 0xBB, 0XCC, 0XDD.
+
+	   To read length - read each octet and shift left by 1 octect before
+	   reading next octet.
+	*/
+	/* check if short or long length form */
+	if(input[pos] & 0x80)
+	{
+		len_bytes = (input[pos] & ~(0x80));
+		pos++;
+	}
+	while(len_bytes)
+	{
+		/* Shift len by 1 octet */
+		len = len << 8;
+
+		/* Read next octet */
+		len = len | input[pos];
+		pos++; len_bytes--;
+	}
+
+	/* Add number of octets representing sequence id and length  */
+	len += pos;
+
+	return len;
+}
+
+static int add_attribute_to_img(unsigned char *ptr, AUTH_ATTR *input)
+{
+	return i2d_AUTH_ATTR(input, &ptr);
+}
+
+bool boot_verify_compare_sha256(unsigned char *image_ptr,
+		unsigned int image_size, unsigned char *signature_ptr, RSA *rsa)
+{
+	int ret = -1;
+	bool auth = false;
+	unsigned char *plain_text = NULL;
+
+	/* The magic numbers here are drawn from the PKCS#1 standard and are the ASN.1
+	 *encoding of the SHA256 object identifier that is required for a PKCS#1
+	* signature.*/
+	uint8_t digest[ASN1_ENCODED_SHA256_SIZE] = {0x30, 0x31, 0x30, 0x0d, 0x06,
+												0x09, 0x60, 0x86, 0x48, 0x01,
+												0x65, 0x03, 0x04, 0x02, 0x01,
+												0x05, 0x00, 0x04, 0x20};
+
+	plain_text = (unsigned char *)calloc(sizeof(char), SIGNATURE_SIZE);
+	if (plain_text == NULL) {
+		dprintf(CRITICAL, "boot_verifier: Calloc failed during verification\n");
+		goto cleanup;
+	}
+
+	/* Calculate SHA256 of image and place it into the ASN.1 structure*/
+	image_find_digest(image_ptr, image_size, CRYPTO_AUTH_ALG_SHA256,
+			digest + ASN1_ENCODED_SHA256_OFFSET);
+
+	/* Find digest from the image. This performs the PKCS#1 padding checks up to
+	 * but not including the ASN.1 OID and hash function check. The return value
+	 * is not positive for a failure or the length of the part after the padding */
+	ret = image_decrypt_signature_rsa(signature_ptr, plain_text, rsa);
+
+	/* Make sure the length returned from rsa decrypt is same as x509 signature format
+	 * otherwise the signature is invalid and we fail
+	 */
+	if (ret != ASN1_ENCODED_SHA256_SIZE)
+	{
+		dprintf(CRITICAL, "boot_verifier: Signature decrypt failed! Signature invalid = %d\n",
+			ret);
+		goto cleanup;
+	}
+	/* So plain_text contains the ASN.1 encoded hash from the signature and
+	* digest contains the value that this should be for the image that we're
+	* verifying, so compare them.*/
+
+	ret = memcmp(plain_text, digest, ASN1_ENCODED_SHA256_SIZE);
+	if(ret == 0)
+	{
+		auth = true;
+#ifdef TZ_SAVE_KERNEL_HASH
+		save_kernel_hash((unsigned char *) digest + ASN1_ENCODED_SHA256_OFFSET, CRYPTO_AUTH_ALG_SHA256);
+#endif
+	}
+
+cleanup:
+	if (plain_text != NULL)
+		free(plain_text);
+	EVP_cleanup();
+	CRYPTO_cleanup_all_ex_data();
+	ERR_remove_thread_state(NULL);
+	return auth;
+
+}
+
+static bool verify_image_with_sig(unsigned char* img_addr, uint32_t img_size,
+		char *pname, VERIFIED_BOOT_SIG *sig, KEYSTORE *ks)
+{
+	bool ret = false;
+	uint32_t len;
+	int shift_bytes;
+	RSA *rsa = NULL;
+	bool keystore_verification = false;
+	EVP_PKEY* key = NULL;
+
+	if(!strcmp(pname, "keystore"))
+		keystore_verification = true;
+
+	/* Verify target name */
+	if(strncmp((char*)(sig->auth_attr->target->data), pname,
+				sig->auth_attr->target->length) ||
+				(strlen(pname) != (unsigned long) sig->auth_attr->target->length))
+	{
+		dprintf(CRITICAL,
+				"boot_verifier: verification failure due to target name mismatch\n");
+		goto verify_image_with_sig_error;
+	}
+	/* Read image size from signature */
+	/* A len = 0xAABBCC (represented by 3 octets) would be stored in
+	   len->data as 0X00CCBBAA and len->length as 3(octets).
+
+	   To read len we need to left shift data to number of missing octets and
+	   then change it to host long
+	 */
+	len = *((uint32_t*)sig->auth_attr->len->data);
+	shift_bytes = sizeof(uint32_t) - sig->auth_attr->len->length;
+	if(shift_bytes > 0) {
+		len = len << (shift_bytes*8);
+	}
+	len = ntohl(len);
+
+	/* Verify image size*/
+	if(len != img_size)
+	{
+		dprintf(CRITICAL,
+				"boot_verifier: image length is different. (%d vs %d)\n",
+				len, img_size);
+		goto verify_image_with_sig_error;
+	}
+
+	/* append attribute to image */
+	if(!keystore_verification)
+	{
+		// verifying a non keystore partition
+		img_size += add_attribute_to_img((unsigned char*)(img_addr + img_size),
+				sig->auth_attr);
+	}
+
+	/* compare SHA256SUM of image with value in signature */
+	if(ks != NULL)
+	{
+		// use rsa from keystore
+		rsa = ks->mykeybag->mykey->key_material;
+	}
+	else
+	{
+		dprintf(CRITICAL, "%s:%d: Keystore is null\n", __func__, __LINE__);
+		ASSERT(0);
+	}
+
+	// verify boot.img with rsa from oem keystore
+	if((ret = boot_verify_compare_sha256(img_addr, img_size,
+			(unsigned char*)sig->sig->data, rsa)))
+
+	{
+		dprintf(SPEW, "Verified boot.img with oem keystore\n");
+		boot_verify_send_event(BOOTIMG_KEYSTORE_VERIFICATION_PASS);
+		goto verify_image_with_sig_done;
+	}
+	else
+	{
+		dprintf(INFO, "Verification with oem keystore failed. Use embedded certificate for verification\n");
+		// get the public key from certificate in boot.img
+		if ((key = X509_get_pubkey(sig->certificate)))
+		{
+			// convert to rsa key format
+			dprintf(INFO, "RSA KEY found from the embedded certificate\n");
+			rsa = EVP_PKEY_get1_RSA(key);
+			rsa_from_cert = rsa;
+		}
+		else
+		{
+			dprintf(CRITICAL, "Unable to extract public key from certificate\n");
+			ASSERT(0);
+		}
+	}
+
+	// verify boot.img with rsa from embedded certificate
+	if ((ret = boot_verify_compare_sha256(img_addr, img_size,
+			(unsigned char*)sig->sig->data, rsa)))
+	{
+		dprintf(SPEW, "Verified boot.img with embedded certificate in boot image\n");
+		boot_verify_send_event(BOOTIMG_EMBEDDED_CERT_VERIFICATION_PASS);
+		goto verify_image_with_sig_done;
+	}
+	else
+	{
+		dprintf(INFO, "verified for red state\n");
+		boot_verify_send_event(BOOTIMG_VERIFICATION_FAIL);
+		goto verify_image_with_sig_done;
+	}
+
+verify_image_with_sig_error:
+verify_image_with_sig_done:
+	return ret;
+}
+
+static int encode_inner_keystore(unsigned char *ptr, KEYSTORE *ks)
+{
+	int ret = 0;
+	KEYSTORE_INNER  *ks_inner = KEYSTORE_INNER_new();
+	if (ks_inner == NULL)
+		return ret;
+	ASN1_INTEGER *tmp_version = ks_inner->version;
+	KEYBAG *tmp_mykeybag = ks_inner->mykeybag;
+
+	ks_inner->version = ks->version;
+	ks_inner->mykeybag = ks->mykeybag;
+	ret = i2d_KEYSTORE_INNER(ks_inner, &ptr);
+
+	ks_inner->version = tmp_version;
+	ks_inner->mykeybag = tmp_mykeybag;
+
+	if(ks_inner != NULL)
+		KEYSTORE_INNER_free(ks_inner);
+	return ret;
+}
+
+static bool verify_keystore(unsigned char * ks_addr, KEYSTORE *ks)
+{
+	bool ret = false;
+	unsigned char * ptr = ks_addr;
+	uint32_t inner_len = encode_inner_keystore(ptr, ks);
+	ret = verify_image_with_sig(ks_addr, inner_len, "keystore", ks->sig,
+			oem_keystore);
+	return ret;
+}
+
+static void read_oem_keystore()
+{
+	KEYSTORE *ks = NULL;
+	uint32_t len = 0;
+	const unsigned char *input = OEM_KEYSTORE;
+
+	if(oem_keystore != NULL)
+		return;
+
+	len = read_der_message_length((unsigned char *)input);
+	if(!len)
+	{
+		dprintf(CRITICAL, "boot_verifier: oem keystore length is invalid.\n");
+		return;
+	}
+
+	ks = d2i_KEYSTORE(NULL, (const unsigned char **) &input, len);
+	if(ks != NULL)
+	{
+		oem_keystore = ks;
+		user_keystore = ks;
+	}
+}
+
+uint32_t boot_verify_keystore_init()
+{
+	/* Read OEM Keystore */
+	read_oem_keystore();
+
+	return dev_boot_state;
+}
+
+bool send_rot_command(uint32_t is_unlocked)
+{
+	int ret = 0;
+	unsigned char *input = NULL;
+	char *rot_input = NULL;
+	unsigned int digest[9] = {0}, final_digest[8] = {0};
+	uint32_t auth_algo = CRYPTO_AUTH_ALG_SHA256;
+	uint32_t boot_device_state = boot_verify_get_state();
+	int app_handle = 0;
+	uint32_t len_oem_rsa = 0, len_from_cert = 0;
+	km_set_rot_req_t *read_req;
+	km_set_rot_rsp_t read_rsp;
+	app_handle = get_secapp_handle();
+	int n = 0, e = 0;
+	switch (boot_device_state)
+	{
+		case GREEN:
+			// Locked device and boot.img verified against OEM keystore.
+			// n is length of modulus and e is length exponent
+			n = BN_num_bytes(oem_keystore->mykeybag->mykey->key_material->n);
+			e = BN_num_bytes(oem_keystore->mykeybag->mykey->key_material->e);
+			len_oem_rsa = n + e;
+			if(!(input = malloc(len_oem_rsa)))
+			{
+				dprintf(CRITICAL, "Failed to allocate memory for ROT structure\n");
+				ASSERT(0);
+			}
+			// convert the absolute value on n, e to big endian form
+			BN_bn2bin(oem_keystore->mykeybag->mykey->key_material->n, input);
+			BN_bn2bin(oem_keystore->mykeybag->mykey->key_material->e, input+n);
+			// Hash of key from OEM KEYSTORE
+			hash_find((unsigned char *)input, len_oem_rsa, (unsigned char *) &digest, auth_algo);
+			digest[8] = is_unlocked;
+			break;
+		case YELLOW:
+		case RED:
+			// Locked device and boot.img passed (yellow) or failed (red) verification with the certificate embedded to the boot.img.
+			if (!rsa_from_cert)
+			{
+				dprintf(CRITICAL, "RSA is null from the embedded certificate\n");
+				ASSERT(0);
+			}
+			// n is length of modulus and e is length exponent
+			n = BN_num_bytes(rsa_from_cert->n);
+			e = BN_num_bytes(rsa_from_cert->e);
+			len_from_cert = n + e;
+			if(!(input = malloc(len_from_cert)))
+			{
+				dprintf(CRITICAL, "Failed to allocate memory for ROT structure\n");
+				ASSERT(0);
+			}
+			// convert the absolute value on n, e to big endian form
+			BN_bn2bin(rsa_from_cert->n, input);
+			BN_bn2bin(rsa_from_cert->e, input+n);
+			// Hash of key from certificate in boot image
+			hash_find((unsigned char *)input, len_from_cert, (unsigned char *) &digest, auth_algo);
+			digest[8] = is_unlocked;
+			break;
+		case ORANGE:
+			// Unlocked device and no verification done.
+			// Send the hash of boot device state
+			input = NULL;
+			digest[0] = is_unlocked;
+			break;
+	}
+	// Hash of hash(key) + device state (locked/unlocked)
+	hash_find((unsigned char *) digest, sizeof(digest), (unsigned char *)&final_digest, auth_algo);
+	dprintf(SPEW, "Digest: ");
+	for(uint8_t i = 0; i < 8; i++)
+		dprintf(SPEW, "0x%x ", final_digest[i]);
+	dprintf(SPEW, "\n");
+	if(!(read_req = malloc(sizeof(km_set_rot_req_t) + sizeof(final_digest))))
+	{
+		dprintf(CRITICAL, "Failed to allocate memory for ROT structure\n");
+		ASSERT(0);
+	}
+
+	void *cpy_ptr = (uint8_t *) read_req + sizeof(km_set_rot_req_t);
+	// set ROT stucture
+	read_req->cmd_id = KEYMASTER_SET_ROT;
+	read_req->rot_ofset = (uint32_t) sizeof(km_set_rot_req_t);
+	read_req->rot_size  = sizeof(final_digest);
+	// copy the digest
+	memcpy(cpy_ptr, (void *) &final_digest, sizeof(final_digest));
+	dprintf(SPEW, "Sending Root of Trust to trustzone: start\n");
+
+	ret = qseecom_send_command(app_handle, (void*) read_req, sizeof(km_set_rot_req_t) + sizeof(final_digest), (void*) &read_rsp, sizeof(read_rsp));
+	if (ret < 0 || read_rsp.status < 0)
+	{
+		dprintf(CRITICAL, "QSEEcom command for Sending Root of Trust returned error: %d\n", read_rsp.status);
+		if(input)
+			free(input);
+		free(read_req);
+		free(rot_input);
+		return false;
+	}
+	dprintf(SPEW, "Sending Root of Trust to trustzone: end\n");
+	if(input)
+		free(input);
+	free(read_req);
+	free(rot_input);
+	return true;
+}
+
+unsigned char* get_boot_fingerprint(unsigned int* buf_size)
+{
+	*buf_size = fp_size;
+
+	return fp;
+}
+
+bool boot_verify_image(unsigned char* img_addr, uint32_t img_size, char *pname)
+{
+	bool ret = false;
+	X509 *cert = NULL;
+	const EVP_MD *fp_type = NULL;
+	VERIFIED_BOOT_SIG *sig = NULL;
+	unsigned char* sig_addr = (unsigned char*)(img_addr + img_size);
+	uint32_t sig_len = read_der_message_length(sig_addr);
+
+	if(dev_boot_state == ORANGE)
+	{
+		dprintf(INFO, "boot_verifier: Device is in ORANGE boot state.\n");
+		dprintf(INFO, "boot_verifier: Skipping boot verification.\n");
+		return false;
+	}
+
+	if(!sig_len)
+	{
+		dprintf(CRITICAL, "boot_verifier: Error while reading signature length.\n");
+		ASSERT(0);
+	}
+
+	if((sig = d2i_VERIFIED_BOOT_SIG(NULL, (const unsigned char **) &sig_addr, sig_len)) == NULL)
+	{
+		dprintf(CRITICAL,
+				"boot_verifier: verification failure due to target name mismatch\n");
+		ASSERT(0);
+	}
+
+	cert = sig->certificate;
+	fp_type = EVP_sha1();
+	if(!X509_digest(cert, fp_type, (unsigned char *)fp, &fp_size)) {
+		dprintf(INFO,"Fail to create certificate fingerprint.\n");
+	}
+
+	ret = verify_image_with_sig(img_addr, img_size, pname, sig, user_keystore);
+
+	if(sig != NULL)
+		VERIFIED_BOOT_SIG_free(sig);
+	return ret;
+}
+
+void boot_verify_send_event(uint32_t event)
+{
+	switch(event)
+	{
+		case BOOT_INIT:
+			dev_boot_state = GREEN;
+			break;
+		case BOOTIMG_KEYSTORE_VERIFICATION_PASS:
+			dev_boot_state = GREEN;
+			break;
+		case BOOTIMG_EMBEDDED_CERT_VERIFICATION_PASS:
+			if(dev_boot_state == GREEN)
+				dev_boot_state = YELLOW;
+			break;
+		case BOOTIMG_VERIFICATION_FAIL:
+			if(dev_boot_state == GREEN || dev_boot_state == YELLOW)
+				dev_boot_state = RED;
+			break;
+		case DEV_UNLOCK:
+			dev_boot_state = ORANGE;
+			break;
+		case USER_DENIES:
+			if(dev_boot_state == YELLOW || dev_boot_state == ORANGE)
+				dev_boot_state = RED;
+			break;
+	}
+}
+
+uint32_t boot_verify_get_state()
+{
+	return dev_boot_state;
+}
+
+void boot_verify_print_state()
+{
+	switch(dev_boot_state)
+	{
+		case GREEN:
+			dprintf(INFO, "boot_verifier: Device is in GREEN boot state.\n");
+			break;
+		case ORANGE:
+			dprintf(INFO, "boot_verifier: Device is in ORANGE boot state.\n");
+			break;
+		case YELLOW:
+			dprintf(INFO, "boot_verifier: Device is in YELLOW boot state.\n");
+			break;
+		case RED:
+			dprintf(INFO, "boot_verifier: Device is in RED boot state.\n");
+			break;
+	}
+}
+
+bool boot_verify_validate_keystore(unsigned char * user_addr)
+{
+	bool ret = false;
+	unsigned char *input = user_addr;
+	KEYSTORE *ks = NULL;
+	uint32_t len = read_der_message_length(input);
+	if(!len)
+	{
+		dprintf(CRITICAL, "boot_verifier: keystore length is invalid.\n");
+		return ret;
+	}
+
+	ks = d2i_KEYSTORE(NULL, (const unsigned char **)&input, len);
+	if(ks != NULL)
+	{
+		ret = true;
+	}
+	return ret;
+}
+
+static bool check_list(const char **list, const char* entry)
+{
+	if(list == NULL || entry == NULL)
+		return false;
+
+	while(*list != NULL)
+	{
+		if(!strcmp(entry, *list))
+			return true;
+
+		list++;
+	}
+
+	return false;
+}
+
+KEYSTORE *boot_gerity_get_oem_keystore()
+{
+	read_oem_keystore();
+	return oem_keystore;
+}
diff --git a/platform/msm_shared/crypto5_eng.c b/platform/msm_shared/crypto5_eng.c
index 17fbf88..83381a8 100644
--- a/platform/msm_shared/crypto5_eng.c
+++ b/platform/msm_shared/crypto5_eng.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2014, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2015, 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
@@ -139,6 +139,8 @@
 #else
 	ret = (uint32_t)bam_add_cmd_element(&cmd_list_ptr, reg_addr, val, CE_WRITE_TYPE);
 
+	arch_clean_invalidate_cache_range((addr_t)&cmd_list_ptr, sizeof(struct cmd_element));
+
 	/* Enqueue the desc for the above command */
 	ret = bam_add_one_desc(bam_core,
 						   CRYPTO_WRITE_PIPE_INDEX,
@@ -321,12 +323,22 @@
 
 static uint32_t crypto5_get_sha_cfg(void *ctx_ptr, crypto_auth_alg_type auth_alg)
 {
-   crypto_SHA256_ctx *sha256_ctx = (crypto_SHA256_ctx *) ctx_ptr;
-   uint32_t seg_cfg_val;
+	crypto_SHA256_ctx *sha256_ctx = (crypto_SHA256_ctx *) ctx_ptr;
+	crypto_SHA1_ctx *sha1_ctx = (crypto_SHA1_ctx *) ctx_ptr;
+	uint32_t seg_cfg_val;
 
-   seg_cfg_val = SEG_CFG_AUTH_ALG_SHA;
+	seg_cfg_val = SEG_CFG_AUTH_ALG_SHA;
 
-	if (auth_alg == CRYPTO_AUTH_ALG_SHA256)
+	if (auth_alg == CRYPTO_AUTH_ALG_SHA1)
+	{
+		seg_cfg_val |= SEG_CFG_AUTH_SIZE_SHA1;
+
+		if (sha1_ctx->flags & CRYPTO_LAST_CHUNK)
+		{
+			seg_cfg_val |= SEG_CFG_LAST;
+		}
+	}
+	else if (auth_alg == CRYPTO_AUTH_ALG_SHA256)
 	{
 		seg_cfg_val |= SEG_CFG_AUTH_SIZE_SHA256;
 
@@ -364,13 +376,13 @@
 		iv_len = SHA256_INIT_VECTOR_SIZE;
 	}
 
-    seg_cfg_val = crypto5_get_sha_cfg(ctx_ptr, auth_alg);
+	seg_cfg_val = crypto5_get_sha_cfg(ctx_ptr, auth_alg);
 
-    if (!seg_cfg_val)
-    {
+	if (!seg_cfg_val)
+	{
 		dprintf(CRITICAL, "Authentication alg config failed.\n");
 		return;
-    }
+	}
 
 	/* Initialize CE pointers. */
 	REG_WRITE_QUEUE_INIT(dev);
@@ -379,13 +391,13 @@
 	REG_WRITE_QUEUE(dev, CRYPTO_ENCR_SEG_CFG(dev->base), 0);
 	REG_WRITE_QUEUE(dev, CRYPTO_AUTH_SEG_CFG(dev->base), seg_cfg_val);
 
-    for (i = 0; i < iv_len; i++)
-    {
+	for (i = 0; i < iv_len; i++)
+	{
 		if (sha256_ctx->flags & CRYPTO_FIRST_CHUNK)
 			REG_WRITE_QUEUE(dev, CRYPTO_AUTH_IVn(dev->base, i), BE32(*(auth_iv + i)));
 		else
 			REG_WRITE_QUEUE(dev, CRYPTO_AUTH_IVn(dev->base, i), (*(auth_iv + i)));
-    }
+	}
 
 	/* Typecast with crypto_SHA1_ctx because offset of auth_bytecnt
 	 * in both crypto_SHA1_ctx and crypto_SHA256_ctx are same.
@@ -393,7 +405,6 @@
 	REG_WRITE_QUEUE(dev, CRYPTO_AUTH_BYTECNTn(dev->base, 0), ((crypto_SHA1_ctx *) ctx_ptr)->auth_bytecnt[0]);
 	REG_WRITE_QUEUE(dev, CRYPTO_AUTH_BYTECNTn(dev->base, 1), ((crypto_SHA1_ctx *) ctx_ptr)->auth_bytecnt[1]);
 }
-
 /* Function: crypto5_set_auth_cfg
  * Arg     : dev, ptr to data buffer, buffer_size, burst_mask for alignment
  * Return  : aligned buffer incase of unaligned data_ptr and total no. of bytes
@@ -518,9 +529,16 @@
 
 CRYPTO_SEND_DATA_ERR:
 
+	crypto5_unlock_pipes(dev);
+
 	return ret_status;
 }
 
+void crypto5_unlock_pipes(struct crypto_dev *dev)
+{
+	CLEAR_STATUS(dev);
+}
+
 void crypto5_cleanup(struct crypto_dev *dev)
 {
 	CLEAR_STATUS(dev);
diff --git a/platform/msm_shared/crypto5_wrapper.c b/platform/msm_shared/crypto5_wrapper.c
index db12320..0be227a 100644
--- a/platform/msm_shared/crypto5_wrapper.c
+++ b/platform/msm_shared/crypto5_wrapper.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012,2015, 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
@@ -45,6 +45,11 @@
 	crypto5_cleanup(&dev);
 }
 
+void crypto_unlock(void)
+{
+	crypto5_unlock_pipes(&dev);
+}
+
 void ce_clock_init(void)
 {
 	/* Clock init is done during crypto_init. */
@@ -109,4 +114,4 @@
 uint32_t crypto_get_max_auth_blk_size()
 {
 	return crypto5_get_max_auth_blk_size(&dev);
-}
\ No newline at end of file
+}
diff --git a/platform/msm_shared/crypto_hash.c b/platform/msm_shared/crypto_hash.c
index 50d4a17..0d3cce8 100644
--- a/platform/msm_shared/crypto_hash.c
+++ b/platform/msm_shared/crypto_hash.c
@@ -50,7 +50,7 @@
 	crypto_result_type ret_val = CRYPTO_SHA_ERR_NONE;
 	crypto_engine_type platform_ce_type = board_ce_type();
 
-	if (auth_alg == 1) {
+	if (auth_alg == CRYPTO_AUTH_ALG_SHA1) {
 		if(platform_ce_type == CRYPTO_ENGINE_TYPE_SW)
 			/* Hardware CE is not present , use software hashing */
 			digest = SHA1(addr, size, digest);
@@ -58,7 +58,7 @@
 			ret_val = crypto_sha1(addr, size, digest);
 		else
 			ret_val = CRYPTO_SHA_ERR_FAIL;
-	} else if (auth_alg == 2) {
+	} else if (auth_alg == CRYPTO_AUTH_ALG_SHA256) {
 		if(platform_ce_type == CRYPTO_ENGINE_TYPE_SW)
 			/* Hardware CE is not present , use software hashing */
 			digest = SHA256(addr, size, digest);
@@ -67,6 +67,8 @@
 		else
 		ret_val = CRYPTO_SHA_ERR_FAIL;
 	}
+	else
+		ret_val = CRYPTO_SHA_ERR_FAIL;
 
 	if (ret_val != CRYPTO_SHA_ERR_NONE) {
 		dprintf(CRITICAL, "crypto_sha256 returns error %d\n", ret_val);
diff --git a/platform/msm_shared/image_verify.c b/platform/msm_shared/image_verify.c
index 0d280f2..2e7366e 100644
--- a/platform/msm_shared/image_verify.c
+++ b/platform/msm_shared/image_verify.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011,2013-2014 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2011,2013-2015 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
@@ -25,11 +25,36 @@
  * SUCH DAMAGE.
  */
 #include <x509.h>
+#include <err.h>
 #include <certificate.h>
 #include <crypto_hash.h>
+#include <string.h>
+#include <openssl/err.h>
 #include "image_verify.h"
 #include "scm.h"
 
+
+/*
+ * Returns -1 if decryption failed otherwise size of plain_text in bytes
+ */
+int image_decrypt_signature_rsa(unsigned char *signature_ptr,
+		unsigned char *plain_text, RSA *rsa_key)
+{
+	int ret = -1;
+
+	if (rsa_key == NULL) {
+		dprintf(CRITICAL, "ERROR: Boot Invalid, RSA_KEY is NULL!\n");
+		return ret;
+	}
+
+	ret = RSA_public_decrypt(SIGNATURE_SIZE, signature_ptr, plain_text,
+				 rsa_key, RSA_PKCS1_PADDING);
+	dprintf(SPEW, "DEBUG openssl: Return of RSA_public_decrypt = %d\n",
+		ret);
+
+	return ret;
+}
+
 /*
  * Returns -1 if decryption failed otherwise size of plain_text in bytes
  */
@@ -41,7 +66,7 @@
 	 */
 	int ret = -1;
 	X509 *x509_certificate = NULL;
-	unsigned char *cert_ptr = certBuffer;
+	const unsigned char *cert_ptr = (const unsigned char *)certBuffer;
 	unsigned int cert_size = sizeof(certBuffer);
 	EVP_PKEY *pub_key = NULL;
 	RSA *rsa_key = NULL;
@@ -61,8 +86,7 @@
 		goto cleanup;
 	}
 
-	ret = RSA_public_decrypt(SIGNATURE_SIZE, signature_ptr, plain_text,
-				 rsa_key, RSA_PKCS1_PADDING);
+	ret = image_decrypt_signature_rsa(signature_ptr, plain_text, rsa_key);
 	dprintf(SPEW, "DEBUG openssl: Return of RSA_public_decrypt = %d\n",
 		ret);
 
@@ -76,6 +100,27 @@
 	return ret;
 }
 
+/* Calculates digest of an image and save it in digest buffer */
+void image_find_digest(unsigned char *image_ptr, unsigned int image_size,
+		unsigned hash_type, unsigned char *digest)
+{
+	/*
+	 * Calculate hash of image and save calculated hash on TZ.
+	 */
+	hash_find(image_ptr, image_size, (unsigned char *)digest, hash_type);
+}
+
+#ifdef TZ_SAVE_KERNEL_HASH
+void save_kernel_hash(unsigned char *digest, unsigned hash_type)
+{
+	if (hash_type == CRYPTO_AUTH_ALG_SHA256) {
+		save_kernel_hash_cmd(digest);
+		dprintf(INFO, "Image hash saved.\n");
+	} else
+		dprintf(INFO, "image_verify: hash is not SHA-256.\n");
+}
+#endif
+
 /*
  * Returns 1 when image is signed and authorized.
  * Returns 0 when image is unauthorized.
@@ -91,7 +136,7 @@
 	int auth = 0;
 	unsigned char *plain_text = NULL;
 	unsigned int digest[8];
-	unsigned int hash_size;
+	int hash_size;
 
 	plain_text = (unsigned char *)calloc(sizeof(char), SIGNATURE_SIZE);
 	if (plain_text == NULL) {
@@ -104,13 +149,10 @@
 	 */
 	hash_size =
 	    (hash_type == CRYPTO_AUTH_ALG_SHA256) ? SHA256_SIZE : SHA1_SIZE;
-	hash_find(image_ptr, image_size, (unsigned char *)&digest, hash_type);
+	image_find_digest(image_ptr, image_size, hash_type,
+			(unsigned char *)&digest);
 #ifdef TZ_SAVE_KERNEL_HASH
-	if (hash_type == CRYPTO_AUTH_ALG_SHA256) {
-		save_kernel_hash_cmd(digest);
-		dprintf(INFO, "Image hash saved.\n");
-	} else
-		dprintf(INFO, "image_verify: hash is not SHA-256.\n");
+	save_kernel_hash((unsigned char *) &digest, hash_type);
 #endif
 
 	/*
diff --git a/platform/msm_shared/include/boot_verifier.h b/platform/msm_shared/include/boot_verifier.h
new file mode 100644
index 0000000..62968fc
--- /dev/null
+++ b/platform/msm_shared/include/boot_verifier.h
@@ -0,0 +1,184 @@
+/*
+ * Copyright (c) 2014-2015, 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 __BOOT_VERIFIER_H
+#define __BOOT_VERIFIER_H
+
+#include <asn1.h>
+#include <rsa.h>
+
+/**
+ *    AndroidVerifiedBootSignature DEFINITIONS ::=
+ *    BEGIN
+ *        FormatVersion ::= INTEGER
+ *        Certificate ::= Certificate
+ *        AlgorithmIdentifier ::=  SEQUENCE {
+ *            algorithm OBJECT IDENTIFIER,
+ *            parameters ANY DEFINED BY algorithm OPTIONAL
+ *        }
+ *        AuthenticatedAttributes ::= SEQUENCE {
+ *            target CHARACTER STRING,
+ *            length INTEGER
+ *        }
+ *        Signature ::= OCTET STRING
+ *     END
+ */
+
+typedef struct auth_attr_st
+{
+	ASN1_PRINTABLESTRING *target;
+	ASN1_INTEGER *len;
+}AUTH_ATTR;
+
+DECLARE_STACK_OF(AUTH_ATTR)
+DECLARE_ASN1_SET_OF(AUTH_ATTR)
+DECLARE_ASN1_FUNCTIONS(AUTH_ATTR)
+
+typedef struct verif_boot_sig_st
+{
+	ASN1_INTEGER *version;
+	X509 *certificate;
+	X509_ALGOR *algor;
+	AUTH_ATTR *auth_attr;
+	ASN1_OCTET_STRING *sig;
+}VERIFIED_BOOT_SIG;
+
+DECLARE_STACK_OF(VERIFIED_BOOT_SIG)
+DECLARE_ASN1_SET_OF(VERIFIED_BOOT_SIG)
+DECLARE_ASN1_FUNCTIONS(VERIFIED_BOOT_SIG)
+
+/**
+ * AndroidVerifiedBootKeystore DEFINITIONS ::=
+ * BEGIN
+ *     FormatVersion ::= INTEGER
+ *     KeyBag ::= SEQUENCE {
+ *         Key  ::= SEQUENCE {
+ *             AlgorithmIdentifier  ::=  SEQUENCE {
+ *                 algorithm OBJECT IDENTIFIER,
+ *                 parameters ANY DEFINED BY algorithm OPTIONAL
+ *             }
+ *             KeyMaterial ::= RSAPublicKey
+ *         }
+ *     }
+ *     Signature ::= AndroidVerifiedBootSignature
+ * END
+ */
+
+typedef struct key_st
+{
+	X509_ALGOR *algorithm_id;
+	RSA *key_material;
+}KEY;
+
+DECLARE_STACK_OF(KEY)
+DECLARE_ASN1_SET_OF(KEY)
+DECLARE_ASN1_FUNCTIONS(KEY)
+
+typedef struct keybag_st
+{
+	KEY *mykey;
+}KEYBAG;
+
+DECLARE_STACK_OF(KEYBAG)
+DECLARE_ASN1_SET_OF(KEYBAG)
+DECLARE_ASN1_FUNCTIONS(KEYBAG)
+
+typedef struct keystore_inner_st
+{
+	ASN1_INTEGER *version;
+	KEYBAG *mykeybag;
+}KEYSTORE_INNER;
+
+DECLARE_STACK_OF(KEYSTORE_INNER)
+DECLARE_ASN1_SET_OF(KEYSTORE_INNER)
+DECLARE_ASN1_FUNCTIONS(KEYSTORE_INNER)
+
+typedef struct keystore_st
+{
+	ASN1_INTEGER *version;
+	KEYBAG *mykeybag;
+	VERIFIED_BOOT_SIG *sig;
+}KEYSTORE;
+
+DECLARE_STACK_OF(KEYSTORE)
+DECLARE_ASN1_SET_OF(KEYSTORE)
+DECLARE_ASN1_FUNCTIONS(KEYSTORE)
+
+enum boot_state
+{
+	GREEN,
+	ORANGE,
+	YELLOW,
+	RED,
+};
+
+struct verified_boot_verity_mode
+{
+	bool verity_mode_enforcing;
+	char *name;
+};
+
+struct verified_boot_state_name
+{
+	uint32_t boot_state;
+	char *name;
+};
+
+enum boot_verfiy_event
+{
+	BOOT_INIT,
+	DEV_UNLOCK,
+	BOOTIMG_EMBEDDED_CERT_VERIFICATION_PASS,
+	BOOTIMG_KEYSTORE_VERIFICATION_PASS,
+	BOOTIMG_VERIFICATION_FAIL,
+	USER_DENIES,
+};
+
+extern char KEYSTORE_PTN_NAME[];
+/* Function to initialize keystore */
+uint32_t boot_verify_keystore_init();
+/* Function to verify boot/recovery image */
+bool boot_verify_image(unsigned char* img_addr, uint32_t img_size, char *pname);
+/* Function to send event to boot state machine */
+void boot_verify_send_event(uint32_t event);
+/* Read current boot state */
+uint32_t boot_verify_get_state();
+/* Print current boot state */
+void boot_verify_print_state();
+/* Function to validate keystore */
+bool boot_verify_validate_keystore(unsigned char * user_addr);
+/* Function to check if partition is allowed to flash in verified mode */
+bool boot_verify_flash_allowed(const char * entry);
+/* Function to send root of trust to trust zone */
+bool send_rot_command(uint32_t is_unlocked);
+unsigned char* get_boot_fingerprint(unsigned int* buf_size);
+bool boot_verify_compare_sha256(unsigned char *image_ptr,
+		unsigned int image_size, unsigned char *signature_ptr, RSA *rsa);
+KEYSTORE *boot_gerity_get_oem_keystore();
+#endif
diff --git a/platform/msm_shared/include/crypto5_eng.h b/platform/msm_shared/include/crypto5_eng.h
index 872f46e..7f81488 100644
--- a/platform/msm_shared/include/crypto5_eng.h
+++ b/platform/msm_shared/include/crypto5_eng.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012,2015, 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
@@ -177,5 +177,6 @@
 							crypto_auth_alg_type auth_alg);
 void crypto5_get_ctx(struct crypto_dev *dev, void *ctx_ptr);
 uint32_t crypto5_get_max_auth_blk_size(struct crypto_dev *dev);
+void crypto5_unlock_pipes(struct crypto_dev *dev);
 
 #endif
diff --git a/platform/msm_shared/include/crypto5_wrapper.h b/platform/msm_shared/include/crypto5_wrapper.h
index 9c9af9b..7fc8611 100644
--- a/platform/msm_shared/include/crypto5_wrapper.h
+++ b/platform/msm_shared/include/crypto5_wrapper.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012,2015 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
@@ -33,5 +33,6 @@
 
 void crypto_init_params(struct crypto_init_params * params);
 uint32_t crypto_get_max_auth_blk_size();
+void crypto_unlock(void);
 
 #endif
diff --git a/platform/msm_shared/include/crypto_hash.h b/platform/msm_shared/include/crypto_hash.h
index 800ebaf..bdcf7e0 100644
--- a/platform/msm_shared/include/crypto_hash.h
+++ b/platform/msm_shared/include/crypto_hash.h
@@ -71,17 +71,18 @@
 	unsigned int auth_bytecnt[2];
 	unsigned char saved_buff[64];
 	unsigned char saved_buff_indx;
-	unsigned int auth_iv[5];
+	uint32_t bytes_to_write;
 	uint32_t flags;
+	unsigned int auth_iv[5];
 } crypto_SHA1_ctx;
 
 typedef struct {
 	unsigned int auth_bytecnt[2];
 	unsigned char saved_buff[64];
 	unsigned char saved_buff_indx;
-	unsigned int auth_iv[8];
 	uint32_t bytes_to_write;
 	uint32_t flags;
+	unsigned int auth_iv[8];
 } crypto_SHA256_ctx;
 
 extern void crypto_eng_reset(void);
diff --git a/platform/msm_shared/include/image_verify.h b/platform/msm_shared/include/image_verify.h
index 709aa93..240803f 100644
--- a/platform/msm_shared/include/image_verify.h
+++ b/platform/msm_shared/include/image_verify.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2011,2014-2015 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
@@ -27,6 +27,8 @@
 #ifndef __IMAGE_VERIFY_H
 #define __IMAGE_VERIFY_H
 
+#include <x509.h>
+
 #define SHA1_SIZE      16
 #define SHA256_SIZE    32
 /* For keys of length 2048 bits */
@@ -37,4 +39,14 @@
 int image_verify(unsigned char *image_ptr,
 		 unsigned char *signature_ptr,
 		 unsigned int image_size, unsigned hash_type);
+
+/* Decrypt signature with RSA public key */
+int image_decrypt_signature_rsa(unsigned char *signature_ptr,
+		unsigned char *plain_text, RSA *rsa_key);
+
+/* Find hash of image */
+void image_find_digest(unsigned char *image_ptr, unsigned int image_size,
+		unsigned hash_type, unsigned char *digest);
+void save_kernel_hash_cmd(void *digest);
+void save_kernel_hash(unsigned char *digest, unsigned hash_type);
 #endif
diff --git a/platform/msm_shared/include/oem_keystore.h b/platform/msm_shared/include/oem_keystore.h
new file mode 100755
index 0000000..7f6e935
--- /dev/null
+++ b/platform/msm_shared/include/oem_keystore.h
@@ -0,0 +1,170 @@
+/* Copyright (c) 2014-2015, 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_KEYSTORE_H
+#define __OEM_KEYSTORE_H
+const unsigned char OEM_KEYSTORE[] = {
+  0x30, 0x82, 0x06, 0x4f, 0x02, 0x01, 0x00, 0x30, 0x82, 0x01, 0x1f, 0x30,
+  0x82, 0x01, 0x1b, 0x30, 0x0b, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
+  0x0d, 0x01, 0x01, 0x0b, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01,
+  0x00, 0xe8, 0xeb, 0x78, 0x4d, 0x2f, 0x4d, 0x54, 0x91, 0x7a, 0x7b, 0xb3,
+  0x3b, 0xdb, 0xe7, 0x69, 0x67, 0xe4, 0xd1, 0xe4, 0x33, 0x61, 0xa6, 0xf4,
+  0x82, 0xaa, 0x62, 0xeb, 0x10, 0x33, 0x8b, 0xa7, 0x66, 0x0f, 0xeb, 0xa0,
+  0xa0, 0x42, 0x89, 0x99, 0xb3, 0xe2, 0xb8, 0x4e, 0x43, 0xc1, 0xfd, 0xb5,
+  0x8a, 0xc6, 0x7d, 0xba, 0x15, 0x14, 0xbb, 0x47, 0x50, 0x33, 0x8e, 0x9d,
+  0x2b, 0x8a, 0x1c, 0x2b, 0x13, 0x11, 0xad, 0xc9, 0xe6, 0x1b, 0x1c, 0x9d,
+  0x16, 0x7e, 0xa8, 0x7e, 0xcd, 0xce, 0x0c, 0x93, 0x17, 0x3a, 0x4b, 0xf6,
+  0x80, 0xa5, 0xcb, 0xfc, 0x57, 0x5b, 0x10, 0xf7, 0x43, 0x6f, 0x1c, 0xdd,
+  0xbb, 0xcc, 0xf7, 0xca, 0x4f, 0x96, 0xeb, 0xbb, 0x9d, 0x33, 0xf7, 0xd6,
+  0xed, 0x66, 0xda, 0x43, 0x70, 0xce, 0xd2, 0x49, 0xee, 0xfa, 0x2c, 0xca,
+  0x6a, 0x4f, 0xf7, 0x4f, 0x8d, 0x5c, 0xe6, 0xea, 0x17, 0x99, 0x0f, 0x35,
+  0x50, 0xdb, 0x40, 0xcd, 0x11, 0xb3, 0x19, 0xc8, 0x4d, 0x55, 0x73, 0x26,
+  0x5a, 0xe4, 0xc6, 0x3a, 0x48, 0x3a, 0x53, 0xed, 0x08, 0xd9, 0x37, 0x7b,
+  0x2b, 0xcc, 0xaf, 0x50, 0xc5, 0xa1, 0x01, 0x63, 0xcf, 0xa4, 0xa2, 0xed,
+  0x54, 0x7f, 0x6b, 0x00, 0xbe, 0x53, 0xce, 0x36, 0x0d, 0x47, 0xdd, 0xa2,
+  0xcd, 0xd2, 0x9c, 0xcf, 0x70, 0x23, 0x46, 0xc2, 0x37, 0x09, 0x38, 0xed,
+  0xa6, 0x25, 0x40, 0x04, 0x67, 0x97, 0xd1, 0x37, 0x23, 0x45, 0x2b, 0x99,
+  0x07, 0xb2, 0xbd, 0x10, 0xae, 0x7a, 0x1d, 0x5f, 0x8e, 0x14, 0xd4, 0xba,
+  0x23, 0x53, 0x4f, 0x8d, 0xd0, 0xfb, 0x14, 0x84, 0xa1, 0xc8, 0x69, 0x6a,
+  0xa9, 0x97, 0x54, 0x3a, 0x40, 0x14, 0x65, 0x86, 0xa7, 0x6e, 0x98, 0x1e,
+  0x4f, 0x93, 0x7b, 0x40, 0xbe, 0xae, 0xba, 0xa7, 0x06, 0xa6, 0x84, 0xce,
+  0x91, 0xa9, 0x6e, 0xea, 0x49, 0x02, 0x03, 0x01, 0x00, 0x01, 0x30, 0x82,
+  0x05, 0x25, 0x02, 0x01, 0x01, 0x30, 0x82, 0x03, 0xfd, 0x30, 0x82, 0x02,
+  0xe5, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x09, 0x00, 0x97, 0x0f, 0x98,
+  0x39, 0x09, 0xaa, 0x89, 0x49, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48,
+  0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x81, 0x94, 0x31,
+  0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53,
+  0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0c, 0x0a, 0x43,
+  0x61, 0x6c, 0x69, 0x66, 0x6f, 0x72, 0x6e, 0x69, 0x61, 0x31, 0x16, 0x30,
+  0x14, 0x06, 0x03, 0x55, 0x04, 0x07, 0x0c, 0x0d, 0x4d, 0x6f, 0x75, 0x6e,
+  0x74, 0x61, 0x69, 0x6e, 0x20, 0x56, 0x69, 0x65, 0x77, 0x31, 0x10, 0x30,
+  0x0e, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x07, 0x41, 0x6e, 0x64, 0x72,
+  0x6f, 0x69, 0x64, 0x31, 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x0b,
+  0x0c, 0x07, 0x41, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x31, 0x10, 0x30,
+  0x0e, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x07, 0x41, 0x6e, 0x64, 0x72,
+  0x6f, 0x69, 0x64, 0x31, 0x22, 0x30, 0x20, 0x06, 0x09, 0x2a, 0x86, 0x48,
+  0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01, 0x16, 0x13, 0x61, 0x6e, 0x64, 0x72,
+  0x6f, 0x69, 0x64, 0x40, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x2e,
+  0x63, 0x6f, 0x6d, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x34, 0x31, 0x31, 0x30,
+  0x36, 0x31, 0x39, 0x30, 0x37, 0x34, 0x30, 0x5a, 0x17, 0x0d, 0x34, 0x32,
+  0x30, 0x33, 0x32, 0x34, 0x31, 0x39, 0x30, 0x37, 0x34, 0x30, 0x5a, 0x30,
+  0x81, 0x94, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13,
+  0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08,
+  0x0c, 0x0a, 0x43, 0x61, 0x6c, 0x69, 0x66, 0x6f, 0x72, 0x6e, 0x69, 0x61,
+  0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x07, 0x0c, 0x0d, 0x4d,
+  0x6f, 0x75, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x20, 0x56, 0x69, 0x65, 0x77,
+  0x31, 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x07, 0x41,
+  0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x31, 0x10, 0x30, 0x0e, 0x06, 0x03,
+  0x55, 0x04, 0x0b, 0x0c, 0x07, 0x41, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64,
+  0x31, 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x07, 0x41,
+  0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x31, 0x22, 0x30, 0x20, 0x06, 0x09,
+  0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01, 0x16, 0x13, 0x61,
+  0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x40, 0x61, 0x6e, 0x64, 0x72, 0x6f,
+  0x69, 0x64, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d,
+  0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05,
+  0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82,
+  0x01, 0x01, 0x00, 0xe8, 0xeb, 0x78, 0x4d, 0x2f, 0x4d, 0x54, 0x91, 0x7a,
+  0x7b, 0xb3, 0x3b, 0xdb, 0xe7, 0x69, 0x67, 0xe4, 0xd1, 0xe4, 0x33, 0x61,
+  0xa6, 0xf4, 0x82, 0xaa, 0x62, 0xeb, 0x10, 0x33, 0x8b, 0xa7, 0x66, 0x0f,
+  0xeb, 0xa0, 0xa0, 0x42, 0x89, 0x99, 0xb3, 0xe2, 0xb8, 0x4e, 0x43, 0xc1,
+  0xfd, 0xb5, 0x8a, 0xc6, 0x7d, 0xba, 0x15, 0x14, 0xbb, 0x47, 0x50, 0x33,
+  0x8e, 0x9d, 0x2b, 0x8a, 0x1c, 0x2b, 0x13, 0x11, 0xad, 0xc9, 0xe6, 0x1b,
+  0x1c, 0x9d, 0x16, 0x7e, 0xa8, 0x7e, 0xcd, 0xce, 0x0c, 0x93, 0x17, 0x3a,
+  0x4b, 0xf6, 0x80, 0xa5, 0xcb, 0xfc, 0x57, 0x5b, 0x10, 0xf7, 0x43, 0x6f,
+  0x1c, 0xdd, 0xbb, 0xcc, 0xf7, 0xca, 0x4f, 0x96, 0xeb, 0xbb, 0x9d, 0x33,
+  0xf7, 0xd6, 0xed, 0x66, 0xda, 0x43, 0x70, 0xce, 0xd2, 0x49, 0xee, 0xfa,
+  0x2c, 0xca, 0x6a, 0x4f, 0xf7, 0x4f, 0x8d, 0x5c, 0xe6, 0xea, 0x17, 0x99,
+  0x0f, 0x35, 0x50, 0xdb, 0x40, 0xcd, 0x11, 0xb3, 0x19, 0xc8, 0x4d, 0x55,
+  0x73, 0x26, 0x5a, 0xe4, 0xc6, 0x3a, 0x48, 0x3a, 0x53, 0xed, 0x08, 0xd9,
+  0x37, 0x7b, 0x2b, 0xcc, 0xaf, 0x50, 0xc5, 0xa1, 0x01, 0x63, 0xcf, 0xa4,
+  0xa2, 0xed, 0x54, 0x7f, 0x6b, 0x00, 0xbe, 0x53, 0xce, 0x36, 0x0d, 0x47,
+  0xdd, 0xa2, 0xcd, 0xd2, 0x9c, 0xcf, 0x70, 0x23, 0x46, 0xc2, 0x37, 0x09,
+  0x38, 0xed, 0xa6, 0x25, 0x40, 0x04, 0x67, 0x97, 0xd1, 0x37, 0x23, 0x45,
+  0x2b, 0x99, 0x07, 0xb2, 0xbd, 0x10, 0xae, 0x7a, 0x1d, 0x5f, 0x8e, 0x14,
+  0xd4, 0xba, 0x23, 0x53, 0x4f, 0x8d, 0xd0, 0xfb, 0x14, 0x84, 0xa1, 0xc8,
+  0x69, 0x6a, 0xa9, 0x97, 0x54, 0x3a, 0x40, 0x14, 0x65, 0x86, 0xa7, 0x6e,
+  0x98, 0x1e, 0x4f, 0x93, 0x7b, 0x40, 0xbe, 0xae, 0xba, 0xa7, 0x06, 0xa6,
+  0x84, 0xce, 0x91, 0xa9, 0x6e, 0xea, 0x49, 0x02, 0x03, 0x01, 0x00, 0x01,
+  0xa3, 0x50, 0x30, 0x4e, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04,
+  0x16, 0x04, 0x14, 0x7e, 0x43, 0x33, 0xf9, 0xbb, 0xa0, 0x0a, 0xdf, 0xe0,
+  0xed, 0xe9, 0x79, 0xe2, 0x8e, 0xd1, 0x92, 0x04, 0x92, 0xb4, 0x0f, 0x30,
+  0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14,
+  0x7e, 0x43, 0x33, 0xf9, 0xbb, 0xa0, 0x0a, 0xdf, 0xe0, 0xed, 0xe9, 0x79,
+  0xe2, 0x8e, 0xd1, 0x92, 0x04, 0x92, 0xb4, 0x0f, 0x30, 0x0c, 0x06, 0x03,
+  0x55, 0x1d, 0x13, 0x04, 0x05, 0x30, 0x03, 0x01, 0x01, 0xff, 0x30, 0x0d,
+  0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05,
+  0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x73, 0xb7, 0x35, 0x2b, 0xc3, 0x13,
+  0x98, 0xc5, 0xbc, 0xc7, 0xa1, 0x18, 0x6b, 0x52, 0xf0, 0x19, 0xc5, 0x61,
+  0xd1, 0x4a, 0x44, 0x88, 0x25, 0x0c, 0xc7, 0x38, 0x9e, 0x25, 0x92, 0xce,
+  0x1c, 0xce, 0x55, 0x84, 0x47, 0xe1, 0x66, 0xa3, 0xc5, 0xdb, 0x41, 0x59,
+  0xce, 0x5f, 0xc7, 0x48, 0xb1, 0x34, 0x5f, 0xfe, 0x85, 0x52, 0x95, 0x84,
+  0xfe, 0x80, 0x20, 0xe4, 0x1a, 0xfb, 0xef, 0xac, 0x93, 0xe1, 0xc8, 0x8b,
+  0xb4, 0x6f, 0x8a, 0x83, 0xcf, 0x6e, 0x18, 0xdc, 0xb1, 0x59, 0x59, 0x7b,
+  0xb7, 0x14, 0x10, 0x6a, 0xcb, 0x49, 0x2b, 0xde, 0x1a, 0x8b, 0x90, 0xc9,
+  0xcf, 0xa3, 0xd3, 0xe9, 0xba, 0x24, 0x5f, 0x38, 0x92, 0xcc, 0xc8, 0x97,
+  0x91, 0x86, 0x34, 0xc4, 0xe7, 0xc7, 0x45, 0xd1, 0x3c, 0xef, 0xa0, 0xf2,
+  0xde, 0xa1, 0xe4, 0xb5, 0x9f, 0x9d, 0x5c, 0x9d, 0x81, 0x97, 0xe9, 0x19,
+  0x14, 0x60, 0xf9, 0x61, 0xde, 0xc2, 0x4d, 0x54, 0xd8, 0x79, 0x6f, 0x4e,
+  0x32, 0x1c, 0x79, 0xbd, 0x0d, 0x75, 0xca, 0x09, 0xf1, 0x62, 0x89, 0x00,
+  0x55, 0x9d, 0x72, 0xe1, 0x3b, 0x54, 0x89, 0xb8, 0xc3, 0xeb, 0xc5, 0xfc,
+  0x36, 0x17, 0xfc, 0x0d, 0x8e, 0xcb, 0x3a, 0xf6, 0xf9, 0x04, 0x61, 0x99,
+  0x84, 0xaf, 0xd5, 0xcb, 0xac, 0x80, 0x07, 0x82, 0xd6, 0xdb, 0xc7, 0xe1,
+  0xaa, 0x7e, 0x27, 0x52, 0xe0, 0x52, 0x73, 0xae, 0xe4, 0xa8, 0x7f, 0x16,
+  0xa3, 0xcb, 0x2d, 0x2c, 0x0d, 0x55, 0x0a, 0x78, 0x06, 0xee, 0xdb, 0xf5,
+  0x01, 0x5f, 0xa8, 0xaf, 0x0c, 0xa2, 0x3f, 0x38, 0x6e, 0x3f, 0x3c, 0x36,
+  0xa4, 0x46, 0x66, 0x00, 0xf2, 0xab, 0x3b, 0x93, 0xac, 0x5c, 0x67, 0xe8,
+  0x55, 0xbb, 0x76, 0x6c, 0x80, 0xca, 0xdb, 0x6e, 0x00, 0x90, 0x04, 0x03,
+  0x29, 0xa4, 0xd6, 0x68, 0xa9, 0x77, 0xdf, 0xb3, 0xa7, 0x7f, 0x30, 0x0b,
+  0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x30,
+  0x0e, 0x13, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x02,
+  0x02, 0x01, 0x2a, 0x04, 0x82, 0x01, 0x00, 0x4d, 0xc0, 0xf7, 0xf4, 0x94,
+  0xa8, 0x2a, 0x78, 0x27, 0x28, 0xaa, 0x11, 0x33, 0xa6, 0x3c, 0x65, 0xf4,
+  0x0d, 0xab, 0xb8, 0x06, 0x10, 0x24, 0x29, 0xe9, 0xa9, 0xe1, 0x56, 0xb7,
+  0x2b, 0x4d, 0x08, 0x4e, 0xd1, 0xfd, 0xd9, 0x43, 0x7d, 0x67, 0xd3, 0x69,
+  0x42, 0xf0, 0x3c, 0xc9, 0x7b, 0xf7, 0xdf, 0xb4, 0xd8, 0x33, 0x24, 0x75,
+  0x3d, 0xd3, 0xe8, 0xc2, 0xa4, 0xe3, 0xfc, 0x5c, 0xe3, 0x7c, 0xdb, 0x1f,
+  0x00, 0x85, 0x86, 0x74, 0x47, 0xa5, 0xcb, 0x51, 0xc2, 0xb9, 0x09, 0x07,
+  0xa5, 0x91, 0x29, 0x34, 0xf7, 0x69, 0x1e, 0xdf, 0xf3, 0xa8, 0xcf, 0x68,
+  0x73, 0x2e, 0xd3, 0xff, 0x48, 0x4f, 0xc3, 0x7d, 0x8c, 0xde, 0x9d, 0xa1,
+  0x9b, 0x5d, 0x1e, 0xbb, 0xb4, 0x1e, 0x1d, 0xb0, 0xce, 0x4c, 0x5a, 0x45,
+  0x65, 0x8d, 0xd6, 0xcf, 0x1f, 0x9c, 0x73, 0x0d, 0x4d, 0xc0, 0x4b, 0x56,
+  0x58, 0x44, 0x0a, 0x20, 0xba, 0x1c, 0xad, 0xf9, 0xba, 0xa9, 0xa1, 0x9d,
+  0xd5, 0x43, 0xa1, 0xd3, 0xb1, 0x4e, 0xd0, 0x5e, 0xfd, 0xc8, 0x76, 0x7d,
+  0x6a, 0xbc, 0xa3, 0xac, 0xa9, 0xd1, 0x22, 0xb6, 0xdd, 0x3d, 0xe0, 0x09,
+  0xd3, 0xf3, 0x66, 0xe9, 0xba, 0xf4, 0xa0, 0x70, 0xf6, 0xb6, 0xfb, 0xe2,
+  0xe9, 0x60, 0x7b, 0x04, 0x14, 0xb3, 0x46, 0x38, 0x46, 0x8e, 0x04, 0x4a,
+  0x1d, 0x24, 0x16, 0x95, 0x4f, 0xea, 0xc6, 0x90, 0xfe, 0x04, 0xef, 0x3e,
+  0x93, 0x3f, 0x8f, 0xea, 0xa7, 0x3b, 0xbd, 0x92, 0x63, 0xc6, 0xfd, 0xe0,
+  0xbf, 0x62, 0xad, 0x51, 0xee, 0x62, 0x16, 0x29, 0xe1, 0x97, 0xf9, 0xaf,
+  0xbe, 0xb9, 0xa7, 0x31, 0x3e, 0xfc, 0x0a, 0x92, 0x8b, 0xa7, 0x72, 0x15,
+  0xb2, 0xa9, 0xb0, 0x5c, 0xf0, 0x2e, 0x0b, 0xb3, 0xaf, 0x6e, 0x59, 0x95,
+  0xae, 0xaa, 0x10, 0x09, 0x68, 0x0d, 0x0b, 0x64, 0x02, 0x51, 0x26
+};
+
+#endif
diff --git a/platform/msm_shared/include/partition_parser.h b/platform/msm_shared/include/partition_parser.h
index bbd8422..cf89433 100644
--- a/platform/msm_shared/include/partition_parser.h
+++ b/platform/msm_shared/include/partition_parser.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2011-2014, 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
@@ -155,11 +155,13 @@
 	unsigned long long size;
 	unsigned long long attribute_flag;
 	unsigned char name[MAX_GPT_NAME_SIZE];
+	uint8_t lun;
 };
 
 int partition_get_index(const char *name);
 unsigned long long partition_get_size(int index);
 unsigned long long partition_get_offset(int index);
+uint8_t partition_get_lun(int index);
 unsigned int partition_read_table();
 unsigned int write_partition(unsigned size, unsigned char *partition);
 bool partition_gpt_exists();
diff --git a/platform/msm_shared/include/qseecom_lk.h b/platform/msm_shared/include/qseecom_lk.h
new file mode 100644
index 0000000..dd130ed
--- /dev/null
+++ b/platform/msm_shared/include/qseecom_lk.h
@@ -0,0 +1,164 @@
+/* Copyright (c) 2015, 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 _QSEECOM_LK_H_
+#define _QSEECOM_LK_H_
+
+#define MAX_APP_NAME_SIZE  32
+#define QSEECOM_HASH_SIZE  32
+
+/* TZ Diagnostic Area legacy version number */
+#define TZBSP_DIAG_MAJOR_VERSION_LEGACY 2
+
+/*
+ * Log ring buffer position
+ */
+struct tzdbg_log_pos_t {
+	uint16_t wrap;
+	uint16_t offset;
+};
+
+ /*
+ * Log ring buffer
+ */
+struct tzdbg_log_t {
+	struct tzdbg_log_pos_t log_pos;
+	/* open ended array to the end of the 4K IMEM buffer */
+	uint8_t log_buf[];
+};
+struct scm_desc {
+	uint32_t arginfo;
+	uint32_t args[10];
+	uint32_t ret[3];
+	/* private */
+	void *extra_arg_buf;
+	uint64_t x5;
+};
+/*
+ * struct qseecom_register_listener_req -
+ *      for register listener ioctl request
+ * @listener_id - service id (shared between userspace and QSE)
+ * @ifd_data_fd - ion handle
+ * @virt_sb_base - shared buffer base in user space
+ * @sb_size - shared buffer size
+ */
+struct qseecom_register_listener_req {
+	uint32_t listener_id; /* in */
+	void *virt_sb_base; /* in */
+	uint32_t sb_size; /* in */
+};
+
+/*
+ * struct qseecom_send_cmd_req - for send command ioctl request
+ * @cmd_req_len - command buffer length
+ * @cmd_req_buf - command buffer
+ * @resp_len - response buffer length
+ * @resp_buf - response buffer
+ */
+struct qseecom_send_cmd_req {
+	void *cmd_req_buf; /* in */
+	unsigned int cmd_req_len; /* in */
+	void *resp_buf; /* in/out */
+	unsigned int resp_len; /* in/out */
+};
+
+/*
+ * struct qseecom_ion_fd_info - ion fd handle data information
+ * @fd - ion handle to some memory allocated in user space
+ * @cmd_buf_offset - command buffer offset
+ */
+struct qseecom_ion_fd_info {
+	int32_t fd;
+	uint32_t cmd_buf_offset;
+};
+
+/*
+ * struct qseecom_listener_send_resp_req - signal to continue the send_cmd req.
+ * Used as a trigger from HLOS service to notify QSEECOM that it's done with its
+ * operation and provide the response for QSEECOM can continue the incomplete
+ * command execution
+ * @resp_len - Length of the response
+ * @resp_buf - Response buffer where the response of the cmd should go.
+ */
+struct qseecom_send_resp_req {
+	void *resp_buf; /* in */
+	unsigned int resp_len; /* in */
+};
+
+/*
+ * struct qseecom_load_img_data - for sending image length information and
+ * ion file descriptor to the qseecom driver. ion file descriptor is used
+ * for retrieving the ion file handle and in turn the physical address of
+ * the image location.
+ * @mdt_len - Length of the .mdt file in bytes.
+ * @img_len - Length of the .mdt + .b00 +..+.bxx images files in bytes
+ * @ion_fd - Ion file descriptor used when allocating memory.
+ * @img_name - Name of the image.
+*/
+struct qseecom_load_img_req {
+	uint32_t mdt_len; /* in */
+	uint32_t img_len; /* in */
+	int32_t  ifd_data_fd; /* in */
+	char  img_name[MAX_APP_NAME_SIZE]; /* in */
+	int app_id; /* out*/
+};
+
+struct qseecom_set_sb_mem_param_req {
+	int32_t ifd_data_fd; /* in */
+	void *virt_sb_base; /* in */
+	uint32_t sb_len; /* in */
+};
+
+/*
+ * struct qseecom_qseos_version_req - get qseos version
+ * @qseos_version - version number
+ */
+struct qseecom_qseos_version_req {
+	unsigned int qseos_version; /* in */
+};
+
+/*
+ * struct qseecom_qseos_app_load_query - verify if app is loaded in qsee
+ * @app_name[MAX_APP_NAME_SIZE]-  name of the app.
+ * @app_id - app id.
+ */
+struct qseecom_qseos_app_load_query {
+	char app_name[MAX_APP_NAME_SIZE]; /* in */
+	int app_id; /* out */
+};
+
+struct qseecom_send_svc_cmd_req {
+	uint32_t cmd_id;
+	void *cmd_req_buf; /* in */
+	unsigned int cmd_req_len; /* in */
+	void *resp_buf; /* in/out */
+	unsigned int resp_len; /* in/out */
+};
+
+
+#endif /* _QSEECOM_LK_H_ */
diff --git a/platform/msm_shared/include/qseecom_lk_api.h b/platform/msm_shared/include/qseecom_lk_api.h
new file mode 100644
index 0000000..c26da9b
--- /dev/null
+++ b/platform/msm_shared/include/qseecom_lk_api.h
@@ -0,0 +1,189 @@
+/* Copyright (c) 2015, 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 __QSEECOM_LK_API_H_
+#define __QSEECOM_LK_API_H_
+
+#define MAX_APP_NAME_LEN 32
+
+#include <stdint.h>
+/**
+* Qseecom Init
+*	To be called before any calls to qsee secure apps.
+*
+* @return int
+*   Success:	Init succeeded.
+*   Failure:	Error code (negative only).
+*/
+int qseecom_init();
+
+/**
+* Qseecom Tz Init
+*	To be called before any calls to qsee secure apps.
+*
+* @return int
+*   Success:	Tz init succeeded.
+*   Failure:	Error code (negative only).
+*/
+int qseecom_tz_init();
+
+/**
+* Qseecom Exit
+*	To be called before exit of lk.
+*	Once this is called no calls to
+*	Qsee Apps.
+*
+* @return int
+*   Success:	Exit succeeded.
+*   Failure:	Error code (negative only).
+*/
+int qseecom_exit();
+
+/**
+* Start a Secure App
+*
+* @param char* app_name
+*   App name of the Secure App to be started
+*   The app_name provided should be the same
+*   name as the partition/ file and should
+*   be the same name mentioned in TZ_APP_NAME
+*   in the secure app.
+*
+* @return int
+*   Success:	handle to be used for all calls to
+*   			Secure app. Always greater than zero.
+*   Failure:	Error code (negative only).
+*/
+int qseecom_start_app(char *app_name);
+
+/**
+* Shutdown a Secure App
+*
+* @param int handle
+*   Handle  of the Secure App to be shutdown
+*
+* @return int
+*   Status:
+*     0 - Success
+*     Negative value indicates failure.
+*/
+int qseecom_shutdown_app(int handle);
+
+/**
+* Shutdown a Secure App
+*
+* @param int handle
+*   Handle  of the Secure App to send the cmd
+*
+* @param void *send_buf
+*   Pointer to the App request buffer
+*
+* @param uint32_t sbuf_len
+*   Size of the request buffer
+*
+* @param void *resp_buf
+*   Pointer to the App response buffer
+*
+* @param uint32_t rbuf_len
+*   Size of the response buffer
+*
+* @return int
+*   Status:
+*     0 - Success
+*     Negative value indicates failure.
+*/
+int qseecom_send_command(int handle, void *send_buf,
+			uint32_t sbuf_len, void *resp_buf, uint32_t rbuf_len);
+
+typedef int (*ListenerCallback)(void*, uint32_t);
+
+/**
+ * @param char* service_name
+ * 	 The name of the listener service.
+ * @param uint32_t  id
+ * 	 The id used to register a listener with
+ * 	 QSEE in the secure side. This id should
+ * 	 be unique.
+ * @param ListenerCallback service_cmd_handler
+ *   This is the service cmd handler, this cb
+ *   is called for a specific service request.
+ *   The input params are,
+ * 		@param void *buf
+ * 		  The shared buffer which contains the
+ * 		  request from the secure side. The service
+ * 		  also updates this buffer with the response.
+ * 		@param uint32_t size
+ * 		  The size of the shared buffer.
+ *      @return int
+ *        Success:	Exit succeeded.
+ *        Failure:	Error code (negative only).
+ */
+struct qseecom_listener_services {
+	char *service_name;
+	uint32_t  id;
+	uint32_t sb_size;
+	ListenerCallback service_cmd_handler;
+};
+
+/**
+* Registers a Listener Service with QSEE
+*  This api should be called after all
+*  service specific initialization is
+*  completed, once this is called the
+*  service_cmd_handler for the service can
+*  be called.
+*
+* @param struct qseecom_listener_services listnr
+*   Listener structure that contains all the info
+*   to register a listener service.
+*
+* @return int
+*   Status:
+*     0 - Success
+*     Negative value indicates failure.
+*/
+int qseecom_register_listener(struct qseecom_listener_services *listnr);
+
+/**
+* De-Registers a Listener Service with QSEE
+*  This api should be called before exiting lk and
+*  all service de-init should be done before calling
+*  the api. service_cmd_handler will not be called
+*  after this api is called.
+*
+* @param uint32_t listnr_id
+*   Pre-defined Listener ID to be de-registered
+*
+* @return int
+*   Status:
+*     0 - Success
+*     Negative value indicates failure.
+*/
+int qseecom_deregister_listener(uint32_t listnr_id);
+
+#endif /* __QSEECOM_API_LK_H_ */
diff --git a/platform/msm_shared/include/qseecomi_lk.h b/platform/msm_shared/include/qseecomi_lk.h
new file mode 100644
index 0000000..1209833
--- /dev/null
+++ b/platform/msm_shared/include/qseecomi_lk.h
@@ -0,0 +1,520 @@
+/* Copyright (c) 2013-2014, 2015, 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 __QSEECOMI_LK_H_
+#define __QSEECOMI_LK_H_
+
+#include <qseecom_lk.h>
+
+#define QSEECOM_KEY_ID_SIZE   32
+
+#define QSEOS_RESULT_FAIL_UNSUPPORTED_CE_PIPE -63
+#define QSEOS_RESULT_FAIL_KS_OP               -64
+#define QSEOS_RESULT_FAIL_KEY_ID_EXISTS       -65
+#define QSEOS_RESULT_FAIL_MAX_KEYS            -66
+#define QSEOS_RESULT_FAIL_SAVE_KS             -67
+#define QSEOS_RESULT_FAIL_LOAD_KS             -68
+#define QSEOS_RESULT_FAIL_KS_ALREADY_DONE     -69
+#define QSEOS_RESULT_FAIL_KEY_ID_DNE          -70
+#define QSEOS_RESULT_FAIL_INCORRECT_PSWD      -71
+#define QSEOS_RESULT_FAIL_MAX_ATTEMPT         -72
+
+enum qseecom_command_scm_resp_type {
+	QSEOS_APP_ID = 0xEE01,
+	QSEOS_LISTENER_ID,
+    QSEOS_PIPE_ENUM_FILL1 = 0x7FFFFFFF
+};
+
+typedef enum
+{
+  QSEE_APP_START_COMMAND = 0x01,
+  QSEE_APP_SHUTDOWN_COMMAND,
+  QSEE_APP_LOOKUP_COMMAND,
+  QSEE_REGISTER_LISTENER,
+  QSEE_DEREGISTER_LISTENER,
+  QSEE_CLIENT_SEND_DATA_COMMAND,
+  QSEE_LISTENER_DATA_RSP_COMMAND,
+  QSEE_LOAD_EXTERNAL_ELF_COMMAND,
+  QSEE_UNLOAD_EXTERNAL_ELF_COMMAND,
+  QSEE_GET_APP_STATE_COMMAND,
+  QSEE_LOAD_SERV_IMAGE_COMMAND,
+  QSEE_UNLOAD_SERV_IMAGE_COMMAND,
+  QSEE_APP_REGION_NOTIFICATION,
+  QSEE_REGISTER_LOG_BUF_COMMAND,
+  QSEE_RPMB_PROVISION_KEY_COMMAND,
+  QSEE_RPMB_ERASE_COMMAND,
+  QSEE_KS_GEN_KEY_COMMAND,
+  QSEE_KS_DEL_KEY_COMMAND,
+  QSEE_KS_GET_MAX_KEYS_COMMAND,
+  QSEE_KS_SET_PIPE_KEY_COMMAND,
+  QSEE_KS_UPDATE_KEY_COMMAND,
+  QSEE_GP_OPEN_SESSION,
+  QSEE_GP_INVOKE_COMMAND,
+  QSEE_GP_CLOSE_SESSION,
+  QSEOS_PIPE_ENUM_FILL2 = 0x7FFFFFFF
+}qsee_smc_command_type;
+
+enum qseecom_qceos_cmd_status {
+	QSEOS_RESULT_SUCCESS = 0,
+	QSEOS_RESULT_INCOMPLETE,
+	QSEOS_RESULT_FAILURE  = 0xFFFFFFFF
+};
+
+enum qseecom_pipe_type {
+	QSEOS_PIPE_ENC = 0x1,
+	QSEOS_PIPE_ENC_XTS = 0x2,
+	QSEOS_PIPE_AUTH = 0x4,
+	QSEOS_PIPE_ENUM_FILL = 0x7FFFFFFF
+};
+
+struct __attribute__ ((packed)) qsee_apps_region_info_ireq {
+	uint32_t qsee_cmd_id;
+	uint32_t addr;
+	uint32_t size;
+};
+
+struct __attribute__ ((packed)) qseecom_check_app_ireq {
+	uint32_t qsee_cmd_id;
+	char     app_name[MAX_APP_NAME_SIZE];
+};
+
+struct __attribute__ ((packed)) qseecom_load_app_ireq {
+	uint32_t qsee_cmd_id;
+	uint32_t mdt_len;		/* Length of the mdt file */
+	uint32_t img_len;		/* Length of .bxx and .mdt files */
+	uint32_t phy_addr;		/* phy addr of the start of image */
+	char     app_name[MAX_APP_NAME_SIZE];	/* application name*/
+};
+
+struct __attribute__ ((packed)) qseecom_unload_app_ireq {
+	uint32_t qsee_cmd_id;
+	uint32_t  app_id;
+};
+
+struct __attribute__ ((packed)) qseecom_load_lib_image_ireq {
+	uint32_t qsee_cmd_id;
+	uint32_t mdt_len;
+	uint32_t img_len;
+	uint32_t phy_addr;
+};
+
+struct __attribute__ ((packed)) qseecom_unload_lib_image_ireq {
+	uint32_t qsee_cmd_id;
+};
+
+struct __attribute__ ((packed)) qseecom_register_listener_ireq {
+	uint32_t qsee_cmd_id;
+	uint32_t listener_id;
+	uint32_t sb_ptr;
+	uint32_t sb_len;
+};
+
+struct __attribute__ ((packed)) qseecom_unregister_listener_ireq {
+	uint32_t qsee_cmd_id;
+	uint32_t  listener_id;
+};
+
+struct __attribute__ ((packed)) qseecom_client_send_data_ireq {
+	uint32_t qsee_cmd_id;
+	uint32_t app_id;
+	uint32_t req_ptr;
+	uint32_t req_len;
+	uint32_t rsp_ptr;/* First 4 bytes should be the return status */
+	uint32_t rsp_len;
+};
+
+struct __attribute__ ((packed)) qseecom_reg_log_buf_ireq {
+	uint32_t qsee_cmd_id;
+	uint32_t phy_addr;
+	uint32_t len;
+};
+
+/* send_data resp */
+struct __attribute__ ((packed)) qseecom_client_listener_data_irsp {
+	uint32_t qsee_cmd_id;
+	uint32_t listener_id;
+	uint32_t status;
+};
+
+/*
+ * struct qseecom_command_scm_resp - qseecom response buffer
+ * @cmd_status: value from enum tz_sched_cmd_status
+ * @sb_in_rsp_addr: points to physical location of response
+ *                buffer
+ * @sb_in_rsp_len: length of command response
+ */
+struct __attribute__ ((packed)) qseecom_command_scm_resp {
+	uint32_t result;
+	enum qseecom_command_scm_resp_type resp_type;
+	unsigned int data;
+};
+
+struct qseecom_rpmb_provision_key {
+	uint32_t key_type;
+};
+
+struct __attribute__ ((packed)) qseecom_client_send_service_ireq {
+	uint32_t qsee_cmd_id;
+	uint32_t key_type; /* in */
+	unsigned int req_len; /* in */
+	uint32_t rsp_ptr; /* in/out */
+	unsigned int rsp_len; /* in/out */
+};
+
+struct __attribute__ ((packed)) qseecom_key_generate_ireq {
+	uint32_t qsee_command_id;
+	uint32_t flags;
+	uint8_t key_id[QSEECOM_KEY_ID_SIZE];
+	uint8_t hash32[QSEECOM_HASH_SIZE];
+};
+
+struct __attribute__ ((packed)) qseecom_key_select_ireq {
+	uint32_t qsee_command_id;
+	uint32_t ce;
+	uint32_t pipe;
+	uint32_t pipe_type;
+	uint32_t flags;
+	uint8_t key_id[QSEECOM_KEY_ID_SIZE];
+	uint8_t hash32[QSEECOM_HASH_SIZE];
+};
+
+struct __attribute__ ((packed)) qseecom_key_delete_ireq {
+	uint32_t qsee_command_id;
+	uint32_t flags;
+	uint8_t key_id[QSEECOM_KEY_ID_SIZE];
+	uint8_t hash32[QSEECOM_HASH_SIZE];
+
+};
+
+struct __attribute__ ((packed)) qseecom_key_userinfo_update_ireq {
+	uint32_t qsee_command_id;
+	uint32_t flags;
+	uint8_t key_id[QSEECOM_KEY_ID_SIZE];
+	uint8_t current_hash32[QSEECOM_HASH_SIZE];
+	uint8_t new_hash32[QSEECOM_HASH_SIZE];
+};
+
+struct __attribute__ ((packed)) qseecom_key_max_count_query_ireq {
+	uint32_t flags;
+};
+
+struct __attribute__ ((packed)) qseecom_key_max_count_query_irsp {
+	uint32_t max_key_count;
+};
+
+struct __attribute__ ((packed)) qseecom_qteec_ireq {
+	uint32_t    qsee_cmd_id;
+	uint32_t    app_id;
+	uint32_t    req_ptr;
+	uint32_t    req_len;
+	uint32_t    resp_ptr;
+	uint32_t    resp_len;
+};
+
+struct __attribute__ ((packed)) qseecom_client_send_fsm_key_req {
+	uint32_t qsee_cmd_id;
+	uint32_t req_ptr;
+	uint32_t req_len;
+	uint32_t rsp_ptr;
+	uint32_t rsp_len;
+};
+
+
+/**********      ARMV8 SMC INTERFACE TZ MACRO     *******************/
+
+#define TZ_SVC_APP_MGR                   1     /* Application management */
+#define TZ_SVC_LISTENER                  2     /* Listener service management */
+#define TZ_SVC_EXTERNAL                  3     /* External image loading */
+#define TZ_SVC_RPMB                      4     /* RPMB */
+#define TZ_SVC_KEYSTORE                  5     /* Keystore management */
+#define TZ_SVC_ES                        16    /* Enterprise Security */
+
+/*----------------------------------------------------------------------------
+ * Owning Entity IDs (defined by ARM SMC doc)
+ * -------------------------------------------------------------------------*/
+#define TZ_OWNER_ARM                     0     /** ARM Architecture call ID */
+#define TZ_OWNER_CPU                     1     /** CPU service call ID */
+#define TZ_OWNER_SIP                     2     /** SIP service call ID */
+#define TZ_OWNER_OEM                     3     /** OEM service call ID */
+#define TZ_OWNER_STD                     4     /** Standard service call ID */
+
+/** Values 5-47 are reserved for future use */
+
+/** Trusted Application call IDs */
+#define TZ_OWNER_TZ_APPS                 48
+#define TZ_OWNER_TZ_APPS_RESERVED        49
+/** Trusted OS Call IDs */
+#define TZ_OWNER_QSEE_OS                 50
+#define TZ_OWNER_MOBI_OS                 51
+#define TZ_OWNER_OS_RESERVED_3           52
+#define TZ_OWNER_OS_RESERVED_4           53
+#define TZ_OWNER_OS_RESERVED_5           54
+#define TZ_OWNER_OS_RESERVED_6           55
+#define TZ_OWNER_OS_RESERVED_7           56
+#define TZ_OWNER_OS_RESERVED_8           57
+#define TZ_OWNER_OS_RESERVED_9           58
+#define TZ_OWNER_OS_RESERVED_10          59
+#define TZ_OWNER_OS_RESERVED_11          60
+#define TZ_OWNER_OS_RESERVED_12          61
+#define TZ_OWNER_OS_RESERVED_13          62
+#define TZ_OWNER_OS_RESERVED_14          63
+
+#define TZ_SVC_INFO                      6     /* Misc. information services */
+
+/** Trusted Application call groups */
+#define TZ_SVC_APP_ID_PLACEHOLDER        0     /* SVC bits will contain App ID */
+
+/** General helper macro to create a bitmask from bits low to high. */
+#define TZ_MASK_BITS(h, l)     ((0xffffffff >> (32 - ((h - l) + 1))) << l)
+
+/**
+   Macro used to define an SMC ID based on the owner ID,
+   service ID, and function number.
+*/
+#define TZ_SYSCALL_CREATE_SMC_ID(o, s, f) \
+	((uint32_t)((((o & 0x3f) << 24) | (s & 0xff) << 8) | (f & 0xff)))
+
+#define TZ_SYSCALL_PARAM_NARGS_MASK  TZ_MASK_BITS(3, 0)
+#define TZ_SYSCALL_PARAM_TYPE_MASK   TZ_MASK_BITS(1, 0)
+
+#define TZ_SYSCALL_CREATE_PARAM_ID(nargs, p1, p2, p3, \
+	p4, p5, p6, p7, p8, p9, p10) \
+	((nargs&TZ_SYSCALL_PARAM_NARGS_MASK)+ \
+	((p1&TZ_SYSCALL_PARAM_TYPE_MASK)<<4)+ \
+	((p2&TZ_SYSCALL_PARAM_TYPE_MASK)<<6)+ \
+	((p3&TZ_SYSCALL_PARAM_TYPE_MASK)<<8)+ \
+	((p4&TZ_SYSCALL_PARAM_TYPE_MASK)<<10)+ \
+	((p5&TZ_SYSCALL_PARAM_TYPE_MASK)<<12)+ \
+	((p6&TZ_SYSCALL_PARAM_TYPE_MASK)<<14)+ \
+	((p7&TZ_SYSCALL_PARAM_TYPE_MASK)<<16)+ \
+	((p8&TZ_SYSCALL_PARAM_TYPE_MASK)<<18)+ \
+	((p9&TZ_SYSCALL_PARAM_TYPE_MASK)<<20)+ \
+	((p10&TZ_SYSCALL_PARAM_TYPE_MASK)<<22))
+
+/**
+   Macros used to create the Parameter ID associated with the syscall
+ */
+#define TZ_SYSCALL_CREATE_PARAM_ID_0 0
+#define TZ_SYSCALL_CREATE_PARAM_ID_1(p1) \
+	TZ_SYSCALL_CREATE_PARAM_ID(1, p1, 0, 0, 0, 0, 0, 0, 0, 0, 0)
+#define TZ_SYSCALL_CREATE_PARAM_ID_2(p1, p2) \
+	TZ_SYSCALL_CREATE_PARAM_ID(2, p1, p2, 0, 0, 0, 0, 0, 0, 0, 0)
+#define TZ_SYSCALL_CREATE_PARAM_ID_3(p1, p2, p3) \
+	TZ_SYSCALL_CREATE_PARAM_ID(3, p1, p2, p3, 0, 0, 0, 0, 0, 0, 0)
+#define TZ_SYSCALL_CREATE_PARAM_ID_4(p1, p2, p3, p4) \
+	TZ_SYSCALL_CREATE_PARAM_ID(4, p1, p2, p3, p4, 0, 0, 0, 0, 0, 0)
+#define TZ_SYSCALL_CREATE_PARAM_ID_5(p1, p2, p3, p4, p5) \
+	TZ_SYSCALL_CREATE_PARAM_ID(5, p1, p2, p3, p4, p5, 0, 0, 0, 0, 0)
+#define TZ_SYSCALL_CREATE_PARAM_ID_6(p1, p2, p3, p4, p5, p6) \
+	TZ_SYSCALL_CREATE_PARAM_ID(6, p1, p2, p3, p4, p5, p6, 0, 0, 0, 0)
+#define TZ_SYSCALL_CREATE_PARAM_ID_7(p1, p2, p3, p4, p5, p6, p7) \
+	TZ_SYSCALL_CREATE_PARAM_ID(7, p1, p2, p3, p4, p5, p6, p7, 0, 0, 0)
+#define TZ_SYSCALL_CREATE_PARAM_ID_8(p1, p2, p3, p4, p5, p6, p7, p8) \
+	TZ_SYSCALL_CREATE_PARAM_ID(8, p1, p2, p3, p4, p5, p6, p7, p8, 0, 0)
+#define TZ_SYSCALL_CREATE_PARAM_ID_9(p1, p2, p3, p4, p5, p6, p7, p8, p9) \
+	TZ_SYSCALL_CREATE_PARAM_ID(9, p1, p2, p3, p4, p5, p6, p7, p8, p9, 0)
+#define TZ_SYSCALL_CREATE_PARAM_ID_10(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10) \
+	TZ_SYSCALL_CREATE_PARAM_ID(10, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10)
+
+/**
+   Macro used to obtain the Parameter ID associated with the syscall
+ */
+#define TZ_SYSCALL_GET_PARAM_ID(CMD_ID)        CMD_ID ## _PARAM_ID
+
+#define TZ_SYSCALL_PARAM_TYPE_VAL              0x0     /** type of value */
+#define TZ_SYSCALL_PARAM_TYPE_BUF_RO           0x1     /** type of buffer read-only */
+#define TZ_SYSCALL_PARAM_TYPE_BUF_RW           0x2     /** type of buffer read-write */
+
+#define TZ_OS_APP_START_ID \
+	TZ_SYSCALL_CREATE_SMC_ID(TZ_OWNER_QSEE_OS, TZ_SVC_APP_MGR, 0x01)
+
+#define TZ_OS_APP_START_ID_PARAM_ID \
+	TZ_SYSCALL_CREATE_PARAM_ID_3( \
+	TZ_SYSCALL_PARAM_TYPE_VAL, TZ_SYSCALL_PARAM_TYPE_VAL, \
+	TZ_SYSCALL_PARAM_TYPE_VAL)
+
+#define TZ_OS_APP_SHUTDOWN_ID \
+	TZ_SYSCALL_CREATE_SMC_ID(TZ_OWNER_QSEE_OS, TZ_SVC_APP_MGR, 0x02)
+
+#define TZ_OS_APP_SHUTDOWN_ID_PARAM_ID \
+	TZ_SYSCALL_CREATE_PARAM_ID_1(TZ_SYSCALL_PARAM_TYPE_VAL)
+
+#define TZ_OS_APP_LOOKUP_ID \
+	TZ_SYSCALL_CREATE_SMC_ID(TZ_OWNER_QSEE_OS, TZ_SVC_APP_MGR, 0x03)
+
+#define TZ_OS_APP_LOOKUP_ID_PARAM_ID \
+	TZ_SYSCALL_CREATE_PARAM_ID_2( \
+	TZ_SYSCALL_PARAM_TYPE_BUF_RW, TZ_SYSCALL_PARAM_TYPE_VAL)
+
+#define TZ_OS_APP_GET_STATE_ID \
+	TZ_SYSCALL_CREATE_SMC_ID(TZ_OWNER_QSEE_OS, TZ_SVC_APP_MGR, 0x04)
+
+#define TZ_OS_APP_GET_STATE_ID_PARAM_ID \
+	TZ_SYSCALL_CREATE_PARAM_ID_1(TZ_SYSCALL_PARAM_TYPE_VAL)
+
+#define TZ_OS_APP_REGION_NOTIFICATION_ID \
+	TZ_SYSCALL_CREATE_SMC_ID(TZ_OWNER_QSEE_OS, TZ_SVC_APP_MGR, 0x05)
+
+#define TZ_OS_APP_REGION_NOTIFICATION_ID_PARAM_ID \
+	TZ_SYSCALL_CREATE_PARAM_ID_2( \
+	TZ_SYSCALL_PARAM_TYPE_BUF_RW, TZ_SYSCALL_PARAM_TYPE_VAL)
+
+#define TZ_OS_REGISTER_LOG_BUFFER_ID \
+	TZ_SYSCALL_CREATE_SMC_ID(TZ_OWNER_QSEE_OS, TZ_SVC_APP_MGR, 0x06)
+
+#define TZ_OS_REGISTER_LOG_BUFFER_ID_PARAM_ID \
+	TZ_SYSCALL_CREATE_PARAM_ID_2( \
+	TZ_SYSCALL_PARAM_TYPE_BUF_RW, TZ_SYSCALL_PARAM_TYPE_VAL)
+
+#define TZ_OS_LOAD_SERVICES_IMAGE_ID \
+	TZ_SYSCALL_CREATE_SMC_ID(TZ_OWNER_QSEE_OS, TZ_SVC_APP_MGR, 0x07)
+
+#define TZ_OS_LOAD_SERVICES_IMAGE_ID_PARAM_ID \
+	TZ_SYSCALL_CREATE_PARAM_ID_3( \
+	TZ_SYSCALL_PARAM_TYPE_VAL, TZ_SYSCALL_PARAM_TYPE_VAL, \
+	TZ_SYSCALL_PARAM_TYPE_VAL)
+
+#define TZ_OS_UNLOAD_SERVICES_IMAGE_ID \
+	TZ_SYSCALL_CREATE_SMC_ID(TZ_OWNER_QSEE_OS, TZ_SVC_APP_MGR, 0x08)
+
+#define TZ_OS_UNLOAD_SERVICES_IMAGE_ID_PARAM_ID \
+	TZ_SYSCALL_CREATE_PARAM_ID_0
+
+#define TZ_OS_REGISTER_LISTENER_ID \
+	TZ_SYSCALL_CREATE_SMC_ID(TZ_OWNER_QSEE_OS, TZ_SVC_LISTENER, 0x01)
+
+#define TZ_OS_REGISTER_LISTENER_ID_PARAM_ID \
+	TZ_SYSCALL_CREATE_PARAM_ID_3( \
+	TZ_SYSCALL_PARAM_TYPE_VAL, TZ_SYSCALL_PARAM_TYPE_BUF_RW, \
+	TZ_SYSCALL_PARAM_TYPE_VAL)
+
+#define TZ_OS_DEREGISTER_LISTENER_ID \
+	TZ_SYSCALL_CREATE_SMC_ID(TZ_OWNER_QSEE_OS, TZ_SVC_LISTENER, 0x02)
+
+#define TZ_OS_DEREGISTER_LISTENER_ID_PARAM_ID \
+	TZ_SYSCALL_CREATE_PARAM_ID_1(TZ_SYSCALL_PARAM_TYPE_VAL)
+
+#define TZ_OS_LISTENER_RESPONSE_HANDLER_ID \
+	TZ_SYSCALL_CREATE_SMC_ID(TZ_OWNER_QSEE_OS, TZ_SVC_LISTENER, 0x03)
+
+#define TZ_OS_LISTENER_RESPONSE_HANDLER_ID_PARAM_ID \
+	TZ_SYSCALL_CREATE_PARAM_ID_2( \
+	TZ_SYSCALL_PARAM_TYPE_VAL, TZ_SYSCALL_PARAM_TYPE_VAL)
+
+#define TZ_OS_LOAD_EXTERNAL_IMAGE_ID \
+	TZ_SYSCALL_CREATE_SMC_ID(TZ_OWNER_QSEE_OS, TZ_SVC_EXTERNAL, 0x01)
+
+#define TZ_OS_LOAD_EXTERNAL_IMAGE_ID_PARAM_ID \
+	TZ_SYSCALL_CREATE_PARAM_ID_3( \
+	TZ_SYSCALL_PARAM_TYPE_VAL, TZ_SYSCALL_PARAM_TYPE_VAL, \
+	TZ_SYSCALL_PARAM_TYPE_VAL)
+
+#define TZ_APP_QSAPP_SEND_DATA_ID \
+	TZ_SYSCALL_CREATE_SMC_ID(TZ_OWNER_TZ_APPS, \
+	TZ_SVC_APP_ID_PLACEHOLDER, 0x01)
+
+
+#define TZ_APP_QSAPP_SEND_DATA_ID_PARAM_ID \
+	TZ_SYSCALL_CREATE_PARAM_ID_5( \
+	TZ_SYSCALL_PARAM_TYPE_VAL, TZ_SYSCALL_PARAM_TYPE_BUF_RW, \
+	TZ_SYSCALL_PARAM_TYPE_VAL, TZ_SYSCALL_PARAM_TYPE_BUF_RW, \
+	TZ_SYSCALL_PARAM_TYPE_VAL)
+
+#define TZ_OS_UNLOAD_EXTERNAL_IMAGE_ID \
+	TZ_SYSCALL_CREATE_SMC_ID(TZ_OWNER_QSEE_OS, TZ_SVC_EXTERNAL, 0x02)
+
+#define TZ_OS_UNLOAD_EXTERNAL_IMAGE_ID_PARAM_ID \
+	TZ_SYSCALL_CREATE_PARAM_ID_0
+
+#define TZ_INFO_IS_SVC_AVAILABLE_ID \
+	TZ_SYSCALL_CREATE_SMC_ID(TZ_OWNER_SIP, TZ_SVC_INFO, 0x01)
+
+#define TZ_INFO_IS_SVC_AVAILABLE_ID_PARAM_ID \
+	TZ_SYSCALL_CREATE_PARAM_ID_1(TZ_SYSCALL_PARAM_TYPE_VAL)
+
+#define TZ_INFO_GET_FEATURE_VERSION_ID \
+	TZ_SYSCALL_CREATE_SMC_ID(TZ_OWNER_SIP, TZ_SVC_INFO, 0x03)
+
+#define TZ_INFO_GET_FEATURE_VERSION_ID_PARAM_ID \
+	TZ_SYSCALL_CREATE_PARAM_ID_1(TZ_SYSCALL_PARAM_TYPE_VAL)
+
+#define TZ_OS_RPMB_PROVISION_KEY_ID \
+	TZ_SYSCALL_CREATE_SMC_ID(TZ_OWNER_QSEE_OS, TZ_SVC_RPMB, 0x01)
+
+#define TZ_OS_RPMB_PROVISION_KEY_ID_PARAM_ID \
+	TZ_SYSCALL_CREATE_PARAM_ID_1(TZ_SYSCALL_PARAM_TYPE_VAL)
+
+#define TZ_OS_RPMB_ERASE_ID \
+	TZ_SYSCALL_CREATE_SMC_ID(TZ_OWNER_QSEE_OS, TZ_SVC_RPMB, 0x02)
+
+#define TZ_OS_RPMB_ERASE_ID_PARAM_ID \
+	TZ_SYSCALL_CREATE_PARAM_ID_0
+
+#define TZ_OS_KS_GEN_KEY_ID \
+	TZ_SYSCALL_CREATE_SMC_ID(TZ_OWNER_QSEE_OS, TZ_SVC_KEYSTORE, 0x01)
+
+#define TZ_OS_KS_GEN_KEY_ID_PARAM_ID \
+	TZ_SYSCALL_CREATE_PARAM_ID_2( \
+	TZ_SYSCALL_PARAM_TYPE_BUF_RW, TZ_SYSCALL_PARAM_TYPE_VAL)
+
+#define TZ_OS_KS_DEL_KEY_ID \
+	TZ_SYSCALL_CREATE_SMC_ID(TZ_OWNER_QSEE_OS, TZ_SVC_KEYSTORE, 0x02)
+
+#define TZ_OS_KS_DEL_KEY_ID_PARAM_ID \
+	TZ_SYSCALL_CREATE_PARAM_ID_2( \
+	TZ_SYSCALL_PARAM_TYPE_BUF_RW, TZ_SYSCALL_PARAM_TYPE_VAL)
+
+#define TZ_OS_KS_GET_MAX_KEYS_ID \
+	TZ_SYSCALL_CREATE_SMC_ID(TZ_OWNER_QSEE_OS, TZ_SVC_KEYSTORE, 0x03)
+
+#define TZ_OS_KS_GET_MAX_KEYS_ID_PARAM_ID \
+	TZ_SYSCALL_CREATE_PARAM_ID_1(TZ_SYSCALL_PARAM_TYPE_VAL)
+
+#define TZ_OS_KS_SET_PIPE_KEY_ID \
+	TZ_SYSCALL_CREATE_SMC_ID(TZ_OWNER_QSEE_OS, TZ_SVC_KEYSTORE, 0x04)
+
+#define TZ_OS_KS_SET_PIPE_KEY_ID_PARAM_ID \
+	TZ_SYSCALL_CREATE_PARAM_ID_2( \
+	TZ_SYSCALL_PARAM_TYPE_BUF_RW, TZ_SYSCALL_PARAM_TYPE_VAL)
+
+#define TZ_OS_KS_UPDATE_KEY_ID \
+	TZ_SYSCALL_CREATE_SMC_ID(TZ_OWNER_QSEE_OS, TZ_SVC_KEYSTORE, 0x05)
+
+#define TZ_OS_KS_UPDATE_KEY_ID_PARAM_ID \
+	TZ_SYSCALL_CREATE_PARAM_ID_2( \
+	TZ_SYSCALL_PARAM_TYPE_BUF_RW, TZ_SYSCALL_PARAM_TYPE_VAL)
+
+#define TZ_ES_SAVE_PARTITION_HASH_ID \
+	TZ_SYSCALL_CREATE_SMC_ID(TZ_OWNER_SIP, TZ_SVC_ES, 0x01)
+
+#define TZ_ES_SAVE_PARTITION_HASH_ID_PARAM_ID \
+	TZ_SYSCALL_CREATE_PARAM_ID_3( \
+	TZ_SYSCALL_PARAM_TYPE_VAL, TZ_SYSCALL_PARAM_TYPE_BUF_RW, \
+	TZ_SYSCALL_PARAM_TYPE_VAL)
+
+#endif /* __QSEECOMI_LK_H_ */
diff --git a/platform/msm_shared/include/scm.h b/platform/msm_shared/include/scm.h
index 2c0bb42..6ca7d34 100644
--- a/platform/msm_shared/include/scm.h
+++ b/platform/msm_shared/include/scm.h
@@ -127,6 +127,7 @@
 #define IOMMU_SECURE_CFG            0x02
 
 #define TZ_INFO_GET_FEATURE_ID      0x03
+#define IS_SECURE_BOOT_ENABLED      0x04
 
 #define PRNG_CMD_ID                 0x01
 
@@ -185,6 +186,8 @@
 #define SCM_SVC_PWR                     0x9
 #define SCM_IO_DISABLE_PMIC_ARBITER     0x1
 
+#define SCM_SVC_TZSCHEDULER             0xFC
+
 enum ap_ce_channel_type {
 AP_CE_REGISTER_USE = 0,
 AP_CE_ADM_USE = 1
diff --git a/platform/msm_shared/include/secapp_loader.h b/platform/msm_shared/include/secapp_loader.h
new file mode 100644
index 0000000..0949562
--- /dev/null
+++ b/platform/msm_shared/include/secapp_loader.h
@@ -0,0 +1,63 @@
+/* Copyright (c) 2015, 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 SAL_MAIN_H
+#define SAL_MAIN_H
+
+#include <km_main.h>
+
+enum app_commands
+{
+	CLIENT_CMD_READ_LK_DEVICE_STATE = 0,
+	CLIENT_CMD_LK_END_MILESTONE,
+	CLIENT_CMD_GET_VERSION,
+	CLIENT_CMD_WRITE_LK_DEVICE_STATE,
+};
+
+struct send_cmd_req
+{
+	uint32_t cmd_id;
+	uint32_t data;
+	uint32_t len;
+}__PACKED;
+
+struct send_cmd_rsp
+{
+	uint32_t cmd_id;
+	uint32_t data;
+	int32_t status;
+}__PACKED;
+
+int get_secapp_handle();
+bool is_sec_app_loaded();
+int load_sec_app();
+int get_secapp_handle();
+int send_milestone_call_to_tz();
+int send_delete_keys_to_tz();
+
+#endif /* SAL_MAIN_H */
diff --git a/platform/msm_shared/partition_parser.c b/platform/msm_shared/partition_parser.c
index 52fc4f9..e7fb0e5 100644
--- a/platform/msm_shared/partition_parser.c
+++ b/platform/msm_shared/partition_parser.c
@@ -37,6 +37,24 @@
 static bool flashing_gpt = 0;
 static bool parse_secondary_gpt = 0;
 
+__WEAK void mmc_set_lun(uint8_t lun)
+{
+}
+
+__WEAK uint8_t mmc_get_lun(void)
+{
+	return 0;
+}
+
+__WEAK void mmc_read_partition_table(uint8_t arg)
+{
+	if(partition_read_table())
+	{
+		dprintf(CRITICAL, "Error reading the partition table info\n");
+		ASSERT(0);
+	}
+}
+
 static uint32_t mmc_boot_read_gpt(uint32_t block_size);
 static uint32_t mmc_boot_read_mbr(uint32_t block_size);
 static void mbr_fill_name(struct partition_entry *partition_ent,
@@ -66,7 +84,7 @@
 
 struct partition_entry *partition_entries;
 static unsigned gpt_partitions_exist = 0;
-unsigned partition_count = 0;
+static unsigned partition_count;
 
 unsigned int partition_read_table()
 {
@@ -76,8 +94,11 @@
 	block_size = mmc_get_device_blocksize();
 
 	/* Allocate partition entries array */
-	partition_entries = (struct partition_entry *) calloc(NUM_PARTITIONS, sizeof(struct partition_entry));
-	ASSERT(partition_entries);
+	if(!partition_entries)
+	{
+		partition_entries = (struct partition_entry *) calloc(NUM_PARTITIONS, sizeof(struct partition_entry));
+		ASSERT(partition_entries);
+	}
 
 	/* Read MBR of the card */
 	ret = mmc_boot_read_mbr(block_size);
@@ -136,7 +157,6 @@
 	 * Process each of the four partitions in the MBR by reading the table
 	 * information into our mbr table.
 	 */
-	partition_count = 0;
 	idx = TABLE_ENTRY_0;
 	for (i = 0; i < 4; i++) {
 		/* Type 0xEE indicates end of MBR and GPT partitions exist */
@@ -245,8 +265,6 @@
 	uint8_t *data = NULL;
 	uint32_t part_entry_cnt = block_size / ENTRY_SIZE;
 
-	partition_count = 0;
-
 	/* Get the density of the mmc device */
 
 	device_density = mmc_get_device_capacity();
@@ -349,6 +367,8 @@
 			memcpy(UTF16_name, &data[(j * partition_entry_size) +
 						 PARTITION_NAME_OFFSET],
 			       MAX_GPT_NAME_SIZE);
+			partition_entries[partition_count].lun = mmc_get_lun();
+
 			/*
 			 * Currently partition names in *.xml are UTF-8 and lowercase
 			 * Only supporting english for now so removing 2nd byte of UTF-16
@@ -727,13 +747,9 @@
 
 	/* Re-read the GPT partition table */
 	dprintf(INFO, "Re-reading the GPT Partition Table\n");
-	ret = mmc_boot_read_gpt(block_size);
-	if (ret) {
-		dprintf(CRITICAL,
-			"GPT: Failure to re- read the GPT Partition table\n");
-		goto end;
-	}
 	flashing_gpt = 0;
+	partition_count = 0;
+	mmc_read_partition_table(0);
 	partition_dump();
 	dprintf(CRITICAL, "GPT: Partition Table written\n");
 	memset(primary_gpt_header, 0x00, size);
@@ -902,6 +918,11 @@
 	}
 }
 
+uint8_t partition_get_lun(int index)
+{
+	return partition_entries[index].lun;
+}
+
 /* Debug: Print all parsed partitions */
 void partition_dump()
 {
diff --git a/platform/msm_shared/qseecom_lk.c b/platform/msm_shared/qseecom_lk.c
new file mode 100644
index 0000000..bd073a6
--- /dev/null
+++ b/platform/msm_shared/qseecom_lk.c
@@ -0,0 +1,1166 @@
+/* Copyright (c) 2012-2015, 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.
+ */
+
+#define pr_fmt(fmt) "QSEECOM: %s: " fmt, __func__
+
+#include <partition_parser.h>
+#include <qseecom_lk.h>
+#include <scm.h>
+#include <qseecomi_lk.h>
+#include "qseecom_lk_api.h"
+#include <debug.h>
+#include <kernel/mutex.h>
+#include <malloc.h>
+#include <stdlib.h>
+#include <arch/defines.h>
+#include <string.h>
+#include <platform/iomap.h>
+#include <platform.h>
+
+#define QSEOS_VERSION_14  0x14
+#define QSEEE_VERSION_00  0x400000
+#define QSEE_VERSION_20   0x800000
+
+
+#define QSEOS_CHECK_VERSION_CMD  0x00001803
+
+#define MAX_SCM_ARGS 10
+#define N_EXT_SCM_ARGS 7
+#define FIRST_EXT_ARG_IDX 3
+
+#define N_REGISTER_ARGS (MAX_SCM_ARGS - N_EXT_SCM_ARGS + 1)
+
+#define QSEE_LOG_BUF_SIZE (4096)
+#define GENERIC_ERROR -1
+#define LISTENER_ALREADY_PRESENT_ERROR -2
+
+#define TZ_CALL 6
+enum qseecom_client_handle_type {
+	QSEECOM_CLIENT_APP = 1,
+	QSEECOM_LISTENER_SERVICE,
+	QSEECOM_SECURE_SERVICE,
+	QSEECOM_GENERIC,
+	QSEECOM_UNAVAILABLE_CLIENT_APP,
+};
+
+struct qseecom_registered_listener_list {
+	struct list_node node;
+	struct qseecom_register_listener_req svc;
+	ListenerCallback CallbackFn;
+};
+
+struct qseecom_registered_app_list {
+	struct list_node node;
+	uint32_t  app_id;
+	uint32_t  ref_cnt;
+	char app_name[MAX_APP_NAME_SIZE];
+	int  handle;
+};
+
+struct qseecom_control {
+	struct list_node  registered_listener_list_head;
+	mutex_t           registered_listener_list_lock;
+
+	struct list_node  registered_app_list_head;
+	mutex_t           registered_app_list_lock;
+
+	uint32_t          qseos_version;
+	uint32_t          qsee_version;
+	int               handle;
+	bool              commonlib_loaded;
+	mutex_t           global_data_lock;
+	uint32_t          cmnlib_loaded;
+	uint32_t          qseecom_init_done;
+	uint32_t          qseecom_tz_init_done;
+};
+
+struct qseecom_listener_handle {
+	uint32_t               id;
+};
+
+static struct qseecom_reg_log_buf_ireq logbuf_req;
+static struct qseecom_control qseecom;
+static int __qseecom_process_incomplete_cmd(struct qseecom_command_scm_resp *resp,
+          struct qseecom_client_listener_data_irsp *send_data_rsp);
+
+/*
+ * Appsbl runs in Aarch32 when this is ported for Aarch64,
+ * change return type for uint64_t.
+ */
+static uint32_t __qseecom_uvirt_to_kphys(uint64_t virt)
+{
+	dprintf(SPEW, "%s called\n", __func__);
+	return (uint32_t)platform_get_virt_to_phys_mapping((addr_t)virt);
+}
+
+static int _disp_log_stats(struct tzdbg_log_t *log, uint32_t log_len,
+		uint32_t startOffset, uint32_t endOffset)
+{
+	uint32_t MaxBufSize = 0;
+	uint32_t LogBufSize = 0;
+	uint32_t LogBufFirstHalf = 0;
+	uint32_t len = 0;
+	char *pCurPos, *pPrintPos = NULL;
+	void *pLogBuf = NULL;
+	int ret = GENERIC_ERROR;
+
+	MaxBufSize = QSEE_LOG_BUF_SIZE - sizeof(struct tzdbg_log_pos_t);
+
+	dprintf(SPEW, "%s called\n", __func__);
+	if (startOffset < endOffset)
+	{
+		LogBufSize = endOffset - startOffset;
+		pLogBuf = malloc(LogBufSize);
+		if (NULL == pLogBuf)
+		{
+			ret = GENERIC_ERROR;
+			dprintf(CRITICAL, "Failed to alloc buffer to print TZ Log:%u\n", LogBufSize);
+			goto err;
+		}
+		memset(pLogBuf, 0, LogBufSize);
+		memscpy(pLogBuf, LogBufSize, (char *)((uint32_t)log->log_buf + startOffset), LogBufSize);
+	}
+	else if ( endOffset < startOffset)
+	{
+		LogBufSize =  MaxBufSize - (startOffset - endOffset);
+		LogBufFirstHalf = MaxBufSize - startOffset;
+		pLogBuf = malloc(LogBufSize);
+		if (NULL == pLogBuf)
+		{
+			ret = GENERIC_ERROR;
+			dprintf(CRITICAL, "Failed to alloc buffer to print TZ Log:%u\n", LogBufSize);
+			goto err;
+		}
+		memset(pLogBuf, 0, LogBufSize);
+		memscpy(pLogBuf, LogBufSize, (char *)((uint32_t)log->log_buf + startOffset), LogBufFirstHalf);
+		memscpy((char *)((uint32_t)pLogBuf+ LogBufFirstHalf), (LogBufSize - LogBufFirstHalf), log->log_buf, endOffset);
+	}
+	else //endOffset == startOffset
+	{
+		ret = 0;
+		goto err;
+	}
+
+	/*
+	 *  Read from ring buff while there is data and space in return buff
+	 */
+	pCurPos = pLogBuf;
+	pPrintPos = pCurPos;
+	while (len < LogBufSize)
+	{
+			//QSEE separate each line by "\r \n"
+			if ((*pCurPos == '\r')&&(*(pCurPos+1) == '\n'))
+			{
+				//update the line to dump
+				*pCurPos = '\0';
+				len++;
+				pCurPos++;
+				*pCurPos = '\0';
+				len++;
+				pCurPos++;
+				dprintf(ALWAYS, "%s\n", pPrintPos);
+				pPrintPos = pCurPos;
+				continue;
+			}
+			len++;
+			pCurPos++;
+	}
+	ret = 0;
+	free(pLogBuf);
+err:
+	return ret;
+}
+
+static int qseecom_scm_call(uint32_t svc_id, uint32_t tz_cmd_id, void *cmd_buf,
+		size_t cmd_len, void *resp_buf, size_t resp_len)
+{
+	void *req = NULL;
+	struct qseecom_command_scm_resp *resp = NULL;
+	struct qseecom_client_listener_data_irsp send_data_rsp = {0};
+	int ret = GENERIC_ERROR;
+	uint32_t qseos_cmd_id = 0;
+
+	if ((!cmd_buf) || (!resp_buf))
+			return GENERIC_ERROR;
+
+	dprintf(SPEW, "%s called\n", __func__);
+	mutex_acquire(&qseecom.registered_app_list_lock);
+	req = cmd_buf;
+	qseos_cmd_id = *(uint32_t *)req;
+	resp = (struct qseecom_command_scm_resp *) resp_buf;
+
+	do {
+		ret = scm_call(svc_id, tz_cmd_id, req, cmd_len,
+				resp_buf, resp_len);
+
+		if (ret) {
+			dprintf(CRITICAL, "ERROR: scm_call to load failed : ret %d\n", ret);
+			ret = GENERIC_ERROR;
+			goto err;
+		}
+
+		if (svc_id == TZ_CALL) {
+			goto err;
+		}
+
+		switch (resp->result) {
+			case QSEOS_RESULT_SUCCESS:
+				if(((resp->resp_type != QSEOS_APP_ID) || (resp->data <= 0)) &&
+					((qseos_cmd_id == QSEE_CLIENT_SEND_DATA_COMMAND) ||
+							(qseos_cmd_id == QSEE_LISTENER_DATA_RSP_COMMAND)))
+				{
+					dprintf(CRITICAL, "ERROR: Resp type %d or Resp Data %d incorrect\n",
+							resp->resp_type, resp->data);
+					ret = GENERIC_ERROR;
+					goto err;
+				}
+				goto err;
+			case QSEOS_RESULT_FAILURE:
+				dprintf(CRITICAL, "scm call failed w/response result%d\n", resp->result);
+				ret = GENERIC_ERROR;
+				goto err;
+			case  QSEOS_RESULT_INCOMPLETE:
+				if(resp->resp_type != QSEOS_LISTENER_ID)
+				{
+					ret = GENERIC_ERROR;
+					dprintf(CRITICAL, "Listener service incorrect resp->result:%d resp->resp_type:%d\n",
+							resp->result, resp->resp_type);
+					goto err;
+				}
+				__qseecom_process_incomplete_cmd(resp, &send_data_rsp);
+				req = (void *)&send_data_rsp;
+				qseos_cmd_id = QSEE_LISTENER_DATA_RSP_COMMAND;
+				break;
+			default:
+				dprintf(CRITICAL, "scm call return unknown response %d\n",	resp->result);
+				ret = GENERIC_ERROR;
+				goto err;
+		}
+	} while(true);
+
+err:
+	mutex_release(&qseecom.registered_app_list_lock);
+	return ret;
+
+}
+
+static int __qseecom_process_incomplete_cmd(struct qseecom_command_scm_resp *resp,
+		struct qseecom_client_listener_data_irsp *send_data_rsp)
+{
+	int ret = 0;
+	struct qseecom_registered_listener_list *entry;
+
+	if ((!resp) || (!send_data_rsp))
+	{
+		return GENERIC_ERROR;
+	}
+
+	dprintf(SPEW, "%s called\n", __func__);
+	mutex_acquire(&qseecom.global_data_lock);
+
+	list_for_every_entry(&qseecom.registered_listener_list_head,
+			entry, struct qseecom_registered_listener_list, node) {
+		if (resp->data == entry->svc.listener_id) {
+			arch_invalidate_cache_range((addr_t) entry->svc.virt_sb_base, entry->svc.sb_size);
+			entry->CallbackFn(entry->svc.virt_sb_base, entry->svc.sb_size);
+			arch_clean_invalidate_cache_range((addr_t) entry->svc.virt_sb_base, entry->svc.sb_size);
+			break;
+		}
+	}
+	send_data_rsp->qsee_cmd_id = QSEE_LISTENER_DATA_RSP_COMMAND;
+	send_data_rsp->listener_id  = entry->svc.listener_id;
+	send_data_rsp->status  = 0;
+	mutex_release(&qseecom.global_data_lock);
+	return ret;
+}
+
+static int __qseecom_load_app(const char *app_name, unsigned int *app_id)
+{
+	int index = INVALID_PTN;
+	unsigned long long ptn = 0;
+	unsigned long long size = 0;
+	void *buf = NULL;
+	void *req = NULL;
+	struct qseecom_load_app_ireq load_req = {0};
+	struct qseecom_command_scm_resp resp;
+	struct tzdbg_log_t *log = NULL;
+	uint32_t QseeLogStart = 0;
+	uint32_t QseeLogNewStart = 0;
+
+	int ret = GENERIC_ERROR;
+	uint8_t lun = 0;
+
+	if (!app_name)
+		return GENERIC_ERROR;
+
+	dprintf(SPEW, "%s called\n", __func__);
+	index = partition_get_index(app_name);
+	lun = partition_get_lun(index);
+	mmc_set_lun(lun);
+
+	size = partition_get_size(index);
+
+	buf = memalign(PAGE_SIZE, ROUNDUP(size, PAGE_SIZE));
+	if (!buf) {
+		dprintf(CRITICAL, "%s: Aloc failed for %s image\n",
+				__func__, app_name);
+		ret = GENERIC_ERROR;
+		goto err;
+	}
+
+	ptn = partition_get_offset(index);
+	if(ptn == 0) {
+		dprintf(CRITICAL, "ERROR: No %s found\n", app_name);
+		ret = GENERIC_ERROR;
+		goto err;
+	}
+	if (mmc_read(ptn, (unsigned int *) buf, size)) {
+		dprintf(CRITICAL, "ERROR: Cannot read %s image\n", app_name);
+		ret = GENERIC_ERROR;
+		goto err;
+	}
+
+	/* Currently on 8994 only 32-bit phy addr is supported
+	 * Hence downcasting is okay
+	 */
+	load_req.phy_addr = (uint32_t)__qseecom_uvirt_to_kphys((uint32_t) buf);
+	load_req.qsee_cmd_id = QSEE_APP_START_COMMAND;
+	load_req.img_len = size;
+	load_req.mdt_len = 0;
+	dprintf(SPEW, "phy_addr:%u img_len:%u\n", load_req.phy_addr, load_req.img_len);
+
+	memscpy(&load_req.app_name, MAX_APP_NAME_SIZE, app_name, MAX_APP_NAME_SIZE);
+	req = (void *)&load_req;
+
+	log = (struct tzdbg_log_t *)logbuf_req.phy_addr;
+	arch_invalidate_cache_range((addr_t) logbuf_req.phy_addr, logbuf_req.len);
+	QseeLogStart = (uint32_t) log->log_pos.offset;
+
+	arch_clean_invalidate_cache_range((addr_t) load_req.phy_addr, load_req.img_len);
+	ret = qseecom_scm_call(SCM_SVC_TZSCHEDULER, 1, req,
+				sizeof(struct qseecom_load_lib_image_ireq),
+							&resp, sizeof(resp));
+	if(ret == 0)
+		*app_id = resp.data;
+	else
+		*app_id = 0;
+	arch_invalidate_cache_range((addr_t) logbuf_req.phy_addr, logbuf_req.len);
+	QseeLogNewStart = (uint32_t) log->log_pos.offset;
+
+	_disp_log_stats((struct tzdbg_log_t *) logbuf_req.phy_addr, QSEE_LOG_BUF_SIZE - sizeof(struct tzdbg_log_pos_t),
+			QseeLogStart, QseeLogNewStart);
+err:
+	if (buf)
+		free(buf);
+	return ret;
+}
+
+static int qseecom_load_commonlib_image(char * app_name)
+{
+	int index = INVALID_PTN;
+	unsigned long long ptn = 0;
+	unsigned long long size = 0;
+	void *buf = NULL;
+	void *req = NULL;
+	struct qseecom_load_app_ireq load_req = {0};
+	struct qseecom_command_scm_resp resp = {0};
+	int ret = GENERIC_ERROR;
+	uint8_t lun = 0;
+
+	dprintf(SPEW, "%s called\n", __func__);
+	index = partition_get_index(app_name);
+	lun = partition_get_lun(index);
+	mmc_set_lun(lun);
+
+	size = partition_get_size(index);
+
+	buf = memalign(PAGE_SIZE, ROUNDUP(size, PAGE_SIZE));
+	if (!buf) {
+		dprintf(CRITICAL, "%s: Aloc failed for %s image\n",
+				__func__, app_name);
+		ret = GENERIC_ERROR;
+		goto err;
+	}
+
+	ptn = partition_get_offset(index);
+	if(ptn == 0) {
+		dprintf(CRITICAL, "ERROR: No %s found\n", app_name);
+		ret = GENERIC_ERROR;
+		goto err;
+	}
+	if (mmc_read(ptn, (unsigned int *) buf, size)) {
+		dprintf(CRITICAL, "ERROR: Cannot read %s image\n", app_name);
+		ret = GENERIC_ERROR;
+		goto err;
+	}
+
+	/* Currently on 8994 only 32-bit phy addr is supported
+	 * Hence downcasting is okay
+	 */
+	load_req.phy_addr = (uint32_t)__qseecom_uvirt_to_kphys((uint32_t) buf);
+	load_req.qsee_cmd_id = QSEE_LOAD_SERV_IMAGE_COMMAND;
+	load_req.img_len = size;
+	load_req.mdt_len = 0;
+
+	memscpy(load_req.app_name, MAX_APP_NAME_SIZE, app_name, MAX_APP_NAME_SIZE);
+	req = (void *)&load_req;
+
+	arch_clean_invalidate_cache_range((addr_t) load_req.phy_addr, load_req.img_len);
+	ret = qseecom_scm_call(SCM_SVC_TZSCHEDULER, 1, req,
+				sizeof(struct qseecom_load_lib_image_ireq),
+							&resp, sizeof(resp));
+	if(ret == 0)
+		ret = resp.data;
+
+err:
+	if (buf)
+		free(buf);
+	return ret;
+}
+
+static int qseecom_unload_commonlib_image(void)
+{
+	int ret = GENERIC_ERROR;
+	struct qseecom_unload_lib_image_ireq unload_req = {0};
+	struct qseecom_command_scm_resp resp;
+
+	dprintf(SPEW, "%s called\n", __func__);
+	/* Populate the remaining parameters */
+	unload_req.qsee_cmd_id = QSEE_UNLOAD_SERV_IMAGE_COMMAND;
+	/* SCM_CALL to load the image */
+	ret = qseecom_scm_call(SCM_SVC_TZSCHEDULER, 1, &unload_req,
+			sizeof(struct qseecom_unload_lib_image_ireq),
+						&resp, sizeof(resp));
+	return ret;
+}
+
+/*
+ * This function is called with the global
+ * data mutex acquired.
+ */
+static struct qseecom_registered_app_list *
+	__qseecom_add_app_entry(char *app_name, uint32_t app_id)
+{
+	struct qseecom_registered_app_list *entry = NULL;
+	int32_t ret = GENERIC_ERROR;
+
+	if ((!app_name) || (app_id == 0)) {
+		dprintf(CRITICAL, "%s: Invalid Input\n", __func__);
+		return NULL;
+	}
+	dprintf(SPEW, "%s called\n", __func__);
+
+	entry = malloc(sizeof(*entry));
+	if (!entry) {
+		dprintf(CRITICAL, "malloc for app entry failed\n");
+		ret =  GENERIC_ERROR;
+		goto err;
+	}
+	entry->app_id = app_id;
+	entry->ref_cnt = 1;
+	strlcpy(entry->app_name, app_name, MAX_APP_NAME_SIZE);
+
+	dprintf(SPEW, "%s: Adding app:%s app_id:%u to list\n", __func__, entry->app_name, entry->app_id);
+	list_add_tail(&qseecom.registered_app_list_head, &entry->node);
+	ret = 0;
+err:
+	if (entry && (ret < 0)) {
+		free(entry);
+		return NULL;
+	}
+	return entry;
+}
+
+/*
+ * This function is called with the global
+ * data mutex acquired.
+ */
+static int
+	__qseecom_remove_app_entry(struct qseecom_registered_app_list *entry)
+{
+	if (!entry) {
+		dprintf(CRITICAL, "%s: Invalid Input\n", __func__);
+		return GENERIC_ERROR;
+	}
+	dprintf(SPEW, "%s called\n", __func__);
+	list_delete(&entry->node);
+	free(entry);
+
+	return 0;
+}
+
+/*
+ * This function is called with the global
+ * data mutex acquired.
+ */
+struct qseecom_registered_listener_list *
+	__qseecom_check_listener_exists(uint32_t listener_id)
+{
+	struct qseecom_registered_listener_list *entry = NULL;
+	bool listener_present = false;
+
+	if (!listener_id) {
+		dprintf(CRITICAL, "%s: Invalid Input\n", __func__);
+		return NULL;
+	}
+	dprintf(SPEW, "%s called\n", __func__);
+
+	list_for_every_entry(&qseecom.registered_listener_list_head,
+			entry, struct qseecom_registered_listener_list, node) {
+		if (entry->svc.listener_id == listener_id) {
+			listener_present = true;
+			break;
+		}
+	}
+	if (listener_present)
+		return entry;
+	else
+		return NULL;
+}
+
+/*
+ * This function is called with the global
+ * data mutex acquired.
+ */
+static struct qseecom_registered_app_list
+	*__qseecom_check_handle_exists(int handle)
+{
+	struct qseecom_registered_app_list *entry;
+	bool app_present = false;
+
+	if (handle <= 0) {
+		dprintf(CRITICAL, "%s: Invalid Input\n", __func__);
+		return NULL;
+	}
+	dprintf(SPEW, "%s called\n", __func__);
+	list_for_every_entry(&qseecom.registered_app_list_head,
+			entry, struct qseecom_registered_app_list, node) {
+		if (entry->handle == handle) {
+			app_present = true;
+			break;
+		}
+	}
+
+	if (app_present == true)
+		return entry;
+	else
+		return NULL;
+
+}
+
+
+static struct qseecom_registered_app_list *
+	__qseecom_check_app_exists(char *app_name)
+{
+	struct qseecom_registered_app_list *entry = NULL;
+
+	dprintf(SPEW, "%s called\n", __func__);
+	list_for_every_entry(&qseecom.registered_app_list_head,
+			entry, struct qseecom_registered_app_list, node) {
+		if (!strncmp(app_name, entry->app_name, 32)) {
+			dprintf(SPEW, "%s: app_name:%s\n", __func__, app_name);
+			return entry;
+		}
+	}
+	return NULL;
+}
+
+static int qseecom_unload_app(uint32_t app_id)
+{
+	int ret = 0;
+	struct qseecom_command_scm_resp resp;
+	struct qseecom_unload_app_ireq req;
+
+	dprintf(SPEW, "%s called\n", __func__);
+	/* Populate the structure for sending scm call to load image */
+	req.qsee_cmd_id = QSEE_APP_SHUTDOWN_COMMAND;
+	req.app_id = app_id;
+
+	/* SCM_CALL to unload the app */
+	ret = qseecom_scm_call(SCM_SVC_TZSCHEDULER, 1, &req,
+			sizeof(struct qseecom_unload_app_ireq),
+			&resp, sizeof(resp));
+
+	return ret;
+}
+
+
+static int __qseecom_send_cmd(uint32_t app_id, struct qseecom_send_cmd_req *req)
+{
+	int ret = 0;
+	struct qseecom_client_send_data_ireq send_data_req;
+	struct qseecom_command_scm_resp resp;
+	void *buf = NULL;
+	uint32_t size = 0;
+
+	if (req->cmd_req_buf == NULL || req->resp_buf == NULL) {
+		dprintf(CRITICAL, "%s: cmd buffer or response buffer is null\n",
+				__func__);
+		return GENERIC_ERROR;
+	}
+	dprintf(SPEW, "%s called\n", __func__);
+
+	/* Allocate for req or rsp len whichever is higher, both req and rsp point
+	 * to the same buffer
+	 */
+	size = (req->cmd_req_len > req->resp_len) ? req->cmd_req_len : req->resp_len;
+
+	/* The req rsp buffer will be xPU protected by TZ during a TZ APP call
+	 * This will still be protected during a listener call and there is a
+	 * possibility of prefetching happening, which will cause xPU violation.
+	 * Hence using (device memory with xN set) to prevent I or D prefetching.
+	 * This is a contiguous region of 1MB used only for this, hence will not
+	 * free this.
+	 */
+	buf = (void *)RPMB_SND_RCV_BUF;
+	if (!buf) {
+		dprintf(CRITICAL, "%s: Aloc failed for app_id:%d of size:%d\n",
+				__func__, app_id, size);
+		return GENERIC_ERROR;
+	}
+
+	memscpy(buf, ROUNDUP(size, PAGE_SIZE), req->cmd_req_buf, req->cmd_req_len);
+
+	send_data_req.qsee_cmd_id = QSEE_CLIENT_SEND_DATA_COMMAND;
+	send_data_req.app_id = app_id;
+
+	/* Currently on 8994 only 32-bit phy addr is supported
+	 * Hence downcasting is okay
+	 */
+	send_data_req.req_ptr = (uint32_t)__qseecom_uvirt_to_kphys((uint32_t) buf);
+	send_data_req.req_len = req->cmd_req_len;
+	send_data_req.rsp_ptr = (uint32_t)__qseecom_uvirt_to_kphys((uint32_t) buf);
+	send_data_req.rsp_len = req->resp_len;
+
+	ret = qseecom_scm_call(SCM_SVC_TZSCHEDULER, 1,
+				(void *)&send_data_req,
+				sizeof(send_data_req), (void *)&resp, sizeof(resp));
+
+	memscpy(req->resp_buf, req->resp_len, (void *)send_data_req.rsp_ptr, send_data_req.rsp_len);
+	return ret;
+}
+
+/**
+* Start a Secure App
+*
+* @param char* app_name
+*   App name of the Secure App to be started
+*
+* @return int
+*   Success:	handle to be used for all calls to
+*   			Secure app. Always greater than zero.
+*   Failure:	Error code (negative only).
+*/
+int qseecom_start_app(char *app_name)
+{
+	int32_t ret = GENERIC_ERROR;
+	int handle = 0;
+	struct qseecom_registered_app_list *entry = NULL;
+	unsigned int app_id = 0;
+
+	if (!app_name) {
+		dprintf(CRITICAL, "%s: Input error\n", __func__);
+		goto err;
+	}
+	dprintf(SPEW, "%s called\n", __func__);
+
+
+	mutex_acquire(&qseecom.global_data_lock);
+	if ((!qseecom.qseecom_init_done)
+			|| (!qseecom.qseecom_tz_init_done)){
+		dprintf(CRITICAL, "%s qseecom_init not done\n",
+							__func__);
+		mutex_release(&qseecom.global_data_lock);
+		return ret;
+	}
+	/* Load commonlib image*/
+	if (!qseecom.cmnlib_loaded) {
+		ret = qseecom_load_commonlib_image("cmnlib");
+		if (ret) {
+			mutex_release(&qseecom.global_data_lock);
+			dprintf(CRITICAL, "%s qseecom_load_commonlib_image failed with status:%d\n",
+					__func__, ret);
+			goto err;
+		}
+		qseecom.cmnlib_loaded = 1;
+	}
+	/* Check if App already exits, if exits increase ref_cnt
+	 * and return handle, else load the app from partition,
+	 * call into TZ to load it, add to list and then return
+	 * handle.
+	 */
+
+	entry = __qseecom_check_app_exists(app_name);
+	if (!entry) {
+		mutex_release(&qseecom.global_data_lock);
+		/* load the app and get the app_id  */
+		dprintf(INFO, "%s: Loading app %s for the first time'\n",
+				__func__, app_name);
+
+		ret = __qseecom_load_app(app_name, &app_id);
+		if ((ret < 0) || (app_id ==0)) {
+			dprintf(CRITICAL, "%s: __qseecom_load_app failed with err:%d for app:%s\n",
+					__func__, ret, app_name);
+			ret = GENERIC_ERROR;
+			goto err;
+		}
+		mutex_acquire(&qseecom.global_data_lock);
+		entry = __qseecom_add_app_entry(app_name, app_id);
+		if (!entry)
+		{
+			dprintf(CRITICAL, "%s: __qseecom_add_app_entry failed\n", __func__);
+			ret = GENERIC_ERROR;
+			mutex_release(&qseecom.global_data_lock);
+			goto err;
+		}
+		qseecom.handle++;
+		entry->handle = qseecom.handle;
+		handle = entry->handle;
+		mutex_release(&qseecom.global_data_lock);
+	}
+	else {
+		entry->ref_cnt++;
+		handle = entry->handle;
+		mutex_release(&qseecom.global_data_lock);
+	}
+	return handle;
+err:
+	return ret;
+}
+
+/**
+* Shutdown a Secure App
+*
+* @param int handle
+*   Handle  of the Secure App to be shutdown
+*
+* @return int
+*   Status:
+*     0 - Success
+*     Negative value indicates failure.
+*/
+int qseecom_shutdown_app(int handle)
+{
+	int ret = GENERIC_ERROR;
+	int ref_cnt = 0;
+	struct qseecom_registered_app_list *entry = NULL;
+	struct tzdbg_log_t *log = NULL;
+	uint32_t QseeLogStart = 0;
+	uint32_t QseeLogNewStart = 0;
+
+	if (handle <= 0) {
+		dprintf(CRITICAL, "%s: Invalid Handle %d\n", __func__, handle);
+		goto err;
+	}
+	dprintf(SPEW, "%s called\n", __func__);
+	mutex_acquire(&qseecom.global_data_lock);
+	if ((!qseecom.qseecom_init_done)
+			|| (!qseecom.qseecom_tz_init_done)) {
+		dprintf(CRITICAL, "%s qseecom_init not done\n",
+							__func__);
+		mutex_release(&qseecom.global_data_lock);
+		return ret;
+	}
+	entry = __qseecom_check_handle_exists(handle);
+	if (!entry) {
+		dprintf(CRITICAL, "%s: Shutdown on an app that was never loaded handle:%d\n",
+				__func__, handle);
+		ret = GENERIC_ERROR;
+		mutex_release(&qseecom.global_data_lock);
+		goto err;
+	}
+
+	/* Decrement ref_cnt by 1, if ref_cnt is 0 after
+	 * decrementing unload the app by calling into
+	 * TZ else just return.
+	 */
+
+	if(entry->ref_cnt != 0)
+		entry->ref_cnt--;
+	ref_cnt = entry->ref_cnt;
+	mutex_release(&qseecom.global_data_lock);
+	if (ref_cnt == 0) {
+		log = (struct tzdbg_log_t *)logbuf_req.phy_addr;
+		arch_invalidate_cache_range((addr_t) logbuf_req.phy_addr, logbuf_req.len);
+		QseeLogStart = (uint32_t) log->log_pos.offset;
+
+		ret = qseecom_unload_app(entry->app_id);
+		arch_invalidate_cache_range((addr_t) logbuf_req.phy_addr, logbuf_req.len);
+		QseeLogNewStart = (uint32_t) log->log_pos.offset;
+
+		_disp_log_stats((struct tzdbg_log_t *) logbuf_req.phy_addr, QSEE_LOG_BUF_SIZE - sizeof(struct tzdbg_log_pos_t),
+				QseeLogStart, QseeLogNewStart);
+		if(ret) {
+			dprintf(CRITICAL, "%s: qseecom_unload_app failed with err:%d for handle:%d\n",
+					__func__, ret, handle);
+			goto err;
+		}
+		mutex_acquire(&qseecom.global_data_lock);
+		ret = __qseecom_remove_app_entry(entry);
+		mutex_release(&qseecom.global_data_lock);
+		if(ret) {
+			dprintf(CRITICAL, "%s: __qseecom_remove_app_entry failed with err:%d for handle:%d\n",
+					__func__, ret, handle);
+			goto err;
+		}
+	}
+	ret = 0;
+err:
+	return ret;
+}
+
+/**
+* Send cmd to a Secure App
+*
+* @param int handle
+*   Handle  of the Secure App to send the cmd
+*
+* @param void *send_buf
+*   Pointer to the App request buffer
+*
+* @param uint32_t sbuf_len
+*   Size of the request buffer
+*
+* @param void *resp_buf
+*   Pointer to the App response buffer
+*
+* @param uint32_t rbuf_len
+*   Size of the response buffer
+*
+* @return int
+*   Status:
+*     0 - Success
+*     Negative value indicates failure.
+*/
+int qseecom_send_command(int handle, void *send_buf,
+			uint32_t sbuf_len, void *resp_buf, uint32_t rbuf_len)
+{
+	int ret = GENERIC_ERROR;
+	uint32_t app_id = 0;
+	struct qseecom_registered_app_list *entry = NULL;
+	struct qseecom_send_cmd_req req = {0, 0, 0, 0};
+	struct tzdbg_log_t *log = NULL;
+	uint32_t QseeLogStart = 0;
+	uint32_t QseeLogNewStart = 0;
+
+	if (handle <= 0) {
+		dprintf(CRITICAL, "%s Handle is Invalid\n", __func__);
+		return GENERIC_ERROR;
+	}
+
+	if((!send_buf) || (!resp_buf)) {
+		dprintf(CRITICAL, "%s: Input Buffers invalid\n", __func__);
+		return GENERIC_ERROR;
+	}
+	dprintf(SPEW, "%s called\n", __func__);
+	mutex_acquire(&qseecom.global_data_lock);
+	if ((!qseecom.qseecom_init_done)
+			|| (!qseecom.qseecom_tz_init_done)) {
+		dprintf(CRITICAL, "%s qseecom_init not done\n",
+							__func__);
+		mutex_release(&qseecom.global_data_lock);
+		return ret;
+	}
+	entry = __qseecom_check_handle_exists(handle);
+	if (!entry) {
+		dprintf(CRITICAL, "%s: Send cmd on an app that was never loaded handle:%d\n",
+				__func__, handle);
+		ret = GENERIC_ERROR;
+		mutex_release(&qseecom.global_data_lock);
+		goto err;
+	}
+
+	app_id = entry->app_id;
+	mutex_release(&qseecom.global_data_lock);
+
+	req.cmd_req_len = sbuf_len;
+	req.resp_len = rbuf_len;
+	req.cmd_req_buf = send_buf;
+	req.resp_buf = resp_buf;
+
+	log = (struct tzdbg_log_t *)logbuf_req.phy_addr;
+	arch_invalidate_cache_range((addr_t) logbuf_req.phy_addr, logbuf_req.len);
+	QseeLogStart = (uint32_t) log->log_pos.offset;
+
+	ret = __qseecom_send_cmd(app_id, &req);
+	if (ret) {
+		dprintf(CRITICAL, "%s __qseecom_send_cmd failed with err:%d for handle:%d\n",
+				__func__, ret, handle);
+		goto err;
+	}
+	arch_invalidate_cache_range((addr_t) logbuf_req.phy_addr, logbuf_req.len);
+	QseeLogNewStart = (uint32_t) log->log_pos.offset;
+
+	_disp_log_stats((struct tzdbg_log_t *) logbuf_req.phy_addr, QSEE_LOG_BUF_SIZE - sizeof(struct tzdbg_log_pos_t),
+			QseeLogStart, QseeLogNewStart);
+	ret = 0;
+	dprintf(SPEW, "sending cmd_req->rsp size: %u, ptr: 0x%p\n",
+			req.resp_len, req.resp_buf);
+err:
+	return ret;
+}
+
+/**
+* Registers a Listener Service with QSEE
+*
+* @param uint32_t listnr_id
+*   Pre-defined Listener ID to be registered
+*
+* @param uint32_t sb_size
+*   Shared buffer size required for the listener
+*   service.
+*
+* @return int
+*   Status:
+*     0 - Success
+*     Negative value indicates failure.
+*/
+int qseecom_register_listener(struct qseecom_listener_services *listnr)
+{
+	int ret = GENERIC_ERROR;
+	struct qseecom_registered_listener_list *new_entry = NULL;
+	struct qseecom_register_listener_ireq req;
+	struct qseecom_command_scm_resp resp;
+
+	mutex_acquire(&qseecom.global_data_lock);
+	if (!qseecom.qseecom_init_done) {
+		dprintf(CRITICAL, "%s qseecom_init not done\n",
+							__func__);
+		mutex_release(&qseecom.global_data_lock);
+		return ret;
+	}
+	mutex_release(&qseecom.global_data_lock);
+
+	mutex_acquire(&qseecom.registered_listener_list_lock);
+
+	if ((!listnr)) {
+		dprintf(CRITICAL, "%s Invalid Input listnr\n", __func__);
+		return GENERIC_ERROR;
+	}
+
+	if ((!listnr->id) || (!listnr->sb_size) || (!listnr->service_cmd_handler)) {
+		dprintf(CRITICAL, "%s Invalid Input listnr_id:%d sb_size:%d\n",
+				__func__, listnr->id, listnr->sb_size);
+		return GENERIC_ERROR;
+	}
+	dprintf(SPEW, "%s called\n", __func__);
+	new_entry = __qseecom_check_listener_exists(listnr->id);
+	if (new_entry) {
+		dprintf(CRITICAL, "Service is not unique and is already registered\n");
+		ret = LISTENER_ALREADY_PRESENT_ERROR;
+		goto err;
+	}
+
+	new_entry = malloc(sizeof(*new_entry));
+	if (!new_entry) {
+		dprintf(CRITICAL, "%s new_entry malloc failed for size:%d\n", __func__, sizeof(*new_entry));
+		ret = GENERIC_ERROR;
+		goto err;
+	}
+	memset(new_entry, 0, sizeof(*new_entry));
+	new_entry->svc.listener_id = listnr->id;
+	new_entry->svc.sb_size = listnr->sb_size;
+	new_entry->CallbackFn = listnr->service_cmd_handler;
+
+	new_entry->svc.virt_sb_base = memalign(PAGE_SIZE, ROUNDUP(listnr->sb_size, PAGE_SIZE));
+	if (!new_entry->svc.virt_sb_base) {
+		dprintf(CRITICAL, "%s virt_sb_base malloc failed for size:%d\n", __func__, listnr->sb_size);
+		ret = GENERIC_ERROR;
+		goto err;
+	}
+	memset(new_entry->svc.virt_sb_base, 0, ROUNDUP(listnr->sb_size, PAGE_SIZE));
+	arch_clean_invalidate_cache_range((addr_t) new_entry->svc.virt_sb_base, ROUNDUP(listnr->sb_size, PAGE_SIZE));
+
+	req.qsee_cmd_id = QSEE_REGISTER_LISTENER;
+	req.listener_id = new_entry->svc.listener_id;
+	req.sb_len = new_entry->svc.sb_size;
+	/* convert to 32bit addr for tz */
+	req.sb_ptr = (uint32_t)__qseecom_uvirt_to_kphys((uint32_t) new_entry->svc.virt_sb_base);
+
+	resp.result = QSEOS_RESULT_INCOMPLETE;
+
+	ret = qseecom_scm_call(SCM_SVC_TZSCHEDULER, 1, &req,
+					sizeof(req), &resp, sizeof(resp));
+	if (ret) {
+		dprintf(CRITICAL, "qseecom_scm_call failed with err: %d\n", ret);
+		ret = GENERIC_ERROR;
+		goto err;
+	}
+	/* Add entry to Listener list */
+	list_add_tail(&qseecom.registered_listener_list_head, &new_entry->node);
+err:
+	if ((ret) &&
+			(ret != LISTENER_ALREADY_PRESENT_ERROR)) {
+		if ((new_entry) &&
+				(new_entry->svc.virt_sb_base))
+			free(new_entry->svc.virt_sb_base);
+		if (new_entry)
+			free(new_entry);
+	}
+	mutex_release(&qseecom.registered_listener_list_lock);
+	return ret;
+}
+
+/**
+* De-Registers a Listener Service with QSEE
+*
+* @param uint32_t listnr_id
+*   Pre-defined Listener ID to be de-registered
+*
+* @return int
+*   Status:
+*     0 - Success
+*     Negative value indicates failure.
+*/
+int qseecom_deregister_listener(uint32_t listnr_id)
+{
+	int ret = GENERIC_ERROR;
+	struct qseecom_registered_listener_list *new_entry = NULL;
+	struct qseecom_unregister_listener_ireq req;
+	struct qseecom_command_scm_resp resp;
+
+	mutex_acquire(&qseecom.global_data_lock);
+	if (!qseecom.qseecom_init_done) {
+		dprintf(CRITICAL, "%s qseecom_init not done\n",
+							__func__);
+		mutex_release(&qseecom.global_data_lock);
+		return ret;
+	}
+	mutex_release(&qseecom.global_data_lock);
+
+	mutex_acquire(&qseecom.registered_listener_list_lock);
+	dprintf(SPEW, "%s called\n", __func__);
+	new_entry = __qseecom_check_listener_exists(listnr_id);
+	if (!new_entry) {
+		dprintf(CRITICAL, "Service not present\n");
+		ret = GENERIC_ERROR;
+		goto err;
+	}
+
+	req.qsee_cmd_id = QSEE_DEREGISTER_LISTENER;
+	req.listener_id = listnr_id;
+	resp.result = QSEOS_RESULT_INCOMPLETE;
+
+	ret = qseecom_scm_call(SCM_SVC_TZSCHEDULER, 1, &req,
+					sizeof(req), &resp, sizeof(resp));
+	if (ret) {
+		dprintf(CRITICAL, "scm_call() failed with err: %d (lstnr id=%d)\n",
+				ret, req.listener_id);
+		ret = GENERIC_ERROR;
+		goto err;
+	}
+
+	list_delete(&new_entry->node);
+
+err:
+	if (ret == 0) {
+		if (new_entry)
+			free(new_entry);
+	}
+	mutex_release(&qseecom.registered_listener_list_lock);
+	return ret;
+}
+
+int qseecom_tz_init()
+{
+	struct qsee_apps_region_info_ireq req;
+	struct qseecom_command_scm_resp resp;
+	int rc = GENERIC_ERROR;
+	/* register log buffer scm request */
+	void *buf = NULL;
+	/* Register app region with TZ */
+	req.qsee_cmd_id = QSEE_APP_REGION_NOTIFICATION;
+	req.addr = APP_REGION_ADDR;
+	req.size = APP_REGION_SIZE;
+	dprintf(ALWAYS, "secure app region addr=0x%x size=0x%x",
+					req.addr, req.size);
+	rc = qseecom_scm_call(SCM_SVC_TZSCHEDULER, 1,
+			&req, sizeof(req),
+			&resp, sizeof(resp));
+	dprintf(ALWAYS, "TZ App region notif returned with status:%d addr:%x size:%d\n",
+			rc, req.addr, req.size);
+	if (rc)
+		goto err;
+	buf = memalign(PAGE_SIZE, ROUNDUP(QSEE_LOG_BUF_SIZE, PAGE_SIZE));
+	if (!buf) {
+		rc = GENERIC_ERROR;
+		goto err;
+	}
+	memset(buf, 0, ROUNDUP(QSEE_LOG_BUF_SIZE, PAGE_SIZE));
+	logbuf_req.qsee_cmd_id = QSEE_REGISTER_LOG_BUF_COMMAND;
+	logbuf_req.phy_addr = (uint32_t)__qseecom_uvirt_to_kphys((uint32_t) buf);
+	logbuf_req.len = QSEE_LOG_BUF_SIZE;
+
+	rc = qseecom_scm_call(SCM_SVC_TZSCHEDULER, 1,
+			&logbuf_req, sizeof(logbuf_req),
+			&resp, sizeof(resp));
+	dprintf(ALWAYS, "TZ App log region register returned with status:%d addr:%x size:%d\n",
+			rc, logbuf_req.phy_addr, logbuf_req.len);
+	if (rc)
+		goto err;
+err:
+	if (!rc) {
+		qseecom.qseecom_tz_init_done = 1;
+		dprintf(ALWAYS, "Qseecom TZ Init Done in Appsbl\n");
+	}
+	return rc;
+}
+
+int qseecom_init()
+{
+	int rc = GENERIC_ERROR;
+
+	memset (&qseecom, 0, sizeof(struct qseecom_control));
+	dprintf(SPEW, "%s called\n", __func__);
+	mutex_init(&(qseecom.global_data_lock));
+	mutex_init(&(qseecom.registered_app_list_lock));
+	mutex_init(&(qseecom.registered_listener_list_lock));
+
+	list_initialize(&(qseecom.registered_app_list_head));
+	list_initialize(&(qseecom.registered_listener_list_head));
+
+	qseecom.qseos_version = QSEOS_VERSION_14;
+	rc = 0;
+
+	if (!rc) {
+		qseecom.qseecom_init_done = 1;
+		dprintf(ALWAYS, "Qseecom Init Done in Appsbl\n");
+	}
+	return rc;
+}
+
+int qseecom_exit()
+{
+	dprintf(SPEW, "%s called\n", __func__);
+
+	if (logbuf_req.phy_addr)
+		free((void *)logbuf_req.phy_addr);
+	qseecom.qseecom_init_done = 0;
+	dprintf(ALWAYS, "Qseecom De-Init Done in Appsbl\n");
+	return 0;
+}
diff --git a/platform/msm_shared/reboot.h b/platform/msm_shared/reboot.h
new file mode 100644
index 0000000..479a841
--- /dev/null
+++ b/platform/msm_shared/reboot.h
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2015, 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 __REBOOT_H__
+#define __REBOOT_H__
+#if USE_PON_REBOOT_REG
+#define RECOVERY_MODE     0x20
+#define FASTBOOT_MODE     0x40
+#define ALARM_BOOT        0x60
+#define DM_VERITY_LOGGING   0x80
+#define DM_VERITY_ENFORCING 0xA0
+#define DM_VERITY_KEYSCLEAR 0xC0
+#else
+#define FASTBOOT_MODE     0x77665500
+#define RECOVERY_MODE     0x77665502
+#define ALARM_BOOT        0x77665503
+#define DM_VERITY_LOGGING    0x77665508
+#define DM_VERITY_ENFORCING  0x77665509
+#define DM_VERITY_KEYSCLEAR  0x7766550A
+#endif
+
+#define RTC_TRG           4
+#define PON_SOFT_RB_SPARE 0x88F
+
+#if USER_FORCE_RESET_SUPPORT
+/* Return 1 if it is a force resin triggered by user. */
+uint32_t is_user_force_reset(void);
+#endif
+
+unsigned check_reboot_mode(void);
+
+unsigned check_hard_reboot_mode(void);
+
+uint32_t check_alarm_boot(void);
+
+void reboot_device(unsigned reboot_reason);
+void shutdown_device();
+
+#endif
diff --git a/platform/msm_shared/rules.mk b/platform/msm_shared/rules.mk
old mode 100755
new mode 100644
index 42e4fcf..0d2c077
--- a/platform/msm_shared/rules.mk
+++ b/platform/msm_shared/rules.mk
@@ -16,6 +16,10 @@
 	$(LOCAL_DIR)/boot_stats.o \
 	$(LOCAL_DIR)/crc32.o
 
+ifeq ($(ENABLE_SECAPP_LOADER), 1)
+OBJS += $(LOCAL_DIR)/secapp_loader.o
+endif
+
 ifeq ($(ENABLE_SDHCI_SUPPORT),1)
 OBJS += \
 	$(LOCAL_DIR)/sdhci.o \
@@ -27,6 +31,11 @@
 	$(LOCAL_DIR)/mmc.o
 endif
 
+ifeq ($(VERIFIED_BOOT),1)
+OBJS += \
+	$(LOCAL_DIR)/boot_verifier.o
+endif
+
 ifeq ($(PLATFORM),msm8x60)
 	OBJS += $(LOCAL_DIR)/mipi_dsi.o \
 			$(LOCAL_DIR)/i2c_qup.o \
@@ -134,7 +143,8 @@
 			$(LOCAL_DIR)/dev_tree.o \
 			$(LOCAL_DIR)/gpio.o \
 			$(LOCAL_DIR)/dload_util.o \
-			$(LOCAL_DIR)/shutdown_detect.o
+			$(LOCAL_DIR)/shutdown_detect.o \
+			$(LOCAL_DIR)/qseecom_lk.o
 endif
 
 ifeq ($(PLATFORM),mpq8092)
diff --git a/platform/msm_shared/scm.c b/platform/msm_shared/scm.c
index 1ba6be8..ddf086d 100644
--- a/platform/msm_shared/scm.c
+++ b/platform/msm_shared/scm.c
@@ -143,7 +143,7 @@
 {
 	uint32_t context_id;
 	register uint32_t r0 __asm__("r0") = SCM_ATOMIC(svc, cmd, 1);
-	register uint32_t r1 __asm__("r1") = &context_id;
+	register uint32_t r1 __asm__("r1") = (uint32_t)&context_id;
 	register uint32_t r2 __asm__("r2") = arg1;
 
 	__asm__ volatile(
@@ -642,3 +642,30 @@
 
 	return canary;
 }
+static bool secure_boot_enabled = true;
+static bool wdog_debug_fuse_disabled = true;
+
+void scm_check_boot_fuses()
+{
+	uint32_t ret = 0;
+	uint32_t resp;
+
+	ret = scm_call(TZBSP_SVC_INFO, IS_SECURE_BOOT_ENABLED, NULL, 0, &resp, sizeof(resp));
+
+	/* Parse Bit 0 and Bit 2 of the response */
+	if(!ret) {
+		/* Bit 0 - SECBOOT_ENABLE_CHECK */
+		if(resp & 0x1)
+			secure_boot_enabled = false;
+		/* Bit 2 - DEBUG_DISABLE_CHECK */
+		if(resp & 0x4)
+			wdog_debug_fuse_disabled = false;
+	} else
+		dprintf(CRITICAL, "scm call to check secure boot fuses failed\n");
+}
+
+bool is_secure_boot_enable()
+{
+	scm_check_boot_fuses();
+	return secure_boot_enabled;
+}
diff --git a/platform/msm_shared/secapp_loader.c b/platform/msm_shared/secapp_loader.c
new file mode 100644
index 0000000..19613b6
--- /dev/null
+++ b/platform/msm_shared/secapp_loader.c
@@ -0,0 +1,101 @@
+/* Copyright (c) 2015, 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 <stdlib.h>
+#include <string.h>
+
+#include <secapp_loader.h>
+#include <qseecom_lk_api.h>
+
+static bool lksec_app_loaded;
+static int app_handle;
+
+int load_sec_app()
+{
+	/* start TZ app */
+	app_handle = qseecom_start_app("keymaster");
+
+	if (app_handle <= 0)
+	{
+		dprintf(CRITICAL, "Failure to load TZ app: lksecapp, error: %d\n", app_handle);
+		return -1;
+	}
+	lksec_app_loaded = true;
+	return 0;
+}
+
+int get_secapp_handle()
+{
+	dprintf(INFO, "SECAPP Handle: 0x%x\n", app_handle);
+	return app_handle;
+}
+
+int send_delete_keys_to_tz()
+{
+	int ret = 0;
+	key_op_delete_all_req_t req = {0};
+	key_op_delete_all_rsp_t rsp = {0};
+	req.cmd_id = KEYMASTER_DELETE_ALL_KEYS;
+
+	// send delete all keys command
+	ret = qseecom_send_command(app_handle, (void *)&req, sizeof(req), (void *)&rsp, sizeof(rsp));
+
+	if (ret < 0 || rsp.status < 0)
+	{
+		dprintf(CRITICAL, "Failed to send delete keys command: Error: %x\n", rsp.status);
+		return -1;
+	}
+
+	return 0;
+}
+
+int send_milestone_call_to_tz()
+{
+	int ret = 0;
+
+	km_set_milestone_req_t req = {0};
+	km_set_milestone_rsp_t rsp = {0};
+
+	req.cmd_id = KEYMASTER_MILESTONE_CALL;
+
+	/* Milestone end command */
+	ret = qseecom_send_command(app_handle, (void *)&req, sizeof(req), (void *)&rsp, sizeof(rsp));
+
+	if (ret < 0 || rsp.status < 0)
+	{
+		dprintf(CRITICAL, "Failed to send milestone end command: Error: %x\n", rsp.status);
+		return -1;
+	}
+
+	return 0;
+}
+
+bool is_sec_app_loaded()
+{
+	return lksec_app_loaded;
+}
diff --git a/platform/msm_shared/smem.c b/platform/msm_shared/smem.c
index 00a1872..dc1b141 100644
--- a/platform/msm_shared/smem.c
+++ b/platform/msm_shared/smem.c
@@ -2,6 +2,8 @@
  * Copyright (c) 2009, Google Inc.
  * All rights reserved.
  *
+ * Copyright (c) 2014, 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:
@@ -33,7 +35,7 @@
 
 #include "smem.h"
 
-static struct smem *smem = (void *)(MSM_SHARED_BASE);
+static struct smem *smem;
 
 /* buf MUST be 4byte aligned, and len MUST be a multiple of 8. */
 unsigned smem_read_alloc_entry(smem_mem_type_t type, void *buf, int len)
@@ -42,6 +44,11 @@
 	unsigned *dest = buf;
 	unsigned src;
 	unsigned size;
+	uint32_t smem_addr = 0;
+
+	smem_addr = platform_get_smem_base_addr();
+
+	smem = (struct smem *)smem_addr;
 
 	if (((len & 0x3) != 0) || (((unsigned)buf & 0x3) != 0))
 		return 1;
@@ -59,7 +66,7 @@
 	if (size != (unsigned)((len + 7) & ~0x00000007))
 		return 1;
 
-	src = MSM_SHARED_BASE + readl(&ainfo->offset);
+	src = smem_addr + readl(&ainfo->offset);
 	for (; len > 0; src += 4, len -= 4)
 		*(dest++) = readl(src);
 
@@ -74,6 +81,11 @@
 	unsigned *dest = buf;
 	unsigned src;
 	unsigned size = len;
+	uint32_t smem_addr = 0;
+
+	smem_addr = platform_get_smem_base_addr();
+
+	smem = (struct smem *)smem_addr;
 
 	if (((len & 0x3) != 0) || (((unsigned)buf & 0x3) != 0))
 		return 1;
@@ -85,7 +97,7 @@
 	if (readl(&ainfo->allocated) == 0)
 		return 1;
 
-	src = MSM_SHARED_BASE + readl(&ainfo->offset) + offset;
+	src = smem_addr + readl(&ainfo->offset) + offset;
 	for (; size > 0; src += 4, size -= 4)
 		*(dest++) = readl(src);
 
diff --git a/platform/msm_shared/smem.h b/platform/msm_shared/smem.h
index e287c8e..a5e97fb 100755
--- a/platform/msm_shared/smem.h
+++ b/platform/msm_shared/smem.h
@@ -37,6 +37,8 @@
 #define SMEM_V8_SMEM_MAX_PMIC_DEVICES   3
 #define SMEM_MAX_PMIC_DEVICES           SMEM_V8_SMEM_MAX_PMIC_DEVICES
 
+#define SMEM_TARGET_INFO_IDENTIFIER     0x49494953
+
 struct smem_proc_comm {
 	unsigned command;
 	unsigned status;
diff --git a/project/msm8226.mk b/project/msm8226.mk
index 5109297..6d15113 100644
--- a/project/msm8226.mk
+++ b/project/msm8226.mk
@@ -14,6 +14,7 @@
 
 EMMC_BOOT := 1
 ENABLE_SDHCI_SUPPORT := 1
+ENABLE_SECAPP_LOADER := 1
 
 #enable power on vibrator feature
 ENABLE_PON_VIB_SUPPORT := true
diff --git a/target/init.c b/target/init.c
index 8eeb906..80a43c0 100644
--- a/target/init.c
+++ b/target/init.c
@@ -163,3 +163,12 @@
 {
 	return 0;
 }
+/* Return Build variant */
+__WEAK bool target_build_variant_user()
+{
+#if USER_BUILD_VARIANT
+	return true;
+#else
+	return false;
+#endif
+}
diff --git a/target/msm8226/init.c b/target/msm8226/init.c
index da09390..c27e07a 100644
--- a/target/msm8226/init.c
+++ b/target/msm8226/init.c
@@ -141,11 +141,16 @@
 /* Return 1 if vol_up pressed */
 static int target_volume_up()
 {
+	static uint8_t first_time = 0;
 	uint8_t status = 0;
 
-	gpio_tlmm_config(TLMM_VOL_UP_BTN_GPIO, 0, GPIO_INPUT, GPIO_PULL_UP, GPIO_2MA, GPIO_ENABLE);
+	if (!first_time) {
+		gpio_tlmm_config(TLMM_VOL_UP_BTN_GPIO, 0, GPIO_INPUT, GPIO_PULL_UP, GPIO_2MA, GPIO_ENABLE);
 
-	thread_sleep(10);
+		 /* Wait for the gpio config to take effect - debounce time */
+		udelay(10000);
+		first_time = 1;
+	}
 
 	/* Get status of GPIO */
 	status = gpio_status(TLMM_VOL_UP_BTN_GPIO);
@@ -243,6 +248,7 @@
 
 void target_init(void)
 {
+	int ret = 0;
 	dprintf(INFO, "target_init()\n");
 
 	spmi_init(PMIC_ARB_CHANNEL_NUM, PMIC_ARB_OWNER_ID);
@@ -250,14 +256,43 @@
 	target_keystatus();
 
 	target_sdc_init();
+	clock_ce_enable(SSD_CE_INSTANCE);
+	if (target_use_signed_kernel())
+		target_crypto_init_params();
 
+#if VERIFIED_BOOT
+	/* Initialize Qseecom */
+	ret = qseecom_init();
+
+	if (ret < 0)
+	{
+		dprintf(CRITICAL, "Failed to initialize qseecom, error: %d\n", ret);
+		ASSERT(0);
+	}
+
+	/* Start Qseecom */
+	ret = qseecom_tz_init();
+
+	if (ret < 0)
+	{
+		dprintf(CRITICAL, "Failed to start qseecom, error: %d\n", ret);
+		ASSERT(0);
+	}
+
+	/*
+	 * Load the sec app for first time
+	 */
+	if (load_sec_app() < 0)
+	{
+		dprintf(CRITICAL, "Failed to load App for verified\n");
+		ASSERT(0);
+	}
+#endif
 	shutdown_detect();
 
 	/* turn on vibrator to indicate that phone is booting up to end user */
 	vib_timed_turn_on(VIBRATE_TIME);
 
-	if (target_use_signed_kernel())
-		target_crypto_init_params();
 }
 
 /* Do any target specific intialization needed before entering fastboot mode */
@@ -418,14 +453,20 @@
 
 	mmc_put_card_to_sleep(dev);
 
+	clock_ce_disable(SSD_CE_INSTANCE);
 	if (crypto_initialized())
 		crypto_eng_cleanup();
 
-	if (target_is_ssd_enabled())
-		clock_ce_disable(SSD_CE_INSTANCE);
-
-	/* Disable HC mode before jumping to kernel */
-	sdhci_mode_disable(&dev->host);
+#if VERIFIED_BOOT
+	if (is_sec_app_loaded())
+	{
+		if (send_milestone_call_to_tz() < 0)
+		{
+			dprintf(CRITICAL, "Failed to send milestone call\n");
+			ASSERT(0);
+		}
+	}
+#endif
 }
 
 void target_usb_init(void)
diff --git a/target/msm8226/rules.mk b/target/msm8226/rules.mk
index d31f2bc..da6eecb 100755
--- a/target/msm8226/rules.mk
+++ b/target/msm8226/rules.mk
@@ -6,14 +6,14 @@
 PLATFORM := msm8226
 
 MEMBASE := 0x0FF00000 # SDRAM
-MEMSIZE := 0x00100000 # 1MB
+MEMSIZE := 0x00200000 # 2MB
 
 BASE_ADDR        := 0x00000
 
 TAGS_ADDR        := BASE_ADDR+0x00000100
 KERNEL_ADDR      := BASE_ADDR+0x00008000
 RAMDISK_ADDR     := BASE_ADDR+0x01000000
-SCRATCH_ADDR     := 0x10000000
+SCRATCH_ADDR     := 0x10200000
 
 DEFINES += DISPLAY_SPLASH_SCREEN=1
 DEFINES += DISPLAY_TYPE_MIPI=1