From 6726390eb02e9659cfaf2d3598be9bf12fbc5901 Mon Sep 17 00:00:00 2001 From: Sieu Mun Tang Date: Tue, 10 May 2022 17:30:00 +0800 Subject: [PATCH] feat(intel): support AES Crypt Service Enable Support for AES Crypt Service to send request to encrypt or decrypt a blob. Command will send a memory location that SDM will read and also memory location that SDM will write back after encryption or decryption operation. Response will be sent back after the crypto operation is done, and data is written back to the destination Signed-off-by: Boon Khai Ng Signed-off-by: Sieu Mun Tang Change-Id: I86ea4ff64dda2fbb1000591e30fa8cb2640ce954 --- plat/intel/soc/common/include/socfpga_fcs.h | 20 ++++ .../soc/common/include/socfpga_mailbox.h | 1 + .../soc/common/include/socfpga_sip_svc.h | 2 + plat/intel/soc/common/sip/socfpga_sip_fcs.c | 109 ++++++++++++++++++ plat/intel/soc/common/socfpga_sip_svc.c | 13 +++ 5 files changed, 145 insertions(+) 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);