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 */