app: aboot: Implement RMA solution for FRP issue

If the device is locked RMA procedure cannot update the images on
the device in fastboot. Add a mechanism for the device to be unlocked
for RMA.

Change-Id: I5fa45b48160e52716e6834ab79bb9d8d89562498
diff --git a/app/aboot/aboot.c b/app/aboot/aboot.c
index 531ff4e..0d99283 100644
--- a/app/aboot/aboot.c
+++ b/app/aboot/aboot.c
@@ -102,6 +102,7 @@
 void write_device_info_mmc(device_info *dev);
 void write_device_info_flash(device_info *dev);
 static int aboot_save_boot_hash_mmc(uint32_t image_addr, uint32_t image_size);
+static int aboot_frp_unlock(char *pname, void *data, unsigned sz);
 
 /* fastboot command function pointer */
 typedef void (*fastboot_cmd_fn) (const char *, void *, unsigned);
@@ -2252,6 +2253,14 @@
 		cmd_erase_nand(arg, data, sz);
 }
 
+static uint32_t aboot_get_secret_key()
+{
+	/* 0 is invalid secret key, update this implementation to return
+	 * device specific unique secret key
+	 */
+	return 0;
+}
+
 void cmd_flash_mmc_img(const char *arg, void *data, unsigned sz)
 {
 	unsigned long long ptn = 0;
@@ -2275,6 +2284,19 @@
 
 	if (pname)
 	{
+		if (!strncmp(pname, "frp-unlock", strlen("frp-unlock")))
+		{
+			if (!aboot_frp_unlock(pname, data, sz))
+			{
+				fastboot_info("FRP unlock successful");
+				fastboot_okay("");
+			}
+			else
+				fastboot_fail("Secret key is invalid, please update the bootloader with secret key");
+
+			return;
+		}
+
 		if (!strcmp(pname, "partition"))
 		{
 			dprintf(INFO, "Attempt to write partition image.\n");
@@ -2905,6 +2927,26 @@
 	fastboot_okay("");
 }
 
+static int aboot_frp_unlock(char *pname, void *data, unsigned sz)
+{
+	int ret = 1;
+	uint32_t secret_key;
+	char seckey_buffer[MAX_RSP_SIZE];
+
+	secret_key = aboot_get_secret_key();
+	if (secret_key)
+	{
+		snprintf((char *) seckey_buffer, MAX_RSP_SIZE, "%x", secret_key);
+		if (!memcmp((void *)data, (void *)seckey_buffer, sz))
+		{
+			is_allow_unlock = true;
+			write_allow_oem_unlock(is_allow_unlock);
+			ret = 0;
+		}
+	}
+	return ret;
+}
+
 void cmd_oem_lock(const char *arg, void *data, unsigned sz)
 {
 	struct recovery_message msg;