feat(intel): support crypto service key operation

Support crypto service key operation mailbox commands through SMC.

Crypto service key operation begin by sending an open crypto service
session request to SDM firmware. Once successfully open the session,
send crypto service key management commands (import, export, remove
and get key info) with the associated session id to SDM firmware.
The crypto service key is required before perform any crypto service
(encryption, signing, etc). Last, close the session after finishes
crypto service. All crypto service keys associated with this session
will be erased by SDM firmware.

Signed-off-by: Siew Chin Lim <elly.siew.chin.lim@intel.com>
Signed-off-by: Boon Khai Ng <boon.khai.ng@intel.com>
Signed-off-by: Sieu Mun Tang <sieu.mun.tang@intel.com>
Change-Id: I02406533f38b9607eb1ec7e1395b9dc2d084a9e3
This commit is contained in:
Sieu Mun Tang 2022-05-09 14:16:14 +08:00
parent 6dc00c24ab
commit 342a0618c7
5 changed files with 224 additions and 0 deletions

View File

@ -48,6 +48,13 @@
#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
/* FCS Payload Structure */
typedef struct fcs_encrypt_payload_t {
@ -78,6 +85,13 @@ typedef struct fcs_cntr_set_preauth_payload_t {
uint32_t counter_value;
} fcs_cntr_set_preauth_payload;
typedef struct fcs_cs_key_payload_t {
uint32_t session_id;
uint32_t reserved0;
uint32_t reserved1;
uint32_t key_id;
} fcs_cs_key_payload;
/* Functions Definitions */
uint32_t intel_fcs_random_number_gen(uint64_t addr, uint64_t *ret_size,
@ -118,4 +132,15 @@ int intel_fcs_open_crypto_service_session(uint32_t *session_id,
int intel_fcs_close_crypto_service_session(uint32_t session_id,
uint32_t *mbox_error);
int intel_fcs_import_crypto_service_key(uint64_t src_addr, uint32_t src_size,
uint32_t *mbox_error);
int intel_fcs_export_crypto_service_key(uint32_t session_id, uint32_t key_id,
uint64_t dst_addr, uint32_t *dst_size,
uint32_t *mbox_error);
int intel_fcs_remove_crypto_service_key(uint32_t session_id, uint32_t key_id,
uint32_t *mbox_error);
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);
#endif /* SOCFPGA_FCS_H */

View File

@ -77,6 +77,10 @@
#define MBOX_FCS_RANDOM_GEN 0x80
#define MBOX_FCS_OPEN_CS_SESSION 0xA0
#define MBOX_FCS_CLOSE_CS_SESSION 0xA1
#define MBOX_FCS_IMPORT_CS_KEY 0xA5
#define MBOX_FCS_EXPORT_CS_KEY 0xA6
#define MBOX_FCS_REMOVE_CS_KEY 0xA7
#define MBOX_FCS_GET_CS_KEY_INFO 0xA8
/* PSG SIGMA Commands */
#define MBOX_PSG_SIGMA_TEARDOWN 0xD5

View File

@ -88,6 +88,10 @@
#define INTEL_SIP_SMC_FCS_CREATE_CERT_ON_RELOAD 0xC2000069
#define INTEL_SIP_SMC_FCS_OPEN_CS_SESSION 0xC200006E
#define INTEL_SIP_SMC_FCS_CLOSE_CS_SESSION 0xC200006F
#define INTEL_SIP_SMC_FCS_IMPORT_CS_KEY 0x42000070
#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
/* ECC DBE */
#define WARM_RESET_WFI_FLAG BIT(31)

View File

@ -462,3 +462,175 @@ int intel_fcs_close_crypto_service_session(uint32_t session_id,
return INTEL_SIP_SMC_STATUS_OK;
}
int intel_fcs_import_crypto_service_key(uint64_t src_addr, uint32_t src_size,
uint32_t *send_id)
{
int status;
if (src_size > (FCS_CS_KEY_OBJ_MAX_WORD_SIZE *
MBOX_WORD_BYTE)) {
return INTEL_SIP_SMC_STATUS_REJECTED;
}
if (!is_address_in_ddr_range(src_addr, src_size)) {
return INTEL_SIP_SMC_STATUS_REJECTED;
}
status = mailbox_send_cmd_async(send_id, MBOX_FCS_IMPORT_CS_KEY,
(uint32_t *)src_addr, src_size / MBOX_WORD_BYTE,
CMD_INDIRECT);
if (status < 0) {
return INTEL_SIP_SMC_STATUS_ERROR;
}
return INTEL_SIP_SMC_STATUS_OK;
}
int intel_fcs_export_crypto_service_key(uint32_t session_id, uint32_t key_id,
uint64_t dst_addr, uint32_t *dst_size,
uint32_t *mbox_error)
{
int status;
uint32_t i;
uint32_t payload_size;
uint32_t resp_len = FCS_CS_KEY_OBJ_MAX_WORD_SIZE;
uint32_t resp_data[FCS_CS_KEY_OBJ_MAX_WORD_SIZE] = {0U};
uint32_t op_status = 0U;
if ((dst_size == NULL) || (mbox_error == NULL)) {
return INTEL_SIP_SMC_STATUS_REJECTED;
}
if (!is_address_in_ddr_range(dst_addr, *dst_size)) {
return INTEL_SIP_SMC_STATUS_REJECTED;
}
fcs_cs_key_payload payload = {
session_id,
RESERVED_AS_ZERO,
RESERVED_AS_ZERO,
key_id
};
payload_size = sizeof(payload) / MBOX_WORD_BYTE;
status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_EXPORT_CS_KEY,
(uint32_t *) &payload, payload_size,
CMD_CASUAL, resp_data, &resp_len);
if (resp_len > 0) {
op_status = resp_data[0] & FCS_CS_KEY_RESP_STATUS_MASK;
}
if (status < 0) {
*mbox_error = (-status) | (op_status << FCS_CS_KEY_RESP_STATUS_OFFSET);
return INTEL_SIP_SMC_STATUS_ERROR;
}
if (resp_len > 1) {
/* Export key object is start at second response data */
*dst_size = (resp_len - 1) * MBOX_WORD_BYTE;
for (i = 1U; i < resp_len; i++) {
mmio_write_32(dst_addr, resp_data[i]);
dst_addr += MBOX_WORD_BYTE;
}
flush_dcache_range(dst_addr - *dst_size, *dst_size);
} else {
/* Unexpected response, missing key object in response */
*mbox_error = MBOX_RET_ERROR;
return INTEL_SIP_SMC_STATUS_ERROR;
}
return INTEL_SIP_SMC_STATUS_OK;
}
int intel_fcs_remove_crypto_service_key(uint32_t session_id, uint32_t key_id,
uint32_t *mbox_error)
{
int status;
uint32_t payload_size;
uint32_t resp_len = 1U;
uint32_t resp_data = 0U;
uint32_t op_status = 0U;
if (mbox_error == NULL) {
return INTEL_SIP_SMC_STATUS_REJECTED;
}
fcs_cs_key_payload payload = {
session_id,
RESERVED_AS_ZERO,
RESERVED_AS_ZERO,
key_id
};
payload_size = sizeof(payload) / MBOX_WORD_BYTE;
status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_REMOVE_CS_KEY,
(uint32_t *) &payload, payload_size,
CMD_CASUAL, &resp_data, &resp_len);
if (resp_len > 0) {
op_status = resp_data & FCS_CS_KEY_RESP_STATUS_MASK;
}
if (status < 0) {
*mbox_error = (-status) | (op_status << FCS_CS_KEY_RESP_STATUS_OFFSET);
return INTEL_SIP_SMC_STATUS_ERROR;
}
return INTEL_SIP_SMC_STATUS_OK;
}
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 status;
uint32_t payload_size;
uint32_t resp_len = FCS_CS_KEY_INFO_MAX_WORD_SIZE;
uint32_t op_status = 0U;
if ((dst_size == NULL) || (mbox_error == NULL)) {
return INTEL_SIP_SMC_STATUS_REJECTED;
}
if (!is_address_in_ddr_range(dst_addr, *dst_size)) {
return INTEL_SIP_SMC_STATUS_REJECTED;
}
fcs_cs_key_payload payload = {
session_id,
RESERVED_AS_ZERO,
RESERVED_AS_ZERO,
key_id
};
payload_size = sizeof(payload) / MBOX_WORD_BYTE;
status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_GET_CS_KEY_INFO,
(uint32_t *) &payload, payload_size,
CMD_CASUAL, (uint32_t *) dst_addr, &resp_len);
if (resp_len > 0) {
op_status = mmio_read_32(dst_addr) &
FCS_CS_KEY_RESP_STATUS_MASK;
}
if (status < 0) {
*mbox_error = (-status) | (op_status << FCS_CS_KEY_RESP_STATUS_OFFSET);
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;
}

View File

@ -843,6 +843,25 @@ uintptr_t sip_smc_handler(uint32_t smc_fid,
status = intel_fcs_close_crypto_service_session(x1, &mbox_error);
SMC_RET2(handle, status, mbox_error);
case INTEL_SIP_SMC_FCS_IMPORT_CS_KEY:
status = intel_fcs_import_crypto_service_key(x1, x2, &send_id);
SMC_RET1(handle, status);
case INTEL_SIP_SMC_FCS_EXPORT_CS_KEY:
status = intel_fcs_export_crypto_service_key(x1, x2, x3,
(uint32_t *) &x4, &mbox_error);
SMC_RET4(handle, status, mbox_error, x3, x4);
case INTEL_SIP_SMC_FCS_REMOVE_CS_KEY:
status = intel_fcs_remove_crypto_service_key(x1, x2,
&mbox_error);
SMC_RET2(handle, status, mbox_error);
case INTEL_SIP_SMC_FCS_GET_CS_KEY_INFO:
status = intel_fcs_get_crypto_service_key_info(x1, x2, x3,
(uint32_t *) &x4, &mbox_error);
SMC_RET4(handle, status, mbox_error, x3, x4);
case INTEL_SIP_SMC_GET_ROM_PATCH_SHA384:
status = intel_fcs_get_rom_patch_sha384(x1, &retval64,
&mbox_error);