From eedc3373016bcc6471e6bee61bcafc92562ba315 Mon Sep 17 00:00:00 2001 From: Praveenkumar I Date: Wed, 25 Jul 2018 16:11:10 +0530 Subject: [PATCH] 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 --- board/qca/arm/common/cmd_bootqca.c | 104 ++++++++++++++++++++++++++++- include/configs/ipq40xx.h | 3 + include/configs/ipq806x.h | 3 + include/configs/ipq807x.h | 3 + 4 files changed, 112 insertions(+), 1 deletion(-) diff --git a/board/qca/arm/common/cmd_bootqca.c b/board/qca/arm/common/cmd_bootqca.c index e0d9f99de2..1b0e35ea60 100644 --- a/board/qca/arm/common/cmd_bootqca.c +++ b/board/qca/arm/common/cmd_bootqca.c @@ -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. diff --git a/include/configs/ipq40xx.h b/include/configs/ipq40xx.h index b294004f53..b25b0054f0 100644 --- a/include/configs/ipq40xx.h +++ b/include/configs/ipq40xx.h @@ -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 */ diff --git a/include/configs/ipq806x.h b/include/configs/ipq806x.h index 40e1d6b2a9..912c9f2943 100644 --- a/include/configs/ipq806x.h +++ b/include/configs/ipq806x.h @@ -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 */ diff --git a/include/configs/ipq807x.h b/include/configs/ipq807x.h index 877eb25cda..1a82777387 100644 --- a/include/configs/ipq807x.h +++ b/include/configs/ipq807x.h @@ -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 */