From 1d97dd74cd128edd7ad45b725603444333c7b262 Mon Sep 17 00:00:00 2001 From: Sieu Mun Tang Date: Thu, 28 Apr 2022 16:23:20 +0800 Subject: [PATCH] fix(intel): extending to support large file size for SHA-2 ECDSA data signing and signature verifying This patch is to extend to support large file size for SHA-2 ECDSA data signing and signature verifying. The large file will be split into smaller chunk and send using initialize, update and finalize staging method. Signed-off-by: Sieu Mun Tang Change-Id: If277b2b375a404fe44b0858006c8ba6316a5ce23 --- plat/intel/soc/common/include/socfpga_fcs.h | 10 +- .../soc/common/include/socfpga_sip_svc.h | 2 + plat/intel/soc/common/sip/socfpga_sip_fcs.c | 119 ++++++++++++------ plat/intel/soc/common/socfpga_sip_svc.c | 27 +++- 4 files changed, 114 insertions(+), 44 deletions(-) diff --git a/plat/intel/soc/common/include/socfpga_fcs.h b/plat/intel/soc/common/include/socfpga_fcs.h index 8aeb6283f..37456bc45 100644 --- a/plat/intel/soc/common/include/socfpga_fcs.h +++ b/plat/intel/soc/common/include/socfpga_fcs.h @@ -154,6 +154,7 @@ typedef struct fcs_crypto_service_data_t { uint32_t key_id; uint32_t crypto_param_size; uint64_t crypto_param; + uint8_t is_updated; } fcs_crypto_service_data; typedef struct fcs_crypto_service_aes_data_t { @@ -263,20 +264,21 @@ int intel_fcs_ecdsa_sha2_data_sign_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_ecdsa_sha2_data_sign_finalize(uint32_t session_id, +int intel_fcs_ecdsa_sha2_data_sign_update_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); + uint32_t *dst_size, uint8_t is_finalised, + uint32_t *mbox_error); int intel_fcs_ecdsa_sha2_data_sig_verify_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_ecdsa_sha2_data_sig_verify_finalize(uint32_t session_id, +int intel_fcs_ecdsa_sha2_data_sig_verify_update_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 data_size, - uint32_t *mbox_error); + uint8_t is_finalised, uint32_t *mbox_error); int intel_fcs_ecdsa_get_pubkey_init(uint32_t session_id, uint32_t context_id, uint32_t key_id, uint32_t param_size, diff --git a/plat/intel/soc/common/include/socfpga_sip_svc.h b/plat/intel/soc/common/include/socfpga_sip_svc.h index 41ed8b247..36ba4aa4d 100644 --- a/plat/intel/soc/common/include/socfpga_sip_svc.h +++ b/plat/intel/soc/common/include/socfpga_sip_svc.h @@ -116,10 +116,12 @@ #define INTEL_SIP_SMC_FCS_ECDSA_HASH_SIGN_INIT 0xC200007D #define INTEL_SIP_SMC_FCS_ECDSA_HASH_SIGN_FINALIZE 0xC200007F #define INTEL_SIP_SMC_FCS_ECDSA_SHA2_DATA_SIGN_INIT 0xC2000080 +#define INTEL_SIP_SMC_FCS_ECDSA_SHA2_DATA_SIGN_UPDATE 0xC2000081 #define INTEL_SIP_SMC_FCS_ECDSA_SHA2_DATA_SIGN_FINALIZE 0xC2000082 #define INTEL_SIP_SMC_FCS_ECDSA_HASH_SIG_VERIFY_INIT 0xC2000083 #define INTEL_SIP_SMC_FCS_ECDSA_HASH_SIG_VERIFY_FINALIZE 0xC2000085 #define INTEL_SIP_SMC_FCS_ECDSA_SHA2_DATA_SIG_VERIFY_INIT 0xC2000086 +#define INTEL_SIP_SMC_FCS_ECDSA_SHA2_DATA_SIG_VERIFY_UPDATE 0xC2000087 #define INTEL_SIP_SMC_FCS_ECDSA_SHA2_DATA_SIG_VERIFY_FINALIZE 0xC2000088 #define INTEL_SIP_SMC_FCS_ECDSA_GET_PUBKEY_INIT 0xC2000089 #define INTEL_SIP_SMC_FCS_ECDSA_GET_PUBKEY_FINALIZE 0xC200008B diff --git a/plat/intel/soc/common/sip/socfpga_sip_fcs.c b/plat/intel/soc/common/sip/socfpga_sip_fcs.c index a987a6e35..8e223866c 100644 --- a/plat/intel/soc/common/sip/socfpga_sip_fcs.c +++ b/plat/intel/soc/common/sip/socfpga_sip_fcs.c @@ -71,6 +71,8 @@ static int intel_fcs_crypto_service_init(uint32_t session_id, data_addr->crypto_param_size = param_size; data_addr->crypto_param = param_data; + data_addr->is_updated = 0; + *mbox_error = 0; return INTEL_SIP_SMC_STATUS_OK; @@ -1197,13 +1199,16 @@ int intel_fcs_ecdsa_sha2_data_sign_init(uint32_t session_id, mbox_error); } -int intel_fcs_ecdsa_sha2_data_sign_finalize(uint32_t session_id, +int intel_fcs_ecdsa_sha2_data_sign_update_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) + uint32_t *dst_size, uint8_t is_finalised, + uint32_t *mbox_error) { int status; int i; + uint32_t flag; + uint32_t crypto_header; uint32_t payload[FCS_ECDSA_SHA2_DATA_SIGN_CMD_MAX_WORD_SIZE] = {0U}; uint32_t resp_len; @@ -1228,26 +1233,43 @@ int intel_fcs_ecdsa_sha2_data_sign_finalize(uint32_t session_id, resp_len = *dst_size / MBOX_WORD_BYTE; + /* Prepare crypto header */ + flag = 0; + if (fcs_sha2_data_sign_param.is_updated) { + fcs_sha2_data_sign_param.crypto_param_size = 0; + } else { + flag |= FCS_CS_FIELD_FLAG_INIT; + } + + if (is_finalised != 0U) { + flag |= FCS_CS_FIELD_FLAG_FINALIZE; + } else { + flag |= FCS_CS_FIELD_FLAG_UPDATE; + fcs_sha2_data_sign_param.is_updated = 1; + } + crypto_header = (flag << FCS_CS_FIELD_FLAG_OFFSET) | + fcs_sha2_data_sign_param.crypto_param_size; + /* Prepare command payload */ - /* Crypto header */ i = 0; payload[i] = fcs_sha2_data_sign_param.session_id; i++; payload[i] = fcs_sha2_data_sign_param.context_id; i++; - payload[i] = fcs_sha2_data_sign_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; + payload[i] = crypto_header; i++; - payload[i] = fcs_sha2_data_sign_param.key_id; - /* Crypto parameters */ - i++; - payload[i] = fcs_sha2_data_sign_param.crypto_param - & INTEL_SIP_SMC_FCS_ECC_ALGO_MASK; + + if ((crypto_header >> FCS_CS_FIELD_FLAG_OFFSET) & + FCS_CS_FIELD_FLAG_INIT) { + payload[i] = fcs_sha2_data_sign_param.key_id; + /* Crypto parameters */ + i++; + payload[i] = fcs_sha2_data_sign_param.crypto_param + & INTEL_SIP_SMC_FCS_ECC_ALGO_MASK; + i++; + } + /* Data source address and size */ - i++; payload[i] = src_addr; i++; payload[i] = src_size; @@ -1257,8 +1279,10 @@ int intel_fcs_ecdsa_sha2_data_sign_finalize(uint32_t session_id, i, CMD_CASUAL, (uint32_t *) dst_addr, &resp_len); - memset((void *)&fcs_sha2_data_sign_param, 0, + if (is_finalised != 0U) { + memset((void *)&fcs_sha2_data_sign_param, 0, sizeof(fcs_crypto_service_data)); + } if (status < 0) { *mbox_error = -status; @@ -1282,14 +1306,16 @@ int intel_fcs_ecdsa_sha2_data_sig_verify_init(uint32_t session_id, mbox_error); } -int intel_fcs_ecdsa_sha2_data_sig_verify_finalize(uint32_t session_id, +int intel_fcs_ecdsa_sha2_data_sig_verify_update_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 data_size, - uint32_t *mbox_error) + uint8_t is_finalised, uint32_t *mbox_error) { int status; uint32_t i; + uint32_t flag; + uint32_t crypto_header; uint32_t payload[FCS_ECDSA_SHA2_DATA_SIG_VERIFY_CMD_MAX_WORD_SIZE] = {0U}; uint32_t resp_len; uintptr_t sig_pubkey_offset; @@ -1319,44 +1345,65 @@ int intel_fcs_ecdsa_sha2_data_sig_verify_finalize(uint32_t session_id, resp_len = *dst_size / MBOX_WORD_BYTE; + /* Prepare crypto header */ + flag = 0; + if (fcs_sha2_data_sig_verify_param.is_updated) + fcs_sha2_data_sig_verify_param.crypto_param_size = 0; + else + flag |= FCS_CS_FIELD_FLAG_INIT; + + if (is_finalised != 0U) + flag |= FCS_CS_FIELD_FLAG_FINALIZE; + else { + flag |= FCS_CS_FIELD_FLAG_UPDATE; + fcs_sha2_data_sig_verify_param.is_updated = 1; + } + crypto_header = (flag << FCS_CS_FIELD_FLAG_OFFSET) | + fcs_sha2_data_sig_verify_param.crypto_param_size; + /* Prepare command payload */ - /* Crypto header */ i = 0; payload[i] = fcs_sha2_data_sig_verify_param.session_id; i++; payload[i] = fcs_sha2_data_sig_verify_param.context_id; i++; + payload[i] = crypto_header; + i++; + + if ((crypto_header >> FCS_CS_FIELD_FLAG_OFFSET) & + FCS_CS_FIELD_FLAG_INIT) { + payload[i] = fcs_sha2_data_sig_verify_param.key_id; + i++; + /* Crypto parameters */ + payload[i] = fcs_sha2_data_sig_verify_param.crypto_param + & INTEL_SIP_SMC_FCS_ECC_ALGO_MASK; + i++; + } - payload[i] = fcs_sha2_data_sig_verify_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_sha2_data_sig_verify_param.key_id; - i++; - /* Crypto parameters */ - payload[i] = fcs_sha2_data_sig_verify_param.crypto_param - & INTEL_SIP_SMC_FCS_ECC_ALGO_MASK; - i++; /* Data source address and size */ payload[i] = src_addr; i++; payload[i] = data_size; i++; - /* Signature + Public Key Data */ - sig_pubkey_offset = src_addr + data_size; - memcpy((uint8_t *) &payload[i], (uint8_t *) sig_pubkey_offset, - src_size - data_size); - i += (src_size - data_size) / MBOX_WORD_BYTE; + if ((crypto_header >> FCS_CS_FIELD_FLAG_OFFSET) & + FCS_CS_FIELD_FLAG_FINALIZE) { + /* Signature + Public Key Data */ + sig_pubkey_offset = src_addr + data_size; + memcpy((uint8_t *) &payload[i], (uint8_t *) sig_pubkey_offset, + src_size - data_size); + + i += (src_size - data_size) / MBOX_WORD_BYTE; + } status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_ECDSA_SHA2_DATA_SIGN_VERIFY, payload, i, CMD_CASUAL, (uint32_t *) dst_addr, &resp_len); - memset((void *) &fcs_sha2_data_sig_verify_param, 0, + if (is_finalised != 0U) { + memset((void *) &fcs_sha2_data_sig_verify_param, 0, sizeof(fcs_crypto_service_data)); + } if (status < 0) { *mbox_error = -status; diff --git a/plat/intel/soc/common/socfpga_sip_svc.c b/plat/intel/soc/common/socfpga_sip_svc.c index 8f1f1a9e8..b2133cc1c 100644 --- a/plat/intel/soc/common/socfpga_sip_svc.c +++ b/plat/intel/soc/common/socfpga_sip_svc.c @@ -930,11 +930,20 @@ uintptr_t sip_smc_handler_v1(uint32_t smc_fid, x4, x5, &mbox_error); SMC_RET2(handle, status, mbox_error); + case INTEL_SIP_SMC_FCS_ECDSA_SHA2_DATA_SIGN_UPDATE: + x5 = SMC_GET_GP(handle, CTX_GPREG_X5); + x6 = SMC_GET_GP(handle, CTX_GPREG_X6); + status = intel_fcs_ecdsa_sha2_data_sign_update_finalize(x1, x2, + x3, x4, x5, (uint32_t *) &x6, false, + &mbox_error); + SMC_RET4(handle, status, mbox_error, x5, x6); + case INTEL_SIP_SMC_FCS_ECDSA_SHA2_DATA_SIGN_FINALIZE: x5 = SMC_GET_GP(handle, CTX_GPREG_X5); x6 = SMC_GET_GP(handle, CTX_GPREG_X6); - status = intel_fcs_ecdsa_sha2_data_sign_finalize(x1, x2, x3, - x4, x5, (uint32_t *) &x6, &mbox_error); + status = intel_fcs_ecdsa_sha2_data_sign_update_finalize(x1, x2, + x3, x4, x5, (uint32_t *) &x6, true, + &mbox_error); SMC_RET4(handle, status, mbox_error, x5, x6); case INTEL_SIP_SMC_FCS_ECDSA_HASH_SIGN_INIT: @@ -969,12 +978,22 @@ uintptr_t sip_smc_handler_v1(uint32_t smc_fid, x4, x5, &mbox_error); SMC_RET2(handle, status, mbox_error); + case INTEL_SIP_SMC_FCS_ECDSA_SHA2_DATA_SIG_VERIFY_UPDATE: + x5 = SMC_GET_GP(handle, CTX_GPREG_X5); + x6 = SMC_GET_GP(handle, CTX_GPREG_X6); + x7 = SMC_GET_GP(handle, CTX_GPREG_X7); + status = intel_fcs_ecdsa_sha2_data_sig_verify_update_finalize( + x1, x2, x3, x4, x5, (uint32_t *) &x6, + x7, false, &mbox_error); + SMC_RET4(handle, status, mbox_error, x5, x6); + case INTEL_SIP_SMC_FCS_ECDSA_SHA2_DATA_SIG_VERIFY_FINALIZE: x5 = SMC_GET_GP(handle, CTX_GPREG_X5); x6 = SMC_GET_GP(handle, CTX_GPREG_X6); x7 = SMC_GET_GP(handle, CTX_GPREG_X7); - status = intel_fcs_ecdsa_sha2_data_sig_verify_finalize(x1, x2, x3, - x4, x5, (uint32_t *) &x6, x7, &mbox_error); + status = intel_fcs_ecdsa_sha2_data_sig_verify_update_finalize( + x1, x2, x3, x4, x5, (uint32_t *) &x6, + x7, true, &mbox_error); SMC_RET4(handle, status, mbox_error, x5, x6); case INTEL_SIP_SMC_FCS_ECDSA_GET_PUBKEY_INIT: