TBB: authenticate BL3-x images and certificates
This patch adds support to authenticate the Trusted Key certificate
and the BL3-x certificates and images at BL2.
Change-Id: I69a8c13a14c8da8b75f93097d3a4576aed71c5dd
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 <arch.h>
#include <arch_helpers.h>
#include <assert.h>
+#include <auth.h>
#include <bl_common.h>
#include <debug.h>
#include <platform.h>
#include <platform_def.h>
#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 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 */
+
- if (e == 0)
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
}