From b785e44ce2d042c51386dadb6ec6693344a16fc6 Mon Sep 17 00:00:00 2001 From: Clement Faure Date: Tue, 28 May 2019 17:01:07 +0200 Subject: [PATCH] MLK-21297 imx8: Add DEK blob encapsulation Add DEK encapsulation support for imx8. The DEK blob is generated by the SECO through the SCFW API. Signed-off-by: Clement Faure --- arch/arm/include/asm/arch-imx8/image.h | 11 ++ arch/arm/mach-imx/Kconfig | 7 ++ arch/arm/mach-imx/cmd_dek.c | 153 +++++++++++++++++++++++++ arch/arm/mach-imx/imx8/Kconfig | 1 + 4 files changed, 172 insertions(+) diff --git a/arch/arm/include/asm/arch-imx8/image.h b/arch/arm/include/asm/arch-imx8/image.h index 2b21f8878e..5773dd370f 100644 --- a/arch/arm/include/asm/arch-imx8/image.h +++ b/arch/arm/include/asm/arch-imx8/image.h @@ -47,3 +47,14 @@ uint16_t signature_offset; uint32_t reserved; }__attribute__((packed)); + +struct generate_key_blob_hdr { + uint8_t version; + uint8_t length_lsb; + uint8_t length_msb; + uint8_t tag; + uint8_t flags; + uint8_t size; + uint8_t algorithm; + uint8_t mode; +} __attribute__((packed)); diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig index b5a4255c66..27a1731a4b 100644 --- a/arch/arm/mach-imx/Kconfig +++ b/arch/arm/mach-imx/Kconfig @@ -97,6 +97,7 @@ config CMD_DEKBLOB bool "Support the 'dek_blob' command" select IMX_CAAM_DEK_ENCAP if ARCH_MX6 || ARCH_MX7 || ARCH_MX7ULP select IMX_OPTEE_DEK_ENCAP if ARCH_IMX8M + select IMX_SECO_DEK_ENCAP if ARCH_IMX8 help This enables the 'dek_blob' command which is used with the Freescale secure boot mechanism. This command encapsulates and @@ -118,6 +119,12 @@ config IMX_OPTEE_DEK_ENCAP with OP-TEE is done through a SMC call and OP-TEE shared memory. This option is available on imx8mm. +config IMX_SECO_DEK_ENCAP + bool "Support the DEK blob encapsulation with SECO" + help + This enabled the DEK blob encapsulation with the SECO API. This option + is only available on imx8. + config CMD_PRIBLOB bool "Support the set_priblob_bitfield command" depends on HAS_CAAM && SECURE_BOOT diff --git a/arch/arm/mach-imx/cmd_dek.c b/arch/arm/mach-imx/cmd_dek.c index 62f33899ff..68ff4a4c1b 100644 --- a/arch/arm/mach-imx/cmd_dek.c +++ b/arch/arm/mach-imx/cmd_dek.c @@ -15,6 +15,10 @@ #include #include #include +#ifdef CONFIG_IMX_SECO_DEK_ENCAP +#include +#include +#endif /** * blob_dek() - Encapsulate the DEK as a blob using CAM's Key @@ -130,6 +134,155 @@ error: return ret; } #endif /* CONFIG_IMX_OPTEE_DEK_ENCAP */ +#ifdef CONFIG_IMX_SECO_DEK_ENCAP + +#define DEK_BLOB_KEY_ID 0x0 + +#define AHAB_PRIVATE_KEY 0x81 +#define AHAB_VERSION 0x00 +#define AHAB_MODE_CBC 0x67 +#define AHAB_ALG_AES 0x55 +#define AHAB_128_AES_KEY 0x10 +#define AHAB_192_AES_KEY 0x18 +#define AHAB_256_AES_KEY 0x20 +#define AHAB_FLAG_KEK 0x80 +#define AHAB_DEK_BLOB 0x01 + +#define DEK_BLOB_HDR_SIZE 8 +#define SECO_PT 2U + +static int blob_encap_dek(uint32_t src_addr, uint32_t dst_addr, uint32_t len) +{ + sc_err_t err; + sc_rm_mr_t mr_input, mr_output; + struct generate_key_blob_hdr hdr; + uint8_t in_size, out_size; + uint8_t *src_ptr, *dst_ptr; + int ret = 0; + int i; + + /* Set sizes */ + in_size = sizeof(struct generate_key_blob_hdr) + len / 8; + out_size = BLOB_SIZE(len / 8) + DEK_BLOB_HDR_SIZE; + + /* Get src and dst virtual addresses */ + src_ptr = map_sysmem(src_addr, in_size); + dst_ptr = map_sysmem(dst_addr, out_size); + + /* Check addr input */ + if (!(src_ptr && dst_ptr)) { + debug("src_addr or dst_addr invalid\n"); + return -1; + } + + /* Build key header */ + hdr.version = AHAB_VERSION; + hdr.length_lsb = sizeof(struct generate_key_blob_hdr) + len / 8; + hdr.length_msb = 0x00; + hdr.tag = AHAB_PRIVATE_KEY; + hdr.flags = AHAB_DEK_BLOB; + hdr.algorithm = AHAB_ALG_AES; + hdr.mode = AHAB_MODE_CBC; + + switch (len) { + case 128: + hdr.size = AHAB_128_AES_KEY; + break; + case 192: + hdr.size = AHAB_192_AES_KEY; + break; + case 256: + hdr.size = AHAB_256_AES_KEY; + break; + default: + /* Not supported */ + debug("Invalid DEK size. Valid sizes are 128, 192 and 256b\n"); + return -1; + } + + /* Build input message */ + memmove((void *)(src_ptr + sizeof(struct generate_key_blob_hdr)), + (void *)src_ptr, len / 8); + memcpy((void *)src_ptr, (void *)&hdr, + sizeof(struct generate_key_blob_hdr)); + + /* Flush the cache before triggering the CAAM DMA */ + flush_dcache_range(src_addr, src_addr + in_size); + + /* Find input memory region */ + err = sc_rm_find_memreg( + (-1), &mr_input, src_addr & ~(CONFIG_SYS_CACHELINE_SIZE - 1), + ALIGN(src_addr + in_size, CONFIG_SYS_CACHELINE_SIZE)); + if (err) { + printf("Error: find memory region 0x%X\n", src_addr); + return -ENOMEM; + } + + /* Find output memory region */ + err = sc_rm_find_memreg( + (-1), &mr_output, dst_addr & ~(CONFIG_SYS_CACHELINE_SIZE - 1), + ALIGN(dst_addr + out_size, CONFIG_SYS_CACHELINE_SIZE)); + if (err) { + printf("Error: find memory region 0x%X\n", dst_addr); + return -ENOMEM; + } + + /* Set memory region permissions for SECO */ + err = sc_rm_set_memreg_permissions(-1, mr_input, SECO_PT, + SC_RM_PERM_FULL); + if (err) { + printf("Set permission failed for input memory region\n"); + ret = -EPERM; + goto error; + } + + err = sc_rm_set_memreg_permissions(-1, mr_output, SECO_PT, + SC_RM_PERM_FULL); + if (err) { + printf("Set permission failed for output memory region\n"); + ret = -EPERM; + goto error; + } + + /* Flush output data before SECO operation */ + flush_dcache_range(dst_ptr, dst_ptr + + roundup(out_size, ARCH_DMA_MINALIGN)); + + /* Generate DEK blob */ + err = sc_seco_gen_key_blob((-1), 0x0, src_addr, dst_addr, out_size); + if (err) { + ret = -EPERM; + goto error; + } + + /* Invalidate output buffer */ + invalidate_dcache_range(dst_ptr, dst_ptr + + roundup(out_size, ARCH_DMA_MINALIGN)); + + printf("DEK Blob\n"); + for (i = 0; i < DEK_BLOB_HDR_SIZE + BLOB_SIZE(len / 8); i++) + printf("%02X", ((uint8_t *)(dst_ptr)[i])); + printf("\n"); + +error: + /* Remove memory region permission to SECO */ + err = sc_rm_set_memreg_permissions(-1, mr_input, SECO_PT, + SC_RM_PERM_NONE); + if (err) { + printf("Error: remove permission failed for input\n"); + ret = -EPERM; + } + + err = sc_rm_set_memreg_permissions(-1, mr_output, SECO_PT, + SC_RM_PERM_NONE); + if (err) { + printf("Error: remove permission failed for output\n"); + ret = -EPERM; + } + + return ret; +} +#endif /* CONFIG_IMX_SECO_DEK_ENCAP */ /** * do_dek_blob() - Handle the "dek_blob" command-line command diff --git a/arch/arm/mach-imx/imx8/Kconfig b/arch/arm/mach-imx/imx8/Kconfig index 268a54d29b..dde53632e7 100644 --- a/arch/arm/mach-imx/imx8/Kconfig +++ b/arch/arm/mach-imx/imx8/Kconfig @@ -12,6 +12,7 @@ config IMX_SMMU config AHAB_BOOT bool "Support i.MX8 AHAB features" + imply CMD_DEKBLOB help This option enables the support for AHAB secure boot. -- 2.17.1