diff --git a/plat/intel/soc/common/include/socfpga_fcs.h b/plat/intel/soc/common/include/socfpga_fcs.h index 5c1a76eed..2eed3412d 100644 --- a/plat/intel/soc/common/include/socfpga_fcs.h +++ b/plat/intel/soc/common/include/socfpga_fcs.h @@ -64,6 +64,10 @@ #define FCS_CS_FIELD_FLAG_UPDATE BIT(1) #define FCS_CS_FIELD_FLAG_FINALIZE BIT(2) +#define FCS_AES_MAX_DATA_SIZE 0x10000000 /* 256 MB */ +#define FCS_AES_MIN_DATA_SIZE 0x20 /* 32 Byte */ +#define FCS_AES_CMD_MAX_WORD_SIZE 15U + #define FCS_GET_DIGEST_CMD_MAX_WORD_SIZE 7U #define FCS_GET_DIGEST_RESP_MAX_WORD_SIZE 19U #define FCS_MAC_VERIFY_CMD_MAX_WORD_SIZE 23U @@ -120,6 +124,14 @@ typedef struct fcs_crypto_service_data_t { uint64_t crypto_param; } fcs_crypto_service_data; +typedef struct fcs_crypto_service_aes_data_t { + uint32_t session_id; + uint32_t context_id; + uint32_t param_size; + uint32_t key_id; + uint32_t crypto_param[7]; +} fcs_crypto_service_aes_data; + /* Functions Definitions */ uint32_t intel_fcs_random_number_gen(uint64_t addr, uint64_t *ret_size, @@ -189,4 +201,12 @@ int intel_fcs_mac_verify_finalize(uint32_t session_id, uint32_t context_id, uint64_t dst_addr, uint32_t *dst_size, uint32_t data_size, uint32_t *mbox_error); +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, + uint32_t *send_id); + #endif /* SOCFPGA_FCS_H */ diff --git a/plat/intel/soc/common/include/socfpga_mailbox.h b/plat/intel/soc/common/include/socfpga_mailbox.h index a04264de8..a7e2bc33e 100644 --- a/plat/intel/soc/common/include/socfpga_mailbox.h +++ b/plat/intel/soc/common/include/socfpga_mailbox.h @@ -75,6 +75,7 @@ #define MBOX_FCS_ENCRYPT_REQ 0x7E #define MBOX_FCS_DECRYPT_REQ 0x7F #define MBOX_FCS_RANDOM_GEN 0x80 +#define MBOX_FCS_AES_CRYPT_REQ 0x81 #define MBOX_FCS_GET_DIGEST_REQ 0x82 #define MBOX_FCS_MAC_VERIFY_REQ 0x83 #define MBOX_FCS_OPEN_CS_SESSION 0xA0 diff --git a/plat/intel/soc/common/include/socfpga_sip_svc.h b/plat/intel/soc/common/include/socfpga_sip_svc.h index 379a12360..3983533c1 100644 --- a/plat/intel/soc/common/include/socfpga_sip_svc.h +++ b/plat/intel/soc/common/include/socfpga_sip_svc.h @@ -93,6 +93,8 @@ #define INTEL_SIP_SMC_FCS_EXPORT_CS_KEY 0xC2000071 #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_FINALIZE 0x42000076 #define INTEL_SIP_SMC_FCS_GET_DIGEST_INIT 0xC2000077 #define INTEL_SIP_SMC_FCS_GET_DIGEST_FINALIZE 0xC2000079 #define INTEL_SIP_SMC_FCS_MAC_VERIFY_INIT 0xC200007A diff --git a/plat/intel/soc/common/sip/socfpga_sip_fcs.c b/plat/intel/soc/common/sip/socfpga_sip_fcs.c index 7da01fde9..ff31c9714 100644 --- a/plat/intel/soc/common/sip/socfpga_sip_fcs.c +++ b/plat/intel/soc/common/sip/socfpga_sip_fcs.c @@ -12,6 +12,7 @@ #include "socfpga_sip_svc.h" /* FCS static variables */ +static fcs_crypto_service_aes_data fcs_aes_init_payload; static fcs_crypto_service_data fcs_sha_get_digest_param; static fcs_crypto_service_data fcs_sha_mac_verify_param; @@ -33,6 +34,15 @@ static bool is_8_bytes_aligned(uint32_t data) } } +static bool is_32_bytes_aligned(uint32_t data) +{ + if ((data % (8U * MBOX_WORD_BYTE)) != 0U) { + return false; + } else { + return true; + } +} + static int intel_fcs_crypto_service_init(uint32_t session_id, uint32_t context_id, uint32_t key_id, uint32_t param_size, uint64_t param_data, @@ -893,3 +903,102 @@ int intel_fcs_mac_verify_finalize(uint32_t session_id, uint32_t context_id, return INTEL_SIP_SMC_STATUS_OK; } + +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) +{ + if (mbox_error == NULL) { + return INTEL_SIP_SMC_STATUS_REJECTED; + } + + memset((void *)&fcs_aes_init_payload, 0U, sizeof(fcs_aes_init_payload)); + + fcs_aes_init_payload.session_id = session_id; + fcs_aes_init_payload.context_id = context_id; + fcs_aes_init_payload.param_size = param_size; + fcs_aes_init_payload.key_id = key_id; + + memcpy((uint8_t *) fcs_aes_init_payload.crypto_param, + (uint8_t *) param_addr, param_size); + + *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, + uint32_t *send_id) +{ + int status; + int i; + uint32_t crypto_header; + uint32_t fcs_aes_crypt_payload[FCS_AES_CMD_MAX_WORD_SIZE]; + + if (fcs_aes_init_payload.session_id != session_id || + fcs_aes_init_payload.context_id != context_id) { + return INTEL_SIP_SMC_STATUS_REJECTED; + } + + if ((!is_8_bytes_aligned(src_addr)) || + (!is_32_bytes_aligned(src_size)) || + (!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))) { + return INTEL_SIP_SMC_STATUS_REJECTED; + } + + if ((dst_size > FCS_AES_MAX_DATA_SIZE || + dst_size < FCS_AES_MIN_DATA_SIZE) || + (src_size > FCS_AES_MAX_DATA_SIZE || + src_size < FCS_AES_MIN_DATA_SIZE)) { + 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) | + fcs_aes_init_payload.param_size; + i = 0U; + fcs_aes_crypt_payload[i] = session_id; + i++; + fcs_aes_crypt_payload[i] = 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); + + i += fcs_aes_init_payload.param_size / MBOX_WORD_BYTE; + + fcs_aes_crypt_payload[i] = (uint32_t) src_addr; + i++; + fcs_aes_crypt_payload[i] = src_size; + i++; + fcs_aes_crypt_payload[i] = (uint32_t) dst_addr; + i++; + fcs_aes_crypt_payload[i] = dst_size; + i++; + + status = mailbox_send_cmd_async(send_id, MBOX_FCS_AES_CRYPT_REQ, + fcs_aes_crypt_payload, i, + CMD_INDIRECT); + + memset((void *)&fcs_aes_init_payload, 0U, sizeof(fcs_aes_init_payload)); + + if (status < 0U) { + return INTEL_SIP_SMC_STATUS_ERROR; + } + + return INTEL_SIP_SMC_STATUS_OK; +} diff --git a/plat/intel/soc/common/socfpga_sip_svc.c b/plat/intel/soc/common/socfpga_sip_svc.c index 3f92cf651..fff12856d 100644 --- a/plat/intel/soc/common/socfpga_sip_svc.c +++ b/plat/intel/soc/common/socfpga_sip_svc.c @@ -894,6 +894,19 @@ uintptr_t sip_smc_handler(uint32_t smc_fid, x4, x5, (uint32_t *) &x6, x7, &mbox_error); SMC_RET4(handle, status, mbox_error, x5, x6); + case INTEL_SIP_SMC_FCS_AES_CRYPT_INIT: + x5 = SMC_GET_GP(handle, CTX_GPREG_X5); + status = intel_fcs_aes_crypt_init(x1, x2, x3, x4, x5, + &mbox_error); + SMC_RET2(handle, status, mbox_error); + + 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); + SMC_RET1(handle, status); + case INTEL_SIP_SMC_GET_ROM_PATCH_SHA384: status = intel_fcs_get_rom_patch_sha384(x1, &retval64, &mbox_error);