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