platform: msm_shared: Add verified boot hash support

Compute the digest over all vbmeta's
present on device and provide the digest
to keymaster. This digest is provided as
part of the keymaster attestation certificate.

Change-Id: I183793a6aa229441ef2eeced42e455d2c7a6de69
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