Merge 0b15c029b76ae8c9164a5360156e4119f97b4c95 on remote branch

Change-Id: I9313cf8bd456f3560d33943f62bf8445e2dd1e7a
diff --git a/include/km_main.h b/include/km_main.h
index 946683e..544dc55 100644
--- a/include/km_main.h
+++ b/include/km_main.h
@@ -71,10 +71,15 @@
     KEYMASTER_WRITE_LK_DEVICE_STATE			= (KEYMASTER_UTILS_CMD_ID + 3UL),
     KEYMASTER_MILESTONE_CALL				= (KEYMASTER_UTILS_CMD_ID + 4UL),
     KEYMASTER_SECURE_WRITE_PROTECT			= (KEYMASTER_UTILS_CMD_ID + 6UL),
+    KEYMASTER_SET_VBH					= (KEYMASTER_UTILS_CMD_ID + 17UL),
 
     KEYMASTER_LAST_CMD_ENTRY				= (int)0xFFFFFFFFULL
 } keymaster_cmd_t;
 
+typedef enum {
+	KM_ERROR_INVALID_TAG = -40,
+} keymaster_error_t;
+
 
 /*
  * Utils Api struct
@@ -263,4 +268,15 @@
 	int status;
 }__attribute__((packed)) km_set_boot_state_rsp_t;
 
+typedef struct
+{
+	uint32_t cmd_id;
+	char vbh[32];
+} __attribute__ ((packed)) km_set_vbh_req_t;
+
+typedef struct
+{
+	int status;
+} __attribute__ ((packed)) km_set_vbh_rsp_t;
+
 #endif /* KM_MAIN_H */
diff --git a/platform/msm_shared/avb/VerifiedBoot.c b/platform/msm_shared/avb/VerifiedBoot.c
index d76b209..92a2c15 100644
--- a/platform/msm_shared/avb/VerifiedBoot.c
+++ b/platform/msm_shared/avb/VerifiedBoot.c
@@ -39,6 +39,7 @@
 #include "verifiedboot.h"
 #include <err.h>
 #include <target.h>
+#include <libavb/avb_sha.h>
 
 #ifndef DTB_PAD_SIZE
 #define DTB_PAD_SIZE            2048
@@ -358,6 +359,18 @@
 	}
 }
 
+static VOID ComputeVbMetaDigest (AvbSlotVerifyData* SlotData, CHAR8* Digest) {
+	size_t Index;
+	AvbSHA256Ctx Ctx;
+	avb_sha256_init (&Ctx);
+	for (Index = 0; Index < SlotData->num_vbmeta_images; Index++) {
+		avb_sha256_update (&Ctx,
+			SlotData->vbmeta_images[Index].vbmeta_data,
+			SlotData->vbmeta_images[Index].vbmeta_size);
+	}
+	avb_memcpy (Digest, avb_sha256_final(&Ctx), AVB_SHA256_DIGEST_SIZE);
+}
+
 static EFI_STATUS load_image_and_authVB2(bootinfo *Info)
 {
 	EFI_STATUS Status = EFI_SUCCESS;
@@ -383,6 +396,7 @@
            AVB_SLOT_VERIFY_FLAGS_NONE;
 	AvbHashtreeErrorMode VerityFlags = AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE;
 	device_info DevInfo_vb;
+	CHAR8 Digest[AVB_SHA256_DIGEST_SIZE] = {0};
 
 	HeaderVersion = Info->header_version;
 	Info->boot_state = RED;
@@ -551,6 +565,9 @@
 	set_os_version(ADD_SALT_BUFF_OFFSET(Info->images[0].image_buffer));
 	if(!send_rot_command((uint32_t)DevInfo_vb.is_unlocked))
 		return EFI_LOAD_ERROR;
+
+	ComputeVbMetaDigest(SlotData, (CHAR8 *)&Digest);
+	GUARD_OUT(set_verified_boot_hash((const CHAR8 *)&Digest, sizeof(Digest)));
 	dprintf(INFO, "VB2: Authenticate complete! boot state is: %s\n",
 	       VbSn[Info->boot_state].name);
 
diff --git a/platform/msm_shared/boot_verifier.c b/platform/msm_shared/boot_verifier.c
index b81f3f2..4bc0995 100644
--- a/platform/msm_shared/boot_verifier.c
+++ b/platform/msm_shared/boot_verifier.c
@@ -799,3 +799,29 @@
 	return;
 }
 #endif
+
+int set_verified_boot_hash (const char *vbh, size_t vbh_size)
+{
+	int ret = 0;
+	km_set_vbh_req_t vbh_req = {0};
+	km_set_vbh_rsp_t vbh_rsp = {0};
+	int app_handle = get_secapp_handle();
+
+	if (!vbh || vbh_size != sizeof (vbh_req.vbh)) {
+		dprintf(CRITICAL, "Vbh input params invalid\n");
+		ASSERT(0);
+	}
+	vbh_req.cmd_id = KEYMASTER_SET_VBH;
+	memscpy (vbh_req.vbh, sizeof(vbh_req.vbh), vbh, vbh_size);
+	ret = qseecom_send_command (app_handle, (void *)&vbh_req, sizeof (vbh_req), (void *)&vbh_rsp, sizeof (vbh_rsp));
+
+	if (ret != 0 || vbh_rsp.status != 0) {
+		dprintf(CRITICAL, "QSEEcom command for setting vbh returned error: %d\n",vbh_rsp.status);
+		if (ret == 0 && vbh_rsp.status == KM_ERROR_INVALID_TAG) {
+			dprintf(INFO, "VBH not supported in keymaster, continue boot\n");
+			return ret;
+		}
+		ASSERT(0);
+	}
+	return ret;
+}
diff --git a/platform/msm_shared/include/boot_verifier.h b/platform/msm_shared/include/boot_verifier.h
index 9bf34b6..5525a7a 100644
--- a/platform/msm_shared/include/boot_verifier.h
+++ b/platform/msm_shared/include/boot_verifier.h
@@ -183,4 +183,6 @@
 		unsigned int image_size, unsigned char *signature_ptr, RSA *rsa);
 KEYSTORE *boot_gerity_get_oem_keystore();
 uint32_t read_der_message_length(unsigned char* input, unsigned sz);
+/* Function to set verified boot hash in keymaster */
+int set_verified_boot_hash (const char *vbh, size_t vbh_size);
 #endif