:)
[platform/kernel/u-boot.git] / tools / image-host.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Copyright (c) 2013, Google Inc.
4  *
5  * (C) Copyright 2008 Semihalf
6  *
7  * (C) Copyright 2000-2006
8  * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
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 #include <openssl/pem.h>
18 #include <openssl/evp.h>
19
20 #define IMAGE_PRE_LOAD_PATH                             "/image/pre-load/sig"
21
22 /**
23  * fit_set_hash_value - set hash value in requested has node
24  * @fit: pointer to the FIT format image header
25  * @noffset: hash node offset
26  * @value: hash value to be set
27  * @value_len: hash value length
28  *
29  * fit_set_hash_value() attempts to set hash value in a node at offset
30  * given and returns operation status to the caller.
31  *
32  * returns
33  *     0, on success
34  *     -1, on failure
35  */
36 static int fit_set_hash_value(void *fit, int noffset, uint8_t *value,
37                                 int value_len)
38 {
39         int ret;
40
41         ret = fdt_setprop(fit, noffset, FIT_VALUE_PROP, value, value_len);
42         if (ret) {
43                 printf("Can't set hash '%s' property for '%s' node(%s)\n",
44                        FIT_VALUE_PROP, fit_get_name(fit, noffset, NULL),
45                        fdt_strerror(ret));
46                 return ret == -FDT_ERR_NOSPACE ? -ENOSPC : -EIO;
47         }
48
49         return 0;
50 }
51
52 /**
53  * fit_image_process_hash - Process a single subnode of the images/ node
54  *
55  * Check each subnode and process accordingly. For hash nodes we generate
56  * a hash of the supplied data and store it in the node.
57  *
58  * @fit:        pointer to the FIT format image header
59  * @image_name: name of image being processed (used to display errors)
60  * @noffset:    subnode offset
61  * @data:       data to process
62  * @size:       size of data in bytes
63  * Return: 0 if ok, -1 on error
64  */
65 static int fit_image_process_hash(void *fit, const char *image_name,
66                 int noffset, const void *data, size_t size)
67 {
68         uint8_t value[FIT_MAX_HASH_LEN];
69         const char *node_name;
70         int value_len;
71         const char *algo;
72         int ret;
73
74         node_name = fit_get_name(fit, noffset, NULL);
75
76         if (fit_image_hash_get_algo(fit, noffset, &algo)) {
77                 printf("Can't get hash algo property for '%s' hash node in '%s' image node\n",
78                        node_name, image_name);
79                 return -ENOENT;
80         }
81
82         if (calculate_hash(data, size, algo, value, &value_len)) {
83                 printf("Unsupported hash algorithm (%s) for '%s' hash node in '%s' image node\n",
84                        algo, node_name, image_name);
85                 return -EPROTONOSUPPORT;
86         }
87
88         ret = fit_set_hash_value(fit, noffset, value, value_len);
89         if (ret) {
90                 printf("Can't set hash value for '%s' hash node in '%s' image node\n",
91                        node_name, image_name);
92                 return ret;
93         }
94
95         return 0;
96 }
97
98 /**
99  * fit_image_write_sig() - write the signature to a FIT
100  *
101  * This writes the signature and signer data to the FIT.
102  *
103  * @fit: pointer to the FIT format image header
104  * @noffset: hash node offset
105  * @value: signature value to be set
106  * @value_len: signature value length
107  * @comment: Text comment to write (NULL for none)
108  *
109  * returns
110  *     0, on success
111  *     -FDT_ERR_..., on failure
112  */
113 static int fit_image_write_sig(void *fit, int noffset, uint8_t *value,
114                 int value_len, const char *comment, const char *region_prop,
115                 int region_proplen, const char *cmdname, const char *algo_name)
116 {
117         int string_size;
118         int ret;
119
120         /*
121          * Get the current string size, before we update the FIT and add
122          * more
123          */
124         string_size = fdt_size_dt_strings(fit);
125
126         ret = fdt_setprop(fit, noffset, FIT_VALUE_PROP, value, value_len);
127         if (!ret) {
128                 ret = fdt_setprop_string(fit, noffset, "signer-name",
129                                          "mkimage");
130         }
131         if (!ret) {
132                 ret = fdt_setprop_string(fit, noffset, "signer-version",
133                                   PLAIN_VERSION);
134         }
135         if (comment && !ret)
136                 ret = fdt_setprop_string(fit, noffset, "comment", comment);
137         if (!ret) {
138                 time_t timestamp = imagetool_get_source_date(cmdname,
139                                                              time(NULL));
140                 uint32_t t = cpu_to_uimage(timestamp);
141
142                 ret = fdt_setprop(fit, noffset, FIT_TIMESTAMP_PROP, &t,
143                         sizeof(uint32_t));
144         }
145         if (region_prop && !ret) {
146                 uint32_t strdata[2];
147
148                 ret = fdt_setprop(fit, noffset, "hashed-nodes",
149                                    region_prop, region_proplen);
150                 /* This is a legacy offset, it is unused, and must remain 0. */
151                 strdata[0] = 0;
152                 strdata[1] = cpu_to_fdt32(string_size);
153                 if (!ret) {
154                         ret = fdt_setprop(fit, noffset, "hashed-strings",
155                                           strdata, sizeof(strdata));
156                 }
157         }
158         if (algo_name && !ret)
159                 ret = fdt_setprop_string(fit, noffset, "algo", algo_name);
160
161         return ret;
162 }
163
164 static int fit_image_setup_sig(struct image_sign_info *info,
165                 const char *keydir, const char *keyfile, void *fit,
166                 const char *image_name, int noffset, const char *require_keys,
167                 const char *engine_id, const char *algo_name)
168 {
169         const char *node_name;
170         const char *padding_name;
171
172         node_name = fit_get_name(fit, noffset, NULL);
173         if (!algo_name) {
174                 if (fit_image_hash_get_algo(fit, noffset, &algo_name)) {
175                         printf("Can't get algo property for '%s' signature node in '%s' image node\n",
176                                node_name, image_name);
177                         return -1;
178                 }
179         }
180
181         padding_name = fdt_getprop(fit, noffset, "padding", NULL);
182
183         memset(info, '\0', sizeof(*info));
184         info->keydir = keydir;
185         info->keyfile = keyfile;
186         info->keyname = fdt_getprop(fit, noffset, FIT_KEY_HINT, NULL);
187         info->fit = fit;
188         info->node_offset = noffset;
189         info->name = strdup(algo_name);
190         info->checksum = image_get_checksum_algo(algo_name);
191         info->crypto = image_get_crypto_algo(algo_name);
192         info->padding = image_get_padding_algo(padding_name);
193         info->require_keys = require_keys;
194         info->engine_id = engine_id;
195         if (!info->checksum || !info->crypto) {
196                 printf("Unsupported signature algorithm (%s) for '%s' signature node in '%s' image node\n",
197                        algo_name, node_name, image_name);
198                 return -1;
199         }
200
201         return 0;
202 }
203
204 /**
205  * fit_image_process_sig- Process a single subnode of the images/ node
206  *
207  * Check each subnode and process accordingly. For signature nodes we
208  * generate a signed hash of the supplied data and store it in the node.
209  *
210  * @keydir:     Directory containing keys to use for signing
211  * @keydest:    Destination FDT blob to write public keys into (NULL if none)
212  * @fit:        pointer to the FIT format image header
213  * @image_name: name of image being processed (used to display errors)
214  * @noffset:    subnode offset
215  * @data:       data to process
216  * @size:       size of data in bytes
217  * @comment:    Comment to add to signature nodes
218  * @require_keys: Mark all keys as 'required'
219  * @engine_id:  Engine to use for signing
220  * Return: keydest node if @keydest is non-NULL, else 0 if none; -ve error code
221  *      on failure
222  */
223 static int fit_image_process_sig(const char *keydir, const char *keyfile,
224                 void *keydest, void *fit, const char *image_name,
225                 int noffset, const void *data, size_t size,
226                 const char *comment, int require_keys, const char *engine_id,
227                 const char *cmdname, const char *algo_name)
228 {
229         struct image_sign_info info;
230         struct image_region region;
231         const char *node_name;
232         uint8_t *value;
233         uint value_len;
234         int ret;
235
236         if (fit_image_setup_sig(&info, keydir, keyfile, fit, image_name,
237                                 noffset, require_keys ? "image" : NULL,
238                                 engine_id, algo_name))
239                 return -1;
240
241         node_name = fit_get_name(fit, noffset, NULL);
242         region.data = data;
243         region.size = size;
244         ret = info.crypto->sign(&info, &region, 1, &value, &value_len);
245         if (ret) {
246                 printf("Failed to sign '%s' signature node in '%s' image node: %d\n",
247                        node_name, image_name, ret);
248
249                 /* We allow keys to be missing */
250                 if (ret == -ENOENT)
251                         return 0;
252                 return -1;
253         }
254
255         ret = fit_image_write_sig(fit, noffset, value, value_len, comment,
256                         NULL, 0, cmdname, algo_name);
257         if (ret) {
258                 if (ret == -FDT_ERR_NOSPACE)
259                         return -ENOSPC;
260                 printf("Can't write signature for '%s' signature node in '%s' conf node: %s\n",
261                        node_name, image_name, fdt_strerror(ret));
262                 return -1;
263         }
264         free(value);
265
266         /* Get keyname again, as FDT has changed and invalidated our pointer */
267         info.keyname = fdt_getprop(fit, noffset, FIT_KEY_HINT, NULL);
268
269         /*
270          * Write the public key into the supplied FDT file; this might fail
271          * several times, since we try signing with successively increasing
272          * size values
273          */
274         if (keydest) {
275                 ret = info.crypto->add_verify_data(&info, keydest);
276                 if (ret < 0) {
277                         printf("Failed to add verification data for '%s' signature node in '%s' image node\n",
278                                node_name, image_name);
279                         return ret;
280                 }
281                 /* Return the node that was written to */
282                 return ret;
283         }
284
285         return 0;
286 }
287
288 static int fit_image_read_data(char *filename, unsigned char *data,
289                                int expected_size)
290 {
291         struct stat sbuf;
292         int fd, ret = -1;
293         ssize_t n;
294
295         /* Open file */
296         fd = open(filename, O_RDONLY | O_BINARY);
297         if (fd < 0) {
298                 printf("Can't open file %s (err=%d => %s)\n",
299                        filename, errno, strerror(errno));
300                 return -1;
301         }
302
303         /* Compute file size */
304         if (fstat(fd, &sbuf) < 0) {
305                 printf("Can't fstat file %s (err=%d => %s)\n",
306                        filename, errno, strerror(errno));
307                 goto err;
308         }
309
310         /* Check file size */
311         if (sbuf.st_size != expected_size) {
312                 printf("File %s don't have the expected size (size=%lld, expected=%d)\n",
313                        filename, (long long)sbuf.st_size, expected_size);
314                 goto err;
315         }
316
317         /* Read data */
318         n = read(fd, data, sbuf.st_size);
319         if (n < 0) {
320                 printf("Can't read file %s (err=%d => %s)\n",
321                        filename, errno, strerror(errno));
322                 goto err;
323         }
324
325         /* Check that we have read all the file */
326         if (n != sbuf.st_size) {
327                 printf("Can't read all file %s (read %zd bytes, expected %lld)\n",
328                        filename, n, (long long)sbuf.st_size);
329                 goto err;
330         }
331
332         ret = 0;
333
334 err:
335         close(fd);
336         return ret;
337 }
338
339 static int get_random_data(void *data, int size)
340 {
341         unsigned char *tmp = data;
342         struct timespec date;
343         int i, ret;
344
345         if (!tmp) {
346                 printf("%s: pointer data is NULL\n", __func__);
347                 ret = -1;
348                 goto out;
349         }
350
351         ret = clock_gettime(CLOCK_MONOTONIC, &date);
352         if (ret) {
353                 printf("%s: clock_gettime has failed (%s)\n", __func__,
354                        strerror(errno));
355                 goto out;
356         }
357
358         srandom(date.tv_nsec);
359
360         for (i = 0; i < size; i++) {
361                 *tmp = random() & 0xff;
362                 tmp++;
363         }
364
365  out:
366         return ret;
367 }
368
369 static int fit_image_setup_cipher(struct image_cipher_info *info,
370                                   const char *keydir, void *fit,
371                                   const char *image_name, int image_noffset,
372                                   int noffset)
373 {
374         char *algo_name;
375         char filename[128];
376         int ret = -1;
377
378         if (fit_image_cipher_get_algo(fit, noffset, &algo_name)) {
379                 printf("Can't get algo name for cipher in image '%s'\n",
380                        image_name);
381                 goto out;
382         }
383
384         info->keydir = keydir;
385
386         /* Read the key name */
387         info->keyname = fdt_getprop(fit, noffset, FIT_KEY_HINT, NULL);
388         if (!info->keyname) {
389                 printf("Can't get key name for cipher in image '%s'\n",
390                        image_name);
391                 goto out;
392         }
393
394         /*
395          * Read the IV name
396          *
397          * If this property is not provided then mkimage will generate
398          * a random IV and store it in the FIT image
399          */
400         info->ivname = fdt_getprop(fit, noffset, "iv-name-hint", NULL);
401
402         info->fit = fit;
403         info->node_noffset = noffset;
404         info->name = algo_name;
405
406         info->cipher = image_get_cipher_algo(algo_name);
407         if (!info->cipher) {
408                 printf("Can't get algo for cipher '%s'\n", image_name);
409                 goto out;
410         }
411
412         /* Read the key in the file */
413         snprintf(filename, sizeof(filename), "%s/%s%s",
414                  info->keydir, info->keyname, ".bin");
415         info->key = malloc(info->cipher->key_len);
416         if (!info->key) {
417                 printf("Can't allocate memory for key\n");
418                 ret = -1;
419                 goto out;
420         }
421         ret = fit_image_read_data(filename, (unsigned char *)info->key,
422                                   info->cipher->key_len);
423         if (ret < 0)
424                 goto out;
425
426         info->iv = malloc(info->cipher->iv_len);
427         if (!info->iv) {
428                 printf("Can't allocate memory for iv\n");
429                 ret = -1;
430                 goto out;
431         }
432
433         if (info->ivname) {
434                 /* Read the IV in the file */
435                 snprintf(filename, sizeof(filename), "%s/%s%s",
436                          info->keydir, info->ivname, ".bin");
437                 ret = fit_image_read_data(filename, (unsigned char *)info->iv,
438                                           info->cipher->iv_len);
439         } else {
440                 /* Generate an ramdom IV */
441                 ret = get_random_data((void *)info->iv, info->cipher->iv_len);
442         }
443
444  out:
445         return ret;
446 }
447
448 int fit_image_write_cipher(void *fit, int image_noffset, int noffset,
449                            const void *data, size_t size,
450                            unsigned char *data_ciphered, int data_ciphered_len)
451 {
452         int ret = -1;
453
454         /* Replace data with ciphered data */
455         ret = fdt_setprop(fit, image_noffset, FIT_DATA_PROP,
456                           data_ciphered, data_ciphered_len);
457         if (ret == -FDT_ERR_NOSPACE) {
458                 ret = -ENOSPC;
459                 goto out;
460         }
461         if (ret) {
462                 printf("Can't replace data with ciphered data (err = %d)\n", ret);
463                 goto out;
464         }
465
466         /* add non ciphered data size */
467         ret = fdt_setprop_u32(fit, image_noffset, "data-size-unciphered", size);
468         if (ret == -FDT_ERR_NOSPACE) {
469                 ret = -ENOSPC;
470                 goto out;
471         }
472         if (ret) {
473                 printf("Can't add unciphered data size (err = %d)\n", ret);
474                 goto out;
475         }
476
477  out:
478         return ret;
479 }
480
481 static int
482 fit_image_process_cipher(const char *keydir, void *keydest, void *fit,
483                          const char *image_name, int image_noffset,
484                          int node_noffset, const void *data, size_t size,
485                          const char *cmdname)
486 {
487         struct image_cipher_info info;
488         unsigned char *data_ciphered = NULL;
489         int data_ciphered_len;
490         int ret;
491
492         memset(&info, 0, sizeof(info));
493
494         ret = fit_image_setup_cipher(&info, keydir, fit, image_name,
495                                      image_noffset, node_noffset);
496         if (ret)
497                 goto out;
498
499         ret = info.cipher->encrypt(&info, data, size,
500                                     &data_ciphered, &data_ciphered_len);
501         if (ret)
502                 goto out;
503
504         /*
505          * Write the public key into the supplied FDT file; this might fail
506          * several times, since we try signing with successively increasing
507          * size values
508          * And, if needed, write the iv in the FIT file
509          */
510         if (keydest) {
511                 ret = info.cipher->add_cipher_data(&info, keydest, fit, node_noffset);
512                 if (ret) {
513                         printf("Failed to add verification data for cipher '%s' in image '%s'\n",
514                                info.keyname, image_name);
515                         goto out;
516                 }
517         }
518
519         ret = fit_image_write_cipher(fit, image_noffset, node_noffset,
520                                      data, size,
521                                      data_ciphered, data_ciphered_len);
522
523  out:
524         free(data_ciphered);
525         free((void *)info.key);
526         free((void *)info.iv);
527         return ret;
528 }
529
530 int fit_image_cipher_data(const char *keydir, void *keydest,
531                           void *fit, int image_noffset, const char *comment,
532                           int require_keys, const char *engine_id,
533                           const char *cmdname)
534 {
535         const char *image_name;
536         const void *data;
537         size_t size;
538         int cipher_node_offset, len;
539
540         /* Get image name */
541         image_name = fit_get_name(fit, image_noffset, NULL);
542         if (!image_name) {
543                 printf("Can't get image name\n");
544                 return -1;
545         }
546
547         /* Get image data and data length */
548         if (fit_image_get_data(fit, image_noffset, &data, &size)) {
549                 printf("Can't get image data/size\n");
550                 return -1;
551         }
552
553         /*
554          * Don't cipher ciphered data.
555          *
556          * If the data-size-unciphered property is present the data for this
557          * image is already encrypted. This is important as 'mkimage -F' can be
558          * run multiple times on a FIT image.
559          */
560         if (fdt_getprop(fit, image_noffset, "data-size-unciphered", &len))
561                 return 0;
562         if (len != -FDT_ERR_NOTFOUND) {
563                 printf("Failure testing for data-size-unciphered\n");
564                 return -1;
565         }
566
567         /* Process cipher node if present */
568         cipher_node_offset = fdt_subnode_offset(fit, image_noffset,
569                                                 FIT_CIPHER_NODENAME);
570         if (cipher_node_offset == -FDT_ERR_NOTFOUND)
571                 return 0;
572         if (cipher_node_offset < 0) {
573                 printf("Failure getting cipher node\n");
574                 return -1;
575         }
576         if (!IMAGE_ENABLE_ENCRYPT || !keydir)
577                 return 0;
578         return fit_image_process_cipher(keydir, keydest, fit, image_name,
579                 image_noffset, cipher_node_offset, data, size, cmdname);
580 }
581
582 /**
583  * fit_image_add_verification_data() - calculate/set verig. data for image node
584  *
585  * This adds hash and signature values for an component image node.
586  *
587  * All existing hash subnodes are checked, if algorithm property is set to
588  * one of the supported hash algorithms, hash value is computed and
589  * corresponding hash node property is set, for example:
590  *
591  * Input component image node structure:
592  *
593  * o image-1 (at image_noffset)
594  *   | - data = [binary data]
595  *   o hash-1
596  *     |- algo = "sha1"
597  *
598  * Output component image node structure:
599  *
600  * o image-1 (at image_noffset)
601  *   | - data = [binary data]
602  *   o hash-1
603  *     |- algo = "sha1"
604  *     |- value = sha1(data)
605  *
606  * For signature details, please see doc/uImage.FIT/signature.txt
607  *
608  * @keydir      Directory containing *.key and *.crt files (or NULL)
609  * @keydest     FDT Blob to write public keys into (NULL if none)
610  * @fit:        Pointer to the FIT format image header
611  * @image_noffset: Requested component image node
612  * @comment:    Comment to add to signature nodes
613  * @require_keys: Mark all keys as 'required'
614  * @engine_id:  Engine to use for signing
615  * @return: 0 on success, <0 on failure
616  */
617 int fit_image_add_verification_data(const char *keydir, const char *keyfile,
618                 void *keydest, void *fit, int image_noffset,
619                 const char *comment, int require_keys, const char *engine_id,
620                 const char *cmdname, const char* algo_name)
621 {
622         const char *image_name;
623         const void *data;
624         size_t size;
625         int noffset;
626
627         /* Get image data and data length */
628         if (fit_image_get_data(fit, image_noffset, &data, &size)) {
629                 printf("Can't get image data/size\n");
630                 return -1;
631         }
632
633         image_name = fit_get_name(fit, image_noffset, NULL);
634
635         /* Process all hash subnodes of the component image node */
636         for (noffset = fdt_first_subnode(fit, image_noffset);
637              noffset >= 0;
638              noffset = fdt_next_subnode(fit, noffset)) {
639                 const char *node_name;
640                 int ret = 0;
641
642                 /*
643                  * Check subnode name, must be equal to "hash" or "signature".
644                  * Multiple hash nodes require unique unit node
645                  * names, e.g. hash-1, hash-2, signature-1, etc.
646                  */
647                 node_name = fit_get_name(fit, noffset, NULL);
648                 if (!strncmp(node_name, FIT_HASH_NODENAME,
649                              strlen(FIT_HASH_NODENAME))) {
650                         ret = fit_image_process_hash(fit, image_name, noffset,
651                                                 data, size);
652                 } else if (IMAGE_ENABLE_SIGN && (keydir || keyfile) &&
653                            !strncmp(node_name, FIT_SIG_NODENAME,
654                                 strlen(FIT_SIG_NODENAME))) {
655                         ret = fit_image_process_sig(keydir, keyfile, keydest,
656                                 fit, image_name, noffset, data, size,
657                                 comment, require_keys, engine_id, cmdname,
658                                 algo_name);
659                 }
660                 if (ret < 0)
661                         return ret;
662         }
663
664         return 0;
665 }
666
667 struct strlist {
668         int count;
669         char **strings;
670 };
671
672 static void strlist_init(struct strlist *list)
673 {
674         memset(list, '\0', sizeof(*list));
675 }
676
677 static void strlist_free(struct strlist *list)
678 {
679         int i;
680
681         for (i = 0; i < list->count; i++)
682                 free(list->strings[i]);
683         free(list->strings);
684 }
685
686 static int strlist_add(struct strlist *list, const char *str)
687 {
688         char *dup;
689
690         dup = strdup(str);
691         list->strings = realloc(list->strings,
692                                 (list->count + 1) * sizeof(char *));
693         if (!list || !str)
694                 return -1;
695         list->strings[list->count++] = dup;
696
697         return 0;
698 }
699
700 static const char *fit_config_get_image_list(const void *fit, int noffset,
701                                              int *lenp, int *allow_missingp)
702 {
703         static const char default_list[] = FIT_KERNEL_PROP "\0"
704                         FIT_FDT_PROP;
705         const char *prop;
706
707         /* If there is an "sign-image" property, use that */
708         prop = fdt_getprop(fit, noffset, "sign-images", lenp);
709         if (prop) {
710                 *allow_missingp = 0;
711                 return *lenp ? prop : NULL;
712         }
713
714         /* Default image list */
715         *allow_missingp = 1;
716         *lenp = sizeof(default_list);
717
718         return default_list;
719 }
720
721 /**
722  * fit_config_add_hash() - Add a list of nodes to hash for an image
723  *
724  * This adds a list of paths to image nodes (as referred to by a particular
725  * offset) that need to be hashed, to protect a configuration
726  *
727  * @fit:        Pointer to the FIT format image header
728  * @image_noffset: Offset of image to process (e.g. /images/kernel-1)
729  * @node_inc:   List of nodes to add to
730  * @conf_name   Configuration-node name, child of /configurations node (only
731  *      used for error messages)
732  * @sig_name    Signature-node name (only used for error messages)
733  * @iname:      Name of image being processed (e.g. "kernel-1" (only used
734  *      for error messages)
735  */
736 static int fit_config_add_hash(const void *fit, int image_noffset,
737                                struct strlist *node_inc, const char *conf_name,
738                                const char *sig_name, const char *iname)
739 {
740         char path[200];
741         int noffset;
742         int hash_count;
743         int ret;
744
745         ret = fdt_get_path(fit, image_noffset, path, sizeof(path));
746         if (ret < 0)
747                 goto err_path;
748         if (strlist_add(node_inc, path))
749                 goto err_mem;
750
751         /* Add all this image's hashes */
752         hash_count = 0;
753         for (noffset = fdt_first_subnode(fit, image_noffset);
754              noffset >= 0;
755              noffset = fdt_next_subnode(fit, noffset)) {
756                 const char *name = fit_get_name(fit, noffset, NULL);
757
758                 if (strncmp(name, FIT_HASH_NODENAME,
759                             strlen(FIT_HASH_NODENAME)))
760                         continue;
761                 ret = fdt_get_path(fit, noffset, path, sizeof(path));
762                 if (ret < 0)
763                         goto err_path;
764                 if (strlist_add(node_inc, path))
765                         goto err_mem;
766                 hash_count++;
767         }
768
769         if (!hash_count) {
770                 printf("Failed to find any hash nodes in configuration '%s/%s' image '%s' - without these it is not possible to verify this image\n",
771                        conf_name, sig_name, iname);
772                 return -ENOMSG;
773         }
774
775         /* Add this image's cipher node if present */
776         noffset = fdt_subnode_offset(fit, image_noffset,
777                                      FIT_CIPHER_NODENAME);
778         if (noffset != -FDT_ERR_NOTFOUND) {
779                 if (noffset < 0) {
780                         printf("Failed to get cipher node in configuration '%s/%s' image '%s': %s\n",
781                                conf_name, sig_name, iname,
782                                fdt_strerror(noffset));
783                         return -EIO;
784                 }
785                 ret = fdt_get_path(fit, noffset, path, sizeof(path));
786                 if (ret < 0)
787                         goto err_path;
788                 if (strlist_add(node_inc, path))
789                         goto err_mem;
790         }
791
792         return 0;
793
794 err_mem:
795         printf("Out of memory processing configuration '%s/%s'\n", conf_name,
796                sig_name);
797         return -ENOMEM;
798
799 err_path:
800         printf("Failed to get path for image '%s' in configuration '%s/%s': %s\n",
801                iname, conf_name, sig_name, fdt_strerror(ret));
802         return -ENOENT;
803 }
804
805 /**
806  * fit_config_get_hash_list() - Get the regions to sign
807  *
808  * This calculates a list of nodes to hash for this particular configuration,
809  * returning it as a string list (struct strlist, not a devicetree string list)
810  *
811  * @fit:        Pointer to the FIT format image header
812  * @conf_noffset: Offset of configuration node to sign (child of
813  *      /configurations node)
814  * @sig_offset: Offset of signature node containing info about how to sign it
815  *      (child of 'signatures' node)
816  * @return 0 if OK, -ENOENT if an image referred to by the configuration cannot
817  *      be found, -ENOMSG if ther were no images in the configuration
818  */
819 static int fit_config_get_hash_list(const void *fit, int conf_noffset,
820                                     int sig_offset, struct strlist *node_inc)
821 {
822         int allow_missing;
823         const char *prop, *iname, *end;
824         const char *conf_name, *sig_name;
825         char name[200];
826         int image_count;
827         int ret, len;
828
829         conf_name = fit_get_name(fit, conf_noffset, NULL);
830         sig_name = fit_get_name(fit, sig_offset, NULL);
831
832         /*
833          * Build a list of nodes we need to hash. We always need the root
834          * node and the configuration.
835          */
836         strlist_init(node_inc);
837         snprintf(name, sizeof(name), "%s/%s", FIT_CONFS_PATH, conf_name);
838         if (strlist_add(node_inc, "/") ||
839             strlist_add(node_inc, name))
840                 goto err_mem;
841
842         /* Get a list of images that we intend to sign */
843         prop = fit_config_get_image_list(fit, sig_offset, &len,
844                                         &allow_missing);
845         if (!prop)
846                 return 0;
847
848         /* Locate the images */
849         end = prop + len;
850         image_count = 0;
851         for (iname = prop; iname < end; iname += strlen(iname) + 1) {
852                 int image_noffset;
853                 int index, max_index;
854
855                 max_index = fdt_stringlist_count(fit, conf_noffset, iname);
856
857                 for (index = 0; index < max_index; index++) {
858                         image_noffset = fit_conf_get_prop_node_index(fit, conf_noffset,
859                                                                      iname, index);
860
861                         if (image_noffset < 0) {
862                                 printf("Failed to find image '%s' in  configuration '%s/%s'\n",
863                                        iname, conf_name, sig_name);
864                                 if (allow_missing)
865                                         continue;
866
867                                 return -ENOENT;
868                         }
869
870                         ret = fit_config_add_hash(fit, image_noffset, node_inc,
871                                                   conf_name, sig_name, iname);
872                         if (ret < 0)
873                                 return ret;
874
875                         image_count++;
876                 }
877         }
878
879         if (!image_count) {
880                 printf("Failed to find any images for configuration '%s/%s'\n",
881                        conf_name, sig_name);
882                 return -ENOMSG;
883         }
884
885         return 0;
886
887 err_mem:
888         printf("Out of memory processing configuration '%s/%s'\n", conf_name,
889                sig_name);
890         return -ENOMEM;
891 }
892
893 /**
894  * fit_config_get_regions() - Get the regions to sign
895  *
896  * This calculates a list of node to hash for this particular configuration,
897  * then finds which regions of the devicetree they correspond to.
898  *
899  * @fit:        Pointer to the FIT format image header
900  * @conf_noffset: Offset of configuration node to sign (child of
901  *      /configurations node)
902  * @sig_offset: Offset of signature node containing info about how to sign it
903  *      (child of 'signatures' node)
904  * @regionp: Returns list of regions that need to be hashed (allocated; must be
905  *      freed by the caller)
906  * @region_count: Returns number of regions
907  * @region_propp: Returns string-list property containing the list of nodes
908  *      that correspond to the regions. Each entry is a full path to the node.
909  *      This is in devicetree format, i.e. a \0 between each string. This is
910  *      allocated and must be freed by the caller.
911  * @region_proplen: Returns length of *@@region_propp in bytes
912  * @return 0 if OK, -ENOMEM if out of memory, -EIO if the regions to hash could
913  * not be found, -EINVAL if no registers were found to hash
914  */
915 static int fit_config_get_regions(const void *fit, int conf_noffset,
916                                   int sig_offset, struct image_region **regionp,
917                                   int *region_countp, char **region_propp,
918                                   int *region_proplen)
919 {
920         char * const exc_prop[] = {"data"};
921         struct strlist node_inc;
922         struct image_region *region;
923         struct fdt_region fdt_regions[100];
924         const char *conf_name, *sig_name;
925         char path[200];
926         int count, i;
927         char *region_prop;
928         int ret, len;
929
930         conf_name = fit_get_name(fit, conf_noffset, NULL);
931         sig_name = fit_get_name(fit, sig_offset, NULL);
932         debug("%s: conf='%s', sig='%s'\n", __func__, conf_name, sig_name);
933
934         /* Get a list of nodes we want to hash */
935         ret = fit_config_get_hash_list(fit, conf_noffset, sig_offset,
936                                        &node_inc);
937         if (ret)
938                 return ret;
939
940         /* Get a list of regions to hash */
941         count = fdt_find_regions(fit, node_inc.strings, node_inc.count,
942                         exc_prop, ARRAY_SIZE(exc_prop),
943                         fdt_regions, ARRAY_SIZE(fdt_regions),
944                         path, sizeof(path), 1);
945         if (count < 0) {
946                 printf("Failed to hash configuration '%s/%s': %s\n", conf_name,
947                        sig_name, fdt_strerror(ret));
948                 return -EIO;
949         }
950         if (count == 0) {
951                 printf("No data to hash for configuration '%s/%s': %s\n",
952                        conf_name, sig_name, fdt_strerror(ret));
953                 return -EINVAL;
954         }
955
956         /* Build our list of data blocks */
957         region = fit_region_make_list(fit, fdt_regions, count, NULL);
958         if (!region) {
959                 printf("Out of memory hashing configuration '%s/%s'\n",
960                        conf_name, sig_name);
961                 return -ENOMEM;
962         }
963
964         /* Create a list of all hashed properties */
965         debug("Hash nodes:\n");
966         for (i = len = 0; i < node_inc.count; i++) {
967                 debug("   %s\n", node_inc.strings[i]);
968                 len += strlen(node_inc.strings[i]) + 1;
969         }
970         region_prop = malloc(len);
971         if (!region_prop) {
972                 printf("Out of memory setting up regions for configuration '%s/%s'\n",
973                        conf_name, sig_name);
974                 return -ENOMEM;
975         }
976         for (i = len = 0; i < node_inc.count;
977              len += strlen(node_inc.strings[i]) + 1, i++)
978                 strcpy(region_prop + len, node_inc.strings[i]);
979         strlist_free(&node_inc);
980
981         *region_countp = count;
982         *regionp = region;
983         *region_propp = region_prop;
984         *region_proplen = len;
985
986         return 0;
987 }
988
989 /**
990  * fit_config_process_sig - Process a single subnode of the configurations/ node
991  *
992  * Generate a signed hash of the supplied data and store it in the node.
993  *
994  * @keydir:     Directory containing keys to use for signing
995  * @keydest:    Destination FDT blob to write public keys into (NULL if none)
996  * @fit:        pointer to the FIT format image header
997  * @conf_name   name of config being processed (used to display errors)
998  * @conf_noffset: Offset of configuration node, e.g. '/configurations/conf-1'
999  * @noffset:    subnode offset, e.g. '/configurations/conf-1/sig-1'
1000  * @comment:    Comment to add to signature nodes
1001  * @require_keys: Mark all keys as 'required'
1002  * @engine_id:  Engine to use for signing
1003  * @cmdname:    Command name used when reporting errors
1004  * @return keydest node if @keydest is non-NULL, else 0 if none; -ve error code
1005  *      on failure
1006  */
1007 static int fit_config_process_sig(const char *keydir, const char *keyfile,
1008                 void *keydest, void *fit, const char *conf_name,
1009                 int conf_noffset, int noffset, const char *comment,
1010                 int require_keys, const char *engine_id, const char *cmdname,
1011                 const char *algo_name)
1012 {
1013         struct image_sign_info info;
1014         const char *node_name;
1015         struct image_region *region;
1016         char *region_prop;
1017         int region_proplen;
1018         int region_count;
1019         uint8_t *value;
1020         uint value_len;
1021         int ret;
1022
1023         node_name = fit_get_name(fit, noffset, NULL);
1024         if (fit_config_get_regions(fit, conf_noffset, noffset, &region,
1025                                    &region_count, &region_prop,
1026                                    &region_proplen))
1027                 return -1;
1028
1029         if (fit_image_setup_sig(&info, keydir, keyfile, fit, conf_name, noffset,
1030                                 require_keys ? "conf" : NULL, engine_id,
1031                                 algo_name))
1032                 return -1;
1033
1034         ret = info.crypto->sign(&info, region, region_count, &value,
1035                                 &value_len);
1036         free(region);
1037         if (ret) {
1038                 printf("Failed to sign '%s' signature node in '%s' conf node\n",
1039                        node_name, conf_name);
1040
1041                 /* We allow keys to be missing */
1042                 if (ret == -ENOENT)
1043                         return 0;
1044                 return -1;
1045         }
1046
1047         ret = fit_image_write_sig(fit, noffset, value, value_len, comment,
1048                                   region_prop, region_proplen, cmdname,
1049                                   algo_name);
1050         if (ret) {
1051                 if (ret == -FDT_ERR_NOSPACE)
1052                         return -ENOSPC;
1053                 printf("Can't write signature for '%s' signature node in '%s' conf node: %s\n",
1054                        node_name, conf_name, fdt_strerror(ret));
1055                 return -1;
1056         }
1057         free(value);
1058         free(region_prop);
1059
1060         /* Get keyname again, as FDT has changed and invalidated our pointer */
1061         info.keyname = fdt_getprop(fit, noffset, FIT_KEY_HINT, NULL);
1062
1063         /* Write the public key into the supplied FDT file */
1064         if (keydest) {
1065                 ret = info.crypto->add_verify_data(&info, keydest);
1066                 if (ret < 0) {
1067                         printf("Failed to add verification data for '%s' signature node in '%s' configuration node\n",
1068                                node_name, conf_name);
1069                 }
1070                 return ret;
1071         }
1072
1073         return 0;
1074 }
1075
1076 static int fit_config_add_verification_data(const char *keydir,
1077                 const char *keyfile, void *keydest, void *fit, int conf_noffset,
1078                 const char *comment, int require_keys, const char *engine_id,
1079                 const char *cmdname, const char *algo_name,
1080                 struct image_summary *summary)
1081 {
1082         const char *conf_name;
1083         int noffset;
1084
1085         conf_name = fit_get_name(fit, conf_noffset, NULL);
1086
1087         /* Process all hash subnodes of the configuration node */
1088         for (noffset = fdt_first_subnode(fit, conf_noffset);
1089              noffset >= 0;
1090              noffset = fdt_next_subnode(fit, noffset)) {
1091                 const char *node_name;
1092                 int ret = 0;
1093
1094                 node_name = fit_get_name(fit, noffset, NULL);
1095                 if (!strncmp(node_name, FIT_SIG_NODENAME,
1096                              strlen(FIT_SIG_NODENAME))) {
1097                         ret = fit_config_process_sig(keydir, keyfile, keydest,
1098                                 fit, conf_name, conf_noffset, noffset, comment,
1099                                 require_keys, engine_id, cmdname, algo_name);
1100                         if (ret < 0)
1101                                 return ret;
1102
1103                         summary->sig_offset = noffset;
1104                         fdt_get_path(fit, noffset, summary->sig_path,
1105                                      sizeof(summary->sig_path));
1106
1107                         if (keydest) {
1108                                 summary->keydest_offset = ret;
1109                                 fdt_get_path(keydest, ret,
1110                                              summary->keydest_path,
1111                                              sizeof(summary->keydest_path));
1112                         }
1113                 }
1114         }
1115
1116         return 0;
1117 }
1118
1119 /*
1120  * 0) open file (open)
1121  * 1) read certificate (PEM_read_X509)
1122  * 2) get public key (X509_get_pubkey)
1123  * 3) provide der format (d2i_RSAPublicKey)
1124  */
1125 static int read_pub_key(const char *keydir, const void *name,
1126                         unsigned char **pubkey, int *pubkey_len)
1127 {
1128         char path[1024];
1129         EVP_PKEY *key = NULL;
1130         X509 *cert;
1131         FILE *f;
1132         int ret;
1133
1134         memset(path, 0, 1024);
1135         snprintf(path, sizeof(path), "%s/%s.crt", keydir, (char *)name);
1136
1137         /* Open certificate file */
1138         f = fopen(path, "r");
1139         if (!f) {
1140                 fprintf(stderr, "Couldn't open RSA certificate: '%s': %s\n",
1141                         path, strerror(errno));
1142                 return -EACCES;
1143         }
1144
1145         /* Read the certificate */
1146         cert = NULL;
1147         if (!PEM_read_X509(f, &cert, NULL, NULL)) {
1148                 printf("Couldn't read certificate");
1149                 ret = -EINVAL;
1150                 goto err_cert;
1151         }
1152
1153         /* Get the public key from the certificate. */
1154         key = X509_get_pubkey(cert);
1155         if (!key) {
1156                 printf("Couldn't read public key\n");
1157                 ret = -EINVAL;
1158                 goto err_pubkey;
1159         }
1160
1161         /* Get DER form */
1162         ret = i2d_PublicKey(key, pubkey);
1163         if (ret < 0) {
1164                 printf("Couldn't get DER form\n");
1165                 ret = -EINVAL;
1166                 goto err_pubkey;
1167         }
1168
1169         *pubkey_len = ret;
1170         ret = 0;
1171
1172 err_pubkey:
1173         X509_free(cert);
1174 err_cert:
1175         fclose(f);
1176         return ret;
1177 }
1178
1179 int fit_pre_load_data(const char *keydir, void *keydest, void *fit)
1180 {
1181         int pre_load_noffset;
1182         const void *algo_name;
1183         const void *key_name;
1184         unsigned char *pubkey = NULL;
1185         int ret, pubkey_len;
1186
1187         if (!keydir || !keydest || !fit)
1188                 return 0;
1189
1190         /* Search node pre-load sig */
1191         pre_load_noffset = fdt_path_offset(keydest, IMAGE_PRE_LOAD_PATH);
1192         if (pre_load_noffset < 0) {
1193                 ret = 0;
1194                 goto out;
1195         }
1196
1197         algo_name = fdt_getprop(keydest, pre_load_noffset, "algo-name", NULL);
1198         key_name  = fdt_getprop(keydest, pre_load_noffset, "key-name", NULL);
1199
1200         /* Check that all mandatory properties are present */
1201         if (!algo_name || !key_name) {
1202                 if (!algo_name)
1203                         printf("The property algo-name is missing in the node %s\n",
1204                                IMAGE_PRE_LOAD_PATH);
1205                 if (!key_name)
1206                         printf("The property key-name is missing in the node %s\n",
1207                                IMAGE_PRE_LOAD_PATH);
1208                 ret = -EINVAL;
1209                 goto out;
1210         }
1211
1212         /* Read public key */
1213         ret = read_pub_key(keydir, key_name, &pubkey, &pubkey_len);
1214         if (ret < 0)
1215                 goto out;
1216
1217         /* Add the public key to the device tree */
1218         ret = fdt_setprop(keydest, pre_load_noffset, "public-key",
1219                           pubkey, pubkey_len);
1220         if (ret)
1221                 printf("Can't set public-key in node %s (ret = %d)\n",
1222                        IMAGE_PRE_LOAD_PATH, ret);
1223
1224  out:
1225         return ret;
1226 }
1227
1228 int fit_cipher_data(const char *keydir, void *keydest, void *fit,
1229                     const char *comment, int require_keys,
1230                     const char *engine_id, const char *cmdname)
1231 {
1232         int images_noffset;
1233         int noffset;
1234         int ret;
1235
1236         /* Find images parent node offset */
1237         images_noffset = fdt_path_offset(fit, FIT_IMAGES_PATH);
1238         if (images_noffset < 0) {
1239                 printf("Can't find images parent node '%s' (%s)\n",
1240                        FIT_IMAGES_PATH, fdt_strerror(images_noffset));
1241                 return images_noffset;
1242         }
1243
1244         /* Process its subnodes, print out component images details */
1245         for (noffset = fdt_first_subnode(fit, images_noffset);
1246              noffset >= 0;
1247              noffset = fdt_next_subnode(fit, noffset)) {
1248                 /*
1249                  * Direct child node of the images parent node,
1250                  * i.e. component image node.
1251                  */
1252                 ret = fit_image_cipher_data(keydir, keydest,
1253                                             fit, noffset, comment,
1254                                             require_keys, engine_id,
1255                                             cmdname);
1256                 if (ret)
1257                         return ret;
1258         }
1259
1260         return 0;
1261 }
1262
1263 int fit_add_verification_data(const char *keydir, const char *keyfile,
1264                               void *keydest, void *fit, const char *comment,
1265                               int require_keys, const char *engine_id,
1266                               const char *cmdname, const char *algo_name,
1267                               struct image_summary *summary)
1268 {
1269         int images_noffset, confs_noffset;
1270         int noffset;
1271         int ret;
1272
1273         /* Find images parent node offset */
1274         images_noffset = fdt_path_offset(fit, FIT_IMAGES_PATH);
1275         if (images_noffset < 0) {
1276                 printf("Can't find images parent node '%s' (%s)\n",
1277                        FIT_IMAGES_PATH, fdt_strerror(images_noffset));
1278                 return images_noffset;
1279         }
1280
1281         /* Process its subnodes, print out component images details */
1282         for (noffset = fdt_first_subnode(fit, images_noffset);
1283              noffset >= 0;
1284              noffset = fdt_next_subnode(fit, noffset)) {
1285                 /*
1286                  * Direct child node of the images parent node,
1287                  * i.e. component image node.
1288                  */
1289                 ret = fit_image_add_verification_data(keydir, keyfile, keydest,
1290                                 fit, noffset, comment, require_keys, engine_id,
1291                                 cmdname, algo_name);
1292                 if (ret)
1293                         return ret;
1294         }
1295
1296         /* If there are no keys, we can't sign configurations */
1297         if (!IMAGE_ENABLE_SIGN || !(keydir || keyfile))
1298                 return 0;
1299
1300         /* Find configurations parent node offset */
1301         confs_noffset = fdt_path_offset(fit, FIT_CONFS_PATH);
1302         if (confs_noffset < 0) {
1303                 printf("Can't find images parent node '%s' (%s)\n",
1304                        FIT_CONFS_PATH, fdt_strerror(confs_noffset));
1305                 return -ENOENT;
1306         }
1307
1308         /* Process its subnodes, print out component images details */
1309         for (noffset = fdt_first_subnode(fit, confs_noffset);
1310              noffset >= 0;
1311              noffset = fdt_next_subnode(fit, noffset)) {
1312                 ret = fit_config_add_verification_data(keydir, keyfile, keydest,
1313                                                        fit, noffset, comment,
1314                                                        require_keys,
1315                                                        engine_id, cmdname,
1316                                                        algo_name, summary);
1317                 if (ret)
1318                         return ret;
1319         }
1320
1321         return 0;
1322 }
1323
1324 #ifdef CONFIG_FIT_SIGNATURE
1325 int fit_check_sign(const void *fit, const void *key,
1326                    const char *fit_uname_config)
1327 {
1328         int cfg_noffset;
1329         int ret;
1330
1331         cfg_noffset = fit_conf_get_node(fit, fit_uname_config);
1332         if (!cfg_noffset)
1333                 return -1;
1334
1335         printf("Verifying Hash Integrity for node '%s'... ",
1336                fdt_get_name(fit, cfg_noffset, NULL));
1337         ret = fit_config_verify(fit, cfg_noffset);
1338         if (ret)
1339                 return ret;
1340         printf("Verified OK, loading images\n");
1341         ret = bootm_host_load_images(fit, cfg_noffset);
1342
1343         return ret;
1344 }
1345 #endif