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