xref: /rk3399_ARM-atf/common/bl_common.c (revision ff2743e544f0f82381ebb9dff8f14eacb837d2e0)
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. This
27  * capability is restricted to LOAD_IMAGE_V2.
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 - 1)) {
53 		value &= ~(PAGE_SIZE - 1);
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 #if !LOAD_IMAGE_V2
105 /******************************************************************************
106  * Inside a given memory region, determine whether a sub-region of memory is
107  * closer from the top or the bottom of the encompassing region. Return the
108  * size of the smallest chunk of free memory surrounding the sub-region in
109  * 'small_chunk_size'.
110  *****************************************************************************/
111 static unsigned int choose_mem_pos(uintptr_t mem_start, uintptr_t mem_end,
112 				  uintptr_t submem_start, uintptr_t submem_end,
113 				  size_t *small_chunk_size)
114 {
115 	size_t top_chunk_size, bottom_chunk_size;
116 
117 	assert(mem_start <= submem_start);
118 	assert(submem_start <= submem_end);
119 	assert(submem_end <= mem_end);
120 	assert(small_chunk_size != NULL);
121 
122 	top_chunk_size = mem_end - submem_end;
123 	bottom_chunk_size = submem_start - mem_start;
124 
125 	if (top_chunk_size < bottom_chunk_size) {
126 		*small_chunk_size = top_chunk_size;
127 		return TOP;
128 	} else {
129 		*small_chunk_size = bottom_chunk_size;
130 		return BOTTOM;
131 	}
132 }
133 
134 /******************************************************************************
135  * Reserve the memory region delimited by 'addr' and 'size'. The extents of free
136  * memory are passed in 'free_base' and 'free_size' and they will be updated to
137  * reflect the memory usage.
138  * The caller must ensure the memory to reserve is free and that the addresses
139  * and sizes passed in arguments are sane.
140  *****************************************************************************/
141 void reserve_mem(uintptr_t *free_base, size_t *free_size,
142 		 uintptr_t addr, size_t size)
143 {
144 	size_t discard_size;
145 	size_t reserved_size;
146 	unsigned int pos;
147 
148 	assert(free_base != NULL);
149 	assert(free_size != NULL);
150 	assert(is_mem_free(*free_base, *free_size, addr, size));
151 
152 	if (size == 0) {
153 		WARN("Nothing to allocate, requested size is zero\n");
154 		return;
155 	}
156 
157 	pos = choose_mem_pos(*free_base, *free_base + (*free_size - 1),
158 			     addr, addr + (size - 1),
159 			     &discard_size);
160 
161 	reserved_size = size + discard_size;
162 	*free_size -= reserved_size;
163 
164 	if (pos == BOTTOM)
165 		*free_base = addr + size;
166 
167 	VERBOSE("Reserved 0x%zx bytes (discarded 0x%zx bytes %s)\n",
168 	     reserved_size, discard_size,
169 	     pos == TOP ? "above" : "below");
170 }
171 
172 static void dump_load_info(uintptr_t image_load_addr,
173 			   size_t image_size,
174 			   const meminfo_t *mem_layout)
175 {
176 	INFO("Trying to load image at address %p, size = 0x%zx\n",
177 		(void *)image_load_addr, image_size);
178 	INFO("Current memory layout:\n");
179 	INFO("  total region = [base = %p, size = 0x%zx]\n",
180 		(void *) mem_layout->total_base, mem_layout->total_size);
181 	INFO("  free region = [base = %p, size = 0x%zx]\n",
182 		(void *) mem_layout->free_base, mem_layout->free_size);
183 }
184 #endif /* LOAD_IMAGE_V2 */
185 
186 /* Generic function to return the size of an image */
187 size_t get_image_size(unsigned int image_id)
188 {
189 	uintptr_t dev_handle;
190 	uintptr_t image_handle;
191 	uintptr_t image_spec;
192 	size_t image_size = 0;
193 	int io_result;
194 
195 	/* Obtain a reference to the image by querying the platform layer */
196 	io_result = plat_get_image_source(image_id, &dev_handle, &image_spec);
197 	if (io_result != 0) {
198 		WARN("Failed to obtain reference to image id=%u (%i)\n",
199 			image_id, io_result);
200 		return 0;
201 	}
202 
203 	/* Attempt to access the image */
204 	io_result = io_open(dev_handle, image_spec, &image_handle);
205 	if (io_result != 0) {
206 		WARN("Failed to access image id=%u (%i)\n",
207 			image_id, io_result);
208 		return 0;
209 	}
210 
211 	/* Find the size of the image */
212 	io_result = io_size(image_handle, &image_size);
213 	if ((io_result != 0) || (image_size == 0)) {
214 		WARN("Failed to determine the size of the image id=%u (%i)\n",
215 			image_id, io_result);
216 	}
217 	io_result = io_close(image_handle);
218 	/* Ignore improbable/unrecoverable error in 'close' */
219 
220 	/* TODO: Consider maintaining open device connection from this
221 	 * bootloader stage
222 	 */
223 	io_result = io_dev_close(dev_handle);
224 	/* Ignore improbable/unrecoverable error in 'dev_close' */
225 
226 	return image_size;
227 }
228 
229 #if LOAD_IMAGE_V2
230 
231 /*******************************************************************************
232  * Internal function to load an image at a specific address given
233  * an image ID and extents of free memory.
234  *
235  * If the load is successful then the image information is updated.
236  *
237  * Returns 0 on success, a negative error code otherwise.
238  ******************************************************************************/
239 static int load_image(unsigned int image_id, image_info_t *image_data)
240 {
241 	uintptr_t dev_handle;
242 	uintptr_t image_handle;
243 	uintptr_t image_spec;
244 	uintptr_t image_base;
245 	size_t image_size;
246 	size_t bytes_read;
247 	int io_result;
248 
249 	assert(image_data != NULL);
250 	assert(image_data->h.version >= VERSION_2);
251 
252 	image_base = image_data->image_base;
253 
254 	/* Obtain a reference to the image by querying the platform layer */
255 	io_result = plat_get_image_source(image_id, &dev_handle, &image_spec);
256 	if (io_result != 0) {
257 		WARN("Failed to obtain reference to image id=%u (%i)\n",
258 			image_id, io_result);
259 		return io_result;
260 	}
261 
262 	/* Attempt to access the image */
263 	io_result = io_open(dev_handle, image_spec, &image_handle);
264 	if (io_result != 0) {
265 		WARN("Failed to access image id=%u (%i)\n",
266 			image_id, io_result);
267 		return io_result;
268 	}
269 
270 	INFO("Loading image id=%u at address %p\n", image_id,
271 		(void *) image_base);
272 
273 	/* Find the size of the image */
274 	io_result = io_size(image_handle, &image_size);
275 	if ((io_result != 0) || (image_size == 0)) {
276 		WARN("Failed to determine the size of the image id=%u (%i)\n",
277 			image_id, io_result);
278 		goto exit;
279 	}
280 
281 	/* Check that the image size to load is within limit */
282 	if (image_size > image_data->image_max_size) {
283 		WARN("Image id=%u size out of bounds\n", image_id);
284 		io_result = -EFBIG;
285 		goto exit;
286 	}
287 
288 	image_data->image_size = image_size;
289 
290 	/* We have enough space so load the image now */
291 	/* TODO: Consider whether to try to recover/retry a partially successful read */
292 	io_result = io_read(image_handle, image_base, image_size, &bytes_read);
293 	if ((io_result != 0) || (bytes_read < image_size)) {
294 		WARN("Failed to load image id=%u (%i)\n", image_id, io_result);
295 		goto exit;
296 	}
297 
298 	INFO("Image id=%u loaded: %p - %p\n", image_id, (void *) image_base,
299 	     (void *) (image_base + image_size));
300 
301 exit:
302 	io_close(image_handle);
303 	/* Ignore improbable/unrecoverable error in 'close' */
304 
305 	/* TODO: Consider maintaining open device connection from this bootloader stage */
306 	io_dev_close(dev_handle);
307 	/* Ignore improbable/unrecoverable error in 'dev_close' */
308 
309 	return io_result;
310 }
311 
312 static int load_auth_image_internal(unsigned int image_id,
313 				    image_info_t *image_data,
314 				    int is_parent_image)
315 {
316 	int rc;
317 
318 #if TRUSTED_BOARD_BOOT
319 	if (dyn_is_auth_disabled() == 0) {
320 		unsigned int parent_id;
321 
322 		/* Use recursion to authenticate parent images */
323 		rc = auth_mod_get_parent_id(image_id, &parent_id);
324 		if (rc == 0) {
325 			rc = load_auth_image_internal(parent_id, image_data, 1);
326 			if (rc != 0) {
327 				return rc;
328 			}
329 		}
330 	}
331 #endif /* TRUSTED_BOARD_BOOT */
332 
333 	/* Load the image */
334 	rc = load_image(image_id, image_data);
335 	if (rc != 0) {
336 		return rc;
337 	}
338 
339 #if TRUSTED_BOARD_BOOT
340 	if (dyn_is_auth_disabled() == 0) {
341 		/* Authenticate it */
342 		rc = auth_mod_verify_img(image_id,
343 					 (void *)image_data->image_base,
344 					 image_data->image_size);
345 		if (rc != 0) {
346 			/* Authentication error, zero memory and flush it right away. */
347 			zero_normalmem((void *)image_data->image_base,
348 			       image_data->image_size);
349 			flush_dcache_range(image_data->image_base,
350 					   image_data->image_size);
351 			return -EAUTH;
352 		}
353 	}
354 #endif /* TRUSTED_BOARD_BOOT */
355 
356 	/*
357 	 * Flush the image to main memory so that it can be executed later by
358 	 * any CPU, regardless of cache and MMU state. If TBB is enabled, then
359 	 * the file has been successfully loaded and authenticated and flush
360 	 * only for child images, not for the parents (certificates).
361 	 */
362 	if (!is_parent_image) {
363 		flush_dcache_range(image_data->image_base,
364 				   image_data->image_size);
365 	}
366 
367 
368 	return 0;
369 }
370 
371 /*******************************************************************************
372  * Generic function to load and authenticate an image. The image is actually
373  * loaded by calling the 'load_image()' function. Therefore, it returns the
374  * same error codes if the loading operation failed, or -EAUTH if the
375  * authentication failed. In addition, this function uses recursion to
376  * authenticate the parent images up to the root of trust.
377  ******************************************************************************/
378 int load_auth_image(unsigned int image_id, image_info_t *image_data)
379 {
380 	int err;
381 
382 	do {
383 		err = load_auth_image_internal(image_id, image_data, 0);
384 	} while (err != 0 && plat_try_next_boot_source());
385 
386 	return err;
387 }
388 
389 #else /* LOAD_IMAGE_V2 */
390 
391 /*******************************************************************************
392  * Generic function to load an image at a specific address given an image ID and
393  * extents of free memory.
394  *
395  * If the load is successful then the image information is updated.
396  *
397  * If the entry_point_info argument is not NULL then this function also updates:
398  * - the memory layout to mark the memory as reserved;
399  * - the entry point information.
400  *
401  * The caller might pass a NULL pointer for the entry point if they are not
402  * interested in this information. This is typically the case for non-executable
403  * images (e.g. certificates) and executable images that won't ever be executed
404  * on the application processor (e.g. additional microcontroller firmware).
405  *
406  * Returns 0 on success, a negative error code otherwise.
407  ******************************************************************************/
408 int load_image(meminfo_t *mem_layout,
409 	       unsigned int image_id,
410 	       uintptr_t image_base,
411 	       image_info_t *image_data,
412 	       entry_point_info_t *entry_point_info)
413 {
414 	uintptr_t dev_handle;
415 	uintptr_t image_handle;
416 	uintptr_t image_spec;
417 	size_t image_size;
418 	size_t bytes_read;
419 	int io_result;
420 
421 	assert(mem_layout != NULL);
422 	assert(image_data != NULL);
423 	assert(image_data->h.version == VERSION_1);
424 
425 	/* Obtain a reference to the image by querying the platform layer */
426 	io_result = plat_get_image_source(image_id, &dev_handle, &image_spec);
427 	if (io_result != 0) {
428 		WARN("Failed to obtain reference to image id=%u (%i)\n",
429 			image_id, io_result);
430 		return io_result;
431 	}
432 
433 	/* Attempt to access the image */
434 	io_result = io_open(dev_handle, image_spec, &image_handle);
435 	if (io_result != 0) {
436 		WARN("Failed to access image id=%u (%i)\n",
437 			image_id, io_result);
438 		return io_result;
439 	}
440 
441 	INFO("Loading image id=%u at address %p\n", image_id,
442 		(void *) image_base);
443 
444 	/* Find the size of the image */
445 	io_result = io_size(image_handle, &image_size);
446 	if ((io_result != 0) || (image_size == 0)) {
447 		WARN("Failed to determine the size of the image id=%u (%i)\n",
448 			image_id, io_result);
449 		goto exit;
450 	}
451 
452 	/* Check that the memory where the image will be loaded is free */
453 	if (!is_mem_free(mem_layout->free_base, mem_layout->free_size,
454 			 image_base, image_size)) {
455 		WARN("Failed to reserve region [base = %p, size = 0x%zx]\n",
456 		     (void *) image_base, image_size);
457 		dump_load_info(image_base, image_size, mem_layout);
458 		io_result = -ENOMEM;
459 		goto exit;
460 	}
461 
462 	/* We have enough space so load the image now */
463 	/* TODO: Consider whether to try to recover/retry a partially successful read */
464 	io_result = io_read(image_handle, image_base, image_size, &bytes_read);
465 	if ((io_result != 0) || (bytes_read < image_size)) {
466 		WARN("Failed to load image id=%u (%i)\n", image_id, io_result);
467 		goto exit;
468 	}
469 
470 	image_data->image_base = image_base;
471 	image_data->image_size = image_size;
472 
473 	/*
474 	 * Update the memory usage info.
475 	 * This is done after the actual loading so that it is not updated when
476 	 * the load is unsuccessful.
477 	 * If the caller does not provide an entry point, bypass the memory
478 	 * reservation.
479 	 */
480 	if (entry_point_info != NULL) {
481 		reserve_mem(&mem_layout->free_base, &mem_layout->free_size,
482 				image_base, image_size);
483 		entry_point_info->pc = image_base;
484 	} else {
485 		INFO("Skip reserving region [base = %p, size = 0x%zx]\n",
486 		     (void *) image_base, image_size);
487 	}
488 
489 #if !TRUSTED_BOARD_BOOT
490 	/*
491 	 * File has been successfully loaded.
492 	 * Flush the image to main memory so that it can be executed later by
493 	 * any CPU, regardless of cache and MMU state.
494 	 * When TBB is enabled the image is flushed later, after image
495 	 * authentication.
496 	 */
497 	flush_dcache_range(image_base, image_size);
498 #endif /* TRUSTED_BOARD_BOOT */
499 
500 	INFO("Image id=%u loaded at address %p, size = 0x%zx\n", image_id,
501 		(void *) image_base, image_size);
502 
503 exit:
504 	io_close(image_handle);
505 	/* Ignore improbable/unrecoverable error in 'close' */
506 
507 	/* TODO: Consider maintaining open device connection from this bootloader stage */
508 	io_dev_close(dev_handle);
509 	/* Ignore improbable/unrecoverable error in 'dev_close' */
510 
511 	return io_result;
512 }
513 
514 static int load_auth_image_internal(meminfo_t *mem_layout,
515 				    unsigned int image_id,
516 				    uintptr_t image_base,
517 				    image_info_t *image_data,
518 				    entry_point_info_t *entry_point_info,
519 				    int is_parent_image)
520 {
521 	int rc;
522 
523 #if TRUSTED_BOARD_BOOT
524 	unsigned int parent_id;
525 
526 	/* Use recursion to authenticate parent images */
527 	rc = auth_mod_get_parent_id(image_id, &parent_id);
528 	if (rc == 0) {
529 		rc = load_auth_image_internal(mem_layout, parent_id, image_base,
530 				     image_data, NULL, 1);
531 		if (rc != 0) {
532 			return rc;
533 		}
534 	}
535 #endif /* TRUSTED_BOARD_BOOT */
536 
537 	/* Load the image */
538 	rc = load_image(mem_layout, image_id, image_base, image_data,
539 			entry_point_info);
540 	if (rc != 0) {
541 		return rc;
542 	}
543 
544 #if TRUSTED_BOARD_BOOT
545 	/* Authenticate it */
546 	rc = auth_mod_verify_img(image_id,
547 				 (void *)image_data->image_base,
548 				 image_data->image_size);
549 	if (rc != 0) {
550 		/* Authentication error, zero memory and flush it right away. */
551 		zero_normalmem((void *)image_data->image_base,
552 		       image_data->image_size);
553 		flush_dcache_range(image_data->image_base,
554 				   image_data->image_size);
555 		return -EAUTH;
556 	}
557 	/*
558 	 * File has been successfully loaded and authenticated.
559 	 * Flush the image to main memory so that it can be executed later by
560 	 * any CPU, regardless of cache and MMU state.
561 	 * Do it only for child images, not for the parents (certificates).
562 	 */
563 	if (!is_parent_image) {
564 		flush_dcache_range(image_data->image_base,
565 				   image_data->image_size);
566 	}
567 #endif /* TRUSTED_BOARD_BOOT */
568 
569 	return 0;
570 }
571 
572 /*******************************************************************************
573  * Generic function to load and authenticate an image. The image is actually
574  * loaded by calling the 'load_image()' function. Therefore, it returns the
575  * same error codes if the loading operation failed, or -EAUTH if the
576  * authentication failed. In addition, this function uses recursion to
577  * authenticate the parent images up to the root of trust.
578  ******************************************************************************/
579 int load_auth_image(meminfo_t *mem_layout,
580 		    unsigned int image_id,
581 		    uintptr_t image_base,
582 		    image_info_t *image_data,
583 		    entry_point_info_t *entry_point_info)
584 {
585 	int err;
586 
587 	do {
588 		err = load_auth_image_internal(mem_layout, image_id, image_base,
589 					       image_data, entry_point_info, 0);
590 	} while (err != 0 && plat_try_next_boot_source());
591 
592 	return err;
593 }
594 
595 #endif /* LOAD_IMAGE_V2 */
596 
597 /*******************************************************************************
598  * Print the content of an entry_point_info_t structure.
599  ******************************************************************************/
600 void print_entry_point_info(const entry_point_info_t *ep_info)
601 {
602 	INFO("Entry point address = %p\n", (void *)ep_info->pc);
603 	INFO("SPSR = 0x%x\n", ep_info->spsr);
604 
605 #define PRINT_IMAGE_ARG(n)					\
606 	VERBOSE("Argument #" #n " = 0x%llx\n",			\
607 		(unsigned long long) ep_info->args.arg##n)
608 
609 	PRINT_IMAGE_ARG(0);
610 	PRINT_IMAGE_ARG(1);
611 	PRINT_IMAGE_ARG(2);
612 	PRINT_IMAGE_ARG(3);
613 #ifndef AARCH32
614 	PRINT_IMAGE_ARG(4);
615 	PRINT_IMAGE_ARG(5);
616 	PRINT_IMAGE_ARG(6);
617 	PRINT_IMAGE_ARG(7);
618 #endif
619 #undef PRINT_IMAGE_ARG
620 }
621