bl_common.c 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280
  1. /*
  2. * Copyright (c) 2013-2022, Arm Limited and Contributors. All rights reserved.
  3. *
  4. * SPDX-License-Identifier: BSD-3-Clause
  5. */
  6. #include <assert.h>
  7. #include <errno.h>
  8. #include <string.h>
  9. #include <arch.h>
  10. #include <arch_features.h>
  11. #include <arch_helpers.h>
  12. #include <common/bl_common.h>
  13. #include <common/debug.h>
  14. #include <drivers/auth/auth_mod.h>
  15. #include <drivers/io/io_storage.h>
  16. #include <lib/utils.h>
  17. #include <lib/xlat_tables/xlat_tables_defs.h>
  18. #include <plat/common/platform.h>
  19. #if TRUSTED_BOARD_BOOT
  20. # ifdef DYN_DISABLE_AUTH
  21. static int disable_auth;
  22. /******************************************************************************
  23. * API to dynamically disable authentication. Only meant for development
  24. * systems. This is only invoked if DYN_DISABLE_AUTH is defined.
  25. *****************************************************************************/
  26. void dyn_disable_auth(void)
  27. {
  28. INFO("Disabling authentication of images dynamically\n");
  29. disable_auth = 1;
  30. }
  31. # endif /* DYN_DISABLE_AUTH */
  32. /******************************************************************************
  33. * Function to determine whether the authentication is disabled dynamically.
  34. *****************************************************************************/
  35. static int dyn_is_auth_disabled(void)
  36. {
  37. # ifdef DYN_DISABLE_AUTH
  38. return disable_auth;
  39. # else
  40. return 0;
  41. # endif
  42. }
  43. #endif /* TRUSTED_BOARD_BOOT */
  44. uintptr_t page_align(uintptr_t value, unsigned dir)
  45. {
  46. /* Round up the limit to the next page boundary */
  47. if ((value & PAGE_SIZE_MASK) != 0U) {
  48. value &= ~PAGE_SIZE_MASK;
  49. if (dir == UP)
  50. value += PAGE_SIZE;
  51. }
  52. return value;
  53. }
  54. /*******************************************************************************
  55. * Internal function to load an image at a specific address given
  56. * an image ID and extents of free memory.
  57. *
  58. * If the load is successful then the image information is updated.
  59. *
  60. * Returns 0 on success, a negative error code otherwise.
  61. ******************************************************************************/
  62. static int load_image(unsigned int image_id, image_info_t *image_data)
  63. {
  64. uintptr_t dev_handle;
  65. uintptr_t image_handle;
  66. uintptr_t image_spec;
  67. uintptr_t image_base;
  68. size_t image_size;
  69. size_t bytes_read;
  70. int io_result;
  71. assert(image_data != NULL);
  72. assert(image_data->h.version >= VERSION_2);
  73. image_base = image_data->image_base;
  74. /* Obtain a reference to the image by querying the platform layer */
  75. io_result = plat_get_image_source(image_id, &dev_handle, &image_spec);
  76. if (io_result != 0) {
  77. WARN("Failed to obtain reference to image id=%u (%i)\n",
  78. image_id, io_result);
  79. return io_result;
  80. }
  81. /* Attempt to access the image */
  82. io_result = io_open(dev_handle, image_spec, &image_handle);
  83. if (io_result != 0) {
  84. WARN("Failed to access image id=%u (%i)\n",
  85. image_id, io_result);
  86. return io_result;
  87. }
  88. INFO("Loading image id=%u at address 0x%lx\n", image_id, image_base);
  89. /* Find the size of the image */
  90. io_result = io_size(image_handle, &image_size);
  91. if ((io_result != 0) || (image_size == 0U)) {
  92. WARN("Failed to determine the size of the image id=%u (%i)\n",
  93. image_id, io_result);
  94. goto exit;
  95. }
  96. /* Check that the image size to load is within limit */
  97. if (image_size > image_data->image_max_size) {
  98. WARN("Image id=%u size out of bounds\n", image_id);
  99. io_result = -EFBIG;
  100. goto exit;
  101. }
  102. /*
  103. * image_data->image_max_size is a uint32_t so image_size will always
  104. * fit in image_data->image_size.
  105. */
  106. image_data->image_size = (uint32_t)image_size;
  107. /* We have enough space so load the image now */
  108. /* TODO: Consider whether to try to recover/retry a partially successful read */
  109. io_result = io_read(image_handle, image_base, image_size, &bytes_read);
  110. if ((io_result != 0) || (bytes_read < image_size)) {
  111. WARN("Failed to load image id=%u (%i)\n", image_id, io_result);
  112. goto exit;
  113. }
  114. INFO("Image id=%u loaded: 0x%lx - 0x%lx\n", image_id, image_base,
  115. (uintptr_t)(image_base + image_size));
  116. exit:
  117. (void)io_close(image_handle);
  118. /* Ignore improbable/unrecoverable error in 'close' */
  119. /* TODO: Consider maintaining open device connection from this bootloader stage */
  120. (void)io_dev_close(dev_handle);
  121. /* Ignore improbable/unrecoverable error in 'dev_close' */
  122. return io_result;
  123. }
  124. #if TRUSTED_BOARD_BOOT
  125. /*
  126. * This function uses recursion to authenticate the parent images up to the root
  127. * of trust.
  128. */
  129. static int load_auth_image_recursive(unsigned int image_id,
  130. image_info_t *image_data,
  131. int is_parent_image)
  132. {
  133. int rc;
  134. unsigned int parent_id;
  135. /* Use recursion to authenticate parent images */
  136. rc = auth_mod_get_parent_id(image_id, &parent_id);
  137. if (rc == 0) {
  138. rc = load_auth_image_recursive(parent_id, image_data, 1);
  139. if (rc != 0) {
  140. return rc;
  141. }
  142. }
  143. /* Load the image */
  144. rc = load_image(image_id, image_data);
  145. if (rc != 0) {
  146. return rc;
  147. }
  148. /* Authenticate it */
  149. rc = auth_mod_verify_img(image_id,
  150. (void *)image_data->image_base,
  151. image_data->image_size);
  152. if (rc != 0) {
  153. /* Authentication error, zero memory and flush it right away. */
  154. zero_normalmem((void *)image_data->image_base,
  155. image_data->image_size);
  156. flush_dcache_range(image_data->image_base,
  157. image_data->image_size);
  158. return -EAUTH;
  159. }
  160. return 0;
  161. }
  162. #endif /* TRUSTED_BOARD_BOOT */
  163. static int load_auth_image_internal(unsigned int image_id,
  164. image_info_t *image_data)
  165. {
  166. #if TRUSTED_BOARD_BOOT
  167. if (dyn_is_auth_disabled() == 0) {
  168. return load_auth_image_recursive(image_id, image_data, 0);
  169. }
  170. #endif
  171. return load_image(image_id, image_data);
  172. }
  173. /*******************************************************************************
  174. * Generic function to load and authenticate an image. The image is actually
  175. * loaded by calling the 'load_image()' function. Therefore, it returns the
  176. * same error codes if the loading operation failed, or -EAUTH if the
  177. * authentication failed. In addition, this function uses recursion to
  178. * authenticate the parent images up to the root of trust (if TBB is enabled).
  179. ******************************************************************************/
  180. int load_auth_image(unsigned int image_id, image_info_t *image_data)
  181. {
  182. int err;
  183. /*
  184. * All firmware banks should be part of the same non-volatile storage as per
  185. * PSA FWU specification, hence don't check for any alternate boot source
  186. * when PSA FWU is enabled.
  187. */
  188. #if PSA_FWU_SUPPORT
  189. err = load_auth_image_internal(image_id, image_data);
  190. #else
  191. do {
  192. err = load_auth_image_internal(image_id, image_data);
  193. } while ((err != 0) && (plat_try_next_boot_source() != 0));
  194. #endif /* PSA_FWU_SUPPORT */
  195. if (err == 0) {
  196. /*
  197. * If loading of the image gets passed (along with its
  198. * authentication in case of Trusted-Boot flow) then measure
  199. * it (if MEASURED_BOOT flag is enabled).
  200. */
  201. err = plat_mboot_measure_image(image_id, image_data);
  202. if (err != 0) {
  203. return err;
  204. }
  205. /*
  206. * Flush the image to main memory so that it can be executed
  207. * later by any CPU, regardless of cache and MMU state.
  208. */
  209. flush_dcache_range(image_data->image_base,
  210. image_data->image_size);
  211. }
  212. return err;
  213. }
  214. /*******************************************************************************
  215. * Print the content of an entry_point_info_t structure.
  216. ******************************************************************************/
  217. void print_entry_point_info(const entry_point_info_t *ep_info)
  218. {
  219. INFO("Entry point address = 0x%lx\n", ep_info->pc);
  220. INFO("SPSR = 0x%x\n", ep_info->spsr);
  221. #define PRINT_IMAGE_ARG(n) \
  222. VERBOSE("Argument #" #n " = 0x%llx\n", \
  223. (unsigned long long) ep_info->args.arg##n)
  224. PRINT_IMAGE_ARG(0);
  225. PRINT_IMAGE_ARG(1);
  226. PRINT_IMAGE_ARG(2);
  227. PRINT_IMAGE_ARG(3);
  228. #ifdef __aarch64__
  229. PRINT_IMAGE_ARG(4);
  230. PRINT_IMAGE_ARG(5);
  231. PRINT_IMAGE_ARG(6);
  232. PRINT_IMAGE_ARG(7);
  233. #endif
  234. #undef PRINT_IMAGE_ARG
  235. }
  236. /*
  237. * This function is for returning the TF-A version
  238. */
  239. const char *get_version(void)
  240. {
  241. extern const char version[];
  242. return version;
  243. }