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);