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