xref: /OK3568_Linux_fs/u-boot/common/image-sig.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1 /*
2  * Copyright (c) 2013, Google Inc.
3  *
4  * SPDX-License-Identifier:	GPL-2.0+
5  */
6 
7 #ifdef USE_HOSTCC
8 #include "mkimage.h"
9 #include <time.h>
10 #else
11 #include <common.h>
12 #include <malloc.h>
13 #include <optee_include/OpteeClientInterface.h>
14 DECLARE_GLOBAL_DATA_PTR;
15 #endif /* !USE_HOSTCC*/
16 #include <image.h>
17 #include <u-boot/rsa.h>
18 #include <u-boot/rsa-checksum.h>
19 
20 #define IMAGE_MAX_HASHED_NODES		100
21 
22 #ifdef USE_HOSTCC
23 void *host_blob;
image_set_host_blob(void * blob)24 void image_set_host_blob(void *blob)
25 {
26 	host_blob = blob;
27 }
image_get_host_blob(void)28 void *image_get_host_blob(void)
29 {
30 	return host_blob;
31 }
32 #endif
33 
34 static const uint8_t sha1_der_prefix_data[SHA1_DER_LEN] = {
35 	0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e,
36 	0x03, 0x02, 0x1a, 0x05, 0x00, 0x04, 0x14
37 };
38 
39 static const uint8_t sha256_der_prefix_data[SHA256_DER_LEN] = {
40 	0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86,
41 	0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05,
42 	0x00, 0x04, 0x20
43 };
44 
45 struct checksum_algo checksum_algos[] = {
46 	{
47 		.name = "sha1",
48 		.checksum_len = SHA1_SUM_LEN,
49 		.der_len = SHA1_DER_LEN,
50 		.der_prefix = sha1_der_prefix_data,
51 #if IMAGE_ENABLE_SIGN
52 		.calculate_sign = EVP_sha1,
53 #endif
54 		.calculate = hash_calculate,
55 	},
56 	{
57 		.name = "sha256",
58 		.checksum_len = SHA256_SUM_LEN,
59 		.der_len = SHA256_DER_LEN,
60 		.der_prefix = sha256_der_prefix_data,
61 #if IMAGE_ENABLE_SIGN
62 		.calculate_sign = EVP_sha256,
63 #endif
64 		.calculate = hash_calculate,
65 	}
66 
67 };
68 
69 struct crypto_algo crypto_algos[] = {
70 	{
71 		.name = "rsa2048",
72 		.key_len = RSA2048_BYTES,
73 		.sign = rsa_sign,
74 		.add_verify_data = rsa_add_verify_data,
75 		.verify = rsa_verify,
76 	},
77 	{
78 		.name = "rsa4096",
79 		.key_len = RSA4096_BYTES,
80 		.sign = rsa_sign,
81 		.add_verify_data = rsa_add_verify_data,
82 		.verify = rsa_verify,
83 	}
84 
85 };
86 
87 struct padding_algo padding_algos[] = {
88 	{
89 		.name = "pkcs-1.5",
90 		.verify = padding_pkcs_15_verify,
91 	},
92 #ifdef CONFIG_FIT_ENABLE_RSASSA_PSS_SUPPORT
93 	{
94 		.name = "pss",
95 		.verify = padding_pss_verify,
96 	}
97 #endif /* CONFIG_FIT_ENABLE_RSASSA_PSS_SUPPORT */
98 };
99 
image_get_checksum_algo(const char * full_name)100 struct checksum_algo *image_get_checksum_algo(const char *full_name)
101 {
102 	int i;
103 	const char *name;
104 
105 	for (i = 0; i < ARRAY_SIZE(checksum_algos); i++) {
106 		name = checksum_algos[i].name;
107 		/* Make sure names match and next char is a comma */
108 		if (!strncmp(name, full_name, strlen(name)) &&
109 		    full_name[strlen(name)] == ',')
110 			return &checksum_algos[i];
111 	}
112 
113 	return NULL;
114 }
115 
image_get_crypto_algo(const char * full_name)116 struct crypto_algo *image_get_crypto_algo(const char *full_name)
117 {
118 	int i;
119 	const char *name;
120 
121 	/* Move name to after the comma */
122 	name = strchr(full_name, ',');
123 	if (!name)
124 		return NULL;
125 	name += 1;
126 
127 	for (i = 0; i < ARRAY_SIZE(crypto_algos); i++) {
128 		if (!strcmp(crypto_algos[i].name, name))
129 			return &crypto_algos[i];
130 	}
131 
132 	return NULL;
133 }
134 
image_get_padding_algo(const char * name)135 struct padding_algo *image_get_padding_algo(const char *name)
136 {
137 	int i;
138 
139 	if (!name)
140 		return NULL;
141 
142 	for (i = 0; i < ARRAY_SIZE(padding_algos); i++) {
143 		if (!strcmp(padding_algos[i].name, name))
144 			return &padding_algos[i];
145 	}
146 
147 	return NULL;
148 }
149 
150 /**
151  * fit_region_make_list() - Make a list of image regions
152  *
153  * Given a list of fdt_regions, create a list of image_regions. This is a
154  * simple conversion routine since the FDT and image code use different
155  * structures.
156  *
157  * @fit: FIT image
158  * @fdt_regions: Pointer to FDT regions
159  * @count: Number of FDT regions
160  * @region: Pointer to image regions, which must hold @count records. If
161  * region is NULL, then (except for an SPL build) the array will be
162  * allocated.
163  * @return: Pointer to image regions
164  */
fit_region_make_list(const void * fit,struct fdt_region * fdt_regions,int count,struct image_region * region)165 struct image_region *fit_region_make_list(const void *fit,
166 		struct fdt_region *fdt_regions, int count,
167 		struct image_region *region)
168 {
169 	int i;
170 
171 	debug("Hash regions:\n");
172 	debug("%10s %10s\n", "Offset", "Size");
173 
174 	/*
175 	 * Use malloc() except in SPL (to save code size). In SPL the caller
176 	 * must allocate the array.
177 	 */
178 #ifndef CONFIG_SPL_BUILD
179 	if (!region)
180 		region = calloc(sizeof(*region), count);
181 #endif
182 	if (!region)
183 		return NULL;
184 	for (i = 0; i < count; i++) {
185 		debug("%10x %10x\n", fdt_regions[i].offset,
186 		      fdt_regions[i].size);
187 		region[i].data = fit + fdt_regions[i].offset;
188 		region[i].size = fdt_regions[i].size;
189 	}
190 
191 	return region;
192 }
193 
fit_image_setup_verify(struct image_sign_info * info,const void * fit,int noffset,int required_keynode,char ** err_msgp)194 static int fit_image_setup_verify(struct image_sign_info *info,
195 		const void *fit, int noffset, int required_keynode,
196 		char **err_msgp)
197 {
198 	char *algo_name;
199 	const char *padding_name;
200 
201 	if (fit_image_hash_get_algo(fit, noffset, &algo_name)) {
202 		*err_msgp = "Can't get hash algo property";
203 		return -1;
204 	}
205 
206 	padding_name = fdt_getprop(fit, noffset, "padding", NULL);
207 	if (!padding_name)
208 		padding_name = RSA_DEFAULT_PADDING_NAME;
209 
210 	memset(info, '\0', sizeof(*info));
211 	info->keyname = fdt_getprop(fit, noffset, "key-name-hint", NULL);
212 	info->fit = (void *)fit;
213 	info->node_offset = noffset;
214 	info->name = algo_name;
215 	info->checksum = image_get_checksum_algo(algo_name);
216 	info->crypto = image_get_crypto_algo(algo_name);
217 	info->padding = image_get_padding_algo(padding_name);
218 	info->fdt_blob = gd_fdt_blob();
219 	info->required_keynode = required_keynode;
220 	printf("%s:%s", algo_name, info->keyname);
221 
222 	if (!info->checksum || !info->crypto) {
223 		*err_msgp = "Unknown signature algorithm";
224 		return -1;
225 	}
226 
227 	return 0;
228 }
229 
fit_image_check_sig(const void * fit,int noffset,const void * data,size_t size,int required_keynode,char ** err_msgp)230 int fit_image_check_sig(const void *fit, int noffset, const void *data,
231 		size_t size, int required_keynode, char **err_msgp)
232 {
233 	struct image_sign_info info;
234 	struct image_region region;
235 	uint8_t *fit_value;
236 	int fit_value_len;
237 
238 	*err_msgp = NULL;
239 	if (fit_image_setup_verify(&info, fit, noffset, required_keynode,
240 				   err_msgp))
241 		return -1;
242 
243 	if (fit_image_hash_get_value(fit, noffset, &fit_value,
244 				     &fit_value_len)) {
245 		*err_msgp = "Can't get hash value property";
246 		return -1;
247 	}
248 
249 	region.data = data;
250 	region.size = size;
251 
252 	if (info.crypto->verify(&info, &region, 1, fit_value, fit_value_len)) {
253 		*err_msgp = "Verification failed";
254 		return -1;
255 	}
256 
257 	return 0;
258 }
259 
fit_image_verify_sig(const void * fit,int image_noffset,const char * data,size_t size,const void * sig_blob,int sig_offset)260 static int fit_image_verify_sig(const void *fit, int image_noffset,
261 		const char *data, size_t size, const void *sig_blob,
262 		int sig_offset)
263 {
264 	int noffset;
265 	char *err_msg = "";
266 	int verified = 0;
267 	int ret;
268 
269 	/* Process all hash subnodes of the component image node */
270 	fdt_for_each_subnode(noffset, fit, image_noffset) {
271 		const char *name = fit_get_name(fit, noffset, NULL);
272 
273 		if (!strncmp(name, FIT_SIG_NODENAME,
274 			     strlen(FIT_SIG_NODENAME))) {
275 			ret = fit_image_check_sig(fit, noffset, data,
276 							size, -1, &err_msg);
277 			if (ret) {
278 				puts("- ");
279 			} else {
280 				puts("+ ");
281 				verified = 1;
282 				break;
283 			}
284 		}
285 	}
286 
287 	if (noffset == -FDT_ERR_TRUNCATED || noffset == -FDT_ERR_BADSTRUCTURE) {
288 		err_msg = "Corrupted or truncated tree";
289 		goto error;
290 	}
291 
292 	if (verified)
293 		return 0;
294 
295 error:
296 	printf(" error!\n%s for '%s' hash node in '%s' image node\n",
297 	       err_msg, fit_get_name(fit, noffset, NULL),
298 	       fit_get_name(fit, image_noffset, NULL));
299 	return -1;
300 }
301 
fit_image_verify_required_sigs(const void * fit,int image_noffset,const char * data,size_t size,const void * sig_blob,int * no_sigsp)302 int fit_image_verify_required_sigs(const void *fit, int image_noffset,
303 		const char *data, size_t size, const void *sig_blob,
304 		int *no_sigsp)
305 {
306 	int verify_count = 0;
307 	int noffset;
308 	int sig_node;
309 
310 	/* Work out what we need to verify */
311 	*no_sigsp = 1;
312 	sig_node = fdt_subnode_offset(sig_blob, 0, FIT_SIG_NODENAME);
313 	if (sig_node < 0) {
314 		printf("No RSA key found\n");
315 		return -EINVAL;
316 	}
317 
318 	fdt_for_each_subnode(noffset, sig_blob, sig_node) {
319 		const char *required;
320 		int ret;
321 
322 		required = fdt_getprop(sig_blob, noffset, "required", NULL);
323 		if (!required || strcmp(required, "image"))
324 			continue;
325 		ret = fit_image_verify_sig(fit, image_noffset, data, size,
326 					sig_blob, noffset);
327 		if (ret) {
328 			printf("Failed to verify required signature '%s'\n",
329 			       fit_get_name(sig_blob, noffset, NULL));
330 			return ret;
331 		}
332 		verify_count++;
333 	}
334 
335 	if (verify_count)
336 		*no_sigsp = 0;
337 
338 	return 0;
339 }
340 
fit_config_check_sig(const void * fit,int noffset,int required_keynode,char ** err_msgp)341 int fit_config_check_sig(const void *fit, int noffset, int required_keynode,
342 			 char **err_msgp)
343 {
344 	char * const exc_prop[] = {"data"};
345 	const char *prop, *end, *name;
346 	struct image_sign_info info;
347 	const uint32_t *strings;
348 	uint8_t *fit_value;
349 	int fit_value_len;
350 	int max_regions;
351 	int i, prop_len;
352 	char path[200];
353 	int count;
354 
355 	debug("%s: fdt=%p, conf='%s', sig='%s'\n", __func__, gd_fdt_blob(),
356 	      fit_get_name(fit, noffset, NULL),
357 	      fit_get_name(gd_fdt_blob(), required_keynode, NULL));
358 	*err_msgp = NULL;
359 	if (fit_image_setup_verify(&info, fit, noffset, required_keynode,
360 				   err_msgp))
361 		return -1;
362 
363 	if (fit_image_hash_get_value(fit, noffset, &fit_value,
364 				     &fit_value_len)) {
365 		*err_msgp = "Can't get hash value property";
366 		return -1;
367 	}
368 
369 	/* Count the number of strings in the property */
370 	prop = fdt_getprop(fit, noffset, "hashed-nodes", &prop_len);
371 	end = prop ? prop + prop_len : prop;
372 	for (name = prop, count = 0; name < end; name++)
373 		if (!*name)
374 			count++;
375 	if (!count) {
376 		*err_msgp = "Can't get hashed-nodes property";
377 		return -1;
378 	}
379 
380 	/* Add a sanity check here since we are using the stack */
381 	if (count > IMAGE_MAX_HASHED_NODES) {
382 		*err_msgp = "Number of hashed nodes exceeds maximum";
383 		return -1;
384 	}
385 
386 	/* Create a list of node names from those strings */
387 	char *node_inc[count];
388 
389 	debug("Hash nodes (%d):\n", count);
390 	for (name = prop, i = 0; name < end; name += strlen(name) + 1, i++) {
391 		debug("   '%s'\n", name);
392 		node_inc[i] = (char *)name;
393 	}
394 
395 	/*
396 	 * Each node can generate one region for each sub-node. Allow for
397 	 * 7 sub-nodes (hash@1, signature@1, etc.) and some extra.
398 	 */
399 	max_regions = 20 + count * 7;
400 	struct fdt_region fdt_regions[max_regions];
401 
402 	/* Get a list of regions to hash */
403 	count = fdt_find_regions(fit, node_inc, count,
404 			exc_prop, ARRAY_SIZE(exc_prop),
405 			fdt_regions, max_regions - 1,
406 			path, sizeof(path), 0);
407 	if (count < 0) {
408 		*err_msgp = "Failed to hash configuration";
409 		return -1;
410 	}
411 	if (count == 0) {
412 		*err_msgp = "No data to hash";
413 		return -1;
414 	}
415 	if (count >= max_regions - 1) {
416 		*err_msgp = "Too many hash regions";
417 		return -1;
418 	}
419 
420 	/* Add the strings */
421 	strings = fdt_getprop(fit, noffset, "hashed-strings", NULL);
422 	if (strings) {
423 		fdt_regions[count].offset = fdt_off_dt_strings(fit) +
424 				fdt32_to_cpu(strings[0]);
425 		fdt_regions[count].size = fdt32_to_cpu(strings[1]);
426 		count++;
427 	}
428 
429 	/* Allocate the region list on the stack */
430 	struct image_region region[count];
431 
432 	fit_region_make_list(fit, fdt_regions, count, region);
433 	if (info.crypto->verify(&info, region, count, fit_value,
434 				fit_value_len)) {
435 		*err_msgp = "Verification failed";
436 		return -1;
437 	}
438 	/* Get the secure flag here and write the secure data and the secure flag */
439 #if !defined(USE_HOSTCC)
440 #if defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_FIT_HW_CRYPTO) && \
441     defined(CONFIG_SPL_ROCKCHIP_SECURE_OTP)
442 	rsa_burn_key_hash(&info);
443 #endif
444 #endif
445 
446 	return 0;
447 }
448 
fit_config_verify_sig(const void * fit,int conf_noffset,const void * sig_blob,int sig_offset)449 static int fit_config_verify_sig(const void *fit, int conf_noffset,
450 		const void *sig_blob, int sig_offset)
451 {
452 	int noffset;
453 	char *err_msg = "";
454 	int verified = 0;
455 	int ret;
456 
457 	/* Process all hash subnodes of the component conf node */
458 	fdt_for_each_subnode(noffset, fit, conf_noffset) {
459 		const char *name = fit_get_name(fit, noffset, NULL);
460 
461 		if (!strncmp(name, FIT_SIG_NODENAME,
462 			     strlen(FIT_SIG_NODENAME))) {
463 			ret = fit_config_check_sig(fit, noffset, sig_offset,
464 						   &err_msg);
465 			if (ret) {
466 				puts("- ");
467 			} else {
468 				puts("+ ");
469 				verified = 1;
470 				break;
471 			}
472 		}
473 	}
474 
475 	if (noffset == -FDT_ERR_TRUNCATED || noffset == -FDT_ERR_BADSTRUCTURE) {
476 		err_msg = "Corrupted or truncated tree";
477 		goto error;
478 	}
479 
480 	if (verified)
481 		return 0;
482 
483 error:
484 	printf(" error!\n%s for '%s' hash node in '%s' config node\n",
485 	       err_msg, fit_get_name(fit, noffset, NULL),
486 	       fit_get_name(fit, conf_noffset, NULL));
487 	return -1;
488 }
489 
fit_config_verify_required_sigs(const void * fit,int conf_noffset,const void * sig_blob)490 int fit_config_verify_required_sigs(const void *fit, int conf_noffset,
491 		const void *sig_blob)
492 {
493 	int noffset;
494 	int sig_node;
495 
496 	/* Work out what we need to verify */
497 	sig_node = fdt_subnode_offset(sig_blob, 0, FIT_SIG_NODENAME);
498 	if (sig_node < 0) {
499 		printf("No RSA key found\n");
500 		return -EINVAL;
501 	}
502 
503 	fdt_for_each_subnode(noffset, sig_blob, sig_node) {
504 		const char *required;
505 		int ret;
506 
507 		required = fdt_getprop(sig_blob, noffset, "required", NULL);
508 		if (!required || strcmp(required, "conf"))
509 			continue;
510 		ret = fit_config_verify_sig(fit, conf_noffset, sig_blob,
511 					    noffset);
512 		if (ret) {
513 			printf("Failed to verify required signature '%s'\n",
514 			       fit_get_name(sig_blob, noffset, NULL));
515 			return ret;
516 		}
517 	}
518 
519 	return 0;
520 }
521 
fit_config_verify(const void * fit,int conf_noffset)522 int fit_config_verify(const void *fit, int conf_noffset)
523 {
524 	return fit_config_verify_required_sigs(fit, conf_noffset,
525 					       gd_fdt_blob());
526 }
527 
528 #ifndef USE_HOSTCC
529 #if CONFIG_IS_ENABLED(FIT_ROLLBACK_PROTECT)
fit_read_otp_rollback_index(uint32_t fit_index,uint32_t * otp_index)530 __weak int fit_read_otp_rollback_index(uint32_t fit_index, uint32_t *otp_index)
531 {
532 	*otp_index = 0;
533 
534 	return 0;
535 }
fit_rollback_index_verify(const void * fit,uint32_t rollback_fd,uint32_t * this_index,uint32_t * min_index)536 __weak int fit_rollback_index_verify(const void *fit, uint32_t rollback_fd,
537 				     uint32_t *this_index, uint32_t *min_index)
538 {
539 	*this_index = 0;
540 	*min_index = 0;
541 
542 	return 0;
543 }
544 #endif
545 #endif
546