diff --git a/plat/intel/soc/common/include/socfpga_fcs.h b/plat/intel/soc/common/include/socfpga_fcs.h index 3a71b4f34..8aeb6283f 100644 --- a/plat/intel/soc/common/include/socfpga_fcs.h +++ b/plat/intel/soc/common/include/socfpga_fcs.h @@ -162,6 +162,7 @@ typedef struct fcs_crypto_service_aes_data_t { uint32_t param_size; uint32_t key_id; uint32_t crypto_param[7]; + uint8_t is_updated; } fcs_crypto_service_aes_data; /* Functions Definitions */ @@ -295,9 +296,10 @@ int intel_fcs_ecdh_request_finalize(uint32_t session_id, uint32_t context_id, int intel_fcs_aes_crypt_init(uint32_t session_id, uint32_t context_id, uint32_t key_id, uint64_t param_addr, uint32_t param_size, uint32_t *mbox_error); -int intel_fcs_aes_crypt_finalize(uint32_t session_id, uint32_t context_id, - uint64_t src_addr, uint32_t src_size, - uint64_t dst_addr, uint32_t dst_size, +int intel_fcs_aes_crypt_update_finalize(uint32_t session_id, + uint32_t context_id, uint64_t src_addr, + uint32_t src_size, uint64_t dst_addr, + uint32_t dst_size, uint8_t is_finalised, uint32_t *send_id); #endif /* SOCFPGA_FCS_H */ diff --git a/plat/intel/soc/common/include/socfpga_sip_svc.h b/plat/intel/soc/common/include/socfpga_sip_svc.h index b1be6a688..41ed8b247 100644 --- a/plat/intel/soc/common/include/socfpga_sip_svc.h +++ b/plat/intel/soc/common/include/socfpga_sip_svc.h @@ -107,6 +107,7 @@ #define INTEL_SIP_SMC_FCS_REMOVE_CS_KEY 0xC2000072 #define INTEL_SIP_SMC_FCS_GET_CS_KEY_INFO 0xC2000073 #define INTEL_SIP_SMC_FCS_AES_CRYPT_INIT 0xC2000074 +#define INTEL_SIP_SMC_FCS_AES_CRYPT_UPDATE 0x42000075 #define INTEL_SIP_SMC_FCS_AES_CRYPT_FINALIZE 0x42000076 #define INTEL_SIP_SMC_FCS_GET_DIGEST_INIT 0xC2000077 #define INTEL_SIP_SMC_FCS_GET_DIGEST_FINALIZE 0xC2000079 diff --git a/plat/intel/soc/common/sip/socfpga_sip_fcs.c b/plat/intel/soc/common/sip/socfpga_sip_fcs.c index 2342e45c9..a987a6e35 100644 --- a/plat/intel/soc/common/sip/socfpga_sip_fcs.c +++ b/plat/intel/soc/common/sip/socfpga_sip_fcs.c @@ -1534,18 +1534,22 @@ int intel_fcs_aes_crypt_init(uint32_t session_id, uint32_t context_id, memcpy((uint8_t *) fcs_aes_init_payload.crypto_param, (uint8_t *) param_addr, param_size); + fcs_aes_init_payload.is_updated = 0; + *mbox_error = 0; return INTEL_SIP_SMC_STATUS_OK; } -int intel_fcs_aes_crypt_finalize(uint32_t session_id, uint32_t context_id, - uint64_t src_addr, uint32_t src_size, - uint64_t dst_addr, uint32_t dst_size, +int intel_fcs_aes_crypt_update_finalize(uint32_t session_id, + uint32_t context_id, uint64_t src_addr, + uint32_t src_size, uint64_t dst_addr, + uint32_t dst_size, uint8_t is_finalised, uint32_t *send_id) { int status; int i; + uint32_t flag; uint32_t crypto_header; uint32_t fcs_aes_crypt_payload[FCS_AES_CMD_MAX_WORD_SIZE]; @@ -1572,11 +1576,23 @@ int intel_fcs_aes_crypt_finalize(uint32_t session_id, uint32_t context_id, return INTEL_SIP_SMC_STATUS_REJECTED; } - crypto_header = ((FCS_CS_FIELD_FLAG_INIT | - FCS_CS_FIELD_FLAG_UPDATE | - FCS_CS_FIELD_FLAG_FINALIZE) << - FCS_CS_FIELD_FLAG_OFFSET) | + /* Prepare crypto header*/ + flag = 0; + if (fcs_aes_init_payload.is_updated) { + fcs_aes_init_payload.param_size = 0; + } else { + flag |= FCS_CS_FIELD_FLAG_INIT; + } + + if (is_finalised != 0U) { + flag |= FCS_CS_FIELD_FLAG_FINALIZE; + } else { + flag |= FCS_CS_FIELD_FLAG_UPDATE; + fcs_aes_init_payload.is_updated = 1; + } + crypto_header = (flag << FCS_CS_FIELD_FLAG_OFFSET) | fcs_aes_init_payload.param_size; + i = 0U; fcs_aes_crypt_payload[i] = session_id; i++; @@ -1584,14 +1600,18 @@ int intel_fcs_aes_crypt_finalize(uint32_t session_id, uint32_t context_id, i++; fcs_aes_crypt_payload[i] = crypto_header; i++; - fcs_aes_crypt_payload[i] = fcs_aes_init_payload.key_id; - i++; - memcpy((uint8_t *) &fcs_aes_crypt_payload[i], - (uint8_t *) fcs_aes_init_payload.crypto_param, - fcs_aes_init_payload.param_size); + if ((crypto_header >> FCS_CS_FIELD_FLAG_OFFSET) & + FCS_CS_FIELD_FLAG_INIT) { + fcs_aes_crypt_payload[i] = fcs_aes_init_payload.key_id; + i++; - i += fcs_aes_init_payload.param_size / MBOX_WORD_BYTE; + memcpy((uint8_t *) &fcs_aes_crypt_payload[i], + (uint8_t *) fcs_aes_init_payload.crypto_param, + fcs_aes_init_payload.param_size); + + i += fcs_aes_init_payload.param_size / MBOX_WORD_BYTE; + } fcs_aes_crypt_payload[i] = (uint32_t) src_addr; i++; @@ -1606,7 +1626,10 @@ int intel_fcs_aes_crypt_finalize(uint32_t session_id, uint32_t context_id, fcs_aes_crypt_payload, i, CMD_INDIRECT); - memset((void *)&fcs_aes_init_payload, 0U, sizeof(fcs_aes_init_payload)); + if (is_finalised != 0U) { + memset((void *)&fcs_aes_init_payload, 0, + sizeof(fcs_aes_init_payload)); + } if (status < 0U) { return INTEL_SIP_SMC_STATUS_ERROR; diff --git a/plat/intel/soc/common/socfpga_sip_svc.c b/plat/intel/soc/common/socfpga_sip_svc.c index e7344cbaa..8f1f1a9e8 100644 --- a/plat/intel/soc/common/socfpga_sip_svc.c +++ b/plat/intel/soc/common/socfpga_sip_svc.c @@ -1007,11 +1007,18 @@ uintptr_t sip_smc_handler_v1(uint32_t smc_fid, &mbox_error); SMC_RET2(handle, status, mbox_error); + case INTEL_SIP_SMC_FCS_AES_CRYPT_UPDATE: + x5 = SMC_GET_GP(handle, CTX_GPREG_X5); + x6 = SMC_GET_GP(handle, CTX_GPREG_X6); + status = intel_fcs_aes_crypt_update_finalize(x1, x2, x3, x4, + x5, x6, false, &send_id); + SMC_RET1(handle, status); + case INTEL_SIP_SMC_FCS_AES_CRYPT_FINALIZE: x5 = SMC_GET_GP(handle, CTX_GPREG_X5); x6 = SMC_GET_GP(handle, CTX_GPREG_X6); - status = intel_fcs_aes_crypt_finalize(x1, x2, x3, x4, x5, x6, - &send_id); + status = intel_fcs_aes_crypt_update_finalize(x1, x2, x3, x4, + x5, x6, true, &send_id); SMC_RET1(handle, status); case INTEL_SIP_SMC_GET_ROM_PATCH_SHA384: