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 (fit_image_hash_get_algo(fit, noffset, &algo_name)) { 160 *err_msgp = "Can't get hash algo property"; 161 return -1; 162 } 163 memset(info, '\0', sizeof(*info)); 164 info->keyname = fdt_getprop(fit, noffset, "key-name-hint", NULL); 165 info->fit = (void *)fit; 166 info->node_offset = noffset; 167 info->name = algo_name; 168 info->checksum = image_get_checksum_algo(algo_name); 169 info->crypto = image_get_crypto_algo(algo_name); 170 info->fdt_blob = gd_fdt_blob(); 171 info->required_keynode = required_keynode; 172 printf("%s:%s", algo_name, info->keyname); 173 174 if (!info->checksum || !info->crypto) { 175 *err_msgp = "Unknown signature algorithm"; 176 return -1; 177 } 178 179 return 0; 180 } 181 182 int fit_image_check_sig(const void *fit, int noffset, const void *data, 183 size_t size, int required_keynode, char **err_msgp) 184 { 185 struct image_sign_info info; 186 struct image_region region; 187 uint8_t *fit_value; 188 int fit_value_len; 189 190 *err_msgp = NULL; 191 if (fit_image_setup_verify(&info, fit, noffset, required_keynode, 192 err_msgp)) 193 return -1; 194 195 if (fit_image_hash_get_value(fit, noffset, &fit_value, 196 &fit_value_len)) { 197 *err_msgp = "Can't get hash value property"; 198 return -1; 199 } 200 201 region.data = data; 202 region.size = size; 203 204 if (info.crypto->verify(&info, ®ion, 1, fit_value, fit_value_len)) { 205 *err_msgp = "Verification failed"; 206 return -1; 207 } 208 209 return 0; 210 } 211 212 static int fit_image_verify_sig(const void *fit, int image_noffset, 213 const char *data, size_t size, const void *sig_blob, 214 int sig_offset) 215 { 216 int noffset; 217 char *err_msg = ""; 218 int verified = 0; 219 int ret; 220 221 /* Process all hash subnodes of the component image node */ 222 fdt_for_each_subnode(noffset, fit, image_noffset) { 223 const char *name = fit_get_name(fit, noffset, NULL); 224 225 if (!strncmp(name, FIT_SIG_NODENAME, 226 strlen(FIT_SIG_NODENAME))) { 227 ret = fit_image_check_sig(fit, noffset, data, 228 size, -1, &err_msg); 229 if (ret) { 230 puts("- "); 231 } else { 232 puts("+ "); 233 verified = 1; 234 break; 235 } 236 } 237 } 238 239 if (noffset == -FDT_ERR_TRUNCATED || noffset == -FDT_ERR_BADSTRUCTURE) { 240 err_msg = "Corrupted or truncated tree"; 241 goto error; 242 } 243 244 return verified ? 0 : -EPERM; 245 246 error: 247 printf(" error!\n%s for '%s' hash node in '%s' image node\n", 248 err_msg, fit_get_name(fit, noffset, NULL), 249 fit_get_name(fit, image_noffset, NULL)); 250 return -1; 251 } 252 253 int fit_image_verify_required_sigs(const void *fit, int image_noffset, 254 const char *data, size_t size, const void *sig_blob, 255 int *no_sigsp) 256 { 257 int verify_count = 0; 258 int noffset; 259 int sig_node; 260 261 /* Work out what we need to verify */ 262 *no_sigsp = 1; 263 sig_node = fdt_subnode_offset(sig_blob, 0, FIT_SIG_NODENAME); 264 if (sig_node < 0) { 265 debug("%s: No signature node found: %s\n", __func__, 266 fdt_strerror(sig_node)); 267 return 0; 268 } 269 270 fdt_for_each_subnode(noffset, sig_blob, sig_node) { 271 const char *required; 272 int ret; 273 274 required = fdt_getprop(sig_blob, noffset, "required", NULL); 275 if (!required || strcmp(required, "image")) 276 continue; 277 ret = fit_image_verify_sig(fit, image_noffset, data, size, 278 sig_blob, noffset); 279 if (ret) { 280 printf("Failed to verify required signature '%s'\n", 281 fit_get_name(sig_blob, noffset, NULL)); 282 return ret; 283 } 284 verify_count++; 285 } 286 287 if (verify_count) 288 *no_sigsp = 0; 289 290 return 0; 291 } 292 293 int fit_config_check_sig(const void *fit, int noffset, int required_keynode, 294 char **err_msgp) 295 { 296 char * const exc_prop[] = {"data"}; 297 const char *prop, *end, *name; 298 struct image_sign_info info; 299 const uint32_t *strings; 300 uint8_t *fit_value; 301 int fit_value_len; 302 int max_regions; 303 int i, prop_len; 304 char path[200]; 305 int count; 306 307 debug("%s: fdt=%p, conf='%s', sig='%s'\n", __func__, gd_fdt_blob(), 308 fit_get_name(fit, noffset, NULL), 309 fit_get_name(gd_fdt_blob(), required_keynode, NULL)); 310 *err_msgp = NULL; 311 if (fit_image_setup_verify(&info, fit, noffset, required_keynode, 312 err_msgp)) 313 return -1; 314 315 if (fit_image_hash_get_value(fit, noffset, &fit_value, 316 &fit_value_len)) { 317 *err_msgp = "Can't get hash value property"; 318 return -1; 319 } 320 321 /* Count the number of strings in the property */ 322 prop = fdt_getprop(fit, noffset, "hashed-nodes", &prop_len); 323 end = prop ? prop + prop_len : prop; 324 for (name = prop, count = 0; name < end; name++) 325 if (!*name) 326 count++; 327 if (!count) { 328 *err_msgp = "Can't get hashed-nodes property"; 329 return -1; 330 } 331 332 /* Add a sanity check here since we are using the stack */ 333 if (count > IMAGE_MAX_HASHED_NODES) { 334 *err_msgp = "Number of hashed nodes exceeds maximum"; 335 return -1; 336 } 337 338 /* Create a list of node names from those strings */ 339 char *node_inc[count]; 340 341 debug("Hash nodes (%d):\n", count); 342 for (name = prop, i = 0; name < end; name += strlen(name) + 1, i++) { 343 debug(" '%s'\n", name); 344 node_inc[i] = (char *)name; 345 } 346 347 /* 348 * Each node can generate one region for each sub-node. Allow for 349 * 7 sub-nodes (hash-1, signature-1, etc.) and some extra. 350 */ 351 max_regions = 20 + count * 7; 352 struct fdt_region fdt_regions[max_regions]; 353 354 /* Get a list of regions to hash */ 355 count = fdt_find_regions(fit, node_inc, count, 356 exc_prop, ARRAY_SIZE(exc_prop), 357 fdt_regions, max_regions - 1, 358 path, sizeof(path), 0); 359 if (count < 0) { 360 *err_msgp = "Failed to hash configuration"; 361 return -1; 362 } 363 if (count == 0) { 364 *err_msgp = "No data to hash"; 365 return -1; 366 } 367 if (count >= max_regions - 1) { 368 *err_msgp = "Too many hash regions"; 369 return -1; 370 } 371 372 /* Add the strings */ 373 strings = fdt_getprop(fit, noffset, "hashed-strings", NULL); 374 if (strings) { 375 fdt_regions[count].offset = fdt_off_dt_strings(fit) + 376 fdt32_to_cpu(strings[0]); 377 fdt_regions[count].size = fdt32_to_cpu(strings[1]); 378 count++; 379 } 380 381 /* Allocate the region list on the stack */ 382 struct image_region region[count]; 383 384 fit_region_make_list(fit, fdt_regions, count, region); 385 if (info.crypto->verify(&info, region, count, fit_value, 386 fit_value_len)) { 387 *err_msgp = "Verification failed"; 388 return -1; 389 } 390 391 return 0; 392 } 393 394 static int fit_config_verify_sig(const void *fit, int conf_noffset, 395 const void *sig_blob, int sig_offset) 396 { 397 int noffset; 398 char *err_msg = ""; 399 int verified = 0; 400 int ret; 401 402 /* Process all hash subnodes of the component conf node */ 403 fdt_for_each_subnode(noffset, fit, conf_noffset) { 404 const char *name = fit_get_name(fit, noffset, NULL); 405 406 if (!strncmp(name, FIT_SIG_NODENAME, 407 strlen(FIT_SIG_NODENAME))) { 408 ret = fit_config_check_sig(fit, noffset, sig_offset, 409 &err_msg); 410 if (ret) { 411 puts("- "); 412 } else { 413 puts("+ "); 414 verified = 1; 415 break; 416 } 417 } 418 } 419 420 if (noffset == -FDT_ERR_TRUNCATED || noffset == -FDT_ERR_BADSTRUCTURE) { 421 err_msg = "Corrupted or truncated tree"; 422 goto error; 423 } 424 425 return verified ? 0 : -EPERM; 426 427 error: 428 printf(" error!\n%s for '%s' hash node in '%s' config node\n", 429 err_msg, fit_get_name(fit, noffset, NULL), 430 fit_get_name(fit, conf_noffset, NULL)); 431 return -1; 432 } 433 434 int fit_config_verify_required_sigs(const void *fit, int conf_noffset, 435 const void *sig_blob) 436 { 437 int noffset; 438 int sig_node; 439 440 /* Work out what we need to verify */ 441 sig_node = fdt_subnode_offset(sig_blob, 0, FIT_SIG_NODENAME); 442 if (sig_node < 0) { 443 debug("%s: No signature node found: %s\n", __func__, 444 fdt_strerror(sig_node)); 445 return 0; 446 } 447 448 fdt_for_each_subnode(noffset, sig_blob, sig_node) { 449 const char *required; 450 int ret; 451 452 required = fdt_getprop(sig_blob, noffset, "required", NULL); 453 if (!required || strcmp(required, "conf")) 454 continue; 455 ret = fit_config_verify_sig(fit, conf_noffset, sig_blob, 456 noffset); 457 if (ret) { 458 printf("Failed to verify required signature '%s'\n", 459 fit_get_name(sig_blob, noffset, NULL)); 460 return ret; 461 } 462 } 463 464 return 0; 465 } 466 467 int fit_config_verify(const void *fit, int conf_noffset) 468 { 469 return fit_config_verify_required_sigs(fit, conf_noffset, 470 gd_fdt_blob()); 471 } 472