fix(intel): fix fcs_client crashed when increased param size

No overflow buffer checking for param size. There is a security threat.
Update code to check for param size according to cryto param mode.

Signed-off-by: Jit Loon Lim <jit.loon.lim@intel.com>
Change-Id: I37a2d047edd9ff835b3f0986d85309c402887bef
diff --git a/plat/intel/soc/common/include/socfpga_fcs.h b/plat/intel/soc/common/include/socfpga_fcs.h
index 893551d..91e0036 100644
--- a/plat/intel/soc/common/include/socfpga_fcs.h
+++ b/plat/intel/soc/common/include/socfpga_fcs.h
@@ -84,6 +84,14 @@
 #define FCS_ECDSA_HASH_SIGN_CMD_MAX_WORD_SIZE			17U
 #define FCS_ECDSA_HASH_SIG_VERIFY_CMD_MAX_WORD_SIZE		52U
 #define FCS_ECDH_REQUEST_CMD_MAX_WORD_SIZE			29U
+
+#define FCS_CRYPTO_ECB_BUFFER_SIZE			12U
+#define FCS_CRYPTO_CBC_CTR_BUFFER_SIZE			28U
+#define FCS_CRYPTO_BLOCK_MODE_MASK			0x07
+#define FCS_CRYPTO_ECB_MODE			0x00
+#define FCS_CRYPTO_CBC_MODE			0x01
+#define FCS_CRYPTO_CTR_MODE			0x02
+
 /* FCS Payload Structure */
 typedef struct fcs_rng_payload_t {
 	uint32_t session_id;
diff --git a/plat/intel/soc/common/sip/socfpga_sip_fcs.c b/plat/intel/soc/common/sip/socfpga_sip_fcs.c
index facee0f..5f6f5de 100644
--- a/plat/intel/soc/common/sip/socfpga_sip_fcs.c
+++ b/plat/intel/soc/common/sip/socfpga_sip_fcs.c
@@ -1620,6 +1620,29 @@
 				uint32_t key_id, uint64_t param_addr,
 				uint32_t param_size, uint32_t *mbox_error)
 {
+	/* ptr to get param_addr value */
+	uint64_t *param_addr_ptr;
+
+	param_addr_ptr = (uint64_t *) param_addr;
+
+	/*
+	 * Since crypto param size vary between mode.
+	 * Check ECB here and limit to size 12 bytes
+	 */
+	if (((*param_addr_ptr & FCS_CRYPTO_BLOCK_MODE_MASK) == FCS_CRYPTO_ECB_MODE) &&
+		(param_size > FCS_CRYPTO_ECB_BUFFER_SIZE)) {
+		return INTEL_SIP_SMC_STATUS_REJECTED;
+	}
+	/*
+	 * Since crypto param size vary between mode.
+	 * Check CBC/CTR here and limit to size 28 bytes
+	 */
+	if ((((*param_addr_ptr & FCS_CRYPTO_BLOCK_MODE_MASK) == FCS_CRYPTO_CBC_MODE) ||
+		((*param_addr_ptr & FCS_CRYPTO_BLOCK_MODE_MASK) == FCS_CRYPTO_CTR_MODE)) &&
+		(param_size > FCS_CRYPTO_CBC_CTR_BUFFER_SIZE)) {
+		return INTEL_SIP_SMC_STATUS_REJECTED;
+	}
+
 	if (mbox_error == NULL) {
 		return INTEL_SIP_SMC_STATUS_REJECTED;
 	}