"Das U-Boot" Source Tree
at master 1403 lines 38 kB view raw
1// SPDX-License-Identifier: GPL-2.0+ 2/* 3 * Copyright (c) 2013, Google Inc. 4 * 5 * (C) Copyright 2008 Semihalf 6 * 7 * (C) Copyright 2000-2006 8 * Wolfgang Denk, DENX Software Engineering, wd@denx.de. 9 */ 10 11#include "mkimage.h" 12#include <bootm.h> 13#include <fdt_region.h> 14#include <image.h> 15#include <version.h> 16 17#if CONFIG_IS_ENABLED(FIT_SIGNATURE) 18#include <openssl/pem.h> 19#include <openssl/evp.h> 20#endif 21 22/** 23 * fit_set_hash_value - set hash value in requested has node 24 * @fit: pointer to the FIT format image header 25 * @noffset: hash node offset 26 * @value: hash value to be set 27 * @value_len: hash value length 28 * 29 * fit_set_hash_value() attempts to set hash value in a node at offset 30 * given and returns operation status to the caller. 31 * 32 * returns 33 * 0, on success 34 * -1, on failure 35 */ 36static int fit_set_hash_value(void *fit, int noffset, uint8_t *value, 37 int value_len) 38{ 39 int ret; 40 41 ret = fdt_setprop(fit, noffset, FIT_VALUE_PROP, value, value_len); 42 if (ret) { 43 fprintf(stderr, "Can't set hash '%s' property for '%s' node(%s)\n", 44 FIT_VALUE_PROP, fit_get_name(fit, noffset, NULL), 45 fdt_strerror(ret)); 46 return ret == -FDT_ERR_NOSPACE ? -ENOSPC : -EIO; 47 } 48 49 return 0; 50} 51 52/** 53 * fit_image_process_hash - Process a single subnode of the images/ node 54 * 55 * Check each subnode and process accordingly. For hash nodes we generate 56 * a hash of the supplied data and store it in the node. 57 * 58 * @fit: pointer to the FIT format image header 59 * @image_name: name of image being processed (used to display errors) 60 * @noffset: subnode offset 61 * @data: data to process 62 * @size: size of data in bytes 63 * Return: 0 if ok, -1 on error 64 */ 65static int fit_image_process_hash(void *fit, const char *image_name, 66 int noffset, const void *data, size_t size) 67{ 68 uint8_t value[FIT_MAX_HASH_LEN]; 69 const char *node_name; 70 int value_len; 71 const char *algo; 72 int ret; 73 74 node_name = fit_get_name(fit, noffset, NULL); 75 76 if (fit_image_hash_get_algo(fit, noffset, &algo)) { 77 fprintf(stderr, 78 "Can't get hash algo property for '%s' hash node in '%s' image node\n", 79 node_name, image_name); 80 return -ENOENT; 81 } 82 83 if (calculate_hash(data, size, algo, value, &value_len)) { 84 fprintf(stderr, 85 "Unsupported hash algorithm (%s) for '%s' hash node in '%s' image node\n", 86 algo, node_name, image_name); 87 return -EPROTONOSUPPORT; 88 } 89 90 ret = fit_set_hash_value(fit, noffset, value, value_len); 91 if (ret) { 92 fprintf(stderr, "Can't set hash value for '%s' hash node in '%s' image node\n", 93 node_name, image_name); 94 return ret; 95 } 96 97 return 0; 98} 99 100/** 101 * fit_image_write_sig() - write the signature to a FIT 102 * 103 * This writes the signature and signer data to the FIT. 104 * 105 * @fit: pointer to the FIT format image header 106 * @noffset: hash node offset 107 * @value: signature value to be set 108 * @value_len: signature value length 109 * @comment: Text comment to write (NULL for none) 110 * 111 * returns 112 * 0, on success 113 * -FDT_ERR_..., on failure 114 */ 115static int fit_image_write_sig(void *fit, int noffset, uint8_t *value, 116 int value_len, const char *comment, const char *region_prop, 117 int region_proplen, const char *cmdname, const char *algo_name) 118{ 119 int string_size; 120 int ret; 121 122 /* 123 * Get the current string size, before we update the FIT and add 124 * more 125 */ 126 string_size = fdt_size_dt_strings(fit); 127 128 ret = fdt_setprop(fit, noffset, FIT_VALUE_PROP, value, value_len); 129 if (!ret) { 130 ret = fdt_setprop_string(fit, noffset, "signer-name", 131 "mkimage"); 132 } 133 if (!ret) { 134 ret = fdt_setprop_string(fit, noffset, "signer-version", 135 PLAIN_VERSION); 136 } 137 if (comment && !ret) 138 ret = fdt_setprop_string(fit, noffset, "comment", comment); 139 if (!ret) { 140 time_t timestamp = imagetool_get_source_date(cmdname, 141 time(NULL)); 142 uint32_t t = cpu_to_uimage(timestamp); 143 144 ret = fdt_setprop(fit, noffset, FIT_TIMESTAMP_PROP, &t, 145 sizeof(uint32_t)); 146 } 147 if (region_prop && !ret) { 148 uint32_t strdata[2]; 149 150 ret = fdt_setprop(fit, noffset, "hashed-nodes", 151 region_prop, region_proplen); 152 /* This is a legacy offset, it is unused, and must remain 0. */ 153 strdata[0] = 0; 154 strdata[1] = cpu_to_fdt32(string_size); 155 if (!ret) { 156 ret = fdt_setprop(fit, noffset, "hashed-strings", 157 strdata, sizeof(strdata)); 158 } 159 } 160 if (algo_name && !ret) 161 ret = fdt_setprop_string(fit, noffset, "algo", algo_name); 162 163 return ret; 164} 165 166static int fit_image_setup_sig(struct image_sign_info *info, 167 const char *keydir, const char *keyfile, void *fit, 168 const char *image_name, int noffset, const char *require_keys, 169 const char *engine_id, const char *algo_name) 170{ 171 const char *node_name; 172 const char *padding_name; 173 174 node_name = fit_get_name(fit, noffset, NULL); 175 if (!algo_name) { 176 if (fit_image_hash_get_algo(fit, noffset, &algo_name)) { 177 fprintf(stderr, 178 "Can't get algo property for '%s' signature node in '%s' image node\n", 179 node_name, image_name); 180 return -1; 181 } 182 } 183 184 padding_name = fdt_getprop(fit, noffset, "padding", NULL); 185 186 memset(info, '\0', sizeof(*info)); 187 info->keydir = keydir; 188 info->keyfile = keyfile; 189 info->keyname = fdt_getprop(fit, noffset, FIT_KEY_HINT, NULL); 190 info->fit = fit; 191 info->node_offset = noffset; 192 info->name = strdup(algo_name); 193 info->checksum = image_get_checksum_algo(algo_name); 194 info->crypto = image_get_crypto_algo(algo_name); 195 info->padding = image_get_padding_algo(padding_name); 196 info->require_keys = require_keys; 197 info->engine_id = engine_id; 198 if (!info->checksum || !info->crypto) { 199 fprintf(stderr, 200 "Unsupported signature algorithm (%s) for '%s' signature node in '%s' image node\n", 201 algo_name, node_name, image_name); 202 return -1; 203 } 204 205 return 0; 206} 207 208/** 209 * fit_image_process_sig- Process a single subnode of the images/ node 210 * 211 * Check each subnode and process accordingly. For signature nodes we 212 * generate a signed hash of the supplied data and store it in the node. 213 * 214 * @keydir: Directory containing keys to use for signing 215 * @keydest: Destination FDT blob to write public keys into (NULL if none) 216 * @fit: pointer to the FIT format image header 217 * @image_name: name of image being processed (used to display errors) 218 * @noffset: subnode offset 219 * @data: data to process 220 * @size: size of data in bytes 221 * @comment: Comment to add to signature nodes 222 * @require_keys: Mark all keys as 'required' 223 * @engine_id: Engine to use for signing 224 * Return: keydest node if @keydest is non-NULL, else 0 if none; -ve error code 225 * on failure 226 */ 227static int fit_image_process_sig(const char *keydir, const char *keyfile, 228 void *keydest, void *fit, const char *image_name, 229 int noffset, const void *data, size_t size, 230 const char *comment, int require_keys, const char *engine_id, 231 const char *cmdname, const char *algo_name) 232{ 233 struct image_sign_info info; 234 struct image_region region; 235 const char *node_name; 236 uint8_t *value; 237 uint value_len; 238 int ret; 239 240 if (fit_image_setup_sig(&info, keydir, keyfile, fit, image_name, 241 noffset, require_keys ? "image" : NULL, 242 engine_id, algo_name)) 243 return -1; 244 245 node_name = fit_get_name(fit, noffset, NULL); 246 region.data = data; 247 region.size = size; 248 ret = info.crypto->sign(&info, &region, 1, &value, &value_len); 249 if (ret) { 250 fprintf(stderr, "Failed to sign '%s' signature node in '%s' image node: %d\n", 251 node_name, image_name, ret); 252 253 /* We allow keys to be missing */ 254 if (ret == -ENOENT) 255 return 0; 256 return -1; 257 } 258 259 ret = fit_image_write_sig(fit, noffset, value, value_len, comment, 260 NULL, 0, cmdname, algo_name); 261 if (ret) { 262 if (ret == -FDT_ERR_NOSPACE) 263 return -ENOSPC; 264 fprintf(stderr, 265 "Can't write signature for '%s' signature node in '%s' conf node: %s\n", 266 node_name, image_name, fdt_strerror(ret)); 267 return -1; 268 } 269 free(value); 270 271 /* Get keyname again, as FDT has changed and invalidated our pointer */ 272 info.keyname = fdt_getprop(fit, noffset, FIT_KEY_HINT, NULL); 273 274 /* 275 * Write the public key into the supplied FDT file; this might fail 276 * several times, since we try signing with successively increasing 277 * size values 278 */ 279 if (keydest) { 280 ret = info.crypto->add_verify_data(&info, keydest); 281 if (ret < 0) { 282 fprintf(stderr, 283 "Failed to add verification data for '%s' signature node in '%s' image node\n", 284 node_name, image_name); 285 return ret; 286 } 287 /* Return the node that was written to */ 288 return ret; 289 } 290 291 return 0; 292} 293 294static int fit_image_read_data(char *filename, unsigned char *data, 295 int expected_size) 296{ 297 struct stat sbuf; 298 int fd, ret = -1; 299 ssize_t n; 300 301 /* Open file */ 302 fd = open(filename, O_RDONLY | O_BINARY); 303 if (fd < 0) { 304 fprintf(stderr, "Can't open file %s (err=%d => %s)\n", 305 filename, errno, strerror(errno)); 306 return -1; 307 } 308 309 /* Compute file size */ 310 if (fstat(fd, &sbuf) < 0) { 311 fprintf(stderr, "Can't fstat file %s (err=%d => %s)\n", 312 filename, errno, strerror(errno)); 313 goto err; 314 } 315 316 /* Check file size */ 317 if (sbuf.st_size != expected_size) { 318 fprintf(stderr, "File %s don't have the expected size (size=%lld, expected=%d)\n", 319 filename, (long long)sbuf.st_size, expected_size); 320 goto err; 321 } 322 323 /* Read data */ 324 n = read(fd, data, sbuf.st_size); 325 if (n < 0) { 326 fprintf(stderr, "Can't read file %s (err=%d => %s)\n", 327 filename, errno, strerror(errno)); 328 goto err; 329 } 330 331 /* Check that we have read all the file */ 332 if (n != sbuf.st_size) { 333 fprintf(stderr, "Can't read all file %s (read %zd bytes, expected %lld)\n", 334 filename, n, (long long)sbuf.st_size); 335 goto err; 336 } 337 338 ret = 0; 339 340err: 341 close(fd); 342 return ret; 343} 344 345static int fit_image_read_key_iv_data(const char *keydir, const char *key_iv_name, 346 unsigned char *key_iv_data, int expected_size) 347{ 348 char filename[PATH_MAX]; 349 int ret; 350 351 ret = snprintf(filename, sizeof(filename), "%s/%s%s", 352 keydir, key_iv_name, ".bin"); 353 if (ret >= sizeof(filename)) { 354 fprintf(stderr, "Can't format the key or IV filename when setting up the cipher: insufficient buffer space\n"); 355 return -1; 356 } 357 if (ret < 0) { 358 fprintf(stderr, "Can't format the key or IV filename when setting up the cipher: snprintf error\n"); 359 return -1; 360 } 361 362 ret = fit_image_read_data(filename, key_iv_data, expected_size); 363 364 return ret; 365} 366 367/** 368 * get_random_data() - fill buffer with random data 369 * 370 * There is no common cryptographically safe function in Linux and BSD. 371 * Hence directly access the /dev/urandom PRNG. 372 * 373 * @data: buffer to fill 374 * @size: buffer size 375 */ 376static int get_random_data(void *data, size_t size) 377{ 378 int fd; 379 int ret; 380 381 fd = open("/dev/urandom", O_RDONLY); 382 if (fd < 0) { 383 perror("Failed to open /dev/urandom"); 384 return -1; 385 } 386 387 while (size) { 388 ssize_t count; 389 390 count = read(fd, data, size); 391 if (count < 0) { 392 if (errno == EINTR) { 393 continue; 394 } else { 395 perror("Failed to read from /dev/urandom"); 396 ret = -1; 397 goto out; 398 } 399 } 400 data += count; 401 size -= count; 402 } 403 ret = 0; 404out: 405 close(fd); 406 407 return ret; 408} 409 410static int fit_image_setup_cipher(struct image_cipher_info *info, 411 const char *keydir, void *fit, 412 const char *image_name, int image_noffset, 413 int noffset) 414{ 415 char *algo_name; 416 int ret = -1; 417 418 if (fit_image_cipher_get_algo(fit, noffset, &algo_name)) { 419 fprintf(stderr, "Can't get algo name for cipher in image '%s'\n", 420 image_name); 421 goto out; 422 } 423 424 info->keydir = keydir; 425 426 /* Read the key name */ 427 info->keyname = fdt_getprop(fit, noffset, FIT_KEY_HINT, NULL); 428 if (!info->keyname) { 429 fprintf(stderr, "Can't get key name for cipher in image '%s'\n", 430 image_name); 431 goto out; 432 } 433 434 /* 435 * Read the IV name 436 * 437 * If this property is not provided then mkimage will generate 438 * a random IV and store it in the FIT image 439 */ 440 info->ivname = fdt_getprop(fit, noffset, "iv-name-hint", NULL); 441 442 info->fit = fit; 443 info->node_noffset = noffset; 444 info->name = algo_name; 445 446 info->cipher = image_get_cipher_algo(algo_name); 447 if (!info->cipher) { 448 fprintf(stderr, "Can't get algo for cipher '%s'\n", image_name); 449 goto out; 450 } 451 452 info->key = malloc(info->cipher->key_len); 453 if (!info->key) { 454 fprintf(stderr, "Can't allocate memory for key\n"); 455 ret = -1; 456 goto out; 457 } 458 459 /* Read the key in the file */ 460 ret = fit_image_read_key_iv_data(info->keydir, info->keyname, 461 (unsigned char *)info->key, 462 info->cipher->key_len); 463 if (ret < 0) 464 goto out; 465 466 info->iv = malloc(info->cipher->iv_len); 467 if (!info->iv) { 468 fprintf(stderr, "Can't allocate memory for iv\n"); 469 ret = -1; 470 goto out; 471 } 472 473 if (info->ivname) { 474 /* Read the IV in the file */ 475 ret = fit_image_read_key_iv_data(info->keydir, info->ivname, 476 (unsigned char *)info->iv, 477 info->cipher->iv_len); 478 if (ret < 0) 479 goto out; 480 } else { 481 /* Generate an ramdom IV */ 482 ret = get_random_data((void *)info->iv, info->cipher->iv_len); 483 } 484 485 out: 486 return ret; 487} 488 489int fit_image_write_cipher(void *fit, int image_noffset, int noffset, 490 const void *data, size_t size, 491 unsigned char *data_ciphered, int data_ciphered_len) 492{ 493 int ret = -1; 494 495 /* Replace data with ciphered data */ 496 ret = fdt_setprop(fit, image_noffset, FIT_DATA_PROP, 497 data_ciphered, data_ciphered_len); 498 if (ret == -FDT_ERR_NOSPACE) { 499 ret = -ENOSPC; 500 goto out; 501 } 502 if (ret) { 503 fprintf(stderr, "Can't replace data with ciphered data (err = %d)\n", ret); 504 goto out; 505 } 506 507 /* add non ciphered data size */ 508 ret = fdt_setprop_u32(fit, image_noffset, "data-size-unciphered", size); 509 if (ret == -FDT_ERR_NOSPACE) { 510 ret = -ENOSPC; 511 goto out; 512 } 513 if (ret) { 514 fprintf(stderr, "Can't add unciphered data size (err = %d)\n", ret); 515 goto out; 516 } 517 518 out: 519 return ret; 520} 521 522static int 523fit_image_process_cipher(const char *keydir, void *keydest, void *fit, 524 const char *image_name, int image_noffset, 525 int node_noffset, const void *data, size_t size, 526 const char *cmdname) 527{ 528 struct image_cipher_info info; 529 unsigned char *data_ciphered = NULL; 530 int data_ciphered_len; 531 int ret; 532 533 memset(&info, 0, sizeof(info)); 534 535 ret = fit_image_setup_cipher(&info, keydir, fit, image_name, 536 image_noffset, node_noffset); 537 if (ret) 538 goto out; 539 540 ret = info.cipher->encrypt(&info, data, size, 541 &data_ciphered, &data_ciphered_len); 542 if (ret) 543 goto out; 544 545 /* 546 * Write the public key into the supplied FDT file; this might fail 547 * several times, since we try signing with successively increasing 548 * size values 549 * And, if needed, write the iv in the FIT file 550 */ 551 if (keydest || (!keydest && !info.ivname)) { 552 ret = info.cipher->add_cipher_data(&info, keydest, fit, node_noffset); 553 if (ret) { 554 fprintf(stderr, 555 "Failed to add verification data for cipher '%s' in image '%s'\n", 556 info.keyname, image_name); 557 goto out; 558 } 559 } 560 561 ret = fit_image_write_cipher(fit, image_noffset, node_noffset, 562 data, size, 563 data_ciphered, data_ciphered_len); 564 565 out: 566 free(data_ciphered); 567 free((void *)info.key); 568 free((void *)info.iv); 569 return ret; 570} 571 572int fit_image_cipher_data(const char *keydir, void *keydest, 573 void *fit, int image_noffset, const char *comment, 574 int require_keys, const char *engine_id, 575 const char *cmdname) 576{ 577 const char *image_name; 578 const void *data; 579 size_t size; 580 int cipher_node_offset, len; 581 582 /* Get image name */ 583 image_name = fit_get_name(fit, image_noffset, NULL); 584 if (!image_name) { 585 fprintf(stderr, "Can't get image name\n"); 586 return -1; 587 } 588 589 /* Get image data and data length */ 590 if (fit_image_get_emb_data(fit, image_noffset, &data, &size)) { 591 fprintf(stderr, "Can't get image data/size\n"); 592 return -1; 593 } 594 595 /* 596 * Don't cipher ciphered data. 597 * 598 * If the data-size-unciphered property is present the data for this 599 * image is already encrypted. This is important as 'mkimage -F' can be 600 * run multiple times on a FIT image. 601 */ 602 if (fdt_getprop(fit, image_noffset, "data-size-unciphered", &len)) 603 return 0; 604 if (len != -FDT_ERR_NOTFOUND) { 605 fprintf(stderr, "Failure testing for data-size-unciphered\n"); 606 return -1; 607 } 608 609 /* Process cipher node if present */ 610 cipher_node_offset = fdt_subnode_offset(fit, image_noffset, 611 FIT_CIPHER_NODENAME); 612 if (cipher_node_offset == -FDT_ERR_NOTFOUND) 613 return 0; 614 if (cipher_node_offset < 0) { 615 fprintf(stderr, "Failure getting cipher node\n"); 616 return -1; 617 } 618 if (!IMAGE_ENABLE_ENCRYPT || !keydir) 619 return 0; 620 return fit_image_process_cipher(keydir, keydest, fit, image_name, 621 image_noffset, cipher_node_offset, data, size, cmdname); 622} 623 624/** 625 * fit_image_add_verification_data() - calculate/set verig. data for image node 626 * 627 * This adds hash and signature values for an component image node. 628 * 629 * All existing hash subnodes are checked, if algorithm property is set to 630 * one of the supported hash algorithms, hash value is computed and 631 * corresponding hash node property is set, for example: 632 * 633 * Input component image node structure: 634 * 635 * o image-1 (at image_noffset) 636 * | - data = [binary data] 637 * o hash-1 638 * |- algo = "sha1" 639 * 640 * Output component image node structure: 641 * 642 * o image-1 (at image_noffset) 643 * | - data = [binary data] 644 * o hash-1 645 * |- algo = "sha1" 646 * |- value = sha1(data) 647 * 648 * For signature details, please see doc/uImage.FIT/signature.txt 649 * 650 * @keydir Directory containing *.key and *.crt files (or NULL) 651 * @keydest FDT Blob to write public keys into (NULL if none) 652 * @fit: Pointer to the FIT format image header 653 * @image_noffset: Requested component image node 654 * @comment: Comment to add to signature nodes 655 * @require_keys: Mark all keys as 'required' 656 * @engine_id: Engine to use for signing 657 * @return: 0 on success, <0 on failure 658 */ 659int fit_image_add_verification_data(const char *keydir, const char *keyfile, 660 void *keydest, void *fit, int image_noffset, 661 const char *comment, int require_keys, const char *engine_id, 662 const char *cmdname, const char* algo_name) 663{ 664 const char *image_name; 665 const void *data; 666 size_t size; 667 int noffset; 668 669 /* Get image data and data length */ 670 if (fit_image_get_emb_data(fit, image_noffset, &data, &size)) { 671 fprintf(stderr, "Can't get image data/size\n"); 672 return -1; 673 } 674 675 image_name = fit_get_name(fit, image_noffset, NULL); 676 677 /* Process all hash subnodes of the component image node */ 678 for (noffset = fdt_first_subnode(fit, image_noffset); 679 noffset >= 0; 680 noffset = fdt_next_subnode(fit, noffset)) { 681 const char *node_name; 682 int ret = 0; 683 684 /* 685 * Check subnode name, must be equal to "hash" or "signature". 686 * Multiple hash nodes require unique unit node 687 * names, e.g. hash-1, hash-2, signature-1, etc. 688 */ 689 node_name = fit_get_name(fit, noffset, NULL); 690 if (!strncmp(node_name, FIT_HASH_NODENAME, 691 strlen(FIT_HASH_NODENAME))) { 692 ret = fit_image_process_hash(fit, image_name, noffset, 693 data, size); 694 } else if (IMAGE_ENABLE_SIGN && (keydir || keyfile) && 695 !strncmp(node_name, FIT_SIG_NODENAME, 696 strlen(FIT_SIG_NODENAME))) { 697 ret = fit_image_process_sig(keydir, keyfile, keydest, 698 fit, image_name, noffset, data, size, 699 comment, require_keys, engine_id, cmdname, 700 algo_name); 701 } 702 if (ret < 0) 703 return ret; 704 } 705 706 return 0; 707} 708 709struct strlist { 710 int count; 711 char **strings; 712}; 713 714static void strlist_init(struct strlist *list) 715{ 716 memset(list, '\0', sizeof(*list)); 717} 718 719static void strlist_free(struct strlist *list) 720{ 721 int i; 722 723 for (i = 0; i < list->count; i++) 724 free(list->strings[i]); 725 free(list->strings); 726} 727 728static int strlist_add(struct strlist *list, const char *str) 729{ 730 char *dup; 731 732 dup = strdup(str); 733 list->strings = realloc(list->strings, 734 (list->count + 1) * sizeof(char *)); 735 if (!list || !str) 736 return -1; 737 list->strings[list->count++] = dup; 738 739 return 0; 740} 741 742static const char *fit_config_get_image_list(const void *fit, int noffset, 743 int *lenp, int *allow_missingp) 744{ 745 static const char default_list[] = FIT_KERNEL_PROP "\0" 746 FIT_FDT_PROP "\0" FIT_SCRIPT_PROP; 747 const char *prop; 748 749 /* If there is an "sign-image" property, use that */ 750 prop = fdt_getprop(fit, noffset, "sign-images", lenp); 751 if (prop) { 752 *allow_missingp = 0; 753 return *lenp ? prop : NULL; 754 } 755 756 /* Default image list */ 757 *allow_missingp = 1; 758 *lenp = sizeof(default_list); 759 760 return default_list; 761} 762 763/** 764 * fit_config_add_hash() - Add a list of nodes to hash for an image 765 * 766 * This adds a list of paths to image nodes (as referred to by a particular 767 * offset) that need to be hashed, to protect a configuration 768 * 769 * @fit: Pointer to the FIT format image header 770 * @image_noffset: Offset of image to process (e.g. /images/kernel-1) 771 * @node_inc: List of nodes to add to 772 * @conf_name Configuration-node name, child of /configurations node (only 773 * used for error messages) 774 * @sig_name Signature-node name (only used for error messages) 775 * @iname: Name of image being processed (e.g. "kernel-1" (only used 776 * for error messages) 777 */ 778static int fit_config_add_hash(const void *fit, int image_noffset, 779 struct strlist *node_inc, const char *conf_name, 780 const char *sig_name, const char *iname) 781{ 782 char path[200]; 783 int noffset; 784 int hash_count; 785 int ret; 786 787 ret = fdt_get_path(fit, image_noffset, path, sizeof(path)); 788 if (ret < 0) 789 goto err_path; 790 if (strlist_add(node_inc, path)) 791 goto err_mem; 792 793 /* Add all this image's hashes */ 794 hash_count = 0; 795 for (noffset = fdt_first_subnode(fit, image_noffset); 796 noffset >= 0; 797 noffset = fdt_next_subnode(fit, noffset)) { 798 const char *name = fit_get_name(fit, noffset, NULL); 799 800 if (strncmp(name, FIT_HASH_NODENAME, 801 strlen(FIT_HASH_NODENAME))) 802 continue; 803 ret = fdt_get_path(fit, noffset, path, sizeof(path)); 804 if (ret < 0) 805 goto err_path; 806 if (strlist_add(node_inc, path)) 807 goto err_mem; 808 hash_count++; 809 } 810 811 if (!hash_count) { 812 fprintf(stderr, 813 "Failed to find any hash nodes in configuration '%s/%s' image '%s' - without these it is not possible to verify this image\n", 814 conf_name, sig_name, iname); 815 return -ENOMSG; 816 } 817 818 /* Add this image's cipher node if present */ 819 noffset = fdt_subnode_offset(fit, image_noffset, 820 FIT_CIPHER_NODENAME); 821 if (noffset != -FDT_ERR_NOTFOUND) { 822 if (noffset < 0) { 823 fprintf(stderr, 824 "Failed to get cipher node in configuration '%s/%s' image '%s': %s\n", 825 conf_name, sig_name, iname, 826 fdt_strerror(noffset)); 827 return -EIO; 828 } 829 ret = fdt_get_path(fit, noffset, path, sizeof(path)); 830 if (ret < 0) 831 goto err_path; 832 if (strlist_add(node_inc, path)) 833 goto err_mem; 834 } 835 836 return 0; 837 838err_mem: 839 fprintf(stderr, "Out of memory processing configuration '%s/%s'\n", conf_name, 840 sig_name); 841 return -ENOMEM; 842 843err_path: 844 fprintf(stderr, "Failed to get path for image '%s' in configuration '%s/%s': %s\n", 845 iname, conf_name, sig_name, fdt_strerror(ret)); 846 return -ENOENT; 847} 848 849/** 850 * fit_config_get_hash_list() - Get the regions to sign 851 * 852 * This calculates a list of nodes to hash for this particular configuration, 853 * returning it as a string list (struct strlist, not a devicetree string list) 854 * 855 * @fit: Pointer to the FIT format image header 856 * @conf_noffset: Offset of configuration node to sign (child of 857 * /configurations node) 858 * @sig_offset: Offset of signature node containing info about how to sign it 859 * (child of 'signatures' node) 860 * @return 0 if OK, -ENOENT if an image referred to by the configuration cannot 861 * be found, -ENOMSG if ther were no images in the configuration 862 */ 863static int fit_config_get_hash_list(const void *fit, int conf_noffset, 864 int sig_offset, struct strlist *node_inc) 865{ 866 int allow_missing; 867 const char *prop, *iname, *end; 868 const char *conf_name, *sig_name; 869 char name[200]; 870 int image_count; 871 int ret, len; 872 873 conf_name = fit_get_name(fit, conf_noffset, NULL); 874 sig_name = fit_get_name(fit, sig_offset, NULL); 875 876 /* 877 * Build a list of nodes we need to hash. We always need the root 878 * node and the configuration. 879 */ 880 strlist_init(node_inc); 881 snprintf(name, sizeof(name), "%s/%s", FIT_CONFS_PATH, conf_name); 882 if (strlist_add(node_inc, "/") || 883 strlist_add(node_inc, name)) 884 goto err_mem; 885 886 /* Get a list of images that we intend to sign */ 887 prop = fit_config_get_image_list(fit, sig_offset, &len, 888 &allow_missing); 889 if (!prop) 890 return 0; 891 892 /* Locate the images */ 893 end = prop + len; 894 image_count = 0; 895 for (iname = prop; iname < end; iname += strlen(iname) + 1) { 896 int image_noffset; 897 int index, max_index; 898 899 max_index = fdt_stringlist_count(fit, conf_noffset, iname); 900 901 for (index = 0; index < max_index; index++) { 902 image_noffset = fit_conf_get_prop_node_index(fit, conf_noffset, 903 iname, index); 904 905 if (image_noffset < 0) { 906 fprintf(stderr, 907 "Failed to find image '%s' in configuration '%s/%s'\n", 908 iname, conf_name, sig_name); 909 if (allow_missing) 910 continue; 911 912 return -ENOENT; 913 } 914 915 ret = fit_config_add_hash(fit, image_noffset, node_inc, 916 conf_name, sig_name, iname); 917 if (ret < 0) 918 return ret; 919 920 image_count++; 921 } 922 } 923 924 if (!image_count) { 925 fprintf(stderr, "Failed to find any images for configuration '%s/%s'\n", 926 conf_name, sig_name); 927 return -ENOMSG; 928 } 929 930 return 0; 931 932err_mem: 933 fprintf(stderr, "Out of memory processing configuration '%s/%s'\n", conf_name, 934 sig_name); 935 return -ENOMEM; 936} 937 938/** 939 * fit_config_get_regions() - Get the regions to sign 940 * 941 * This calculates a list of node to hash for this particular configuration, 942 * then finds which regions of the devicetree they correspond to. 943 * 944 * @fit: Pointer to the FIT format image header 945 * @conf_noffset: Offset of configuration node to sign (child of 946 * /configurations node) 947 * @sig_offset: Offset of signature node containing info about how to sign it 948 * (child of 'signatures' node) 949 * @regionp: Returns list of regions that need to be hashed (allocated; must be 950 * freed by the caller) 951 * @region_count: Returns number of regions 952 * @region_propp: Returns string-list property containing the list of nodes 953 * that correspond to the regions. Each entry is a full path to the node. 954 * This is in devicetree format, i.e. a \0 between each string. This is 955 * allocated and must be freed by the caller. 956 * @region_proplen: Returns length of *@@region_propp in bytes 957 * @return 0 if OK, -ENOMEM if out of memory, -EIO if the regions to hash could 958 * not be found, -EINVAL if no registers were found to hash 959 */ 960static int fit_config_get_regions(const void *fit, int conf_noffset, 961 int sig_offset, struct image_region **regionp, 962 int *region_countp, char **region_propp, 963 int *region_proplen) 964{ 965 char * const exc_prop[] = { 966 FIT_DATA_PROP, 967 FIT_DATA_SIZE_PROP, 968 FIT_DATA_POSITION_PROP, 969 FIT_DATA_OFFSET_PROP, 970 }; 971 struct strlist node_inc; 972 struct image_region *region; 973 struct fdt_region fdt_regions[100]; 974 const char *conf_name, *sig_name; 975 char path[200]; 976 int count, i; 977 char *region_prop; 978 int ret, len; 979 980 conf_name = fit_get_name(fit, conf_noffset, NULL); 981 sig_name = fit_get_name(fit, sig_offset, NULL); 982 debug("%s: conf='%s', sig='%s'\n", __func__, conf_name, sig_name); 983 984 /* Get a list of nodes we want to hash */ 985 ret = fit_config_get_hash_list(fit, conf_noffset, sig_offset, 986 &node_inc); 987 if (ret) 988 return ret; 989 990 /* Get a list of regions to hash */ 991 count = fdt_find_regions(fit, node_inc.strings, node_inc.count, 992 exc_prop, ARRAY_SIZE(exc_prop), 993 fdt_regions, ARRAY_SIZE(fdt_regions), 994 path, sizeof(path), 1); 995 if (count < 0) { 996 fprintf(stderr, "Failed to hash configuration '%s/%s': %s\n", conf_name, 997 sig_name, fdt_strerror(ret)); 998 return -EIO; 999 } 1000 if (count == 0) { 1001 fprintf(stderr, "No data to hash for configuration '%s/%s': %s\n", 1002 conf_name, sig_name, fdt_strerror(ret)); 1003 return -EINVAL; 1004 } 1005 1006 /* Build our list of data blocks */ 1007 region = fit_region_make_list(fit, fdt_regions, count, NULL); 1008 if (!region) { 1009 fprintf(stderr, "Out of memory hashing configuration '%s/%s'\n", 1010 conf_name, sig_name); 1011 return -ENOMEM; 1012 } 1013 1014 /* Create a list of all hashed properties */ 1015 debug("Hash nodes:\n"); 1016 for (i = len = 0; i < node_inc.count; i++) { 1017 debug(" %s\n", node_inc.strings[i]); 1018 len += strlen(node_inc.strings[i]) + 1; 1019 } 1020 region_prop = malloc(len); 1021 if (!region_prop) { 1022 fprintf(stderr, "Out of memory setting up regions for configuration '%s/%s'\n", 1023 conf_name, sig_name); 1024 return -ENOMEM; 1025 } 1026 for (i = len = 0; i < node_inc.count; 1027 len += strlen(node_inc.strings[i]) + 1, i++) 1028 strcpy(region_prop + len, node_inc.strings[i]); 1029 strlist_free(&node_inc); 1030 1031 *region_countp = count; 1032 *regionp = region; 1033 *region_propp = region_prop; 1034 *region_proplen = len; 1035 1036 return 0; 1037} 1038 1039/** 1040 * fit_config_process_sig - Process a single subnode of the configurations/ node 1041 * 1042 * Generate a signed hash of the supplied data and store it in the node. 1043 * 1044 * @keydir: Directory containing keys to use for signing 1045 * @keydest: Destination FDT blob to write public keys into (NULL if none) 1046 * @fit: pointer to the FIT format image header 1047 * @conf_name name of config being processed (used to display errors) 1048 * @conf_noffset: Offset of configuration node, e.g. '/configurations/conf-1' 1049 * @noffset: subnode offset, e.g. '/configurations/conf-1/sig-1' 1050 * @comment: Comment to add to signature nodes 1051 * @require_keys: Mark all keys as 'required' 1052 * @engine_id: Engine to use for signing 1053 * @cmdname: Command name used when reporting errors 1054 * @return keydest node if @keydest is non-NULL, else 0 if none; -ve error code 1055 * on failure 1056 */ 1057static int fit_config_process_sig(const char *keydir, const char *keyfile, 1058 void *keydest, void *fit, const char *conf_name, 1059 int conf_noffset, int noffset, const char *comment, 1060 int require_keys, const char *engine_id, const char *cmdname, 1061 const char *algo_name) 1062{ 1063 struct image_sign_info info; 1064 const char *node_name; 1065 struct image_region *region; 1066 char *region_prop; 1067 int region_proplen; 1068 int region_count; 1069 uint8_t *value; 1070 uint value_len; 1071 int ret; 1072 1073 node_name = fit_get_name(fit, noffset, NULL); 1074 if (fit_config_get_regions(fit, conf_noffset, noffset, &region, 1075 &region_count, &region_prop, 1076 &region_proplen)) 1077 return -1; 1078 1079 if (fit_image_setup_sig(&info, keydir, keyfile, fit, conf_name, noffset, 1080 require_keys ? "conf" : NULL, engine_id, 1081 algo_name)) 1082 return -1; 1083 1084 ret = info.crypto->sign(&info, region, region_count, &value, 1085 &value_len); 1086 free(region); 1087 if (ret) { 1088 fprintf(stderr, "Failed to sign '%s' signature node in '%s' conf node\n", 1089 node_name, conf_name); 1090 1091 /* We allow keys to be missing */ 1092 if (ret == -ENOENT) 1093 return 0; 1094 return -1; 1095 } 1096 1097 ret = fit_image_write_sig(fit, noffset, value, value_len, comment, 1098 region_prop, region_proplen, cmdname, 1099 algo_name); 1100 if (ret) { 1101 if (ret == -FDT_ERR_NOSPACE) 1102 return -ENOSPC; 1103 fprintf(stderr, 1104 "Can't write signature for '%s' signature node in '%s' conf node: %s\n", 1105 node_name, conf_name, fdt_strerror(ret)); 1106 return -1; 1107 } 1108 free(value); 1109 free(region_prop); 1110 1111 /* Get keyname again, as FDT has changed and invalidated our pointer */ 1112 info.keyname = fdt_getprop(fit, noffset, FIT_KEY_HINT, NULL); 1113 1114 /* Write the public key into the supplied FDT file */ 1115 if (keydest) { 1116 ret = info.crypto->add_verify_data(&info, keydest); 1117 if (ret < 0) { 1118 fprintf(stderr, 1119 "Failed to add verification data for '%s' signature node in '%s' configuration node\n", 1120 node_name, conf_name); 1121 } 1122 return ret; 1123 } 1124 1125 return 0; 1126} 1127 1128static int fit_config_add_verification_data(const char *keydir, 1129 const char *keyfile, void *keydest, void *fit, int conf_noffset, 1130 const char *comment, int require_keys, const char *engine_id, 1131 const char *cmdname, const char *algo_name, 1132 struct image_summary *summary) 1133{ 1134 const char *conf_name; 1135 int noffset; 1136 1137 conf_name = fit_get_name(fit, conf_noffset, NULL); 1138 1139 /* Process all hash subnodes of the configuration node */ 1140 for (noffset = fdt_first_subnode(fit, conf_noffset); 1141 noffset >= 0; 1142 noffset = fdt_next_subnode(fit, noffset)) { 1143 const char *node_name; 1144 int ret = 0; 1145 1146 node_name = fit_get_name(fit, noffset, NULL); 1147 if (!strncmp(node_name, FIT_SIG_NODENAME, 1148 strlen(FIT_SIG_NODENAME))) { 1149 ret = fit_config_process_sig(keydir, keyfile, keydest, 1150 fit, conf_name, conf_noffset, noffset, comment, 1151 require_keys, engine_id, cmdname, algo_name); 1152 if (ret < 0) 1153 return ret; 1154 1155 summary->sig_offset = noffset; 1156 fdt_get_path(fit, noffset, summary->sig_path, 1157 sizeof(summary->sig_path)); 1158 1159 if (keydest) { 1160 summary->keydest_offset = ret; 1161 fdt_get_path(keydest, ret, 1162 summary->keydest_path, 1163 sizeof(summary->keydest_path)); 1164 } 1165 } 1166 } 1167 1168 return 0; 1169} 1170 1171#if CONFIG_IS_ENABLED(FIT_SIGNATURE) 1172/* 1173 * 0) open file (open) 1174 * 1) read certificate (PEM_read_X509) 1175 * 2) get public key (X509_get_pubkey) 1176 * 3) provide der format (d2i_RSAPublicKey) 1177 */ 1178static int read_pub_key(const char *keydir, const void *name, 1179 unsigned char **pubkey, int *pubkey_len) 1180{ 1181 char path[1024]; 1182 EVP_PKEY *key = NULL; 1183 X509 *cert; 1184 FILE *f; 1185 int ret; 1186 1187 memset(path, 0, 1024); 1188 snprintf(path, sizeof(path), "%s/%s.crt", keydir, (char *)name); 1189 1190 /* Open certificate file */ 1191 f = fopen(path, "r"); 1192 if (!f) { 1193 fprintf(stderr, "Couldn't open RSA certificate: '%s': %s\n", 1194 path, strerror(errno)); 1195 return -EACCES; 1196 } 1197 1198 /* Read the certificate */ 1199 cert = NULL; 1200 if (!PEM_read_X509(f, &cert, NULL, NULL)) { 1201 fprintf(stderr, "Couldn't read certificate"); 1202 ret = -EINVAL; 1203 goto err_cert; 1204 } 1205 1206 /* Get the public key from the certificate. */ 1207 key = X509_get_pubkey(cert); 1208 if (!key) { 1209 fprintf(stderr, "Couldn't read public key\n"); 1210 ret = -EINVAL; 1211 goto err_pubkey; 1212 } 1213 1214 /* Get DER form */ 1215 ret = i2d_PublicKey(key, pubkey); 1216 if (ret < 0) { 1217 fprintf(stderr, "Couldn't get DER form\n"); 1218 ret = -EINVAL; 1219 goto err_pubkey; 1220 } 1221 1222 *pubkey_len = ret; 1223 ret = 0; 1224 1225err_pubkey: 1226 X509_free(cert); 1227err_cert: 1228 fclose(f); 1229 return ret; 1230} 1231 1232int fit_pre_load_data(const char *keydir, void *keydest, void *fit) 1233{ 1234 int pre_load_noffset; 1235 const void *algo_name; 1236 const void *key_name; 1237 unsigned char *pubkey = NULL; 1238 int ret, pubkey_len; 1239 1240 if (!keydir || !keydest || !fit) 1241 return 0; 1242 1243 /* Search node pre-load sig */ 1244 pre_load_noffset = fdt_path_offset(keydest, IMAGE_PRE_LOAD_PATH); 1245 if (pre_load_noffset < 0) { 1246 ret = 0; 1247 goto out; 1248 } 1249 1250 algo_name = fdt_getprop(keydest, pre_load_noffset, "algo-name", NULL); 1251 key_name = fdt_getprop(keydest, pre_load_noffset, "key-name", NULL); 1252 1253 /* Check that all mandatory properties are present */ 1254 if (!algo_name || !key_name) { 1255 if (!algo_name) 1256 fprintf(stderr, "The property algo-name is missing in the node %s\n", 1257 IMAGE_PRE_LOAD_PATH); 1258 if (!key_name) 1259 fprintf(stderr, "The property key-name is missing in the node %s\n", 1260 IMAGE_PRE_LOAD_PATH); 1261 ret = -EINVAL; 1262 goto out; 1263 } 1264 1265 /* Read public key */ 1266 ret = read_pub_key(keydir, key_name, &pubkey, &pubkey_len); 1267 if (ret < 0) 1268 goto out; 1269 1270 /* Add the public key to the device tree */ 1271 ret = fdt_setprop(keydest, pre_load_noffset, "public-key", 1272 pubkey, pubkey_len); 1273 if (ret) 1274 fprintf(stderr, "Can't set public-key in node %s (ret = %d)\n", 1275 IMAGE_PRE_LOAD_PATH, ret); 1276 1277 out: 1278 return ret; 1279} 1280#endif 1281 1282int fit_cipher_data(const char *keydir, void *keydest, void *fit, 1283 const char *comment, int require_keys, 1284 const char *engine_id, const char *cmdname) 1285{ 1286 int images_noffset; 1287 int noffset; 1288 int ret; 1289 1290 /* Find images parent node offset */ 1291 images_noffset = fdt_path_offset(fit, FIT_IMAGES_PATH); 1292 if (images_noffset < 0) { 1293 fprintf(stderr, "Can't find images parent node '%s' (%s)\n", 1294 FIT_IMAGES_PATH, fdt_strerror(images_noffset)); 1295 return images_noffset; 1296 } 1297 1298 /* Process its subnodes, print out component images details */ 1299 for (noffset = fdt_first_subnode(fit, images_noffset); 1300 noffset >= 0; 1301 noffset = fdt_next_subnode(fit, noffset)) { 1302 /* 1303 * Direct child node of the images parent node, 1304 * i.e. component image node. 1305 */ 1306 ret = fit_image_cipher_data(keydir, keydest, 1307 fit, noffset, comment, 1308 require_keys, engine_id, 1309 cmdname); 1310 if (ret) 1311 return ret; 1312 } 1313 1314 return 0; 1315} 1316 1317int fit_add_verification_data(const char *keydir, const char *keyfile, 1318 void *keydest, void *fit, const char *comment, 1319 int require_keys, const char *engine_id, 1320 const char *cmdname, const char *algo_name, 1321 struct image_summary *summary) 1322{ 1323 int images_noffset, confs_noffset; 1324 int noffset; 1325 int ret; 1326 1327 /* Find images parent node offset */ 1328 images_noffset = fdt_path_offset(fit, FIT_IMAGES_PATH); 1329 if (images_noffset < 0) { 1330 fprintf(stderr, "Can't find images parent node '%s' (%s)\n", 1331 FIT_IMAGES_PATH, fdt_strerror(images_noffset)); 1332 return images_noffset; 1333 } 1334 1335 /* Process its subnodes, print out component images details */ 1336 for (noffset = fdt_first_subnode(fit, images_noffset); 1337 noffset >= 0; 1338 noffset = fdt_next_subnode(fit, noffset)) { 1339 /* 1340 * Direct child node of the images parent node, 1341 * i.e. component image node. 1342 */ 1343 ret = fit_image_add_verification_data(keydir, keyfile, keydest, 1344 fit, noffset, comment, require_keys, engine_id, 1345 cmdname, algo_name); 1346 if (ret) { 1347 fprintf(stderr, "Can't add verification data for node '%s' (%s)\n", 1348 fdt_get_name(fit, noffset, NULL), 1349 strerror(-ret)); 1350 return ret; 1351 } 1352 } 1353 1354 /* If there are no keys, we can't sign configurations */ 1355 if (!IMAGE_ENABLE_SIGN || !(keydir || keyfile)) 1356 return 0; 1357 1358 /* Find configurations parent node offset */ 1359 confs_noffset = fdt_path_offset(fit, FIT_CONFS_PATH); 1360 if (confs_noffset < 0) { 1361 fprintf(stderr, "Can't find images parent node '%s' (%s)\n", 1362 FIT_CONFS_PATH, fdt_strerror(confs_noffset)); 1363 return -ENOENT; 1364 } 1365 1366 /* Process its subnodes, print out component images details */ 1367 for (noffset = fdt_first_subnode(fit, confs_noffset); 1368 noffset >= 0; 1369 noffset = fdt_next_subnode(fit, noffset)) { 1370 ret = fit_config_add_verification_data(keydir, keyfile, keydest, 1371 fit, noffset, comment, 1372 require_keys, 1373 engine_id, cmdname, 1374 algo_name, summary); 1375 if (ret) 1376 return ret; 1377 } 1378 1379 return 0; 1380} 1381 1382#ifdef CONFIG_FIT_SIGNATURE 1383int fit_check_sign(const void *fit, const void *key, 1384 const char *fit_uname_config) 1385{ 1386 int cfg_noffset; 1387 int ret; 1388 1389 cfg_noffset = fit_conf_get_node(fit, fit_uname_config); 1390 if (!cfg_noffset) 1391 return -1; 1392 1393 printf("Verifying Hash Integrity for node '%s'... ", 1394 fdt_get_name(fit, cfg_noffset, NULL)); 1395 ret = fit_config_verify(fit, cfg_noffset); 1396 if (ret) 1397 return ret; 1398 printf("Verified OK, loading images\n"); 1399 ret = bootm_host_load_images(fit, cfg_noffset); 1400 1401 return ret; 1402} 1403#endif