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