1
2
3
4
5
6
7
8
9
10
11#include "mkimage.h"
12#include <bootm.h>
13#include <fdt_region.h>
14#include <image.h>
15#include <version.h>
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31static int fit_set_hash_value(void *fit, int noffset, uint8_t *value,
32 int value_len)
33{
34 int ret;
35
36 ret = fdt_setprop(fit, noffset, FIT_VALUE_PROP, value, value_len);
37 if (ret) {
38 printf("Can't set hash '%s' property for '%s' node(%s)\n",
39 FIT_VALUE_PROP, fit_get_name(fit, noffset, NULL),
40 fdt_strerror(ret));
41 return ret == -FDT_ERR_NOSPACE ? -ENOSPC : -EIO;
42 }
43
44 return 0;
45}
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60static int fit_image_process_hash(void *fit, const char *image_name,
61 int noffset, const void *data, size_t size)
62{
63 uint8_t value[FIT_MAX_HASH_LEN];
64 const char *node_name;
65 int value_len;
66 const char *algo;
67 int ret;
68
69 node_name = fit_get_name(fit, noffset, NULL);
70
71 if (fit_image_hash_get_algo(fit, noffset, &algo)) {
72 printf("Can't get hash algo property for '%s' hash node in '%s' image node\n",
73 node_name, image_name);
74 return -ENOENT;
75 }
76
77 if (calculate_hash(data, size, algo, value, &value_len)) {
78 printf("Unsupported hash algorithm (%s) for '%s' hash node in '%s' image node\n",
79 algo, node_name, image_name);
80 return -EPROTONOSUPPORT;
81 }
82
83 ret = fit_set_hash_value(fit, noffset, value, value_len);
84 if (ret) {
85 printf("Can't set hash value for '%s' hash node in '%s' image node\n",
86 node_name, image_name);
87 return ret;
88 }
89
90 return 0;
91}
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108static int fit_image_write_sig(void *fit, int noffset, uint8_t *value,
109 int value_len, const char *comment, const char *region_prop,
110 int region_proplen, const char *cmdname, const char *algo_name)
111{
112 int string_size;
113 int ret;
114
115
116
117
118
119 string_size = fdt_size_dt_strings(fit);
120
121 ret = fdt_setprop(fit, noffset, FIT_VALUE_PROP, value, value_len);
122 if (!ret) {
123 ret = fdt_setprop_string(fit, noffset, "signer-name",
124 "mkimage");
125 }
126 if (!ret) {
127 ret = fdt_setprop_string(fit, noffset, "signer-version",
128 PLAIN_VERSION);
129 }
130 if (comment && !ret)
131 ret = fdt_setprop_string(fit, noffset, "comment", comment);
132 if (!ret) {
133 time_t timestamp = imagetool_get_source_date(cmdname,
134 time(NULL));
135 uint32_t t = cpu_to_uimage(timestamp);
136
137 ret = fdt_setprop(fit, noffset, FIT_TIMESTAMP_PROP, &t,
138 sizeof(uint32_t));
139 }
140 if (region_prop && !ret) {
141 uint32_t strdata[2];
142
143 ret = fdt_setprop(fit, noffset, "hashed-nodes",
144 region_prop, region_proplen);
145
146 strdata[0] = 0;
147 strdata[1] = cpu_to_fdt32(string_size);
148 if (!ret) {
149 ret = fdt_setprop(fit, noffset, "hashed-strings",
150 strdata, sizeof(strdata));
151 }
152 }
153 if (algo_name && !ret)
154 ret = fdt_setprop_string(fit, noffset, "algo", algo_name);
155
156 return ret;
157}
158
159static int fit_image_setup_sig(struct image_sign_info *info,
160 const char *keydir, const char *keyfile, void *fit,
161 const char *image_name, int noffset, const char *require_keys,
162 const char *engine_id, const char *algo_name)
163{
164 const char *node_name;
165 const char *padding_name;
166
167 node_name = fit_get_name(fit, noffset, NULL);
168 if (!algo_name) {
169 if (fit_image_hash_get_algo(fit, noffset, &algo_name)) {
170 printf("Can't get algo property for '%s' signature node in '%s' image node\n",
171 node_name, image_name);
172 return -1;
173 }
174 }
175
176 padding_name = fdt_getprop(fit, noffset, "padding", NULL);
177
178 memset(info, '\0', sizeof(*info));
179 info->keydir = keydir;
180 info->keyfile = keyfile;
181 info->keyname = fdt_getprop(fit, noffset, FIT_KEY_HINT, NULL);
182 info->fit = fit;
183 info->node_offset = noffset;
184 info->name = strdup(algo_name);
185 info->checksum = image_get_checksum_algo(algo_name);
186 info->crypto = image_get_crypto_algo(algo_name);
187 info->padding = image_get_padding_algo(padding_name);
188 info->require_keys = require_keys;
189 info->engine_id = engine_id;
190 if (!info->checksum || !info->crypto) {
191 printf("Unsupported signature algorithm (%s) for '%s' signature node in '%s' image node\n",
192 algo_name, node_name, image_name);
193 return -1;
194 }
195
196 return 0;
197}
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218static int fit_image_process_sig(const char *keydir, const char *keyfile,
219 void *keydest, void *fit, const char *image_name,
220 int noffset, const void *data, size_t size,
221 const char *comment, int require_keys, const char *engine_id,
222 const char *cmdname, const char *algo_name)
223{
224 struct image_sign_info info;
225 struct image_region region;
226 const char *node_name;
227 uint8_t *value;
228 uint value_len;
229 int ret;
230
231 if (fit_image_setup_sig(&info, keydir, keyfile, fit, image_name,
232 noffset, require_keys ? "image" : NULL,
233 engine_id, algo_name))
234 return -1;
235
236 node_name = fit_get_name(fit, noffset, NULL);
237 region.data = data;
238 region.size = size;
239 ret = info.crypto->sign(&info, ®ion, 1, &value, &value_len);
240 if (ret) {
241 printf("Failed to sign '%s' signature node in '%s' image node: %d\n",
242 node_name, image_name, ret);
243
244
245 if (ret == -ENOENT)
246 return 0;
247 return -1;
248 }
249
250 ret = fit_image_write_sig(fit, noffset, value, value_len, comment,
251 NULL, 0, cmdname, algo_name);
252 if (ret) {
253 if (ret == -FDT_ERR_NOSPACE)
254 return -ENOSPC;
255 printf("Can't write signature for '%s' signature node in '%s' conf node: %s\n",
256 node_name, image_name, fdt_strerror(ret));
257 return -1;
258 }
259 free(value);
260
261
262 info.keyname = fdt_getprop(fit, noffset, FIT_KEY_HINT, NULL);
263
264
265
266
267
268
269 if (keydest) {
270 ret = info.crypto->add_verify_data(&info, keydest);
271 if (ret < 0) {
272 printf("Failed to add verification data for '%s' signature node in '%s' image node\n",
273 node_name, image_name);
274 return ret;
275 }
276
277 return ret;
278 }
279
280 return 0;
281}
282
283static int fit_image_read_data(char *filename, unsigned char *data,
284 int expected_size)
285{
286 struct stat sbuf;
287 int fd, ret = -1;
288 ssize_t n;
289
290
291 fd = open(filename, O_RDONLY | O_BINARY);
292 if (fd < 0) {
293 printf("Can't open file %s (err=%d => %s)\n",
294 filename, errno, strerror(errno));
295 return -1;
296 }
297
298
299 if (fstat(fd, &sbuf) < 0) {
300 printf("Can't fstat file %s (err=%d => %s)\n",
301 filename, errno, strerror(errno));
302 goto err;
303 }
304
305
306 if (sbuf.st_size != expected_size) {
307 printf("File %s don't have the expected size (size=%lld, expected=%d)\n",
308 filename, (long long)sbuf.st_size, expected_size);
309 goto err;
310 }
311
312
313 n = read(fd, data, sbuf.st_size);
314 if (n < 0) {
315 printf("Can't read file %s (err=%d => %s)\n",
316 filename, errno, strerror(errno));
317 goto err;
318 }
319
320
321 if (n != sbuf.st_size) {
322 printf("Can't read all file %s (read %zd bytes, expected %lld)\n",
323 filename, n, (long long)sbuf.st_size);
324 goto err;
325 }
326
327 ret = 0;
328
329err:
330 close(fd);
331 return ret;
332}
333
334static int get_random_data(void *data, int size)
335{
336 unsigned char *tmp = data;
337 struct timespec date;
338 int i, ret;
339
340 if (!tmp) {
341 printf("%s: pointer data is NULL\n", __func__);
342 ret = -1;
343 goto out;
344 }
345
346 ret = clock_gettime(CLOCK_MONOTONIC, &date);
347 if (ret) {
348 printf("%s: clock_gettime has failed (%s)\n", __func__,
349 strerror(errno));
350 goto out;
351 }
352
353 srandom(date.tv_nsec);
354
355 for (i = 0; i < size; i++) {
356 *tmp = random() & 0xff;
357 tmp++;
358 }
359
360 out:
361 return ret;
362}
363
364static int fit_image_setup_cipher(struct image_cipher_info *info,
365 const char *keydir, void *fit,
366 const char *image_name, int image_noffset,
367 int noffset)
368{
369 char *algo_name;
370 char filename[128];
371 int ret = -1;
372
373 if (fit_image_cipher_get_algo(fit, noffset, &algo_name)) {
374 printf("Can't get algo name for cipher in image '%s'\n",
375 image_name);
376 goto out;
377 }
378
379 info->keydir = keydir;
380
381
382 info->keyname = fdt_getprop(fit, noffset, FIT_KEY_HINT, NULL);
383 if (!info->keyname) {
384 printf("Can't get key name for cipher in image '%s'\n",
385 image_name);
386 goto out;
387 }
388
389
390
391
392
393
394
395 info->ivname = fdt_getprop(fit, noffset, "iv-name-hint", NULL);
396
397 info->fit = fit;
398 info->node_noffset = noffset;
399 info->name = algo_name;
400
401 info->cipher = image_get_cipher_algo(algo_name);
402 if (!info->cipher) {
403 printf("Can't get algo for cipher '%s'\n", image_name);
404 goto out;
405 }
406
407
408 snprintf(filename, sizeof(filename), "%s/%s%s",
409 info->keydir, info->keyname, ".bin");
410 info->key = malloc(info->cipher->key_len);
411 if (!info->key) {
412 printf("Can't allocate memory for key\n");
413 ret = -1;
414 goto out;
415 }
416 ret = fit_image_read_data(filename, (unsigned char *)info->key,
417 info->cipher->key_len);
418 if (ret < 0)
419 goto out;
420
421 info->iv = malloc(info->cipher->iv_len);
422 if (!info->iv) {
423 printf("Can't allocate memory for iv\n");
424 ret = -1;
425 goto out;
426 }
427
428 if (info->ivname) {
429
430 snprintf(filename, sizeof(filename), "%s/%s%s",
431 info->keydir, info->ivname, ".bin");
432 ret = fit_image_read_data(filename, (unsigned char *)info->iv,
433 info->cipher->iv_len);
434 } else {
435
436 ret = get_random_data((void *)info->iv, info->cipher->iv_len);
437 }
438
439 out:
440 return ret;
441}
442
443int fit_image_write_cipher(void *fit, int image_noffset, int noffset,
444 const void *data, size_t size,
445 unsigned char *data_ciphered, int data_ciphered_len)
446{
447 int ret = -1;
448
449
450 ret = fdt_setprop(fit, image_noffset, FIT_DATA_PROP,
451 data_ciphered, data_ciphered_len);
452 if (ret == -FDT_ERR_NOSPACE) {
453 ret = -ENOSPC;
454 goto out;
455 }
456 if (ret) {
457 printf("Can't replace data with ciphered data (err = %d)\n", ret);
458 goto out;
459 }
460
461
462 ret = fdt_setprop_u32(fit, image_noffset, "data-size-unciphered", size);
463 if (ret == -FDT_ERR_NOSPACE) {
464 ret = -ENOSPC;
465 goto out;
466 }
467 if (ret) {
468 printf("Can't add unciphered data size (err = %d)\n", ret);
469 goto out;
470 }
471
472 out:
473 return ret;
474}
475
476static int
477fit_image_process_cipher(const char *keydir, void *keydest, void *fit,
478 const char *image_name, int image_noffset,
479 int node_noffset, const void *data, size_t size,
480 const char *cmdname)
481{
482 struct image_cipher_info info;
483 unsigned char *data_ciphered = NULL;
484 int data_ciphered_len;
485 int ret;
486
487 memset(&info, 0, sizeof(info));
488
489 ret = fit_image_setup_cipher(&info, keydir, fit, image_name,
490 image_noffset, node_noffset);
491 if (ret)
492 goto out;
493
494 ret = info.cipher->encrypt(&info, data, size,
495 &data_ciphered, &data_ciphered_len);
496 if (ret)
497 goto out;
498
499
500
501
502
503
504
505 if (keydest) {
506 ret = info.cipher->add_cipher_data(&info, keydest, fit, node_noffset);
507 if (ret) {
508 printf("Failed to add verification data for cipher '%s' in image '%s'\n",
509 info.keyname, image_name);
510 goto out;
511 }
512 }
513
514 ret = fit_image_write_cipher(fit, image_noffset, node_noffset,
515 data, size,
516 data_ciphered, data_ciphered_len);
517
518 out:
519 free(data_ciphered);
520 free((void *)info.key);
521 free((void *)info.iv);
522 return ret;
523}
524
525int fit_image_cipher_data(const char *keydir, void *keydest,
526 void *fit, int image_noffset, const char *comment,
527 int require_keys, const char *engine_id,
528 const char *cmdname)
529{
530 const char *image_name;
531 const void *data;
532 size_t size;
533 int cipher_node_offset, len;
534
535
536 image_name = fit_get_name(fit, image_noffset, NULL);
537 if (!image_name) {
538 printf("Can't get image name\n");
539 return -1;
540 }
541
542
543 if (fit_image_get_data(fit, image_noffset, &data, &size)) {
544 printf("Can't get image data/size\n");
545 return -1;
546 }
547
548
549
550
551
552
553
554
555 if (fdt_getprop(fit, image_noffset, "data-size-unciphered", &len))
556 return 0;
557 if (len != -FDT_ERR_NOTFOUND) {
558 printf("Failure testing for data-size-unciphered\n");
559 return -1;
560 }
561
562
563 cipher_node_offset = fdt_subnode_offset(fit, image_noffset,
564 FIT_CIPHER_NODENAME);
565 if (cipher_node_offset == -FDT_ERR_NOTFOUND)
566 return 0;
567 if (cipher_node_offset < 0) {
568 printf("Failure getting cipher node\n");
569 return -1;
570 }
571 if (!IMAGE_ENABLE_ENCRYPT || !keydir)
572 return 0;
573 return fit_image_process_cipher(keydir, keydest, fit, image_name,
574 image_noffset, cipher_node_offset, data, size, cmdname);
575}
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612int fit_image_add_verification_data(const char *keydir, const char *keyfile,
613 void *keydest, void *fit, int image_noffset,
614 const char *comment, int require_keys, const char *engine_id,
615 const char *cmdname, const char* algo_name)
616{
617 const char *image_name;
618 const void *data;
619 size_t size;
620 int noffset;
621
622
623 if (fit_image_get_data(fit, image_noffset, &data, &size)) {
624 printf("Can't get image data/size\n");
625 return -1;
626 }
627
628 image_name = fit_get_name(fit, image_noffset, NULL);
629
630
631 for (noffset = fdt_first_subnode(fit, image_noffset);
632 noffset >= 0;
633 noffset = fdt_next_subnode(fit, noffset)) {
634 const char *node_name;
635 int ret = 0;
636
637
638
639
640
641
642 node_name = fit_get_name(fit, noffset, NULL);
643 if (!strncmp(node_name, FIT_HASH_NODENAME,
644 strlen(FIT_HASH_NODENAME))) {
645 ret = fit_image_process_hash(fit, image_name, noffset,
646 data, size);
647 } else if (IMAGE_ENABLE_SIGN && (keydir || keyfile) &&
648 !strncmp(node_name, FIT_SIG_NODENAME,
649 strlen(FIT_SIG_NODENAME))) {
650 ret = fit_image_process_sig(keydir, keyfile, keydest,
651 fit, image_name, noffset, data, size,
652 comment, require_keys, engine_id, cmdname,
653 algo_name);
654 }
655 if (ret < 0)
656 return ret;
657 }
658
659 return 0;
660}
661
662struct strlist {
663 int count;
664 char **strings;
665};
666
667static void strlist_init(struct strlist *list)
668{
669 memset(list, '\0', sizeof(*list));
670}
671
672static void strlist_free(struct strlist *list)
673{
674 int i;
675
676 for (i = 0; i < list->count; i++)
677 free(list->strings[i]);
678 free(list->strings);
679}
680
681static int strlist_add(struct strlist *list, const char *str)
682{
683 char *dup;
684
685 dup = strdup(str);
686 list->strings = realloc(list->strings,
687 (list->count + 1) * sizeof(char *));
688 if (!list || !str)
689 return -1;
690 list->strings[list->count++] = dup;
691
692 return 0;
693}
694
695static const char *fit_config_get_image_list(const void *fit, int noffset,
696 int *lenp, int *allow_missingp)
697{
698 static const char default_list[] = FIT_KERNEL_PROP "\0"
699 FIT_FDT_PROP;
700 const char *prop;
701
702
703 prop = fdt_getprop(fit, noffset, "sign-images", lenp);
704 if (prop) {
705 *allow_missingp = 0;
706 return *lenp ? prop : NULL;
707 }
708
709
710 *allow_missingp = 1;
711 *lenp = sizeof(default_list);
712
713 return default_list;
714}
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731static int fit_config_add_hash(const void *fit, int image_noffset,
732 struct strlist *node_inc, const char *conf_name,
733 const char *sig_name, const char *iname)
734{
735 char path[200];
736 int noffset;
737 int hash_count;
738 int ret;
739
740 ret = fdt_get_path(fit, image_noffset, path, sizeof(path));
741 if (ret < 0)
742 goto err_path;
743 if (strlist_add(node_inc, path))
744 goto err_mem;
745
746
747 hash_count = 0;
748 for (noffset = fdt_first_subnode(fit, image_noffset);
749 noffset >= 0;
750 noffset = fdt_next_subnode(fit, noffset)) {
751 const char *name = fit_get_name(fit, noffset, NULL);
752
753 if (strncmp(name, FIT_HASH_NODENAME,
754 strlen(FIT_HASH_NODENAME)))
755 continue;
756 ret = fdt_get_path(fit, noffset, path, sizeof(path));
757 if (ret < 0)
758 goto err_path;
759 if (strlist_add(node_inc, path))
760 goto err_mem;
761 hash_count++;
762 }
763
764 if (!hash_count) {
765 printf("Failed to find any hash nodes in configuration '%s/%s' image '%s' - without these it is not possible to verify this image\n",
766 conf_name, sig_name, iname);
767 return -ENOMSG;
768 }
769
770
771 noffset = fdt_subnode_offset(fit, image_noffset,
772 FIT_CIPHER_NODENAME);
773 if (noffset != -FDT_ERR_NOTFOUND) {
774 if (noffset < 0) {
775 printf("Failed to get cipher node in configuration '%s/%s' image '%s': %s\n",
776 conf_name, sig_name, iname,
777 fdt_strerror(noffset));
778 return -EIO;
779 }
780 ret = fdt_get_path(fit, noffset, path, sizeof(path));
781 if (ret < 0)
782 goto err_path;
783 if (strlist_add(node_inc, path))
784 goto err_mem;
785 }
786
787 return 0;
788
789err_mem:
790 printf("Out of memory processing configuration '%s/%s'\n", conf_name,
791 sig_name);
792 return -ENOMEM;
793
794err_path:
795 printf("Failed to get path for image '%s' in configuration '%s/%s': %s\n",
796 iname, conf_name, sig_name, fdt_strerror(ret));
797 return -ENOENT;
798}
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814static int fit_config_get_hash_list(const void *fit, int conf_noffset,
815 int sig_offset, struct strlist *node_inc)
816{
817 int allow_missing;
818 const char *prop, *iname, *end;
819 const char *conf_name, *sig_name;
820 char name[200];
821 int image_count;
822 int ret, len;
823
824 conf_name = fit_get_name(fit, conf_noffset, NULL);
825 sig_name = fit_get_name(fit, sig_offset, NULL);
826
827
828
829
830
831 strlist_init(node_inc);
832 snprintf(name, sizeof(name), "%s/%s", FIT_CONFS_PATH, conf_name);
833 if (strlist_add(node_inc, "/") ||
834 strlist_add(node_inc, name))
835 goto err_mem;
836
837
838 prop = fit_config_get_image_list(fit, sig_offset, &len,
839 &allow_missing);
840 if (!prop)
841 return 0;
842
843
844 end = prop + len;
845 image_count = 0;
846 for (iname = prop; iname < end; iname += strlen(iname) + 1) {
847 int image_noffset;
848 int index, max_index;
849
850 max_index = fdt_stringlist_count(fit, conf_noffset, iname);
851
852 for (index = 0; index < max_index; index++) {
853 image_noffset = fit_conf_get_prop_node_index(fit, conf_noffset,
854 iname, index);
855
856 if (image_noffset < 0) {
857 printf("Failed to find image '%s' in configuration '%s/%s'\n",
858 iname, conf_name, sig_name);
859 if (allow_missing)
860 continue;
861
862 return -ENOENT;
863 }
864
865 ret = fit_config_add_hash(fit, image_noffset, node_inc,
866 conf_name, sig_name, iname);
867 if (ret < 0)
868 return ret;
869
870 image_count++;
871 }
872 }
873
874 if (!image_count) {
875 printf("Failed to find any images for configuration '%s/%s'\n",
876 conf_name, sig_name);
877 return -ENOMSG;
878 }
879
880 return 0;
881
882err_mem:
883 printf("Out of memory processing configuration '%s/%s'\n", conf_name,
884 sig_name);
885 return -ENOMEM;
886}
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910static int fit_config_get_regions(const void *fit, int conf_noffset,
911 int sig_offset, struct image_region **regionp,
912 int *region_countp, char **region_propp,
913 int *region_proplen)
914{
915 char * const exc_prop[] = {"data"};
916 struct strlist node_inc;
917 struct image_region *region;
918 struct fdt_region fdt_regions[100];
919 const char *conf_name, *sig_name;
920 char path[200];
921 int count, i;
922 char *region_prop;
923 int ret, len;
924
925 conf_name = fit_get_name(fit, conf_noffset, NULL);
926 sig_name = fit_get_name(fit, sig_offset, NULL);
927 debug("%s: conf='%s', sig='%s'\n", __func__, conf_name, sig_name);
928
929
930 ret = fit_config_get_hash_list(fit, conf_noffset, sig_offset,
931 &node_inc);
932 if (ret)
933 return ret;
934
935
936 count = fdt_find_regions(fit, node_inc.strings, node_inc.count,
937 exc_prop, ARRAY_SIZE(exc_prop),
938 fdt_regions, ARRAY_SIZE(fdt_regions),
939 path, sizeof(path), 1);
940 if (count < 0) {
941 printf("Failed to hash configuration '%s/%s': %s\n", conf_name,
942 sig_name, fdt_strerror(ret));
943 return -EIO;
944 }
945 if (count == 0) {
946 printf("No data to hash for configuration '%s/%s': %s\n",
947 conf_name, sig_name, fdt_strerror(ret));
948 return -EINVAL;
949 }
950
951
952 region = fit_region_make_list(fit, fdt_regions, count, NULL);
953 if (!region) {
954 printf("Out of memory hashing configuration '%s/%s'\n",
955 conf_name, sig_name);
956 return -ENOMEM;
957 }
958
959
960 debug("Hash nodes:\n");
961 for (i = len = 0; i < node_inc.count; i++) {
962 debug(" %s\n", node_inc.strings[i]);
963 len += strlen(node_inc.strings[i]) + 1;
964 }
965 region_prop = malloc(len);
966 if (!region_prop) {
967 printf("Out of memory setting up regions for configuration '%s/%s'\n",
968 conf_name, sig_name);
969 return -ENOMEM;
970 }
971 for (i = len = 0; i < node_inc.count;
972 len += strlen(node_inc.strings[i]) + 1, i++)
973 strcpy(region_prop + len, node_inc.strings[i]);
974 strlist_free(&node_inc);
975
976 *region_countp = count;
977 *regionp = region;
978 *region_propp = region_prop;
979 *region_proplen = len;
980
981 return 0;
982}
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002static int fit_config_process_sig(const char *keydir, const char *keyfile,
1003 void *keydest, void *fit, const char *conf_name,
1004 int conf_noffset, int noffset, const char *comment,
1005 int require_keys, const char *engine_id, const char *cmdname,
1006 const char *algo_name)
1007{
1008 struct image_sign_info info;
1009 const char *node_name;
1010 struct image_region *region;
1011 char *region_prop;
1012 int region_proplen;
1013 int region_count;
1014 uint8_t *value;
1015 uint value_len;
1016 int ret;
1017
1018 node_name = fit_get_name(fit, noffset, NULL);
1019 if (fit_config_get_regions(fit, conf_noffset, noffset, ®ion,
1020 ®ion_count, ®ion_prop,
1021 ®ion_proplen))
1022 return -1;
1023
1024 if (fit_image_setup_sig(&info, keydir, keyfile, fit, conf_name, noffset,
1025 require_keys ? "conf" : NULL, engine_id,
1026 algo_name))
1027 return -1;
1028
1029 ret = info.crypto->sign(&info, region, region_count, &value,
1030 &value_len);
1031 free(region);
1032 if (ret) {
1033 printf("Failed to sign '%s' signature node in '%s' conf node\n",
1034 node_name, conf_name);
1035
1036
1037 if (ret == -ENOENT)
1038 return 0;
1039 return -1;
1040 }
1041
1042 ret = fit_image_write_sig(fit, noffset, value, value_len, comment,
1043 region_prop, region_proplen, cmdname,
1044 algo_name);
1045 if (ret) {
1046 if (ret == -FDT_ERR_NOSPACE)
1047 return -ENOSPC;
1048 printf("Can't write signature for '%s' signature node in '%s' conf node: %s\n",
1049 node_name, conf_name, fdt_strerror(ret));
1050 return -1;
1051 }
1052 free(value);
1053 free(region_prop);
1054
1055
1056 info.keyname = fdt_getprop(fit, noffset, FIT_KEY_HINT, NULL);
1057
1058
1059 if (keydest) {
1060 ret = info.crypto->add_verify_data(&info, keydest);
1061 if (ret < 0) {
1062 printf("Failed to add verification data for '%s' signature node in '%s' configuration node\n",
1063 node_name, conf_name);
1064 }
1065 return ret;
1066 }
1067
1068 return 0;
1069}
1070
1071static int fit_config_add_verification_data(const char *keydir,
1072 const char *keyfile, void *keydest, void *fit, int conf_noffset,
1073 const char *comment, int require_keys, const char *engine_id,
1074 const char *cmdname, const char *algo_name,
1075 struct image_summary *summary)
1076{
1077 const char *conf_name;
1078 int noffset;
1079
1080 conf_name = fit_get_name(fit, conf_noffset, NULL);
1081
1082
1083 for (noffset = fdt_first_subnode(fit, conf_noffset);
1084 noffset >= 0;
1085 noffset = fdt_next_subnode(fit, noffset)) {
1086 const char *node_name;
1087 int ret = 0;
1088
1089 node_name = fit_get_name(fit, noffset, NULL);
1090 if (!strncmp(node_name, FIT_SIG_NODENAME,
1091 strlen(FIT_SIG_NODENAME))) {
1092 ret = fit_config_process_sig(keydir, keyfile, keydest,
1093 fit, conf_name, conf_noffset, noffset, comment,
1094 require_keys, engine_id, cmdname, algo_name);
1095 if (ret < 0)
1096 return ret;
1097
1098 summary->sig_offset = noffset;
1099 fdt_get_path(fit, noffset, summary->sig_path,
1100 sizeof(summary->sig_path));
1101
1102 if (keydest) {
1103 summary->keydest_offset = ret;
1104 fdt_get_path(keydest, ret,
1105 summary->keydest_path,
1106 sizeof(summary->keydest_path));
1107 }
1108 }
1109 }
1110
1111 return 0;
1112}
1113
1114int fit_cipher_data(const char *keydir, void *keydest, void *fit,
1115 const char *comment, int require_keys,
1116 const char *engine_id, const char *cmdname)
1117{
1118 int images_noffset;
1119 int noffset;
1120 int ret;
1121
1122
1123 images_noffset = fdt_path_offset(fit, FIT_IMAGES_PATH);
1124 if (images_noffset < 0) {
1125 printf("Can't find images parent node '%s' (%s)\n",
1126 FIT_IMAGES_PATH, fdt_strerror(images_noffset));
1127 return images_noffset;
1128 }
1129
1130
1131 for (noffset = fdt_first_subnode(fit, images_noffset);
1132 noffset >= 0;
1133 noffset = fdt_next_subnode(fit, noffset)) {
1134
1135
1136
1137
1138 ret = fit_image_cipher_data(keydir, keydest,
1139 fit, noffset, comment,
1140 require_keys, engine_id,
1141 cmdname);
1142 if (ret)
1143 return ret;
1144 }
1145
1146 return 0;
1147}
1148
1149int fit_add_verification_data(const char *keydir, const char *keyfile,
1150 void *keydest, void *fit, const char *comment,
1151 int require_keys, const char *engine_id,
1152 const char *cmdname, const char *algo_name,
1153 struct image_summary *summary)
1154{
1155 int images_noffset, confs_noffset;
1156 int noffset;
1157 int ret;
1158
1159
1160 images_noffset = fdt_path_offset(fit, FIT_IMAGES_PATH);
1161 if (images_noffset < 0) {
1162 printf("Can't find images parent node '%s' (%s)\n",
1163 FIT_IMAGES_PATH, fdt_strerror(images_noffset));
1164 return images_noffset;
1165 }
1166
1167
1168 for (noffset = fdt_first_subnode(fit, images_noffset);
1169 noffset >= 0;
1170 noffset = fdt_next_subnode(fit, noffset)) {
1171
1172
1173
1174
1175 ret = fit_image_add_verification_data(keydir, keyfile, keydest,
1176 fit, noffset, comment, require_keys, engine_id,
1177 cmdname, algo_name);
1178 if (ret)
1179 return ret;
1180 }
1181
1182
1183 if (!IMAGE_ENABLE_SIGN || !(keydir || keyfile))
1184 return 0;
1185
1186
1187 confs_noffset = fdt_path_offset(fit, FIT_CONFS_PATH);
1188 if (confs_noffset < 0) {
1189 printf("Can't find images parent node '%s' (%s)\n",
1190 FIT_CONFS_PATH, fdt_strerror(confs_noffset));
1191 return -ENOENT;
1192 }
1193
1194
1195 for (noffset = fdt_first_subnode(fit, confs_noffset);
1196 noffset >= 0;
1197 noffset = fdt_next_subnode(fit, noffset)) {
1198 ret = fit_config_add_verification_data(keydir, keyfile, keydest,
1199 fit, noffset, comment,
1200 require_keys,
1201 engine_id, cmdname,
1202 algo_name, summary);
1203 if (ret)
1204 return ret;
1205 }
1206
1207 return 0;
1208}
1209
1210#ifdef CONFIG_FIT_SIGNATURE
1211int fit_check_sign(const void *fit, const void *key,
1212 const char *fit_uname_config)
1213{
1214 int cfg_noffset;
1215 int ret;
1216
1217 cfg_noffset = fit_conf_get_node(fit, fit_uname_config);
1218 if (!cfg_noffset)
1219 return -1;
1220
1221 printf("Verifying Hash Integrity for node '%s'... ",
1222 fdt_get_name(fit, cfg_noffset, NULL));
1223 ret = fit_config_verify(fit, cfg_noffset);
1224 if (ret)
1225 return ret;
1226 printf("Verified OK, loading images\n");
1227 ret = bootm_host_load_images(fit, cfg_noffset);
1228
1229 return ret;
1230}
1231#endif
1232