platform: msm_shared: Updates to verified boot

 * Verify boot.img with oem keystore (green state)
 * If verification fails with oem keystore use public key
   from certificate embedded in boot.img for verification
   (yellow state)
 * Boot with failed verification state (red state) if green
   and yellow states fail
 * Remove user keystore and verify flash allowed functions
 * Do not assert when verified boot is enabled

Change-Id: Ic740696e89b62321eb59cb9f4d6730f472047c72
diff --git a/app/aboot/aboot.c b/app/aboot/aboot.c
index 88ba62d..8ac7fc7 100644
--- a/app/aboot/aboot.c
+++ b/app/aboot/aboot.c
@@ -793,24 +793,23 @@
 #endif
 
 #if VERIFIED_BOOT
-	if(boot_verify_get_state() == RED)
+	switch(boot_verify_get_state())
 	{
-		if(!boot_into_recovery)
-		{
-			dprintf(CRITICAL,
-					"Device verification failed. Rebooting into recovery.\n");
-			mdelay(1000);
-			reboot_device(RECOVERY_MODE);
-		}
-		else
-		{
-			dprintf(CRITICAL,
-					"Recovery image verification failed. Asserting..\n");
-			ASSERT(0);
-		}
+		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);
@@ -822,7 +821,7 @@
 		ASSERT(0);
 	#endif
 	}
-
+#endif
 }
 
 static bool check_format_bit()
@@ -1060,6 +1059,15 @@
 		aboot_save_boot_hash_mmc((uint32_t) image_addr, imagesize_actual);
 		#endif /* TZ_SAVE_KERNEL_HASH */
 
+#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);
+	}
+#endif
+
 #ifdef MDTP_SUPPORT
 		{
 			/* Verify MDTP lock.
@@ -2804,10 +2812,16 @@
 
 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("");
 }
diff --git a/platform/msm_shared/boot_verifier.c b/platform/msm_shared/boot_verifier.c
index 36c72c9..d399afc 100644
--- a/platform/msm_shared/boot_verifier.c
+++ b/platform/msm_shared/boot_verifier.c
@@ -1,28 +1,30 @@
 /*
- * Copyright (c) 2014-2015 The Linux Foundation. All rights reserved.
+ * 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:
+ * 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.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE 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.
+ *  * 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>
@@ -39,19 +41,15 @@
 #include <string.h>
 #include <openssl/err.h>
 #include <platform.h>
+#include <qseecom_lk_api.h>
+#include <secapp_loader.h>
+#include <target.h>
 
 static KEYSTORE *oem_keystore;
 static KEYSTORE *user_keystore;
 static uint32_t dev_boot_state = RED;
-BUF_DMA_ALIGN(keystore_buf, 4096);
 char KEYSTORE_PTN_NAME[] = "keystore";
-
-static const char *VERIFIED_FLASH_ALLOWED_PTN[] = {
-	"aboot",
-	"boot",
-	"recovery",
-	"system",
-	NULL };
+RSA *rsa_from_cert = NULL;
 
 ASN1_SEQUENCE(AUTH_ATTR) ={
 	ASN1_SIMPLE(AUTH_ATTR, target, ASN1_PRINTABLESTRING),
@@ -221,6 +219,7 @@
 	int shift_bytes;
 	RSA *rsa = NULL;
 	bool keystore_verification = false;
+	EVP_PKEY* key = NULL;
 
 	if(!strcmp(pname, "keystore"))
 		keystore_verification = true;
@@ -259,23 +258,68 @@
 
 	/* 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)
-		rsa = ks->mykeybag->mykey->key_material;
-
-	ret = boot_verify_compare_sha256(img_addr, img_size,
-			(unsigned char*)sig->sig->data, rsa);
-
-	if(!ret)
 	{
-		dprintf(CRITICAL,
-				"boot_verifier: Image verification failed.\n");
+		// 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;
 }
 
@@ -334,62 +378,11 @@
 	}
 }
 
-static int read_user_keystore_ptn()
-{
-	int index = INVALID_PTN;
-	unsigned long long ptn = 0;
-
-	index = partition_get_index(KEYSTORE_PTN_NAME);
-	ptn = partition_get_offset(index);
-	if(ptn == 0) {
-		dprintf(CRITICAL, "boot_verifier: No keystore partition found\n");
-		return -1;
-	}
-
-	if (mmc_read(ptn, (unsigned int *) keystore_buf, mmc_page_size())) {
-		dprintf(CRITICAL, "boot_verifier: Cannot read user keystore\n");
-		return -1;
-	}
-	return 0;
-}
-
-static void read_user_keystore(unsigned char *user_addr)
-{
-	unsigned char *input = user_addr;
-	KEYSTORE *ks = NULL;
-	uint32_t len = read_der_message_length(input);
-	if(!len)
-	{
-		dprintf(CRITICAL, "boot_verifier: user keystore length is invalid.\n");
-		return;
-	}
-
-	ks = d2i_KEYSTORE(NULL, (const unsigned char **)&input, len);
-	if(ks != NULL)
-	{
-		if(verify_keystore(user_addr, ks) == false)
-		{
-			dprintf(CRITICAL, "boot_verifier: Keystore verification failed!\n");
-			boot_verify_send_event(KEYSTORE_VERIFICATION_FAIL);
-		}
-		else
-			dprintf(CRITICAL, "boot_verifier: Keystore verification success!\n");
-		user_keystore = ks;
-	}
-	else
-	{
-		user_keystore = oem_keystore;
-	}
-}
-
 uint32_t boot_verify_keystore_init()
 {
 	/* Read OEM Keystore */
 	read_oem_keystore();
 
-	/* Read User Keystore */
-	if(!read_user_keystore_ptn())
-		read_user_keystore((unsigned char *)keystore_buf);
 	return dev_boot_state;
 }
 
@@ -409,7 +402,7 @@
 
 	if(!sig_len)
 	{
-		dprintf(CRITICAL, "boot_verifier: Error while reading singature length.\n");
+		dprintf(CRITICAL, "boot_verifier: Error while reading signature length.\n");
 		goto verify_image_error;
 	}
 
@@ -425,8 +418,6 @@
 verify_image_error:
 	if(sig != NULL)
 		VERIFIED_BOOT_SIG_free(sig);
-	if(!ret)
-		boot_verify_send_event(BOOT_VERIFICATION_FAIL);
 	return ret;
 }
 
@@ -437,11 +428,14 @@
 		case BOOT_INIT:
 			dev_boot_state = GREEN;
 			break;
-		case KEYSTORE_VERIFICATION_FAIL:
+		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 BOOT_VERIFICATION_FAIL:
+		case BOOTIMG_VERIFICATION_FAIL:
 			if(dev_boot_state == GREEN || dev_boot_state == YELLOW)
 				dev_boot_state = RED;
 			break;
@@ -516,8 +510,3 @@
 
 	return false;
 }
-
-bool boot_verify_flash_allowed(const char * entry)
-{
-	return check_list(VERIFIED_FLASH_ALLOWED_PTN, entry);
-}
diff --git a/platform/msm_shared/include/boot_verifier.h b/platform/msm_shared/include/boot_verifier.h
index efe0c1b..55f0d0a 100644
--- a/platform/msm_shared/include/boot_verifier.h
+++ b/platform/msm_shared/include/boot_verifier.h
@@ -1,29 +1,32 @@
 /*
- * Copyright (c) 2014-2015 The Linux Foundation. All rights reserved.
+ * 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:
+ * 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.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE 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.
+ *  * 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
 
@@ -34,6 +37,7 @@
  *    AndroidVerifiedBootSignature DEFINITIONS ::=
  *    BEGIN
  *        FormatVersion ::= INTEGER
+ *        Certificate ::= Certificate
  *        AlgorithmIdentifier ::=  SEQUENCE {
  *            algorithm OBJECT IDENTIFIER,
  *            parameters ANY DEFINED BY algorithm OPTIONAL
@@ -138,8 +142,9 @@
 {
 	BOOT_INIT,
 	DEV_UNLOCK,
-	KEYSTORE_VERIFICATION_FAIL,
-	BOOT_VERIFICATION_FAIL,
+	BOOTIMG_EMBEDDED_CERT_VERIFICATION_PASS,
+	BOOTIMG_KEYSTORE_VERIFICATION_PASS,
+	BOOTIMG_VERIFICATION_FAIL,
 	USER_DENIES,
 };