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