1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * Copyright 2008-2015 Freescale Semiconductor, Inc. 4 * 5 * Command for encapsulating DEK blob 6 */ 7 8 #include <common.h> 9 #include <command.h> 10 #include <log.h> 11 #include <malloc.h> 12 #include <asm/byteorder.h> 13 #include <linux/compiler.h> 14 #include <fsl_sec.h> 15 #include <asm/arch/clock.h> 16 #include <mapmem.h> 17 #include <tee.h> 18 #ifdef CONFIG_IMX_SECO_DEK_ENCAP 19 #include <asm/arch/sci/sci.h> 20 #include <asm/arch/image.h> 21 #endif 22 #include <cpu_func.h> 23 24 /** 25 * blob_dek() - Encapsulate the DEK as a blob using CAM's Key 26 * @src: - Address of data to be encapsulated 27 * @dst: - Desination address of encapsulated data 28 * @len: - Size of data to be encapsulated 29 * 30 * Returns zero on success,and negative on error. 31 */ 32 #ifdef CONFIG_IMX_CAAM_DEK_ENCAP 33 static int blob_encap_dek(u32 src_addr, u32 dst_addr, u32 len) 34 { 35 u8 *src_ptr, *dst_ptr; 36 37 src_ptr = map_sysmem(src_addr, len / 8); 38 dst_ptr = map_sysmem(dst_addr, BLOB_SIZE(len / 8)); 39 40 hab_caam_clock_enable(1); 41 42 u32 out_jr_size = sec_in32(CONFIG_SYS_FSL_JR0_ADDR + 43 FSL_CAAM_ORSR_JRa_OFFSET); 44 if (out_jr_size != FSL_CAAM_MAX_JR_SIZE) 45 sec_init(); 46 47 if (!((len == 128) | (len == 192) | (len == 256))) { 48 debug("Invalid DEK size. Valid sizes are 128, 192 and 256b\n"); 49 return -1; 50 } 51 52 len /= 8; 53 return blob_dek(src_ptr, dst_ptr, len); 54 } 55 #endif /* CONFIG_IMX_CAAM_DEK_ENCAP */ 56 57 #ifdef CONFIG_IMX_OPTEE_DEK_ENCAP 58 59 #define PTA_DEK_BLOB_PTA_UUID {0xef477737, 0x0db1, 0x4a9d, \ 60 {0x84, 0x37, 0xf2, 0xf5, 0x35, 0xc0, 0xbd, 0x92} } 61 62 #define OPTEE_BLOB_HDR_SIZE 8 63 64 static int blob_encap_dek(u32 src_addr, u32 dst_addr, u32 len) 65 { 66 struct udevice *dev = NULL; 67 struct tee_shm *shm_input, *shm_output; 68 struct tee_open_session_arg arg = {0}; 69 struct tee_invoke_arg arg_func = {0}; 70 const struct tee_optee_ta_uuid uuid = PTA_DEK_BLOB_PTA_UUID; 71 struct tee_param param[4] = {0}; 72 int ret; 73 74 /* Get tee device */ 75 dev = tee_find_device(NULL, NULL, NULL, NULL); 76 if (!dev) { 77 printf("Cannot get OP-TEE device\n"); 78 return -1; 79 } 80 81 /* Set TA UUID */ 82 tee_optee_ta_uuid_to_octets(arg.uuid, &uuid); 83 84 /* Open TA session */ 85 ret = tee_open_session(dev, &arg, 0, NULL); 86 if (ret < 0) { 87 printf("Cannot open session with PTA Blob 0x%X\n", ret); 88 return -1; 89 } 90 91 /* Allocate shared input and output buffers for TA */ 92 ret = tee_shm_register(dev, (void *)(ulong)src_addr, len / 8, 0x0, &shm_input); 93 if (ret < 0) { 94 printf("Cannot register input shared memory 0x%X\n", ret); 95 goto error; 96 } 97 98 ret = tee_shm_register(dev, (void *)(ulong)dst_addr, 99 BLOB_SIZE(len / 8) + OPTEE_BLOB_HDR_SIZE, 100 0x0, &shm_output); 101 if (ret < 0) { 102 printf("Cannot register output shared memory 0x%X\n", ret); 103 goto error; 104 } 105 106 param[0].u.memref.shm = shm_input; 107 param[0].u.memref.size = shm_input->size; 108 param[0].attr = TEE_PARAM_ATTR_TYPE_MEMREF_INPUT; 109 param[1].u.memref.shm = shm_output; 110 param[1].u.memref.size = shm_output->size; 111 param[1].attr = TEE_PARAM_ATTR_TYPE_MEMREF_OUTPUT; 112 param[2].attr = TEE_PARAM_ATTR_TYPE_NONE; 113 param[3].attr = TEE_PARAM_ATTR_TYPE_NONE; 114 115 arg_func.func = 0; 116 arg_func.session = arg.session; 117 118 /* Generate DEK blob */ 119 arg_func.session = arg.session; 120 ret = tee_invoke_func(dev, &arg_func, 4, param); 121 if (ret < 0) 122 printf("Cannot generate Blob with PTA DEK Blob 0x%X\n", ret); 123 124 error: 125 /* Free shared memory */ 126 tee_shm_free(shm_input); 127 tee_shm_free(shm_output); 128 129 /* Close session */ 130 ret = tee_close_session(dev, arg.session); 131 if (ret < 0) 132 printf("Cannot close session with PTA DEK Blob 0x%X\n", ret); 133 134 return ret; 135 } 136 #endif /* CONFIG_IMX_OPTEE_DEK_ENCAP */ 137 #ifdef CONFIG_IMX_SECO_DEK_ENCAP 138 139 #define DEK_BLOB_KEY_ID 0x0 140 141 #define AHAB_PRIVATE_KEY 0x81 142 #define AHAB_VERSION 0x00 143 #define AHAB_MODE_CBC 0x67 144 #define AHAB_ALG_AES 0x55 145 #define AHAB_128_AES_KEY 0x10 146 #define AHAB_192_AES_KEY 0x18 147 #define AHAB_256_AES_KEY 0x20 148 #define AHAB_FLAG_KEK 0x80 149 #define AHAB_DEK_BLOB 0x01 150 151 #define DEK_BLOB_HDR_SIZE 8 152 #define SECO_PT 2U 153 154 static int blob_encap_dek(u32 src_addr, u32 dst_addr, u32 len) 155 { 156 sc_err_t err; 157 sc_rm_mr_t mr_input, mr_output; 158 struct generate_key_blob_hdr hdr; 159 u8 in_size, out_size; 160 u8 *src_ptr, *dst_ptr; 161 int ret = 0; 162 int i; 163 164 /* Set sizes */ 165 in_size = sizeof(struct generate_key_blob_hdr) + len / 8; 166 out_size = BLOB_SIZE(len / 8) + DEK_BLOB_HDR_SIZE; 167 168 /* Get src and dst virtual addresses */ 169 src_ptr = map_sysmem(src_addr, in_size); 170 dst_ptr = map_sysmem(dst_addr, out_size); 171 172 /* Check addr input */ 173 if (!(src_ptr && dst_ptr)) { 174 debug("src_addr or dst_addr invalid\n"); 175 return -1; 176 } 177 178 /* Build key header */ 179 hdr.version = AHAB_VERSION; 180 hdr.length_lsb = sizeof(struct generate_key_blob_hdr) + len / 8; 181 hdr.length_msb = 0x00; 182 hdr.tag = AHAB_PRIVATE_KEY; 183 hdr.flags = AHAB_DEK_BLOB; 184 hdr.algorithm = AHAB_ALG_AES; 185 hdr.mode = AHAB_MODE_CBC; 186 187 switch (len) { 188 case 128: 189 hdr.size = AHAB_128_AES_KEY; 190 break; 191 case 192: 192 hdr.size = AHAB_192_AES_KEY; 193 break; 194 case 256: 195 hdr.size = AHAB_256_AES_KEY; 196 break; 197 default: 198 /* Not supported */ 199 debug("Invalid DEK size. Valid sizes are 128, 192 and 256b\n"); 200 return -1; 201 } 202 203 /* Build input message */ 204 memmove((void *)(src_ptr + sizeof(struct generate_key_blob_hdr)), 205 (void *)src_ptr, len / 8); 206 memcpy((void *)src_ptr, (void *)&hdr, 207 sizeof(struct generate_key_blob_hdr)); 208 209 /* Flush the cache before triggering the CAAM DMA */ 210 flush_dcache_range(src_addr, src_addr + in_size); 211 212 /* Find input memory region */ 213 err = sc_rm_find_memreg((-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((-1), &mr_output, dst_addr & ~(CONFIG_SYS_CACHELINE_SIZE - 1), 222 ALIGN(dst_addr + out_size, CONFIG_SYS_CACHELINE_SIZE)); 223 if (err) { 224 printf("Error: find memory region 0x%X\n", dst_addr); 225 return -ENOMEM; 226 } 227 228 /* Set memory region permissions for SECO */ 229 err = sc_rm_set_memreg_permissions(-1, mr_input, SECO_PT, 230 SC_RM_PERM_FULL); 231 if (err) { 232 printf("Set permission failed for input memory region\n"); 233 ret = -EPERM; 234 goto error; 235 } 236 237 err = sc_rm_set_memreg_permissions(-1, mr_output, SECO_PT, 238 SC_RM_PERM_FULL); 239 if (err) { 240 printf("Set permission failed for output memory region\n"); 241 ret = -EPERM; 242 goto error; 243 } 244 245 /* Flush output data before SECO operation */ 246 flush_dcache_range((ulong)dst_ptr, (ulong)(dst_ptr + 247 roundup(out_size, ARCH_DMA_MINALIGN))); 248 249 /* Generate DEK blob */ 250 err = sc_seco_gen_key_blob((-1), 0x0, src_addr, dst_addr, out_size); 251 if (err) { 252 ret = -EPERM; 253 goto error; 254 } 255 256 /* Invalidate output buffer */ 257 invalidate_dcache_range((ulong)dst_ptr, (ulong)(dst_ptr + 258 roundup(out_size, ARCH_DMA_MINALIGN))); 259 260 printf("DEK Blob\n"); 261 for (i = 0; i < DEK_BLOB_HDR_SIZE + BLOB_SIZE(len / 8); i++) 262 printf("%02X", dst_ptr[i]); 263 printf("\n"); 264 265 error: 266 /* Remove memory region permission to SECO */ 267 err = sc_rm_set_memreg_permissions(-1, mr_input, SECO_PT, 268 SC_RM_PERM_NONE); 269 if (err) { 270 printf("Error: remove permission failed for input\n"); 271 ret = -EPERM; 272 } 273 274 err = sc_rm_set_memreg_permissions(-1, mr_output, SECO_PT, 275 SC_RM_PERM_NONE); 276 if (err) { 277 printf("Error: remove permission failed for output\n"); 278 ret = -EPERM; 279 } 280 281 return ret; 282 } 283 #endif /* CONFIG_IMX_SECO_DEK_ENCAP */ 284 285 /** 286 * do_dek_blob() - Handle the "dek_blob" command-line command 287 * @cmdtp: Command data struct pointer 288 * @flag: Command flag 289 * @argc: Command-line argument count 290 * @argv: Array of command-line arguments 291 * 292 * Returns zero on success, CMD_RET_USAGE in case of misuse and negative 293 * on error. 294 */ 295 static int do_dek_blob(struct cmd_tbl *cmdtp, int flag, int argc, 296 char *const argv[]) 297 { 298 uint32_t src_addr, dst_addr, len; 299 300 if (argc != 4) 301 return CMD_RET_USAGE; 302 303 src_addr = simple_strtoul(argv[1], NULL, 16); 304 dst_addr = simple_strtoul(argv[2], NULL, 16); 305 len = simple_strtoul(argv[3], NULL, 10); 306 307 return blob_encap_dek(src_addr, dst_addr, len); 308 } 309 310 /***************************************************/ 311 static char dek_blob_help_text[] = 312 "src dst len - Encapsulate and create blob of data\n" 313 " $len bits long at address $src and\n" 314 " store the result at address $dst.\n"; 315 316 U_BOOT_CMD( 317 dek_blob, 4, 1, do_dek_blob, 318 "Data Encryption Key blob encapsulation", 319 dek_blob_help_text 320 ); 321