diff --git a/drivers/st/io/io_stm32image.c b/drivers/st/io/io_stm32image.c index 971dcce..413521b 100644 --- a/drivers/st/io/io_stm32image.c +++ b/drivers/st/io/io_stm32image.c @@ -246,7 +246,7 @@ 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 @@ 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 f7e55b3..165ffa0 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 0000000..3075d18 --- /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 0000000..0ef6d54 --- /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 + +#include + +#include +#include +#include +#include +#include +#include + +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 c6aefe3..d9e29b4 100644 --- a/plat/st/stm32mp1/bl2_plat_setup.c +++ b/plat/st/stm32mp1/bl2_plat_setup.c @@ -32,6 +32,7 @@ #include static struct console_stm32 console; +static struct stm32mp_auth_ops stm32mp1_auth_ops; static void print_reset_reason(void) { @@ -284,6 +285,12 @@ 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 @@ 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 c841a74..2284970 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 /* + * 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 @@ 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 83d9770..90b3e3c 100644 --- a/plat/st/stm32mp1/platform.mk +++ b/plat/st/stm32mp1/platform.mk @@ -71,7 +71,9 @@ 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_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 0eba8a6..a40852b 100644 --- a/plat/st/stm32mp1/stm32mp1_def.h +++ b/plat/st/stm32mp1/stm32mp1_def.h @@ -19,6 +19,7 @@ #include #include +#include #include #include #include @@ -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)