1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Copyright (c) 2013, Google Inc.
4  *
5  * (C) Copyright 2008 Semihalf
6  *
7  * (C) Copyright 2000-2006
8  * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
9  */
10 
11 #define LOG_CATEGORY LOGC_BOOT
12 
13 #ifdef USE_HOSTCC
14 #include "mkimage.h"
15 #include <time.h>
16 #include <linux/libfdt.h>
17 #include <u-boot/crc.h>
18 #include <linux/kconfig.h>
19 #else
20 #include <linux/compiler.h>
21 #include <linux/sizes.h>
22 #include <errno.h>
23 #include <log.h>
24 #include <mapmem.h>
25 #include <asm/io.h>
26 #include <malloc.h>
27 #include <memalign.h>
28 #include <asm/global_data.h>
29 #ifdef CONFIG_DM_HASH
30 #include <dm.h>
31 #include <u-boot/hash.h>
32 #endif
33 DECLARE_GLOBAL_DATA_PTR;
34 #endif /* !USE_HOSTCC*/
35 
36 #include <bootm.h>
37 #include <image.h>
38 #include <bootstage.h>
39 #include <upl.h>
40 #include <u-boot/crc.h>
41 
42 /*****************************************************************************/
43 /* New uImage format routines */
44 /*****************************************************************************/
45 #ifndef USE_HOSTCC
fit_parse_spec(const char * spec,char sepc,ulong addr_curr,ulong * addr,const char ** name)46 static int fit_parse_spec(const char *spec, char sepc, ulong addr_curr,
47 		ulong *addr, const char **name)
48 {
49 	const char *sep;
50 
51 	*addr = addr_curr;
52 	*name = NULL;
53 
54 	sep = strchr(spec, sepc);
55 	if (sep) {
56 		if (sep - spec > 0)
57 			*addr = hextoul(spec, NULL);
58 
59 		*name = sep + 1;
60 		return 1;
61 	}
62 
63 	return 0;
64 }
65 
66 /**
67  * fit_parse_conf - parse FIT configuration spec
68  * @spec: input string, containing configuration spec
69  * @add_curr: current image address (to be used as a possible default)
70  * @addr: pointer to a ulong variable, will hold FIT image address of a given
71  * configuration
72  * @conf_name double pointer to a char, will hold pointer to a configuration
73  * unit name
74  *
75  * fit_parse_conf() expects configuration spec in the form of [<addr>]#<conf>,
76  * where <addr> is a FIT image address that contains configuration
77  * with a <conf> unit name.
78  *
79  * Address part is optional, and if omitted default add_curr will
80  * be used instead.
81  *
82  * returns:
83  *     1 if spec is a valid configuration string,
84  *     addr and conf_name are set accordingly
85  *     0 otherwise
86  */
fit_parse_conf(const char * spec,ulong addr_curr,ulong * addr,const char ** conf_name)87 int fit_parse_conf(const char *spec, ulong addr_curr,
88 		ulong *addr, const char **conf_name)
89 {
90 	return fit_parse_spec(spec, '#', addr_curr, addr, conf_name);
91 }
92 
93 /**
94  * fit_parse_subimage - parse FIT subimage spec
95  * @spec: input string, containing subimage spec
96  * @add_curr: current image address (to be used as a possible default)
97  * @addr: pointer to a ulong variable, will hold FIT image address of a given
98  * subimage
99  * @image_name: double pointer to a char, will hold pointer to a subimage name
100  *
101  * fit_parse_subimage() expects subimage spec in the form of
102  * [<addr>]:<subimage>, where <addr> is a FIT image address that contains
103  * subimage with a <subimg> unit name.
104  *
105  * Address part is optional, and if omitted default add_curr will
106  * be used instead.
107  *
108  * returns:
109  *     1 if spec is a valid subimage string,
110  *     addr and image_name are set accordingly
111  *     0 otherwise
112  */
fit_parse_subimage(const char * spec,ulong addr_curr,ulong * addr,const char ** image_name)113 int fit_parse_subimage(const char *spec, ulong addr_curr,
114 		ulong *addr, const char **image_name)
115 {
116 	return fit_parse_spec(spec, ':', addr_curr, addr, image_name);
117 }
118 #endif /* !USE_HOSTCC */
119 
120 #ifdef USE_HOSTCC
121 /* Host tools use these implementations for Cipher and Signature support */
122 static void *host_blob;
123 
image_set_host_blob(void * blob)124 void image_set_host_blob(void *blob)
125 {
126 	host_blob = blob;
127 }
128 
image_get_host_blob(void)129 void *image_get_host_blob(void)
130 {
131 	return host_blob;
132 }
133 #endif /* USE_HOSTCC */
134 
fit_get_debug(const void * fit,int noffset,char * prop_name,int err)135 static void fit_get_debug(const void *fit, int noffset,
136 		char *prop_name, int err)
137 {
138 	debug("Can't get '%s' property from FIT 0x%08lx, node: offset %d, name %s (%s)\n",
139 	      prop_name, (ulong)fit, noffset, fit_get_name(fit, noffset, NULL),
140 	      fdt_strerror(err));
141 }
142 
143 /**
144  * fit_get_subimage_count - get component (sub-image) count
145  * @fit: pointer to the FIT format image header
146  * @images_noffset: offset of images node
147  *
148  * returns:
149  *     number of image components
150  */
fit_get_subimage_count(const void * fit,int images_noffset)151 int fit_get_subimage_count(const void *fit, int images_noffset)
152 {
153 	int noffset;
154 	int ndepth;
155 	int count = 0;
156 
157 	/* Process its subnodes, print out component images details */
158 	for (ndepth = 0, count = 0,
159 		noffset = fdt_next_node(fit, images_noffset, &ndepth);
160 	     (noffset >= 0) && (ndepth > 0);
161 	     noffset = fdt_next_node(fit, noffset, &ndepth)) {
162 		if (ndepth == 1) {
163 			count++;
164 		}
165 	}
166 
167 	return count;
168 }
169 
170 /**
171  * fit_image_print_data() - prints out the hash node details
172  * @fit: pointer to the FIT format image header
173  * @noffset: offset of the hash node
174  * @p: pointer to prefix string
175  * @type: Type of information to print ("hash" or "sign")
176  *
177  * fit_image_print_data() lists properties for the processed hash node
178  *
179  * This function avoid using puts() since it prints a newline on the host
180  * but does not in U-Boot.
181  *
182  * returns:
183  *     no returned results
184  */
fit_image_print_data(const void * fit,int noffset,const char * p,const char * type)185 static void fit_image_print_data(const void *fit, int noffset, const char *p,
186 				 const char *type)
187 {
188 	const char *keyname;
189 	uint8_t *value;
190 	int value_len;
191 	const char *algo;
192 	const char *padding;
193 	bool required;
194 	int ret, i;
195 
196 	debug("%s  %s node:    '%s'\n", p, type,
197 	      fit_get_name(fit, noffset, NULL));
198 	printf("%s  %s algo:    ", p, type);
199 	if (fit_image_hash_get_algo(fit, noffset, &algo)) {
200 		printf("invalid/unsupported\n");
201 		return;
202 	}
203 	printf("%s", algo);
204 	keyname = fdt_getprop(fit, noffset, FIT_KEY_HINT, NULL);
205 	required = fdt_getprop(fit, noffset, FIT_KEY_REQUIRED, NULL) != NULL;
206 	if (keyname)
207 		printf(":%s", keyname);
208 	if (required)
209 		printf(" (required)");
210 	printf("\n");
211 
212 	padding = fdt_getprop(fit, noffset, "padding", NULL);
213 	if (padding)
214 		printf("%s  %s padding: %s\n", p, type, padding);
215 
216 	ret = fit_image_hash_get_value(fit, noffset, &value,
217 				       &value_len);
218 	printf("%s  %s value:   ", p, type);
219 	if (ret) {
220 		printf("unavailable\n");
221 	} else {
222 		for (i = 0; i < value_len; i++)
223 			printf("%02x", value[i]);
224 		printf("\n");
225 	}
226 
227 	debug("%s  %s len:     %d\n", p, type, value_len);
228 
229 	/* Signatures have a time stamp */
230 	if (IMAGE_ENABLE_TIMESTAMP && keyname) {
231 		time_t timestamp;
232 
233 		printf("%s  Timestamp:    ", p);
234 		if (fit_get_timestamp(fit, noffset, &timestamp))
235 			printf("unavailable\n");
236 		else
237 			genimg_print_time(timestamp);
238 	}
239 }
240 
241 /**
242  * fit_image_print_verification_data() - prints out the hash/signature details
243  * @fit: pointer to the FIT format image header
244  * @noffset: offset of the hash or signature node
245  * @p: pointer to prefix string
246  *
247  * This lists properties for the processed hash node
248  *
249  * returns:
250  *     no returned results
251  */
fit_image_print_verification_data(const void * fit,int noffset,const char * p)252 static void fit_image_print_verification_data(const void *fit, int noffset,
253 					      const char *p)
254 {
255 	const char *name;
256 
257 	/*
258 	 * Check subnode name, must be equal to "hash" or "signature".
259 	 * Multiple hash/signature nodes require unique unit node
260 	 * names, e.g. hash-1, hash-2, signature-1, signature-2, etc.
261 	 */
262 	name = fit_get_name(fit, noffset, NULL);
263 	if (!strncmp(name, FIT_HASH_NODENAME, strlen(FIT_HASH_NODENAME))) {
264 		fit_image_print_data(fit, noffset, p, "Hash");
265 	} else if (!strncmp(name, FIT_SIG_NODENAME,
266 				strlen(FIT_SIG_NODENAME))) {
267 		fit_image_print_data(fit, noffset, p, "Sign");
268 	}
269 }
270 
271 /**
272  * fit_conf_print - prints out the FIT configuration details
273  * @fit: pointer to the FIT format image header
274  * @noffset: offset of the configuration node
275  * @p: pointer to prefix string
276  *
277  * fit_conf_print() lists all mandatory properties for the processed
278  * configuration node.
279  *
280  * returns:
281  *     no returned results
282  */
fit_conf_print(const void * fit,int noffset,const char * p)283 static void fit_conf_print(const void *fit, int noffset, const char *p)
284 {
285 	char *desc;
286 	const char *uname;
287 	int ret;
288 	int fdt_index, loadables_index;
289 	int ndepth;
290 
291 	/* Mandatory properties */
292 	ret = fit_get_desc(fit, noffset, &desc);
293 	printf("%s  Description:  ", p);
294 	if (ret)
295 		printf("unavailable\n");
296 	else
297 		printf("%s\n", desc);
298 
299 	uname = fdt_getprop(fit, noffset, FIT_KERNEL_PROP, NULL);
300 	printf("%s  Kernel:       ", p);
301 	if (!uname)
302 		printf("unavailable\n");
303 	else
304 		printf("%s\n", uname);
305 
306 	/* Optional properties */
307 	uname = fdt_getprop(fit, noffset, FIT_RAMDISK_PROP, NULL);
308 	if (uname)
309 		printf("%s  Init Ramdisk: %s\n", p, uname);
310 
311 	uname = fdt_getprop(fit, noffset, FIT_FIRMWARE_PROP, NULL);
312 	if (uname)
313 		printf("%s  Firmware:     %s\n", p, uname);
314 
315 	for (fdt_index = 0;
316 	     uname = fdt_stringlist_get(fit, noffset, FIT_FDT_PROP,
317 					fdt_index, NULL), uname;
318 	     fdt_index++) {
319 		if (fdt_index == 0)
320 			printf("%s  FDT:          ", p);
321 		else
322 			printf("%s                ", p);
323 		printf("%s\n", uname);
324 	}
325 
326 	uname = fdt_getprop(fit, noffset, FIT_FPGA_PROP, NULL);
327 	if (uname)
328 		printf("%s  FPGA:         %s\n", p, uname);
329 
330 	/* Print out all of the specified loadables */
331 	for (loadables_index = 0;
332 	     uname = fdt_stringlist_get(fit, noffset, FIT_LOADABLE_PROP,
333 					loadables_index, NULL), uname;
334 	     loadables_index++) {
335 		if (loadables_index == 0) {
336 			printf("%s  Loadables:    ", p);
337 		} else {
338 			printf("%s                ", p);
339 		}
340 		printf("%s\n", uname);
341 	}
342 
343 	/* Process all hash subnodes of the component configuration node */
344 	for (ndepth = 0, noffset = fdt_next_node(fit, noffset, &ndepth);
345 	     (noffset >= 0) && (ndepth > 0);
346 	     noffset = fdt_next_node(fit, noffset, &ndepth)) {
347 		if (ndepth == 1) {
348 			/* Direct child node of the component configuration node */
349 			fit_image_print_verification_data(fit, noffset, p);
350 		}
351 	}
352 }
353 
354 /**
355  * fit_print_contents - prints out the contents of the FIT format image
356  * @fit: pointer to the FIT format image header
357  * @p: pointer to prefix string
358  *
359  * fit_print_contents() formats a multi line FIT image contents description.
360  * The routine prints out FIT image properties (root node level) followed by
361  * the details of each component image.
362  *
363  * returns:
364  *     no returned results
365  */
fit_print_contents(const void * fit)366 void fit_print_contents(const void *fit)
367 {
368 	char *desc;
369 	char *uname;
370 	int images_noffset;
371 	int confs_noffset;
372 	int noffset;
373 	int ndepth;
374 	int count = 0;
375 	int ret;
376 	const char *p;
377 	time_t timestamp;
378 
379 	if (!CONFIG_IS_ENABLED(FIT_PRINT))
380 		return;
381 
382 	/* Indent string is defined in header image.h */
383 	p = IMAGE_INDENT_STRING;
384 
385 	/* Root node properties */
386 	ret = fit_get_desc(fit, 0, &desc);
387 	printf("%sFIT description: ", p);
388 	if (ret)
389 		printf("unavailable\n");
390 	else
391 		printf("%s\n", desc);
392 
393 	if (IMAGE_ENABLE_TIMESTAMP) {
394 		ret = fit_get_timestamp(fit, 0, &timestamp);
395 		printf("%sCreated:         ", p);
396 		if (ret)
397 			printf("unavailable\n");
398 		else
399 			genimg_print_time(timestamp);
400 	}
401 
402 	/* Find images parent node offset */
403 	images_noffset = fdt_path_offset(fit, FIT_IMAGES_PATH);
404 	if (images_noffset < 0) {
405 		printf("Can't find images parent node '%s' (%s)\n",
406 		       FIT_IMAGES_PATH, fdt_strerror(images_noffset));
407 		return;
408 	}
409 
410 	/* Process its subnodes, print out component images details */
411 	for (ndepth = 0, count = 0,
412 		noffset = fdt_next_node(fit, images_noffset, &ndepth);
413 	     (noffset >= 0) && (ndepth > 0);
414 	     noffset = fdt_next_node(fit, noffset, &ndepth)) {
415 		if (ndepth == 1) {
416 			/*
417 			 * Direct child node of the images parent node,
418 			 * i.e. component image node.
419 			 */
420 			printf("%s Image %u (%s)\n", p, count++,
421 			       fit_get_name(fit, noffset, NULL));
422 
423 			fit_image_print(fit, noffset, p);
424 		}
425 	}
426 
427 	/* Find configurations parent node offset */
428 	confs_noffset = fdt_path_offset(fit, FIT_CONFS_PATH);
429 	if (confs_noffset < 0) {
430 		debug("Can't get configurations parent node '%s' (%s)\n",
431 		      FIT_CONFS_PATH, fdt_strerror(confs_noffset));
432 		return;
433 	}
434 
435 	/* get default configuration unit name from default property */
436 	uname = (char *)fdt_getprop(fit, noffset, FIT_DEFAULT_PROP, NULL);
437 	if (uname)
438 		printf("%s Default Configuration: '%s'\n", p, uname);
439 
440 	/* Process its subnodes, print out configurations details */
441 	for (ndepth = 0, count = 0,
442 		noffset = fdt_next_node(fit, confs_noffset, &ndepth);
443 	     (noffset >= 0) && (ndepth > 0);
444 	     noffset = fdt_next_node(fit, noffset, &ndepth)) {
445 		if (ndepth == 1) {
446 			/*
447 			 * Direct child node of the configurations parent node,
448 			 * i.e. configuration node.
449 			 */
450 			printf("%s Configuration %u (%s)\n", p, count++,
451 			       fit_get_name(fit, noffset, NULL));
452 
453 			fit_conf_print(fit, noffset, p);
454 		}
455 	}
456 }
457 
458 /**
459  * fit_image_print - prints out the FIT component image details
460  * @fit: pointer to the FIT format image header
461  * @image_noffset: offset of the component image node
462  * @p: pointer to prefix string
463  *
464  * fit_image_print() lists all mandatory properties for the processed component
465  * image. If present, hash nodes are printed out as well. Load
466  * address for images of type firmware is also printed out. Since the load
467  * address is not mandatory for firmware images, it will be output as
468  * "unavailable" when not present.
469  *
470  * returns:
471  *     no returned results
472  */
fit_image_print(const void * fit,int image_noffset,const char * p)473 void fit_image_print(const void *fit, int image_noffset, const char *p)
474 {
475 	char *desc;
476 	uint8_t type, arch, os, comp = IH_COMP_NONE;
477 	size_t size;
478 	ulong load, entry;
479 	const void *data;
480 	int noffset;
481 	int ndepth;
482 	int ret;
483 
484 	if (!CONFIG_IS_ENABLED(FIT_PRINT))
485 		return;
486 
487 	/* Mandatory properties */
488 	ret = fit_get_desc(fit, image_noffset, &desc);
489 	printf("%s  Description:  ", p);
490 	if (ret)
491 		printf("unavailable\n");
492 	else
493 		printf("%s\n", desc);
494 
495 	if (IMAGE_ENABLE_TIMESTAMP) {
496 		time_t timestamp;
497 
498 		ret = fit_get_timestamp(fit, 0, &timestamp);
499 		printf("%s  Created:      ", p);
500 		if (ret)
501 			printf("unavailable\n");
502 		else
503 			genimg_print_time(timestamp);
504 	}
505 
506 	fit_image_get_type(fit, image_noffset, &type);
507 	printf("%s  Type:         %s\n", p, genimg_get_type_name(type));
508 
509 	fit_image_get_comp(fit, image_noffset, &comp);
510 	printf("%s  Compression:  %s\n", p, genimg_get_comp_name(comp));
511 
512 	ret = fit_image_get_data(fit, image_noffset, &data, &size);
513 
514 	if (!tools_build()) {
515 		printf("%s  Data Start:   ", p);
516 		if (ret) {
517 			printf("unavailable\n");
518 		} else {
519 			void *vdata = (void *)data;
520 
521 			printf("0x%08lx\n", (ulong)map_to_sysmem(vdata));
522 		}
523 	}
524 
525 	printf("%s  Data Size:    ", p);
526 	if (ret)
527 		printf("unavailable\n");
528 	else
529 		genimg_print_size(size);
530 
531 	/* Remaining, type dependent properties */
532 	if ((type == IH_TYPE_KERNEL) || (type == IH_TYPE_STANDALONE) ||
533 	    (type == IH_TYPE_RAMDISK) || (type == IH_TYPE_FIRMWARE) ||
534 	    (type == IH_TYPE_FLATDT)) {
535 		fit_image_get_arch(fit, image_noffset, &arch);
536 		printf("%s  Architecture: %s\n", p, genimg_get_arch_name(arch));
537 	}
538 
539 	if ((type == IH_TYPE_KERNEL) || (type == IH_TYPE_RAMDISK) ||
540 	    (type == IH_TYPE_FIRMWARE)) {
541 		fit_image_get_os(fit, image_noffset, &os);
542 		printf("%s  OS:           %s\n", p, genimg_get_os_name(os));
543 	}
544 
545 	if ((type == IH_TYPE_KERNEL) || (type == IH_TYPE_STANDALONE) ||
546 	    (type == IH_TYPE_FIRMWARE) || (type == IH_TYPE_RAMDISK) ||
547 	    (type == IH_TYPE_FPGA)) {
548 		ret = fit_image_get_load(fit, image_noffset, &load);
549 		printf("%s  Load Address: ", p);
550 		if (ret)
551 			printf("unavailable\n");
552 		else
553 			printf("0x%08lx\n", load);
554 	}
555 
556 	/* optional load address for FDT */
557 	if (type == IH_TYPE_FLATDT && !fit_image_get_load(fit, image_noffset, &load))
558 		printf("%s  Load Address: 0x%08lx\n", p, load);
559 
560 	if ((type == IH_TYPE_KERNEL) || (type == IH_TYPE_STANDALONE) ||
561 	    (type == IH_TYPE_RAMDISK)) {
562 		ret = fit_image_get_entry(fit, image_noffset, &entry);
563 		printf("%s  Entry Point:  ", p);
564 		if (ret)
565 			printf("unavailable\n");
566 		else
567 			printf("0x%08lx\n", entry);
568 	}
569 
570 	/* Process all hash subnodes of the component image node */
571 	for (ndepth = 0, noffset = fdt_next_node(fit, image_noffset, &ndepth);
572 	     (noffset >= 0) && (ndepth > 0);
573 	     noffset = fdt_next_node(fit, noffset, &ndepth)) {
574 		if (ndepth == 1) {
575 			/* Direct child node of the component image node */
576 			fit_image_print_verification_data(fit, noffset, p);
577 		}
578 	}
579 }
580 
581 /**
582  * fit_get_desc - get node description property
583  * @fit: pointer to the FIT format image header
584  * @noffset: node offset
585  * @desc: double pointer to the char, will hold pointer to the description
586  *
587  * fit_get_desc() reads description property from a given node, if
588  * description is found pointer to it is returned in third call argument.
589  *
590  * returns:
591  *     0, on success
592  *     -1, on failure
593  */
fit_get_desc(const void * fit,int noffset,char ** desc)594 int fit_get_desc(const void *fit, int noffset, char **desc)
595 {
596 	int len;
597 
598 	*desc = (char *)fdt_getprop(fit, noffset, FIT_DESC_PROP, &len);
599 	if (*desc == NULL) {
600 		fit_get_debug(fit, noffset, FIT_DESC_PROP, len);
601 		return -1;
602 	}
603 
604 	return 0;
605 }
606 
607 /**
608  * fit_get_timestamp - get node timestamp property
609  * @fit: pointer to the FIT format image header
610  * @noffset: node offset
611  * @timestamp: pointer to the time_t, will hold read timestamp
612  *
613  * fit_get_timestamp() reads timestamp property from given node, if timestamp
614  * is found and has a correct size its value is returned in third call
615  * argument.
616  *
617  * returns:
618  *     0, on success
619  *     -1, on property read failure
620  *     -2, on wrong timestamp size
621  */
fit_get_timestamp(const void * fit,int noffset,time_t * timestamp)622 int fit_get_timestamp(const void *fit, int noffset, time_t *timestamp)
623 {
624 	int len;
625 	const void *data;
626 
627 	data = fdt_getprop(fit, noffset, FIT_TIMESTAMP_PROP, &len);
628 	if (data == NULL) {
629 		fit_get_debug(fit, noffset, FIT_TIMESTAMP_PROP, len);
630 		return -1;
631 	}
632 	if (len != sizeof(uint32_t)) {
633 		debug("FIT timestamp with incorrect size of (%u)\n", len);
634 		return -2;
635 	}
636 
637 	*timestamp = uimage_to_cpu(*((uint32_t *)data));
638 	return 0;
639 }
640 
641 /**
642  * fit_image_get_node - get node offset for component image of a given unit name
643  * @fit: pointer to the FIT format image header
644  * @image_uname: component image node unit name
645  *
646  * fit_image_get_node() finds a component image (within the '/images'
647  * node) of a provided unit name. If image is found its node offset is
648  * returned to the caller.
649  *
650  * returns:
651  *     image node offset when found (>=0)
652  *     negative number on failure (FDT_ERR_* code)
653  */
fit_image_get_node(const void * fit,const char * image_uname)654 int fit_image_get_node(const void *fit, const char *image_uname)
655 {
656 	int noffset, images_noffset;
657 
658 	images_noffset = fdt_path_offset(fit, FIT_IMAGES_PATH);
659 	if (images_noffset < 0) {
660 		debug("Can't find images parent node '%s' (%s)\n",
661 		      FIT_IMAGES_PATH, fdt_strerror(images_noffset));
662 		return images_noffset;
663 	}
664 
665 	noffset = fdt_subnode_offset(fit, images_noffset, image_uname);
666 	if (noffset < 0) {
667 		debug("Can't get node offset for image unit name: '%s' (%s)\n",
668 		      image_uname, fdt_strerror(noffset));
669 	}
670 
671 	return noffset;
672 }
673 
674 /**
675  * fit_image_get_os - get os id for a given component image node
676  * @fit: pointer to the FIT format image header
677  * @noffset: component image node offset
678  * @os: pointer to the uint8_t, will hold os numeric id
679  *
680  * fit_image_get_os() finds os property in a given component image node.
681  * If the property is found, its (string) value is translated to the numeric
682  * id which is returned to the caller.
683  *
684  * returns:
685  *     0, on success
686  *     -1, on failure
687  */
fit_image_get_os(const void * fit,int noffset,uint8_t * os)688 int fit_image_get_os(const void *fit, int noffset, uint8_t *os)
689 {
690 	int len;
691 	const void *data;
692 
693 	/* Get OS name from property data */
694 	data = fdt_getprop(fit, noffset, FIT_OS_PROP, &len);
695 	if (data == NULL) {
696 		fit_get_debug(fit, noffset, FIT_OS_PROP, len);
697 		*os = -1;
698 		return -1;
699 	}
700 
701 	/* Translate OS name to id */
702 	*os = genimg_get_os_id(data);
703 	return 0;
704 }
705 
706 /**
707  * fit_image_get_arch - get arch id for a given component image node
708  * @fit: pointer to the FIT format image header
709  * @noffset: component image node offset
710  * @arch: pointer to the uint8_t, will hold arch numeric id
711  *
712  * fit_image_get_arch() finds arch property in a given component image node.
713  * If the property is found, its (string) value is translated to the numeric
714  * id which is returned to the caller.
715  *
716  * returns:
717  *     0, on success
718  *     -1, on failure
719  */
fit_image_get_arch(const void * fit,int noffset,uint8_t * arch)720 int fit_image_get_arch(const void *fit, int noffset, uint8_t *arch)
721 {
722 	int len;
723 	const void *data;
724 
725 	/* Get architecture name from property data */
726 	data = fdt_getprop(fit, noffset, FIT_ARCH_PROP, &len);
727 	if (data == NULL) {
728 		fit_get_debug(fit, noffset, FIT_ARCH_PROP, len);
729 		*arch = -1;
730 		return -1;
731 	}
732 
733 	/* Translate architecture name to id */
734 	*arch = genimg_get_arch_id(data);
735 	return 0;
736 }
737 
738 /**
739  * fit_image_get_type - get type id for a given component image node
740  * @fit: pointer to the FIT format image header
741  * @noffset: component image node offset
742  * @type: pointer to the uint8_t, will hold type numeric id
743  *
744  * fit_image_get_type() finds type property in a given component image node.
745  * If the property is found, its (string) value is translated to the numeric
746  * id which is returned to the caller.
747  *
748  * returns:
749  *     0, on success
750  *     -1, on failure
751  */
fit_image_get_type(const void * fit,int noffset,uint8_t * type)752 int fit_image_get_type(const void *fit, int noffset, uint8_t *type)
753 {
754 	int len;
755 	const void *data;
756 
757 	/* Get image type name from property data */
758 	data = fdt_getprop(fit, noffset, FIT_TYPE_PROP, &len);
759 	if (data == NULL) {
760 		fit_get_debug(fit, noffset, FIT_TYPE_PROP, len);
761 		*type = -1;
762 		return -1;
763 	}
764 
765 	/* Translate image type name to id */
766 	*type = genimg_get_type_id(data);
767 	return 0;
768 }
769 
770 /**
771  * fit_image_get_comp - get comp id for a given component image node
772  * @fit: pointer to the FIT format image header
773  * @noffset: component image node offset
774  * @comp: pointer to the uint8_t, will hold comp numeric id
775  *
776  * fit_image_get_comp() finds comp property in a given component image node.
777  * If the property is found, its (string) value is translated to the numeric
778  * id which is returned to the caller.
779  *
780  * returns:
781  *     0, on success
782  *     -1, on failure
783  */
fit_image_get_comp(const void * fit,int noffset,uint8_t * comp)784 int fit_image_get_comp(const void *fit, int noffset, uint8_t *comp)
785 {
786 	int len;
787 	const void *data;
788 
789 	/* Get compression name from property data */
790 	data = fdt_getprop(fit, noffset, FIT_COMP_PROP, &len);
791 	if (data == NULL) {
792 		fit_get_debug(fit, noffset, FIT_COMP_PROP, len);
793 		return -1;
794 	}
795 
796 	/* Translate compression name to id */
797 	*comp = genimg_get_comp_id(data);
798 	return 0;
799 }
800 
801 /**
802  * fit_image_get_phase() - get the phase for a configuration node
803  * @fit: pointer to the FIT format image header
804  * @offset: configuration-node offset
805  * @phasep: returns the phase
806  *
807  * Finds the phase property in a given configuration node. If the property is
808  * found, its (string) value is translated to the numeric id which is returned
809  * to the caller.
810  *
811  * Returns: 0 on success, -ENOENT if missing, -EINVAL for invalid value
812  */
fit_image_get_phase(const void * fit,int offset,enum image_phase_t * phasep)813 int fit_image_get_phase(const void *fit, int offset, enum image_phase_t *phasep)
814 {
815 	const void *data;
816 	int len, ret;
817 
818 	/* Get phase name from property data */
819 	data = fdt_getprop(fit, offset, FIT_PHASE_PROP, &len);
820 	if (!data) {
821 		fit_get_debug(fit, offset, FIT_PHASE_PROP, len);
822 		*phasep = 0;
823 		return -ENOENT;
824 	}
825 
826 	/* Translate phase name to id */
827 	ret = genimg_get_phase_id(data);
828 	if (ret < 0)
829 		return ret;
830 	*phasep = ret;
831 
832 	return 0;
833 }
834 
fit_image_get_address(const void * fit,int noffset,char * name,ulong * load)835 static int fit_image_get_address(const void *fit, int noffset, char *name,
836 			  ulong *load)
837 {
838 	int len, cell_len;
839 	const fdt32_t *cell;
840 	uint64_t load64 = 0;
841 
842 	cell = fdt_getprop(fit, noffset, name, &len);
843 	if (cell == NULL) {
844 		fit_get_debug(fit, noffset, name, len);
845 		return -1;
846 	}
847 
848 	cell_len = len >> 2;
849 	/* Use load64 to avoid compiling warning for 32-bit target */
850 	while (cell_len--) {
851 		load64 = (load64 << 32) | uimage_to_cpu(*cell);
852 		cell++;
853 	}
854 
855 	if (len > sizeof(ulong) && (uint32_t)(load64 >> 32)) {
856 		printf("Unsupported %s address size\n", name);
857 		return -1;
858 	}
859 
860 	*load = (ulong)load64;
861 
862 	return 0;
863 }
864 /**
865  * fit_image_get_load() - get load addr property for given component image node
866  * @fit: pointer to the FIT format image header
867  * @noffset: component image node offset
868  * @load: pointer to the uint32_t, will hold load address
869  *
870  * fit_image_get_load() finds load address property in a given component
871  * image node. If the property is found, its value is returned to the caller.
872  *
873  * returns:
874  *     0, on success
875  *     -1, on failure
876  */
fit_image_get_load(const void * fit,int noffset,ulong * load)877 int fit_image_get_load(const void *fit, int noffset, ulong *load)
878 {
879 	return fit_image_get_address(fit, noffset, FIT_LOAD_PROP, load);
880 }
881 
882 /**
883  * fit_image_get_entry() - get entry point address property
884  * @fit: pointer to the FIT format image header
885  * @noffset: component image node offset
886  * @entry: pointer to the uint32_t, will hold entry point address
887  *
888  * This gets the entry point address property for a given component image
889  * node.
890  *
891  * fit_image_get_entry() finds entry point address property in a given
892  * component image node.  If the property is found, its value is returned
893  * to the caller.
894  *
895  * returns:
896  *     0, on success
897  *     -1, on failure
898  */
fit_image_get_entry(const void * fit,int noffset,ulong * entry)899 int fit_image_get_entry(const void *fit, int noffset, ulong *entry)
900 {
901 	return fit_image_get_address(fit, noffset, FIT_ENTRY_PROP, entry);
902 }
903 
904 /**
905  * fit_image_get_emb_data - get data property and its size for a given component image node
906  * @fit: pointer to the FIT format image header
907  * @noffset: component image node offset
908  * @data: double pointer to void, will hold data property's data address
909  * @size: pointer to size_t, will hold data property's data size
910  *
911  * fit_image_get_emb_data() finds data property in a given component image node.
912  * If the property is found its data start address and size are returned to
913  * the caller.
914  *
915  * returns:
916  *     0, on success
917  *     -1, on failure
918  */
fit_image_get_emb_data(const void * fit,int noffset,const void ** data,size_t * size)919 int fit_image_get_emb_data(const void *fit, int noffset, const void **data,
920 			   size_t *size)
921 {
922 	int len;
923 
924 	*data = fdt_getprop(fit, noffset, FIT_DATA_PROP, &len);
925 	if (*data == NULL) {
926 		fit_get_debug(fit, noffset, FIT_DATA_PROP, len);
927 		*size = 0;
928 		return -1;
929 	}
930 
931 	*size = len;
932 	return 0;
933 }
934 
935 /**
936  * Get 'data-offset' property from a given image node.
937  *
938  * @fit: pointer to the FIT image header
939  * @noffset: component image node offset
940  * @data_offset: holds the data-offset property
941  *
942  * returns:
943  *     0, on success
944  *     -ENOENT if the property could not be found
945  */
fit_image_get_data_offset(const void * fit,int noffset,int * data_offset)946 int fit_image_get_data_offset(const void *fit, int noffset, int *data_offset)
947 {
948 	const fdt32_t *val;
949 
950 	val = fdt_getprop(fit, noffset, FIT_DATA_OFFSET_PROP, NULL);
951 	if (!val)
952 		return -ENOENT;
953 
954 	*data_offset = fdt32_to_cpu(*val);
955 
956 	return 0;
957 }
958 
959 /**
960  * Get 'data-position' property from a given image node.
961  *
962  * @fit: pointer to the FIT image header
963  * @noffset: component image node offset
964  * @data_position: holds the data-position property
965  *
966  * returns:
967  *     0, on success
968  *     -ENOENT if the property could not be found
969  */
fit_image_get_data_position(const void * fit,int noffset,int * data_position)970 int fit_image_get_data_position(const void *fit, int noffset,
971 				int *data_position)
972 {
973 	const fdt32_t *val;
974 
975 	val = fdt_getprop(fit, noffset, FIT_DATA_POSITION_PROP, NULL);
976 	if (!val)
977 		return -ENOENT;
978 
979 	*data_position = fdt32_to_cpu(*val);
980 
981 	return 0;
982 }
983 
984 /**
985  * Get 'data-size' property from a given image node.
986  *
987  * @fit: pointer to the FIT image header
988  * @noffset: component image node offset
989  * @data_size: holds the data-size property
990  *
991  * returns:
992  *     0, on success
993  *     -ENOENT if the property could not be found
994  */
fit_image_get_data_size(const void * fit,int noffset,int * data_size)995 int fit_image_get_data_size(const void *fit, int noffset, int *data_size)
996 {
997 	const fdt32_t *val;
998 
999 	val = fdt_getprop(fit, noffset, FIT_DATA_SIZE_PROP, NULL);
1000 	if (!val)
1001 		return -ENOENT;
1002 
1003 	*data_size = fdt32_to_cpu(*val);
1004 
1005 	return 0;
1006 }
1007 
1008 /**
1009  * Get 'data-size-unciphered' property from a given image node.
1010  *
1011  * @fit: pointer to the FIT image header
1012  * @noffset: component image node offset
1013  * @data_size: holds the data-size property
1014  *
1015  * returns:
1016  *     0, on success
1017  *     -ENOENT if the property could not be found
1018  */
fit_image_get_data_size_unciphered(const void * fit,int noffset,size_t * data_size)1019 int fit_image_get_data_size_unciphered(const void *fit, int noffset,
1020 				       size_t *data_size)
1021 {
1022 	const fdt32_t *val;
1023 
1024 	val = fdt_getprop(fit, noffset, "data-size-unciphered", NULL);
1025 	if (!val)
1026 		return -ENOENT;
1027 
1028 	*data_size = (size_t)fdt32_to_cpu(*val);
1029 
1030 	return 0;
1031 }
1032 
1033 /**
1034  * fit_image_get_data - get data and its size including
1035  *				 both embedded and external data
1036  * @fit: pointer to the FIT format image header
1037  * @noffset: component image node offset
1038  * @data: double pointer to void, will hold data property's data address
1039  * @size: pointer to size_t, will hold data property's data size
1040  *
1041  * fit_image_get_data() finds data and its size including
1042  * both embedded and external data. If the property is found
1043  * its data start address and size are returned to the caller.
1044  *
1045  * returns:
1046  *     0, on success
1047  *     otherwise, on failure
1048  */
fit_image_get_data(const void * fit,int noffset,const void ** data,size_t * size)1049 int fit_image_get_data(const void *fit, int noffset, const void **data,
1050 		       size_t *size)
1051 {
1052 	bool external_data = false;
1053 	int offset;
1054 	int len;
1055 	int ret;
1056 
1057 	if (!fit_image_get_data_position(fit, noffset, &offset)) {
1058 		external_data = true;
1059 	} else if (!fit_image_get_data_offset(fit, noffset, &offset)) {
1060 		external_data = true;
1061 		/*
1062 		 * For FIT with external data, figure out where
1063 		 * the external images start. This is the base
1064 		 * for the data-offset properties in each image.
1065 		 */
1066 		offset += ((fdt_totalsize(fit) + 3) & ~3);
1067 	}
1068 
1069 	if (external_data) {
1070 		debug("External Data\n");
1071 		ret = fit_image_get_data_size(fit, noffset, &len);
1072 		if (!ret) {
1073 			*data = fit + offset;
1074 			*size = len;
1075 		}
1076 	} else {
1077 		ret = fit_image_get_emb_data(fit, noffset, data, size);
1078 	}
1079 
1080 	return ret;
1081 }
1082 
1083 /**
1084  * fit_image_hash_get_algo - get hash algorithm name
1085  * @fit: pointer to the FIT format image header
1086  * @noffset: hash node offset
1087  * @algo: double pointer to char, will hold pointer to the algorithm name
1088  *
1089  * fit_image_hash_get_algo() finds hash algorithm property in a given hash node.
1090  * If the property is found its data start address is returned to the caller.
1091  *
1092  * returns:
1093  *     0, on success
1094  *     -1, on failure
1095  */
fit_image_hash_get_algo(const void * fit,int noffset,const char ** algo)1096 int fit_image_hash_get_algo(const void *fit, int noffset, const char **algo)
1097 {
1098 	int len;
1099 
1100 	*algo = (const char *)fdt_getprop(fit, noffset, FIT_ALGO_PROP, &len);
1101 	if (*algo == NULL) {
1102 		fit_get_debug(fit, noffset, FIT_ALGO_PROP, len);
1103 		return -1;
1104 	}
1105 
1106 	return 0;
1107 }
1108 
1109 /**
1110  * fit_image_hash_get_value - get hash value and length
1111  * @fit: pointer to the FIT format image header
1112  * @noffset: hash node offset
1113  * @value: double pointer to uint8_t, will hold address of a hash value data
1114  * @value_len: pointer to an int, will hold hash data length
1115  *
1116  * fit_image_hash_get_value() finds hash value property in a given hash node.
1117  * If the property is found its data start address and size are returned to
1118  * the caller.
1119  *
1120  * returns:
1121  *     0, on success
1122  *     -1, on failure
1123  */
fit_image_hash_get_value(const void * fit,int noffset,uint8_t ** value,int * value_len)1124 int fit_image_hash_get_value(const void *fit, int noffset, uint8_t **value,
1125 				int *value_len)
1126 {
1127 	int len;
1128 
1129 	*value = (uint8_t *)fdt_getprop(fit, noffset, FIT_VALUE_PROP, &len);
1130 	if (*value == NULL) {
1131 		fit_get_debug(fit, noffset, FIT_VALUE_PROP, len);
1132 		*value_len = 0;
1133 		return -1;
1134 	}
1135 
1136 	*value_len = len;
1137 	return 0;
1138 }
1139 
1140 /**
1141  * fit_image_hash_get_ignore - get hash ignore flag
1142  * @fit: pointer to the FIT format image header
1143  * @noffset: hash node offset
1144  * @ignore: pointer to an int, will hold hash ignore flag
1145  *
1146  * fit_image_hash_get_ignore() finds hash ignore property in a given hash node.
1147  * If the property is found and non-zero, the hash algorithm is not verified by
1148  * u-boot automatically.
1149  *
1150  * returns:
1151  *     0, on ignore not found
1152  *     value, on ignore found
1153  */
fit_image_hash_get_ignore(const void * fit,int noffset,int * ignore)1154 static int fit_image_hash_get_ignore(const void *fit, int noffset, int *ignore)
1155 {
1156 	int len;
1157 	int *value;
1158 
1159 	value = (int *)fdt_getprop(fit, noffset, FIT_IGNORE_PROP, &len);
1160 	if (value == NULL || len != sizeof(int))
1161 		*ignore = 0;
1162 	else
1163 		*ignore = *value;
1164 
1165 	return 0;
1166 }
1167 
1168 /**
1169  * fit_image_cipher_get_algo - get cipher algorithm name
1170  * @fit: pointer to the FIT format image header
1171  * @noffset: cipher node offset
1172  * @algo: double pointer to char, will hold pointer to the algorithm name
1173  *
1174  * fit_image_cipher_get_algo() finds cipher algorithm property in a given
1175  * cipher node. If the property is found its data start address is returned
1176  * to the caller.
1177  *
1178  * returns:
1179  *     0, on success
1180  *     -1, on failure
1181  */
fit_image_cipher_get_algo(const void * fit,int noffset,char ** algo)1182 int fit_image_cipher_get_algo(const void *fit, int noffset, char **algo)
1183 {
1184 	int len;
1185 
1186 	*algo = (char *)fdt_getprop(fit, noffset, FIT_ALGO_PROP, &len);
1187 	if (!*algo) {
1188 		fit_get_debug(fit, noffset, FIT_ALGO_PROP, len);
1189 		return -1;
1190 	}
1191 
1192 	return 0;
1193 }
1194 
fit_get_end(const void * fit)1195 ulong fit_get_end(const void *fit)
1196 {
1197 	return map_to_sysmem((void *)(fit + fdt_totalsize(fit)));
1198 }
1199 
1200 /**
1201  * fit_set_timestamp - set node timestamp property
1202  * @fit: pointer to the FIT format image header
1203  * @noffset: node offset
1204  * @timestamp: timestamp value to be set
1205  *
1206  * fit_set_timestamp() attempts to set timestamp property in the requested
1207  * node and returns operation status to the caller.
1208  *
1209  * returns:
1210  *     0, on success
1211  *     -ENOSPC if no space in device tree, -1 for other error
1212  */
fit_set_timestamp(void * fit,int noffset,time_t timestamp)1213 int fit_set_timestamp(void *fit, int noffset, time_t timestamp)
1214 {
1215 	uint32_t t;
1216 	int ret;
1217 
1218 	t = cpu_to_uimage(timestamp);
1219 	ret = fdt_setprop(fit, noffset, FIT_TIMESTAMP_PROP, &t,
1220 				sizeof(uint32_t));
1221 	if (ret) {
1222 		debug("Can't set '%s' property for '%s' node (%s)\n",
1223 		      FIT_TIMESTAMP_PROP, fit_get_name(fit, noffset, NULL),
1224 		      fdt_strerror(ret));
1225 		return ret == -FDT_ERR_NOSPACE ? -ENOSPC : -1;
1226 	}
1227 
1228 	return 0;
1229 }
1230 
1231 /**
1232  * calculate_hash - calculate and return hash for provided input data
1233  * @data: pointer to the input data
1234  * @data_len: data length
1235  * @name: requested hash algorithm name
1236  * @value: pointer to the char, will hold hash value data (caller must
1237  * allocate enough free space)
1238  * value_len: length of the calculated hash
1239  *
1240  * calculate_hash() computes input data hash according to the requested
1241  * algorithm.
1242  * Resulting hash value is placed in caller provided 'value' buffer, length
1243  * of the calculated hash is returned via value_len pointer argument.
1244  *
1245  * returns:
1246  *     0, on success
1247  *    -1, when algo is unsupported
1248  */
calculate_hash(const void * data,int data_len,const char * name,uint8_t * value,int * value_len)1249 int calculate_hash(const void *data, int data_len, const char *name,
1250 			uint8_t *value, int *value_len)
1251 {
1252 #if !defined(USE_HOSTCC) && defined(CONFIG_DM_HASH)
1253 	int rc;
1254 	enum HASH_ALGO hash_algo;
1255 	struct udevice *dev;
1256 
1257 	rc = uclass_get_device(UCLASS_HASH, 0, &dev);
1258 	if (rc) {
1259 		debug("failed to get hash device, rc=%d\n", rc);
1260 		return -1;
1261 	}
1262 
1263 	hash_algo = hash_algo_lookup_by_name(name);
1264 	if (hash_algo == HASH_ALGO_INVALID) {
1265 		debug("Unsupported hash algorithm\n");
1266 		return -1;
1267 	};
1268 
1269 	rc = hash_digest_wd(dev, hash_algo, data, data_len, value, CHUNKSZ);
1270 	if (rc) {
1271 		debug("failed to get hash value, rc=%d\n", rc);
1272 		return -1;
1273 	}
1274 
1275 	*value_len = hash_algo_digest_size(hash_algo);
1276 #else
1277 	struct hash_algo *algo;
1278 	int ret;
1279 
1280 	ret = hash_lookup_algo(name, &algo);
1281 	if (ret < 0) {
1282 		debug("Unsupported hash alogrithm\n");
1283 		return -1;
1284 	}
1285 
1286 	algo->hash_func_ws(data, data_len, value, algo->chunk_size);
1287 	*value_len = algo->digest_size;
1288 #endif
1289 
1290 	return 0;
1291 }
1292 
fit_image_check_hash(const void * fit,int noffset,const void * data,size_t size,char ** err_msgp)1293 static int fit_image_check_hash(const void *fit, int noffset, const void *data,
1294 				size_t size, char **err_msgp)
1295 {
1296 	ALLOC_CACHE_ALIGN_BUFFER(uint8_t, value, FIT_MAX_HASH_LEN);
1297 	int value_len;
1298 	const char *algo;
1299 	uint8_t *fit_value;
1300 	int fit_value_len;
1301 	int ignore;
1302 
1303 	*err_msgp = NULL;
1304 
1305 	if (fit_image_hash_get_algo(fit, noffset, &algo)) {
1306 		*err_msgp = "Can't get hash algo property";
1307 		return -1;
1308 	}
1309 	printf("%s", algo);
1310 
1311 	if (!tools_build()) {
1312 		fit_image_hash_get_ignore(fit, noffset, &ignore);
1313 		if (ignore) {
1314 			printf("-skipped ");
1315 			return 0;
1316 		}
1317 	}
1318 
1319 	if (fit_image_hash_get_value(fit, noffset, &fit_value,
1320 				     &fit_value_len)) {
1321 		*err_msgp = "Can't get hash value property";
1322 		return -1;
1323 	}
1324 
1325 	if (calculate_hash(data, size, algo, value, &value_len)) {
1326 		*err_msgp = "Unsupported hash algorithm";
1327 		return -1;
1328 	}
1329 
1330 	if (value_len != fit_value_len) {
1331 		*err_msgp = "Bad hash value len";
1332 		return -1;
1333 	} else if (memcmp(value, fit_value, value_len) != 0) {
1334 		*err_msgp = "Bad hash value";
1335 		return -1;
1336 	}
1337 
1338 	return 0;
1339 }
1340 
fit_image_verify_with_data(const void * fit,int image_noffset,const void * key_blob,const void * data,size_t size)1341 int fit_image_verify_with_data(const void *fit, int image_noffset,
1342 			       const void *key_blob, const void *data,
1343 			       size_t size)
1344 {
1345 	int		noffset = 0;
1346 	char		*err_msg = "";
1347 	int verify_all = 1;
1348 	int ret;
1349 
1350 	/* Verify all required signatures */
1351 	if (FIT_IMAGE_ENABLE_VERIFY &&
1352 	    fit_image_verify_required_sigs(fit, image_noffset, data, size,
1353 					   key_blob, &verify_all)) {
1354 		err_msg = "Unable to verify required signature";
1355 		goto error;
1356 	}
1357 
1358 	/* Process all hash subnodes of the component image node */
1359 	fdt_for_each_subnode(noffset, fit, image_noffset) {
1360 		const char *name = fit_get_name(fit, noffset, NULL);
1361 
1362 		/*
1363 		 * Check subnode name, must be equal to "hash".
1364 		 * Multiple hash nodes require unique unit node
1365 		 * names, e.g. hash-1, hash-2, etc.
1366 		 */
1367 		if (!strncmp(name, FIT_HASH_NODENAME,
1368 			     strlen(FIT_HASH_NODENAME))) {
1369 			if (fit_image_check_hash(fit, noffset, data, size,
1370 						 &err_msg))
1371 				goto error;
1372 			puts("+ ");
1373 		} else if (FIT_IMAGE_ENABLE_VERIFY && verify_all &&
1374 				!strncmp(name, FIT_SIG_NODENAME,
1375 					strlen(FIT_SIG_NODENAME))) {
1376 			ret = fit_image_check_sig(fit, noffset, data, size,
1377 						  gd_fdt_blob(), -1, &err_msg);
1378 
1379 			/*
1380 			 * Show an indication on failure, but do not return
1381 			 * an error. Only keys marked 'required' can cause
1382 			 * an image validation failure. See the call to
1383 			 * fit_image_verify_required_sigs() above.
1384 			 */
1385 			if (ret)
1386 				puts("- ");
1387 			else
1388 				puts("+ ");
1389 		}
1390 	}
1391 
1392 	if (noffset == -FDT_ERR_TRUNCATED || noffset == -FDT_ERR_BADSTRUCTURE) {
1393 		err_msg = "Corrupted or truncated tree";
1394 		goto error;
1395 	}
1396 
1397 	return 1;
1398 
1399 error:
1400 	printf(" error!\n%s for '%s' hash node in '%s' image node\n",
1401 	       err_msg, fit_get_name(fit, noffset, NULL),
1402 	       fit_get_name(fit, image_noffset, NULL));
1403 	return 0;
1404 }
1405 
1406 /**
1407  * fit_image_verify - verify data integrity
1408  * @fit: pointer to the FIT format image header
1409  * @image_noffset: component image node offset
1410  *
1411  * fit_image_verify() goes over component image hash nodes,
1412  * re-calculates each data hash and compares with the value stored in hash
1413  * node.
1414  *
1415  * returns:
1416  *     1, if all hashes are valid
1417  *     0, otherwise (or on error)
1418  */
fit_image_verify(const void * fit,int image_noffset)1419 int fit_image_verify(const void *fit, int image_noffset)
1420 {
1421 	const char *name = fit_get_name(fit, image_noffset, NULL);
1422 	const void	*data;
1423 	size_t		size;
1424 	char		*err_msg = "";
1425 
1426 	if (IS_ENABLED(CONFIG_FIT_SIGNATURE) && strchr(name, '@')) {
1427 		/*
1428 		 * We don't support this since libfdt considers names with the
1429 		 * name root but different @ suffix to be equal
1430 		 */
1431 		err_msg = "Node name contains @";
1432 		goto err;
1433 	}
1434 	/* Get image data and data length */
1435 	if (fit_image_get_data(fit, image_noffset, &data, &size)) {
1436 		err_msg = "Can't get image data/size";
1437 		goto err;
1438 	}
1439 
1440 	return fit_image_verify_with_data(fit, image_noffset, gd_fdt_blob(),
1441 					  data, size);
1442 
1443 err:
1444 	printf("error!\n%s in '%s' image node\n", err_msg,
1445 	       fit_get_name(fit, image_noffset, NULL));
1446 	return 0;
1447 }
1448 
1449 /**
1450  * fit_all_image_verify - verify data integrity for all images
1451  * @fit: pointer to the FIT format image header
1452  *
1453  * fit_all_image_verify() goes over all images in the FIT and
1454  * for every images checks if all it's hashes are valid.
1455  *
1456  * returns:
1457  *     1, if all hashes of all images are valid
1458  *     0, otherwise (or on error)
1459  */
fit_all_image_verify(const void * fit)1460 int fit_all_image_verify(const void *fit)
1461 {
1462 	int images_noffset;
1463 	int noffset;
1464 	int ndepth;
1465 	int count;
1466 
1467 	/* Find images parent node offset */
1468 	images_noffset = fdt_path_offset(fit, FIT_IMAGES_PATH);
1469 	if (images_noffset < 0) {
1470 		printf("Can't find images parent node '%s' (%s)\n",
1471 		       FIT_IMAGES_PATH, fdt_strerror(images_noffset));
1472 		return 0;
1473 	}
1474 
1475 	/* Process all image subnodes, check hashes for each */
1476 	printf("## Checking hash(es) for FIT Image at %08lx ...\n",
1477 	       (ulong)fit);
1478 	for (ndepth = 0, count = 0,
1479 	     noffset = fdt_next_node(fit, images_noffset, &ndepth);
1480 			(noffset >= 0) && (ndepth > 0);
1481 			noffset = fdt_next_node(fit, noffset, &ndepth)) {
1482 		if (ndepth == 1) {
1483 			/*
1484 			 * Direct child node of the images parent node,
1485 			 * i.e. component image node.
1486 			 */
1487 			printf("   Hash(es) for Image %u (%s): ", count,
1488 			       fit_get_name(fit, noffset, NULL));
1489 			count++;
1490 
1491 			if (!fit_image_verify(fit, noffset))
1492 				return 0;
1493 			printf("\n");
1494 		}
1495 	}
1496 	return 1;
1497 }
1498 
fit_image_uncipher(const void * fit,int image_noffset,void ** data,size_t * size)1499 static int fit_image_uncipher(const void *fit, int image_noffset,
1500 			      void **data, size_t *size)
1501 {
1502 	int cipher_noffset, ret;
1503 	void *dst;
1504 	size_t size_dst;
1505 
1506 	cipher_noffset = fdt_subnode_offset(fit, image_noffset,
1507 					    FIT_CIPHER_NODENAME);
1508 	if (cipher_noffset < 0)
1509 		return 0;
1510 
1511 	ret = fit_image_decrypt_data(fit, image_noffset, cipher_noffset,
1512 				     *data, *size, &dst, &size_dst);
1513 	if (ret)
1514 		goto out;
1515 
1516 	*data = dst;
1517 	*size = size_dst;
1518 
1519  out:
1520 	return ret;
1521 }
1522 
1523 /**
1524  * fit_image_check_os - check whether image node is of a given os type
1525  * @fit: pointer to the FIT format image header
1526  * @noffset: component image node offset
1527  * @os: requested image os
1528  *
1529  * fit_image_check_os() reads image os property and compares its numeric
1530  * id with the requested os. Comparison result is returned to the caller.
1531  *
1532  * returns:
1533  *     1 if image is of given os type
1534  *     0 otherwise (or on error)
1535  */
fit_image_check_os(const void * fit,int noffset,uint8_t os)1536 int fit_image_check_os(const void *fit, int noffset, uint8_t os)
1537 {
1538 	uint8_t image_os;
1539 
1540 	if (fit_image_get_os(fit, noffset, &image_os))
1541 		return 0;
1542 	return (os == image_os);
1543 }
1544 
1545 /**
1546  * fit_image_check_arch - check whether image node is of a given arch
1547  * @fit: pointer to the FIT format image header
1548  * @noffset: component image node offset
1549  * @arch: requested imagearch
1550  *
1551  * fit_image_check_arch() reads image arch property and compares its numeric
1552  * id with the requested arch. Comparison result is returned to the caller.
1553  *
1554  * returns:
1555  *     1 if image is of given arch
1556  *     0 otherwise (or on error)
1557  */
fit_image_check_arch(const void * fit,int noffset,uint8_t arch)1558 int fit_image_check_arch(const void *fit, int noffset, uint8_t arch)
1559 {
1560 	uint8_t image_arch;
1561 	int aarch32_support = 0;
1562 
1563 	/* Let's assume that sandbox can load any architecture */
1564 	if (IS_ENABLED(CONFIG_SANDBOX))
1565 		return true;
1566 
1567 	if (IS_ENABLED(CONFIG_ARM64_SUPPORT_AARCH32))
1568 		aarch32_support = 1;
1569 
1570 	if (fit_image_get_arch(fit, noffset, &image_arch))
1571 		return 0;
1572 	return (arch == image_arch) ||
1573 		(arch == IH_ARCH_I386 && image_arch == IH_ARCH_X86_64) ||
1574 		(arch == IH_ARCH_ARM64 && image_arch == IH_ARCH_ARM &&
1575 		 aarch32_support);
1576 }
1577 
1578 /**
1579  * fit_image_check_type - check whether image node is of a given type
1580  * @fit: pointer to the FIT format image header
1581  * @noffset: component image node offset
1582  * @type: requested image type
1583  *
1584  * fit_image_check_type() reads image type property and compares its numeric
1585  * id with the requested type. Comparison result is returned to the caller.
1586  *
1587  * returns:
1588  *     1 if image is of given type
1589  *     0 otherwise (or on error)
1590  */
fit_image_check_type(const void * fit,int noffset,uint8_t type)1591 int fit_image_check_type(const void *fit, int noffset, uint8_t type)
1592 {
1593 	uint8_t image_type;
1594 
1595 	if (fit_image_get_type(fit, noffset, &image_type))
1596 		return 0;
1597 	return (type == image_type);
1598 }
1599 
1600 /**
1601  * fit_image_check_comp - check whether image node uses given compression
1602  * @fit: pointer to the FIT format image header
1603  * @noffset: component image node offset
1604  * @comp: requested image compression type
1605  *
1606  * fit_image_check_comp() reads image compression property and compares its
1607  * numeric id with the requested compression type. Comparison result is
1608  * returned to the caller.
1609  *
1610  * returns:
1611  *     1 if image uses requested compression
1612  *     0 otherwise (or on error)
1613  */
fit_image_check_comp(const void * fit,int noffset,uint8_t comp)1614 int fit_image_check_comp(const void *fit, int noffset, uint8_t comp)
1615 {
1616 	uint8_t image_comp;
1617 
1618 	if (fit_image_get_comp(fit, noffset, &image_comp))
1619 		return 0;
1620 	return (comp == image_comp);
1621 }
1622 
1623 /**
1624  * fdt_check_no_at() - Check for nodes whose names contain '@'
1625  *
1626  * This checks the parent node and all subnodes recursively
1627  *
1628  * @fit: FIT to check
1629  * @parent: Parent node to check
1630  * Return: 0 if OK, -EADDRNOTAVAIL is a node has a name containing '@'
1631  */
fdt_check_no_at(const void * fit,int parent)1632 static int fdt_check_no_at(const void *fit, int parent)
1633 {
1634 	const char *name;
1635 	int node;
1636 	int ret;
1637 
1638 	name = fdt_get_name(fit, parent, NULL);
1639 	if (!name || strchr(name, '@'))
1640 		return -EADDRNOTAVAIL;
1641 
1642 	fdt_for_each_subnode(node, fit, parent) {
1643 		ret = fdt_check_no_at(fit, node);
1644 		if (ret)
1645 			return ret;
1646 	}
1647 
1648 	return 0;
1649 }
1650 
fit_check_format(const void * fit,ulong size)1651 int fit_check_format(const void *fit, ulong size)
1652 {
1653 	int ret;
1654 
1655 	/* A FIT image must be a valid FDT */
1656 	ret = fdt_check_header(fit);
1657 	if (ret) {
1658 		log_debug("Wrong FIT format: not a flattened device tree (err=%d)\n",
1659 			  ret);
1660 		return -ENOEXEC;
1661 	}
1662 
1663 	if (CONFIG_IS_ENABLED(FIT_FULL_CHECK)) {
1664 		/*
1665 		 * If we are not given the size, make do wtih calculating it.
1666 		 * This is not as secure, so we should consider a flag to
1667 		 * control this.
1668 		 */
1669 		if (size == IMAGE_SIZE_INVAL)
1670 			size = fdt_totalsize(fit);
1671 		ret = fdt_check_full(fit, size);
1672 		if (ret)
1673 			ret = -EINVAL;
1674 
1675 		/*
1676 		 * U-Boot stopped using unit addressed in 2017. Since libfdt
1677 		 * can match nodes ignoring any unit address, signature
1678 		 * verification can see the wrong node if one is inserted with
1679 		 * the same name as a valid node but with a unit address
1680 		 * attached. Protect against this by disallowing unit addresses.
1681 		 */
1682 		if (!ret && CONFIG_IS_ENABLED(FIT_SIGNATURE)) {
1683 			ret = fdt_check_no_at(fit, 0);
1684 
1685 			if (ret) {
1686 				log_debug("FIT check error %d\n", ret);
1687 				return ret;
1688 			}
1689 		}
1690 		if (ret) {
1691 			log_debug("FIT check error %d\n", ret);
1692 			return ret;
1693 		}
1694 	}
1695 
1696 	/* mandatory / node 'description' property */
1697 	if (!fdt_getprop(fit, 0, FIT_DESC_PROP, NULL)) {
1698 		log_debug("Wrong FIT format: no description\n");
1699 		return -ENOMSG;
1700 	}
1701 
1702 	if (IMAGE_ENABLE_TIMESTAMP) {
1703 		/* mandatory / node 'timestamp' property */
1704 		if (!fdt_getprop(fit, 0, FIT_TIMESTAMP_PROP, NULL)) {
1705 			log_debug("Wrong FIT format: no timestamp\n");
1706 			return -EBADMSG;
1707 		}
1708 	}
1709 
1710 	/* mandatory subimages parent '/images' node */
1711 	if (fdt_path_offset(fit, FIT_IMAGES_PATH) < 0) {
1712 		log_debug("Wrong FIT format: no images parent node\n");
1713 		return -ENOENT;
1714 	}
1715 
1716 	return 0;
1717 }
1718 
fit_conf_find_compat(const void * fit,const void * fdt)1719 int fit_conf_find_compat(const void *fit, const void *fdt)
1720 {
1721 	int ndepth = 0;
1722 	int noffset, confs_noffset, images_noffset;
1723 	const void *fdt_compat;
1724 	int fdt_compat_len;
1725 	int best_match_offset = 0;
1726 	int best_match_pos = 0;
1727 
1728 	confs_noffset = fdt_path_offset(fit, FIT_CONFS_PATH);
1729 	images_noffset = fdt_path_offset(fit, FIT_IMAGES_PATH);
1730 	if (confs_noffset < 0 || images_noffset < 0) {
1731 		debug("Can't find configurations or images nodes.\n");
1732 		return -EINVAL;
1733 	}
1734 
1735 	fdt_compat = fdt_getprop(fdt, 0, "compatible", &fdt_compat_len);
1736 	if (!fdt_compat) {
1737 		debug("Fdt for comparison has no \"compatible\" property.\n");
1738 		return -ENXIO;
1739 	}
1740 
1741 	/*
1742 	 * Loop over the configurations in the FIT image.
1743 	 */
1744 	for (noffset = fdt_next_node(fit, confs_noffset, &ndepth);
1745 			(noffset >= 0) && (ndepth > 0);
1746 			noffset = fdt_next_node(fit, noffset, &ndepth)) {
1747 		const void *fdt;
1748 		const char *kfdt_name;
1749 		int kfdt_noffset, compat_noffset;
1750 		const char *cur_fdt_compat;
1751 		int len;
1752 		size_t sz;
1753 		int i;
1754 
1755 		if (ndepth > 1)
1756 			continue;
1757 
1758 		/* If there's a compat property in the config node, use that. */
1759 		if (fdt_getprop(fit, noffset, "compatible", NULL)) {
1760 			fdt = fit;		  /* search in FIT image */
1761 			compat_noffset = noffset; /* search under config node */
1762 		} else {	/* Otherwise extract it from the kernel FDT. */
1763 			kfdt_name = fdt_getprop(fit, noffset, "fdt", &len);
1764 			if (!kfdt_name) {
1765 				debug("No fdt property found.\n");
1766 				continue;
1767 			}
1768 			kfdt_noffset = fdt_subnode_offset(fit, images_noffset,
1769 							  kfdt_name);
1770 			if (kfdt_noffset < 0) {
1771 				debug("No image node named \"%s\" found.\n",
1772 				      kfdt_name);
1773 				continue;
1774 			}
1775 
1776 			if (!fit_image_check_comp(fit, kfdt_noffset,
1777 						  IH_COMP_NONE)) {
1778 				debug("Can't extract compat from \"%s\" "
1779 				      "(compressed)\n", kfdt_name);
1780 				continue;
1781 			}
1782 
1783 			/* search in this config's kernel FDT */
1784 			if (fit_image_get_data(fit, kfdt_noffset, &fdt, &sz)) {
1785 				debug("Failed to get fdt \"%s\".\n", kfdt_name);
1786 				continue;
1787 			}
1788 
1789 			compat_noffset = 0;  /* search kFDT under root node */
1790 		}
1791 
1792 		len = fdt_compat_len;
1793 		cur_fdt_compat = fdt_compat;
1794 		/*
1795 		 * Look for a match for each U-Boot compatibility string in
1796 		 * turn in the compat string property.
1797 		 */
1798 		for (i = 0; len > 0 &&
1799 		     (!best_match_offset || best_match_pos > i); i++) {
1800 			int cur_len = strlen(cur_fdt_compat) + 1;
1801 
1802 			if (!fdt_node_check_compatible(fdt, compat_noffset,
1803 						       cur_fdt_compat)) {
1804 				best_match_offset = noffset;
1805 				best_match_pos = i;
1806 				break;
1807 			}
1808 			len -= cur_len;
1809 			cur_fdt_compat += cur_len;
1810 		}
1811 	}
1812 	if (!best_match_offset) {
1813 		debug("No match found.\n");
1814 		return -ENOENT;
1815 	}
1816 
1817 	return best_match_offset;
1818 }
1819 
fit_conf_get_node(const void * fit,const char * conf_uname)1820 int fit_conf_get_node(const void *fit, const char *conf_uname)
1821 {
1822 	int noffset, confs_noffset;
1823 	int len;
1824 	const char *s;
1825 	char *conf_uname_copy = NULL;
1826 
1827 	confs_noffset = fdt_path_offset(fit, FIT_CONFS_PATH);
1828 	if (confs_noffset < 0) {
1829 		debug("Can't find configurations parent node '%s' (%s)\n",
1830 		      FIT_CONFS_PATH, fdt_strerror(confs_noffset));
1831 		return confs_noffset;
1832 	}
1833 
1834 	if (conf_uname == NULL) {
1835 		/* get configuration unit name from the default property */
1836 		debug("No configuration specified, trying default...\n");
1837 		if (!tools_build() && IS_ENABLED(CONFIG_MULTI_DTB_FIT)) {
1838 			noffset = fit_find_config_node(fit);
1839 			if (noffset < 0)
1840 				return noffset;
1841 			conf_uname = fdt_get_name(fit, noffset, NULL);
1842 		} else {
1843 			conf_uname = (char *)fdt_getprop(fit, confs_noffset,
1844 							 FIT_DEFAULT_PROP, &len);
1845 			if (conf_uname == NULL) {
1846 				fit_get_debug(fit, confs_noffset, FIT_DEFAULT_PROP,
1847 					      len);
1848 				return len;
1849 			}
1850 		}
1851 		debug("Found default configuration: '%s'\n", conf_uname);
1852 	}
1853 
1854 	s = strchr(conf_uname, '#');
1855 	if (s) {
1856 		len = s - conf_uname;
1857 		conf_uname_copy = malloc(len + 1);
1858 		if (!conf_uname_copy) {
1859 			debug("Can't allocate uname copy: '%s'\n",
1860 					conf_uname);
1861 			return -ENOMEM;
1862 		}
1863 		memcpy(conf_uname_copy, conf_uname, len);
1864 		conf_uname_copy[len] = '\0';
1865 		conf_uname = conf_uname_copy;
1866 	}
1867 
1868 	noffset = fdt_subnode_offset(fit, confs_noffset, conf_uname);
1869 	if (noffset < 0) {
1870 		debug("Can't get node offset for configuration unit name: '%s' (%s)\n",
1871 		      conf_uname, fdt_strerror(noffset));
1872 	}
1873 
1874 	free(conf_uname_copy);
1875 
1876 	return noffset;
1877 }
1878 
fit_conf_get_prop_node_count(const void * fit,int noffset,const char * prop_name)1879 int fit_conf_get_prop_node_count(const void *fit, int noffset,
1880 		const char *prop_name)
1881 {
1882 	return fdt_stringlist_count(fit, noffset, prop_name);
1883 }
1884 
fit_conf_get_prop_node_index(const void * fit,int noffset,const char * prop_name,int index)1885 int fit_conf_get_prop_node_index(const void *fit, int noffset,
1886 		const char *prop_name, int index)
1887 {
1888 	const char *uname;
1889 	int len;
1890 
1891 	/* get kernel image unit name from configuration kernel property */
1892 	uname = fdt_stringlist_get(fit, noffset, prop_name, index, &len);
1893 	if (uname == NULL)
1894 		return len;
1895 
1896 	return fit_image_get_node(fit, uname);
1897 }
1898 
fit_conf_get_prop_node(const void * fit,int noffset,const char * prop_name,enum image_phase_t sel_phase)1899 int fit_conf_get_prop_node(const void *fit, int noffset, const char *prop_name,
1900 			   enum image_phase_t sel_phase)
1901 {
1902 	int i, count;
1903 
1904 	if (sel_phase == IH_PHASE_NONE)
1905 		return fit_conf_get_prop_node_index(fit, noffset, prop_name, 0);
1906 
1907 	count = fit_conf_get_prop_node_count(fit, noffset, prop_name);
1908 	if (count < 0)
1909 		return count;
1910 	log_debug("looking for %s (%s, image-count %d):\n", prop_name,
1911 		  genimg_get_phase_name(image_ph_phase(sel_phase)), count);
1912 
1913 	/* check each image in the list */
1914 	for (i = 0; i < count; i++) {
1915 		enum image_phase_t phase = IH_PHASE_NONE;
1916 		int ret, node;
1917 
1918 		node = fit_conf_get_prop_node_index(fit, noffset, prop_name, i);
1919 		ret = fit_image_get_phase(fit, node, &phase);
1920 		log_debug("- %s (%s): ", fdt_get_name(fit, node, NULL),
1921 			  genimg_get_phase_name(phase));
1922 
1923 		/* if the image is for any phase, let's use it */
1924 		if (ret == -ENOENT || phase == sel_phase) {
1925 			log_debug("found\n");
1926 			return node;
1927 		} else if (ret < 0) {
1928 			log_debug("err=%d\n", ret);
1929 			return ret;
1930 		}
1931 		log_debug("no match\n");
1932 	}
1933 	log_debug("- not found\n");
1934 
1935 	return -ENOENT;
1936 }
1937 
fit_get_data_tail(const void * fit,int noffset,const void ** data,size_t * size)1938 static int fit_get_data_tail(const void *fit, int noffset,
1939 			     const void **data, size_t *size)
1940 {
1941 	char *desc;
1942 
1943 	if (noffset < 0)
1944 		return noffset;
1945 
1946 	if (!fit_image_verify(fit, noffset))
1947 		return -EINVAL;
1948 
1949 	if (fit_image_get_data(fit, noffset, data, size))
1950 		return -ENOENT;
1951 
1952 	if (!fit_get_desc(fit, noffset, &desc))
1953 		printf("%s\n", desc);
1954 
1955 	return 0;
1956 }
1957 
fit_get_data_node(const void * fit,const char * image_uname,const void ** data,size_t * size)1958 int fit_get_data_node(const void *fit, const char *image_uname,
1959 		      const void **data, size_t *size)
1960 {
1961 	int noffset = fit_image_get_node(fit, image_uname);
1962 
1963 	return fit_get_data_tail(fit, noffset, data, size);
1964 }
1965 
fit_get_data_conf_prop(const void * fit,const char * prop_name,const void ** data,size_t * size)1966 int fit_get_data_conf_prop(const void *fit, const char *prop_name,
1967 			   const void **data, size_t *size)
1968 {
1969 	int noffset = fit_conf_get_node(fit, NULL);
1970 
1971 	noffset = fit_conf_get_prop_node(fit, noffset, prop_name,
1972 					 IH_PHASE_NONE);
1973 	return fit_get_data_tail(fit, noffset, data, size);
1974 }
1975 
fit_image_select(const void * fit,int rd_noffset,int verify)1976 static int fit_image_select(const void *fit, int rd_noffset, int verify)
1977 {
1978 	fit_image_print(fit, rd_noffset, "   ");
1979 
1980 	if (verify) {
1981 		puts("   Verifying Hash Integrity ... ");
1982 		if (!fit_image_verify(fit, rd_noffset)) {
1983 			puts("Bad Data Hash\n");
1984 			return -EACCES;
1985 		}
1986 		puts("OK\n");
1987 	}
1988 
1989 	return 0;
1990 }
1991 
fit_get_node_from_config(struct bootm_headers * images,const char * prop_name,ulong addr)1992 int fit_get_node_from_config(struct bootm_headers *images,
1993 			     const char *prop_name, ulong addr)
1994 {
1995 	int cfg_noffset;
1996 	void *fit_hdr;
1997 	int noffset;
1998 
1999 	debug("*  %s: using config '%s' from image at 0x%08lx\n",
2000 	      prop_name, images->fit_uname_cfg, addr);
2001 
2002 	/* Check whether configuration has this property defined */
2003 	fit_hdr = map_sysmem(addr, 0);
2004 	cfg_noffset = fit_conf_get_node(fit_hdr, images->fit_uname_cfg);
2005 	if (cfg_noffset < 0) {
2006 		debug("*  %s: no such config\n", prop_name);
2007 		return -EINVAL;
2008 	}
2009 
2010 	noffset = fit_conf_get_prop_node(fit_hdr, cfg_noffset, prop_name,
2011 					 IH_PHASE_NONE);
2012 	if (noffset < 0) {
2013 		debug("*  %s: no '%s' in config\n", prop_name, prop_name);
2014 		return -ENOENT;
2015 	}
2016 
2017 	return noffset;
2018 }
2019 
2020 /**
2021  * fit_get_image_type_property() - get property name for sel_phase
2022  *
2023  * Return: the properly name where we expect to find the image in the
2024  * config node
2025  */
fit_get_image_type_property(int ph_type)2026 static const char *fit_get_image_type_property(int ph_type)
2027 {
2028 	int type = image_ph_type(ph_type);
2029 
2030 	/*
2031 	 * This is sort-of available in the uimage_type[] table in image.c
2032 	 * but we don't have access to the short name, and "fdt" is different
2033 	 * anyway. So let's just keep it here.
2034 	 */
2035 	switch (type) {
2036 	case IH_TYPE_FLATDT:
2037 		return FIT_FDT_PROP;
2038 	case IH_TYPE_KERNEL:
2039 		return FIT_KERNEL_PROP;
2040 	case IH_TYPE_FIRMWARE:
2041 		return FIT_FIRMWARE_PROP;
2042 	case IH_TYPE_RAMDISK:
2043 		return FIT_RAMDISK_PROP;
2044 	case IH_TYPE_X86_SETUP:
2045 		return FIT_SETUP_PROP;
2046 	case IH_TYPE_LOADABLE:
2047 		return FIT_LOADABLE_PROP;
2048 	case IH_TYPE_FPGA:
2049 		return FIT_FPGA_PROP;
2050 	case IH_TYPE_STANDALONE:
2051 		return FIT_STANDALONE_PROP;
2052 	}
2053 
2054 	return "unknown";
2055 }
2056 
fit_image_load(struct bootm_headers * images,ulong addr,const char ** fit_unamep,const char ** fit_uname_configp,int arch,int ph_type,int bootstage_id,enum fit_load_op load_op,ulong * datap,ulong * lenp)2057 int fit_image_load(struct bootm_headers *images, ulong addr,
2058 		   const char **fit_unamep, const char **fit_uname_configp,
2059 		   int arch, int ph_type, int bootstage_id,
2060 		   enum fit_load_op load_op, ulong *datap, ulong *lenp)
2061 {
2062 	int image_type = image_ph_type(ph_type);
2063 	int cfg_noffset, noffset;
2064 	const char *fit_uname;
2065 	const char *fit_uname_config;
2066 	const char *fit_base_uname_config;
2067 	const void *fit;
2068 	void *buf;
2069 	void *loadbuf;
2070 	size_t size;
2071 	int type_ok, os_ok;
2072 	ulong load, load_end, data, len;
2073 	uint8_t os, comp;
2074 	const char *prop_name;
2075 	int ret;
2076 
2077 	fit = map_sysmem(addr, 0);
2078 	fit_uname = fit_unamep ? *fit_unamep : NULL;
2079 	fit_uname_config = fit_uname_configp ? *fit_uname_configp : NULL;
2080 	fit_base_uname_config = NULL;
2081 	prop_name = fit_get_image_type_property(ph_type);
2082 	printf("## Loading %s (%s) from FIT Image at %08lx ...\n",
2083 	       prop_name, genimg_get_phase_name(image_ph_phase(ph_type)), addr);
2084 
2085 	bootstage_mark(bootstage_id + BOOTSTAGE_SUB_FORMAT);
2086 	ret = fit_check_format(fit, IMAGE_SIZE_INVAL);
2087 	if (ret) {
2088 		printf("Bad FIT %s image format! (err=%d)\n", prop_name, ret);
2089 		if (CONFIG_IS_ENABLED(FIT_SIGNATURE) && ret == -EADDRNOTAVAIL)
2090 			printf("Signature checking prevents use of unit addresses (@) in nodes\n");
2091 		bootstage_error(bootstage_id + BOOTSTAGE_SUB_FORMAT);
2092 		return ret;
2093 	}
2094 	bootstage_mark(bootstage_id + BOOTSTAGE_SUB_FORMAT_OK);
2095 	if (fit_uname) {
2096 		/* get FIT component image node offset */
2097 		bootstage_mark(bootstage_id + BOOTSTAGE_SUB_UNIT_NAME);
2098 		noffset = fit_image_get_node(fit, fit_uname);
2099 	} else {
2100 		/*
2101 		 * no image node unit name, try to get config
2102 		 * node first. If config unit node name is NULL
2103 		 * fit_conf_get_node() will try to find default config node
2104 		 */
2105 		bootstage_mark(bootstage_id + BOOTSTAGE_SUB_NO_UNIT_NAME);
2106 		ret = -ENXIO;
2107 		if (IS_ENABLED(CONFIG_FIT_BEST_MATCH) && !fit_uname_config)
2108 			ret = fit_conf_find_compat(fit, gd_fdt_blob());
2109 		if (ret < 0 && ret != -EINVAL)
2110 			ret = fit_conf_get_node(fit, fit_uname_config);
2111 		if (ret < 0) {
2112 			puts("Could not find configuration node\n");
2113 			bootstage_error(bootstage_id +
2114 					BOOTSTAGE_SUB_NO_UNIT_NAME);
2115 			return -ENOENT;
2116 		}
2117 		cfg_noffset = ret;
2118 
2119 		fit_base_uname_config = fdt_get_name(fit, cfg_noffset, NULL);
2120 		printf("   Using '%s' configuration\n", fit_base_uname_config);
2121 		/* Remember this config */
2122 		if (image_type == IH_TYPE_KERNEL)
2123 			images->fit_uname_cfg = fit_base_uname_config;
2124 
2125 		if (FIT_IMAGE_ENABLE_VERIFY && images->verify) {
2126 			puts("   Verifying Hash Integrity ... ");
2127 			if (fit_config_verify(fit, cfg_noffset)) {
2128 				puts("Bad Data Hash\n");
2129 				bootstage_error(bootstage_id +
2130 					BOOTSTAGE_SUB_HASH);
2131 				return -EACCES;
2132 			}
2133 			puts("OK\n");
2134 		}
2135 
2136 		bootstage_mark(BOOTSTAGE_ID_FIT_CONFIG);
2137 
2138 		noffset = fit_conf_get_prop_node(fit, cfg_noffset, prop_name,
2139 						 image_ph_phase(ph_type));
2140 		fit_uname = fit_get_name(fit, noffset, NULL);
2141 	}
2142 	if (noffset < 0) {
2143 		printf("Could not find subimage node type '%s'\n", prop_name);
2144 		bootstage_error(bootstage_id + BOOTSTAGE_SUB_SUBNODE);
2145 		return -ENOENT;
2146 	}
2147 
2148 	printf("   Trying '%s' %s subimage\n", fit_uname, prop_name);
2149 
2150 	ret = fit_image_select(fit, noffset, images->verify);
2151 	if (ret) {
2152 		bootstage_error(bootstage_id + BOOTSTAGE_SUB_HASH);
2153 		return ret;
2154 	}
2155 
2156 	bootstage_mark(bootstage_id + BOOTSTAGE_SUB_CHECK_ARCH);
2157 	if (!tools_build() && IS_ENABLED(CONFIG_SANDBOX)) {
2158 		if (!fit_image_check_target_arch(fit, noffset)) {
2159 			puts("Unsupported Architecture\n");
2160 			bootstage_error(bootstage_id + BOOTSTAGE_SUB_CHECK_ARCH);
2161 			return -ENOEXEC;
2162 		}
2163 	}
2164 
2165 #ifndef USE_HOSTCC
2166 	{
2167 	uint8_t os_arch;
2168 
2169 	fit_image_get_arch(fit, noffset, &os_arch);
2170 	images->os.arch = os_arch;
2171 	}
2172 #endif
2173 
2174 	bootstage_mark(bootstage_id + BOOTSTAGE_SUB_CHECK_ALL);
2175 	type_ok = fit_image_check_type(fit, noffset, image_type) ||
2176 		  fit_image_check_type(fit, noffset, IH_TYPE_FIRMWARE) ||
2177 		  fit_image_check_type(fit, noffset, IH_TYPE_TEE) ||
2178 		  fit_image_check_type(fit, noffset, IH_TYPE_TFA_BL31) ||
2179 		  (image_type == IH_TYPE_KERNEL &&
2180 		   fit_image_check_type(fit, noffset, IH_TYPE_KERNEL_NOLOAD));
2181 
2182 	os_ok = image_type == IH_TYPE_FLATDT ||
2183 		image_type == IH_TYPE_FPGA ||
2184 		fit_image_check_os(fit, noffset, IH_OS_LINUX) ||
2185 		fit_image_check_os(fit, noffset, IH_OS_U_BOOT) ||
2186 		fit_image_check_os(fit, noffset, IH_OS_TEE) ||
2187 		fit_image_check_os(fit, noffset, IH_OS_OPENRTOS) ||
2188 		fit_image_check_os(fit, noffset, IH_OS_EFI) ||
2189 		fit_image_check_os(fit, noffset, IH_OS_VXWORKS) ||
2190 		fit_image_check_os(fit, noffset, IH_OS_ELF);
2191 
2192 	/*
2193 	 * If either of the checks fail, we should report an error, but
2194 	 * if the image type is coming from the "loadables" field, we
2195 	 * don't care what it is
2196 	 */
2197 	if ((!type_ok || !os_ok) && image_type != IH_TYPE_LOADABLE) {
2198 		fit_image_get_os(fit, noffset, &os);
2199 		printf("No %s %s %s Image\n",
2200 		       genimg_get_os_name(os),
2201 		       genimg_get_arch_name(arch),
2202 		       genimg_get_type_name(image_type));
2203 		bootstage_error(bootstage_id + BOOTSTAGE_SUB_CHECK_ALL);
2204 		return -EIO;
2205 	}
2206 
2207 	bootstage_mark(bootstage_id + BOOTSTAGE_SUB_CHECK_ALL_OK);
2208 
2209 	/* get image data address and length */
2210 	if (fit_image_get_data(fit, noffset, (const void **)&buf, &size)) {
2211 		printf("Could not find %s subimage data!\n", prop_name);
2212 		bootstage_error(bootstage_id + BOOTSTAGE_SUB_GET_DATA);
2213 		return -ENOENT;
2214 	}
2215 
2216 	/* Decrypt data before uncompress/move */
2217 	if (IS_ENABLED(CONFIG_FIT_CIPHER) && IMAGE_ENABLE_DECRYPT) {
2218 		puts("   Decrypting Data ... ");
2219 		if (fit_image_uncipher(fit, noffset, &buf, &size)) {
2220 			puts("Error\n");
2221 			return -EACCES;
2222 		}
2223 		puts("OK\n");
2224 	}
2225 
2226 	/* perform any post-processing on the image data */
2227 	if (!tools_build() && IS_ENABLED(CONFIG_FIT_IMAGE_POST_PROCESS))
2228 		board_fit_image_post_process(fit, noffset, &buf, &size);
2229 
2230 	len = (ulong)size;
2231 
2232 	bootstage_mark(bootstage_id + BOOTSTAGE_SUB_GET_DATA_OK);
2233 
2234 	data = map_to_sysmem(buf);
2235 	load = data;
2236 	if (load_op == FIT_LOAD_IGNORED) {
2237 		log_debug("load_op: not loading\n");
2238 		/* Don't load */
2239 	} else if (fit_image_get_load(fit, noffset, &load)) {
2240 		if (load_op == FIT_LOAD_REQUIRED) {
2241 			printf("Can't get %s subimage load address!\n",
2242 			       prop_name);
2243 			bootstage_error(bootstage_id + BOOTSTAGE_SUB_LOAD);
2244 			return -EBADF;
2245 		}
2246 	} else if (load_op != FIT_LOAD_OPTIONAL_NON_ZERO || load) {
2247 		ulong image_start, image_end;
2248 
2249 		/*
2250 		 * move image data to the load address,
2251 		 * make sure we don't overwrite initial image
2252 		 */
2253 		image_start = addr;
2254 		image_end = addr + fit_get_size(fit);
2255 
2256 		load_end = load + len;
2257 		if (image_type != IH_TYPE_KERNEL &&
2258 		    load < image_end && load_end > image_start) {
2259 			printf("Error: %s overwritten\n", prop_name);
2260 			return -EXDEV;
2261 		}
2262 
2263 		printf("   Loading %s from 0x%08lx to 0x%08lx\n",
2264 		       prop_name, data, load);
2265 	} else {
2266 		load = data;	/* No load address specified */
2267 	}
2268 
2269 	comp = IH_COMP_NONE;
2270 	loadbuf = buf;
2271 	/* Kernel images get decompressed later in bootm_load_os(). */
2272 	if (!fit_image_get_comp(fit, noffset, &comp) &&
2273 	    comp != IH_COMP_NONE &&
2274 	    load_op != FIT_LOAD_IGNORED &&
2275 	    !(image_type == IH_TYPE_KERNEL ||
2276 	      image_type == IH_TYPE_KERNEL_NOLOAD ||
2277 	      image_type == IH_TYPE_RAMDISK)) {
2278 		ulong max_decomp_len = len * 20;
2279 
2280 		log_debug("decompressing image\n");
2281 		if (load == data) {
2282 			loadbuf = malloc(max_decomp_len);
2283 			load = map_to_sysmem(loadbuf);
2284 		} else {
2285 			loadbuf = map_sysmem(load, max_decomp_len);
2286 		}
2287 		if (image_decomp(comp, load, data, image_type,
2288 				loadbuf, buf, len, max_decomp_len, &load_end)) {
2289 			printf("Error decompressing %s\n", prop_name);
2290 
2291 			return -ENOEXEC;
2292 		}
2293 		len = load_end - load;
2294 	} else if (load != data) {
2295 		log_debug("copying\n");
2296 		loadbuf = map_sysmem(load, len);
2297 		memcpy(loadbuf, buf, len);
2298 	}
2299 
2300 	if (image_type == IH_TYPE_RAMDISK && comp != IH_COMP_NONE)
2301 		puts("WARNING: 'compression' nodes for ramdisks are deprecated,"
2302 		     " please fix your .its file!\n");
2303 
2304 	/* verify that image data is a proper FDT blob */
2305 	if (load_op != FIT_LOAD_IGNORED && image_type == IH_TYPE_FLATDT &&
2306 	    fdt_check_header(loadbuf)) {
2307 		puts("Subimage data is not a FDT\n");
2308 		return -ENOEXEC;
2309 	}
2310 
2311 	bootstage_mark(bootstage_id + BOOTSTAGE_SUB_LOAD);
2312 
2313 	upl_add_image(fit, noffset, load, len);
2314 
2315 	*datap = load;
2316 	*lenp = len;
2317 	if (fit_unamep)
2318 		*fit_unamep = (char *)fit_uname;
2319 	if (fit_uname_configp)
2320 		*fit_uname_configp = (char *)(fit_uname_config ? :
2321 					      fit_base_uname_config);
2322 
2323 	return noffset;
2324 }
2325 
boot_get_setup_fit(struct bootm_headers * images,uint8_t arch,ulong * setup_start,ulong * setup_len)2326 int boot_get_setup_fit(struct bootm_headers *images, uint8_t arch,
2327 		       ulong *setup_start, ulong *setup_len)
2328 {
2329 	int noffset;
2330 	ulong addr;
2331 	ulong len;
2332 	int ret;
2333 
2334 	addr = map_to_sysmem(images->fit_hdr_os);
2335 	noffset = fit_get_node_from_config(images, FIT_SETUP_PROP, addr);
2336 	if (noffset < 0)
2337 		return noffset;
2338 
2339 	ret = fit_image_load(images, addr, NULL, NULL, arch,
2340 			     IH_TYPE_X86_SETUP, BOOTSTAGE_ID_FIT_SETUP_START,
2341 			     FIT_LOAD_REQUIRED, setup_start, &len);
2342 
2343 	return ret;
2344 }
2345 
2346 #ifndef USE_HOSTCC
boot_get_fdt_fit(struct bootm_headers * images,ulong addr,const char ** fit_unamep,const char ** fit_uname_configp,int arch,ulong * datap,ulong * lenp)2347 int boot_get_fdt_fit(struct bootm_headers *images, ulong addr,
2348 		     const char **fit_unamep, const char **fit_uname_configp,
2349 		     int arch, ulong *datap, ulong *lenp)
2350 {
2351 	int fdt_noffset, cfg_noffset, count;
2352 	const void *fit;
2353 	const char *fit_uname = NULL;
2354 	const char *fit_uname_config = NULL;
2355 	char *fit_uname_config_copy = NULL;
2356 	char *next_config = NULL;
2357 	ulong load, len;
2358 #ifdef CONFIG_OF_LIBFDT_OVERLAY
2359 	ulong ovload, ovlen, ovcopylen;
2360 	const char *uconfig;
2361 	const char *uname;
2362 	/*
2363 	 * of_flat_tree is storing the void * returned by map_sysmem, then its
2364 	 * address is passed to boot_relocate_fdt which expects a char ** and it
2365 	 * is then cast into a ulong. Setting its type to void * would require
2366 	 * to cast its address to char ** when passing it to boot_relocate_fdt.
2367 	 * Instead, let's be lazy and use void *.
2368 	 */
2369 	char *of_flat_tree;
2370 	void *base, *ov, *ovcopy = NULL;
2371 	int i, err, noffset, ov_noffset;
2372 #endif
2373 
2374 	fit_uname = fit_unamep ? *fit_unamep : NULL;
2375 
2376 	if (fit_uname_configp && *fit_uname_configp) {
2377 		fit_uname_config_copy = strdup(*fit_uname_configp);
2378 		if (!fit_uname_config_copy)
2379 			return -ENOMEM;
2380 
2381 		next_config = strchr(fit_uname_config_copy, '#');
2382 		if (next_config)
2383 			*next_config++ = '\0';
2384 		if (next_config - 1 > fit_uname_config_copy)
2385 			fit_uname_config = fit_uname_config_copy;
2386 	}
2387 
2388 	fdt_noffset = fit_image_load(images,
2389 		addr, &fit_uname, &fit_uname_config,
2390 		arch, IH_TYPE_FLATDT,
2391 		BOOTSTAGE_ID_FIT_FDT_START,
2392 		FIT_LOAD_OPTIONAL, &load, &len);
2393 
2394 	if (fdt_noffset < 0)
2395 		goto out;
2396 
2397 	debug("fit_uname=%s, fit_uname_config=%s\n",
2398 			fit_uname ? fit_uname : "<NULL>",
2399 			fit_uname_config ? fit_uname_config : "<NULL>");
2400 
2401 	fit = map_sysmem(addr, 0);
2402 
2403 	cfg_noffset = fit_conf_get_node(fit, fit_uname_config);
2404 
2405 	/* single blob, or error just return as well */
2406 	count = fit_conf_get_prop_node_count(fit, cfg_noffset, FIT_FDT_PROP);
2407 	if (count <= 1 && !next_config)
2408 		goto out;
2409 
2410 	/* we need to apply overlays */
2411 
2412 #ifdef CONFIG_OF_LIBFDT_OVERLAY
2413 	/* Relocate FDT so resizing does not overwrite other data in FIT. */
2414 	of_flat_tree = map_sysmem(load, len);
2415 	len = ALIGN(fdt_totalsize(load), SZ_4K);
2416 	err = boot_relocate_fdt(&of_flat_tree, &len);
2417 	if (err) {
2418 		printf("Required FDT relocation for applying DTOs failed: %d\n",
2419 		       err);
2420 		fdt_noffset = -EBADF;
2421 		goto out;
2422 	}
2423 
2424 	load = (ulong)of_flat_tree;
2425 
2426 	/* apply extra configs in FIT first, followed by args */
2427 	for (i = 1; ; i++) {
2428 		if (i < count) {
2429 			noffset = fit_conf_get_prop_node_index(fit, cfg_noffset,
2430 							       FIT_FDT_PROP, i);
2431 			uname = fit_get_name(fit, noffset, NULL);
2432 			uconfig = NULL;
2433 		} else {
2434 			if (!next_config)
2435 				break;
2436 			uconfig = next_config;
2437 			next_config = strchr(next_config, '#');
2438 			if (next_config)
2439 				*next_config++ = '\0';
2440 			uname = NULL;
2441 
2442 			/*
2443 			 * fit_image_load() would load the first FDT from the
2444 			 * extra config only when uconfig is specified.
2445 			 * Check if the extra config contains multiple FDTs and
2446 			 * if so, load them.
2447 			 */
2448 			cfg_noffset = fit_conf_get_node(fit, uconfig);
2449 
2450 			i = 0;
2451 			count = fit_conf_get_prop_node_count(fit, cfg_noffset,
2452 							     FIT_FDT_PROP);
2453 		}
2454 
2455 		debug("%d: using uname=%s uconfig=%s\n", i, uname, uconfig);
2456 
2457 		ov_noffset = fit_image_load(images,
2458 			addr, &uname, &uconfig,
2459 			arch, IH_TYPE_FLATDT,
2460 			BOOTSTAGE_ID_FIT_FDT_START,
2461 			FIT_LOAD_IGNORED, &ovload, &ovlen);
2462 		if (ov_noffset < 0) {
2463 			printf("load of %s failed\n", uname);
2464 			continue;
2465 		}
2466 		debug("%s loaded at 0x%08lx len=0x%08lx\n",
2467 				uname, ovload, ovlen);
2468 		ov = map_sysmem(ovload, ovlen);
2469 
2470 		ovcopylen = ALIGN(fdt_totalsize(ov), SZ_4K);
2471 		ovcopy = malloc(ovcopylen);
2472 		if (!ovcopy) {
2473 			printf("failed to duplicate DTO before application\n");
2474 			fdt_noffset = -ENOMEM;
2475 			goto out;
2476 		}
2477 
2478 		err = fdt_open_into(ov, ovcopy, ovcopylen);
2479 		if (err < 0) {
2480 			printf("failed on fdt_open_into for DTO\n");
2481 			fdt_noffset = err;
2482 			goto out;
2483 		}
2484 
2485 		base = map_sysmem(load, len + ovlen);
2486 		err = fdt_open_into(base, base, len + ovlen);
2487 		if (err < 0) {
2488 			printf("failed on fdt_open_into\n");
2489 			fdt_noffset = err;
2490 			goto out;
2491 		}
2492 
2493 		/* the verbose method prints out messages on error */
2494 		err = fdt_overlay_apply_verbose(base, ovcopy);
2495 		if (err < 0) {
2496 			fdt_noffset = err;
2497 			goto out;
2498 		}
2499 		fdt_pack(base);
2500 		len = fdt_totalsize(base);
2501 	}
2502 #else
2503 	printf("config with overlays but CONFIG_OF_LIBFDT_OVERLAY not set\n");
2504 	fdt_noffset = -EBADF;
2505 #endif
2506 
2507 out:
2508 	if (datap)
2509 		*datap = load;
2510 	if (lenp)
2511 		*lenp = len;
2512 	if (fit_unamep)
2513 		*fit_unamep = fit_uname;
2514 	if (fit_uname_configp)
2515 		*fit_uname_configp = fit_uname_config;
2516 
2517 #ifdef CONFIG_OF_LIBFDT_OVERLAY
2518 	free(ovcopy);
2519 #endif
2520 	free(fit_uname_config_copy);
2521 	return fdt_noffset;
2522 }
2523 #endif
2524