1 /* 2 * Copyright (c) 2013-2016, ARM Limited and Contributors. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions are met: 6 * 7 * Redistributions of source code must retain the above copyright notice, this 8 * list of conditions and the following disclaimer. 9 * 10 * Redistributions in binary form must reproduce the above copyright notice, 11 * this list of conditions and the following disclaimer in the documentation 12 * and/or other materials provided with the distribution. 13 * 14 * Neither the name of ARM nor the names of its contributors may be used 15 * to endorse or promote products derived from this software without specific 16 * prior written permission. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 22 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 * POSSIBILITY OF SUCH DAMAGE. 29 */ 30 31 #include <arch.h> 32 #include <arch_helpers.h> 33 #include <assert.h> 34 #include <auth_mod.h> 35 #include <bl_common.h> 36 #include <debug.h> 37 #include <errno.h> 38 #include <io_storage.h> 39 #include <platform.h> 40 #include <string.h> 41 #include <utils.h> 42 #include <xlat_tables.h> 43 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 - 1)) { 48 value &= ~(PAGE_SIZE - 1); 49 if (dir == UP) 50 value += PAGE_SIZE; 51 } 52 53 return value; 54 } 55 56 static inline unsigned int is_page_aligned (uintptr_t addr) { 57 return (addr & (PAGE_SIZE - 1)) == 0; 58 } 59 60 /****************************************************************************** 61 * Determine whether the memory region delimited by 'addr' and 'size' is free, 62 * given the extents of free memory. 63 * Return 1 if it is free, 0 if it is not free or if the input values are 64 * invalid. 65 *****************************************************************************/ 66 static int is_mem_free(uintptr_t free_base, size_t free_size, 67 uintptr_t addr, size_t size) 68 { 69 uintptr_t free_end, requested_end; 70 71 /* 72 * Handle corner cases first. 73 * 74 * The order of the 2 tests is important, because if there's no space 75 * left (i.e. free_size == 0) but we don't ask for any memory 76 * (i.e. size == 0) then we should report that the memory is free. 77 */ 78 if (size == 0) 79 return 1; /* A zero-byte region is always free */ 80 if (free_size == 0) 81 return 0; 82 83 /* 84 * Check that the end addresses don't overflow. 85 * If they do, consider that this memory region is not free, as this 86 * is an invalid scenario. 87 */ 88 if (check_uptr_overflow(free_base, free_size - 1)) 89 return 0; 90 free_end = free_base + (free_size - 1); 91 92 if (check_uptr_overflow(addr, size - 1)) 93 return 0; 94 requested_end = addr + (size - 1); 95 96 /* 97 * Finally, check that the requested memory region lies within the free 98 * region. 99 */ 100 return (addr >= free_base) && (requested_end <= free_end); 101 } 102 103 /****************************************************************************** 104 * Inside a given memory region, determine whether a sub-region of memory is 105 * closer from the top or the bottom of the encompassing region. Return the 106 * size of the smallest chunk of free memory surrounding the sub-region in 107 * 'small_chunk_size'. 108 *****************************************************************************/ 109 static unsigned int choose_mem_pos(uintptr_t mem_start, uintptr_t mem_end, 110 uintptr_t submem_start, uintptr_t submem_end, 111 size_t *small_chunk_size) 112 { 113 size_t top_chunk_size, bottom_chunk_size; 114 115 assert(mem_start <= submem_start); 116 assert(submem_start <= submem_end); 117 assert(submem_end <= mem_end); 118 assert(small_chunk_size != NULL); 119 120 top_chunk_size = mem_end - submem_end; 121 bottom_chunk_size = submem_start - mem_start; 122 123 if (top_chunk_size < bottom_chunk_size) { 124 *small_chunk_size = top_chunk_size; 125 return TOP; 126 } else { 127 *small_chunk_size = bottom_chunk_size; 128 return BOTTOM; 129 } 130 } 131 132 /****************************************************************************** 133 * Reserve the memory region delimited by 'addr' and 'size'. The extents of free 134 * memory are passed in 'free_base' and 'free_size' and they will be updated to 135 * reflect the memory usage. 136 * The caller must ensure the memory to reserve is free and that the addresses 137 * and sizes passed in arguments are sane. 138 *****************************************************************************/ 139 void reserve_mem(uintptr_t *free_base, size_t *free_size, 140 uintptr_t addr, size_t size) 141 { 142 size_t discard_size; 143 size_t reserved_size; 144 unsigned int pos; 145 146 assert(free_base != NULL); 147 assert(free_size != NULL); 148 assert(is_mem_free(*free_base, *free_size, addr, size)); 149 150 if (size == 0) { 151 WARN("Nothing to allocate, requested size is zero\n"); 152 return; 153 } 154 155 pos = choose_mem_pos(*free_base, *free_base + (*free_size - 1), 156 addr, addr + (size - 1), 157 &discard_size); 158 159 reserved_size = size + discard_size; 160 *free_size -= reserved_size; 161 162 if (pos == BOTTOM) 163 *free_base = addr + size; 164 165 VERBOSE("Reserved 0x%zx bytes (discarded 0x%zx bytes %s)\n", 166 reserved_size, discard_size, 167 pos == TOP ? "above" : "below"); 168 } 169 170 static void dump_load_info(uintptr_t image_load_addr, 171 size_t image_size, 172 const meminfo_t *mem_layout) 173 { 174 INFO("Trying to load image at address %p, size = 0x%zx\n", 175 (void *)image_load_addr, image_size); 176 INFO("Current memory layout:\n"); 177 INFO(" total region = [base = %p, size = 0x%zx]\n", 178 (void *) mem_layout->total_base, mem_layout->total_size); 179 INFO(" free region = [base = %p, size = 0x%zx]\n", 180 (void *) mem_layout->free_base, mem_layout->free_size); 181 } 182 183 /* Generic function to return the size of an image */ 184 size_t image_size(unsigned int image_id) 185 { 186 uintptr_t dev_handle; 187 uintptr_t image_handle; 188 uintptr_t image_spec; 189 size_t image_size = 0; 190 int io_result; 191 192 /* Obtain a reference to the image by querying the platform layer */ 193 io_result = plat_get_image_source(image_id, &dev_handle, &image_spec); 194 if (io_result != 0) { 195 WARN("Failed to obtain reference to image id=%u (%i)\n", 196 image_id, io_result); 197 return 0; 198 } 199 200 /* Attempt to access the image */ 201 io_result = io_open(dev_handle, image_spec, &image_handle); 202 if (io_result != 0) { 203 WARN("Failed to access image id=%u (%i)\n", 204 image_id, io_result); 205 return 0; 206 } 207 208 /* Find the size of the image */ 209 io_result = io_size(image_handle, &image_size); 210 if ((io_result != 0) || (image_size == 0)) { 211 WARN("Failed to determine the size of the image id=%u (%i)\n", 212 image_id, io_result); 213 } 214 io_result = io_close(image_handle); 215 /* Ignore improbable/unrecoverable error in 'close' */ 216 217 /* TODO: Consider maintaining open device connection from this 218 * bootloader stage 219 */ 220 io_result = io_dev_close(dev_handle); 221 /* Ignore improbable/unrecoverable error in 'dev_close' */ 222 223 return image_size; 224 } 225 226 /******************************************************************************* 227 * Generic function to load an image at a specific address given an image ID and 228 * extents of free memory. 229 * 230 * If the load is successful then the image information is updated. 231 * 232 * If the entry_point_info argument is not NULL then this function also updates: 233 * - the memory layout to mark the memory as reserved; 234 * - the entry point information. 235 * 236 * The caller might pass a NULL pointer for the entry point if they are not 237 * interested in this information. This is typically the case for non-executable 238 * images (e.g. certificates) and executable images that won't ever be executed 239 * on the application processor (e.g. additional microcontroller firmware). 240 * 241 * Returns 0 on success, a negative error code otherwise. 242 ******************************************************************************/ 243 int load_image(meminfo_t *mem_layout, 244 unsigned int image_id, 245 uintptr_t image_base, 246 image_info_t *image_data, 247 entry_point_info_t *entry_point_info) 248 { 249 uintptr_t dev_handle; 250 uintptr_t image_handle; 251 uintptr_t image_spec; 252 size_t image_size; 253 size_t bytes_read; 254 int io_result; 255 256 assert(mem_layout != NULL); 257 assert(image_data != NULL); 258 assert(image_data->h.version >= VERSION_1); 259 260 /* Obtain a reference to the image by querying the platform layer */ 261 io_result = plat_get_image_source(image_id, &dev_handle, &image_spec); 262 if (io_result != 0) { 263 WARN("Failed to obtain reference to image id=%u (%i)\n", 264 image_id, io_result); 265 return io_result; 266 } 267 268 /* Attempt to access the image */ 269 io_result = io_open(dev_handle, image_spec, &image_handle); 270 if (io_result != 0) { 271 WARN("Failed to access image id=%u (%i)\n", 272 image_id, io_result); 273 return io_result; 274 } 275 276 INFO("Loading image id=%u at address %p\n", image_id, 277 (void *) image_base); 278 279 /* Find the size of the image */ 280 io_result = io_size(image_handle, &image_size); 281 if ((io_result != 0) || (image_size == 0)) { 282 WARN("Failed to determine the size of the image id=%u (%i)\n", 283 image_id, io_result); 284 goto exit; 285 } 286 287 /* Check that the memory where the image will be loaded is free */ 288 if (!is_mem_free(mem_layout->free_base, mem_layout->free_size, 289 image_base, image_size)) { 290 WARN("Failed to reserve region [base = %p, size = 0x%zx]\n", 291 (void *) image_base, image_size); 292 dump_load_info(image_base, image_size, mem_layout); 293 io_result = -ENOMEM; 294 goto exit; 295 } 296 297 /* We have enough space so load the image now */ 298 /* TODO: Consider whether to try to recover/retry a partially successful read */ 299 io_result = io_read(image_handle, image_base, image_size, &bytes_read); 300 if ((io_result != 0) || (bytes_read < image_size)) { 301 WARN("Failed to load image id=%u (%i)\n", image_id, io_result); 302 goto exit; 303 } 304 305 image_data->image_base = image_base; 306 image_data->image_size = image_size; 307 308 /* 309 * Update the memory usage info. 310 * This is done after the actual loading so that it is not updated when 311 * the load is unsuccessful. 312 * If the caller does not provide an entry point, bypass the memory 313 * reservation. 314 */ 315 if (entry_point_info != NULL) { 316 reserve_mem(&mem_layout->free_base, &mem_layout->free_size, 317 image_base, image_size); 318 entry_point_info->pc = image_base; 319 } else { 320 INFO("Skip reserving region [base = %p, size = 0x%zx]\n", 321 (void *) image_base, image_size); 322 } 323 324 #if !TRUSTED_BOARD_BOOT 325 /* 326 * File has been successfully loaded. 327 * Flush the image to main memory so that it can be executed later by 328 * any CPU, regardless of cache and MMU state. 329 * When TBB is enabled the image is flushed later, after image 330 * authentication. 331 */ 332 flush_dcache_range(image_base, image_size); 333 #endif /* TRUSTED_BOARD_BOOT */ 334 335 INFO("Image id=%u loaded at address %p, size = 0x%zx\n", image_id, 336 (void *) image_base, image_size); 337 338 exit: 339 io_close(image_handle); 340 /* Ignore improbable/unrecoverable error in 'close' */ 341 342 /* TODO: Consider maintaining open device connection from this bootloader stage */ 343 io_dev_close(dev_handle); 344 /* Ignore improbable/unrecoverable error in 'dev_close' */ 345 346 return io_result; 347 } 348 349 /******************************************************************************* 350 * Generic function to load and authenticate an image. The image is actually 351 * loaded by calling the 'load_image()' function. In addition, this function 352 * uses recursion to authenticate the parent images up to the root of trust. 353 ******************************************************************************/ 354 int load_auth_image(meminfo_t *mem_layout, 355 unsigned int image_id, 356 uintptr_t image_base, 357 image_info_t *image_data, 358 entry_point_info_t *entry_point_info) 359 { 360 int rc; 361 362 #if TRUSTED_BOARD_BOOT 363 unsigned int parent_id; 364 365 /* Use recursion to authenticate parent images */ 366 rc = auth_mod_get_parent_id(image_id, &parent_id); 367 if (rc == 0) { 368 rc = load_auth_image(mem_layout, parent_id, image_base, 369 image_data, NULL); 370 if (rc != 0) { 371 return rc; 372 } 373 } 374 #endif /* TRUSTED_BOARD_BOOT */ 375 376 /* Load the image */ 377 rc = load_image(mem_layout, image_id, image_base, image_data, 378 entry_point_info); 379 if (rc != 0) { 380 return rc; 381 } 382 383 #if TRUSTED_BOARD_BOOT 384 /* Authenticate it */ 385 rc = auth_mod_verify_img(image_id, 386 (void *)image_data->image_base, 387 image_data->image_size); 388 if (rc != 0) { 389 memset((void *)image_data->image_base, 0x00, 390 image_data->image_size); 391 flush_dcache_range(image_data->image_base, 392 image_data->image_size); 393 return -EAUTH; 394 } 395 /* 396 * File has been successfully loaded and authenticated. 397 * Flush the image to main memory so that it can be executed later by 398 * any CPU, regardless of cache and MMU state. 399 */ 400 flush_dcache_range(image_data->image_base, image_data->image_size); 401 #endif /* TRUSTED_BOARD_BOOT */ 402 403 return 0; 404 } 405 406 /******************************************************************************* 407 * Print the content of an entry_point_info_t structure. 408 ******************************************************************************/ 409 void print_entry_point_info(const entry_point_info_t *ep_info) 410 { 411 INFO("Entry point address = %p\n", (void *)ep_info->pc); 412 INFO("SPSR = 0x%x\n", ep_info->spsr); 413 414 #define PRINT_IMAGE_ARG(n) \ 415 VERBOSE("Argument #" #n " = 0x%llx\n", \ 416 (unsigned long long) ep_info->args.arg##n) 417 418 PRINT_IMAGE_ARG(0); 419 PRINT_IMAGE_ARG(1); 420 PRINT_IMAGE_ARG(2); 421 PRINT_IMAGE_ARG(3); 422 #ifndef AARCH32 423 PRINT_IMAGE_ARG(4); 424 PRINT_IMAGE_ARG(5); 425 PRINT_IMAGE_ARG(6); 426 PRINT_IMAGE_ARG(7); 427 #endif 428 #undef PRINT_IMAGE_ARG 429 } 430