Commit 14f7558113319025508e38fbd36ad057c56e3237

Authored by Clement Faure
Committed by Ye Li
1 parent c2cf89d203

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 <clement.faure@nxp.com>
(cherry picked from commit b785e44ce2d042c51386dadb6ec6693344a16fc6)

Showing 4 changed files with 173 additions and 0 deletions Side-by-side Diff

arch/arm/include/asm/arch-imx8/image.h
... ... @@ -53,5 +53,16 @@
53 53 u16 signature_offset;
54 54 u32 reserved;
55 55 } __packed;
  56 +
  57 +struct generate_key_blob_hdr {
  58 + u8 version;
  59 + u8 length_lsb;
  60 + u8 length_msb;
  61 + u8 tag;
  62 + u8 flags;
  63 + u8 size;
  64 + u8 algorithm;
  65 + u8 mode;
  66 +} __packed;
56 67 #endif
arch/arm/mach-imx/Kconfig
... ... @@ -104,6 +104,7 @@
104 104 bool "Support the 'dek_blob' command"
105 105 select IMX_CAAM_DEK_ENCAP if ARCH_MX6 || ARCH_MX7 || ARCH_MX7ULP
106 106 select IMX_OPTEE_DEK_ENCAP if ARCH_IMX8M
  107 + select IMX_SECO_DEK_ENCAP if ARCH_IMX8
107 108 help
108 109 This enables the 'dek_blob' command which is used with the
109 110 Freescale secure boot mechanism. This command encapsulates and
... ... @@ -124,6 +125,12 @@
124 125 This enabled the DEK blob encapsulation with OP-TEE. The communication
125 126 with OP-TEE is done through a SMC call and OP-TEE shared memory. This
126 127 option is available on imx8mm.
  128 +
  129 +config IMX_SECO_DEK_ENCAP
  130 + bool "Support the DEK blob encapsulation with SECO"
  131 + help
  132 + This enabled the DEK blob encapsulation with the SECO API. This option
  133 + is only available on imx8.
127 134  
128 135 config CMD_PRIBLOB
129 136 bool "Support the set_priblob_bitfield command"
arch/arm/mach-imx/cmd_dek.c
... ... @@ -14,6 +14,11 @@
14 14 #include <asm/arch/clock.h>
15 15 #include <mapmem.h>
16 16 #include <tee.h>
  17 +#ifdef CONFIG_IMX_SECO_DEK_ENCAP
  18 +#include <asm/arch/sci/sci.h>
  19 +#include <asm/arch/image.h>
  20 +#endif
  21 +#include <cpu_func.h>
17 22  
18 23 /**
19 24 * blob_dek() - Encapsulate the DEK as a blob using CAM's Key
... ... @@ -128,6 +133,155 @@
128 133 return ret;
129 134 }
130 135 #endif /* CONFIG_IMX_OPTEE_DEK_ENCAP */
  136 +#ifdef CONFIG_IMX_SECO_DEK_ENCAP
  137 +
  138 +#define DEK_BLOB_KEY_ID 0x0
  139 +
  140 +#define AHAB_PRIVATE_KEY 0x81
  141 +#define AHAB_VERSION 0x00
  142 +#define AHAB_MODE_CBC 0x67
  143 +#define AHAB_ALG_AES 0x55
  144 +#define AHAB_128_AES_KEY 0x10
  145 +#define AHAB_192_AES_KEY 0x18
  146 +#define AHAB_256_AES_KEY 0x20
  147 +#define AHAB_FLAG_KEK 0x80
  148 +#define AHAB_DEK_BLOB 0x01
  149 +
  150 +#define DEK_BLOB_HDR_SIZE 8
  151 +#define SECO_PT 2U
  152 +
  153 +static int blob_encap_dek(uint32_t src_addr, uint32_t dst_addr, uint32_t len)
  154 +{
  155 + sc_err_t err;
  156 + sc_rm_mr_t mr_input, mr_output;
  157 + struct generate_key_blob_hdr hdr;
  158 + uint8_t in_size, out_size;
  159 + uint8_t *src_ptr, *dst_ptr;
  160 + int ret = 0;
  161 + int i;
  162 +
  163 + /* Set sizes */
  164 + in_size = sizeof(struct generate_key_blob_hdr) + len / 8;
  165 + out_size = BLOB_SIZE(len / 8) + DEK_BLOB_HDR_SIZE;
  166 +
  167 + /* Get src and dst virtual addresses */
  168 + src_ptr = map_sysmem(src_addr, in_size);
  169 + dst_ptr = map_sysmem(dst_addr, out_size);
  170 +
  171 + /* Check addr input */
  172 + if (!(src_ptr && dst_ptr)) {
  173 + debug("src_addr or dst_addr invalid\n");
  174 + return -1;
  175 + }
  176 +
  177 + /* Build key header */
  178 + hdr.version = AHAB_VERSION;
  179 + hdr.length_lsb = sizeof(struct generate_key_blob_hdr) + len / 8;
  180 + hdr.length_msb = 0x00;
  181 + hdr.tag = AHAB_PRIVATE_KEY;
  182 + hdr.flags = AHAB_DEK_BLOB;
  183 + hdr.algorithm = AHAB_ALG_AES;
  184 + hdr.mode = AHAB_MODE_CBC;
  185 +
  186 + switch (len) {
  187 + case 128:
  188 + hdr.size = AHAB_128_AES_KEY;
  189 + break;
  190 + case 192:
  191 + hdr.size = AHAB_192_AES_KEY;
  192 + break;
  193 + case 256:
  194 + hdr.size = AHAB_256_AES_KEY;
  195 + break;
  196 + default:
  197 + /* Not supported */
  198 + debug("Invalid DEK size. Valid sizes are 128, 192 and 256b\n");
  199 + return -1;
  200 + }
  201 +
  202 + /* Build input message */
  203 + memmove((void *)(src_ptr + sizeof(struct generate_key_blob_hdr)),
  204 + (void *)src_ptr, len / 8);
  205 + memcpy((void *)src_ptr, (void *)&hdr,
  206 + sizeof(struct generate_key_blob_hdr));
  207 +
  208 + /* Flush the cache before triggering the CAAM DMA */
  209 + flush_dcache_range(src_addr, src_addr + in_size);
  210 +
  211 + /* Find input memory region */
  212 + err = sc_rm_find_memreg(
  213 + (-1), &mr_input, src_addr & ~(CONFIG_SYS_CACHELINE_SIZE - 1),
  214 + ALIGN(src_addr + in_size, CONFIG_SYS_CACHELINE_SIZE));
  215 + if (err) {
  216 + printf("Error: find memory region 0x%X\n", src_addr);
  217 + return -ENOMEM;
  218 + }
  219 +
  220 + /* Find output memory region */
  221 + err = sc_rm_find_memreg(
  222 + (-1), &mr_output, dst_addr & ~(CONFIG_SYS_CACHELINE_SIZE - 1),
  223 + ALIGN(dst_addr + out_size, CONFIG_SYS_CACHELINE_SIZE));
  224 + if (err) {
  225 + printf("Error: find memory region 0x%X\n", dst_addr);
  226 + return -ENOMEM;
  227 + }
  228 +
  229 + /* Set memory region permissions for SECO */
  230 + err = sc_rm_set_memreg_permissions(-1, mr_input, SECO_PT,
  231 + SC_RM_PERM_FULL);
  232 + if (err) {
  233 + printf("Set permission failed for input memory region\n");
  234 + ret = -EPERM;
  235 + goto error;
  236 + }
  237 +
  238 + err = sc_rm_set_memreg_permissions(-1, mr_output, SECO_PT,
  239 + SC_RM_PERM_FULL);
  240 + if (err) {
  241 + printf("Set permission failed for output memory region\n");
  242 + ret = -EPERM;
  243 + goto error;
  244 + }
  245 +
  246 + /* Flush output data before SECO operation */
  247 + flush_dcache_range((ulong)dst_ptr, (ulong)(dst_ptr +
  248 + roundup(out_size, ARCH_DMA_MINALIGN)));
  249 +
  250 + /* Generate DEK blob */
  251 + err = sc_seco_gen_key_blob((-1), 0x0, src_addr, dst_addr, out_size);
  252 + if (err) {
  253 + ret = -EPERM;
  254 + goto error;
  255 + }
  256 +
  257 + /* Invalidate output buffer */
  258 + invalidate_dcache_range((ulong)dst_ptr, (ulong)(dst_ptr +
  259 + roundup(out_size, ARCH_DMA_MINALIGN)));
  260 +
  261 + printf("DEK Blob\n");
  262 + for (i = 0; i < DEK_BLOB_HDR_SIZE + BLOB_SIZE(len / 8); i++)
  263 + printf("%02X", dst_ptr[i]);
  264 + printf("\n");
  265 +
  266 +error:
  267 + /* Remove memory region permission to SECO */
  268 + err = sc_rm_set_memreg_permissions(-1, mr_input, SECO_PT,
  269 + SC_RM_PERM_NONE);
  270 + if (err) {
  271 + printf("Error: remove permission failed for input\n");
  272 + ret = -EPERM;
  273 + }
  274 +
  275 + err = sc_rm_set_memreg_permissions(-1, mr_output, SECO_PT,
  276 + SC_RM_PERM_NONE);
  277 + if (err) {
  278 + printf("Error: remove permission failed for output\n");
  279 + ret = -EPERM;
  280 + }
  281 +
  282 + return ret;
  283 +}
  284 +#endif /* CONFIG_IMX_SECO_DEK_ENCAP */
131 285  
132 286 /**
133 287 * do_dek_blob() - Handle the "dek_blob" command-line command
arch/arm/mach-imx/imx8/Kconfig
... ... @@ -7,6 +7,7 @@
7 7  
8 8 config AHAB_BOOT
9 9 bool "Support i.MX8 AHAB features"
  10 + imply CMD_DEKBLOB
10 11 help
11 12 This option enables the support for AHAB secure boot.
12 13