diff --git a/plat/intel/soc/common/include/socfpga_fcs.h b/plat/intel/soc/common/include/socfpga_fcs.h index 2eed3412d..15b7a2c23 100644 --- a/plat/intel/soc/common/include/socfpga_fcs.h +++ b/plat/intel/soc/common/include/socfpga_fcs.h @@ -25,6 +25,9 @@ #define FCS_ENCRYPTION_DATA_0 0x10100 #define FCS_DECRYPTION_DATA_0 0x10102 #define FCS_OWNER_ID_OFFSET 0xC +#define FCS_CRYPTION_CRYPTO_HEADER 0x07000000 +#define FCS_CRYPTION_RESP_WORD_SIZE 4U +#define FCS_CRYPTION_RESP_SIZE_OFFSET 3U #define PSGSIGMA_TEARDOWN_MAGIC 0xB852E2A4 #define PSGSIGMA_SESSION_ID_ONE 0x1 @@ -98,6 +101,27 @@ typedef struct fcs_decrypt_payload_t { uint32_t dst_size; } fcs_decrypt_payload; +typedef struct fcs_encrypt_ext_payload_t { + uint32_t session_id; + uint32_t context_id; + uint32_t crypto_header; + uint32_t src_addr; + uint32_t src_size; + uint32_t dst_addr; + uint32_t dst_size; +} fcs_encrypt_ext_payload; + +typedef struct fcs_decrypt_ext_payload_t { + uint32_t session_id; + uint32_t context_id; + uint32_t crypto_header; + uint32_t owner_id[2]; + uint32_t src_addr; + uint32_t src_size; + uint32_t dst_addr; + uint32_t dst_size; +} fcs_decrypt_ext_payload; + typedef struct psgsigma_teardown_msg_t { uint32_t reserved_word; uint32_t magic_word; @@ -153,6 +177,15 @@ uint32_t intel_fcs_decryption(uint32_t src_addr, uint32_t src_size, uint32_t dst_addr, uint32_t dst_size, uint32_t *send_id); +int intel_fcs_encryption_ext(uint32_t session_id, uint32_t context_id, + uint32_t src_addr, uint32_t src_size, + uint32_t dst_addr, uint32_t *dst_size, + uint32_t *mbox_error); +int intel_fcs_decryption_ext(uint32_t sesion_id, uint32_t context_id, + uint32_t src_addr, uint32_t src_size, + uint32_t dst_addr, uint32_t *dst_size, + uint32_t *mbox_error); + int intel_fcs_sigma_teardown(uint32_t session_id, uint32_t *mbox_error); int intel_fcs_chip_id(uint32_t *id_low, uint32_t *id_high, uint32_t *mbox_error); int intel_fcs_attestation_subkey(uint64_t src_addr, uint32_t src_size, diff --git a/plat/intel/soc/common/include/socfpga_sip_svc.h b/plat/intel/soc/common/include/socfpga_sip_svc.h index 3983533c1..3c92a4ac9 100644 --- a/plat/intel/soc/common/include/socfpga_sip_svc.h +++ b/plat/intel/soc/common/include/socfpga_sip_svc.h @@ -78,6 +78,7 @@ #define INTEL_SIP_SMC_FCS_RANDOM_NUMBER 0xC200005A #define INTEL_SIP_SMC_FCS_RANDOM_NUMBER_EXT 0x4200008F #define INTEL_SIP_SMC_FCS_CRYPTION 0x4200005B +#define INTEL_SIP_SMC_FCS_CRYPTION_EXT 0xC2000090 #define INTEL_SIP_SMC_FCS_SEND_CERTIFICATE 0x4200005D #define INTEL_SIP_SMC_FCS_GET_PROVISION_DATA 0x4200005E #define INTEL_SIP_SMC_FCS_CNTR_SET_PREAUTH 0xC200005F diff --git a/plat/intel/soc/common/sip/socfpga_sip_fcs.c b/plat/intel/soc/common/sip/socfpga_sip_fcs.c index ff31c9714..4f2c73d77 100644 --- a/plat/intel/soc/common/sip/socfpga_sip_fcs.c +++ b/plat/intel/soc/common/sip/socfpga_sip_fcs.c @@ -337,6 +337,118 @@ uint32_t intel_fcs_get_rom_patch_sha384(uint64_t addr, uint64_t *ret_size, return INTEL_SIP_SMC_STATUS_OK; } +int intel_fcs_encryption_ext(uint32_t session_id, uint32_t context_id, + uint32_t src_addr, uint32_t src_size, + uint32_t dst_addr, uint32_t *dst_size, uint32_t *mbox_error) +{ + int status; + uint32_t payload_size; + uint32_t resp_len = FCS_CRYPTION_RESP_WORD_SIZE; + uint32_t resp_data[FCS_CRYPTION_RESP_WORD_SIZE] = {0U}; + + if ((dst_size == NULL) || (mbox_error == NULL)) { + return INTEL_SIP_SMC_STATUS_REJECTED; + } + + if (!is_address_in_ddr_range(src_addr, src_size) || + !is_address_in_ddr_range(dst_addr, *dst_size)) { + return INTEL_SIP_SMC_STATUS_REJECTED; + } + + if (!is_size_4_bytes_aligned(src_size)) { + return INTEL_SIP_SMC_STATUS_REJECTED; + } + + fcs_encrypt_ext_payload payload = { + session_id, + context_id, + FCS_CRYPTION_CRYPTO_HEADER, + src_addr, + src_size, + dst_addr, + *dst_size + }; + + payload_size = sizeof(payload) / MBOX_WORD_BYTE; + + status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_ENCRYPT_REQ, + (uint32_t *) &payload, payload_size, + CMD_CASUAL, resp_data, &resp_len); + + if (status < 0) { + *mbox_error = -status; + return INTEL_SIP_SMC_STATUS_ERROR; + } + + if (resp_len != FCS_CRYPTION_RESP_WORD_SIZE) { + *mbox_error = MBOX_RET_ERROR; + return INTEL_SIP_SMC_STATUS_ERROR; + } + + *dst_size = resp_data[FCS_CRYPTION_RESP_SIZE_OFFSET]; + inv_dcache_range(dst_addr, *dst_size); + + return INTEL_SIP_SMC_STATUS_OK; +} + +int intel_fcs_decryption_ext(uint32_t session_id, uint32_t context_id, + uint32_t src_addr, uint32_t src_size, + uint32_t dst_addr, uint32_t *dst_size, uint32_t *mbox_error) +{ + int status; + uintptr_t id_offset; + uint32_t payload_size; + uint32_t resp_len = FCS_CRYPTION_RESP_WORD_SIZE; + uint32_t resp_data[FCS_CRYPTION_RESP_WORD_SIZE] = {0U}; + + if ((dst_size == NULL) || (mbox_error == NULL)) { + return INTEL_SIP_SMC_STATUS_REJECTED; + } + + if (!is_address_in_ddr_range(src_addr, src_size) || + !is_address_in_ddr_range(dst_addr, *dst_size)) { + return INTEL_SIP_SMC_STATUS_REJECTED; + } + + if (!is_size_4_bytes_aligned(src_size)) { + return INTEL_SIP_SMC_STATUS_REJECTED; + } + + id_offset = src_addr + FCS_OWNER_ID_OFFSET; + fcs_decrypt_ext_payload payload = { + session_id, + context_id, + FCS_CRYPTION_CRYPTO_HEADER, + {mmio_read_32(id_offset), + mmio_read_32(id_offset + MBOX_WORD_BYTE)}, + src_addr, + src_size, + dst_addr, + *dst_size + }; + + payload_size = sizeof(payload) / MBOX_WORD_BYTE; + + status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_DECRYPT_REQ, + (uint32_t *) &payload, payload_size, + CMD_CASUAL, resp_data, &resp_len); + + if (status < 0) { + *mbox_error = -status; + return INTEL_SIP_SMC_STATUS_ERROR; + } + + if (resp_len != FCS_CRYPTION_RESP_WORD_SIZE) { + *mbox_error = MBOX_RET_ERROR; + return INTEL_SIP_SMC_STATUS_ERROR; + } + + *dst_size = resp_data[FCS_CRYPTION_RESP_SIZE_OFFSET]; + inv_dcache_range(dst_addr, *dst_size); + + return INTEL_SIP_SMC_STATUS_OK; +} + int intel_fcs_sigma_teardown(uint32_t session_id, uint32_t *mbox_error) { int status; diff --git a/plat/intel/soc/common/socfpga_sip_svc.c b/plat/intel/soc/common/socfpga_sip_svc.c index fff12856d..824ee3854 100644 --- a/plat/intel/soc/common/socfpga_sip_svc.c +++ b/plat/intel/soc/common/socfpga_sip_svc.c @@ -786,6 +786,23 @@ uintptr_t sip_smc_handler(uint32_t smc_fid, SMC_RET3(handle, status, x4, x5); + case INTEL_SIP_SMC_FCS_CRYPTION_EXT: + x5 = SMC_GET_GP(handle, CTX_GPREG_X5); + x6 = SMC_GET_GP(handle, CTX_GPREG_X6); + x7 = SMC_GET_GP(handle, CTX_GPREG_X7); + + if (x3 == FCS_MODE_DECRYPT) { + status = intel_fcs_decryption_ext(x1, x2, x4, x5, x6, + (uint32_t *) &x7, &mbox_error); + } else if (x3 == FCS_MODE_ENCRYPT) { + status = intel_fcs_encryption_ext(x1, x2, x4, x5, x6, + (uint32_t *) &x7, &mbox_error); + } else { + status = INTEL_SIP_SMC_STATUS_REJECTED; + } + + SMC_RET4(handle, status, mbox_error, x6, x7); + case INTEL_SIP_SMC_FCS_RANDOM_NUMBER: status = intel_fcs_random_number_gen(x1, &retval64, &mbox_error);