diff --git a/Makefile b/Makefile
index bd52c0bd752730f2726b0c2c51617406812d5eb6..72db2a74ae517bd1fcc912148ca6a091890e87c0 100644
--- a/Makefile
+++ b/Makefile
@@ -604,6 +604,14 @@ ifeq ($(CTX_INCLUDE_MTE_REGS),1)
     endif
 endif
 
+ifeq ($(MEASURED_BOOT),1)
+    ifneq (${TRUSTED_BOARD_BOOT},1)
+        $(error MEASURED_BOOT requires TRUSTED_BOARD_BOOT=1")
+    else
+        $(info MEASURED_BOOT is an experimental feature)
+    endif
+endif
+
 ################################################################################
 # Process platform overrideable behaviour
 ################################################################################
@@ -751,6 +759,7 @@ $(eval $(call assert_boolean,GENERATE_COT))
 $(eval $(call assert_boolean,GICV2_G0_FOR_EL3))
 $(eval $(call assert_boolean,HANDLE_EA_EL3_FIRST))
 $(eval $(call assert_boolean,HW_ASSISTED_COHERENCY))
+$(eval $(call assert_boolean,MEASURED_BOOT))
 $(eval $(call assert_boolean,NS_TIMER_SWITCH))
 $(eval $(call assert_boolean,OVERRIDE_LIBC))
 $(eval $(call assert_boolean,PL011_GENERIC_UART))
@@ -817,6 +826,7 @@ $(eval $(call add_define,GICV2_G0_FOR_EL3))
 $(eval $(call add_define,HANDLE_EA_EL3_FIRST))
 $(eval $(call add_define,HW_ASSISTED_COHERENCY))
 $(eval $(call add_define,LOG_LEVEL))
+$(eval $(call add_define,MEASURED_BOOT))
 $(eval $(call add_define,NS_TIMER_SWITCH))
 $(eval $(call add_define,PL011_GENERIC_UART))
 $(eval $(call add_define,PLAT_${PLAT}))
diff --git a/docs/getting_started/build-options.rst b/docs/getting_started/build-options.rst
index fc4545571fd128030f9e9147ffd265d57ecc4043..b702c34def0f07968262b3c71052084c7580bccd 100644
--- a/docs/getting_started/build-options.rst
+++ b/docs/getting_started/build-options.rst
@@ -387,6 +387,11 @@ Common build options
    All log output up to and including the selected log level is compiled into
    the build. The default value is 40 in debug builds and 20 in release builds.
 
+-  ``MEASURED_BOOT``: Boolean flag to include support for the Measured Boot
+   feature. If this flag is enabled ``TRUSTED_BOARD_BOOT`` must be set.
+   This option defaults to 0 and is an experimental feature in the stage of
+   development.
+
 -  ``NON_TRUSTED_WORLD_KEY``: This option is used when ``GENERATE_COT=1``. It
    specifies the file that contains the Non-Trusted World private key in PEM
    format. If ``SAVE_KEYS=1``, this file name will be used to save the key.
diff --git a/drivers/auth/crypto_mod.c b/drivers/auth/crypto_mod.c
index 5e5ac2b03d100c20250459d10e38f28a953871d9..110c5045fd09c69a1df702c075ae707de627f82c 100644
--- a/drivers/auth/crypto_mod.c
+++ b/drivers/auth/crypto_mod.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -103,3 +103,24 @@ int crypto_mod_verify_hash(void *data_ptr, unsigned int data_len,
 	return crypto_lib_desc.verify_hash(data_ptr, data_len,
 					   digest_info_ptr, digest_info_len);
 }
+
+#if MEASURED_BOOT
+/*
+ * Calculate a hash
+ *
+ * Parameters:
+ *
+ *   alg: message digest algorithm
+ *   data_ptr, data_len: data to be hashed
+ *   output: resulting hash
+ */
+int crypto_mod_calc_hash(unsigned int alg, void *data_ptr,
+			 unsigned int data_len, unsigned char *output)
+{
+	assert(data_ptr != NULL);
+	assert(data_len != 0);
+	assert(output != NULL);
+
+	return crypto_lib_desc.calc_hash(alg, data_ptr, data_len, output);
+}
+#endif	/* MEASURED_BOOT */
diff --git a/drivers/auth/mbedtls/mbedtls_crypto.c b/drivers/auth/mbedtls/mbedtls_crypto.c
index 33420fbbd1b0c59ca7f954b8c193a6ac1ba14e85..04fbc648b9d9f096e10e684005fca5e925ce6eea 100644
--- a/drivers/auth/mbedtls/mbedtls_crypto.c
+++ b/drivers/auth/mbedtls/mbedtls_crypto.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -205,7 +205,32 @@ static int verify_hash(void *data_ptr, unsigned int data_len,
 	return CRYPTO_SUCCESS;
 }
 
+#if MEASURED_BOOT
+/*
+ * Calculate a hash
+ *
+ * output points to the computed hash
+ */
+int calc_hash(unsigned int alg, void *data_ptr,
+	      unsigned int data_len, unsigned char *output)
+{
+	const mbedtls_md_info_t *md_info;
+
+	md_info = mbedtls_md_info_from_type((mbedtls_md_type_t)alg);
+	if (md_info == NULL) {
+		return CRYPTO_ERR_HASH;
+	}
+
+	/* Calculate the hash of the data */
+	return mbedtls_md(md_info, data_ptr, data_len, output);
+}
+#endif /* MEASURED_BOOT */
+
 /*
  * Register crypto library descriptor
  */
+#if MEASURED_BOOT
+REGISTER_CRYPTO_LIB(LIB_NAME, init, verify_signature, verify_hash, calc_hash);
+#else
 REGISTER_CRYPTO_LIB(LIB_NAME, init, verify_signature, verify_hash);
+#endif /* MEASURED_BOOT */
diff --git a/include/drivers/auth/crypto_mod.h b/include/drivers/auth/crypto_mod.h
index 3a4210569c0b8748cff42a3933bb6f93cd130b1c..f211035d707a5c9fa8c4bf78c82ac675fefbce7b 100644
--- a/include/drivers/auth/crypto_mod.h
+++ b/include/drivers/auth/crypto_mod.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -37,6 +37,13 @@ typedef struct crypto_lib_desc_s {
 	/* Verify a hash. Return one of the 'enum crypto_ret_value' options */
 	int (*verify_hash)(void *data_ptr, unsigned int data_len,
 			   void *digest_info_ptr, unsigned int digest_info_len);
+
+#if MEASURED_BOOT
+	/* Calculate a hash. Return hash value */
+	int (*calc_hash)(unsigned int alg, void *data_ptr,
+			 unsigned int data_len, unsigned char *output);
+#endif /* MEASURED_BOOT */
+
 } crypto_lib_desc_t;
 
 /* Public functions */
@@ -48,7 +55,21 @@ int crypto_mod_verify_signature(void *data_ptr, unsigned int data_len,
 int crypto_mod_verify_hash(void *data_ptr, unsigned int data_len,
 			   void *digest_info_ptr, unsigned int digest_info_len);
 
+#if MEASURED_BOOT
+int crypto_mod_calc_hash(unsigned int alg, void *data_ptr,
+			 unsigned int data_len, unsigned char *output);
+
 /* Macro to register a cryptographic library */
+#define REGISTER_CRYPTO_LIB(_name, _init, _verify_signature, _verify_hash, \
+							     _calc_hash) \
+	const crypto_lib_desc_t crypto_lib_desc = { \
+		.name = _name, \
+		.init = _init, \
+		.verify_signature = _verify_signature, \
+		.verify_hash = _verify_hash, \
+		.calc_hash = _calc_hash \
+	}
+#else
 #define REGISTER_CRYPTO_LIB(_name, _init, _verify_signature, _verify_hash) \
 	const crypto_lib_desc_t crypto_lib_desc = { \
 		.name = _name, \
@@ -56,6 +77,7 @@ int crypto_mod_verify_hash(void *data_ptr, unsigned int data_len,
 		.verify_signature = _verify_signature, \
 		.verify_hash = _verify_hash \
 	}
+#endif	/* MEASURED_BOOT */
 
 extern const crypto_lib_desc_t crypto_lib_desc;
 
diff --git a/make_helpers/defaults.mk b/make_helpers/defaults.mk
index 53832c5611454bc9aec3c751674d0307d03cb74b..4af1da6b2c0a573f50b47ae58f0b9ad2dbaf3c8b 100644
--- a/make_helpers/defaults.mk
+++ b/make_helpers/defaults.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2016-2019, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2016-2020, ARM Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -139,6 +139,9 @@ HW_ASSISTED_COHERENCY		:= 0
 # Set the default algorithm for the generation of Trusted Board Boot keys
 KEY_ALG				:= rsa
 
+# Option to build TF with Measured Boot support
+MEASURED_BOOT			:= 0
+
 # NS timer register save and restore
 NS_TIMER_SWITCH			:= 0