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