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