From 02d3ef333d4a0a07a3e40defb12a8cde3a7cba03 Mon Sep 17 00:00:00 2001 From: Sieu Mun Tang Date: Wed, 11 May 2022 09:49:25 +0800 Subject: [PATCH 01/28] fix(intel): update encryption and decryption command logic This change is to re-align HPS cryption logic with underlying Secure Device Manager's (SDM) mailbox API. Signed-off-by: Abdul Halim, Muhammad Hadi Asyrafi Signed-off-by: Sieu Mun Tang Change-Id: I8fc90982d3cddceaf401c1a112ff8e20861bf4c5 --- plat/intel/soc/common/include/socfpga_fcs.h | 29 +++++++-- .../soc/common/include/socfpga_sip_svc.h | 5 +- plat/intel/soc/common/sip/socfpga_sip_fcs.c | 61 ++++++++++++++----- plat/intel/soc/common/socfpga_sip_svc.c | 13 ++++ 4 files changed, 86 insertions(+), 22 deletions(-) diff --git a/plat/intel/soc/common/include/socfpga_fcs.h b/plat/intel/soc/common/include/socfpga_fcs.h index d3b7141b1..a3efd808c 100644 --- a/plat/intel/soc/common/include/socfpga_fcs.h +++ b/plat/intel/soc/common/include/socfpga_fcs.h @@ -17,17 +17,30 @@ #define FCS_PROV_DATA_BYTE_SIZE (FCS_PROV_DATA_WORD_SIZE * 4U) #define FCS_SHA384_BYTE_SIZE (FCS_SHA384_WORD_SIZE * 4U) -#define FCS_CRYPTION_DATA_0 0x10100 +#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 /* FCS Payload Structure */ -typedef struct fcs_crypt_payload_t { +typedef struct fcs_encrypt_payload_t { uint32_t first_word; uint32_t src_addr; uint32_t src_size; uint32_t dst_addr; uint32_t dst_size; -} fcs_crypt_payload; +} fcs_encrypt_payload; + +typedef struct fcs_decrypt_payload_t { + uint32_t first_word; + uint32_t owner_id[2]; + uint32_t src_addr; + uint32_t src_size; + uint32_t dst_addr; + uint32_t dst_size; +} fcs_decrypt_payload; /* Functions Definitions */ @@ -36,9 +49,13 @@ uint32_t intel_fcs_random_number_gen(uint64_t addr, uint64_t *ret_size, uint32_t intel_fcs_send_cert(uint64_t addr, uint64_t size, uint32_t *send_id); uint32_t intel_fcs_get_provision_data(uint32_t *send_id); -uint32_t intel_fcs_cryption(uint32_t mode, uint32_t src_addr, - uint32_t src_size, uint32_t dst_addr, - uint32_t dst_size, uint32_t *send_id); +uint32_t intel_fcs_encryption(uint32_t src_addr, uint32_t src_size, + uint32_t dst_addr, uint32_t dst_size, + uint32_t *send_id); + +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); uint32_t intel_fcs_get_rom_patch_sha384(uint64_t addr, uint64_t *ret_size, uint32_t *mbox_error); diff --git a/plat/intel/soc/common/include/socfpga_sip_svc.h b/plat/intel/soc/common/include/socfpga_sip_svc.h index ca6f1f856..fcd545098 100644 --- a/plat/intel/soc/common/include/socfpga_sip_svc.h +++ b/plat/intel/soc/common/include/socfpga_sip_svc.h @@ -71,7 +71,8 @@ /* Mailbox Command */ #define INTEL_SIP_SMC_GET_USERCODE 0xC200003D -/* SiP Definitions */ +/* FPGA Crypto Services */ +#define INTEL_SIP_SMC_FCS_CRYPTION 0x4200005B /* ECC DBE */ #define WARM_RESET_WFI_FLAG BIT(31) @@ -103,7 +104,7 @@ struct fpga_config_info { }; /* Function Definitions */ - +bool is_size_4_bytes_aligned(uint32_t size); bool is_address_in_ddr_range(uint64_t addr, uint64_t size); /* ECC DBE */ diff --git a/plat/intel/soc/common/sip/socfpga_sip_fcs.c b/plat/intel/soc/common/sip/socfpga_sip_fcs.c index 85551a4d9..a174e5f2d 100644 --- a/plat/intel/soc/common/sip/socfpga_sip_fcs.c +++ b/plat/intel/soc/common/sip/socfpga_sip_fcs.c @@ -11,7 +11,7 @@ #include "socfpga_mailbox.h" #include "socfpga_sip_svc.h" -static bool is_size_4_bytes_aligned(uint32_t size) +bool is_size_4_bytes_aligned(uint32_t size) { if ((size % MBOX_WORD_BYTE) != 0U) { return false; @@ -95,37 +95,70 @@ uint32_t intel_fcs_get_provision_data(uint32_t *send_id) return INTEL_SIP_SMC_STATUS_OK; } -uint32_t intel_fcs_cryption(uint32_t mode, uint32_t src_addr, - uint32_t src_size, uint32_t dst_addr, - uint32_t dst_size, uint32_t *send_id) +uint32_t intel_fcs_encryption(uint32_t src_addr, uint32_t src_size, + uint32_t dst_addr, uint32_t dst_size, uint32_t *send_id) { int status; - uint32_t cmd; + uint32_t load_size; - fcs_crypt_payload payload = { - FCS_CRYPTION_DATA_0, + fcs_encrypt_payload payload = { + FCS_ENCRYPTION_DATA_0, src_addr, src_size, dst_addr, dst_size }; + load_size = sizeof(payload) / MBOX_WORD_BYTE; 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(sizeof(fcs_crypt_payload))) { + if (!is_size_4_bytes_aligned(src_size)) { return INTEL_SIP_SMC_STATUS_REJECTED; } - if (mode != 0U) { - cmd = MBOX_FCS_ENCRYPT_REQ; - } else { - cmd = MBOX_FCS_DECRYPT_REQ; + status = mailbox_send_cmd_async(send_id, MBOX_FCS_ENCRYPT_REQ, + (uint32_t *) &payload, load_size, + CMD_INDIRECT); + inv_dcache_range(dst_addr, dst_size); + + if (status < 0) { + return INTEL_SIP_SMC_STATUS_REJECTED; } - status = mailbox_send_cmd_async(send_id, cmd, (uint32_t *) &payload, - sizeof(fcs_crypt_payload) / MBOX_WORD_BYTE, + return INTEL_SIP_SMC_STATUS_OK; +} + +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 status; + uint32_t load_size; + uintptr_t id_offset; + + id_offset = src_addr + FCS_OWNER_ID_OFFSET; + fcs_decrypt_payload payload = { + FCS_DECRYPTION_DATA_0, + {mmio_read_32(id_offset), + mmio_read_32(id_offset + MBOX_WORD_BYTE)}, + src_addr, + src_size, + dst_addr, + dst_size }; + load_size = sizeof(payload) / MBOX_WORD_BYTE; + + 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; + } + + status = mailbox_send_cmd_async(send_id, MBOX_FCS_DECRYPT_REQ, + (uint32_t *) &payload, load_size, CMD_INDIRECT); inv_dcache_range(dst_addr, dst_size); diff --git a/plat/intel/soc/common/socfpga_sip_svc.c b/plat/intel/soc/common/socfpga_sip_svc.c index 79444cfa6..a80208fae 100644 --- a/plat/intel/soc/common/socfpga_sip_svc.c +++ b/plat/intel/soc/common/socfpga_sip_svc.c @@ -711,6 +711,19 @@ uintptr_t sip_smc_handler(uint32_t smc_fid, status = intel_smc_get_usercode(&retval); SMC_RET2(handle, status, retval); + case INTEL_SIP_SMC_FCS_CRYPTION: + x5 = SMC_GET_GP(handle, CTX_GPREG_X5); + + if (x1 == FCS_MODE_DECRYPT) { + status = intel_fcs_decryption(x2, x3, x4, x5, &send_id); + } else if (x1 == FCS_MODE_ENCRYPT) { + status = intel_fcs_encryption(x2, x3, x4, x5, &send_id); + } else { + status = INTEL_SIP_SMC_STATUS_REJECTED; + } + + SMC_RET3(handle, status, x4, x5); + case INTEL_SIP_SMC_HPS_SET_BRIDGES: status = intel_hps_set_bridges(x1, x2); SMC_RET1(handle, status); From d17408316db10db611e23716e8a5b9b9f53ad509 Mon Sep 17 00:00:00 2001 From: Sieu Mun Tang Date: Wed, 11 May 2022 09:59:55 +0800 Subject: [PATCH 02/28] feat(intel): initial commit for attestation service This is to extend the functionality of FPGA Crypto Service (FCS) to support FPGA Attestation feature in Stratix 10 device. Signed-off-by: Boon Khai Ng Signed-off-by: Sieu Mun Tang Change-Id: Ib15783383dc9a06a2f0dc6dc1786f44b89f32cb1 --- plat/intel/soc/common/include/socfpga_fcs.h | 21 ++++ .../soc/common/include/socfpga_mailbox.h | 9 ++ .../soc/common/include/socfpga_sip_svc.h | 4 + plat/intel/soc/common/sip/socfpga_sip_fcs.c | 104 ++++++++++++++++++ plat/intel/soc/common/socfpga_sip_svc.c | 22 +++- 5 files changed, 158 insertions(+), 2 deletions(-) diff --git a/plat/intel/soc/common/include/socfpga_fcs.h b/plat/intel/soc/common/include/socfpga_fcs.h index a3efd808c..d5125df71 100644 --- a/plat/intel/soc/common/include/socfpga_fcs.h +++ b/plat/intel/soc/common/include/socfpga_fcs.h @@ -23,6 +23,12 @@ #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 RESERVED_AS_ZERO 0x0 + /* FCS Payload Structure */ typedef struct fcs_encrypt_payload_t { @@ -42,6 +48,13 @@ typedef struct fcs_decrypt_payload_t { uint32_t dst_size; } fcs_decrypt_payload; +typedef struct psgsigma_teardown_msg_t { + uint32_t reserved_word; + uint32_t magic_word; + uint32_t session_id; +} psgsigma_teardown_msg; + + /* Functions Definitions */ uint32_t intel_fcs_random_number_gen(uint64_t addr, uint64_t *ret_size, @@ -57,6 +70,14 @@ 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_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, + uint64_t dst_addr, uint32_t *dst_size, + uint32_t *mbox_error); +int intel_fcs_get_measurement(uint64_t src_addr, uint32_t src_size, + uint64_t dst_addr, uint32_t *dst_size, + uint32_t *mbox_error); uint32_t intel_fcs_get_rom_patch_sha384(uint64_t addr, uint64_t *ret_size, uint32_t *mbox_error); diff --git a/plat/intel/soc/common/include/socfpga_mailbox.h b/plat/intel/soc/common/include/socfpga_mailbox.h index b260a627e..eafe2411b 100644 --- a/plat/intel/soc/common/include/socfpga_mailbox.h +++ b/plat/intel/soc/common/include/socfpga_mailbox.h @@ -43,6 +43,7 @@ #define MBOX_CMD_VAB_SRC_CERT 0x0B #define MBOX_CMD_GET_IDCODE 0x10 #define MBOX_CMD_GET_USERCODE 0x13 +#define MBOX_CMD_GET_CHIPID 0x12 #define MBOX_CMD_REBOOT_HPS 0x47 /* Reconfiguration Commands */ @@ -73,6 +74,14 @@ #define MBOX_FCS_ENCRYPT_REQ 0x7E #define MBOX_FCS_DECRYPT_REQ 0x7F #define MBOX_FCS_RANDOM_GEN 0x80 + +/* PSG SIGMA Commands */ +#define MBOX_PSG_SIGMA_TEARDOWN 0xD5 + +/* Attestation Commands */ +#define MBOX_ATTESTATION_SUBKEY 0x182 +#define MBOX_GET_MEASUREMENT 0x183 + /* Miscellaneous commands */ #define MBOX_GET_ROM_PATCH_SHA384 0x1B0 diff --git a/plat/intel/soc/common/include/socfpga_sip_svc.h b/plat/intel/soc/common/include/socfpga_sip_svc.h index fcd545098..26db14b39 100644 --- a/plat/intel/soc/common/include/socfpga_sip_svc.h +++ b/plat/intel/soc/common/include/socfpga_sip_svc.h @@ -73,6 +73,10 @@ /* FPGA Crypto Services */ #define INTEL_SIP_SMC_FCS_CRYPTION 0x4200005B +#define INTEL_SIP_SMC_FCS_PSGSIGMA_TEARDOWN 0xC2000064 +#define INTEL_SIP_SMC_FCS_CHIP_ID 0xC2000065 +#define INTEL_SIP_SMC_FCS_ATTESTATION_SUBKEY 0xC2000066 +#define INTEL_SIP_SMC_FCS_ATTESTATION_MEASUREMENTS 0xC2000067 /* ECC DBE */ #define WARM_RESET_WFI_FLAG BIT(31) diff --git a/plat/intel/soc/common/sip/socfpga_sip_fcs.c b/plat/intel/soc/common/sip/socfpga_sip_fcs.c index a174e5f2d..4b06fa60c 100644 --- a/plat/intel/soc/common/sip/socfpga_sip_fcs.c +++ b/plat/intel/soc/common/sip/socfpga_sip_fcs.c @@ -198,3 +198,107 @@ uint32_t intel_fcs_get_rom_patch_sha384(uint64_t addr, uint64_t *ret_size, return INTEL_SIP_SMC_STATUS_OK; } + +int intel_fcs_sigma_teardown(uint32_t session_id, uint32_t *mbox_error) +{ + int status; + + if ((session_id != PSGSIGMA_SESSION_ID_ONE) && + (session_id != PSGSIGMA_UNKNOWN_SESSION)) { + return INTEL_SIP_SMC_STATUS_REJECTED; + } + + psgsigma_teardown_msg message = { + RESERVED_AS_ZERO, + PSGSIGMA_TEARDOWN_MAGIC, + session_id + }; + + status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_PSG_SIGMA_TEARDOWN, + (uint32_t *) &message, sizeof(message) / MBOX_WORD_BYTE, + CMD_CASUAL, NULL, NULL); + + if (status < 0) { + *mbox_error = -status; + return INTEL_SIP_SMC_STATUS_ERROR; + } + + return INTEL_SIP_SMC_STATUS_OK; +} + +int intel_fcs_chip_id(uint32_t *id_low, uint32_t *id_high, uint32_t *mbox_error) +{ + int status; + uint32_t load_size; + uint32_t chip_id[2]; + + load_size = sizeof(chip_id) / MBOX_WORD_BYTE; + + status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_CMD_GET_CHIPID, NULL, + 0U, CMD_CASUAL, (uint32_t *) chip_id, &load_size); + + if (status < 0) { + *mbox_error = -status; + return INTEL_SIP_SMC_STATUS_ERROR; + } + + *id_low = chip_id[0]; + *id_high = chip_id[1]; + + return INTEL_SIP_SMC_STATUS_OK; +} + +int intel_fcs_attestation_subkey(uint64_t src_addr, uint32_t src_size, + uint64_t dst_addr, uint32_t *dst_size, uint32_t *mbox_error) +{ + int status; + uint32_t send_size = src_size / MBOX_WORD_BYTE; + uint32_t ret_size = *dst_size / MBOX_WORD_BYTE; + + + 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; + } + + status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_ATTESTATION_SUBKEY, + (uint32_t *) src_addr, send_size, CMD_CASUAL, + (uint32_t *) dst_addr, &ret_size); + + if (status < 0) { + *mbox_error = -status; + return INTEL_SIP_SMC_STATUS_ERROR; + } + + *dst_size = ret_size * MBOX_WORD_BYTE; + flush_dcache_range(dst_addr, *dst_size); + + return INTEL_SIP_SMC_STATUS_OK; +} + +int intel_fcs_get_measurement(uint64_t src_addr, uint32_t src_size, + uint64_t dst_addr, uint32_t *dst_size, uint32_t *mbox_error) +{ + int status; + uint32_t send_size = src_size / MBOX_WORD_BYTE; + uint32_t ret_size = *dst_size / MBOX_WORD_BYTE; + + 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; + } + + status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_GET_MEASUREMENT, + (uint32_t *) src_addr, send_size, CMD_CASUAL, + (uint32_t *) dst_addr, &ret_size); + + if (status < 0) { + *mbox_error = -status; + return INTEL_SIP_SMC_STATUS_ERROR; + } + + *dst_size = ret_size * 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 a80208fae..851bc941c 100644 --- a/plat/intel/soc/common/socfpga_sip_svc.c +++ b/plat/intel/soc/common/socfpga_sip_svc.c @@ -565,9 +565,9 @@ uintptr_t sip_smc_handler(uint32_t smc_fid, void *handle, u_register_t flags) { - uint32_t retval = 0; + uint32_t retval = 0, completed_addr[3]; + uint32_t retval2 = 0; uint32_t mbox_error = 0; - uint32_t completed_addr[3]; uint64_t retval64, rsu_respbuf[9]; int status = INTEL_SIP_SMC_STATUS_OK; int mbox_status; @@ -728,6 +728,24 @@ uintptr_t sip_smc_handler(uint32_t smc_fid, status = intel_hps_set_bridges(x1, x2); SMC_RET1(handle, status); + case INTEL_SIP_SMC_FCS_PSGSIGMA_TEARDOWN: + status = intel_fcs_sigma_teardown(x1, &mbox_error); + SMC_RET2(handle, status, mbox_error); + + case INTEL_SIP_SMC_FCS_CHIP_ID: + status = intel_fcs_chip_id(&retval, &retval2, &mbox_error); + SMC_RET4(handle, status, mbox_error, retval, retval2); + + case INTEL_SIP_SMC_FCS_ATTESTATION_SUBKEY: + status = intel_fcs_attestation_subkey(x1, x2, x3, + (uint32_t *) &x4, &mbox_error); + SMC_RET4(handle, status, mbox_error, x3, x4); + + case INTEL_SIP_SMC_FCS_ATTESTATION_MEASUREMENTS: + status = intel_fcs_get_measurement(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); From 7facacec6328e505b243a4974d045d45fe068afd Mon Sep 17 00:00:00 2001 From: Sieu Mun Tang Date: Wed, 11 May 2022 10:01:54 +0800 Subject: [PATCH 03/28] feat(intel): single certificate feature enablement Extend the functionality of FPGA Crypto Service (FCS) to support FPGA single certificate feature so that the counter value can be updated with only one preauthorized certificate Signed-off-by: Boon Khai Ng Signed-off-by: Sieu Mun Tang Change-Id: Ibde87e4ee46367cf7f27f7bb0172838ab8766340 --- plat/intel/soc/common/include/socfpga_fcs.h | 19 ++++++++ .../soc/common/include/socfpga_mailbox.h | 3 +- .../soc/common/include/socfpga_sip_svc.h | 1 + plat/intel/soc/common/sip/socfpga_sip_fcs.c | 47 +++++++++++++++++++ plat/intel/soc/common/socfpga_sip_svc.c | 5 ++ 5 files changed, 74 insertions(+), 1 deletion(-) diff --git a/plat/intel/soc/common/include/socfpga_fcs.h b/plat/intel/soc/common/include/socfpga_fcs.h index d5125df71..1df163971 100644 --- a/plat/intel/soc/common/include/socfpga_fcs.h +++ b/plat/intel/soc/common/include/socfpga_fcs.h @@ -28,6 +28,17 @@ #define PSGSIGMA_UNKNOWN_SESSION 0xFFFFFFFF #define RESERVED_AS_ZERO 0x0 +/* FCS Single cert */ + +#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_BIG_CNTR_VAL_MAX 495U +#define FCS_SVN_CNTR_VAL_MAX 64U /* FCS Payload Structure */ @@ -54,6 +65,10 @@ typedef struct psgsigma_teardown_msg_t { uint32_t session_id; } psgsigma_teardown_msg; +typedef struct fcs_cntr_set_preauth_payload_t { + uint32_t first_word; + uint32_t counter_value; +} fcs_cntr_set_preauth_payload; /* Functions Definitions */ @@ -62,6 +77,10 @@ uint32_t intel_fcs_random_number_gen(uint64_t addr, uint64_t *ret_size, uint32_t intel_fcs_send_cert(uint64_t addr, uint64_t size, uint32_t *send_id); uint32_t intel_fcs_get_provision_data(uint32_t *send_id); +uint32_t intel_fcs_cntr_set_preauth(uint8_t counter_type, + int32_t counter_value, + uint32_t test_bit, + uint32_t *mbox_error); uint32_t intel_fcs_encryption(uint32_t src_addr, uint32_t src_size, uint32_t dst_addr, uint32_t dst_size, uint32_t *send_id); diff --git a/plat/intel/soc/common/include/socfpga_mailbox.h b/plat/intel/soc/common/include/socfpga_mailbox.h index eafe2411b..64024b8a9 100644 --- a/plat/intel/soc/common/include/socfpga_mailbox.h +++ b/plat/intel/soc/common/include/socfpga_mailbox.h @@ -16,7 +16,7 @@ #define MBOX_MAX_JOB_ID 0xFU #define MBOX_MAX_IND_JOB_ID (MBOX_MAX_JOB_ID - 1U) #define MBOX_JOB_ID MBOX_MAX_JOB_ID - +#define MBOX_TEST_BIT BIT(31) /* Mailbox Shared Memory Register Map */ #define MBOX_CIN 0x00 @@ -71,6 +71,7 @@ /* FCS Command */ #define MBOX_FCS_GET_PROVISION 0x7B +#define MBOX_FCS_CNTR_SET_PREAUTH 0x7C #define MBOX_FCS_ENCRYPT_REQ 0x7E #define MBOX_FCS_DECRYPT_REQ 0x7F #define MBOX_FCS_RANDOM_GEN 0x80 diff --git a/plat/intel/soc/common/include/socfpga_sip_svc.h b/plat/intel/soc/common/include/socfpga_sip_svc.h index 26db14b39..53aece3ba 100644 --- a/plat/intel/soc/common/include/socfpga_sip_svc.h +++ b/plat/intel/soc/common/include/socfpga_sip_svc.h @@ -73,6 +73,7 @@ /* FPGA Crypto Services */ #define INTEL_SIP_SMC_FCS_CRYPTION 0x4200005B +#define INTEL_SIP_SMC_FCS_CNTR_SET_PREAUTH 0xC200005F #define INTEL_SIP_SMC_FCS_PSGSIGMA_TEARDOWN 0xC2000064 #define INTEL_SIP_SMC_FCS_CHIP_ID 0xC2000065 #define INTEL_SIP_SMC_FCS_ATTESTATION_SUBKEY 0xC2000066 diff --git a/plat/intel/soc/common/sip/socfpga_sip_fcs.c b/plat/intel/soc/common/sip/socfpga_sip_fcs.c index 4b06fa60c..26da55efc 100644 --- a/plat/intel/soc/common/sip/socfpga_sip_fcs.c +++ b/plat/intel/soc/common/sip/socfpga_sip_fcs.c @@ -95,6 +95,53 @@ uint32_t intel_fcs_get_provision_data(uint32_t *send_id) return INTEL_SIP_SMC_STATUS_OK; } +uint32_t intel_fcs_cntr_set_preauth(uint8_t counter_type, int32_t counter_value, + uint32_t test_bit, uint32_t *mbox_error) +{ + int status; + uint32_t first_word; + uint32_t payload_size; + + if ((test_bit != MBOX_TEST_BIT) && + (test_bit != 0)) { + return INTEL_SIP_SMC_STATUS_REJECTED; + } + + if ((counter_type < FCS_BIG_CNTR_SEL) || + (counter_type > FCS_SVN_CNTR_3_SEL)) { + return INTEL_SIP_SMC_STATUS_REJECTED; + } + + if ((counter_type == FCS_BIG_CNTR_SEL) && + (counter_value > FCS_BIG_CNTR_VAL_MAX)) { + return INTEL_SIP_SMC_STATUS_REJECTED; + } + + if ((counter_type >= FCS_SVN_CNTR_0_SEL) && + (counter_type <= FCS_SVN_CNTR_3_SEL) && + (counter_value > FCS_SVN_CNTR_VAL_MAX)) { + return INTEL_SIP_SMC_STATUS_REJECTED; + } + + first_word = test_bit | counter_type; + fcs_cntr_set_preauth_payload payload = { + first_word, + counter_value + }; + + payload_size = sizeof(payload) / MBOX_WORD_BYTE; + status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_CNTR_SET_PREAUTH, + (uint32_t *) &payload, payload_size, + CMD_CASUAL, NULL, NULL); + + if (status < 0) { + *mbox_error = -status; + return INTEL_SIP_SMC_STATUS_ERROR; + } + + return INTEL_SIP_SMC_STATUS_OK; +} + uint32_t intel_fcs_encryption(uint32_t src_addr, uint32_t src_size, uint32_t dst_addr, uint32_t dst_size, uint32_t *send_id) { diff --git a/plat/intel/soc/common/socfpga_sip_svc.c b/plat/intel/soc/common/socfpga_sip_svc.c index 851bc941c..294040b9b 100644 --- a/plat/intel/soc/common/socfpga_sip_svc.c +++ b/plat/intel/soc/common/socfpga_sip_svc.c @@ -724,6 +724,11 @@ uintptr_t sip_smc_handler(uint32_t smc_fid, SMC_RET3(handle, status, x4, x5); + case INTEL_SIP_SMC_FCS_CNTR_SET_PREAUTH: + status = intel_fcs_cntr_set_preauth(x1, x2, x3, + &mbox_error); + SMC_RET2(handle, status, mbox_error); + case INTEL_SIP_SMC_HPS_SET_BRIDGES: status = intel_hps_set_bridges(x1, x2); SMC_RET1(handle, status); From 4837a640934630f8034ceec1bb84cc40673d8a6b Mon Sep 17 00:00:00 2001 From: Sieu Mun Tang Date: Sat, 7 May 2022 00:50:37 +0800 Subject: [PATCH 04/28] fix(intel): allow non-secure access to FPGA Crypto Services (FCS) Allows non-secure software to access FPGA Crypto Services (FCS) through secure monitor calls (SMC). Signed-off-by: Abdul Halim, Muhammad Hadi Asyrafi Signed-off-by: Sieu Mun Tang Change-Id: I805b3f650abf5e118e2c55e469866d5d0ca68048 --- .../soc/common/include/socfpga_mailbox.h | 21 +++++ .../soc/common/include/socfpga_sip_svc.h | 16 +++- plat/intel/soc/common/soc/socfpga_mailbox.c | 91 +++++++++++++++++++ plat/intel/soc/common/socfpga_sip_svc.c | 59 ++++++++++++ 4 files changed, 182 insertions(+), 5 deletions(-) diff --git a/plat/intel/soc/common/include/socfpga_mailbox.h b/plat/intel/soc/common/include/socfpga_mailbox.h index 64024b8a9..fcf5fc206 100644 --- a/plat/intel/soc/common/include/socfpga_mailbox.h +++ b/plat/intel/soc/common/include/socfpga_mailbox.h @@ -108,6 +108,7 @@ #define MBOX_NO_RESPONSE -2 #define MBOX_WRONG_ID -3 #define MBOX_BUFFER_FULL -4 +#define MBOX_BUSY -5 #define MBOX_TIMEOUT -2047 /* Reconfig Status Response */ @@ -157,6 +158,10 @@ #define MBOX_INDIRECT(val) ((val) << 11) #define MBOX_CMD_MASK(header) ((header) & 0x7ff) +/* Mailbox payload */ +#define MBOX_DATA_MAX_LEN 0x3ff +#define MBOX_PAYLOAD_FLAG_BUSY BIT(0) + /* RSU Macros */ #define RSU_VERSION_ACMF BIT(8) #define RSU_VERSION_ACMF_MASK 0xff00 @@ -166,6 +171,19 @@ #define CONFIG_STATUS_FW_VER_OFFSET 1 #define CONFIG_STATUS_FW_VER_MASK 0x00FFFFFF +/* Data structure */ + +typedef struct mailbox_payload { + uint32_t header; + uint32_t data[MBOX_DATA_MAX_LEN]; +} mailbox_payload_t; + +typedef struct mailbox_container { + uint32_t flag; + uint32_t index; + mailbox_payload_t *payload; +} mailbox_container_t; + /* Mailbox Function Definitions */ void mailbox_set_int(uint32_t interrupt_input); @@ -180,6 +198,9 @@ int mailbox_send_cmd_async(uint32_t *job_id, uint32_t cmd, uint32_t *args, unsigned int len, unsigned int indirect); int mailbox_read_response(uint32_t *job_id, uint32_t *response, unsigned int *resp_len); +int mailbox_read_response_async(uint32_t *job_id, uint32_t *header, + uint32_t *response, unsigned int *resp_len, + uint8_t ignore_client_id); int iterate_resp(uint32_t mbox_resp_len, uint32_t *resp_buf, unsigned int *resp_len); diff --git a/plat/intel/soc/common/include/socfpga_sip_svc.h b/plat/intel/soc/common/include/socfpga_sip_svc.h index 53aece3ba..e46bee701 100644 --- a/plat/intel/soc/common/include/socfpga_sip_svc.h +++ b/plat/intel/soc/common/include/socfpga_sip_svc.h @@ -12,6 +12,7 @@ #define INTEL_SIP_SMC_STATUS_OK 0 #define INTEL_SIP_SMC_STATUS_BUSY 0x1 #define INTEL_SIP_SMC_STATUS_REJECTED 0x2 +#define INTEL_SIP_SMC_STATUS_NO_RESPONSE 0x3 #define INTEL_SIP_SMC_STATUS_ERROR 0x4 #define INTEL_SIP_SMC_RSU_ERROR 0x7 @@ -68,16 +69,21 @@ #define INTEL_SIP_SMC_FIRMWARE_VERSION 0xC200001F #define INTEL_SIP_SMC_HPS_SET_BRIDGES 0xC2000032 +#define SERVICE_COMPLETED_MODE_ASYNC 0x00004F4E + /* Mailbox Command */ #define INTEL_SIP_SMC_GET_USERCODE 0xC200003D /* FPGA Crypto Services */ +#define INTEL_SIP_SMC_FCS_RANDOM_NUMBER 0xC200005A #define INTEL_SIP_SMC_FCS_CRYPTION 0x4200005B -#define INTEL_SIP_SMC_FCS_CNTR_SET_PREAUTH 0xC200005F -#define INTEL_SIP_SMC_FCS_PSGSIGMA_TEARDOWN 0xC2000064 -#define INTEL_SIP_SMC_FCS_CHIP_ID 0xC2000065 -#define INTEL_SIP_SMC_FCS_ATTESTATION_SUBKEY 0xC2000066 -#define INTEL_SIP_SMC_FCS_ATTESTATION_MEASUREMENTS 0xC2000067 +#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 +#define INTEL_SIP_SMC_FCS_PSGSIGMA_TEARDOWN 0xC2000064 +#define INTEL_SIP_SMC_FCS_CHIP_ID 0xC2000065 +#define INTEL_SIP_SMC_FCS_ATTESTATION_SUBKEY 0xC2000066 +#define INTEL_SIP_SMC_FCS_ATTESTATION_MEASUREMENTS 0xC2000067 /* ECC DBE */ #define WARM_RESET_WFI_FLAG BIT(31) diff --git a/plat/intel/soc/common/soc/socfpga_mailbox.c b/plat/intel/soc/common/soc/socfpga_mailbox.c index 8ecd6db60..0f1214731 100644 --- a/plat/intel/soc/common/soc/socfpga_mailbox.c +++ b/plat/intel/soc/common/soc/socfpga_mailbox.c @@ -11,6 +11,8 @@ #include "socfpga_mailbox.h" #include "socfpga_sip_svc.h" +static mailbox_payload_t mailbox_resp_payload; +static mailbox_container_t mailbox_resp_ctr = {0, 0, &mailbox_resp_payload}; static bool is_mailbox_cmdbuf_full(uint32_t cin) { @@ -171,6 +173,95 @@ int mailbox_read_response(unsigned int *job_id, uint32_t *response, return MBOX_NO_RESPONSE; } +int mailbox_read_response_async(unsigned int *job_id, uint32_t *header, + uint32_t *response, unsigned int *resp_len, + uint8_t ignore_client_id) +{ + uint32_t rin; + uint32_t rout; + uint32_t resp_data; + uint32_t ret_resp_len = 0; + uint8_t is_done = 0; + + if ((mailbox_resp_ctr.flag & MBOX_PAYLOAD_FLAG_BUSY) != 0) { + ret_resp_len = MBOX_RESP_LEN( + mailbox_resp_ctr.payload->header) - + mailbox_resp_ctr.index; + } + + if (mmio_read_32(MBOX_OFFSET + MBOX_DOORBELL_FROM_SDM) == 1U) { + mmio_write_32(MBOX_OFFSET + MBOX_DOORBELL_FROM_SDM, 0U); + } + + rin = mmio_read_32(MBOX_OFFSET + MBOX_RIN); + rout = mmio_read_32(MBOX_OFFSET + MBOX_ROUT); + + while (rout != rin && !is_done) { + + resp_data = mmio_read_32(MBOX_ENTRY_TO_ADDR(RESP, (rout)++)); + + rout %= MBOX_RESP_BUFFER_SIZE; + mmio_write_32(MBOX_OFFSET + MBOX_ROUT, rout); + rin = mmio_read_32(MBOX_OFFSET + MBOX_RIN); + + if ((mailbox_resp_ctr.flag & MBOX_PAYLOAD_FLAG_BUSY) != 0) { + mailbox_resp_ctr.payload->data[mailbox_resp_ctr.index] = resp_data; + mailbox_resp_ctr.index++; + ret_resp_len--; + } else { + if (!ignore_client_id) { + if (MBOX_RESP_CLIENT_ID(resp_data) != MBOX_ATF_CLIENT_ID) { + *resp_len = 0; + return MBOX_WRONG_ID; + } + } + + *job_id = MBOX_RESP_JOB_ID(resp_data); + ret_resp_len = MBOX_RESP_LEN(resp_data); + mailbox_resp_ctr.payload->header = resp_data; + mailbox_resp_ctr.flag |= MBOX_PAYLOAD_FLAG_BUSY; + } + + if (ret_resp_len == 0) { + is_done = 1; + } + } + + if (is_done != 0) { + + /* copy header data to input address if applicable */ + if (header != 0) { + *header = mailbox_resp_ctr.payload->header; + } + + /* copy response data to input buffer if applicable */ + ret_resp_len = MBOX_RESP_LEN(mailbox_resp_ctr.payload->header); + if (ret_resp_len > 0 && response && resp_len) { + if (*resp_len > ret_resp_len) { + *resp_len = ret_resp_len; + } + + memcpy((uint8_t *) response, + (uint8_t *) mailbox_resp_ctr.payload->data, + *resp_len * MBOX_WORD_BYTE); + } + + /* reset async response param */ + mailbox_resp_ctr.index = 0; + mailbox_resp_ctr.flag = 0; + + if (MBOX_RESP_ERR(mailbox_resp_ctr.payload->header) > 0U) { + INFO("Error in async response: %x\n", + mailbox_resp_ctr.payload->header); + return -MBOX_RESP_ERR(mailbox_resp_ctr.payload->header); + } + + return MBOX_RET_OK; + } + + *resp_len = 0; + return (mailbox_resp_ctr.flag & MBOX_PAYLOAD_FLAG_BUSY) ? MBOX_BUSY : MBOX_NO_RESPONSE; +} int mailbox_poll_response(uint32_t job_id, uint32_t urgent, uint32_t *response, unsigned int *resp_len) diff --git a/plat/intel/soc/common/socfpga_sip_svc.c b/plat/intel/soc/common/socfpga_sip_svc.c index 294040b9b..b0b56e932 100644 --- a/plat/intel/soc/common/socfpga_sip_svc.c +++ b/plat/intel/soc/common/socfpga_sip_svc.c @@ -552,6 +552,52 @@ uint32_t intel_hps_set_bridges(uint64_t enable, uint64_t mask) return INTEL_SIP_SMC_STATUS_OK; } +uint32_t intel_smc_service_completed(uint64_t addr, uint32_t size, + uint32_t mode, uint32_t *job_id, + uint32_t *ret_size, uint32_t *mbox_error) +{ + int status = 0; + uint32_t resp_len = size / MBOX_WORD_BYTE; + + if (resp_len > MBOX_DATA_MAX_LEN) { + return INTEL_SIP_SMC_STATUS_REJECTED; + } + + if (!is_address_in_ddr_range(addr, size)) { + return INTEL_SIP_SMC_STATUS_REJECTED; + } + + if (mode == SERVICE_COMPLETED_MODE_ASYNC) { + status = mailbox_read_response_async(job_id, + NULL, (uint32_t *) addr, &resp_len, 0); + } else { + status = mailbox_read_response(job_id, + (uint32_t *) addr, &resp_len); + + if (status == MBOX_NO_RESPONSE) { + status = MBOX_BUSY; + } + } + + if (status == MBOX_NO_RESPONSE) { + return INTEL_SIP_SMC_STATUS_NO_RESPONSE; + } + + if (status == MBOX_BUSY) { + return INTEL_SIP_SMC_STATUS_BUSY; + } + + *ret_size = resp_len * MBOX_WORD_BYTE; + flush_dcache_range(addr, *ret_size); + + if (status != MBOX_RET_OK) { + *mbox_error = -status; + return INTEL_SIP_SMC_STATUS_ERROR; + } + + return INTEL_SIP_SMC_STATUS_OK; +} + /* * This function is responsible for handling all SiP calls from the NS world */ @@ -724,6 +770,19 @@ uintptr_t sip_smc_handler(uint32_t smc_fid, SMC_RET3(handle, status, x4, x5); + case INTEL_SIP_SMC_FCS_RANDOM_NUMBER: + status = intel_fcs_random_number_gen(x1, &retval64, + &mbox_error); + SMC_RET4(handle, status, mbox_error, x1, retval64); + + case INTEL_SIP_SMC_FCS_SEND_CERTIFICATE: + status = intel_fcs_send_cert(x1, x2, &send_id); + SMC_RET1(handle, status); + + case INTEL_SIP_SMC_FCS_GET_PROVISION_DATA: + status = intel_fcs_get_provision_data(&send_id); + SMC_RET1(handle, status); + case INTEL_SIP_SMC_FCS_CNTR_SET_PREAUTH: status = intel_fcs_cntr_set_preauth(x1, x2, x3, &mbox_error); From 651841f20110ce6fac650e3ac47b0a9cce18e6f3 Mon Sep 17 00:00:00 2001 From: Sieu Mun Tang Date: Tue, 12 Apr 2022 15:00:13 +0800 Subject: [PATCH 05/28] fix(intel): introduce a generic response error code This patch will introduce a generic error code (0x3ff) to be used in case where Secure Device Manager (SDM) mailbox request is not failing (returns OK with no error code) but BL31 instead wants to return error/reject to the calling software. This value aligns with generic error code implemented in SDM for consistency. Signed-off-by: Abdul Halim, Muhammad Hadi Asyrafi Signed-off-by: Sieu Mun Tang Change-Id: I9894c7df8897fff9aa80970940a6f3f6bfa30bb7 --- plat/intel/soc/common/socfpga_sip_svc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plat/intel/soc/common/socfpga_sip_svc.c b/plat/intel/soc/common/socfpga_sip_svc.c index b0b56e932..da75efa01 100644 --- a/plat/intel/soc/common/socfpga_sip_svc.c +++ b/plat/intel/soc/common/socfpga_sip_svc.c @@ -493,7 +493,7 @@ static uint32_t intel_mbox_send_cmd(uint32_t cmd, uint32_t *args, unsigned int *len_in_resp) { *len_in_resp = 0; - *mbox_status = 0; + *mbox_status = GENERIC_RESPONSE_ERROR; if (!is_address_in_ddr_range((uint64_t)args, sizeof(uint32_t) * len)) return INTEL_SIP_SMC_STATUS_REJECTED; From 49d44ec5f357b1bcf8eae9e91fbd72aef09e00dd Mon Sep 17 00:00:00 2001 From: Boon Khai Ng Date: Wed, 26 May 2021 01:50:34 +0800 Subject: [PATCH 06/28] fix(intel): flush dcache before sending certificate to mailbox Due to the cache coherency issue the dcache need to flush before sending the certificate to the mailbox Signed-off-by: Boon Khai Ng Signed-off-by: Sieu Mun Tang Change-Id: I39d5144519d9c7308597698b4cbea1b8aba0a849 --- plat/intel/soc/common/sip/socfpga_sip_fcs.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/plat/intel/soc/common/sip/socfpga_sip_fcs.c b/plat/intel/soc/common/sip/socfpga_sip_fcs.c index 26da55efc..37dc77259 100644 --- a/plat/intel/soc/common/sip/socfpga_sip_fcs.c +++ b/plat/intel/soc/common/sip/socfpga_sip_fcs.c @@ -74,6 +74,8 @@ uint32_t intel_fcs_send_cert(uint64_t addr, uint64_t size, (uint32_t *)addr, size / MBOX_WORD_BYTE, CMD_DIRECT); + flush_dcache_range(addr, size); + if (status < 0) { return INTEL_SIP_SMC_STATUS_ERROR; } From 581182c1916df03860744d8e32941c72b2cc3fda Mon Sep 17 00:00:00 2001 From: Sieu Mun Tang Date: Mon, 9 May 2022 10:48:53 +0800 Subject: [PATCH 07/28] feat(intel): extend attestation service to Agilex family This patch extends the functionality of FPGA Crypto Services (FCS) to support FPGA Attestation feature in Agilex device. Signed-off-by: Boon Khai Ng Signed-off-by: Sieu Mun Tang Change-Id: I3c2e29d2fa04d394e9f65d8143d7f4e57389cd02 --- plat/intel/soc/common/include/socfpga_fcs.h | 13 ++++ .../soc/common/include/socfpga_mailbox.h | 2 + .../soc/common/include/socfpga_sip_svc.h | 2 + plat/intel/soc/common/sip/socfpga_sip_fcs.c | 70 +++++++++++++++++++ plat/intel/soc/common/socfpga_sip_svc.c | 59 +++++++++++----- 5 files changed, 129 insertions(+), 17 deletions(-) diff --git a/plat/intel/soc/common/include/socfpga_fcs.h b/plat/intel/soc/common/include/socfpga_fcs.h index 1df163971..d9b8be4bb 100644 --- a/plat/intel/soc/common/include/socfpga_fcs.h +++ b/plat/intel/soc/common/include/socfpga_fcs.h @@ -40,6 +40,14 @@ #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 + /* FCS Payload Structure */ typedef struct fcs_encrypt_payload_t { @@ -100,4 +108,9 @@ int intel_fcs_get_measurement(uint64_t src_addr, uint32_t src_size, uint32_t intel_fcs_get_rom_patch_sha384(uint64_t addr, uint64_t *ret_size, uint32_t *mbox_error); +int intel_fcs_create_cert_on_reload(uint32_t cert_request, + uint32_t *mbox_error); +int intel_fcs_get_attestation_cert(uint32_t cert_request, 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 fcf5fc206..21cb1591b 100644 --- a/plat/intel/soc/common/include/socfpga_mailbox.h +++ b/plat/intel/soc/common/include/socfpga_mailbox.h @@ -80,6 +80,8 @@ #define MBOX_PSG_SIGMA_TEARDOWN 0xD5 /* Attestation Commands */ +#define MBOX_CREATE_CERT_ON_RELOAD 0x180 +#define MBOX_GET_ATTESTATION_CERT 0x181 #define MBOX_ATTESTATION_SUBKEY 0x182 #define MBOX_GET_MEASUREMENT 0x183 diff --git a/plat/intel/soc/common/include/socfpga_sip_svc.h b/plat/intel/soc/common/include/socfpga_sip_svc.h index e46bee701..53b949d02 100644 --- a/plat/intel/soc/common/include/socfpga_sip_svc.h +++ b/plat/intel/soc/common/include/socfpga_sip_svc.h @@ -84,6 +84,8 @@ #define INTEL_SIP_SMC_FCS_CHIP_ID 0xC2000065 #define INTEL_SIP_SMC_FCS_ATTESTATION_SUBKEY 0xC2000066 #define INTEL_SIP_SMC_FCS_ATTESTATION_MEASUREMENTS 0xC2000067 +#define INTEL_SIP_SMC_FCS_GET_ATTESTATION_CERT 0xC2000068 +#define INTEL_SIP_SMC_FCS_CREATE_CERT_ON_RELOAD 0xC2000069 /* ECC DBE */ #define WARM_RESET_WFI_FLAG BIT(31) diff --git a/plat/intel/soc/common/sip/socfpga_sip_fcs.c b/plat/intel/soc/common/sip/socfpga_sip_fcs.c index 37dc77259..5ba81eebb 100644 --- a/plat/intel/soc/common/sip/socfpga_sip_fcs.c +++ b/plat/intel/soc/common/sip/socfpga_sip_fcs.c @@ -351,3 +351,73 @@ int intel_fcs_get_measurement(uint64_t src_addr, uint32_t src_size, return INTEL_SIP_SMC_STATUS_OK; } + +int intel_fcs_get_attestation_cert(uint32_t cert_request, uint64_t dst_addr, + uint32_t *dst_size, uint32_t *mbox_error) +{ + int status; + uint32_t ret_size = *dst_size / MBOX_WORD_BYTE; + + if (mbox_error == NULL) { + return INTEL_SIP_SMC_STATUS_REJECTED; + } + + if (cert_request < FCS_ALIAS_CERT || + cert_request > + (FCS_ALIAS_CERT | + FCS_DEV_ID_SELF_SIGN_CERT | + FCS_DEV_ID_ENROLL_CERT | + FCS_ENROLL_SELF_SIGN_CERT | + FCS_PLAT_KEY_CERT)) { + return INTEL_SIP_SMC_STATUS_REJECTED; + } + + if (!is_address_in_ddr_range(dst_addr, *dst_size)) { + return INTEL_SIP_SMC_STATUS_REJECTED; + } + + status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_GET_ATTESTATION_CERT, + (uint32_t *) &cert_request, 1U, CMD_CASUAL, + (uint32_t *) dst_addr, &ret_size); + + if (status < 0) { + *mbox_error = -status; + return INTEL_SIP_SMC_STATUS_ERROR; + } + + *dst_size = ret_size * MBOX_WORD_BYTE; + flush_dcache_range(dst_addr, *dst_size); + + return INTEL_SIP_SMC_STATUS_OK; +} + +int intel_fcs_create_cert_on_reload(uint32_t cert_request, + uint32_t *mbox_error) +{ + int status; + + if (mbox_error == NULL) { + return INTEL_SIP_SMC_STATUS_REJECTED; + } + + if (cert_request < FCS_ALIAS_CERT || + cert_request > + (FCS_ALIAS_CERT | + FCS_DEV_ID_SELF_SIGN_CERT | + FCS_DEV_ID_ENROLL_CERT | + FCS_ENROLL_SELF_SIGN_CERT | + FCS_PLAT_KEY_CERT)) { + return INTEL_SIP_SMC_STATUS_REJECTED; + } + + status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_CREATE_CERT_ON_RELOAD, + (uint32_t *) &cert_request, 1U, CMD_CASUAL, + NULL, NULL); + + if (status < 0) { + *mbox_error = -status; + 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 da75efa01..f0c2ebe49 100644 --- a/plat/intel/soc/common/socfpga_sip_svc.c +++ b/plat/intel/soc/common/socfpga_sip_svc.c @@ -63,8 +63,9 @@ static int intel_fpga_sdm_write_buffer(struct fpga_config_info *buffer) args[2] = buffer->size - buffer->size_written; current_buffer++; current_buffer %= FPGA_CONFIG_BUFFER_SIZE; - } else + } else { args[2] = bytes_per_block; + } buffer->size_written += args[2]; mailbox_send_cmd_async(&send_id, MBOX_RECONFIG_DATA, args, @@ -79,10 +80,12 @@ static int intel_fpga_sdm_write_buffer(struct fpga_config_info *buffer) static int intel_fpga_sdm_write_all(void) { - for (int i = 0; i < FPGA_CONFIG_BUFFER_SIZE; i++) + for (int i = 0; i < FPGA_CONFIG_BUFFER_SIZE; i++) { if (intel_fpga_sdm_write_buffer( - &fpga_config_buffers[current_buffer])) + &fpga_config_buffers[current_buffer])) { break; + } + } return 0; } @@ -174,10 +177,11 @@ static int intel_fpga_config_completed_write(uint32_t *completed_addr, intel_fpga_sdm_write_all(); - if (*count > 0) + if (*count > 0) { status = INTEL_SIP_SMC_STATUS_OK; - else if (*count == 0) + } else if (*count == 0) { status = INTEL_SIP_SMC_STATUS_BUSY; + } for (int i = 0; i < FPGA_CONFIG_BUFFER_SIZE; i++) { if (fpga_config_buffers[i].write_requested != 0) { @@ -186,8 +190,9 @@ static int intel_fpga_config_completed_write(uint32_t *completed_addr, } } - if (all_completed == 1) + if (all_completed == 1) { return INTEL_SIP_SMC_STATUS_OK; + } return status; } @@ -249,9 +254,11 @@ static int intel_fpga_config_start(uint32_t flag) static bool is_fpga_config_buffer_full(void) { - for (int i = 0; i < FPGA_CONFIG_BUFFER_SIZE; i++) - if (!fpga_config_buffers[i].write_requested) + for (int i = 0; i < FPGA_CONFIG_BUFFER_SIZE; i++) { + if (!fpga_config_buffers[i].write_requested) { return false; + } + } return true; } @@ -260,12 +267,15 @@ bool is_address_in_ddr_range(uint64_t addr, uint64_t size) if (!addr && !size) { return true; } - if (size > (UINT64_MAX - addr)) + if (size > (UINT64_MAX - addr)) { return false; - if (addr < BL31_LIMIT) + } + if (addr < BL31_LIMIT) { return false; - if (addr + size > DRAM_BASE + DRAM_SIZE) + } + if (addr + size > DRAM_BASE + DRAM_SIZE) { return false; + } return true; } @@ -349,8 +359,9 @@ static int is_out_of_sec_range(uint64_t reg_addr) /* Secure register access */ uint32_t intel_secure_reg_read(uint64_t reg_addr, uint32_t *retval) { - if (is_out_of_sec_range(reg_addr)) + if (is_out_of_sec_range(reg_addr)) { return INTEL_SIP_SMC_STATUS_ERROR; + } *retval = mmio_read_32(reg_addr); @@ -360,8 +371,9 @@ uint32_t intel_secure_reg_read(uint64_t reg_addr, uint32_t *retval) uint32_t intel_secure_reg_write(uint64_t reg_addr, uint32_t val, uint32_t *retval) { - if (is_out_of_sec_range(reg_addr)) + if (is_out_of_sec_range(reg_addr)) { return INTEL_SIP_SMC_STATUS_ERROR; + } mmio_write_32(reg_addr, val); @@ -385,8 +397,9 @@ uint64_t intel_rsu_update_address; static uint32_t intel_rsu_status(uint64_t *respbuf, unsigned int respbuf_sz) { - if (mailbox_rsu_status((uint32_t *)respbuf, respbuf_sz) < 0) + if (mailbox_rsu_status((uint32_t *)respbuf, respbuf_sz) < 0) { return INTEL_SIP_SMC_RSU_ERROR; + } return INTEL_SIP_SMC_STATUS_OK; } @@ -399,8 +412,9 @@ static uint32_t intel_rsu_update(uint64_t update_address) static uint32_t intel_rsu_notify(uint32_t execution_stage) { - if (mailbox_hps_stage_notify(execution_stage) < 0) + if (mailbox_hps_stage_notify(execution_stage) < 0) { return INTEL_SIP_SMC_RSU_ERROR; + } return INTEL_SIP_SMC_STATUS_OK; } @@ -408,8 +422,9 @@ static uint32_t intel_rsu_notify(uint32_t execution_stage) static uint32_t intel_rsu_retry_counter(uint32_t *respbuf, uint32_t respbuf_sz, uint32_t *ret_stat) { - if (mailbox_rsu_status((uint32_t *)respbuf, respbuf_sz) < 0) + if (mailbox_rsu_status((uint32_t *)respbuf, respbuf_sz) < 0) { return INTEL_SIP_SMC_RSU_ERROR; + } *ret_stat = respbuf[8]; return INTEL_SIP_SMC_STATUS_OK; @@ -495,8 +510,9 @@ static uint32_t intel_mbox_send_cmd(uint32_t cmd, uint32_t *args, *len_in_resp = 0; *mbox_status = GENERIC_RESPONSE_ERROR; - if (!is_address_in_ddr_range((uint64_t)args, sizeof(uint32_t) * len)) + if (!is_address_in_ddr_range((uint64_t)args, sizeof(uint32_t) * len)) { return INTEL_SIP_SMC_STATUS_REJECTED; + } int status = mailbox_send_cmd(MBOX_JOB_ID, cmd, args, len, urgent, response, &resp_len); @@ -810,6 +826,15 @@ 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_ATTESTATION_CERT: + status = intel_fcs_get_attestation_cert(x1, x2, + (uint32_t *) &x3, &mbox_error); + SMC_RET4(handle, status, mbox_error, x2, x3); + + case INTEL_SIP_SMC_FCS_CREATE_CERT_ON_RELOAD: + status = intel_fcs_create_cert_on_reload(x1, &mbox_error); + SMC_RET2(handle, status, mbox_error); + case INTEL_SIP_SMC_GET_ROM_PATCH_SHA384: status = intel_fcs_get_rom_patch_sha384(x1, &retval64, &mbox_error); From 6dc00c24ab0100a2aae0f416c72470f8ed17e149 Mon Sep 17 00:00:00 2001 From: Sieu Mun Tang Date: Mon, 9 May 2022 12:08:42 +0800 Subject: [PATCH 08/28] feat(intel): support crypto service session Support crypto service open and close session mailbox commands through SMC. Crypto service support begin by sending an open crypto service session request to SDM firmware. Last, close the session after finishes crypto service. All crypto service parameters with this session will be erased by SDM firmware. Signed-off-by: Siew Chin Lim Signed-off-by: Boon Khai Ng Signed-off-by: Sieu Mun Tang Change-Id: I48968498bbd6f2e71791f4ed38dd5f369e171082 --- plat/intel/soc/common/include/socfpga_fcs.h | 5 + .../soc/common/include/socfpga_mailbox.h | 178 +++++++++--------- .../soc/common/include/socfpga_sip_svc.h | 2 + plat/intel/soc/common/sip/socfpga_sip_fcs.c | 41 ++++ plat/intel/soc/common/socfpga_sip_svc.c | 8 + 5 files changed, 146 insertions(+), 88 deletions(-) diff --git a/plat/intel/soc/common/include/socfpga_fcs.h b/plat/intel/soc/common/include/socfpga_fcs.h index d9b8be4bb..99421e6bf 100644 --- a/plat/intel/soc/common/include/socfpga_fcs.h +++ b/plat/intel/soc/common/include/socfpga_fcs.h @@ -113,4 +113,9 @@ int intel_fcs_create_cert_on_reload(uint32_t cert_request, int intel_fcs_get_attestation_cert(uint32_t cert_request, uint64_t dst_addr, uint32_t *dst_size, uint32_t *mbox_error); +int intel_fcs_open_crypto_service_session(uint32_t *session_id, + uint32_t *mbox_error); +int intel_fcs_close_crypto_service_session(uint32_t session_id, + 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 21cb1591b..b6903d87d 100644 --- a/plat/intel/soc/common/include/socfpga_mailbox.h +++ b/plat/intel/soc/common/include/socfpga_mailbox.h @@ -10,108 +10,110 @@ #include -#define MBOX_OFFSET 0xffa30000 +#define MBOX_OFFSET 0xffa30000 -#define MBOX_ATF_CLIENT_ID 0x1U -#define MBOX_MAX_JOB_ID 0xFU -#define MBOX_MAX_IND_JOB_ID (MBOX_MAX_JOB_ID - 1U) -#define MBOX_JOB_ID MBOX_MAX_JOB_ID -#define MBOX_TEST_BIT BIT(31) +#define MBOX_ATF_CLIENT_ID 0x1U +#define MBOX_MAX_JOB_ID 0xFU +#define MBOX_MAX_IND_JOB_ID (MBOX_MAX_JOB_ID - 1U) +#define MBOX_JOB_ID MBOX_MAX_JOB_ID +#define MBOX_TEST_BIT BIT(31) /* Mailbox Shared Memory Register Map */ -#define MBOX_CIN 0x00 -#define MBOX_ROUT 0x04 -#define MBOX_URG 0x08 -#define MBOX_INT 0x0C -#define MBOX_COUT 0x20 -#define MBOX_RIN 0x24 -#define MBOX_STATUS 0x2C -#define MBOX_CMD_BUFFER 0x40 -#define MBOX_RESP_BUFFER 0xC0 +#define MBOX_CIN 0x00 +#define MBOX_ROUT 0x04 +#define MBOX_URG 0x08 +#define MBOX_INT 0x0C +#define MBOX_COUT 0x20 +#define MBOX_RIN 0x24 +#define MBOX_STATUS 0x2C +#define MBOX_CMD_BUFFER 0x40 +#define MBOX_RESP_BUFFER 0xC0 /* Mailbox SDM doorbell */ -#define MBOX_DOORBELL_TO_SDM 0x400 -#define MBOX_DOORBELL_FROM_SDM 0x480 +#define MBOX_DOORBELL_TO_SDM 0x400 +#define MBOX_DOORBELL_FROM_SDM 0x480 /* Mailbox commands */ -#define MBOX_CMD_NOOP 0x00 -#define MBOX_CMD_SYNC 0x01 -#define MBOX_CMD_RESTART 0x02 -#define MBOX_CMD_CANCEL 0x03 -#define MBOX_CMD_VAB_SRC_CERT 0x0B -#define MBOX_CMD_GET_IDCODE 0x10 -#define MBOX_CMD_GET_USERCODE 0x13 -#define MBOX_CMD_GET_CHIPID 0x12 -#define MBOX_CMD_REBOOT_HPS 0x47 +#define MBOX_CMD_NOOP 0x00 +#define MBOX_CMD_SYNC 0x01 +#define MBOX_CMD_RESTART 0x02 +#define MBOX_CMD_CANCEL 0x03 +#define MBOX_CMD_VAB_SRC_CERT 0x0B +#define MBOX_CMD_GET_IDCODE 0x10 +#define MBOX_CMD_GET_USERCODE 0x13 +#define MBOX_CMD_GET_CHIPID 0x12 +#define MBOX_CMD_REBOOT_HPS 0x47 /* Reconfiguration Commands */ -#define MBOX_CONFIG_STATUS 0x04 -#define MBOX_RECONFIG 0x06 -#define MBOX_RECONFIG_DATA 0x08 -#define MBOX_RECONFIG_STATUS 0x09 +#define MBOX_CONFIG_STATUS 0x04 +#define MBOX_RECONFIG 0x06 +#define MBOX_RECONFIG_DATA 0x08 +#define MBOX_RECONFIG_STATUS 0x09 /* HWMON Commands */ -#define MBOX_HWMON_READVOLT 0x18 -#define MBOX_HWMON_READTEMP 0x19 +#define MBOX_HWMON_READVOLT 0x18 +#define MBOX_HWMON_READTEMP 0x19 /* QSPI Commands */ -#define MBOX_CMD_QSPI_OPEN 0x32 -#define MBOX_CMD_QSPI_CLOSE 0x33 -#define MBOX_CMD_QSPI_SET_CS 0x34 -#define MBOX_CMD_QSPI_DIRECT 0x3B +#define MBOX_CMD_QSPI_OPEN 0x32 +#define MBOX_CMD_QSPI_CLOSE 0x33 +#define MBOX_CMD_QSPI_SET_CS 0x34 +#define MBOX_CMD_QSPI_DIRECT 0x3B /* RSU Commands */ -#define MBOX_GET_SUBPARTITION_TABLE 0x5A -#define MBOX_RSU_STATUS 0x5B -#define MBOX_RSU_UPDATE 0x5C -#define MBOX_HPS_STAGE_NOTIFY 0x5D +#define MBOX_GET_SUBPARTITION_TABLE 0x5A +#define MBOX_RSU_STATUS 0x5B +#define MBOX_RSU_UPDATE 0x5C +#define MBOX_HPS_STAGE_NOTIFY 0x5D /* FCS Command */ -#define MBOX_FCS_GET_PROVISION 0x7B -#define MBOX_FCS_CNTR_SET_PREAUTH 0x7C -#define MBOX_FCS_ENCRYPT_REQ 0x7E -#define MBOX_FCS_DECRYPT_REQ 0x7F -#define MBOX_FCS_RANDOM_GEN 0x80 +#define MBOX_FCS_GET_PROVISION 0x7B +#define MBOX_FCS_CNTR_SET_PREAUTH 0x7C +#define MBOX_FCS_ENCRYPT_REQ 0x7E +#define MBOX_FCS_DECRYPT_REQ 0x7F +#define MBOX_FCS_RANDOM_GEN 0x80 +#define MBOX_FCS_OPEN_CS_SESSION 0xA0 +#define MBOX_FCS_CLOSE_CS_SESSION 0xA1 /* PSG SIGMA Commands */ -#define MBOX_PSG_SIGMA_TEARDOWN 0xD5 +#define MBOX_PSG_SIGMA_TEARDOWN 0xD5 /* Attestation Commands */ -#define MBOX_CREATE_CERT_ON_RELOAD 0x180 -#define MBOX_GET_ATTESTATION_CERT 0x181 -#define MBOX_ATTESTATION_SUBKEY 0x182 -#define MBOX_GET_MEASUREMENT 0x183 +#define MBOX_CREATE_CERT_ON_RELOAD 0x180 +#define MBOX_GET_ATTESTATION_CERT 0x181 +#define MBOX_ATTESTATION_SUBKEY 0x182 +#define MBOX_GET_MEASUREMENT 0x183 /* Miscellaneous commands */ #define MBOX_GET_ROM_PATCH_SHA384 0x1B0 /* Mailbox Definitions */ -#define CMD_DIRECT 0 -#define CMD_INDIRECT 1 -#define CMD_CASUAL 0 -#define CMD_URGENT 1 +#define CMD_DIRECT 0 +#define CMD_INDIRECT 1 +#define CMD_CASUAL 0 +#define CMD_URGENT 1 -#define MBOX_WORD_BYTE 4U -#define MBOX_RESP_BUFFER_SIZE 16 -#define MBOX_CMD_BUFFER_SIZE 32 +#define MBOX_WORD_BYTE 4U +#define MBOX_RESP_BUFFER_SIZE 16 +#define MBOX_CMD_BUFFER_SIZE 32 /* Execution states for HPS_STAGE_NOTIFY */ -#define HPS_EXECUTION_STATE_FSBL 0 -#define HPS_EXECUTION_STATE_SSBL 1 -#define HPS_EXECUTION_STATE_OS 2 +#define HPS_EXECUTION_STATE_FSBL 0 +#define HPS_EXECUTION_STATE_SSBL 1 +#define HPS_EXECUTION_STATE_OS 2 /* Status Response */ -#define MBOX_RET_OK 0 -#define MBOX_RET_ERROR -1 -#define MBOX_NO_RESPONSE -2 -#define MBOX_WRONG_ID -3 -#define MBOX_BUFFER_FULL -4 -#define MBOX_BUSY -5 -#define MBOX_TIMEOUT -2047 +#define MBOX_RET_OK 0 +#define MBOX_RET_ERROR -1 +#define MBOX_NO_RESPONSE -2 +#define MBOX_WRONG_ID -3 +#define MBOX_BUFFER_FULL -4 +#define MBOX_BUSY -5 +#define MBOX_TIMEOUT -2047 /* Reconfig Status Response */ #define RECONFIG_STATUS_STATE 0 @@ -136,37 +138,37 @@ /* Mailbox Macros */ -#define MBOX_ENTRY_TO_ADDR(_buf, ptr) (MBOX_OFFSET + (MBOX_##_buf##_BUFFER) \ - + MBOX_WORD_BYTE * (ptr)) +#define MBOX_ENTRY_TO_ADDR(_buf, ptr) (MBOX_OFFSET + (MBOX_##_buf##_BUFFER) \ + + MBOX_WORD_BYTE * (ptr)) /* Mailbox interrupt flags and masks */ -#define MBOX_INT_FLAG_COE 0x1 -#define MBOX_INT_FLAG_RIE 0x2 -#define MBOX_INT_FLAG_UAE 0x100 -#define MBOX_COE_BIT(INTERRUPT) ((INTERRUPT) & 0x3) -#define MBOX_UAE_BIT(INTERRUPT) (((INTERRUPT) & (1<<8))) +#define MBOX_INT_FLAG_COE 0x1 +#define MBOX_INT_FLAG_RIE 0x2 +#define MBOX_INT_FLAG_UAE 0x100 +#define MBOX_COE_BIT(INTERRUPT) ((INTERRUPT) & 0x3) +#define MBOX_UAE_BIT(INTERRUPT) (((INTERRUPT) & (1<<8))) /* Mailbox response and status */ -#define MBOX_RESP_ERR(BUFFER) ((BUFFER) & 0x00000fff) -#define MBOX_RESP_LEN(BUFFER) (((BUFFER) & 0x007ff000) >> 12) -#define MBOX_RESP_CLIENT_ID(BUFFER) (((BUFFER) & 0xf0000000) >> 28) -#define MBOX_RESP_JOB_ID(BUFFER) (((BUFFER) & 0x0f000000) >> 24) -#define MBOX_STATUS_UA_MASK (1<<8) +#define MBOX_RESP_ERR(BUFFER) ((BUFFER) & 0x000007ff) +#define MBOX_RESP_LEN(BUFFER) (((BUFFER) & 0x007ff000) >> 12) +#define MBOX_RESP_CLIENT_ID(BUFFER) (((BUFFER) & 0xf0000000) >> 28) +#define MBOX_RESP_JOB_ID(BUFFER) (((BUFFER) & 0x0f000000) >> 24) +#define MBOX_STATUS_UA_MASK (1<<8) /* Mailbox command and response */ -#define MBOX_CLIENT_ID_CMD(CLIENT_ID) ((CLIENT_ID) << 28) -#define MBOX_JOB_ID_CMD(JOB_ID) (JOB_ID<<24) -#define MBOX_CMD_LEN_CMD(CMD_LEN) ((CMD_LEN) << 12) -#define MBOX_INDIRECT(val) ((val) << 11) -#define MBOX_CMD_MASK(header) ((header) & 0x7ff) +#define MBOX_CLIENT_ID_CMD(CLIENT_ID) ((CLIENT_ID) << 28) +#define MBOX_JOB_ID_CMD(JOB_ID) (JOB_ID<<24) +#define MBOX_CMD_LEN_CMD(CMD_LEN) ((CMD_LEN) << 12) +#define MBOX_INDIRECT(val) ((val) << 11) +#define MBOX_CMD_MASK(header) ((header) & 0x7ff) /* Mailbox payload */ -#define MBOX_DATA_MAX_LEN 0x3ff -#define MBOX_PAYLOAD_FLAG_BUSY BIT(0) +#define MBOX_DATA_MAX_LEN 0x3ff +#define MBOX_PAYLOAD_FLAG_BUSY BIT(0) /* RSU Macros */ -#define RSU_VERSION_ACMF BIT(8) -#define RSU_VERSION_ACMF_MASK 0xff00 +#define RSU_VERSION_ACMF BIT(8) +#define RSU_VERSION_ACMF_MASK 0xff00 /* Config Status Macros */ #define CONFIG_STATUS_WORD_SIZE 16U diff --git a/plat/intel/soc/common/include/socfpga_sip_svc.h b/plat/intel/soc/common/include/socfpga_sip_svc.h index 53b949d02..90ea3be1e 100644 --- a/plat/intel/soc/common/include/socfpga_sip_svc.h +++ b/plat/intel/soc/common/include/socfpga_sip_svc.h @@ -86,6 +86,8 @@ #define INTEL_SIP_SMC_FCS_ATTESTATION_MEASUREMENTS 0xC2000067 #define INTEL_SIP_SMC_FCS_GET_ATTESTATION_CERT 0xC2000068 #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 /* ECC DBE */ #define WARM_RESET_WFI_FLAG BIT(31) diff --git a/plat/intel/soc/common/sip/socfpga_sip_fcs.c b/plat/intel/soc/common/sip/socfpga_sip_fcs.c index 5ba81eebb..f50795e9c 100644 --- a/plat/intel/soc/common/sip/socfpga_sip_fcs.c +++ b/plat/intel/soc/common/sip/socfpga_sip_fcs.c @@ -421,3 +421,44 @@ int intel_fcs_create_cert_on_reload(uint32_t cert_request, return INTEL_SIP_SMC_STATUS_OK; } + +int intel_fcs_open_crypto_service_session(uint32_t *session_id, + uint32_t *mbox_error) +{ + int status; + uint32_t resp_len = 1U; + + if ((session_id == NULL) || (mbox_error == NULL)) { + return INTEL_SIP_SMC_STATUS_REJECTED; + } + + status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_OPEN_CS_SESSION, + NULL, 0U, CMD_CASUAL, session_id, &resp_len); + + if (status < 0) { + *mbox_error = -status; + return INTEL_SIP_SMC_STATUS_ERROR; + } + + return INTEL_SIP_SMC_STATUS_OK; +} + +int intel_fcs_close_crypto_service_session(uint32_t session_id, + uint32_t *mbox_error) +{ + int status; + + if (mbox_error == NULL) { + return INTEL_SIP_SMC_STATUS_REJECTED; + } + + status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_CLOSE_CS_SESSION, + &session_id, 1U, CMD_CASUAL, NULL, NULL); + + if (status < 0) { + *mbox_error = -status; + 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 f0c2ebe49..c85fda478 100644 --- a/plat/intel/soc/common/socfpga_sip_svc.c +++ b/plat/intel/soc/common/socfpga_sip_svc.c @@ -835,6 +835,14 @@ uintptr_t sip_smc_handler(uint32_t smc_fid, status = intel_fcs_create_cert_on_reload(x1, &mbox_error); SMC_RET2(handle, status, mbox_error); + case INTEL_SIP_SMC_FCS_OPEN_CS_SESSION: + status = intel_fcs_open_crypto_service_session(&retval, &mbox_error); + SMC_RET3(handle, status, mbox_error, retval); + + case INTEL_SIP_SMC_FCS_CLOSE_CS_SESSION: + status = intel_fcs_close_crypto_service_session(x1, &mbox_error); + SMC_RET2(handle, status, mbox_error); + case INTEL_SIP_SMC_GET_ROM_PATCH_SHA384: status = intel_fcs_get_rom_patch_sha384(x1, &retval64, &mbox_error); From 342a0618c7ff89327ac5b34dc0713509ffae609b Mon Sep 17 00:00:00 2001 From: Sieu Mun Tang Date: Mon, 9 May 2022 14:16:14 +0800 Subject: [PATCH 09/28] 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 Signed-off-by: Boon Khai Ng Signed-off-by: Sieu Mun Tang Change-Id: I02406533f38b9607eb1ec7e1395b9dc2d084a9e3 --- plat/intel/soc/common/include/socfpga_fcs.h | 25 +++ .../soc/common/include/socfpga_mailbox.h | 4 + .../soc/common/include/socfpga_sip_svc.h | 4 + plat/intel/soc/common/sip/socfpga_sip_fcs.c | 172 ++++++++++++++++++ plat/intel/soc/common/socfpga_sip_svc.c | 19 ++ 5 files changed, 224 insertions(+) diff --git a/plat/intel/soc/common/include/socfpga_fcs.h b/plat/intel/soc/common/include/socfpga_fcs.h index 99421e6bf..294d1e5e8 100644 --- a/plat/intel/soc/common/include/socfpga_fcs.h +++ b/plat/intel/soc/common/include/socfpga_fcs.h @@ -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 */ diff --git a/plat/intel/soc/common/include/socfpga_mailbox.h b/plat/intel/soc/common/include/socfpga_mailbox.h index b6903d87d..f969a353e 100644 --- a/plat/intel/soc/common/include/socfpga_mailbox.h +++ b/plat/intel/soc/common/include/socfpga_mailbox.h @@ -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 diff --git a/plat/intel/soc/common/include/socfpga_sip_svc.h b/plat/intel/soc/common/include/socfpga_sip_svc.h index 90ea3be1e..fb0c6618d 100644 --- a/plat/intel/soc/common/include/socfpga_sip_svc.h +++ b/plat/intel/soc/common/include/socfpga_sip_svc.h @@ -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) diff --git a/plat/intel/soc/common/sip/socfpga_sip_fcs.c b/plat/intel/soc/common/sip/socfpga_sip_fcs.c index f50795e9c..821beff50 100644 --- a/plat/intel/soc/common/sip/socfpga_sip_fcs.c +++ b/plat/intel/soc/common/sip/socfpga_sip_fcs.c @@ -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; +} diff --git a/plat/intel/soc/common/socfpga_sip_svc.c b/plat/intel/soc/common/socfpga_sip_svc.c index c85fda478..cdb71bf6f 100644 --- a/plat/intel/soc/common/socfpga_sip_svc.c +++ b/plat/intel/soc/common/socfpga_sip_svc.c @@ -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); From 24f9dc8a43fea350416ca9312a78ab4e786da8ad Mon Sep 17 00:00:00 2001 From: Sieu Mun Tang Date: Tue, 10 May 2022 17:18:19 +0800 Subject: [PATCH 10/28] feat(intel): support extended random number generation The random number generation (RNG) mailbox command format is updated to extends the support to upto 4080 bytes random number generation. The new RNG format requires an opened crypto service session. A separated SMC function ID is introduced for the new RNG format and it is only supported by Agilex. Signed-off-by: Siew Chin Lim Signed-off-by: Boon Khai Ng Signed-off-by: Sieu Mun Tang Change-Id: I3f044a3c01ff7cb50be4705e2c1f982bf6f61432 --- plat/intel/soc/common/include/socfpga_fcs.h | 17 ++++++++ .../soc/common/include/socfpga_sip_svc.h | 5 ++- plat/intel/soc/common/sip/socfpga_sip_fcs.c | 39 +++++++++++++++++++ plat/intel/soc/common/socfpga_sip_svc.c | 5 +++ 4 files changed, 64 insertions(+), 2 deletions(-) diff --git a/plat/intel/soc/common/include/socfpga_fcs.h b/plat/intel/soc/common/include/socfpga_fcs.h index 294d1e5e8..da982e14e 100644 --- a/plat/intel/soc/common/include/socfpga_fcs.h +++ b/plat/intel/soc/common/include/socfpga_fcs.h @@ -14,9 +14,12 @@ #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_EXT_OFFSET 3 + #define FCS_MODE_DECRYPT 0x0 #define FCS_MODE_ENCRYPT 0x1 #define FCS_ENCRYPTION_DATA_0 0x10100 @@ -55,7 +58,19 @@ #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) + /* FCS Payload Structure */ +typedef struct fcs_rng_payload_t { + uint32_t session_id; + uint32_t context_id; + uint32_t crypto_header; + uint32_t size; +} fcs_rng_payload; typedef struct fcs_encrypt_payload_t { uint32_t first_word; @@ -96,6 +111,8 @@ typedef struct fcs_cs_key_payload_t { uint32_t intel_fcs_random_number_gen(uint64_t addr, uint64_t *ret_size, uint32_t *mbox_error); +int intel_fcs_random_number_gen_ext(uint32_t session_id, uint32_t context_id, + uint32_t size, uint32_t *send_id); uint32_t intel_fcs_send_cert(uint64_t addr, uint64_t size, uint32_t *send_id); uint32_t intel_fcs_get_provision_data(uint32_t *send_id); diff --git a/plat/intel/soc/common/include/socfpga_sip_svc.h b/plat/intel/soc/common/include/socfpga_sip_svc.h index fb0c6618d..e790669d5 100644 --- a/plat/intel/soc/common/include/socfpga_sip_svc.h +++ b/plat/intel/soc/common/include/socfpga_sip_svc.h @@ -76,6 +76,7 @@ /* FPGA Crypto Services */ #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_SEND_CERTIFICATE 0x4200005D #define INTEL_SIP_SMC_FCS_GET_PROVISION_DATA 0x4200005E @@ -96,8 +97,8 @@ /* ECC DBE */ #define WARM_RESET_WFI_FLAG BIT(31) #define SYSMGR_ECC_DBE_COLD_RST_MASK (SYSMGR_ECC_OCRAM_MASK |\ - SYSMGR_ECC_DDR0_MASK |\ - SYSMGR_ECC_DDR1_MASK) + SYSMGR_ECC_DDR0_MASK |\ + SYSMGR_ECC_DDR1_MASK) /* Non-mailbox SMC Call */ #define INTEL_SIP_SMC_SVC_VERSION 0xC2000200 diff --git a/plat/intel/soc/common/sip/socfpga_sip_fcs.c b/plat/intel/soc/common/sip/socfpga_sip_fcs.c index 821beff50..7b3069ba8 100644 --- a/plat/intel/soc/common/sip/socfpga_sip_fcs.c +++ b/plat/intel/soc/common/sip/socfpga_sip_fcs.c @@ -57,6 +57,45 @@ uint32_t intel_fcs_random_number_gen(uint64_t addr, uint64_t *ret_size, return INTEL_SIP_SMC_STATUS_OK; } +int intel_fcs_random_number_gen_ext(uint32_t session_id, uint32_t context_id, + uint32_t size, uint32_t *send_id) +{ + int status; + uint32_t payload_size; + uint32_t crypto_header; + + if (size > (FCS_RANDOM_EXT_MAX_WORD_SIZE * + MBOX_WORD_BYTE) || size == 0U) { + return INTEL_SIP_SMC_STATUS_REJECTED; + } + + if (!is_size_4_bytes_aligned(size)) { + return INTEL_SIP_SMC_STATUS_REJECTED; + } + + crypto_header = (FCS_CS_FIELD_FLAG_INIT | FCS_CS_FIELD_FLAG_FINALIZE) << + FCS_CS_FIELD_FLAG_OFFSET; + + fcs_rng_payload payload = { + session_id, + context_id, + crypto_header, + size + }; + + payload_size = sizeof(payload) / MBOX_WORD_BYTE; + + status = mailbox_send_cmd_async(send_id, MBOX_FCS_RANDOM_GEN, + (uint32_t *) &payload, payload_size, + CMD_INDIRECT); + + if (status < 0) { + return INTEL_SIP_SMC_STATUS_ERROR; + } + + return INTEL_SIP_SMC_STATUS_OK; +} + uint32_t intel_fcs_send_cert(uint64_t addr, uint64_t size, uint32_t *send_id) { diff --git a/plat/intel/soc/common/socfpga_sip_svc.c b/plat/intel/soc/common/socfpga_sip_svc.c index cdb71bf6f..24683ea6d 100644 --- a/plat/intel/soc/common/socfpga_sip_svc.c +++ b/plat/intel/soc/common/socfpga_sip_svc.c @@ -791,6 +791,11 @@ uintptr_t sip_smc_handler(uint32_t smc_fid, &mbox_error); SMC_RET4(handle, status, mbox_error, x1, retval64); + case INTEL_SIP_SMC_FCS_RANDOM_NUMBER_EXT: + status = intel_fcs_random_number_gen_ext(x1, x2, x3, + &send_id); + SMC_RET1(handle, status); + case INTEL_SIP_SMC_FCS_SEND_CERTIFICATE: status = intel_fcs_send_cert(x1, x2, &send_id); SMC_RET1(handle, status); From 7e8249a2dbacfa751990c47644f0403311c6e260 Mon Sep 17 00:00:00 2001 From: Sieu Mun Tang Date: Tue, 10 May 2022 17:24:05 +0800 Subject: [PATCH 11/28] feat(intel): support SHA-2 hash digest generation on a blob This command is to request the SHA-2 hash digest on a blob. If input has a key, the output shall be key-hash digest. Signed-off-by: Siew Chin Lim Signed-off-by: Boon Khai Ng Signed-off-by: Sieu Mun Tang Change-Id: I08cb82d89a8e8f7bfe04f5f01e079ea49fe38cf5 --- plat/intel/soc/common/include/socfpga_fcs.h | 95 ++++++++------ .../soc/common/include/socfpga_mailbox.h | 1 + .../soc/common/include/socfpga_sip_svc.h | 5 + plat/intel/soc/common/sip/socfpga_sip_fcs.c | 124 ++++++++++++++++++ plat/intel/soc/common/socfpga_sip_svc.c | 13 ++ 5 files changed, 200 insertions(+), 38 deletions(-) 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); From c05ea2969070be90a7dbb2d0344c66d89401edf6 Mon Sep 17 00:00:00 2001 From: Sieu Mun Tang Date: Tue, 10 May 2022 17:27:12 +0800 Subject: [PATCH 12/28] feat(intel): support HMAC SHA-2 MAC verify request This command sends request on checking the integrity and authenticity of a blob by comparing the calculated MAC with tagged MAC. The comparison result will be returned in response. Signed-off-by: Siew Chin Lim Signed-off-by: Boon Khai Ng Signed-off-by: Sieu Mun Tang Change-Id: Ifefdf67f088d7612d2ec2459d71faf2ec8181222 --- plat/intel/soc/common/include/socfpga_fcs.h | 10 ++ .../soc/common/include/socfpga_mailbox.h | 1 + .../soc/common/include/socfpga_sip_svc.h | 2 + plat/intel/soc/common/sip/socfpga_sip_fcs.c | 96 +++++++++++++++++++ plat/intel/soc/common/socfpga_sip_svc.c | 16 +++- 5 files changed, 124 insertions(+), 1 deletion(-) diff --git a/plat/intel/soc/common/include/socfpga_fcs.h b/plat/intel/soc/common/include/socfpga_fcs.h index db8f558eb..5c1a76eed 100644 --- a/plat/intel/soc/common/include/socfpga_fcs.h +++ b/plat/intel/soc/common/include/socfpga_fcs.h @@ -66,6 +66,8 @@ #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 +#define FCS_MAC_VERIFY_RESP_MAX_WORD_SIZE 4U #define FCS_SHA_HMAC_CRYPTO_PARAM_SIZE_OFFSET 8U /* FCS Payload Structure */ typedef struct fcs_rng_payload_t { @@ -179,4 +181,12 @@ int intel_fcs_get_digest_finalize(uint32_t session_id, uint32_t context_id, uint64_t dst_addr, uint32_t *dst_size, uint32_t *mbox_error); +int intel_fcs_mac_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_mac_verify_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); + #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 498402014..a04264de8 100644 --- a/plat/intel/soc/common/include/socfpga_mailbox.h +++ b/plat/intel/soc/common/include/socfpga_mailbox.h @@ -76,6 +76,7 @@ #define MBOX_FCS_DECRYPT_REQ 0x7F #define MBOX_FCS_RANDOM_GEN 0x80 #define MBOX_FCS_GET_DIGEST_REQ 0x82 +#define MBOX_FCS_MAC_VERIFY_REQ 0x83 #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 f05e861b6..379a12360 100644 --- a/plat/intel/soc/common/include/socfpga_sip_svc.h +++ b/plat/intel/soc/common/include/socfpga_sip_svc.h @@ -95,6 +95,8 @@ #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_MAC_VERIFY_INIT 0xC200007A +#define INTEL_SIP_SMC_FCS_MAC_VERIFY_FINALIZE 0xC200007C #define INTEL_SIP_SMC_FCS_SHA_MODE_MASK 0xF #define INTEL_SIP_SMC_FCS_DIGEST_SIZE_MASK 0xF diff --git a/plat/intel/soc/common/sip/socfpga_sip_fcs.c b/plat/intel/soc/common/sip/socfpga_sip_fcs.c index 809037e9d..7da01fde9 100644 --- a/plat/intel/soc/common/sip/socfpga_sip_fcs.c +++ b/plat/intel/soc/common/sip/socfpga_sip_fcs.c @@ -13,6 +13,7 @@ /* FCS static variables */ static fcs_crypto_service_data fcs_sha_get_digest_param; +static fcs_crypto_service_data fcs_sha_mac_verify_param; bool is_size_4_bytes_aligned(uint32_t size) { @@ -797,3 +798,98 @@ int intel_fcs_get_digest_finalize(uint32_t session_id, uint32_t context_id, return INTEL_SIP_SMC_STATUS_OK; } + +int intel_fcs_mac_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) +{ + return intel_fcs_crypto_service_init(session_id, context_id, + key_id, param_size, param_data, + (void *) &fcs_sha_mac_verify_param, + mbox_error); +} + +int intel_fcs_mac_verify_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) +{ + int status; + uint32_t i; + uint32_t resp_len = *dst_size / MBOX_WORD_BYTE; + uint32_t payload[FCS_MAC_VERIFY_CMD_MAX_WORD_SIZE] = {0U}; + uintptr_t mac_offset; + + if (dst_size == NULL || mbox_error == NULL) { + return INTEL_SIP_SMC_STATUS_REJECTED; + } + + if (fcs_sha_mac_verify_param.session_id != session_id || + fcs_sha_mac_verify_param.context_id != context_id) { + return INTEL_SIP_SMC_STATUS_REJECTED; + } + + if (data_size >= src_size) { + return INTEL_SIP_SMC_STATUS_REJECTED; + } + + if (!is_size_4_bytes_aligned(src_size) || + !is_8_bytes_aligned(data_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_mac_verify_param.session_id; + i++; + payload[i] = fcs_sha_mac_verify_param.context_id; + i++; + payload[i] = fcs_sha_mac_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_sha_mac_verify_param.key_id; + i++; + /* Crypto parameters */ + payload[i] = ((fcs_sha_mac_verify_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] = data_size; + i++; + /* Copy mac data to command */ + mac_offset = src_addr + data_size; + memcpy((uint8_t *) &payload[i], (uint8_t *) mac_offset, + src_size - data_size); + + i += (src_size - data_size) / MBOX_WORD_BYTE; + + status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_MAC_VERIFY_REQ, + payload, i, CMD_CASUAL, + (uint32_t *) dst_addr, &resp_len); + + memset((void *)&fcs_sha_mac_verify_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 f9a376e97..3f92cf651 100644 --- a/plat/intel/soc/common/socfpga_sip_svc.c +++ b/plat/intel/soc/common/socfpga_sip_svc.c @@ -634,7 +634,7 @@ uintptr_t sip_smc_handler(uint32_t smc_fid, int status = INTEL_SIP_SMC_STATUS_OK; int mbox_status; unsigned int len_in_resp; - u_register_t x5, x6; + u_register_t x5, x6, x7; switch (smc_fid) { case SIP_SVC_UID: @@ -880,6 +880,20 @@ uintptr_t sip_smc_handler(uint32_t smc_fid, x4, x5, (uint32_t *) &x6, &mbox_error); SMC_RET4(handle, status, mbox_error, x5, x6); + case INTEL_SIP_SMC_FCS_MAC_VERIFY_INIT: + x5 = SMC_GET_GP(handle, CTX_GPREG_X5); + status = intel_fcs_mac_verify_init(x1, x2, x3, + x4, x5, &mbox_error); + SMC_RET2(handle, status, mbox_error); + + case INTEL_SIP_SMC_FCS_MAC_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_mac_verify_finalize(x1, x2, x3, + x4, x5, (uint32_t *) &x6, x7, &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); From 6726390eb02e9659cfaf2d3598be9bf12fbc5901 Mon Sep 17 00:00:00 2001 From: Sieu Mun Tang Date: Tue, 10 May 2022 17:30:00 +0800 Subject: [PATCH 13/28] 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); From 537ff052579862a4865d36d06940feaa796d16da Mon Sep 17 00:00:00 2001 From: Sieu Mun Tang Date: Mon, 9 May 2022 16:05:58 +0800 Subject: [PATCH 14/28] feat(intel): support session based SDOS encrypt and decrypt Extends existing Secure Data Object Service (SDOS) encryption and decryption mailbox command to include session id and context id. The new format requires an opened crypto service session. A separated SMC function ID is introduced for the new format and it is only supported by Agilex. Signed-off-by: Siew Chin Lim Signed-off-by: Boon Khai Ng Signed-off-by: Sieu Mun Tang Change-Id: I2627750e8337c1af66217e9cb45981a9e06e7d19 --- plat/intel/soc/common/include/socfpga_fcs.h | 33 ++++++ .../soc/common/include/socfpga_sip_svc.h | 1 + plat/intel/soc/common/sip/socfpga_sip_fcs.c | 112 ++++++++++++++++++ plat/intel/soc/common/socfpga_sip_svc.c | 17 +++ 4 files changed, 163 insertions(+) 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); From d2fee94afa6ba7e76508e6bead7eb2936c5eafb8 Mon Sep 17 00:00:00 2001 From: Sieu Mun Tang Date: Tue, 10 May 2022 17:36:32 +0800 Subject: [PATCH 15/28] feat(intel): support ECDSA Get Public Key To support the ECDSA feature and send the command as a request to get the public key Signed-off-by: Boon Khai Ng Signed-off-by: Sieu Mun Tang Change-Id: I9d7bb5b6ab8ef7d4f3ceb21ff0068baf3175a1ac --- plat/intel/soc/common/include/socfpga_fcs.h | 9 +++ .../soc/common/include/socfpga_mailbox.h | 1 + .../soc/common/include/socfpga_sip_svc.h | 3 + plat/intel/soc/common/sip/socfpga_sip_fcs.c | 67 +++++++++++++++++++ plat/intel/soc/common/socfpga_sip_svc.c | 11 +++ 5 files changed, 91 insertions(+) diff --git a/plat/intel/soc/common/include/socfpga_fcs.h b/plat/intel/soc/common/include/socfpga_fcs.h index 15b7a2c23..f58f9faef 100644 --- a/plat/intel/soc/common/include/socfpga_fcs.h +++ b/plat/intel/soc/common/include/socfpga_fcs.h @@ -76,6 +76,8 @@ #define FCS_MAC_VERIFY_CMD_MAX_WORD_SIZE 23U #define FCS_MAC_VERIFY_RESP_MAX_WORD_SIZE 4U #define FCS_SHA_HMAC_CRYPTO_PARAM_SIZE_OFFSET 8U + +#define FCS_ECDSA_GET_PUBKEY_MAX_WORD_SIZE 5U /* FCS Payload Structure */ typedef struct fcs_rng_payload_t { uint32_t session_id; @@ -234,6 +236,13 @@ 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_ecdsa_get_pubkey_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_get_pubkey_finalize(uint32_t session_id, uint32_t context_id, + uint64_t dst_addr, uint32_t *dst_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); diff --git a/plat/intel/soc/common/include/socfpga_mailbox.h b/plat/intel/soc/common/include/socfpga_mailbox.h index a7e2bc33e..1d749a0d6 100644 --- a/plat/intel/soc/common/include/socfpga_mailbox.h +++ b/plat/intel/soc/common/include/socfpga_mailbox.h @@ -78,6 +78,7 @@ #define MBOX_FCS_AES_CRYPT_REQ 0x81 #define MBOX_FCS_GET_DIGEST_REQ 0x82 #define MBOX_FCS_MAC_VERIFY_REQ 0x83 +#define MBOX_FCS_ECDSA_GET_PUBKEY 0x88 #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 3c92a4ac9..ff13af977 100644 --- a/plat/intel/soc/common/include/socfpga_sip_svc.h +++ b/plat/intel/soc/common/include/socfpga_sip_svc.h @@ -100,10 +100,13 @@ #define INTEL_SIP_SMC_FCS_GET_DIGEST_FINALIZE 0xC2000079 #define INTEL_SIP_SMC_FCS_MAC_VERIFY_INIT 0xC200007A #define INTEL_SIP_SMC_FCS_MAC_VERIFY_FINALIZE 0xC200007C +#define INTEL_SIP_SMC_FCS_ECDSA_GET_PUBKEY_INIT 0xC2000089 +#define INTEL_SIP_SMC_FCS_ECDSA_GET_PUBKEY_FINALIZE 0xC200008B #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 +#define INTEL_SIP_SMC_FCS_ECC_ALGO_MASK 0xF /* 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 4f2c73d77..f5bcf7472 100644 --- a/plat/intel/soc/common/sip/socfpga_sip_fcs.c +++ b/plat/intel/soc/common/sip/socfpga_sip_fcs.c @@ -15,6 +15,7 @@ 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; +static fcs_crypto_service_data fcs_ecdsa_get_pubkey_param; bool is_size_4_bytes_aligned(uint32_t size) { @@ -1016,6 +1017,72 @@ int intel_fcs_mac_verify_finalize(uint32_t session_id, uint32_t context_id, return INTEL_SIP_SMC_STATUS_OK; } +int intel_fcs_ecdsa_get_pubkey_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_ecdsa_get_pubkey_param, + mbox_error); +} + +int intel_fcs_ecdsa_get_pubkey_finalize(uint32_t session_id, uint32_t context_id, + uint64_t dst_addr, uint32_t *dst_size, + uint32_t *mbox_error) +{ + int status; + int i; + uint32_t crypto_header; + uint32_t ret_size = *dst_size / MBOX_WORD_BYTE; + uint32_t payload[FCS_ECDSA_GET_PUBKEY_MAX_WORD_SIZE] = {0U}; + + if ((dst_size == NULL) || (mbox_error == NULL)) { + return INTEL_SIP_SMC_STATUS_REJECTED; + } + + if (fcs_ecdsa_get_pubkey_param.session_id != session_id || + fcs_ecdsa_get_pubkey_param.context_id != context_id) { + 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_ecdsa_get_pubkey_param.crypto_param_size; + i = 0; + /* Prepare command payload */ + payload[i] = session_id; + i++; + payload[i] = context_id; + i++; + payload[i] = crypto_header; + i++; + payload[i] = fcs_ecdsa_get_pubkey_param.key_id; + i++; + payload[i] = (uint32_t) fcs_ecdsa_get_pubkey_param.crypto_param & + INTEL_SIP_SMC_FCS_ECC_ALGO_MASK; + i++; + + status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_ECDSA_GET_PUBKEY, + payload, i, CMD_CASUAL, + (uint32_t *) dst_addr, &ret_size); + + memset((void *) &fcs_ecdsa_get_pubkey_param, 0, + sizeof(fcs_crypto_service_data)); + + if (status < 0) { + *mbox_error = -status; + return INTEL_SIP_SMC_STATUS_ERROR; + } + + *dst_size = ret_size * MBOX_WORD_BYTE; + flush_dcache_range(dst_addr, *dst_size); + + 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) diff --git a/plat/intel/soc/common/socfpga_sip_svc.c b/plat/intel/soc/common/socfpga_sip_svc.c index 824ee3854..d6196a474 100644 --- a/plat/intel/soc/common/socfpga_sip_svc.c +++ b/plat/intel/soc/common/socfpga_sip_svc.c @@ -911,6 +911,17 @@ 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_ECDSA_GET_PUBKEY_INIT: + x5 = SMC_GET_GP(handle, CTX_GPREG_X5); + status = intel_fcs_ecdsa_get_pubkey_init(x1, x2, x3, + x4, x5, &mbox_error); + SMC_RET2(handle, status, mbox_error); + + case INTEL_SIP_SMC_FCS_ECDSA_GET_PUBKEY_FINALIZE: + status = intel_fcs_ecdsa_get_pubkey_finalize(x1, x2, x3, + (uint32_t *) &x4, &mbox_error); + SMC_RET4(handle, status, mbox_error, x3, x4); + 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, From 07912da1b7663451493fb5e40e4c33deeb18a639 Mon Sep 17 00:00:00 2001 From: Sieu Mun Tang Date: Tue, 10 May 2022 17:39:26 +0800 Subject: [PATCH 16/28] feat(intel): support ECDSA SHA-2 Data Signing This command support ECC based signing on a blob. Supported ECC algorithm are NISP P-256, NISP P-384, Brainpool 256 and Brainpool 384. Signed-off-by: Siew Chin Lim Signed-off-by: Boon Khai Ng Signed-off-by: Sieu Mun Tang Change-Id: I82f95ddafa6b62f8cd882fce9a3e63e469c85067 --- plat/intel/soc/common/include/socfpga_fcs.h | 10 +++ .../soc/common/include/socfpga_mailbox.h | 1 + .../soc/common/include/socfpga_sip_svc.h | 2 + plat/intel/soc/common/sip/socfpga_sip_fcs.c | 84 +++++++++++++++++++ plat/intel/soc/common/socfpga_sip_svc.c | 14 ++++ 5 files changed, 111 insertions(+) diff --git a/plat/intel/soc/common/include/socfpga_fcs.h b/plat/intel/soc/common/include/socfpga_fcs.h index f58f9faef..f5cab14c5 100644 --- a/plat/intel/soc/common/include/socfpga_fcs.h +++ b/plat/intel/soc/common/include/socfpga_fcs.h @@ -78,6 +78,7 @@ #define FCS_SHA_HMAC_CRYPTO_PARAM_SIZE_OFFSET 8U #define FCS_ECDSA_GET_PUBKEY_MAX_WORD_SIZE 5U +#define FCS_ECDSA_SHA2_DATA_SIGN_CMD_MAX_WORD_SIZE 7U /* FCS Payload Structure */ typedef struct fcs_rng_payload_t { uint32_t session_id; @@ -236,6 +237,15 @@ 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_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, + 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 intel_fcs_ecdsa_get_pubkey_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); diff --git a/plat/intel/soc/common/include/socfpga_mailbox.h b/plat/intel/soc/common/include/socfpga_mailbox.h index 1d749a0d6..e5e1d140f 100644 --- a/plat/intel/soc/common/include/socfpga_mailbox.h +++ b/plat/intel/soc/common/include/socfpga_mailbox.h @@ -78,6 +78,7 @@ #define MBOX_FCS_AES_CRYPT_REQ 0x81 #define MBOX_FCS_GET_DIGEST_REQ 0x82 #define MBOX_FCS_MAC_VERIFY_REQ 0x83 +#define MBOX_FCS_ECDSA_SHA2_DATA_SIGN_REQ 0x85 #define MBOX_FCS_ECDSA_GET_PUBKEY 0x88 #define MBOX_FCS_OPEN_CS_SESSION 0xA0 #define MBOX_FCS_CLOSE_CS_SESSION 0xA1 diff --git a/plat/intel/soc/common/include/socfpga_sip_svc.h b/plat/intel/soc/common/include/socfpga_sip_svc.h index ff13af977..14be92b45 100644 --- a/plat/intel/soc/common/include/socfpga_sip_svc.h +++ b/plat/intel/soc/common/include/socfpga_sip_svc.h @@ -100,6 +100,8 @@ #define INTEL_SIP_SMC_FCS_GET_DIGEST_FINALIZE 0xC2000079 #define INTEL_SIP_SMC_FCS_MAC_VERIFY_INIT 0xC200007A #define INTEL_SIP_SMC_FCS_MAC_VERIFY_FINALIZE 0xC200007C +#define INTEL_SIP_SMC_FCS_ECDSA_SHA2_DATA_SIGN_INIT 0xC2000080 +#define INTEL_SIP_SMC_FCS_ECDSA_SHA2_DATA_SIGN_FINALIZE 0xC2000082 #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 f5bcf7472..953ba5540 100644 --- a/plat/intel/soc/common/sip/socfpga_sip_fcs.c +++ b/plat/intel/soc/common/sip/socfpga_sip_fcs.c @@ -16,6 +16,7 @@ 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; static fcs_crypto_service_data fcs_ecdsa_get_pubkey_param; +static fcs_crypto_service_data fcs_sha2_data_sign_param; bool is_size_4_bytes_aligned(uint32_t size) { @@ -1017,6 +1018,89 @@ int intel_fcs_mac_verify_finalize(uint32_t session_id, uint32_t context_id, return INTEL_SIP_SMC_STATUS_OK; } +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) +{ + return intel_fcs_crypto_service_init(session_id, context_id, + key_id, param_size, param_data, + (void *) &fcs_sha2_data_sign_param, + mbox_error); +} + +int intel_fcs_ecdsa_sha2_data_sign_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; + int i; + uint32_t payload[FCS_ECDSA_SHA2_DATA_SIGN_CMD_MAX_WORD_SIZE] = {0U}; + uint32_t resp_len = *dst_size / MBOX_WORD_BYTE; + + if ((dst_size == NULL) || (mbox_error == NULL)) { + return INTEL_SIP_SMC_STATUS_REJECTED; + } + + if (fcs_sha2_data_sign_param.session_id != session_id || + fcs_sha2_data_sign_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 */ + /* 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; + 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; + /* Data source address and size */ + i++; + payload[i] = src_addr; + i++; + payload[i] = src_size; + i++; + status = mailbox_send_cmd(MBOX_JOB_ID, + MBOX_FCS_ECDSA_SHA2_DATA_SIGN_REQ, payload, + i, CMD_CASUAL, (uint32_t *) dst_addr, + &resp_len); + + memset((void *)&fcs_sha2_data_sign_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; +} + int intel_fcs_ecdsa_get_pubkey_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) diff --git a/plat/intel/soc/common/socfpga_sip_svc.c b/plat/intel/soc/common/socfpga_sip_svc.c index d6196a474..d6239c94b 100644 --- a/plat/intel/soc/common/socfpga_sip_svc.c +++ b/plat/intel/soc/common/socfpga_sip_svc.c @@ -911,6 +911,20 @@ 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_ECDSA_SHA2_DATA_SIGN_INIT: + x5 = SMC_GET_GP(handle, CTX_GPREG_X5); + status = intel_fcs_ecdsa_sha2_data_sign_init(x1, x2, x3, + x4, x5, &mbox_error); + SMC_RET2(handle, status, mbox_error); + + 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); + SMC_RET4(handle, status, mbox_error, x5, x6); + + case INTEL_SIP_SMC_FCS_ECDSA_GET_PUBKEY_INIT: x5 = SMC_GET_GP(handle, CTX_GPREG_X5); status = intel_fcs_ecdsa_get_pubkey_init(x1, x2, x3, From 583050607e43cef8b544a5700386a019e54c422f Mon Sep 17 00:00:00 2001 From: Sieu Mun Tang Date: Wed, 11 May 2022 10:16:40 +0800 Subject: [PATCH 17/28] feat(intel): support ECDSA SHA-2 Data Signature Verification This command support ECC based signature verification on a blob. Supported ECC algorithm are NISP P-256, NISP P-384, Brainpool 256 and Brainpool 384. Signed-off-by: Siew Chin Lim Signed-off-by: Boon Khai Ng Signed-off-by: Sieu Mun Tang Change-Id: I7f43d2a69bbe6693ec1bb90f32b817cf00f9f5ae --- plat/intel/soc/common/include/socfpga_fcs.h | 113 ++++++------ .../soc/common/include/socfpga_mailbox.h | 1 + .../soc/common/include/socfpga_sip_svc.h | 162 +++++++++--------- plat/intel/soc/common/sip/socfpga_sip_fcs.c | 99 ++++++++++- plat/intel/soc/common/socfpga_sip_svc.c | 13 ++ 5 files changed, 255 insertions(+), 133 deletions(-) diff --git a/plat/intel/soc/common/include/socfpga_fcs.h b/plat/intel/soc/common/include/socfpga_fcs.h index f5cab14c5..3fd71c130 100644 --- a/plat/intel/soc/common/include/socfpga_fcs.h +++ b/plat/intel/soc/common/include/socfpga_fcs.h @@ -9,76 +9,77 @@ /* 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_CRYPTION_CRYPTO_HEADER 0x07000000 -#define FCS_CRYPTION_RESP_WORD_SIZE 4U -#define FCS_CRYPTION_RESP_SIZE_OFFSET 3U +#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_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 -#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_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_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 -#define FCS_MAC_VERIFY_RESP_MAX_WORD_SIZE 4U -#define FCS_SHA_HMAC_CRYPTO_PARAM_SIZE_OFFSET 8U +#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 +#define FCS_MAC_VERIFY_RESP_MAX_WORD_SIZE 4U +#define FCS_SHA_HMAC_CRYPTO_PARAM_SIZE_OFFSET 8U -#define FCS_ECDSA_GET_PUBKEY_MAX_WORD_SIZE 5U -#define FCS_ECDSA_SHA2_DATA_SIGN_CMD_MAX_WORD_SIZE 7U +#define FCS_ECDSA_GET_PUBKEY_MAX_WORD_SIZE 5U +#define FCS_ECDSA_SHA2_DATA_SIGN_CMD_MAX_WORD_SIZE 7U +#define FCS_ECDSA_SHA2_DATA_SIG_VERIFY_CMD_MAX_WORD_SIZE 43U /* FCS Payload Structure */ typedef struct fcs_rng_payload_t { uint32_t session_id; @@ -246,6 +247,16 @@ int intel_fcs_ecdsa_sha2_data_sign_finalize(uint32_t session_id, uint32_t src_size, uint64_t dst_addr, uint32_t *dst_size, 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, + 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); + int intel_fcs_ecdsa_get_pubkey_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); diff --git a/plat/intel/soc/common/include/socfpga_mailbox.h b/plat/intel/soc/common/include/socfpga_mailbox.h index e5e1d140f..042532cb3 100644 --- a/plat/intel/soc/common/include/socfpga_mailbox.h +++ b/plat/intel/soc/common/include/socfpga_mailbox.h @@ -79,6 +79,7 @@ #define MBOX_FCS_GET_DIGEST_REQ 0x82 #define MBOX_FCS_MAC_VERIFY_REQ 0x83 #define MBOX_FCS_ECDSA_SHA2_DATA_SIGN_REQ 0x85 +#define MBOX_FCS_ECDSA_SHA2_DATA_SIGN_VERIFY 0x87 #define MBOX_FCS_ECDSA_GET_PUBKEY 0x88 #define MBOX_FCS_OPEN_CS_SESSION 0xA0 #define MBOX_FCS_CLOSE_CS_SESSION 0xA1 diff --git a/plat/intel/soc/common/include/socfpga_sip_svc.h b/plat/intel/soc/common/include/socfpga_sip_svc.h index 14be92b45..445fd646b 100644 --- a/plat/intel/soc/common/include/socfpga_sip_svc.h +++ b/plat/intel/soc/common/include/socfpga_sip_svc.h @@ -9,30 +9,30 @@ /* SiP status response */ -#define INTEL_SIP_SMC_STATUS_OK 0 -#define INTEL_SIP_SMC_STATUS_BUSY 0x1 -#define INTEL_SIP_SMC_STATUS_REJECTED 0x2 -#define INTEL_SIP_SMC_STATUS_NO_RESPONSE 0x3 -#define INTEL_SIP_SMC_STATUS_ERROR 0x4 -#define INTEL_SIP_SMC_RSU_ERROR 0x7 +#define INTEL_SIP_SMC_STATUS_OK 0 +#define INTEL_SIP_SMC_STATUS_BUSY 0x1 +#define INTEL_SIP_SMC_STATUS_REJECTED 0x2 +#define INTEL_SIP_SMC_STATUS_NO_RESPONSE 0x3 +#define INTEL_SIP_SMC_STATUS_ERROR 0x4 +#define INTEL_SIP_SMC_RSU_ERROR 0x7 /* SiP mailbox error code */ -#define GENERIC_RESPONSE_ERROR 0x3FF +#define GENERIC_RESPONSE_ERROR 0x3FF /* SMC SiP service function identifier */ /* FPGA Reconfig */ -#define INTEL_SIP_SMC_FPGA_CONFIG_START 0xC2000001 -#define INTEL_SIP_SMC_FPGA_CONFIG_WRITE 0x42000002 -#define INTEL_SIP_SMC_FPGA_CONFIG_COMPLETED_WRITE 0xC2000003 -#define INTEL_SIP_SMC_FPGA_CONFIG_ISDONE 0xC2000004 -#define INTEL_SIP_SMC_FPGA_CONFIG_GET_MEM 0xC2000005 +#define INTEL_SIP_SMC_FPGA_CONFIG_START 0xC2000001 +#define INTEL_SIP_SMC_FPGA_CONFIG_WRITE 0x42000002 +#define INTEL_SIP_SMC_FPGA_CONFIG_COMPLETED_WRITE 0xC2000003 +#define INTEL_SIP_SMC_FPGA_CONFIG_ISDONE 0xC2000004 +#define INTEL_SIP_SMC_FPGA_CONFIG_GET_MEM 0xC2000005 /* FPGA Bitstream Flag */ -#define FLAG_PARTIAL_CONFIG BIT(0) -#define FLAG_AUTHENTICATION BIT(1) -#define CONFIG_TEST_FLAG(_flag, _type) (((flag) & FLAG_##_type) \ - == FLAG_##_type) +#define FLAG_PARTIAL_CONFIG BIT(0) +#define FLAG_AUTHENTICATION BIT(1) +#define CONFIG_TEST_FLAG(_flag, _type) (((flag) & FLAG_##_type) \ + == FLAG_##_type) /* Secure Register Access */ #define INTEL_SIP_SMC_REG_READ 0xC2000007 @@ -40,92 +40,92 @@ #define INTEL_SIP_SMC_REG_UPDATE 0xC2000009 /* Remote System Update */ -#define INTEL_SIP_SMC_RSU_STATUS 0xC200000B -#define INTEL_SIP_SMC_RSU_UPDATE 0xC200000C -#define INTEL_SIP_SMC_RSU_NOTIFY 0xC200000E -#define INTEL_SIP_SMC_RSU_RETRY_COUNTER 0xC200000F -#define INTEL_SIP_SMC_RSU_DCMF_VERSION 0xC2000010 -#define INTEL_SIP_SMC_RSU_COPY_DCMF_VERSION 0xC2000011 -#define INTEL_SIP_SMC_RSU_MAX_RETRY 0xC2000012 -#define INTEL_SIP_SMC_RSU_COPY_MAX_RETRY 0xC2000013 -#define INTEL_SIP_SMC_RSU_DCMF_STATUS 0xC2000014 -#define INTEL_SIP_SMC_RSU_COPY_DCMF_STATUS 0xC2000015 +#define INTEL_SIP_SMC_RSU_STATUS 0xC200000B +#define INTEL_SIP_SMC_RSU_UPDATE 0xC200000C +#define INTEL_SIP_SMC_RSU_NOTIFY 0xC200000E +#define INTEL_SIP_SMC_RSU_RETRY_COUNTER 0xC200000F +#define INTEL_SIP_SMC_RSU_DCMF_VERSION 0xC2000010 +#define INTEL_SIP_SMC_RSU_COPY_DCMF_VERSION 0xC2000011 +#define INTEL_SIP_SMC_RSU_MAX_RETRY 0xC2000012 +#define INTEL_SIP_SMC_RSU_COPY_MAX_RETRY 0xC2000013 +#define INTEL_SIP_SMC_RSU_DCMF_STATUS 0xC2000014 +#define INTEL_SIP_SMC_RSU_COPY_DCMF_STATUS 0xC2000015 /* Hardware monitor */ -#define INTEL_SIP_SMC_HWMON_READTEMP 0xC2000020 -#define INTEL_SIP_SMC_HWMON_READVOLT 0xC2000021 -#define TEMP_CHANNEL_MAX (1 << 15) -#define VOLT_CHANNEL_MAX (1 << 15) +#define INTEL_SIP_SMC_HWMON_READTEMP 0xC2000020 +#define INTEL_SIP_SMC_HWMON_READVOLT 0xC2000021 +#define TEMP_CHANNEL_MAX (1 << 15) +#define VOLT_CHANNEL_MAX (1 << 15) /* ECC */ -#define INTEL_SIP_SMC_ECC_DBE 0xC200000D +#define INTEL_SIP_SMC_ECC_DBE 0xC200000D /* Generic Command */ -#define INTEL_SIP_SMC_HPS_SET_BRIDGES 0xC2000032 -#define INTEL_SIP_SMC_GET_ROM_PATCH_SHA384 0xC2000040 +#define INTEL_SIP_SMC_MBOX_SEND_CMD 0xC200001E +#define INTEL_SIP_SMC_FIRMWARE_VERSION 0xC200001F +#define INTEL_SIP_SMC_HPS_SET_BRIDGES 0xC2000032 +#define INTEL_SIP_SMC_GET_ROM_PATCH_SHA384 0xC2000040 -/* Send Mailbox Command */ -#define INTEL_SIP_SMC_MBOX_SEND_CMD 0xC200001E -#define INTEL_SIP_SMC_FIRMWARE_VERSION 0xC200001F -#define INTEL_SIP_SMC_HPS_SET_BRIDGES 0xC2000032 - -#define SERVICE_COMPLETED_MODE_ASYNC 0x00004F4E +#define SERVICE_COMPLETED_MODE_ASYNC 0x00004F4E /* Mailbox Command */ -#define INTEL_SIP_SMC_GET_USERCODE 0xC200003D +#define INTEL_SIP_SMC_GET_USERCODE 0xC200003D /* FPGA Crypto Services */ -#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 -#define INTEL_SIP_SMC_FCS_PSGSIGMA_TEARDOWN 0xC2000064 -#define INTEL_SIP_SMC_FCS_CHIP_ID 0xC2000065 -#define INTEL_SIP_SMC_FCS_ATTESTATION_SUBKEY 0xC2000066 -#define INTEL_SIP_SMC_FCS_ATTESTATION_MEASUREMENTS 0xC2000067 -#define INTEL_SIP_SMC_FCS_GET_ATTESTATION_CERT 0xC2000068 -#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 -#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 -#define INTEL_SIP_SMC_FCS_MAC_VERIFY_FINALIZE 0xC200007C -#define INTEL_SIP_SMC_FCS_ECDSA_SHA2_DATA_SIGN_INIT 0xC2000080 -#define INTEL_SIP_SMC_FCS_ECDSA_SHA2_DATA_SIGN_FINALIZE 0xC2000082 -#define INTEL_SIP_SMC_FCS_ECDSA_GET_PUBKEY_INIT 0xC2000089 -#define INTEL_SIP_SMC_FCS_ECDSA_GET_PUBKEY_FINALIZE 0xC200008B +#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 +#define INTEL_SIP_SMC_FCS_PSGSIGMA_TEARDOWN 0xC2000064 +#define INTEL_SIP_SMC_FCS_CHIP_ID 0xC2000065 +#define INTEL_SIP_SMC_FCS_ATTESTATION_SUBKEY 0xC2000066 +#define INTEL_SIP_SMC_FCS_ATTESTATION_MEASUREMENTS 0xC2000067 +#define INTEL_SIP_SMC_FCS_GET_ATTESTATION_CERT 0xC2000068 +#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 +#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 +#define INTEL_SIP_SMC_FCS_MAC_VERIFY_FINALIZE 0xC200007C +#define INTEL_SIP_SMC_FCS_ECDSA_SHA2_DATA_SIGN_INIT 0xC2000080 +#define INTEL_SIP_SMC_FCS_ECDSA_SHA2_DATA_SIGN_FINALIZE 0xC2000082 +#define INTEL_SIP_SMC_FCS_ECDSA_SHA2_DATA_SIG_VERIFY_INIT 0xC2000086 +#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 + +#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 +#define INTEL_SIP_SMC_FCS_ECC_ALGO_MASK 0xF -#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 -#define INTEL_SIP_SMC_FCS_ECC_ALGO_MASK 0xF /* ECC DBE */ -#define WARM_RESET_WFI_FLAG BIT(31) -#define SYSMGR_ECC_DBE_COLD_RST_MASK (SYSMGR_ECC_OCRAM_MASK |\ +#define WARM_RESET_WFI_FLAG BIT(31) +#define SYSMGR_ECC_DBE_COLD_RST_MASK (SYSMGR_ECC_OCRAM_MASK |\ SYSMGR_ECC_DDR0_MASK |\ SYSMGR_ECC_DDR1_MASK) /* Non-mailbox SMC Call */ -#define INTEL_SIP_SMC_SVC_VERSION 0xC2000200 +#define INTEL_SIP_SMC_SVC_VERSION 0xC2000200 /* SMC function IDs for SiP Service queries */ -#define SIP_SVC_CALL_COUNT 0x8200ff00 -#define SIP_SVC_UID 0x8200ff01 -#define SIP_SVC_VERSION 0x8200ff03 +#define SIP_SVC_CALL_COUNT 0x8200ff00 +#define SIP_SVC_UID 0x8200ff01 +#define SIP_SVC_VERSION 0x8200ff03 /* SiP Service Calls version numbers */ -#define SIP_SVC_VERSION_MAJOR 1 -#define SIP_SVC_VERSION_MINOR 0 +#define SIP_SVC_VERSION_MAJOR 1 +#define SIP_SVC_VERSION_MINOR 0 /* Structure Definitions */ diff --git a/plat/intel/soc/common/sip/socfpga_sip_fcs.c b/plat/intel/soc/common/sip/socfpga_sip_fcs.c index 953ba5540..d6c0166c1 100644 --- a/plat/intel/soc/common/sip/socfpga_sip_fcs.c +++ b/plat/intel/soc/common/sip/socfpga_sip_fcs.c @@ -15,8 +15,9 @@ 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; -static fcs_crypto_service_data fcs_ecdsa_get_pubkey_param; static fcs_crypto_service_data fcs_sha2_data_sign_param; +static fcs_crypto_service_data fcs_sha2_data_sig_verify_param; +static fcs_crypto_service_data fcs_ecdsa_get_pubkey_param; bool is_size_4_bytes_aligned(uint32_t size) { @@ -1101,6 +1102,102 @@ int intel_fcs_ecdsa_sha2_data_sign_finalize(uint32_t session_id, return INTEL_SIP_SMC_STATUS_OK; } +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) +{ + return intel_fcs_crypto_service_init(session_id, context_id, + key_id, param_size, param_data, + (void *) &fcs_sha2_data_sig_verify_param, + mbox_error); +} + +int intel_fcs_ecdsa_sha2_data_sig_verify_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) +{ + int status; + uint32_t i; + uint32_t payload[FCS_ECDSA_SHA2_DATA_SIG_VERIFY_CMD_MAX_WORD_SIZE] = {0U}; + uint32_t resp_len = *dst_size / MBOX_WORD_BYTE; + uintptr_t sig_pubkey_offset; + + if ((dst_size == NULL) || (mbox_error == NULL)) { + return INTEL_SIP_SMC_STATUS_REJECTED; + } + + if (fcs_sha2_data_sig_verify_param.session_id != session_id || + fcs_sha2_data_sig_verify_param.context_id != context_id) { + return INTEL_SIP_SMC_STATUS_REJECTED; + } + + if (!is_size_4_bytes_aligned(src_size)) { + return INTEL_SIP_SMC_STATUS_REJECTED; + } + + if (!is_8_bytes_aligned(data_size) || + !is_8_bytes_aligned(src_addr)) { + 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 */ + /* 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] = 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; + + 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, + 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; +} + int intel_fcs_ecdsa_get_pubkey_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) diff --git a/plat/intel/soc/common/socfpga_sip_svc.c b/plat/intel/soc/common/socfpga_sip_svc.c index d6239c94b..df500ff0f 100644 --- a/plat/intel/soc/common/socfpga_sip_svc.c +++ b/plat/intel/soc/common/socfpga_sip_svc.c @@ -924,6 +924,19 @@ uintptr_t sip_smc_handler(uint32_t smc_fid, x4, x5, (uint32_t *) &x6, &mbox_error); SMC_RET4(handle, status, mbox_error, x5, x6); + case INTEL_SIP_SMC_FCS_ECDSA_SHA2_DATA_SIG_VERIFY_INIT: + x5 = SMC_GET_GP(handle, CTX_GPREG_X5); + status = intel_fcs_ecdsa_sha2_data_sig_verify_init(x1, x2, x3, + x4, x5, &mbox_error); + SMC_RET2(handle, status, mbox_error); + + 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); + SMC_RET4(handle, status, mbox_error, x5, x6); case INTEL_SIP_SMC_FCS_ECDSA_GET_PUBKEY_INIT: x5 = SMC_GET_GP(handle, CTX_GPREG_X5); From 49446866a515c2db855d456f39df3d586b2084b7 Mon Sep 17 00:00:00 2001 From: Sieu Mun Tang Date: Tue, 10 May 2022 17:48:11 +0800 Subject: [PATCH 18/28] feat(intel): support ECDH request This command sends the request on generating a share secret on Diffie-Hellman key exchange. Signed-off-by: Siew Chin Lim Signed-off-by: Boon Khai Ng Signed-off-by: Sieu Mun Tang Change-Id: Ic7c8470cf036ea8c17bf87401f49936950b3e1d6 --- plat/intel/soc/common/include/socfpga_fcs.h | 9 +++ .../soc/common/include/socfpga_mailbox.h | 1 + .../soc/common/include/socfpga_sip_svc.h | 2 + plat/intel/soc/common/sip/socfpga_sip_fcs.c | 78 +++++++++++++++++++ plat/intel/soc/common/socfpga_sip_svc.c | 13 ++++ 5 files changed, 103 insertions(+) diff --git a/plat/intel/soc/common/include/socfpga_fcs.h b/plat/intel/soc/common/include/socfpga_fcs.h index 3fd71c130..cdb40607f 100644 --- a/plat/intel/soc/common/include/socfpga_fcs.h +++ b/plat/intel/soc/common/include/socfpga_fcs.h @@ -80,6 +80,7 @@ #define FCS_ECDSA_GET_PUBKEY_MAX_WORD_SIZE 5U #define FCS_ECDSA_SHA2_DATA_SIGN_CMD_MAX_WORD_SIZE 7U #define FCS_ECDSA_SHA2_DATA_SIG_VERIFY_CMD_MAX_WORD_SIZE 43U +#define FCS_ECDH_REQUEST_CMD_MAX_WORD_SIZE 29U /* FCS Payload Structure */ typedef struct fcs_rng_payload_t { uint32_t session_id; @@ -264,6 +265,14 @@ int intel_fcs_ecdsa_get_pubkey_finalize(uint32_t session_id, uint32_t context_id uint64_t dst_addr, uint32_t *dst_size, uint32_t *mbox_error); +int intel_fcs_ecdh_request_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_ecdh_request_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 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); diff --git a/plat/intel/soc/common/include/socfpga_mailbox.h b/plat/intel/soc/common/include/socfpga_mailbox.h index 042532cb3..f2780c2ab 100644 --- a/plat/intel/soc/common/include/socfpga_mailbox.h +++ b/plat/intel/soc/common/include/socfpga_mailbox.h @@ -81,6 +81,7 @@ #define MBOX_FCS_ECDSA_SHA2_DATA_SIGN_REQ 0x85 #define MBOX_FCS_ECDSA_SHA2_DATA_SIGN_VERIFY 0x87 #define MBOX_FCS_ECDSA_GET_PUBKEY 0x88 +#define MBOX_FCS_ECDH_REQUEST 0x89 #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 445fd646b..9f966d338 100644 --- a/plat/intel/soc/common/include/socfpga_sip_svc.h +++ b/plat/intel/soc/common/include/socfpga_sip_svc.h @@ -103,6 +103,8 @@ #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 +#define INTEL_SIP_SMC_FCS_ECDH_REQUEST_INIT 0xC200008C +#define INTEL_SIP_SMC_FCS_ECDH_REQUEST_FINALIZE 0xC200008E #define INTEL_SIP_SMC_FCS_SHA_MODE_MASK 0xF #define INTEL_SIP_SMC_FCS_DIGEST_SIZE_MASK 0xF diff --git a/plat/intel/soc/common/sip/socfpga_sip_fcs.c b/plat/intel/soc/common/sip/socfpga_sip_fcs.c index d6c0166c1..e3ed4e065 100644 --- a/plat/intel/soc/common/sip/socfpga_sip_fcs.c +++ b/plat/intel/soc/common/sip/socfpga_sip_fcs.c @@ -18,6 +18,7 @@ static fcs_crypto_service_data fcs_sha_mac_verify_param; static fcs_crypto_service_data fcs_sha2_data_sign_param; static fcs_crypto_service_data fcs_sha2_data_sig_verify_param; static fcs_crypto_service_data fcs_ecdsa_get_pubkey_param; +static fcs_crypto_service_data fcs_ecdh_request_param; bool is_size_4_bytes_aligned(uint32_t size) { @@ -1264,6 +1265,83 @@ int intel_fcs_ecdsa_get_pubkey_finalize(uint32_t session_id, uint32_t context_id return INTEL_SIP_SMC_STATUS_OK; } +int intel_fcs_ecdh_request_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_ecdh_request_param, + mbox_error); +} + +int intel_fcs_ecdh_request_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 payload[FCS_ECDH_REQUEST_CMD_MAX_WORD_SIZE] = {0U}; + uint32_t resp_len = *dst_size / MBOX_WORD_BYTE; + uintptr_t pubkey; + + if ((dst_size == NULL) || (mbox_error == NULL)) { + return INTEL_SIP_SMC_STATUS_REJECTED; + } + + if (fcs_ecdh_request_param.session_id != session_id || + fcs_ecdh_request_param.context_id != context_id) { + 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_ecdh_request_param.session_id; + i++; + payload[i] = fcs_ecdh_request_param.context_id; + i++; + payload[i] = fcs_ecdh_request_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_ecdh_request_param.key_id; + i++; + /* Crypto parameters */ + payload[i] = fcs_ecdh_request_param.crypto_param + & INTEL_SIP_SMC_FCS_ECC_ALGO_MASK; + i++; + /* Public key data */ + pubkey = src_addr; + memcpy((uint8_t *) &payload[i], (uint8_t *) pubkey, src_size); + i += src_size / MBOX_WORD_BYTE; + + status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_ECDH_REQUEST, + payload, i, CMD_CASUAL, (uint32_t *) dst_addr, + &resp_len); + + memset((void *)&fcs_ecdh_request_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; +} + 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) diff --git a/plat/intel/soc/common/socfpga_sip_svc.c b/plat/intel/soc/common/socfpga_sip_svc.c index df500ff0f..b7e9b1f67 100644 --- a/plat/intel/soc/common/socfpga_sip_svc.c +++ b/plat/intel/soc/common/socfpga_sip_svc.c @@ -949,6 +949,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_ECDH_REQUEST_INIT: + x5 = SMC_GET_GP(handle, CTX_GPREG_X5); + status = intel_fcs_ecdh_request_init(x1, x2, x3, + x4, x5, &mbox_error); + SMC_RET2(handle, status, mbox_error); + + case INTEL_SIP_SMC_FCS_ECDH_REQUEST_FINALIZE: + x5 = SMC_GET_GP(handle, CTX_GPREG_X5); + x6 = SMC_GET_GP(handle, CTX_GPREG_X6); + status = intel_fcs_ecdh_request_finalize(x1, x2, x3, + x4, x5, (uint32_t *) &x6, &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, From 692541051b8cb0f435ae46c5d7351231ee292319 Mon Sep 17 00:00:00 2001 From: Sieu Mun Tang Date: Tue, 10 May 2022 17:50:30 +0800 Subject: [PATCH 19/28] feat(intel): support ECDSA HASH Signing Supporting the command to send digital signature signing request on a data blob. This include ECC algorithm such as NISP P-256, NISP P-384, Brainpool 256 and, Branpool 384 Signed-off-by: Boon Khai Ng Signed-off-by: Sieu Mun Tang Change-Id: I12cf0f1ceaf07c33a110eae398d3ad82a9b13d38 --- plat/intel/soc/common/include/socfpga_fcs.h | 9 ++ .../soc/common/include/socfpga_mailbox.h | 1 + .../soc/common/include/socfpga_sip_svc.h | 2 + plat/intel/soc/common/sip/socfpga_sip_fcs.c | 83 +++++++++++++++++++ plat/intel/soc/common/socfpga_sip_svc.c | 13 +++ 5 files changed, 108 insertions(+) diff --git a/plat/intel/soc/common/include/socfpga_fcs.h b/plat/intel/soc/common/include/socfpga_fcs.h index cdb40607f..e8f01f019 100644 --- a/plat/intel/soc/common/include/socfpga_fcs.h +++ b/plat/intel/soc/common/include/socfpga_fcs.h @@ -80,6 +80,7 @@ #define FCS_ECDSA_GET_PUBKEY_MAX_WORD_SIZE 5U #define FCS_ECDSA_SHA2_DATA_SIGN_CMD_MAX_WORD_SIZE 7U #define FCS_ECDSA_SHA2_DATA_SIG_VERIFY_CMD_MAX_WORD_SIZE 43U +#define FCS_ECDSA_HASH_SIGN_CMD_MAX_WORD_SIZE 17U #define FCS_ECDH_REQUEST_CMD_MAX_WORD_SIZE 29U /* FCS Payload Structure */ typedef struct fcs_rng_payload_t { @@ -239,6 +240,14 @@ 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_ecdsa_hash_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_hash_sign_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 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, diff --git a/plat/intel/soc/common/include/socfpga_mailbox.h b/plat/intel/soc/common/include/socfpga_mailbox.h index f2780c2ab..b5d8e4b72 100644 --- a/plat/intel/soc/common/include/socfpga_mailbox.h +++ b/plat/intel/soc/common/include/socfpga_mailbox.h @@ -78,6 +78,7 @@ #define MBOX_FCS_AES_CRYPT_REQ 0x81 #define MBOX_FCS_GET_DIGEST_REQ 0x82 #define MBOX_FCS_MAC_VERIFY_REQ 0x83 +#define MBOX_FCS_ECDSA_HASH_SIGN_REQ 0x84 #define MBOX_FCS_ECDSA_SHA2_DATA_SIGN_REQ 0x85 #define MBOX_FCS_ECDSA_SHA2_DATA_SIGN_VERIFY 0x87 #define MBOX_FCS_ECDSA_GET_PUBKEY 0x88 diff --git a/plat/intel/soc/common/include/socfpga_sip_svc.h b/plat/intel/soc/common/include/socfpga_sip_svc.h index 9f966d338..332dc20de 100644 --- a/plat/intel/soc/common/include/socfpga_sip_svc.h +++ b/plat/intel/soc/common/include/socfpga_sip_svc.h @@ -97,6 +97,8 @@ #define INTEL_SIP_SMC_FCS_GET_DIGEST_FINALIZE 0xC2000079 #define INTEL_SIP_SMC_FCS_MAC_VERIFY_INIT 0xC200007A #define INTEL_SIP_SMC_FCS_MAC_VERIFY_FINALIZE 0xC200007C +#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_FINALIZE 0xC2000082 #define INTEL_SIP_SMC_FCS_ECDSA_SHA2_DATA_SIG_VERIFY_INIT 0xC2000086 diff --git a/plat/intel/soc/common/sip/socfpga_sip_fcs.c b/plat/intel/soc/common/sip/socfpga_sip_fcs.c index e3ed4e065..70514fe1a 100644 --- a/plat/intel/soc/common/sip/socfpga_sip_fcs.c +++ b/plat/intel/soc/common/sip/socfpga_sip_fcs.c @@ -15,6 +15,7 @@ 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; +static fcs_crypto_service_data fcs_ecdsa_hash_sign_param; static fcs_crypto_service_data fcs_sha2_data_sign_param; static fcs_crypto_service_data fcs_sha2_data_sig_verify_param; static fcs_crypto_service_data fcs_ecdsa_get_pubkey_param; @@ -1020,6 +1021,88 @@ int intel_fcs_mac_verify_finalize(uint32_t session_id, uint32_t context_id, return INTEL_SIP_SMC_STATUS_OK; } +int intel_fcs_ecdsa_hash_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) +{ + return intel_fcs_crypto_service_init(session_id, context_id, + key_id, param_size, param_data, + (void *) &fcs_ecdsa_hash_sign_param, + mbox_error); +} + +int intel_fcs_ecdsa_hash_sign_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 payload[FCS_ECDSA_HASH_SIGN_CMD_MAX_WORD_SIZE] = {0U}; + uint32_t resp_len = *dst_size / MBOX_WORD_BYTE; + uintptr_t hash_data_addr; + + if ((dst_size == NULL) || (mbox_error == NULL)) { + return INTEL_SIP_SMC_STATUS_REJECTED; + } + + if (fcs_ecdsa_hash_sign_param.session_id != session_id || + fcs_ecdsa_hash_sign_param.context_id != context_id) { + 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 */ + /* Crypto header */ + i = 0; + payload[i] = fcs_ecdsa_hash_sign_param.session_id; + i++; + payload[i] = fcs_ecdsa_hash_sign_param.context_id; + + i++; + payload[i] = fcs_ecdsa_hash_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; + i++; + payload[i] = fcs_ecdsa_hash_sign_param.key_id; + + /* Crypto parameters */ + i++; + payload[i] = fcs_ecdsa_hash_sign_param.crypto_param + & INTEL_SIP_SMC_FCS_ECC_ALGO_MASK; + + /* Hash Data */ + i++; + hash_data_addr = src_addr; + memcpy((uint8_t *) &payload[i], (uint8_t *) hash_data_addr, + src_size); + + i += src_size / MBOX_WORD_BYTE; + + status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_ECDSA_HASH_SIGN_REQ, + payload, i, CMD_CASUAL, (uint32_t *) dst_addr, + &resp_len); + + memset((void *) &fcs_ecdsa_hash_sign_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; +} + 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, diff --git a/plat/intel/soc/common/socfpga_sip_svc.c b/plat/intel/soc/common/socfpga_sip_svc.c index b7e9b1f67..7e9e561f2 100644 --- a/plat/intel/soc/common/socfpga_sip_svc.c +++ b/plat/intel/soc/common/socfpga_sip_svc.c @@ -924,6 +924,19 @@ uintptr_t sip_smc_handler(uint32_t smc_fid, x4, x5, (uint32_t *) &x6, &mbox_error); SMC_RET4(handle, status, mbox_error, x5, x6); + case INTEL_SIP_SMC_FCS_ECDSA_HASH_SIGN_INIT: + x5 = SMC_GET_GP(handle, CTX_GPREG_X5); + status = intel_fcs_ecdsa_hash_sign_init(x1, x2, x3, + x4, x5, &mbox_error); + SMC_RET2(handle, status, mbox_error); + + case INTEL_SIP_SMC_FCS_ECDSA_HASH_SIGN_FINALIZE: + x5 = SMC_GET_GP(handle, CTX_GPREG_X5); + x6 = SMC_GET_GP(handle, CTX_GPREG_X6); + status = intel_fcs_ecdsa_hash_sign_finalize(x1, x2, x3, + x4, x5, (uint32_t *) &x6, &mbox_error); + SMC_RET4(handle, status, mbox_error, x5, x6); + case INTEL_SIP_SMC_FCS_ECDSA_SHA2_DATA_SIG_VERIFY_INIT: x5 = SMC_GET_GP(handle, CTX_GPREG_X5); status = intel_fcs_ecdsa_sha2_data_sig_verify_init(x1, x2, x3, From 7e25eb87016ba8355cf0a3a5f71fb8b8785de044 Mon Sep 17 00:00:00 2001 From: Sieu Mun Tang Date: Tue, 10 May 2022 17:53:32 +0800 Subject: [PATCH 20/28] feat(intel): support ECDSA HASH Verification Supporting the command to send digital signature verification request on a data blob. This include ECC algorithm such as NISP P-256, NISP P-384, Brainpool 256 and, Branpool 384 Signed-off-by: Boon Khai Ng Signed-off-by: Sieu Mun Tang Change-Id: Ic86f531bfe7cc7606699f2b064ac677aaf806a76 --- plat/intel/soc/common/include/socfpga_fcs.h | 9 ++ .../soc/common/include/socfpga_mailbox.h | 1 + .../soc/common/include/socfpga_sip_svc.h | 5 +- plat/intel/soc/common/sip/socfpga_sip_fcs.c | 85 +++++++++++++++++++ plat/intel/soc/common/socfpga_sip_svc.c | 13 +++ 5 files changed, 112 insertions(+), 1 deletion(-) diff --git a/plat/intel/soc/common/include/socfpga_fcs.h b/plat/intel/soc/common/include/socfpga_fcs.h index e8f01f019..6b1f1608c 100644 --- a/plat/intel/soc/common/include/socfpga_fcs.h +++ b/plat/intel/soc/common/include/socfpga_fcs.h @@ -81,6 +81,7 @@ #define FCS_ECDSA_SHA2_DATA_SIGN_CMD_MAX_WORD_SIZE 7U #define FCS_ECDSA_SHA2_DATA_SIG_VERIFY_CMD_MAX_WORD_SIZE 43U #define FCS_ECDSA_HASH_SIGN_CMD_MAX_WORD_SIZE 17U +#define FCS_ECDSA_HASH_SIG_VERIFY_CMD_MAX_WORD_SIZE 52U #define FCS_ECDH_REQUEST_CMD_MAX_WORD_SIZE 29U /* FCS Payload Structure */ typedef struct fcs_rng_payload_t { @@ -248,6 +249,14 @@ int intel_fcs_ecdsa_hash_sign_finalize(uint32_t session_id, uint32_t context_id, uint64_t dst_addr, uint32_t *dst_size, uint32_t *mbox_error); +int intel_fcs_ecdsa_hash_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_hash_sig_verify_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 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, diff --git a/plat/intel/soc/common/include/socfpga_mailbox.h b/plat/intel/soc/common/include/socfpga_mailbox.h index b5d8e4b72..90b1fa69e 100644 --- a/plat/intel/soc/common/include/socfpga_mailbox.h +++ b/plat/intel/soc/common/include/socfpga_mailbox.h @@ -80,6 +80,7 @@ #define MBOX_FCS_MAC_VERIFY_REQ 0x83 #define MBOX_FCS_ECDSA_HASH_SIGN_REQ 0x84 #define MBOX_FCS_ECDSA_SHA2_DATA_SIGN_REQ 0x85 +#define MBOX_FCS_ECDSA_HASH_SIG_VERIFY 0x86 #define MBOX_FCS_ECDSA_SHA2_DATA_SIGN_VERIFY 0x87 #define MBOX_FCS_ECDSA_GET_PUBKEY 0x88 #define MBOX_FCS_ECDH_REQUEST 0x89 diff --git a/plat/intel/soc/common/include/socfpga_sip_svc.h b/plat/intel/soc/common/include/socfpga_sip_svc.h index 332dc20de..9c5088bae 100644 --- a/plat/intel/soc/common/include/socfpga_sip_svc.h +++ b/plat/intel/soc/common/include/socfpga_sip_svc.h @@ -76,8 +76,9 @@ #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_SERVICE_REQUEST 0x4200005C #define INTEL_SIP_SMC_FCS_SEND_CERTIFICATE 0x4200005D -#define INTEL_SIP_SMC_FCS_GET_PROVISION_DATA 0x4200005E +#define INTEL_SIP_SMC_FCS_GET_PROVISION_DATA 0xC200005E #define INTEL_SIP_SMC_FCS_CNTR_SET_PREAUTH 0xC200005F #define INTEL_SIP_SMC_FCS_PSGSIGMA_TEARDOWN 0xC2000064 #define INTEL_SIP_SMC_FCS_CHIP_ID 0xC2000065 @@ -101,6 +102,8 @@ #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_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_FINALIZE 0xC2000088 #define INTEL_SIP_SMC_FCS_ECDSA_GET_PUBKEY_INIT 0xC2000089 diff --git a/plat/intel/soc/common/sip/socfpga_sip_fcs.c b/plat/intel/soc/common/sip/socfpga_sip_fcs.c index 70514fe1a..35dd2c58c 100644 --- a/plat/intel/soc/common/sip/socfpga_sip_fcs.c +++ b/plat/intel/soc/common/sip/socfpga_sip_fcs.c @@ -16,6 +16,7 @@ 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; static fcs_crypto_service_data fcs_ecdsa_hash_sign_param; +static fcs_crypto_service_data fcs_ecdsa_hash_sig_verify_param; static fcs_crypto_service_data fcs_sha2_data_sign_param; static fcs_crypto_service_data fcs_sha2_data_sig_verify_param; static fcs_crypto_service_data fcs_ecdsa_get_pubkey_param; @@ -1103,6 +1104,90 @@ int intel_fcs_ecdsa_hash_sign_finalize(uint32_t session_id, uint32_t context_id, return INTEL_SIP_SMC_STATUS_OK; } +int intel_fcs_ecdsa_hash_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) +{ + return intel_fcs_crypto_service_init(session_id, context_id, + key_id, param_size, param_data, + (void *) &fcs_ecdsa_hash_sig_verify_param, + mbox_error); +} + +int intel_fcs_ecdsa_hash_sig_verify_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 = 0; + uint32_t payload[FCS_ECDSA_HASH_SIG_VERIFY_CMD_MAX_WORD_SIZE] = {0U}; + uint32_t resp_len = *dst_size / MBOX_WORD_BYTE; + uintptr_t hash_sig_pubkey_addr; + + if ((dst_size == NULL) || (mbox_error == NULL)) { + return INTEL_SIP_SMC_STATUS_REJECTED; + } + + if (fcs_ecdsa_hash_sig_verify_param.session_id != session_id || + fcs_ecdsa_hash_sig_verify_param.context_id != context_id) { + 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 */ + /* Crypto header */ + i = 0; + payload[i] = fcs_ecdsa_hash_sig_verify_param.session_id; + + i++; + payload[i] = fcs_ecdsa_hash_sig_verify_param.context_id; + + i++; + payload[i] = fcs_ecdsa_hash_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_ecdsa_hash_sig_verify_param.key_id; + + /* Crypto parameters */ + i++; + payload[i] = fcs_ecdsa_hash_sig_verify_param.crypto_param + & INTEL_SIP_SMC_FCS_ECC_ALGO_MASK; + + /* Hash Data Word, Signature Data Word and Public Key Data word */ + i++; + hash_sig_pubkey_addr = src_addr; + memcpy((uint8_t *) &payload[i], + (uint8_t *) hash_sig_pubkey_addr, src_size); + + i += (src_size / MBOX_WORD_BYTE); + + status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_ECDSA_HASH_SIG_VERIFY, + payload, i, CMD_CASUAL, (uint32_t *) dst_addr, + &resp_len); + + memset((void *)&fcs_ecdsa_hash_sig_verify_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; +} + 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, diff --git a/plat/intel/soc/common/socfpga_sip_svc.c b/plat/intel/soc/common/socfpga_sip_svc.c index 7e9e561f2..6842de7ca 100644 --- a/plat/intel/soc/common/socfpga_sip_svc.c +++ b/plat/intel/soc/common/socfpga_sip_svc.c @@ -937,6 +937,19 @@ uintptr_t sip_smc_handler(uint32_t smc_fid, x4, x5, (uint32_t *) &x6, &mbox_error); SMC_RET4(handle, status, mbox_error, x5, x6); + case INTEL_SIP_SMC_FCS_ECDSA_HASH_SIG_VERIFY_INIT: + x5 = SMC_GET_GP(handle, CTX_GPREG_X5); + status = intel_fcs_ecdsa_hash_sig_verify_init(x1, x2, x3, + x4, x5, &mbox_error); + SMC_RET2(handle, status, mbox_error); + + case INTEL_SIP_SMC_FCS_ECDSA_HASH_SIG_VERIFY_FINALIZE: + x5 = SMC_GET_GP(handle, CTX_GPREG_X5); + x6 = SMC_GET_GP(handle, CTX_GPREG_X6); + status = intel_fcs_ecdsa_hash_sig_verify_finalize(x1, x2, x3, + x4, x5, (uint32_t *) &x6, &mbox_error); + SMC_RET4(handle, status, mbox_error, x5, x6); + case INTEL_SIP_SMC_FCS_ECDSA_SHA2_DATA_SIG_VERIFY_INIT: x5 = SMC_GET_GP(handle, CTX_GPREG_X5); status = intel_fcs_ecdsa_sha2_data_sig_verify_init(x1, x2, x3, From b703facaaae1e3fe5afa4742b436bb07e065b5e9 Mon Sep 17 00:00:00 2001 From: Sieu Mun Tang Date: Wed, 11 May 2022 10:23:13 +0800 Subject: [PATCH 21/28] feat(intel): update to support maximum response data size Update to support maximum (4092 bytes) response data size. And, clean up the intel_smc_service_completed function to directly write the response data to addr to avoid additional copy. Signed-off-by: Siew Chin Lim Signed-off-by: Boon Khai Ng Signed-off-by: Sieu Mun Tang Change-Id: I0a230e73c563d22e6999ad3473587b07382dacfe --- .../soc/common/include/socfpga_sip_svc.h | 5 +- plat/intel/soc/common/socfpga_sip_svc.c | 57 ++++++++++--------- 2 files changed, 34 insertions(+), 28 deletions(-) diff --git a/plat/intel/soc/common/include/socfpga_sip_svc.h b/plat/intel/soc/common/include/socfpga_sip_svc.h index 9c5088bae..9591983f3 100644 --- a/plat/intel/soc/common/include/socfpga_sip_svc.h +++ b/plat/intel/soc/common/include/socfpga_sip_svc.h @@ -61,7 +61,7 @@ #define INTEL_SIP_SMC_ECC_DBE 0xC200000D /* Generic Command */ -#define INTEL_SIP_SMC_MBOX_SEND_CMD 0xC200001E +#define INTEL_SIP_SMC_SERVICE_COMPLETED 0xC200001E #define INTEL_SIP_SMC_FIRMWARE_VERSION 0xC200001F #define INTEL_SIP_SMC_HPS_SET_BRIDGES 0xC2000032 #define INTEL_SIP_SMC_GET_ROM_PATCH_SHA384 0xC2000040 @@ -69,6 +69,7 @@ #define SERVICE_COMPLETED_MODE_ASYNC 0x00004F4E /* Mailbox Command */ +#define INTEL_SIP_SMC_MBOX_SEND_CMD 0xC200003C #define INTEL_SIP_SMC_GET_USERCODE 0xC200003D /* FPGA Crypto Services */ @@ -78,7 +79,7 @@ #define INTEL_SIP_SMC_FCS_CRYPTION_EXT 0xC2000090 #define INTEL_SIP_SMC_FCS_SERVICE_REQUEST 0x4200005C #define INTEL_SIP_SMC_FCS_SEND_CERTIFICATE 0x4200005D -#define INTEL_SIP_SMC_FCS_GET_PROVISION_DATA 0xC200005E +#define INTEL_SIP_SMC_FCS_GET_PROVISION_DATA 0x4200005E #define INTEL_SIP_SMC_FCS_CNTR_SET_PREAUTH 0xC200005F #define INTEL_SIP_SMC_FCS_PSGSIGMA_TEARDOWN 0xC2000064 #define INTEL_SIP_SMC_FCS_CHIP_ID 0xC2000065 diff --git a/plat/intel/soc/common/socfpga_sip_svc.c b/plat/intel/soc/common/socfpga_sip_svc.c index 6842de7ca..f1f4a5a8b 100644 --- a/plat/intel/soc/common/socfpga_sip_svc.c +++ b/plat/intel/soc/common/socfpga_sip_svc.c @@ -542,32 +542,6 @@ static int intel_smc_get_usercode(uint32_t *user_code) return INTEL_SIP_SMC_STATUS_OK; } -/* Miscellaneous HPS services */ -uint32_t intel_hps_set_bridges(uint64_t enable, uint64_t mask) -{ - int status = 0; - - if (enable & SOCFPGA_BRIDGE_ENABLE) { - if ((enable & SOCFPGA_BRIDGE_HAS_MASK) != 0) { - status = socfpga_bridges_enable((uint32_t)mask); - } else { - status = socfpga_bridges_enable(~0); - } - } else { - if ((enable & SOCFPGA_BRIDGE_HAS_MASK) != 0) { - status = socfpga_bridges_disable((uint32_t)mask); - } else { - status = socfpga_bridges_disable(~0); - } - } - - if (status < 0) { - return INTEL_SIP_SMC_STATUS_ERROR; - } - - return INTEL_SIP_SMC_STATUS_OK; -} - uint32_t intel_smc_service_completed(uint64_t addr, uint32_t size, uint32_t mode, uint32_t *job_id, uint32_t *ret_size, uint32_t *mbox_error) @@ -614,6 +588,32 @@ uint32_t intel_smc_service_completed(uint64_t addr, uint32_t size, return INTEL_SIP_SMC_STATUS_OK; } +/* Miscellaneous HPS services */ +uint32_t intel_hps_set_bridges(uint64_t enable, uint64_t mask) +{ + int status = 0; + + if (enable & SOCFPGA_BRIDGE_ENABLE) { + if ((enable & SOCFPGA_BRIDGE_HAS_MASK) != 0) { + status = socfpga_bridges_enable((uint32_t)mask); + } else { + status = socfpga_bridges_enable(~0); + } + } else { + if ((enable & SOCFPGA_BRIDGE_HAS_MASK) != 0) { + status = socfpga_bridges_disable((uint32_t)mask); + } else { + status = socfpga_bridges_disable(~0); + } + } + + if (status < 0) { + return INTEL_SIP_SMC_STATUS_ERROR; + } + + return INTEL_SIP_SMC_STATUS_OK; +} + /* * This function is responsible for handling all SiP calls from the NS world */ @@ -757,6 +757,11 @@ uintptr_t sip_smc_handler(uint32_t smc_fid, status = intel_ecc_dbe_notification(x1); SMC_RET1(handle, status); + case INTEL_SIP_SMC_SERVICE_COMPLETED: + status = intel_smc_service_completed(x1, x2, x3, &rcv_id, + &len_in_resp, &mbox_error); + SMC_RET4(handle, status, mbox_error, x1, len_in_resp); + case INTEL_SIP_SMC_FIRMWARE_VERSION: status = intel_smc_fw_version(&retval); SMC_RET2(handle, status, retval); From fe5637f27aebfdab42915c2ced2c34d8685ee2bb Mon Sep 17 00:00:00 2001 From: Boon Khai Ng Date: Mon, 30 Aug 2021 15:05:49 +0800 Subject: [PATCH 22/28] fix(intel): update certificate mask for FPGA Attestation Update the certificate mask to 0xff to cover all certificate in Agilex family. Signed-off-by: Boon Khai Ng Signed-off-by: Sieu Mun Tang Change-Id: Id40bc3aa4b3e4f7568a58581bbb03a75b0f20a0b --- plat/intel/soc/common/include/socfpga_fcs.h | 11 ++--- plat/intel/soc/common/sip/socfpga_sip_fcs.c | 50 ++++++++++++--------- 2 files changed, 34 insertions(+), 27 deletions(-) diff --git a/plat/intel/soc/common/include/socfpga_fcs.h b/plat/intel/soc/common/include/socfpga_fcs.h index 6b1f1608c..3a71b4f34 100644 --- a/plat/intel/soc/common/include/socfpga_fcs.h +++ b/plat/intel/soc/common/include/socfpga_fcs.h @@ -48,11 +48,12 @@ /* 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_ATTEST_FIRMWARE_CERT 0x01 +#define FCS_ATTEST_DEV_ID_SELF_SIGN_CERT 0x02 +#define FCS_ATTEST_DEV_ID_ENROLL_CERT 0x04 +#define FCS_ATTEST_ENROLL_SELF_SIGN_CERT 0x08 +#define FCS_ATTEST_ALIAS_CERT 0x10 +#define FCS_ATTEST_CERT_MAX_REQ_PARAM 0xFF /* FCS Crypto Service */ diff --git a/plat/intel/soc/common/sip/socfpga_sip_fcs.c b/plat/intel/soc/common/sip/socfpga_sip_fcs.c index 35dd2c58c..2342e45c9 100644 --- a/plat/intel/soc/common/sip/socfpga_sip_fcs.c +++ b/plat/intel/soc/common/sip/socfpga_sip_fcs.c @@ -569,13 +569,8 @@ int intel_fcs_get_attestation_cert(uint32_t cert_request, uint64_t dst_addr, return INTEL_SIP_SMC_STATUS_REJECTED; } - if (cert_request < FCS_ALIAS_CERT || - cert_request > - (FCS_ALIAS_CERT | - FCS_DEV_ID_SELF_SIGN_CERT | - FCS_DEV_ID_ENROLL_CERT | - FCS_ENROLL_SELF_SIGN_CERT | - FCS_PLAT_KEY_CERT)) { + if (cert_request < FCS_ATTEST_FIRMWARE_CERT || + cert_request > FCS_ATTEST_CERT_MAX_REQ_PARAM) { return INTEL_SIP_SMC_STATUS_REJECTED; } @@ -607,13 +602,8 @@ int intel_fcs_create_cert_on_reload(uint32_t cert_request, return INTEL_SIP_SMC_STATUS_REJECTED; } - if (cert_request < FCS_ALIAS_CERT || - cert_request > - (FCS_ALIAS_CERT | - FCS_DEV_ID_SELF_SIGN_CERT | - FCS_DEV_ID_ENROLL_CERT | - FCS_ENROLL_SELF_SIGN_CERT | - FCS_PLAT_KEY_CERT)) { + if (cert_request < FCS_ATTEST_FIRMWARE_CERT || + cert_request > FCS_ATTEST_CERT_MAX_REQ_PARAM) { return INTEL_SIP_SMC_STATUS_REJECTED; } @@ -859,7 +849,7 @@ int intel_fcs_get_digest_finalize(uint32_t session_id, uint32_t context_id, { int status; uint32_t i; - uint32_t resp_len = *dst_size / MBOX_WORD_BYTE; + uint32_t resp_len; uint32_t payload[FCS_GET_DIGEST_CMD_MAX_WORD_SIZE] = {0U}; if (dst_size == NULL || mbox_error == NULL) { @@ -881,6 +871,8 @@ int intel_fcs_get_digest_finalize(uint32_t session_id, uint32_t context_id, return INTEL_SIP_SMC_STATUS_REJECTED; } + resp_len = *dst_size / MBOX_WORD_BYTE; + /* Prepare command payload */ i = 0; /* Crypto header */ @@ -944,7 +936,7 @@ int intel_fcs_mac_verify_finalize(uint32_t session_id, uint32_t context_id, { int status; uint32_t i; - uint32_t resp_len = *dst_size / MBOX_WORD_BYTE; + uint32_t resp_len; uint32_t payload[FCS_MAC_VERIFY_CMD_MAX_WORD_SIZE] = {0U}; uintptr_t mac_offset; @@ -971,6 +963,8 @@ int intel_fcs_mac_verify_finalize(uint32_t session_id, uint32_t context_id, return INTEL_SIP_SMC_STATUS_REJECTED; } + resp_len = *dst_size / MBOX_WORD_BYTE; + /* Prepare command payload */ i = 0; /* Crypto header */ @@ -1040,7 +1034,7 @@ int intel_fcs_ecdsa_hash_sign_finalize(uint32_t session_id, uint32_t context_id, int status; uint32_t i; uint32_t payload[FCS_ECDSA_HASH_SIGN_CMD_MAX_WORD_SIZE] = {0U}; - uint32_t resp_len = *dst_size / MBOX_WORD_BYTE; + uint32_t resp_len; uintptr_t hash_data_addr; if ((dst_size == NULL) || (mbox_error == NULL)) { @@ -1057,6 +1051,8 @@ int intel_fcs_ecdsa_hash_sign_finalize(uint32_t session_id, uint32_t context_id, return INTEL_SIP_SMC_STATUS_REJECTED; } + resp_len = *dst_size / MBOX_WORD_BYTE; + /* Prepare command payload */ /* Crypto header */ i = 0; @@ -1122,7 +1118,7 @@ int intel_fcs_ecdsa_hash_sig_verify_finalize(uint32_t session_id, uint32_t conte int status; uint32_t i = 0; uint32_t payload[FCS_ECDSA_HASH_SIG_VERIFY_CMD_MAX_WORD_SIZE] = {0U}; - uint32_t resp_len = *dst_size / MBOX_WORD_BYTE; + uint32_t resp_len; uintptr_t hash_sig_pubkey_addr; if ((dst_size == NULL) || (mbox_error == NULL)) { @@ -1139,6 +1135,8 @@ int intel_fcs_ecdsa_hash_sig_verify_finalize(uint32_t session_id, uint32_t conte return INTEL_SIP_SMC_STATUS_REJECTED; } + resp_len = *dst_size / MBOX_WORD_BYTE; + /* Prepare command payload */ /* Crypto header */ i = 0; @@ -1207,7 +1205,7 @@ int intel_fcs_ecdsa_sha2_data_sign_finalize(uint32_t session_id, int status; int i; uint32_t payload[FCS_ECDSA_SHA2_DATA_SIGN_CMD_MAX_WORD_SIZE] = {0U}; - uint32_t resp_len = *dst_size / MBOX_WORD_BYTE; + uint32_t resp_len; if ((dst_size == NULL) || (mbox_error == NULL)) { return INTEL_SIP_SMC_STATUS_REJECTED; @@ -1228,6 +1226,8 @@ int intel_fcs_ecdsa_sha2_data_sign_finalize(uint32_t session_id, return INTEL_SIP_SMC_STATUS_REJECTED; } + resp_len = *dst_size / MBOX_WORD_BYTE; + /* Prepare command payload */ /* Crypto header */ i = 0; @@ -1291,7 +1291,7 @@ int intel_fcs_ecdsa_sha2_data_sig_verify_finalize(uint32_t session_id, int status; uint32_t i; uint32_t payload[FCS_ECDSA_SHA2_DATA_SIG_VERIFY_CMD_MAX_WORD_SIZE] = {0U}; - uint32_t resp_len = *dst_size / MBOX_WORD_BYTE; + uint32_t resp_len; uintptr_t sig_pubkey_offset; if ((dst_size == NULL) || (mbox_error == NULL)) { @@ -1317,6 +1317,8 @@ int intel_fcs_ecdsa_sha2_data_sig_verify_finalize(uint32_t session_id, return INTEL_SIP_SMC_STATUS_REJECTED; } + resp_len = *dst_size / MBOX_WORD_BYTE; + /* Prepare command payload */ /* Crypto header */ i = 0; @@ -1384,7 +1386,7 @@ int intel_fcs_ecdsa_get_pubkey_finalize(uint32_t session_id, uint32_t context_id int status; int i; uint32_t crypto_header; - uint32_t ret_size = *dst_size / MBOX_WORD_BYTE; + uint32_t ret_size; uint32_t payload[FCS_ECDSA_GET_PUBKEY_MAX_WORD_SIZE] = {0U}; if ((dst_size == NULL) || (mbox_error == NULL)) { @@ -1396,6 +1398,8 @@ int intel_fcs_ecdsa_get_pubkey_finalize(uint32_t session_id, uint32_t context_id return INTEL_SIP_SMC_STATUS_REJECTED; } + ret_size = *dst_size / MBOX_WORD_BYTE; + crypto_header = ((FCS_CS_FIELD_FLAG_INIT | FCS_CS_FIELD_FLAG_UPDATE | FCS_CS_FIELD_FLAG_FINALIZE) << @@ -1451,7 +1455,7 @@ int intel_fcs_ecdh_request_finalize(uint32_t session_id, uint32_t context_id, int status; uint32_t i; uint32_t payload[FCS_ECDH_REQUEST_CMD_MAX_WORD_SIZE] = {0U}; - uint32_t resp_len = *dst_size / MBOX_WORD_BYTE; + uint32_t resp_len; uintptr_t pubkey; if ((dst_size == NULL) || (mbox_error == NULL)) { @@ -1468,6 +1472,8 @@ int intel_fcs_ecdh_request_finalize(uint32_t session_id, uint32_t context_id, return INTEL_SIP_SMC_STATUS_REJECTED; } + resp_len = *dst_size / MBOX_WORD_BYTE; + /* Prepare command payload */ i = 0; /* Crypto header */ From ad47f1422f3f9aa4a622e08b71fc8f5caab98a98 Mon Sep 17 00:00:00 2001 From: Sieu Mun Tang Date: Wed, 11 May 2022 10:45:19 +0800 Subject: [PATCH 23/28] feat(intel): support version 2 SiP SVC SMC function ID for non-mailbox commands A separated SMC function ID of non-mailbox command is introduced for the new format of SMC protocol. The new format of SMC procotol will be started using by Zephyr. Signed-off-by: Siew Chin Lim Signed-off-by: Sieu Mun Tang Change-Id: I01cff2739364b1bda2ebb9507ddbcef6095f5d29 --- plat/intel/soc/agilex/bl2_plat_setup.c | 2 +- plat/intel/soc/agilex/platform.mk | 1 + .../common/include/socfpga_reset_manager.h | 18 +++---- .../soc/common/include/socfpga_sip_svc.h | 36 ++++++++++++- .../soc/common/soc/socfpga_reset_manager.c | 2 +- plat/intel/soc/common/socfpga_sip_svc.c | 45 +++++++++++----- plat/intel/soc/common/socfpga_sip_svc_v2.c | 53 +++++++++++++++++++ plat/intel/soc/n5x/platform.mk | 1 + plat/intel/soc/stratix10/bl2_plat_setup.c | 4 +- plat/intel/soc/stratix10/platform.mk | 1 + 10 files changed, 137 insertions(+), 26 deletions(-) create mode 100644 plat/intel/soc/common/socfpga_sip_svc_v2.c diff --git a/plat/intel/soc/agilex/bl2_plat_setup.c b/plat/intel/soc/agilex/bl2_plat_setup.c index 7b3b0e26b..211a7b738 100644 --- a/plat/intel/soc/agilex/bl2_plat_setup.c +++ b/plat/intel/soc/agilex/bl2_plat_setup.c @@ -84,7 +84,7 @@ void bl2_el3_early_platform_setup(u_register_t x0, u_register_t x1, if (!intel_mailbox_is_fpga_not_ready()) { socfpga_bridges_enable(SOC2FPGA_MASK | LWHPS2FPGA_MASK | - FPGA2SOC_MASK); + FPGA2SOC_MASK); } } diff --git a/plat/intel/soc/agilex/platform.mk b/plat/intel/soc/agilex/platform.mk index 0e5f91187..6fe0be19d 100644 --- a/plat/intel/soc/agilex/platform.mk +++ b/plat/intel/soc/agilex/platform.mk @@ -65,6 +65,7 @@ BL31_SOURCES += \ plat/intel/soc/agilex/soc/agilex_clock_manager.c \ plat/intel/soc/common/socfpga_psci.c \ plat/intel/soc/common/socfpga_sip_svc.c \ + plat/intel/soc/common/socfpga_sip_svc_v2.c \ plat/intel/soc/common/socfpga_topology.c \ plat/intel/soc/common/sip/socfpga_sip_ecc.c \ plat/intel/soc/common/sip/socfpga_sip_fcs.c \ diff --git a/plat/intel/soc/common/include/socfpga_reset_manager.h b/plat/intel/soc/common/include/socfpga_reset_manager.h index 35ee672bb..cce16ab5d 100644 --- a/plat/intel/soc/common/include/socfpga_reset_manager.h +++ b/plat/intel/soc/common/include/socfpga_reset_manager.h @@ -9,15 +9,15 @@ #include "socfpga_plat_def.h" -#define SOCFPGA_BRIDGE_ENABLE BIT(0) -#define SOCFPGA_BRIDGE_HAS_MASK BIT(1) +#define SOCFPGA_BRIDGE_ENABLE BIT(0) +#define SOCFPGA_BRIDGE_HAS_MASK BIT(1) -#define SOC2FPGA_MASK (1<<0) -#define LWHPS2FPGA_MASK (1<<1) -#define FPGA2SOC_MASK (1<<2) -#define F2SDRAM0_MASK (1<<3) -#define F2SDRAM1_MASK (1<<4) -#define F2SDRAM2_MASK (1<<5) +#define SOC2FPGA_MASK (1<<0) +#define LWHPS2FPGA_MASK (1<<1) +#define FPGA2SOC_MASK (1<<2) +#define F2SDRAM0_MASK (1<<3) +#define F2SDRAM1_MASK (1<<4) +#define F2SDRAM2_MASK (1<<5) /* Register Mapping */ @@ -111,7 +111,7 @@ /* Macros */ #define SOCFPGA_RSTMGR(_reg) (SOCFPGA_RSTMGR_REG_BASE \ - + (SOCFPGA_RSTMGR_##_reg)) + + (SOCFPGA_RSTMGR_##_reg)) #define RSTMGR_FIELD(_reg, _field) (RSTMGR_##_reg##MODRST_##_field) /* Function Declarations */ diff --git a/plat/intel/soc/common/include/socfpga_sip_svc.h b/plat/intel/soc/common/include/socfpga_sip_svc.h index 9591983f3..cc44db50d 100644 --- a/plat/intel/soc/common/include/socfpga_sip_svc.h +++ b/plat/intel/soc/common/include/socfpga_sip_svc.h @@ -19,7 +19,12 @@ /* SiP mailbox error code */ #define GENERIC_RESPONSE_ERROR 0x3FF -/* SMC SiP service function identifier */ +/* SiP V2 command code range */ +#define INTEL_SIP_SMC_CMD_MASK 0xFFFF +#define INTEL_SIP_SMC_CMD_V2_RANGE_BEGIN 0x400 +#define INTEL_SIP_SMC_CMD_V2_RANGE_END 0x4FF + +/* SMC SiP service function identifier for version 1 */ /* FPGA Reconfig */ #define INTEL_SIP_SMC_FPGA_CONFIG_START 0xC2000001 @@ -126,6 +131,18 @@ /* Non-mailbox SMC Call */ #define INTEL_SIP_SMC_SVC_VERSION 0xC2000200 +/** + * SMC SiP service function identifier for version 2 + * Command code from 0x400 ~ 0x4FF + */ + +/* V2: Non-mailbox function identifier */ +#define INTEL_SIP_SMC_V2_GET_SVC_VERSION 0xC2000400 +#define INTEL_SIP_SMC_V2_REG_READ 0xC2000401 +#define INTEL_SIP_SMC_V2_REG_WRITE 0xC2000402 +#define INTEL_SIP_SMC_V2_REG_UPDATE 0xC2000403 +#define INTEL_SIP_SMC_V2_HPS_SET_BRIDGES 0xC2000404 + /* SMC function IDs for SiP Service queries */ #define SIP_SVC_CALL_COUNT 0x8200ff00 #define SIP_SVC_UID 0x8200ff01 @@ -154,7 +171,24 @@ bool is_address_in_ddr_range(uint64_t addr, uint64_t size); bool cold_reset_for_ecc_dbe(void); uint32_t intel_ecc_dbe_notification(uint64_t dbe_value); +/* Secure register access */ +uint32_t intel_secure_reg_read(uint64_t reg_addr, uint32_t *retval); +uint32_t intel_secure_reg_write(uint64_t reg_addr, uint32_t val, + uint32_t *retval); +uint32_t intel_secure_reg_update(uint64_t reg_addr, uint32_t mask, + uint32_t val, uint32_t *retval); + /* Miscellaneous HPS services */ uint32_t intel_hps_set_bridges(uint64_t enable, uint64_t mask); +/* SiP Service handler for version 2 */ +uintptr_t sip_smc_handler_v2(uint32_t smc_fid, + u_register_t x1, + u_register_t x2, + u_register_t x3, + u_register_t x4, + void *cookie, + void *handle, + u_register_t flags); + #endif /* SOCFPGA_SIP_SVC_H */ diff --git a/plat/intel/soc/common/soc/socfpga_reset_manager.c b/plat/intel/soc/common/soc/socfpga_reset_manager.c index c2d55356c..bb4efab93 100644 --- a/plat/intel/soc/common/soc/socfpga_reset_manager.c +++ b/plat/intel/soc/common/soc/socfpga_reset_manager.c @@ -4,9 +4,9 @@ * SPDX-License-Identifier: BSD-3-Clause */ +#include #include #include -#include #include #include "socfpga_f2sdram_manager.h" diff --git a/plat/intel/soc/common/socfpga_sip_svc.c b/plat/intel/soc/common/socfpga_sip_svc.c index f1f4a5a8b..e7344cbaa 100644 --- a/plat/intel/soc/common/socfpga_sip_svc.c +++ b/plat/intel/soc/common/socfpga_sip_svc.c @@ -593,14 +593,14 @@ uint32_t intel_hps_set_bridges(uint64_t enable, uint64_t mask) { int status = 0; - if (enable & SOCFPGA_BRIDGE_ENABLE) { - if ((enable & SOCFPGA_BRIDGE_HAS_MASK) != 0) { + if ((enable & SOCFPGA_BRIDGE_ENABLE) != 0U) { + if ((enable & SOCFPGA_BRIDGE_HAS_MASK) != 0U) { status = socfpga_bridges_enable((uint32_t)mask); } else { status = socfpga_bridges_enable(~0); } } else { - if ((enable & SOCFPGA_BRIDGE_HAS_MASK) != 0) { + if ((enable & SOCFPGA_BRIDGE_HAS_MASK) != 0U) { status = socfpga_bridges_disable((uint32_t)mask); } else { status = socfpga_bridges_disable(~0); @@ -618,7 +618,7 @@ uint32_t intel_hps_set_bridges(uint64_t enable, uint64_t mask) * This function is responsible for handling all SiP calls from the NS world */ -uintptr_t sip_smc_handler(uint32_t smc_fid, +uintptr_t sip_smc_handler_v1(uint32_t smc_fid, u_register_t x1, u_register_t x2, u_register_t x3, @@ -835,6 +835,14 @@ uintptr_t sip_smc_handler(uint32_t smc_fid, status = intel_hps_set_bridges(x1, x2); SMC_RET1(handle, status); + case INTEL_SIP_SMC_HWMON_READTEMP: + status = intel_hwmon_readtemp(x1, &retval); + SMC_RET2(handle, status, retval); + + case INTEL_SIP_SMC_HWMON_READVOLT: + status = intel_hwmon_readvolt(x1, &retval); + SMC_RET2(handle, status, retval); + case INTEL_SIP_SMC_FCS_PSGSIGMA_TEARDOWN: status = intel_fcs_sigma_teardown(x1, &mbox_error); SMC_RET2(handle, status, mbox_error); @@ -1016,20 +1024,33 @@ uintptr_t sip_smc_handler(uint32_t smc_fid, SIP_SVC_VERSION_MAJOR, SIP_SVC_VERSION_MINOR); - case INTEL_SIP_SMC_HWMON_READTEMP: - status = intel_hwmon_readtemp(x1, &retval); - SMC_RET2(handle, status, retval); - - case INTEL_SIP_SMC_HWMON_READVOLT: - status = intel_hwmon_readvolt(x1, &retval); - SMC_RET2(handle, status, retval); - default: return socfpga_sip_handler(smc_fid, x1, x2, x3, x4, cookie, handle, flags); } } +uintptr_t sip_smc_handler(uint32_t smc_fid, + u_register_t x1, + u_register_t x2, + u_register_t x3, + u_register_t x4, + void *cookie, + void *handle, + u_register_t flags) +{ + uint32_t cmd = smc_fid & INTEL_SIP_SMC_CMD_MASK; + + if (cmd >= INTEL_SIP_SMC_CMD_V2_RANGE_BEGIN && + cmd <= INTEL_SIP_SMC_CMD_V2_RANGE_END) { + return sip_smc_handler_v2(smc_fid, x1, x2, x3, x4, + cookie, handle, flags); + } else { + return sip_smc_handler_v1(smc_fid, x1, x2, x3, x4, + cookie, handle, flags); + } +} + DECLARE_RT_SVC( socfpga_sip_svc, OEN_SIP_START, diff --git a/plat/intel/soc/common/socfpga_sip_svc_v2.c b/plat/intel/soc/common/socfpga_sip_svc_v2.c new file mode 100644 index 000000000..d1d19920a --- /dev/null +++ b/plat/intel/soc/common/socfpga_sip_svc_v2.c @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2022, Intel Corporation. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include +#include + +#include "socfpga_sip_svc.h" + +uintptr_t sip_smc_handler_v2(uint32_t smc_fid, + u_register_t x1, + u_register_t x2, + u_register_t x3, + u_register_t x4, + void *cookie, + void *handle, + u_register_t flags) +{ + uint32_t retval = 0; + int status = INTEL_SIP_SMC_STATUS_OK; + + switch (smc_fid) { + case INTEL_SIP_SMC_V2_GET_SVC_VERSION: + SMC_RET4(handle, INTEL_SIP_SMC_STATUS_OK, x1, + SIP_SVC_VERSION_MAJOR, + SIP_SVC_VERSION_MINOR); + + case INTEL_SIP_SMC_V2_REG_READ: + status = intel_secure_reg_read(x2, &retval); + SMC_RET4(handle, status, x1, retval, x2); + + case INTEL_SIP_SMC_V2_REG_WRITE: + status = intel_secure_reg_write(x2, (uint32_t)x3, &retval); + SMC_RET4(handle, status, x1, retval, x2); + + case INTEL_SIP_SMC_V2_REG_UPDATE: + status = intel_secure_reg_update(x2, (uint32_t)x3, + (uint32_t)x4, &retval); + SMC_RET4(handle, status, x1, retval, x2); + + case INTEL_SIP_SMC_V2_HPS_SET_BRIDGES: + status = intel_hps_set_bridges(x2, x3); + SMC_RET2(handle, status, x1); + + default: + ERROR("%s: unhandled SMC V2 (0x%x)\n", __func__, smc_fid); + SMC_RET1(handle, SMC_UNK); + } +} diff --git a/plat/intel/soc/n5x/platform.mk b/plat/intel/soc/n5x/platform.mk index b72bcc41a..953bf0caf 100644 --- a/plat/intel/soc/n5x/platform.mk +++ b/plat/intel/soc/n5x/platform.mk @@ -38,6 +38,7 @@ BL31_SOURCES += \ plat/intel/soc/n5x/bl31_plat_setup.c \ plat/intel/soc/common/socfpga_psci.c \ plat/intel/soc/common/socfpga_sip_svc.c \ + plat/intel/soc/common/socfpga_sip_svc_v2.c \ plat/intel/soc/common/socfpga_topology.c \ plat/intel/soc/common/sip/socfpga_sip_ecc.c \ plat/intel/soc/common/sip/socfpga_sip_fcs.c \ diff --git a/plat/intel/soc/stratix10/bl2_plat_setup.c b/plat/intel/soc/stratix10/bl2_plat_setup.c index 92d827af0..73e3216aa 100644 --- a/plat/intel/soc/stratix10/bl2_plat_setup.c +++ b/plat/intel/soc/stratix10/bl2_plat_setup.c @@ -82,8 +82,8 @@ void bl2_el3_early_platform_setup(u_register_t x0, u_register_t x1, if (!intel_mailbox_is_fpga_not_ready()) { socfpga_bridges_enable(SOC2FPGA_MASK | LWHPS2FPGA_MASK | - FPGA2SOC_MASK | F2SDRAM0_MASK | F2SDRAM1_MASK | - F2SDRAM2_MASK); + FPGA2SOC_MASK | F2SDRAM0_MASK | F2SDRAM1_MASK | + F2SDRAM2_MASK); } } diff --git a/plat/intel/soc/stratix10/platform.mk b/plat/intel/soc/stratix10/platform.mk index 273b97532..8b39b6ff8 100644 --- a/plat/intel/soc/stratix10/platform.mk +++ b/plat/intel/soc/stratix10/platform.mk @@ -64,6 +64,7 @@ BL31_SOURCES += \ plat/intel/soc/stratix10/bl31_plat_setup.c \ plat/intel/soc/common/socfpga_psci.c \ plat/intel/soc/common/socfpga_sip_svc.c \ + plat/intel/soc/common/socfpga_sip_svc_v2.c \ plat/intel/soc/common/socfpga_topology.c \ plat/intel/soc/common/sip/socfpga_sip_ecc.c \ plat/intel/soc/common/sip/socfpga_sip_fcs.c \ From c436707bc6eed31ab61408ef40db6063d05f0912 Mon Sep 17 00:00:00 2001 From: Sieu Mun Tang Date: Tue, 10 May 2022 23:26:57 +0800 Subject: [PATCH 24/28] feat(intel): support version 2 SiP SVC SMC function ID for mailbox commands A separated SMC function ID of mailbox command is introduced for the new format of SMC protocol. The new format of SMC procotol will be started using by Zephyr. Signed-off-by: Siew Chin Lim Signed-off-by: Sieu Mun Tang Change-Id: I7996d5054f76c139b5ad55451c373f5669a1017f --- .../soc/common/include/socfpga_mailbox.h | 3 + .../soc/common/include/socfpga_sip_svc.h | 12 ++ plat/intel/soc/common/soc/socfpga_mailbox.c | 8 +- plat/intel/soc/common/socfpga_sip_svc_v2.c | 121 ++++++++++++++++++ 4 files changed, 143 insertions(+), 1 deletion(-) diff --git a/plat/intel/soc/common/include/socfpga_mailbox.h b/plat/intel/soc/common/include/socfpga_mailbox.h index 90b1fa69e..1f4b2a4a0 100644 --- a/plat/intel/soc/common/include/socfpga_mailbox.h +++ b/plat/intel/soc/common/include/socfpga_mailbox.h @@ -113,6 +113,7 @@ #define MBOX_WORD_BYTE 4U #define MBOX_RESP_BUFFER_SIZE 16 #define MBOX_CMD_BUFFER_SIZE 32 +#define MBOX_INC_HEADER_MAX_WORD_SIZE 1024U /* Execution states for HPS_STAGE_NOTIFY */ #define HPS_EXECUTION_STATE_FSBL 0 @@ -213,6 +214,8 @@ int mailbox_send_cmd(uint32_t job_id, uint32_t cmd, uint32_t *args, unsigned int *resp_len); int mailbox_send_cmd_async(uint32_t *job_id, uint32_t cmd, uint32_t *args, unsigned int len, unsigned int indirect); +int mailbox_send_cmd_async_ext(uint32_t header_cmd, uint32_t *args, + unsigned int len); int mailbox_read_response(uint32_t *job_id, uint32_t *response, unsigned int *resp_len); int mailbox_read_response_async(uint32_t *job_id, uint32_t *header, diff --git a/plat/intel/soc/common/include/socfpga_sip_svc.h b/plat/intel/soc/common/include/socfpga_sip_svc.h index cc44db50d..b1be6a688 100644 --- a/plat/intel/soc/common/include/socfpga_sip_svc.h +++ b/plat/intel/soc/common/include/socfpga_sip_svc.h @@ -24,6 +24,14 @@ #define INTEL_SIP_SMC_CMD_V2_RANGE_BEGIN 0x400 #define INTEL_SIP_SMC_CMD_V2_RANGE_END 0x4FF +/* SiP V2 protocol header */ +#define INTEL_SIP_SMC_HEADER_JOB_ID_MASK 0xF +#define INTEL_SIP_SMC_HEADER_JOB_ID_OFFSET 0U +#define INTEL_SIP_SMC_HEADER_CID_MASK 0xF +#define INTEL_SIP_SMC_HEADER_CID_OFFSET 4U +#define INTEL_SIP_SMC_HEADER_VERSION_MASK 0xF +#define INTEL_SIP_SMC_HEADER_VERSION_OFFSET 60U + /* SMC SiP service function identifier for version 1 */ /* FPGA Reconfig */ @@ -143,6 +151,10 @@ #define INTEL_SIP_SMC_V2_REG_UPDATE 0xC2000403 #define INTEL_SIP_SMC_V2_HPS_SET_BRIDGES 0xC2000404 +/* V2: Mailbox function identifier */ +#define INTEL_SIP_SMC_V2_MAILBOX_SEND_COMMAND 0xC2000420 +#define INTEL_SIP_SMC_V2_MAILBOX_POLL_RESPONSE 0xC2000421 + /* SMC function IDs for SiP Service queries */ #define SIP_SVC_CALL_COUNT 0x8200ff00 #define SIP_SVC_UID 0x8200ff01 diff --git a/plat/intel/soc/common/soc/socfpga_mailbox.c b/plat/intel/soc/common/soc/socfpga_mailbox.c index 0f1214731..778d4af3c 100644 --- a/plat/intel/soc/common/soc/socfpga_mailbox.c +++ b/plat/intel/soc/common/soc/socfpga_mailbox.c @@ -236,7 +236,7 @@ int mailbox_read_response_async(unsigned int *job_id, uint32_t *header, /* copy response data to input buffer if applicable */ ret_resp_len = MBOX_RESP_LEN(mailbox_resp_ctr.payload->header); - if (ret_resp_len > 0 && response && resp_len) { + if ((ret_resp_len > 0) && (response == NULL) && resp_len) { if (*resp_len > ret_resp_len) { *resp_len = ret_resp_len; } @@ -385,6 +385,12 @@ int iterate_resp(uint32_t mbox_resp_len, uint32_t *resp_buf, return MBOX_RET_OK; } +int mailbox_send_cmd_async_ext(uint32_t header_cmd, uint32_t *args, + unsigned int len) +{ + return fill_mailbox_circular_buffer(header_cmd, args, len); +} + int mailbox_send_cmd_async(uint32_t *job_id, uint32_t cmd, uint32_t *args, unsigned int len, unsigned int indirect) { diff --git a/plat/intel/soc/common/socfpga_sip_svc_v2.c b/plat/intel/soc/common/socfpga_sip_svc_v2.c index d1d19920a..791c7148b 100644 --- a/plat/intel/soc/common/socfpga_sip_svc_v2.c +++ b/plat/intel/soc/common/socfpga_sip_svc_v2.c @@ -9,8 +9,119 @@ #include #include +#include "socfpga_mailbox.h" #include "socfpga_sip_svc.h" +static uint32_t intel_v2_mbox_send_cmd(uint32_t req_header, + uint32_t *data, uint32_t data_size) +{ + uint32_t value; + uint32_t len; + + if ((data == NULL) || (data_size == 0)) { + return INTEL_SIP_SMC_STATUS_REJECTED; + } + + if (data_size > (MBOX_INC_HEADER_MAX_WORD_SIZE * MBOX_WORD_BYTE)) { + return INTEL_SIP_SMC_STATUS_REJECTED; + } + + if (!is_size_4_bytes_aligned(data_size)) { + return INTEL_SIP_SMC_STATUS_REJECTED; + } + + /* Make sure client id align in SMC SiP V2 header and mailbox header */ + value = (req_header >> INTEL_SIP_SMC_HEADER_CID_OFFSET) & + INTEL_SIP_SMC_HEADER_CID_MASK; + + if (value != MBOX_RESP_CLIENT_ID(data[0])) { + return INTEL_SIP_SMC_STATUS_REJECTED; + } + + /* Make sure job id align in SMC SiP V2 header and mailbox header */ + value = (req_header >> INTEL_SIP_SMC_HEADER_JOB_ID_OFFSET) & + INTEL_SIP_SMC_HEADER_JOB_ID_MASK; + + if (value != MBOX_RESP_JOB_ID(data[0])) { + return INTEL_SIP_SMC_STATUS_REJECTED; + } + + /* + * Make sure data length align in SMC SiP V2 header and + * mailbox header + */ + len = (data_size / MBOX_WORD_BYTE) - 1; + + if (len != MBOX_RESP_LEN(data[0])) { + return INTEL_SIP_SMC_STATUS_REJECTED; + } + + return mailbox_send_cmd_async_ext(data[0], &data[1], len); +} + +static uint32_t intel_v2_mbox_poll_resp(uint64_t req_header, + uint32_t *data, uint32_t *data_size, + uint64_t *resp_header) +{ + int status = 0; + uint32_t resp_len; + uint32_t job_id = 0; + uint32_t client_id = 0; + uint32_t version; + + if ((data == NULL) || (data_size == NULL) || (resp_header == NULL)) { + return INTEL_SIP_SMC_STATUS_REJECTED; + } + + if (!is_size_4_bytes_aligned(*data_size)) { + return INTEL_SIP_SMC_STATUS_REJECTED; + } + + resp_len = (*data_size / MBOX_WORD_BYTE) - 1; + status = mailbox_read_response_async(&job_id, &data[0], &data[1], + &resp_len, 1); + + if (status == MBOX_BUSY) { + status = INTEL_SIP_SMC_STATUS_BUSY; + } else if (status == MBOX_NO_RESPONSE) { + status = INTEL_SIP_SMC_STATUS_NO_RESPONSE; + } else { + *data_size = 0; + + if (resp_len > 0) { + /* + * Fill in the final response length, + * the length include both mailbox header and payload + */ + *data_size = (resp_len + 1) * MBOX_WORD_BYTE; + + /* Extract the client id from mailbox header */ + client_id = MBOX_RESP_CLIENT_ID(data[0]); + } + + /* + * Extract SMC SiP V2 protocol version from + * SMC request header + */ + version = (req_header >> INTEL_SIP_SMC_HEADER_VERSION_OFFSET) & + INTEL_SIP_SMC_HEADER_VERSION_MASK; + + /* Fill in SMC SiP V2 protocol response header */ + *resp_header = 0; + *resp_header |= (((uint64_t)job_id) & + INTEL_SIP_SMC_HEADER_JOB_ID_MASK) << + INTEL_SIP_SMC_HEADER_JOB_ID_OFFSET; + *resp_header |= (((uint64_t)client_id) & + INTEL_SIP_SMC_HEADER_CID_MASK) << + INTEL_SIP_SMC_HEADER_CID_OFFSET; + *resp_header |= (((uint64_t)version) & + INTEL_SIP_SMC_HEADER_VERSION_MASK) << + INTEL_SIP_SMC_HEADER_VERSION_OFFSET; + } + + return status; +} + uintptr_t sip_smc_handler_v2(uint32_t smc_fid, u_register_t x1, u_register_t x2, @@ -21,6 +132,7 @@ uintptr_t sip_smc_handler_v2(uint32_t smc_fid, u_register_t flags) { uint32_t retval = 0; + uint64_t retval64 = 0; int status = INTEL_SIP_SMC_STATUS_OK; switch (smc_fid) { @@ -46,6 +158,15 @@ uintptr_t sip_smc_handler_v2(uint32_t smc_fid, status = intel_hps_set_bridges(x2, x3); SMC_RET2(handle, status, x1); + case INTEL_SIP_SMC_V2_MAILBOX_SEND_COMMAND: + status = intel_v2_mbox_send_cmd(x1, (uint32_t *)x2, x3); + SMC_RET2(handle, status, x1); + + case INTEL_SIP_SMC_V2_MAILBOX_POLL_RESPONSE: + status = intel_v2_mbox_poll_resp(x1, (uint32_t *)x2, + (uint32_t *) &x3, &retval64); + SMC_RET4(handle, status, retval64, x2, x3); + default: ERROR("%s: unhandled SMC V2 (0x%x)\n", __func__, smc_fid); SMC_RET1(handle, SMC_UNK); From dcb144f1fbcef73ddcc448d5ed6134aa279069b6 Mon Sep 17 00:00:00 2001 From: Sieu Mun Tang Date: Thu, 28 Apr 2022 16:15:54 +0800 Subject: [PATCH 25/28] fix(intel): extending to support large file size for AES encryption and decryption This patch is to extend to support large file size for AES encryption and decryption. 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: Ie2ceaf247e0d7082aad84faf399fbd18d129c36a --- plat/intel/soc/common/include/socfpga_fcs.h | 8 +-- .../soc/common/include/socfpga_sip_svc.h | 1 + plat/intel/soc/common/sip/socfpga_sip_fcs.c | 51 ++++++++++++++----- plat/intel/soc/common/socfpga_sip_svc.c | 11 +++- 4 files changed, 52 insertions(+), 19 deletions(-) diff --git a/plat/intel/soc/common/include/socfpga_fcs.h b/plat/intel/soc/common/include/socfpga_fcs.h index 3a71b4f34..8aeb6283f 100644 --- a/plat/intel/soc/common/include/socfpga_fcs.h +++ b/plat/intel/soc/common/include/socfpga_fcs.h @@ -162,6 +162,7 @@ typedef struct fcs_crypto_service_aes_data_t { uint32_t param_size; uint32_t key_id; uint32_t crypto_param[7]; + uint8_t is_updated; } fcs_crypto_service_aes_data; /* Functions Definitions */ @@ -295,9 +296,10 @@ int intel_fcs_ecdh_request_finalize(uint32_t session_id, uint32_t context_id, 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, +int intel_fcs_aes_crypt_update_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, uint8_t is_finalised, uint32_t *send_id); #endif /* SOCFPGA_FCS_H */ diff --git a/plat/intel/soc/common/include/socfpga_sip_svc.h b/plat/intel/soc/common/include/socfpga_sip_svc.h index b1be6a688..41ed8b247 100644 --- a/plat/intel/soc/common/include/socfpga_sip_svc.h +++ b/plat/intel/soc/common/include/socfpga_sip_svc.h @@ -107,6 +107,7 @@ #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_UPDATE 0x42000075 #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 diff --git a/plat/intel/soc/common/sip/socfpga_sip_fcs.c b/plat/intel/soc/common/sip/socfpga_sip_fcs.c index 2342e45c9..a987a6e35 100644 --- a/plat/intel/soc/common/sip/socfpga_sip_fcs.c +++ b/plat/intel/soc/common/sip/socfpga_sip_fcs.c @@ -1534,18 +1534,22 @@ int intel_fcs_aes_crypt_init(uint32_t session_id, uint32_t context_id, memcpy((uint8_t *) fcs_aes_init_payload.crypto_param, (uint8_t *) param_addr, param_size); + fcs_aes_init_payload.is_updated = 0; + *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, +int intel_fcs_aes_crypt_update_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, uint8_t is_finalised, uint32_t *send_id) { int status; int i; + uint32_t flag; uint32_t crypto_header; uint32_t fcs_aes_crypt_payload[FCS_AES_CMD_MAX_WORD_SIZE]; @@ -1572,11 +1576,23 @@ int intel_fcs_aes_crypt_finalize(uint32_t session_id, uint32_t context_id, 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) | + /* Prepare crypto header*/ + flag = 0; + if (fcs_aes_init_payload.is_updated) { + fcs_aes_init_payload.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_aes_init_payload.is_updated = 1; + } + crypto_header = (flag << FCS_CS_FIELD_FLAG_OFFSET) | fcs_aes_init_payload.param_size; + i = 0U; fcs_aes_crypt_payload[i] = session_id; i++; @@ -1584,14 +1600,18 @@ int intel_fcs_aes_crypt_finalize(uint32_t session_id, uint32_t 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); + if ((crypto_header >> FCS_CS_FIELD_FLAG_OFFSET) & + FCS_CS_FIELD_FLAG_INIT) { + fcs_aes_crypt_payload[i] = fcs_aes_init_payload.key_id; + i++; - i += fcs_aes_init_payload.param_size / MBOX_WORD_BYTE; + 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++; @@ -1606,7 +1626,10 @@ int intel_fcs_aes_crypt_finalize(uint32_t session_id, uint32_t context_id, fcs_aes_crypt_payload, i, CMD_INDIRECT); - memset((void *)&fcs_aes_init_payload, 0U, sizeof(fcs_aes_init_payload)); + if (is_finalised != 0U) { + memset((void *)&fcs_aes_init_payload, 0, + sizeof(fcs_aes_init_payload)); + } if (status < 0U) { return INTEL_SIP_SMC_STATUS_ERROR; diff --git a/plat/intel/soc/common/socfpga_sip_svc.c b/plat/intel/soc/common/socfpga_sip_svc.c index e7344cbaa..8f1f1a9e8 100644 --- a/plat/intel/soc/common/socfpga_sip_svc.c +++ b/plat/intel/soc/common/socfpga_sip_svc.c @@ -1007,11 +1007,18 @@ uintptr_t sip_smc_handler_v1(uint32_t smc_fid, &mbox_error); SMC_RET2(handle, status, mbox_error); + case INTEL_SIP_SMC_FCS_AES_CRYPT_UPDATE: + x5 = SMC_GET_GP(handle, CTX_GPREG_X5); + x6 = SMC_GET_GP(handle, CTX_GPREG_X6); + status = intel_fcs_aes_crypt_update_finalize(x1, x2, x3, x4, + x5, x6, false, &send_id); + SMC_RET1(handle, status); + 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); + status = intel_fcs_aes_crypt_update_finalize(x1, x2, x3, x4, + x5, x6, true, &send_id); SMC_RET1(handle, status); case INTEL_SIP_SMC_GET_ROM_PATCH_SHA384: From 1d97dd74cd128edd7ad45b725603444333c7b262 Mon Sep 17 00:00:00 2001 From: Sieu Mun Tang Date: Thu, 28 Apr 2022 16:23:20 +0800 Subject: [PATCH 26/28] 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: From 70a7e6af958f3541476a8de6baac8e376fcc67f9 Mon Sep 17 00:00:00 2001 From: Sieu Mun Tang Date: Thu, 28 Apr 2022 16:28:48 +0800 Subject: [PATCH 27/28] fix(intel): extending to support large file size for SHA2/HMAC get digest and verifying This patch is to extend to support large file size for SHA2/HMAC get digest and verifying. The large file will be split into smaller chunk and send using initialize, update and finalize staging method. Signed-off-by: Yuslaimi, Alif Zakuan Signed-off-by: Sieu Mun Tang Change-Id: I1815deeb61287b32c3e77c5ac1b547b79ef12674 --- plat/intel/soc/common/include/socfpga_fcs.h | 9 +- .../soc/common/include/socfpga_sip_svc.h | 2 + plat/intel/soc/common/sip/socfpga_sip_fcs.c | 143 ++++++++++++------ plat/intel/soc/common/socfpga_sip_svc.c | 27 +++- 4 files changed, 128 insertions(+), 53 deletions(-) diff --git a/plat/intel/soc/common/include/socfpga_fcs.h b/plat/intel/soc/common/include/socfpga_fcs.h index 37456bc45..893551de3 100644 --- a/plat/intel/soc/common/include/socfpga_fcs.h +++ b/plat/intel/soc/common/include/socfpga_fcs.h @@ -231,18 +231,19 @@ int intel_fcs_get_crypto_service_key_info(uint32_t session_id, uint32_t key_id, 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, +int intel_fcs_get_digest_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); + uint8_t is_finalised, uint32_t *mbox_error); int intel_fcs_mac_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_mac_verify_finalize(uint32_t session_id, uint32_t context_id, +int intel_fcs_mac_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); + uint32_t data_size, uint8_t is_finalised, + uint32_t *mbox_error); int intel_fcs_ecdsa_hash_sign_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 36ba4aa4d..f9a6ffdec 100644 --- a/plat/intel/soc/common/include/socfpga_sip_svc.h +++ b/plat/intel/soc/common/include/socfpga_sip_svc.h @@ -110,8 +110,10 @@ #define INTEL_SIP_SMC_FCS_AES_CRYPT_UPDATE 0x42000075 #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_UPDATE 0xC2000078 #define INTEL_SIP_SMC_FCS_GET_DIGEST_FINALIZE 0xC2000079 #define INTEL_SIP_SMC_FCS_MAC_VERIFY_INIT 0xC200007A +#define INTEL_SIP_SMC_FCS_MAC_VERIFY_UPDATE 0xC200007B #define INTEL_SIP_SMC_FCS_MAC_VERIFY_FINALIZE 0xC200007C #define INTEL_SIP_SMC_FCS_ECDSA_HASH_SIGN_INIT 0xC200007D #define INTEL_SIP_SMC_FCS_ECDSA_HASH_SIGN_FINALIZE 0xC200007F diff --git a/plat/intel/soc/common/sip/socfpga_sip_fcs.c b/plat/intel/soc/common/sip/socfpga_sip_fcs.c index 8e223866c..c4e30a240 100644 --- a/plat/intel/soc/common/sip/socfpga_sip_fcs.c +++ b/plat/intel/soc/common/sip/socfpga_sip_fcs.c @@ -844,13 +844,16 @@ int intel_fcs_get_digest_init(uint32_t session_id, uint32_t context_id, 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, +int intel_fcs_get_digest_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, uint8_t is_finalised, uint32_t *mbox_error) { int status; uint32_t i; + uint32_t flag; + uint32_t crypto_header; uint32_t resp_len; uint32_t payload[FCS_GET_DIGEST_CMD_MAX_WORD_SIZE] = {0U}; @@ -875,29 +878,48 @@ int intel_fcs_get_digest_finalize(uint32_t session_id, uint32_t context_id, resp_len = *dst_size / MBOX_WORD_BYTE; + /* Prepare crypto header */ + flag = 0; + + if (fcs_sha_get_digest_param.is_updated) { + fcs_sha_get_digest_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_sha_get_digest_param.is_updated = 1; + } + + crypto_header = ((flag << FCS_CS_FIELD_FLAG_OFFSET) | + (fcs_sha_get_digest_param.crypto_param_size & + FCS_CS_FIELD_SIZE_MASK)); + /* 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; + payload[i] = crypto_header; i++; + + if ((crypto_header >> FCS_CS_FIELD_FLAG_OFFSET) & + FCS_CS_FIELD_FLAG_INIT) { + 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++; @@ -908,7 +930,10 @@ int intel_fcs_get_digest_finalize(uint32_t session_id, uint32_t context_id, payload, i, CMD_CASUAL, (uint32_t *) dst_addr, &resp_len); - memset((void *)&fcs_sha_get_digest_param, 0, sizeof(fcs_crypto_service_data)); + if (is_finalised != 0U) { + memset((void *)&fcs_sha_get_digest_param, 0, + sizeof(fcs_crypto_service_data)); + } if (status < 0) { *mbox_error = -status; @@ -931,13 +956,16 @@ int intel_fcs_mac_verify_init(uint32_t session_id, uint32_t context_id, mbox_error); } -int intel_fcs_mac_verify_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) +int intel_fcs_mac_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, + uint8_t is_finalised, uint32_t *mbox_error) { int status; uint32_t i; + uint32_t flag; + uint32_t crypto_header; uint32_t resp_len; uint32_t payload[FCS_MAC_VERIFY_CMD_MAX_WORD_SIZE] = {0U}; uintptr_t mac_offset; @@ -967,45 +995,70 @@ int intel_fcs_mac_verify_finalize(uint32_t session_id, uint32_t context_id, resp_len = *dst_size / MBOX_WORD_BYTE; + /* Prepare crypto header */ + flag = 0; + + if (fcs_sha_mac_verify_param.is_updated) { + fcs_sha_mac_verify_param.crypto_param_size = 0; + } else { + flag |= FCS_CS_FIELD_FLAG_INIT; + } + + if (is_finalised) { + flag |= FCS_CS_FIELD_FLAG_FINALIZE; + } else { + flag |= FCS_CS_FIELD_FLAG_UPDATE; + fcs_sha_mac_verify_param.is_updated = 1; + } + + crypto_header = ((flag << FCS_CS_FIELD_FLAG_OFFSET) | + (fcs_sha_mac_verify_param.crypto_param_size & + FCS_CS_FIELD_SIZE_MASK)); + /* Prepare command payload */ i = 0; - /* Crypto header */ payload[i] = fcs_sha_mac_verify_param.session_id; i++; payload[i] = fcs_sha_mac_verify_param.context_id; i++; - payload[i] = fcs_sha_mac_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_sha_mac_verify_param.key_id; - i++; - /* Crypto parameters */ - payload[i] = ((fcs_sha_mac_verify_param.crypto_param - >> INTEL_SIP_SMC_FCS_DIGEST_SIZE_OFFSET) - & INTEL_SIP_SMC_FCS_DIGEST_SIZE_MASK) - << FCS_SHA_HMAC_CRYPTO_PARAM_SIZE_OFFSET; + payload[i] = crypto_header; i++; + + if ((crypto_header >> FCS_CS_FIELD_FLAG_OFFSET) & + FCS_CS_FIELD_FLAG_INIT) { + payload[i] = fcs_sha_mac_verify_param.key_id; + i++; + /* Crypto parameters */ + payload[i] = ((fcs_sha_mac_verify_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] = data_size; i++; - /* Copy mac data to command */ - mac_offset = src_addr + data_size; - memcpy((uint8_t *) &payload[i], (uint8_t *) mac_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) { + /* Copy mac data to command */ + mac_offset = src_addr + data_size; + memcpy((uint8_t *) &payload[i], (uint8_t *) mac_offset, + src_size - data_size); + + i += (src_size - data_size) / MBOX_WORD_BYTE; + } status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_MAC_VERIFY_REQ, payload, i, CMD_CASUAL, (uint32_t *) dst_addr, &resp_len); - memset((void *)&fcs_sha_mac_verify_param, 0, - sizeof(fcs_crypto_service_data)); + if (is_finalised) { + memset((void *)&fcs_sha_mac_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 b2133cc1c..421d59a80 100644 --- a/plat/intel/soc/common/socfpga_sip_svc.c +++ b/plat/intel/soc/common/socfpga_sip_svc.c @@ -903,11 +903,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_GET_DIGEST_UPDATE: + x5 = SMC_GET_GP(handle, CTX_GPREG_X5); + x6 = SMC_GET_GP(handle, CTX_GPREG_X6); + status = intel_fcs_get_digest_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_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); + status = intel_fcs_get_digest_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_MAC_VERIFY_INIT: @@ -916,12 +925,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_MAC_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_mac_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_MAC_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_mac_verify_finalize(x1, x2, x3, - x4, x5, (uint32_t *) &x6, x7, &mbox_error); + status = intel_fcs_mac_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_SHA2_DATA_SIGN_INIT: From ac097fdf07ad63b567ca751dc518f8445a0baef6 Mon Sep 17 00:00:00 2001 From: Sieu Mun Tang Date: Tue, 10 May 2022 23:17:04 +0800 Subject: [PATCH 28/28] fix(intel): add flash dcache after return response for INTEL_SIP_SMC_MBOX_SEND_CMD This patch is to add flash dcache after return response in INTEL_SIP_SMC_MBOX_SEND_CMD. Signed-off-by: Sieu Mun Tang Change-Id: Ie9451e352f2b7c41ebb44a1f6be9da35f4600fb9 --- plat/intel/soc/common/socfpga_sip_svc.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/plat/intel/soc/common/socfpga_sip_svc.c b/plat/intel/soc/common/socfpga_sip_svc.c index 421d59a80..f7dd3929a 100644 --- a/plat/intel/soc/common/socfpga_sip_svc.c +++ b/plat/intel/soc/common/socfpga_sip_svc.c @@ -502,8 +502,7 @@ static uint32_t intel_smc_fw_version(uint32_t *fw_version) } static uint32_t intel_mbox_send_cmd(uint32_t cmd, uint32_t *args, - unsigned int len, - uint32_t urgent, uint32_t *response, + unsigned int len, uint32_t urgent, uint64_t response, unsigned int resp_len, int *mbox_status, unsigned int *len_in_resp) { @@ -515,7 +514,7 @@ static uint32_t intel_mbox_send_cmd(uint32_t cmd, uint32_t *args, } int status = mailbox_send_cmd(MBOX_JOB_ID, cmd, args, len, urgent, - response, &resp_len); + (uint32_t *) response, &resp_len); if (status < 0) { *mbox_status = -status; @@ -524,6 +523,9 @@ static uint32_t intel_mbox_send_cmd(uint32_t cmd, uint32_t *args, *mbox_status = 0; *len_in_resp = resp_len; + + flush_dcache_range(response, resp_len * MBOX_WORD_BYTE); + return INTEL_SIP_SMC_STATUS_OK; } @@ -769,9 +771,8 @@ uintptr_t sip_smc_handler_v1(uint32_t smc_fid, case INTEL_SIP_SMC_MBOX_SEND_CMD: x5 = SMC_GET_GP(handle, CTX_GPREG_X5); x6 = SMC_GET_GP(handle, CTX_GPREG_X6); - status = intel_mbox_send_cmd(x1, (uint32_t *)x2, x3, x4, - (uint32_t *)x5, x6, &mbox_status, - &len_in_resp); + status = intel_mbox_send_cmd(x1, (uint32_t *)x2, x3, x4, x5, x6, + &mbox_status, &len_in_resp); SMC_RET3(handle, status, mbox_status, len_in_resp); case INTEL_SIP_SMC_GET_USERCODE: