diff --git a/bl2/bl2_main.c b/bl2/bl2_main.c index b7e2cff..29ca0a5 100644 --- a/bl2/bl2_main.c +++ b/bl2/bl2_main.c @@ -31,12 +31,149 @@ #include #include #include +#include #include #include #include #include #include "bl2_private.h" +#if TRUSTED_BOARD_BOOT + +#ifdef BL32_BASE +static int bl32_cert_error; +#endif + +/* + * Load and authenticate the key and content certificates for a BL3-x image + * + * Parameters: + * key_cert_blob: key certificate blob id (see auth.h) + * key_cert_name: key certificate filename + * cont_cert_blob: content certificate blob id (see auth.h) + * cont_cert_name: content certificate filename + * mem_layout: Trusted SRAM memory layout + * load_addr: load the certificates at this address + * + * Return: 0 = success, Otherwise = error + */ +static int load_cert_bl3x(int key_cert_blob, const char *key_cert_name, + int cont_cert_blob, const char *cont_cert_name, + meminfo_t *mem_layout, uint64_t load_addr) +{ + image_info_t image_info; + int err; + + /* Load Key certificate */ + image_info.h.version = VERSION_1; + err = load_image(mem_layout, key_cert_name, load_addr, &image_info, NULL); + if (err) { + ERROR("Cannot load %s.\n", key_cert_name); + return err; + } + + err = auth_verify_obj(key_cert_blob, image_info.image_base, + image_info.image_size); + if (err) { + ERROR("Invalid key certificate %s.\n", key_cert_name); + return err; + } + + /* Load Content certificate */ + image_info.h.version = VERSION_1; + err = load_image(mem_layout, cont_cert_name, load_addr, &image_info, NULL); + if (err) { + ERROR("Cannot load %s.\n", cont_cert_name); + return err; + } + + err = auth_verify_obj(cont_cert_blob, image_info.image_base, + image_info.image_size); + if (err) { + ERROR("Invalid content certificate %s.\n", cont_cert_name); + return err; + } + + return 0; +} + +/* + * Load and authenticate the Trusted Key certificate the key and content + * certificates for each of the BL3-x images. + * + * Return: 0 = success, Otherwise = error + */ +static int load_certs(void) +{ + const uint64_t load_addr = BL31_BASE; + image_info_t image_info; + meminfo_t *mem_layout; + int err; + + /* Find out how much free trusted ram remains after BL2 load */ + mem_layout = bl2_plat_sec_mem_layout(); + + /* Load the Trusted Key certificate in the BL31 region */ + image_info.h.version = VERSION_1; + err = load_image(mem_layout, TRUSTED_KEY_CERT_NAME, load_addr, + &image_info, NULL); + if (err) { + ERROR("Failed to load Trusted Key certificate.\n"); + return err; + } + + /* Validate the certificate */ + err = auth_verify_obj(AUTH_TRUSTED_KEY_CERT, image_info.image_base, + image_info.image_size); + if (err) { + ERROR("Invalid Trusted Key certificate.\n"); + return err; + } + + /* Load and validate Key and Content certificates for BL3-x images */ +#ifdef BL30_BASE + err = load_cert_bl3x(AUTH_BL30_KEY_CERT, BL30_KEY_CERT_NAME, + AUTH_BL30_IMG_CERT, BL30_CERT_NAME, + mem_layout, load_addr); + if (err) { + ERROR("Failed to verify BL3-0 authenticity\n"); + return err; + } +#endif /* BL30_BASE */ + + err = load_cert_bl3x(AUTH_BL31_KEY_CERT, BL31_KEY_CERT_NAME, + AUTH_BL31_IMG_CERT, BL31_CERT_NAME, + mem_layout, load_addr); + if (err) { + ERROR("Failed to verify BL3-1 authenticity\n"); + return err; + } + +#ifdef BL32_BASE + /* BL3-2 image is optional, but keep the return value in case the + * image is present but the certificate is missing */ + err = load_cert_bl3x(AUTH_BL32_KEY_CERT, BL32_KEY_CERT_NAME, + AUTH_BL32_IMG_CERT, BL32_CERT_NAME, + mem_layout, load_addr); + if (err) { + WARN("Failed to verify BL3-2 authenticity\n"); + } + bl32_cert_error = err; +#endif /* BL32_BASE */ + + err = load_cert_bl3x(AUTH_BL33_KEY_CERT, BL33_KEY_CERT_NAME, + AUTH_BL33_IMG_CERT, BL33_CERT_NAME, + mem_layout, load_addr); + if (err) { + ERROR("Failed to verify BL3-3 authenticity\n"); + return err; + } + + return 0; +} + +#endif /* TRUSTED_BOARD_BOOT */ + /******************************************************************************* * Load the BL3-0 image if there's one. * If a platform does not want to attempt to load BL3-0 image it must leave @@ -69,6 +206,20 @@ NULL); if (e == 0) { +#if TRUSTED_BOARD_BOOT + e = auth_verify_obj(AUTH_BL30_IMG, + bl30_image_info.image_base, + bl30_image_info.image_size); + if (e) { + ERROR("Failed to authenticate BL3-0 image.\n"); + panic(); + } + + /* After working with data, invalidate the data cache */ + inv_dcache_range(bl30_image_info.image_base, + (size_t)bl30_image_info.image_size); +#endif /* TRUSTED_BOARD_BOOT */ + /* The subsequent handling of BL3-0 is platform specific */ bl2_plat_handle_bl30(&bl30_image_info); } @@ -106,9 +257,24 @@ bl2_to_bl31_params->bl31_image_info, bl31_ep_info); - if (e == 0) + if (e == 0) { +#if TRUSTED_BOARD_BOOT + e = auth_verify_obj(AUTH_BL31_IMG, + bl2_to_bl31_params->bl31_image_info->image_base, + bl2_to_bl31_params->bl31_image_info->image_size); + if (e) { + ERROR("Failed to authenticate BL3-1 image.\n"); + panic(); + } + + /* After working with data, invalidate the data cache */ + inv_dcache_range(bl2_to_bl31_params->bl31_image_info->image_base, + (size_t)bl2_to_bl31_params->bl31_image_info->image_size); +#endif /* TRUSTED_BOARD_BOOT */ + bl2_plat_set_bl31_ep_info(bl2_to_bl31_params->bl31_image_info, bl31_ep_info); + } return e; } @@ -144,6 +310,25 @@ bl2_to_bl31_params->bl32_ep_info); if (e == 0) { +#if TRUSTED_BOARD_BOOT + /* Image is present. Check if there is a valid certificate */ + if (bl32_cert_error) { + ERROR("Failed to authenticate BL3-2 certificates.\n"); + panic(); + } + + e = auth_verify_obj(AUTH_BL32_IMG, + bl2_to_bl31_params->bl32_image_info->image_base, + bl2_to_bl31_params->bl32_image_info->image_size); + if (e) { + ERROR("Failed to authenticate BL3-2 image.\n"); + panic(); + } + /* After working with data, invalidate the data cache */ + inv_dcache_range(bl2_to_bl31_params->bl32_image_info->image_base, + (size_t)bl2_to_bl31_params->bl32_image_info->image_size); +#endif /* TRUSTED_BOARD_BOOT */ + bl2_plat_set_bl32_ep_info( bl2_to_bl31_params->bl32_image_info, bl2_to_bl31_params->bl32_ep_info); @@ -176,9 +361,23 @@ bl2_to_bl31_params->bl33_image_info, bl2_to_bl31_params->bl33_ep_info); - if (e == 0) + if (e == 0) { +#if TRUSTED_BOARD_BOOT + e = auth_verify_obj(AUTH_BL33_IMG, + bl2_to_bl31_params->bl33_image_info->image_base, + bl2_to_bl31_params->bl33_image_info->image_size); + if (e) { + ERROR("Failed to authenticate BL3-3 image.\n"); + panic(); + } + /* After working with data, invalidate the data cache */ + inv_dcache_range(bl2_to_bl31_params->bl33_image_info->image_base, + (size_t)bl2_to_bl31_params->bl33_image_info->image_size); +#endif /* TRUSTED_BOARD_BOOT */ + bl2_plat_set_bl33_ep_info(bl2_to_bl31_params->bl33_image_info, bl2_to_bl31_params->bl33_ep_info); + } return e; } @@ -200,6 +399,18 @@ /* Perform remaining generic architectural setup in S-EL1 */ bl2_arch_setup(); +#if TRUSTED_BOARD_BOOT + /* Initialize authentication module */ + auth_init(); + + /* Validate the certificates involved in the Chain of Trust */ + e = load_certs(); + if (e) { + ERROR("Chain of Trust invalid. Aborting...\n"); + panic(); + } +#endif /* TRUSTED_BOARD_BOOT */ + /* * Load the subsequent bootloader images */ diff --git a/drivers/io/io_fip.c b/drivers/io/io_fip.c index 7d20590..0cec804 100644 --- a/drivers/io/io_fip.c +++ b/drivers/io/io_fip.c @@ -79,6 +79,19 @@ #if TRUSTED_BOARD_BOOT /* Certificates */ {BL2_CERT_NAME, UUID_TRUSTED_BOOT_FIRMWARE_BL2_CERT}, + {TRUSTED_KEY_CERT_NAME, UUID_TRUSTED_KEY_CERT}, +#ifdef BL30_KEY_CERT_NAME + {BL30_KEY_CERT_NAME, UUID_SCP_FIRMWARE_BL30_KEY_CERT}, +#endif + {BL31_KEY_CERT_NAME, UUID_EL3_RUNTIME_FIRMWARE_BL31_KEY_CERT}, + {BL32_KEY_CERT_NAME, UUID_SECURE_PAYLOAD_BL32_KEY_CERT}, + {BL33_KEY_CERT_NAME, UUID_NON_TRUSTED_FIRMWARE_BL33_KEY_CERT}, +#ifdef BL30_CERT_NAME + {BL30_CERT_NAME, UUID_SCP_FIRMWARE_BL30_CERT}, +#endif + {BL31_CERT_NAME, UUID_EL3_RUNTIME_FIRMWARE_BL31_CERT}, + {BL32_CERT_NAME, UUID_SECURE_PAYLOAD_BL32_CERT}, + {BL33_CERT_NAME, UUID_NON_TRUSTED_FIRMWARE_BL33_CERT}, #endif /* TRUSTED_BOARD_BOOT */ }; diff --git a/plat/fvp/fvp_io_storage.c b/plat/fvp/fvp_io_storage.c index b1e033e..ec1fe58 100644 --- a/plat/fvp/fvp_io_storage.c +++ b/plat/fvp/fvp_io_storage.c @@ -82,6 +82,51 @@ .path = BL2_CERT_NAME, .mode = FOPEN_MODE_RB }; + +static const io_file_spec_t trusted_key_cert_file_spec = { + .path = TRUSTED_KEY_CERT_NAME, + .mode = FOPEN_MODE_RB +}; + +static const io_file_spec_t bl30_key_cert_file_spec = { + .path = BL30_KEY_CERT_NAME, + .mode = FOPEN_MODE_RB +}; + +static const io_file_spec_t bl31_key_cert_file_spec = { + .path = BL31_KEY_CERT_NAME, + .mode = FOPEN_MODE_RB +}; + +static const io_file_spec_t bl32_key_cert_file_spec = { + .path = BL32_KEY_CERT_NAME, + .mode = FOPEN_MODE_RB +}; + +static const io_file_spec_t bl33_key_cert_file_spec = { + .path = BL33_KEY_CERT_NAME, + .mode = FOPEN_MODE_RB +}; + +static const io_file_spec_t bl30_cert_file_spec = { + .path = BL30_CERT_NAME, + .mode = FOPEN_MODE_RB +}; + +static const io_file_spec_t bl31_cert_file_spec = { + .path = BL31_CERT_NAME, + .mode = FOPEN_MODE_RB +}; + +static const io_file_spec_t bl32_cert_file_spec = { + .path = BL32_CERT_NAME, + .mode = FOPEN_MODE_RB +}; + +static const io_file_spec_t bl33_cert_file_spec = { + .path = BL33_CERT_NAME, + .mode = FOPEN_MODE_RB +}; #endif /* TRUSTED_BOARD_BOOT */ static int open_fip(const uintptr_t spec); @@ -127,6 +172,51 @@ (uintptr_t)&bl2_cert_file_spec, open_fip }, { + TRUSTED_KEY_CERT_NAME, + &fip_dev_handle, + (uintptr_t)&trusted_key_cert_file_spec, + open_fip + }, { + BL30_KEY_CERT_NAME, + &fip_dev_handle, + (uintptr_t)&bl30_key_cert_file_spec, + open_fip + }, { + BL31_KEY_CERT_NAME, + &fip_dev_handle, + (uintptr_t)&bl31_key_cert_file_spec, + open_fip + }, { + BL32_KEY_CERT_NAME, + &fip_dev_handle, + (uintptr_t)&bl32_key_cert_file_spec, + open_fip + }, { + BL33_KEY_CERT_NAME, + &fip_dev_handle, + (uintptr_t)&bl33_key_cert_file_spec, + open_fip + }, { + BL30_CERT_NAME, + &fip_dev_handle, + (uintptr_t)&bl30_cert_file_spec, + open_fip + }, { + BL31_CERT_NAME, + &fip_dev_handle, + (uintptr_t)&bl31_cert_file_spec, + open_fip + }, { + BL32_CERT_NAME, + &fip_dev_handle, + (uintptr_t)&bl32_cert_file_spec, + open_fip + }, { + BL33_CERT_NAME, + &fip_dev_handle, + (uintptr_t)&bl33_cert_file_spec, + open_fip + }, { #endif /* TRUSTED_BOARD_BOOT */ 0, 0, 0 } diff --git a/plat/fvp/include/platform_def.h b/plat/fvp/include/platform_def.h index edbbdf3..326ba9d 100644 --- a/plat/fvp/include/platform_def.h +++ b/plat/fvp/include/platform_def.h @@ -83,6 +83,17 @@ #if TRUSTED_BOARD_BOOT /* Certificates */ # define BL2_CERT_NAME "bl2.crt" +# define TRUSTED_KEY_CERT_NAME "trusted_key.crt" + +# define BL30_KEY_CERT_NAME "bl30_key.crt" +# define BL31_KEY_CERT_NAME "bl31_key.crt" +# define BL32_KEY_CERT_NAME "bl32_key.crt" +# define BL33_KEY_CERT_NAME "bl33_key.crt" + +# define BL30_CERT_NAME "bl30.crt" +# define BL31_CERT_NAME "bl31.crt" +# define BL32_CERT_NAME "bl32.crt" +# define BL33_CERT_NAME "bl33.crt" #endif /* TRUSTED_BOARD_BOOT */ #define PLATFORM_CACHE_LINE_SIZE 64 diff --git a/plat/juno/include/platform_def.h b/plat/juno/include/platform_def.h index 748b32d..1071d12 100644 --- a/plat/juno/include/platform_def.h +++ b/plat/juno/include/platform_def.h @@ -74,6 +74,17 @@ #if TRUSTED_BOARD_BOOT /* Certificates */ # define BL2_CERT_NAME "bl2.crt" +# define TRUSTED_KEY_CERT_NAME "trusted_key.crt" + +# define BL30_KEY_CERT_NAME "bl30_key.crt" +# define BL31_KEY_CERT_NAME "bl31_key.crt" +# define BL32_KEY_CERT_NAME "bl32_key.crt" +# define BL33_KEY_CERT_NAME "bl33_key.crt" + +# define BL30_CERT_NAME "bl30.crt" +# define BL31_CERT_NAME "bl31.crt" +# define BL32_CERT_NAME "bl32.crt" +# define BL33_CERT_NAME "bl33.crt" #endif /* TRUSTED_BOARD_BOOT */ #define PLATFORM_CACHE_LINE_SIZE 64 diff --git a/plat/juno/plat_io_storage.c b/plat/juno/plat_io_storage.c index dd9f048..b31865e 100644 --- a/plat/juno/plat_io_storage.c +++ b/plat/juno/plat_io_storage.c @@ -82,6 +82,51 @@ .path = BL2_CERT_NAME, .mode = FOPEN_MODE_RB }; + +static const io_file_spec_t trusted_key_cert_file_spec = { + .path = TRUSTED_KEY_CERT_NAME, + .mode = FOPEN_MODE_RB +}; + +static const io_file_spec_t bl30_key_cert_file_spec = { + .path = BL30_KEY_CERT_NAME, + .mode = FOPEN_MODE_RB +}; + +static const io_file_spec_t bl31_key_cert_file_spec = { + .path = BL31_KEY_CERT_NAME, + .mode = FOPEN_MODE_RB +}; + +static const io_file_spec_t bl32_key_cert_file_spec = { + .path = BL32_KEY_CERT_NAME, + .mode = FOPEN_MODE_RB +}; + +static const io_file_spec_t bl33_key_cert_file_spec = { + .path = BL33_KEY_CERT_NAME, + .mode = FOPEN_MODE_RB +}; + +static const io_file_spec_t bl30_cert_file_spec = { + .path = BL30_CERT_NAME, + .mode = FOPEN_MODE_RB +}; + +static const io_file_spec_t bl31_cert_file_spec = { + .path = BL31_CERT_NAME, + .mode = FOPEN_MODE_RB +}; + +static const io_file_spec_t bl32_cert_file_spec = { + .path = BL32_CERT_NAME, + .mode = FOPEN_MODE_RB +}; + +static const io_file_spec_t bl33_cert_file_spec = { + .path = BL33_CERT_NAME, + .mode = FOPEN_MODE_RB +}; #endif /* TRUSTED_BOARD_BOOT */ static int open_fip(const uintptr_t spec); @@ -132,6 +177,51 @@ (uintptr_t)&bl2_cert_file_spec, open_fip }, { + TRUSTED_KEY_CERT_NAME, + &fip_dev_handle, + (uintptr_t)&trusted_key_cert_file_spec, + open_fip + }, { + BL30_KEY_CERT_NAME, + &fip_dev_handle, + (uintptr_t)&bl30_key_cert_file_spec, + open_fip + }, { + BL31_KEY_CERT_NAME, + &fip_dev_handle, + (uintptr_t)&bl31_key_cert_file_spec, + open_fip + }, { + BL32_KEY_CERT_NAME, + &fip_dev_handle, + (uintptr_t)&bl32_key_cert_file_spec, + open_fip + }, { + BL33_KEY_CERT_NAME, + &fip_dev_handle, + (uintptr_t)&bl33_key_cert_file_spec, + open_fip + }, { + BL30_CERT_NAME, + &fip_dev_handle, + (uintptr_t)&bl30_cert_file_spec, + open_fip + }, { + BL31_CERT_NAME, + &fip_dev_handle, + (uintptr_t)&bl31_cert_file_spec, + open_fip + }, { + BL32_CERT_NAME, + &fip_dev_handle, + (uintptr_t)&bl32_cert_file_spec, + open_fip + }, { + BL33_CERT_NAME, + &fip_dev_handle, + (uintptr_t)&bl33_cert_file_spec, + open_fip + }, { #endif /* TRUSTED_BOARD_BOOT */ 0, 0, 0 }