fix(intel): update FCS AES method for GCM block modes

On the Agilex5 platform, AES enc/dec with GCM and GCM-GHASH
modes, the source and destination size should be in multiples
of 16 bytes. For other platforms and other modes, it should
be in multiples of 32 bytes.

Change-Id: I0fa9adafb5d7fc4c794a4acb9339cf8259df0c78
Signed-off-by: Girisha Dengi <girisha.dengi@intel.com>
Signed-off-by: Jit Loon Lim <jit.loon.lim@altera.com>
diff --git a/plat/intel/soc/common/include/socfpga_fcs.h b/plat/intel/soc/common/include/socfpga_fcs.h
index f92678f..97ea850 100644
--- a/plat/intel/soc/common/include/socfpga_fcs.h
+++ b/plat/intel/soc/common/include/socfpga_fcs.h
@@ -362,7 +362,7 @@
 				uint32_t session_id, uint32_t context_id,
 				uint64_t src_addr, uint32_t src_size,
 				uint64_t dst_addr, uint32_t dst_size,
-				uint32_t aad_size, uint8_t is_finalised,
+				uint32_t padding_size, uint8_t is_finalised,
 				uint32_t *send_id, uint64_t smmu_src_addr,
 				uint64_t smmu_dst_addr);
 
diff --git a/plat/intel/soc/common/include/socfpga_mailbox.h b/plat/intel/soc/common/include/socfpga_mailbox.h
index f965b7d..29b76ab 100644
--- a/plat/intel/soc/common/include/socfpga_mailbox.h
+++ b/plat/intel/soc/common/include/socfpga_mailbox.h
@@ -309,7 +309,7 @@
 				((client_id << MBOX_CLIENT_ID_SHIFT) |	 \
 				(job_id << MBOX_JOB_ID_SHIFT) |		 \
 				(args_len << MBOX_CMD_LEN_SHIFT) |	 \
-				(indirect << MBOX_CMD_LEN_SHIFT) |	 \
+				(indirect << MBOX_INDIRECT_SHIFT) |	 \
 				cmd)
 
 #define FLAG_SDM_RESPONSE_IS_VALID			BIT(0)
diff --git a/plat/intel/soc/common/sip/socfpga_sip_fcs.c b/plat/intel/soc/common/sip/socfpga_sip_fcs.c
index b9c7b59..443f6b1 100644
--- a/plat/intel/soc/common/sip/socfpga_sip_fcs.c
+++ b/plat/intel/soc/common/sip/socfpga_sip_fcs.c
@@ -304,6 +304,17 @@
 	}
 }
 
+/* As of now used on only Agilex5 platform. */
+#if PLATFORM_MODEL == PLAT_SOCFPGA_AGILEX5
+static bool is_16_bytes_aligned(uint32_t data)
+{
+	if ((data % (MBOX_WORD_BYTE * 4U)) != 0U)
+		return false;
+	else
+		return true;
+}
+#endif
+
 static bool is_32_bytes_aligned(uint32_t data)
 {
 	if ((data % (8U * MBOX_WORD_BYTE)) != 0U) {
@@ -2708,7 +2719,7 @@
 				uint32_t session_id, uint32_t context_id,
 				uint64_t src_addr, uint32_t src_size,
 				uint64_t dst_addr, uint32_t dst_size,
-				uint32_t aad_size, uint8_t is_finalised,
+				uint32_t padding_size, uint8_t is_finalised,
 				uint32_t *send_id, uint64_t smmu_src_addr,
 				uint64_t smmu_dst_addr)
 {
@@ -2719,20 +2730,42 @@
 	uint32_t fcs_aes_crypt_payload[FCS_AES_CMD_MAX_WORD_SIZE];
 	uint32_t src_addr_sdm = (uint32_t)src_addr;
 	uint32_t dst_addr_sdm = (uint32_t)dst_addr;
+	bool is_src_size_aligned;
+	bool is_dst_size_aligned;
 
 	if (fcs_aes_init_payload.session_id != session_id ||
 		fcs_aes_init_payload.context_id != context_id) {
 		return INTEL_SIP_SMC_STATUS_REJECTED;
 	}
 
+	/* Default source and destination size align check, 32 bytes alignment. */
+	is_src_size_aligned = is_32_bytes_aligned(src_size);
+	is_dst_size_aligned = is_32_bytes_aligned(dst_size);
+
+	/*
+	 * Get the requested block mode.
+	 * On the Agilex5 platform with GCM and GCM-GHASH modes, the source and destination size
+	 * should be in multiples of 16 bytes. For other platforms and other modes, it should be
+	 * in multiples of 32 bytes.
+	 */
+#if PLATFORM_MODEL == PLAT_SOCFPGA_AGILEX5
+	uint32_t block_mode = fcs_aes_init_payload.crypto_param[0] & FCS_CRYPTO_BLOCK_MODE_MASK;
+
+	if ((block_mode == FCS_CRYPTO_GCM_MODE) ||
+	    (block_mode == FCS_CRYPTO_GCM_GHASH_MODE)) {
+		is_src_size_aligned = is_16_bytes_aligned(src_size);
+		is_dst_size_aligned = is_16_bytes_aligned(dst_size);
+	}
+#endif
+
 	if ((!is_8_bytes_aligned(src_addr)) ||
-		(!is_32_bytes_aligned(src_size)) ||
+		(!is_src_size_aligned) ||
 		(!is_address_in_ddr_range(src_addr, src_size))) {
 		return INTEL_SIP_SMC_STATUS_REJECTED;
 	}
 
 	if ((!is_8_bytes_aligned(dst_addr)) ||
-		(!is_32_bytes_aligned(dst_size)) ||
+		(!is_dst_size_aligned) ||
 		(!is_address_in_ddr_range(dst_addr, dst_size))) {
 		return INTEL_SIP_SMC_STATUS_REJECTED;
 	}
@@ -2802,11 +2835,14 @@
 	fcs_aes_crypt_payload[i] = dst_size;
 	i++;
 
-	/* Additional Authenticated Data size */
-	if (aad_size > 0) {
-		fcs_aes_crypt_payload[i] = aad_size;
+	/* Padding data size, only on Agilex5 with GCM and GCM-GHASH modes. */
+#if PLATFORM_MODEL == PLAT_SOCFPGA_AGILEX5
+	if ((block_mode == FCS_CRYPTO_GCM_MODE) ||
+	    (block_mode == FCS_CRYPTO_GCM_GHASH_MODE)) {
+		fcs_aes_crypt_payload[i] = padding_size;
 		i++;
 	}
+#endif
 
 	status = ((smc_fid == ALTERA_SIP_SMC_ASYNC_FCS_AES_CRYPT_UPDATE) ||
 		  (smc_fid == ALTERA_SIP_SMC_ASYNC_FCS_AES_CRYPT_FINALIZE)) ?
@@ -2828,7 +2864,7 @@
 			sizeof(fcs_aes_init_payload));
 	}
 
-	if (status < 0U) {
+	if (status < 0) {
 		return INTEL_SIP_SMC_STATUS_ERROR;
 	}