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