diff options
-rw-r--r-- | arch/arm/include/asm/arch-imx8/imx-regs.h | 2 | ||||
-rw-r--r-- | common/image-android.c | 9 | ||||
-rw-r--r-- | common/spl/spl_mmc.c | 9 | ||||
-rw-r--r-- | configs/imx8qm_mek_androidauto_trusty_defconfig | 3 | ||||
-rw-r--r-- | configs/imx8qxp_mek_androidauto_trusty_defconfig | 3 | ||||
-rw-r--r-- | include/configs/imx8qm_mek_android_auto.h | 7 | ||||
-rw-r--r-- | include/configs/imx8qxp_mek_android_auto.h | 7 | ||||
-rw-r--r-- | lib/avb/fsl/fsl_avbkey.c | 295 | ||||
-rw-r--r-- | lib/avb/fsl/fsl_avbkey.h | 2 | ||||
-rw-r--r-- | lib/trusty/ql-tipc/hwcrypto.c | 2 | ||||
-rw-r--r-- | lib/trusty/ql-tipc/libtipc.c | 21 |
11 files changed, 284 insertions, 76 deletions
diff --git a/arch/arm/include/asm/arch-imx8/imx-regs.h b/arch/arm/include/asm/arch-imx8/imx-regs.h index 8ddc1a6010..3bc6714648 100644 --- a/arch/arm/include/asm/arch-imx8/imx-regs.h +++ b/arch/arm/include/asm/arch-imx8/imx-regs.h @@ -58,6 +58,8 @@ #define USB_BASE_ADDR 0x5b0d0000 #define USB_PHY0_BASE_ADDR 0x5b100000 +#define CAAM_ARB_BASE_ADDR (0x31800000) + #if !(defined(__KERNEL_STRICT_NAMES) || defined(__ASSEMBLY__)) #include <asm/types.h> #include <stdbool.h> diff --git a/common/image-android.c b/common/image-android.c index f569725c82..dac4236bdb 100644 --- a/common/image-android.c +++ b/common/image-android.c @@ -204,9 +204,12 @@ int android_image_get_kernel(const struct andr_img_hdr *hdr, int verify, #endif #ifdef CONFIG_IMX_TRUSTY_OS - char *bootargs_trusty = "androidboot.keystore=trusty"; - strncat(commandline, " ", sizeof(commandline) - strlen(commandline)); - strncat(commandline, bootargs_trusty, sizeof(commandline) - strlen(commandline)); + char *keystore = env_get("keystore"); + if (!strncpy(keystore, "software", sizeof("software"))) { + char *bootargs_trusty = "androidboot.keystore=trusty"; + strncat(commandline, " ", sizeof(commandline) - strlen(commandline)); + strncat(commandline, bootargs_trusty, sizeof(commandline) - strlen(commandline)); + } #endif /* Add 'append_bootargs' to hold some paramemters which need to be appended diff --git a/common/spl/spl_mmc.c b/common/spl/spl_mmc.c index 90935aab1a..91b5190c07 100644 --- a/common/spl/spl_mmc.c +++ b/common/spl/spl_mmc.c @@ -54,6 +54,11 @@ ulong h_spl_load_read(struct spl_load_info *load, ulong sector, return blk_dread(mmc_get_blk_desc(mmc), sector, count, buf); } +#if defined(CONFIG_IMX_TRUSTY_OS) && defined(CONFIG_ANDROID_AUTO_SUPPORT) +/* Pre-declaration of check_rpmb_blob. */ +int check_rpmb_blob(struct mmc *mmc); +#endif + #ifdef CONFIG_DUAL_BOOTLOADER /* Pre-declaration of mmc_load_image_raw_sector_dual_uboot(). */ @@ -103,6 +108,10 @@ int mmc_load_image_raw_sector(struct spl_image_info *spl_image, return -1; } + /* Images loaded, now check the rpmb keyblob for Trusty OS. */ +#if defined(CONFIG_IMX_TRUSTY_OS) && defined(CONFIG_ANDROID_AUTO_SUPPORT) + ret = check_rpmb_blob(mmc); +#endif return 0; } diff --git a/configs/imx8qm_mek_androidauto_trusty_defconfig b/configs/imx8qm_mek_androidauto_trusty_defconfig index a896c9c620..955023c566 100644 --- a/configs/imx8qm_mek_androidauto_trusty_defconfig +++ b/configs/imx8qm_mek_androidauto_trusty_defconfig @@ -117,3 +117,6 @@ CONFIG_SPL_FIT=y CONFIG_SPL_LOAD_FIT=y CONFIG_SPL_MMC_SUPPORT=y CONFIG_SPL_GPIO_SUPPORT=y + +CONFIG_SPL_ENV_SUPPORT=y +CONFIG_SPL_LIBDISK_SUPPORT=y diff --git a/configs/imx8qxp_mek_androidauto_trusty_defconfig b/configs/imx8qxp_mek_androidauto_trusty_defconfig index 279250d256..644e47ae96 100644 --- a/configs/imx8qxp_mek_androidauto_trusty_defconfig +++ b/configs/imx8qxp_mek_androidauto_trusty_defconfig @@ -119,3 +119,6 @@ CONFIG_SPL_FIT=y CONFIG_SPL_LOAD_FIT=y CONFIG_SPL_MMC_SUPPORT=y CONFIG_SPL_GPIO_SUPPORT=y + +CONFIG_SPL_ENV_SUPPORT=y +CONFIG_SPL_LIBDISK_SUPPORT=y diff --git a/include/configs/imx8qm_mek_android_auto.h b/include/configs/imx8qm_mek_android_auto.h index ebdc1bcc5a..6aa19e7865 100644 --- a/include/configs/imx8qm_mek_android_auto.h +++ b/include/configs/imx8qm_mek_android_auto.h @@ -35,6 +35,9 @@ #define CONFIG_FASTBOOT_LOCK #define FSL_FASTBOOT_FB_DEV "mmc" +#define KEYSLOT_HWPARTITION_ID 2 +#define KEYSLOT_BLKS 0x3FFF + #ifdef CONFIG_SYS_MALLOC_LEN #undef CONFIG_SYS_MALLOC_LEN #define CONFIG_SYS_MALLOC_LEN (96 * SZ_1M) @@ -98,6 +101,10 @@ #include "imx8qm_mek_android_auto_xen.h" #endif +#ifdef CONFIG_SPL_BUILD +#undef CONFIG_BLK +#endif + #define AVB_AB_I_UNDERSTAND_LIBAVB_AB_IS_DEPRECATED #endif /* IMX8QM_MEK_ANDROID_AUTO_H */ diff --git a/include/configs/imx8qxp_mek_android_auto.h b/include/configs/imx8qxp_mek_android_auto.h index 65ce4be8f7..97f6487a98 100644 --- a/include/configs/imx8qxp_mek_android_auto.h +++ b/include/configs/imx8qxp_mek_android_auto.h @@ -34,6 +34,9 @@ #define CONFIG_FASTBOOT_LOCK #define FSL_FASTBOOT_FB_DEV "mmc" +#define KEYSLOT_HWPARTITION_ID 2 +#define KEYSLOT_BLKS 0x3FFF + #ifdef CONFIG_SYS_MALLOC_LEN #undef CONFIG_SYS_MALLOC_LEN #define CONFIG_SYS_MALLOC_LEN (96 * SZ_1M) @@ -91,6 +94,10 @@ #undef CONFIG_USB_HOST_ETHER #undef CONFIG_USB_FUNCTION_MASS_STORAGE +#ifdef CONFIG_SPL_BUILD +#undef CONFIG_BLK +#endif + #define AVB_AB_I_UNDERSTAND_LIBAVB_AB_IS_DEPRECATED #endif /* IMX8QXP_MEK_ANDROID_AUTO_H */ diff --git a/lib/avb/fsl/fsl_avbkey.c b/lib/avb/fsl/fsl_avbkey.c index 7c192f31ef..d6031452ab 100644 --- a/lib/avb/fsl/fsl_avbkey.c +++ b/lib/avb/fsl/fsl_avbkey.c @@ -25,6 +25,7 @@ #include "utils.h" #include "debug.h" #include <memalign.h> +#include "trusty/hwcrypto.h" #define INITFLAG_FUSE_OFFSET 0 #define INITFLAG_FUSE_MASK 0x00000001 @@ -307,6 +308,92 @@ AvbIOResult fsl_read_permanent_attributes_hash( #endif /* CONFIG_AVB_ATX */ #endif /* CONFIG_SPL_BUILD */ +#if defined(AVB_RPMB) || defined(CONFIG_IMX_TRUSTY_OS) +void fill_secure_keyslot_package(struct keyslot_package *kp) { + + memcpy((void*)CAAM_ARB_BASE_ADDR, kp, sizeof(struct keyslot_package)); + + /* invalidate the cache to make sure no critical information left in it */ + memset(kp, 0, sizeof(struct keyslot_package)); + invalidate_dcache_range(((ulong)kp) & 0xffffffc0,(((((ulong)kp) + + sizeof(struct keyslot_package)) & 0xffffff00) + + 0x100)); +} + +int read_keyslot_package(struct keyslot_package* kp) { + char original_part; + int blksz; + unsigned char* fill = NULL; + int ret = 0; + /* load tee from boot1 of eMMC. */ + int mmcc = mmc_get_env_dev(); + struct blk_desc *dev_desc = NULL; + + struct mmc *mmc; + mmc = find_mmc_device(mmcc); + if (!mmc) { + printf("boota: cannot find '%d' mmc device\n", mmcc); + return -1; + } +#ifndef CONFIG_BLK + original_part = mmc->block_dev.hwpart; + dev_desc = blk_get_dev("mmc", mmcc); +#else + dev_desc = mmc_get_blk_desc(mmc); + original_part = dev_desc->hwpart; +#endif + if (NULL == dev_desc) { + printf("** Block device MMC %d not supported\n", mmcc); + return -1; + } + + blksz = dev_desc->blksz; + fill = (unsigned char *)memalign(ALIGN_BYTES, blksz); + + /* below was i.MX mmc operation code */ + if (mmc_init(mmc)) { + printf("mmc%d init failed\n", mmcc); + ret = -1; + goto fail;; + } + + mmc_switch_part(mmc, KEYSLOT_HWPARTITION_ID); +#ifndef CONFIG_BLK + mmc->block_dev.hwpart = KEYSLOT_HWPARTITION_ID; +#else + dev_desc->hwpart = KEYSLOT_HWPARTITION_ID; +#endif + if (blk_dread(dev_desc, KEYSLOT_BLKS, + 1, fill) != 1) { + printf("Failed to read rpmbkeyblob."); + ret = -1; + goto fail; + } else { + memcpy(kp, fill, sizeof(struct keyslot_package)); + } + +fail: + /* Free allocated memory. */ + if (fill != NULL) + free(fill); + /* Return to original partition */ +#ifndef CONFIG_BLK + if (mmc->block_dev.hwpart != original_part) { + if (mmc_switch_part(mmc, original_part) != 0) + return -1; + mmc->block_dev.hwpart = original_part; + } +#else + if (dev_desc->hwpart != original_part) { + if (mmc_switch_part(mmc, original_part) != 0) + return -1; + dev_desc->hwpart = original_part; + } +#endif + return ret; +} +#endif + #ifndef AVB_RPMB /* ARM64 won't avbkey and rollback index in this stage directly. */ int avbkey_init(uint8_t *plainkey, uint32_t keylen) { @@ -478,70 +565,6 @@ int rpmb_init(void) { } #endif /* CONFIG_IMX_TRUSTY_OS */ -void fill_secure_keyslot_package(struct keyslot_package *kp) { - - memcpy((void*)CAAM_ARB_BASE_ADDR, kp, sizeof(struct keyslot_package)); - - /* invalidate the cache to make sure no critical information left in it */ - memset(kp, 0, sizeof(struct keyslot_package)); - invalidate_dcache_range(((ulong)kp) & 0xffffffc0,(((((ulong)kp) + - sizeof(struct keyslot_package)) & 0xffffff00) + - 0x100)); -} - -int read_keyslot_package(struct keyslot_package* kp) { - char original_part; - int blksz; - unsigned char* fill = NULL; - int ret = 0; - /* load tee from boot1 of eMMC. */ - int mmcc = mmc_get_env_dev(); - struct blk_desc *dev_desc = NULL; - - struct mmc *mmc; - mmc = find_mmc_device(mmcc); - if (!mmc) { - printf("boota: cannot find '%d' mmc device\n", mmcc); - return -1; - } - original_part = mmc->block_dev.hwpart; - - dev_desc = blk_get_dev("mmc", mmcc); - if (NULL == dev_desc) { - printf("** Block device MMC %d not supported\n", mmcc); - return -1; - } - - blksz = dev_desc->blksz; - fill = (unsigned char *)memalign(ALIGN_BYTES, blksz); - - /* below was i.MX mmc operation code */ - if (mmc_init(mmc)) { - printf("mmc%d init failed\n", mmcc); - return -1; - } - - mmc_switch_part(mmc, KEYSLOT_HWPARTITION_ID); - if (blk_dread(dev_desc, KEYSLOT_BLKS, - 1, fill) != 1) { - printf("Failed to read rpmbkeyblob."); - ret = -1; - } else { - memcpy(kp, fill, sizeof(struct keyslot_package)); - } - - /* Return to original partition */ - if (mmc->block_dev.hwpart != original_part) { - if (mmc_switch_part(mmc, original_part) != 0) - return -1; - mmc->block_dev.hwpart = original_part; - } - if (fill != NULL) - free(fill); - - return ret; -} - int gen_rpmb_key(struct keyslot_package *kp) { char original_part; unsigned char* fill = NULL; @@ -877,7 +900,6 @@ fail: return ret; } - #ifndef CONFIG_SPL_BUILD static int rpmb_key(struct mmc *mmc) { @@ -1369,15 +1391,113 @@ fail: #endif /* AVB_RPMB && CONFIG_AVB_ATX */ -#ifdef CONFIG_ANDROID_AUTO_SUPPORT +#if defined(CONFIG_IMX_TRUSTY_OS) && defined(CONFIG_ANDROID_AUTO_SUPPORT) + +extern int mmc_switch(struct mmc *mmc, u8 set, u8 index, u8 value); + +#ifdef CONFIG_SPL_BUILD +int check_rpmb_blob(struct mmc *mmc) +{ + int ret = 0; + char original_part; + struct keyslot_package kp; + + read_keyslot_package(&kp); + if (strcmp(kp.magic, KEYPACK_MAGIC)) { + printf("keyslot package magic error, do nothing here!\n"); + return 0; + } + /* If keyslot package valid, copy it to secure memory */ + fill_secure_keyslot_package(&kp); + + /* switch to boot1 partition. */ + original_part = mmc->block_dev.hwpart; + if (mmc_switch_part(mmc, KEYSLOT_HWPARTITION_ID) != 0) { + printf("ERROR - can't switch to boot1 partition! \n"); + ret = -1; + goto fail; + } else + mmc->block_dev.hwpart = KEYSLOT_HWPARTITION_ID; + /* write power-on write protection for boot1 partition. */ + if (mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, + EXT_CSD_BOOT_WP, BOOT1_PWR_WP)) { + printf("ERROR - unable to set power-on write protection!\n"); + ret = -1; + goto fail; + } +fail: + /* return to original partition. */ + if (mmc->block_dev.hwpart != original_part) { + if (mmc_switch_part(mmc, original_part) != 0) + return -1; + mmc->block_dev.hwpart = original_part; + } + + return ret; +} +#else /* CONFIG_SPL_BUILD */ +bool rpmbkey_is_set(void) +{ + int mmcc; + bool ret; + uint8_t *buf; + struct mmc *mmc; + char original_part; + struct blk_desc *desc = NULL; + + /* Get current mmc device. */ + mmcc = mmc_get_env_dev(); + mmc = find_mmc_device(mmcc); + if (!mmc) { + printf("error - cannot find '%d' mmc device\n", mmcc); + return false; + } + + desc = mmc_get_blk_desc(mmc); + original_part = desc->hwpart; + + /* Switch to the RPMB partition */ + if (desc->hwpart != MMC_PART_RPMB) { + if (mmc_switch_part(mmc, MMC_PART_RPMB) != 0) { + printf("ERROR - can't switch to rpmb partition \n"); + return false; + } + desc->hwpart = MMC_PART_RPMB; + } + + /* Try to read the first one block, return count '1' means the rpmb + * key has been set, otherwise means the key hasn't been set. + */ + buf = (uint8_t *)memalign(ALIGN_BYTES, desc->blksz); + if (mmc_rpmb_read(mmc, buf, 0, 1, NULL) != 1) + ret = false; + else + ret = true; + + /* return to original partition. */ + if (desc->hwpart != original_part) { + if (mmc_switch_part(mmc, original_part) != 0) + ret = false; + desc->hwpart = original_part; + } + /* remember to free the buffer */ + if (buf != NULL) + free(buf); + + return ret; +} + int fastboot_set_rpmb_key(uint8_t *staged_buf, uint32_t key_size) { int ret = 0; int mmcc; struct mmc *mmc; char original_part; + struct keyslot_package kp; struct blk_desc *desc = NULL; - uint8_t rpmb_key[RPMBKEY_LENGTH]; + ALLOC_CACHE_ALIGN_BUFFER(uint8_t, rpmb_key, RPMBKEY_LENGTH); + ALLOC_CACHE_ALIGN_BUFFER(uint8_t, blob, + RPMBKEY_LENGTH + CAAM_PAD); if (memcmp(staged_buf, RPMB_KEY_MAGIC, strlen(RPMB_KEY_MAGIC))) { printf("ERROR - rpmb magic doesn't match!\n"); @@ -1405,7 +1525,8 @@ int fastboot_set_rpmb_key(uint8_t *staged_buf, uint32_t key_size) /* Set rpmb key. */ memset(rpmb_key, 0, RPMBKEY_LENGTH); - memcpy(rpmb_key, staged_buf + strlen(RPMB_KEY_MAGIC), RPMBKEY_LENGTH); + memcpy(rpmb_key, + staged_buf + strlen(RPMB_KEY_MAGIC), RPMBKEY_LENGTH); if (mmc_rpmb_set_key(mmc, rpmb_key)) { printf("ERROR - Key already programmed ?\n"); @@ -1414,9 +1535,40 @@ int fastboot_set_rpmb_key(uint8_t *staged_buf, uint32_t key_size) } else printf("RPMB key programed successfully!"); - /* TODO Generate keyblob with CAAM and store it to boot1, - * this requires CAAM is ready for Android Auto. - */ + /* Generate keyblob with CAAM. */ + kp.rpmb_keyblob_len = RPMBKEY_LENGTH + CAAM_PAD; + strcpy(kp.magic, KEYPACK_MAGIC); + if (hwcrypto_gen_blob((uint32_t)(ulong)rpmb_key, RPMBKEY_LENGTH, + (uint32_t)(ulong)blob) != 0) { + printf("ERROR - generate rpmb key blob error!\n"); + ret = -1; + goto fail; + } + memcpy(kp.rpmb_keyblob, blob, kp.rpmb_keyblob_len); + + /* Store the rpmb key blob to last block of boot1 partition. */ + if (mmc_switch_part(mmc, KEYSLOT_HWPARTITION_ID) != 0) { + printf("ERROR - can't switch to boot1 partition! \n"); + ret = -1; + goto fail; + } else + desc->hwpart = KEYSLOT_HWPARTITION_ID; + if (blk_dwrite(desc, KEYSLOT_BLKS, 1, (void *)&kp) != 1) { + printf("ERROR - failed to write rpmbkeyblob!"); + ret = -1; + goto fail; + } + /* Set power-on write protection to boot1 partition. */ + if (mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, + EXT_CSD_BOOT_WP, BOOT1_PWR_WP)) { + printf("ERROR - unable to set power-on write protection!\n"); + ret = -1; + goto fail; + } + + /* Erase the key buffer. */ + memset(rpmb_key, 0, RPMBKEY_LENGTH); + fail: /* Return to original partition */ if (desc->hwpart != original_part) { @@ -1427,4 +1579,5 @@ fail: return ret; } +#endif /* CONFIG_SPL_BUILD */ #endif diff --git a/lib/avb/fsl/fsl_avbkey.h b/lib/avb/fsl/fsl_avbkey.h index 7300a12d2f..73b0c52718 100644 --- a/lib/avb/fsl/fsl_avbkey.h +++ b/lib/avb/fsl/fsl_avbkey.h @@ -82,4 +82,6 @@ int rpmb_read(struct mmc *mmc, uint8_t *buffer, int rpmb_write(struct mmc *mmc, uint8_t *buffer, size_t num_bytes, int64_t offset); +int check_rpmb_blob(struct mmc *mmc); +bool rpmbkey_is_set(void); #endif diff --git a/lib/trusty/ql-tipc/hwcrypto.c b/lib/trusty/ql-tipc/hwcrypto.c index 69914a9762..02b7b198eb 100644 --- a/lib/trusty/ql-tipc/hwcrypto.c +++ b/lib/trusty/ql-tipc/hwcrypto.c @@ -215,6 +215,6 @@ int hwcrypto_gen_blob(uint32_t plain_pa, invalidate_dcache_range(start, end); int rc = hwcrypto_do_tipc(HWCRYPTO_ENCAP_BLOB, (void*)&req, - sizeof(req), NULL, 0, false); + sizeof(req), NULL, 0, false); return rc; } diff --git a/lib/trusty/ql-tipc/libtipc.c b/lib/trusty/ql-tipc/libtipc.c index 03e6906de4..b2814b6dca 100644 --- a/lib/trusty/ql-tipc/libtipc.c +++ b/lib/trusty/ql-tipc/libtipc.c @@ -23,6 +23,7 @@ * SOFTWARE. */ +#include <common.h> #include <trusty/avb.h> #include <trusty/hwcrypto.h> #include <trusty/keymaster.h> @@ -38,6 +39,9 @@ typedef uintptr_t vaddr_t; static struct trusty_ipc_dev *_ipc_dev; static struct trusty_dev _tdev; /* There should only be one trusty device */ static void *rpmb_ctx; +#ifdef CONFIG_ANDROID_AUTO_SUPPORT +bool rpmbkey_is_set(void); +#endif void rpmb_storage_put_ctx(void *dev); void trusty_ipc_shutdown(void) @@ -84,7 +88,22 @@ int trusty_ipc_init(void) if (rc != 0) { trusty_error("Initlializing RPMB storage proxy service failed (%d)\n", rc); - return rc; +#ifdef CONFIG_ANDROID_AUTO_SUPPORT + /* check if rpmb key has been fused. */ + if(rpmbkey_is_set()) { + /* Go to hang if the key has been destroyed. */ + trusty_error("RPMB key was destroyed!\n"); + hang(); + } else { + /* rpmb key hasn't been set, use software + * keymaster and return earily. + */ + env_set("keystore", "software"); + return rc; + } +#else + return rc; +#endif } trusty_info("Initializing Trusty AVB client\n"); |