image-sig.c 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186
  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. struct image_sig_algo image_sig_algos[] = {
  30. };
  31. struct image_sig_algo *image_get_sig_algo(const char *name)
  32. {
  33. int i;
  34. for (i = 0; i < ARRAY_SIZE(image_sig_algos); i++) {
  35. if (!strcmp(image_sig_algos[i].name, name))
  36. return &image_sig_algos[i];
  37. }
  38. return NULL;
  39. }
  40. static int fit_image_setup_verify(struct image_sign_info *info,
  41. const void *fit, int noffset, int required_keynode,
  42. char **err_msgp)
  43. {
  44. char *algo_name;
  45. if (fit_image_hash_get_algo(fit, noffset, &algo_name)) {
  46. *err_msgp = "Can't get hash algo property";
  47. return -1;
  48. }
  49. memset(info, '\0', sizeof(*info));
  50. info->keyname = fdt_getprop(fit, noffset, "key-name-hint", NULL);
  51. info->fit = (void *)fit;
  52. info->node_offset = noffset;
  53. info->algo = image_get_sig_algo(algo_name);
  54. info->fdt_blob = gd_fdt_blob();
  55. info->required_keynode = required_keynode;
  56. printf("%s:%s", algo_name, info->keyname);
  57. if (!info->algo) {
  58. *err_msgp = "Unknown signature algorithm";
  59. return -1;
  60. }
  61. return 0;
  62. }
  63. int fit_image_check_sig(const void *fit, int noffset, const void *data,
  64. size_t size, int required_keynode, char **err_msgp)
  65. {
  66. struct image_sign_info info;
  67. struct image_region region;
  68. uint8_t *fit_value;
  69. int fit_value_len;
  70. *err_msgp = NULL;
  71. if (fit_image_setup_verify(&info, fit, noffset, required_keynode,
  72. err_msgp))
  73. return -1;
  74. if (fit_image_hash_get_value(fit, noffset, &fit_value,
  75. &fit_value_len)) {
  76. *err_msgp = "Can't get hash value property";
  77. return -1;
  78. }
  79. region.data = data;
  80. region.size = size;
  81. if (info.algo->verify(&info, &region, 1, fit_value, fit_value_len)) {
  82. *err_msgp = "Verification failed";
  83. return -1;
  84. }
  85. return 0;
  86. }
  87. static int fit_image_verify_sig(const void *fit, int image_noffset,
  88. const char *data, size_t size, const void *sig_blob,
  89. int sig_offset)
  90. {
  91. int noffset;
  92. char *err_msg = "";
  93. int verified = 0;
  94. int ret;
  95. /* Process all hash subnodes of the component image node */
  96. for (noffset = fdt_first_subnode(fit, image_noffset);
  97. noffset >= 0;
  98. noffset = fdt_next_subnode(fit, noffset)) {
  99. const char *name = fit_get_name(fit, noffset, NULL);
  100. if (!strncmp(name, FIT_SIG_NODENAME,
  101. strlen(FIT_SIG_NODENAME))) {
  102. ret = fit_image_check_sig(fit, noffset, data,
  103. size, -1, &err_msg);
  104. if (ret) {
  105. puts("- ");
  106. } else {
  107. puts("+ ");
  108. verified = 1;
  109. break;
  110. }
  111. }
  112. }
  113. if (noffset == -FDT_ERR_TRUNCATED || noffset == -FDT_ERR_BADSTRUCTURE) {
  114. err_msg = "Corrupted or truncated tree";
  115. goto error;
  116. }
  117. return verified ? 0 : -EPERM;
  118. error:
  119. printf(" error!\n%s for '%s' hash node in '%s' image node\n",
  120. err_msg, fit_get_name(fit, noffset, NULL),
  121. fit_get_name(fit, image_noffset, NULL));
  122. return -1;
  123. }
  124. int fit_image_verify_required_sigs(const void *fit, int image_noffset,
  125. const char *data, size_t size, const void *sig_blob,
  126. int *no_sigsp)
  127. {
  128. int verify_count = 0;
  129. int noffset;
  130. int sig_node;
  131. /* Work out what we need to verify */
  132. *no_sigsp = 1;
  133. sig_node = fdt_subnode_offset(sig_blob, 0, FIT_SIG_NODENAME);
  134. if (sig_node < 0) {
  135. debug("%s: No signature node found: %s\n", __func__,
  136. fdt_strerror(sig_node));
  137. return 0;
  138. }
  139. for (noffset = fdt_first_subnode(sig_blob, sig_node);
  140. noffset >= 0;
  141. noffset = fdt_next_subnode(sig_blob, noffset)) {
  142. const char *required;
  143. int ret;
  144. required = fdt_getprop(sig_blob, noffset, "required", NULL);
  145. if (!required || strcmp(required, "image"))
  146. continue;
  147. ret = fit_image_verify_sig(fit, image_noffset, data, size,
  148. sig_blob, noffset);
  149. if (ret) {
  150. printf("Failed to verify required signature '%s'\n",
  151. fit_get_name(sig_blob, noffset, NULL));
  152. return ret;
  153. }
  154. verify_count++;
  155. }
  156. if (verify_count)
  157. *no_sigsp = 0;
  158. return 0;
  159. }