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 const 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, const char **algo)
1067{
1068 int len;
1069
1070 *algo = (const 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(name);
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 const 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 *key_blob, const void *data,
1313 size_t size)
1314{
1315 int noffset = 0;
1316 char *err_msg = "";
1317 int verify_all = 1;
1318 int ret;
1319
1320
1321 if (FIT_IMAGE_ENABLE_VERIFY &&
1322 fit_image_verify_required_sigs(fit, image_noffset, data, size,
1323 key_blob, &verify_all)) {
1324 err_msg = "Unable to verify required signature";
1325 goto error;
1326 }
1327
1328
1329 fdt_for_each_subnode(noffset, fit, image_noffset) {
1330 const char *name = fit_get_name(fit, noffset, NULL);
1331
1332
1333
1334
1335
1336
1337 if (!strncmp(name, FIT_HASH_NODENAME,
1338 strlen(FIT_HASH_NODENAME))) {
1339 if (fit_image_check_hash(fit, noffset, data, size,
1340 &err_msg))
1341 goto error;
1342 puts("+ ");
1343 } else if (FIT_IMAGE_ENABLE_VERIFY && verify_all &&
1344 !strncmp(name, FIT_SIG_NODENAME,
1345 strlen(FIT_SIG_NODENAME))) {
1346 ret = fit_image_check_sig(fit, noffset, data, size,
1347 gd_fdt_blob(), -1, &err_msg);
1348
1349
1350
1351
1352
1353
1354
1355 if (ret)
1356 puts("- ");
1357 else
1358 puts("+ ");
1359 }
1360 }
1361
1362 if (noffset == -FDT_ERR_TRUNCATED || noffset == -FDT_ERR_BADSTRUCTURE) {
1363 err_msg = "Corrupted or truncated tree";
1364 goto error;
1365 }
1366
1367 return 1;
1368
1369error:
1370 printf(" error!\n%s for '%s' hash node in '%s' image node\n",
1371 err_msg, fit_get_name(fit, noffset, NULL),
1372 fit_get_name(fit, image_noffset, NULL));
1373 return 0;
1374}
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389int fit_image_verify(const void *fit, int image_noffset)
1390{
1391 const char *name = fit_get_name(fit, image_noffset, NULL);
1392 const void *data;
1393 size_t size;
1394 char *err_msg = "";
1395
1396 if (IS_ENABLED(CONFIG_FIT_SIGNATURE) && strchr(name, '@')) {
1397
1398
1399
1400
1401 err_msg = "Node name contains @";
1402 goto err;
1403 }
1404
1405 if (fit_image_get_data_and_size(fit, image_noffset, &data, &size)) {
1406 err_msg = "Can't get image data/size";
1407 goto err;
1408 }
1409
1410 return fit_image_verify_with_data(fit, image_noffset, gd_fdt_blob(),
1411 data, size);
1412
1413err:
1414 printf("error!\n%s in '%s' image node\n", err_msg,
1415 fit_get_name(fit, image_noffset, NULL));
1416 return 0;
1417}
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430int fit_all_image_verify(const void *fit)
1431{
1432 int images_noffset;
1433 int noffset;
1434 int ndepth;
1435 int count;
1436
1437
1438 images_noffset = fdt_path_offset(fit, FIT_IMAGES_PATH);
1439 if (images_noffset < 0) {
1440 printf("Can't find images parent node '%s' (%s)\n",
1441 FIT_IMAGES_PATH, fdt_strerror(images_noffset));
1442 return 0;
1443 }
1444
1445
1446 printf("## Checking hash(es) for FIT Image at %08lx ...\n",
1447 (ulong)fit);
1448 for (ndepth = 0, count = 0,
1449 noffset = fdt_next_node(fit, images_noffset, &ndepth);
1450 (noffset >= 0) && (ndepth > 0);
1451 noffset = fdt_next_node(fit, noffset, &ndepth)) {
1452 if (ndepth == 1) {
1453
1454
1455
1456
1457 printf(" Hash(es) for Image %u (%s): ", count,
1458 fit_get_name(fit, noffset, NULL));
1459 count++;
1460
1461 if (!fit_image_verify(fit, noffset))
1462 return 0;
1463 printf("\n");
1464 }
1465 }
1466 return 1;
1467}
1468
1469static int fit_image_uncipher(const void *fit, int image_noffset,
1470 void **data, size_t *size)
1471{
1472 int cipher_noffset, ret;
1473 void *dst;
1474 size_t size_dst;
1475
1476 cipher_noffset = fdt_subnode_offset(fit, image_noffset,
1477 FIT_CIPHER_NODENAME);
1478 if (cipher_noffset < 0)
1479 return 0;
1480
1481 ret = fit_image_decrypt_data(fit, image_noffset, cipher_noffset,
1482 *data, *size, &dst, &size_dst);
1483 if (ret)
1484 goto out;
1485
1486 *data = dst;
1487 *size = size_dst;
1488
1489 out:
1490 return ret;
1491}
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506int fit_image_check_os(const void *fit, int noffset, uint8_t os)
1507{
1508 uint8_t image_os;
1509
1510 if (fit_image_get_os(fit, noffset, &image_os))
1511 return 0;
1512 return (os == image_os);
1513}
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528int fit_image_check_arch(const void *fit, int noffset, uint8_t arch)
1529{
1530 uint8_t image_arch;
1531 int aarch32_support = 0;
1532
1533
1534 if (IS_ENABLED(CONFIG_SANDBOX))
1535 return true;
1536
1537 if (IS_ENABLED(CONFIG_ARM64_SUPPORT_AARCH32))
1538 aarch32_support = 1;
1539
1540 if (fit_image_get_arch(fit, noffset, &image_arch))
1541 return 0;
1542 return (arch == image_arch) ||
1543 (arch == IH_ARCH_I386 && image_arch == IH_ARCH_X86_64) ||
1544 (arch == IH_ARCH_ARM64 && image_arch == IH_ARCH_ARM &&
1545 aarch32_support);
1546}
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561int fit_image_check_type(const void *fit, int noffset, uint8_t type)
1562{
1563 uint8_t image_type;
1564
1565 if (fit_image_get_type(fit, noffset, &image_type))
1566 return 0;
1567 return (type == image_type);
1568}
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584int fit_image_check_comp(const void *fit, int noffset, uint8_t comp)
1585{
1586 uint8_t image_comp;
1587
1588 if (fit_image_get_comp(fit, noffset, &image_comp))
1589 return 0;
1590 return (comp == image_comp);
1591}
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602static int fdt_check_no_at(const void *fit, int parent)
1603{
1604 const char *name;
1605 int node;
1606 int ret;
1607
1608 name = fdt_get_name(fit, parent, NULL);
1609 if (!name || strchr(name, '@'))
1610 return -EADDRNOTAVAIL;
1611
1612 fdt_for_each_subnode(node, fit, parent) {
1613 ret = fdt_check_no_at(fit, node);
1614 if (ret)
1615 return ret;
1616 }
1617
1618 return 0;
1619}
1620
1621int fit_check_format(const void *fit, ulong size)
1622{
1623 int ret;
1624
1625
1626 ret = fdt_check_header(fit);
1627 if (ret) {
1628 log_debug("Wrong FIT format: not a flattened device tree (err=%d)\n",
1629 ret);
1630 return -ENOEXEC;
1631 }
1632
1633 if (CONFIG_IS_ENABLED(FIT_FULL_CHECK)) {
1634
1635
1636
1637
1638
1639 if (size == IMAGE_SIZE_INVAL)
1640 size = fdt_totalsize(fit);
1641 ret = fdt_check_full(fit, size);
1642 if (ret)
1643 ret = -EINVAL;
1644
1645
1646
1647
1648
1649
1650
1651
1652 if (!ret && CONFIG_IS_ENABLED(FIT_SIGNATURE)) {
1653 ret = fdt_check_no_at(fit, 0);
1654
1655 if (ret) {
1656 log_debug("FIT check error %d\n", ret);
1657 return ret;
1658 }
1659 }
1660 if (ret) {
1661 log_debug("FIT check error %d\n", ret);
1662 return ret;
1663 }
1664 }
1665
1666
1667 if (!fdt_getprop(fit, 0, FIT_DESC_PROP, NULL)) {
1668 log_debug("Wrong FIT format: no description\n");
1669 return -ENOMSG;
1670 }
1671
1672 if (IMAGE_ENABLE_TIMESTAMP) {
1673
1674 if (!fdt_getprop(fit, 0, FIT_TIMESTAMP_PROP, NULL)) {
1675 log_debug("Wrong FIT format: no timestamp\n");
1676 return -EBADMSG;
1677 }
1678 }
1679
1680
1681 if (fdt_path_offset(fit, FIT_IMAGES_PATH) < 0) {
1682 log_debug("Wrong FIT format: no images parent node\n");
1683 return -ENOENT;
1684 }
1685
1686 return 0;
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
1730
1731
1732int fit_conf_find_compat(const void *fit, const void *fdt)
1733{
1734 int ndepth = 0;
1735 int noffset, confs_noffset, images_noffset;
1736 const void *fdt_compat;
1737 int fdt_compat_len;
1738 int best_match_offset = 0;
1739 int best_match_pos = 0;
1740
1741 confs_noffset = fdt_path_offset(fit, FIT_CONFS_PATH);
1742 images_noffset = fdt_path_offset(fit, FIT_IMAGES_PATH);
1743 if (confs_noffset < 0 || images_noffset < 0) {
1744 debug("Can't find configurations or images nodes.\n");
1745 return -1;
1746 }
1747
1748 fdt_compat = fdt_getprop(fdt, 0, "compatible", &fdt_compat_len);
1749 if (!fdt_compat) {
1750 debug("Fdt for comparison has no \"compatible\" property.\n");
1751 return -1;
1752 }
1753
1754
1755
1756
1757 for (noffset = fdt_next_node(fit, confs_noffset, &ndepth);
1758 (noffset >= 0) && (ndepth > 0);
1759 noffset = fdt_next_node(fit, noffset, &ndepth)) {
1760 const void *fdt;
1761 const char *kfdt_name;
1762 int kfdt_noffset, compat_noffset;
1763 const char *cur_fdt_compat;
1764 int len;
1765 size_t sz;
1766 int i;
1767
1768 if (ndepth > 1)
1769 continue;
1770
1771
1772 if (fdt_getprop(fit, noffset, "compatible", NULL)) {
1773 fdt = fit;
1774 compat_noffset = noffset;
1775 } else {
1776 kfdt_name = fdt_getprop(fit, noffset, "fdt", &len);
1777 if (!kfdt_name) {
1778 debug("No fdt property found.\n");
1779 continue;
1780 }
1781 kfdt_noffset = fdt_subnode_offset(fit, images_noffset,
1782 kfdt_name);
1783 if (kfdt_noffset < 0) {
1784 debug("No image node named \"%s\" found.\n",
1785 kfdt_name);
1786 continue;
1787 }
1788
1789 if (!fit_image_check_comp(fit, kfdt_noffset,
1790 IH_COMP_NONE)) {
1791 debug("Can't extract compat from \"%s\" "
1792 "(compressed)\n", kfdt_name);
1793 continue;
1794 }
1795
1796
1797 if (fit_image_get_data_and_size(fit, kfdt_noffset,
1798 &fdt, &sz)) {
1799 debug("Failed to get fdt \"%s\".\n", kfdt_name);
1800 continue;
1801 }
1802
1803 compat_noffset = 0;
1804 }
1805
1806 len = fdt_compat_len;
1807 cur_fdt_compat = fdt_compat;
1808
1809
1810
1811
1812 for (i = 0; len > 0 &&
1813 (!best_match_offset || best_match_pos > i); i++) {
1814 int cur_len = strlen(cur_fdt_compat) + 1;
1815
1816 if (!fdt_node_check_compatible(fdt, compat_noffset,
1817 cur_fdt_compat)) {
1818 best_match_offset = noffset;
1819 best_match_pos = i;
1820 break;
1821 }
1822 len -= cur_len;
1823 cur_fdt_compat += cur_len;
1824 }
1825 }
1826 if (!best_match_offset) {
1827 debug("No match found.\n");
1828 return -1;
1829 }
1830
1831 return best_match_offset;
1832}
1833
1834int fit_conf_get_node(const void *fit, const char *conf_uname)
1835{
1836 int noffset, confs_noffset;
1837 int len;
1838 const char *s;
1839 char *conf_uname_copy = NULL;
1840
1841 confs_noffset = fdt_path_offset(fit, FIT_CONFS_PATH);
1842 if (confs_noffset < 0) {
1843 debug("Can't find configurations parent node '%s' (%s)\n",
1844 FIT_CONFS_PATH, fdt_strerror(confs_noffset));
1845 return confs_noffset;
1846 }
1847
1848 if (conf_uname == NULL) {
1849
1850 debug("No configuration specified, trying default...\n");
1851 if (!tools_build() && IS_ENABLED(CONFIG_MULTI_DTB_FIT)) {
1852 noffset = fit_find_config_node(fit);
1853 if (noffset < 0)
1854 return noffset;
1855 conf_uname = fdt_get_name(fit, noffset, NULL);
1856 } else {
1857 conf_uname = (char *)fdt_getprop(fit, confs_noffset,
1858 FIT_DEFAULT_PROP, &len);
1859 if (conf_uname == NULL) {
1860 fit_get_debug(fit, confs_noffset, FIT_DEFAULT_PROP,
1861 len);
1862 return len;
1863 }
1864 }
1865 debug("Found default configuration: '%s'\n", conf_uname);
1866 }
1867
1868 s = strchr(conf_uname, '#');
1869 if (s) {
1870 len = s - conf_uname;
1871 conf_uname_copy = malloc(len + 1);
1872 if (!conf_uname_copy) {
1873 debug("Can't allocate uname copy: '%s'\n",
1874 conf_uname);
1875 return -ENOMEM;
1876 }
1877 memcpy(conf_uname_copy, conf_uname, len);
1878 conf_uname_copy[len] = '\0';
1879 conf_uname = conf_uname_copy;
1880 }
1881
1882 noffset = fdt_subnode_offset(fit, confs_noffset, conf_uname);
1883 if (noffset < 0) {
1884 debug("Can't get node offset for configuration unit name: '%s' (%s)\n",
1885 conf_uname, fdt_strerror(noffset));
1886 }
1887
1888 if (conf_uname_copy)
1889 free(conf_uname_copy);
1890
1891 return noffset;
1892}
1893
1894int fit_conf_get_prop_node_count(const void *fit, int noffset,
1895 const char *prop_name)
1896{
1897 return fdt_stringlist_count(fit, noffset, prop_name);
1898}
1899
1900int fit_conf_get_prop_node_index(const void *fit, int noffset,
1901 const char *prop_name, int index)
1902{
1903 const char *uname;
1904 int len;
1905
1906
1907 uname = fdt_stringlist_get(fit, noffset, prop_name, index, &len);
1908 if (uname == NULL)
1909 return len;
1910
1911 return fit_image_get_node(fit, uname);
1912}
1913
1914int fit_conf_get_prop_node(const void *fit, int noffset,
1915 const char *prop_name)
1916{
1917 return fit_conf_get_prop_node_index(fit, noffset, prop_name, 0);
1918}
1919
1920static int fit_image_select(const void *fit, int rd_noffset, int verify)
1921{
1922 fit_image_print(fit, rd_noffset, " ");
1923
1924 if (verify) {
1925 puts(" Verifying Hash Integrity ... ");
1926 if (!fit_image_verify(fit, rd_noffset)) {
1927 puts("Bad Data Hash\n");
1928 return -EACCES;
1929 }
1930 puts("OK\n");
1931 }
1932
1933 return 0;
1934}
1935
1936int fit_get_node_from_config(bootm_headers_t *images, const char *prop_name,
1937 ulong addr)
1938{
1939 int cfg_noffset;
1940 void *fit_hdr;
1941 int noffset;
1942
1943 debug("* %s: using config '%s' from image at 0x%08lx\n",
1944 prop_name, images->fit_uname_cfg, addr);
1945
1946
1947 fit_hdr = map_sysmem(addr, 0);
1948 cfg_noffset = fit_conf_get_node(fit_hdr, images->fit_uname_cfg);
1949 if (cfg_noffset < 0) {
1950 debug("* %s: no such config\n", prop_name);
1951 return -EINVAL;
1952 }
1953
1954 noffset = fit_conf_get_prop_node(fit_hdr, cfg_noffset, prop_name);
1955 if (noffset < 0) {
1956 debug("* %s: no '%s' in config\n", prop_name, prop_name);
1957 return -ENOENT;
1958 }
1959
1960 return noffset;
1961}
1962
1963
1964
1965
1966
1967
1968
1969static const char *fit_get_image_type_property(int type)
1970{
1971
1972
1973
1974
1975
1976 switch (type) {
1977 case IH_TYPE_FLATDT:
1978 return FIT_FDT_PROP;
1979 case IH_TYPE_KERNEL:
1980 return FIT_KERNEL_PROP;
1981 case IH_TYPE_FIRMWARE:
1982 return FIT_FIRMWARE_PROP;
1983 case IH_TYPE_RAMDISK:
1984 return FIT_RAMDISK_PROP;
1985 case IH_TYPE_X86_SETUP:
1986 return FIT_SETUP_PROP;
1987 case IH_TYPE_LOADABLE:
1988 return FIT_LOADABLE_PROP;
1989 case IH_TYPE_FPGA:
1990 return FIT_FPGA_PROP;
1991 case IH_TYPE_STANDALONE:
1992 return FIT_STANDALONE_PROP;
1993 }
1994
1995 return "unknown";
1996}
1997
1998int fit_image_load(bootm_headers_t *images, ulong addr,
1999 const char **fit_unamep, const char **fit_uname_configp,
2000 int arch, int image_type, int bootstage_id,
2001 enum fit_load_op load_op, ulong *datap, ulong *lenp)
2002{
2003 int cfg_noffset, noffset;
2004 const char *fit_uname;
2005 const char *fit_uname_config;
2006 const char *fit_base_uname_config;
2007 const void *fit;
2008 void *buf;
2009 void *loadbuf;
2010 size_t size;
2011 int type_ok, os_ok;
2012 ulong load, load_end, data, len;
2013 uint8_t os, comp;
2014 const char *prop_name;
2015 int ret;
2016
2017 fit = map_sysmem(addr, 0);
2018 fit_uname = fit_unamep ? *fit_unamep : NULL;
2019 fit_uname_config = fit_uname_configp ? *fit_uname_configp : NULL;
2020 fit_base_uname_config = NULL;
2021 prop_name = fit_get_image_type_property(image_type);
2022 printf("## Loading %s from FIT Image at %08lx ...\n", prop_name, addr);
2023
2024 bootstage_mark(bootstage_id + BOOTSTAGE_SUB_FORMAT);
2025 ret = fit_check_format(fit, IMAGE_SIZE_INVAL);
2026 if (ret) {
2027 printf("Bad FIT %s image format! (err=%d)\n", prop_name, ret);
2028 if (CONFIG_IS_ENABLED(FIT_SIGNATURE) && ret == -EADDRNOTAVAIL)
2029 printf("Signature checking prevents use of unit addresses (@) in nodes\n");
2030 bootstage_error(bootstage_id + BOOTSTAGE_SUB_FORMAT);
2031 return ret;
2032 }
2033 bootstage_mark(bootstage_id + BOOTSTAGE_SUB_FORMAT_OK);
2034 if (fit_uname) {
2035
2036 bootstage_mark(bootstage_id + BOOTSTAGE_SUB_UNIT_NAME);
2037 noffset = fit_image_get_node(fit, fit_uname);
2038 } else {
2039
2040
2041
2042
2043
2044 bootstage_mark(bootstage_id + BOOTSTAGE_SUB_NO_UNIT_NAME);
2045 if (IS_ENABLED(CONFIG_FIT_BEST_MATCH) && !fit_uname_config) {
2046 cfg_noffset = fit_conf_find_compat(fit, gd_fdt_blob());
2047 } else {
2048 cfg_noffset = fit_conf_get_node(fit,
2049 fit_uname_config);
2050 }
2051 if (cfg_noffset < 0) {
2052 puts("Could not find configuration node\n");
2053 bootstage_error(bootstage_id +
2054 BOOTSTAGE_SUB_NO_UNIT_NAME);
2055 return -ENOENT;
2056 }
2057
2058 fit_base_uname_config = fdt_get_name(fit, cfg_noffset, NULL);
2059 printf(" Using '%s' configuration\n", fit_base_uname_config);
2060
2061 if (image_type == IH_TYPE_KERNEL)
2062 images->fit_uname_cfg = fit_base_uname_config;
2063
2064 if (FIT_IMAGE_ENABLE_VERIFY && images->verify) {
2065 puts(" Verifying Hash Integrity ... ");
2066 if (fit_config_verify(fit, cfg_noffset)) {
2067 puts("Bad Data Hash\n");
2068 bootstage_error(bootstage_id +
2069 BOOTSTAGE_SUB_HASH);
2070 return -EACCES;
2071 }
2072 puts("OK\n");
2073 }
2074
2075 bootstage_mark(BOOTSTAGE_ID_FIT_CONFIG);
2076
2077 noffset = fit_conf_get_prop_node(fit, cfg_noffset,
2078 prop_name);
2079 fit_uname = fit_get_name(fit, noffset, NULL);
2080 }
2081 if (noffset < 0) {
2082 printf("Could not find subimage node type '%s'\n", prop_name);
2083 bootstage_error(bootstage_id + BOOTSTAGE_SUB_SUBNODE);
2084 return -ENOENT;
2085 }
2086
2087 printf(" Trying '%s' %s subimage\n", fit_uname, prop_name);
2088
2089 ret = fit_image_select(fit, noffset, images->verify);
2090 if (ret) {
2091 bootstage_error(bootstage_id + BOOTSTAGE_SUB_HASH);
2092 return ret;
2093 }
2094
2095 bootstage_mark(bootstage_id + BOOTSTAGE_SUB_CHECK_ARCH);
2096 if (!tools_build() && IS_ENABLED(CONFIG_SANDBOX)) {
2097 if (!fit_image_check_target_arch(fit, noffset)) {
2098 puts("Unsupported Architecture\n");
2099 bootstage_error(bootstage_id + BOOTSTAGE_SUB_CHECK_ARCH);
2100 return -ENOEXEC;
2101 }
2102 }
2103
2104#ifndef USE_HOSTCC
2105 {
2106 uint8_t os_arch;
2107
2108 fit_image_get_arch(fit, noffset, &os_arch);
2109 images->os.arch = os_arch;
2110 }
2111#endif
2112
2113 bootstage_mark(bootstage_id + BOOTSTAGE_SUB_CHECK_ALL);
2114 type_ok = fit_image_check_type(fit, noffset, image_type) ||
2115 fit_image_check_type(fit, noffset, IH_TYPE_FIRMWARE) ||
2116 fit_image_check_type(fit, noffset, IH_TYPE_TEE) ||
2117 (image_type == IH_TYPE_KERNEL &&
2118 fit_image_check_type(fit, noffset, IH_TYPE_KERNEL_NOLOAD));
2119
2120 os_ok = image_type == IH_TYPE_FLATDT ||
2121 image_type == IH_TYPE_FPGA ||
2122 fit_image_check_os(fit, noffset, IH_OS_LINUX) ||
2123 fit_image_check_os(fit, noffset, IH_OS_U_BOOT) ||
2124 fit_image_check_os(fit, noffset, IH_OS_TEE) ||
2125 fit_image_check_os(fit, noffset, IH_OS_OPENRTOS) ||
2126 fit_image_check_os(fit, noffset, IH_OS_EFI) ||
2127 fit_image_check_os(fit, noffset, IH_OS_VXWORKS);
2128
2129
2130
2131
2132
2133
2134 if ((!type_ok || !os_ok) && image_type != IH_TYPE_LOADABLE) {
2135 fit_image_get_os(fit, noffset, &os);
2136 printf("No %s %s %s Image\n",
2137 genimg_get_os_name(os),
2138 genimg_get_arch_name(arch),
2139 genimg_get_type_name(image_type));
2140 bootstage_error(bootstage_id + BOOTSTAGE_SUB_CHECK_ALL);
2141 return -EIO;
2142 }
2143
2144 bootstage_mark(bootstage_id + BOOTSTAGE_SUB_CHECK_ALL_OK);
2145
2146
2147 if (fit_image_get_data_and_size(fit, noffset,
2148 (const void **)&buf, &size)) {
2149 printf("Could not find %s subimage data!\n", prop_name);
2150 bootstage_error(bootstage_id + BOOTSTAGE_SUB_GET_DATA);
2151 return -ENOENT;
2152 }
2153
2154
2155 if (IS_ENABLED(CONFIG_FIT_CIPHER) && IMAGE_ENABLE_DECRYPT) {
2156 puts(" Decrypting Data ... ");
2157 if (fit_image_uncipher(fit, noffset, &buf, &size)) {
2158 puts("Error\n");
2159 return -EACCES;
2160 }
2161 puts("OK\n");
2162 }
2163
2164
2165 if (!tools_build() && IS_ENABLED(CONFIG_FIT_IMAGE_POST_PROCESS))
2166 board_fit_image_post_process(fit, noffset, &buf, &size);
2167
2168 len = (ulong)size;
2169
2170 bootstage_mark(bootstage_id + BOOTSTAGE_SUB_GET_DATA_OK);
2171
2172 data = map_to_sysmem(buf);
2173 load = data;
2174 if (load_op == FIT_LOAD_IGNORED) {
2175
2176 } else if (fit_image_get_load(fit, noffset, &load)) {
2177 if (load_op == FIT_LOAD_REQUIRED) {
2178 printf("Can't get %s subimage load address!\n",
2179 prop_name);
2180 bootstage_error(bootstage_id + BOOTSTAGE_SUB_LOAD);
2181 return -EBADF;
2182 }
2183 } else if (load_op != FIT_LOAD_OPTIONAL_NON_ZERO || load) {
2184 ulong image_start, image_end;
2185
2186
2187
2188
2189
2190 image_start = addr;
2191 image_end = addr + fit_get_size(fit);
2192
2193 load_end = load + len;
2194 if (image_type != IH_TYPE_KERNEL &&
2195 load < image_end && load_end > image_start) {
2196 printf("Error: %s overwritten\n", prop_name);
2197 return -EXDEV;
2198 }
2199
2200 printf(" Loading %s from 0x%08lx to 0x%08lx\n",
2201 prop_name, data, load);
2202 } else {
2203 load = data;
2204 }
2205
2206 comp = IH_COMP_NONE;
2207 loadbuf = buf;
2208
2209 if (!fit_image_get_comp(fit, noffset, &comp) &&
2210 comp != IH_COMP_NONE &&
2211 !(image_type == IH_TYPE_KERNEL ||
2212 image_type == IH_TYPE_KERNEL_NOLOAD ||
2213 image_type == IH_TYPE_RAMDISK)) {
2214 ulong max_decomp_len = len * 20;
2215 if (load == data) {
2216 loadbuf = malloc(max_decomp_len);
2217 load = map_to_sysmem(loadbuf);
2218 } else {
2219 loadbuf = map_sysmem(load, max_decomp_len);
2220 }
2221 if (image_decomp(comp, load, data, image_type,
2222 loadbuf, buf, len, max_decomp_len, &load_end)) {
2223 printf("Error decompressing %s\n", prop_name);
2224
2225 return -ENOEXEC;
2226 }
2227 len = load_end - load;
2228 } else if (load != data) {
2229 loadbuf = map_sysmem(load, len);
2230 memcpy(loadbuf, buf, len);
2231 }
2232
2233 if (image_type == IH_TYPE_RAMDISK && comp != IH_COMP_NONE)
2234 puts("WARNING: 'compression' nodes for ramdisks are deprecated,"
2235 " please fix your .its file!\n");
2236
2237
2238 if (image_type == IH_TYPE_FLATDT && fdt_check_header(loadbuf)) {
2239 puts("Subimage data is not a FDT");
2240 return -ENOEXEC;
2241 }
2242
2243 bootstage_mark(bootstage_id + BOOTSTAGE_SUB_LOAD);
2244
2245 *datap = load;
2246 *lenp = len;
2247 if (fit_unamep)
2248 *fit_unamep = (char *)fit_uname;
2249 if (fit_uname_configp)
2250 *fit_uname_configp = (char *)(fit_uname_config ? :
2251 fit_base_uname_config);
2252
2253 return noffset;
2254}
2255
2256int boot_get_setup_fit(bootm_headers_t *images, uint8_t arch,
2257 ulong *setup_start, ulong *setup_len)
2258{
2259 int noffset;
2260 ulong addr;
2261 ulong len;
2262 int ret;
2263
2264 addr = map_to_sysmem(images->fit_hdr_os);
2265 noffset = fit_get_node_from_config(images, FIT_SETUP_PROP, addr);
2266 if (noffset < 0)
2267 return noffset;
2268
2269 ret = fit_image_load(images, addr, NULL, NULL, arch,
2270 IH_TYPE_X86_SETUP, BOOTSTAGE_ID_FIT_SETUP_START,
2271 FIT_LOAD_REQUIRED, setup_start, &len);
2272
2273 return ret;
2274}
2275
2276#ifndef USE_HOSTCC
2277int boot_get_fdt_fit(bootm_headers_t *images, ulong addr,
2278 const char **fit_unamep, const char **fit_uname_configp,
2279 int arch, ulong *datap, ulong *lenp)
2280{
2281 int fdt_noffset, cfg_noffset, count;
2282 const void *fit;
2283 const char *fit_uname = NULL;
2284 const char *fit_uname_config = NULL;
2285 char *fit_uname_config_copy = NULL;
2286 char *next_config = NULL;
2287 ulong load, len;
2288#ifdef CONFIG_OF_LIBFDT_OVERLAY
2289 ulong image_start, image_end;
2290 ulong ovload, ovlen, ovcopylen;
2291 const char *uconfig;
2292 const char *uname;
2293 void *base, *ov, *ovcopy = NULL;
2294 int i, err, noffset, ov_noffset;
2295#endif
2296
2297 fit_uname = fit_unamep ? *fit_unamep : NULL;
2298
2299 if (fit_uname_configp && *fit_uname_configp) {
2300 fit_uname_config_copy = strdup(*fit_uname_configp);
2301 if (!fit_uname_config_copy)
2302 return -ENOMEM;
2303
2304 next_config = strchr(fit_uname_config_copy, '#');
2305 if (next_config)
2306 *next_config++ = '\0';
2307 if (next_config - 1 > fit_uname_config_copy)
2308 fit_uname_config = fit_uname_config_copy;
2309 }
2310
2311 fdt_noffset = fit_image_load(images,
2312 addr, &fit_uname, &fit_uname_config,
2313 arch, IH_TYPE_FLATDT,
2314 BOOTSTAGE_ID_FIT_FDT_START,
2315 FIT_LOAD_OPTIONAL, &load, &len);
2316
2317 if (fdt_noffset < 0)
2318 goto out;
2319
2320 debug("fit_uname=%s, fit_uname_config=%s\n",
2321 fit_uname ? fit_uname : "<NULL>",
2322 fit_uname_config ? fit_uname_config : "<NULL>");
2323
2324 fit = map_sysmem(addr, 0);
2325
2326 cfg_noffset = fit_conf_get_node(fit, fit_uname_config);
2327
2328
2329 count = fit_conf_get_prop_node_count(fit, cfg_noffset, FIT_FDT_PROP);
2330 if (count <= 1 && !next_config)
2331 goto out;
2332
2333
2334
2335#ifdef CONFIG_OF_LIBFDT_OVERLAY
2336 image_start = addr;
2337 image_end = addr + fit_get_size(fit);
2338
2339 if (load >= image_start && load < image_end) {
2340
2341 printf("Overlayed FDT requires relocation\n");
2342 fdt_noffset = -EBADF;
2343 goto out;
2344 }
2345
2346 base = map_sysmem(load, len);
2347
2348
2349 for (i = 1; ; i++) {
2350 if (i < count) {
2351 noffset = fit_conf_get_prop_node_index(fit, cfg_noffset,
2352 FIT_FDT_PROP, i);
2353 uname = fit_get_name(fit, noffset, NULL);
2354 uconfig = NULL;
2355 } else {
2356 if (!next_config)
2357 break;
2358 uconfig = next_config;
2359 next_config = strchr(next_config, '#');
2360 if (next_config)
2361 *next_config++ = '\0';
2362 uname = NULL;
2363
2364
2365
2366
2367
2368
2369
2370 cfg_noffset = fit_conf_get_node(fit, uconfig);
2371
2372 i = 0;
2373 count = fit_conf_get_prop_node_count(fit, cfg_noffset,
2374 FIT_FDT_PROP);
2375 }
2376
2377 debug("%d: using uname=%s uconfig=%s\n", i, uname, uconfig);
2378
2379 ov_noffset = fit_image_load(images,
2380 addr, &uname, &uconfig,
2381 arch, IH_TYPE_FLATDT,
2382 BOOTSTAGE_ID_FIT_FDT_START,
2383 FIT_LOAD_IGNORED, &ovload, &ovlen);
2384 if (ov_noffset < 0) {
2385 printf("load of %s failed\n", uname);
2386 continue;
2387 }
2388 debug("%s loaded at 0x%08lx len=0x%08lx\n",
2389 uname, ovload, ovlen);
2390 ov = map_sysmem(ovload, ovlen);
2391
2392 ovcopylen = ALIGN(fdt_totalsize(ov), SZ_4K);
2393 ovcopy = malloc(ovcopylen);
2394 if (!ovcopy) {
2395 printf("failed to duplicate DTO before application\n");
2396 fdt_noffset = -ENOMEM;
2397 goto out;
2398 }
2399
2400 err = fdt_open_into(ov, ovcopy, ovcopylen);
2401 if (err < 0) {
2402 printf("failed on fdt_open_into for DTO\n");
2403 fdt_noffset = err;
2404 goto out;
2405 }
2406
2407 base = map_sysmem(load, len + ovlen);
2408 err = fdt_open_into(base, base, len + ovlen);
2409 if (err < 0) {
2410 printf("failed on fdt_open_into\n");
2411 fdt_noffset = err;
2412 goto out;
2413 }
2414
2415
2416 err = fdt_overlay_apply_verbose(base, ovcopy);
2417 if (err < 0) {
2418 fdt_noffset = err;
2419 goto out;
2420 }
2421 fdt_pack(base);
2422 len = fdt_totalsize(base);
2423
2424 free(ovcopy);
2425 ovcopy = NULL;
2426 }
2427#else
2428 printf("config with overlays but CONFIG_OF_LIBFDT_OVERLAY not set\n");
2429 fdt_noffset = -EBADF;
2430#endif
2431
2432out:
2433 if (datap)
2434 *datap = load;
2435 if (lenp)
2436 *lenp = len;
2437 if (fit_unamep)
2438 *fit_unamep = fit_uname;
2439 if (fit_uname_configp)
2440 *fit_uname_configp = fit_uname_config;
2441
2442#ifdef CONFIG_OF_LIBFDT_OVERLAY
2443 if (ovcopy)
2444 free(ovcopy);
2445#endif
2446 if (fit_uname_config_copy)
2447 free(fit_uname_config_copy);
2448 return fdt_noffset;
2449}
2450#endif
2451