openssl/lk: Enable signed boot img check

This uses openssl to check the boot image prior
to jumping to kernel to see if it is a signed
kernel image.

Change-Id: I92927fd9317a0f701dab395cc6d39929c64340c1
diff --git a/app/aboot/aboot.c b/app/aboot/aboot.c
index b6c60f2..312b278 100644
--- a/app/aboot/aboot.c
+++ b/app/aboot/aboot.c
@@ -47,7 +47,9 @@
 #include <mmc.h>
 #include <partition_parser.h>
 #include <platform.h>
+#include <crypto_hash.h>
 
+#include "image_verify.h"
 #include "recovery.h"
 #include "bootimg.h"
 #include "fastboot.h"
@@ -72,12 +74,16 @@
 static const char *emmc_cmdline = " androidboot.emmc=true";
 static const char *usb_sn_cmdline = " androidboot.serialno=";
 static const char *battchg_pause = " androidboot.battchg_pause=true";
+static const char *auth_kernel = " androidboot.authorized_kernel=true";
 
 static const char *baseband_apq     = " androidboot.baseband=apq";
 static const char *baseband_msm     = " androidboot.baseband=msm";
 static const char *baseband_csfb    = " androidboot.baseband=csfb";
 static const char *baseband_svlte2a = " androidboot.baseband=svlte2a";
 
+/* Assuming unauthorized kernel image by default */
+static int auth_kernel_img = 0;
+
 static struct udc_device surf_udc_device = {
 	.vendor_id	= 0x18d1,
 	.product_id	= 0xD00D,
@@ -175,6 +181,10 @@
 		cmdline_len += strlen(battchg_pause);
 	}
 
+	if(target_use_signed_kernel() && auth_kernel_img) {
+		cmdline_len += strlen(auth_kernel);
+	}
+
 	/* Determine correct androidboot.baseband to use */
 	switch(target_baseband())
 	{
@@ -230,6 +240,12 @@
 			while ((*dst++ = *src++));
 		}
 
+		if(target_use_signed_kernel() && auth_kernel_img) {
+			src = auth_kernel;
+			if (have_cmdline) --dst;
+			while ((*dst++ = *src++));
+		}
+
 		switch(target_baseband())
 		{
 			case BASEBAND_APQ:
@@ -293,6 +309,11 @@
 	const char *cmdline;
 	int index = INVALID_PTN;
 
+	unsigned char *image_addr = 0;
+	unsigned kernel_actual;
+	unsigned ramdisk_actual;
+	unsigned imagesize_actual;
+
 	uhdr = (struct boot_img_hdr *)EMMC_BOOT_IMG_HEADER_ADDR;
 	if (!memcmp(uhdr->magic, BOOT_MAGIC, BOOT_MAGIC_SIZE)) {
 		dprintf(INFO, "Unified boot method!\n");
@@ -330,24 +351,62 @@
 		page_size = hdr->page_size;
 		page_mask = page_size - 1;
 	}
-	offset += page_size;
 
-	n = ROUND_TO_PAGE(hdr->kernel_size, page_mask);
-	if (mmc_read(ptn + offset, (void *)hdr->kernel_addr, n)) {
-		dprintf(CRITICAL, "ERROR: Cannot read kernel image\n");
-                return -1;
-	}
-	offset += n;
-
-	n = ROUND_TO_PAGE(hdr->ramdisk_size, page_mask);
-	if(n != 0)
+	/* Authenticate Kernel */
+	if(target_use_signed_kernel())
 	{
-		if (mmc_read(ptn + offset, (void *)hdr->ramdisk_addr, n)) {
-			dprintf(CRITICAL, "ERROR: Cannot read ramdisk image\n");
-			return -1;
+		image_addr = (unsigned char *)target_get_scratch_address();
+		kernel_actual = ROUND_TO_PAGE(hdr->kernel_size, page_mask);
+		ramdisk_actual = ROUND_TO_PAGE(hdr->ramdisk_size, page_mask);
+		imagesize_actual = (page_size + kernel_actual + ramdisk_actual);
+
+		offset = 0;
+		/* Read image without signature */
+		if (mmc_read(ptn + offset, (void *)image_addr, imagesize_actual))
+		{
+			dprintf(CRITICAL, "ERROR: Cannot read boot image\n");
+				return -1;
 		}
+
+		offset = imagesize_actual;
+		/* Read signature */
+		if(mmc_read(ptn + offset, (void *)(image_addr + offset), page_size))
+		{
+			dprintf(CRITICAL, "ERROR: Cannot read boot image signature\n");
+		}
+		else
+		{
+			auth_kernel_img = image_verify((unsigned char *)image_addr,
+					(unsigned char *)(image_addr + imagesize_actual),
+					imagesize_actual,
+					CRYPTO_AUTH_ALG_SHA256);
+		}
+
+		/* Move kernel and ramdisk to correct address */
+		memmove((void*) hdr->kernel_addr, (char *)(image_addr + page_size), hdr->kernel_size);
+		memmove((void*) hdr->ramdisk_addr, (char *)(image_addr + page_size + kernel_actual), hdr->ramdisk_size);
 	}
-	offset += n;
+	else
+	{
+		offset += page_size;
+
+		n = ROUND_TO_PAGE(hdr->kernel_size, page_mask);
+		if (mmc_read(ptn + offset, (void *)hdr->kernel_addr, n)) {
+			dprintf(CRITICAL, "ERROR: Cannot read kernel image\n");
+					return -1;
+		}
+		offset += n;
+
+		n = ROUND_TO_PAGE(hdr->ramdisk_size, page_mask);
+		if(n != 0)
+		{
+			if (mmc_read(ptn + offset, (void *)hdr->ramdisk_addr, n)) {
+				dprintf(CRITICAL, "ERROR: Cannot read ramdisk image\n");
+				return -1;
+			}
+		}
+		offset += n;
+	}
 
 unified_boot:
 	dprintf(INFO, "\nkernel  @ %x (%d bytes)\n", hdr->kernel_addr,
@@ -379,6 +438,11 @@
 	unsigned offset = 0;
 	const char *cmdline;
 
+	unsigned char *image_addr = 0;
+	unsigned kernel_actual;
+	unsigned ramdisk_actual;
+	unsigned imagesize_actual;
+
 	if (target_is_emmc_boot()) {
 		hdr = (struct boot_img_hdr *)EMMC_BOOT_IMG_HEADER_ADDR;
 		if (memcmp(hdr->magic, BOOT_MAGIC, BOOT_MAGIC_SIZE)) {
@@ -427,20 +491,58 @@
 		return -1;
 	}
 
-	n = ROUND_TO_PAGE(hdr->kernel_size, page_mask);
-	if (flash_read(ptn, offset, (void *)hdr->kernel_addr, n)) {
-		dprintf(CRITICAL, "ERROR: Cannot read kernel image\n");
-		return -1;
-	}
-	offset += n;
+	/* Authenticate Kernel */
+	if(target_use_signed_kernel())
+	{
+		image_addr = (unsigned char *)target_get_scratch_address();
+		kernel_actual = ROUND_TO_PAGE(hdr->kernel_size, page_mask);
+		ramdisk_actual = ROUND_TO_PAGE(hdr->ramdisk_size, page_mask);
+		imagesize_actual = (page_size + kernel_actual + ramdisk_actual);
 
-	n = ROUND_TO_PAGE(hdr->ramdisk_size, page_mask);
-	if (flash_read(ptn, offset, (void *)hdr->ramdisk_addr, n)) {
-		dprintf(CRITICAL, "ERROR: Cannot read ramdisk image\n");
-		return -1;
-	}
-	offset += n;
+		offset = 0;
+		/* Read image without signature */
+		if (flash_read(ptn, offset, (void *)image_addr, imagesize_actual))
+		{
+			dprintf(CRITICAL, "ERROR: Cannot read boot image\n");
+				return -1;
+		}
 
+		offset = imagesize_actual;
+		/* Read signature */
+		if (flash_read(ptn, offset, (void *)(image_addr + offset), page_size))
+		{
+			dprintf(CRITICAL, "ERROR: Cannot read boot image signature\n");
+		}
+		else
+		{
+
+			/* Verify signature */
+			auth_kernel_img = image_verify((unsigned char *)image_addr,
+						(unsigned char *)(image_addr + imagesize_actual),
+						imagesize_actual,
+						CRYPTO_AUTH_ALG_SHA256);
+		}
+
+		/* Move kernel and ramdisk to correct address */
+		memmove((void*) hdr->kernel_addr, (char *)(image_addr + page_size), hdr->kernel_size);
+		memmove((void*) hdr->ramdisk_addr, (char *)(image_addr + page_size + kernel_actual), hdr->ramdisk_size);
+	}
+	else
+	{
+		n = ROUND_TO_PAGE(hdr->kernel_size, page_mask);
+		if (flash_read(ptn, offset, (void *)hdr->kernel_addr, n)) {
+			dprintf(CRITICAL, "ERROR: Cannot read kernel image\n");
+			return -1;
+		}
+		offset += n;
+
+		n = ROUND_TO_PAGE(hdr->ramdisk_size, page_mask);
+		if (flash_read(ptn, offset, (void *)hdr->ramdisk_addr, n)) {
+			dprintf(CRITICAL, "ERROR: Cannot read ramdisk image\n");
+			return -1;
+		}
+		offset += n;
+	}
 continue_boot:
 	dprintf(INFO, "\nkernel  @ %x (%d bytes)\n", hdr->kernel_addr,
 		hdr->kernel_size);