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