Commit c6f1a810082bfd1934f4efe54ffaa607e504112e

Authored by Ye Li
1 parent 58a48836d8

MLK-20933 imx8: ahab: Check image address before using it

Check the OS container image address is belonged to valiad DRAM memory
before accessing it to avoid u-boot crash on invalid address.

Also refine the error print.

Signed-off-by: Ye Li <ye.li@nxp.com>
Reviewed-by: Peng Fan <peng.fan@nxp.com>
(cherry picked from commit f40dc07b3df9ad71ea501c77a19924361b133de7)

Showing 1 changed file with 31 additions and 8 deletions Inline Diff

arch/arm/mach-imx/imx8/ahab.c
1 /* 1 /*
2 * Copyright 2018 NXP 2 * Copyright 2018 NXP
3 * 3 *
4 * SPDX-License-Identifier: GPL-2.0+ 4 * SPDX-License-Identifier: GPL-2.0+
5 * 5 *
6 */ 6 */
7 7
8 #include <common.h> 8 #include <common.h>
9 #include <errno.h> 9 #include <errno.h>
10 #include <asm/io.h> 10 #include <asm/io.h>
11 #include <asm/mach-imx/sci/sci.h> 11 #include <asm/mach-imx/sci/sci.h>
12 #include <asm/mach-imx/sys_proto.h> 12 #include <asm/mach-imx/sys_proto.h>
13 #include <asm/arch-imx/cpu.h> 13 #include <asm/arch-imx/cpu.h>
14 #include <asm/arch/sys_proto.h> 14 #include <asm/arch/sys_proto.h>
15 #include <asm/arch/cpu.h> 15 #include <asm/arch/cpu.h>
16 #include <asm/arch/image.h> 16 #include <asm/arch/image.h>
17 #include <console.h> 17 #include <console.h>
18 18
19 DECLARE_GLOBAL_DATA_PTR; 19 DECLARE_GLOBAL_DATA_PTR;
20 20
21 #define SEC_SECURE_RAM_BASE (0x31800000UL) 21 #define SEC_SECURE_RAM_BASE (0x31800000UL)
22 #define SEC_SECURE_RAM_END_BASE (SEC_SECURE_RAM_BASE + 0xFFFFUL) 22 #define SEC_SECURE_RAM_END_BASE (SEC_SECURE_RAM_BASE + 0xFFFFUL)
23 #define SECO_LOCAL_SEC_SEC_SECURE_RAM_BASE (0x60000000UL) 23 #define SECO_LOCAL_SEC_SEC_SECURE_RAM_BASE (0x60000000UL)
24 24
25 #define SECO_PT 2U 25 #define SECO_PT 2U
26 26
27 static inline bool check_in_dram(ulong addr)
28 {
29 int i;
30 bd_t *bd = gd->bd;
31
32 for (i = 0; i < CONFIG_NR_DRAM_BANKS; ++i) {
33 if (bd->bi_dram[i].size) {
34 if (addr >= bd->bi_dram[i].start &&
35 addr < (bd->bi_dram[i].start + bd->bi_dram[i].size))
36 return true;
37 }
38 }
39
40 return false;
41 }
42
27 int authenticate_os_container(ulong addr) 43 int authenticate_os_container(ulong addr)
28 { 44 {
29 struct container_hdr *phdr; 45 struct container_hdr *phdr;
30 int i, ret = 0; 46 int i, ret = 0;
31 sc_ipc_t ipcHndl = gd->arch.ipc_channel_handle; 47 sc_ipc_t ipcHndl = gd->arch.ipc_channel_handle;
32 sc_err_t err; 48 sc_err_t err;
33 sc_rm_mr_t mr; 49 sc_rm_mr_t mr;
34 sc_faddr_t start, end; 50 sc_faddr_t start, end;
35 uint16_t length; 51 uint16_t length;
36 52
37 if (addr % 4) 53 if (addr % 4) {
54 puts("Error: Image's address is not 4 byte aligned\n");
38 return -EINVAL; 55 return -EINVAL;
56 }
39 57
58 if (!check_in_dram(addr)) {
59 puts("Error: Image's address is invalid \n");
60 return -EINVAL;
61 }
62
40 phdr = (struct container_hdr *)addr; 63 phdr = (struct container_hdr *)addr;
41 if (phdr->tag != 0x87 && phdr->version != 0x0) { 64 if (phdr->tag != 0x87 && phdr->version != 0x0) {
42 printf("Wrong container header\n"); 65 printf("Error: Wrong container header\n");
43 return -EFAULT; 66 return -EFAULT;
44 } 67 }
45 68
46 if (!phdr->num_images) { 69 if (!phdr->num_images) {
47 printf("Wrong container, no image found\n"); 70 printf("Error: Wrong container, no image found\n");
48 return -EFAULT; 71 return -EFAULT;
49 } 72 }
50 73
51 length = phdr->length_lsb + (phdr->length_msb << 8); 74 length = phdr->length_lsb + (phdr->length_msb << 8);
52 75
53 debug("container length %u\n", length); 76 debug("container length %u\n", length);
54 memcpy((void *)SEC_SECURE_RAM_BASE, (const void *)addr, ALIGN(length, CONFIG_SYS_CACHELINE_SIZE)); 77 memcpy((void *)SEC_SECURE_RAM_BASE, (const void *)addr, ALIGN(length, CONFIG_SYS_CACHELINE_SIZE));
55 78
56 err = sc_seco_authenticate(ipcHndl, SC_MISC_AUTH_CONTAINER, SECO_LOCAL_SEC_SEC_SECURE_RAM_BASE); 79 err = sc_seco_authenticate(ipcHndl, SC_MISC_AUTH_CONTAINER, SECO_LOCAL_SEC_SEC_SECURE_RAM_BASE);
57 if (err) { 80 if (err) {
58 printf("authenticate container hdr failed, return %d\n", err); 81 printf("Error: authenticate container hdr failed, return %d\n", err);
59 ret = -EIO; 82 ret = -EIO;
60 goto exit; 83 goto exit;
61 } 84 }
62 85
63 /* Copy images to dest address */ 86 /* Copy images to dest address */
64 for (i=0; i < phdr->num_images; i++) { 87 for (i=0; i < phdr->num_images; i++) {
65 struct boot_img_t *img = (struct boot_img_t *)(addr + sizeof(struct container_hdr) + i * sizeof(struct boot_img_t)); 88 struct boot_img_t *img = (struct boot_img_t *)(addr + sizeof(struct container_hdr) + i * sizeof(struct boot_img_t));
66 89
67 debug("img %d, dst 0x%llx, src 0x%lx, size 0x%x\n", i, img->dst, img->offset + addr, img->size); 90 debug("img %d, dst 0x%llx, src 0x%lx, size 0x%x\n", i, img->dst, img->offset + addr, img->size);
68 91
69 memcpy((void *)img->dst, (const void *)(img->offset + addr), img->size); 92 memcpy((void *)img->dst, (const void *)(img->offset + addr), img->size);
70 flush_dcache_range(img->dst & ~(CONFIG_SYS_CACHELINE_SIZE - 1), 93 flush_dcache_range(img->dst & ~(CONFIG_SYS_CACHELINE_SIZE - 1),
71 ALIGN(img->dst + img->size, CONFIG_SYS_CACHELINE_SIZE)); 94 ALIGN(img->dst + img->size, CONFIG_SYS_CACHELINE_SIZE));
72 95
73 /* Find the memreg and set permission for seco pt */ 96 /* Find the memreg and set permission for seco pt */
74 err = sc_rm_find_memreg(ipcHndl, &mr, 97 err = sc_rm_find_memreg(ipcHndl, &mr,
75 img->dst & ~(CONFIG_SYS_CACHELINE_SIZE - 1), ALIGN(img->dst + img->size, CONFIG_SYS_CACHELINE_SIZE)); 98 img->dst & ~(CONFIG_SYS_CACHELINE_SIZE - 1), ALIGN(img->dst + img->size, CONFIG_SYS_CACHELINE_SIZE));
76 99
77 if (err) { 100 if (err) {
78 printf("can't find memreg for image load address %d, error %d\n", i, err); 101 printf("Error: can't find memreg for image load address %d, error %d\n", i, err);
79 ret = -ENOMEM; 102 ret = -ENOMEM;
80 goto exit; 103 goto exit;
81 } 104 }
82 105
83 err = sc_rm_get_memreg_info(ipcHndl, mr, &start, &end); 106 err = sc_rm_get_memreg_info(ipcHndl, mr, &start, &end);
84 if (!err) 107 if (!err)
85 debug("memreg %u 0x%llx -- 0x%llx\n", mr, start, end); 108 debug("memreg %u 0x%llx -- 0x%llx\n", mr, start, end);
86 109
87 err = sc_rm_set_memreg_permissions(ipcHndl, mr, SECO_PT, SC_RM_PERM_FULL); 110 err = sc_rm_set_memreg_permissions(ipcHndl, mr, SECO_PT, SC_RM_PERM_FULL);
88 if (err) { 111 if (err) {
89 printf("set permission failed for img %d, error %d\n", i, err); 112 printf("Error: set permission failed for img %d, error %d\n", i, err);
90 ret = -EPERM; 113 ret = -EPERM;
91 goto exit; 114 goto exit;
92 } 115 }
93 116
94 err = sc_seco_authenticate(ipcHndl, SC_MISC_VERIFY_IMAGE, (1 << i)); 117 err = sc_seco_authenticate(ipcHndl, SC_MISC_VERIFY_IMAGE, (1 << i));
95 if (err) { 118 if (err) {
96 printf("authenticate img %d failed, return %d\n", i, err); 119 printf("Error: authenticate img %d failed, return %d\n", i, err);
97 ret = -EIO; 120 ret = -EIO;
98 } 121 }
99 122
100 err = sc_rm_set_memreg_permissions(ipcHndl, mr, SECO_PT, SC_RM_PERM_NONE); 123 err = sc_rm_set_memreg_permissions(ipcHndl, mr, SECO_PT, SC_RM_PERM_NONE);
101 if (err) { 124 if (err) {
102 printf("remove permission failed for img %d, error %d\n", i, err); 125 printf("Error: remove permission failed for img %d, error %d\n", i, err);
103 ret = -EPERM; 126 ret = -EPERM;
104 } 127 }
105 128
106 if (ret) 129 if (ret)
107 goto exit; 130 goto exit;
108 } 131 }
109 132
110 exit: 133 exit:
111 sc_seco_authenticate(ipcHndl, SC_MISC_REL_CONTAINER, 0); 134 sc_seco_authenticate(ipcHndl, SC_MISC_REL_CONTAINER, 0);
112 135
113 return ret; 136 return ret;
114 } 137 }
115 138
116 139
117 static int do_authenticate(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) 140 static int do_authenticate(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
118 { 141 {
119 ulong addr; 142 ulong addr;
120 if (argc < 2) 143 if (argc < 2)
121 return CMD_RET_USAGE; 144 return CMD_RET_USAGE;
122 145
123 addr = simple_strtoul(argv[1], NULL, 16); 146 addr = simple_strtoul(argv[1], NULL, 16);
124 147
125 printf("Authenticate OS container at 0x%lx \n", addr); 148 printf("Authenticate OS container at 0x%lx \n", addr);
126 149
127 if (authenticate_os_container(addr)) 150 if (authenticate_os_container(addr))
128 return CMD_RET_FAILURE; 151 return CMD_RET_FAILURE;
129 152
130 return CMD_RET_SUCCESS; 153 return CMD_RET_SUCCESS;
131 } 154 }
132 155
133 static void display_life_cycle(uint16_t lc) 156 static void display_life_cycle(uint16_t lc)
134 { 157 {
135 printf("Lifecycle: 0x%04X, ", lc); 158 printf("Lifecycle: 0x%04X, ", lc);
136 switch (lc) { 159 switch (lc) {
137 case 0x1: 160 case 0x1:
138 printf("Pristine\n\n"); 161 printf("Pristine\n\n");
139 break; 162 break;
140 case 0x2: 163 case 0x2:
141 printf("Fab\n\n"); 164 printf("Fab\n\n");
142 break; 165 break;
143 case 0x8: 166 case 0x8:
144 printf("Open\n\n"); 167 printf("Open\n\n");
145 break; 168 break;
146 case 0x20: 169 case 0x20:
147 printf("NXP closed\n\n"); 170 printf("NXP closed\n\n");
148 break; 171 break;
149 case 0x80: 172 case 0x80:
150 printf("OEM closed\n\n"); 173 printf("OEM closed\n\n");
151 break; 174 break;
152 case 0x100: 175 case 0x100:
153 printf("Partial field return\n\n"); 176 printf("Partial field return\n\n");
154 break; 177 break;
155 case 0x200: 178 case 0x200:
156 printf("Full field return\n\n"); 179 printf("Full field return\n\n");
157 break; 180 break;
158 case 0x400: 181 case 0x400:
159 printf("No return\n\n"); 182 printf("No return\n\n");
160 break; 183 break;
161 default: 184 default:
162 printf("Unknown\n\n"); 185 printf("Unknown\n\n");
163 break; 186 break;
164 } 187 }
165 } 188 }
166 189
167 #define AHAB_AUTH_CONTAINER_REQ 0x87 190 #define AHAB_AUTH_CONTAINER_REQ 0x87
168 #define AHAB_VERIFY_IMAGE_REQ 0x88 191 #define AHAB_VERIFY_IMAGE_REQ 0x88
169 192
170 #define AHAB_NO_AUTHENTICATION_IND 0xee 193 #define AHAB_NO_AUTHENTICATION_IND 0xee
171 #define AHAB_BAD_KEY_HASH_IND 0xfa 194 #define AHAB_BAD_KEY_HASH_IND 0xfa
172 #define AHAB_INVALID_KEY_IND 0xf9 195 #define AHAB_INVALID_KEY_IND 0xf9
173 #define AHAB_BAD_SIGNATURE_IND 0xf0 196 #define AHAB_BAD_SIGNATURE_IND 0xf0
174 #define AHAB_BAD_HASH_IND 0xf1 197 #define AHAB_BAD_HASH_IND 0xf1
175 198
176 static void display_ahab_auth_event(uint32_t event) 199 static void display_ahab_auth_event(uint32_t event)
177 { 200 {
178 uint8_t cmd = (event >> 16) & 0xff; 201 uint8_t cmd = (event >> 16) & 0xff;
179 uint8_t resp_ind =(event >> 8) & 0xff; 202 uint8_t resp_ind =(event >> 8) & 0xff;
180 203
181 switch (cmd) { 204 switch (cmd) {
182 case AHAB_AUTH_CONTAINER_REQ: 205 case AHAB_AUTH_CONTAINER_REQ:
183 printf("\tCMD = AHAB_AUTH_CONTAINER_REQ (0x%02X)\n", cmd); 206 printf("\tCMD = AHAB_AUTH_CONTAINER_REQ (0x%02X)\n", cmd);
184 printf("\tIND = "); 207 printf("\tIND = ");
185 break; 208 break;
186 case AHAB_VERIFY_IMAGE_REQ: 209 case AHAB_VERIFY_IMAGE_REQ:
187 printf("\tCMD = AHAB_VERIFY_IMAGE_REQ (0x%02X)\n", cmd); 210 printf("\tCMD = AHAB_VERIFY_IMAGE_REQ (0x%02X)\n", cmd);
188 printf("\tIND = "); 211 printf("\tIND = ");
189 break; 212 break;
190 default: 213 default:
191 return; 214 return;
192 } 215 }
193 216
194 switch (resp_ind) { 217 switch (resp_ind) {
195 case AHAB_NO_AUTHENTICATION_IND: 218 case AHAB_NO_AUTHENTICATION_IND:
196 printf("AHAB_NO_AUTHENTICATION_IND (0x%02X)\n\n", resp_ind); 219 printf("AHAB_NO_AUTHENTICATION_IND (0x%02X)\n\n", resp_ind);
197 break; 220 break;
198 case AHAB_BAD_KEY_HASH_IND: 221 case AHAB_BAD_KEY_HASH_IND:
199 printf("AHAB_BAD_KEY_HASH_IND (0x%02X)\n\n", resp_ind); 222 printf("AHAB_BAD_KEY_HASH_IND (0x%02X)\n\n", resp_ind);
200 break; 223 break;
201 case AHAB_INVALID_KEY_IND: 224 case AHAB_INVALID_KEY_IND:
202 printf("AHAB_INVALID_KEY_IND (0x%02X)\n\n", resp_ind); 225 printf("AHAB_INVALID_KEY_IND (0x%02X)\n\n", resp_ind);
203 break; 226 break;
204 case AHAB_BAD_SIGNATURE_IND: 227 case AHAB_BAD_SIGNATURE_IND:
205 printf("AHAB_BAD_SIGNATURE_IND (0x%02X)\n\n", resp_ind); 228 printf("AHAB_BAD_SIGNATURE_IND (0x%02X)\n\n", resp_ind);
206 break; 229 break;
207 case AHAB_BAD_HASH_IND: 230 case AHAB_BAD_HASH_IND:
208 printf("AHAB_BAD_HASH_IND (0x%02X)\n\n", resp_ind); 231 printf("AHAB_BAD_HASH_IND (0x%02X)\n\n", resp_ind);
209 break; 232 break;
210 default: 233 default:
211 printf("Unknown Indicator (0x%02X)\n\n", resp_ind); 234 printf("Unknown Indicator (0x%02X)\n\n", resp_ind);
212 break; 235 break;
213 } 236 }
214 } 237 }
215 238
216 239
217 static int do_ahab_status(cmd_tbl_t *cmdtp, int flag, int argc, 240 static int do_ahab_status(cmd_tbl_t *cmdtp, int flag, int argc,
218 char * const argv[]) 241 char * const argv[])
219 { 242 {
220 sc_err_t err; 243 sc_err_t err;
221 uint8_t idx = 0U; 244 uint8_t idx = 0U;
222 uint32_t event; 245 uint32_t event;
223 uint16_t lc; 246 uint16_t lc;
224 sc_ipc_t ipcHndl = gd->arch.ipc_channel_handle; 247 sc_ipc_t ipcHndl = gd->arch.ipc_channel_handle;
225 248
226 err = sc_seco_chip_info(ipcHndl, &lc, NULL, NULL, NULL); 249 err = sc_seco_chip_info(ipcHndl, &lc, NULL, NULL, NULL);
227 if (err != SC_ERR_NONE) { 250 if (err != SC_ERR_NONE) {
228 printf("Error in get lifecycle\n"); 251 printf("Error in get lifecycle\n");
229 return -EIO; 252 return -EIO;
230 } 253 }
231 254
232 display_life_cycle(lc); 255 display_life_cycle(lc);
233 256
234 err = sc_seco_get_event(ipcHndl, idx, &event); 257 err = sc_seco_get_event(ipcHndl, idx, &event);
235 while (err == SC_ERR_NONE) { 258 while (err == SC_ERR_NONE) {
236 printf ("SECO Event[%u] = 0x%08X\n", idx, event); 259 printf ("SECO Event[%u] = 0x%08X\n", idx, event);
237 display_ahab_auth_event(event); 260 display_ahab_auth_event(event);
238 261
239 idx++; 262 idx++;
240 err = sc_seco_get_event(ipcHndl, idx, &event); 263 err = sc_seco_get_event(ipcHndl, idx, &event);
241 } 264 }
242 265
243 if (idx == 0) 266 if (idx == 0)
244 printf("No SECO Events Found!\n\n"); 267 printf("No SECO Events Found!\n\n");
245 268
246 return 0; 269 return 0;
247 } 270 }
248 271
249 static int confirm_close(void) 272 static int confirm_close(void)
250 { 273 {
251 puts("Warning: Please ensure your sample is in NXP closed state, " 274 puts("Warning: Please ensure your sample is in NXP closed state, "
252 "OEM SRK hash has been fused, \n" 275 "OEM SRK hash has been fused, \n"
253 " and you are able to boot a signed image successfully " 276 " and you are able to boot a signed image successfully "
254 "without any SECO events reported.\n" 277 "without any SECO events reported.\n"
255 " If not, your sample will be unrecoverable.\n" 278 " If not, your sample will be unrecoverable.\n"
256 "\nReally perform this operation? <y/N>\n"); 279 "\nReally perform this operation? <y/N>\n");
257 280
258 if (confirm_yesno()) 281 if (confirm_yesno())
259 return 1; 282 return 1;
260 283
261 puts("Ahab close aborted\n"); 284 puts("Ahab close aborted\n");
262 return 0; 285 return 0;
263 } 286 }
264 287
265 static int do_ahab_close(cmd_tbl_t *cmdtp, int flag, int argc, 288 static int do_ahab_close(cmd_tbl_t *cmdtp, int flag, int argc,
266 char * const argv[]) 289 char * const argv[])
267 { 290 {
268 sc_err_t err; 291 sc_err_t err;
269 uint16_t lc; 292 uint16_t lc;
270 sc_ipc_t ipcHndl = gd->arch.ipc_channel_handle; 293 sc_ipc_t ipcHndl = gd->arch.ipc_channel_handle;
271 294
272 if (!confirm_close()) 295 if (!confirm_close())
273 return -EACCES; 296 return -EACCES;
274 297
275 err = sc_seco_chip_info(ipcHndl, &lc, NULL, NULL, NULL); 298 err = sc_seco_chip_info(ipcHndl, &lc, NULL, NULL, NULL);
276 if (err != SC_ERR_NONE) { 299 if (err != SC_ERR_NONE) {
277 printf("Error in get lifecycle\n"); 300 printf("Error in get lifecycle\n");
278 return -EIO; 301 return -EIO;
279 } 302 }
280 303
281 if (lc != 0x20) { 304 if (lc != 0x20) {
282 printf("Current lifecycle is NOT NXP closed, can't move to OEM closed\n"); 305 printf("Current lifecycle is NOT NXP closed, can't move to OEM closed\n");
283 display_life_cycle(lc); 306 display_life_cycle(lc);
284 return -EPERM; 307 return -EPERM;
285 } 308 }
286 309
287 err = sc_seco_forward_lifecycle(ipcHndl, 16); 310 err = sc_seco_forward_lifecycle(ipcHndl, 16);
288 if (err != SC_ERR_NONE) { 311 if (err != SC_ERR_NONE) {
289 printf("Error in forward lifecycle to OEM closed\n"); 312 printf("Error in forward lifecycle to OEM closed\n");
290 return -EIO; 313 return -EIO;
291 } 314 }
292 315
293 printf("Change to OEM closed successfully\n"); 316 printf("Change to OEM closed successfully\n");
294 317
295 return 0; 318 return 0;
296 } 319 }
297 320
298 U_BOOT_CMD( 321 U_BOOT_CMD(
299 auth_cntr, CONFIG_SYS_MAXARGS, 1, do_authenticate, 322 auth_cntr, CONFIG_SYS_MAXARGS, 1, do_authenticate,
300 "autenticate OS container via AHAB", 323 "autenticate OS container via AHAB",
301 "addr\n" 324 "addr\n"
302 "addr - OS container hex address\n" 325 "addr - OS container hex address\n"
303 ); 326 );
304 327
305 U_BOOT_CMD( 328 U_BOOT_CMD(
306 ahab_status, CONFIG_SYS_MAXARGS, 1, do_ahab_status, 329 ahab_status, CONFIG_SYS_MAXARGS, 1, do_ahab_status,
307 "display AHAB lifecycle and events from seco", 330 "display AHAB lifecycle and events from seco",
308 "" 331 ""
309 ); 332 );
310 333
311 U_BOOT_CMD( 334 U_BOOT_CMD(
312 ahab_close, CONFIG_SYS_MAXARGS, 1, do_ahab_close, 335 ahab_close, CONFIG_SYS_MAXARGS, 1, do_ahab_close,
313 "Change AHAB lifecycle to OEM closed", 336 "Change AHAB lifecycle to OEM closed",
314 "" 337 ""
315 ); 338 );
316 339