fdt_add_pubkey.c 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. // SPDX-License-Identifier: GPL-2.0+
  2. #include <image.h>
  3. #include "fit_common.h"
  4. static const char *cmdname;
  5. static const char *algo_name = "sha1,rsa2048"; /* -a <algo> */
  6. static const char *keydir = "."; /* -k <keydir> */
  7. static const char *keyname = "key"; /* -n <keyname> */
  8. static const char *require_keys; /* -r <conf|image> */
  9. static const char *keydest; /* argv[n] */
  10. static void __attribute__((__noreturn__)) print_usage(const char *msg)
  11. {
  12. fprintf(stderr, "Error: %s\n", msg);
  13. fprintf(stderr, "Usage: %s [-a <algo>] [-k <keydir>] [-n <keyname>] [-r <conf|image>]"
  14. " <fdt blob>\n", cmdname);
  15. fprintf(stderr, "Help information: %s [-h]\n", cmdname);
  16. exit(EXIT_FAILURE);
  17. }
  18. static void __attribute__((__noreturn__)) print_help(void)
  19. {
  20. fprintf(stderr, "Options:\n"
  21. "\t-a <algo> Cryptographic algorithm. Optional parameter, default value: sha1,rsa2048\n"
  22. "\t-k <keydir> Directory with public key. Optional parameter, default value: .\n"
  23. "\t-n <keyname> Public key name. Optional parameter, default value: key\n"
  24. "\t-r <conf|image> Required: If present this indicates that the key must be verified for the image / configuration to be considered valid.\n"
  25. "\t<fdt blob> FDT blob file for adding of the public key. Required parameter.\n");
  26. exit(EXIT_FAILURE);
  27. }
  28. static void process_args(int argc, char *argv[])
  29. {
  30. int opt;
  31. while ((opt = getopt(argc, argv, "a:k:n:r:h")) != -1) {
  32. switch (opt) {
  33. case 'k':
  34. keydir = optarg;
  35. break;
  36. case 'a':
  37. algo_name = optarg;
  38. break;
  39. case 'n':
  40. keyname = optarg;
  41. break;
  42. case 'r':
  43. require_keys = optarg;
  44. break;
  45. case 'h':
  46. print_help();
  47. default:
  48. print_usage("Invalid option");
  49. }
  50. }
  51. /* The last parameter is expected to be the .dtb to add the public key to */
  52. if (optind < argc)
  53. keydest = argv[optind];
  54. if (!keydest)
  55. print_usage("Missing dtb file to update");
  56. }
  57. static void reset_info(struct image_sign_info *info)
  58. {
  59. if (!info)
  60. fprintf(stderr, "Error: info is NULL in %s\n", __func__);
  61. memset(info, 0, sizeof(struct image_sign_info));
  62. info->keydir = keydir;
  63. info->keyname = keyname;
  64. info->name = algo_name;
  65. info->require_keys = require_keys;
  66. info->crypto = image_get_crypto_algo(algo_name);
  67. if (!info->crypto) {
  68. fprintf(stderr, "Unsupported signature algorithm '%s'\n",
  69. algo_name);
  70. exit(EXIT_FAILURE);
  71. }
  72. }
  73. static int add_pubkey(struct image_sign_info *info)
  74. {
  75. int destfd = -1, ret;
  76. void *dest_blob = NULL;
  77. struct stat dest_sbuf;
  78. size_t size_inc = 0;
  79. if (!info)
  80. fprintf(stderr, "Error: info is NULL in %s\n", __func__);
  81. do {
  82. if (destfd >= 0) {
  83. munmap(dest_blob, dest_sbuf.st_size);
  84. close(destfd);
  85. fprintf(stderr, ".dtb too small, increasing size by 1024 bytes\n");
  86. size_inc = 1024;
  87. }
  88. destfd = mmap_fdt(cmdname, keydest, size_inc, &dest_blob,
  89. &dest_sbuf, false, false);
  90. if (destfd < 0)
  91. exit(EXIT_FAILURE);
  92. ret = info->crypto->add_verify_data(info, dest_blob);
  93. if (ret == -ENOSPC)
  94. continue;
  95. else if (ret < 0)
  96. break;
  97. } while (ret == -ENOSPC);
  98. return ret;
  99. }
  100. int main(int argc, char *argv[])
  101. {
  102. struct image_sign_info info;
  103. int ret;
  104. cmdname = argv[0];
  105. process_args(argc, argv);
  106. reset_info(&info);
  107. ret = add_pubkey(&info);
  108. if (ret < 0) {
  109. fprintf(stderr, "%s: Cannot add public key to FIT blob: %s\n",
  110. cmdname, strerror(ret));
  111. exit(EXIT_FAILURE);
  112. }
  113. exit(EXIT_SUCCESS);
  114. }