Home | History | Annotate | Download | only in bl2
      1 /*
      2  * Copyright (c) 2013-2014, 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.h>
     35 #include <bl_common.h>
     36 #include <debug.h>
     37 #include <platform.h>
     38 #include <platform_def.h>
     39 #include "bl2_private.h"
     40 
     41 #if TRUSTED_BOARD_BOOT
     42 
     43 #ifdef BL32_BASE
     44 static int bl32_cert_error;
     45 #endif
     46 
     47 /*
     48  * Load and authenticate the key and content certificates for a BL3-x image
     49  *
     50  * Parameters:
     51  *   key_cert_blob: key certificate blob id (see auth.h)
     52  *   key_cert_name: key certificate filename
     53  *   cont_cert_blob: content certificate blob id (see auth.h)
     54  *   cont_cert_name: content certificate filename
     55  *   mem_layout: Trusted SRAM memory layout
     56  *   load_addr: load the certificates at this address
     57  *
     58  * Return: 0 = success, Otherwise = error
     59  */
     60 static int load_cert_bl3x(int key_cert_blob, const char *key_cert_name,
     61 			  int cont_cert_blob, const char *cont_cert_name,
     62 			  meminfo_t *mem_layout, uint64_t load_addr)
     63 {
     64 	image_info_t image_info;
     65 	int err;
     66 
     67 	/* Load Key certificate */
     68 	image_info.h.version = VERSION_1;
     69 	err = load_image(mem_layout, key_cert_name, load_addr, &image_info, NULL);
     70 	if (err) {
     71 		ERROR("Cannot load %s.\n", key_cert_name);
     72 		return err;
     73 	}
     74 
     75 	err = auth_verify_obj(key_cert_blob, image_info.image_base,
     76 			image_info.image_size);
     77 	if (err) {
     78 		ERROR("Invalid key certificate %s.\n", key_cert_name);
     79 		return err;
     80 	}
     81 
     82 	/* Load Content certificate */
     83 	image_info.h.version = VERSION_1;
     84 	err = load_image(mem_layout, cont_cert_name, load_addr, &image_info, NULL);
     85 	if (err) {
     86 		ERROR("Cannot load %s.\n", cont_cert_name);
     87 		return err;
     88 	}
     89 
     90 	err = auth_verify_obj(cont_cert_blob, image_info.image_base,
     91 			image_info.image_size);
     92 	if (err) {
     93 		ERROR("Invalid content certificate %s.\n", cont_cert_name);
     94 		return err;
     95 	}
     96 
     97 	return 0;
     98 }
     99 
    100 /*
    101  * Load and authenticate the Trusted Key certificate the key and content
    102  * certificates for each of the BL3-x images.
    103  *
    104  * Return: 0 = success, Otherwise = error
    105  */
    106 static int load_certs(void)
    107 {
    108 	const uint64_t load_addr = BL31_BASE;
    109 	image_info_t image_info;
    110 	meminfo_t *mem_layout;
    111 	int err;
    112 
    113 	/* Find out how much free trusted ram remains after BL2 load */
    114 	mem_layout = bl2_plat_sec_mem_layout();
    115 
    116 	/* Load the Trusted Key certificate in the BL31 region */
    117 	image_info.h.version = VERSION_1;
    118 	err = load_image(mem_layout, TRUSTED_KEY_CERT_NAME, load_addr,
    119 			 &image_info, NULL);
    120 	if (err) {
    121 		ERROR("Failed to load Trusted Key certificate.\n");
    122 		return err;
    123 	}
    124 
    125 	/* Validate the certificate */
    126 	err = auth_verify_obj(AUTH_TRUSTED_KEY_CERT, image_info.image_base,
    127 			image_info.image_size);
    128 	if (err) {
    129 		ERROR("Invalid Trusted Key certificate.\n");
    130 		return err;
    131 	}
    132 
    133 	/* Load and validate Key and Content certificates for BL3-x images */
    134 #ifdef BL30_BASE
    135 	err = load_cert_bl3x(AUTH_BL30_KEY_CERT, BL30_KEY_CERT_NAME,
    136 			     AUTH_BL30_IMG_CERT, BL30_CERT_NAME,
    137 			     mem_layout, load_addr);
    138 	if (err) {
    139 		ERROR("Failed to verify BL3-0 authenticity\n");
    140 		return err;
    141 	}
    142 #endif /* BL30_BASE */
    143 
    144 	err = load_cert_bl3x(AUTH_BL31_KEY_CERT, BL31_KEY_CERT_NAME,
    145 			     AUTH_BL31_IMG_CERT, BL31_CERT_NAME,
    146 			     mem_layout, load_addr);
    147 	if (err) {
    148 		ERROR("Failed to verify BL3-1 authenticity\n");
    149 		return err;
    150 	}
    151 
    152 #ifdef BL32_BASE
    153 	/* BL3-2 image is optional, but keep the return value in case the
    154 	 * image is present but the certificate is missing */
    155 	err = load_cert_bl3x(AUTH_BL32_KEY_CERT, BL32_KEY_CERT_NAME,
    156 			     AUTH_BL32_IMG_CERT, BL32_CERT_NAME,
    157 			     mem_layout, load_addr);
    158 	if (err) {
    159 		WARN("Failed to verify BL3-2 authenticity\n");
    160 	}
    161 	bl32_cert_error = err;
    162 #endif /* BL32_BASE */
    163 
    164 	err = load_cert_bl3x(AUTH_BL33_KEY_CERT, BL33_KEY_CERT_NAME,
    165 			     AUTH_BL33_IMG_CERT, BL33_CERT_NAME,
    166 			     mem_layout, load_addr);
    167 	if (err) {
    168 		ERROR("Failed to verify BL3-3 authenticity\n");
    169 		return err;
    170 	}
    171 
    172 	return 0;
    173 }
    174 
    175 #endif /* TRUSTED_BOARD_BOOT */
    176 
    177 /*******************************************************************************
    178  * Load the BL3-0 image if there's one.
    179  * If a platform does not want to attempt to load BL3-0 image it must leave
    180  * BL30_BASE undefined.
    181  * Return 0 on success or if there's no BL3-0 image to load, a negative error
    182  * code otherwise.
    183  ******************************************************************************/
    184 static int load_bl30(void)
    185 {
    186 	int e = 0;
    187 #ifdef BL30_BASE
    188 	meminfo_t bl30_mem_info;
    189 	image_info_t bl30_image_info;
    190 
    191 	/*
    192 	 * It is up to the platform to specify where BL3-0 should be loaded if
    193 	 * it exists. It could create space in the secure sram or point to a
    194 	 * completely different memory.
    195 	 *
    196 	 * The entry point information is not relevant in this case as the AP
    197 	 * won't execute the BL3-0 image.
    198 	 */
    199 	INFO("BL2: Loading BL3-0\n");
    200 	bl2_plat_get_bl30_meminfo(&bl30_mem_info);
    201 	bl30_image_info.h.version = VERSION_1;
    202 	e = load_image(&bl30_mem_info,
    203 		       BL30_IMAGE_NAME,
    204 		       BL30_BASE,
    205 		       &bl30_image_info,
    206 		       NULL);
    207 
    208 	if (e == 0) {
    209 #if TRUSTED_BOARD_BOOT
    210 		e = auth_verify_obj(AUTH_BL30_IMG,
    211 				bl30_image_info.image_base,
    212 				bl30_image_info.image_size);
    213 		if (e) {
    214 			ERROR("Failed to authenticate BL3-0 image.\n");
    215 			panic();
    216 		}
    217 
    218 		/* After working with data, invalidate the data cache */
    219 		inv_dcache_range(bl30_image_info.image_base,
    220 				 (size_t)bl30_image_info.image_size);
    221 #endif /* TRUSTED_BOARD_BOOT */
    222 
    223 		/* The subsequent handling of BL3-0 is platform specific */
    224 		bl2_plat_handle_bl30(&bl30_image_info);
    225 	}
    226 #endif /* BL30_BASE */
    227 
    228 	return e;
    229 }
    230 
    231 /*******************************************************************************
    232  * Load the BL3-1 image.
    233  * The bl2_to_bl31_params and bl31_ep_info params will be updated with the
    234  * relevant BL3-1 information.
    235  * Return 0 on success, a negative error code otherwise.
    236  ******************************************************************************/
    237 static int load_bl31(bl31_params_t *bl2_to_bl31_params,
    238 		     entry_point_info_t *bl31_ep_info)
    239 {
    240 	meminfo_t *bl2_tzram_layout;
    241 	int e;
    242 
    243 	INFO("BL2: Loading BL3-1\n");
    244 	assert(bl2_to_bl31_params != NULL);
    245 	assert(bl31_ep_info != NULL);
    246 
    247 	/* Find out how much free trusted ram remains after BL2 load */
    248 	bl2_tzram_layout = bl2_plat_sec_mem_layout();
    249 
    250 	/* Set the X0 parameter to BL3-1 */
    251 	bl31_ep_info->args.arg0 = (unsigned long)bl2_to_bl31_params;
    252 
    253 	/* Load the BL3-1 image */
    254 	e = load_image(bl2_tzram_layout,
    255 		       BL31_IMAGE_NAME,
    256 		       BL31_BASE,
    257 		       bl2_to_bl31_params->bl31_image_info,
    258 		       bl31_ep_info);
    259 
    260 	if (e == 0) {
    261 #if TRUSTED_BOARD_BOOT
    262 		e = auth_verify_obj(AUTH_BL31_IMG,
    263 			bl2_to_bl31_params->bl31_image_info->image_base,
    264 			bl2_to_bl31_params->bl31_image_info->image_size);
    265 		if (e) {
    266 			ERROR("Failed to authenticate BL3-1 image.\n");
    267 			panic();
    268 		}
    269 
    270 		/* After working with data, invalidate the data cache */
    271 		inv_dcache_range(bl2_to_bl31_params->bl31_image_info->image_base,
    272 			(size_t)bl2_to_bl31_params->bl31_image_info->image_size);
    273 #endif /* TRUSTED_BOARD_BOOT */
    274 
    275 		bl2_plat_set_bl31_ep_info(bl2_to_bl31_params->bl31_image_info,
    276 					  bl31_ep_info);
    277 	}
    278 
    279 	return e;
    280 }
    281 
    282 /*******************************************************************************
    283  * Load the BL3-2 image if there's one.
    284  * The bl2_to_bl31_params param will be updated with the relevant BL3-2
    285  * information.
    286  * If a platform does not want to attempt to load BL3-2 image it must leave
    287  * BL32_BASE undefined.
    288  * Return 0 on success or if there's no BL3-2 image to load, a negative error
    289  * code otherwise.
    290  ******************************************************************************/
    291 static int load_bl32(bl31_params_t *bl2_to_bl31_params)
    292 {
    293 	int e = 0;
    294 #ifdef BL32_BASE
    295 	meminfo_t bl32_mem_info;
    296 
    297 	INFO("BL2: Loading BL3-2\n");
    298 	assert(bl2_to_bl31_params != NULL);
    299 
    300 	/*
    301 	 * It is up to the platform to specify where BL3-2 should be loaded if
    302 	 * it exists. It could create space in the secure sram or point to a
    303 	 * completely different memory.
    304 	 */
    305 	bl2_plat_get_bl32_meminfo(&bl32_mem_info);
    306 	e = load_image(&bl32_mem_info,
    307 		       BL32_IMAGE_NAME,
    308 		       BL32_BASE,
    309 		       bl2_to_bl31_params->bl32_image_info,
    310 		       bl2_to_bl31_params->bl32_ep_info);
    311 
    312 	if (e == 0) {
    313 #if TRUSTED_BOARD_BOOT
    314 		/* Image is present. Check if there is a valid certificate */
    315 		if (bl32_cert_error) {
    316 			ERROR("Failed to authenticate BL3-2 certificates.\n");
    317 			panic();
    318 		}
    319 
    320 		e = auth_verify_obj(AUTH_BL32_IMG,
    321 			bl2_to_bl31_params->bl32_image_info->image_base,
    322 			bl2_to_bl31_params->bl32_image_info->image_size);
    323 		if (e) {
    324 			ERROR("Failed to authenticate BL3-2 image.\n");
    325 			panic();
    326 		}
    327 		/* After working with data, invalidate the data cache */
    328 		inv_dcache_range(bl2_to_bl31_params->bl32_image_info->image_base,
    329 			(size_t)bl2_to_bl31_params->bl32_image_info->image_size);
    330 #endif /* TRUSTED_BOARD_BOOT */
    331 
    332 		bl2_plat_set_bl32_ep_info(
    333 			bl2_to_bl31_params->bl32_image_info,
    334 			bl2_to_bl31_params->bl32_ep_info);
    335 	}
    336 #endif /* BL32_BASE */
    337 
    338 	return e;
    339 }
    340 
    341 /*******************************************************************************
    342  * Load the BL3-3 image.
    343  * The bl2_to_bl31_params param will be updated with the relevant BL3-3
    344  * information.
    345  * Return 0 on success, a negative error code otherwise.
    346  ******************************************************************************/
    347 static int load_bl33(bl31_params_t *bl2_to_bl31_params)
    348 {
    349 	meminfo_t bl33_mem_info;
    350 	int e;
    351 
    352 	INFO("BL2: Loading BL3-3\n");
    353 	assert(bl2_to_bl31_params != NULL);
    354 
    355 	bl2_plat_get_bl33_meminfo(&bl33_mem_info);
    356 
    357 	/* Load the BL3-3 image in non-secure memory provided by the platform */
    358 	e = load_image(&bl33_mem_info,
    359 		       BL33_IMAGE_NAME,
    360 		       plat_get_ns_image_entrypoint(),
    361 		       bl2_to_bl31_params->bl33_image_info,
    362 		       bl2_to_bl31_params->bl33_ep_info);
    363 
    364 	if (e == 0) {
    365 #if TRUSTED_BOARD_BOOT
    366 		e = auth_verify_obj(AUTH_BL33_IMG,
    367 				bl2_to_bl31_params->bl33_image_info->image_base,
    368 				bl2_to_bl31_params->bl33_image_info->image_size);
    369 		if (e) {
    370 			ERROR("Failed to authenticate BL3-3 image.\n");
    371 			panic();
    372 		}
    373 		/* After working with data, invalidate the data cache */
    374 		inv_dcache_range(bl2_to_bl31_params->bl33_image_info->image_base,
    375 			(size_t)bl2_to_bl31_params->bl33_image_info->image_size);
    376 #endif /* TRUSTED_BOARD_BOOT */
    377 
    378 		bl2_plat_set_bl33_ep_info(bl2_to_bl31_params->bl33_image_info,
    379 					  bl2_to_bl31_params->bl33_ep_info);
    380 	}
    381 
    382 	return e;
    383 }
    384 
    385 /*******************************************************************************
    386  * The only thing to do in BL2 is to load further images and pass control to
    387  * BL3-1. The memory occupied by BL2 will be reclaimed by BL3-x stages. BL2 runs
    388  * entirely in S-EL1.
    389  ******************************************************************************/
    390 void bl2_main(void)
    391 {
    392 	bl31_params_t *bl2_to_bl31_params;
    393 	entry_point_info_t *bl31_ep_info;
    394 	int e;
    395 
    396 	NOTICE("BL2: %s\n", version_string);
    397 	NOTICE("BL2: %s\n", build_message);
    398 
    399 	/* Perform remaining generic architectural setup in S-EL1 */
    400 	bl2_arch_setup();
    401 
    402 #if TRUSTED_BOARD_BOOT
    403 	/* Initialize authentication module */
    404 	auth_init();
    405 
    406 	/* Validate the certificates involved in the Chain of Trust */
    407 	e = load_certs();
    408 	if (e) {
    409 		ERROR("Chain of Trust invalid. Aborting...\n");
    410 		panic();
    411 	}
    412 #endif /* TRUSTED_BOARD_BOOT */
    413 
    414 	/*
    415 	 * Load the subsequent bootloader images
    416 	 */
    417 	e = load_bl30();
    418 	if (e) {
    419 		ERROR("Failed to load BL3-0 (%i)\n", e);
    420 		ERROR("Please burn mcu image:\n");
    421 		ERROR("  sudo fastboot flash mcuimage mcuimage.bin\n");
    422 	}
    423 
    424 	/* Perform platform setup in BL2 after loading BL3-0 */
    425 	bl2_platform_setup();
    426 
    427 	/*
    428 	 * Get a pointer to the memory the platform has set aside to pass
    429 	 * information to BL3-1.
    430 	 */
    431 	bl2_to_bl31_params = bl2_plat_get_bl31_params();
    432 	bl31_ep_info = bl2_plat_get_bl31_ep_info();
    433 
    434 	e = load_bl31(bl2_to_bl31_params, bl31_ep_info);
    435 	if (e) {
    436 		ERROR("Failed to load BL3-1 (%i)\n", e);
    437 		panic();
    438 	}
    439 
    440 	e = load_bl32(bl2_to_bl31_params);
    441 	if (e)
    442 		WARN("Failed to load BL3-2 (%i)\n", e);
    443 
    444 	e = load_bl33(bl2_to_bl31_params);
    445 	if (e) {
    446 		ERROR("Failed to load BL3-3 (%i)\n", e);
    447 		panic();
    448 	}
    449 
    450 	/* Flush the params to be passed to memory */
    451 	bl2_plat_flush_bl31_params();
    452 
    453 	/*
    454 	 * Run BL3-1 via an SMC to BL1. Information on how to pass control to
    455 	 * the BL3-2 (if present) and BL3-3 software images will be passed to
    456 	 * BL3-1 as an argument.
    457 	 */
    458 	smc(RUN_IMAGE, (unsigned long)bl31_ep_info, 0, 0, 0, 0, 0, 0);
    459 }
    460