1 /* 2 * Copyright (c) 2013, Google Inc. 3 * 4 * SPDX-License-Identifier: GPL-2.0+ 5 */ 6 7 #ifdef USE_HOSTCC 8 #include "mkimage.h" 9 #include <time.h> 10 #else 11 #include <common.h> 12 #include <malloc.h> 13 DECLARE_GLOBAL_DATA_PTR; 14 #endif /* !USE_HOSTCC*/ 15 #include <image.h> 16 #include <rsa.h> 17 #include <rsa-checksum.h> 18 19 #define IMAGE_MAX_HASHED_NODES 100 20 21 #ifdef USE_HOSTCC 22 __attribute__((weak)) void *get_blob(void) 23 { 24 return NULL; 25 } 26 #endif 27 28 struct checksum_algo checksum_algos[] = { 29 { 30 "sha1", 31 SHA1_SUM_LEN, 32 #if IMAGE_ENABLE_SIGN 33 EVP_sha1, 34 #else 35 sha1_calculate, 36 padding_sha1_rsa2048, 37 #endif 38 }, 39 { 40 "sha256", 41 SHA256_SUM_LEN, 42 #if IMAGE_ENABLE_SIGN 43 EVP_sha256, 44 #else 45 sha256_calculate, 46 padding_sha256_rsa2048, 47 #endif 48 } 49 }; 50 struct image_sig_algo image_sig_algos[] = { 51 { 52 "sha1,rsa2048", 53 rsa_sign, 54 rsa_add_verify_data, 55 rsa_verify, 56 &checksum_algos[0], 57 }, 58 { 59 "sha256,rsa2048", 60 rsa_sign, 61 rsa_add_verify_data, 62 rsa_verify, 63 &checksum_algos[1], 64 } 65 }; 66 67 struct image_sig_algo *image_get_sig_algo(const char *name) 68 { 69 int i; 70 71 for (i = 0; i < ARRAY_SIZE(image_sig_algos); i++) { 72 if (!strcmp(image_sig_algos[i].name, name)) 73 return &image_sig_algos[i]; 74 } 75 76 return NULL; 77 } 78 79 /** 80 * fit_region_make_list() - Make a list of image regions 81 * 82 * Given a list of fdt_regions, create a list of image_regions. This is a 83 * simple conversion routine since the FDT and image code use different 84 * structures. 85 * 86 * @fit: FIT image 87 * @fdt_regions: Pointer to FDT regions 88 * @count: Number of FDT regions 89 * @region: Pointer to image regions, which must hold @count records. If 90 * region is NULL, then (except for an SPL build) the array will be 91 * allocated. 92 * @return: Pointer to image regions 93 */ 94 struct image_region *fit_region_make_list(const void *fit, 95 struct fdt_region *fdt_regions, int count, 96 struct image_region *region) 97 { 98 int i; 99 100 debug("Hash regions:\n"); 101 debug("%10s %10s\n", "Offset", "Size"); 102 103 /* 104 * Use malloc() except in SPL (to save code size). In SPL the caller 105 * must allocate the array. 106 */ 107 #ifndef CONFIG_SPL_BUILD 108 if (!region) 109 region = calloc(sizeof(*region), count); 110 #endif 111 if (!region) 112 return NULL; 113 for (i = 0; i < count; i++) { 114 debug("%10x %10x\n", fdt_regions[i].offset, 115 fdt_regions[i].size); 116 region[i].data = fit + fdt_regions[i].offset; 117 region[i].size = fdt_regions[i].size; 118 } 119 120 return region; 121 } 122 123 static int fit_image_setup_verify(struct image_sign_info *info, 124 const void *fit, int noffset, int required_keynode, 125 char **err_msgp) 126 { 127 char *algo_name; 128 129 if (fit_image_hash_get_algo(fit, noffset, &algo_name)) { 130 *err_msgp = "Can't get hash algo property"; 131 return -1; 132 } 133 memset(info, '\0', sizeof(*info)); 134 info->keyname = fdt_getprop(fit, noffset, "key-name-hint", NULL); 135 info->fit = (void *)fit; 136 info->node_offset = noffset; 137 info->algo = image_get_sig_algo(algo_name); 138 info->fdt_blob = gd_fdt_blob(); 139 info->required_keynode = required_keynode; 140 printf("%s:%s", algo_name, info->keyname); 141 142 if (!info->algo) { 143 *err_msgp = "Unknown signature algorithm"; 144 return -1; 145 } 146 147 return 0; 148 } 149 150 int fit_image_check_sig(const void *fit, int noffset, const void *data, 151 size_t size, int required_keynode, char **err_msgp) 152 { 153 struct image_sign_info info; 154 struct image_region region; 155 uint8_t *fit_value; 156 int fit_value_len; 157 158 *err_msgp = NULL; 159 if (fit_image_setup_verify(&info, fit, noffset, required_keynode, 160 err_msgp)) 161 return -1; 162 163 if (fit_image_hash_get_value(fit, noffset, &fit_value, 164 &fit_value_len)) { 165 *err_msgp = "Can't get hash value property"; 166 return -1; 167 } 168 169 region.data = data; 170 region.size = size; 171 172 if (info.algo->verify(&info, ®ion, 1, fit_value, fit_value_len)) { 173 *err_msgp = "Verification failed"; 174 return -1; 175 } 176 177 return 0; 178 } 179 180 static int fit_image_verify_sig(const void *fit, int image_noffset, 181 const char *data, size_t size, const void *sig_blob, 182 int sig_offset) 183 { 184 int noffset; 185 char *err_msg = ""; 186 int verified = 0; 187 int ret; 188 189 /* Process all hash subnodes of the component image node */ 190 for (noffset = fdt_first_subnode(fit, image_noffset); 191 noffset >= 0; 192 noffset = fdt_next_subnode(fit, noffset)) { 193 const char *name = fit_get_name(fit, noffset, NULL); 194 195 if (!strncmp(name, FIT_SIG_NODENAME, 196 strlen(FIT_SIG_NODENAME))) { 197 ret = fit_image_check_sig(fit, noffset, data, 198 size, -1, &err_msg); 199 if (ret) { 200 puts("- "); 201 } else { 202 puts("+ "); 203 verified = 1; 204 break; 205 } 206 } 207 } 208 209 if (noffset == -FDT_ERR_TRUNCATED || noffset == -FDT_ERR_BADSTRUCTURE) { 210 err_msg = "Corrupted or truncated tree"; 211 goto error; 212 } 213 214 return verified ? 0 : -EPERM; 215 216 error: 217 printf(" error!\n%s for '%s' hash node in '%s' image node\n", 218 err_msg, fit_get_name(fit, noffset, NULL), 219 fit_get_name(fit, image_noffset, NULL)); 220 return -1; 221 } 222 223 int fit_image_verify_required_sigs(const void *fit, int image_noffset, 224 const char *data, size_t size, const void *sig_blob, 225 int *no_sigsp) 226 { 227 int verify_count = 0; 228 int noffset; 229 int sig_node; 230 231 /* Work out what we need to verify */ 232 *no_sigsp = 1; 233 sig_node = fdt_subnode_offset(sig_blob, 0, FIT_SIG_NODENAME); 234 if (sig_node < 0) { 235 debug("%s: No signature node found: %s\n", __func__, 236 fdt_strerror(sig_node)); 237 return 0; 238 } 239 240 for (noffset = fdt_first_subnode(sig_blob, sig_node); 241 noffset >= 0; 242 noffset = fdt_next_subnode(sig_blob, noffset)) { 243 const char *required; 244 int ret; 245 246 required = fdt_getprop(sig_blob, noffset, "required", NULL); 247 if (!required || strcmp(required, "image")) 248 continue; 249 ret = fit_image_verify_sig(fit, image_noffset, data, size, 250 sig_blob, noffset); 251 if (ret) { 252 printf("Failed to verify required signature '%s'\n", 253 fit_get_name(sig_blob, noffset, NULL)); 254 return ret; 255 } 256 verify_count++; 257 } 258 259 if (verify_count) 260 *no_sigsp = 0; 261 262 return 0; 263 } 264 265 int fit_config_check_sig(const void *fit, int noffset, int required_keynode, 266 char **err_msgp) 267 { 268 char * const exc_prop[] = {"data"}; 269 const char *prop, *end, *name; 270 struct image_sign_info info; 271 const uint32_t *strings; 272 uint8_t *fit_value; 273 int fit_value_len; 274 int max_regions; 275 int i, prop_len; 276 char path[200]; 277 int count; 278 279 debug("%s: fdt=%p, conf='%s', sig='%s'\n", __func__, gd_fdt_blob(), 280 fit_get_name(fit, noffset, NULL), 281 fit_get_name(gd_fdt_blob(), required_keynode, NULL)); 282 *err_msgp = NULL; 283 if (fit_image_setup_verify(&info, fit, noffset, required_keynode, 284 err_msgp)) 285 return -1; 286 287 if (fit_image_hash_get_value(fit, noffset, &fit_value, 288 &fit_value_len)) { 289 *err_msgp = "Can't get hash value property"; 290 return -1; 291 } 292 293 /* Count the number of strings in the property */ 294 prop = fdt_getprop(fit, noffset, "hashed-nodes", &prop_len); 295 end = prop ? prop + prop_len : prop; 296 for (name = prop, count = 0; name < end; name++) 297 if (!*name) 298 count++; 299 if (!count) { 300 *err_msgp = "Can't get hashed-nodes property"; 301 return -1; 302 } 303 304 /* Add a sanity check here since we are using the stack */ 305 if (count > IMAGE_MAX_HASHED_NODES) { 306 *err_msgp = "Number of hashed nodes exceeds maximum"; 307 return -1; 308 } 309 310 /* Create a list of node names from those strings */ 311 char *node_inc[count]; 312 313 debug("Hash nodes (%d):\n", count); 314 for (name = prop, i = 0; name < end; name += strlen(name) + 1, i++) { 315 debug(" '%s'\n", name); 316 node_inc[i] = (char *)name; 317 } 318 319 /* 320 * Each node can generate one region for each sub-node. Allow for 321 * 7 sub-nodes (hash@1, signature@1, etc.) and some extra. 322 */ 323 max_regions = 20 + count * 7; 324 struct fdt_region fdt_regions[max_regions]; 325 326 /* Get a list of regions to hash */ 327 count = fdt_find_regions(fit, node_inc, count, 328 exc_prop, ARRAY_SIZE(exc_prop), 329 fdt_regions, max_regions - 1, 330 path, sizeof(path), 0); 331 if (count < 0) { 332 *err_msgp = "Failed to hash configuration"; 333 return -1; 334 } 335 if (count == 0) { 336 *err_msgp = "No data to hash"; 337 return -1; 338 } 339 if (count >= max_regions - 1) { 340 *err_msgp = "Too many hash regions"; 341 return -1; 342 } 343 344 /* Add the strings */ 345 strings = fdt_getprop(fit, noffset, "hashed-strings", NULL); 346 if (strings) { 347 fdt_regions[count].offset = fdt_off_dt_strings(fit) + 348 fdt32_to_cpu(strings[0]); 349 fdt_regions[count].size = fdt32_to_cpu(strings[1]); 350 count++; 351 } 352 353 /* Allocate the region list on the stack */ 354 struct image_region region[count]; 355 356 fit_region_make_list(fit, fdt_regions, count, region); 357 if (info.algo->verify(&info, region, count, fit_value, 358 fit_value_len)) { 359 *err_msgp = "Verification failed"; 360 return -1; 361 } 362 363 return 0; 364 } 365 366 static int fit_config_verify_sig(const void *fit, int conf_noffset, 367 const void *sig_blob, int sig_offset) 368 { 369 int noffset; 370 char *err_msg = ""; 371 int verified = 0; 372 int ret; 373 374 /* Process all hash subnodes of the component conf node */ 375 for (noffset = fdt_first_subnode(fit, conf_noffset); 376 noffset >= 0; 377 noffset = fdt_next_subnode(fit, noffset)) { 378 const char *name = fit_get_name(fit, noffset, NULL); 379 380 if (!strncmp(name, FIT_SIG_NODENAME, 381 strlen(FIT_SIG_NODENAME))) { 382 ret = fit_config_check_sig(fit, noffset, sig_offset, 383 &err_msg); 384 if (ret) { 385 puts("- "); 386 } else { 387 puts("+ "); 388 verified = 1; 389 break; 390 } 391 } 392 } 393 394 if (noffset == -FDT_ERR_TRUNCATED || noffset == -FDT_ERR_BADSTRUCTURE) { 395 err_msg = "Corrupted or truncated tree"; 396 goto error; 397 } 398 399 return verified ? 0 : -EPERM; 400 401 error: 402 printf(" error!\n%s for '%s' hash node in '%s' config node\n", 403 err_msg, fit_get_name(fit, noffset, NULL), 404 fit_get_name(fit, conf_noffset, NULL)); 405 return -1; 406 } 407 408 int fit_config_verify_required_sigs(const void *fit, int conf_noffset, 409 const void *sig_blob) 410 { 411 int noffset; 412 int sig_node; 413 414 /* Work out what we need to verify */ 415 sig_node = fdt_subnode_offset(sig_blob, 0, FIT_SIG_NODENAME); 416 if (sig_node < 0) { 417 debug("%s: No signature node found: %s\n", __func__, 418 fdt_strerror(sig_node)); 419 return 0; 420 } 421 422 for (noffset = fdt_first_subnode(sig_blob, sig_node); 423 noffset >= 0; 424 noffset = fdt_next_subnode(sig_blob, noffset)) { 425 const char *required; 426 int ret; 427 428 required = fdt_getprop(sig_blob, noffset, "required", NULL); 429 if (!required || strcmp(required, "conf")) 430 continue; 431 ret = fit_config_verify_sig(fit, conf_noffset, sig_blob, 432 noffset); 433 if (ret) { 434 printf("Failed to verify required signature '%s'\n", 435 fit_get_name(sig_blob, noffset, NULL)); 436 return ret; 437 } 438 } 439 440 return 0; 441 } 442 443 int fit_config_verify(const void *fit, int conf_noffset) 444 { 445 return !fit_config_verify_required_sigs(fit, conf_noffset, 446 gd_fdt_blob()); 447 } 448