ipq: boot: Signed Rootfs authentication

Rootfs's certificate is appended in kernel image. Read from
there, pack it with rootfs image and validate rootfs.

Change-Id: I2b40f88e23225c17362a02f6c7868edda2a8e8bd
Signed-off-by: Praveenkumar I <ipkumar@codeaurora.org>
This commit is contained in:
Praveenkumar I 2018-07-25 16:11:10 +05:30
parent af7feada2e
commit eedc337301
4 changed files with 112 additions and 1 deletions

View file

@ -34,6 +34,8 @@
#define DLOAD_MAGIC_COOKIE 0x10
#define MAX_TFTP_SIZE 0x40000000
#define SEC_AUTH_SW_ID 0x17
#define ROOTFS_IMAGE_TYPE 0x13
static int debug = 0;
static char mtdids[256];
@ -421,6 +423,99 @@ __weak int switch_ce_channel_buf(unsigned int channel_id)
return 0;
}
#ifdef CONFIG_IPQ_ROOTFS_AUTH
static int authenticate_rootfs(unsigned int kernel_addr)
{
unsigned int kernel_imgsize;
unsigned int request;
int ret;
mbn_header_t *mbn_ptr;
char runcmd[256];
struct {
unsigned long type;
unsigned long size;
unsigned long addr;
} rootfs_img_info;
#ifdef CONFIG_QCA_MMC
block_dev_desc_t *blk_dev;
disk_partition_t disk_info;
unsigned int active_part = 0;
#endif
request = CONFIG_ROOTFS_LOAD_ADDR;
rootfs_img_info.addr = CONFIG_ROOTFS_LOAD_ADDR;
rootfs_img_info.type = SEC_AUTH_SW_ID;
request += sizeof(mbn_header_t);/* space for mbn header */
/* get , kernel size = header + kernel + certificate */
mbn_ptr = (mbn_header_t *) kernel_addr;
kernel_imgsize = mbn_ptr->image_size + sizeof(mbn_header_t);
/* get rootfs MBN header and validate it */
mbn_ptr = (mbn_header_t *)((uint32_t)mbn_ptr + kernel_imgsize);
if (mbn_ptr->image_type != ROOTFS_IMAGE_TYPE &&
(mbn_ptr->code_size + mbn_ptr->signature_size +
mbn_ptr->cert_chain_size != mbn_ptr->image_size))
return CMD_RET_FAILURE;
/* pack, MBN header + rootfs + certificate */
/* copy rootfs from the boot device */
if (ipq_fs_on_nand) {
snprintf(runcmd, sizeof(runcmd),
"ubi read 0x%x ubi_rootfs &&", request);
#ifdef CONFIG_QCA_MMC
} else if (sfi->flash_type == SMEM_BOOT_MMC_FLASH ||
((sfi->flash_type == SMEM_BOOT_SPI_FLASH) &&
(sfi->rootfs.offset == 0xBAD0FF5E))) {
blk_dev = mmc_get_dev(host->dev_num);
if (smem_bootconfig_info() == 0) {
active_part = get_rootfs_active_partition();
if (active_part) {
ret = get_partition_info_efi_by_name(blk_dev,
"rootfs_1", &disk_info);
} else {
ret = get_partition_info_efi_by_name(blk_dev,
"rootfs", &disk_info);
}
}else {
ret = get_partition_info_efi_by_name(blk_dev,
"rootfs", &disk_info);
}
if(ret == 0)
snprintf(runcmd, sizeof(runcmd), "mmc read 0x%x 0x%X 0x%X &&",
request, (uint)disk_info.start,
(uint)(mbn_ptr->code_size / disk_info.blksz) + 1);
else
return CMD_RET_FAILURE;
#endif
} else {
snprintf(runcmd, sizeof(runcmd),
"sf read 0x%x 0x%x 0x%x && ",
request, (uint)sfi->rootfs.offset, (uint)sfi->rootfs.size);
}
if (debug)
printf("runcmd: %s\n", runcmd);
if (run_command(runcmd, 0) != CMD_RET_SUCCESS)
return CMD_RET_FAILURE;
/* copy rootfs MBN header */
memcpy((void *)CONFIG_ROOTFS_LOAD_ADDR, (void *)kernel_addr + kernel_imgsize,
sizeof(mbn_header_t));
/* copy rootfs certificate */
memcpy((void *)request + mbn_ptr->code_size,
(void *)kernel_addr + kernel_imgsize + sizeof(mbn_header_t),
mbn_ptr->signature_size + mbn_ptr->cert_chain_size);
/* copy rootfs size */
rootfs_img_info.size = sizeof(mbn_header_t) + mbn_ptr->image_size;
ret = qca_scm_secure_authenticate(&rootfs_img_info, sizeof(rootfs_img_info));
if (ret)
return CMD_RET_FAILURE;
return CMD_RET_SUCCESS;
}
#endif
static int do_boot_signedimg(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
{
char runcmd[256];
@ -553,7 +648,14 @@ static int do_boot_signedimg(cmd_tbl_t *cmdtp, int flag, int argc, char *const a
printf("Kernel image authentication failed \n");
BUG();
}
#ifdef CONFIG_IPQ_ROOTFS_AUTH
/* Rootfs's header and certificate at end of kernel image, copy from
* there and pack with rootfs image and authenticate rootfs */
if (authenticate_rootfs(CONFIG_SYS_LOAD_ADDR) != CMD_RET_SUCCESS) {
printf("Rootfs image authentication failed\n");
BUG();
}
#endif
/*
* This sys call will switch the CE1 channel to ADM usage
* so that HLOS can use it.

View file

@ -59,6 +59,7 @@
#define CONFIG_MAX_RAM_BANK_SIZE CONFIG_SYS_SDRAM_SIZE
#define CONFIG_SYS_LOAD_ADDR (CONFIG_SYS_SDRAM_BASE + (64 << 20))
#define CONFIG_DTB_LOAD_ADDR (CONFIG_SYS_SDRAM_BASE + (96 << 20))
#define CONFIG_ROOTFS_LOAD_ADDR (CONFIG_SYS_SDRAM_BASE + (32 << 20))
#define CONFIG_NR_DRAM_BANKS 1
#define CONFIG_OF_LIBFDT 1
@ -324,5 +325,7 @@ typedef struct {
#define CONFIG_PCI_SCAN_SHOW
#endif
#undef CONFIG_IPQ_ROOTFS_AUTH
#define CONFIG_IPQ_4B_ADDR_SWITCH_REQD
#endif /* _IPQ40XX_H */

View file

@ -135,6 +135,7 @@
#define CONFIG_SYS_SDRAM_SIZE 0x10000000
#define CONFIG_MAX_RAM_BANK_SIZE CONFIG_SYS_SDRAM_SIZE
#define CONFIG_SYS_LOAD_ADDR (CONFIG_SYS_SDRAM_BASE + (64 << 20))
#define CONFIG_ROOTFS_LOAD_ADDR (CONFIG_SYS_SDRAM_BASE + (96 << 20))
#define QCA_KERNEL_START_ADDR CONFIG_SYS_SDRAM_BASE
#define QCA_BOOT_PARAMS_ADDR (QCA_KERNEL_START_ADDR + 0x100)
@ -366,5 +367,7 @@ typedef struct {
#define GPIO_CONFIG_ADDR(x) (TLMM_BASE_ADDR + 0x1000 + (x)*0x10)
#define GPIO_IN_OUT_ADDR(x) (TLMM_BASE_ADDR + 0x1004 + (x)*0x10)
#undef CONFIG_IPQ_ROOTFS_AUTH
#endif /* _IPQ806x_CDP_H */

View file

@ -95,6 +95,7 @@
#define CONFIG_SYS_SDRAM_SIZE 0x10000000
#define CONFIG_MAX_RAM_BANK_SIZE CONFIG_SYS_SDRAM_SIZE
#define CONFIG_SYS_LOAD_ADDR (CONFIG_SYS_SDRAM_BASE + (64 << 20))
#define CONFIG_ROOTFS_LOAD_ADDR (CONFIG_SYS_SDRAM_BASE + (32 << 20))
#define QCA_KERNEL_START_ADDR CONFIG_SYS_SDRAM_BASE
#define QCA_DRAM_KERNEL_SIZE CONFIG_SYS_SDRAM_SIZE
@ -349,5 +350,7 @@ extern loff_t board_env_size;
#define CONFIG_CMD_RUN
#define CONFIG_ARMV7_PSCI
#undef CONFIG_IPQ_ROOTFS_AUTH
#endif /* _IPQCDP_H */