Merge "fix(build): remove handling of mandatory options" into integration
diff --git a/docs/getting_started/build-options.rst b/docs/getting_started/build-options.rst
index 654ddc5..347cf20 100644
--- a/docs/getting_started/build-options.rst
+++ b/docs/getting_started/build-options.rst
@@ -1195,7 +1195,8 @@
   The platform will use PSA compliant Crypto APIs during authentication and
   image measurement process by enabling this option. It uses APIs defined as
   per the `PSA Crypto API specification`_. This feature is only supported if
-  using MbedTLS 3.x version. By default it is disabled (``0``).
+  using MbedTLS 3.x version. By default it is disabled (``0``), and this is an
+  experimental feature.
 
 - ``ENABLE_CONSOLE_GETC``: Boolean option to enable `getc()` feature in console
   driver(s). By default it is disabled (``0``) because it constitutes an attack
diff --git a/drivers/auth/mbedtls/mbedtls_psa_crypto.c b/drivers/auth/mbedtls/mbedtls_psa_crypto.c
index 2fa8e63..5891acf 100644
--- a/drivers/auth/mbedtls/mbedtls_psa_crypto.c
+++ b/drivers/auth/mbedtls/mbedtls_psa_crypto.c
@@ -28,6 +28,13 @@
 
 #define LIB_NAME		"mbed TLS PSA"
 
+/* Maximum length of R_S pair in the ECDSA signature in bytes */
+#define MAX_ECDSA_R_S_PAIR_LEN	64U
+
+/* Size of ASN.1 length and tag in bytes*/
+#define SIZE_OF_ASN1_LEN	1U
+#define SIZE_OF_ASN1_TAG	1U
+
 #if CRYPTO_SUPPORT == CRYPTO_HASH_CALC_ONLY || \
 CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_AND_HASH_CALC
 /*
@@ -108,6 +115,7 @@
 
 static void construct_psa_key_alg_and_type(mbedtls_pk_type_t pk_alg,
 					   mbedtls_md_type_t md_alg,
+					   psa_ecc_family_t psa_ecc_family,
 					   psa_algorithm_t *psa_alg,
 					   psa_key_type_t *psa_key_type)
 {
@@ -118,14 +126,173 @@
 		*psa_alg = PSA_ALG_RSA_PSS(psa_md_alg);
 		*psa_key_type = PSA_KEY_TYPE_RSA_PUBLIC_KEY;
 		break;
+	case MBEDTLS_PK_ECDSA:
+		*psa_alg = PSA_ALG_ECDSA(psa_md_alg);
+		*psa_key_type = PSA_KEY_TYPE_ECC_PUBLIC_KEY(psa_ecc_family);
+		break;
 	default:
 		*psa_alg = PSA_ALG_NONE;
 		*psa_key_type = PSA_KEY_TYPE_NONE;
 		break;
 	}
+}
+
+
+#if TF_MBEDTLS_KEY_ALG_ID == TF_MBEDTLS_ECDSA || \
+TF_MBEDTLS_KEY_ALG_ID == TF_MBEDTLS_RSA_AND_ECDSA
+
+/*
+ * This is a helper function to detect padding byte (if the MSB bit of the
+ * first data byte is set to 1, for example 0x80) and on detection, ignore the
+ * padded byte(0x00) and increase the buffer pointer beyond padded byte and
+ * decrease the length of the buffer by 1.
+ *
+ * On Success returns 0, error otherwise.
+ **/
+static inline int ignore_asn1_int_padding_byte(unsigned char **buf_start,
+					       size_t *buf_len)
+{
+	unsigned char *local_buf = *buf_start;
+
+	/* Check for negative number */
+	if ((local_buf[0] & 0x80U) != 0U) {
+		return -1;
+	}
+
+	if ((local_buf[0] == 0U) && (local_buf[1] > 0x7FU) &&
+	    (*buf_len > 1U)) {
+		*buf_start = &local_buf[1];
+		(*buf_len)--;
+	}
+
+	return 0;
+}
+
+/*
+ * This is a helper function that gets a pointer to the encoded ECDSA publicKey
+ * and its length (as per RFC5280) and returns corresponding decoded publicKey
+ * and its length. As well, it retrieves the family of ECC key in the PSA
+ * format.
+ *
+ * This function returns error(CRYPTO_ERR_SIGNATURE) on ASN.1 parsing failure,
+ * otherwise success(0).
+ **/
+static int get_ecdsa_pkinfo_from_asn1(unsigned char **pk_start,
+				      unsigned int *pk_len,
+				      psa_ecc_family_t *psa_ecc_family)
+{
+	mbedtls_asn1_buf alg_oid, alg_params;
+	mbedtls_ecp_group_id grp_id;
+	int rc;
+	unsigned char *pk_end;
+	size_t len;
+	size_t curve_bits;
+	unsigned char *pk_ptr = *pk_start;
+
+	pk_end = pk_ptr + *pk_len;
+	rc = mbedtls_asn1_get_tag(&pk_ptr, pk_end, &len,
+				  MBEDTLS_ASN1_CONSTRUCTED |
+				  MBEDTLS_ASN1_SEQUENCE);
+	if (rc != 0) {
+		return CRYPTO_ERR_SIGNATURE;
+	}
+
+	pk_end = pk_ptr + len;
+	rc = mbedtls_asn1_get_alg(&pk_ptr, pk_end, &alg_oid, &alg_params);
+	if (rc != 0) {
+		return CRYPTO_ERR_SIGNATURE;
+	}
+
+	if (alg_params.tag == MBEDTLS_ASN1_OID) {
+		if (mbedtls_oid_get_ec_grp(&alg_params, &grp_id) != 0) {
+			return CRYPTO_ERR_SIGNATURE;
+		}
+		*psa_ecc_family = mbedtls_ecc_group_to_psa(grp_id,
+							   &curve_bits);
+	} else {
+		return CRYPTO_ERR_SIGNATURE;
+	}
+
+	pk_end = pk_ptr + len - (alg_oid.len + alg_params.len +
+		 2 * (SIZE_OF_ASN1_LEN + SIZE_OF_ASN1_TAG));
+	rc = mbedtls_asn1_get_bitstring_null(&pk_ptr, pk_end, &len);
+	if (rc != 0) {
+		return CRYPTO_ERR_SIGNATURE;
+	}
+
+	*pk_start = pk_ptr;
+	*pk_len = len;
+
+	return rc;
 }
 
 /*
+ * Ecdsa-Sig-Value  ::=  SEQUENCE  {
+ *   r     INTEGER,
+ *   s     INTEGER
+ * }
+ *
+ * This helper function that gets a pointer to the encoded ECDSA signature and
+ * its length (as per RFC5280) and returns corresponding decoded signature
+ * (R_S pair) and its size.
+ *
+ * This function returns error(CRYPTO_ERR_SIGNATURE) on ASN.1 parsing failure,
+ * otherwise success(0).
+ **/
+static int get_ecdsa_signature_from_asn1(unsigned char *sig_ptr,
+					 size_t *sig_len,
+					 unsigned char *r_s_pair)
+{
+	int rc;
+	unsigned char *sig_end;
+	size_t len, r_len, s_len;
+
+	sig_end = sig_ptr + *sig_len;
+	rc = mbedtls_asn1_get_tag(&sig_ptr, sig_end, &len,
+				  MBEDTLS_ASN1_CONSTRUCTED |
+				  MBEDTLS_ASN1_SEQUENCE);
+	if (rc != 0) {
+		return CRYPTO_ERR_SIGNATURE;
+	}
+
+	sig_end = sig_ptr + len;
+	rc = mbedtls_asn1_get_tag(&sig_ptr, sig_end, &r_len,
+				  MBEDTLS_ASN1_INTEGER);
+	if (rc != 0) {
+		return CRYPTO_ERR_SIGNATURE;
+	}
+
+	if (ignore_asn1_int_padding_byte(&sig_ptr, &r_len) != 0) {
+		return CRYPTO_ERR_SIGNATURE;
+	}
+
+	(void)memcpy((void *)&r_s_pair[0], (const void *)sig_ptr, r_len);
+
+	sig_ptr = sig_ptr + r_len;
+	sig_end = sig_ptr + len - (r_len + (SIZE_OF_ASN1_LEN +
+		  SIZE_OF_ASN1_TAG));
+	rc = mbedtls_asn1_get_tag(&sig_ptr, sig_end, &s_len,
+				  MBEDTLS_ASN1_INTEGER);
+	if (rc != 0) {
+		return CRYPTO_ERR_SIGNATURE;
+	}
+
+	if (ignore_asn1_int_padding_byte(&sig_ptr, &s_len) != 0) {
+		return CRYPTO_ERR_SIGNATURE;
+	}
+
+	(void)memcpy((void *)&r_s_pair[r_len], (const void *)sig_ptr, s_len);
+
+	*sig_len = s_len + r_len;
+
+	return 0;
+}
+#endif /*
+	* TF_MBEDTLS_KEY_ALG_ID == TF_MBEDTLS_ECDSA || \
+	* TF_MBEDTLS_KEY_ALG_ID == TF_MBEDTLS_RSA_AND_ECDSA
+	**/
+
+/*
  * Verify a signature.
  *
  * Parameters are passed using the DER encoding format following the ASN.1
@@ -143,6 +310,10 @@
 	int rc;
 	void *sig_opts = NULL;
 	unsigned char *p, *end;
+	unsigned char *local_sig_ptr;
+	size_t local_sig_len;
+	psa_ecc_family_t psa_ecc_family = 0U;
+	__unused unsigned char reformatted_sig[MAX_ECDSA_R_S_PAIR_LEN] = {0};
 
 	/* construct PSA key algo and type */
 	psa_status_t status = PSA_SUCCESS;
@@ -174,10 +345,36 @@
 		rc = CRYPTO_ERR_SIGNATURE;
 		goto end2;
 	}
-	signature.p = p;
+
+	local_sig_ptr = p;
+	local_sig_len = signature.len;
+
+#if TF_MBEDTLS_KEY_ALG_ID == TF_MBEDTLS_ECDSA || \
+TF_MBEDTLS_KEY_ALG_ID == TF_MBEDTLS_RSA_AND_ECDSA
+	if (pk_alg == MBEDTLS_PK_ECDSA) {
+		rc = get_ecdsa_signature_from_asn1(local_sig_ptr,
+						   &local_sig_len,
+						   reformatted_sig);
+		if (rc != 0) {
+			goto end2;
+		}
+
+		local_sig_ptr = reformatted_sig;
+
+		rc = get_ecdsa_pkinfo_from_asn1((unsigned char **)&pk_ptr,
+						&pk_len,
+						&psa_ecc_family);
+		if (rc != 0) {
+			goto end2;
+		}
+	}
+#endif /*
+	* TF_MBEDTLS_KEY_ALG_ID == TF_MBEDTLS_ECDSA || \
+	* TF_MBEDTLS_KEY_ALG_ID == TF_MBEDTLS_RSA_AND_ECDSA
+	**/
 
 	/* Convert this pk_alg and md_alg to PSA key type and key algorithm */
-	construct_psa_key_alg_and_type(pk_alg, md_alg,
+	construct_psa_key_alg_and_type(pk_alg, md_alg, psa_ecc_family,
 				       &psa_alg, &psa_key_type);
 
 
@@ -208,7 +405,7 @@
 	 */
 	status = psa_verify_message(psa_key_id, psa_alg,
 				    data_ptr, data_len,
-				    signature.p, signature.len);
+				    local_sig_ptr, local_sig_len);
 
 	if (status != PSA_SUCCESS) {
 		rc = CRYPTO_ERR_SIGNATURE;
diff --git a/drivers/partition/partition.c b/drivers/partition/partition.c
index 1881c91..c60820d 100644
--- a/drivers/partition/partition.c
+++ b/drivers/partition/partition.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016-2022, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2023, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -49,30 +49,43 @@
 static int load_mbr_header(uintptr_t image_handle, mbr_entry_t *mbr_entry)
 {
 	size_t bytes_read;
-	uintptr_t offset;
 	int result;
+	mbr_entry_t *tmp;
 
 	assert(mbr_entry != NULL);
 	/* MBR partition table is in LBA0. */
 	result = io_seek(image_handle, IO_SEEK_SET, MBR_OFFSET);
 	if (result != 0) {
-		WARN("Failed to seek (%i)\n", result);
+		VERBOSE("Failed to seek (%i)\n", result);
 		return result;
 	}
 	result = io_read(image_handle, (uintptr_t)&mbr_sector,
 			 PLAT_PARTITION_BLOCK_SIZE, &bytes_read);
-	if (result != 0) {
-		WARN("Failed to read data (%i)\n", result);
+	if ((result != 0) || (bytes_read != PLAT_PARTITION_BLOCK_SIZE)) {
+		VERBOSE("Failed to read data (%i)\n", result);
 		return result;
 	}
 
 	/* Check MBR boot signature. */
 	if ((mbr_sector[LEGACY_PARTITION_BLOCK_SIZE - 2] != MBR_SIGNATURE_FIRST) ||
 	    (mbr_sector[LEGACY_PARTITION_BLOCK_SIZE - 1] != MBR_SIGNATURE_SECOND)) {
+		VERBOSE("MBR boot signature failure\n");
 		return -ENOENT;
 	}
-	offset = (uintptr_t)&mbr_sector + MBR_PRIMARY_ENTRY_OFFSET;
-	memcpy(mbr_entry, (void *)offset, sizeof(mbr_entry_t));
+
+	tmp = (mbr_entry_t *)(&mbr_sector[MBR_PRIMARY_ENTRY_OFFSET]);
+
+	if (tmp->first_lba != 1) {
+		VERBOSE("MBR header may have an invalid first LBA\n");
+		return -EINVAL;
+	}
+
+	if ((tmp->sector_nums == 0) || (tmp->sector_nums == UINT32_MAX)) {
+		VERBOSE("MBR header entry has an invalid number of sectors\n");
+		return -EINVAL;
+	}
+
+	memcpy(mbr_entry, tmp, sizeof(mbr_entry_t));
 	return 0;
 }
 
@@ -80,24 +93,31 @@
  * Load GPT header and check the GPT signature and header CRC.
  * If partition numbers could be found, check & update it.
  */
-static int load_gpt_header(uintptr_t image_handle)
+static int load_gpt_header(uintptr_t image_handle, size_t header_offset,
+			   unsigned long long *part_lba)
 {
 	gpt_header_t header;
 	size_t bytes_read;
 	int result;
 	uint32_t header_crc, calc_crc;
 
-	result = io_seek(image_handle, IO_SEEK_SET, GPT_HEADER_OFFSET);
+	result = io_seek(image_handle, IO_SEEK_SET, header_offset);
 	if (result != 0) {
+		VERBOSE("Failed to seek into the GPT image at offset (%zu)\n",
+			header_offset);
 		return result;
 	}
 	result = io_read(image_handle, (uintptr_t)&header,
 			 sizeof(gpt_header_t), &bytes_read);
 	if ((result != 0) || (sizeof(gpt_header_t) != bytes_read)) {
+		VERBOSE("GPT header read error(%i) or read mismatch occurred,"
+			"expected(%zu) and actual(%zu)\n", result,
+			sizeof(gpt_header_t), bytes_read);
 		return result;
 	}
 	if (memcmp(header.signature, GPT_SIGNATURE,
-		   sizeof(header.signature)) != 0) {
+			   sizeof(header.signature)) != 0) {
+		VERBOSE("GPT header signature failure\n");
 		return -EINVAL;
 	}
 
@@ -109,7 +129,7 @@
 	header_crc = header.header_crc;
 	header.header_crc = 0U;
 
-	calc_crc = tf_crc32(0U, (uint8_t *)&header, DEFAULT_GPT_HEADER_SIZE);
+	calc_crc = tf_crc32(0U, (uint8_t *)&header, sizeof(gpt_header_t));
 	if (header_crc != calc_crc) {
 		ERROR("Invalid GPT Header CRC: Expected 0x%x but got 0x%x.\n",
 		      header_crc, calc_crc);
@@ -123,11 +143,16 @@
 	if (list.entry_count > PLAT_PARTITION_MAX_ENTRIES) {
 		list.entry_count = PLAT_PARTITION_MAX_ENTRIES;
 	}
+
+	*part_lba = header.part_lba;
 	return 0;
 }
 
+/*
+ * Load a single MBR entry based on details from MBR header.
+ */
 static int load_mbr_entry(uintptr_t image_handle, mbr_entry_t *mbr_entry,
-			int part_number)
+			  int part_number)
 {
 	size_t bytes_read;
 	uintptr_t offset;
@@ -137,19 +162,20 @@
 	/* MBR partition table is in LBA0. */
 	result = io_seek(image_handle, IO_SEEK_SET, MBR_OFFSET);
 	if (result != 0) {
-		WARN("Failed to seek (%i)\n", result);
+		VERBOSE("Failed to seek (%i)\n", result);
 		return result;
 	}
 	result = io_read(image_handle, (uintptr_t)&mbr_sector,
 			 PLAT_PARTITION_BLOCK_SIZE, &bytes_read);
 	if (result != 0) {
-		WARN("Failed to read data (%i)\n", result);
+		VERBOSE("Failed to read data (%i)\n", result);
 		return result;
 	}
 
 	/* Check MBR boot signature. */
 	if ((mbr_sector[LEGACY_PARTITION_BLOCK_SIZE - 2] != MBR_SIGNATURE_FIRST) ||
 	    (mbr_sector[LEGACY_PARTITION_BLOCK_SIZE - 1] != MBR_SIGNATURE_SECOND)) {
+		VERBOSE("MBR Entry boot signature failure\n");
 		return -ENOENT;
 	}
 	offset = (uintptr_t)&mbr_sector +
@@ -160,6 +186,9 @@
 	return 0;
 }
 
+/*
+ * Load MBR entries based on max number of partition entries.
+ */
 static int load_mbr_entries(uintptr_t image_handle)
 {
 	mbr_entry_t mbr_entry;
@@ -177,33 +206,60 @@
 	return 0;
 }
 
+/*
+ * Try to read and load a single GPT entry.
+ */
 static int load_gpt_entry(uintptr_t image_handle, gpt_entry_t *entry)
 {
-	size_t bytes_read;
+	size_t bytes_read = 0U;
 	int result;
 
 	assert(entry != NULL);
 	result = io_read(image_handle, (uintptr_t)entry, sizeof(gpt_entry_t),
-			 &bytes_read);
-	if (sizeof(gpt_entry_t) != bytes_read)
+			&bytes_read);
+	if ((result != 0) || (sizeof(gpt_entry_t) != bytes_read)) {
+		VERBOSE("GPT Entry read error(%i) or read mismatch occurred,"
+			"expected(%zu) and actual(%zu)\n", result,
+			sizeof(gpt_entry_t), bytes_read);
 		return -EINVAL;
+	}
+
 	return result;
 }
 
-static int verify_partition_gpt(uintptr_t image_handle)
+/*
+ * Retrieve each entry in the partition table, parse the data from each
+ * entry and store them in the list of partition table entries.
+ */
+static int load_partition_gpt(uintptr_t image_handle,
+			      unsigned long long part_lba)
 {
+	const signed long long gpt_entry_offset = LBA(part_lba);
 	gpt_entry_t entry;
 	int result, i;
 
+	result = io_seek(image_handle, IO_SEEK_SET, gpt_entry_offset);
+	if (result != 0) {
+		VERBOSE("Failed to seek (%i), Failed loading GPT partition"
+			"table entries\n", result);
+		return result;
+	}
+
 	for (i = 0; i < list.entry_count; i++) {
 		result = load_gpt_entry(image_handle, &entry);
-		assert(result == 0);
+		if (result != 0) {
+			VERBOSE("Failed to load gpt entry data(%i) error is (%i)\n",
+				i, result);
+			return result;
+		}
+
 		result = parse_gpt_entry(&entry, &list.list[i]);
 		if (result != 0) {
 			break;
 		}
 	}
 	if (i == 0) {
+		VERBOSE("No Valid GPT Entries found\n");
 		return -EINVAL;
 	}
 	/*
@@ -216,6 +272,94 @@
 	return 0;
 }
 
+/*
+ * Try retrieving and parsing the backup-GPT header and backup GPT entries.
+ * Last 33 blocks contains the backup-GPT entries and header.
+ */
+static int load_backup_gpt(unsigned int image_id, unsigned int sector_nums)
+{
+	int result;
+	unsigned long long part_lba = 0;
+	size_t gpt_header_offset;
+	uintptr_t dev_handle, image_spec, image_handle;
+	io_block_spec_t *block_spec;
+	int part_num_entries;
+
+	result = plat_get_image_source(image_id, &dev_handle, &image_spec);
+	if (result != 0) {
+		VERBOSE("Failed to obtain reference to image id=%u (%i)\n",
+			image_id, result);
+		return result;
+	}
+
+	block_spec = (io_block_spec_t *)image_spec;
+	/*
+	 * We need to read 32 blocks of GPT entries and one block of GPT header
+	 * try mapping only last 33 last blocks from the image to read the
+	 * Backup-GPT header and its entries.
+	 */
+	part_num_entries = (PLAT_PARTITION_MAX_ENTRIES / 4);
+	/* Move the offset base to LBA-33 */
+	block_spec->offset += LBA(sector_nums - part_num_entries);
+	/*
+	 * Set length as LBA-33, 32 blocks of backup-GPT entries and one
+	 * block of backup-GPT header.
+	 */
+	block_spec->length = LBA(part_num_entries + 1);
+
+	result = io_open(dev_handle, image_spec, &image_handle);
+	if (result != 0) {
+		VERBOSE("Failed to access image id (%i)\n", result);
+		return result;
+	}
+
+	INFO("Trying to retrieve back-up GPT header\n");
+	/* Last block is backup-GPT header, after the end of GPT entries */
+	gpt_header_offset = LBA(part_num_entries);
+	result = load_gpt_header(image_handle, gpt_header_offset, &part_lba);
+	if ((result != 0) || (part_lba == 0)) {
+		ERROR("Failed to retrieve Backup GPT header,"
+		      "Partition maybe corrupted\n");
+		goto out;
+	}
+
+	/*
+	 * Note we mapped last 33 blocks(LBA-33), first block here starts with
+	 * entries while last block was header.
+	 */
+	result = load_partition_gpt(image_handle, 0);
+
+out:
+	io_close(image_handle);
+	return result;
+}
+
+/*
+ * Load a GPT partition, Try retrieving and parsing the primary GPT header,
+ * if its corrupted try loading backup GPT header and then retrieve list
+ * of partition table entries found from the GPT.
+ */
+static int load_primary_gpt(uintptr_t image_handle, unsigned int first_lba)
+{
+	int result;
+	unsigned long long part_lba;
+	size_t gpt_header_offset;
+
+	/* Try to load Primary GPT header from LBA1 */
+	gpt_header_offset = LBA(first_lba);
+	result = load_gpt_header(image_handle, gpt_header_offset, &part_lba);
+	if ((result != 0) || (part_lba == 0)) {
+		VERBOSE("Failed to retrieve Primary GPT header,"
+			"trying to retrieve back-up GPT header\n");
+		return result;
+	}
+
+	return load_partition_gpt(image_handle, part_lba);
+}
+
+/*
+ * Load the partition table info based on the image id provided.
+ */
 int load_partition_table(unsigned int image_id)
 {
 	uintptr_t dev_handle, image_handle, image_spec = 0;
@@ -224,36 +368,41 @@
 
 	result = plat_get_image_source(image_id, &dev_handle, &image_spec);
 	if (result != 0) {
-		WARN("Failed to obtain reference to image id=%u (%i)\n",
+		VERBOSE("Failed to obtain reference to image id=%u (%i)\n",
 			image_id, result);
 		return result;
 	}
 
 	result = io_open(dev_handle, image_spec, &image_handle);
 	if (result != 0) {
-		WARN("Failed to access image id=%u (%i)\n", image_id, result);
+		VERBOSE("Failed to access image id=%u (%i)\n", image_id, result);
 		return result;
 	}
 
 	result = load_mbr_header(image_handle, &mbr_entry);
 	if (result != 0) {
-		WARN("Failed to access image id=%u (%i)\n", image_id, result);
-		return result;
+		VERBOSE("Failed to access image id=%u (%i)\n", image_id, result);
+		goto out;
 	}
 	if (mbr_entry.type == PARTITION_TYPE_GPT) {
-		result = load_gpt_header(image_handle);
-		assert(result == 0);
-		result = io_seek(image_handle, IO_SEEK_SET, GPT_ENTRY_OFFSET);
-		assert(result == 0);
-		result = verify_partition_gpt(image_handle);
+		result = load_primary_gpt(image_handle, mbr_entry.first_lba);
+		if (result != 0) {
+			io_close(image_handle);
+			return load_backup_gpt(BKUP_GPT_IMAGE_ID,
+					       mbr_entry.sector_nums);
+		}
 	} else {
 		result = load_mbr_entries(image_handle);
 	}
 
+out:
 	io_close(image_handle);
 	return result;
 }
 
+/*
+ * Try retrieving a partition table entry based on the name of the partition.
+ */
 const partition_entry_t *get_partition_entry(const char *name)
 {
 	int i;
@@ -266,6 +415,9 @@
 	return NULL;
 }
 
+/*
+ * Try retrieving a partition table entry based on the GUID.
+ */
 const partition_entry_t *get_partition_entry_by_type(const uuid_t *type_uuid)
 {
 	int i;
@@ -279,6 +431,9 @@
 	return NULL;
 }
 
+/*
+ * Try retrieving a partition table entry based on the UUID.
+ */
 const partition_entry_t *get_partition_entry_by_uuid(const uuid_t *part_uuid)
 {
 	int i;
@@ -292,12 +447,32 @@
 	return NULL;
 }
 
+/*
+ * Return entry to the list of partition table entries.
+ */
 const partition_entry_list_t *get_partition_entry_list(void)
 {
 	return &list;
 }
 
+/*
+ * Try loading partition table info for the given image ID.
+ */
 void partition_init(unsigned int image_id)
 {
+	int ret;
+
+	ret = load_partition_table(image_id);
+	if (ret != 0) {
+		ERROR("Failed to parse partition with image id = %u\n",
+		      image_id);
+	}
+}
+
+/*
+ * Load a GPT based image.
+ */
+int gpt_partition_init(void)
+{
-	load_partition_table(image_id);
+	return load_partition_table(GPT_IMAGE_ID);
 }
diff --git a/include/common/tbbr/cot_def.h b/include/common/tbbr/cot_def.h
index 1d28772..bf23917 100644
--- a/include/common/tbbr/cot_def.h
+++ b/include/common/tbbr/cot_def.h
@@ -32,7 +32,12 @@
  * buffers must be big enough to hold either. As RSA keys are bigger than ECDSA
  * ones for all key sizes we support, they impose the minimum size of these
  * buffers.
+ *
+ * If the platform employs its own mbedTLS configuration, it is the platform's
+ * responsibility to define TF_MBEDTLS_USE_RSA or TF_MBEDTLS_USE_ECDSA to
+ * establish the appropriate PK_DER_LEN size.
  */
+#ifdef MBEDTLS_CONFIG_FILE
 #if TF_MBEDTLS_USE_RSA
 #if TF_MBEDTLS_KEY_SIZE == 1024
 #define PK_DER_LEN                      162
@@ -45,7 +50,7 @@
 #else
 #error "Invalid value for TF_MBEDTLS_KEY_SIZE"
 #endif
-#else /* Only using ECDSA keys. */
+#elif TF_MBEDTLS_USE_ECDSA
 #if TF_MBEDTLS_KEY_SIZE == 384
 #define PK_DER_LEN                      120
 #elif TF_MBEDTLS_KEY_SIZE == 256
@@ -53,7 +58,9 @@
 #else
 #error "Invalid value for TF_MBEDTLS_KEY_SIZE"
 #endif
-#endif
+#else
+#error "Invalid value of algorithm"
+#endif /* TF_MBEDTLS_USE_RSA */
 
 #if TF_MBEDTLS_HASH_ALG_ID == TF_MBEDTLS_SHA256
 #define HASH_DER_LEN                    51
@@ -64,5 +71,6 @@
 #else
 #error "Invalid value for TF_MBEDTLS_HASH_ALG_ID"
 #endif
+#endif /* MBEDTLS_CONFIG_FILE */
 
 #endif /* COT_DEF_H */
diff --git a/include/drivers/partition/gpt.h b/include/drivers/partition/gpt.h
index c2a229e..383c17d 100644
--- a/include/drivers/partition/gpt.h
+++ b/include/drivers/partition/gpt.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2023, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -12,10 +12,6 @@
 #include <tools_share/uuid.h>
 
 #define PARTITION_TYPE_GPT		0xee
-#define GPT_HEADER_OFFSET		PLAT_PARTITION_BLOCK_SIZE
-#define GPT_ENTRY_OFFSET		(GPT_HEADER_OFFSET +		\
-					 PLAT_PARTITION_BLOCK_SIZE)
-
 #define GPT_SIGNATURE			"EFI PART"
 
 typedef struct gpt_entry {
@@ -45,7 +41,7 @@
 	/* size of a single partition entry (usually 128) */
 	unsigned int		part_size;
 	unsigned int		part_crc;
-} gpt_header_t;
+} __packed gpt_header_t;
 
 int parse_gpt_entry(gpt_entry_t *gpt_entry, partition_entry_t *entry);
 
diff --git a/include/drivers/partition/partition.h b/include/drivers/partition/partition.h
index 6cb59c3..d567d4c 100644
--- a/include/drivers/partition/partition.h
+++ b/include/drivers/partition/partition.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016-2022, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2023, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -29,7 +29,7 @@
 
 #define LEGACY_PARTITION_BLOCK_SIZE	512
 
-#define DEFAULT_GPT_HEADER_SIZE 	92
+#define LBA(n) ((unsigned long long)(n) * PLAT_PARTITION_BLOCK_SIZE)
 
 typedef struct partition_entry {
 	uint64_t		start;
@@ -50,5 +50,6 @@
 const partition_entry_t *get_partition_entry_by_uuid(const uuid_t *part_uuid);
 const partition_entry_list_t *get_partition_entry_list(void);
 void partition_init(unsigned int image_id);
+int gpt_partition_init(void);
 
 #endif /* PARTITION_H */
diff --git a/include/export/common/tbbr/tbbr_img_def_exp.h b/include/export/common/tbbr/tbbr_img_def_exp.h
index 98a0099..ce17b4a 100644
--- a/include/export/common/tbbr/tbbr_img_def_exp.h
+++ b/include/export/common/tbbr/tbbr_img_def_exp.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019-2022, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2019-2023, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -79,41 +79,44 @@
 /* NT_FW_CONFIG */
 #define NT_FW_CONFIG_ID			U(27)
 
-/* GPT Partition */
+/* GPT primary header and entries */
 #define GPT_IMAGE_ID			U(28)
 
+/* GPT backup header and entries */
+#define BKUP_GPT_IMAGE_ID		U(29)
+
 /* Binary with STM32 header */
-#define STM32_IMAGE_ID			U(29)
+#define STM32_IMAGE_ID			U(30)
 
 /* Encrypted image identifier */
-#define ENC_IMAGE_ID			U(30)
+#define ENC_IMAGE_ID			U(31)
 
 /* FW_CONFIG */
-#define FW_CONFIG_ID			U(31)
+#define FW_CONFIG_ID			U(32)
 
 /*
  * Primary FWU metadata image ID
  */
-#define FWU_METADATA_IMAGE_ID		U(32)
+#define FWU_METADATA_IMAGE_ID		U(33)
 
 /*
  * Backup FWU metadata image ID
  */
-#define BKUP_FWU_METADATA_IMAGE_ID	U(33)
+#define BKUP_FWU_METADATA_IMAGE_ID	U(34)
 
 /* Realm Monitor Manager (RMM) */
-#define RMM_IMAGE_ID			U(34)
+#define RMM_IMAGE_ID			U(35)
 
 /* CCA Content Certificate ID */
-#define CCA_CONTENT_CERT_ID		U(35)
+#define CCA_CONTENT_CERT_ID		U(36)
 
 /* Core SWD Key Certificate ID */
-#define CORE_SWD_KEY_CERT_ID		U(36)
+#define CORE_SWD_KEY_CERT_ID		U(37)
 
 /* Platform Key Certificate ID */
-#define PLAT_KEY_CERT_ID		U(37)
+#define PLAT_KEY_CERT_ID		U(38)
 
 /* Max Images */
-#define MAX_IMAGE_IDS			U(38)
+#define MAX_IMAGE_IDS			U(39)
 
 #endif /* ARM_TRUSTED_FIRMWARE_EXPORT_COMMON_TBBR_TBBR_IMG_DEF_EXP_H */
diff --git a/include/lib/cpus/aarch64/travis.h b/include/lib/cpus/aarch64/travis.h
new file mode 100644
index 0000000..a8a2556
--- /dev/null
+++ b/include/lib/cpus/aarch64/travis.h
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2023, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef TRAVIS_H
+#define TRAVIS_H
+
+#define TRAVIS_MIDR					U(0x410FD8C0)
+
+/*******************************************************************************
+ * CPU Extended Control register specific definitions
+ ******************************************************************************/
+#define TRAVIS_IMP_CPUECTLR_EL1				S3_0_C15_C1_4
+
+/*******************************************************************************
+ * CPU Power Control register specific definitions
+ ******************************************************************************/
+#define TRAVIS_IMP_CPUPWRCTLR_EL1			S3_0_C15_C2_7
+#define TRAVIS_IMP_CPUPWRCTLR_EL1_CORE_PWRDN_EN_BIT	U(1)
+
+/*******************************************************************************
+ * SME Control registers
+ ******************************************************************************/
+#define TRAVIS_SVCRSM					S0_3_C4_C2_3
+#define TRAVIS_SVCRZA					S0_3_C4_C4_3
+
+#endif /* TRAVIS_H */
diff --git a/include/services/rmmd_svc.h b/include/services/rmmd_svc.h
index 55d778e..a567d28 100644
--- a/include/services/rmmd_svc.h
+++ b/include/services/rmmd_svc.h
@@ -91,6 +91,10 @@
 #define E_RMM_NOMEM			-4
 #define E_RMM_INVAL			-5
 
+/* Return error codes from RMI SMCs */
+#define RMI_SUCCESS			0
+#define RMI_ERROR_INPUT			1
+
 /* Acceptable SHA sizes for Challenge object */
 #define SHA256_DIGEST_SIZE	32U
 #define SHA384_DIGEST_SIZE	48U
diff --git a/lib/cpus/aarch64/travis.S b/lib/cpus/aarch64/travis.S
new file mode 100644
index 0000000..2abefe9
--- /dev/null
+++ b/lib/cpus/aarch64/travis.S
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2023, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch.h>
+#include <asm_macros.S>
+#include <common/bl_common.h>
+#include <travis.h>
+#include <cpu_macros.S>
+#include <plat_macros.S>
+
+/* Hardware handled coherency */
+#if HW_ASSISTED_COHERENCY == 0
+#error "Travis must be compiled with HW_ASSISTED_COHERENCY enabled"
+#endif
+
+/* 64-bit only core */
+#if CTX_INCLUDE_AARCH32_REGS == 1
+#error "Travis supports only AArch64. Compile with CTX_INCLUDE_AARCH32_REGS=0"
+#endif
+
+cpu_reset_func_start travis
+	/* ----------------------------------------------------
+	 * Disable speculative loads
+	 * ----------------------------------------------------
+	 */
+	msr	SSBS, xzr
+cpu_reset_func_end travis
+
+func travis_core_pwr_dwn
+#if ENABLE_SME_FOR_NS
+        /* ---------------------------------------------------
+         * Disable SME if enabled and supported
+         * ---------------------------------------------------
+         */
+	mrs     x0, ID_AA64PFR1_EL1
+	ubfx	x0, x0, #ID_AA64PFR1_EL1_SME_SHIFT, \
+		#ID_AA64PFR1_EL1_SME_WIDTH
+        cmp     x0, #ID_AA64PFR1_EL1_SME_NOT_SUPPORTED
+	b.eq	1f
+	msr	TRAVIS_SVCRSM, xzr
+	msr	TRAVIS_SVCRZA, xzr
+1:
+#endif
+	/* ---------------------------------------------------
+	 * Enable CPU power down bit in power control register
+	 * ---------------------------------------------------
+	 */
+	sysreg_bit_set TRAVIS_IMP_CPUPWRCTLR_EL1, \
+		TRAVIS_IMP_CPUPWRCTLR_EL1_CORE_PWRDN_EN_BIT
+	isb
+	ret
+endfunc travis_core_pwr_dwn
+
+errata_report_shim travis
+
+.section .rodata.travis_regs, "aS"
+travis_regs: /* The ASCII list of register names to be reported */
+	.asciz	"cpuectlr_el1", ""
+
+func travis_cpu_reg_dump
+	adr 	x6, travis_regs
+	mrs	x8, TRAVIS_IMP_CPUECTLR_EL1
+	ret
+endfunc travis_cpu_reg_dump
+
+declare_cpu_ops travis, TRAVIS_MIDR, \
+	travis_reset_func, \
+	travis_core_pwr_dwn
diff --git a/lib/psa/delegated_attestation.c b/lib/psa/delegated_attestation.c
index a813e84..81e2621 100644
--- a/lib/psa/delegated_attestation.c
+++ b/lib/psa/delegated_attestation.c
@@ -5,13 +5,10 @@
  *
  */
 
-#include <string.h>
-
 #include <delegated_attestation.h>
 #include <psa/client.h>
 #include <psa_manifest/sid.h>
 
-#if !PLAT_RSS_NOT_SUPPORTED
 psa_status_t
 rss_delegated_attest_get_delegated_key(uint8_t   ecc_curve,
 				       uint32_t  key_bits,
@@ -74,143 +71,3 @@
 
 	return status;
 }
-
-
-#else /* !PLAT_RSS_NOT_SUPPORTED */
-
-static const uint8_t delegated_key[] = {
-	0x20, 0x11, 0xC7, 0xF0, 0x3C, 0xEE, 0x43, 0x25, 0x17, 0x6E,
-	0x52, 0x4F, 0x03, 0x3C, 0x0C, 0xE1, 0xE2, 0x1A, 0x76, 0xE6,
-	0xC1, 0xA4, 0xF0, 0xB8, 0x39, 0xAA, 0x1D, 0xF6, 0x1E, 0x0E,
-	0x8A, 0x5C, 0x8A, 0x05, 0x74, 0x0F, 0x9B, 0x69, 0xEF, 0xA7,
-	0xEB, 0x1A, 0x41, 0x85, 0xBD, 0x11, 0x7F, 0x68
-};
-
-static const uint8_t platform_token[] = {
-	0xD2, 0x84, 0x44, 0xA1, 0x01, 0x38, 0x22, 0xA0,
-	0x59, 0x02, 0x33, 0xA9, 0x19, 0x01, 0x09, 0x78,
-	0x1C, 0x68, 0x74, 0x74, 0x70, 0x3A, 0x2F, 0x2F,
-	0x61, 0x72, 0x6D, 0x2E, 0x63, 0x6F, 0x6D, 0x2F,
-	0x43, 0x43, 0x41, 0x2D, 0x53, 0x53, 0x44, 0x2F,
-	0x31, 0x2E, 0x30, 0x2E, 0x30, 0x0A, 0x58, 0x20,
-	0xB5, 0x97, 0x3C, 0xB6, 0x8B, 0xAA, 0x9F, 0xC5,
-	0x55, 0x58, 0x78, 0x6B, 0x7E, 0xC6, 0x7F, 0x69,
-	0xE4, 0x0D, 0xF5, 0xBA, 0x5A, 0xA9, 0x21, 0xCD,
-	0x0C, 0x27, 0xF4, 0x05, 0x87, 0xA0, 0x11, 0xEA,
-	0x19, 0x09, 0x5C, 0x58, 0x20, 0x7F, 0x45, 0x4C,
-	0x46, 0x02, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x3E,
-	0x00, 0x01, 0x00, 0x00, 0x00, 0x50, 0x58, 0x00,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0x01, 0x00,
-	0x58, 0x21, 0x01, 0x07, 0x06, 0x05, 0x04, 0x03,
-	0x02, 0x01, 0x00, 0x0F, 0x0E, 0x0D, 0x0C, 0x0B,
-	0x0A, 0x09, 0x08, 0x17, 0x16, 0x15, 0x14, 0x13,
-	0x12, 0x11, 0x10, 0x1F, 0x1E, 0x1D, 0x1C, 0x1B,
-	0x1A, 0x19, 0x18, 0x19, 0x09, 0x61, 0x58, 0x21,
-	0x01, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01,
-	0x00, 0x0F, 0x0E, 0x0D, 0x0C, 0x0B, 0x0A, 0x09,
-	0x08, 0x17, 0x16, 0x15, 0x14, 0x13, 0x12, 0x11,
-	0x10, 0x1F, 0x1E, 0x1D, 0x1C, 0x1B, 0x1A, 0x19,
-	0x18, 0x19, 0x09, 0x5B, 0x19, 0x30, 0x03, 0x19,
-	0x09, 0x62, 0x67, 0x73, 0x68, 0x61, 0x2D, 0x32,
-	0x35, 0x36, 0x19, 0x09, 0x5F, 0x84, 0xA5, 0x01,
-	0x62, 0x42, 0x4C, 0x05, 0x58, 0x20, 0x07, 0x06,
-	0x05, 0x04, 0x03, 0x02, 0x01, 0x00, 0x0F, 0x0E,
-	0x0D, 0x0C, 0x0B, 0x0A, 0x09, 0x08, 0x17, 0x16,
-	0x15, 0x14, 0x13, 0x12, 0x11, 0x10, 0x1F, 0x1E,
-	0x1D, 0x1C, 0x1B, 0x1A, 0x19, 0x18, 0x04, 0x65,
-	0x33, 0x2E, 0x34, 0x2E, 0x32, 0x02, 0x58, 0x20,
-	0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00,
-	0x0F, 0x0E, 0x0D, 0x0C, 0x0B, 0x0A, 0x09, 0x08,
-	0x17, 0x16, 0x15, 0x14, 0x13, 0x12, 0x11, 0x10,
-	0x1F, 0x1E, 0x1D, 0x1C, 0x1B, 0x1A, 0x19, 0x18,
-	0x06, 0x74, 0x54, 0x46, 0x2D, 0x4D, 0x5F, 0x53,
-	0x48, 0x41, 0x32, 0x35, 0x36, 0x4D, 0x65, 0x6D,
-	0x50, 0x72, 0x65, 0x58, 0x49, 0x50, 0xA4, 0x01,
-	0x62, 0x4D, 0x31, 0x05, 0x58, 0x20, 0x07, 0x06,
-	0x05, 0x04, 0x03, 0x02, 0x01, 0x00, 0x0F, 0x0E,
-	0x0D, 0x0C, 0x0B, 0x0A, 0x09, 0x08, 0x17, 0x16,
-	0x15, 0x14, 0x13, 0x12, 0x11, 0x10, 0x1F, 0x1E,
-	0x1D, 0x1C, 0x1B, 0x1A, 0x19, 0x18, 0x04, 0x63,
-	0x31, 0x2E, 0x32, 0x02, 0x58, 0x20, 0x07, 0x06,
-	0x05, 0x04, 0x03, 0x02, 0x01, 0x00, 0x0F, 0x0E,
-	0x0D, 0x0C, 0x0B, 0x0A, 0x09, 0x08, 0x17, 0x16,
-	0x15, 0x14, 0x13, 0x12, 0x11, 0x10, 0x1F, 0x1E,
-	0x1D, 0x1C, 0x1B, 0x1A, 0x19, 0x18, 0xA4, 0x01,
-	0x62, 0x4D, 0x32, 0x05, 0x58, 0x20, 0x07, 0x06,
-	0x05, 0x04, 0x03, 0x02, 0x01, 0x00, 0x0F, 0x0E,
-	0x0D, 0x0C, 0x0B, 0x0A, 0x09, 0x08, 0x17, 0x16,
-	0x15, 0x14, 0x13, 0x12, 0x11, 0x10, 0x1F, 0x1E,
-	0x1D, 0x1C, 0x1B, 0x1A, 0x19, 0x18, 0x04, 0x65,
-	0x31, 0x2E, 0x32, 0x2E, 0x33, 0x02, 0x58, 0x20,
-	0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00,
-	0x0F, 0x0E, 0x0D, 0x0C, 0x0B, 0x0A, 0x09, 0x08,
-	0x17, 0x16, 0x15, 0x14, 0x13, 0x12, 0x11, 0x10,
-	0x1F, 0x1E, 0x1D, 0x1C, 0x1B, 0x1A, 0x19, 0x18,
-	0xA4, 0x01, 0x62, 0x4D, 0x33, 0x05, 0x58, 0x20,
-	0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00,
-	0x0F, 0x0E, 0x0D, 0x0C, 0x0B, 0x0A, 0x09, 0x08,
-	0x17, 0x16, 0x15, 0x14, 0x13, 0x12, 0x11, 0x10,
-	0x1F, 0x1E, 0x1D, 0x1C, 0x1B, 0x1A, 0x19, 0x18,
-	0x04, 0x61, 0x31, 0x02, 0x58, 0x20, 0x07, 0x06,
-	0x05, 0x04, 0x03, 0x02, 0x01, 0x00, 0x0F, 0x0E,
-	0x0D, 0x0C, 0x0B, 0x0A, 0x09, 0x08, 0x17, 0x16,
-	0x15, 0x14, 0x13, 0x12, 0x11, 0x10, 0x1F, 0x1E,
-	0x1D, 0x1C, 0x1B, 0x1A, 0x19, 0x18, 0x19, 0x09,
-	0x60, 0x6C, 0x77, 0x68, 0x61, 0x74, 0x65, 0x76,
-	0x65, 0x72, 0x2E, 0x63, 0x6F, 0x6D, 0x58, 0x60,
-	0xE6, 0xB6, 0x38, 0x4F, 0xAE, 0x3F, 0x6E, 0x67,
-	0xF5, 0xD4, 0x97, 0x4B, 0x3F, 0xFD, 0x0A, 0xFA,
-	0x1D, 0xF0, 0x2F, 0x73, 0xB8, 0xFF, 0x5F, 0x02,
-	0xC0, 0x0F, 0x40, 0xAC, 0xF3, 0xA2, 0x9D, 0xB5,
-	0x31, 0x50, 0x16, 0x4F, 0xFA, 0x34, 0x3D, 0x0E,
-	0xAF, 0xE0, 0xD0, 0xD1, 0x6C, 0xF0, 0x9D, 0xC1,
-	0x01, 0x42, 0xA2, 0x3C, 0xCE, 0xD4, 0x4A, 0x59,
-	0xDC, 0x29, 0x0A, 0x30, 0x93, 0x5F, 0xB4, 0x98,
-	0x61, 0xBA, 0xE3, 0x91, 0x22, 0x95, 0x24, 0xF4,
-	0xAE, 0x47, 0x93, 0xD3, 0x84, 0xA3, 0x76, 0xD0,
-	0xC1, 0x26, 0x96, 0x53, 0xA3, 0x60, 0x3F, 0x6C,
-	0x75, 0x96, 0x90, 0x6A, 0xF9, 0x4E, 0xDA, 0x30
-};
-
-psa_status_t
-rss_delegated_attest_get_delegated_key(uint8_t   ecc_curve,
-				       uint32_t  key_bits,
-				       uint8_t  *key_buf,
-				       size_t    key_buf_size,
-				       size_t   *key_size,
-				       uint32_t  hash_algo)
-{
-	(void)ecc_curve;
-	(void)key_bits;
-	(void)hash_algo;
-
-	if (key_buf_size < sizeof(delegated_key)) {
-		return PSA_ERROR_BUFFER_TOO_SMALL;
-	}
-
-	(void)memcpy(key_buf, delegated_key, sizeof(delegated_key));
-	*key_size = sizeof(delegated_key);
-
-	return PSA_SUCCESS;
-}
-psa_status_t
-rss_delegated_attest_get_token(const uint8_t *dak_pub_hash,
-			       size_t         dak_pub_hash_size,
-			       uint8_t       *token_buf,
-			       size_t         token_buf_size,
-			       size_t        *token_size)
-{
-	(void)dak_pub_hash;
-	(void)dak_pub_hash_size;
-
-	if (token_buf_size < sizeof(platform_token)) {
-		return PSA_ERROR_BUFFER_TOO_SMALL;
-	}
-
-	(void)memcpy(token_buf, platform_token, sizeof(platform_token));
-	*token_size = sizeof(platform_token);
-
-	return PSA_SUCCESS;
-}
-#endif /* !PLAT_RSS_NOT_SUPPORTED */
diff --git a/make_helpers/arch_features.mk b/make_helpers/arch_features.mk
index f957f0d..a337e76 100644
--- a/make_helpers/arch_features.mk
+++ b/make_helpers/arch_features.mk
@@ -217,13 +217,13 @@
 # Build option to enable MPAM for lower ELs.
 # Enabling it by default
 ifeq (${ARCH},aarch64)
-	ENABLE_FEAT_MPAM		?=	2
+        ENABLE_FEAT_MPAM		?=	2
 else ifeq (${ARCH},aarch32)
-	ifdef ENABLE_FEAT_MPAM
-		$(error ENABLE_FEAT_MPAM is not supported for AArch32)
-	else
-		ENABLE_FEAT_MPAM	:=	0
-	endif
+        ifneq ($(or $(ENABLE_FEAT_MPAM),0),0)
+                $(error ENABLE_FEAT_MPAM is not supported for AArch32)
+        else
+                ENABLE_FEAT_MPAM	:=	0
+        endif
 endif
 
 # Include nested virtualization control (Armv8.4-NV) registers in cpu context.
diff --git a/plat/arm/board/a5ds/a5ds_bl2_setup.c b/plat/arm/board/a5ds/a5ds_bl2_setup.c
index 1979c50..a0aa639 100644
--- a/plat/arm/board/a5ds/a5ds_bl2_setup.c
+++ b/plat/arm/board/a5ds/a5ds_bl2_setup.c
@@ -16,3 +16,8 @@
 {
 	arm_bl2_platform_setup();
 }
+
+int bl2_plat_handle_post_image_load(unsigned int image_id)
+{
+	return arm_bl2_plat_handle_post_image_load(image_id);
+}
diff --git a/plat/arm/board/arm_fpga/platform.mk b/plat/arm/board/arm_fpga/platform.mk
index c71c99a..f44b37d 100644
--- a/plat/arm/board/arm_fpga/platform.mk
+++ b/plat/arm/board/arm_fpga/platform.mk
@@ -41,7 +41,6 @@
 ENABLE_FEAT_ECV			:= 2
 ENABLE_FEAT_FGT			:= 2
 ENABLE_FEAT_HCX			:= 2
-ENABLE_FEAT_MPAM		:= 2
 ENABLE_SYS_REG_TRACE_FOR_NS	:= 2
 ENABLE_TRF_FOR_NS		:= 2
 
diff --git a/plat/arm/board/fvp/fvp_bl2_setup.c b/plat/arm/board/fvp/fvp_bl2_setup.c
index b93922a..ebd5266 100644
--- a/plat/arm/board/fvp/fvp_bl2_setup.c
+++ b/plat/arm/board/fvp/fvp_bl2_setup.c
@@ -11,6 +11,7 @@
 #include <drivers/arm/sp804_delay_timer.h>
 #include <lib/fconf/fconf.h>
 #include <lib/fconf/fconf_dyn_cfg_getter.h>
+#include <lib/transfer_list.h>
 
 #include <plat/arm/common/plat_arm.h>
 #include <plat/common/platform.h>
@@ -18,6 +19,8 @@
 
 #include "fvp_private.h"
 
+static struct transfer_list_header *ns_tl __unused;
+
 void bl2_early_platform_setup2(u_register_t arg0, u_register_t arg1, u_register_t arg2, u_register_t arg3)
 {
 	arm_bl2_early_platform_setup((uintptr_t)arg0, (meminfo_t *)arg1);
@@ -30,6 +33,10 @@
 {
 	arm_bl2_platform_setup();
 
+#if TRANSFER_LIST
+	ns_tl = transfer_list_init((void *)FW_NS_HANDOFF_BASE, FW_HANDOFF_SIZE);
+	assert(ns_tl != NULL);
+#endif
 	/* Initialize System level generic or SP804 timer */
 	fvp_timer_init();
 }
@@ -41,6 +48,7 @@
 {
 	struct bl_params *arm_bl_params;
 	const struct dyn_cfg_dtb_info_t *hw_config_info __unused;
+	struct transfer_list_entry *te __unused;
 	bl_mem_params_node_t *param_node __unused;
 
 	arm_bl_params = arm_get_next_bl_params();
@@ -48,7 +56,6 @@
 #if !RESET_TO_BL2 && !EL3_PAYLOAD_BASE
 	const struct dyn_cfg_dtb_info_t *fw_config_info;
 	uintptr_t fw_config_base = 0UL;
-	entry_point_info_t *ep_info;
 
 #if __aarch64__
 	/* Get BL31 image node */
@@ -59,47 +66,75 @@
 #endif /* __aarch64__ */
 	assert(param_node != NULL);
 
-	/* get fw_config load address */
+	/* Update the next image's ep info with the FW config address */
 	fw_config_info = FCONF_GET_PROPERTY(dyn_cfg, dtb, FW_CONFIG_ID);
 	assert(fw_config_info != NULL);
 
 	fw_config_base = fw_config_info->config_addr;
 	assert(fw_config_base != 0UL);
 
+	param_node->ep_info.args.arg1 = (uint32_t)fw_config_base;
+
+	/* Update BL33's ep info with the NS HW config address */
+	param_node = get_bl_mem_params_node(BL33_IMAGE_ID);
+	assert(param_node != NULL);
+
-	/*
-	 * Get the entry point info of next executable image and override
-	 * arg1 of entry point info with fw_config base address
-	 */
-	ep_info = &param_node->ep_info;
-	ep_info->args.arg1 = (uint32_t)fw_config_base;
+#if TRANSFER_LIST
+	/* Update BL33's ep info with NS HW config address  */
+	te = transfer_list_find(ns_tl, TL_TAG_FDT);
+	assert(te != NULL);
 
-	/* grab NS HW config address */
+	param_node->ep_info.args.arg1 = TRANSFER_LIST_SIGNATURE |
+					REGISTER_CONVENTION_VERSION_MASK;
+	param_node->ep_info.args.arg2 = 0;
+	param_node->ep_info.args.arg3 = (uintptr_t)ns_tl;
+	param_node->ep_info.args.arg0 =
+		te ? (uintptr_t)transfer_list_entry_data(te) : 0;
+#else
 	hw_config_info = FCONF_GET_PROPERTY(dyn_cfg, dtb, HW_CONFIG_ID);
 	assert(hw_config_info != NULL);
 
-	/* To retrieve actual size of the HW_CONFIG */
-	param_node = get_bl_mem_params_node(HW_CONFIG_ID);
-	assert(param_node != NULL);
+	param_node->ep_info.args.arg1 = hw_config_info->secondary_config_addr;
+#endif /* TRANSFER_LIST */
+#endif /* !RESET_TO_BL2 && !EL3_PAYLOAD_BASE */
+
+	return arm_bl_params;
+}
 
-	/* Copy HW config from Secure address to NS address */
-	memcpy((void *)hw_config_info->secondary_config_addr,
-	       (void *)hw_config_info->config_addr,
-	       (size_t)param_node->image_info.image_size);
+int bl2_plat_handle_post_image_load(unsigned int image_id)
+{
+#if !RESET_TO_BL2 && !EL3_PAYLOAD_BASE
+	if (image_id == HW_CONFIG_ID) {
+		const struct dyn_cfg_dtb_info_t *hw_config_info;
+		struct transfer_list_entry *te __unused;
 
-	/*
-	 * Ensure HW-config device tree committed to memory, as there is
-	 * a possibility to use HW-config without cache and MMU enabled
-	 * at BL33
-	 */
-	flush_dcache_range(hw_config_info->secondary_config_addr,
-			   param_node->image_info.image_size);
+		const bl_mem_params_node_t *param_node =
+			get_bl_mem_params_node(image_id);
+		assert(param_node != NULL);
 
-	param_node = get_bl_mem_params_node(BL33_IMAGE_ID);
-	assert(param_node != NULL);
+		hw_config_info = FCONF_GET_PROPERTY(dyn_cfg, dtb, HW_CONFIG_ID);
+		assert(hw_config_info != NULL);
 
-	/* Update BL33's ep info with NS HW config address  */
-	param_node->ep_info.args.arg1 = hw_config_info->secondary_config_addr;
+#if TRANSFER_LIST
+		/* Update BL33's ep info with NS HW config address  */
+		te = transfer_list_add(ns_tl, TL_TAG_FDT,
+				       param_node->image_info.image_size,
+				       (void *)hw_config_info->config_addr);
+		assert(te != NULL);
+#else
+		memcpy((void *)hw_config_info->secondary_config_addr,
+		       (void *)hw_config_info->config_addr,
+		       (size_t)param_node->image_info.image_size);
+
+		/*
+		 * Ensure HW-config device tree is committed to memory, as the HW-Config
+		 * might be used without cache and MMU enabled at BL33.
+		 */
+		flush_dcache_range(hw_config_info->secondary_config_addr,
+				   param_node->image_info.image_size);
+#endif /* TRANSFER_LIST */
+	}
 #endif /* !RESET_TO_BL2 && !EL3_PAYLOAD_BASE */
 
-	return arm_bl_params;
+	return arm_bl2_plat_handle_post_image_load(image_id);
 }
diff --git a/plat/arm/board/fvp/fvp_common.c b/plat/arm/board/fvp/fvp_common.c
index 283918b..c40a3ce 100644
--- a/plat/arm/board/fvp/fvp_common.c
+++ b/plat/arm/board/fvp/fvp_common.c
@@ -71,6 +71,14 @@
 					DEVICE2_SIZE,			\
 					MT_DEVICE | MT_RW | MT_SECURE)
 
+#if TRANSFER_LIST
+#ifdef FW_NS_HANDOFF_BASE
+#define MAP_FW_NS_HANDOFF MAP_REGION_FLAT(FW_NS_HANDOFF_BASE, \
+					  FW_HANDOFF_SIZE,    \
+					  MT_MEMORY | MT_RW | MT_NS)
+#endif
+#endif
+
 /*
  * Table of memory regions for various BL stages to map using the MMU.
  * This doesn't include Trusted SRAM as setup_page_tables() already takes care
@@ -183,6 +191,9 @@
 	ARM_MAP_GPT_L1_DRAM,
 	ARM_MAP_EL3_RMM_SHARED_MEM,
 #endif
+#ifdef MAP_FW_NS_HANDOFF
+	MAP_FW_NS_HANDOFF,
+#endif
 	{0}
 };
 
diff --git a/plat/arm/board/fvp/fvp_plat_attest_token.c b/plat/arm/board/fvp/fvp_plat_attest_token.c
index 5af2405..5fb3141 100644
--- a/plat/arm/board/fvp/fvp_plat_attest_token.c
+++ b/plat/arm/board/fvp/fvp_plat_attest_token.c
@@ -4,23 +4,115 @@
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
-#include <delegated_attestation.h>
-#include <psa/error.h>
+#include <errno.h>
+#include <string.h>
+
+#include <plat/common/platform.h>
+
+static const uint8_t sample_platform_token[] = {
+	0xD2, 0x84, 0x44, 0xA1, 0x01, 0x38, 0x22, 0xA0,
+	0x59, 0x02, 0x33, 0xA9, 0x19, 0x01, 0x09, 0x78,
+	0x1C, 0x68, 0x74, 0x74, 0x70, 0x3A, 0x2F, 0x2F,
+	0x61, 0x72, 0x6D, 0x2E, 0x63, 0x6F, 0x6D, 0x2F,
+	0x43, 0x43, 0x41, 0x2D, 0x53, 0x53, 0x44, 0x2F,
+	0x31, 0x2E, 0x30, 0x2E, 0x30, 0x0A, 0x58, 0x20,
+	0xB5, 0x97, 0x3C, 0xB6, 0x8B, 0xAA, 0x9F, 0xC5,
+	0x55, 0x58, 0x78, 0x6B, 0x7E, 0xC6, 0x7F, 0x69,
+	0xE4, 0x0D, 0xF5, 0xBA, 0x5A, 0xA9, 0x21, 0xCD,
+	0x0C, 0x27, 0xF4, 0x05, 0x87, 0xA0, 0x11, 0xEA,
+	0x19, 0x09, 0x5C, 0x58, 0x20, 0x7F, 0x45, 0x4C,
+	0x46, 0x02, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x3E,
+	0x00, 0x01, 0x00, 0x00, 0x00, 0x50, 0x58, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0x01, 0x00,
+	0x58, 0x21, 0x01, 0x07, 0x06, 0x05, 0x04, 0x03,
+	0x02, 0x01, 0x00, 0x0F, 0x0E, 0x0D, 0x0C, 0x0B,
+	0x0A, 0x09, 0x08, 0x17, 0x16, 0x15, 0x14, 0x13,
+	0x12, 0x11, 0x10, 0x1F, 0x1E, 0x1D, 0x1C, 0x1B,
+	0x1A, 0x19, 0x18, 0x19, 0x09, 0x61, 0x58, 0x21,
+	0x01, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01,
+	0x00, 0x0F, 0x0E, 0x0D, 0x0C, 0x0B, 0x0A, 0x09,
+	0x08, 0x17, 0x16, 0x15, 0x14, 0x13, 0x12, 0x11,
+	0x10, 0x1F, 0x1E, 0x1D, 0x1C, 0x1B, 0x1A, 0x19,
+	0x18, 0x19, 0x09, 0x5B, 0x19, 0x30, 0x03, 0x19,
+	0x09, 0x62, 0x67, 0x73, 0x68, 0x61, 0x2D, 0x32,
+	0x35, 0x36, 0x19, 0x09, 0x5F, 0x84, 0xA5, 0x01,
+	0x62, 0x42, 0x4C, 0x05, 0x58, 0x20, 0x07, 0x06,
+	0x05, 0x04, 0x03, 0x02, 0x01, 0x00, 0x0F, 0x0E,
+	0x0D, 0x0C, 0x0B, 0x0A, 0x09, 0x08, 0x17, 0x16,
+	0x15, 0x14, 0x13, 0x12, 0x11, 0x10, 0x1F, 0x1E,
+	0x1D, 0x1C, 0x1B, 0x1A, 0x19, 0x18, 0x04, 0x65,
+	0x33, 0x2E, 0x34, 0x2E, 0x32, 0x02, 0x58, 0x20,
+	0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00,
+	0x0F, 0x0E, 0x0D, 0x0C, 0x0B, 0x0A, 0x09, 0x08,
+	0x17, 0x16, 0x15, 0x14, 0x13, 0x12, 0x11, 0x10,
+	0x1F, 0x1E, 0x1D, 0x1C, 0x1B, 0x1A, 0x19, 0x18,
+	0x06, 0x74, 0x54, 0x46, 0x2D, 0x4D, 0x5F, 0x53,
+	0x48, 0x41, 0x32, 0x35, 0x36, 0x4D, 0x65, 0x6D,
+	0x50, 0x72, 0x65, 0x58, 0x49, 0x50, 0xA4, 0x01,
+	0x62, 0x4D, 0x31, 0x05, 0x58, 0x20, 0x07, 0x06,
+	0x05, 0x04, 0x03, 0x02, 0x01, 0x00, 0x0F, 0x0E,
+	0x0D, 0x0C, 0x0B, 0x0A, 0x09, 0x08, 0x17, 0x16,
+	0x15, 0x14, 0x13, 0x12, 0x11, 0x10, 0x1F, 0x1E,
+	0x1D, 0x1C, 0x1B, 0x1A, 0x19, 0x18, 0x04, 0x63,
+	0x31, 0x2E, 0x32, 0x02, 0x58, 0x20, 0x07, 0x06,
+	0x05, 0x04, 0x03, 0x02, 0x01, 0x00, 0x0F, 0x0E,
+	0x0D, 0x0C, 0x0B, 0x0A, 0x09, 0x08, 0x17, 0x16,
+	0x15, 0x14, 0x13, 0x12, 0x11, 0x10, 0x1F, 0x1E,
+	0x1D, 0x1C, 0x1B, 0x1A, 0x19, 0x18, 0xA4, 0x01,
+	0x62, 0x4D, 0x32, 0x05, 0x58, 0x20, 0x07, 0x06,
+	0x05, 0x04, 0x03, 0x02, 0x01, 0x00, 0x0F, 0x0E,
+	0x0D, 0x0C, 0x0B, 0x0A, 0x09, 0x08, 0x17, 0x16,
+	0x15, 0x14, 0x13, 0x12, 0x11, 0x10, 0x1F, 0x1E,
+	0x1D, 0x1C, 0x1B, 0x1A, 0x19, 0x18, 0x04, 0x65,
+	0x31, 0x2E, 0x32, 0x2E, 0x33, 0x02, 0x58, 0x20,
+	0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00,
+	0x0F, 0x0E, 0x0D, 0x0C, 0x0B, 0x0A, 0x09, 0x08,
+	0x17, 0x16, 0x15, 0x14, 0x13, 0x12, 0x11, 0x10,
+	0x1F, 0x1E, 0x1D, 0x1C, 0x1B, 0x1A, 0x19, 0x18,
+	0xA4, 0x01, 0x62, 0x4D, 0x33, 0x05, 0x58, 0x20,
+	0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00,
+	0x0F, 0x0E, 0x0D, 0x0C, 0x0B, 0x0A, 0x09, 0x08,
+	0x17, 0x16, 0x15, 0x14, 0x13, 0x12, 0x11, 0x10,
+	0x1F, 0x1E, 0x1D, 0x1C, 0x1B, 0x1A, 0x19, 0x18,
+	0x04, 0x61, 0x31, 0x02, 0x58, 0x20, 0x07, 0x06,
+	0x05, 0x04, 0x03, 0x02, 0x01, 0x00, 0x0F, 0x0E,
+	0x0D, 0x0C, 0x0B, 0x0A, 0x09, 0x08, 0x17, 0x16,
+	0x15, 0x14, 0x13, 0x12, 0x11, 0x10, 0x1F, 0x1E,
+	0x1D, 0x1C, 0x1B, 0x1A, 0x19, 0x18, 0x19, 0x09,
+	0x60, 0x6C, 0x77, 0x68, 0x61, 0x74, 0x65, 0x76,
+	0x65, 0x72, 0x2E, 0x63, 0x6F, 0x6D, 0x58, 0x60,
+	0xE6, 0xB6, 0x38, 0x4F, 0xAE, 0x3F, 0x6E, 0x67,
+	0xF5, 0xD4, 0x97, 0x4B, 0x3F, 0xFD, 0x0A, 0xFA,
+	0x1D, 0xF0, 0x2F, 0x73, 0xB8, 0xFF, 0x5F, 0x02,
+	0xC0, 0x0F, 0x40, 0xAC, 0xF3, 0xA2, 0x9D, 0xB5,
+	0x31, 0x50, 0x16, 0x4F, 0xFA, 0x34, 0x3D, 0x0E,
+	0xAF, 0xE0, 0xD0, 0xD1, 0x6C, 0xF0, 0x9D, 0xC1,
+	0x01, 0x42, 0xA2, 0x3C, 0xCE, 0xD4, 0x4A, 0x59,
+	0xDC, 0x29, 0x0A, 0x30, 0x93, 0x5F, 0xB4, 0x98,
+	0x61, 0xBA, 0xE3, 0x91, 0x22, 0x95, 0x24, 0xF4,
+	0xAE, 0x47, 0x93, 0xD3, 0x84, 0xA3, 0x76, 0xD0,
+	0xC1, 0x26, 0x96, 0x53, 0xA3, 0x60, 0x3F, 0x6C,
+	0x75, 0x96, 0x90, 0x6A, 0xF9, 0x4E, 0xDA, 0x30
+};
 
 /*
- * Get the platform attestation token through the PSA delegated attestation
- * layer.
- *
- * FVP cannot support RSS hardware at the moment, but it can still mock the
- * RSS implementation of the PSA interface (see PLAT_RSS_NOT_SUPPORTED).
+ * Get the hardcoded platform attestation token as FVP does not support
+ * RSS.
  */
 int plat_rmmd_get_cca_attest_token(uintptr_t buf, size_t *len,
 				   uintptr_t hash, size_t hash_size)
 {
-	psa_status_t ret;
+	(void)hash;
+	(void)hash_size;
 
-	ret = rss_delegated_attest_get_token((const uint8_t *)hash, hash_size,
-					     (uint8_t *)buf, *len, len);
+	if (*len < sizeof(sample_platform_token)) {
+		return -EINVAL;
+	}
+
+	(void)memcpy((void *)buf, (const void *)sample_platform_token,
+		     sizeof(sample_platform_token));
+	*len = sizeof(sample_platform_token);
 
-	return ret;
+	return 0;
 }
diff --git a/plat/arm/board/fvp/fvp_realm_attest_key.c b/plat/arm/board/fvp/fvp_realm_attest_key.c
index 26354f4..fe0cde7 100644
--- a/plat/arm/board/fvp/fvp_realm_attest_key.c
+++ b/plat/arm/board/fvp/fvp_realm_attest_key.c
@@ -4,27 +4,33 @@
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
-#include <assert.h>
-#include <delegated_attestation.h>
-#include <psa/error.h>
-#include <services/rmmd_svc.h>
+#include <errno.h>
+#include <string.h>
+
+#include <plat/common/platform.h>
+
+static const uint8_t sample_delegated_key[] = {
+	0x20, 0x11, 0xC7, 0xF0, 0x3C, 0xEE, 0x43, 0x25, 0x17, 0x6E,
+	0x52, 0x4F, 0x03, 0x3C, 0x0C, 0xE1, 0xE2, 0x1A, 0x76, 0xE6,
+	0xC1, 0xA4, 0xF0, 0xB8, 0x39, 0xAA, 0x1D, 0xF6, 0x1E, 0x0E,
+	0x8A, 0x5C, 0x8A, 0x05, 0x74, 0x0F, 0x9B, 0x69, 0xEF, 0xA7,
+	0xEB, 0x1A, 0x41, 0x85, 0xBD, 0x11, 0x7F, 0x68
+};
 
 /*
- * Get the delegated realm attestation key through the PSA delegated
- * attestation layer.
- *
- * FVP cannot support RSS hardware at the moment, but it can still mock
- * the RSS implementation of the PSA interface (see PLAT_RSS_NOT_SUPPORTED).
+ * Get the hardcoded delegated realm attestation key as FVP
+ * does not support RSS.
  */
 int plat_rmmd_get_cca_realm_attest_key(uintptr_t buf, size_t *len,
 				       unsigned int type)
 {
-	psa_status_t ret;
+	if (*len < sizeof(sample_delegated_key)) {
+		return -EINVAL;
+	}
 
-	assert(type == ATTEST_KEY_CURVE_ECC_SECP384R1);
-
-	ret = rss_delegated_attest_get_delegated_key(0U, 0U, (uint8_t *)buf,
-						     *len, len, 0U);
+	(void)memcpy((void *)buf, (const void *)sample_delegated_key,
+		     sizeof(sample_delegated_key));
+	*len = sizeof(sample_delegated_key);
 
-	return ret;
+	return 0;
 }
diff --git a/plat/arm/board/fvp/include/platform_def.h b/plat/arm/board/fvp/include/platform_def.h
index 826fca2..aad0417 100644
--- a/plat/arm/board/fvp/include/platform_def.h
+++ b/plat/arm/board/fvp/include/platform_def.h
@@ -128,6 +128,11 @@
  */
 #define PLAT_ARM_NS_IMAGE_BASE		(ARM_DRAM1_BASE + UL(0x8000000))
 
+#if TRANSFER_LIST
+#define FW_HANDOFF_SIZE			0x4000
+#define FW_NS_HANDOFF_BASE		(PLAT_ARM_NS_IMAGE_BASE - FW_HANDOFF_SIZE)
+#endif
+
 /*
  * PLAT_ARM_MMAP_ENTRIES depends on the number of entries in the
  * plat_arm_mmap array defined for each BL stage.
@@ -188,8 +193,10 @@
 /*
  * PLAT_ARM_MAX_BL1_RW_SIZE is calculated using the current BL1 RW debug size
  * plus a little space for growth.
+ * In case of PSA Crypto API, few algorithms like ECDSA needs bigger BL1 RW
+ * area.
  */
-#if TF_MBEDTLS_KEY_ALG_ID == TF_MBEDTLS_RSA_AND_ECDSA
+#if TF_MBEDTLS_KEY_ALG_ID == TF_MBEDTLS_RSA_AND_ECDSA || PSA_CRYPTO
 #define PLAT_ARM_MAX_BL1_RW_SIZE	UL(0xC000)
 #else
 #define PLAT_ARM_MAX_BL1_RW_SIZE	UL(0xB000)
diff --git a/plat/arm/board/fvp/platform.mk b/plat/arm/board/fvp/platform.mk
index e21a17e..f7c174f 100644
--- a/plat/arm/board/fvp/platform.mk
+++ b/plat/arm/board/fvp/platform.mk
@@ -53,7 +53,6 @@
 	ENABLE_FEAT_AMU			:= 2
 	ENABLE_FEAT_AMUv1p1		:= 2
 	ENABLE_FEAT_HCX			:= 2
-	ENABLE_FEAT_MPAM		:= 2
 	ENABLE_FEAT_RNG			:= 2
 	ENABLE_FEAT_TWED		:= 2
 	ENABLE_FEAT_GCS			:= 2
@@ -214,7 +213,8 @@
 					lib/cpus/aarch64/neoverse_e1.S		\
 					lib/cpus/aarch64/cortex_x2.S		\
 					lib/cpus/aarch64/cortex_gelas.S		\
-					lib/cpus/aarch64/nevis.S
+					lib/cpus/aarch64/nevis.S		\
+					lib/cpus/aarch64/travis.S
 	endif
 	# AArch64/AArch32 cores
 	FVP_CPU_LIBS	+=	lib/cpus/aarch64/cortex_a55.S		\
@@ -268,11 +268,6 @@
 
 BL31_SOURCES		+=	plat/arm/board/fvp/fvp_plat_attest_token.c	\
 				plat/arm/board/fvp/fvp_realm_attest_key.c
-
-# FVP platform does not support RSS, but it can leverage RSS APIs to
-# provide hardcoded token/key on request.
-BL31_SOURCES		+=	lib/psa/delegated_attestation.c
-
 endif
 
 ifeq (${ENABLE_FEAT_RNG_TRAP},1)
@@ -357,6 +352,10 @@
 $(eval $(call TOOL_ADD_PAYLOAD,${FVP_TOS_FW_CONFIG},--tos-fw-config,${FVP_TOS_FW_CONFIG}))
 endif
 
+ifeq (${TRANSFER_LIST}, 1)
+include lib/transfer_list/transfer_list.mk
+endif
+
 ifeq (${SPD},spmd)
 
 ifeq ($(ARM_SPMC_MANIFEST_DTS),)
diff --git a/plat/arm/board/fvp_ve/fvp_ve_bl2_setup.c b/plat/arm/board/fvp_ve/fvp_ve_bl2_setup.c
index 4ccae27..cc29f36 100644
--- a/plat/arm/board/fvp_ve/fvp_ve_bl2_setup.c
+++ b/plat/arm/board/fvp_ve/fvp_ve_bl2_setup.c
@@ -39,3 +39,8 @@
 	generic_delay_timer_init();
 #endif /* USE_SP804_TIMER */
 }
+
+int bl2_plat_handle_post_image_load(unsigned int image_id)
+{
+	return arm_bl2_plat_handle_post_image_load(image_id);
+}
diff --git a/plat/arm/common/arm_bl2_setup.c b/plat/arm/common/arm_bl2_setup.c
index b142b62..e15bf0f 100644
--- a/plat/arm/common/arm_bl2_setup.c
+++ b/plat/arm/common/arm_bl2_setup.c
@@ -69,6 +69,8 @@
 void arm_bl2_early_platform_setup(uintptr_t fw_config,
 				  struct meminfo *mem_layout)
 {
+	int __maybe_unused ret;
+
 	/* Initialize the console to provide early debug support */
 	arm_console_boot_init();
 
@@ -82,9 +84,13 @@
 
 	/* Load partition table */
 #if ARM_GPT_SUPPORT
-	partition_init(GPT_IMAGE_ID);
-#endif /* ARM_GPT_SUPPORT */
+	ret = gpt_partition_init();
+	if (ret != 0) {
+		ERROR("GPT partition initialisation failed!\n");
+		panic();
+	}
 
+#endif /* ARM_GPT_SUPPORT */
 }
 
 void bl2_early_platform_setup2(u_register_t arg0, u_register_t arg1, u_register_t arg2, u_register_t arg3)
@@ -312,8 +318,3 @@
 #endif
 	return arm_bl2_handle_post_image_load(image_id);
 }
-
-int bl2_plat_handle_post_image_load(unsigned int image_id)
-{
-	return arm_bl2_plat_handle_post_image_load(image_id);
-}
diff --git a/plat/arm/common/fconf/arm_fconf_io.c b/plat/arm/common/fconf/arm_fconf_io.c
index 27acc3a..07f6a82 100644
--- a/plat/arm/common/fconf/arm_fconf_io.c
+++ b/plat/arm/common/fconf/arm_fconf_io.c
@@ -45,10 +45,21 @@
 	 * each sector has 4 partition entries, and there are
 	 * 2 reserved sectors i.e. protective MBR and primary
 	 * GPT header hence length gets calculated as,
-	 * length = 512 * (128/4 + 2)
+	 * length = PLAT_PARTITION_BLOCK_SIZE * (128/4 + 2)
 	 */
-	.length         = PLAT_PARTITION_BLOCK_SIZE *
-			  (PLAT_PARTITION_MAX_ENTRIES / 4 + 2),
+	.length         = LBA(PLAT_PARTITION_MAX_ENTRIES / 4 + 2),
+};
+
+/*
+ * length will be assigned at runtime based on MBR header data.
+ * Backup GPT Header is present in Last LBA-1 and its entries
+ * are last 32 blocks starts at LBA-33, On runtime update these
+ * before device usage. Update offset to beginning LBA-33 and
+ * length to LBA-33.
+ */
+static io_block_spec_t bkup_gpt_spec = {
+	.offset         = PLAT_ARM_FLASH_IMAGE_BASE,
+	.length         = 0,
 };
 #endif /* ARM_GPT_SUPPORT */
 
@@ -107,6 +118,11 @@
 		(uintptr_t)&gpt_spec,
 		open_memmap
 	},
+	[BKUP_GPT_IMAGE_ID] = {
+		&memmap_dev_handle,
+		(uintptr_t)&bkup_gpt_spec,
+		open_memmap
+	},
 #endif /* ARM_GPT_SUPPORT */
 #if PSA_FWU_SUPPORT
 	[FWU_METADATA_IMAGE_ID] = {
diff --git a/plat/arm/css/common/css_bl2_setup.c b/plat/arm/css/common/css_bl2_setup.c
index 002c6eb..1e055c5 100644
--- a/plat/arm/css/common/css_bl2_setup.c
+++ b/plat/arm/css/common/css_bl2_setup.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2023, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -84,3 +84,8 @@
 # endif /* EL3_PAYLOAD_BASE */
 
 #endif /* CSS_USE_SCMI_SDS_DRIVER */
+
+int bl2_plat_handle_post_image_load(unsigned int image_id)
+{
+	return arm_bl2_plat_handle_post_image_load(image_id);
+}
diff --git a/plat/aspeed/ast2700/plat_bl31_setup.c b/plat/aspeed/ast2700/plat_bl31_setup.c
index fde5dbb..92a48ff 100644
--- a/plat/aspeed/ast2700/plat_bl31_setup.c
+++ b/plat/aspeed/ast2700/plat_bl31_setup.c
@@ -76,6 +76,12 @@
 			BL_END - BL_CODE_END,
 			MT_RW_DATA | MT_SECURE);
 
+#if USE_COHERENT_MEM
+	mmap_add_region(BL_COHERENT_RAM_BASE, BL_COHERENT_RAM_BASE,
+			BL_COHERENT_RAM_END - BL_COHERENT_RAM_BASE,
+			MT_DEVICE | MT_RW | MT_SECURE);
+#endif
+
 	mmap_add_region(BL32_BASE, BL32_BASE, BL32_SIZE,
 			MT_MEMORY | MT_RW);
 
diff --git a/plat/ti/k3/common/k3_bl31_setup.c b/plat/ti/k3/common/k3_bl31_setup.c
index bbfb5bb..c5f60fe 100644
--- a/plat/ti/k3/common/k3_bl31_setup.c
+++ b/plat/ti/k3/common/k3_bl31_setup.c
@@ -20,14 +20,20 @@
 #include <k3_gicv3.h>
 #include <ti_sci.h>
 
+#define ADDR_DOWN(_adr) (_adr & XLAT_ADDR_MASK(2U))
+#define SIZE_UP(_adr, _sz) (round_up((_adr + _sz), XLAT_BLOCK_SIZE(2U)) - ADDR_DOWN(_adr))
+
+#define K3_MAP_REGION_FLAT(_adr, _sz, _attr) \
+	MAP_REGION_FLAT(ADDR_DOWN(_adr), SIZE_UP(_adr, _sz), _attr)
+
 /* Table of regions to map using the MMU */
 const mmap_region_t plat_k3_mmap[] = {
-	MAP_REGION_FLAT(K3_USART_BASE,       K3_USART_SIZE,       MT_DEVICE | MT_RW | MT_SECURE),
-	MAP_REGION_FLAT(K3_GIC_BASE,         K3_GIC_SIZE,         MT_DEVICE | MT_RW | MT_SECURE),
-	MAP_REGION_FLAT(K3_GTC_BASE,         K3_GTC_SIZE,         MT_DEVICE | MT_RW | MT_SECURE),
-	MAP_REGION_FLAT(SEC_PROXY_RT_BASE,   SEC_PROXY_RT_SIZE,   MT_DEVICE | MT_RW | MT_SECURE),
-	MAP_REGION_FLAT(SEC_PROXY_SCFG_BASE, SEC_PROXY_SCFG_SIZE, MT_DEVICE | MT_RW | MT_SECURE),
-	MAP_REGION_FLAT(SEC_PROXY_DATA_BASE, SEC_PROXY_DATA_SIZE, MT_DEVICE | MT_RW | MT_SECURE),
+	K3_MAP_REGION_FLAT(K3_USART_BASE,       K3_USART_SIZE,       MT_DEVICE | MT_RW | MT_SECURE),
+	K3_MAP_REGION_FLAT(K3_GIC_BASE,         K3_GIC_SIZE,         MT_DEVICE | MT_RW | MT_SECURE),
+	K3_MAP_REGION_FLAT(K3_GTC_BASE,         K3_GTC_SIZE,         MT_DEVICE | MT_RW | MT_SECURE),
+	K3_MAP_REGION_FLAT(SEC_PROXY_RT_BASE,   SEC_PROXY_RT_SIZE,   MT_DEVICE | MT_RW | MT_SECURE),
+	K3_MAP_REGION_FLAT(SEC_PROXY_SCFG_BASE, SEC_PROXY_SCFG_SIZE, MT_DEVICE | MT_RW | MT_SECURE),
+	K3_MAP_REGION_FLAT(SEC_PROXY_DATA_BASE, SEC_PROXY_DATA_SIZE, MT_DEVICE | MT_RW | MT_SECURE),
 	{ /* sentinel */ }
 };
 
diff --git a/plat/ti/k3/include/platform_def.h b/plat/ti/k3/include/platform_def.h
index ae3775a..a2cc62d 100644
--- a/plat/ti/k3/include/platform_def.h
+++ b/plat/ti/k3/include/platform_def.h
@@ -70,11 +70,7 @@
  * used, choose the smallest value needed to map the required virtual addresses
  * for each BL stage.
  */
-#if USE_COHERENT_MEM
-#define MAX_XLAT_TABLES		10
-#else
-#define MAX_XLAT_TABLES		9
-#endif
+#define MAX_XLAT_TABLES		4
 
 /*
  * Defines the maximum number of regions that are allocated by the translation
@@ -86,7 +82,11 @@
  * runtime memory used, choose the smallest value needed to register the
  * required regions for each BL stage.
  */
+#if USE_COHERENT_MEM
 #define MAX_MMAP_REGIONS	11
+#else
+#define MAX_MMAP_REGIONS	10
+#endif
 
 /*
  * Defines the total size of the address space in bytes. For example, for a 32
diff --git a/plat/xilinx/versal/include/platform_def.h b/plat/xilinx/versal/include/platform_def.h
index 4c02402..286a706 100644
--- a/plat/xilinx/versal/include/platform_def.h
+++ b/plat/xilinx/versal/include/platform_def.h
@@ -35,10 +35,10 @@
 # define BL31_BASE			U(0xfffe0000)
 # define BL31_LIMIT			U(0x100000000)
 #else
-# define BL31_BASE			(VERSAL_ATF_MEM_BASE)
-# define BL31_LIMIT			(VERSAL_ATF_MEM_BASE + VERSAL_ATF_MEM_SIZE)
+# define BL31_BASE			U(VERSAL_ATF_MEM_BASE)
+# define BL31_LIMIT			U(VERSAL_ATF_MEM_BASE + VERSAL_ATF_MEM_SIZE)
 # ifdef VERSAL_ATF_MEM_PROGBITS_SIZE
-#  define BL31_PROGBITS_LIMIT		(VERSAL_ATF_MEM_BASE + VERSAL_ATF_MEM_PROGBITS_SIZE)
+#  define BL31_PROGBITS_LIMIT		U(VERSAL_ATF_MEM_BASE + VERSAL_ATF_MEM_PROGBITS_SIZE)
 # endif
 #endif
 
@@ -49,8 +49,8 @@
 # define BL32_BASE			U(0x60000000)
 # define BL32_LIMIT			U(0x80000000)
 #else
-# define BL32_BASE			(VERSAL_BL32_MEM_BASE)
-# define BL32_LIMIT			(VERSAL_BL32_MEM_BASE + VERSAL_BL32_MEM_SIZE)
+# define BL32_BASE			U(VERSAL_BL32_MEM_BASE)
+# define BL32_LIMIT			U(VERSAL_BL32_MEM_BASE + VERSAL_BL32_MEM_SIZE)
 #endif
 
 /*******************************************************************************
@@ -59,7 +59,7 @@
 #ifndef PRELOADED_BL33_BASE
 # define PLAT_ARM_NS_IMAGE_BASE		U(0x8000000)
 #else
-# define PLAT_ARM_NS_IMAGE_BASE		PRELOADED_BL33_BASE
+# define PLAT_ARM_NS_IMAGE_BASE		U(PRELOADED_BL33_BASE)
 #endif
 
 /*******************************************************************************
diff --git a/services/std_svc/rmmd/trp/trp_main.c b/services/std_svc/rmmd/trp/trp_main.c
index 4eb3e12..33f2fb0 100644
--- a/services/std_svc/rmmd/trp/trp_main.c
+++ b/services/std_svc/rmmd/trp/trp_main.c
@@ -106,11 +106,18 @@
 /*******************************************************************************
  * Returning RMI version back to Normal World
  ******************************************************************************/
-static void trp_ret_rmi_version(struct trp_smc_result *smc_ret)
+static void trp_ret_rmi_version(unsigned long long rmi_version,
+				struct trp_smc_result *smc_ret)
 {
+	if (rmi_version != RMI_ABI_VERSION) {
+		smc_ret->x[0] = RMI_ERROR_INPUT;
+	} else {
+		smc_ret->x[0] = RMI_SUCCESS;
+	}
 	VERBOSE("RMM version is %u.%u\n", RMI_ABI_VERSION_MAJOR,
 					  RMI_ABI_VERSION_MINOR);
-	smc_ret->x[0] = RMI_ABI_VERSION;
+	smc_ret->x[1] = RMI_ABI_VERSION;
+	smc_ret->x[2] = RMI_ABI_VERSION;
 }
 
 /*******************************************************************************
@@ -163,7 +170,7 @@
 
 	switch (fid) {
 	case RMI_RMM_REQ_VERSION:
-		trp_ret_rmi_version(smc_ret);
+		trp_ret_rmi_version(x1, smc_ret);
 		break;
 	case RMI_RMM_GRANULE_DELEGATE:
 		trp_asc_mark_realm(x1, smc_ret);