Commit cbc0a6698241cf12e131d8722220657ae4d684ae

Authored by Clement Faure
Committed by Ye Li
1 parent bbd5783540

TEE-346 Add DEK blob encapsulation for imx8m

Add DEK blob encapsulation support for IMX8M through "dek_blob" command.
On ARMv8, u-boot runs in non-secure, thus cannot encapsulate a DEK blob
for encrypted boot.
The DEK blob is encapsulated by OP-TEE through a trusted application call.
U-boot sends and receives the DEK and the DEK blob binaries through OP-TEE
dynamic shared memory.

To enable the DEK blob encapsulation, add to the defconfig:
CONFIG_SECURE_BOOT=y
CONFIG_FAT_WRITE=y
CONFIG_CMD_DEKBLOB=y

Signed-off-by: Clement Faure <clement.faure@nxp.com>
Reviewed-by: Ye Li <ye.li@nxp.com>
(cherry picked from commit 7ffd25bddc89db30612f4e805d103c7d8dde5d95)

Showing 7 changed files with 136 additions and 15 deletions Side-by-side Diff

arch/arm/dts/imx8mm-evk-u-boot.dtsi
... ... @@ -3,6 +3,15 @@
3 3 * Copyright 2019 NXP
4 4 */
5 5  
  6 +/ {
  7 + firmware {
  8 + optee {
  9 + compatible = "linaro,optee-tz";
  10 + method = "smc";
  11 + };
  12 + };
  13 +};
  14 +
6 15 &{/soc@0} {
7 16 u-boot,dm-pre-reloc;
8 17 u-boot,dm-spl;
arch/arm/dts/imx8mn-ddr4-evk-u-boot.dtsi
... ... @@ -3,6 +3,15 @@
3 3 * Copyright 2019 NXP
4 4 */
5 5  
  6 +/ {
  7 + firmware {
  8 + optee {
  9 + compatible = "linaro,optee-tz";
  10 + method = "smc";
  11 + };
  12 + };
  13 +};
  14 +
6 15 &{/soc@0} {
7 16 u-boot,dm-pre-reloc;
8 17 u-boot,dm-spl;
arch/arm/dts/imx8mp-evk-u-boot.dtsi
... ... @@ -3,6 +3,15 @@
3 3 * Copyright 2019 NXP
4 4 */
5 5  
  6 +/ {
  7 + firmware {
  8 + optee {
  9 + compatible = "linaro,optee-tz";
  10 + method = "smc";
  11 + };
  12 + };
  13 +};
  14 +
6 15 &{/soc@0} {
7 16 u-boot,dm-pre-reloc;
8 17 u-boot,dm-spl;
arch/arm/mach-imx/Kconfig
... ... @@ -102,11 +102,28 @@
102 102  
103 103 config CMD_DEKBLOB
104 104 bool "Support the 'dek_blob' command"
  105 + select IMX_CAAM_DEK_ENCAP if ARCH_MX6 || ARCH_MX7 || ARCH_MX7ULP
  106 + select IMX_OPTEE_DEK_ENCAP if ARCH_IMX8M
105 107 help
106 108 This enables the 'dek_blob' command which is used with the
107 109 Freescale secure boot mechanism. This command encapsulates and
108 110 creates a blob of data. See also CMD_BLOB and doc/README.mxc_hab for
109 111 more information.
  112 +
  113 +config IMX_CAAM_DEK_ENCAP
  114 + bool "Support the DEK blob encapsulation with CAAM U-Boot driver"
  115 + help
  116 + This enables the DEK blob encapsulation with the U-Boot CAAM driver.
  117 + This option is only available on imx6, imx7 and imx7ulp.
  118 +
  119 +config IMX_OPTEE_DEK_ENCAP
  120 + select TEE
  121 + select OPTEE
  122 + bool "Support the DEK blob encapsulation with OP-TEE"
  123 + help
  124 + This enabled the DEK blob encapsulation with OP-TEE. The communication
  125 + with OP-TEE is done through a SMC call and OP-TEE shared memory. This
  126 + option is available on imx8mm.
110 127  
111 128 config CMD_PRIBLOB
112 129 bool "Support the set_priblob_bitfield command"
arch/arm/mach-imx/cmd_dek.c
... ... @@ -13,6 +13,7 @@
13 13 #include <fsl_sec.h>
14 14 #include <asm/arch/clock.h>
15 15 #include <mapmem.h>
  16 +#include <tee.h>
16 17  
17 18 /**
18 19 * blob_dek() - Encapsulate the DEK as a blob using CAM's Key
19 20  
20 21  
... ... @@ -22,10 +23,14 @@
22 23 *
23 24 * Returns zero on success,and negative on error.
24 25 */
25   -static int blob_encap_dek(const u8 *src, u8 *dst, u32 len)
  26 +#ifdef CONFIG_IMX_CAAM_DEK_ENCAP
  27 +static int blob_encap_dek(uint32_t src_addr, uint32_t dst_addr, uint32_t len)
26 28 {
27   - int ret = 0;
  29 + uint8_t *src_ptr, *dst_ptr;
28 30  
  31 + src_ptr = map_sysmem(src_addr, len / 8);
  32 + dst_ptr = map_sysmem(dst_addr, BLOB_SIZE(len / 8));
  33 +
29 34 hab_caam_clock_enable(1);
30 35  
31 36 u32 out_jr_size = sec_in32(CONFIG_SYS_FSL_JR0_ADDR +
32 37  
33 38  
... ... @@ -39,10 +44,90 @@
39 44 }
40 45  
41 46 len /= 8;
42   - ret = blob_dek(src, dst, len);
  47 + return blob_dek(src_ptr, dst_ptr, len);
  48 +}
  49 +#endif /* CONFIG_IMX_CAAM_DEK_ENCAP */
43 50  
  51 +#ifdef CONFIG_IMX_OPTEE_DEK_ENCAP
  52 +
  53 +#define PTA_DEK_BLOB_PTA_UUID {0xef477737, 0x0db1, 0x4a9d, \
  54 + {0x84, 0x37, 0xf2, 0xf5, 0x35, 0xc0, 0xbd, 0x92} }
  55 +
  56 +#define OPTEE_BLOB_HDR_SIZE 8
  57 +
  58 +static int blob_encap_dek(uint32_t src_addr, uint32_t dst_addr, uint32_t len)
  59 +{
  60 + struct udevice *dev = NULL;
  61 + struct tee_shm *shm_input, *shm_output;
  62 + struct tee_open_session_arg arg = {0};
  63 + struct tee_invoke_arg arg_func = {0};
  64 + const struct tee_optee_ta_uuid uuid = PTA_DEK_BLOB_PTA_UUID;
  65 + struct tee_param param[4] = {0};
  66 + int ret;
  67 +
  68 + /* Get tee device */
  69 + dev = tee_find_device(NULL, NULL, NULL, NULL);
  70 + if (dev == NULL) {
  71 + printf("Cannot get OP-TEE device\n");
  72 + return -1;
  73 + }
  74 +
  75 + /* Set TA UUID */
  76 + tee_optee_ta_uuid_to_octets(arg.uuid, &uuid);
  77 +
  78 + /* Open TA session */
  79 + ret = tee_open_session(dev, &arg, 0, NULL);
  80 + if (ret < 0) {
  81 + printf("Cannot open session with PTA Blob 0x%X\n", ret);
  82 + return -1;
  83 + }
  84 +
  85 + /* Allocate shared input and output buffers for TA */
  86 + ret = tee_shm_register(dev, (void *)(ulong)src_addr, len / 8, 0x0, &shm_input);
  87 + if (ret < 0) {
  88 + printf("Cannot register input shared memory 0x%X\n", ret);
  89 + goto error;
  90 + }
  91 +
  92 + ret = tee_shm_register(dev, (void *)(ulong)dst_addr,
  93 + BLOB_SIZE(len / 8) + OPTEE_BLOB_HDR_SIZE,
  94 + 0x0, &shm_output);
  95 + if (ret < 0) {
  96 + printf("Cannot register output shared memory 0x%X\n", ret);
  97 + goto error;
  98 + }
  99 +
  100 + param[0].u.memref.shm = shm_input;
  101 + param[0].u.memref.size = shm_input->size;
  102 + param[0].attr = TEE_PARAM_ATTR_TYPE_MEMREF_INPUT;
  103 + param[1].u.memref.shm = shm_output;
  104 + param[1].u.memref.size = shm_output->size;
  105 + param[1].attr = TEE_PARAM_ATTR_TYPE_MEMREF_OUTPUT;
  106 + param[2].attr = TEE_PARAM_ATTR_TYPE_NONE;
  107 + param[3].attr = TEE_PARAM_ATTR_TYPE_NONE;
  108 +
  109 + arg_func.func = 0;
  110 + arg_func.session = arg.session;
  111 +
  112 + /* Generate DEK blob */
  113 + arg_func.session = arg.session;
  114 + ret = tee_invoke_func(dev, &arg_func, 4, param);
  115 + if (ret < 0)
  116 + printf("Cannot generate Blob with PTA DEK Blob 0x%X\n", ret);
  117 +
  118 +error:
  119 + /* Free shared memory */
  120 + tee_shm_free(shm_input);
  121 + tee_shm_free(shm_output);
  122 +
  123 + /* Close session */
  124 + ret = tee_close_session(dev, arg.session);
  125 + if (ret < 0)
  126 + printf("Cannot close session with PTA DEK Blob 0x%X\n", ret);
  127 +
44 128 return ret;
45 129 }
  130 +#endif /* CONFIG_IMX_OPTEE_DEK_ENCAP */
46 131  
47 132 /**
48 133 * do_dek_blob() - Handle the "dek_blob" command-line command
... ... @@ -57,8 +142,6 @@
57 142 static int do_dek_blob(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
58 143 {
59 144 uint32_t src_addr, dst_addr, len;
60   - uint8_t *src_ptr, *dst_ptr;
61   - int ret = 0;
62 145  
63 146 if (argc != 4)
64 147 return CMD_RET_USAGE;
... ... @@ -67,12 +150,7 @@
67 150 dst_addr = simple_strtoul(argv[2], NULL, 16);
68 151 len = simple_strtoul(argv[3], NULL, 10);
69 152  
70   - src_ptr = map_sysmem(src_addr, len/8);
71   - dst_ptr = map_sysmem(dst_addr, BLOB_SIZE(len/8));
72   -
73   - ret = blob_encap_dek(src_ptr, dst_ptr, len);
74   -
75   - return ret;
  153 + return blob_encap_dek(src_addr, dst_addr, len);
76 154 }
77 155  
78 156 /***************************************************/
drivers/crypto/fsl/Makefile
... ... @@ -4,8 +4,7 @@
4 4  
5 5 obj-y += sec.o
6 6 obj-$(CONFIG_FSL_CAAM) += jr.o fsl_hash.o jobdesc.o error.o
7   -obj-$(CONFIG_CMD_BLOB) += fsl_blob.o
8   -obj-$(CONFIG_CMD_DEKBLOB) += fsl_blob.o
  7 +obj-$(CONFIG_CMD_BLOB)$(CONFIG_IMX_CAAM_DEK_ENCAP) += fsl_blob.o
9 8 obj-$(CONFIG_RSA_FREESCALE_EXP) += fsl_rsa.o
10 9 obj-$(CONFIG_FSL_MFGPROT) += fsl_mfgprot.o
... ... @@ -28,6 +28,8 @@
28 28 #error Neither CONFIG_SYS_FSL_SEC_LE nor CONFIG_SYS_FSL_SEC_BE is defined
29 29 #endif
30 30  
  31 +#define BLOB_SIZE(x) ((x) + 32 + 16) /* Blob buffer size */
  32 +
31 33 /* Security Engine Block (MS = Most Sig., LS = Least Sig.) */
32 34 #if CONFIG_SYS_FSL_SEC_COMPAT >= 4
33 35 /* RNG4 TRNG test registers */
... ... @@ -227,8 +229,6 @@
227 229 #define SG_ENTRY_OFFSET_MASK 0x00001FFF
228 230 #define SG_ENTRY_OFFSET_SHIFT 0
229 231 };
230   -
231   -#define BLOB_SIZE(x) ((x) + 32 + 16) /* Blob buffer size */
232 232  
233 233 #if defined(CONFIG_MX6) || defined(CONFIG_MX7) || \
234 234 defined(CONFIG_MX7ULP) || defined(CONFIG_IMX8M)