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