From: Clement Faure Date: Thu, 25 Mar 2021 09:30:34 +0000 (+0800) Subject: imx8: Add DEK blob encapsulation X-Git-Url: http://git.dujemihanovic.xyz/?a=commitdiff_plain;h=69f542ca2b68b88cd31118c3bf926dd59b544473;p=u-boot.git 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 Signed-off-by: Peng Fan --- diff --git a/arch/arm/include/asm/arch-imx8/image.h b/arch/arm/include/asm/arch-imx8/image.h index c1e5700859..547beeb986 100644 --- a/arch/arm/include/asm/arch-imx8/image.h +++ b/arch/arm/include/asm/arch-imx8/image.h @@ -53,4 +53,15 @@ struct signature_block_hdr { u16 signature_offset; u32 reserved; } __packed; + +struct generate_key_blob_hdr { + u8 version; + u8 length_lsb; + u8 length_msb; + u8 tag; + u8 flags; + u8 size; + u8 algorithm; + u8 mode; +} __packed; #endif diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig index 3bcfced8f0..26bfc5ccc4 100644 --- a/arch/arm/mach-imx/Kconfig +++ b/arch/arm/mach-imx/Kconfig @@ -77,6 +77,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 @@ -98,6 +99,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 && IMX_HAB diff --git a/arch/arm/mach-imx/cmd_dek.c b/arch/arm/mach-imx/cmd_dek.c index 75aec2cef0..b10ead1942 100644 --- a/arch/arm/mach-imx/cmd_dek.c +++ b/arch/arm/mach-imx/cmd_dek.c @@ -15,6 +15,11 @@ #include #include #include +#ifdef CONFIG_IMX_SECO_DEK_ENCAP +#include +#include +#endif +#include /** * blob_dek() - Encapsulate the DEK as a blob using CAM's Key @@ -129,6 +134,153 @@ 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(u32 src_addr, u32 dst_addr, u32 len) +{ + sc_err_t err; + sc_rm_mr_t mr_input, mr_output; + struct generate_key_blob_hdr hdr; + u8 in_size, out_size; + u8 *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((ulong)dst_ptr, (ulong)(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((ulong)dst_ptr, (ulong)(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", 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 04b9729109..4e76612d05 100644 --- a/arch/arm/mach-imx/imx8/Kconfig +++ b/arch/arm/mach-imx/imx8/Kconfig @@ -2,6 +2,7 @@ if ARCH_IMX8 config AHAB_BOOT bool "Support i.MX8 AHAB features" + imply CMD_DEKBLOB help This option enables the support for AHAB secure boot.