summaryrefslogtreecommitdiff
path: root/bl2
diff options
context:
space:
mode:
authorJuan Castillo <juan.castillo@arm.com>2015-01-28 16:46:57 +0000
committerDan Handley <dan.handley@arm.com>2015-01-28 18:27:54 +0000
commitdec840af4b2d071516863faa274e9fa68a72d42a (patch)
tree0338507519574f6f86cd77f31f1ec956d5729429 /bl2
parentbed82ac9dfa856ff034491c68b66b3661766d26e (diff)
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
Diffstat (limited to 'bl2')
-rw-r--r--bl2/bl2_main.c215
1 files changed, 213 insertions, 2 deletions
diff --git a/bl2/bl2_main.c b/bl2/bl2_main.c
index b7e2cff4..29ca0a5a 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 @@ static int load_bl30(void)
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 @@ static int load_bl31(bl31_params_t *bl2_to_bl31_params,
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 @@ static int load_bl32(bl31_params_t *bl2_to_bl31_params)
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 @@ static int load_bl33(bl31_params_t *bl2_to_bl31_params)
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 @@ void bl2_main(void)
/* 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
*/