xref: /rk3399_ARM-atf/common/bl_common.c (revision c948f77136c42a92d0bb660543a3600c36dcf7f1)
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