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>
28DECLARE_GLOBAL_DATA_PTR;
29#endif
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
43
44#ifndef USE_HOSTCC
45static int fit_parse_spec(const char *spec, char sepc, ulong addr_curr,
46 ulong *addr, const char **name)
47{
48 const char *sep;
49
50 *addr = addr_curr;
51 *name = NULL;
52
53 sep = strchr(spec, sepc);
54 if (sep) {
55 if (sep - spec > 0)
56 *addr = hextoul(spec, NULL);
57
58 *name = sep + 1;
59 return 1;
60 }
61
62 return 0;
63}
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86int 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
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112int 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
118
119#ifdef USE_HOSTCC
120
121static void *host_blob;
122
123void image_set_host_blob(void *blob)
124{
125 host_blob = blob;
126}
127
128void *image_get_host_blob(void)
129{
130 return host_blob;
131}
132#endif
133
134static 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
144
145
146
147
148
149
150int fit_get_subimage_count(const void *fit, int images_noffset)
151{
152 int noffset;
153 int ndepth;
154 int count = 0;
155
156
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
172
173
174
175
176
177
178
179
180
181
182
183
184
185static 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
230 if (IMAGE_ENABLE_TIMESTAMP && keyname) {
231 time_t timestamp;
232
233 printf("%s Timestamp: ", p);
234 if (fit_get_timestamp(fit, noffset, ×tamp))
235 printf("unavailable\n");
236 else
237 genimg_print_time(timestamp);
238 }
239}
240
241
242
243
244
245
246
247
248
249
250
251
252static void fit_image_print_verification_data(const void *fit, int noffset,
253 const char *p)
254{
255 const char *name;
256
257
258
259
260
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
273
274
275
276
277
278
279
280
281
282
283static 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
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
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
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
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
349 fit_image_print_verification_data(fit, noffset, p);
350 }
351 }
352}
353
354
355
356
357
358
359
360
361
362
363
364
365
366void 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
380 p = IMAGE_INDENT_STRING;
381
382
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, ×tamp);
392 printf("%sCreated: ", p);
393 if (ret)
394 printf("unavailable\n");
395 else
396 genimg_print_time(timestamp);
397 }
398
399
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
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
415
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
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
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
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
445
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
457
458
459
460
461
462
463
464
465
466
467
468
469
470void 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
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, ×tamp);
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
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
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
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
570 fit_image_print_verification_data(fit, noffset, p);
571 }
572 }
573}
574#else
575void fit_print_contents(const void *fit) { }
576void fit_image_print(const void *fit, int image_noffset, const char *p) { }
577#endif
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592int 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
607
608
609
610
611
612
613
614
615
616
617
618
619
620int 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
641
642
643
644
645
646
647
648
649
650
651
652int 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
674
675
676
677
678
679
680
681
682
683
684
685
686int fit_image_get_os(const void *fit, int noffset, uint8_t *os)
687{
688 int len;
689 const void *data;
690
691
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
700 *os = genimg_get_os_id(data);
701 return 0;
702}
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718int fit_image_get_arch(const void *fit, int noffset, uint8_t *arch)
719{
720 int len;
721 const void *data;
722
723
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
732 *arch = genimg_get_arch_id(data);
733 return 0;
734}
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750int fit_image_get_type(const void *fit, int noffset, uint8_t *type)
751{
752 int len;
753 const void *data;
754
755
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
764 *type = genimg_get_type_id(data);
765 return 0;
766}
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782int fit_image_get_comp(const void *fit, int noffset, uint8_t *comp)
783{
784 int len;
785 const void *data;
786
787
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
796 *comp = genimg_get_comp_id(data);
797 return 0;
798}
799
800static 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
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
831
832
833
834
835
836
837
838
839
840
841
842int 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
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864int 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
871
872
873
874
875
876
877
878
879
880
881
882
883
884int 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
902
903
904
905
906
907
908
909
910
911int 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
926
927
928
929
930
931
932
933
934
935int 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
951
952
953
954
955
956
957
958
959
960int 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
975
976
977
978
979
980
981
982
983
984int 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
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014int 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
1028
1029
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
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061int 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
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089int 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
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119static 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
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147int 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
1160ulong fit_get_end(const void *fit)
1161{
1162 return map_to_sysmem((void *)(fit + fdt_totalsize(fit)));
1163}
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178int 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
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214int calculate_hash(const void *data, int data_len, const char *name,
1215 uint8_t *value, int *value_len)
1216{
1217 struct hash_algo *algo;
1218 int ret;
1219
1220 ret = hash_lookup_algo(name, &algo);
1221 if (ret < 0) {
1222 debug("Unsupported hash alogrithm\n");
1223 return -1;
1224 }
1225
1226 algo->hash_func_ws(data, data_len, value, algo->chunk_size);
1227 *value_len = algo->digest_size;
1228
1229 return 0;
1230}
1231
1232static int fit_image_check_hash(const void *fit, int noffset, const void *data,
1233 size_t size, char **err_msgp)
1234{
1235 uint8_t value[FIT_MAX_HASH_LEN];
1236 int value_len;
1237 char *algo;
1238 uint8_t *fit_value;
1239 int fit_value_len;
1240 int ignore;
1241
1242 *err_msgp = NULL;
1243
1244 if (fit_image_hash_get_algo(fit, noffset, &algo)) {
1245 *err_msgp = "Can't get hash algo property";
1246 return -1;
1247 }
1248 printf("%s", algo);
1249
1250 if (IMAGE_ENABLE_IGNORE) {
1251 fit_image_hash_get_ignore(fit, noffset, &ignore);
1252 if (ignore) {
1253 printf("-skipped ");
1254 return 0;
1255 }
1256 }
1257
1258 if (fit_image_hash_get_value(fit, noffset, &fit_value,
1259 &fit_value_len)) {
1260 *err_msgp = "Can't get hash value property";
1261 return -1;
1262 }
1263
1264 if (calculate_hash(data, size, algo, value, &value_len)) {
1265 *err_msgp = "Unsupported hash algorithm";
1266 return -1;
1267 }
1268
1269 if (value_len != fit_value_len) {
1270 *err_msgp = "Bad hash value len";
1271 return -1;
1272 } else if (memcmp(value, fit_value, value_len) != 0) {
1273 *err_msgp = "Bad hash value";
1274 return -1;
1275 }
1276
1277 return 0;
1278}
1279
1280int fit_image_verify_with_data(const void *fit, int image_noffset,
1281 const void *data, size_t size)
1282{
1283 int noffset = 0;
1284 char *err_msg = "";
1285 int verify_all = 1;
1286 int ret;
1287
1288
1289 if (FIT_IMAGE_ENABLE_VERIFY &&
1290 fit_image_verify_required_sigs(fit, image_noffset, data, size,
1291 gd_fdt_blob(), &verify_all)) {
1292 err_msg = "Unable to verify required signature";
1293 goto error;
1294 }
1295
1296
1297 fdt_for_each_subnode(noffset, fit, image_noffset) {
1298 const char *name = fit_get_name(fit, noffset, NULL);
1299
1300
1301
1302
1303
1304
1305 if (!strncmp(name, FIT_HASH_NODENAME,
1306 strlen(FIT_HASH_NODENAME))) {
1307 if (fit_image_check_hash(fit, noffset, data, size,
1308 &err_msg))
1309 goto error;
1310 puts("+ ");
1311 } else if (FIT_IMAGE_ENABLE_VERIFY && verify_all &&
1312 !strncmp(name, FIT_SIG_NODENAME,
1313 strlen(FIT_SIG_NODENAME))) {
1314 ret = fit_image_check_sig(fit, noffset, data,
1315 size, -1, &err_msg);
1316
1317
1318
1319
1320
1321
1322
1323 if (ret)
1324 puts("- ");
1325 else
1326 puts("+ ");
1327 }
1328 }
1329
1330 if (noffset == -FDT_ERR_TRUNCATED || noffset == -FDT_ERR_BADSTRUCTURE) {
1331 err_msg = "Corrupted or truncated tree";
1332 goto error;
1333 }
1334
1335 return 1;
1336
1337error:
1338 printf(" error!\n%s for '%s' hash node in '%s' image node\n",
1339 err_msg, fit_get_name(fit, noffset, NULL),
1340 fit_get_name(fit, image_noffset, NULL));
1341 return 0;
1342}
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357int fit_image_verify(const void *fit, int image_noffset)
1358{
1359 const char *name = fit_get_name(fit, image_noffset, NULL);
1360 const void *data;
1361 size_t size;
1362 char *err_msg = "";
1363
1364 if (IS_ENABLED(CONFIG_FIT_SIGNATURE) && strchr(name, '@')) {
1365
1366
1367
1368
1369 err_msg = "Node name contains @";
1370 goto err;
1371 }
1372
1373 if (fit_image_get_data_and_size(fit, image_noffset, &data, &size)) {
1374 err_msg = "Can't get image data/size";
1375 goto err;
1376 }
1377
1378 return fit_image_verify_with_data(fit, image_noffset, data, size);
1379
1380err:
1381 printf("error!\n%s in '%s' image node\n", err_msg,
1382 fit_get_name(fit, image_noffset, NULL));
1383 return 0;
1384}
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397int fit_all_image_verify(const void *fit)
1398{
1399 int images_noffset;
1400 int noffset;
1401 int ndepth;
1402 int count;
1403
1404
1405 images_noffset = fdt_path_offset(fit, FIT_IMAGES_PATH);
1406 if (images_noffset < 0) {
1407 printf("Can't find images parent node '%s' (%s)\n",
1408 FIT_IMAGES_PATH, fdt_strerror(images_noffset));
1409 return 0;
1410 }
1411
1412
1413 printf("## Checking hash(es) for FIT Image at %08lx ...\n",
1414 (ulong)fit);
1415 for (ndepth = 0, count = 0,
1416 noffset = fdt_next_node(fit, images_noffset, &ndepth);
1417 (noffset >= 0) && (ndepth > 0);
1418 noffset = fdt_next_node(fit, noffset, &ndepth)) {
1419 if (ndepth == 1) {
1420
1421
1422
1423
1424 printf(" Hash(es) for Image %u (%s): ", count,
1425 fit_get_name(fit, noffset, NULL));
1426 count++;
1427
1428 if (!fit_image_verify(fit, noffset))
1429 return 0;
1430 printf("\n");
1431 }
1432 }
1433 return 1;
1434}
1435
1436static int fit_image_uncipher(const void *fit, int image_noffset,
1437 void **data, size_t *size)
1438{
1439 int cipher_noffset, ret;
1440 void *dst;
1441 size_t size_dst;
1442
1443 cipher_noffset = fdt_subnode_offset(fit, image_noffset,
1444 FIT_CIPHER_NODENAME);
1445 if (cipher_noffset < 0)
1446 return 0;
1447
1448 ret = fit_image_decrypt_data(fit, image_noffset, cipher_noffset,
1449 *data, *size, &dst, &size_dst);
1450 if (ret)
1451 goto out;
1452
1453 *data = dst;
1454 *size = size_dst;
1455
1456 out:
1457 return ret;
1458}
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473int fit_image_check_os(const void *fit, int noffset, uint8_t os)
1474{
1475 uint8_t image_os;
1476
1477 if (fit_image_get_os(fit, noffset, &image_os))
1478 return 0;
1479 return (os == image_os);
1480}
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495int fit_image_check_arch(const void *fit, int noffset, uint8_t arch)
1496{
1497 uint8_t image_arch;
1498 int aarch32_support = 0;
1499
1500
1501 if (IS_ENABLED(CONFIG_SANDBOX))
1502 return true;
1503
1504 if (IS_ENABLED(CONFIG_ARM64_SUPPORT_AARCH32))
1505 aarch32_support = 1;
1506
1507 if (fit_image_get_arch(fit, noffset, &image_arch))
1508 return 0;
1509 return (arch == image_arch) ||
1510 (arch == IH_ARCH_I386 && image_arch == IH_ARCH_X86_64) ||
1511 (arch == IH_ARCH_ARM64 && image_arch == IH_ARCH_ARM &&
1512 aarch32_support);
1513}
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528int fit_image_check_type(const void *fit, int noffset, uint8_t type)
1529{
1530 uint8_t image_type;
1531
1532 if (fit_image_get_type(fit, noffset, &image_type))
1533 return 0;
1534 return (type == image_type);
1535}
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551int fit_image_check_comp(const void *fit, int noffset, uint8_t comp)
1552{
1553 uint8_t image_comp;
1554
1555 if (fit_image_get_comp(fit, noffset, &image_comp))
1556 return 0;
1557 return (comp == image_comp);
1558}
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569static int fdt_check_no_at(const void *fit, int parent)
1570{
1571 const char *name;
1572 int node;
1573 int ret;
1574
1575 name = fdt_get_name(fit, parent, NULL);
1576 if (!name || strchr(name, '@'))
1577 return -EADDRNOTAVAIL;
1578
1579 fdt_for_each_subnode(node, fit, parent) {
1580 ret = fdt_check_no_at(fit, node);
1581 if (ret)
1582 return ret;
1583 }
1584
1585 return 0;
1586}
1587
1588int fit_check_format(const void *fit, ulong size)
1589{
1590 int ret;
1591
1592
1593 ret = fdt_check_header(fit);
1594 if (ret) {
1595 log_debug("Wrong FIT format: not a flattened device tree (err=%d)\n",
1596 ret);
1597 return -ENOEXEC;
1598 }
1599
1600 if (CONFIG_IS_ENABLED(FIT_FULL_CHECK)) {
1601
1602
1603
1604
1605
1606 if (size == IMAGE_SIZE_INVAL)
1607 size = fdt_totalsize(fit);
1608 ret = fdt_check_full(fit, size);
1609 if (ret)
1610 ret = -EINVAL;
1611
1612
1613
1614
1615
1616
1617
1618
1619 if (!ret && CONFIG_IS_ENABLED(FIT_SIGNATURE)) {
1620 ret = fdt_check_no_at(fit, 0);
1621
1622 if (ret) {
1623 log_debug("FIT check error %d\n", ret);
1624 return ret;
1625 }
1626 }
1627 if (ret) {
1628 log_debug("FIT check error %d\n", ret);
1629 return ret;
1630 }
1631 }
1632
1633
1634 if (!fdt_getprop(fit, 0, FIT_DESC_PROP, NULL)) {
1635 log_debug("Wrong FIT format: no description\n");
1636 return -ENOMSG;
1637 }
1638
1639 if (IMAGE_ENABLE_TIMESTAMP) {
1640
1641 if (!fdt_getprop(fit, 0, FIT_TIMESTAMP_PROP, NULL)) {
1642 log_debug("Wrong FIT format: no timestamp\n");
1643 return -EBADMSG;
1644 }
1645 }
1646
1647
1648 if (fdt_path_offset(fit, FIT_IMAGES_PATH) < 0) {
1649 log_debug("Wrong FIT format: no images parent node\n");
1650 return -ENOENT;
1651 }
1652
1653 return 0;
1654}
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699int fit_conf_find_compat(const void *fit, const void *fdt)
1700{
1701 int ndepth = 0;
1702 int noffset, confs_noffset, images_noffset;
1703 const void *fdt_compat;
1704 int fdt_compat_len;
1705 int best_match_offset = 0;
1706 int best_match_pos = 0;
1707
1708 confs_noffset = fdt_path_offset(fit, FIT_CONFS_PATH);
1709 images_noffset = fdt_path_offset(fit, FIT_IMAGES_PATH);
1710 if (confs_noffset < 0 || images_noffset < 0) {
1711 debug("Can't find configurations or images nodes.\n");
1712 return -1;
1713 }
1714
1715 fdt_compat = fdt_getprop(fdt, 0, "compatible", &fdt_compat_len);
1716 if (!fdt_compat) {
1717 debug("Fdt for comparison has no \"compatible\" property.\n");
1718 return -1;
1719 }
1720
1721
1722
1723
1724 for (noffset = fdt_next_node(fit, confs_noffset, &ndepth);
1725 (noffset >= 0) && (ndepth > 0);
1726 noffset = fdt_next_node(fit, noffset, &ndepth)) {
1727 const void *fdt;
1728 const char *kfdt_name;
1729 int kfdt_noffset, compat_noffset;
1730 const char *cur_fdt_compat;
1731 int len;
1732 size_t sz;
1733 int i;
1734
1735 if (ndepth > 1)
1736 continue;
1737
1738
1739 if (fdt_getprop(fit, noffset, "compatible", NULL)) {
1740 fdt = fit;
1741 compat_noffset = noffset;
1742 } else {
1743 kfdt_name = fdt_getprop(fit, noffset, "fdt", &len);
1744 if (!kfdt_name) {
1745 debug("No fdt property found.\n");
1746 continue;
1747 }
1748 kfdt_noffset = fdt_subnode_offset(fit, images_noffset,
1749 kfdt_name);
1750 if (kfdt_noffset < 0) {
1751 debug("No image node named \"%s\" found.\n",
1752 kfdt_name);
1753 continue;
1754 }
1755
1756 if (!fit_image_check_comp(fit, kfdt_noffset,
1757 IH_COMP_NONE)) {
1758 debug("Can't extract compat from \"%s\" "
1759 "(compressed)\n", kfdt_name);
1760 continue;
1761 }
1762
1763
1764 if (fit_image_get_data_and_size(fit, kfdt_noffset,
1765 &fdt, &sz)) {
1766 debug("Failed to get fdt \"%s\".\n", kfdt_name);
1767 continue;
1768 }
1769
1770 compat_noffset = 0;
1771 }
1772
1773 len = fdt_compat_len;
1774 cur_fdt_compat = fdt_compat;
1775
1776
1777
1778
1779 for (i = 0; len > 0 &&
1780 (!best_match_offset || best_match_pos > i); i++) {
1781 int cur_len = strlen(cur_fdt_compat) + 1;
1782
1783 if (!fdt_node_check_compatible(fdt, compat_noffset,
1784 cur_fdt_compat)) {
1785 best_match_offset = noffset;
1786 best_match_pos = i;
1787 break;
1788 }
1789 len -= cur_len;
1790 cur_fdt_compat += cur_len;
1791 }
1792 }
1793 if (!best_match_offset) {
1794 debug("No match found.\n");
1795 return -1;
1796 }
1797
1798 return best_match_offset;
1799}
1800
1801int fit_conf_get_node(const void *fit, const char *conf_uname)
1802{
1803 int noffset, confs_noffset;
1804 int len;
1805 const char *s;
1806 char *conf_uname_copy = NULL;
1807
1808 confs_noffset = fdt_path_offset(fit, FIT_CONFS_PATH);
1809 if (confs_noffset < 0) {
1810 debug("Can't find configurations parent node '%s' (%s)\n",
1811 FIT_CONFS_PATH, fdt_strerror(confs_noffset));
1812 return confs_noffset;
1813 }
1814
1815 if (conf_uname == NULL) {
1816
1817 debug("No configuration specified, trying default...\n");
1818 if (!host_build() && IS_ENABLED(CONFIG_MULTI_DTB_FIT)) {
1819 noffset = fit_find_config_node(fit);
1820 if (noffset < 0)
1821 return noffset;
1822 conf_uname = fdt_get_name(fit, noffset, NULL);
1823 } else {
1824 conf_uname = (char *)fdt_getprop(fit, confs_noffset,
1825 FIT_DEFAULT_PROP, &len);
1826 if (conf_uname == NULL) {
1827 fit_get_debug(fit, confs_noffset, FIT_DEFAULT_PROP,
1828 len);
1829 return len;
1830 }
1831 }
1832 debug("Found default configuration: '%s'\n", conf_uname);
1833 }
1834
1835 s = strchr(conf_uname, '#');
1836 if (s) {
1837 len = s - conf_uname;
1838 conf_uname_copy = malloc(len + 1);
1839 if (!conf_uname_copy) {
1840 debug("Can't allocate uname copy: '%s'\n",
1841 conf_uname);
1842 return -ENOMEM;
1843 }
1844 memcpy(conf_uname_copy, conf_uname, len);
1845 conf_uname_copy[len] = '\0';
1846 conf_uname = conf_uname_copy;
1847 }
1848
1849 noffset = fdt_subnode_offset(fit, confs_noffset, conf_uname);
1850 if (noffset < 0) {
1851 debug("Can't get node offset for configuration unit name: '%s' (%s)\n",
1852 conf_uname, fdt_strerror(noffset));
1853 }
1854
1855 if (conf_uname_copy)
1856 free(conf_uname_copy);
1857
1858 return noffset;
1859}
1860
1861int fit_conf_get_prop_node_count(const void *fit, int noffset,
1862 const char *prop_name)
1863{
1864 return fdt_stringlist_count(fit, noffset, prop_name);
1865}
1866
1867int fit_conf_get_prop_node_index(const void *fit, int noffset,
1868 const char *prop_name, int index)
1869{
1870 const char *uname;
1871 int len;
1872
1873
1874 uname = fdt_stringlist_get(fit, noffset, prop_name, index, &len);
1875 if (uname == NULL)
1876 return len;
1877
1878 return fit_image_get_node(fit, uname);
1879}
1880
1881int fit_conf_get_prop_node(const void *fit, int noffset,
1882 const char *prop_name)
1883{
1884 return fit_conf_get_prop_node_index(fit, noffset, prop_name, 0);
1885}
1886
1887static int fit_image_select(const void *fit, int rd_noffset, int verify)
1888{
1889 fit_image_print(fit, rd_noffset, " ");
1890
1891 if (verify) {
1892 puts(" Verifying Hash Integrity ... ");
1893 if (!fit_image_verify(fit, rd_noffset)) {
1894 puts("Bad Data Hash\n");
1895 return -EACCES;
1896 }
1897 puts("OK\n");
1898 }
1899
1900 return 0;
1901}
1902
1903int fit_get_node_from_config(bootm_headers_t *images, const char *prop_name,
1904 ulong addr)
1905{
1906 int cfg_noffset;
1907 void *fit_hdr;
1908 int noffset;
1909
1910 debug("* %s: using config '%s' from image at 0x%08lx\n",
1911 prop_name, images->fit_uname_cfg, addr);
1912
1913
1914 fit_hdr = map_sysmem(addr, 0);
1915 cfg_noffset = fit_conf_get_node(fit_hdr, images->fit_uname_cfg);
1916 if (cfg_noffset < 0) {
1917 debug("* %s: no such config\n", prop_name);
1918 return -EINVAL;
1919 }
1920
1921 noffset = fit_conf_get_prop_node(fit_hdr, cfg_noffset, prop_name);
1922 if (noffset < 0) {
1923 debug("* %s: no '%s' in config\n", prop_name, prop_name);
1924 return -ENOENT;
1925 }
1926
1927 return noffset;
1928}
1929
1930
1931
1932
1933
1934
1935
1936static const char *fit_get_image_type_property(int type)
1937{
1938
1939
1940
1941
1942
1943 switch (type) {
1944 case IH_TYPE_FLATDT:
1945 return FIT_FDT_PROP;
1946 case IH_TYPE_KERNEL:
1947 return FIT_KERNEL_PROP;
1948 case IH_TYPE_FIRMWARE:
1949 return FIT_FIRMWARE_PROP;
1950 case IH_TYPE_RAMDISK:
1951 return FIT_RAMDISK_PROP;
1952 case IH_TYPE_X86_SETUP:
1953 return FIT_SETUP_PROP;
1954 case IH_TYPE_LOADABLE:
1955 return FIT_LOADABLE_PROP;
1956 case IH_TYPE_FPGA:
1957 return FIT_FPGA_PROP;
1958 case IH_TYPE_STANDALONE:
1959 return FIT_STANDALONE_PROP;
1960 }
1961
1962 return "unknown";
1963}
1964
1965int fit_image_load(bootm_headers_t *images, ulong addr,
1966 const char **fit_unamep, const char **fit_uname_configp,
1967 int arch, int image_type, int bootstage_id,
1968 enum fit_load_op load_op, ulong *datap, ulong *lenp)
1969{
1970 int cfg_noffset, noffset;
1971 const char *fit_uname;
1972 const char *fit_uname_config;
1973 const char *fit_base_uname_config;
1974 const void *fit;
1975 void *buf;
1976 void *loadbuf;
1977 size_t size;
1978 int type_ok, os_ok;
1979 ulong load, load_end, data, len;
1980 uint8_t os, comp;
1981#ifndef USE_HOSTCC
1982 uint8_t os_arch;
1983#endif
1984 const char *prop_name;
1985 int ret;
1986
1987 fit = map_sysmem(addr, 0);
1988 fit_uname = fit_unamep ? *fit_unamep : NULL;
1989 fit_uname_config = fit_uname_configp ? *fit_uname_configp : NULL;
1990 fit_base_uname_config = NULL;
1991 prop_name = fit_get_image_type_property(image_type);
1992 printf("## Loading %s from FIT Image at %08lx ...\n", prop_name, addr);
1993
1994 bootstage_mark(bootstage_id + BOOTSTAGE_SUB_FORMAT);
1995 ret = fit_check_format(fit, IMAGE_SIZE_INVAL);
1996 if (ret) {
1997 printf("Bad FIT %s image format! (err=%d)\n", prop_name, ret);
1998 if (CONFIG_IS_ENABLED(FIT_SIGNATURE) && ret == -EADDRNOTAVAIL)
1999 printf("Signature checking prevents use of unit addresses (@) in nodes\n");
2000 bootstage_error(bootstage_id + BOOTSTAGE_SUB_FORMAT);
2001 return ret;
2002 }
2003 bootstage_mark(bootstage_id + BOOTSTAGE_SUB_FORMAT_OK);
2004 if (fit_uname) {
2005
2006 bootstage_mark(bootstage_id + BOOTSTAGE_SUB_UNIT_NAME);
2007 noffset = fit_image_get_node(fit, fit_uname);
2008 } else {
2009
2010
2011
2012
2013
2014 bootstage_mark(bootstage_id + BOOTSTAGE_SUB_NO_UNIT_NAME);
2015 if (IS_ENABLED(CONFIG_FIT_BEST_MATCH) && !fit_uname_config) {
2016 cfg_noffset = fit_conf_find_compat(fit, gd_fdt_blob());
2017 } else {
2018 cfg_noffset = fit_conf_get_node(fit,
2019 fit_uname_config);
2020 }
2021 if (cfg_noffset < 0) {
2022 puts("Could not find configuration node\n");
2023 bootstage_error(bootstage_id +
2024 BOOTSTAGE_SUB_NO_UNIT_NAME);
2025 return -ENOENT;
2026 }
2027
2028 fit_base_uname_config = fdt_get_name(fit, cfg_noffset, NULL);
2029 printf(" Using '%s' configuration\n", fit_base_uname_config);
2030
2031 if (image_type == IH_TYPE_KERNEL)
2032 images->fit_uname_cfg = fit_base_uname_config;
2033
2034 if (FIT_IMAGE_ENABLE_VERIFY && images->verify) {
2035 puts(" Verifying Hash Integrity ... ");
2036 if (fit_config_verify(fit, cfg_noffset)) {
2037 puts("Bad Data Hash\n");
2038 bootstage_error(bootstage_id +
2039 BOOTSTAGE_SUB_HASH);
2040 return -EACCES;
2041 }
2042 puts("OK\n");
2043 }
2044
2045 bootstage_mark(BOOTSTAGE_ID_FIT_CONFIG);
2046
2047 noffset = fit_conf_get_prop_node(fit, cfg_noffset,
2048 prop_name);
2049 fit_uname = fit_get_name(fit, noffset, NULL);
2050 }
2051 if (noffset < 0) {
2052 printf("Could not find subimage node type '%s'\n", prop_name);
2053 bootstage_error(bootstage_id + BOOTSTAGE_SUB_SUBNODE);
2054 return -ENOENT;
2055 }
2056
2057 printf(" Trying '%s' %s subimage\n", fit_uname, prop_name);
2058
2059 ret = fit_image_select(fit, noffset, images->verify);
2060 if (ret) {
2061 bootstage_error(bootstage_id + BOOTSTAGE_SUB_HASH);
2062 return ret;
2063 }
2064
2065 bootstage_mark(bootstage_id + BOOTSTAGE_SUB_CHECK_ARCH);
2066 if (!host_build() && IS_ENABLED(CONFIG_SANDBOX)) {
2067 if (!fit_image_check_target_arch(fit, noffset)) {
2068 puts("Unsupported Architecture\n");
2069 bootstage_error(bootstage_id + BOOTSTAGE_SUB_CHECK_ARCH);
2070 return -ENOEXEC;
2071 }
2072 }
2073
2074#ifndef USE_HOSTCC
2075 fit_image_get_arch(fit, noffset, &os_arch);
2076 images->os.arch = os_arch;
2077#endif
2078
2079 bootstage_mark(bootstage_id + BOOTSTAGE_SUB_CHECK_ALL);
2080 type_ok = fit_image_check_type(fit, noffset, image_type) ||
2081 fit_image_check_type(fit, noffset, IH_TYPE_FIRMWARE) ||
2082 fit_image_check_type(fit, noffset, IH_TYPE_TEE) ||
2083 (image_type == IH_TYPE_KERNEL &&
2084 fit_image_check_type(fit, noffset, IH_TYPE_KERNEL_NOLOAD));
2085
2086 os_ok = image_type == IH_TYPE_FLATDT ||
2087 image_type == IH_TYPE_FPGA ||
2088 fit_image_check_os(fit, noffset, IH_OS_LINUX) ||
2089 fit_image_check_os(fit, noffset, IH_OS_U_BOOT) ||
2090 fit_image_check_os(fit, noffset, IH_OS_TEE) ||
2091 fit_image_check_os(fit, noffset, IH_OS_OPENRTOS) ||
2092 fit_image_check_os(fit, noffset, IH_OS_EFI) ||
2093 fit_image_check_os(fit, noffset, IH_OS_VXWORKS);
2094
2095
2096
2097
2098
2099
2100 if ((!type_ok || !os_ok) && image_type != IH_TYPE_LOADABLE) {
2101 fit_image_get_os(fit, noffset, &os);
2102 printf("No %s %s %s Image\n",
2103 genimg_get_os_name(os),
2104 genimg_get_arch_name(arch),
2105 genimg_get_type_name(image_type));
2106 bootstage_error(bootstage_id + BOOTSTAGE_SUB_CHECK_ALL);
2107 return -EIO;
2108 }
2109
2110 bootstage_mark(bootstage_id + BOOTSTAGE_SUB_CHECK_ALL_OK);
2111
2112
2113 if (fit_image_get_data_and_size(fit, noffset,
2114 (const void **)&buf, &size)) {
2115 printf("Could not find %s subimage data!\n", prop_name);
2116 bootstage_error(bootstage_id + BOOTSTAGE_SUB_GET_DATA);
2117 return -ENOENT;
2118 }
2119
2120
2121 if (IS_ENABLED(CONFIG_FIT_CIPHER) && IMAGE_ENABLE_DECRYPT) {
2122 puts(" Decrypting Data ... ");
2123 if (fit_image_uncipher(fit, noffset, &buf, &size)) {
2124 puts("Error\n");
2125 return -EACCES;
2126 }
2127 puts("OK\n");
2128 }
2129
2130
2131 if (!host_build() && IS_ENABLED(CONFIG_FIT_IMAGE_POST_PROCESS))
2132 board_fit_image_post_process(fit, noffset, &buf, &size);
2133
2134 len = (ulong)size;
2135
2136 bootstage_mark(bootstage_id + BOOTSTAGE_SUB_GET_DATA_OK);
2137
2138 data = map_to_sysmem(buf);
2139 load = data;
2140 if (load_op == FIT_LOAD_IGNORED) {
2141
2142 } else if (fit_image_get_load(fit, noffset, &load)) {
2143 if (load_op == FIT_LOAD_REQUIRED) {
2144 printf("Can't get %s subimage load address!\n",
2145 prop_name);
2146 bootstage_error(bootstage_id + BOOTSTAGE_SUB_LOAD);
2147 return -EBADF;
2148 }
2149 } else if (load_op != FIT_LOAD_OPTIONAL_NON_ZERO || load) {
2150 ulong image_start, image_end;
2151
2152
2153
2154
2155
2156 image_start = addr;
2157 image_end = addr + fit_get_size(fit);
2158
2159 load_end = load + len;
2160 if (image_type != IH_TYPE_KERNEL &&
2161 load < image_end && load_end > image_start) {
2162 printf("Error: %s overwritten\n", prop_name);
2163 return -EXDEV;
2164 }
2165
2166 printf(" Loading %s from 0x%08lx to 0x%08lx\n",
2167 prop_name, data, load);
2168 } else {
2169 load = data;
2170 }
2171
2172 comp = IH_COMP_NONE;
2173 loadbuf = buf;
2174
2175 if (!fit_image_get_comp(fit, noffset, &comp) &&
2176 comp != IH_COMP_NONE &&
2177 !(image_type == IH_TYPE_KERNEL ||
2178 image_type == IH_TYPE_KERNEL_NOLOAD ||
2179 image_type == IH_TYPE_RAMDISK)) {
2180 ulong max_decomp_len = len * 20;
2181 if (load == data) {
2182 loadbuf = malloc(max_decomp_len);
2183 load = map_to_sysmem(loadbuf);
2184 } else {
2185 loadbuf = map_sysmem(load, max_decomp_len);
2186 }
2187 if (image_decomp(comp, load, data, image_type,
2188 loadbuf, buf, len, max_decomp_len, &load_end)) {
2189 printf("Error decompressing %s\n", prop_name);
2190
2191 return -ENOEXEC;
2192 }
2193 len = load_end - load;
2194 } else if (load != data) {
2195 loadbuf = map_sysmem(load, len);
2196 memcpy(loadbuf, buf, len);
2197 }
2198
2199 if (image_type == IH_TYPE_RAMDISK && comp != IH_COMP_NONE)
2200 puts("WARNING: 'compression' nodes for ramdisks are deprecated,"
2201 " please fix your .its file!\n");
2202
2203
2204 if (image_type == IH_TYPE_FLATDT && fdt_check_header(loadbuf)) {
2205 puts("Subimage data is not a FDT");
2206 return -ENOEXEC;
2207 }
2208
2209 bootstage_mark(bootstage_id + BOOTSTAGE_SUB_LOAD);
2210
2211 *datap = load;
2212 *lenp = len;
2213 if (fit_unamep)
2214 *fit_unamep = (char *)fit_uname;
2215 if (fit_uname_configp)
2216 *fit_uname_configp = (char *)(fit_uname_config ? :
2217 fit_base_uname_config);
2218
2219 return noffset;
2220}
2221
2222int boot_get_setup_fit(bootm_headers_t *images, uint8_t arch,
2223 ulong *setup_start, ulong *setup_len)
2224{
2225 int noffset;
2226 ulong addr;
2227 ulong len;
2228 int ret;
2229
2230 addr = map_to_sysmem(images->fit_hdr_os);
2231 noffset = fit_get_node_from_config(images, FIT_SETUP_PROP, addr);
2232 if (noffset < 0)
2233 return noffset;
2234
2235 ret = fit_image_load(images, addr, NULL, NULL, arch,
2236 IH_TYPE_X86_SETUP, BOOTSTAGE_ID_FIT_SETUP_START,
2237 FIT_LOAD_REQUIRED, setup_start, &len);
2238
2239 return ret;
2240}
2241
2242#ifndef USE_HOSTCC
2243int boot_get_fdt_fit(bootm_headers_t *images, ulong addr,
2244 const char **fit_unamep, const char **fit_uname_configp,
2245 int arch, ulong *datap, ulong *lenp)
2246{
2247 int fdt_noffset, cfg_noffset, count;
2248 const void *fit;
2249 const char *fit_uname = NULL;
2250 const char *fit_uname_config = NULL;
2251 char *fit_uname_config_copy = NULL;
2252 char *next_config = NULL;
2253 ulong load, len;
2254#ifdef CONFIG_OF_LIBFDT_OVERLAY
2255 ulong image_start, image_end;
2256 ulong ovload, ovlen, ovcopylen;
2257 const char *uconfig;
2258 const char *uname;
2259 void *base, *ov, *ovcopy = NULL;
2260 int i, err, noffset, ov_noffset;
2261#endif
2262
2263 fit_uname = fit_unamep ? *fit_unamep : NULL;
2264
2265 if (fit_uname_configp && *fit_uname_configp) {
2266 fit_uname_config_copy = strdup(*fit_uname_configp);
2267 if (!fit_uname_config_copy)
2268 return -ENOMEM;
2269
2270 next_config = strchr(fit_uname_config_copy, '#');
2271 if (next_config)
2272 *next_config++ = '\0';
2273 if (next_config - 1 > fit_uname_config_copy)
2274 fit_uname_config = fit_uname_config_copy;
2275 }
2276
2277 fdt_noffset = fit_image_load(images,
2278 addr, &fit_uname, &fit_uname_config,
2279 arch, IH_TYPE_FLATDT,
2280 BOOTSTAGE_ID_FIT_FDT_START,
2281 FIT_LOAD_OPTIONAL, &load, &len);
2282
2283 if (fdt_noffset < 0)
2284 goto out;
2285
2286 debug("fit_uname=%s, fit_uname_config=%s\n",
2287 fit_uname ? fit_uname : "<NULL>",
2288 fit_uname_config ? fit_uname_config : "<NULL>");
2289
2290 fit = map_sysmem(addr, 0);
2291
2292 cfg_noffset = fit_conf_get_node(fit, fit_uname_config);
2293
2294
2295 count = fit_conf_get_prop_node_count(fit, cfg_noffset, FIT_FDT_PROP);
2296 if (count <= 1 && !next_config)
2297 goto out;
2298
2299
2300
2301#ifdef CONFIG_OF_LIBFDT_OVERLAY
2302 image_start = addr;
2303 image_end = addr + fit_get_size(fit);
2304
2305 if (load >= image_start && load < image_end) {
2306
2307 printf("Overlayed FDT requires relocation\n");
2308 fdt_noffset = -EBADF;
2309 goto out;
2310 }
2311
2312 base = map_sysmem(load, len);
2313
2314
2315 for (i = 1; ; i++) {
2316 if (i < count) {
2317 noffset = fit_conf_get_prop_node_index(fit, cfg_noffset,
2318 FIT_FDT_PROP, i);
2319 uname = fit_get_name(fit, noffset, NULL);
2320 uconfig = NULL;
2321 } else {
2322 if (!next_config)
2323 break;
2324 uconfig = next_config;
2325 next_config = strchr(next_config, '#');
2326 if (next_config)
2327 *next_config++ = '\0';
2328 uname = NULL;
2329
2330
2331
2332
2333
2334
2335
2336 cfg_noffset = fit_conf_get_node(fit, uconfig);
2337
2338 i = 0;
2339 count = fit_conf_get_prop_node_count(fit, cfg_noffset,
2340 FIT_FDT_PROP);
2341 }
2342
2343 debug("%d: using uname=%s uconfig=%s\n", i, uname, uconfig);
2344
2345 ov_noffset = fit_image_load(images,
2346 addr, &uname, &uconfig,
2347 arch, IH_TYPE_FLATDT,
2348 BOOTSTAGE_ID_FIT_FDT_START,
2349 FIT_LOAD_IGNORED, &ovload, &ovlen);
2350 if (ov_noffset < 0) {
2351 printf("load of %s failed\n", uname);
2352 continue;
2353 }
2354 debug("%s loaded at 0x%08lx len=0x%08lx\n",
2355 uname, ovload, ovlen);
2356 ov = map_sysmem(ovload, ovlen);
2357
2358 ovcopylen = ALIGN(fdt_totalsize(ov), SZ_4K);
2359 ovcopy = malloc(ovcopylen);
2360 if (!ovcopy) {
2361 printf("failed to duplicate DTO before application\n");
2362 fdt_noffset = -ENOMEM;
2363 goto out;
2364 }
2365
2366 err = fdt_open_into(ov, ovcopy, ovcopylen);
2367 if (err < 0) {
2368 printf("failed on fdt_open_into for DTO\n");
2369 fdt_noffset = err;
2370 goto out;
2371 }
2372
2373 base = map_sysmem(load, len + ovlen);
2374 err = fdt_open_into(base, base, len + ovlen);
2375 if (err < 0) {
2376 printf("failed on fdt_open_into\n");
2377 fdt_noffset = err;
2378 goto out;
2379 }
2380
2381
2382 err = fdt_overlay_apply_verbose(base, ovcopy);
2383 if (err < 0) {
2384 fdt_noffset = err;
2385 goto out;
2386 }
2387 fdt_pack(base);
2388 len = fdt_totalsize(base);
2389
2390 free(ovcopy);
2391 ovcopy = NULL;
2392 }
2393#else
2394 printf("config with overlays but CONFIG_OF_LIBFDT_OVERLAY not set\n");
2395 fdt_noffset = -EBADF;
2396#endif
2397
2398out:
2399 if (datap)
2400 *datap = load;
2401 if (lenp)
2402 *lenp = len;
2403 if (fit_unamep)
2404 *fit_unamep = fit_uname;
2405 if (fit_uname_configp)
2406 *fit_uname_configp = fit_uname_config;
2407
2408#ifdef CONFIG_OF_LIBFDT_OVERLAY
2409 if (ovcopy)
2410 free(ovcopy);
2411#endif
2412 if (fit_uname_config_copy)
2413 free(fit_uname_config_copy);
2414 return fdt_noffset;
2415}
2416#endif
2417