diff --git a/plat/intel/soc/common/include/socfpga_fcs.h b/plat/intel/soc/common/include/socfpga_fcs.h index da982e14e..db8f558eb 100644 --- a/plat/intel/soc/common/include/socfpga_fcs.h +++ b/plat/intel/soc/common/include/socfpga_fcs.h @@ -9,61 +9,64 @@ /* FCS Definitions */ -#define FCS_RANDOM_WORD_SIZE 8U -#define FCS_PROV_DATA_WORD_SIZE 44U -#define FCS_SHA384_WORD_SIZE 12U +#define FCS_RANDOM_WORD_SIZE 8U +#define FCS_PROV_DATA_WORD_SIZE 44U +#define FCS_SHA384_WORD_SIZE 12U -#define FCS_RANDOM_BYTE_SIZE (FCS_RANDOM_WORD_SIZE * 4U) -#define FCS_RANDOM_EXT_MAX_WORD_SIZE 1020U -#define FCS_PROV_DATA_BYTE_SIZE (FCS_PROV_DATA_WORD_SIZE * 4U) -#define FCS_SHA384_BYTE_SIZE (FCS_SHA384_WORD_SIZE * 4U) +#define FCS_RANDOM_BYTE_SIZE (FCS_RANDOM_WORD_SIZE * 4U) +#define FCS_RANDOM_EXT_MAX_WORD_SIZE 1020U +#define FCS_PROV_DATA_BYTE_SIZE (FCS_PROV_DATA_WORD_SIZE * 4U) +#define FCS_SHA384_BYTE_SIZE (FCS_SHA384_WORD_SIZE * 4U) -#define FCS_RANDOM_EXT_OFFSET 3 +#define FCS_RANDOM_EXT_OFFSET 3 -#define FCS_MODE_DECRYPT 0x0 -#define FCS_MODE_ENCRYPT 0x1 -#define FCS_ENCRYPTION_DATA_0 0x10100 -#define FCS_DECRYPTION_DATA_0 0x10102 -#define FCS_OWNER_ID_OFFSET 0xC +#define FCS_MODE_DECRYPT 0x0 +#define FCS_MODE_ENCRYPT 0x1 +#define FCS_ENCRYPTION_DATA_0 0x10100 +#define FCS_DECRYPTION_DATA_0 0x10102 +#define FCS_OWNER_ID_OFFSET 0xC -#define PSGSIGMA_TEARDOWN_MAGIC 0xB852E2A4 -#define PSGSIGMA_SESSION_ID_ONE 0x1 -#define PSGSIGMA_UNKNOWN_SESSION 0xFFFFFFFF +#define PSGSIGMA_TEARDOWN_MAGIC 0xB852E2A4 +#define PSGSIGMA_SESSION_ID_ONE 0x1 +#define PSGSIGMA_UNKNOWN_SESSION 0xFFFFFFFF -#define RESERVED_AS_ZERO 0x0 +#define RESERVED_AS_ZERO 0x0 /* FCS Single cert */ -#define FCS_BIG_CNTR_SEL 0x1 +#define FCS_BIG_CNTR_SEL 0x1 -#define FCS_SVN_CNTR_0_SEL 0x2 -#define FCS_SVN_CNTR_1_SEL 0x3 -#define FCS_SVN_CNTR_2_SEL 0x4 -#define FCS_SVN_CNTR_3_SEL 0x5 +#define FCS_SVN_CNTR_0_SEL 0x2 +#define FCS_SVN_CNTR_1_SEL 0x3 +#define FCS_SVN_CNTR_2_SEL 0x4 +#define FCS_SVN_CNTR_3_SEL 0x5 -#define FCS_BIG_CNTR_VAL_MAX 495U -#define FCS_SVN_CNTR_VAL_MAX 64U +#define FCS_BIG_CNTR_VAL_MAX 495U +#define FCS_SVN_CNTR_VAL_MAX 64U /* FCS Attestation Cert Request Parameter */ -#define FCS_ALIAS_CERT 0x01 -#define FCS_DEV_ID_SELF_SIGN_CERT 0x02 -#define FCS_DEV_ID_ENROLL_CERT 0x04 -#define FCS_ENROLL_SELF_SIGN_CERT 0x08 -#define FCS_PLAT_KEY_CERT 0x10 +#define FCS_ALIAS_CERT 0x01 +#define FCS_DEV_ID_SELF_SIGN_CERT 0x02 +#define FCS_DEV_ID_ENROLL_CERT 0x04 +#define FCS_ENROLL_SELF_SIGN_CERT 0x08 +#define FCS_PLAT_KEY_CERT 0x10 /* FCS Crypto Service */ -#define FCS_CS_KEY_OBJ_MAX_WORD_SIZE 88U -#define FCS_CS_KEY_INFO_MAX_WORD_SIZE 36U -#define FCS_CS_KEY_RESP_STATUS_MASK 0xFF -#define FCS_CS_KEY_RESP_STATUS_OFFSET 16U +#define FCS_CS_KEY_OBJ_MAX_WORD_SIZE 88U +#define FCS_CS_KEY_INFO_MAX_WORD_SIZE 36U +#define FCS_CS_KEY_RESP_STATUS_MASK 0xFF +#define FCS_CS_KEY_RESP_STATUS_OFFSET 16U -#define FCS_CS_FIELD_SIZE_MASK 0xFFFF -#define FCS_CS_FIELD_FLAG_OFFSET 24 -#define FCS_CS_FIELD_FLAG_INIT BIT(0) -#define FCS_CS_FIELD_FLAG_UPDATE BIT(1) -#define FCS_CS_FIELD_FLAG_FINALIZE BIT(2) +#define FCS_CS_FIELD_SIZE_MASK 0xFFFF +#define FCS_CS_FIELD_FLAG_OFFSET 24 +#define FCS_CS_FIELD_FLAG_INIT BIT(0) +#define FCS_CS_FIELD_FLAG_UPDATE BIT(1) +#define FCS_CS_FIELD_FLAG_FINALIZE BIT(2) +#define FCS_GET_DIGEST_CMD_MAX_WORD_SIZE 7U +#define FCS_GET_DIGEST_RESP_MAX_WORD_SIZE 19U +#define FCS_SHA_HMAC_CRYPTO_PARAM_SIZE_OFFSET 8U /* FCS Payload Structure */ typedef struct fcs_rng_payload_t { uint32_t session_id; @@ -107,6 +110,14 @@ typedef struct fcs_cs_key_payload_t { uint32_t key_id; } fcs_cs_key_payload; +typedef struct fcs_crypto_service_data_t { + uint32_t session_id; + uint32_t context_id; + uint32_t key_id; + uint32_t crypto_param_size; + uint64_t crypto_param; +} fcs_crypto_service_data; + /* Functions Definitions */ uint32_t intel_fcs_random_number_gen(uint64_t addr, uint64_t *ret_size, @@ -160,4 +171,12 @@ int intel_fcs_get_crypto_service_key_info(uint32_t session_id, uint32_t key_id, uint64_t dst_addr, uint32_t *dst_size, uint32_t *mbox_error); +int intel_fcs_get_digest_init(uint32_t session_id, uint32_t context_id, + uint32_t key_id, uint32_t param_size, + uint64_t param_data, uint32_t *mbox_error); +int intel_fcs_get_digest_finalize(uint32_t session_id, uint32_t context_id, + uint32_t src_addr, uint32_t src_size, + uint64_t dst_addr, uint32_t *dst_size, + uint32_t *mbox_error); + #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 f969a353e..498402014 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_GET_DIGEST_REQ 0x82 #define MBOX_FCS_OPEN_CS_SESSION 0xA0 #define MBOX_FCS_CLOSE_CS_SESSION 0xA1 #define MBOX_FCS_IMPORT_CS_KEY 0xA5 diff --git a/plat/intel/soc/common/include/socfpga_sip_svc.h b/plat/intel/soc/common/include/socfpga_sip_svc.h index e790669d5..f05e861b6 100644 --- a/plat/intel/soc/common/include/socfpga_sip_svc.h +++ b/plat/intel/soc/common/include/socfpga_sip_svc.h @@ -93,7 +93,12 @@ #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_GET_DIGEST_INIT 0xC2000077 +#define INTEL_SIP_SMC_FCS_GET_DIGEST_FINALIZE 0xC2000079 +#define INTEL_SIP_SMC_FCS_SHA_MODE_MASK 0xF +#define INTEL_SIP_SMC_FCS_DIGEST_SIZE_MASK 0xF +#define INTEL_SIP_SMC_FCS_DIGEST_SIZE_OFFSET 4U /* ECC DBE */ #define WARM_RESET_WFI_FLAG BIT(31) #define SYSMGR_ECC_DBE_COLD_RST_MASK (SYSMGR_ECC_OCRAM_MASK |\ diff --git a/plat/intel/soc/common/sip/socfpga_sip_fcs.c b/plat/intel/soc/common/sip/socfpga_sip_fcs.c index 7b3069ba8..809037e9d 100644 --- a/plat/intel/soc/common/sip/socfpga_sip_fcs.c +++ b/plat/intel/soc/common/sip/socfpga_sip_fcs.c @@ -11,6 +11,9 @@ #include "socfpga_mailbox.h" #include "socfpga_sip_svc.h" +/* FCS static variables */ +static fcs_crypto_service_data fcs_sha_get_digest_param; + bool is_size_4_bytes_aligned(uint32_t size) { if ((size % MBOX_WORD_BYTE) != 0U) { @@ -20,6 +23,42 @@ bool is_size_4_bytes_aligned(uint32_t size) } } +static bool is_8_bytes_aligned(uint32_t data) +{ + if ((data % (MBOX_WORD_BYTE * 2U)) != 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, + fcs_crypto_service_data *data_addr, + uint32_t *mbox_error) +{ + if (mbox_error == NULL) { + return INTEL_SIP_SMC_STATUS_REJECTED; + } + + if (param_size != 4) { + return INTEL_SIP_SMC_STATUS_REJECTED; + } + + memset(data_addr, 0, sizeof(fcs_crypto_service_data)); + + data_addr->session_id = session_id; + data_addr->context_id = context_id; + data_addr->key_id = key_id; + data_addr->crypto_param_size = param_size; + data_addr->crypto_param = param_data; + + *mbox_error = 0; + + return INTEL_SIP_SMC_STATUS_OK; +} + uint32_t intel_fcs_random_number_gen(uint64_t addr, uint64_t *ret_size, uint32_t *mbox_error) { @@ -673,3 +712,88 @@ int intel_fcs_get_crypto_service_key_info(uint32_t session_id, uint32_t key_id, return INTEL_SIP_SMC_STATUS_OK; } + +int intel_fcs_get_digest_init(uint32_t session_id, uint32_t context_id, + uint32_t key_id, uint32_t param_size, + uint64_t param_data, uint32_t *mbox_error) +{ + return intel_fcs_crypto_service_init(session_id, context_id, + key_id, param_size, param_data, + (void *) &fcs_sha_get_digest_param, + mbox_error); +} + +int intel_fcs_get_digest_finalize(uint32_t session_id, uint32_t context_id, + uint32_t src_addr, uint32_t src_size, + uint64_t dst_addr, uint32_t *dst_size, + uint32_t *mbox_error) +{ + int status; + uint32_t i; + uint32_t resp_len = *dst_size / MBOX_WORD_BYTE; + uint32_t payload[FCS_GET_DIGEST_CMD_MAX_WORD_SIZE] = {0U}; + + if (dst_size == NULL || mbox_error == NULL) { + return INTEL_SIP_SMC_STATUS_REJECTED; + } + + if (fcs_sha_get_digest_param.session_id != session_id || + fcs_sha_get_digest_param.context_id != context_id) { + return INTEL_SIP_SMC_STATUS_REJECTED; + } + + /* Source data must be 8 bytes aligned */ + if (!is_8_bytes_aligned(src_size)) { + 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; + } + + /* Prepare command payload */ + i = 0; + /* Crypto header */ + payload[i] = fcs_sha_get_digest_param.session_id; + i++; + payload[i] = fcs_sha_get_digest_param.context_id; + i++; + payload[i] = fcs_sha_get_digest_param.crypto_param_size + & FCS_CS_FIELD_SIZE_MASK; + payload[i] |= (FCS_CS_FIELD_FLAG_INIT | FCS_CS_FIELD_FLAG_UPDATE + | FCS_CS_FIELD_FLAG_FINALIZE) + << FCS_CS_FIELD_FLAG_OFFSET; + i++; + payload[i] = fcs_sha_get_digest_param.key_id; + i++; + /* Crypto parameters */ + payload[i] = fcs_sha_get_digest_param.crypto_param + & INTEL_SIP_SMC_FCS_SHA_MODE_MASK; + payload[i] |= ((fcs_sha_get_digest_param.crypto_param + >> INTEL_SIP_SMC_FCS_DIGEST_SIZE_OFFSET) + & INTEL_SIP_SMC_FCS_DIGEST_SIZE_MASK) + << FCS_SHA_HMAC_CRYPTO_PARAM_SIZE_OFFSET; + i++; + /* Data source address and size */ + payload[i] = src_addr; + i++; + payload[i] = src_size; + i++; + + status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_GET_DIGEST_REQ, + payload, i, CMD_CASUAL, + (uint32_t *) dst_addr, &resp_len); + + memset((void *)&fcs_sha_get_digest_param, 0, sizeof(fcs_crypto_service_data)); + + if (status < 0) { + *mbox_error = -status; + return INTEL_SIP_SMC_STATUS_ERROR; + } + + *dst_size = resp_len * MBOX_WORD_BYTE; + flush_dcache_range(dst_addr, *dst_size); + + 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 24683ea6d..f9a376e97 100644 --- a/plat/intel/soc/common/socfpga_sip_svc.c +++ b/plat/intel/soc/common/socfpga_sip_svc.c @@ -867,6 +867,19 @@ uintptr_t sip_smc_handler(uint32_t smc_fid, (uint32_t *) &x4, &mbox_error); SMC_RET4(handle, status, mbox_error, x3, x4); + case INTEL_SIP_SMC_FCS_GET_DIGEST_INIT: + x5 = SMC_GET_GP(handle, CTX_GPREG_X5); + status = intel_fcs_get_digest_init(x1, x2, x3, + x4, x5, &mbox_error); + SMC_RET2(handle, status, mbox_error); + + case INTEL_SIP_SMC_FCS_GET_DIGEST_FINALIZE: + x5 = SMC_GET_GP(handle, CTX_GPREG_X5); + x6 = SMC_GET_GP(handle, CTX_GPREG_X6); + status = intel_fcs_get_digest_finalize(x1, x2, x3, + x4, x5, (uint32_t *) &x6, &mbox_error); + SMC_RET4(handle, status, mbox_error, x5, x6); + case INTEL_SIP_SMC_GET_ROM_PATCH_SHA384: status = intel_fcs_get_rom_patch_sha384(x1, &retval64, &mbox_error);