summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--arch/arm/include/asm/arch-imx8/imx-regs.h2
-rw-r--r--common/image-android.c9
-rw-r--r--common/spl/spl_mmc.c9
-rw-r--r--configs/imx8qm_mek_androidauto_trusty_defconfig3
-rw-r--r--configs/imx8qxp_mek_androidauto_trusty_defconfig3
-rw-r--r--include/configs/imx8qm_mek_android_auto.h7
-rw-r--r--include/configs/imx8qxp_mek_android_auto.h7
-rw-r--r--lib/avb/fsl/fsl_avbkey.c295
-rw-r--r--lib/avb/fsl/fsl_avbkey.h2
-rw-r--r--lib/trusty/ql-tipc/hwcrypto.c2
-rw-r--r--lib/trusty/ql-tipc/libtipc.c21
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");