summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLionel Debieve <lionel.debieve@st.com>2019-09-03 12:22:23 +0200
committerLionel Debieve <lionel.debieve@st.com>2019-09-23 09:48:07 +0000
commit4bdb1a7a6a1325343b0f0c375b43e9b874e31fca (patch)
treeaf4502cef222e473172193ee4889cb227538c89d
parentf700423c1f2426ca3c5ccb9ee4e765743424b074 (diff)
stm32mp1: add authentication support for stm32image
This commit adds authentication binary support for STM32MP1. It prints the bootrom authentication result if signed image is used and authenticates the next loaded STM32 images. It also enables the dynamic translation table support (PLAT_XLAT_TABLES_DYNAMIC) to use bootrom services. Signed-off-by: Lionel Debieve <lionel.debieve@st.com> Change-Id: Iba706519e0dc6b6fae1f3dd498383351f0f75f51
-rw-r--r--drivers/st/io/io_stm32image.c8
-rw-r--r--fdts/stm32mp157c-security.dtsi4
-rw-r--r--plat/st/common/include/stm32mp_auth.h19
-rw-r--r--plat/st/common/stm32mp_auth.c90
-rw-r--r--plat/st/stm32mp1/bl2_plat_setup.c13
-rw-r--r--plat/st/stm32mp1/include/boot_api.h36
-rw-r--r--plat/st/stm32mp1/platform.mk4
-rw-r--r--plat/st/stm32mp1/stm32mp1_def.h3
8 files changed, 174 insertions, 3 deletions
diff --git a/drivers/st/io/io_stm32image.c b/drivers/st/io/io_stm32image.c
index 971dcce5..413521b1 100644
--- a/drivers/st/io/io_stm32image.c
+++ b/drivers/st/io/io_stm32image.c
@@ -246,7 +246,7 @@ static int stm32image_partition_size(io_entity_t *entity, size_t *length)
static int stm32image_partition_read(io_entity_t *entity, uintptr_t buffer,
size_t length, size_t *length_read)
{
- int result = 0;
+ int result;
uint8_t *local_buffer = (uint8_t *)buffer;
boot_api_image_header_t *header =
(boot_api_image_header_t *)first_lba_buffer;
@@ -341,6 +341,12 @@ static int stm32image_partition_read(io_entity_t *entity, uintptr_t buffer,
header->magic = 0;
}
+ result = stm32mp_auth_image(header, buffer);
+ if (result != 0) {
+ ERROR("Authentication Failed (%i)\n", result);
+ return result;
+ }
+
io_close(backend_handle);
}
diff --git a/fdts/stm32mp157c-security.dtsi b/fdts/stm32mp157c-security.dtsi
index f7e55b36..165ffa0c 100644
--- a/fdts/stm32mp157c-security.dtsi
+++ b/fdts/stm32mp157c-security.dtsi
@@ -28,6 +28,10 @@
};
};
+&hash1 {
+ secure-status = "okay";
+};
+
&sdmmc1 {
compatible = "st,stm32-sdmmc2";
};
diff --git a/plat/st/common/include/stm32mp_auth.h b/plat/st/common/include/stm32mp_auth.h
new file mode 100644
index 00000000..3075d18a
--- /dev/null
+++ b/plat/st/common/include/stm32mp_auth.h
@@ -0,0 +1,19 @@
+/*
+ * Copyright (c) 2019, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef STM32MP_AUTH_H
+#define STM32MP_AUTH_H
+
+struct stm32mp_auth_ops {
+ uint32_t (*check_key)(uint8_t *pubkey_in, uint8_t *pubkey_out);
+ uint32_t (*verify_signature)(uint8_t *hash_in, uint8_t *pubkey_in,
+ uint8_t *signature, uint32_t ecc_algo);
+};
+
+void stm32mp_init_auth(struct stm32mp_auth_ops *init_ptr);
+int stm32mp_auth_image(boot_api_image_header_t *header, uintptr_t buffer);
+
+#endif /* STM32MP_AUTH_H */
diff --git a/plat/st/common/stm32mp_auth.c b/plat/st/common/stm32mp_auth.c
new file mode 100644
index 00000000..0ef6d545
--- /dev/null
+++ b/plat/st/common/stm32mp_auth.c
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 2019, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <errno.h>
+
+#include <platform_def.h>
+
+#include <common/debug.h>
+#include <drivers/io/io_storage.h>
+#include <drivers/st/bsec.h>
+#include <drivers/st/stm32_hash.h>
+#include <lib/xlat_tables/xlat_tables_v2.h>
+#include <plat/common/platform.h>
+
+static const struct stm32mp_auth_ops *auth_ops;
+
+void stm32mp_init_auth(struct stm32mp_auth_ops *init_ptr)
+{
+ if ((init_ptr == NULL) ||
+ (init_ptr->check_key == NULL) ||
+ (init_ptr->verify_signature == NULL) ||
+ (stm32_hash_register() != 0)) {
+ panic();
+ }
+
+ auth_ops = init_ptr;
+}
+
+int stm32mp_auth_image(boot_api_image_header_t *header, uintptr_t buffer)
+{
+ int ret;
+ uint8_t image_hash[BOOT_API_SHA256_DIGEST_SIZE_IN_BYTES];
+ uint32_t header_skip_cksum = sizeof(header->magic) +
+ sizeof(header->image_signature) +
+ sizeof(header->payload_checksum);
+
+ /* Check Security Status */
+ if (!stm32mp_is_closed_device()) {
+ if (header->option_flags != 0U) {
+ WARN("Skip signature check (header option)\n");
+ return 0;
+ }
+ INFO("Check signature on Open device\n");
+ }
+
+ ret = mmap_add_dynamic_region(STM32MP_ROM_BASE, STM32MP_ROM_BASE,
+ STM32MP_ROM_SIZE, MT_CODE | MT_SECURE);
+ if (ret != 0) {
+ return ret;
+ }
+
+ /* Check Public Key */
+ if (auth_ops->check_key(header->ecc_pubk, NULL) != BOOT_API_RETURN_OK) {
+ ret = -EINVAL;
+ goto err;
+ }
+
+ /* Compute end of header hash and payload hash */
+ stm32_hash_init(HASH_SHA256);
+
+ ret = stm32_hash_update((uint8_t *)&header->header_version,
+ sizeof(boot_api_image_header_t) -
+ header_skip_cksum);
+ if (ret != 0) {
+ ERROR("Hash of header failed, %i\n", ret);
+ goto err;
+ }
+
+ ret = stm32_hash_final_update((uint8_t *)buffer,
+ header->image_length, image_hash);
+ if (ret != 0) {
+ ERROR("Hash of payload failed\n");
+ goto err;
+ }
+
+ /* Verify signature */
+ if (auth_ops->verify_signature(image_hash, header->ecc_pubk,
+ header->image_signature,
+ header->ecc_algo_type) !=
+ BOOT_API_RETURN_OK) {
+ ret = -EINVAL;
+ }
+
+err:
+ mmap_remove_dynamic_region(STM32MP_ROM_BASE, STM32MP_ROM_SIZE);
+ return ret;
+}
diff --git a/plat/st/stm32mp1/bl2_plat_setup.c b/plat/st/stm32mp1/bl2_plat_setup.c
index c6aefe32..d9e29b4e 100644
--- a/plat/st/stm32mp1/bl2_plat_setup.c
+++ b/plat/st/stm32mp1/bl2_plat_setup.c
@@ -32,6 +32,7 @@
#include <stm32mp1_dbgmcu.h>
static struct console_stm32 console;
+static struct stm32mp_auth_ops stm32mp1_auth_ops;
static void print_reset_reason(void)
{
@@ -284,6 +285,12 @@ void bl2_el3_plat_arch_setup(void)
stm32mp_print_boardinfo();
+ if (boot_context->auth_status != BOOT_API_CTX_AUTH_NO) {
+ NOTICE("Bootrom authentication %s\n",
+ (boot_context->auth_status == BOOT_API_CTX_AUTH_FAILED) ?
+ "failed" : "succeeded");
+ }
+
skip_console_init:
if (stm32_iwdg_init() < 0) {
panic();
@@ -302,6 +309,12 @@ skip_console_init:
ERROR("Cannot save boot interface\n");
}
+ stm32mp1_auth_ops.check_key = boot_context->bootrom_ecdsa_check_key;
+ stm32mp1_auth_ops.verify_signature =
+ boot_context->bootrom_ecdsa_verify_signature;
+
+ stm32mp_init_auth(&stm32mp1_auth_ops);
+
stm32mp1_arch_security_setup();
print_reset_reason();
diff --git a/plat/st/stm32mp1/include/boot_api.h b/plat/st/stm32mp1/include/boot_api.h
index c841a745..2284970f 100644
--- a/plat/st/stm32mp1/include/boot_api.h
+++ b/plat/st/stm32mp1/include/boot_api.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017-2018, STMicroelectronics - All Rights Reserved
+ * Copyright (c) 2017-2019, STMicroelectronics - All Rights Reserved
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -11,6 +11,16 @@
#include <stdio.h>
/*
+ * Possible value of boot context field 'auth_status'
+ */
+/* No authentication done */
+#define BOOT_API_CTX_AUTH_NO 0x0U
+/* Authentication done and failed */
+#define BOOT_API_CTX_AUTH_FAILED 0x1U
+/* Authentication done and succeeded */
+#define BOOT_API_CTX_AUTH_SUCCESS 0x2U
+
+/*
* Possible value of boot context field 'boot_interface_sel'
*/
@@ -114,6 +124,8 @@
/* Closed = OTP_CFG0[6] */
#define BOOT_API_OTP_MODE_CLOSED_BIT_POS 6
+#define BOOT_API_RETURN_OK 0x66U
+
/*
* Boot Context related definitions
*/
@@ -132,7 +144,27 @@ typedef struct {
uint16_t boot_interface_instance;
uint32_t reserved1[13];
uint32_t otp_afmux_values[3];
- uint32_t reserved[9];
+ uint32_t reserved[5];
+ uint32_t auth_status;
+
+ /*
+ * Pointers to bootROM External Secure Services
+ * - ECDSA check key
+ * - ECDSA verify signature
+ * - ECDSA verify signature and go
+ */
+ uint32_t (*bootrom_ecdsa_check_key)(uint8_t *pubkey_in,
+ uint8_t *pubkey_out);
+ uint32_t (*bootrom_ecdsa_verify_signature)(uint8_t *hash_in,
+ uint8_t *pubkey_in,
+ uint8_t *signature,
+ uint32_t ecc_algo);
+ uint32_t (*bootrom_ecdsa_verify_and_go)(uint8_t *hash_in,
+ uint8_t *pub_key_in,
+ uint8_t *signature,
+ uint32_t ecc_algo,
+ uint32_t *entry_in);
+
/*
* Information specific to an SD boot
* Updated each time an SD boot is at least attempted,
diff --git a/plat/st/stm32mp1/platform.mk b/plat/st/stm32mp1/platform.mk
index 83d97703..90b3e3c1 100644
--- a/plat/st/stm32mp1/platform.mk
+++ b/plat/st/stm32mp1/platform.mk
@@ -71,7 +71,9 @@ PLAT_BL_COMMON_SOURCES += drivers/arm/tzc/tzc400.c \
BL2_SOURCES += drivers/io/io_block.c \
drivers/io/io_dummy.c \
drivers/io/io_storage.c \
+ drivers/st/crypto/stm32_hash.c \
drivers/st/io/io_stm32image.c \
+ plat/st/common/stm32mp_auth.c \
plat/st/common/bl2_io_storage.c \
plat/st/stm32mp1/bl2_plat_setup.c
@@ -103,6 +105,8 @@ STM32_TF_ELF := $(STM32_TF_STM32:.stm32=.elf)
STM32_TF_DTBFILE := ${BUILD_PLAT}/fdts/${DTB_FILE_NAME}
STM32_TF_OBJS := ${BUILD_PLAT}/stm32mp1.o
+BL2_CFLAGS += -DPLAT_XLAT_TABLES_DYNAMIC=1
+
# Variables for use with stm32image
STM32IMAGEPATH ?= tools/stm32image
STM32IMAGE ?= ${STM32IMAGEPATH}/stm32image${BIN_EXT}
diff --git a/plat/st/stm32mp1/stm32mp1_def.h b/plat/st/stm32mp1/stm32mp1_def.h
index 0eba8a64..a40852bd 100644
--- a/plat/st/stm32mp1/stm32mp1_def.h
+++ b/plat/st/stm32mp1/stm32mp1_def.h
@@ -19,6 +19,7 @@
#include <drivers/st/stm32mp1_clk.h>
#include <boot_api.h>
+#include <stm32mp_auth.h>
#include <stm32mp_common.h>
#include <stm32mp_dt.h>
#include <stm32mp_shres_helpers.h>
@@ -49,6 +50,8 @@
/*******************************************************************************
* STM32MP1 memory map related constants
******************************************************************************/
+#define STM32MP_ROM_BASE U(0x00000000)
+#define STM32MP_ROM_SIZE U(0x00020000)
#define STM32MP_SYSRAM_BASE U(0x2FFC0000)
#define STM32MP_SYSRAM_SIZE U(0x00040000)