Merge "feat(stm32mp1): save boot auth status and partition info" into integration
diff --git a/changelog.yaml b/changelog.yaml
index 6d395bc..37a9c6d 100644
--- a/changelog.yaml
+++ b/changelog.yaml
@@ -89,6 +89,9 @@
       - title: Activity Monitors Extension (FEAT_AMU)
         scope: amu
 
+      - title: Confidential Compute Architecture (CCA)
+        scope: cca
+
       - title: Support for the `HCRX_EL2` register (FEAT_HCX)
         scope: hcx
 
diff --git a/drivers/auth/cca/cot.c b/drivers/auth/cca/cot.c
new file mode 100644
index 0000000..d3f3087
--- /dev/null
+++ b/drivers/auth/cca/cot.c
@@ -0,0 +1,675 @@
+/*
+ * Copyright (c) 2022, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stddef.h>
+
+#include <drivers/auth/auth_mod.h>
+#include MBEDTLS_CONFIG_FILE
+#include <tools_share/cca_oid.h>
+
+#include <platform_def.h>
+
+/*
+ * Allocate static buffers to store the authentication parameters extracted from
+ * the certificates.
+ */
+static unsigned char fw_config_hash_buf[HASH_DER_LEN];
+static unsigned char tb_fw_hash_buf[HASH_DER_LEN];
+static unsigned char tb_fw_config_hash_buf[HASH_DER_LEN];
+static unsigned char hw_config_hash_buf[HASH_DER_LEN];
+static unsigned char soc_fw_hash_buf[HASH_DER_LEN];
+static unsigned char soc_fw_config_hash_buf[HASH_DER_LEN];
+static unsigned char rmm_hash_buf[HASH_DER_LEN];
+
+#ifdef IMAGE_BL2
+static unsigned char nt_world_bl_hash_buf[HASH_DER_LEN];
+static unsigned char tos_fw_hash_buf[HASH_DER_LEN];
+static unsigned char tos_fw_config_hash_buf[HASH_DER_LEN];
+static unsigned char nt_fw_config_hash_buf[HASH_DER_LEN];
+#if defined(SPD_spmd)
+static unsigned char sp_pkg_hash_buf[MAX_SP_IDS][HASH_DER_LEN];
+#endif /* SPD_spmd */
+
+static unsigned char core_swd_pk_buf[PK_DER_LEN];
+static unsigned char plat_pk_buf[PK_DER_LEN];
+#endif /* IMAGE_BL2 */
+
+/*
+ * Parameter type descriptors.
+ */
+static auth_param_type_desc_t trusted_nv_ctr = AUTH_PARAM_TYPE_DESC(
+		AUTH_PARAM_NV_CTR, TRUSTED_FW_NVCOUNTER_OID);
+static auth_param_type_desc_t subject_pk = AUTH_PARAM_TYPE_DESC(
+		AUTH_PARAM_PUB_KEY, 0);
+static auth_param_type_desc_t sig = AUTH_PARAM_TYPE_DESC(
+		AUTH_PARAM_SIG, 0);
+static auth_param_type_desc_t sig_alg = AUTH_PARAM_TYPE_DESC(
+		AUTH_PARAM_SIG_ALG, 0);
+static auth_param_type_desc_t raw_data = AUTH_PARAM_TYPE_DESC(
+		AUTH_PARAM_RAW_DATA, 0);
+
+static auth_param_type_desc_t tb_fw_hash = AUTH_PARAM_TYPE_DESC(
+		AUTH_PARAM_HASH, TRUSTED_BOOT_FW_HASH_OID);
+static auth_param_type_desc_t tb_fw_config_hash = AUTH_PARAM_TYPE_DESC(
+		AUTH_PARAM_HASH, TRUSTED_BOOT_FW_CONFIG_HASH_OID);
+static auth_param_type_desc_t hw_config_hash = AUTH_PARAM_TYPE_DESC(
+		AUTH_PARAM_HASH, HW_CONFIG_HASH_OID);
+static auth_param_type_desc_t fw_config_hash = AUTH_PARAM_TYPE_DESC(
+		AUTH_PARAM_HASH, FW_CONFIG_HASH_OID);
+static auth_param_type_desc_t soc_fw_hash = AUTH_PARAM_TYPE_DESC(
+		AUTH_PARAM_HASH, SOC_AP_FW_HASH_OID);
+static auth_param_type_desc_t soc_fw_config_hash = AUTH_PARAM_TYPE_DESC(
+		AUTH_PARAM_HASH, SOC_FW_CONFIG_HASH_OID);
+static auth_param_type_desc_t rmm_hash = AUTH_PARAM_TYPE_DESC(
+		AUTH_PARAM_HASH, RMM_HASH_OID);
+
+#ifdef IMAGE_BL2
+static auth_param_type_desc_t non_trusted_nv_ctr = AUTH_PARAM_TYPE_DESC(
+		AUTH_PARAM_NV_CTR, NON_TRUSTED_FW_NVCOUNTER_OID);
+
+static auth_param_type_desc_t prot_pk = AUTH_PARAM_TYPE_DESC(
+		AUTH_PARAM_PUB_KEY, PROT_PK_OID);
+static auth_param_type_desc_t swd_rot_pk = AUTH_PARAM_TYPE_DESC(
+		AUTH_PARAM_PUB_KEY, SWD_ROT_PK_OID);
+static auth_param_type_desc_t core_swd_pk = AUTH_PARAM_TYPE_DESC(
+		AUTH_PARAM_PUB_KEY, CORE_SWD_PK_OID);
+static auth_param_type_desc_t plat_pk = AUTH_PARAM_TYPE_DESC(
+		AUTH_PARAM_PUB_KEY, PLAT_PK_OID);
+
+static auth_param_type_desc_t tos_fw_hash = AUTH_PARAM_TYPE_DESC(
+		AUTH_PARAM_HASH, TRUSTED_OS_FW_HASH_OID);
+static auth_param_type_desc_t tos_fw_config_hash = AUTH_PARAM_TYPE_DESC(
+		AUTH_PARAM_HASH, TRUSTED_OS_FW_CONFIG_HASH_OID);
+static auth_param_type_desc_t nt_world_bl_hash = AUTH_PARAM_TYPE_DESC(
+		AUTH_PARAM_HASH, NON_TRUSTED_WORLD_BOOTLOADER_HASH_OID);
+static auth_param_type_desc_t nt_fw_config_hash = AUTH_PARAM_TYPE_DESC(
+		AUTH_PARAM_HASH, NON_TRUSTED_FW_CONFIG_HASH_OID);
+#if defined(SPD_spmd)
+static auth_param_type_desc_t sp_pkg1_hash = AUTH_PARAM_TYPE_DESC(
+		AUTH_PARAM_HASH, SP_PKG1_HASH_OID);
+static auth_param_type_desc_t sp_pkg2_hash = AUTH_PARAM_TYPE_DESC(
+		AUTH_PARAM_HASH, SP_PKG2_HASH_OID);
+static auth_param_type_desc_t sp_pkg3_hash = AUTH_PARAM_TYPE_DESC(
+		AUTH_PARAM_HASH, SP_PKG3_HASH_OID);
+static auth_param_type_desc_t sp_pkg4_hash = AUTH_PARAM_TYPE_DESC(
+		AUTH_PARAM_HASH, SP_PKG4_HASH_OID);
+static auth_param_type_desc_t sp_pkg5_hash = AUTH_PARAM_TYPE_DESC(
+		AUTH_PARAM_HASH, SP_PKG5_HASH_OID);
+static auth_param_type_desc_t sp_pkg6_hash = AUTH_PARAM_TYPE_DESC(
+		AUTH_PARAM_HASH, SP_PKG6_HASH_OID);
+static auth_param_type_desc_t sp_pkg7_hash = AUTH_PARAM_TYPE_DESC(
+		AUTH_PARAM_HASH, SP_PKG7_HASH_OID);
+static auth_param_type_desc_t sp_pkg8_hash = AUTH_PARAM_TYPE_DESC(
+		AUTH_PARAM_HASH, SP_PKG8_HASH_OID);
+#endif /* SPD_spmd */
+#endif /* IMAGE_BL2 */
+
+/* CCA Content Certificate */
+static const auth_img_desc_t cca_content_cert = {
+	.img_id = CCA_CONTENT_CERT_ID,
+	.img_type = IMG_CERT,
+	.parent = NULL,
+	.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
+		[0] = {
+			.type = AUTH_METHOD_SIG,
+			.param.sig = {
+				.pk = &subject_pk,
+				.sig = &sig,
+				.alg = &sig_alg,
+				.data = &raw_data
+			}
+		},
+		[1] = {
+			.type = AUTH_METHOD_NV_CTR,
+			.param.nv_ctr = {
+				.cert_nv_ctr = &trusted_nv_ctr,
+				.plat_nv_ctr = &trusted_nv_ctr
+			}
+		}
+	},
+	.authenticated_data = (const auth_param_desc_t[COT_MAX_VERIFIED_PARAMS]) {
+		[0] = {
+			.type_desc = &tb_fw_hash,
+			.data = {
+				.ptr = (void *)tb_fw_hash_buf,
+				.len = (unsigned int)HASH_DER_LEN
+			}
+		},
+		[1] = {
+			.type_desc = &tb_fw_config_hash,
+			.data = {
+				.ptr = (void *)tb_fw_config_hash_buf,
+				.len = (unsigned int)HASH_DER_LEN
+			}
+		},
+		[2] = {
+			.type_desc = &fw_config_hash,
+			.data = {
+				.ptr = (void *)fw_config_hash_buf,
+				.len = (unsigned int)HASH_DER_LEN
+			}
+		},
+		[3] = {
+			.type_desc = &hw_config_hash,
+			.data = {
+				.ptr = (void *)hw_config_hash_buf,
+				.len = (unsigned int)HASH_DER_LEN
+			}
+		},
+		[4] = {
+			.type_desc = &soc_fw_hash,
+			.data = {
+				.ptr = (void *)soc_fw_hash_buf,
+				.len = (unsigned int)HASH_DER_LEN
+			}
+		},
+		[5] = {
+			.type_desc = &soc_fw_config_hash,
+			.data = {
+				.ptr = (void *)soc_fw_config_hash_buf,
+				.len = (unsigned int)HASH_DER_LEN
+			}
+		},
+		[6] = {
+			.type_desc = &rmm_hash,
+			.data = {
+				.ptr = (void *)rmm_hash_buf,
+				.len = (unsigned int)HASH_DER_LEN
+			}
+		}
+	}
+};
+
+#ifdef IMAGE_BL1
+static const auth_img_desc_t bl2_image = {
+	.img_id = BL2_IMAGE_ID,
+	.img_type = IMG_RAW,
+	.parent = &cca_content_cert,
+	.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
+		[0] = {
+			.type = AUTH_METHOD_HASH,
+			.param.hash = {
+				.data = &raw_data,
+				.hash = &tb_fw_hash
+			}
+		}
+	}
+};
+
+static const auth_img_desc_t tb_fw_config = {
+	.img_id = TB_FW_CONFIG_ID,
+	.img_type = IMG_RAW,
+	.parent = &cca_content_cert,
+	.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
+		[0] = {
+			.type = AUTH_METHOD_HASH,
+			.param.hash = {
+				.data = &raw_data,
+				.hash = &tb_fw_config_hash
+			}
+		}
+	}
+};
+
+static const auth_img_desc_t fw_config = {
+	.img_id = FW_CONFIG_ID,
+	.img_type = IMG_RAW,
+	.parent = &cca_content_cert,
+	.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
+		[0] = {
+			.type = AUTH_METHOD_HASH,
+			.param.hash = {
+				.data = &raw_data,
+				.hash = &fw_config_hash
+			}
+		}
+	}
+};
+#endif /* IMAGE_BL1 */
+
+#ifdef IMAGE_BL2
+/* HW Config */
+static const auth_img_desc_t hw_config = {
+	.img_id = HW_CONFIG_ID,
+	.img_type = IMG_RAW,
+	.parent = &cca_content_cert,
+	.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
+		[0] = {
+			.type = AUTH_METHOD_HASH,
+			.param.hash = {
+				.data = &raw_data,
+				.hash = &hw_config_hash
+			}
+		}
+	}
+};
+
+/* BL31 */
+static const auth_img_desc_t bl31_image = {
+	.img_id = BL31_IMAGE_ID,
+	.img_type = IMG_RAW,
+	.parent = &cca_content_cert,
+	.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
+		[0] = {
+			.type = AUTH_METHOD_HASH,
+			.param.hash = {
+				.data = &raw_data,
+				.hash = &soc_fw_hash
+			}
+		}
+	}
+};
+
+/* BL31 Config */
+static const auth_img_desc_t soc_fw_config = {
+	.img_id = SOC_FW_CONFIG_ID,
+	.img_type = IMG_RAW,
+	.parent = &cca_content_cert,
+	.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
+		[0] = {
+			.type = AUTH_METHOD_HASH,
+			.param.hash = {
+				.data = &raw_data,
+				.hash = &soc_fw_config_hash
+			}
+		}
+	}
+};
+
+/* RMM */
+static const auth_img_desc_t rmm_image = {
+	.img_id = RMM_IMAGE_ID,
+	.img_type = IMG_RAW,
+	.parent = &cca_content_cert,
+	.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
+		[0] = {
+			.type = AUTH_METHOD_HASH,
+			.param.hash = {
+				.data = &raw_data,
+				.hash = &rmm_hash
+			}
+		}
+	}
+};
+
+/* Core SWD Key Certificate */
+static const auth_img_desc_t core_swd_key_cert = {
+	.img_id = CORE_SWD_KEY_CERT_ID,
+	.img_type = IMG_CERT,
+	.parent = NULL, /* SWD ROOT CERT */
+	.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
+		[0] = {
+			.type = AUTH_METHOD_SIG,
+			.param.sig = {
+				.pk = &swd_rot_pk,
+				.sig = &sig,
+				.alg = &sig_alg,
+				.data = &raw_data
+			}
+		},
+		[1] = {
+			.type = AUTH_METHOD_NV_CTR,
+			.param.nv_ctr = {
+				.cert_nv_ctr = &trusted_nv_ctr,
+				.plat_nv_ctr = &trusted_nv_ctr
+			}
+		}
+	},
+	.authenticated_data = (const auth_param_desc_t[COT_MAX_VERIFIED_PARAMS]) {
+		[0] = {
+			.type_desc = &core_swd_pk,
+			.data = {
+				.ptr = (void *)core_swd_pk_buf,
+				.len = (unsigned int)PK_DER_LEN
+			}
+		}
+	}
+};
+
+/* SPMC Content Certificate */
+static const auth_img_desc_t trusted_os_fw_content_cert = {
+	.img_id = TRUSTED_OS_FW_CONTENT_CERT_ID,
+	.img_type = IMG_CERT,
+	.parent = &core_swd_key_cert,
+	.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
+		[0] = {
+			.type = AUTH_METHOD_SIG,
+			.param.sig = {
+				.pk = &core_swd_pk,
+				.sig = &sig,
+				.alg = &sig_alg,
+				.data = &raw_data
+			}
+		},
+		[1] = {
+			.type = AUTH_METHOD_NV_CTR,
+			.param.nv_ctr = {
+				.cert_nv_ctr = &trusted_nv_ctr,
+				.plat_nv_ctr = &trusted_nv_ctr
+			}
+		}
+	},
+	.authenticated_data = (const auth_param_desc_t[COT_MAX_VERIFIED_PARAMS]) {
+		[0] = {
+			.type_desc = &tos_fw_hash,
+			.data = {
+				.ptr = (void *)tos_fw_hash_buf,
+				.len = (unsigned int)HASH_DER_LEN
+			}
+		},
+		[1] = {
+			.type_desc = &tos_fw_config_hash,
+			.data = {
+				.ptr = (void *)tos_fw_config_hash_buf,
+				.len = (unsigned int)HASH_DER_LEN
+			}
+		}
+	}
+};
+
+/* SPMC */
+static const auth_img_desc_t bl32_image = {
+	.img_id = BL32_IMAGE_ID,
+	.img_type = IMG_RAW,
+	.parent = &trusted_os_fw_content_cert,
+	.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
+		[0] = {
+			.type = AUTH_METHOD_HASH,
+			.param.hash = {
+				.data = &raw_data,
+				.hash = &tos_fw_hash
+			}
+		}
+	}
+};
+
+/* SPM Config */
+static const auth_img_desc_t tos_fw_config = {
+	.img_id = TOS_FW_CONFIG_ID,
+	.img_type = IMG_RAW,
+	.parent = &trusted_os_fw_content_cert,
+	.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
+		[0] = {
+			.type = AUTH_METHOD_HASH,
+			.param.hash = {
+				.data = &raw_data,
+				.hash = &tos_fw_config_hash
+			}
+		}
+	}
+};
+
+/* Platform Key Certificate */
+static const auth_img_desc_t plat_key_cert = {
+	.img_id = PLAT_KEY_CERT_ID,
+	.img_type = IMG_CERT,
+	.parent = NULL, /* PLATFORM ROOT CERT */
+	.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
+		[0] = {
+			.type = AUTH_METHOD_SIG,
+			.param.sig = {
+				.pk = &prot_pk,
+				.sig = &sig,
+				.alg = &sig_alg,
+				.data = &raw_data
+			}
+		},
+		[1] = {
+			.type = AUTH_METHOD_NV_CTR,
+			.param.nv_ctr = {
+				.cert_nv_ctr = &non_trusted_nv_ctr,
+				.plat_nv_ctr = &non_trusted_nv_ctr
+			}
+		}
+	},
+	.authenticated_data = (const auth_param_desc_t[COT_MAX_VERIFIED_PARAMS]) {
+		[0] = {
+			.type_desc = &plat_pk,
+			.data = {
+				.ptr = (void *)plat_pk_buf,
+				.len = (unsigned int)PK_DER_LEN
+			}
+		}
+	}
+};
+
+/* Non-Trusted Firmware */
+static const auth_img_desc_t non_trusted_fw_content_cert = {
+	.img_id = NON_TRUSTED_FW_CONTENT_CERT_ID,
+	.img_type = IMG_CERT,
+	.parent = &plat_key_cert,
+	.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
+		[0] = {
+			.type = AUTH_METHOD_SIG,
+			.param.sig = {
+				.pk = &plat_pk,
+				.sig = &sig,
+				.alg = &sig_alg,
+				.data = &raw_data
+			}
+		},
+		[1] = {
+			.type = AUTH_METHOD_NV_CTR,
+			.param.nv_ctr = {
+				.cert_nv_ctr = &non_trusted_nv_ctr,
+				.plat_nv_ctr = &non_trusted_nv_ctr
+			}
+		}
+	},
+	.authenticated_data = (const auth_param_desc_t[COT_MAX_VERIFIED_PARAMS]) {
+		[0] = {
+			.type_desc = &nt_world_bl_hash,
+			.data = {
+				.ptr = (void *)nt_world_bl_hash_buf,
+				.len = (unsigned int)HASH_DER_LEN
+			}
+		},
+		[1] = {
+			.type_desc = &nt_fw_config_hash,
+			.data = {
+				.ptr = (void *)nt_fw_config_hash_buf,
+				.len = (unsigned int)HASH_DER_LEN
+			}
+		}
+	}
+};
+
+static const auth_img_desc_t bl33_image = {
+	.img_id = BL33_IMAGE_ID,
+	.img_type = IMG_RAW,
+	.parent = &non_trusted_fw_content_cert,
+	.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
+		[0] = {
+			.type = AUTH_METHOD_HASH,
+			.param.hash = {
+				.data = &raw_data,
+				.hash = &nt_world_bl_hash
+			}
+		}
+	}
+};
+
+/* NT FW Config */
+static const auth_img_desc_t nt_fw_config = {
+	.img_id = NT_FW_CONFIG_ID,
+	.img_type = IMG_RAW,
+	.parent = &non_trusted_fw_content_cert,
+	.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
+		[0] = {
+			.type = AUTH_METHOD_HASH,
+			.param.hash = {
+				.data = &raw_data,
+				.hash = &nt_fw_config_hash
+			}
+		}
+	}
+};
+
+/*
+ * Secure Partitions
+ */
+#if defined(SPD_spmd)
+static const auth_img_desc_t sip_sp_content_cert = {
+	.img_id = SIP_SP_CONTENT_CERT_ID,
+	.img_type = IMG_CERT,
+	.parent = &core_swd_key_cert,
+	.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
+		[0] = {
+			.type = AUTH_METHOD_SIG,
+			.param.sig = {
+				.pk = &core_swd_pk,
+				.sig = &sig,
+				.alg = &sig_alg,
+				.data = &raw_data
+			}
+		},
+		[1] = {
+			.type = AUTH_METHOD_NV_CTR,
+			.param.nv_ctr = {
+				.cert_nv_ctr = &trusted_nv_ctr,
+				.plat_nv_ctr = &trusted_nv_ctr
+			}
+		}
+	},
+	.authenticated_data = (const auth_param_desc_t[COT_MAX_VERIFIED_PARAMS]) {
+		[0] = {
+			.type_desc = &sp_pkg1_hash,
+			.data = {
+				.ptr = (void *)sp_pkg_hash_buf[0],
+				.len = (unsigned int)HASH_DER_LEN
+			}
+		},
+		[1] = {
+			.type_desc = &sp_pkg2_hash,
+			.data = {
+				.ptr = (void *)sp_pkg_hash_buf[1],
+				.len = (unsigned int)HASH_DER_LEN
+			}
+		},
+		[2] = {
+			.type_desc = &sp_pkg3_hash,
+			.data = {
+				.ptr = (void *)sp_pkg_hash_buf[2],
+				.len = (unsigned int)HASH_DER_LEN
+			}
+		},
+		[3] = {
+			.type_desc = &sp_pkg4_hash,
+			.data = {
+				.ptr = (void *)sp_pkg_hash_buf[3],
+				.len = (unsigned int)HASH_DER_LEN
+			}
+		}
+	}
+};
+
+DEFINE_SIP_SP_PKG(1);
+DEFINE_SIP_SP_PKG(2);
+DEFINE_SIP_SP_PKG(3);
+DEFINE_SIP_SP_PKG(4);
+
+static const auth_img_desc_t plat_sp_content_cert = {
+	.img_id = PLAT_SP_CONTENT_CERT_ID,
+	.img_type = IMG_CERT,
+	.parent = &plat_key_cert,
+	.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
+		[0] = {
+			.type = AUTH_METHOD_SIG,
+			.param.sig = {
+				.pk = &plat_pk,
+				.sig = &sig,
+				.alg = &sig_alg,
+				.data = &raw_data
+			}
+		},
+		[1] = {
+			.type = AUTH_METHOD_NV_CTR,
+			.param.nv_ctr = {
+				.cert_nv_ctr = &non_trusted_nv_ctr,
+				.plat_nv_ctr = &non_trusted_nv_ctr
+			}
+		}
+	},
+	.authenticated_data = (const auth_param_desc_t[COT_MAX_VERIFIED_PARAMS]) {
+		[0] = {
+			.type_desc = &sp_pkg5_hash,
+			.data = {
+				.ptr = (void *)sp_pkg_hash_buf[4],
+				.len = (unsigned int)HASH_DER_LEN
+			}
+		},
+		[1] = {
+			.type_desc = &sp_pkg6_hash,
+			.data = {
+				.ptr = (void *)sp_pkg_hash_buf[5],
+				.len = (unsigned int)HASH_DER_LEN
+			}
+		},
+		[2] = {
+			.type_desc = &sp_pkg7_hash,
+			.data = {
+				.ptr = (void *)sp_pkg_hash_buf[6],
+				.len = (unsigned int)HASH_DER_LEN
+			}
+		},
+		[3] = {
+			.type_desc = &sp_pkg8_hash,
+			.data = {
+				.ptr = (void *)sp_pkg_hash_buf[7],
+				.len = (unsigned int)HASH_DER_LEN
+			}
+		}
+	}
+};
+
+DEFINE_PLAT_SP_PKG(5);
+DEFINE_PLAT_SP_PKG(6);
+DEFINE_PLAT_SP_PKG(7);
+DEFINE_PLAT_SP_PKG(8);
+#endif /* SPD_spmd */
+#endif /* IMAGE_BL2 */
+/*
+ * Chain of trust definition
+ */
+#ifdef IMAGE_BL1
+static const auth_img_desc_t * const cot_desc[] = {
+	[CCA_CONTENT_CERT_ID]			=	&cca_content_cert,
+	[BL2_IMAGE_ID]				=	&bl2_image,
+	[TB_FW_CONFIG_ID]			=	&tb_fw_config,
+	[FW_CONFIG_ID]				=	&fw_config,
+};
+#else /* IMAGE_BL2 */
+static const auth_img_desc_t * const cot_desc[] = {
+	[CCA_CONTENT_CERT_ID]			=	&cca_content_cert,
+	[HW_CONFIG_ID]				=	&hw_config,
+	[BL31_IMAGE_ID]				=	&bl31_image,
+	[SOC_FW_CONFIG_ID]			=	&soc_fw_config,
+	[RMM_IMAGE_ID]				=	&rmm_image,
+	[CORE_SWD_KEY_CERT_ID]			=	&core_swd_key_cert,
+	[TRUSTED_OS_FW_CONTENT_CERT_ID]		=	&trusted_os_fw_content_cert,
+	[BL32_IMAGE_ID]				=	&bl32_image,
+	[TOS_FW_CONFIG_ID]			=	&tos_fw_config,
+	[PLAT_KEY_CERT_ID]			=	&plat_key_cert,
+	[NON_TRUSTED_FW_CONTENT_CERT_ID]	=	&non_trusted_fw_content_cert,
+	[BL33_IMAGE_ID]				=	&bl33_image,
+	[NT_FW_CONFIG_ID]			=	&nt_fw_config,
+#if defined(SPD_spmd)
+	[SIP_SP_CONTENT_CERT_ID]		=	&sip_sp_content_cert,
+	[PLAT_SP_CONTENT_CERT_ID]		=	&plat_sp_content_cert,
+	[SP_PKG1_ID]				=	&sp_pkg1,
+	[SP_PKG2_ID]				=	&sp_pkg2,
+	[SP_PKG3_ID]				=	&sp_pkg3,
+	[SP_PKG4_ID]				=	&sp_pkg4,
+	[SP_PKG5_ID]				=	&sp_pkg5,
+	[SP_PKG6_ID]				=	&sp_pkg6,
+	[SP_PKG7_ID]				=	&sp_pkg7,
+	[SP_PKG8_ID]				=       &sp_pkg8,
+#endif
+};
+#endif /* IMAGE_BL1 */
+
+/* Register the CoT in the authentication module */
+REGISTER_COT(cot_desc);
diff --git a/drivers/auth/mbedtls/mbedtls_common.mk b/drivers/auth/mbedtls/mbedtls_common.mk
index 3eb4161..16ce65f 100644
--- a/drivers/auth/mbedtls/mbedtls_common.mk
+++ b/drivers/auth/mbedtls/mbedtls_common.mk
@@ -97,18 +97,6 @@
     TF_MBEDTLS_USE_AES_GCM	:=	0
 endif
 
-ifeq ($(MEASURED_BOOT),1)
-    ifeq (${TPM_HASH_ALG}, sha256)
-        TF_MBEDTLS_TPM_HASH_ALG_ID	:=	TF_MBEDTLS_SHA256
-    else ifeq (${TPM_HASH_ALG}, sha384)
-        TF_MBEDTLS_TPM_HASH_ALG_ID	:=	TF_MBEDTLS_SHA384
-    else ifeq (${TPM_HASH_ALG}, sha512)
-        TF_MBEDTLS_TPM_HASH_ALG_ID	:=	TF_MBEDTLS_SHA512
-    else
-        $(error "TPM_HASH_ALG not defined.")
-    endif
-endif
-
 # Needs to be set to drive mbed TLS configuration correctly
 $(eval $(call add_defines,\
     $(sort \
@@ -118,10 +106,6 @@
         TF_MBEDTLS_USE_AES_GCM \
 )))
 
-ifeq ($(MEASURED_BOOT),1)
-  $(eval $(call add_define,TF_MBEDTLS_TPM_HASH_ALG_ID))
-endif
-
 $(eval $(call MAKE_LIB,mbedtls))
 
 endif
diff --git a/drivers/measured_boot/event_log/event_log.c b/drivers/measured_boot/event_log/event_log.c
index 792f235..abe469b 100644
--- a/drivers/measured_boot/event_log/event_log.c
+++ b/drivers/measured_boot/event_log/event_log.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020-2021, Arm Limited. All rights reserved.
+ * Copyright (c) 2020-2022, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -180,6 +180,8 @@
 
 	/* event_log_init() must have been called prior to this. */
 	assert(log_ptr != NULL);
+	assert(((uintptr_t)log_ptr + ID_EVENT_SIZE + LOC_EVENT_SIZE) <
+		log_end);
 
 	/*
 	 * Add Specification ID Event first
@@ -219,7 +221,7 @@
 	((tpmt_ha *)ptr)->algorithm_id = TPM_ALG_ID;
 
 	/* TCG_PCR_EVENT2.Digests[].Digest[] */
-	(void)memset(&((tpmt_ha *)ptr)->digest, 0, TPM_ALG_ID);
+	(void)memset(&((tpmt_ha *)ptr)->digest, 0, TCG_DIGEST_SIZE);
 	ptr = (uint8_t *)((uintptr_t)ptr +
 			offsetof(tpmt_ha, digest) + TCG_DIGEST_SIZE);
 
diff --git a/drivers/measured_boot/event_log/event_log.mk b/drivers/measured_boot/event_log/event_log.mk
index 1ff4aa8..5ea4c55 100644
--- a/drivers/measured_boot/event_log/event_log.mk
+++ b/drivers/measured_boot/event_log/event_log.mk
@@ -7,20 +7,25 @@
 # Default log level to dump the event log (LOG_LEVEL_INFO)
 EVENT_LOG_LEVEL         ?= 40
 
-# TPM hash algorithm.
+# Measured Boot hash algorithm.
 # SHA-256 (or stronger) is required for all devices that are TPM 2.0 compliant.
-TPM_HASH_ALG			:=	sha256
+ifdef TPM_HASH_ALG
+    $(warning "TPM_HASH_ALG is deprecated. Please use MBOOT_EL_HASH_ALG instead.")
+    MBOOT_EL_HASH_ALG		:=	${TPM_HASH_ALG}
+else
+    MBOOT_EL_HASH_ALG		:=	sha256
+endif
 
-ifeq (${TPM_HASH_ALG}, sha512)
+ifeq (${MBOOT_EL_HASH_ALG}, sha512)
     TPM_ALG_ID			:=	TPM_ALG_SHA512
     TCG_DIGEST_SIZE		:=	64U
-else ifeq (${TPM_HASH_ALG}, sha384)
+else ifeq (${MBOOT_EL_HASH_ALG}, sha384)
     TPM_ALG_ID			:=	TPM_ALG_SHA384
     TCG_DIGEST_SIZE		:=	48U
 else
     TPM_ALG_ID			:=	TPM_ALG_SHA256
     TCG_DIGEST_SIZE		:=	32U
-endif #TPM_HASH_ALG
+endif #MBOOT_EL_HASH_ALG
 
 # Set definitions for Measured Boot driver.
 $(eval $(call add_defines,\
diff --git a/drivers/measured_boot/rss/rss_measured_boot.mk b/drivers/measured_boot/rss/rss_measured_boot.mk
index 01545af..18ee836 100644
--- a/drivers/measured_boot/rss/rss_measured_boot.mk
+++ b/drivers/measured_boot/rss/rss_measured_boot.mk
@@ -6,21 +6,18 @@
 
 # Hash algorithm for measured boot
 # SHA-256 (or stronger) is required.
-# TODO: The measurement algorithm incorrectly suggests that the TPM backend
-#       is used which may not be the case. It is currently being worked on and
-#       soon TPM_HASH_ALG will be replaced by a more generic name.
-TPM_HASH_ALG			:=	sha256
+MBOOT_RSS_HASH_ALG		:=	sha256
 
-ifeq (${TPM_HASH_ALG}, sha512)
+ifeq (${MBOOT_RSS_HASH_ALG}, sha512)
     MBOOT_ALG_ID		:=	MBOOT_ALG_SHA512
     MBOOT_DIGEST_SIZE		:=	64U
-else ifeq (${TPM_HASH_ALG}, sha384)
+else ifeq (${MBOOT_RSS_HASH_ALG}, sha384)
     MBOOT_ALG_ID		:=	MBOOT_ALG_SHA384
     MBOOT_DIGEST_SIZE		:=	48U
 else
     MBOOT_ALG_ID		:=	MBOOT_ALG_SHA256
     MBOOT_DIGEST_SIZE		:=	32U
-endif #TPM_HASH_ALG
+endif #MBOOT_RSS_HASH_ALG
 
 # Set definitions for Measured Boot driver.
 $(eval $(call add_defines,\
diff --git a/drivers/nxp/ddr/phy-gen2/phy.c b/drivers/nxp/ddr/phy-gen2/phy.c
index c8245a8..9e52145 100644
--- a/drivers/nxp/ddr/phy-gen2/phy.c
+++ b/drivers/nxp/ddr/phy-gen2/phy.c
@@ -2216,14 +2216,6 @@
 
 	size = PHY_GEN2_MAX_IMAGE_SIZE;
 	image_buf = (uintptr_t)phy_gen2_fw_img_buf;
-	ret = mmap_add_dynamic_region(phy_gen2_fw_img_buf,
-			phy_gen2_fw_img_buf,
-			PHY_GEN2_MAX_IMAGE_SIZE,
-			MT_MEMORY | MT_RW | MT_SECURE);
-	if (ret != 0) {
-		ERROR("Failed to add dynamic memory region.\n");
-		return ret;
-	}
 	ret = img_loadr(imem_id, &image_buf, &size);
 	if (ret != 0) {
 		ERROR("Failed to load %d firmware.\n", imem_id);
@@ -2592,6 +2584,15 @@
 		}
 	} else {
 #endif
+		/* Mapping IMG buffer firstly */
+		ret = mmap_add_dynamic_region(priv->phy_gen2_fw_img_buf,
+			priv->phy_gen2_fw_img_buf,
+			PHY_GEN2_MAX_IMAGE_SIZE,
+			MT_MEMORY | MT_RW | MT_SECURE);
+		if (ret != 0) {
+			ERROR("Failed to add dynamic memory region.\n");
+			return ret;
+		}
 
 		debug("Load 1D firmware\n");
 		ret = load_fw(priv->phy, &input, 0, &msg_1d,
diff --git a/include/common/tbbr/cot_def.h b/include/common/tbbr/cot_def.h
index 800ad07..e0c2212 100644
--- a/include/common/tbbr/cot_def.h
+++ b/include/common/tbbr/cot_def.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2022, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -14,6 +14,8 @@
 /* TBBR CoT definitions */
 #if defined(SPD_spmd)
 #define COT_MAX_VERIFIED_PARAMS		8
+#elif defined(ARM_COT_cca)
+#define COT_MAX_VERIFIED_PARAMS		8
 #else
 #define COT_MAX_VERIFIED_PARAMS		4
 #endif
diff --git a/include/drivers/auth/mbedtls/mbedtls_config.h b/include/drivers/auth/mbedtls/mbedtls_config.h
index 8ad6d7a..01e261a 100644
--- a/include/drivers/auth/mbedtls/mbedtls_config.h
+++ b/include/drivers/auth/mbedtls/mbedtls_config.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2021, Arm Limited. All rights reserved.
+ * Copyright (c) 2015-2022, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -80,8 +80,7 @@
 #define	MBEDTLS_SHA512_C
 #else
    /* TBB uses SHA-256, what about measured boot? */
-#if defined(TF_MBEDTLS_TPM_HASH_ALG_ID) && \
-	(TF_MBEDTLS_TPM_HASH_ALG_ID != TF_MBEDTLS_SHA256)
+#if defined(TF_MBEDTLS_MBOOT_USE_SHA512)
 #define MBEDTLS_SHA512_C
 #endif
 #endif
@@ -141,4 +140,13 @@
 #endif
 #endif
 
+/*
+ * Warn if errors from certain functions are ignored.
+ *
+ * The warnings are always enabled (where supported) for critical functions
+ * where ignoring the return value is almost always a bug. This macro extends
+ * the warnings to more functions.
+ */
+#define MBEDTLS_CHECK_RETURN_WARNING
+
 #endif /* MBEDTLS_CONFIG_H */
diff --git a/include/export/common/tbbr/tbbr_img_def_exp.h b/include/export/common/tbbr/tbbr_img_def_exp.h
index 98544c0..98a0099 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-2021, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2019-2022, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -104,7 +104,16 @@
 /* Realm Monitor Manager (RMM) */
 #define RMM_IMAGE_ID			U(34)
 
+/* CCA Content Certificate ID */
+#define CCA_CONTENT_CERT_ID		U(35)
+
+/* Core SWD Key Certificate ID */
+#define CORE_SWD_KEY_CERT_ID		U(36)
+
+/* Platform Key Certificate ID */
+#define PLAT_KEY_CERT_ID		U(37)
+
 /* Max Images */
-#define MAX_IMAGE_IDS			U(35)
+#define MAX_IMAGE_IDS			U(38)
 
 #endif /* ARM_TRUSTED_FIRMWARE_EXPORT_COMMON_TBBR_TBBR_IMG_DEF_EXP_H */
diff --git a/include/tools_share/cca_oid.h b/include/tools_share/cca_oid.h
new file mode 100644
index 0000000..e586b8c
--- /dev/null
+++ b/include/tools_share/cca_oid.h
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2022, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef CCA_OID_H
+#define CCA_OID_H
+
+/* Reuse the Object IDs defined by TBBR for certificate extensions. */
+#include "tbbr_oid.h"
+
+/*
+ * Assign arbitrary Object ID values that do not conflict with any of the
+ * TBBR reserved OIDs.
+ */
+/* Platform root-of-trust public key */
+#define PROT_PK_OID				"1.3.6.1.4.1.4128.2100.1102"
+/* Secure World root-of-trust public key */
+#define SWD_ROT_PK_OID				"1.3.6.1.4.1.4128.2100.1103"
+/* Core Secure World public key */
+#define CORE_SWD_PK_OID				"1.3.6.1.4.1.4128.2100.1104"
+/* Platform public key */
+#define PLAT_PK_OID				"1.3.6.1.4.1.4128.2100.1105"
+/* Realm Monitor Manager (RMM) Hash */
+#define RMM_HASH_OID				"1.3.6.1.4.1.4128.2100.1106"
+
+#endif /* CCA_OID_H */
diff --git a/include/tools_share/firmware_image_package.h b/include/tools_share/firmware_image_package.h
index bd5b14b..b73eec7 100644
--- a/include/tools_share/firmware_image_package.h
+++ b/include/tools_share/firmware_image_package.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014-2021, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2014-2022, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -24,6 +24,12 @@
 	{{0x4f, 0x51, 0x1d, 0x11}, {0x2b, 0xe5}, {0x4e, 0x49}, 0xb4, 0xc5, {0x83, 0xc2, 0xf7, 0x15, 0x84, 0x0a} }
 #define UUID_TRUSTED_FWU_CERT \
 	{{0x71, 0x40, 0x8a, 0xb2}, {0x18, 0xd6}, {0x87, 0x4c}, 0x8b, 0x2e, {0xc6, 0xdc, 0xcd, 0x50, 0xf0, 0x96} }
+#define UUID_CCA_CONTENT_CERT \
+	{{0x36,  0xd8, 0x3d, 0x85}, {0x76, 0x1d}, {0x4d, 0xaf}, 0x96, 0xf1, {0xcd, 0x99, 0xd6, 0x56, 0x9b, 0x00} }
+#define UUID_CORE_SWD_KEY_CERT \
+	{{0x52,  0x22, 0x2d, 0x31}, {0x82, 0x0f}, {0x49, 0x4d}, 0x8b, 0xbc, {0xea, 0x68, 0x25, 0xd3, 0xc3, 0x5a} }
+#define UUID_PLAT_KEY_CERT \
+	{{0xd4,  0x3c, 0xd9, 0x02}, {0x5b, 0x9f}, {0x41, 0x2e}, 0x8a, 0xc6, {0x92, 0xb6, 0xd1, 0x8b, 0xe6, 0x0d} }
 #define UUID_TRUSTED_BOOT_FIRMWARE_BL2 \
 	{{0x5f, 0xf9, 0xec, 0x0b}, {0x4d, 0x22}, {0x3e, 0x4d}, 0xa5, 0x44, {0xc3, 0x9d, 0x81, 0xc7, 0x3f, 0x0a} }
 #define UUID_SCP_FIRMWARE_SCP_BL2 \
diff --git a/lib/optee/optee_utils.c b/lib/optee/optee_utils.c
index 72979cd..d30248f 100644
--- a/lib/optee/optee_utils.c
+++ b/lib/optee/optee_utils.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2021, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2022, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -192,8 +192,17 @@
 				&header->optee_image_list[num]);
 		} else if (header->optee_image_list[num].image_id ==
 				OPTEE_PAGED_IMAGE_ID) {
-			ret = parse_optee_image(paged_image_info,
-				&header->optee_image_list[num]);
+			if (paged_image_info == NULL) {
+				if (header->optee_image_list[num].size != 0U) {
+					ERROR("Paged image is not supported\n");
+					return -1;
+				}
+
+				continue;
+			} else {
+				ret = parse_optee_image(paged_image_info,
+							&header->optee_image_list[num]);
+			}
 		} else {
 			ERROR("Parse optee image failed.\n");
 			return -1;
@@ -215,8 +224,10 @@
 	 * header image arguments so that can be read by the
 	 * BL32 SPD.
 	 */
-	header_ep->args.arg1 = paged_image_info->image_base;
-	header_ep->args.arg2 = paged_image_info->image_size;
+	if (paged_image_info != NULL) {
+		header_ep->args.arg1 = paged_image_info->image_base;
+		header_ep->args.arg2 = paged_image_info->image_size;
+	}
 
 	/* Set OPTEE runtime arch - aarch32/aarch64 */
 	if (header->arch == 0) {
diff --git a/lib/psa/measured_boot.c b/lib/psa/measured_boot.c
index 693e01f..90e4ef3 100644
--- a/lib/psa/measured_boot.c
+++ b/lib/psa/measured_boot.c
@@ -14,8 +14,9 @@
 
 #include "measured_boot_private.h"
 
-static void print_byte_array(const uint8_t *array, size_t len)
+static void print_byte_array(const uint8_t *array __unused, size_t len __unused)
 {
+#if LOG_LEVEL >= LOG_LEVEL_INFO
 	size_t i;
 
 	if (array == NULL || len == 0U) {
@@ -31,6 +32,7 @@
 			}
 		}
 	}
+#endif
 }
 
 static void log_measurement(uint8_t index,
diff --git a/make_helpers/tbbr/tbbr_tools.mk b/make_helpers/tbbr/tbbr_tools.mk
index 0a280b4..5ef2d85 100644
--- a/make_helpers/tbbr/tbbr_tools.mk
+++ b/make_helpers/tbbr/tbbr_tools.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2015-2021, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2015-2022, ARM Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -25,6 +25,9 @@
 #   KEY_SIZE
 #   ROT_KEY
 #   PROT_KEY
+#   PLAT_KEY
+#   SWD_ROT_KEY
+#   CORE_SWD_KEY
 #   TRUSTED_WORLD_KEY
 #   NON_TRUSTED_WORLD_KEY
 #   SCP_BL2_KEY
@@ -46,10 +49,18 @@
 $(eval $(call CERT_ADD_CMD_OPT,${NTFW_NVCTR_VAL},--ntfw-nvctr))
 
 # Add Trusted Key certificate to the fiptool and cert_create command line options
+ifneq (${COT},cca)
 $(eval $(call TOOL_ADD_PAYLOAD,${TRUSTED_KEY_CERT},--trusted-key-cert))
+else
+$(eval $(call TOOL_ADD_PAYLOAD,${BUILD_PLAT}/cca.crt,--cca-cert))
+$(eval $(call TOOL_ADD_PAYLOAD,${BUILD_PLAT}/core-swd.crt,--core-swd-cert))
+$(eval $(call TOOL_ADD_PAYLOAD,${BUILD_PLAT}/plat-key.crt,--plat-key-cert))
+endif
 
 # Add fwu certificate to the fiptool and cert_create command line options
+ifneq (${COT},cca)
 $(eval $(call TOOL_ADD_PAYLOAD,${FWU_CERT},--fwu-cert,,FWU_))
+endif
 
 # Add the keys to the cert_create command line options (private keys are NOT
 # packed in the FIP). Developers can use their own keys by specifying the proper
@@ -63,6 +74,9 @@
 $(if ${ROT_KEY},$(eval $(call CERT_ADD_CMD_OPT,${ROT_KEY},--rot-key)))
 $(if ${ROT_KEY},$(eval $(call CERT_ADD_CMD_OPT,${ROT_KEY},--rot-key,FWU_)))
 $(if ${PROT_KEY},$(eval $(call CERT_ADD_CMD_OPT,${PROT_KEY},--prot-key)))
+$(if ${PLAT_KEY},$(eval $(call CERT_ADD_CMD_OPT,${PLAT_KEY},--plat-key)))
+$(if ${SWD_ROT_KEY},$(eval $(call CERT_ADD_CMD_OPT,${SWD_ROT_KEY},--swd-rot-key)))
+$(if ${CORE_SWD_KEY},$(eval $(call CERT_ADD_CMD_OPT,${CORE_SWD_KEY},--core-swd-key)))
 $(if ${TRUSTED_WORLD_KEY},$(eval $(call CERT_ADD_CMD_OPT,${TRUSTED_WORLD_KEY},--trusted-world-key)))
 $(if ${NON_TRUSTED_WORLD_KEY},$(eval $(call CERT_ADD_CMD_OPT,${NON_TRUSTED_WORLD_KEY},--non-trusted-world-key)))
 
@@ -70,25 +84,31 @@
 # Add the BL2 CoT (image cert)
 ifeq (${NEED_BL2},yes)
 ifeq (${BL2_AT_EL3}, 0)
+ifneq (${COT},cca)
 $(eval $(call TOOL_ADD_PAYLOAD,${BUILD_PLAT}/tb_fw.crt,--tb-fw-cert))
 endif
 endif
+endif
 
 # Add the SCP_BL2 CoT (key cert + img cert)
 ifneq (${SCP_BL2},)
+ifneq (${COT},cca)
     $(if ${SCP_BL2_KEY},$(eval $(call CERT_ADD_CMD_OPT,${SCP_BL2_KEY},--scp-fw-key)))
     $(eval $(call TOOL_ADD_PAYLOAD,${BUILD_PLAT}/scp_fw_content.crt,--scp-fw-cert))
     $(eval $(call TOOL_ADD_PAYLOAD,${BUILD_PLAT}/scp_fw_key.crt,--scp-fw-key-cert))
 endif
+endif
 
 ifeq (${ARCH},aarch64)
 ifeq (${NEED_BL31},yes)
 # Add the BL31 CoT (key cert + img cert)
 $(if ${BL31_KEY},$(eval $(call CERT_ADD_CMD_OPT,${BL31_KEY},--soc-fw-key)))
+ifneq (${COT},cca)
 $(eval $(call TOOL_ADD_PAYLOAD,${BUILD_PLAT}/soc_fw_content.crt,--soc-fw-cert))
 $(eval $(call TOOL_ADD_PAYLOAD,${BUILD_PLAT}/soc_fw_key.crt,--soc-fw-key-cert))
 endif
 endif
+endif
 
 # Add the BL32 CoT (key cert + img cert)
 ifeq (${NEED_BL32},yes)
@@ -102,7 +122,9 @@
     $(if ${BL33_KEY},$(eval $(call CERT_ADD_CMD_OPT,${BL33_KEY},--nt-fw-key)))
     $(eval $(call TOOL_ADD_PAYLOAD,${BUILD_PLAT}/nt_fw_content.crt,--nt-fw-cert))
 ifneq (${COT},dualroot)
-    $(eval $(call TOOL_ADD_PAYLOAD,${BUILD_PLAT}/nt_fw_key.crt,--nt-fw-key-cert))
+    ifneq (${COT},cca)
+        $(eval $(call TOOL_ADD_PAYLOAD,${BUILD_PLAT}/nt_fw_key.crt,--nt-fw-key-cert))
+    endif
 endif
 endif
 
@@ -112,4 +134,7 @@
 ifeq (${COT},dualroot)
     $(eval $(call TOOL_ADD_PAYLOAD,${BUILD_PLAT}/plat_sp_content.crt,--plat-sp-cert))
 endif
+ifeq (${COT},cca)
+    $(eval $(call TOOL_ADD_PAYLOAD,${BUILD_PLAT}/plat_sp_content.crt,--plat-sp-cert))
+endif
 endif
diff --git a/plat/arm/board/common/board_arm_trusted_boot.c b/plat/arm/board/common/board_arm_trusted_boot.c
index 66cc3e9..714c444 100644
--- a/plat/arm/board/common/board_arm_trusted_boot.c
+++ b/plat/arm/board/common/board_arm_trusted_boot.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2022, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -13,18 +13,20 @@
 #include <drivers/delay_timer.h>
 #include <lib/cassert.h>
 #include <lib/fconf/fconf.h>
-#include <plat/arm/common/plat_arm.h>
-#include <plat/arm/common/fconf_nv_cntr_getter.h>
 #include <plat/common/common_def.h>
 #include <plat/common/platform.h>
-#include <platform_def.h>
-
-#if defined(ARM_COT_tbbr)
-#include <tools_share/tbbr_oid.h>
+#if defined(ARM_COT_cca)
+#include <tools_share/cca_oid.h>
 #elif defined(ARM_COT_dualroot)
 #include <tools_share/dualroot_oid.h>
+#elif defined(ARM_COT_tbbr)
+#include <tools_share/tbbr_oid.h>
 #endif
 
+#include <plat/arm/common/fconf_nv_cntr_getter.h>
+#include <plat/arm/common/plat_arm.h>
+#include <platform_def.h>
+
 #if !ARM_CRYPTOCELL_INTEG
 #if !ARM_ROTPK_LOCATION_ID
   #error "ARM_ROTPK_LOCATION_ID not defined"
@@ -181,6 +183,40 @@
 		return 1;
 	}
 }
+
+#elif defined(ARM_COT_cca)
+
+int arm_get_rotpk_info(void *cookie, void **key_ptr, unsigned int *key_len,
+		       unsigned int *flags)
+{
+	/*
+	 * Return the right root of trust key hash based on the cookie value:
+	 *  - NULL means the primary ROTPK.
+	 *  - Otherwise, interpret cookie as the OID of the certificate
+	 *    extension containing the key.
+	 */
+	if (cookie == NULL) {
+		return get_rotpk_info(key_ptr, key_len, flags);
+	} else if (strcmp(cookie, PROT_PK_OID) == 0) {
+		extern unsigned char arm_protpk_hash[];
+		extern unsigned char arm_protpk_hash_end[];
+		*key_ptr = arm_protpk_hash;
+		*key_len = arm_protpk_hash_end - arm_protpk_hash;
+		*flags = ROTPK_IS_HASH;
+		return 0;
+	} else if (strcmp(cookie, SWD_ROT_PK_OID) == 0) {
+		extern unsigned char arm_swd_rotpk_hash[];
+		extern unsigned char arm_swd_rotpk_hash_end[];
+		*key_ptr = arm_swd_rotpk_hash;
+		*key_len = arm_swd_rotpk_hash_end - arm_swd_rotpk_hash;
+		*flags = ROTPK_IS_HASH;
+		return 0;
+	} else {
+		/* Invalid key ID. */
+		return 1;
+	}
+}
+
 #endif
 
 /*
diff --git a/plat/arm/board/common/board_common.mk b/plat/arm/board/common/board_common.mk
index 5cdf1bf..b11811c 100644
--- a/plat/arm/board/common/board_common.mk
+++ b/plat/arm/board/common/board_common.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2015-2022, ARM Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -38,6 +38,10 @@
 
 $(eval $(call add_define,ARM_ROTPK_LOCATION_ID))
 
+ifeq (${ENABLE_RME}, 1)
+COT	:=	cca
+endif
+
 # Force generation of the new hash if ROT_KEY is specified
 ifdef ROT_KEY
 	HASH_PREREQUISITES = $(ROT_KEY) FORCE
@@ -85,7 +89,32 @@
 BL2_SOURCES		+=	plat/arm/board/common/protpk/arm_dev_protpk.S
 
 $(BUILD_PLAT)/bl1/arm_dev_protpk.o: $(ARM_PROTPK_HASH)
+$(BUILD_PLAT)/bl2/arm_dev_protpk.o: $(ARM_PROTPK_HASH)
+endif
+
+ifeq (${COT},cca)
+# Platform and Secure World Root of Trust key files.
+ARM_PROT_KEY		:=	plat/arm/board/common/protpk/arm_protprivk_rsa.pem
+ARM_PROTPK_HASH		:=	plat/arm/board/common/protpk/arm_protpk_rsa_sha256.bin
+ARM_SWD_ROT_KEY		:=	plat/arm/board/common/swd_rotpk/arm_swd_rotprivk_rsa.pem
+ARM_SWD_ROTPK_HASH	:=	plat/arm/board/common/swd_rotpk/arm_swd_rotpk_rsa_sha256.bin
+
+# Provide the private keys to cert_create tool. It needs them to sign the images.
+PROT_KEY		:=	${ARM_PROT_KEY}
+SWD_ROT_KEY		:=	${ARM_SWD_ROT_KEY}
+
+$(eval $(call add_define_val,ARM_PROTPK_HASH,'"$(ARM_PROTPK_HASH)"'))
+$(eval $(call add_define_val,ARM_SWD_ROTPK_HASH,'"$(ARM_SWD_ROTPK_HASH)"'))
+
+BL1_SOURCES		+=	plat/arm/board/common/protpk/arm_dev_protpk.S \
+				plat/arm/board/common/swd_rotpk/arm_dev_swd_rotpk.S
+BL2_SOURCES		+=	plat/arm/board/common/protpk/arm_dev_protpk.S \
+				plat/arm/board/common/swd_rotpk/arm_dev_swd_rotpk.S
+
+$(BUILD_PLAT)/bl1/arm_dev_protpk.o: $(ARM_PROTPK_HASH)
+$(BUILD_PLAT)/bl1/arm_dev_swd_rotpk.o: $(ARM_SWD_ROTPK_HASH)
 $(BUILD_PLAT)/bl2/arm_dev_protpk.o: $(ARM_PROTPK_HASH)
+$(BUILD_PLAT)/bl2/arm_dev_swd_rotpk.o: $(ARM_SWD_ROTPK_HASH)
 endif
 
 endif
diff --git a/plat/arm/board/common/swd_rotpk/README b/plat/arm/board/common/swd_rotpk/README
new file mode 100644
index 0000000..b628a5f
--- /dev/null
+++ b/plat/arm/board/common/swd_rotpk/README
@@ -0,0 +1,14 @@
+This directory contains some development keys to be used as the secure world
+root-of-trust key used in the CCA chain of trust.
+
+* swd_rotprivk_rsa.pem is a 2K RSA private key in PEM format. It has been
+  generated using the openssl command line tool:
+
+  openssl genrsa 2048 > arm_swd_rotprivk_rsa.pem
+
+* swd_rotpk_rsa_sha256.bin is the SHA-256 hash of the DER-encoded public key
+  associated with the above private key. It has been generated using the openssl
+  command line tool:
+
+  openssl rsa -in arm_swd_rotprivk_rsa.pem -pubout -outform DER | \
+    openssl dgst -sha256 -binary > arm_swd_rotpk_rsa_sha256.bin
diff --git a/plat/arm/board/common/swd_rotpk/arm_dev_swd_rotpk.S b/plat/arm/board/common/swd_rotpk/arm_dev_swd_rotpk.S
new file mode 100644
index 0000000..ae4f9d2
--- /dev/null
+++ b/plat/arm/board/common/swd_rotpk/arm_dev_swd_rotpk.S
@@ -0,0 +1,18 @@
+/*
+ * Copyright (c) 2022, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+	.global arm_swd_rotpk_hash
+	.global arm_swd_rotpk_hash_end
+
+	.section .rodata.arm_swd_rotpk_hash, "a"
+
+arm_swd_rotpk_hash:
+	/* DER header. */
+	.byte 0x30, 0x31, 0x30, 0x0D, 0x06, 0x09, 0x60, 0x86, 0x48
+	.byte 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0x04, 0x20
+	/* Key hash. */
+	.incbin ARM_SWD_ROTPK_HASH
+arm_swd_rotpk_hash_end:
diff --git a/plat/arm/board/common/swd_rotpk/arm_swd_rotpk_rsa_sha256.bin b/plat/arm/board/common/swd_rotpk/arm_swd_rotpk_rsa_sha256.bin
new file mode 100644
index 0000000..b2f3e60
--- /dev/null
+++ b/plat/arm/board/common/swd_rotpk/arm_swd_rotpk_rsa_sha256.bin
@@ -0,0 +1 @@
+0¾âÃ’æœÈË“(ì¨0ŠwIӁÕéã¡gk
\ No newline at end of file
diff --git a/plat/arm/board/common/swd_rotpk/arm_swd_rotprivk_rsa.pem b/plat/arm/board/common/swd_rotpk/arm_swd_rotprivk_rsa.pem
new file mode 100644
index 0000000..0de655d
--- /dev/null
+++ b/plat/arm/board/common/swd_rotpk/arm_swd_rotprivk_rsa.pem
@@ -0,0 +1,27 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIEpQIBAAKCAQEA8igTd5QdZd181kz9vINr7Au34Rr/pQ1jpesfLlc1ZXCNAI9y
+/rhQlpw00y8rwOfgZsf18gPwGWWGhDJMsXI7OPem7BEUr8xKumuJuCiOdJh1STcR
+/JoFvz8wJPyycj/DOERRGsz+RvFBs6cLjSZHNQdzKDW+DE5vVJpmNWBVkoK7MCRD
+Wh/PMZVSoq9PeJOzayYcsipKvifT1+Wo9y2MG5zTDxi28rLr/FBm0CpTepBcRe8L
+pmgS7XJKhCQYxdDSzxi/0t/qXAwWuME4jv2HbNxsUZjahiBYpA0BafXanSuxVHly
+qpD0BmKAu7PpgKrEnUcPuHpZ2W+a05lNk6zjewIDAQABAoIBAG3twYCcTYgrtvs1
+8k38vyZl33CiKAGOhXkRtpL75fKJ2IizljmKBJOKj/R6ynsFCHrANadLIFj3HMyw
+ZN59A+OFkVJDIsf3jsj3/ooKZzkI6N120YSBizBZiAqSaJOy3HWTldn7y0b7SJ88
+quLFyLeLDTzowMCnbqTSfqmmdNJQAn+Q+7RX5sZGyBQUF2pRAA67cOYzc3a5MZ5E
+zBOs2u8VboC3ulEq876XWQbcXpRh/ap3eplQ1kAdyy64IPp2WbxqyXW0IQAQqaqh
+6oj19ME6mVD5wtELcYscJCDb7pA6WJtPp6nz/og2ifCJE/75T5RJ6fc6eBFMcofQ
+STIClGECgYEA/ZC0GX1HTKEKK3c1TiS3Zy0DS5ZoN5KFK7Sp1ZAjPE63iAr1a3z9
+Kepb+L8TBSw50tVD74MF5ChEid/ghF5BrVC3/YJkiiNpM1F51SMLGFeiDPRzJcx5
+KJkSflX7Q36BAXqj85Yz5AjgTPKcBqQRVZ6pNZN1HY99MloMg22WPRECgYEA9HtU
+FXmnTplXaNnihdq+vL5Z4/KDM+1f1E95y1PB8vkLI+o1szVNFP+BYz+w42lKtHW+
+c+z40AhFBGZQ0QCx83NOyObCReFjEbP8Nz71BsHe6GyMk9tSPIpzu9XB49Rs+9EO
+DAvFM5y2j5bH+lXE0pSyS3oBf51L9ZCPhp/vB8sCgYEAydwB1Gzsbu+hFfs/v2bx
+brzh67HgY6VMSP/5WF/3/RG5gB8hQ6HsNQsyjrMmZC7SFarb+3e2H+2CqrREm3wi
+EuS4pKPCgEoyfL03HVtZgNZ61o9gf83pAk3h8Bto/VFfSBsnHEsOIlKCph9Z4NuK
+RTwa/uDWEmNhyszvO03pldECgYEA2zB7GWnhc1mNgabfLY0JtuSeaPzzXqnyYcID
+eyUT3QglUcTY8lvWSP4ufdILgEfVP2fVIdAS30iawDAPQuLxqEf4Gayx/r7s+GE6
+vjlGqxFEDXPMsX9QApFK49voop/AOiCbDHe9DOHy11ei4TDmbrn8BClVkJlxEa/S
+ziszvfMCgYEA2V0zXziooI0toaOJEWZlAYhEONS5SG2z28HMLNgbdMcueGNhseaR
+NBGgPcu3EQhbL/hD0tBs09u6gjy1WD1i0HYnm1K1YQ1flzfbjUa3BqZETMbNhugd
+CM9yv0GEL/udZyOmO401aYl+QGXZX/WwlLQOe7WqQXOXJvW73oSqy7M=
+-----END RSA PRIVATE KEY-----
diff --git a/plat/arm/board/fvp/fdts/fvp_tb_fw_config.dts b/plat/arm/board/fvp/fdts/fvp_tb_fw_config.dts
index cf4ef2d..6fd334d 100644
--- a/plat/arm/board/fvp/fdts/fvp_tb_fw_config.dts
+++ b/plat/arm/board/fvp/fdts/fvp_tb_fw_config.dts
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020-2021, ARM Limited. All rights reserved.
+ * Copyright (c) 2020-2022, ARM Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -47,6 +47,9 @@
 			soc_fw_cfg_uuid = "9979814b-0376-fb46-8c8e-8d267f7859e0";
 			tos_fw_cfg_uuid = "26257c1a-dbc6-7f47-8d96-c4c4b0248021";
 			nt_fw_cfg_uuid = "28da9815-93e8-7e44-ac66-1aaf801550f9";
+			cca_cert_uuid = "36d83d85-761d-4daf-96f1-cd99d6569b00";
+			core_swd_cert_uuid = "52222d31-820f-494d-8bbc-ea6825d3c35a";
+			plat_cert_uuid = "d43cd902-5b9f-412e-8ac6-92b6d18be60d";
 			t_key_cert_uuid = "827ee890-f860-e411-a1b4-777a21b4f94c";
 			scp_fw_key_uuid = "024221a1-f860-e411-8d9b-f33c0e15a014";
 			soc_fw_key_uuid = "8ab8becc-f960-e411-9ad0-eb4822d8dcf8";
diff --git a/plat/arm/board/fvp/include/platform_def.h b/plat/arm/board/fvp/include/platform_def.h
index 82bd7c8..c75aca7 100644
--- a/plat/arm/board/fvp/include/platform_def.h
+++ b/plat/arm/board/fvp/include/platform_def.h
@@ -197,6 +197,9 @@
 # define PLAT_ARM_MAX_BL2_SIZE	(UL(0x1E000) - FVP_BL2_ROMLIB_OPTIMIZATION)
 #elif CRYPTO_SUPPORT
 # define PLAT_ARM_MAX_BL2_SIZE	(UL(0x1D000) - FVP_BL2_ROMLIB_OPTIMIZATION)
+#elif ARM_BL31_IN_DRAM
+/* When ARM_BL31_IN_DRAM is set, BL2 can use almost all of Trusted SRAM. */
+# define PLAT_ARM_MAX_BL2_SIZE	(UL(0x1F000) - FVP_BL2_ROMLIB_OPTIMIZATION)
 #else
 # define PLAT_ARM_MAX_BL2_SIZE	(UL(0x13000) - FVP_BL2_ROMLIB_OPTIMIZATION)
 #endif
diff --git a/plat/arm/board/fvp/platform.mk b/plat/arm/board/fvp/platform.mk
index 54c5e75..f9053a8 100644
--- a/plat/arm/board/fvp/platform.mk
+++ b/plat/arm/board/fvp/platform.mk
@@ -375,6 +375,10 @@
     $(info Including ${RSS_MEASURED_BOOT_MK})
     include ${RSS_MEASURED_BOOT_MK}
 
+    ifneq (${MBOOT_RSS_HASH_ALG}, sha256)
+        $(eval $(call add_define,TF_MBEDTLS_MBOOT_USE_SHA512))
+    endif
+
     BL1_SOURCES		+=	${MEASURED_BOOT_SOURCES}
     BL2_SOURCES		+=	${MEASURED_BOOT_SOURCES}
 endif
diff --git a/plat/arm/common/arm_common.mk b/plat/arm/common/arm_common.mk
index 6d7aa2d..290b4ee 100644
--- a/plat/arm/common/arm_common.mk
+++ b/plat/arm/common/arm_common.mk
@@ -373,6 +373,8 @@
         endif
     else ifeq (${COT},dualroot)
         AUTH_SOURCES	+=	drivers/auth/dualroot/cot.c
+    else ifeq (${COT},cca)
+        AUTH_SOURCES	+=	drivers/auth/cca/cot.c
     else
         $(error Unknown chain of trust ${COT})
     endif
@@ -401,6 +403,10 @@
     $(info Including ${MEASURED_BOOT_MK})
     include ${MEASURED_BOOT_MK}
 
+    ifneq (${MBOOT_EL_HASH_ALG}, sha256)
+        $(eval $(call add_define,TF_MBEDTLS_MBOOT_USE_SHA512))
+    endif
+
     BL1_SOURCES		+= 	${EVENT_LOG_SOURCES}
     BL2_SOURCES		+= 	${EVENT_LOG_SOURCES}
 endif
diff --git a/plat/arm/common/fconf/arm_fconf_io.c b/plat/arm/common/fconf/arm_fconf_io.c
index aea2f38..6c32331 100644
--- a/plat/arm/common/fconf/arm_fconf_io.c
+++ b/plat/arm/common/fconf/arm_fconf_io.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019-2021, ARM Limited. All rights reserved.
+ * Copyright (c) 2019-2022, ARM Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -72,6 +72,9 @@
 #if TRUSTED_BOARD_BOOT
 	[TRUSTED_BOOT_FW_CERT_ID] = {UUID_TRUSTED_BOOT_FW_CERT},
 #if !ARM_IO_IN_DTB
+	[CCA_CONTENT_CERT_ID] = {UUID_CCA_CONTENT_CERT},
+	[CORE_SWD_KEY_CERT_ID] = {UUID_CORE_SWD_KEY_CERT},
+	[PLAT_KEY_CERT_ID] = {UUID_PLAT_KEY_CERT},
 	[TRUSTED_KEY_CERT_ID] = {UUID_TRUSTED_KEY_CERT},
 	[SCP_FW_KEY_CERT_ID] = {UUID_SCP_FW_KEY_CERT},
 	[SOC_FW_KEY_CERT_ID] = {UUID_SOC_FW_KEY_CERT},
@@ -196,6 +199,21 @@
 		open_fip
 	},
 #if !ARM_IO_IN_DTB
+	[CCA_CONTENT_CERT_ID] = {
+		&fip_dev_handle,
+		(uintptr_t)&arm_uuid_spec[CCA_CONTENT_CERT_ID],
+		open_fip
+	},
+	[CORE_SWD_KEY_CERT_ID] = {
+		&fip_dev_handle,
+		(uintptr_t)&arm_uuid_spec[CORE_SWD_KEY_CERT_ID],
+		open_fip
+	},
+	[PLAT_KEY_CERT_ID] = {
+		&fip_dev_handle,
+		(uintptr_t)&arm_uuid_spec[PLAT_KEY_CERT_ID],
+		open_fip
+	},
 	[TRUSTED_KEY_CERT_ID] = {
 		&fip_dev_handle,
 		(uintptr_t)&arm_uuid_spec[TRUSTED_KEY_CERT_ID],
@@ -260,7 +278,7 @@
 #ifdef IMAGE_BL2
 
 #if TRUSTED_BOARD_BOOT
-#define FCONF_ARM_IO_UUID_NUMBER	U(21)
+#define FCONF_ARM_IO_UUID_NUMBER	U(24)
 #else
 #define FCONF_ARM_IO_UUID_NUMBER	U(10)
 #endif
@@ -286,6 +304,9 @@
 	{TOS_FW_CONFIG_ID, "tos_fw_cfg_uuid"},
 	{NT_FW_CONFIG_ID, "nt_fw_cfg_uuid"},
 #if TRUSTED_BOARD_BOOT
+	{CCA_CONTENT_CERT_ID, "cca_cert_uuid"},
+	{CORE_SWD_KEY_CERT_ID, "core_swd_cert_uuid"},
+	{PLAT_KEY_CERT_ID, "plat_cert_uuid"},
 	{TRUSTED_KEY_CERT_ID, "t_key_cert_uuid"},
 	{SCP_FW_KEY_CERT_ID, "scp_fw_key_uuid"},
 	{SOC_FW_KEY_CERT_ID, "soc_fw_key_uuid"},
diff --git a/plat/imx/imx8m/imx8mm/platform.mk b/plat/imx/imx8m/imx8mm/platform.mk
index 0cce7ca..60fa325 100644
--- a/plat/imx/imx8m/imx8mm/platform.mk
+++ b/plat/imx/imx8m/imx8mm/platform.mk
@@ -162,6 +162,10 @@
     $(info Including ${MEASURED_BOOT_MK})
     include ${MEASURED_BOOT_MK}
 
+ifneq (${MBOOT_EL_HASH_ALG}, sha256)
+    $(eval $(call add_define,TF_MBEDTLS_MBOOT_USE_SHA512))
+endif
+
 BL2_SOURCES		+=	plat/imx/imx8m/imx8m_measured_boot.c	\
 				plat/imx/imx8m/imx8m_dyn_cfg_helpers.c	\
 				${EVENT_LOG_SOURCES}
diff --git a/plat/qemu/qemu/platform.mk b/plat/qemu/qemu/platform.mk
index 6a877c3..8e7f7c8 100644
--- a/plat/qemu/qemu/platform.mk
+++ b/plat/qemu/qemu/platform.mk
@@ -104,6 +104,10 @@
     $(info Including ${MEASURED_BOOT_MK})
     include ${MEASURED_BOOT_MK}
 
+    ifneq (${MBOOT_EL_HASH_ALG}, sha256)
+        $(eval $(call add_define,TF_MBEDTLS_MBOOT_USE_SHA512))
+    endif
+
     BL2_SOURCES		+=	plat/qemu/qemu/qemu_measured_boot.c	\
 				plat/qemu/qemu/qemu_common_measured_boot.c	\
 				plat/qemu/qemu/qemu_helpers.c		\
diff --git a/plat/socionext/synquacer/include/platform_def.h b/plat/socionext/synquacer/include/platform_def.h
index 49ffbf9..a84660b 100644
--- a/plat/socionext/synquacer/include/platform_def.h
+++ b/plat/socionext/synquacer/include/platform_def.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2022, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -42,16 +42,52 @@
 #define MAX_XLAT_TABLES			8
 #define MAX_MMAP_REGIONS		8
 
+#if TRUSTED_BOARD_BOOT
+#define PLATFORM_STACK_SIZE		0x1000
+#else
 #define PLATFORM_STACK_SIZE		0x400
+#endif
+
+#if !RESET_TO_BL31
+
+/* A mailbox page will be mapped from BL2 and BL31 */
+#define BL2_MAILBOX_BASE		0x0403f000
+#define BL2_MAILBOX_SIZE		0x1000
+
+#define PLAT_SQ_BOOTIDX_BASE		0x08510000
+#define PLAT_SQ_MAX_BOOT_INDEX		2
+
+#define MAX_IO_HANDLES			2
+#define MAX_IO_DEVICES			2
+#define MAX_IO_BLOCK_DEVICES	U(1)
+
+#define BL2_BASE			0x04000000
+#define BL2_SIZE			(256 * 1024)
+#define BL2_LIMIT			(BL2_BASE + BL2_SIZE)
+
+/* If BL2 is enabled, the BL31 is loaded on secure DRAM */
+#define BL31_BASE			0xfbe00000
+#define BL31_SIZE			0x00100000
+#else
 
 #define BL31_BASE			0x04000000
 #define BL31_SIZE			0x00080000
+#endif
+
 #define BL31_LIMIT			(BL31_BASE + BL31_SIZE)
 
 #define BL32_BASE			0xfc000000
 #define BL32_SIZE			0x03c00000
 #define BL32_LIMIT			(BL32_BASE + BL32_SIZE)
 
+/* Alternative BL33 */
+#define PLAT_SQ_BL33_BASE		0xe0000000
+#define PLAT_SQ_BL33_SIZE		0x00100000
+
+/* FWU FIP IO base */
+#define PLAT_SQ_FIP_IOBASE		0x08600000
+#define PLAT_SQ_FIP_MAXSIZE		0x00400000
+
 #define PLAT_SQ_CCN_BASE		0x32000000
 #define PLAT_SQ_CLUSTER_TO_CCN_ID_MAP					\
 					0,	/* Cluster 0 */		\
diff --git a/plat/socionext/synquacer/include/sq_common.h b/plat/socionext/synquacer/include/sq_common.h
index b09d22a..eef0e1f 100644
--- a/plat/socionext/synquacer/include/sq_common.h
+++ b/plat/socionext/synquacer/include/sq_common.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2022, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -39,6 +39,8 @@
 void sq_gic_cpuif_disable(void);
 void sq_gic_pcpu_init(void);
 
+int sq_io_setup(void);
+struct image_info *sq_get_image_info(unsigned int image_id);
 void sq_mmap_setup(uintptr_t total_base, size_t total_size,
 		   const struct mmap_region *mmap);
 
diff --git a/plat/socionext/synquacer/platform.mk b/plat/socionext/synquacer/platform.mk
index dcd5d31..3eab3d6 100644
--- a/plat/socionext/synquacer/platform.mk
+++ b/plat/socionext/synquacer/platform.mk
@@ -1,18 +1,26 @@
 #
-# Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2018-2022, ARM Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
 
-override RESET_TO_BL31			:= 1
 override PROGRAMMABLE_RESET_ADDRESS	:= 1
 override USE_COHERENT_MEM		:= 1
 override SEPARATE_CODE_AND_RODATA	:= 1
 override ENABLE_SVE_FOR_NS		:= 0
 # Enable workarounds for selected Cortex-A53 erratas.
 ERRATA_A53_855873		:= 1
-# Enable SCMI support
-SQ_USE_SCMI_DRIVER		?= 0
+
+ifeq (${RESET_TO_BL31}, 1)
+override RESET_TO_BL31          := 1
+override TRUSTED_BOARD_BOOT     := 0
+SQ_USE_SCMI_DRIVER              ?= 0
+else
+override RESET_TO_BL31          := 0
+override BL2_AT_EL3             := 1
+SQ_USE_SCMI_DRIVER              := 1
+BL2_CPPFLAGS                    += -DPLAT_XLAT_TABLES_DYNAMIC
+endif
 
 # Libraries
 include lib/xlat_tables_v2/xlat_tables.mk
@@ -28,14 +36,55 @@
 				drivers/arm/pl011/aarch64/pl011_console.S \
 				drivers/delay_timer/delay_timer.c	\
 				drivers/delay_timer/generic_delay_timer.c \
+				lib/cpus/aarch64/cortex_a53.S		\
+				$(PLAT_PATH)/sq_xlat_setup.c	\
 				${XLAT_TABLES_LIB_SRCS}
 
 # Include GICv3 driver files
 include drivers/arm/gic/v3/gicv3.mk
 
+ifneq (${RESET_TO_BL31}, 1)
+BL2_SOURCES		+=	common/desc_image_load.c		\
+				drivers/io/io_fip.c			\
+				drivers/io/io_memmap.c			\
+				drivers/io/io_storage.c			\
+				$(PLAT_PATH)/sq_bl2_setup.c		\
+				$(PLAT_PATH)/sq_image_desc.c	\
+				$(PLAT_PATH)/sq_io_storage.c
+
+ifeq (${TRUSTED_BOARD_BOOT},1)
+include drivers/auth/mbedtls/mbedtls_crypto.mk
+include drivers/auth/mbedtls/mbedtls_x509.mk
+BL2_SOURCES		+=	drivers/auth/auth_mod.c			\
+				drivers/auth/crypto_mod.c		\
+				drivers/auth/img_parser_mod.c		\
+				drivers/auth/tbbr/tbbr_cot_common.c	\
+				drivers/auth/tbbr/tbbr_cot_bl2.c	\
+				plat/common/tbbr/plat_tbbr.c		\
+				$(PLAT_PATH)/sq_rotpk.S		\
+				$(PLAT_PATH)/sq_tbbr.c
+
+ROT_KEY			= $(BUILD_PLAT)/rot_key.pem
+ROTPK_HASH		= $(BUILD_PLAT)/rotpk_sha256.bin
+
+$(eval $(call add_define_val,ROTPK_HASH,'"$(ROTPK_HASH)"'))
+$(BUILD_PLAT)/bl2/sq_rotpk.o: $(ROTPK_HASH)
+
+certificates: $(ROT_KEY)
+$(ROT_KEY): | $(BUILD_PLAT)
+	@echo "  OPENSSL $@"
+	$(Q)openssl genrsa 2048 > $@ 2>/dev/null
+
+$(ROTPK_HASH): $(ROT_KEY)
+	@echo "  OPENSSL $@"
+	$(Q)openssl rsa -in $< -pubout -outform DER 2>/dev/null |\
+	openssl dgst -sha256 -binary > $@ 2>/dev/null
+
+endif	# TRUSTED_BOARD_BOOT
+endif
+
 BL31_SOURCES		+=	drivers/arm/ccn/ccn.c			\
 				${GICV3_SOURCES}			\
-				lib/cpus/aarch64/cortex_a53.S		\
 				plat/common/plat_gicv3.c		\
 				plat/common/plat_psci_common.c		\
 				$(PLAT_PATH)/sq_bl31_setup.c		\
@@ -43,7 +92,6 @@
 				$(PLAT_PATH)/sq_topology.c		\
 				$(PLAT_PATH)/sq_psci.c			\
 				$(PLAT_PATH)/sq_gicv3.c			\
-				$(PLAT_PATH)/sq_xlat_setup.c	\
 				$(PLAT_PATH)/drivers/scp/sq_scp.c
 
 ifeq (${SQ_USE_SCMI_DRIVER},0)
diff --git a/plat/socionext/synquacer/sq_bl2_setup.c b/plat/socionext/synquacer/sq_bl2_setup.c
new file mode 100644
index 0000000..a98d912
--- /dev/null
+++ b/plat/socionext/synquacer/sq_bl2_setup.c
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2022, Socionext Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <errno.h>
+
+#include <common/bl_common.h>
+#include <common/debug.h>
+#include <common/desc_image_load.h>
+#include <common/image_decompress.h>
+#include <drivers/arm/pl011.h>
+#include <drivers/io/io_storage.h>
+#include <lib/xlat_tables/xlat_tables_v2.h>
+#include <plat/common/platform.h>
+
+#include <platform_def.h>
+#include <sq_common.h>
+
+static console_t console;
+
+void bl2_el3_early_platform_setup(u_register_t x0, u_register_t x1,
+				  u_register_t x2, u_register_t x3)
+{
+	/* Initialize the console to provide early debug support */
+	(void)console_pl011_register(PLAT_SQ_BOOT_UART_BASE,
+			       PLAT_SQ_BOOT_UART_CLK_IN_HZ,
+			       SQ_CONSOLE_BAUDRATE, &console);
+	console_set_scope(&console, CONSOLE_FLAG_BOOT);
+}
+
+void bl2_el3_plat_arch_setup(void)
+{
+	int ret;
+
+	sq_mmap_setup(BL2_BASE, BL2_SIZE, NULL);
+
+	ret = sq_io_setup();
+	if (ret) {
+		ERROR("failed to setup io devices\n");
+		plat_error_handler(ret);
+	}
+}
+
+void bl2_platform_setup(void)
+{
+}
+
+void plat_flush_next_bl_params(void)
+{
+	flush_bl_params_desc();
+}
+
+bl_load_info_t *plat_get_bl_image_load_info(void)
+{
+	return get_bl_load_info_from_mem_params_desc();
+}
+
+bl_params_t *plat_get_next_bl_params(void)
+{
+	return get_next_bl_params_from_mem_params_desc();
+}
+
+void bl2_plat_preload_setup(void)
+{
+}
+
+int bl2_plat_handle_pre_image_load(unsigned int image_id)
+{
+	struct image_info *image_info;
+
+	image_info = sq_get_image_info(image_id);
+
+	return mmap_add_dynamic_region(image_info->image_base,
+				      image_info->image_base,
+				      image_info->image_max_size,
+				      MT_MEMORY | MT_RW | MT_NS);
+}
+
+int bl2_plat_handle_post_image_load(unsigned int image_id)
+{
+	return 0;
+}
diff --git a/plat/socionext/synquacer/sq_bl31_setup.c b/plat/socionext/synquacer/sq_bl31_setup.c
index a7a0ce0..967437b 100644
--- a/plat/socionext/synquacer/sq_bl31_setup.c
+++ b/plat/socionext/synquacer/sq_bl31_setup.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2022, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -44,6 +44,35 @@
 	return type == NON_SECURE ? &bl33_image_ep_info : &bl32_image_ep_info;
 }
 
+#if !RESET_TO_BL31
+void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
+				u_register_t arg2, u_register_t arg3)
+{
+	void *from_bl2 = (void *) arg0;
+	bl_params_node_t *bl_params = ((bl_params_t *) from_bl2)->head;
+
+	/* Initialize the console to provide early debug support */
+	(void)console_pl011_register(PLAT_SQ_BOOT_UART_BASE,
+			       PLAT_SQ_BOOT_UART_CLK_IN_HZ,
+			       SQ_CONSOLE_BAUDRATE, &console);
+
+	console_set_scope(&console, CONSOLE_FLAG_BOOT | CONSOLE_FLAG_RUNTIME);
+
+	/* Initialize power controller before setting up topology */
+	plat_sq_pwrc_setup();
+
+	while (bl_params) {
+		if (bl_params->image_id == BL32_IMAGE_ID)
+			bl32_image_ep_info = *bl_params->ep_info;
+
+		if (bl_params->image_id == BL33_IMAGE_ID)
+			bl33_image_ep_info = *bl_params->ep_info;
+
+		bl_params = bl_params->next_params_info;
+	}
+}
+
+#else
 /*******************************************************************************
  * Gets SPSR for BL32 entry
  ******************************************************************************/
@@ -129,6 +158,7 @@
 	bl33_image_ep_info.spsr = sq_get_spsr_for_bl33_entry();
 	SET_SECURITY_STATE(bl33_image_ep_info.h.attr, NON_SECURE);
 }
+#endif
 
 static void sq_configure_sys_timer(void)
 {
@@ -192,6 +222,11 @@
 				PLAT_SQ_SP_PRIV_SIZE,
 				MT_RW_DATA | MT_SECURE),
 #endif
+#if !RESET_TO_BL31
+		MAP_REGION_FLAT(BL2_MAILBOX_BASE,
+				BL2_MAILBOX_SIZE,
+				MT_RW | MT_SECURE),
+#endif
 		{0},
 	};
 
diff --git a/plat/socionext/synquacer/sq_helpers.S b/plat/socionext/synquacer/sq_helpers.S
index 7a2d97b..5f9eab4 100644
--- a/plat/socionext/synquacer/sq_helpers.S
+++ b/plat/socionext/synquacer/sq_helpers.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2022, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -46,7 +46,12 @@
  * code that secondary CPUs jump to.
  */
 func plat_secondary_cold_boot_setup
+#if !RESET_TO_BL31
+	mov_imm	x0, BL2_MAILBOX_BASE
+	ldr	x0, [x0]
+#else
 	ldr	x0, sq_sec_entrypoint
+#endif
 
 	/* Wait until the mailbox gets populated */
 poll_mailbox:
diff --git a/plat/socionext/synquacer/sq_image_desc.c b/plat/socionext/synquacer/sq_image_desc.c
new file mode 100644
index 0000000..5fe125b
--- /dev/null
+++ b/plat/socionext/synquacer/sq_image_desc.c
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2022, Socionext Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+
+#include <arch.h>
+#include <common/desc_image_load.h>
+
+#include <platform_def.h>
+
+static struct bl_mem_params_node sq_image_descs[] = {
+	{
+		.image_id = BL31_IMAGE_ID,
+
+		SET_STATIC_PARAM_HEAD(image_info, PARAM_EP,
+				      VERSION_2, image_info_t, 0),
+		.image_info.image_base = BL31_BASE,
+		.image_info.image_max_size = BL31_SIZE,
+
+		SET_STATIC_PARAM_HEAD(ep_info, PARAM_EP,
+				      VERSION_2, entry_point_info_t,
+				      SECURE | EXECUTABLE | EP_FIRST_EXE),
+		.ep_info.pc = BL31_BASE,
+		.ep_info.spsr = SPSR_64(MODE_EL3, MODE_SP_ELX,
+					DISABLE_ALL_EXCEPTIONS),
+
+		.next_handoff_image_id = BL32_IMAGE_ID,
+	},
+	{
+		.image_id = BL32_IMAGE_ID,
+
+		SET_STATIC_PARAM_HEAD(image_info, PARAM_EP,
+				      VERSION_2, image_info_t, 0),
+		.image_info.image_base = BL32_BASE,
+		.image_info.image_max_size = BL32_SIZE,
+
+		SET_STATIC_PARAM_HEAD(ep_info, PARAM_EP,
+				      VERSION_2, entry_point_info_t,
+				      SECURE | EXECUTABLE),
+		.ep_info.pc = BL32_BASE,
+		.ep_info.spsr = SPSR_64(MODE_EL3, MODE_SP_ELX,
+					DISABLE_ALL_EXCEPTIONS),
+
+		.next_handoff_image_id = BL33_IMAGE_ID,
+	},
+	{
+		.image_id = BL33_IMAGE_ID,
+
+		SET_STATIC_PARAM_HEAD(image_info, PARAM_EP,
+				      VERSION_2, image_info_t, 0),
+		.image_info.image_base = PLAT_SQ_BL33_BASE,
+		.image_info.image_max_size = PLAT_SQ_BL33_SIZE,
+
+		SET_STATIC_PARAM_HEAD(ep_info, PARAM_EP,
+				      VERSION_2, entry_point_info_t,
+				      NON_SECURE | EXECUTABLE),
+		.ep_info.pc = PLAT_SQ_BL33_BASE,
+		.ep_info.spsr = SPSR_64(MODE_EL2, MODE_SP_ELX,
+					DISABLE_ALL_EXCEPTIONS),
+
+		.next_handoff_image_id = INVALID_IMAGE_ID,
+	},
+};
+REGISTER_BL_IMAGE_DESCS(sq_image_descs)
+
+struct image_info *sq_get_image_info(unsigned int image_id)
+{
+	struct bl_mem_params_node *desc;
+
+	desc = get_bl_mem_params_node(image_id);
+	assert(desc);
+	return &desc->image_info;
+}
diff --git a/plat/socionext/synquacer/sq_io_storage.c b/plat/socionext/synquacer/sq_io_storage.c
new file mode 100644
index 0000000..ea83dad
--- /dev/null
+++ b/plat/socionext/synquacer/sq_io_storage.c
@@ -0,0 +1,246 @@
+/*
+ * Copyright (c) 2022, Socionext Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <errno.h>
+#include <stdint.h>
+
+#include <drivers/io/io_block.h>
+#include <drivers/io/io_driver.h>
+#include <drivers/io/io_fip.h>
+#include <drivers/io/io_memmap.h>
+#include <lib/mmio.h>
+#include <lib/utils_def.h>
+#include <lib/xlat_tables/xlat_tables_v2.h>
+#include <tools_share/firmware_image_package.h>
+
+#include <platform_def.h>
+#include <sq_common.h>
+
+static const io_dev_connector_t *sq_fip_dev_con;
+static uintptr_t sq_fip_dev_handle;
+
+static const io_dev_connector_t *sq_backend_dev_con;
+static uintptr_t sq_backend_dev_handle;
+
+static io_block_spec_t sq_fip_spec = {
+	.offset = PLAT_SQ_FIP_IOBASE,	/* FIP Image is at 5MB offset on memory-mapped NOR flash */
+	.length = PLAT_SQ_FIP_MAXSIZE,	/* Expected maximum FIP image size */
+};
+
+static const io_uuid_spec_t sq_bl2_spec = {
+	.uuid = UUID_TRUSTED_BOOT_FIRMWARE_BL2,
+};
+
+static const io_uuid_spec_t sq_bl31_spec = {
+	.uuid = UUID_EL3_RUNTIME_FIRMWARE_BL31,
+};
+
+static const io_uuid_spec_t sq_bl32_spec = {
+	.uuid = UUID_SECURE_PAYLOAD_BL32,
+};
+
+static const io_uuid_spec_t sq_bl33_spec = {
+	.uuid = UUID_NON_TRUSTED_FIRMWARE_BL33,
+};
+
+#if TRUSTED_BOARD_BOOT
+static const io_uuid_spec_t sq_tb_fw_cert_spec = {
+	.uuid = UUID_TRUSTED_BOOT_FW_CERT,
+};
+
+static const io_uuid_spec_t sq_trusted_key_cert_spec = {
+	.uuid = UUID_TRUSTED_KEY_CERT,
+};
+
+static const io_uuid_spec_t sq_soc_fw_key_cert_spec = {
+	.uuid = UUID_SOC_FW_KEY_CERT,
+};
+
+static const io_uuid_spec_t sq_tos_fw_key_cert_spec = {
+	.uuid = UUID_TRUSTED_OS_FW_KEY_CERT,
+};
+
+static const io_uuid_spec_t sq_nt_fw_key_cert_spec = {
+	.uuid = UUID_NON_TRUSTED_FW_KEY_CERT,
+};
+
+static const io_uuid_spec_t sq_soc_fw_cert_spec = {
+	.uuid = UUID_SOC_FW_CONTENT_CERT,
+};
+
+static const io_uuid_spec_t sq_tos_fw_cert_spec = {
+	.uuid = UUID_TRUSTED_OS_FW_CONTENT_CERT,
+};
+
+static const io_uuid_spec_t sq_nt_fw_cert_spec = {
+	.uuid = UUID_NON_TRUSTED_FW_CONTENT_CERT,
+};
+#endif /* TRUSTED_BOARD_BOOT */
+
+struct sq_io_policy {
+	uintptr_t *dev_handle;
+	uintptr_t image_spec;
+	uintptr_t init_params;
+};
+
+static const struct sq_io_policy sq_io_policies[] = {
+	[FIP_IMAGE_ID] = {
+		.dev_handle = &sq_backend_dev_handle,
+		.image_spec = (uintptr_t)&sq_fip_spec,
+	},
+	[BL2_IMAGE_ID] = {
+		.dev_handle = &sq_fip_dev_handle,
+		.image_spec = (uintptr_t)&sq_bl2_spec,
+		.init_params = FIP_IMAGE_ID,
+	},
+	[BL31_IMAGE_ID] = {
+		.dev_handle = &sq_fip_dev_handle,
+		.image_spec = (uintptr_t)&sq_bl31_spec,
+		.init_params = FIP_IMAGE_ID,
+	},
+	[BL32_IMAGE_ID] = {
+		.dev_handle = &sq_fip_dev_handle,
+		.image_spec = (uintptr_t)&sq_bl32_spec,
+		.init_params = FIP_IMAGE_ID,
+	},
+	[BL33_IMAGE_ID] = {
+		.dev_handle = &sq_fip_dev_handle,
+		.image_spec = (uintptr_t)&sq_bl33_spec,
+		.init_params = FIP_IMAGE_ID,
+	},
+#if TRUSTED_BOARD_BOOT
+	[TRUSTED_BOOT_FW_CERT_ID] = {
+		.dev_handle = &sq_fip_dev_handle,
+		.image_spec = (uintptr_t)&sq_tb_fw_cert_spec,
+		.init_params = FIP_IMAGE_ID,
+	},
+	[TRUSTED_KEY_CERT_ID] = {
+		.dev_handle = &sq_fip_dev_handle,
+		.image_spec = (uintptr_t)&sq_trusted_key_cert_spec,
+		.init_params = FIP_IMAGE_ID,
+	},
+	[SOC_FW_KEY_CERT_ID] = {
+		.dev_handle = &sq_fip_dev_handle,
+		.image_spec = (uintptr_t)&sq_soc_fw_key_cert_spec,
+		.init_params = FIP_IMAGE_ID,
+	},
+	[TRUSTED_OS_FW_KEY_CERT_ID] = {
+		.dev_handle = &sq_fip_dev_handle,
+		.image_spec = (uintptr_t)&sq_tos_fw_key_cert_spec,
+		.init_params = FIP_IMAGE_ID,
+	},
+	[NON_TRUSTED_FW_KEY_CERT_ID] = {
+		.dev_handle = &sq_fip_dev_handle,
+		.image_spec = (uintptr_t)&sq_nt_fw_key_cert_spec,
+		.init_params = FIP_IMAGE_ID,
+	},
+	[SOC_FW_CONTENT_CERT_ID] = {
+		.dev_handle = &sq_fip_dev_handle,
+		.image_spec = (uintptr_t)&sq_soc_fw_cert_spec,
+		.init_params = FIP_IMAGE_ID,
+	},
+	[TRUSTED_OS_FW_CONTENT_CERT_ID] = {
+		.dev_handle = &sq_fip_dev_handle,
+		.image_spec = (uintptr_t)&sq_tos_fw_cert_spec,
+		.init_params = FIP_IMAGE_ID,
+	},
+	[NON_TRUSTED_FW_CONTENT_CERT_ID] = {
+		.dev_handle = &sq_fip_dev_handle,
+		.image_spec = (uintptr_t)&sq_nt_fw_cert_spec,
+		.init_params = FIP_IMAGE_ID,
+	},
+#endif
+};
+
+static int sq_update_fip_spec(void)
+{
+	uint32_t boot_index;
+	int ret;
+
+	ret = mmap_add_dynamic_region(PLAT_SQ_BOOTIDX_BASE, PLAT_SQ_BOOTIDX_BASE,
+				      PAGE_SIZE, MT_RO_DATA | MT_SECURE);
+	if (ret) {
+		return ret;
+	}
+
+	boot_index = mmio_read_32(PLAT_SQ_BOOTIDX_BASE);
+	if (boot_index < PLAT_SQ_MAX_BOOT_INDEX) {
+		sq_fip_spec.offset += PLAT_SQ_FIP_MAXSIZE * boot_index;
+		INFO("FWU Enabled: boot_index %d\n", boot_index);
+	} else {
+		WARN("FWU Disabled: wrong boot_index value. Fallback to index 0.\n");
+	}
+
+	mmap_remove_dynamic_region(PLAT_SQ_BOOTIDX_BASE, PAGE_SIZE);
+	return 0;
+}
+
+static int sq_io_memmap_setup(void)
+{
+	int ret;
+
+	ret = sq_update_fip_spec();
+	if (ret) {
+		return ret;
+	}
+
+	ret = mmap_add_dynamic_region(sq_fip_spec.offset, sq_fip_spec.offset,
+				      sq_fip_spec.length, MT_RO_DATA | MT_SECURE);
+	if (ret) {
+		return ret;
+	}
+
+	ret = register_io_dev_memmap(&sq_backend_dev_con);
+	if (ret) {
+		return ret;
+	}
+
+	return io_dev_open(sq_backend_dev_con, 0, &sq_backend_dev_handle);
+}
+
+static int sq_io_fip_setup(void)
+{
+	int ret;
+
+	ret = register_io_dev_fip(&sq_fip_dev_con);
+	if (ret) {
+		return ret;
+	}
+
+	return io_dev_open(sq_fip_dev_con, 0, &sq_fip_dev_handle);
+}
+
+int sq_io_setup(void)
+{
+	int ret;
+
+	ret = sq_io_memmap_setup();
+	if (ret) {
+		return ret;
+	}
+
+	ret = sq_io_fip_setup();
+	if (ret) {
+		return ret;
+	}
+
+	return 0;
+}
+
+int plat_get_image_source(unsigned int image_id, uintptr_t *dev_handle,
+			  uintptr_t *image_spec)
+{
+	uintptr_t init_params;
+
+	assert(image_id < ARRAY_SIZE(sq_io_policies));
+
+	*dev_handle = *sq_io_policies[image_id].dev_handle;
+	*image_spec = sq_io_policies[image_id].image_spec;
+	init_params = sq_io_policies[image_id].init_params;
+
+	return io_dev_init(*dev_handle, init_params);
+}
diff --git a/plat/socionext/synquacer/sq_psci.c b/plat/socionext/synquacer/sq_psci.c
index 3062f63..017516f 100644
--- a/plat/socionext/synquacer/sq_psci.c
+++ b/plat/socionext/synquacer/sq_psci.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2022, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -197,9 +197,17 @@
 int plat_setup_psci_ops(uintptr_t sec_entrypoint,
 			const struct plat_psci_ops **psci_ops)
 {
+#if !RESET_TO_BL31
+	uintptr_t *sq_sec_ep = (uintptr_t *)BL2_MAILBOX_BASE;
+
+	*sq_sec_ep = sec_entrypoint;
+	flush_dcache_range((uint64_t)sq_sec_ep,
+			   sizeof(*sq_sec_ep));
+#else
 	sq_sec_entrypoint = sec_entrypoint;
 	flush_dcache_range((uint64_t)&sq_sec_entrypoint,
 			   sizeof(sq_sec_entrypoint));
+#endif
 
 	*psci_ops = &sq_psci_ops;
 
diff --git a/plat/socionext/synquacer/sq_rotpk.S b/plat/socionext/synquacer/sq_rotpk.S
new file mode 100644
index 0000000..61227ed
--- /dev/null
+++ b/plat/socionext/synquacer/sq_rotpk.S
@@ -0,0 +1,16 @@
+/*
+ * Copyright (c) 2022, Socionext Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+	.global sq_rotpk_hash
+	.global sq_rotpk_hash_end
+	.section .rodata.sq_rotpk_hash, "a"
+sq_rotpk_hash:
+	/* DER header */
+	.byte 0x30, 0x31, 0x30, 0x0D, 0x06, 0x09, 0x60, 0x86, 0x48
+	.byte 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0x04, 0x20
+	/* SHA256 */
+	.incbin ROTPK_HASH
+sq_rotpk_hash_end:
diff --git a/plat/socionext/synquacer/sq_tbbr.c b/plat/socionext/synquacer/sq_tbbr.c
new file mode 100644
index 0000000..e9fa18c
--- /dev/null
+++ b/plat/socionext/synquacer/sq_tbbr.c
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2022, Socionext Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <plat/common/platform.h>
+
+extern char sq_rotpk_hash[], sq_rotpk_hash_end[];
+
+int plat_get_rotpk_info(void *cookie, void **key_ptr, unsigned int *key_len,
+			unsigned int *flags)
+{
+	*key_ptr = sq_rotpk_hash;
+	*key_len = sq_rotpk_hash_end - sq_rotpk_hash;
+	*flags = ROTPK_IS_HASH;
+
+	return 0;
+}
+
+int plat_get_nv_ctr(void *cookie, unsigned int *nv_ctr)
+{
+	/*
+	 * No support for non-volatile counter.  Update the ROT key to protect
+	 * the system against rollback.
+	 */
+	*nv_ctr = 0;
+
+	return 0;
+}
+
+int plat_set_nv_ctr(void *cookie, unsigned int nv_ctr)
+{
+	return 0;
+}
+
+int plat_get_mbedtls_heap(void **heap_addr, size_t *heap_size)
+{
+	return get_mbedtls_heap_helper(heap_addr, heap_size);
+}
diff --git a/plat/st/stm32mp1/bl2_plat_setup.c b/plat/st/stm32mp1/bl2_plat_setup.c
index 059e1cf..5015f7d 100644
--- a/plat/st/stm32mp1/bl2_plat_setup.c
+++ b/plat/st/stm32mp1/bl2_plat_setup.c
@@ -472,11 +472,13 @@
 
 				/* Init base and size for pager if exist */
 				paged_mem_params = get_bl_mem_params_node(BL32_EXTRA2_IMAGE_ID);
-				assert(paged_mem_params != NULL);
-				paged_mem_params->image_info.image_base = STM32MP_DDR_BASE +
-					(dt_get_ddr_size() - STM32MP_DDR_S_SIZE -
-					 STM32MP_DDR_SHMEM_SIZE);
-				paged_mem_params->image_info.image_max_size = STM32MP_DDR_S_SIZE;
+				if (paged_mem_params != NULL) {
+					paged_mem_params->image_info.image_base = STM32MP_DDR_BASE +
+						(dt_get_ddr_size() - STM32MP_DDR_S_SIZE -
+						 STM32MP_DDR_SHMEM_SIZE);
+					paged_mem_params->image_info.image_max_size =
+						STM32MP_DDR_S_SIZE;
+				}
 				break;
 
 			case BL33_IMAGE_ID:
@@ -496,11 +498,17 @@
 
 	case BL32_IMAGE_ID:
 		if (optee_header_is_valid(bl_mem_params->image_info.image_base)) {
+			image_info_t *paged_image_info = NULL;
+
 			/* BL32 is OP-TEE header */
 			bl_mem_params->ep_info.pc = bl_mem_params->image_info.image_base;
 			pager_mem_params = get_bl_mem_params_node(BL32_EXTRA1_IMAGE_ID);
+			assert(pager_mem_params != NULL);
+
 			paged_mem_params = get_bl_mem_params_node(BL32_EXTRA2_IMAGE_ID);
-			assert((pager_mem_params != NULL) && (paged_mem_params != NULL));
+			if (paged_mem_params != NULL) {
+				paged_image_info = &paged_mem_params->image_info;
+			}
 
 #if STM32MP_USE_STM32IMAGE && defined(AARCH32_SP_OPTEE)
 			/* Set OP-TEE extra image load areas at run-time */
@@ -516,16 +524,22 @@
 
 			err = parse_optee_header(&bl_mem_params->ep_info,
 						 &pager_mem_params->image_info,
-						 &paged_mem_params->image_info);
-			if (err) {
+						 paged_image_info);
+			if (err != 0) {
 				ERROR("OPTEE header parse error.\n");
 				panic();
 			}
 
 			/* Set optee boot info from parsed header data */
-			bl_mem_params->ep_info.args.arg0 = paged_mem_params->image_info.image_base;
-			bl_mem_params->ep_info.args.arg1 = 0; /* Unused */
-			bl_mem_params->ep_info.args.arg2 = 0; /* No DT supported */
+			if (paged_mem_params != NULL) {
+				bl_mem_params->ep_info.args.arg0 =
+					paged_mem_params->image_info.image_base;
+			} else {
+				bl_mem_params->ep_info.args.arg0 = 0U;
+			}
+
+			bl_mem_params->ep_info.args.arg1 = 0U; /* Unused */
+			bl_mem_params->ep_info.args.arg2 = 0U; /* No DT supported */
 		} else {
 #if !STM32MP_USE_STM32IMAGE
 			bl_mem_params->ep_info.pc = bl_mem_params->image_info.image_base;
diff --git a/plat/st/stm32mp1/plat_bl2_mem_params_desc.c b/plat/st/stm32mp1/plat_bl2_mem_params_desc.c
index 7963c4a..9ca0930 100644
--- a/plat/st/stm32mp1/plat_bl2_mem_params_desc.c
+++ b/plat/st/stm32mp1/plat_bl2_mem_params_desc.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016-2021, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2022, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -68,6 +68,7 @@
 
 		.next_handoff_image_id = INVALID_IMAGE_ID,
 	},
+#if STM32MP15
 	/* Fill BL32 external 2 image related information */
 	{
 		.image_id = BL32_EXTRA2_IMAGE_ID,
@@ -82,6 +83,7 @@
 
 		.next_handoff_image_id = INVALID_IMAGE_ID,
 	},
+#endif
 
 	/* Fill HW_CONFIG related information if it exists */
 	{
diff --git a/plat/xilinx/common/ipi_mailbox_service/ipi_mailbox_svc.c b/plat/xilinx/common/ipi_mailbox_service/ipi_mailbox_svc.c
index f531158..a46ac80 100644
--- a/plat/xilinx/common/ipi_mailbox_service/ipi_mailbox_svc.c
+++ b/plat/xilinx/common/ipi_mailbox_service/ipi_mailbox_svc.c
@@ -64,7 +64,7 @@
  * function with rt_svc_handle signature
  */
 uint64_t ipi_smc_handler(uint32_t smc_fid, uint64_t x1, uint64_t x2,
-			 uint64_t x3, uint64_t x4, void *cookie,
+			 uint64_t x3, uint64_t x4, const void *cookie,
 			 void *handle, uint64_t flags)
 {
 	int ret;
diff --git a/plat/xilinx/common/ipi_mailbox_service/ipi_mailbox_svc.h b/plat/xilinx/common/ipi_mailbox_service/ipi_mailbox_svc.h
index 10682d8..af13db9 100644
--- a/plat/xilinx/common/ipi_mailbox_service/ipi_mailbox_svc.h
+++ b/plat/xilinx/common/ipi_mailbox_service/ipi_mailbox_svc.h
@@ -33,7 +33,7 @@
 
 /* IPI SMC handler */
 uint64_t ipi_smc_handler(uint32_t smc_fid, uint64_t x1, uint64_t x2,
-			 uint64_t x3, uint64_t x4, void *cookie, void *handle,
+			 uint64_t x3, uint64_t x4, const void *cookie, void *handle,
 			 uint64_t flags);
 
 #endif /* IPI_MAILBOX_SVC_H */
diff --git a/plat/xilinx/versal/aarch64/versal_common.c b/plat/xilinx/versal/aarch64/versal_common.c
index 897ed59..f55cde9 100644
--- a/plat/xilinx/versal/aarch64/versal_common.c
+++ b/plat/xilinx/versal/aarch64/versal_common.c
@@ -47,7 +47,7 @@
 	generic_delay_timer_init();
 }
 
-unsigned int plat_get_syscnt_freq2(void)
+uint32_t plat_get_syscnt_freq2(void)
 {
 	return VERSAL_CPU_CLOCK;
 }
diff --git a/plat/xilinx/versal/bl31_versal_setup.c b/plat/xilinx/versal/bl31_versal_setup.c
index 78bfc29..0d0d598 100644
--- a/plat/xilinx/versal/bl31_versal_setup.c
+++ b/plat/xilinx/versal/bl31_versal_setup.c
@@ -67,19 +67,19 @@
 	if (VERSAL_CONSOLE_IS(pl011) || (VERSAL_CONSOLE_IS(pl011_1))) {
 		static console_t versal_runtime_console;
 		/* Initialize the console to provide early debug support */
-		int rc = console_pl011_register((unsigned long)VERSAL_UART_BASE,
-						(unsigned int)VERSAL_UART_CLOCK,
-						(unsigned int)VERSAL_UART_BAUDRATE,
+		int32_t rc = console_pl011_register((unsigned long)VERSAL_UART_BASE,
+						(uint32_t)VERSAL_UART_CLOCK,
+						(uint32_t)VERSAL_UART_BAUDRATE,
 						&versal_runtime_console);
 		if (rc == 0) {
 			panic();
 		}
 
-		console_set_scope(&versal_runtime_console, (unsigned int)(CONSOLE_FLAG_BOOT |
+		console_set_scope(&versal_runtime_console, (uint32_t)(CONSOLE_FLAG_BOOT |
 				  CONSOLE_FLAG_RUNTIME));
 	} else if (VERSAL_CONSOLE_IS(dcc)) {
 		/* Initialize the dcc console for debug */
-		int rc = console_dcc_register();
+		int32_t rc = console_dcc_register();
 		if (rc == 0) {
 			panic();
 		}
@@ -126,7 +126,7 @@
 
 static interrupt_type_handler_t type_el3_interrupt_handler;
 
-int request_intr_type_el3(uint32_t id, interrupt_type_handler_t handler)
+int32_t request_intr_type_el3(uint32_t id, interrupt_type_handler_t handler)
 {
 	/* Validate 'handler'*/
 	if (handler == NULL) {
diff --git a/plat/xilinx/versal/include/plat_private.h b/plat/xilinx/versal/include/plat_private.h
index d12d13a..109c95e 100644
--- a/plat/xilinx/versal/include/plat_private.h
+++ b/plat/xilinx/versal/include/plat_private.h
@@ -22,11 +22,11 @@
 void plat_versal_gic_save(void);
 void plat_versal_gic_resume(void);
 
-unsigned int versal_calc_core_pos(u_register_t mpidr);
+uint32_t versal_calc_core_pos(u_register_t mpidr);
 /*
  * Register handler to specific GIC entrance
  * for INTR_TYPE_EL3 type of interrupt
  */
-int request_intr_type_el3(uint32_t irq, interrupt_type_handler_t fiq_handler);
+int32_t request_intr_type_el3(uint32_t irq, interrupt_type_handler_t fiq_handler);
 
 #endif /* PLAT_PRIVATE_H */
diff --git a/plat/xilinx/versal/plat_psci.c b/plat/xilinx/versal/plat_psci.c
index eb05e58..acecbb1 100644
--- a/plat/xilinx/versal/plat_psci.c
+++ b/plat/xilinx/versal/plat_psci.c
@@ -19,9 +19,9 @@
 
 static uintptr_t versal_sec_entry;
 
-static int versal_pwr_domain_on(u_register_t mpidr)
+static int32_t versal_pwr_domain_on(u_register_t mpidr)
 {
-	int cpu_id = plat_core_pos_by_mpidr(mpidr);
+	int32_t cpu_id = plat_core_pos_by_mpidr(mpidr);
 	const struct pm_proc *proc;
 
 	VERBOSE("%s: mpidr: 0x%lx\n", __func__, mpidr);
@@ -30,7 +30,7 @@
 		return PSCI_E_INTERN_FAIL;
 	}
 
-	proc = pm_get_proc((unsigned int)cpu_id);
+	proc = pm_get_proc((uint32_t)cpu_id);
 
 	/* Send request to PMC to wake up selected ACPU core */
 	(void)pm_req_wakeup(proc->node_id, (versal_sec_entry & 0xFFFFFFFFU) | 0x1U,
@@ -50,8 +50,8 @@
  */
 static void versal_pwr_domain_suspend(const psci_power_state_t *target_state)
 {
-	unsigned int state;
-	unsigned int cpu_id = plat_my_core_pos();
+	uint32_t state;
+	uint32_t cpu_id = plat_my_core_pos();
 	const struct pm_proc *proc = pm_get_proc(cpu_id);
 
 	for (size_t i = 0U; i <= PLAT_MAX_PWR_LVL; i++) {
@@ -88,7 +88,7 @@
 static void versal_pwr_domain_suspend_finish(
 					const psci_power_state_t *target_state)
 {
-	unsigned int cpu_id = plat_my_core_pos();
+	uint32_t cpu_id = plat_my_core_pos();
 	const struct pm_proc *proc = pm_get_proc(cpu_id);
 
 	for (size_t i = 0U; i <= PLAT_MAX_PWR_LVL; i++) {
@@ -156,7 +156,7 @@
  */
 static void versal_pwr_domain_off(const psci_power_state_t *target_state)
 {
-	unsigned int cpu_id = plat_my_core_pos();
+	uint32_t cpu_id = plat_my_core_pos();
 	const struct pm_proc *proc = pm_get_proc(cpu_id);
 
 	for (size_t i = 0U; i <= PLAT_MAX_PWR_LVL; i++) {
@@ -188,12 +188,12 @@
  *
  * @return	Returns status, either success or reason
  */
-static int versal_validate_power_state(unsigned int power_state,
+static int32_t versal_validate_power_state(uint32_t power_state,
 				       psci_power_state_t *req_state)
 {
 	VERBOSE("%s: power_state: 0x%x\n", __func__, power_state);
 
-	unsigned int pstate = psci_get_pstate_type(power_state);
+	uint32_t pstate = psci_get_pstate_type(power_state);
 
 	assert(req_state);
 
diff --git a/plat/xilinx/versal/plat_topology.c b/plat/xilinx/versal/plat_topology.c
index 66d4fae..6a94544 100644
--- a/plat/xilinx/versal/plat_topology.c
+++ b/plat/xilinx/versal/plat_topology.c
@@ -6,9 +6,9 @@
 
 #include <platform_def.h>
 
-static const unsigned char plat_power_domain_tree_desc[] = {1, PLATFORM_CORE_COUNT};
+static const uint8_t plat_power_domain_tree_desc[] = {1, PLATFORM_CORE_COUNT};
 
-const unsigned char *plat_get_power_domain_tree_desc(void)
+const uint8_t *plat_get_power_domain_tree_desc(void)
 {
 	return plat_power_domain_tree_desc;
 }
diff --git a/plat/xilinx/versal/plat_versal.c b/plat/xilinx/versal/plat_versal.c
index 54c35b6..132c7b7 100644
--- a/plat/xilinx/versal/plat_versal.c
+++ b/plat/xilinx/versal/plat_versal.c
@@ -7,7 +7,7 @@
 #include <plat_private.h>
 #include <plat/common/platform.h>
 
-int plat_core_pos_by_mpidr(u_register_t mpidr)
+int32_t plat_core_pos_by_mpidr(u_register_t mpidr)
 {
 	if ((mpidr & MPIDR_CLUSTER_MASK) != 0U) {
 		return -1;
@@ -17,5 +17,5 @@
 		return -1;
 	}
 
-	return (int)versal_calc_core_pos(mpidr);
+	return (int32_t)versal_calc_core_pos(mpidr);
 }
diff --git a/plat/xilinx/versal/pm_service/pm_api_sys.c b/plat/xilinx/versal/pm_service/pm_api_sys.c
index 04258cc..db78049 100644
--- a/plat/xilinx/versal/pm_service/pm_api_sys.c
+++ b/plat/xilinx/versal/pm_service/pm_api_sys.c
@@ -28,14 +28,14 @@
 #define MODULE_ID_MASK		0x0000ff00
 
 /* default shutdown/reboot scope is system(2) */
-static unsigned int pm_shutdown_scope = XPM_SHUTDOWN_SUBTYPE_RST_SYSTEM;
+static uint32_t pm_shutdown_scope = XPM_SHUTDOWN_SUBTYPE_RST_SYSTEM;
 
 /**
  * pm_get_shutdown_scope() - Get the currently set shutdown scope
  *
  * @return	Shutdown scope value
  */
-unsigned int pm_get_shutdown_scope(void)
+uint32_t pm_get_shutdown_scope(void)
 {
 	return pm_shutdown_scope;
 }
@@ -93,8 +93,9 @@
 	module_id = (x0 & MODULE_ID_MASK) >> 8;
 
 	//default module id is for LIBPM
-	if (module_id == 0)
+	if (module_id == 0) {
 		module_id = LIBPM_MODULE_ID;
+	}
 
 	PM_PACK_PAYLOAD6(payload, module_id, flag, x0, x1, x2, x3, x4, x5);
 	return pm_ipi_send_sync(primary_proc, payload, (uint32_t *)result, PAYLOAD_ARG_CNT);
@@ -115,12 +116,12 @@
  * @return	Returns status, either success or error+reason
  */
 enum pm_ret_status pm_self_suspend(uint32_t nid,
-				   unsigned int latency,
-				   unsigned int state,
+				   uint32_t latency,
+				   uint32_t state,
 				   uintptr_t address, uint32_t flag)
 {
 	uint32_t payload[PAYLOAD_ARG_CNT];
-	unsigned int cpuid = plat_my_core_pos();
+	uint32_t cpuid = plat_my_core_pos();
 	const struct pm_proc *proc = pm_get_proc(cpuid);
 
 	if (proc == NULL) {
@@ -182,7 +183,7 @@
  * @return	Returns status, either success or error+reason
  */
 enum pm_ret_status pm_req_suspend(uint32_t target, uint8_t ack,
-				  unsigned int latency, unsigned int state,
+				  uint32_t latency, uint32_t state,
 				  uint32_t flag)
 {
 	uint32_t payload[PAYLOAD_ARG_CNT];
@@ -501,7 +502,7 @@
 			return PM_RET_ERROR_ARGS;
 		}
 		gicd_write_irouter(gicv3_driver_data->gicd_base,
-				  (unsigned int)PLAT_VERSAL_IPI_IRQ, MODE);
+				  (uint32_t)PLAT_VERSAL_IPI_IRQ, MODE);
 		ret =  PM_RET_SUCCESS;
 		break;
 	default:
diff --git a/plat/xilinx/versal/pm_service/pm_api_sys.h b/plat/xilinx/versal/pm_service/pm_api_sys.h
index 86a46d0..8343533 100644
--- a/plat/xilinx/versal/pm_service/pm_api_sys.h
+++ b/plat/xilinx/versal/pm_service/pm_api_sys.h
@@ -18,14 +18,14 @@
 				       uint32_t x2, uint32_t x3, uint32_t x4,
 				       uint32_t x5, uint64_t *result);
 enum pm_ret_status pm_self_suspend(uint32_t nid,
-				   unsigned int latency,
-				   unsigned int state,
+				   uint32_t latency,
+				   uint32_t state,
 				   uintptr_t address, uint32_t flag);
 enum pm_ret_status pm_abort_suspend(enum pm_abort_reason reason, uint32_t flag);
 enum pm_ret_status pm_req_suspend(uint32_t target,
 				  uint8_t ack,
-				  unsigned int latency,
-				  unsigned int state, uint32_t flag);
+				  uint32_t latency,
+				  uint32_t state, uint32_t flag);
 enum pm_ret_status pm_req_wakeup(uint32_t target, uint32_t set_address,
 				 uintptr_t address, uint8_t ack, uint32_t flag);
 enum pm_ret_status pm_set_wakeup_source(uint32_t target, uint32_t device_id,
@@ -48,7 +48,7 @@
 				uint32_t *value, uint32_t flag);
 enum pm_ret_status pm_query_data(uint32_t qid, uint32_t arg1, uint32_t arg2,
 				 uint32_t arg3, uint32_t *data, uint32_t flag);
-unsigned int pm_get_shutdown_scope(void);
+uint32_t pm_get_shutdown_scope(void);
 enum pm_ret_status pm_feature_check(uint32_t api_id, uint32_t *ret_payload,
 				    uint32_t flag);
 enum pm_ret_status pm_load_pdi(uint32_t src, uint32_t address_low,
diff --git a/plat/xilinx/versal/pm_service/pm_client.c b/plat/xilinx/versal/pm_service/pm_client.c
index 4012f32..ce5e533 100644
--- a/plat/xilinx/versal/pm_service/pm_client.c
+++ b/plat/xilinx/versal/pm_service/pm_client.c
@@ -105,7 +105,7 @@
  *
  * Return:	PM node index corresponding to the specified interrupt
  */
-static enum pm_device_node_idx irq_to_pm_node_idx(unsigned int irq)
+static enum pm_device_node_idx irq_to_pm_node_idx(uint32_t irq)
 {
 	assert(irq <= IRQ_MAX);
 	return irq_node_map[irq];
@@ -170,7 +170,7 @@
  * required prior to sending suspend request to PMU
  * Actions taken depend on the state system is suspending to.
  */
-void pm_client_suspend(const struct pm_proc *proc, unsigned int state)
+void pm_client_suspend(const struct pm_proc *proc, uint32_t state)
 {
 	bakery_lock_get(&pm_client_secure_lock);
 
@@ -211,7 +211,7 @@
  *
  * Return: the cpu ID (starting from 0) for the subsystem
  */
-static unsigned int pm_get_cpuid(uint32_t nid)
+static uint32_t pm_get_cpuid(uint32_t nid)
 {
 	for (size_t i = 0U; i < ARRAY_SIZE(pm_procs_all); i++) {
 		if (pm_procs_all[i].node_id == nid) {
@@ -229,7 +229,7 @@
  */
 void pm_client_wakeup(const struct pm_proc *proc)
 {
-	unsigned int cpuid = pm_get_cpuid(proc->node_id);
+	uint32_t cpuid = pm_get_cpuid(proc->node_id);
 
 	if (cpuid == UNDEFINED_CPUID) {
 		return;
@@ -251,7 +251,7 @@
  *
  * Return: pointer to a proc structure if proc is found, otherwise NULL
  */
-const struct pm_proc *pm_get_proc(unsigned int cpuid)
+const struct pm_proc *pm_get_proc(uint32_t cpuid)
 {
 	if (cpuid < ARRAY_SIZE(pm_procs_all)) {
 		return &pm_procs_all[cpuid];
diff --git a/plat/xilinx/versal/pm_service/pm_svc_main.c b/plat/xilinx/versal/pm_service/pm_svc_main.c
index 24b68e7..f4d04b8 100644
--- a/plat/xilinx/versal/pm_service/pm_svc_main.c
+++ b/plat/xilinx/versal/pm_service/pm_svc_main.c
@@ -25,19 +25,19 @@
 
 /* pm_up = true - UP, pm_up = false - DOWN */
 static bool pm_up;
-static unsigned int sgi = (unsigned int)INVALID_SGI;
+static uint32_t sgi = (uint32_t)INVALID_SGI;
 
 static uint64_t ipi_fiq_handler(uint32_t id, uint32_t flags, void *handle,
 				void *cookie)
 {
-	unsigned int cpu;
-	unsigned int reg;
+	uint32_t cpu;
+	uint32_t reg;
 
 	(void)plat_ic_acknowledge_interrupt();
 	cpu = plat_my_core_pos() + 1U;
 
-	if ((unsigned int)sgi != (unsigned int)INVALID_SGI) {
-		reg = (cpu | ((unsigned int)sgi << (unsigned int)XSCUGIC_SGIR_EL1_INITID_SHIFT));
+	if ((uint32_t)sgi != (uint32_t)INVALID_SGI) {
+		reg = (cpu | ((uint32_t)sgi << (uint32_t)XSCUGIC_SGIR_EL1_INITID_SHIFT));
 		write_icc_asgi1r_el1(reg);
 	}
 
@@ -59,7 +59,7 @@
  * Update the SGI number to be used.
  *
  */
-int pm_register_sgi(unsigned int sgi_num, unsigned int reset)
+int pm_register_sgi(uint32_t sgi_num, uint32_t reset)
 {
 	if (reset == 1U) {
 		sgi = INVALID_SGI;
@@ -74,7 +74,7 @@
 		return -EINVAL;
 	}
 
-	sgi = (unsigned int)sgi_num;
+	sgi = (uint32_t)sgi_num;
 	return 0;
 }
 
@@ -93,7 +93,7 @@
  */
 int pm_setup(void)
 {
-	int status, ret = 0;
+	int32_t status, ret = 0;
 
 	status = pm_ipi_init(primary_proc);
 
@@ -239,7 +239,7 @@
 
 	case TF_A_PM_REGISTER_SGI:
 	{
-		int ret;
+		int32_t ret;
 
 		ret = pm_register_sgi(pm_arg[0], pm_arg[1]);
 		if (ret != 0) {
@@ -324,7 +324,7 @@
  * function with rt_svc_handle signature
  */
 uint64_t pm_smc_handler(uint32_t smc_fid, uint64_t x1, uint64_t x2, uint64_t x3,
-			uint64_t x4, void *cookie, void *handle, uint64_t flags)
+			uint64_t x4, const void *cookie, void *handle, uint64_t flags)
 {
 	uintptr_t ret;
 	uint32_t pm_arg[PAYLOAD_ARG_CNT] = {0};
@@ -332,8 +332,9 @@
 	uint32_t api_id;
 
 	/* Handle case where PM wasn't initialized properly */
-	if (!pm_up)
+	if (!pm_up) {
 		SMC_RET1(handle, SMC_UNK);
+	}
 
 	/*
 	 * Mark BIT24 payload (i.e 1st bit of pm_arg[3] ) as non-secure (1)
@@ -352,16 +353,19 @@
 	api_id = smc_fid & FUNCID_NUM_MASK;
 
 	ret = eemi_for_compatibility(api_id, pm_arg, handle, security_flag);
-	if (ret != (uintptr_t)0)
+	if (ret != (uintptr_t)0) {
 		return ret;
+	}
 
 	ret = eemi_psci_debugfs_handler(api_id, pm_arg, handle, flags);
-	if (ret !=  (uintptr_t)0)
+	if (ret !=  (uintptr_t)0) {
 		return ret;
+	}
 
 	ret = TF_A_specific_handler(api_id, pm_arg, handle, security_flag);
-	if (ret !=  (uintptr_t)0)
+	if (ret !=  (uintptr_t)0) {
 		return ret;
+	}
 
 	ret = eemi_handler(api_id, pm_arg, handle, security_flag);
 
diff --git a/plat/xilinx/versal/pm_service/pm_svc_main.h b/plat/xilinx/versal/pm_service/pm_svc_main.h
index 2dff5b2..b6e764f 100644
--- a/plat/xilinx/versal/pm_service/pm_svc_main.h
+++ b/plat/xilinx/versal/pm_service/pm_svc_main.h
@@ -9,10 +9,10 @@
 
 #include <pm_common.h>
 
-int pm_setup(void);
+int32_t pm_setup(void);
 uint64_t pm_smc_handler(uint32_t smc_fid, uint64_t x1, uint64_t x2, uint64_t x3,
-			uint64_t x4, void *cookie, void *handle,
+			uint64_t x4, const void *cookie, void *handle,
 			uint64_t flags);
 
-int pm_register_sgi(unsigned int sgi_num, unsigned int reset);
+int32_t pm_register_sgi(uint32_t sgi_num, uint32_t reset);
 #endif /* PM_SVC_MAIN_H */
diff --git a/plat/xilinx/versal/versal_gicv3.c b/plat/xilinx/versal/versal_gicv3.c
index 08e7cf9..d410906 100644
--- a/plat/xilinx/versal/versal_gicv3.c
+++ b/plat/xilinx/versal/versal_gicv3.c
@@ -53,7 +53,7 @@
  *   - All CPUs implemented in the system have MPIDR_EL1.MT bit set;
  *   - No CPUs implemented in the system use affinity level 3.
  */
-static unsigned int versal_gicv3_mpidr_hash(u_register_t mpidr)
+static uint32_t versal_gicv3_mpidr_hash(u_register_t mpidr)
 {
 	mpidr |= (read_mpidr_el1() & MPIDR_MT_MASK);
 	return versal_calc_core_pos(mpidr);
diff --git a/plat/xilinx/zynqmp/include/platform_def.h b/plat/xilinx/zynqmp/include/platform_def.h
index 9c1600a..66bbf30 100644
--- a/plat/xilinx/zynqmp/include/platform_def.h
+++ b/plat/xilinx/zynqmp/include/platform_def.h
@@ -40,8 +40,8 @@
 # define BL31_BASE			U(0xfffea000)
 # define BL31_LIMIT			U(0x100000000)
 #else
-# define BL31_BASE			U(0x1000)
-# define BL31_LIMIT			U(0x7ffff)
+# define BL31_BASE			U(0xfff5a000)
+# define BL31_LIMIT			U(0x100000000)
 #endif
 #else
 # define BL31_BASE			(ZYNQMP_ATF_MEM_BASE)
diff --git a/plat/xilinx/zynqmp/pm_service/pm_svc_main.c b/plat/xilinx/zynqmp/pm_service/pm_svc_main.c
index 953bb4a..493ff85 100644
--- a/plat/xilinx/zynqmp/pm_service/pm_svc_main.c
+++ b/plat/xilinx/zynqmp/pm_service/pm_svc_main.c
@@ -255,7 +255,7 @@
  * function with rt_svc_handle signature
  */
 uint64_t pm_smc_handler(uint32_t smc_fid, uint64_t x1, uint64_t x2, uint64_t x3,
-			uint64_t x4, void *cookie, void *handle, uint64_t flags)
+			uint64_t x4, const void *cookie, void *handle, uint64_t flags)
 {
 	enum pm_ret_status ret;
 	uint32_t payload[PAYLOAD_ARG_CNT];
@@ -575,7 +575,7 @@
  * function with rt_svc_handle signature
  */
 uint64_t em_smc_handler(uint32_t smc_fid, uint64_t x1, uint64_t x2, uint64_t x3,
-			uint64_t x4, void *cookie, void *handle, uint64_t flags)
+			uint64_t x4, const void *cookie, void *handle, uint64_t flags)
 {
 	enum pm_ret_status ret;
 
diff --git a/plat/xilinx/zynqmp/pm_service/pm_svc_main.h b/plat/xilinx/zynqmp/pm_service/pm_svc_main.h
index abadd40..9cff3cb 100644
--- a/plat/xilinx/zynqmp/pm_service/pm_svc_main.h
+++ b/plat/xilinx/zynqmp/pm_service/pm_svc_main.h
@@ -11,10 +11,10 @@
 
 int pm_setup(void);
 uint64_t pm_smc_handler(uint32_t smc_fid, uint64_t x1, uint64_t x2, uint64_t x3,
-			uint64_t x4, void *cookie, void *handle,
+			uint64_t x4, const void *cookie, void *handle,
 			uint64_t flags);
 
 uint64_t em_smc_handler(uint32_t smc_fid, uint64_t x1, uint64_t x2, uint64_t x3,
-			uint64_t x4, void *cookie, void *handle,
+			uint64_t x4, const void *cookie, void *handle,
 			uint64_t flags);
 #endif /* PM_SVC_MAIN_H */
diff --git a/tools/cert_create/Makefile b/tools/cert_create/Makefile
index ca548b8..d951286 100644
--- a/tools/cert_create/Makefile
+++ b/tools/cert_create/Makefile
@@ -35,6 +35,8 @@
   include src/tbbr/tbbr.mk
 else ifeq (${COT},dualroot)
   include src/dualroot/cot.mk
+else ifeq (${COT},cca)
+  include src/cca/cot.mk
 else
   $(error Unknown chain of trust ${COT})
 endif
diff --git a/tools/cert_create/include/cca/cca_cot.h b/tools/cert_create/include/cca/cca_cot.h
new file mode 100644
index 0000000..56585fb
--- /dev/null
+++ b/tools/cert_create/include/cca/cca_cot.h
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2022, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef CCA_COT_H
+#define CCA_COT_H
+
+/* Certificates. */
+enum {
+	/* Certificates owned by the silicon provider. */
+	CCA_CONTENT_CERT,
+	CORE_SWD_KEY_CERT,
+	SPMC_CONTENT_CERT,
+	SIP_SECURE_PARTITION_CONTENT_CERT,
+
+	/* Certificates owned by the platform owner. */
+	PLAT_KEY_CERT,
+	PLAT_SECURE_PARTITION_CONTENT_CERT,
+	NON_TRUSTED_FW_CONTENT_CERT,
+};
+
+/* Certificate extensions. */
+enum {
+	/* Extensions used in certificates owned by the silicon provider. */
+	TRUSTED_FW_NVCOUNTER_EXT,
+	TRUSTED_BOOT_FW_HASH_EXT,
+	TRUSTED_BOOT_FW_CONFIG_HASH_EXT,
+	HW_CONFIG_HASH_EXT,
+	FW_CONFIG_HASH_EXT,
+	SWD_ROT_PK_EXT,
+	CORE_SWD_PK_EXT,
+	SOC_AP_FW_HASH_EXT,
+	SOC_FW_CONFIG_HASH_EXT,
+	RMM_HASH_EXT,
+	TRUSTED_OS_FW_HASH_EXT,
+	TRUSTED_OS_FW_CONFIG_HASH_EXT,
+	SP_PKG1_HASH_EXT,
+	SP_PKG2_HASH_EXT,
+	SP_PKG3_HASH_EXT,
+	SP_PKG4_HASH_EXT,
+
+	/* Extensions used in certificates owned by the platform owner. */
+	PROT_PK_EXT,
+	PLAT_PK_EXT,
+	SP_PKG5_HASH_EXT,
+	SP_PKG6_HASH_EXT,
+	SP_PKG7_HASH_EXT,
+	SP_PKG8_HASH_EXT,
+	NON_TRUSTED_FW_NVCOUNTER_EXT,
+	NON_TRUSTED_WORLD_BOOTLOADER_HASH_EXT,
+	NON_TRUSTED_FW_CONFIG_HASH_EXT,
+};
+
+/* Keys. */
+enum {
+	/* Keys owned by the silicon provider. */
+	ROT_KEY,
+	SWD_ROT_KEY,
+	CORE_SWD_KEY,
+
+	/* Keys owned by the platform owner. */
+	PROT_KEY,
+	PLAT_KEY,
+};
+
+#endif /* CCA_COT_H */
diff --git a/tools/cert_create/src/cca/cot.c b/tools/cert_create/src/cca/cot.c
new file mode 100644
index 0000000..5a35ff6
--- /dev/null
+++ b/tools/cert_create/src/cca/cot.c
@@ -0,0 +1,439 @@
+/*
+ * Copyright (c) 2022, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include "cca/cca_cot.h"
+
+#include <cca_oid.h>
+
+#include "cert.h"
+#include "ext.h"
+#include "key.h"
+
+/*
+ * Certificates used in the chain of trust.
+ *
+ * All certificates are self-signed so the issuer certificate field points to
+ * itself.
+ */
+static cert_t cot_certs[] = {
+	[CCA_CONTENT_CERT] = {
+		.id = CCA_CONTENT_CERT,
+		.opt = "cca-cert",
+		.help_msg = "CCA Content Certificate (output file)",
+		.cn = "CCA Content Certificate",
+		.key = ROT_KEY,
+		.issuer = CCA_CONTENT_CERT,
+		.ext = {
+			TRUSTED_FW_NVCOUNTER_EXT,
+			SOC_AP_FW_HASH_EXT,
+			SOC_FW_CONFIG_HASH_EXT,
+			RMM_HASH_EXT,
+			TRUSTED_BOOT_FW_HASH_EXT,
+			TRUSTED_BOOT_FW_CONFIG_HASH_EXT,
+			HW_CONFIG_HASH_EXT,
+			FW_CONFIG_HASH_EXT,
+		},
+		.num_ext = 8
+	},
+
+	[CORE_SWD_KEY_CERT] = {
+		.id = CORE_SWD_KEY_CERT,
+		.opt = "core-swd-cert",
+		.help_msg = "Core Secure World Key Certificate (output file)",
+		.cn = "Core Secure World Key Certificate",
+		.key = SWD_ROT_KEY,
+		.issuer = CORE_SWD_KEY_CERT,
+		.ext = {
+			TRUSTED_FW_NVCOUNTER_EXT,
+			SWD_ROT_PK_EXT,
+			CORE_SWD_PK_EXT,
+		},
+		.num_ext = 3
+	},
+
+	[SPMC_CONTENT_CERT] = {
+		.id = SPMC_CONTENT_CERT,
+		.opt = "tos-fw-cert",
+		.help_msg = "SPMC Content Certificate (output file)",
+		.cn = "SPMC Content Certificate",
+		.key = CORE_SWD_KEY,
+		.issuer = SPMC_CONTENT_CERT,
+		.ext = {
+			TRUSTED_FW_NVCOUNTER_EXT,
+			TRUSTED_OS_FW_HASH_EXT,
+			TRUSTED_OS_FW_CONFIG_HASH_EXT,
+		},
+		.num_ext = 3
+	},
+
+	[SIP_SECURE_PARTITION_CONTENT_CERT] = {
+		.id = SIP_SECURE_PARTITION_CONTENT_CERT,
+		.opt = "sip-sp-cert",
+		.help_msg = "SiP owned Secure Partition Content Certificate (output file)",
+		.cn = "SiP owned Secure Partition Content Certificate",
+		.key = CORE_SWD_KEY,
+		.issuer = SIP_SECURE_PARTITION_CONTENT_CERT,
+		.ext = {
+			TRUSTED_FW_NVCOUNTER_EXT,
+			SP_PKG1_HASH_EXT,
+			SP_PKG2_HASH_EXT,
+			SP_PKG3_HASH_EXT,
+			SP_PKG4_HASH_EXT,
+		},
+		.num_ext = 5
+	},
+
+	[PLAT_KEY_CERT] = {
+		.id = PLAT_KEY_CERT,
+		.opt = "plat-key-cert",
+		.help_msg = "Platform Key Certificate (output file)",
+		.cn = "Platform Key Certificate",
+		.key = PROT_KEY,
+		.issuer = PLAT_KEY_CERT,
+		.ext = {
+			NON_TRUSTED_FW_NVCOUNTER_EXT,
+			PROT_PK_EXT,
+			PLAT_PK_EXT,
+		},
+		.num_ext = 3
+	},
+
+	[PLAT_SECURE_PARTITION_CONTENT_CERT] = {
+		.id = PLAT_SECURE_PARTITION_CONTENT_CERT,
+		.opt = "plat-sp-cert",
+		.help_msg = "Platform owned Secure Partition Content Certificate (output file)",
+		.cn = "Platform owned Secure Partition Content Certificate",
+		.key = PLAT_KEY,
+		.issuer = PLAT_SECURE_PARTITION_CONTENT_CERT,
+		.ext = {
+			NON_TRUSTED_FW_NVCOUNTER_EXT,
+			SP_PKG5_HASH_EXT,
+			SP_PKG6_HASH_EXT,
+			SP_PKG7_HASH_EXT,
+			SP_PKG8_HASH_EXT,
+		},
+		.num_ext = 5
+	},
+
+	[NON_TRUSTED_FW_CONTENT_CERT] = {
+		.id = NON_TRUSTED_FW_CONTENT_CERT,
+		.opt = "nt-fw-cert",
+		.help_msg = "Non-Trusted Firmware Content Certificate (output file)",
+		.cn = "Non-Trusted Firmware Content Certificate",
+		.key = PLAT_KEY,
+		.issuer = NON_TRUSTED_FW_CONTENT_CERT,
+		.ext = {
+			NON_TRUSTED_FW_NVCOUNTER_EXT,
+			NON_TRUSTED_WORLD_BOOTLOADER_HASH_EXT,
+			NON_TRUSTED_FW_CONFIG_HASH_EXT,
+		},
+		.num_ext = 3
+	},
+};
+
+REGISTER_COT(cot_certs);
+
+
+/* Certificate extensions. */
+static ext_t cot_ext[] = {
+	[TRUSTED_FW_NVCOUNTER_EXT] = {
+		.oid = TRUSTED_FW_NVCOUNTER_OID,
+		.opt = "tfw-nvctr",
+		.help_msg = "Trusted Firmware Non-Volatile counter value",
+		.sn = "TrustedWorldNVCounter",
+		.ln = "Trusted World Non-Volatile counter",
+		.asn1_type = V_ASN1_INTEGER,
+		.type = EXT_TYPE_NVCOUNTER,
+		.attr.nvctr_type = NVCTR_TYPE_TFW
+	},
+
+	[TRUSTED_BOOT_FW_HASH_EXT] = {
+		.oid = TRUSTED_BOOT_FW_HASH_OID,
+		.opt = "tb-fw",
+		.help_msg = "Trusted Boot Firmware image file",
+		.sn = "TrustedBootFirmwareHash",
+		.ln = "Trusted Boot Firmware hash (SHA256)",
+		.asn1_type = V_ASN1_OCTET_STRING,
+		.type = EXT_TYPE_HASH
+	},
+
+	[TRUSTED_BOOT_FW_CONFIG_HASH_EXT] = {
+		.oid = TRUSTED_BOOT_FW_CONFIG_HASH_OID,
+		.opt = "tb-fw-config",
+		.help_msg = "Trusted Boot Firmware Config file",
+		.sn = "TrustedBootFirmwareConfigHash",
+		.ln = "Trusted Boot Firmware Config hash",
+		.asn1_type = V_ASN1_OCTET_STRING,
+		.type = EXT_TYPE_HASH,
+		.optional = 1
+	},
+
+	[HW_CONFIG_HASH_EXT] = {
+		.oid = HW_CONFIG_HASH_OID,
+		.opt = "hw-config",
+		.help_msg = "HW Config file",
+		.sn = "HWConfigHash",
+		.ln = "HW Config hash",
+		.asn1_type = V_ASN1_OCTET_STRING,
+		.type = EXT_TYPE_HASH,
+		.optional = 1
+	},
+
+	[FW_CONFIG_HASH_EXT] = {
+		.oid = FW_CONFIG_HASH_OID,
+		.opt = "fw-config",
+		.help_msg = "Firmware Config file",
+		.sn = "FirmwareConfigHash",
+		.ln = "Firmware Config hash",
+		.asn1_type = V_ASN1_OCTET_STRING,
+		.type = EXT_TYPE_HASH,
+		.optional = 1
+	},
+
+	[SWD_ROT_PK_EXT] = {
+		.oid = SWD_ROT_PK_OID,
+		.sn = "SWDRoTKey",
+		.ln = "Secure World Root of Trust Public Key",
+		.asn1_type = V_ASN1_OCTET_STRING,
+		.type = EXT_TYPE_PKEY,
+		.attr.key = SWD_ROT_KEY
+	},
+
+	[CORE_SWD_PK_EXT] = {
+		.oid = CORE_SWD_PK_OID,
+		.sn = "CORESWDKey",
+		.ln = "Core Secure World Public Key",
+		.asn1_type = V_ASN1_OCTET_STRING,
+		.type = EXT_TYPE_PKEY,
+		.attr.key = CORE_SWD_KEY
+	},
+
+	[SOC_AP_FW_HASH_EXT] = {
+		.oid = SOC_AP_FW_HASH_OID,
+		.opt = "soc-fw",
+		.help_msg = "SoC AP Firmware image file",
+		.sn = "SoCAPFirmwareHash",
+		.ln = "SoC AP Firmware hash (SHA256)",
+		.asn1_type = V_ASN1_OCTET_STRING,
+		.type = EXT_TYPE_HASH
+	},
+
+	[SOC_FW_CONFIG_HASH_EXT] = {
+		.oid = SOC_FW_CONFIG_HASH_OID,
+		.opt = "soc-fw-config",
+		.help_msg = "SoC Firmware Config file",
+		.sn = "SocFirmwareConfigHash",
+		.ln = "SoC Firmware Config hash",
+		.asn1_type = V_ASN1_OCTET_STRING,
+		.type = EXT_TYPE_HASH,
+		.optional = 1
+	},
+
+	[RMM_HASH_EXT] = {
+		.oid = RMM_HASH_OID,
+		.opt = "rmm-fw",
+		.help_msg = "RMM Firmware image file",
+		.sn = "RMMFirmwareHash",
+		.ln = "RMM Firmware hash (SHA256)",
+		.asn1_type = V_ASN1_OCTET_STRING,
+		.type = EXT_TYPE_HASH
+	},
+
+	[TRUSTED_OS_FW_HASH_EXT] = {
+		.oid = TRUSTED_OS_FW_HASH_OID,
+		.opt = "tos-fw",
+		.help_msg = "Trusted OS image file",
+		.sn = "TrustedOSHash",
+		.ln = "Trusted OS hash (SHA256)",
+		.asn1_type = V_ASN1_OCTET_STRING,
+		.type = EXT_TYPE_HASH
+	},
+
+	[TRUSTED_OS_FW_CONFIG_HASH_EXT] = {
+		.oid = TRUSTED_OS_FW_CONFIG_HASH_OID,
+		.opt = "tos-fw-config",
+		.help_msg = "Trusted OS Firmware Config file",
+		.sn = "TrustedOSFirmwareConfigHash",
+		.ln = "Trusted OS Firmware Config hash",
+		.asn1_type = V_ASN1_OCTET_STRING,
+		.type = EXT_TYPE_HASH,
+		.optional = 1
+	},
+
+	[SP_PKG1_HASH_EXT] = {
+		.oid = SP_PKG1_HASH_OID,
+		.opt = "sp-pkg1",
+		.help_msg = "Secure Partition Package1 file",
+		.sn = "SPPkg1Hash",
+		.ln = "SP Pkg1 hash (SHA256)",
+		.asn1_type = V_ASN1_OCTET_STRING,
+		.type = EXT_TYPE_HASH,
+		.optional = 1
+	},
+	[SP_PKG2_HASH_EXT] = {
+		.oid = SP_PKG2_HASH_OID,
+		.opt = "sp-pkg2",
+		.help_msg = "Secure Partition Package2 file",
+		.sn = "SPPkg2Hash",
+		.ln = "SP Pkg2 hash (SHA256)",
+		.asn1_type = V_ASN1_OCTET_STRING,
+		.type = EXT_TYPE_HASH,
+		.optional = 1
+	},
+	[SP_PKG3_HASH_EXT] = {
+		.oid = SP_PKG3_HASH_OID,
+		.opt = "sp-pkg3",
+		.help_msg = "Secure Partition Package3 file",
+		.sn = "SPPkg3Hash",
+		.ln = "SP Pkg3 hash (SHA256)",
+		.asn1_type = V_ASN1_OCTET_STRING,
+		.type = EXT_TYPE_HASH,
+		.optional = 1
+	},
+	[SP_PKG4_HASH_EXT] = {
+		.oid = SP_PKG4_HASH_OID,
+		.opt = "sp-pkg4",
+		.help_msg = "Secure Partition Package4 file",
+		.sn = "SPPkg4Hash",
+		.ln = "SP Pkg4 hash (SHA256)",
+		.asn1_type = V_ASN1_OCTET_STRING,
+		.type = EXT_TYPE_HASH,
+		.optional = 1
+	},
+
+	[PROT_PK_EXT] = {
+		.oid = PROT_PK_OID,
+		.sn = "PlatformRoTKey",
+		.ln = "Platform Root of Trust Public Key",
+		.asn1_type = V_ASN1_OCTET_STRING,
+		.type = EXT_TYPE_PKEY,
+		.attr.key = PROT_KEY
+	},
+
+	[PLAT_PK_EXT] = {
+		.oid = PLAT_PK_OID,
+		.sn = "PLATKey",
+		.ln = "Platform Public Key",
+		.asn1_type = V_ASN1_OCTET_STRING,
+		.type = EXT_TYPE_PKEY,
+		.attr.key = PLAT_KEY
+	},
+
+	[SP_PKG5_HASH_EXT] = {
+		.oid = SP_PKG5_HASH_OID,
+		.opt = "sp-pkg5",
+		.help_msg = "Secure Partition Package5 file",
+		.sn = "SPPkg5Hash",
+		.ln = "SP Pkg5 hash (SHA256)",
+		.asn1_type = V_ASN1_OCTET_STRING,
+		.type = EXT_TYPE_HASH,
+		.optional = 1
+	},
+	[SP_PKG6_HASH_EXT] = {
+		.oid = SP_PKG6_HASH_OID,
+		.opt = "sp-pkg6",
+		.help_msg = "Secure Partition Package6 file",
+		.sn = "SPPkg6Hash",
+		.ln = "SP Pkg6 hash (SHA256)",
+		.asn1_type = V_ASN1_OCTET_STRING,
+		.type = EXT_TYPE_HASH,
+		.optional = 1
+	},
+	[SP_PKG7_HASH_EXT] = {
+		.oid = SP_PKG7_HASH_OID,
+		.opt = "sp-pkg7",
+		.help_msg = "Secure Partition Package7 file",
+		.sn = "SPPkg7Hash",
+		.ln = "SP Pkg7 hash (SHA256)",
+		.asn1_type = V_ASN1_OCTET_STRING,
+		.type = EXT_TYPE_HASH,
+		.optional = 1
+	},
+	[SP_PKG8_HASH_EXT] = {
+		.oid = SP_PKG8_HASH_OID,
+		.opt = "sp-pkg8",
+		.help_msg = "Secure Partition Package8 file",
+		.sn = "SPPkg8Hash",
+		.ln = "SP Pkg8 hash (SHA256)",
+		.asn1_type = V_ASN1_OCTET_STRING,
+		.type = EXT_TYPE_HASH,
+		.optional = 1
+	},
+
+	[NON_TRUSTED_FW_NVCOUNTER_EXT] = {
+		.oid = NON_TRUSTED_FW_NVCOUNTER_OID,
+		.opt = "ntfw-nvctr",
+		.help_msg = "Non-Trusted Firmware Non-Volatile counter value",
+		.sn = "NormalWorldNVCounter",
+		.ln = "Non-Trusted Firmware Non-Volatile counter",
+		.asn1_type = V_ASN1_INTEGER,
+		.type = EXT_TYPE_NVCOUNTER,
+		.attr.nvctr_type = NVCTR_TYPE_NTFW
+	},
+
+	[NON_TRUSTED_WORLD_BOOTLOADER_HASH_EXT] = {
+		.oid = NON_TRUSTED_WORLD_BOOTLOADER_HASH_OID,
+		.opt = "nt-fw",
+		.help_msg = "Non-Trusted World Bootloader image file",
+		.sn = "NonTrustedWorldBootloaderHash",
+		.ln = "Non-Trusted World hash (SHA256)",
+		.asn1_type = V_ASN1_OCTET_STRING,
+		.type = EXT_TYPE_HASH
+	},
+
+	[NON_TRUSTED_FW_CONFIG_HASH_EXT] = {
+		.oid = NON_TRUSTED_FW_CONFIG_HASH_OID,
+		.opt = "nt-fw-config",
+		.help_msg = "Non Trusted OS Firmware Config file",
+		.sn = "NonTrustedOSFirmwareConfigHash",
+		.ln = "Non-Trusted OS Firmware Config hash",
+		.asn1_type = V_ASN1_OCTET_STRING,
+		.type = EXT_TYPE_HASH,
+		.optional = 1
+	},
+};
+
+REGISTER_EXTENSIONS(cot_ext);
+
+/* Keys used to establish the chain of trust. */
+static key_t cot_keys[] = {
+	[ROT_KEY] = {
+		.id = ROT_KEY,
+		.opt = "rot-key",
+		.help_msg = "Root Of Trust key (input/output file)",
+		.desc = "Root Of Trust key"
+	},
+
+	[SWD_ROT_KEY] = {
+		.id = SWD_ROT_KEY,
+		.opt = "swd-rot-key",
+		.help_msg = "Secure World Root of Trust key",
+		.desc = "Secure World Root of Trust key"
+	},
+
+	[CORE_SWD_KEY] = {
+		.id = CORE_SWD_KEY,
+		.opt = "core-swd-key",
+		.help_msg = "Core Secure World key",
+		.desc = "Core Secure World key"
+	},
+
+	[PROT_KEY] = {
+		.id = PROT_KEY,
+		.opt = "prot-key",
+		.help_msg = "Platform Root of Trust key",
+		.desc = "Platform Root of Trust key"
+	},
+
+	[PLAT_KEY] = {
+		.id = PLAT_KEY,
+		.opt = "plat-key",
+		.help_msg = "Platform key",
+		.desc = "Platform key"
+	},
+};
+
+REGISTER_KEYS(cot_keys);
diff --git a/tools/cert_create/src/cca/cot.mk b/tools/cert_create/src/cca/cot.mk
new file mode 100644
index 0000000..d0c80bb
--- /dev/null
+++ b/tools/cert_create/src/cca/cot.mk
@@ -0,0 +1,10 @@
+#
+# Copyright (c) 2022, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+PLAT_MSG		:=	Confidential Compute Architecture root of trust
+PLAT_INCLUDE		:=	../../include/tools_share
+
+OBJECTS += src/cca/cot.o
diff --git a/tools/fiptool/tbbr_config.c b/tools/fiptool/tbbr_config.c
index 4998bb2..cdbf389 100644
--- a/tools/fiptool/tbbr_config.c
+++ b/tools/fiptool/tbbr_config.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016-2021, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2022, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -172,6 +172,21 @@
 		.cmdline_name = "plat-sp-cert"
 	},
 	{
+		.name = "CCA Content Certificate",
+		.uuid = UUID_CCA_CONTENT_CERT,
+		.cmdline_name = "cca-cert"
+	},
+	{
+		.name = "Core Secure World Key Certificate",
+		.uuid = UUID_CORE_SWD_KEY_CERT,
+		.cmdline_name = "core-swd-cert"
+	},
+	{
+		.name = "Platform Key Certificate",
+		.uuid = UUID_PLAT_KEY_CERT,
+		.cmdline_name = "plat-key-cert"
+	},
+	{
 		.name = NULL,
 		.uuid = { {0} },
 		.cmdline_name = NULL,