diff --git a/drivers/st/io/io_stm32image.c b/drivers/st/io/io_stm32image.c index aef65eec0f814122f2221b14a185b66446417174..5fbbb33ac6f5f3f7215bb048813a3c138d3fcccd 100644 --- a/drivers/st/io/io_stm32image.c +++ b/drivers/st/io/io_stm32image.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -284,6 +284,9 @@ static int stm32image_partition_read(io_entity_t *entity, uintptr_t buffer, break; } } +#if TRUSTED_BOARD_BOOT + stm32mp_save_loaded_header(header); +#endif /* Part of image already loaded with the header */ memcpy(local_buffer, (uint8_t *)first_lba_buffer + @@ -335,19 +338,6 @@ static int stm32image_partition_read(io_entity_t *entity, uintptr_t buffer, continue; } - result = stm32mp_check_header(header, buffer); - if (result != 0) { - ERROR("Header check failed\n"); - *length_read = 0; - 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/stm32mp151.dtsi b/fdts/stm32mp151.dtsi index 966dcd54e5475790ce7081677bcdfded1a64013c..7ffedba3d1e058fc313d2f61933c83bd6fd5c8a8 100644 --- a/fdts/stm32mp151.dtsi +++ b/fdts/stm32mp151.dtsi @@ -33,7 +33,8 @@ <&nand_otp>, <&uid_otp>, <&package_otp>, - <&hw2_otp>; + <&hw2_otp>, + <&pkh_otp>; nvmem-cell-names = "cfg0_otp", "part_number_otp", @@ -41,7 +42,8 @@ "nand_otp", "uid_otp", "package_otp", - "hw2_otp"; + "hw2_otp", + "pkh_otp"; }; psci { @@ -474,6 +476,9 @@ ts_cal2: calib@5e { reg = <0x5e 0x2>; }; + pkh_otp: pkh_otp@60 { + reg = <0x60 0x20>; + }; mac_addr: mac_addr@e4 { reg = <0xe4 0x8>; st,non-secure-otp; diff --git a/fdts/stm32mp157c-ed1.dts b/fdts/stm32mp157c-ed1.dts index 7414f35c9c611b26b2f6d0074b5a196fb012af93..8c6fedf95d6dac665d5dd27126872b02e29eaae1 100644 --- a/fdts/stm32mp157c-ed1.dts +++ b/fdts/stm32mp157c-ed1.dts @@ -223,6 +223,7 @@ <&uid_otp>, <&package_otp>, <&hw2_otp>, + <&pkh_otp>, <&board_id>; nvmem-cell-names = "cfg0_otp", @@ -232,6 +233,7 @@ "uid_otp", "package_otp", "hw2_otp", + "pkh_otp", "board_id"; }; diff --git a/fdts/stm32mp15xx-dkx.dtsi b/fdts/stm32mp15xx-dkx.dtsi index 036e992ba47b0552b9d048c5a9b51a7df67cfa3c..0e75165e3c3aa5fbb87feb27011e3bf9b4760801 100644 --- a/fdts/stm32mp15xx-dkx.dtsi +++ b/fdts/stm32mp15xx-dkx.dtsi @@ -195,6 +195,7 @@ <&uid_otp>, <&package_otp>, <&hw2_otp>, + <&pkh_otp>, <&board_id>; nvmem-cell-names = "cfg0_otp", @@ -204,6 +205,7 @@ "uid_otp", "package_otp", "hw2_otp", + "pkh_otp", "board_id"; }; diff --git a/plat/st/common/include/stm32mp_auth.h b/plat/st/common/include/stm32mp_auth.h deleted file mode 100644 index 3075d18ac7dc5803f693b8a961e4880b6cec1100..0000000000000000000000000000000000000000 --- a/plat/st/common/include/stm32mp_auth.h +++ /dev/null @@ -1,19 +0,0 @@ -/* - * 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/include/stm32mp_common.h b/plat/st/common/include/stm32mp_common.h index f2bd67d9fb8acafbe4d7f14a82b2854fc0773569..95a595aa6fcca2abfa0c02583c65b366f259f926 100644 --- a/plat/st/common/include/stm32mp_common.h +++ b/plat/st/common/include/stm32mp_common.h @@ -126,6 +126,12 @@ void stm32mp_io_setup(void); */ int stm32mp_check_header(boot_api_image_header_t *header, uintptr_t buffer); +#if TRUSTED_BOARD_BOOT +void stm32mp_save_loaded_header(void *header); +void stm32mp_delete_loaded_header(void); +boot_api_image_header_t *stm32mp_get_loaded_header(void); +#endif + /* Functions to map DDR in MMU with non-cacheable attribute, and unmap it */ int stm32mp_map_ddr_non_cacheable(void); int stm32mp_unmap_ddr(void); diff --git a/plat/st/common/stm32mp_auth.c b/plat/st/common/stm32mp_auth.c deleted file mode 100644 index 29b7cc0df83f386b8097b219380a955b61aed185..0000000000000000000000000000000000000000 --- a/plat/st/common/stm32mp_auth.c +++ /dev/null @@ -1,95 +0,0 @@ -/* - * 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"); - } - - if (auth_ops == NULL) { - ERROR("Device doesn't support image authentication\n"); - return -EOPNOTSUPP; - } - - 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/common/stm32mp_common.c b/plat/st/common/stm32mp_common.c index 908e6832da6cfb1b1ba8121da1b2adcfb9f1e8eb..495de74767bc6eacd82a1c59843a626c9c1d52ec 100644 --- a/plat/st/common/stm32mp_common.c +++ b/plat/st/common/stm32mp_common.c @@ -14,6 +14,7 @@ #include <drivers/st/stm32mp_clkfunc.h> #include <drivers/st/stm32mp_pmic.h> #include <lib/spinlock.h> +#include <lib/utils.h> #include <lib/xlat_tables/xlat_tables_v2.h> #include <plat/common/platform.h> @@ -109,14 +110,11 @@ void stm32mp_pwr_regs_unlock(void) int stm32mp_check_header(boot_api_image_header_t *header, uintptr_t buffer) { - uint32_t i; - uint32_t img_checksum = 0U; - /* * Check header/payload validity: * - Header magic * - Header version - * - Payload checksum + * - Payload checksum if no signature verification */ if (header->magic != BOOT_API_IMAGE_HEADER_MAGIC_NB) { ERROR("Header magic\n"); @@ -129,14 +127,19 @@ int stm32mp_check_header(boot_api_image_header_t *header, uintptr_t buffer) return -EINVAL; } - for (i = 0U; i < header->image_length; i++) { - img_checksum += *(uint8_t *)(buffer + i); - } + if (header->option_flags == 1U) { + uint32_t i; + uint32_t img_checksum = 0U; - if (header->payload_checksum != img_checksum) { - ERROR("Checksum: 0x%x (awaited: 0x%x)\n", img_checksum, - header->payload_checksum); - return -EINVAL; + for (i = 0U; i < header->image_length; i++) { + img_checksum += *(uint8_t *)(buffer + i); + } + + if (header->payload_checksum != img_checksum) { + ERROR("Checksum: 0x%x (awaited: 0x%x)\n", img_checksum, + header->payload_checksum); + return -EINVAL; + } } return 0; @@ -162,6 +165,38 @@ const char *stm32mp_get_cpu_supply_name(void) return supply; } +#if TRUSTED_BOARD_BOOT +/* Save pointer to last loaded header */ +static boot_api_image_header_t *latest_stm32_header; + +/* Save last loaded header */ +void stm32mp_save_loaded_header(void *header) +{ + assert(latest_stm32_header == NULL); + + latest_stm32_header = header; +} + +/* Discard last loaded header */ +void stm32mp_delete_loaded_header(void) +{ + if (latest_stm32_header == NULL) { + return; + } + + zeromem(latest_stm32_header, sizeof(boot_api_image_header_t)); + latest_stm32_header = NULL; +} + +/* Get last loaded header */ +boot_api_image_header_t *stm32mp_get_loaded_header(void) +{ + assert(latest_stm32_header != NULL); + + return latest_stm32_header; +} +#endif /* TRUSTED_BOARD_BOOT */ + int stm32mp_map_ddr_non_cacheable(void) { return mmap_add_dynamic_region(STM32MP_DDR_BASE, STM32MP_DDR_BASE, diff --git a/plat/st/common/stm32mp_cot.c b/plat/st/common/stm32mp_cot.c new file mode 100644 index 0000000000000000000000000000000000000000..5f673fde78cfebafd199205c4886891680773ecf --- /dev/null +++ b/plat/st/common/stm32mp_cot.c @@ -0,0 +1,114 @@ +/* + * Copyright (c) 2020, STMicroelectronics - All Rights Reserved + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <platform_def.h> + +#include <drivers/auth/auth_mod.h> +#include <plat/common/platform.h> + +static auth_param_type_desc_t stm32_header_pk = + AUTH_PARAM_TYPE_DESC(AUTH_PARAM_PUB_KEY, 0); +static auth_param_type_desc_t stm32_header_sig = + AUTH_PARAM_TYPE_DESC(AUTH_PARAM_SIG, 0); +static auth_param_type_desc_t stm32_header_sig_alg = + AUTH_PARAM_TYPE_DESC(AUTH_PARAM_SIG_ALG, 0); +static auth_param_type_desc_t stm32_load = + AUTH_PARAM_TYPE_DESC(AUTH_PARAM_RAW_DATA, 0); + +#if defined(AARCH32_SP_OPTEE) +static const auth_img_desc_t bl32_image = { + .img_id = BL32_IMAGE_ID, + .img_type = IMG_PLAT, + .parent = NULL, + .img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) { + [0] = { + .type = AUTH_METHOD_SIG, + .param.sig = { + .pk = &stm32_header_pk, + .sig = &stm32_header_sig, + .alg = &stm32_header_sig_alg, + .data = &stm32_load + } + }, + }, +}; + +static const auth_img_desc_t bl32_extra1_image = { + .img_id = BL32_EXTRA1_IMAGE_ID, + .img_type = IMG_PLAT, + .parent = NULL, + .img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) { + [0] = { + .type = AUTH_METHOD_SIG, + .param.sig = { + .pk = &stm32_header_pk, + .sig = &stm32_header_sig, + .alg = &stm32_header_sig_alg, + .data = &stm32_load + } + }, + }, +}; + +static const auth_img_desc_t bl32_extra2_image = { + .img_id = BL32_EXTRA2_IMAGE_ID, + .img_type = IMG_PLAT, + .parent = NULL, + .img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) { + [0] = { + .type = AUTH_METHOD_SIG, + .param.sig = { + .pk = &stm32_header_pk, + .sig = &stm32_header_sig, + .alg = &stm32_header_sig_alg, + .data = &stm32_load + } + }, + }, +}; +#else +static const auth_img_desc_t bl32_image = { + .img_id = BL32_IMAGE_ID, + .img_type = IMG_RAW, + .parent = NULL, + .img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) { + [0] = { + .type = AUTH_METHOD_NONE, /* Already verified by BL1 + * as loaded in the same time + * as BL2 + */ + } + }, +}; +#endif + +static const auth_img_desc_t bl33_image = { + .img_id = BL33_IMAGE_ID, + .img_type = IMG_PLAT, + .parent = NULL, + .img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) { + [0] = { + .type = AUTH_METHOD_SIG, + .param.sig = { + .pk = &stm32_header_pk, + .sig = &stm32_header_sig, + .alg = &stm32_header_sig_alg, + .data = &stm32_load + } + }, + }, +}; + +static const auth_img_desc_t * const cot_desc[] = { + [BL32_IMAGE_ID] = &bl32_image, +#if defined(AARCH32_SP_OPTEE) + [BL32_EXTRA1_IMAGE_ID] = &bl32_extra1_image, + [BL32_EXTRA2_IMAGE_ID] = &bl32_extra2_image, +#endif + [BL33_IMAGE_ID] = &bl33_image, +}; + +REGISTER_COT(cot_desc); diff --git a/plat/st/common/stm32mp_crypto_lib.c b/plat/st/common/stm32mp_crypto_lib.c new file mode 100644 index 0000000000000000000000000000000000000000..140fb8858c81433000fdccbd7e13ec2404fdabb6 --- /dev/null +++ b/plat/st/common/stm32mp_crypto_lib.c @@ -0,0 +1,158 @@ +/* + * Copyright (c) 2020, STMicroelectronics - All Rights Reserved + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <assert.h> +#include <errno.h> + +#include <platform_def.h> + +#include <common/debug.h> +#include <drivers/auth/crypto_mod.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> + +struct stm32mp_auth_ops { + uint32_t (*verify_signature)(uint8_t *hash_in, uint8_t *pubkey_in, + uint8_t *signature, uint32_t ecc_algo); +}; + +static struct stm32mp_auth_ops auth_ops; + +static void crypto_lib_init(void) +{ + boot_api_context_t *boot_context = + (boot_api_context_t *)stm32mp_get_boot_ctx_address(); + + if (!stm32mp_is_auth_supported()) { + return; + } + + auth_ops.verify_signature = + boot_context->bootrom_ecdsa_verify_signature; + + if (stm32_hash_register() != 0) { + panic(); + } +} + +static int crypto_verify_signature(void *data_ptr, unsigned int data_len, + void *sig_ptr, unsigned int sig_len, + void *sig_alg, unsigned int sig_alg_len, + void *pk_ptr, unsigned int pk_len) +{ + uint8_t image_hash[BOOT_API_SHA256_DIGEST_SIZE_IN_BYTES]; + uint32_t option_flags; + uint32_t ecc_algo_type; + uint32_t header_len; + int result; + boot_api_image_header_t *header = stm32mp_get_loaded_header(); + + header_len = sizeof(boot_api_image_header_t) - sizeof(header->magic) - + sizeof(header->image_signature) - + sizeof(header->payload_checksum); + + if ((((size_t)sig_alg % __alignof__(uint32_t)) != 0) || + (sig_alg_len != sizeof(option_flags) + sizeof(ecc_algo_type))) { + return -EINVAL; + } + + option_flags = ((uint32_t *)sig_alg)[0]; + ecc_algo_type = ((uint32_t *)sig_alg)[1]; + + /* Check security status */ + if (!stm32mp_is_closed_device()) { + if (option_flags != 0U) { + WARN("Skip signature check (header option)\n"); + stm32mp_delete_loaded_header(); + return 0; + } + INFO("Check signature on Open device\n"); + } + + /* Check key/sign size */ + if ((pk_len != BOOT_API_ECDSA_PUB_KEY_LEN_IN_BYTES) || + (sig_len != BOOT_API_ECDSA_SIGNATURE_LEN_IN_BYTES)) { + return -EINVAL; + } + + result = mmap_add_dynamic_region(STM32MP_ROM_BASE, STM32MP_ROM_BASE, + STM32MP_ROM_SIZE, MT_CODE | MT_SECURE); + if (result != 0) { + return result; + } + + /* Compute hash for the data covered by the signature */ + stm32_hash_init(HASH_SHA256); + + result = stm32_hash_update((void *)&header->header_version, header_len); + if (result != 0) { + VERBOSE("Hash of header failed, %i\n", result); + goto out; + } + + result = stm32_hash_final_update((uint8_t *)data_ptr, + data_len, image_hash); + if (result != 0) { + VERBOSE("Hash of payload failed, %i\n", result); + goto out; + } + + /* Verify signature */ + if (auth_ops.verify_signature(image_hash, pk_ptr, sig_ptr, + ecc_algo_type) != BOOT_API_RETURN_OK) { + result = -EAUTH; + } + +out: + mmap_remove_dynamic_region(STM32MP_ROM_BASE, STM32MP_ROM_SIZE); + if (result != 0) { + stm32mp_delete_loaded_header(); + } + + return result; +} + +static int crypto_verify_hash(void *data_ptr, unsigned int data_len, + void *digest_info_ptr, + unsigned int digest_info_len) +{ + int ret; + uint8_t calc_hash[BOOT_API_SHA256_DIGEST_SIZE_IN_BYTES]; + + if (digest_info_len != BOOT_API_SHA256_DIGEST_SIZE_IN_BYTES) { + VERBOSE("%s: unexpected digest_len\n", __func__); + ret = -EINVAL; + goto out; + } + + stm32_hash_init(HASH_SHA256); + ret = stm32_hash_final_update(data_ptr, data_len, calc_hash); + if (ret != 0) { + VERBOSE("%s: hash failed\n", __func__); + goto out; + } + + ret = memcmp(calc_hash, digest_info_ptr, digest_info_len); + if (ret != 0) { + VERBOSE("%s: not expected digest\n", __func__); + ret = -EAUTH; + } + +out: + /* Clean header as no more used */ + stm32mp_delete_loaded_header(); + + return ret; +} + +REGISTER_CRYPTO_LIB("stm32_crypto_lib", + crypto_lib_init, + crypto_verify_signature, + crypto_verify_hash, + NULL); diff --git a/plat/st/common/stm32mp_img_parser_lib.c b/plat/st/common/stm32mp_img_parser_lib.c new file mode 100644 index 0000000000000000000000000000000000000000..f4c8bd642f554566dc8144fe153180af04149728 --- /dev/null +++ b/plat/st/common/stm32mp_img_parser_lib.c @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2020, STMicroelectronics - All Rights Reserved + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <errno.h> + +#include <platform_def.h> + +#include <common/debug.h> +#include <drivers/auth/img_parser_mod.h> +#include <plat/common/platform.h> + +static void img_lib_init(void) +{ +} + +static int img_check_integrity(void *img, unsigned int img_len) +{ + return stm32mp_check_header(stm32mp_get_loaded_header(), + (uintptr_t)img); +} + +static int img_get_auth_param(const auth_param_type_desc_t *type_desc, + void *img, unsigned int img_len, void **param, + unsigned int *param_len) +{ + boot_api_image_header_t *image_header = stm32mp_get_loaded_header(); + + switch (type_desc->type) { + case AUTH_PARAM_SIG: + *param_len = sizeof(image_header->image_signature); + *param = &image_header->image_signature; + break; + case AUTH_PARAM_SIG_ALG: + *param_len = sizeof(image_header->option_flags) + + sizeof(image_header->ecc_algo_type); + *param = &image_header->option_flags; + /* + * Store option_flags and ecc_alog_type in same param + * structure because they both have the same header fields. + */ + break; + case AUTH_PARAM_PUB_KEY: + *param_len = sizeof(image_header->ecc_pubk); + *param = &image_header->ecc_pubk; + break; + case AUTH_PARAM_RAW_DATA: + if (type_desc->cookie == NULL) { + *param_len = image_header->image_length; + *param = img; + } else { + return -EINVAL; + } + break; + case AUTH_PARAM_NV_CTR: + if (type_desc->cookie == NULL) { + *param_len = sizeof(image_header->image_version); + *param = &image_header->image_version; + } else { + return -EINVAL; + } + break; + default: + return -EINVAL; + } + + return 0; +} + +REGISTER_IMG_PARSER_LIB(IMG_PLAT, "stm32_img_parser_lib", + img_lib_init, + img_check_integrity, + img_get_auth_param); diff --git a/plat/st/common/stm32mp_trusted_boot.c b/plat/st/common/stm32mp_trusted_boot.c new file mode 100644 index 0000000000000000000000000000000000000000..cb6a314d6e6333e140eb2c438840411d430842e1 --- /dev/null +++ b/plat/st/common/stm32mp_trusted_boot.c @@ -0,0 +1,98 @@ +/* + * Copyright (c) 2020-2021, STMicroelectronics - All Rights Reserved + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <endian.h> +#include <errno.h> +#include <limits.h> + +#include <platform_def.h> + +#include <common/debug.h> +#include <plat/common/platform.h> + +static uint32_t root_pk_hash[BOOT_API_SHA256_DIGEST_SIZE_IN_BYTES / + sizeof(uint32_t)]; + +int plat_get_rotpk_info(void *cookie, void **key_ptr, unsigned int *key_len, + unsigned int *flags) +{ + uint32_t otp_idx; + uint32_t otp_val; + uint32_t len; + size_t i; + + if (cookie != NULL) { + return -EINVAL; + } + + if (stm32_get_otp_index(PKH_OTP, &otp_idx, &len) != 0) { + VERBOSE("get_rot_pk_hash: get index error\n"); + return -EINVAL; + } + if (len != (CHAR_BIT * BOOT_API_SHA256_DIGEST_SIZE_IN_BYTES)) { + VERBOSE("get_rot_pk_hash: length Error\n"); + return -EINVAL; + } + + for (i = 0U; i < ARRAY_SIZE(root_pk_hash); i++) { + if (stm32_get_otp_value_from_idx(otp_idx + i, &otp_val) != 0) { + return -EINVAL; + } + + root_pk_hash[i] = bswap32(otp_val); + } + + *key_ptr = &root_pk_hash; + *key_len = BOOT_API_SHA256_DIGEST_SIZE_IN_BYTES; + *flags = ROTPK_IS_HASH; + + if (!stm32mp_is_closed_device()) { + /* Check if key hash values in OTP are 0 or 0xFFFFFFFFF programmed : Invalid Key */ + uint32_t res; + uint32_t rootpk; + uint8_t *proot_pk = root_pk_hash; + uint8_t idx = sizeof(uint32_t); + +#if !STM32MP_USE_STM32IMAGE + idx += sizeof(der_sha256_header); + proot_pk = root_pk_hash + sizeof(der_sha256_header); +#endif + memcpy(&res, proot_pk, sizeof(uint32_t)); + if ((res == 0U) || (res == 0xFFFFFFFFU)) { + while (idx < ARRAY_SIZE(root_pk_hash)) { + memcpy(&rootpk, (proot_pk + idx), sizeof(uint32_t)); + if (res != rootpk) { + return 0; + } + + idx += sizeof(uint32_t); + } + + *flags |= ROTPK_NOT_DEPLOYED; + } + } + + return 0; +} + +int plat_get_nv_ctr(void *cookie, unsigned int *nv_ctr) +{ + /* + * This monotonic counter is the counter used by ROM code + * to identify BL2. + */ + if ((cookie == NULL) && + (stm32_get_otp_value(MONOTONIC_OTP, nv_ctr) == 0)) { + return 0; + } + + return -EINVAL; +} + +int plat_set_nv_ctr(void *cookie, unsigned int nv_ctr) +{ + return -EINVAL; +} diff --git a/plat/st/stm32mp1/bl2_plat_setup.c b/plat/st/stm32mp1/bl2_plat_setup.c index 20c0af2d49cb3d9c3bdfce59fcc03d07ad704a1b..545e870a5f78f104b52c484e6e899639561fed3d 100644 --- a/plat/st/stm32mp1/bl2_plat_setup.c +++ b/plat/st/stm32mp1/bl2_plat_setup.c @@ -56,7 +56,6 @@ static const char debug_msg[626] = { static console_t console; static enum boot_device_e boot_device = BOOT_DEVICE_BOARD; -static struct stm32mp_auth_ops stm32mp1_auth_ops; static bool wakeup_standby; static void print_reset_reason(void) @@ -484,13 +483,23 @@ void bl2_el3_plat_arch_setup(void) stm32mp_print_boardinfo(); +#if TRUSTED_BOARD_BOOT 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"); } +#endif skip_console_init: +#if !TRUSTED_BOARD_BOOT + if (stm32mp_is_closed_device()) { + /* Closed chip required authentication */ + ERROR("Secured chip must enabled TRUSTED_BOARD_BOOT\n"); + panic(); + } +#endif + if (stm32_iwdg_init() < 0) { panic(); } @@ -514,15 +523,6 @@ skip_console_init: ERROR("Cannot save boot interface\n"); } - if (stm32mp_is_auth_supported()) { - 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(); @@ -580,6 +580,11 @@ int bl2_plat_handle_post_image_load(unsigned int image_id) assert(bl_mem_params != NULL); +#if TRUSTED_BOARD_BOOT + /* Clean header to avoid loaded header reused */ + stm32mp_delete_loaded_header(); +#endif + switch (image_id) { case BL32_IMAGE_ID: #if defined(AARCH32_SP_OPTEE) diff --git a/plat/st/stm32mp1/include/boot_api.h b/plat/st/stm32mp1/include/boot_api.h index 9ea508d77a745f33400b2dc5e6cc99d208fea330..cd3154c7ceca53703e0f82b6dcbf9aa8004784d4 100644 --- a/plat/st/stm32mp1/include/boot_api.h +++ b/plat/st/stm32mp1/include/boot_api.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2019, STMicroelectronics - All Rights Reserved + * Copyright (c) 2017-2021, STMicroelectronics - All Rights Reserved * * SPDX-License-Identifier: BSD-3-Clause */ @@ -267,21 +267,14 @@ typedef struct { /* * 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 reserved3; 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); + uint32_t reserved4; /* * Information specific to an SD boot diff --git a/plat/st/stm32mp1/platform.mk b/plat/st/stm32mp1/platform.mk index 6dc857f936aeacac5f960b4f9c981dfdeefcddc7..ad4f1670eaad5e1de888021a2ef3ee8a7a08abc0 100644 --- a/plat/st/stm32mp1/platform.mk +++ b/plat/st/stm32mp1/platform.mk @@ -13,6 +13,8 @@ USE_COHERENT_MEM := 0 ST_VERSION := r1.0 VERSION_STRING := v${VERSION_MAJOR}.${VERSION_MINOR}-${ST_VERSION}(${BUILD_TYPE}):${BUILD_STRING} +TRUSTED_BOARD_BOOT := 1 + # Please don't increment this value without good understanding of # the monotonic counter STM32_TF_VERSION ?= 0 @@ -169,10 +171,21 @@ BL2_SOURCES += drivers/io/io_block.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 +ifeq (${TRUSTED_BOARD_BOOT},1) +AUTH_SOURCES := drivers/auth/auth_mod.c \ + drivers/auth/crypto_mod.c \ + drivers/auth/img_parser_mod.c + +BL2_SOURCES += $(AUTH_SOURCES) \ + plat/st/common/stm32mp_cot.c \ + plat/st/common/stm32mp_crypto_lib.c \ + plat/st/common/stm32mp_img_parser_lib.c \ + plat/st/common/stm32mp_trusted_boot.c +endif + ifneq ($(filter 1,${STM32MP_EMMC} ${STM32MP_SDMMC}),) BL2_SOURCES += drivers/mmc/mmc.c \ drivers/partition/gpt.c \ diff --git a/plat/st/stm32mp1/stm32mp1_def.h b/plat/st/stm32mp1/stm32mp1_def.h index fa7b5d32874fa8d3aca77684ebb282d7d8f4c913..4cf88e22b99d3597abb487a065b065fa9dd70cd9 100644 --- a/plat/st/stm32mp1/stm32mp1_def.h +++ b/plat/st/stm32mp1/stm32mp1_def.h @@ -23,7 +23,6 @@ #include <drivers/st/stm32mp1_pwr.h> #include <boot_api.h> -#include <stm32mp_auth.h> #include <stm32mp_common.h> #include <stm32mp_dt.h> #include <stm32mp_shres_helpers.h> @@ -350,6 +349,7 @@ enum ddr_type { #define NAND_OTP "nand_otp" #define MONOTONIC_OTP "monotonic_otp" #define UID_OTP "uid_otp" +#define PKH_OTP "pkh_otp" #define BOARD_ID_OTP "board_id" /* OTP mask */