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