image-sig.c 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  1. /*
  2. * Copyright (c) 2013, Google Inc.
  3. *
  4. * This program is free software; you can redistribute it and/or
  5. * modify it under the terms of the GNU General Public License as
  6. * published by the Free Software Foundation; either version 2 of
  7. * the License, or (at your option) any later version.
  8. *
  9. * This program is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. * GNU General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU General Public License
  15. * along with this program; if not, write to the Free Software
  16. * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  17. * MA 02111-1307 USA
  18. */
  19. #ifdef USE_HOSTCC
  20. #include "mkimage.h"
  21. #include <time.h>
  22. #else
  23. #include <common.h>
  24. #include <malloc.h>
  25. DECLARE_GLOBAL_DATA_PTR;
  26. #endif /* !USE_HOSTCC*/
  27. #include <errno.h>
  28. #include <image.h>
  29. #include <rsa.h>
  30. struct image_sig_algo image_sig_algos[] = {
  31. {
  32. "sha1,rsa2048",
  33. rsa_sign,
  34. rsa_add_verify_data,
  35. rsa_verify,
  36. }
  37. };
  38. struct image_sig_algo *image_get_sig_algo(const char *name)
  39. {
  40. int i;
  41. for (i = 0; i < ARRAY_SIZE(image_sig_algos); i++) {
  42. if (!strcmp(image_sig_algos[i].name, name))
  43. return &image_sig_algos[i];
  44. }
  45. return NULL;
  46. }
  47. static int fit_image_setup_verify(struct image_sign_info *info,
  48. const void *fit, int noffset, int required_keynode,
  49. char **err_msgp)
  50. {
  51. char *algo_name;
  52. if (fit_image_hash_get_algo(fit, noffset, &algo_name)) {
  53. *err_msgp = "Can't get hash algo property";
  54. return -1;
  55. }
  56. memset(info, '\0', sizeof(*info));
  57. info->keyname = fdt_getprop(fit, noffset, "key-name-hint", NULL);
  58. info->fit = (void *)fit;
  59. info->node_offset = noffset;
  60. info->algo = image_get_sig_algo(algo_name);
  61. info->fdt_blob = gd_fdt_blob();
  62. info->required_keynode = required_keynode;
  63. printf("%s:%s", algo_name, info->keyname);
  64. if (!info->algo) {
  65. *err_msgp = "Unknown signature algorithm";
  66. return -1;
  67. }
  68. return 0;
  69. }
  70. int fit_image_check_sig(const void *fit, int noffset, const void *data,
  71. size_t size, int required_keynode, char **err_msgp)
  72. {
  73. struct image_sign_info info;
  74. struct image_region region;
  75. uint8_t *fit_value;
  76. int fit_value_len;
  77. *err_msgp = NULL;
  78. if (fit_image_setup_verify(&info, fit, noffset, required_keynode,
  79. err_msgp))
  80. return -1;
  81. if (fit_image_hash_get_value(fit, noffset, &fit_value,
  82. &fit_value_len)) {
  83. *err_msgp = "Can't get hash value property";
  84. return -1;
  85. }
  86. region.data = data;
  87. region.size = size;
  88. if (info.algo->verify(&info, &region, 1, fit_value, fit_value_len)) {
  89. *err_msgp = "Verification failed";
  90. return -1;
  91. }
  92. return 0;
  93. }
  94. static int fit_image_verify_sig(const void *fit, int image_noffset,
  95. const char *data, size_t size, const void *sig_blob,
  96. int sig_offset)
  97. {
  98. int noffset;
  99. char *err_msg = "";
  100. int verified = 0;
  101. int ret;
  102. /* Process all hash subnodes of the component image node */
  103. for (noffset = fdt_first_subnode(fit, image_noffset);
  104. noffset >= 0;
  105. noffset = fdt_next_subnode(fit, noffset)) {
  106. const char *name = fit_get_name(fit, noffset, NULL);
  107. if (!strncmp(name, FIT_SIG_NODENAME,
  108. strlen(FIT_SIG_NODENAME))) {
  109. ret = fit_image_check_sig(fit, noffset, data,
  110. size, -1, &err_msg);
  111. if (ret) {
  112. puts("- ");
  113. } else {
  114. puts("+ ");
  115. verified = 1;
  116. break;
  117. }
  118. }
  119. }
  120. if (noffset == -FDT_ERR_TRUNCATED || noffset == -FDT_ERR_BADSTRUCTURE) {
  121. err_msg = "Corrupted or truncated tree";
  122. goto error;
  123. }
  124. return verified ? 0 : -EPERM;
  125. error:
  126. printf(" error!\n%s for '%s' hash node in '%s' image node\n",
  127. err_msg, fit_get_name(fit, noffset, NULL),
  128. fit_get_name(fit, image_noffset, NULL));
  129. return -1;
  130. }
  131. int fit_image_verify_required_sigs(const void *fit, int image_noffset,
  132. const char *data, size_t size, const void *sig_blob,
  133. int *no_sigsp)
  134. {
  135. int verify_count = 0;
  136. int noffset;
  137. int sig_node;
  138. /* Work out what we need to verify */
  139. *no_sigsp = 1;
  140. sig_node = fdt_subnode_offset(sig_blob, 0, FIT_SIG_NODENAME);
  141. if (sig_node < 0) {
  142. debug("%s: No signature node found: %s\n", __func__,
  143. fdt_strerror(sig_node));
  144. return 0;
  145. }
  146. for (noffset = fdt_first_subnode(sig_blob, sig_node);
  147. noffset >= 0;
  148. noffset = fdt_next_subnode(sig_blob, noffset)) {
  149. const char *required;
  150. int ret;
  151. required = fdt_getprop(sig_blob, noffset, "required", NULL);
  152. if (!required || strcmp(required, "image"))
  153. continue;
  154. ret = fit_image_verify_sig(fit, image_noffset, data, size,
  155. sig_blob, noffset);
  156. if (ret) {
  157. printf("Failed to verify required signature '%s'\n",
  158. fit_get_name(sig_blob, noffset, NULL));
  159. return ret;
  160. }
  161. verify_count++;
  162. }
  163. if (verify_count)
  164. *no_sigsp = 0;
  165. return 0;
  166. }