1 /* 2 * Copyright (c) 2013-2018, ARM Limited and Contributors. All rights reserved. 3 * 4 * SPDX-License-Identifier: BSD-3-Clause 5 */ 6 7 #include <assert.h> 8 #include <errno.h> 9 #include <string.h> 10 11 #include <arch.h> 12 #include <arch_helpers.h> 13 #include <common/bl_common.h> 14 #include <common/debug.h> 15 #include <drivers/auth/auth_mod.h> 16 #include <drivers/io/io_storage.h> 17 #include <lib/utils.h> 18 #include <lib/xlat_tables/xlat_tables_defs.h> 19 #include <plat/common/platform.h> 20 21 #if TRUSTED_BOARD_BOOT 22 # ifdef DYN_DISABLE_AUTH 23 static int disable_auth; 24 25 /****************************************************************************** 26 * API to dynamically disable authentication. Only meant for development 27 * systems. This is only invoked if DYN_DISABLE_AUTH is defined. 28 *****************************************************************************/ 29 void dyn_disable_auth(void) 30 { 31 INFO("Disabling authentication of images dynamically\n"); 32 disable_auth = 1; 33 } 34 # endif /* DYN_DISABLE_AUTH */ 35 36 /****************************************************************************** 37 * Function to determine whether the authentication is disabled dynamically. 38 *****************************************************************************/ 39 static int dyn_is_auth_disabled(void) 40 { 41 # ifdef DYN_DISABLE_AUTH 42 return disable_auth; 43 # else 44 return 0; 45 # endif 46 } 47 #endif /* TRUSTED_BOARD_BOOT */ 48 49 uintptr_t page_align(uintptr_t value, unsigned dir) 50 { 51 /* Round up the limit to the next page boundary */ 52 if ((value & (PAGE_SIZE - 1U)) != 0U) { 53 value &= ~(PAGE_SIZE - 1U); 54 if (dir == UP) 55 value += PAGE_SIZE; 56 } 57 58 return value; 59 } 60 61 /****************************************************************************** 62 * Determine whether the memory region delimited by 'addr' and 'size' is free, 63 * given the extents of free memory. 64 * Return 1 if it is free, 0 if it is not free or if the input values are 65 * invalid. 66 *****************************************************************************/ 67 int is_mem_free(uintptr_t free_base, size_t free_size, 68 uintptr_t addr, size_t size) 69 { 70 uintptr_t free_end, requested_end; 71 72 /* 73 * Handle corner cases first. 74 * 75 * The order of the 2 tests is important, because if there's no space 76 * left (i.e. free_size == 0) but we don't ask for any memory 77 * (i.e. size == 0) then we should report that the memory is free. 78 */ 79 if (size == 0) 80 return 1; /* A zero-byte region is always free */ 81 if (free_size == 0) 82 return 0; 83 84 /* 85 * Check that the end addresses don't overflow. 86 * If they do, consider that this memory region is not free, as this 87 * is an invalid scenario. 88 */ 89 if (check_uptr_overflow(free_base, free_size - 1)) 90 return 0; 91 free_end = free_base + (free_size - 1); 92 93 if (check_uptr_overflow(addr, size - 1)) 94 return 0; 95 requested_end = addr + (size - 1); 96 97 /* 98 * Finally, check that the requested memory region lies within the free 99 * region. 100 */ 101 return (addr >= free_base) && (requested_end <= free_end); 102 } 103 104 /* Generic function to return the size of an image */ 105 size_t get_image_size(unsigned int image_id) 106 { 107 uintptr_t dev_handle; 108 uintptr_t image_handle; 109 uintptr_t image_spec; 110 size_t image_size = 0U; 111 int io_result; 112 113 /* Obtain a reference to the image by querying the platform layer */ 114 io_result = plat_get_image_source(image_id, &dev_handle, &image_spec); 115 if (io_result != 0) { 116 WARN("Failed to obtain reference to image id=%u (%i)\n", 117 image_id, io_result); 118 return 0; 119 } 120 121 /* Attempt to access the image */ 122 io_result = io_open(dev_handle, image_spec, &image_handle); 123 if (io_result != 0) { 124 WARN("Failed to access image id=%u (%i)\n", 125 image_id, io_result); 126 return 0; 127 } 128 129 /* Find the size of the image */ 130 io_result = io_size(image_handle, &image_size); 131 if ((io_result != 0) || (image_size == 0U)) { 132 WARN("Failed to determine the size of the image id=%u (%i)\n", 133 image_id, io_result); 134 } 135 io_result = io_close(image_handle); 136 /* Ignore improbable/unrecoverable error in 'close' */ 137 138 /* TODO: Consider maintaining open device connection from this 139 * bootloader stage 140 */ 141 io_result = io_dev_close(dev_handle); 142 /* Ignore improbable/unrecoverable error in 'dev_close' */ 143 144 return image_size; 145 } 146 147 /******************************************************************************* 148 * Internal function to load an image at a specific address given 149 * an image ID and extents of free memory. 150 * 151 * If the load is successful then the image information is updated. 152 * 153 * Returns 0 on success, a negative error code otherwise. 154 ******************************************************************************/ 155 static int load_image(unsigned int image_id, image_info_t *image_data) 156 { 157 uintptr_t dev_handle; 158 uintptr_t image_handle; 159 uintptr_t image_spec; 160 uintptr_t image_base; 161 size_t image_size; 162 size_t bytes_read; 163 int io_result; 164 165 assert(image_data != NULL); 166 assert(image_data->h.version >= VERSION_2); 167 168 image_base = image_data->image_base; 169 170 /* Obtain a reference to the image by querying the platform layer */ 171 io_result = plat_get_image_source(image_id, &dev_handle, &image_spec); 172 if (io_result != 0) { 173 WARN("Failed to obtain reference to image id=%u (%i)\n", 174 image_id, io_result); 175 return io_result; 176 } 177 178 /* Attempt to access the image */ 179 io_result = io_open(dev_handle, image_spec, &image_handle); 180 if (io_result != 0) { 181 WARN("Failed to access image id=%u (%i)\n", 182 image_id, io_result); 183 return io_result; 184 } 185 186 INFO("Loading image id=%u at address 0x%lx\n", image_id, image_base); 187 188 /* Find the size of the image */ 189 io_result = io_size(image_handle, &image_size); 190 if ((io_result != 0) || (image_size == 0U)) { 191 WARN("Failed to determine the size of the image id=%u (%i)\n", 192 image_id, io_result); 193 goto exit; 194 } 195 196 /* Check that the image size to load is within limit */ 197 if (image_size > image_data->image_max_size) { 198 WARN("Image id=%u size out of bounds\n", image_id); 199 io_result = -EFBIG; 200 goto exit; 201 } 202 203 /* 204 * image_data->image_max_size is a uint32_t so image_size will always 205 * fit in image_data->image_size. 206 */ 207 image_data->image_size = (uint32_t)image_size; 208 209 /* We have enough space so load the image now */ 210 /* TODO: Consider whether to try to recover/retry a partially successful read */ 211 io_result = io_read(image_handle, image_base, image_size, &bytes_read); 212 if ((io_result != 0) || (bytes_read < image_size)) { 213 WARN("Failed to load image id=%u (%i)\n", image_id, io_result); 214 goto exit; 215 } 216 217 INFO("Image id=%u loaded: 0x%lx - 0x%lx\n", image_id, image_base, 218 (uintptr_t)(image_base + image_size)); 219 220 exit: 221 (void)io_close(image_handle); 222 /* Ignore improbable/unrecoverable error in 'close' */ 223 224 /* TODO: Consider maintaining open device connection from this bootloader stage */ 225 (void)io_dev_close(dev_handle); 226 /* Ignore improbable/unrecoverable error in 'dev_close' */ 227 228 return io_result; 229 } 230 231 static int load_auth_image_internal(unsigned int image_id, 232 image_info_t *image_data, 233 int is_parent_image) 234 { 235 int rc; 236 237 #if TRUSTED_BOARD_BOOT 238 if (dyn_is_auth_disabled() == 0) { 239 unsigned int parent_id; 240 241 /* Use recursion to authenticate parent images */ 242 rc = auth_mod_get_parent_id(image_id, &parent_id); 243 if (rc == 0) { 244 rc = load_auth_image_internal(parent_id, image_data, 1); 245 if (rc != 0) { 246 return rc; 247 } 248 } 249 } 250 #endif /* TRUSTED_BOARD_BOOT */ 251 252 /* Load the image */ 253 rc = load_image(image_id, image_data); 254 if (rc != 0) { 255 return rc; 256 } 257 258 #if TRUSTED_BOARD_BOOT 259 if (dyn_is_auth_disabled() == 0) { 260 /* Authenticate it */ 261 rc = auth_mod_verify_img(image_id, 262 (void *)image_data->image_base, 263 image_data->image_size); 264 if (rc != 0) { 265 /* Authentication error, zero memory and flush it right away. */ 266 zero_normalmem((void *)image_data->image_base, 267 image_data->image_size); 268 flush_dcache_range(image_data->image_base, 269 image_data->image_size); 270 return -EAUTH; 271 } 272 } 273 #endif /* TRUSTED_BOARD_BOOT */ 274 275 /* 276 * Flush the image to main memory so that it can be executed later by 277 * any CPU, regardless of cache and MMU state. If TBB is enabled, then 278 * the file has been successfully loaded and authenticated and flush 279 * only for child images, not for the parents (certificates). 280 */ 281 if (is_parent_image == 0) { 282 flush_dcache_range(image_data->image_base, 283 image_data->image_size); 284 } 285 286 287 return 0; 288 } 289 290 /******************************************************************************* 291 * Generic function to load and authenticate an image. The image is actually 292 * loaded by calling the 'load_image()' function. Therefore, it returns the 293 * same error codes if the loading operation failed, or -EAUTH if the 294 * authentication failed. In addition, this function uses recursion to 295 * authenticate the parent images up to the root of trust. 296 ******************************************************************************/ 297 int load_auth_image(unsigned int image_id, image_info_t *image_data) 298 { 299 int err; 300 301 do { 302 err = load_auth_image_internal(image_id, image_data, 0); 303 } while ((err != 0) && (plat_try_next_boot_source() != 0)); 304 305 return err; 306 } 307 308 /******************************************************************************* 309 * Print the content of an entry_point_info_t structure. 310 ******************************************************************************/ 311 void print_entry_point_info(const entry_point_info_t *ep_info) 312 { 313 INFO("Entry point address = 0x%lx\n", ep_info->pc); 314 INFO("SPSR = 0x%x\n", ep_info->spsr); 315 316 #define PRINT_IMAGE_ARG(n) \ 317 VERBOSE("Argument #" #n " = 0x%llx\n", \ 318 (unsigned long long) ep_info->args.arg##n) 319 320 PRINT_IMAGE_ARG(0); 321 PRINT_IMAGE_ARG(1); 322 PRINT_IMAGE_ARG(2); 323 PRINT_IMAGE_ARG(3); 324 #ifndef AARCH32 325 PRINT_IMAGE_ARG(4); 326 PRINT_IMAGE_ARG(5); 327 PRINT_IMAGE_ARG(6); 328 PRINT_IMAGE_ARG(7); 329 #endif 330 #undef PRINT_IMAGE_ARG 331 } 332