Merge "docs(juno): update SCP downloads link" into integration
diff --git a/Makefile b/Makefile
index 98e448f..5306ddf 100644
--- a/Makefile
+++ b/Makefile
@@ -1189,6 +1189,7 @@
         ENABLE_FEAT_S1PIE \
         ENABLE_FEAT_S2POE \
         ENABLE_FEAT_S1POE \
+        ENABLE_FEAT_GCS \
         ENABLE_FEAT_VHE \
         ENABLE_MPAM_FOR_LOWER_ELS \
         ENABLE_RME \
@@ -1329,6 +1330,7 @@
         ENABLE_FEAT_S1PIE \
         ENABLE_FEAT_S2POE \
         ENABLE_FEAT_S1POE \
+        ENABLE_FEAT_GCS \
         FEATURE_DETECTION \
         TWED_DELAY \
         ENABLE_FEAT_TWED \
diff --git a/bl1/bl1.mk b/bl1/bl1.mk
index 0c43f13..b1791b1 100644
--- a/bl1/bl1.mk
+++ b/bl1/bl1.mk
@@ -29,4 +29,10 @@
 BL1_SOURCES		+=	bl1/bl1_fwu.c
 endif
 
+ifneq ($(findstring gcc,$(notdir $(LD))),)
+        BL1_LDFLAGS	+=	-Wl,--sort-section=alignment
+else ifneq ($(findstring ld,$(notdir $(LD))),)
+        BL1_LDFLAGS	+=	--sort-section=alignment
+endif
+
 BL1_DEFAULT_LINKER_SCRIPT_SOURCE := bl1/bl1.ld.S
diff --git a/bl32/tsp/tsp_main.c b/bl32/tsp/tsp_main.c
index df9903b..0878ea4 100644
--- a/bl32/tsp/tsp_main.c
+++ b/bl32/tsp/tsp_main.c
@@ -263,7 +263,7 @@
 		results[1] /= service_arg1 ? service_arg1 : 1;
 		break;
 	case TSP_CHECK_DIT:
-		if (!is_armv8_4_dit_present()) {
+		if (!is_feat_dit_supported()) {
 			ERROR("DIT not supported\n");
 			results[0] = 0;
 			results[1] = 0xffff;
diff --git a/changelog.yaml b/changelog.yaml
index 7dcb4df..d54c62b 100644
--- a/changelog.yaml
+++ b/changelog.yaml
@@ -101,9 +101,15 @@
       - title: Extended Cache Index (FEAT_CCIDX)
         scope: ccidx
 
+      - title: Extended Translation Control Register (FEAT_TCR2).
+        scope: tcr2
+
       - title: CPU feature / ID register handling in general
         scope: cpufeat
 
+      - title: Guarded Control Stack (FEAT_GCS)
+        scope: gcs
+
       - title: Support for the `HCRX_EL2` register (FEAT_HCX)
         scope: hcx
 
diff --git a/common/feat_detect.c b/common/feat_detect.c
index 1582b9d..c8a0703 100644
--- a/common/feat_detect.c
+++ b/common/feat_detect.c
@@ -80,16 +80,6 @@
 #endif
 }
 
-/************************************************************
- * Feature : FEAT_DIT (Data Independent Timing Instructions)
- ***********************************************************/
-static void read_feat_dit(void)
-{
-#if (ENABLE_FEAT_DIT == FEAT_STATE_ALWAYS)
-	feat_detect_panic(is_armv8_4_feat_dit_present(), "DIT");
-#endif
-}
-
 /************************************************
  * Feature : FEAT_MTE (Memory Tagging Extension)
  ***********************************************/
@@ -178,7 +168,7 @@
 	read_feat_pauth();
 
 	/* v8.4 features */
-	read_feat_dit();
+	check_feature(ENABLE_FEAT_DIT, read_feat_dit_id_field(), "DIT", 1, 1);
 	check_feature(ENABLE_FEAT_AMU, read_feat_amu_id_field(),
 		      "AMUv1", 1, 2);
 	check_feature(ENABLE_MPAM_FOR_LOWER_ELS, read_feat_mpam_version(),
@@ -228,6 +218,10 @@
 	/* v9.2 features */
 	check_feature(ENABLE_SME_FOR_NS, read_feat_sme_id_field(),
 		      "SME", 1, 2);
+
+	/* v9.4 features */
+	check_feature(ENABLE_FEAT_GCS, read_feat_gcs_id_field(), "GCS", 1, 1);
+
 	read_feat_rme();
 
 	if (tainted) {
diff --git a/docs/about/maintainers.rst b/docs/about/maintainers.rst
index 9b934c9..02dae05 100644
--- a/docs/about/maintainers.rst
+++ b/docs/about/maintainers.rst
@@ -98,6 +98,8 @@
 :|G|: `ManishVB-Arm`_
 :|M|: Lauren Wehrmeister <Lauren.Wehrmeister@arm.com>
 :|G|: `laurenw-arm`_
+:|M|: Jimmy Brisson <jimmy.brisson@arm.com>
+:|G|: `jimmy-brisson`_
 :|F|: drivers/auth/
 
 Secure Partition Manager Core (EL3 FF-A SPMC)
@@ -355,6 +357,8 @@
 :|G|: `sandrine-bailleux-arm`_
 :|M|: Manish Badarkhe <manish.badarkhe@arm.com>
 :|G|: `ManishVB-Arm`_
+:|M|: Jimmy Brisson <jimmy.brisson@arm.com>
+:|G|: `jimmy-brisson`_
 :|F|: drivers/measured_boot
 :|F|: include/drivers/measured_boot
 :|F|: docs/components/measured_boot
@@ -381,6 +385,8 @@
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 :|M|: Sandrine Bailleux <sandrine.bailleux@arm.com>
 :|G|: `sandrine-bailleux-arm`_
+:|M|: Jimmy Brisson <jimmy.brisson@arm.com>
+:|G|: `jimmy-brisson`_
 :|F|: include/lib/psa
 :|F|: lib/psa
 
@@ -844,6 +850,8 @@
 :|G|: `ManishVB-Arm`_
 :|M|: Lauren Wehrmeister <Lauren.Wehrmeister@arm.com>
 :|G|: `laurenw-arm`_
+:|M|: Jimmy Brisson <jimmy.brisson@arm.com>
+:|G|: `jimmy-brisson`_
 :|F|: tools/cert_create/
 
 Encrypt_fw tool
@@ -969,5 +977,6 @@
 .. _jayanthchidanand-arm: https://github.com/jayanthchidanand-arm
 .. _bytefire: https://github.com/bytefire
 .. _rupsin01: https://github.com/rupsin01
+.. _jimmy-brisson: https://github.com/theotherjimmy
 
 .. _Project Maintenance Process: https://developer.trustedfirmware.org/w/collaboration/project-maintenance-process/
diff --git a/docs/design/auth-framework.rst b/docs/design/auth-framework.rst
index 6913e66..597f955 100644
--- a/docs/design/auth-framework.rst
+++ b/docs/design/auth-framework.rst
@@ -236,18 +236,56 @@
                             void *sig_ptr, unsigned int sig_len,
                             void *sig_alg, unsigned int sig_alg_len,
                             void *pk_ptr, unsigned int pk_len);
+    int (*calc_hash)(enum crypto_md_algo alg, void *data_ptr,
+                     unsigned int data_len,
+                     unsigned char output[CRYPTO_MD_MAX_SIZE])
     int (*verify_hash)(void *data_ptr, unsigned int data_len,
                        void *digest_info_ptr, unsigned int digest_info_len);
+    int (*auth_decrypt)(enum crypto_dec_algo dec_algo, void *data_ptr,
+                        size_t len, const void *key, unsigned int key_len,
+                        unsigned int key_flags, const void *iv,
+                        unsigned int iv_len, const void *tag,
+                        unsigned int tag_len);
 
 These functions are registered in the CM using the macro:
 
 .. code:: c
 
-    REGISTER_CRYPTO_LIB(_name, _init, _verify_signature, _verify_hash);
+    REGISTER_CRYPTO_LIB(_name,
+                        _init,
+                        _verify_signature,
+                        _calc_hash,
+                        _verify_hash,
+                        _auth_decrypt,
+                        _convert_pk);
 
 ``_name`` must be a string containing the name of the CL. This name is used for
 debugging purposes.
 
+Crypto module provides a function ``_calc_hash`` to calculate and
+return the hash of the given data using the provided hash algorithm.
+This function is mainly used in the ``MEASURED_BOOT`` and ``DRTM_SUPPORT``
+features to calculate the hashes of various images/data.
+
+Optionally, a platform function can be provided to convert public key
+(_convert_pk). It is only used if the platform saves a hash of the ROTPK.
+Most platforms save the hash of the ROTPK, but some may save slightly different
+information - e.g the hash of the ROTPK plus some related information.
+Defining this function allows to transform the ROTPK used to verify
+the signature to the buffer (a platform specific public key) which
+hash is saved in OTP.
+
+.. code:: c
+
+    int (*convert_pk)(void *full_pk_ptr, unsigned int full_pk_len,
+                      void **hashed_pk_ptr, unsigned int *hashed_pk_len);
+
+
+-  ``full_pk_ptr``: Pointer to Distinguished Encoding Rules (DER) ROTPK.
+-  ``full_pk_len``: DER ROTPK size.
+-  ``hashed_pk_ptr``: to return a pointer to a buffer, which hash should be the one saved in OTP.
+-  ``hashed_pk_len``: previous buffer size
+
 Image Parser Module (IPM)
 ^^^^^^^^^^^^^^^^^^^^^^^^^
 
@@ -936,7 +974,7 @@
 based on mbed TLS, which can be found in
 ``drivers/auth/mbedtls/mbedtls_crypto.c``. This library is registered in the
 authentication framework using the macro ``REGISTER_CRYPTO_LIB()`` and exports
-four functions:
+below functions:
 
 .. code:: c
 
@@ -945,6 +983,9 @@
                          void *sig_ptr, unsigned int sig_len,
                          void *sig_alg, unsigned int sig_alg_len,
                          void *pk_ptr, unsigned int pk_len);
+    int crypto_mod_calc_hash(enum crypto_md_algo alg, void *data_ptr,
+                             unsigned int data_len,
+                             unsigned char output[CRYPTO_MD_MAX_SIZE])
     int verify_hash(void *data_ptr, unsigned int data_len,
                     void *digest_info_ptr, unsigned int digest_info_len);
     int auth_decrypt(enum crypto_dec_algo dec_algo, void *data_ptr,
@@ -975,6 +1016,6 @@
 
 --------------
 
-*Copyright (c) 2017-2020, Arm Limited and Contributors. All rights reserved.*
+*Copyright (c) 2017-2023, Arm Limited and Contributors. All rights reserved.*
 
 .. _TBBR-Client specification: https://developer.arm.com/docs/den0006/latest/trusted-board-boot-requirements-client-tbbr-client-armv8-a
diff --git a/docs/getting_started/build-options.rst b/docs/getting_started/build-options.rst
index 03be786..d2f463f 100644
--- a/docs/getting_started/build-options.rst
+++ b/docs/getting_started/build-options.rst
@@ -374,6 +374,12 @@
    can take the values 0 to 2, to align  with the ``FEATURE_DETECTION``
    mechanism. Default value is ``0``.
 
+-  ``ENABLE_FEAT_GCS``: Numeric value to set the bit SCR_EL3.GCSEn in EL3 to
+   allow use of Guarded Control Stack from EL2 as well as adding the GCS
+   registers to the EL2 context save/restore operations. This flag can take
+   the values 0 to 2, to align  with the ``FEATURE_DETECTION`` mechanism.
+   Default value is ``0``.
+
 -  ``ENABLE_LTO``: Boolean option to enable Link Time Optimization (LTO)
    support in GCC for TF-A. This option is currently only supported for
    AArch64. Default is 0.
diff --git a/docs/global_substitutions.txt b/docs/global_substitutions.txt
index 0cf2946..9428fe9 100644
--- a/docs/global_substitutions.txt
+++ b/docs/global_substitutions.txt
@@ -50,15 +50,18 @@
 .. |SP| replace:: :term:`SP`
 .. |SPD| replace:: :term:`SPD`
 .. |SPM| replace:: :term:`SPM`
+.. |SRTM| replace:: :term:`SRTM`
 .. |SSBS| replace:: :term:`SSBS`
 .. |SVE| replace:: :term:`SVE`
 .. |TBB| replace:: :term:`TBB`
 .. |TBBR| replace:: :term:`TBBR`
+.. |TCG| replace:: :term:`TCG`
 .. |TEE| replace:: :term:`TEE`
 .. |TF-A| replace:: :term:`TF-A`
 .. |TF-M| replace:: :term:`TF-M`
 .. |TLB| replace:: :term:`TLB`
 .. |TLK| replace:: :term:`TLK`
+.. |TPM| replace:: :term:`TPM`
 .. |TRNG| replace:: :term:`TRNG`
 .. |TSP| replace:: :term:`TSP`
 .. |TZC| replace:: :term:`TZC`
diff --git a/docs/glossary.rst b/docs/glossary.rst
index e6b0239..57fde2d 100644
--- a/docs/glossary.rst
+++ b/docs/glossary.rst
@@ -187,6 +187,9 @@
    SPM
       Secure Partition Manager
 
+   SRTM
+      Static Root of Trust for Measurement
+
    SSBS
       Speculative Store Bypass Safe. Introduced in Armv8.5, this configuration
       bit can be set by software to allow or prevent the hardware from
@@ -204,6 +207,9 @@
    TCB
       Trusted Compute Base
 
+   TCG
+      Trusted Computing Group
+
    TEE
       Trusted Execution Environment
 
@@ -219,6 +225,9 @@
    TLK
       Trusted Little Kernel. A Trusted OS from NVIDIA.
 
+   TPM
+      Trusted Platform Module
+
    TRNG
       True Randon Number Generator (hardware based)
 
diff --git a/docs/porting-guide.rst b/docs/porting-guide.rst
index bc9c00f..25b55e8 100644
--- a/docs/porting-guide.rst
+++ b/docs/porting-guide.rst
@@ -894,34 +894,6 @@
 either could not be updated or the authentication image descriptor indicates
 that it is not allowed to be updated.
 
-Function: plat_convert_pk()
-~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-::
-
-    Argument : void *, unsigned int, void **, unsigned int *
-    Return   : int
-
-This function is optional when Trusted Board Boot is enabled, and only
-used if the platform saves a hash of the ROTPK.
-First argument is the Distinguished Encoding Rules (DER) ROTPK.
-Second argument is its size.
-Third argument is used to return a pointer to a buffer, which hash should
-be the one saved in OTP.
-Fourth argument is a pointer to return its size.
-
-Most platforms save the hash of the ROTPK, but some may save slightly different
-information - e.g the hash of the ROTPK plus some related information.
-Defining this function allows to transform the ROTPK used to verify
-the signature to the buffer (a platform specific public key) which
-hash is saved in OTP.
-
-The default implementation copies the input key and length to the output without
-modification.
-
-The function returns 0 on success. Any other value means the expected
-public key buffer cannot be extracted.
-
 Dynamic Root of Trust for Measurement support (in BL31)
 -------------------------------------------------------
 
diff --git a/docs/process/platform-ports-policy.rst b/docs/process/platform-ports-policy.rst
index 7983749..b296a5f 100644
--- a/docs/process/platform-ports-policy.rst
+++ b/docs/process/platform-ports-policy.rst
@@ -10,12 +10,18 @@
 Platform compatibility is mainly affected by changes to Platform APIs (as
 documented in the :ref:`Porting Guide`), driver APIs (like the GICv3 drivers) or
 library interfaces (like xlat_table library). The project will try to maintain
-compatibility for upstream platforms. Due to evolving requirements and
-enhancements, there might be changes affecting platform compatibility which
-means the previous interface needs to be deprecated and a new interface
-introduced to replace it. In case the migration to the new interface is trivial,
-the contributor of the change is expected to make good effort to migrate the
-upstream platforms to the new interface.
+compatibility for upstream platforms.
+
+Due to evolving requirements and enhancements, there might be changes affecting
+platform compatibility, which means the previous interface needs to be deprecated
+and a new interface introduced to replace it. In case the migration to the new
+interface is trivial, the contributor of the change is expected to make good
+effort to migrate the upstream platforms to the new interface.
+
+The project will generally not take into account downstream platforms. If those
+are affected by a deprecation / removal decision, we encourage their maintainers
+to upstream their platform code or copy the latest version of the code being
+deprecated into their downstream tree.
 
 The deprecated interfaces are listed inside :ref:`Release Processes` as well as
 the release after which each one will be removed. When an interface is
@@ -46,6 +52,6 @@
 
 --------------
 
-*Copyright (c) 2018-2022, Arm Limited and Contributors. All rights reserved.*
+*Copyright (c) 2018-2023, Arm Limited and Contributors. All rights reserved.*
 
 .. _TF-A public mailing list: https://lists.trustedfirmware.org/mailman3/lists/tf-a.lists.trustedfirmware.org/
diff --git a/docs/threat_model/threat_model.rst b/docs/threat_model/threat_model.rst
index 940cad5..71ec9b1 100644
--- a/docs/threat_model/threat_model.rst
+++ b/docs/threat_model/threat_model.rst
@@ -36,12 +36,34 @@
 - There is no Secure-EL2. We don't consider threats that may come with
   Secure-EL2 software.
 
-- Measured boot is disabled. We do not consider the threats nor the mitigations
-  that may come with it.
-
 - No experimental features are enabled. We do not consider threats that may come
   from them.
 
+.. note::
+
+ In the current Measured Boot design, BL1, BL2, and BL31, as well as the
+ secure world components, form the |SRTM|. Measurement data is currently
+ considered an asset to be protected against attack, and this is achieved
+ by storing them in the Secure Memory.
+ Beyond the measurements stored inside the TCG-compliant Event Log buffer,
+ there are no other assets to protect or threats to defend against that
+ could compromise |TF-A| execution environment's security.
+
+ There are general security assets and threats associated with remote/delegated
+ attestation. However, these are outside the |TF-A| security boundary and
+ should be dealt with by the appropriate agent in the platform/system.
+ Since current Measured Boot design does not use local attestation, there would
+ be no further assets to protect(like unsealed keys).
+
+ A limitation of the current Measured Boot design is that it is dependent upon
+ Secure Boot as implementation of Measured Boot does not extend measurements
+ into a discrete |TPM|, where they would be securely stored and protected
+ against tampering. This implies that if Secure-Boot is compromised, Measured
+ Boot may also be compromised.
+
+ Platforms must carefully evaluate the security of the default implementation
+ since the |SRTM| includes all secure world components.
+
 Data Flow Diagram
 =================
 
diff --git a/drivers/auth/auth_mod.c b/drivers/auth/auth_mod.c
index 1bf03d4..7a9cca8 100644
--- a/drivers/auth/auth_mod.c
+++ b/drivers/auth/auth_mod.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2022, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2023, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -31,8 +31,6 @@
 	} while (0)
 
 #pragma weak plat_set_nv_ctr2
-#pragma weak plat_convert_pk
-
 
 static int cmp_auth_param_type_desc(const auth_param_type_desc_t *a,
 		const auth_param_type_desc_t *b)
@@ -150,8 +148,8 @@
 			  const auth_img_desc_t *img_desc,
 			  void *img, unsigned int img_len)
 {
-	void *data_ptr, *pk_ptr, *pk_hash_ptr, *sig_ptr, *sig_alg_ptr;
-	unsigned int data_len, pk_len, pk_hash_len, sig_len, sig_alg_len;
+	void *data_ptr, *pk_ptr, *pk_plat_ptr, *sig_ptr, *sig_alg_ptr;
+	unsigned int data_len, pk_len, pk_plat_len, sig_len, sig_alg_len;
 	unsigned int flags = 0;
 	int rc = 0;
 
@@ -173,52 +171,69 @@
 	/* Get the public key from the parent. If there is no parent (NULL),
 	 * the certificate has been signed with the ROTPK, so we have to get
 	 * the PK from the platform */
-	if (img_desc->parent) {
+	if (img_desc->parent != NULL) {
 		rc = auth_get_param(param->pk, img_desc->parent,
 				&pk_ptr, &pk_len);
+		return_if_error(rc);
 	} else {
-		rc = plat_get_rotpk_info(param->pk->cookie, &pk_ptr, &pk_len,
-				&flags);
-	}
-	return_if_error(rc);
-
-	if (flags & (ROTPK_IS_HASH | ROTPK_NOT_DEPLOYED)) {
-		/* If the PK is a hash of the key or if the ROTPK is not
-		   deployed on the platform, retrieve the key from the image */
-		pk_hash_ptr = pk_ptr;
-		pk_hash_len = pk_len;
-		rc = img_parser_get_auth_param(img_desc->img_type,
-					param->pk, img, img_len,
-					&pk_ptr, &pk_len);
+		/*
+		 * Root certificates are signed with the ROTPK, so we have to
+		 * get it from the platform.
+		 */
+		rc = plat_get_rotpk_info(param->pk->cookie, &pk_plat_ptr,
+					 &pk_plat_len, &flags);
 		return_if_error(rc);
 
+		assert(is_rotpk_flags_valid(flags));
+
-		/* Ask the crypto module to verify the signature */
-		rc = crypto_mod_verify_signature(data_ptr, data_len,
-						 sig_ptr, sig_len,
-						 sig_alg_ptr, sig_alg_len,
-						 pk_ptr, pk_len);
+		/* Also retrieve the key from the image. */
+		rc = img_parser_get_auth_param(img_desc->img_type,
+					       param->pk, img, img_len,
+					       &pk_ptr, &pk_len);
 		return_if_error(rc);
 
-		if (flags & ROTPK_NOT_DEPLOYED) {
+		/*
+		 * Validate the certificate's key against the platform ROTPK.
+		 *
+		 * Platform may store key in one of the following way -
+		 * 1. Hash of ROTPK
+		 * 2. Hash if prefixed, suffixed or modified ROTPK
+		 * 3. Full ROTPK
+		 */
+		if ((flags & ROTPK_NOT_DEPLOYED) != 0U) {
 			NOTICE("ROTPK is not deployed on platform. "
 				"Skipping ROTPK verification.\n");
-		} else {
-			/* platform may store the hash of a prefixed, suffixed or modified pk */
-			rc = plat_convert_pk(pk_ptr, pk_len, &pk_ptr, &pk_len);
+		} else if ((flags & ROTPK_IS_HASH) != 0U) {
+			/*
+			 * platform may store the hash of a prefixed,
+			 * suffixed or modified pk
+			 */
+			rc = crypto_mod_convert_pk(pk_ptr, pk_len, &pk_ptr, &pk_len);
 			return_if_error(rc);
 
-			/* Ask the crypto-module to verify the key hash */
+			/*
+			 * The hash of the certificate's public key must match
+			 * the hash of the ROTPK.
+			 */
 			rc = crypto_mod_verify_hash(pk_ptr, pk_len,
-				    pk_hash_ptr, pk_hash_len);
+						    pk_plat_ptr, pk_plat_len);
+			return_if_error(rc);
+		} else {
+			/* Platform supports full ROTPK */
+			if ((pk_len != pk_plat_len) ||
+			    (memcmp(pk_plat_ptr, pk_ptr, pk_len) != 0)) {
+				ERROR("plat and cert ROTPK len mismatch\n");
+				return -1;
+			}
 		}
-	} else {
-		/* Ask the crypto module to verify the signature */
-		rc = crypto_mod_verify_signature(data_ptr, data_len,
-						 sig_ptr, sig_len,
-						 sig_alg_ptr, sig_alg_len,
-						 pk_ptr, pk_len);
 	}
 
+	/* Ask the crypto module to verify the signature */
+	rc = crypto_mod_verify_signature(data_ptr, data_len,
+					 sig_ptr, sig_len,
+					 sig_alg_ptr, sig_alg_len,
+					 pk_ptr, pk_len);
+
 	return rc;
 }
 
@@ -314,15 +329,6 @@
 	return plat_set_nv_ctr(cookie, nv_ctr);
 }
 
-int plat_convert_pk(void *full_pk_ptr, unsigned int full_pk_len,
-		    void **hashed_pk_ptr, unsigned int *hashed_pk_len)
-{
-	*hashed_pk_ptr = full_pk_ptr;
-	*hashed_pk_len = full_pk_len;
-
-	return 0;
-}
-
 /*
  * Return the parent id in the output parameter '*parent_id'
  *
diff --git a/drivers/auth/crypto_mod.c b/drivers/auth/crypto_mod.c
index fa1adb4..e36b285 100644
--- a/drivers/auth/crypto_mod.c
+++ b/drivers/auth/crypto_mod.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2022, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2023, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -142,6 +142,20 @@
 #endif /* CRYPTO_SUPPORT == CRYPTO_HASH_CALC_ONLY || \
 	  CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_AND_HASH_CALC */
 
+int crypto_mod_convert_pk(void *full_pk_ptr, unsigned int full_pk_len,
+			  void **hashed_pk_ptr, unsigned int *hashed_pk_len)
+{
+	if (crypto_lib_desc.convert_pk != NULL) {
+		return crypto_lib_desc.convert_pk(full_pk_ptr, full_pk_len,
+						  hashed_pk_ptr, hashed_pk_len);
+	}
+
+	*hashed_pk_ptr = full_pk_ptr;
+	*hashed_pk_len = full_pk_len;
+
+	return 0;
+}
+
 /*
  * Authenticated decryption of data
  *
diff --git a/drivers/auth/cryptocell/712/cryptocell_crypto.c b/drivers/auth/cryptocell/712/cryptocell_crypto.c
index e2b189b..bba13f8 100644
--- a/drivers/auth/cryptocell/712/cryptocell_crypto.c
+++ b/drivers/auth/cryptocell/712/cryptocell_crypto.c
@@ -330,5 +330,5 @@
 /*
  * Register crypto library descriptor
  */
-REGISTER_CRYPTO_LIB(LIB_NAME, init, verify_signature, verify_hash, NULL);
+REGISTER_CRYPTO_LIB(LIB_NAME, init, verify_signature, verify_hash, NULL, NULL, NULL);
 
diff --git a/drivers/auth/cryptocell/713/cryptocell_crypto.c b/drivers/auth/cryptocell/713/cryptocell_crypto.c
index 388264e..6601b3a 100644
--- a/drivers/auth/cryptocell/713/cryptocell_crypto.c
+++ b/drivers/auth/cryptocell/713/cryptocell_crypto.c
@@ -302,4 +302,4 @@
 /*
  * Register crypto library descriptor
  */
-REGISTER_CRYPTO_LIB(LIB_NAME, init, verify_signature, verify_hash, NULL);
+REGISTER_CRYPTO_LIB(LIB_NAME, init, verify_signature, verify_hash, NULL, NULL, NULL);
diff --git a/drivers/auth/mbedtls/mbedtls_crypto.c b/drivers/auth/mbedtls/mbedtls_crypto.c
index 4241d21..6d6364f 100644
--- a/drivers/auth/mbedtls/mbedtls_crypto.c
+++ b/drivers/auth/mbedtls/mbedtls_crypto.c
@@ -396,18 +396,19 @@
 #if CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_AND_HASH_CALC
 #if TF_MBEDTLS_USE_AES_GCM
 REGISTER_CRYPTO_LIB(LIB_NAME, init, verify_signature, verify_hash, calc_hash,
-		    auth_decrypt);
+		    auth_decrypt, NULL);
 #else
 REGISTER_CRYPTO_LIB(LIB_NAME, init, verify_signature, verify_hash, calc_hash,
-		    NULL);
+		    NULL, NULL);
 #endif
 #elif CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_ONLY
 #if TF_MBEDTLS_USE_AES_GCM
-REGISTER_CRYPTO_LIB(LIB_NAME, init, verify_signature, verify_hash,
-		    auth_decrypt);
+REGISTER_CRYPTO_LIB(LIB_NAME, init, verify_signature, verify_hash, NULL,
+		    auth_decrypt, NULL);
 #else
-REGISTER_CRYPTO_LIB(LIB_NAME, init, verify_signature, verify_hash, NULL);
+REGISTER_CRYPTO_LIB(LIB_NAME, init, verify_signature, verify_hash, NULL,
+		    NULL, NULL);
 #endif
 #elif CRYPTO_SUPPORT == CRYPTO_HASH_CALC_ONLY
-REGISTER_CRYPTO_LIB(LIB_NAME, init, calc_hash);
+REGISTER_CRYPTO_LIB(LIB_NAME, init, NULL, NULL, calc_hash, NULL, NULL);
 #endif /* CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_AND_HASH_CALC */
diff --git a/drivers/nxp/crypto/caam/src/auth/nxp_crypto.c b/drivers/nxp/crypto/caam/src/auth/nxp_crypto.c
index 646e981..408d974 100644
--- a/drivers/nxp/crypto/caam/src/auth/nxp_crypto.c
+++ b/drivers/nxp/crypto/caam/src/auth/nxp_crypto.c
@@ -120,4 +120,4 @@
 /*
  * Register crypto library descriptor
  */
-REGISTER_CRYPTO_LIB(LIB_NAME, init, verify_signature, verify_hash, NULL);
+REGISTER_CRYPTO_LIB(LIB_NAME, init, verify_signature, verify_hash, NULL, NULL, NULL);
diff --git a/include/arch/aarch32/arch_features.h b/include/arch/aarch32/arch_features.h
index 7c25b99..62a512b 100644
--- a/include/arch/aarch32/arch_features.h
+++ b/include/arch/aarch32/arch_features.h
@@ -92,6 +92,24 @@
 	return read_feat_coptrc_id_field() != 0U;
 }
 
+static inline unsigned int read_feat_dit_id_field(void)
+{
+	return ISOLATE_FIELD(read_id_pfr0(), ID_PFR0_DIT);
+}
+
+static inline bool is_feat_dit_supported(void)
+{
+	if (ENABLE_FEAT_DIT == FEAT_STATE_DISABLED) {
+		return false;
+	}
+
+	if (ENABLE_FEAT_DIT == FEAT_STATE_ALWAYS) {
+		return true;
+	}
+
+	return read_feat_dit_id_field() != 0U;
+}
+
 static inline bool is_feat_spe_supported(void)
 {
 	/* FEAT_SPE is AArch64 only */
diff --git a/include/arch/aarch64/arch.h b/include/arch/aarch64/arch.h
index 89f4b40..9e061bf 100644
--- a/include/arch/aarch64/arch.h
+++ b/include/arch/aarch64/arch.h
@@ -371,6 +371,9 @@
 #define ID_AA64MMFR3_EL1_TCRX_MASK		ULL(0xf)
 
 /* ID_AA64PFR1_EL1 definitions */
+#define ID_AA64PFR1_EL1_GCS_SHIFT	U(44)
+#define ID_AA64PFR1_EL1_GCS_MASK	ULL(0xf)
+
 #define ID_AA64PFR1_EL1_SSBS_SHIFT	U(4)
 #define ID_AA64PFR1_EL1_SSBS_MASK	ULL(0xf)
 
@@ -527,6 +530,7 @@
 #define SCR_PIEN_BIT		(UL(1) << 45)
 #define SCR_TCR2EN_BIT		(UL(1) << 43)
 #define SCR_TRNDR_BIT		(UL(1) << 40)
+#define SCR_GCSEn_BIT		(UL(1) << 39)
 #define SCR_HXEn_BIT		(UL(1) << 38)
 #define SCR_ENTP2_SHIFT		U(41)
 #define SCR_ENTP2_BIT		(UL(1) << SCR_ENTP2_SHIFT)
@@ -1351,6 +1355,12 @@
 #define S2PIR_EL2		S3_4_C10_C2_5
 
 /*******************************************************************************
+ * FEAT_GCS - Guarded Control Stack Registers
+ ******************************************************************************/
+#define GCSCR_EL2		S3_4_C2_C5_0
+#define GCSPR_EL2		S3_4_C2_C5_1
+
+/*******************************************************************************
  * Definitions for DynamicIQ Shared Unit registers
  ******************************************************************************/
 #define CLUSTERPWRDN_EL1	S3_0_c15_c3_6
diff --git a/include/arch/aarch64/arch_features.h b/include/arch/aarch64/arch_features.h
index 840b117..40ab82f 100644
--- a/include/arch/aarch64/arch_features.h
+++ b/include/arch/aarch64/arch_features.h
@@ -89,12 +89,6 @@
 		is_feat_pacqarma3_present());
 }
 
-static inline bool is_armv8_4_dit_present(void)
-{
-	return ((read_id_aa64pfr0_el1() >> ID_AA64PFR0_DIT_SHIFT) &
-		ID_AA64PFR0_DIT_MASK) == 1U;
-}
-
 static inline bool is_armv8_4_ttst_present(void)
 {
 	return ((read_id_aa64mmfr2_el1() >> ID_AA64MMFR2_EL1_ST_SHIFT) &
@@ -316,6 +310,24 @@
 	return is_feat_s1pie_supported() || is_feat_s2pie_supported();
 }
 
+static unsigned int read_feat_gcs_id_field(void)
+{
+	return ISOLATE_FIELD(read_id_aa64pfr1_el1(), ID_AA64PFR1_EL1_GCS);
+}
+
+static inline bool is_feat_gcs_supported(void)
+{
+	if (ENABLE_FEAT_GCS == FEAT_STATE_DISABLED) {
+		return false;
+	}
+
+	if (ENABLE_FEAT_GCS == FEAT_STATE_ALWAYS) {
+		return true;
+	}
+
+	return read_feat_gcs_id_field() != 0U;
+}
+
 /*******************************************************************************
  * Functions to identify the presence of the Activity Monitors Extension
  ******************************************************************************/
@@ -497,13 +509,22 @@
 		ID_AA64PFR0_RAS_MASK) != ID_AA64PFR0_RAS_NOT_SUPPORTED);
 }
 
+static unsigned int read_feat_dit_id_field(void)
+{
+	return ISOLATE_FIELD(read_id_aa64pfr0_el1(), ID_AA64PFR0_DIT);
+}
+
-/**************************************************************************
- * Function to identify the presence of FEAT_DIT (Data Independent Timing)
- *************************************************************************/
-static inline bool is_armv8_4_feat_dit_present(void)
+static inline bool is_feat_dit_supported(void)
 {
-	return (((read_id_aa64pfr0_el1() >> ID_AA64PFR0_DIT_SHIFT) &
-		ID_AA64PFR0_DIT_MASK) == ID_AA64PFR0_DIT_SUPPORTED);
+	if (ENABLE_FEAT_DIT == FEAT_STATE_DISABLED) {
+		return false;
+	}
+
+	if (ENABLE_FEAT_DIT == FEAT_STATE_ALWAYS) {
+		return true;
+	}
+
+	return read_feat_dit_id_field() != 0U;
 }
 
 static inline unsigned int read_feat_tracever_id_field(void)
diff --git a/include/arch/aarch64/arch_helpers.h b/include/arch/aarch64/arch_helpers.h
index f877f5b..1b4bc11 100644
--- a/include/arch/aarch64/arch_helpers.h
+++ b/include/arch/aarch64/arch_helpers.h
@@ -613,6 +613,10 @@
 /* FEAT_SxPOE Registers */
 DEFINE_RENAME_SYSREG_RW_FUNCS(por_el2, POR_EL2)
 
+/* FEAT_GCS Registers */
+DEFINE_RENAME_SYSREG_RW_FUNCS(gcscr_el2, GCSCR_EL2)
+DEFINE_RENAME_SYSREG_RW_FUNCS(gcspr_el2, GCSPR_EL2)
+
 /* DynamIQ Shared Unit power management */
 DEFINE_RENAME_SYSREG_RW_FUNCS(clusterpwrdn_el1, CLUSTERPWRDN_EL1)
 
diff --git a/include/arch/aarch64/el3_common_macros.S b/include/arch/aarch64/el3_common_macros.S
index 45a86c1..2dee07d 100644
--- a/include/arch/aarch64/el3_common_macros.S
+++ b/include/arch/aarch64/el3_common_macros.S
@@ -243,14 +243,20 @@
 	 * register value for DIT.
 	 */
 #if ENABLE_FEAT_DIT
-#if ENABLE_ASSERTIONS
+#if ENABLE_ASSERTIONS || ENABLE_FEAT_DIT > 1
 	mrs	x0, id_aa64pfr0_el1
 	ubfx	x0, x0, #ID_AA64PFR0_DIT_SHIFT, #ID_AA64PFR0_DIT_LENGTH
+#if ENABLE_FEAT_DIT > 1
+	cbz	x0, 1f
+#else
 	cmp	x0, #ID_AA64PFR0_DIT_SUPPORTED
 	ASM_ASSERT(eq)
+#endif
+
 #endif /* ENABLE_ASSERTIONS */
 	mov	x0, #DIT_BIT
 	msr	DIT, x0
+1:
 #endif
 	.endm
 
diff --git a/include/drivers/auth/crypto_mod.h b/include/drivers/auth/crypto_mod.h
index 3a23df4..00ea8c6 100644
--- a/include/drivers/auth/crypto_mod.h
+++ b/include/drivers/auth/crypto_mod.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2022, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2023, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -52,8 +52,6 @@
 
 	/* Verify a digital signature. Return one of the
 	 * 'enum crypto_ret_value' options */
-#if CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_ONLY || \
-CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_AND_HASH_CALC
 	int (*verify_signature)(void *data_ptr, unsigned int data_len,
 				void *sig_ptr, unsigned int sig_len,
 				void *sig_alg, unsigned int sig_alg_len,
@@ -62,17 +60,15 @@
 	/* 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);
-#endif /* CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_ONLY || \
-	  CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_AND_HASH_CALC */
 
-#if CRYPTO_SUPPORT == CRYPTO_HASH_CALC_ONLY || \
-CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_AND_HASH_CALC
 	/* Calculate a hash. Return hash value */
 	int (*calc_hash)(enum crypto_md_algo md_alg, void *data_ptr,
 			 unsigned int data_len,
 			 unsigned char output[CRYPTO_MD_MAX_SIZE]);
-#endif /* CRYPTO_SUPPORT == CRYPTO_HASH_CALC_ONLY || \
-	  CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_AND_HASH_CALC */
+
+	/* Convert Public key (optional) */
+	int (*convert_pk)(void *full_pk_ptr, unsigned int full_pk_len,
+			  void **hashed_pk_ptr, unsigned int *hashed_pk_len);
 
 	/*
 	 * Authenticated decryption. Return one of the
@@ -94,16 +90,16 @@
 }
 #endif /* CRYPTO_SUPPORT */
 
-#if CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_ONLY || \
-CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_AND_HASH_CALC
+#if (CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_ONLY) || \
+    (CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_AND_HASH_CALC)
 int crypto_mod_verify_signature(void *data_ptr, unsigned int data_len,
 				void *sig_ptr, unsigned int sig_len,
 				void *sig_alg_ptr, unsigned int sig_alg_len,
 				void *pk_ptr, unsigned int pk_len);
 int crypto_mod_verify_hash(void *data_ptr, unsigned int data_len,
 			   void *digest_info_ptr, unsigned int digest_info_len);
-#endif /* CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_ONLY || \
-	  CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_AND_HASH_CALC */
+#endif /* (CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_ONLY) || \
+	  (CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_AND_HASH_CALC) */
 
 int crypto_mod_auth_decrypt(enum crypto_dec_algo dec_algo, void *data_ptr,
 			    size_t len, const void *key, unsigned int key_len,
@@ -111,44 +107,29 @@
 			    unsigned int iv_len, const void *tag,
 			    unsigned int tag_len);
 
-#if CRYPTO_SUPPORT == CRYPTO_HASH_CALC_ONLY || \
-CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_AND_HASH_CALC
+#if (CRYPTO_SUPPORT == CRYPTO_HASH_CALC_ONLY) || \
+    (CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_AND_HASH_CALC)
 int crypto_mod_calc_hash(enum crypto_md_algo alg, void *data_ptr,
 			 unsigned int data_len,
 			 unsigned char output[CRYPTO_MD_MAX_SIZE]);
-#endif /* CRYPTO_SUPPORT == CRYPTO_HASH_CALC_ONLY || \
-	  CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_AND_HASH_CALC */
+#endif /* (CRYPTO_SUPPORT == CRYPTO_HASH_CALC_ONLY) || \
+	  (CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_AND_HASH_CALC) */
+
+int crypto_mod_convert_pk(void *full_pk_ptr, unsigned int full_pk_len,
+			  void **hashed_pk_ptr, unsigned int *hashed_pk_len);
 
-#if CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_AND_HASH_CALC
 /* Macro to register a cryptographic library */
 #define REGISTER_CRYPTO_LIB(_name, _init, _verify_signature, _verify_hash, \
-			    _calc_hash, _auth_decrypt) \
-	const crypto_lib_desc_t crypto_lib_desc = { \
-		.name = _name, \
-		.init = _init, \
-		.verify_signature = _verify_signature, \
-		.verify_hash = _verify_hash, \
-		.calc_hash = _calc_hash, \
-		.auth_decrypt = _auth_decrypt \
-	}
-#elif CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_ONLY
-#define REGISTER_CRYPTO_LIB(_name, _init, _verify_signature, _verify_hash, \
-			    _auth_decrypt) \
+			    _calc_hash, _auth_decrypt, _convert_pk) \
 	const crypto_lib_desc_t crypto_lib_desc = { \
 		.name = _name, \
 		.init = _init, \
 		.verify_signature = _verify_signature, \
 		.verify_hash = _verify_hash, \
-		.auth_decrypt = _auth_decrypt \
-	}
-#elif CRYPTO_SUPPORT == CRYPTO_HASH_CALC_ONLY
-#define REGISTER_CRYPTO_LIB(_name, _init, _calc_hash) \
-	const crypto_lib_desc_t crypto_lib_desc = { \
-		.name = _name, \
-		.init = _init, \
 		.calc_hash = _calc_hash, \
+		.auth_decrypt = _auth_decrypt, \
+		.convert_pk = _convert_pk \
 	}
-#endif /* CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_AND_HASH_CALC */
 
 extern const crypto_lib_desc_t crypto_lib_desc;
 
diff --git a/include/lib/el3_runtime/aarch64/context.h b/include/lib/el3_runtime/aarch64/context.h
index a8e6d8a..dd2b836 100644
--- a/include/lib/el3_runtime/aarch64/context.h
+++ b/include/lib/el3_runtime/aarch64/context.h
@@ -234,9 +234,11 @@
 #define CTX_PIRE0_EL2           U(0x1e8)
 #define CTX_PIR_EL2             U(0x1f0)
 #define CTX_S2PIR_EL2		U(0x1f8)
+#define CTX_GCSCR_EL2           U(0x200)
+#define CTX_GCSPR_EL2           U(0x208)
 
 /* Align to the next 16 byte boundary */
-#define CTX_EL2_SYSREGS_END	U(0x200)
+#define CTX_EL2_SYSREGS_END	U(0x210)
 
 #endif /* CTX_INCLUDE_EL2_REGS */
 
diff --git a/include/plat/common/platform.h b/include/plat/common/platform.h
index a14d775..d146a29 100644
--- a/include/plat/common/platform.h
+++ b/include/plat/common/platform.h
@@ -44,10 +44,17 @@
  * plat_get_rotpk_info() flags
  ******************************************************************************/
 #define ROTPK_IS_HASH			(1 << 0)
+
 /* Flag used to skip verification of the certificate ROTPK while the platform
    ROTPK is not deployed */
 #define ROTPK_NOT_DEPLOYED		(1 << 1)
 
+static inline bool is_rotpk_flags_valid(unsigned int flags)
+{
+	unsigned int valid_flags = ROTPK_IS_HASH;
+	return (flags == ROTPK_NOT_DEPLOYED) || ((flags & ~valid_flags) == 0);
+}
+
 /*******************************************************************************
  * plat_get_enc_key_info() flags
  ******************************************************************************/
@@ -345,8 +352,6 @@
 int plat_set_nv_ctr(void *cookie, unsigned int nv_ctr);
 int plat_set_nv_ctr2(void *cookie, const struct auth_img_desc_s *img_desc,
 		unsigned int nv_ctr);
-int plat_convert_pk(void *full_pk_ptr, unsigned int full_pk_len,
-		    void **hashed_pk_ptr, unsigned int *hash_pk_len);
 int get_mbedtls_heap_helper(void **heap_addr, size_t *heap_size);
 int plat_get_enc_key_info(enum fw_enc_status_t fw_enc_status, uint8_t *key,
 			  size_t *key_len, unsigned int *flags,
diff --git a/lib/cpus/aarch64/neoverse_n1.S b/lib/cpus/aarch64/neoverse_n1.S
index 827c0b0..2cf94c7 100644
--- a/lib/cpus/aarch64/neoverse_n1.S
+++ b/lib/cpus/aarch64/neoverse_n1.S
@@ -706,7 +706,6 @@
 	ldp	x4, x5, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X4]
 	ldr	x30, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_LR]
 
-#if IMAGE_BL31 && RAS_EXTENSION
 	/*
 	 * Issue Error Synchronization Barrier to synchronize SErrors before
 	 * exiting EL3. We're running with EAs unmasked, so any synchronized
@@ -714,7 +713,6 @@
 	 * DISR_EL1 register.
 	 */
 	esb
-#endif
 	exception_return
 1:
 	ret
diff --git a/lib/el3_runtime/aarch64/context.S b/lib/el3_runtime/aarch64/context.S
index 013a505..7691171 100644
--- a/lib/el3_runtime/aarch64/context.S
+++ b/lib/el3_runtime/aarch64/context.S
@@ -553,8 +553,14 @@
 	 * always enable DIT in EL3
 	 */
 #if ENABLE_FEAT_DIT
+#if ENABLE_FEAT_DIT == 2
+	mrs	x8, id_aa64pfr0_el1
+	and	x8, x8, #(ID_AA64PFR0_DIT_MASK << ID_AA64PFR0_DIT_SHIFT)
+	cbz	x8, 1f
+#endif
 	mov     x8, #DIT_BIT
 	msr     DIT, x8
+1:
 #endif /* ENABLE_FEAT_DIT */
 	.endm /* set_unset_pstate_bits */
 
diff --git a/lib/el3_runtime/aarch64/context_mgmt.c b/lib/el3_runtime/aarch64/context_mgmt.c
index c411b73..e38b34d 100644
--- a/lib/el3_runtime/aarch64/context_mgmt.c
+++ b/lib/el3_runtime/aarch64/context_mgmt.c
@@ -376,6 +376,13 @@
 	}
 
 	/*
+	 * SCR_EL3.GCSEn: Enable GCS registers for AArch64 if present.
+	 */
+	if ((is_feat_gcs_supported()) && (GET_RW(ep->spsr) == MODE_RW_64)) {
+		scr_el3 |= SCR_GCSEn_BIT;
+	}
+
+	/*
 	 * CPTR_EL3 was initialized out of reset, copy that value to the
 	 * context register.
 	 */
@@ -1039,6 +1046,10 @@
 		if (is_feat_sxpoe_supported()) {
 			write_ctx_reg(el2_sysregs_ctx, CTX_POR_EL2, read_por_el2());
 		}
+		if (is_feat_gcs_supported()) {
+			write_ctx_reg(el2_sysregs_ctx, CTX_GCSPR_EL2, read_gcspr_el2());
+			write_ctx_reg(el2_sysregs_ctx, CTX_GCSCR_EL2, read_gcscr_el2());
+		}
 	}
 }
 
@@ -1116,6 +1127,10 @@
 		if (is_feat_sxpoe_supported()) {
 			write_por_el2(read_ctx_reg(el2_sysregs_ctx, CTX_POR_EL2));
 		}
+		if (is_feat_gcs_supported()) {
+			write_gcscr_el2(read_ctx_reg(el2_sysregs_ctx, CTX_GCSCR_EL2));
+			write_gcspr_el2(read_ctx_reg(el2_sysregs_ctx, CTX_GCSPR_EL2));
+		}
 	}
 }
 #endif /* CTX_INCLUDE_EL2_REGS */
diff --git a/make_helpers/defaults.mk b/make_helpers/defaults.mk
index 808a058..34a9bc6 100644
--- a/make_helpers/defaults.mk
+++ b/make_helpers/defaults.mk
@@ -188,6 +188,9 @@
 # Flag to enable access to Stage 1 Permission Overlay (FEAT_S1POE)
 ENABLE_FEAT_S1POE		:= 0
 
+# Flag to enable access to Guarded Control Stack (FEAT_GCS)
+ENABLE_FEAT_GCS			:= 0
+
 # By default BL31 encryption disabled
 ENCRYPT_BL31			:= 0
 
diff --git a/plat/arm/board/fvp/include/platform_def.h b/plat/arm/board/fvp/include/platform_def.h
index 84e2e82..79d7451 100644
--- a/plat/arm/board/fvp/include/platform_def.h
+++ b/plat/arm/board/fvp/include/platform_def.h
@@ -404,7 +404,7 @@
 #define PLAT_ARM_SP_IMAGE_STACK_BASE	(PLAT_SP_IMAGE_NS_BUF_BASE +	\
 					 PLAT_SP_IMAGE_NS_BUF_SIZE)
 
-#define PLAT_SP_PRI			PLAT_RAS_PRI
+#define PLAT_SP_PRI			0x20
 
 /*
  * Physical and virtual address space limits for MMU in AARCH64 & AARCH32 modes
diff --git a/plat/arm/board/fvp/platform.mk b/plat/arm/board/fvp/platform.mk
index 3fb323b..214064b 100644
--- a/plat/arm/board/fvp/platform.mk
+++ b/plat/arm/board/fvp/platform.mk
@@ -49,6 +49,7 @@
 	ENABLE_MPAM_FOR_LOWER_ELS	:= 2
 	ENABLE_FEAT_RNG			:= 2
 	ENABLE_FEAT_TWED		:= 2
+	ENABLE_FEAT_GCS			:= 2
 ifeq (${ARCH},aarch64)
 ifeq (${SPM_MM}, 0)
 ifeq (${ENABLE_RME}, 0)
@@ -69,6 +70,7 @@
 ENABLE_TRBE_FOR_NS		:= 2
 ENABLE_SYS_REG_TRACE_FOR_NS	:= 2
 ENABLE_FEAT_CSV2_2		:= 2
+ENABLE_FEAT_DIT			:= 2
 ENABLE_FEAT_PAN			:= 2
 ENABLE_FEAT_VHE			:= 2
 CTX_INCLUDE_NEVE_REGS		:= 2
diff --git a/plat/arm/board/morello/morello_bl2_setup.c b/plat/arm/board/morello/morello_bl2_setup.c
index ec87a8e..39020e2 100644
--- a/plat/arm/board/morello/morello_bl2_setup.c
+++ b/plat/arm/board/morello/morello_bl2_setup.c
@@ -13,42 +13,6 @@
 #include "morello_def.h"
 #include <platform_def.h>
 
-#ifdef TARGET_PLATFORM_FVP
-/*
- * Platform information structure stored in SDS.
- * This structure holds information about platform's DDR
- * size
- *	- Local DDR size in bytes, DDR memory in main board
- */
-struct morello_plat_info {
-	uint64_t local_ddr_size;
-} __packed;
-#else
-/*
- * Platform information structure stored in SDS.
- * This structure holds information about platform's DDR
- * size which is an information about multichip setup
- *	- Local DDR size in bytes, DDR memory in main board
- *	- Remote DDR size in bytes, DDR memory in remote board
- *	- remote_chip_count
- *	- multichip mode
- *	- scc configuration
- *	- silicon revision
- */
-struct morello_plat_info {
-	uint64_t local_ddr_size;
-	uint64_t remote_ddr_size;
-	uint8_t remote_chip_count;
-	bool multichip_mode;
-	uint32_t scc_config;
-	uint32_t silicon_revision;
-} __packed;
-#endif
-
-/* Compile time assertion to ensure the size of structure is 18 bytes */
-CASSERT(sizeof(struct morello_plat_info) == MORELLO_SDS_PLATFORM_INFO_SIZE,
-		assert_invalid_plat_info_size);
-
 #ifdef TARGET_PLATFORM_SOC
 /*
  * Morello platform supports RDIMMs with ECC capability. To use the ECC
diff --git a/plat/arm/board/morello/morello_bl31_setup.c b/plat/arm/board/morello/morello_bl31_setup.c
index 8f01592..cef42f4 100644
--- a/plat/arm/board/morello/morello_bl31_setup.c
+++ b/plat/arm/board/morello/morello_bl31_setup.c
@@ -14,44 +14,10 @@
 #include "morello_def.h"
 #include <platform_def.h>
 
-#ifdef TARGET_PLATFORM_FVP
-/*
- * Platform information structure stored in SDS.
- * This structure holds information about platform's DDR
- * size
- *	- Local DDR size in bytes, DDR memory in main board
- */
-struct morello_plat_info {
-	uint64_t local_ddr_size;
-} __packed;
-#else
-/*
- * Platform information structure stored in SDS.
- * This structure holds information about platform's DDR
- * size which is an information about multichip setup
- *	- Local DDR size in bytes, DDR memory in main board
- *	- Remote DDR size in bytes, DDR memory in remote board
- *	- remote_chip_count
- *	- multichip mode
- *	- scc configuration
- *	- silicon revision
- */
-struct morello_plat_info {
-	uint64_t local_ddr_size;
-	uint64_t remote_ddr_size;
-	uint8_t remote_chip_count;
-	bool multichip_mode;
-	uint32_t scc_config;
-	uint32_t silicon_revision;
-} __packed;
-
+#ifdef TARGET_PLATFORM_SOC
 struct morello_plat_info plat_info;
 #endif
 
-/* Compile time assertion to ensure the size of structure is of the required bytes */
-CASSERT(sizeof(struct morello_plat_info) == MORELLO_SDS_PLATFORM_INFO_SIZE,
-		assert_invalid_plat_info_size);
-
 static scmi_channel_plat_info_t morello_scmi_plat_info = {
 	.scmi_mbx_mem = MORELLO_SCMI_PAYLOAD_BASE,
 	.db_reg_addr = PLAT_CSS_MHU_BASE + CSS_SCMI_MHU_DB_REG_OFF,
diff --git a/plat/arm/board/morello/morello_def.h b/plat/arm/board/morello/morello_def.h
index 2898774..e42a03c 100644
--- a/plat/arm/board/morello/morello_def.h
+++ b/plat/arm/board/morello/morello_def.h
@@ -89,4 +89,41 @@
 #define MORELLO_DMC_MEMC_CMD_CONFIG		U(0)
 #define MORELLO_DMC_MEMC_CMD_READY		U(3)
 
+/* SDS Platform information struct definition */
+#ifdef TARGET_PLATFORM_FVP
+/*
+ * Platform information structure stored in SDS.
+ * This structure holds information about platform's DDR
+ * size
+ *	- Local DDR size in bytes, DDR memory in main board
+ */
+struct morello_plat_info {
+	uint64_t local_ddr_size;
+} __packed;
+#else
+/*
+ * Platform information structure stored in SDS.
+ * This structure holds information about platform's DDR
+ * size which is an information about multichip setup
+ *	- Local DDR size in bytes, DDR memory in main board
+ *	- Remote DDR size in bytes, DDR memory in remote board
+ *	- remote_chip_count
+ *	- multichip mode
+ *	- scc configuration
+ *	- silicon revision
+ */
+struct morello_plat_info {
+	uint64_t local_ddr_size;
+	uint64_t remote_ddr_size;
+	uint8_t remote_chip_count;
+	bool multichip_mode;
+	uint32_t scc_config;
+	uint32_t silicon_revision;
+} __packed;
+#endif
+
+/* Compile time assertion to ensure the size of structure is of the required bytes */
+CASSERT(sizeof(struct morello_plat_info) == MORELLO_SDS_PLATFORM_INFO_SIZE,
+		assert_invalid_plat_info_size);
+
 #endif /* MORELLO_DEF_H */
diff --git a/plat/arm/board/morello/morello_image_load.c b/plat/arm/board/morello/morello_image_load.c
index 5fc87a0..b5d9bd5 100644
--- a/plat/arm/board/morello/morello_image_load.c
+++ b/plat/arm/board/morello/morello_image_load.c
@@ -14,38 +14,6 @@
 #include <plat/arm/common/plat_arm.h>
 #include <plat/common/platform.h>
 
-#ifdef TARGET_PLATFORM_FVP
-/*
- * Platform information structure stored in SDS.
- * This structure holds information about platform's DDR
- * size which is an information about multichip setup
- *	- Local DDR size in bytes, DDR memory in main board
- */
-struct morello_plat_info {
-	uint64_t local_ddr_size;
-} __packed;
-#else
-/*
- * Platform information structure stored in SDS.
- * This structure holds information about platform's DDR
- * size which is an information about multichip setup
- *	- Local DDR size in bytes, DDR memory in main board
- *	- Remote DDR size in bytes, DDR memory in remote board
- *	- remote_chip_count
- *	- multichip mode
- *	- scc configuration
- *	- silicon revision
- */
-struct morello_plat_info {
-	uint64_t local_ddr_size;
-	uint64_t remote_ddr_size;
-	uint8_t remote_chip_count;
-	bool multichip_mode;
-	uint32_t scc_config;
-	uint32_t silicon_revision;
-} __packed;
-#endif
-
 /* In client mode, a part of the DDR memory is reserved for Tag bits.
  * Calculate the usable memory size after subtracting the Tag memory.
  */
diff --git a/plat/st/common/stm32mp_crypto_lib.c b/plat/st/common/stm32mp_crypto_lib.c
index 0da0019..ea2b8db 100644
--- a/plat/st/common/stm32mp_crypto_lib.c
+++ b/plat/st/common/stm32mp_crypto_lib.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022, STMicroelectronics - All Rights Reserved
+ * Copyright (c) 2022-2023, STMicroelectronics - All Rights Reserved
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -167,8 +167,8 @@
 	return ret;
 }
 
-int plat_convert_pk(void *full_pk_ptr, unsigned int full_pk_len,
-		    void **hashed_pk_ptr, unsigned int *hashed_pk_len)
+static int crypto_convert_pk(void *full_pk_ptr, unsigned int full_pk_len,
+			     void **hashed_pk_ptr, unsigned int *hashed_pk_len)
 {
 	return get_plain_pk_from_asn1(full_pk_ptr, full_pk_len, hashed_pk_ptr, hashed_pk_len, NULL);
 }
@@ -220,8 +220,8 @@
 	return 0;
 }
 
-int plat_convert_pk(void *full_pk_ptr, unsigned int full_pk_len,
-		    void **hashed_pk_ptr, unsigned int *hashed_pk_len)
+static int crypto_convert_pk(void *full_pk_ptr, unsigned int full_pk_len,
+			     void **hashed_pk_ptr, unsigned int *hashed_pk_len)
 {
 	static uint8_t st_pk[CRYPTO_PUBKEY_MAX_SIZE + sizeof(uint32_t)];
 	int ret;
@@ -650,13 +650,16 @@
 		    crypto_lib_init,
 		    crypto_verify_signature,
 		    crypto_verify_hash,
-		    crypto_auth_decrypt);
+		    NULL,
+		    crypto_auth_decrypt,
+		    crypto_convert_pk);
 
 #else /* No decryption support */
 REGISTER_CRYPTO_LIB("stm32_crypto_lib",
 		    crypto_lib_init,
 		    crypto_verify_signature,
 		    crypto_verify_hash,
-		    NULL);
-
+		    NULL,
+		    NULL,
+		    crypto_convert_pk);
 #endif
diff --git a/plat/xilinx/versal/aarch64/versal_common.c b/plat/xilinx/versal/aarch64/versal_common.c
index 2abf794..0c8ee1e 100644
--- a/plat/xilinx/versal/aarch64/versal_common.c
+++ b/plat/xilinx/versal/aarch64/versal_common.c
@@ -11,7 +11,7 @@
 #include <common/debug.h>
 #include <drivers/generic_delay_timer.h>
 #include <lib/mmio.h>
-#include <lib/xlat_tables/xlat_tables.h>
+#include <lib/xlat_tables/xlat_tables_v2.h>
 #include <plat/common/platform.h>
 
 /*
diff --git a/plat/xilinx/versal/bl31_versal_setup.c b/plat/xilinx/versal/bl31_versal_setup.c
index de3d9a2..add8dc4 100644
--- a/plat/xilinx/versal/bl31_versal_setup.c
+++ b/plat/xilinx/versal/bl31_versal_setup.c
@@ -17,7 +17,7 @@
 #include <drivers/arm/pl011.h>
 #include <drivers/console.h>
 #include <lib/mmio.h>
-#include <lib/xlat_tables/xlat_tables.h>
+#include <lib/xlat_tables/xlat_tables_v2.h>
 #include <plat/common/platform.h>
 #include <versal_def.h>
 #include <plat_private.h>
@@ -97,9 +97,6 @@
 
 	/* Initialize the platform config for future decision making */
 	versal_config_setup();
-	/* There are no parameters from BL2 if BL31 is a reset vector */
-	assert(arg0 == 0U);
-	assert(arg1 == 0U);
 
 	/*
 	 * Do initial security configuration to allow DRAM/device access. On
@@ -232,5 +229,5 @@
 	};
 
 	setup_page_tables(bl_regions, plat_versal_get_mmap());
-	enable_mmu_el3(0);
+	enable_mmu(0);
 }
diff --git a/plat/xilinx/versal/include/plat_private.h b/plat/xilinx/versal/include/plat_private.h
index 0f5911a..a6c9e9a 100644
--- a/plat/xilinx/versal/include/plat_private.h
+++ b/plat/xilinx/versal/include/plat_private.h
@@ -9,7 +9,7 @@
 #ifndef PLAT_PRIVATE_H
 #define PLAT_PRIVATE_H
 
-#include <lib/xlat_tables/xlat_tables.h>
+#include <lib/xlat_tables/xlat_tables_v2.h>
 #include <bl31/interrupt_mgmt.h>
 
 typedef struct versal_intr_info_type_el3 {
diff --git a/plat/xilinx/versal/platform.mk b/plat/xilinx/versal/platform.mk
index d68b835..67ee7bf 100644
--- a/plat/xilinx/versal/platform.mk
+++ b/plat/xilinx/versal/platform.mk
@@ -53,10 +53,9 @@
 
 # Include GICv3 driver files
 include drivers/arm/gic/v3/gicv3.mk
+include lib/xlat_tables_v2/xlat_tables.mk
 
-PLAT_BL_COMMON_SOURCES	:=	lib/xlat_tables/xlat_tables_common.c		\
-				lib/xlat_tables/aarch64/xlat_tables.c		\
-				drivers/arm/dcc/dcc_console.c			\
+PLAT_BL_COMMON_SOURCES	:= 	drivers/arm/dcc/dcc_console.c			\
 				drivers/delay_timer/delay_timer.c		\
 				drivers/delay_timer/generic_delay_timer.c	\
 				${GICV3_SOURCES}				\
@@ -66,7 +65,8 @@
 				plat/arm/common/arm_common.c			\
 				plat/common/plat_gicv3.c			\
 				plat/xilinx/versal/aarch64/versal_helpers.S	\
-				plat/xilinx/versal/aarch64/versal_common.c
+				plat/xilinx/versal/aarch64/versal_common.c	\
+				${XLAT_TABLES_LIB_SRCS}
 
 VERSAL_CONSOLE	?=	pl011
 ifeq (${VERSAL_CONSOLE}, $(filter ${VERSAL_CONSOLE},pl011 pl011_0 pl011_1 dcc))
diff --git a/plat/xilinx/versal_net/bl31_versal_net_setup.c b/plat/xilinx/versal_net/bl31_versal_net_setup.c
index 65ecc08..48be081 100644
--- a/plat/xilinx/versal_net/bl31_versal_net_setup.c
+++ b/plat/xilinx/versal_net/bl31_versal_net_setup.c
@@ -123,9 +123,6 @@
 
 	/* Initialize the platform config for future decision making */
 	versal_net_config_setup();
-	/* There are no parameters from BL2 if BL31 is a reset vector */
-	assert(arg0 == 0U);
-	assert(arg1 == 0U);
 
 	/*
 	 * Do initial security configuration to allow DRAM/device access. On
diff --git a/plat/xilinx/zynqmp/bl31_zynqmp_setup.c b/plat/xilinx/zynqmp/bl31_zynqmp_setup.c
index 45f31bd..a83c286 100644
--- a/plat/xilinx/zynqmp/bl31_zynqmp_setup.c
+++ b/plat/xilinx/zynqmp/bl31_zynqmp_setup.c
@@ -94,10 +94,6 @@
 	/* Initialize the platform config for future decision making */
 	zynqmp_config_setup();
 
-	/* There are no parameters from BL2 if BL31 is a reset vector */
-	assert(arg0 == 0U);
-	assert(arg1 == 0U);
-
 	/*
 	 * Do initial security configuration to allow DRAM/device access. On
 	 * Base ZYNQMP only DRAM security is programmable (via TrustZone), but
diff --git a/poetry.lock b/poetry.lock
index 0eb4785..58522c9 100644
--- a/poetry.lock
+++ b/poetry.lock
@@ -841,4 +841,4 @@
 [metadata]
 lock-version = "2.0"
 python-versions = "^3.8"
-content-hash = "79681baa18d1971b35833631ce5b0ad457fa285237853c953010a3502bb7b755"
+content-hash = "07432d506e3dc69114203b554d82c1489372ce0087d4a430d0380e437afa5714"
diff --git a/pyproject.toml b/pyproject.toml
index 7d748c5..b99f777 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -16,3 +16,5 @@
 sphinx-rtd-theme = "^1.1.1"
 pip-tools = "^6.4.0"
 
+[tool.poetry.group.ci.dependencies]
+click = "^8.1.3"