1286b96f4SSieu Mun Tang /*
2e264b557SSieu Mun Tang * Copyright (c) 2020-2023, Intel Corporation. All rights reserved.
3597fff5fSGirisha Dengi * Copyright (c) 2024-2025, Altera Corporation. All rights reserved.
4286b96f4SSieu Mun Tang *
5286b96f4SSieu Mun Tang * SPDX-License-Identifier: BSD-3-Clause
6286b96f4SSieu Mun Tang */
7286b96f4SSieu Mun Tang
8286b96f4SSieu Mun Tang #include <arch_helpers.h>
9597fff5fSGirisha Dengi #include <common/debug.h>
10286b96f4SSieu Mun Tang #include <lib/mmio.h>
11286b96f4SSieu Mun Tang
126fcd047bSJit Loon Lim #include "../lib/utils/alignment_utils.h"
13597fff5fSGirisha Dengi #include "socfpga_plat_def.h"
14286b96f4SSieu Mun Tang #include "socfpga_fcs.h"
15286b96f4SSieu Mun Tang #include "socfpga_mailbox.h"
16286b96f4SSieu Mun Tang #include "socfpga_sip_svc.h"
17286b96f4SSieu Mun Tang
187e8249a2SSieu Mun Tang /* FCS static variables */
196726390eSSieu Mun Tang static fcs_crypto_service_aes_data fcs_aes_init_payload;
207e8249a2SSieu Mun Tang static fcs_crypto_service_data fcs_sha_get_digest_param;
21c05ea296SSieu Mun Tang static fcs_crypto_service_data fcs_sha_mac_verify_param;
2269254105SSieu Mun Tang static fcs_crypto_service_data fcs_ecdsa_hash_sign_param;
237e25eb87SSieu Mun Tang static fcs_crypto_service_data fcs_ecdsa_hash_sig_verify_param;
2407912da1SSieu Mun Tang static fcs_crypto_service_data fcs_sha2_data_sign_param;
2558305060SSieu Mun Tang static fcs_crypto_service_data fcs_sha2_data_sig_verify_param;
2658305060SSieu Mun Tang static fcs_crypto_service_data fcs_ecdsa_get_pubkey_param;
2749446866SSieu Mun Tang static fcs_crypto_service_data fcs_ecdh_request_param;
287e8249a2SSieu Mun Tang
fcs_send_cert_cb(void * resp_desc,void * cmd_desc,uint64_t * ret_args)29cdab4018SGirisha Dengi uint8_t fcs_send_cert_cb(void *resp_desc, void *cmd_desc, uint64_t *ret_args)
30597fff5fSGirisha Dengi {
31597fff5fSGirisha Dengi uint8_t ret_args_len = 0U;
32597fff5fSGirisha Dengi sdm_response_t *resp = (sdm_response_t *)resp_desc;
33597fff5fSGirisha Dengi sdm_command_t *cmd = (sdm_command_t *)cmd_desc;
34597fff5fSGirisha Dengi
35597fff5fSGirisha Dengi (void)cmd;
36597fff5fSGirisha Dengi INFO("MBOX: %s: mailbox_err 0x%x, status_word %d\n",
37597fff5fSGirisha Dengi __func__, resp->err_code, resp->resp_data[0]);
38597fff5fSGirisha Dengi
39597fff5fSGirisha Dengi ret_args[ret_args_len++] = INTEL_SIP_SMC_STATUS_OK;
40597fff5fSGirisha Dengi ret_args[ret_args_len++] = resp->err_code;
41597fff5fSGirisha Dengi ret_args[ret_args_len++] = resp->resp_data[0];
42597fff5fSGirisha Dengi
43597fff5fSGirisha Dengi return ret_args_len;
44597fff5fSGirisha Dengi }
45597fff5fSGirisha Dengi
fcs_cntr_set_preauth_cb(void * resp_desc,void * cmd_desc,uint64_t * ret_args)46cdab4018SGirisha Dengi uint8_t fcs_cntr_set_preauth_cb(void *resp_desc, void *cmd_desc, uint64_t *ret_args)
47597fff5fSGirisha Dengi {
48597fff5fSGirisha Dengi uint8_t ret_args_len = 0U;
49597fff5fSGirisha Dengi sdm_response_t *resp = (sdm_response_t *)resp_desc;
50597fff5fSGirisha Dengi sdm_command_t *cmd = (sdm_command_t *)cmd_desc;
51597fff5fSGirisha Dengi
52597fff5fSGirisha Dengi (void)cmd;
53597fff5fSGirisha Dengi INFO("MBOX: %s: mailbox_err 0x%x\n", __func__, resp->err_code);
54597fff5fSGirisha Dengi
55597fff5fSGirisha Dengi ret_args[ret_args_len++] = INTEL_SIP_SMC_STATUS_OK;
56597fff5fSGirisha Dengi ret_args[ret_args_len++] = resp->err_code;
57597fff5fSGirisha Dengi
58597fff5fSGirisha Dengi return ret_args_len;
59597fff5fSGirisha Dengi }
60597fff5fSGirisha Dengi
fcs_get_attest_cert_cb(void * resp_desc,void * cmd_desc,uint64_t * ret_args)61cdab4018SGirisha Dengi uint8_t fcs_get_attest_cert_cb(void *resp_desc, void *cmd_desc, uint64_t *ret_args)
62597fff5fSGirisha Dengi {
63597fff5fSGirisha Dengi uint8_t ret_args_len = 0U;
64597fff5fSGirisha Dengi sdm_response_t *resp = (sdm_response_t *)resp_desc;
65597fff5fSGirisha Dengi sdm_command_t *cmd = (sdm_command_t *)cmd_desc;
66597fff5fSGirisha Dengi
67597fff5fSGirisha Dengi INFO("MBOX: %s: mailbox_err 0x%x, nbytes_ret %d\n",
68597fff5fSGirisha Dengi __func__, resp->err_code, resp->rcvd_resp_len * MBOX_WORD_BYTE);
69597fff5fSGirisha Dengi
70597fff5fSGirisha Dengi ret_args[ret_args_len++] = INTEL_SIP_SMC_STATUS_OK;
71597fff5fSGirisha Dengi ret_args[ret_args_len++] = resp->err_code;
72597fff5fSGirisha Dengi ret_args[ret_args_len++] = resp->rcvd_resp_len * MBOX_WORD_BYTE;
73597fff5fSGirisha Dengi
74cb3ceb53SGirisha Dengi /* Flush the response data buffer. */
75cb3ceb53SGirisha Dengi flush_dcache_range((uintptr_t)cmd->cb_args, resp->rcvd_resp_len * MBOX_WORD_BYTE);
76cb3ceb53SGirisha Dengi
77597fff5fSGirisha Dengi return ret_args_len;
78597fff5fSGirisha Dengi }
79597fff5fSGirisha Dengi
fcs_hkdf_request_cb(void * resp_desc,void * cmd_desc,uint64_t * ret_args)80cdab4018SGirisha Dengi uint8_t fcs_hkdf_request_cb(void *resp_desc, void *cmd_desc, uint64_t *ret_args)
81597fff5fSGirisha Dengi {
82597fff5fSGirisha Dengi uint8_t ret_args_len = 0U;
83597fff5fSGirisha Dengi sdm_response_t *resp = (sdm_response_t *)resp_desc;
84597fff5fSGirisha Dengi sdm_command_t *cmd = (sdm_command_t *)cmd_desc;
85597fff5fSGirisha Dengi
86597fff5fSGirisha Dengi (void)cmd;
87597fff5fSGirisha Dengi
88597fff5fSGirisha Dengi INFO("MBOX: %s: mbox_err 0x%x, hkdf_status 0x%x\n", __func__,
89597fff5fSGirisha Dengi resp->err_code, resp->resp_data[0]);
90597fff5fSGirisha Dengi
91597fff5fSGirisha Dengi ret_args[ret_args_len++] = INTEL_SIP_SMC_STATUS_OK;
92597fff5fSGirisha Dengi ret_args[ret_args_len++] = resp->err_code;
93597fff5fSGirisha Dengi ret_args[ret_args_len++] = resp->resp_data[0];
94597fff5fSGirisha Dengi
95597fff5fSGirisha Dengi return ret_args_len;
96597fff5fSGirisha Dengi }
97597fff5fSGirisha Dengi
fcs_create_cert_reload_cb(void * resp_desc,void * cmd_desc,uint64_t * ret_args)98cdab4018SGirisha Dengi uint8_t fcs_create_cert_reload_cb(void *resp_desc, void *cmd_desc, uint64_t *ret_args)
99597fff5fSGirisha Dengi {
100597fff5fSGirisha Dengi uint8_t ret_args_len = 0U;
101597fff5fSGirisha Dengi sdm_response_t *resp = (sdm_response_t *)resp_desc;
102597fff5fSGirisha Dengi sdm_command_t *cmd = (sdm_command_t *)cmd_desc;
103597fff5fSGirisha Dengi
104597fff5fSGirisha Dengi (void)cmd;
105597fff5fSGirisha Dengi INFO("MBOX: %s: mailbox_err 0x%x\n", __func__, resp->err_code);
106597fff5fSGirisha Dengi
107597fff5fSGirisha Dengi ret_args[ret_args_len++] = INTEL_SIP_SMC_STATUS_OK;
108597fff5fSGirisha Dengi ret_args[ret_args_len++] = resp->err_code;
109597fff5fSGirisha Dengi
110597fff5fSGirisha Dengi return ret_args_len;
111597fff5fSGirisha Dengi }
112597fff5fSGirisha Dengi
fcs_cs_get_digest_cb(void * resp_desc,void * cmd_desc,uint64_t * ret_args)113cdab4018SGirisha Dengi uint8_t fcs_cs_get_digest_cb(void *resp_desc, void *cmd_desc, uint64_t *ret_args)
114597fff5fSGirisha Dengi {
115597fff5fSGirisha Dengi uint8_t ret_args_len = 0U;
116597fff5fSGirisha Dengi sdm_response_t *resp = (sdm_response_t *)resp_desc;
117597fff5fSGirisha Dengi sdm_command_t *cmd = (sdm_command_t *)cmd_desc;
118597fff5fSGirisha Dengi
119597fff5fSGirisha Dengi INFO("MBOX: %s: mbox_err 0x%x, nbytes_ret %d\n", __func__,
120597fff5fSGirisha Dengi resp->err_code, resp->rcvd_resp_len * MBOX_WORD_BYTE);
121597fff5fSGirisha Dengi
122597fff5fSGirisha Dengi ret_args[ret_args_len++] = INTEL_SIP_SMC_STATUS_OK;
123597fff5fSGirisha Dengi ret_args[ret_args_len++] = resp->err_code;
124597fff5fSGirisha Dengi ret_args[ret_args_len++] = resp->rcvd_resp_len * MBOX_WORD_BYTE;
125597fff5fSGirisha Dengi
126cb3ceb53SGirisha Dengi /* Flush the response data buffer. */
127cb3ceb53SGirisha Dengi flush_dcache_range((uintptr_t)cmd->cb_args, resp->rcvd_resp_len * MBOX_WORD_BYTE);
128cb3ceb53SGirisha Dengi
129597fff5fSGirisha Dengi return ret_args_len;
130597fff5fSGirisha Dengi }
131597fff5fSGirisha Dengi
fcs_cs_mac_verify_cb(void * resp_desc,void * cmd_desc,uint64_t * ret_args)132cdab4018SGirisha Dengi uint8_t fcs_cs_mac_verify_cb(void *resp_desc, void *cmd_desc, uint64_t *ret_args)
133597fff5fSGirisha Dengi {
134597fff5fSGirisha Dengi uint8_t ret_args_len = 0U;
135597fff5fSGirisha Dengi sdm_response_t *resp = (sdm_response_t *)resp_desc;
136597fff5fSGirisha Dengi sdm_command_t *cmd = (sdm_command_t *)cmd_desc;
137597fff5fSGirisha Dengi
138597fff5fSGirisha Dengi INFO("MBOX: %s: mbox_err 0x%x, nbytes_ret %d, verify_result 0x%x\n",
139597fff5fSGirisha Dengi __func__, resp->err_code,
140597fff5fSGirisha Dengi resp->rcvd_resp_len * MBOX_WORD_BYTE,
14113630966SMahesh Rao cmd->cb_args[3]);
142597fff5fSGirisha Dengi
143597fff5fSGirisha Dengi ret_args[ret_args_len++] = INTEL_SIP_SMC_STATUS_OK;
144597fff5fSGirisha Dengi ret_args[ret_args_len++] = resp->err_code;
145597fff5fSGirisha Dengi ret_args[ret_args_len++] = resp->rcvd_resp_len * MBOX_WORD_BYTE;
14613630966SMahesh Rao ret_args[ret_args_len++] = cmd->cb_args[3];
14713630966SMahesh Rao
14813630966SMahesh Rao /* Flush the response data buffer. */
14913630966SMahesh Rao flush_dcache_range((uintptr_t)cmd->cb_args, resp->rcvd_resp_len * MBOX_WORD_BYTE);
150597fff5fSGirisha Dengi
151597fff5fSGirisha Dengi return ret_args_len;
152597fff5fSGirisha Dengi }
153597fff5fSGirisha Dengi
fcs_cs_hash_sign_req_cb(void * resp_desc,void * cmd_desc,uint64_t * ret_args)154cdab4018SGirisha Dengi uint8_t fcs_cs_hash_sign_req_cb(void *resp_desc, void *cmd_desc, uint64_t *ret_args)
155597fff5fSGirisha Dengi {
156597fff5fSGirisha Dengi uint8_t ret_args_len = 0U;
157597fff5fSGirisha Dengi sdm_response_t *resp = (sdm_response_t *)resp_desc;
158597fff5fSGirisha Dengi sdm_command_t *cmd = (sdm_command_t *)cmd_desc;
159597fff5fSGirisha Dengi
160597fff5fSGirisha Dengi INFO("MBOX: %s: [0] 0%x, [1] 0x%x, [2] 0x%x, len_words %d\n",
161597fff5fSGirisha Dengi __func__, resp->resp_data[0], resp->resp_data[1],
162597fff5fSGirisha Dengi resp->resp_data[2], resp->rcvd_resp_len);
163597fff5fSGirisha Dengi
164597fff5fSGirisha Dengi ret_args[ret_args_len++] = INTEL_SIP_SMC_STATUS_OK;
165597fff5fSGirisha Dengi ret_args[ret_args_len++] = resp->err_code;
166597fff5fSGirisha Dengi ret_args[ret_args_len++] = resp->rcvd_resp_len * MBOX_WORD_BYTE;
167597fff5fSGirisha Dengi
168cb3ceb53SGirisha Dengi /* Flush the response data buffer. */
169cb3ceb53SGirisha Dengi flush_dcache_range((uintptr_t)cmd->cb_args, resp->rcvd_resp_len * MBOX_WORD_BYTE);
170cb3ceb53SGirisha Dengi
171597fff5fSGirisha Dengi return ret_args_len;
172597fff5fSGirisha Dengi }
173597fff5fSGirisha Dengi
fcs_cs_hash_sig_verify_req_cb(void * resp_desc,void * cmd_desc,uint64_t * ret_args)174cdab4018SGirisha Dengi uint8_t fcs_cs_hash_sig_verify_req_cb(void *resp_desc, void *cmd_desc, uint64_t *ret_args)
175597fff5fSGirisha Dengi {
176597fff5fSGirisha Dengi uint8_t ret_args_len = 0U;
177597fff5fSGirisha Dengi sdm_response_t *resp = (sdm_response_t *)resp_desc;
178597fff5fSGirisha Dengi sdm_command_t *cmd = (sdm_command_t *)cmd_desc;
179597fff5fSGirisha Dengi
180597fff5fSGirisha Dengi INFO("MBOX: %s: [0] 0%x, [1] 0x%x, [2] 0x%x, [3] 0x%x\n",
181597fff5fSGirisha Dengi __func__, resp->resp_data[0], resp->resp_data[1],
182597fff5fSGirisha Dengi resp->resp_data[2], resp->resp_data[3]);
183597fff5fSGirisha Dengi
184597fff5fSGirisha Dengi ret_args[ret_args_len++] = INTEL_SIP_SMC_STATUS_OK;
185597fff5fSGirisha Dengi ret_args[ret_args_len++] = resp->err_code;
186597fff5fSGirisha Dengi ret_args[ret_args_len++] = resp->rcvd_resp_len * MBOX_WORD_BYTE;
187597fff5fSGirisha Dengi
188cb3ceb53SGirisha Dengi /* Flush the response data buffer. */
189cb3ceb53SGirisha Dengi flush_dcache_range((uintptr_t)cmd->cb_args, resp->rcvd_resp_len * MBOX_WORD_BYTE);
190cb3ceb53SGirisha Dengi
191597fff5fSGirisha Dengi return ret_args_len;
192597fff5fSGirisha Dengi }
193597fff5fSGirisha Dengi
fcs_cs_aes_cb(void * resp_desc,void * cmd_desc,uint64_t * ret_args)194cdab4018SGirisha Dengi uint8_t fcs_cs_aes_cb(void *resp_desc, void *cmd_desc, uint64_t *ret_args)
195597fff5fSGirisha Dengi {
196597fff5fSGirisha Dengi uint8_t ret_args_len = 0U;
197*8e476852SGirisha Dengi uint32_t nbytes_ret = 0U;
198597fff5fSGirisha Dengi sdm_response_t *resp = (sdm_response_t *)resp_desc;
199597fff5fSGirisha Dengi sdm_command_t *cmd = (sdm_command_t *)cmd_desc;
200597fff5fSGirisha Dengi
201597fff5fSGirisha Dengi (void)cmd;
202597fff5fSGirisha Dengi
203*8e476852SGirisha Dengi /* Data size written to the destination is always at last index of the response data. */
204*8e476852SGirisha Dengi nbytes_ret = resp->resp_data[resp->rcvd_resp_len - 1];
205*8e476852SGirisha Dengi
206597fff5fSGirisha Dengi INFO("MBOX: %s: mbox_err 0x%x, nbytes_ret %d\n", __func__,
207*8e476852SGirisha Dengi resp->err_code, nbytes_ret);
208597fff5fSGirisha Dengi
209597fff5fSGirisha Dengi ret_args[ret_args_len++] = INTEL_SIP_SMC_STATUS_OK;
210597fff5fSGirisha Dengi ret_args[ret_args_len++] = resp->err_code;
211*8e476852SGirisha Dengi ret_args[ret_args_len++] = nbytes_ret;
212597fff5fSGirisha Dengi
213597fff5fSGirisha Dengi return ret_args_len;
214597fff5fSGirisha Dengi }
215597fff5fSGirisha Dengi
fcs_cs_data_sign_req_cb(void * resp_desc,void * cmd_desc,uint64_t * ret_args)216cdab4018SGirisha Dengi uint8_t fcs_cs_data_sign_req_cb(void *resp_desc, void *cmd_desc, uint64_t *ret_args)
217597fff5fSGirisha Dengi {
218597fff5fSGirisha Dengi uint8_t ret_args_len = 0U;
219597fff5fSGirisha Dengi sdm_response_t *resp = (sdm_response_t *)resp_desc;
220597fff5fSGirisha Dengi sdm_command_t *cmd = (sdm_command_t *)cmd_desc;
221597fff5fSGirisha Dengi
222597fff5fSGirisha Dengi INFO("MBOX: %s: mbox_err 0x%x, nbytes_ret %d\n", __func__,
223597fff5fSGirisha Dengi resp->err_code, resp->rcvd_resp_len * MBOX_WORD_BYTE);
224597fff5fSGirisha Dengi
225597fff5fSGirisha Dengi ret_args[ret_args_len++] = INTEL_SIP_SMC_STATUS_OK;
226597fff5fSGirisha Dengi ret_args[ret_args_len++] = resp->err_code;
227597fff5fSGirisha Dengi ret_args[ret_args_len++] = resp->rcvd_resp_len * MBOX_WORD_BYTE;
228597fff5fSGirisha Dengi
229cb3ceb53SGirisha Dengi /* Flush the response data buffer. */
230cb3ceb53SGirisha Dengi flush_dcache_range((uintptr_t)cmd->cb_args, resp->rcvd_resp_len * MBOX_WORD_BYTE);
231597fff5fSGirisha Dengi return ret_args_len;
232597fff5fSGirisha Dengi }
233597fff5fSGirisha Dengi
fcs_sdos_crypto_request_cb(void * resp_desc,void * cmd_desc,uint64_t * ret_args)234cdab4018SGirisha Dengi uint8_t fcs_sdos_crypto_request_cb(void *resp_desc, void *cmd_desc, uint64_t *ret_args)
235597fff5fSGirisha Dengi {
236597fff5fSGirisha Dengi uint8_t ret_args_len = 0U;
237597fff5fSGirisha Dengi sdm_response_t *resp = (sdm_response_t *)resp_desc;
238597fff5fSGirisha Dengi sdm_command_t *cmd = (sdm_command_t *)cmd_desc;
239597fff5fSGirisha Dengi
240597fff5fSGirisha Dengi (void)cmd;
241597fff5fSGirisha Dengi INFO("MBOX: %s: mailbox_err 0x%x, nbytes_ret %d\n",
242597fff5fSGirisha Dengi __func__, resp->err_code, resp->resp_data[3]);
243597fff5fSGirisha Dengi
244597fff5fSGirisha Dengi ret_args[ret_args_len++] = INTEL_SIP_SMC_STATUS_OK;
245597fff5fSGirisha Dengi ret_args[ret_args_len++] = resp->err_code;
246597fff5fSGirisha Dengi /* Encrypted/Decrypted data size written to the destination buffer */
247597fff5fSGirisha Dengi ret_args[ret_args_len++] = resp->resp_data[3];
248597fff5fSGirisha Dengi
249597fff5fSGirisha Dengi return ret_args_len;
250597fff5fSGirisha Dengi }
251597fff5fSGirisha Dengi
fcs_cs_get_public_key_cb(void * resp_desc,void * cmd_desc,uint64_t * ret_args)252cdab4018SGirisha Dengi uint8_t fcs_cs_get_public_key_cb(void *resp_desc, void *cmd_desc, uint64_t *ret_args)
253597fff5fSGirisha Dengi {
254597fff5fSGirisha Dengi uint8_t ret_args_len = 0U;
255597fff5fSGirisha Dengi sdm_response_t *resp = (sdm_response_t *)resp_desc;
256597fff5fSGirisha Dengi sdm_command_t *cmd = (sdm_command_t *)cmd_desc;
257597fff5fSGirisha Dengi
258597fff5fSGirisha Dengi INFO("MBOX: %s: mbox_err 0x%x, nbytes_ret %u\n",
259597fff5fSGirisha Dengi __func__, resp->err_code,
260597fff5fSGirisha Dengi resp->rcvd_resp_len * MBOX_WORD_BYTE);
261597fff5fSGirisha Dengi
262597fff5fSGirisha Dengi ret_args[ret_args_len++] = INTEL_SIP_SMC_STATUS_OK;
263597fff5fSGirisha Dengi ret_args[ret_args_len++] = resp->err_code;
264597fff5fSGirisha Dengi ret_args[ret_args_len++] = resp->rcvd_resp_len * MBOX_WORD_BYTE;
265597fff5fSGirisha Dengi
266cb3ceb53SGirisha Dengi /* Flush the response data buffer. */
267cb3ceb53SGirisha Dengi flush_dcache_range((uintptr_t)cmd->cb_args, resp->rcvd_resp_len * MBOX_WORD_BYTE);
268cb3ceb53SGirisha Dengi
269597fff5fSGirisha Dengi return ret_args_len;
270597fff5fSGirisha Dengi }
271597fff5fSGirisha Dengi
fcs_cs_data_sig_verify_req_cb(void * resp_desc,void * cmd_desc,uint64_t * ret_args)272cdab4018SGirisha Dengi uint8_t fcs_cs_data_sig_verify_req_cb(void *resp_desc, void *cmd_desc, uint64_t *ret_args)
273597fff5fSGirisha Dengi {
274597fff5fSGirisha Dengi uint8_t ret_args_len = 0U;
275597fff5fSGirisha Dengi sdm_response_t *resp = (sdm_response_t *)resp_desc;
276597fff5fSGirisha Dengi sdm_command_t *cmd = (sdm_command_t *)cmd_desc;
277597fff5fSGirisha Dengi
278597fff5fSGirisha Dengi INFO("MBOX: %s: mbox_err 0x%x, nbytes_ret 0x%x\n",
279597fff5fSGirisha Dengi __func__, resp->err_code, resp->rcvd_resp_len);
280597fff5fSGirisha Dengi
281597fff5fSGirisha Dengi ret_args[ret_args_len++] = INTEL_SIP_SMC_STATUS_OK;
282597fff5fSGirisha Dengi ret_args[ret_args_len++] = resp->err_code;
283597fff5fSGirisha Dengi ret_args[ret_args_len++] = resp->rcvd_resp_len * MBOX_WORD_BYTE;
284597fff5fSGirisha Dengi
285cb3ceb53SGirisha Dengi /* Flush the response data buffer. */
286cb3ceb53SGirisha Dengi flush_dcache_range((uintptr_t)cmd->cb_args, resp->rcvd_resp_len * MBOX_WORD_BYTE);
287cb3ceb53SGirisha Dengi
288597fff5fSGirisha Dengi return ret_args_len;
289597fff5fSGirisha Dengi }
290597fff5fSGirisha Dengi
fcs_cs_ecdh_request_cb(void * resp_desc,void * cmd_desc,uint64_t * ret_args)291cdab4018SGirisha Dengi uint8_t fcs_cs_ecdh_request_cb(void *resp_desc, void *cmd_desc, uint64_t *ret_args)
292597fff5fSGirisha Dengi {
293597fff5fSGirisha Dengi uint8_t ret_args_len = 0U;
294597fff5fSGirisha Dengi sdm_response_t *resp = (sdm_response_t *)resp_desc;
295597fff5fSGirisha Dengi sdm_command_t *cmd = (sdm_command_t *)cmd_desc;
296597fff5fSGirisha Dengi
297597fff5fSGirisha Dengi INFO("MBOX: %s: [0] 0%x, [1] 0x%x, [2] 0x%x, len_words %d\n",
298597fff5fSGirisha Dengi __func__, resp->resp_data[0], resp->resp_data[1],
299597fff5fSGirisha Dengi resp->resp_data[2], resp->rcvd_resp_len);
300597fff5fSGirisha Dengi
301597fff5fSGirisha Dengi ret_args[ret_args_len++] = INTEL_SIP_SMC_STATUS_OK;
302597fff5fSGirisha Dengi ret_args[ret_args_len++] = resp->err_code;
303597fff5fSGirisha Dengi ret_args[ret_args_len++] = resp->rcvd_resp_len * MBOX_WORD_BYTE;
304597fff5fSGirisha Dengi
305cb3ceb53SGirisha Dengi /* Flush the response data buffer. */
306cb3ceb53SGirisha Dengi flush_dcache_range((uintptr_t)cmd->cb_args, resp->rcvd_resp_len * MBOX_WORD_BYTE);
307cb3ceb53SGirisha Dengi
308597fff5fSGirisha Dengi return ret_args_len;
309597fff5fSGirisha Dengi }
310597fff5fSGirisha Dengi
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)3117e8249a2SSieu Mun Tang static int intel_fcs_crypto_service_init(uint32_t session_id,
3127e8249a2SSieu Mun Tang uint32_t context_id, uint32_t key_id,
3137e8249a2SSieu Mun Tang uint32_t param_size, uint64_t param_data,
3147e8249a2SSieu Mun Tang fcs_crypto_service_data *data_addr,
3157e8249a2SSieu Mun Tang uint32_t *mbox_error)
3167e8249a2SSieu Mun Tang {
3177e8249a2SSieu Mun Tang if (mbox_error == NULL) {
3187e8249a2SSieu Mun Tang return INTEL_SIP_SMC_STATUS_REJECTED;
3197e8249a2SSieu Mun Tang }
3207e8249a2SSieu Mun Tang
3217e8249a2SSieu Mun Tang if (param_size != 4) {
3227e8249a2SSieu Mun Tang return INTEL_SIP_SMC_STATUS_REJECTED;
3237e8249a2SSieu Mun Tang }
3247e8249a2SSieu Mun Tang
3257e8249a2SSieu Mun Tang memset(data_addr, 0, sizeof(fcs_crypto_service_data));
3267e8249a2SSieu Mun Tang
3277e8249a2SSieu Mun Tang data_addr->session_id = session_id;
3287e8249a2SSieu Mun Tang data_addr->context_id = context_id;
3297e8249a2SSieu Mun Tang data_addr->key_id = key_id;
3307e8249a2SSieu Mun Tang data_addr->crypto_param_size = param_size;
3317e8249a2SSieu Mun Tang data_addr->crypto_param = param_data;
3327e8249a2SSieu Mun Tang
3331d97dd74SSieu Mun Tang data_addr->is_updated = 0;
3341d97dd74SSieu Mun Tang
3357e8249a2SSieu Mun Tang *mbox_error = 0;
3367e8249a2SSieu Mun Tang
3377e8249a2SSieu Mun Tang return INTEL_SIP_SMC_STATUS_OK;
3387e8249a2SSieu Mun Tang }
3397e8249a2SSieu Mun Tang
intel_fcs_random_number_gen(uint64_t addr,uint64_t * ret_size,uint32_t * mbox_error)340286b96f4SSieu Mun Tang uint32_t intel_fcs_random_number_gen(uint64_t addr, uint64_t *ret_size,
341286b96f4SSieu Mun Tang uint32_t *mbox_error)
342286b96f4SSieu Mun Tang {
343286b96f4SSieu Mun Tang int status;
344286b96f4SSieu Mun Tang unsigned int i;
345286b96f4SSieu Mun Tang unsigned int resp_len = FCS_RANDOM_WORD_SIZE;
346286b96f4SSieu Mun Tang uint32_t random_data[FCS_RANDOM_WORD_SIZE] = {0U};
347286b96f4SSieu Mun Tang
348286b96f4SSieu Mun Tang if (!is_address_in_ddr_range(addr, FCS_RANDOM_BYTE_SIZE)) {
349286b96f4SSieu Mun Tang return INTEL_SIP_SMC_STATUS_REJECTED;
350286b96f4SSieu Mun Tang }
351286b96f4SSieu Mun Tang
352286b96f4SSieu Mun Tang status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_RANDOM_GEN, NULL, 0U,
353286b96f4SSieu Mun Tang CMD_CASUAL, random_data, &resp_len);
354286b96f4SSieu Mun Tang
355286b96f4SSieu Mun Tang if (status < 0) {
356286b96f4SSieu Mun Tang *mbox_error = -status;
357286b96f4SSieu Mun Tang return INTEL_SIP_SMC_STATUS_ERROR;
358286b96f4SSieu Mun Tang }
359286b96f4SSieu Mun Tang
360286b96f4SSieu Mun Tang if (resp_len != FCS_RANDOM_WORD_SIZE) {
361286b96f4SSieu Mun Tang *mbox_error = GENERIC_RESPONSE_ERROR;
362286b96f4SSieu Mun Tang return INTEL_SIP_SMC_STATUS_ERROR;
363286b96f4SSieu Mun Tang }
364286b96f4SSieu Mun Tang
365286b96f4SSieu Mun Tang *ret_size = FCS_RANDOM_BYTE_SIZE;
366286b96f4SSieu Mun Tang
367286b96f4SSieu Mun Tang for (i = 0U; i < FCS_RANDOM_WORD_SIZE; i++) {
368286b96f4SSieu Mun Tang mmio_write_32(addr, random_data[i]);
369286b96f4SSieu Mun Tang addr += MBOX_WORD_BYTE;
370286b96f4SSieu Mun Tang }
371286b96f4SSieu Mun Tang
372286b96f4SSieu Mun Tang flush_dcache_range(addr - *ret_size, *ret_size);
373286b96f4SSieu Mun Tang
374286b96f4SSieu Mun Tang return INTEL_SIP_SMC_STATUS_OK;
375286b96f4SSieu Mun Tang }
376286b96f4SSieu Mun Tang
intel_fcs_random_number_gen_ext(uint32_t session_id,uint32_t context_id,uint32_t size,uint32_t * send_id)37724f9dc8aSSieu Mun Tang int intel_fcs_random_number_gen_ext(uint32_t session_id, uint32_t context_id,
37824f9dc8aSSieu Mun Tang uint32_t size, uint32_t *send_id)
37924f9dc8aSSieu Mun Tang {
38024f9dc8aSSieu Mun Tang int status;
38124f9dc8aSSieu Mun Tang uint32_t payload_size;
38224f9dc8aSSieu Mun Tang uint32_t crypto_header;
38324f9dc8aSSieu Mun Tang
38424f9dc8aSSieu Mun Tang if (size > (FCS_RANDOM_EXT_MAX_WORD_SIZE *
38524f9dc8aSSieu Mun Tang MBOX_WORD_BYTE) || size == 0U) {
38624f9dc8aSSieu Mun Tang return INTEL_SIP_SMC_STATUS_REJECTED;
38724f9dc8aSSieu Mun Tang }
38824f9dc8aSSieu Mun Tang
38924f9dc8aSSieu Mun Tang if (!is_size_4_bytes_aligned(size)) {
39024f9dc8aSSieu Mun Tang return INTEL_SIP_SMC_STATUS_REJECTED;
39124f9dc8aSSieu Mun Tang }
39224f9dc8aSSieu Mun Tang
39324f9dc8aSSieu Mun Tang crypto_header = (FCS_CS_FIELD_FLAG_INIT | FCS_CS_FIELD_FLAG_FINALIZE) <<
39424f9dc8aSSieu Mun Tang FCS_CS_FIELD_FLAG_OFFSET;
39524f9dc8aSSieu Mun Tang
39624f9dc8aSSieu Mun Tang fcs_rng_payload payload = {
39724f9dc8aSSieu Mun Tang session_id,
39824f9dc8aSSieu Mun Tang context_id,
39924f9dc8aSSieu Mun Tang crypto_header,
40024f9dc8aSSieu Mun Tang size
40124f9dc8aSSieu Mun Tang };
40224f9dc8aSSieu Mun Tang
40324f9dc8aSSieu Mun Tang payload_size = sizeof(payload) / MBOX_WORD_BYTE;
40424f9dc8aSSieu Mun Tang
40524f9dc8aSSieu Mun Tang status = mailbox_send_cmd_async(send_id, MBOX_FCS_RANDOM_GEN,
40624f9dc8aSSieu Mun Tang (uint32_t *) &payload, payload_size,
40724f9dc8aSSieu Mun Tang CMD_INDIRECT);
40824f9dc8aSSieu Mun Tang
40924f9dc8aSSieu Mun Tang if (status < 0) {
41024f9dc8aSSieu Mun Tang return INTEL_SIP_SMC_STATUS_ERROR;
41124f9dc8aSSieu Mun Tang }
41224f9dc8aSSieu Mun Tang
41324f9dc8aSSieu Mun Tang return INTEL_SIP_SMC_STATUS_OK;
41424f9dc8aSSieu Mun Tang }
41524f9dc8aSSieu Mun Tang
intel_fcs_send_cert(uint32_t smc_fid,uint32_t trans_id,uint64_t addr,uint64_t size,uint32_t * send_id)416597fff5fSGirisha Dengi uint32_t intel_fcs_send_cert(uint32_t smc_fid, uint32_t trans_id,
417597fff5fSGirisha Dengi uint64_t addr, uint64_t size,
418286b96f4SSieu Mun Tang uint32_t *send_id)
419286b96f4SSieu Mun Tang {
420286b96f4SSieu Mun Tang int status;
421286b96f4SSieu Mun Tang
422286b96f4SSieu Mun Tang if (!is_address_in_ddr_range(addr, size)) {
423286b96f4SSieu Mun Tang return INTEL_SIP_SMC_STATUS_REJECTED;
424286b96f4SSieu Mun Tang }
425286b96f4SSieu Mun Tang
42652ed157fSSieu Mun Tang if (!is_size_4_bytes_aligned(size)) {
42752ed157fSSieu Mun Tang return INTEL_SIP_SMC_STATUS_REJECTED;
42852ed157fSSieu Mun Tang }
42952ed157fSSieu Mun Tang
430597fff5fSGirisha Dengi status = (smc_fid == ALTERA_SIP_SMC_ASYNC_FCS_SEND_CERTIFICATE) ?
431597fff5fSGirisha Dengi mailbox_send_cmd_async_v3(GET_CLIENT_ID(trans_id),
432597fff5fSGirisha Dengi GET_JOB_ID(trans_id),
433597fff5fSGirisha Dengi MBOX_CMD_VAB_SRC_CERT,
434597fff5fSGirisha Dengi (uint32_t *) addr,
435597fff5fSGirisha Dengi size / MBOX_WORD_BYTE,
436597fff5fSGirisha Dengi MBOX_CMD_FLAG_CASUAL,
437597fff5fSGirisha Dengi fcs_send_cert_cb,
438597fff5fSGirisha Dengi NULL,
439597fff5fSGirisha Dengi 0U) :
440597fff5fSGirisha Dengi mailbox_send_cmd_async(send_id, MBOX_CMD_VAB_SRC_CERT,
441286b96f4SSieu Mun Tang (uint32_t *)addr, size / MBOX_WORD_BYTE,
442286b96f4SSieu Mun Tang CMD_DIRECT);
443286b96f4SSieu Mun Tang
44449d44ec5SBoon Khai Ng flush_dcache_range(addr, size);
44549d44ec5SBoon Khai Ng
446286b96f4SSieu Mun Tang if (status < 0) {
447286b96f4SSieu Mun Tang return INTEL_SIP_SMC_STATUS_ERROR;
448286b96f4SSieu Mun Tang }
449286b96f4SSieu Mun Tang
450286b96f4SSieu Mun Tang return INTEL_SIP_SMC_STATUS_OK;
451286b96f4SSieu Mun Tang }
452286b96f4SSieu Mun Tang
intel_fcs_get_provision_data(uint32_t * send_id)453286b96f4SSieu Mun Tang uint32_t intel_fcs_get_provision_data(uint32_t *send_id)
454286b96f4SSieu Mun Tang {
455286b96f4SSieu Mun Tang int status;
456286b96f4SSieu Mun Tang
457286b96f4SSieu Mun Tang status = mailbox_send_cmd_async(send_id, MBOX_FCS_GET_PROVISION,
458286b96f4SSieu Mun Tang NULL, 0U, CMD_DIRECT);
459286b96f4SSieu Mun Tang
460286b96f4SSieu Mun Tang if (status < 0) {
461286b96f4SSieu Mun Tang return INTEL_SIP_SMC_STATUS_ERROR;
462286b96f4SSieu Mun Tang }
463286b96f4SSieu Mun Tang
464286b96f4SSieu Mun Tang return INTEL_SIP_SMC_STATUS_OK;
465286b96f4SSieu Mun Tang }
466286b96f4SSieu Mun Tang
intel_fcs_cntr_set_preauth(uint32_t smc_fid,uint32_t trans_id,uint8_t counter_type,int32_t counter_value,uint32_t test_bit,uint32_t * mbox_error)467597fff5fSGirisha Dengi uint32_t intel_fcs_cntr_set_preauth(uint32_t smc_fid, uint32_t trans_id,
468597fff5fSGirisha Dengi uint8_t counter_type, int32_t counter_value,
4697facacecSSieu Mun Tang uint32_t test_bit, uint32_t *mbox_error)
4707facacecSSieu Mun Tang {
4717facacecSSieu Mun Tang int status;
4727facacecSSieu Mun Tang uint32_t first_word;
4737facacecSSieu Mun Tang uint32_t payload_size;
4747facacecSSieu Mun Tang
4757facacecSSieu Mun Tang if ((test_bit != MBOX_TEST_BIT) &&
4767facacecSSieu Mun Tang (test_bit != 0)) {
4777facacecSSieu Mun Tang return INTEL_SIP_SMC_STATUS_REJECTED;
4787facacecSSieu Mun Tang }
4797facacecSSieu Mun Tang
4807facacecSSieu Mun Tang if ((counter_type < FCS_BIG_CNTR_SEL) ||
4817facacecSSieu Mun Tang (counter_type > FCS_SVN_CNTR_3_SEL)) {
4827facacecSSieu Mun Tang return INTEL_SIP_SMC_STATUS_REJECTED;
4837facacecSSieu Mun Tang }
4847facacecSSieu Mun Tang
4857facacecSSieu Mun Tang if ((counter_type == FCS_BIG_CNTR_SEL) &&
4867facacecSSieu Mun Tang (counter_value > FCS_BIG_CNTR_VAL_MAX)) {
4877facacecSSieu Mun Tang return INTEL_SIP_SMC_STATUS_REJECTED;
4887facacecSSieu Mun Tang }
4897facacecSSieu Mun Tang
4907facacecSSieu Mun Tang if ((counter_type >= FCS_SVN_CNTR_0_SEL) &&
4917facacecSSieu Mun Tang (counter_type <= FCS_SVN_CNTR_3_SEL) &&
4927facacecSSieu Mun Tang (counter_value > FCS_SVN_CNTR_VAL_MAX)) {
4937facacecSSieu Mun Tang return INTEL_SIP_SMC_STATUS_REJECTED;
4947facacecSSieu Mun Tang }
4957facacecSSieu Mun Tang
4967facacecSSieu Mun Tang first_word = test_bit | counter_type;
4977facacecSSieu Mun Tang fcs_cntr_set_preauth_payload payload = {
4987facacecSSieu Mun Tang first_word,
4997facacecSSieu Mun Tang counter_value
5007facacecSSieu Mun Tang };
5017facacecSSieu Mun Tang
5027facacecSSieu Mun Tang payload_size = sizeof(payload) / MBOX_WORD_BYTE;
503597fff5fSGirisha Dengi
504597fff5fSGirisha Dengi status = (smc_fid == ALTERA_SIP_SMC_ASYNC_FCS_CNTR_SET_PREAUTH) ?
505597fff5fSGirisha Dengi mailbox_send_cmd_async_v3(GET_CLIENT_ID(trans_id),
506597fff5fSGirisha Dengi GET_JOB_ID(trans_id),
507597fff5fSGirisha Dengi MBOX_FCS_CNTR_SET_PREAUTH,
508597fff5fSGirisha Dengi (uint32_t *) &payload,
509597fff5fSGirisha Dengi payload_size,
510597fff5fSGirisha Dengi MBOX_CMD_FLAG_CASUAL,
511597fff5fSGirisha Dengi fcs_cntr_set_preauth_cb,
512597fff5fSGirisha Dengi NULL,
513597fff5fSGirisha Dengi 0U) :
514597fff5fSGirisha Dengi mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_CNTR_SET_PREAUTH,
5157facacecSSieu Mun Tang (uint32_t *) &payload, payload_size,
5167facacecSSieu Mun Tang CMD_CASUAL, NULL, NULL);
5177facacecSSieu Mun Tang
5187facacecSSieu Mun Tang if (status < 0) {
5197facacecSSieu Mun Tang *mbox_error = -status;
5207facacecSSieu Mun Tang return INTEL_SIP_SMC_STATUS_ERROR;
5217facacecSSieu Mun Tang }
5227facacecSSieu Mun Tang
5237facacecSSieu Mun Tang return INTEL_SIP_SMC_STATUS_OK;
5247facacecSSieu Mun Tang }
5257facacecSSieu Mun Tang
intel_fcs_encryption(uint32_t src_addr,uint32_t src_size,uint32_t dst_addr,uint32_t dst_size,uint32_t * send_id)52602d3ef33SSieu Mun Tang uint32_t intel_fcs_encryption(uint32_t src_addr, uint32_t src_size,
52702d3ef33SSieu Mun Tang uint32_t dst_addr, uint32_t dst_size, uint32_t *send_id)
528286b96f4SSieu Mun Tang {
529286b96f4SSieu Mun Tang int status;
53002d3ef33SSieu Mun Tang uint32_t load_size;
531286b96f4SSieu Mun Tang
53252ed157fSSieu Mun Tang if (!is_address_in_ddr_range(src_addr, src_size) ||
53352ed157fSSieu Mun Tang !is_address_in_ddr_range(dst_addr, dst_size)) {
53452ed157fSSieu Mun Tang return INTEL_SIP_SMC_STATUS_REJECTED;
53552ed157fSSieu Mun Tang }
53652ed157fSSieu Mun Tang
53702d3ef33SSieu Mun Tang if (!is_size_4_bytes_aligned(src_size)) {
53852ed157fSSieu Mun Tang return INTEL_SIP_SMC_STATUS_REJECTED;
53952ed157fSSieu Mun Tang }
54052ed157fSSieu Mun Tang
541e8a3454cSJit Loon Lim fcs_encrypt_payload payload = {
542e8a3454cSJit Loon Lim FCS_ENCRYPTION_DATA_0,
543e8a3454cSJit Loon Lim src_addr,
544e8a3454cSJit Loon Lim src_size,
545e8a3454cSJit Loon Lim dst_addr,
546e8a3454cSJit Loon Lim dst_size };
547e8a3454cSJit Loon Lim load_size = sizeof(payload) / MBOX_WORD_BYTE;
548e8a3454cSJit Loon Lim
54902d3ef33SSieu Mun Tang status = mailbox_send_cmd_async(send_id, MBOX_FCS_ENCRYPT_REQ,
55002d3ef33SSieu Mun Tang (uint32_t *) &payload, load_size,
55102d3ef33SSieu Mun Tang CMD_INDIRECT);
55202d3ef33SSieu Mun Tang inv_dcache_range(dst_addr, dst_size);
55302d3ef33SSieu Mun Tang
55402d3ef33SSieu Mun Tang if (status < 0) {
55502d3ef33SSieu Mun Tang return INTEL_SIP_SMC_STATUS_REJECTED;
556286b96f4SSieu Mun Tang }
557286b96f4SSieu Mun Tang
55802d3ef33SSieu Mun Tang return INTEL_SIP_SMC_STATUS_OK;
55902d3ef33SSieu Mun Tang }
56002d3ef33SSieu Mun Tang
intel_fcs_decryption(uint32_t src_addr,uint32_t src_size,uint32_t dst_addr,uint32_t dst_size,uint32_t * send_id)56102d3ef33SSieu Mun Tang uint32_t intel_fcs_decryption(uint32_t src_addr, uint32_t src_size,
56202d3ef33SSieu Mun Tang uint32_t dst_addr, uint32_t dst_size, uint32_t *send_id)
56302d3ef33SSieu Mun Tang {
56402d3ef33SSieu Mun Tang int status;
56502d3ef33SSieu Mun Tang uint32_t load_size;
56602d3ef33SSieu Mun Tang uintptr_t id_offset;
56702d3ef33SSieu Mun Tang
568e8a3454cSJit Loon Lim if (!is_address_in_ddr_range(src_addr, src_size) ||
569e8a3454cSJit Loon Lim !is_address_in_ddr_range(dst_addr, dst_size)) {
570e8a3454cSJit Loon Lim return INTEL_SIP_SMC_STATUS_REJECTED;
571e8a3454cSJit Loon Lim }
572e8a3454cSJit Loon Lim
573e8a3454cSJit Loon Lim if (!is_size_4_bytes_aligned(src_size)) {
574e8a3454cSJit Loon Lim return INTEL_SIP_SMC_STATUS_REJECTED;
575e8a3454cSJit Loon Lim }
576e8a3454cSJit Loon Lim
577731622feSJit Loon Lim inv_dcache_range(src_addr, src_size); /* flush cache before mmio read to avoid reading old values */
57802d3ef33SSieu Mun Tang id_offset = src_addr + FCS_OWNER_ID_OFFSET;
57902d3ef33SSieu Mun Tang fcs_decrypt_payload payload = {
58002d3ef33SSieu Mun Tang FCS_DECRYPTION_DATA_0,
58102d3ef33SSieu Mun Tang {mmio_read_32(id_offset),
58202d3ef33SSieu Mun Tang mmio_read_32(id_offset + MBOX_WORD_BYTE)},
58302d3ef33SSieu Mun Tang src_addr,
58402d3ef33SSieu Mun Tang src_size,
58502d3ef33SSieu Mun Tang dst_addr,
58602d3ef33SSieu Mun Tang dst_size };
58702d3ef33SSieu Mun Tang load_size = sizeof(payload) / MBOX_WORD_BYTE;
58802d3ef33SSieu Mun Tang
58902d3ef33SSieu Mun Tang status = mailbox_send_cmd_async(send_id, MBOX_FCS_DECRYPT_REQ,
59002d3ef33SSieu Mun Tang (uint32_t *) &payload, load_size,
591286b96f4SSieu Mun Tang CMD_INDIRECT);
592286b96f4SSieu Mun Tang inv_dcache_range(dst_addr, dst_size);
593286b96f4SSieu Mun Tang
594286b96f4SSieu Mun Tang if (status < 0) {
595286b96f4SSieu Mun Tang return INTEL_SIP_SMC_STATUS_REJECTED;
596286b96f4SSieu Mun Tang }
597286b96f4SSieu Mun Tang
598286b96f4SSieu Mun Tang return INTEL_SIP_SMC_STATUS_OK;
599286b96f4SSieu Mun Tang }
60077902fcaSSieu Mun Tang
intel_fcs_encryption_ext(uint32_t smc_fid,uint32_t trans_id,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,uint32_t smmu_src_addr,uint32_t smmu_dst_addr)601597fff5fSGirisha Dengi int intel_fcs_encryption_ext(uint32_t smc_fid, uint32_t trans_id,
602597fff5fSGirisha Dengi uint32_t session_id, uint32_t context_id,
603537ff052SSieu Mun Tang uint32_t src_addr, uint32_t src_size,
604597fff5fSGirisha Dengi uint32_t dst_addr, uint32_t *dst_size, uint32_t *mbox_error,
605597fff5fSGirisha Dengi uint32_t smmu_src_addr, uint32_t smmu_dst_addr)
606537ff052SSieu Mun Tang {
607537ff052SSieu Mun Tang int status;
608537ff052SSieu Mun Tang uint32_t payload_size;
609537ff052SSieu Mun Tang uint32_t resp_len = FCS_CRYPTION_RESP_WORD_SIZE;
610537ff052SSieu Mun Tang uint32_t resp_data[FCS_CRYPTION_RESP_WORD_SIZE] = {0U};
611597fff5fSGirisha Dengi uint32_t src_addr_sdm = src_addr;
612597fff5fSGirisha Dengi uint32_t dst_addr_sdm = dst_addr;
613537ff052SSieu Mun Tang
614537ff052SSieu Mun Tang if ((dst_size == NULL) || (mbox_error == NULL)) {
615537ff052SSieu Mun Tang return INTEL_SIP_SMC_STATUS_REJECTED;
616537ff052SSieu Mun Tang }
617537ff052SSieu Mun Tang
618537ff052SSieu Mun Tang if (!is_address_in_ddr_range(src_addr, src_size) ||
619537ff052SSieu Mun Tang !is_address_in_ddr_range(dst_addr, *dst_size)) {
620537ff052SSieu Mun Tang return INTEL_SIP_SMC_STATUS_REJECTED;
621537ff052SSieu Mun Tang }
622537ff052SSieu Mun Tang
623537ff052SSieu Mun Tang if (!is_size_4_bytes_aligned(src_size)) {
624537ff052SSieu Mun Tang return INTEL_SIP_SMC_STATUS_REJECTED;
625537ff052SSieu Mun Tang }
626537ff052SSieu Mun Tang
627597fff5fSGirisha Dengi /* On the Agilex5 platform, we will use the SMMU payload address */
628597fff5fSGirisha Dengi #if PLATFORM_MODEL == PLAT_SOCFPGA_AGILEX5
629597fff5fSGirisha Dengi src_addr_sdm = smmu_src_addr;
630597fff5fSGirisha Dengi dst_addr_sdm = smmu_dst_addr;
631597fff5fSGirisha Dengi #endif
632597fff5fSGirisha Dengi
633537ff052SSieu Mun Tang fcs_encrypt_ext_payload payload = {
634537ff052SSieu Mun Tang session_id,
635537ff052SSieu Mun Tang context_id,
636537ff052SSieu Mun Tang FCS_CRYPTION_CRYPTO_HEADER,
637597fff5fSGirisha Dengi src_addr_sdm,
638537ff052SSieu Mun Tang src_size,
639597fff5fSGirisha Dengi dst_addr_sdm,
640537ff052SSieu Mun Tang *dst_size
641537ff052SSieu Mun Tang };
642537ff052SSieu Mun Tang
643537ff052SSieu Mun Tang payload_size = sizeof(payload) / MBOX_WORD_BYTE;
644537ff052SSieu Mun Tang
645597fff5fSGirisha Dengi status = (smc_fid == ALTERA_SIP_SMC_ASYNC_FCS_CRYPTION_EXT) ?
646597fff5fSGirisha Dengi mailbox_send_cmd_async_v3(GET_CLIENT_ID(trans_id),
647597fff5fSGirisha Dengi GET_JOB_ID(trans_id),
648597fff5fSGirisha Dengi MBOX_FCS_ENCRYPT_REQ,
649597fff5fSGirisha Dengi (uint32_t *) &payload,
650597fff5fSGirisha Dengi payload_size,
651597fff5fSGirisha Dengi MBOX_CMD_FLAG_INDIRECT,
652597fff5fSGirisha Dengi fcs_sdos_crypto_request_cb,
653597fff5fSGirisha Dengi NULL,
654597fff5fSGirisha Dengi 0U) :
655597fff5fSGirisha Dengi mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_ENCRYPT_REQ,
656537ff052SSieu Mun Tang (uint32_t *) &payload, payload_size,
657537ff052SSieu Mun Tang CMD_CASUAL, resp_data, &resp_len);
658537ff052SSieu Mun Tang
659537ff052SSieu Mun Tang if (status < 0) {
660537ff052SSieu Mun Tang *mbox_error = -status;
661537ff052SSieu Mun Tang return INTEL_SIP_SMC_STATUS_ERROR;
662537ff052SSieu Mun Tang }
663537ff052SSieu Mun Tang
664537ff052SSieu Mun Tang if (resp_len != FCS_CRYPTION_RESP_WORD_SIZE) {
665537ff052SSieu Mun Tang *mbox_error = MBOX_RET_ERROR;
666537ff052SSieu Mun Tang return INTEL_SIP_SMC_STATUS_ERROR;
667537ff052SSieu Mun Tang }
668537ff052SSieu Mun Tang
669537ff052SSieu Mun Tang *dst_size = resp_data[FCS_CRYPTION_RESP_SIZE_OFFSET];
670537ff052SSieu Mun Tang inv_dcache_range(dst_addr, *dst_size);
671537ff052SSieu Mun Tang
672537ff052SSieu Mun Tang return INTEL_SIP_SMC_STATUS_OK;
673537ff052SSieu Mun Tang }
674537ff052SSieu Mun Tang
intel_fcs_decryption_ext(uint32_t smc_fid,uint32_t trans_id,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,uint64_t owner_id,uint32_t smmu_src_addr,uint32_t smmu_dst_addr)675597fff5fSGirisha Dengi int intel_fcs_decryption_ext(uint32_t smc_fid, uint32_t trans_id,
676597fff5fSGirisha Dengi uint32_t session_id, uint32_t context_id,
677537ff052SSieu Mun Tang uint32_t src_addr, uint32_t src_size,
678597fff5fSGirisha Dengi uint32_t dst_addr, uint32_t *dst_size,
679597fff5fSGirisha Dengi uint32_t *mbox_error, uint64_t owner_id,
680597fff5fSGirisha Dengi uint32_t smmu_src_addr, uint32_t smmu_dst_addr)
681537ff052SSieu Mun Tang {
682537ff052SSieu Mun Tang int status;
683537ff052SSieu Mun Tang uintptr_t id_offset;
684537ff052SSieu Mun Tang uint32_t payload_size;
685537ff052SSieu Mun Tang uint32_t resp_len = FCS_CRYPTION_RESP_WORD_SIZE;
686537ff052SSieu Mun Tang uint32_t resp_data[FCS_CRYPTION_RESP_WORD_SIZE] = {0U};
687597fff5fSGirisha Dengi uint32_t src_addr_sdm = src_addr;
688597fff5fSGirisha Dengi uint32_t dst_addr_sdm = dst_addr;
689537ff052SSieu Mun Tang
690537ff052SSieu Mun Tang if ((dst_size == NULL) || (mbox_error == NULL)) {
691537ff052SSieu Mun Tang return INTEL_SIP_SMC_STATUS_REJECTED;
692537ff052SSieu Mun Tang }
693537ff052SSieu Mun Tang
694537ff052SSieu Mun Tang if (!is_address_in_ddr_range(src_addr, src_size) ||
695537ff052SSieu Mun Tang !is_address_in_ddr_range(dst_addr, *dst_size)) {
696537ff052SSieu Mun Tang return INTEL_SIP_SMC_STATUS_REJECTED;
697537ff052SSieu Mun Tang }
698537ff052SSieu Mun Tang
699537ff052SSieu Mun Tang if (!is_size_4_bytes_aligned(src_size)) {
700537ff052SSieu Mun Tang return INTEL_SIP_SMC_STATUS_REJECTED;
701537ff052SSieu Mun Tang }
702537ff052SSieu Mun Tang
703597fff5fSGirisha Dengi /* On the Agilex5 platform, we will use the SMMU payload address */
704597fff5fSGirisha Dengi #if PLATFORM_MODEL == PLAT_SOCFPGA_AGILEX5
705597fff5fSGirisha Dengi src_addr_sdm = smmu_src_addr;
706597fff5fSGirisha Dengi dst_addr_sdm = smmu_dst_addr;
707597fff5fSGirisha Dengi #endif
708597fff5fSGirisha Dengi
709731622feSJit Loon Lim inv_dcache_range(src_addr, src_size); /* flush cache before mmio read to avoid reading old values */
710537ff052SSieu Mun Tang id_offset = src_addr + FCS_OWNER_ID_OFFSET;
711537ff052SSieu Mun Tang fcs_decrypt_ext_payload payload = {
712537ff052SSieu Mun Tang session_id,
713537ff052SSieu Mun Tang context_id,
714537ff052SSieu Mun Tang FCS_CRYPTION_CRYPTO_HEADER,
715537ff052SSieu Mun Tang {mmio_read_32(id_offset),
716537ff052SSieu Mun Tang mmio_read_32(id_offset + MBOX_WORD_BYTE)},
717597fff5fSGirisha Dengi src_addr_sdm,
718537ff052SSieu Mun Tang src_size,
719597fff5fSGirisha Dengi dst_addr_sdm,
720537ff052SSieu Mun Tang *dst_size
721537ff052SSieu Mun Tang };
722537ff052SSieu Mun Tang
723537ff052SSieu Mun Tang payload_size = sizeof(payload) / MBOX_WORD_BYTE;
724537ff052SSieu Mun Tang
725597fff5fSGirisha Dengi status = (smc_fid == ALTERA_SIP_SMC_ASYNC_FCS_CRYPTION_EXT) ?
726597fff5fSGirisha Dengi mailbox_send_cmd_async_v3(GET_CLIENT_ID(trans_id),
727597fff5fSGirisha Dengi GET_JOB_ID(trans_id),
728597fff5fSGirisha Dengi MBOX_FCS_DECRYPT_REQ,
729597fff5fSGirisha Dengi (uint32_t *) &payload,
730597fff5fSGirisha Dengi payload_size,
731597fff5fSGirisha Dengi MBOX_CMD_FLAG_INDIRECT,
732597fff5fSGirisha Dengi fcs_sdos_crypto_request_cb,
733597fff5fSGirisha Dengi NULL,
734597fff5fSGirisha Dengi 0U) :
735597fff5fSGirisha Dengi mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_DECRYPT_REQ,
736537ff052SSieu Mun Tang (uint32_t *) &payload, payload_size,
737537ff052SSieu Mun Tang CMD_CASUAL, resp_data, &resp_len);
738537ff052SSieu Mun Tang
73976ed3223SSieu Mun Tang if (status == MBOX_RET_SDOS_DECRYPTION_ERROR_102 ||
74076ed3223SSieu Mun Tang status == MBOX_RET_SDOS_DECRYPTION_ERROR_103) {
74176ed3223SSieu Mun Tang *mbox_error = -status;
74276ed3223SSieu Mun Tang } else if (status < 0) {
743537ff052SSieu Mun Tang *mbox_error = -status;
744537ff052SSieu Mun Tang return INTEL_SIP_SMC_STATUS_ERROR;
745537ff052SSieu Mun Tang }
746537ff052SSieu Mun Tang
747537ff052SSieu Mun Tang if (resp_len != FCS_CRYPTION_RESP_WORD_SIZE) {
748537ff052SSieu Mun Tang *mbox_error = MBOX_RET_ERROR;
749537ff052SSieu Mun Tang return INTEL_SIP_SMC_STATUS_ERROR;
750537ff052SSieu Mun Tang }
751537ff052SSieu Mun Tang
752537ff052SSieu Mun Tang *dst_size = resp_data[FCS_CRYPTION_RESP_SIZE_OFFSET];
753537ff052SSieu Mun Tang inv_dcache_range(dst_addr, *dst_size);
754537ff052SSieu Mun Tang
755537ff052SSieu Mun Tang return INTEL_SIP_SMC_STATUS_OK;
756537ff052SSieu Mun Tang }
757537ff052SSieu Mun Tang
intel_fcs_sigma_teardown(uint32_t session_id,uint32_t * mbox_error)758d1740831SSieu Mun Tang int intel_fcs_sigma_teardown(uint32_t session_id, uint32_t *mbox_error)
759d1740831SSieu Mun Tang {
760d1740831SSieu Mun Tang int status;
761d1740831SSieu Mun Tang
762d1740831SSieu Mun Tang if ((session_id != PSGSIGMA_SESSION_ID_ONE) &&
763d1740831SSieu Mun Tang (session_id != PSGSIGMA_UNKNOWN_SESSION)) {
764d1740831SSieu Mun Tang return INTEL_SIP_SMC_STATUS_REJECTED;
765d1740831SSieu Mun Tang }
766d1740831SSieu Mun Tang
767d1740831SSieu Mun Tang psgsigma_teardown_msg message = {
768d1740831SSieu Mun Tang RESERVED_AS_ZERO,
769d1740831SSieu Mun Tang PSGSIGMA_TEARDOWN_MAGIC,
770d1740831SSieu Mun Tang session_id
771d1740831SSieu Mun Tang };
772d1740831SSieu Mun Tang
773d1740831SSieu Mun Tang status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_PSG_SIGMA_TEARDOWN,
774d1740831SSieu Mun Tang (uint32_t *) &message, sizeof(message) / MBOX_WORD_BYTE,
775d1740831SSieu Mun Tang CMD_CASUAL, NULL, NULL);
776d1740831SSieu Mun Tang
777d1740831SSieu Mun Tang if (status < 0) {
778d1740831SSieu Mun Tang *mbox_error = -status;
779d1740831SSieu Mun Tang return INTEL_SIP_SMC_STATUS_ERROR;
780d1740831SSieu Mun Tang }
781d1740831SSieu Mun Tang
782d1740831SSieu Mun Tang return INTEL_SIP_SMC_STATUS_OK;
783d1740831SSieu Mun Tang }
784d1740831SSieu Mun Tang
intel_fcs_chip_id(uint32_t * id_low,uint32_t * id_high,uint32_t * mbox_error)785d1740831SSieu Mun Tang int intel_fcs_chip_id(uint32_t *id_low, uint32_t *id_high, uint32_t *mbox_error)
786d1740831SSieu Mun Tang {
787d1740831SSieu Mun Tang int status;
788d1740831SSieu Mun Tang uint32_t load_size;
789d1740831SSieu Mun Tang uint32_t chip_id[2];
790d1740831SSieu Mun Tang
791d1740831SSieu Mun Tang load_size = sizeof(chip_id) / MBOX_WORD_BYTE;
792d1740831SSieu Mun Tang
793d1740831SSieu Mun Tang status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_CMD_GET_CHIPID, NULL,
794d1740831SSieu Mun Tang 0U, CMD_CASUAL, (uint32_t *) chip_id, &load_size);
795d1740831SSieu Mun Tang
796d1740831SSieu Mun Tang if (status < 0) {
797d1740831SSieu Mun Tang *mbox_error = -status;
798d1740831SSieu Mun Tang return INTEL_SIP_SMC_STATUS_ERROR;
799d1740831SSieu Mun Tang }
800d1740831SSieu Mun Tang
801d1740831SSieu Mun Tang *id_low = chip_id[0];
802d1740831SSieu Mun Tang *id_high = chip_id[1];
803d1740831SSieu Mun Tang
804d1740831SSieu Mun Tang return INTEL_SIP_SMC_STATUS_OK;
805d1740831SSieu Mun Tang }
806d1740831SSieu Mun Tang
intel_fcs_attestation_subkey(uint64_t src_addr,uint32_t src_size,uint64_t dst_addr,uint32_t * dst_size,uint32_t * mbox_error)807d1740831SSieu Mun Tang int intel_fcs_attestation_subkey(uint64_t src_addr, uint32_t src_size,
808d1740831SSieu Mun Tang uint64_t dst_addr, uint32_t *dst_size, uint32_t *mbox_error)
809d1740831SSieu Mun Tang {
810d1740831SSieu Mun Tang int status;
811d1740831SSieu Mun Tang uint32_t send_size = src_size / MBOX_WORD_BYTE;
812d1740831SSieu Mun Tang uint32_t ret_size = *dst_size / MBOX_WORD_BYTE;
813d1740831SSieu Mun Tang
814d1740831SSieu Mun Tang
815d1740831SSieu Mun Tang if (!is_address_in_ddr_range(src_addr, src_size) ||
816d1740831SSieu Mun Tang !is_address_in_ddr_range(dst_addr, *dst_size)) {
817d1740831SSieu Mun Tang return INTEL_SIP_SMC_STATUS_REJECTED;
818d1740831SSieu Mun Tang }
819d1740831SSieu Mun Tang
820d1740831SSieu Mun Tang status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_ATTESTATION_SUBKEY,
821d1740831SSieu Mun Tang (uint32_t *) src_addr, send_size, CMD_CASUAL,
822d1740831SSieu Mun Tang (uint32_t *) dst_addr, &ret_size);
823d1740831SSieu Mun Tang
824d1740831SSieu Mun Tang if (status < 0) {
825d1740831SSieu Mun Tang *mbox_error = -status;
826d1740831SSieu Mun Tang return INTEL_SIP_SMC_STATUS_ERROR;
827d1740831SSieu Mun Tang }
828d1740831SSieu Mun Tang
829d1740831SSieu Mun Tang *dst_size = ret_size * MBOX_WORD_BYTE;
830d1740831SSieu Mun Tang flush_dcache_range(dst_addr, *dst_size);
831d1740831SSieu Mun Tang
832d1740831SSieu Mun Tang return INTEL_SIP_SMC_STATUS_OK;
833d1740831SSieu Mun Tang }
834d1740831SSieu Mun Tang
intel_fcs_get_measurement(uint64_t src_addr,uint32_t src_size,uint64_t dst_addr,uint32_t * dst_size,uint32_t * mbox_error)835d1740831SSieu Mun Tang int intel_fcs_get_measurement(uint64_t src_addr, uint32_t src_size,
836d1740831SSieu Mun Tang uint64_t dst_addr, uint32_t *dst_size, uint32_t *mbox_error)
837d1740831SSieu Mun Tang {
838d1740831SSieu Mun Tang int status;
839d1740831SSieu Mun Tang uint32_t send_size = src_size / MBOX_WORD_BYTE;
840d1740831SSieu Mun Tang uint32_t ret_size = *dst_size / MBOX_WORD_BYTE;
841d1740831SSieu Mun Tang
842d1740831SSieu Mun Tang if (!is_address_in_ddr_range(src_addr, src_size) ||
843d1740831SSieu Mun Tang !is_address_in_ddr_range(dst_addr, *dst_size)) {
844d1740831SSieu Mun Tang return INTEL_SIP_SMC_STATUS_REJECTED;
845d1740831SSieu Mun Tang }
846d1740831SSieu Mun Tang
847d1740831SSieu Mun Tang status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_GET_MEASUREMENT,
848d1740831SSieu Mun Tang (uint32_t *) src_addr, send_size, CMD_CASUAL,
849d1740831SSieu Mun Tang (uint32_t *) dst_addr, &ret_size);
850d1740831SSieu Mun Tang
851d1740831SSieu Mun Tang if (status < 0) {
852d1740831SSieu Mun Tang *mbox_error = -status;
853d1740831SSieu Mun Tang return INTEL_SIP_SMC_STATUS_ERROR;
854d1740831SSieu Mun Tang }
855d1740831SSieu Mun Tang
856d1740831SSieu Mun Tang *dst_size = ret_size * MBOX_WORD_BYTE;
857d1740831SSieu Mun Tang flush_dcache_range(dst_addr, *dst_size);
858d1740831SSieu Mun Tang
859d1740831SSieu Mun Tang return INTEL_SIP_SMC_STATUS_OK;
860d1740831SSieu Mun Tang }
861581182c1SSieu Mun Tang
intel_fcs_get_rom_patch_sha384(uint64_t addr,uint64_t * ret_size,uint32_t * mbox_error)862762c34a8SSieu Mun Tang uint32_t intel_fcs_get_rom_patch_sha384(uint64_t addr, uint64_t *ret_size,
863762c34a8SSieu Mun Tang uint32_t *mbox_error)
864762c34a8SSieu Mun Tang {
865762c34a8SSieu Mun Tang int status;
866762c34a8SSieu Mun Tang unsigned int resp_len = FCS_SHA384_WORD_SIZE;
867762c34a8SSieu Mun Tang
868762c34a8SSieu Mun Tang if (!is_address_in_ddr_range(addr, FCS_SHA384_BYTE_SIZE)) {
869762c34a8SSieu Mun Tang return INTEL_SIP_SMC_STATUS_REJECTED;
870762c34a8SSieu Mun Tang }
871762c34a8SSieu Mun Tang
872762c34a8SSieu Mun Tang status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_GET_ROM_PATCH_SHA384, NULL, 0U,
873762c34a8SSieu Mun Tang CMD_CASUAL, (uint32_t *) addr, &resp_len);
874762c34a8SSieu Mun Tang
875762c34a8SSieu Mun Tang if (status < 0) {
876762c34a8SSieu Mun Tang *mbox_error = -status;
877762c34a8SSieu Mun Tang return INTEL_SIP_SMC_STATUS_ERROR;
878762c34a8SSieu Mun Tang }
879762c34a8SSieu Mun Tang
880762c34a8SSieu Mun Tang if (resp_len != FCS_SHA384_WORD_SIZE) {
881762c34a8SSieu Mun Tang *mbox_error = GENERIC_RESPONSE_ERROR;
882762c34a8SSieu Mun Tang return INTEL_SIP_SMC_STATUS_ERROR;
883762c34a8SSieu Mun Tang }
884762c34a8SSieu Mun Tang
885762c34a8SSieu Mun Tang *ret_size = FCS_SHA384_BYTE_SIZE;
886762c34a8SSieu Mun Tang
887762c34a8SSieu Mun Tang flush_dcache_range(addr, *ret_size);
888762c34a8SSieu Mun Tang
889762c34a8SSieu Mun Tang return INTEL_SIP_SMC_STATUS_OK;
890762c34a8SSieu Mun Tang }
891762c34a8SSieu Mun Tang
intel_fcs_get_attestation_cert(uint32_t smc_fid,uint32_t trans_id,uint32_t cert_request,uint64_t dst_addr,uint32_t * dst_size,uint32_t * mbox_error)892597fff5fSGirisha Dengi int intel_fcs_get_attestation_cert(uint32_t smc_fid, uint32_t trans_id,
893597fff5fSGirisha Dengi uint32_t cert_request, uint64_t dst_addr,
894581182c1SSieu Mun Tang uint32_t *dst_size, uint32_t *mbox_error)
895581182c1SSieu Mun Tang {
896581182c1SSieu Mun Tang int status;
897581182c1SSieu Mun Tang uint32_t ret_size = *dst_size / MBOX_WORD_BYTE;
898581182c1SSieu Mun Tang
899581182c1SSieu Mun Tang if (mbox_error == NULL) {
900581182c1SSieu Mun Tang return INTEL_SIP_SMC_STATUS_REJECTED;
901581182c1SSieu Mun Tang }
902581182c1SSieu Mun Tang
903fe5637f2SBoon Khai Ng if (cert_request < FCS_ATTEST_FIRMWARE_CERT ||
904fe5637f2SBoon Khai Ng cert_request > FCS_ATTEST_CERT_MAX_REQ_PARAM) {
905581182c1SSieu Mun Tang return INTEL_SIP_SMC_STATUS_REJECTED;
906581182c1SSieu Mun Tang }
907581182c1SSieu Mun Tang
908581182c1SSieu Mun Tang if (!is_address_in_ddr_range(dst_addr, *dst_size)) {
909581182c1SSieu Mun Tang return INTEL_SIP_SMC_STATUS_REJECTED;
910581182c1SSieu Mun Tang }
911581182c1SSieu Mun Tang
912597fff5fSGirisha Dengi status = (smc_fid == ALTERA_SIP_SMC_ASYNC_FCS_GET_ATTESTATION_CERT) ?
913597fff5fSGirisha Dengi mailbox_send_cmd_async_v3(GET_CLIENT_ID(trans_id),
914597fff5fSGirisha Dengi GET_JOB_ID(trans_id),
915597fff5fSGirisha Dengi MBOX_GET_ATTESTATION_CERT,
916597fff5fSGirisha Dengi (uint32_t *) &cert_request,
917597fff5fSGirisha Dengi 1U,
918597fff5fSGirisha Dengi MBOX_CMD_FLAG_CASUAL,
919597fff5fSGirisha Dengi fcs_get_attest_cert_cb,
920597fff5fSGirisha Dengi (uint32_t *)dst_addr,
921597fff5fSGirisha Dengi 2U) :
922597fff5fSGirisha Dengi mailbox_send_cmd(MBOX_JOB_ID, MBOX_GET_ATTESTATION_CERT,
923581182c1SSieu Mun Tang (uint32_t *) &cert_request, 1U, CMD_CASUAL,
924581182c1SSieu Mun Tang (uint32_t *) dst_addr, &ret_size);
925581182c1SSieu Mun Tang
926581182c1SSieu Mun Tang if (status < 0) {
927581182c1SSieu Mun Tang *mbox_error = -status;
928581182c1SSieu Mun Tang return INTEL_SIP_SMC_STATUS_ERROR;
929581182c1SSieu Mun Tang }
930581182c1SSieu Mun Tang
931581182c1SSieu Mun Tang *dst_size = ret_size * MBOX_WORD_BYTE;
932581182c1SSieu Mun Tang flush_dcache_range(dst_addr, *dst_size);
933581182c1SSieu Mun Tang
934581182c1SSieu Mun Tang return INTEL_SIP_SMC_STATUS_OK;
935581182c1SSieu Mun Tang }
936581182c1SSieu Mun Tang
intel_fcs_create_cert_on_reload(uint32_t smc_fid,uint32_t trans_id,uint32_t cert_request,uint32_t * mbox_error)937597fff5fSGirisha Dengi int intel_fcs_create_cert_on_reload(uint32_t smc_fid, uint32_t trans_id,
938597fff5fSGirisha Dengi uint32_t cert_request, uint32_t *mbox_error)
939581182c1SSieu Mun Tang {
940581182c1SSieu Mun Tang int status;
941581182c1SSieu Mun Tang
942581182c1SSieu Mun Tang if (mbox_error == NULL) {
943581182c1SSieu Mun Tang return INTEL_SIP_SMC_STATUS_REJECTED;
944581182c1SSieu Mun Tang }
945581182c1SSieu Mun Tang
946fe5637f2SBoon Khai Ng if (cert_request < FCS_ATTEST_FIRMWARE_CERT ||
947fe5637f2SBoon Khai Ng cert_request > FCS_ATTEST_CERT_MAX_REQ_PARAM) {
948581182c1SSieu Mun Tang return INTEL_SIP_SMC_STATUS_REJECTED;
949581182c1SSieu Mun Tang }
950581182c1SSieu Mun Tang
951597fff5fSGirisha Dengi status = (smc_fid == ALTERA_SIP_SMC_ASYNC_FCS_CREATE_CERT_ON_RELOAD) ?
952597fff5fSGirisha Dengi mailbox_send_cmd_async_v3(GET_CLIENT_ID(trans_id),
953597fff5fSGirisha Dengi GET_JOB_ID(trans_id),
954597fff5fSGirisha Dengi MBOX_CREATE_CERT_ON_RELOAD,
955597fff5fSGirisha Dengi (uint32_t *) &cert_request,
956597fff5fSGirisha Dengi 1U,
957597fff5fSGirisha Dengi MBOX_CMD_FLAG_CASUAL,
958597fff5fSGirisha Dengi fcs_create_cert_reload_cb,
959597fff5fSGirisha Dengi NULL,
960597fff5fSGirisha Dengi 0U) :
961597fff5fSGirisha Dengi mailbox_send_cmd(MBOX_JOB_ID, MBOX_CREATE_CERT_ON_RELOAD,
962581182c1SSieu Mun Tang (uint32_t *) &cert_request, 1U, CMD_CASUAL,
963581182c1SSieu Mun Tang NULL, NULL);
964581182c1SSieu Mun Tang
965581182c1SSieu Mun Tang if (status < 0) {
966581182c1SSieu Mun Tang *mbox_error = -status;
967581182c1SSieu Mun Tang return INTEL_SIP_SMC_STATUS_ERROR;
968581182c1SSieu Mun Tang }
969581182c1SSieu Mun Tang
970581182c1SSieu Mun Tang return INTEL_SIP_SMC_STATUS_OK;
971581182c1SSieu Mun Tang }
9726dc00c24SSieu Mun Tang
intel_fcs_open_crypto_service_session(uint32_t * session_id,uint32_t * mbox_error)9736dc00c24SSieu Mun Tang int intel_fcs_open_crypto_service_session(uint32_t *session_id,
9746dc00c24SSieu Mun Tang uint32_t *mbox_error)
9756dc00c24SSieu Mun Tang {
9766dc00c24SSieu Mun Tang int status;
9776dc00c24SSieu Mun Tang uint32_t resp_len = 1U;
9786dc00c24SSieu Mun Tang
9796dc00c24SSieu Mun Tang if ((session_id == NULL) || (mbox_error == NULL)) {
9806dc00c24SSieu Mun Tang return INTEL_SIP_SMC_STATUS_REJECTED;
9816dc00c24SSieu Mun Tang }
9826dc00c24SSieu Mun Tang
9836dc00c24SSieu Mun Tang status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_OPEN_CS_SESSION,
9846dc00c24SSieu Mun Tang NULL, 0U, CMD_CASUAL, session_id, &resp_len);
9856dc00c24SSieu Mun Tang
9866dc00c24SSieu Mun Tang if (status < 0) {
9876dc00c24SSieu Mun Tang *mbox_error = -status;
9886dc00c24SSieu Mun Tang return INTEL_SIP_SMC_STATUS_ERROR;
9896dc00c24SSieu Mun Tang }
9906dc00c24SSieu Mun Tang
9916dc00c24SSieu Mun Tang return INTEL_SIP_SMC_STATUS_OK;
9926dc00c24SSieu Mun Tang }
9936dc00c24SSieu Mun Tang
intel_fcs_close_crypto_service_session(uint32_t session_id,uint32_t * mbox_error)9946dc00c24SSieu Mun Tang int intel_fcs_close_crypto_service_session(uint32_t session_id,
9956dc00c24SSieu Mun Tang uint32_t *mbox_error)
9966dc00c24SSieu Mun Tang {
9976dc00c24SSieu Mun Tang int status;
9986dc00c24SSieu Mun Tang
9996dc00c24SSieu Mun Tang if (mbox_error == NULL) {
10006dc00c24SSieu Mun Tang return INTEL_SIP_SMC_STATUS_REJECTED;
10016dc00c24SSieu Mun Tang }
10026dc00c24SSieu Mun Tang
10036dc00c24SSieu Mun Tang status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_CLOSE_CS_SESSION,
10046dc00c24SSieu Mun Tang &session_id, 1U, CMD_CASUAL, NULL, NULL);
10056dc00c24SSieu Mun Tang
10066dc00c24SSieu Mun Tang if (status < 0) {
10076dc00c24SSieu Mun Tang *mbox_error = -status;
10086dc00c24SSieu Mun Tang return INTEL_SIP_SMC_STATUS_ERROR;
10096dc00c24SSieu Mun Tang }
10106dc00c24SSieu Mun Tang
10116dc00c24SSieu Mun Tang return INTEL_SIP_SMC_STATUS_OK;
10126dc00c24SSieu Mun Tang }
1013342a0618SSieu Mun Tang
intel_fcs_import_crypto_service_key(uint64_t src_addr,uint32_t src_size,uint32_t * send_id)1014342a0618SSieu Mun Tang int intel_fcs_import_crypto_service_key(uint64_t src_addr, uint32_t src_size,
1015342a0618SSieu Mun Tang uint32_t *send_id)
1016342a0618SSieu Mun Tang {
1017342a0618SSieu Mun Tang int status;
1018342a0618SSieu Mun Tang
1019342a0618SSieu Mun Tang if (src_size > (FCS_CS_KEY_OBJ_MAX_WORD_SIZE *
1020342a0618SSieu Mun Tang MBOX_WORD_BYTE)) {
1021342a0618SSieu Mun Tang return INTEL_SIP_SMC_STATUS_REJECTED;
1022342a0618SSieu Mun Tang }
1023342a0618SSieu Mun Tang
1024342a0618SSieu Mun Tang if (!is_address_in_ddr_range(src_addr, src_size)) {
1025342a0618SSieu Mun Tang return INTEL_SIP_SMC_STATUS_REJECTED;
1026342a0618SSieu Mun Tang }
1027342a0618SSieu Mun Tang
1028342a0618SSieu Mun Tang status = mailbox_send_cmd_async(send_id, MBOX_FCS_IMPORT_CS_KEY,
1029342a0618SSieu Mun Tang (uint32_t *)src_addr, src_size / MBOX_WORD_BYTE,
1030342a0618SSieu Mun Tang CMD_INDIRECT);
1031342a0618SSieu Mun Tang
1032342a0618SSieu Mun Tang if (status < 0) {
1033342a0618SSieu Mun Tang return INTEL_SIP_SMC_STATUS_ERROR;
1034342a0618SSieu Mun Tang }
1035342a0618SSieu Mun Tang
1036342a0618SSieu Mun Tang return INTEL_SIP_SMC_STATUS_OK;
1037342a0618SSieu Mun Tang }
1038342a0618SSieu Mun Tang
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)1039342a0618SSieu Mun Tang int intel_fcs_export_crypto_service_key(uint32_t session_id, uint32_t key_id,
1040342a0618SSieu Mun Tang uint64_t dst_addr, uint32_t *dst_size,
1041342a0618SSieu Mun Tang uint32_t *mbox_error)
1042342a0618SSieu Mun Tang {
1043342a0618SSieu Mun Tang int status;
1044342a0618SSieu Mun Tang uint32_t i;
1045342a0618SSieu Mun Tang uint32_t payload_size;
1046342a0618SSieu Mun Tang uint32_t resp_len = FCS_CS_KEY_OBJ_MAX_WORD_SIZE;
1047342a0618SSieu Mun Tang uint32_t resp_data[FCS_CS_KEY_OBJ_MAX_WORD_SIZE] = {0U};
1048342a0618SSieu Mun Tang uint32_t op_status = 0U;
1049342a0618SSieu Mun Tang
1050342a0618SSieu Mun Tang if ((dst_size == NULL) || (mbox_error == NULL)) {
1051342a0618SSieu Mun Tang return INTEL_SIP_SMC_STATUS_REJECTED;
1052342a0618SSieu Mun Tang }
1053342a0618SSieu Mun Tang
1054342a0618SSieu Mun Tang if (!is_address_in_ddr_range(dst_addr, *dst_size)) {
1055342a0618SSieu Mun Tang return INTEL_SIP_SMC_STATUS_REJECTED;
1056342a0618SSieu Mun Tang }
1057342a0618SSieu Mun Tang
1058342a0618SSieu Mun Tang fcs_cs_key_payload payload = {
1059342a0618SSieu Mun Tang session_id,
1060342a0618SSieu Mun Tang RESERVED_AS_ZERO,
1061342a0618SSieu Mun Tang RESERVED_AS_ZERO,
1062342a0618SSieu Mun Tang key_id
1063342a0618SSieu Mun Tang };
1064342a0618SSieu Mun Tang
1065342a0618SSieu Mun Tang payload_size = sizeof(payload) / MBOX_WORD_BYTE;
1066342a0618SSieu Mun Tang
1067342a0618SSieu Mun Tang status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_EXPORT_CS_KEY,
1068342a0618SSieu Mun Tang (uint32_t *) &payload, payload_size,
1069342a0618SSieu Mun Tang CMD_CASUAL, resp_data, &resp_len);
1070342a0618SSieu Mun Tang
1071342a0618SSieu Mun Tang if (resp_len > 0) {
1072342a0618SSieu Mun Tang op_status = resp_data[0] & FCS_CS_KEY_RESP_STATUS_MASK;
1073342a0618SSieu Mun Tang }
1074342a0618SSieu Mun Tang
1075342a0618SSieu Mun Tang if (status < 0) {
1076342a0618SSieu Mun Tang *mbox_error = (-status) | (op_status << FCS_CS_KEY_RESP_STATUS_OFFSET);
1077342a0618SSieu Mun Tang return INTEL_SIP_SMC_STATUS_ERROR;
1078342a0618SSieu Mun Tang }
1079342a0618SSieu Mun Tang
1080342a0618SSieu Mun Tang if (resp_len > 1) {
1081342a0618SSieu Mun Tang
1082342a0618SSieu Mun Tang /* Export key object is start at second response data */
1083342a0618SSieu Mun Tang *dst_size = (resp_len - 1) * MBOX_WORD_BYTE;
1084342a0618SSieu Mun Tang
1085342a0618SSieu Mun Tang for (i = 1U; i < resp_len; i++) {
1086342a0618SSieu Mun Tang mmio_write_32(dst_addr, resp_data[i]);
1087342a0618SSieu Mun Tang dst_addr += MBOX_WORD_BYTE;
1088342a0618SSieu Mun Tang }
1089342a0618SSieu Mun Tang
1090342a0618SSieu Mun Tang flush_dcache_range(dst_addr - *dst_size, *dst_size);
1091342a0618SSieu Mun Tang
1092342a0618SSieu Mun Tang } else {
1093342a0618SSieu Mun Tang
1094342a0618SSieu Mun Tang /* Unexpected response, missing key object in response */
1095342a0618SSieu Mun Tang *mbox_error = MBOX_RET_ERROR;
1096342a0618SSieu Mun Tang return INTEL_SIP_SMC_STATUS_ERROR;
1097342a0618SSieu Mun Tang }
1098342a0618SSieu Mun Tang
1099342a0618SSieu Mun Tang return INTEL_SIP_SMC_STATUS_OK;
1100342a0618SSieu Mun Tang }
1101342a0618SSieu Mun Tang
intel_fcs_remove_crypto_service_key(uint32_t session_id,uint32_t key_id,uint32_t * mbox_error)1102342a0618SSieu Mun Tang int intel_fcs_remove_crypto_service_key(uint32_t session_id, uint32_t key_id,
1103342a0618SSieu Mun Tang uint32_t *mbox_error)
1104342a0618SSieu Mun Tang {
1105342a0618SSieu Mun Tang int status;
1106342a0618SSieu Mun Tang uint32_t payload_size;
1107342a0618SSieu Mun Tang uint32_t resp_len = 1U;
1108342a0618SSieu Mun Tang uint32_t resp_data = 0U;
1109342a0618SSieu Mun Tang uint32_t op_status = 0U;
1110342a0618SSieu Mun Tang
1111342a0618SSieu Mun Tang if (mbox_error == NULL) {
1112342a0618SSieu Mun Tang return INTEL_SIP_SMC_STATUS_REJECTED;
1113342a0618SSieu Mun Tang }
1114342a0618SSieu Mun Tang
1115342a0618SSieu Mun Tang fcs_cs_key_payload payload = {
1116342a0618SSieu Mun Tang session_id,
1117342a0618SSieu Mun Tang RESERVED_AS_ZERO,
1118342a0618SSieu Mun Tang RESERVED_AS_ZERO,
1119342a0618SSieu Mun Tang key_id
1120342a0618SSieu Mun Tang };
1121342a0618SSieu Mun Tang
1122342a0618SSieu Mun Tang payload_size = sizeof(payload) / MBOX_WORD_BYTE;
1123342a0618SSieu Mun Tang
1124342a0618SSieu Mun Tang status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_REMOVE_CS_KEY,
1125342a0618SSieu Mun Tang (uint32_t *) &payload, payload_size,
1126342a0618SSieu Mun Tang CMD_CASUAL, &resp_data, &resp_len);
1127342a0618SSieu Mun Tang
1128342a0618SSieu Mun Tang if (resp_len > 0) {
1129342a0618SSieu Mun Tang op_status = resp_data & FCS_CS_KEY_RESP_STATUS_MASK;
1130342a0618SSieu Mun Tang }
1131342a0618SSieu Mun Tang
1132342a0618SSieu Mun Tang if (status < 0) {
1133342a0618SSieu Mun Tang *mbox_error = (-status) | (op_status << FCS_CS_KEY_RESP_STATUS_OFFSET);
1134342a0618SSieu Mun Tang return INTEL_SIP_SMC_STATUS_ERROR;
1135342a0618SSieu Mun Tang }
1136342a0618SSieu Mun Tang
1137342a0618SSieu Mun Tang return INTEL_SIP_SMC_STATUS_OK;
1138342a0618SSieu Mun Tang }
1139342a0618SSieu Mun Tang
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)1140342a0618SSieu Mun Tang int intel_fcs_get_crypto_service_key_info(uint32_t session_id, uint32_t key_id,
1141342a0618SSieu Mun Tang uint64_t dst_addr, uint32_t *dst_size,
1142342a0618SSieu Mun Tang uint32_t *mbox_error)
1143342a0618SSieu Mun Tang {
1144342a0618SSieu Mun Tang int status;
1145342a0618SSieu Mun Tang uint32_t payload_size;
1146342a0618SSieu Mun Tang uint32_t resp_len = FCS_CS_KEY_INFO_MAX_WORD_SIZE;
1147342a0618SSieu Mun Tang uint32_t op_status = 0U;
1148342a0618SSieu Mun Tang
1149342a0618SSieu Mun Tang if ((dst_size == NULL) || (mbox_error == NULL)) {
1150342a0618SSieu Mun Tang return INTEL_SIP_SMC_STATUS_REJECTED;
1151342a0618SSieu Mun Tang }
1152342a0618SSieu Mun Tang
1153342a0618SSieu Mun Tang if (!is_address_in_ddr_range(dst_addr, *dst_size)) {
1154342a0618SSieu Mun Tang return INTEL_SIP_SMC_STATUS_REJECTED;
1155342a0618SSieu Mun Tang }
1156342a0618SSieu Mun Tang
1157342a0618SSieu Mun Tang fcs_cs_key_payload payload = {
1158342a0618SSieu Mun Tang session_id,
1159342a0618SSieu Mun Tang RESERVED_AS_ZERO,
1160342a0618SSieu Mun Tang RESERVED_AS_ZERO,
1161342a0618SSieu Mun Tang key_id
1162342a0618SSieu Mun Tang };
1163342a0618SSieu Mun Tang
1164342a0618SSieu Mun Tang payload_size = sizeof(payload) / MBOX_WORD_BYTE;
1165342a0618SSieu Mun Tang
1166342a0618SSieu Mun Tang status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_GET_CS_KEY_INFO,
1167342a0618SSieu Mun Tang (uint32_t *) &payload, payload_size,
1168342a0618SSieu Mun Tang CMD_CASUAL, (uint32_t *) dst_addr, &resp_len);
1169342a0618SSieu Mun Tang
1170342a0618SSieu Mun Tang if (resp_len > 0) {
1171731622feSJit Loon Lim inv_dcache_range(dst_addr, (resp_len * MBOX_WORD_BYTE)); /* flush cache before mmio read to avoid reading old values */
1172342a0618SSieu Mun Tang op_status = mmio_read_32(dst_addr) &
1173342a0618SSieu Mun Tang FCS_CS_KEY_RESP_STATUS_MASK;
1174342a0618SSieu Mun Tang }
1175342a0618SSieu Mun Tang
1176342a0618SSieu Mun Tang if (status < 0) {
1177342a0618SSieu Mun Tang *mbox_error = (-status) | (op_status << FCS_CS_KEY_RESP_STATUS_OFFSET);
1178342a0618SSieu Mun Tang return INTEL_SIP_SMC_STATUS_ERROR;
1179342a0618SSieu Mun Tang }
1180342a0618SSieu Mun Tang
1181342a0618SSieu Mun Tang *dst_size = resp_len * MBOX_WORD_BYTE;
1182342a0618SSieu Mun Tang flush_dcache_range(dst_addr, *dst_size);
1183342a0618SSieu Mun Tang
1184342a0618SSieu Mun Tang return INTEL_SIP_SMC_STATUS_OK;
1185342a0618SSieu Mun Tang }
11867e8249a2SSieu Mun Tang
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)11877e8249a2SSieu Mun Tang int intel_fcs_get_digest_init(uint32_t session_id, uint32_t context_id,
11887e8249a2SSieu Mun Tang uint32_t key_id, uint32_t param_size,
11897e8249a2SSieu Mun Tang uint64_t param_data, uint32_t *mbox_error)
11907e8249a2SSieu Mun Tang {
11917e8249a2SSieu Mun Tang return intel_fcs_crypto_service_init(session_id, context_id,
11927e8249a2SSieu Mun Tang key_id, param_size, param_data,
11937e8249a2SSieu Mun Tang (void *) &fcs_sha_get_digest_param,
11947e8249a2SSieu Mun Tang mbox_error);
11957e8249a2SSieu Mun Tang }
11967e8249a2SSieu Mun Tang
intel_fcs_get_digest_update_finalize(uint32_t smc_fid,uint32_t trans_id,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,uint32_t smmu_src_addr)1197597fff5fSGirisha Dengi int intel_fcs_get_digest_update_finalize(uint32_t smc_fid, uint32_t trans_id,
1198597fff5fSGirisha Dengi uint32_t session_id, uint32_t context_id,
1199597fff5fSGirisha Dengi uint32_t src_addr, uint32_t src_size,
1200597fff5fSGirisha Dengi uint64_t dst_addr, uint32_t *dst_size,
1201597fff5fSGirisha Dengi uint8_t is_finalised, uint32_t *mbox_error,
1202597fff5fSGirisha Dengi uint32_t smmu_src_addr)
12037e8249a2SSieu Mun Tang {
12047e8249a2SSieu Mun Tang int status;
12057e8249a2SSieu Mun Tang uint32_t i;
120670a7e6afSSieu Mun Tang uint32_t flag;
120770a7e6afSSieu Mun Tang uint32_t crypto_header;
1208fe5637f2SBoon Khai Ng uint32_t resp_len;
12097e8249a2SSieu Mun Tang uint32_t payload[FCS_GET_DIGEST_CMD_MAX_WORD_SIZE] = {0U};
12107e8249a2SSieu Mun Tang
12117e8249a2SSieu Mun Tang if (dst_size == NULL || mbox_error == NULL) {
12127e8249a2SSieu Mun Tang return INTEL_SIP_SMC_STATUS_REJECTED;
12137e8249a2SSieu Mun Tang }
12147e8249a2SSieu Mun Tang
12157e8249a2SSieu Mun Tang if (fcs_sha_get_digest_param.session_id != session_id ||
12167e8249a2SSieu Mun Tang fcs_sha_get_digest_param.context_id != context_id) {
12177e8249a2SSieu Mun Tang return INTEL_SIP_SMC_STATUS_REJECTED;
12187e8249a2SSieu Mun Tang }
12197e8249a2SSieu Mun Tang
12207e8249a2SSieu Mun Tang /* Source data must be 8 bytes aligned */
12217e8249a2SSieu Mun Tang if (!is_8_bytes_aligned(src_size)) {
12227e8249a2SSieu Mun Tang return INTEL_SIP_SMC_STATUS_REJECTED;
12237e8249a2SSieu Mun Tang }
12247e8249a2SSieu Mun Tang
12257e8249a2SSieu Mun Tang if (!is_address_in_ddr_range(src_addr, src_size) ||
12267e8249a2SSieu Mun Tang !is_address_in_ddr_range(dst_addr, *dst_size)) {
12277e8249a2SSieu Mun Tang return INTEL_SIP_SMC_STATUS_REJECTED;
12287e8249a2SSieu Mun Tang }
12297e8249a2SSieu Mun Tang
1230fe5637f2SBoon Khai Ng resp_len = *dst_size / MBOX_WORD_BYTE;
1231fe5637f2SBoon Khai Ng
123270a7e6afSSieu Mun Tang /* Prepare crypto header */
123370a7e6afSSieu Mun Tang flag = 0;
123470a7e6afSSieu Mun Tang
123570a7e6afSSieu Mun Tang if (fcs_sha_get_digest_param.is_updated) {
123670a7e6afSSieu Mun Tang fcs_sha_get_digest_param.crypto_param_size = 0;
123770a7e6afSSieu Mun Tang } else {
123870a7e6afSSieu Mun Tang flag |= FCS_CS_FIELD_FLAG_INIT;
123970a7e6afSSieu Mun Tang }
124070a7e6afSSieu Mun Tang
124170a7e6afSSieu Mun Tang if (is_finalised != 0U) {
124270a7e6afSSieu Mun Tang flag |= FCS_CS_FIELD_FLAG_FINALIZE;
124370a7e6afSSieu Mun Tang } else {
124470a7e6afSSieu Mun Tang flag |= FCS_CS_FIELD_FLAG_UPDATE;
124570a7e6afSSieu Mun Tang fcs_sha_get_digest_param.is_updated = 1;
124670a7e6afSSieu Mun Tang }
124770a7e6afSSieu Mun Tang
124870a7e6afSSieu Mun Tang crypto_header = ((flag << FCS_CS_FIELD_FLAG_OFFSET) |
124970a7e6afSSieu Mun Tang (fcs_sha_get_digest_param.crypto_param_size &
125070a7e6afSSieu Mun Tang FCS_CS_FIELD_SIZE_MASK));
125170a7e6afSSieu Mun Tang
12527e8249a2SSieu Mun Tang /* Prepare command payload */
12537e8249a2SSieu Mun Tang i = 0;
12547e8249a2SSieu Mun Tang payload[i] = fcs_sha_get_digest_param.session_id;
12557e8249a2SSieu Mun Tang i++;
12567e8249a2SSieu Mun Tang payload[i] = fcs_sha_get_digest_param.context_id;
12577e8249a2SSieu Mun Tang i++;
125870a7e6afSSieu Mun Tang payload[i] = crypto_header;
12597e8249a2SSieu Mun Tang i++;
126070a7e6afSSieu Mun Tang
126170a7e6afSSieu Mun Tang if ((crypto_header >> FCS_CS_FIELD_FLAG_OFFSET) &
126270a7e6afSSieu Mun Tang FCS_CS_FIELD_FLAG_INIT) {
12637e8249a2SSieu Mun Tang payload[i] = fcs_sha_get_digest_param.key_id;
12647e8249a2SSieu Mun Tang i++;
12657e8249a2SSieu Mun Tang /* Crypto parameters */
12667e8249a2SSieu Mun Tang payload[i] = fcs_sha_get_digest_param.crypto_param
12677e8249a2SSieu Mun Tang & INTEL_SIP_SMC_FCS_SHA_MODE_MASK;
12687e8249a2SSieu Mun Tang payload[i] |= ((fcs_sha_get_digest_param.crypto_param
12697e8249a2SSieu Mun Tang >> INTEL_SIP_SMC_FCS_DIGEST_SIZE_OFFSET)
12707e8249a2SSieu Mun Tang & INTEL_SIP_SMC_FCS_DIGEST_SIZE_MASK)
12717e8249a2SSieu Mun Tang << FCS_SHA_HMAC_CRYPTO_PARAM_SIZE_OFFSET;
12727e8249a2SSieu Mun Tang i++;
127370a7e6afSSieu Mun Tang }
12747e8249a2SSieu Mun Tang /* Data source address and size */
1275597fff5fSGirisha Dengi
1276597fff5fSGirisha Dengi /* On the Agilex5 platform, we will use the SMMU payload address */
1277597fff5fSGirisha Dengi #if PLATFORM_MODEL == PLAT_SOCFPGA_AGILEX5
1278597fff5fSGirisha Dengi payload[i] = smmu_src_addr;
1279597fff5fSGirisha Dengi #else
12807e8249a2SSieu Mun Tang payload[i] = src_addr;
1281597fff5fSGirisha Dengi #endif
12827e8249a2SSieu Mun Tang i++;
12837e8249a2SSieu Mun Tang payload[i] = src_size;
12847e8249a2SSieu Mun Tang i++;
12857e8249a2SSieu Mun Tang
1286597fff5fSGirisha Dengi status = ((smc_fid == ALTERA_SIP_SMC_ASYNC_FCS_GET_DIGEST_UPDATE) ||
1287597fff5fSGirisha Dengi (smc_fid == ALTERA_SIP_SMC_ASYNC_FCS_GET_DIGEST_FINALIZE)) ?
1288597fff5fSGirisha Dengi mailbox_send_cmd_async_v3(GET_CLIENT_ID(trans_id),
1289597fff5fSGirisha Dengi GET_JOB_ID(trans_id),
1290597fff5fSGirisha Dengi MBOX_FCS_GET_DIGEST_REQ,
1291597fff5fSGirisha Dengi payload,
1292597fff5fSGirisha Dengi i,
1293597fff5fSGirisha Dengi MBOX_CMD_FLAG_CASUAL,
1294597fff5fSGirisha Dengi fcs_cs_get_digest_cb,
1295597fff5fSGirisha Dengi (uint32_t *)dst_addr,
1296597fff5fSGirisha Dengi 2U) :
1297597fff5fSGirisha Dengi mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_GET_DIGEST_REQ,
12987e8249a2SSieu Mun Tang payload, i, CMD_CASUAL,
12997e8249a2SSieu Mun Tang (uint32_t *) dst_addr, &resp_len);
13007e8249a2SSieu Mun Tang
130170a7e6afSSieu Mun Tang if (is_finalised != 0U) {
130270a7e6afSSieu Mun Tang memset((void *)&fcs_sha_get_digest_param, 0,
130370a7e6afSSieu Mun Tang sizeof(fcs_crypto_service_data));
130470a7e6afSSieu Mun Tang }
13057e8249a2SSieu Mun Tang
13067e8249a2SSieu Mun Tang if (status < 0) {
13077e8249a2SSieu Mun Tang *mbox_error = -status;
13087e8249a2SSieu Mun Tang return INTEL_SIP_SMC_STATUS_ERROR;
13097e8249a2SSieu Mun Tang }
13107e8249a2SSieu Mun Tang
13117e8249a2SSieu Mun Tang *dst_size = resp_len * MBOX_WORD_BYTE;
13127e8249a2SSieu Mun Tang flush_dcache_range(dst_addr, *dst_size);
13137e8249a2SSieu Mun Tang
13147e8249a2SSieu Mun Tang return INTEL_SIP_SMC_STATUS_OK;
13157e8249a2SSieu Mun Tang }
1316c05ea296SSieu Mun Tang
intel_fcs_get_digest_smmu_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,uint32_t * send_id)13174687021dSSieu Mun Tang int intel_fcs_get_digest_smmu_update_finalize(uint32_t session_id,
13184687021dSSieu Mun Tang uint32_t context_id, uint32_t src_addr,
13194687021dSSieu Mun Tang uint32_t src_size, uint64_t dst_addr,
13204687021dSSieu Mun Tang uint32_t *dst_size, uint8_t is_finalised,
13214687021dSSieu Mun Tang uint32_t *mbox_error, uint32_t *send_id)
13224687021dSSieu Mun Tang {
13234687021dSSieu Mun Tang int status;
13244687021dSSieu Mun Tang uint32_t i;
13254687021dSSieu Mun Tang uint32_t flag;
13264687021dSSieu Mun Tang uint32_t crypto_header;
13274687021dSSieu Mun Tang uint32_t resp_len;
13284687021dSSieu Mun Tang uint32_t payload[FCS_GET_DIGEST_CMD_MAX_WORD_SIZE] = {0U};
13294687021dSSieu Mun Tang
13304687021dSSieu Mun Tang /* Source data must be 8 bytes aligned */
13314687021dSSieu Mun Tang if (dst_size == NULL || mbox_error == NULL ||
13324687021dSSieu Mun Tang !is_8_bytes_aligned(src_size)) {
13334687021dSSieu Mun Tang return INTEL_SIP_SMC_STATUS_REJECTED;
13344687021dSSieu Mun Tang }
13354687021dSSieu Mun Tang
13364687021dSSieu Mun Tang if (fcs_sha_get_digest_param.session_id != session_id ||
13374687021dSSieu Mun Tang fcs_sha_get_digest_param.context_id != context_id) {
13384687021dSSieu Mun Tang return INTEL_SIP_SMC_STATUS_REJECTED;
13394687021dSSieu Mun Tang }
13404687021dSSieu Mun Tang
13414687021dSSieu Mun Tang if (!is_address_in_ddr_range(src_addr, src_size) ||
13424687021dSSieu Mun Tang !is_address_in_ddr_range(dst_addr, *dst_size)) {
13434687021dSSieu Mun Tang return INTEL_SIP_SMC_STATUS_REJECTED;
13444687021dSSieu Mun Tang }
13454687021dSSieu Mun Tang
13464687021dSSieu Mun Tang resp_len = *dst_size / MBOX_WORD_BYTE;
13474687021dSSieu Mun Tang
13484687021dSSieu Mun Tang /* Prepare crypto header */
13494687021dSSieu Mun Tang flag = 0;
13504687021dSSieu Mun Tang
13514687021dSSieu Mun Tang if (fcs_sha_get_digest_param.is_updated) {
13524687021dSSieu Mun Tang fcs_sha_get_digest_param.crypto_param_size = 0;
13534687021dSSieu Mun Tang } else {
13544687021dSSieu Mun Tang flag |= FCS_CS_FIELD_FLAG_INIT;
13554687021dSSieu Mun Tang }
13564687021dSSieu Mun Tang
13574687021dSSieu Mun Tang if (is_finalised != 0U) {
13584687021dSSieu Mun Tang flag |= FCS_CS_FIELD_FLAG_FINALIZE;
13594687021dSSieu Mun Tang } else {
13604687021dSSieu Mun Tang flag |= FCS_CS_FIELD_FLAG_UPDATE;
13614687021dSSieu Mun Tang fcs_sha_get_digest_param.is_updated = 1;
13624687021dSSieu Mun Tang }
13634687021dSSieu Mun Tang
13644687021dSSieu Mun Tang crypto_header = ((flag << FCS_CS_FIELD_FLAG_OFFSET) |
13654687021dSSieu Mun Tang (fcs_sha_get_digest_param.crypto_param_size &
13664687021dSSieu Mun Tang FCS_CS_FIELD_SIZE_MASK));
13674687021dSSieu Mun Tang
13684687021dSSieu Mun Tang /* Prepare command payload */
13694687021dSSieu Mun Tang i = 0;
13704687021dSSieu Mun Tang payload[i] = fcs_sha_get_digest_param.session_id;
13714687021dSSieu Mun Tang i++;
13724687021dSSieu Mun Tang payload[i] = fcs_sha_get_digest_param.context_id;
13734687021dSSieu Mun Tang i++;
13744687021dSSieu Mun Tang payload[i] = crypto_header;
13754687021dSSieu Mun Tang i++;
13764687021dSSieu Mun Tang
13774687021dSSieu Mun Tang if ((crypto_header >> FCS_CS_FIELD_FLAG_OFFSET) &
13784687021dSSieu Mun Tang FCS_CS_FIELD_FLAG_INIT) {
13794687021dSSieu Mun Tang payload[i] = fcs_sha_get_digest_param.key_id;
13804687021dSSieu Mun Tang i++;
13814687021dSSieu Mun Tang /* Crypto parameters */
13824687021dSSieu Mun Tang payload[i] = fcs_sha_get_digest_param.crypto_param
13834687021dSSieu Mun Tang & INTEL_SIP_SMC_FCS_SHA_MODE_MASK;
13844687021dSSieu Mun Tang payload[i] |= ((fcs_sha_get_digest_param.crypto_param
13854687021dSSieu Mun Tang >> INTEL_SIP_SMC_FCS_DIGEST_SIZE_OFFSET)
13864687021dSSieu Mun Tang & INTEL_SIP_SMC_FCS_DIGEST_SIZE_MASK)
13874687021dSSieu Mun Tang << FCS_SHA_HMAC_CRYPTO_PARAM_SIZE_OFFSET;
13884687021dSSieu Mun Tang i++;
13894687021dSSieu Mun Tang }
13904687021dSSieu Mun Tang /* Data source address and size */
13914687021dSSieu Mun Tang payload[i] = src_addr;
13924687021dSSieu Mun Tang i++;
13934687021dSSieu Mun Tang payload[i] = src_size;
13944687021dSSieu Mun Tang i++;
13954687021dSSieu Mun Tang
13964687021dSSieu Mun Tang status = mailbox_send_cmd_async(send_id, MBOX_FCS_GET_DIGEST_REQ,
13974687021dSSieu Mun Tang payload, i, CMD_INDIRECT);
13984687021dSSieu Mun Tang
13994687021dSSieu Mun Tang if (is_finalised != 0U) {
14004687021dSSieu Mun Tang memset((void *)&fcs_sha_get_digest_param, 0,
14014687021dSSieu Mun Tang sizeof(fcs_crypto_service_data));
14024687021dSSieu Mun Tang }
14034687021dSSieu Mun Tang
14044687021dSSieu Mun Tang if (status < 0) {
14054687021dSSieu Mun Tang *mbox_error = -status;
14064687021dSSieu Mun Tang return INTEL_SIP_SMC_STATUS_ERROR;
14074687021dSSieu Mun Tang }
14084687021dSSieu Mun Tang
14094687021dSSieu Mun Tang *dst_size = resp_len * MBOX_WORD_BYTE;
14104687021dSSieu Mun Tang flush_dcache_range(dst_addr, *dst_size);
14114687021dSSieu Mun Tang
14124687021dSSieu Mun Tang return INTEL_SIP_SMC_STATUS_OK;
14134687021dSSieu Mun Tang }
14144687021dSSieu Mun Tang
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)1415c05ea296SSieu Mun Tang int intel_fcs_mac_verify_init(uint32_t session_id, uint32_t context_id,
1416c05ea296SSieu Mun Tang uint32_t key_id, uint32_t param_size,
1417c05ea296SSieu Mun Tang uint64_t param_data, uint32_t *mbox_error)
1418c05ea296SSieu Mun Tang {
1419c05ea296SSieu Mun Tang return intel_fcs_crypto_service_init(session_id, context_id,
1420c05ea296SSieu Mun Tang key_id, param_size, param_data,
1421c05ea296SSieu Mun Tang (void *) &fcs_sha_mac_verify_param,
1422c05ea296SSieu Mun Tang mbox_error);
1423c05ea296SSieu Mun Tang }
1424c05ea296SSieu Mun Tang
intel_fcs_mac_verify_update_finalize(uint32_t smc_fid,uint32_t trans_id,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,uint64_t smmu_src_addr)1425597fff5fSGirisha Dengi int intel_fcs_mac_verify_update_finalize(uint32_t smc_fid, uint32_t trans_id,
1426597fff5fSGirisha Dengi uint32_t session_id, uint32_t context_id,
1427597fff5fSGirisha Dengi uint32_t src_addr, uint32_t src_size,
1428597fff5fSGirisha Dengi uint64_t dst_addr, uint32_t *dst_size,
1429597fff5fSGirisha Dengi uint32_t data_size, uint8_t is_finalised,
1430597fff5fSGirisha Dengi uint32_t *mbox_error, uint64_t smmu_src_addr)
1431c05ea296SSieu Mun Tang {
1432c05ea296SSieu Mun Tang int status;
1433c05ea296SSieu Mun Tang uint32_t i;
143470a7e6afSSieu Mun Tang uint32_t flag;
143570a7e6afSSieu Mun Tang uint32_t crypto_header;
1436fe5637f2SBoon Khai Ng uint32_t resp_len;
1437c05ea296SSieu Mun Tang uint32_t payload[FCS_MAC_VERIFY_CMD_MAX_WORD_SIZE] = {0U};
1438c05ea296SSieu Mun Tang uintptr_t mac_offset;
1439c418064eSJit Loon Lim uint32_t dst_size_check = 0;
1440c05ea296SSieu Mun Tang
1441c05ea296SSieu Mun Tang if (dst_size == NULL || mbox_error == NULL) {
1442c05ea296SSieu Mun Tang return INTEL_SIP_SMC_STATUS_REJECTED;
1443c05ea296SSieu Mun Tang }
1444c05ea296SSieu Mun Tang
1445c05ea296SSieu Mun Tang if (fcs_sha_mac_verify_param.session_id != session_id ||
1446c05ea296SSieu Mun Tang fcs_sha_mac_verify_param.context_id != context_id) {
1447c05ea296SSieu Mun Tang return INTEL_SIP_SMC_STATUS_REJECTED;
1448c05ea296SSieu Mun Tang }
1449c05ea296SSieu Mun Tang
1450fbf7aef4SSieu Mun Tang if (data_size > src_size) {
1451c05ea296SSieu Mun Tang return INTEL_SIP_SMC_STATUS_REJECTED;
1452c05ea296SSieu Mun Tang }
1453c05ea296SSieu Mun Tang
1454c05ea296SSieu Mun Tang if (!is_size_4_bytes_aligned(src_size) ||
1455c05ea296SSieu Mun Tang !is_8_bytes_aligned(data_size)) {
1456c05ea296SSieu Mun Tang return INTEL_SIP_SMC_STATUS_REJECTED;
1457c05ea296SSieu Mun Tang }
1458c05ea296SSieu Mun Tang
1459c05ea296SSieu Mun Tang if (!is_address_in_ddr_range(src_addr, src_size) ||
1460c05ea296SSieu Mun Tang !is_address_in_ddr_range(dst_addr, *dst_size)) {
1461c05ea296SSieu Mun Tang return INTEL_SIP_SMC_STATUS_REJECTED;
1462c05ea296SSieu Mun Tang }
1463c05ea296SSieu Mun Tang
1464c418064eSJit Loon Lim dst_size_check = *dst_size;
1465c418064eSJit Loon Lim if ((dst_size_check > FCS_MAX_DATA_SIZE ||
1466c418064eSJit Loon Lim dst_size_check < FCS_MIN_DATA_SIZE) ||
1467c418064eSJit Loon Lim (src_size > FCS_MAX_DATA_SIZE ||
1468c418064eSJit Loon Lim src_size < FCS_MIN_DATA_SIZE)) {
1469c418064eSJit Loon Lim return INTEL_SIP_SMC_STATUS_REJECTED;
1470c418064eSJit Loon Lim }
1471c418064eSJit Loon Lim
1472fe5637f2SBoon Khai Ng resp_len = *dst_size / MBOX_WORD_BYTE;
1473fe5637f2SBoon Khai Ng
147470a7e6afSSieu Mun Tang /* Prepare crypto header */
147570a7e6afSSieu Mun Tang flag = 0;
147670a7e6afSSieu Mun Tang
147770a7e6afSSieu Mun Tang if (fcs_sha_mac_verify_param.is_updated) {
147870a7e6afSSieu Mun Tang fcs_sha_mac_verify_param.crypto_param_size = 0;
147970a7e6afSSieu Mun Tang } else {
148070a7e6afSSieu Mun Tang flag |= FCS_CS_FIELD_FLAG_INIT;
148170a7e6afSSieu Mun Tang }
148270a7e6afSSieu Mun Tang
148370a7e6afSSieu Mun Tang if (is_finalised) {
148470a7e6afSSieu Mun Tang flag |= FCS_CS_FIELD_FLAG_FINALIZE;
148570a7e6afSSieu Mun Tang } else {
148670a7e6afSSieu Mun Tang flag |= FCS_CS_FIELD_FLAG_UPDATE;
148770a7e6afSSieu Mun Tang fcs_sha_mac_verify_param.is_updated = 1;
148870a7e6afSSieu Mun Tang }
148970a7e6afSSieu Mun Tang
149070a7e6afSSieu Mun Tang crypto_header = ((flag << FCS_CS_FIELD_FLAG_OFFSET) |
149170a7e6afSSieu Mun Tang (fcs_sha_mac_verify_param.crypto_param_size &
149270a7e6afSSieu Mun Tang FCS_CS_FIELD_SIZE_MASK));
149370a7e6afSSieu Mun Tang
1494c05ea296SSieu Mun Tang /* Prepare command payload */
1495c05ea296SSieu Mun Tang i = 0;
1496c05ea296SSieu Mun Tang payload[i] = fcs_sha_mac_verify_param.session_id;
1497c05ea296SSieu Mun Tang i++;
1498c05ea296SSieu Mun Tang payload[i] = fcs_sha_mac_verify_param.context_id;
1499c05ea296SSieu Mun Tang i++;
150070a7e6afSSieu Mun Tang payload[i] = crypto_header;
1501c05ea296SSieu Mun Tang i++;
150270a7e6afSSieu Mun Tang
150370a7e6afSSieu Mun Tang if ((crypto_header >> FCS_CS_FIELD_FLAG_OFFSET) &
150470a7e6afSSieu Mun Tang FCS_CS_FIELD_FLAG_INIT) {
1505c05ea296SSieu Mun Tang payload[i] = fcs_sha_mac_verify_param.key_id;
1506c05ea296SSieu Mun Tang i++;
1507c05ea296SSieu Mun Tang /* Crypto parameters */
1508c05ea296SSieu Mun Tang payload[i] = ((fcs_sha_mac_verify_param.crypto_param
1509c05ea296SSieu Mun Tang >> INTEL_SIP_SMC_FCS_DIGEST_SIZE_OFFSET)
1510c05ea296SSieu Mun Tang & INTEL_SIP_SMC_FCS_DIGEST_SIZE_MASK)
1511c05ea296SSieu Mun Tang << FCS_SHA_HMAC_CRYPTO_PARAM_SIZE_OFFSET;
1512c05ea296SSieu Mun Tang i++;
151370a7e6afSSieu Mun Tang }
1514597fff5fSGirisha Dengi
1515c05ea296SSieu Mun Tang /* Data source address and size */
1516597fff5fSGirisha Dengi #if PLATFORM_MODEL == PLAT_SOCFPGA_AGILEX5
1517597fff5fSGirisha Dengi payload[i] = (uint32_t)smmu_src_addr;
1518597fff5fSGirisha Dengi #else
1519c05ea296SSieu Mun Tang payload[i] = src_addr;
1520597fff5fSGirisha Dengi #endif
1521c05ea296SSieu Mun Tang i++;
1522c05ea296SSieu Mun Tang payload[i] = data_size;
1523c05ea296SSieu Mun Tang i++;
152470a7e6afSSieu Mun Tang
152570a7e6afSSieu Mun Tang if ((crypto_header >> FCS_CS_FIELD_FLAG_OFFSET) &
152670a7e6afSSieu Mun Tang FCS_CS_FIELD_FLAG_FINALIZE) {
1527c05ea296SSieu Mun Tang /* Copy mac data to command */
1528c05ea296SSieu Mun Tang mac_offset = src_addr + data_size;
1529c418064eSJit Loon Lim
1530c418064eSJit Loon Lim if ((i + ((src_size - data_size) / MBOX_WORD_BYTE)) >
1531c418064eSJit Loon Lim FCS_MAC_VERIFY_CMD_MAX_WORD_SIZE) {
1532c418064eSJit Loon Lim return INTEL_SIP_SMC_STATUS_REJECTED;
1533c418064eSJit Loon Lim }
1534c418064eSJit Loon Lim
1535e264b557SSieu Mun Tang memcpy_s(&payload[i], (src_size - data_size) / MBOX_WORD_BYTE,
1536e264b557SSieu Mun Tang (void *) mac_offset, (src_size - data_size) / MBOX_WORD_BYTE);
1537c05ea296SSieu Mun Tang
1538c05ea296SSieu Mun Tang i += (src_size - data_size) / MBOX_WORD_BYTE;
153970a7e6afSSieu Mun Tang }
1540c05ea296SSieu Mun Tang
1541597fff5fSGirisha Dengi status = ((smc_fid == ALTERA_SIP_SMC_ASYNC_FCS_MAC_VERIFY_UPDATE) ||
1542597fff5fSGirisha Dengi (smc_fid == ALTERA_SIP_SMC_ASYNC_FCS_MAC_VERIFY_FINALIZE)) ?
1543597fff5fSGirisha Dengi mailbox_send_cmd_async_v3(GET_CLIENT_ID(trans_id),
1544597fff5fSGirisha Dengi GET_JOB_ID(trans_id),
1545597fff5fSGirisha Dengi MBOX_FCS_MAC_VERIFY_REQ,
1546597fff5fSGirisha Dengi payload,
1547597fff5fSGirisha Dengi i,
1548597fff5fSGirisha Dengi MBOX_CMD_FLAG_CASUAL,
1549597fff5fSGirisha Dengi fcs_cs_mac_verify_cb,
1550597fff5fSGirisha Dengi (uint32_t *)dst_addr,
1551597fff5fSGirisha Dengi 2U) :
1552597fff5fSGirisha Dengi mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_MAC_VERIFY_REQ,
1553c05ea296SSieu Mun Tang payload, i, CMD_CASUAL,
1554c05ea296SSieu Mun Tang (uint32_t *) dst_addr, &resp_len);
1555c05ea296SSieu Mun Tang
155670a7e6afSSieu Mun Tang if (is_finalised) {
1557c05ea296SSieu Mun Tang memset((void *)&fcs_sha_mac_verify_param, 0,
1558c05ea296SSieu Mun Tang sizeof(fcs_crypto_service_data));
155970a7e6afSSieu Mun Tang }
1560c05ea296SSieu Mun Tang
1561c05ea296SSieu Mun Tang if (status < 0) {
1562c05ea296SSieu Mun Tang *mbox_error = -status;
1563c05ea296SSieu Mun Tang return INTEL_SIP_SMC_STATUS_ERROR;
1564c05ea296SSieu Mun Tang }
1565c05ea296SSieu Mun Tang
1566c05ea296SSieu Mun Tang *dst_size = resp_len * MBOX_WORD_BYTE;
1567c05ea296SSieu Mun Tang flush_dcache_range(dst_addr, *dst_size);
1568c05ea296SSieu Mun Tang
1569c05ea296SSieu Mun Tang return INTEL_SIP_SMC_STATUS_OK;
1570c05ea296SSieu Mun Tang }
15716726390eSSieu Mun Tang
intel_fcs_mac_verify_smmu_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,uint32_t * send_id)15724687021dSSieu Mun Tang int intel_fcs_mac_verify_smmu_update_finalize(uint32_t session_id,
15734687021dSSieu Mun Tang uint32_t context_id, uint32_t src_addr,
15744687021dSSieu Mun Tang uint32_t src_size, uint64_t dst_addr,
15754687021dSSieu Mun Tang uint32_t *dst_size, uint32_t data_size,
15764687021dSSieu Mun Tang uint8_t is_finalised, uint32_t *mbox_error,
15774687021dSSieu Mun Tang uint32_t *send_id)
15784687021dSSieu Mun Tang {
15794687021dSSieu Mun Tang int status;
15804687021dSSieu Mun Tang uint32_t i;
15814687021dSSieu Mun Tang uint32_t flag;
15824687021dSSieu Mun Tang uint32_t crypto_header;
15834687021dSSieu Mun Tang uint32_t resp_len;
15844687021dSSieu Mun Tang uint32_t payload[FCS_MAC_VERIFY_CMD_MAX_WORD_SIZE] = {0U};
15854687021dSSieu Mun Tang uintptr_t mac_offset;
1586c418064eSJit Loon Lim uint32_t dst_size_check = 0;
15874687021dSSieu Mun Tang /*
15884687021dSSieu Mun Tang * Source data must be 4 bytes aligned
15894687021dSSieu Mun Tang * User data must be 8 bytes aligned
15904687021dSSieu Mun Tang */
15914687021dSSieu Mun Tang if (dst_size == NULL || mbox_error == NULL ||
15924687021dSSieu Mun Tang !is_size_4_bytes_aligned(src_size) ||
15934687021dSSieu Mun Tang !is_8_bytes_aligned(data_size)) {
15944687021dSSieu Mun Tang return INTEL_SIP_SMC_STATUS_REJECTED;
15954687021dSSieu Mun Tang }
15964687021dSSieu Mun Tang
15974687021dSSieu Mun Tang if (data_size > src_size) {
15984687021dSSieu Mun Tang return INTEL_SIP_SMC_STATUS_REJECTED;
15994687021dSSieu Mun Tang }
16004687021dSSieu Mun Tang
16014687021dSSieu Mun Tang if (fcs_sha_mac_verify_param.session_id != session_id ||
16024687021dSSieu Mun Tang fcs_sha_mac_verify_param.context_id != context_id) {
16034687021dSSieu Mun Tang return INTEL_SIP_SMC_STATUS_REJECTED;
16044687021dSSieu Mun Tang }
16054687021dSSieu Mun Tang
16064687021dSSieu Mun Tang if (!is_address_in_ddr_range(src_addr, src_size) ||
16074687021dSSieu Mun Tang !is_address_in_ddr_range(dst_addr, *dst_size)) {
16084687021dSSieu Mun Tang return INTEL_SIP_SMC_STATUS_REJECTED;
16094687021dSSieu Mun Tang }
16104687021dSSieu Mun Tang
1611c418064eSJit Loon Lim dst_size_check = *dst_size;
1612c418064eSJit Loon Lim if ((dst_size_check > FCS_MAX_DATA_SIZE ||
1613c418064eSJit Loon Lim dst_size_check < FCS_MIN_DATA_SIZE) ||
1614c418064eSJit Loon Lim (src_size > FCS_MAX_DATA_SIZE ||
1615c418064eSJit Loon Lim src_size < FCS_MIN_DATA_SIZE)) {
1616c418064eSJit Loon Lim return INTEL_SIP_SMC_STATUS_REJECTED;
1617c418064eSJit Loon Lim }
1618c418064eSJit Loon Lim
16194687021dSSieu Mun Tang resp_len = *dst_size / MBOX_WORD_BYTE;
16204687021dSSieu Mun Tang
16214687021dSSieu Mun Tang /* Prepare crypto header */
16224687021dSSieu Mun Tang flag = 0;
16234687021dSSieu Mun Tang
16244687021dSSieu Mun Tang if (fcs_sha_mac_verify_param.is_updated) {
16254687021dSSieu Mun Tang fcs_sha_mac_verify_param.crypto_param_size = 0;
16264687021dSSieu Mun Tang } else {
16274687021dSSieu Mun Tang flag |= FCS_CS_FIELD_FLAG_INIT;
16284687021dSSieu Mun Tang }
16294687021dSSieu Mun Tang
16304687021dSSieu Mun Tang if (is_finalised) {
16314687021dSSieu Mun Tang flag |= FCS_CS_FIELD_FLAG_FINALIZE;
16324687021dSSieu Mun Tang } else {
16334687021dSSieu Mun Tang flag |= FCS_CS_FIELD_FLAG_UPDATE;
16344687021dSSieu Mun Tang fcs_sha_mac_verify_param.is_updated = 1;
16354687021dSSieu Mun Tang }
16364687021dSSieu Mun Tang
16374687021dSSieu Mun Tang crypto_header = ((flag << FCS_CS_FIELD_FLAG_OFFSET) |
16384687021dSSieu Mun Tang (fcs_sha_mac_verify_param.crypto_param_size &
16394687021dSSieu Mun Tang FCS_CS_FIELD_SIZE_MASK));
16404687021dSSieu Mun Tang
16414687021dSSieu Mun Tang /* Prepare command payload */
16424687021dSSieu Mun Tang i = 0;
16434687021dSSieu Mun Tang payload[i] = fcs_sha_mac_verify_param.session_id;
16444687021dSSieu Mun Tang i++;
16454687021dSSieu Mun Tang payload[i] = fcs_sha_mac_verify_param.context_id;
16464687021dSSieu Mun Tang i++;
16474687021dSSieu Mun Tang payload[i] = crypto_header;
16484687021dSSieu Mun Tang i++;
16494687021dSSieu Mun Tang
16504687021dSSieu Mun Tang if ((crypto_header >> FCS_CS_FIELD_FLAG_OFFSET) &
16514687021dSSieu Mun Tang FCS_CS_FIELD_FLAG_INIT) {
16524687021dSSieu Mun Tang payload[i] = fcs_sha_mac_verify_param.key_id;
16534687021dSSieu Mun Tang i++;
16544687021dSSieu Mun Tang /* Crypto parameters */
16554687021dSSieu Mun Tang payload[i] = ((fcs_sha_mac_verify_param.crypto_param
16564687021dSSieu Mun Tang >> INTEL_SIP_SMC_FCS_DIGEST_SIZE_OFFSET)
16574687021dSSieu Mun Tang & INTEL_SIP_SMC_FCS_DIGEST_SIZE_MASK)
16584687021dSSieu Mun Tang << FCS_SHA_HMAC_CRYPTO_PARAM_SIZE_OFFSET;
16594687021dSSieu Mun Tang i++;
16604687021dSSieu Mun Tang }
16614687021dSSieu Mun Tang /* Data source address and size */
16624687021dSSieu Mun Tang payload[i] = src_addr;
16634687021dSSieu Mun Tang i++;
16644687021dSSieu Mun Tang payload[i] = data_size;
16654687021dSSieu Mun Tang i++;
16664687021dSSieu Mun Tang
16674687021dSSieu Mun Tang if ((crypto_header >> FCS_CS_FIELD_FLAG_OFFSET) &
16684687021dSSieu Mun Tang FCS_CS_FIELD_FLAG_FINALIZE) {
16694687021dSSieu Mun Tang /* Copy mac data to command
16704687021dSSieu Mun Tang * Using dst_addr (physical address) to store mac_offset
16714687021dSSieu Mun Tang * mac_offset = MAC data
16724687021dSSieu Mun Tang */
16734687021dSSieu Mun Tang mac_offset = dst_addr;
1674c418064eSJit Loon Lim
1675c418064eSJit Loon Lim if ((i + ((src_size - data_size) / MBOX_WORD_BYTE)) >
1676c418064eSJit Loon Lim FCS_MAC_VERIFY_CMD_MAX_WORD_SIZE) {
1677c418064eSJit Loon Lim return INTEL_SIP_SMC_STATUS_REJECTED;
1678c418064eSJit Loon Lim }
1679c418064eSJit Loon Lim
1680e264b557SSieu Mun Tang memcpy_s(&payload[i], (src_size - data_size) / MBOX_WORD_BYTE,
1681e264b557SSieu Mun Tang (void *) mac_offset, (src_size - data_size) / MBOX_WORD_BYTE);
16824687021dSSieu Mun Tang
1683afe9fcc3SSieu Mun Tang memset((void *) dst_addr, 0, *dst_size);
16844687021dSSieu Mun Tang
16854687021dSSieu Mun Tang i += (src_size - data_size) / MBOX_WORD_BYTE;
16864687021dSSieu Mun Tang }
16874687021dSSieu Mun Tang
16884687021dSSieu Mun Tang status = mailbox_send_cmd_async(send_id, MBOX_FCS_MAC_VERIFY_REQ,
16894687021dSSieu Mun Tang payload, i, CMD_INDIRECT);
16904687021dSSieu Mun Tang
16914687021dSSieu Mun Tang if (is_finalised) {
16924687021dSSieu Mun Tang memset((void *)&fcs_sha_mac_verify_param, 0,
16934687021dSSieu Mun Tang sizeof(fcs_crypto_service_data));
16944687021dSSieu Mun Tang }
16954687021dSSieu Mun Tang
16964687021dSSieu Mun Tang if (status < 0) {
16974687021dSSieu Mun Tang *mbox_error = -status;
16984687021dSSieu Mun Tang return INTEL_SIP_SMC_STATUS_ERROR;
16994687021dSSieu Mun Tang }
17004687021dSSieu Mun Tang
17014687021dSSieu Mun Tang *dst_size = resp_len * MBOX_WORD_BYTE;
17024687021dSSieu Mun Tang flush_dcache_range(dst_addr, *dst_size);
17034687021dSSieu Mun Tang
17044687021dSSieu Mun Tang return INTEL_SIP_SMC_STATUS_OK;
17054687021dSSieu Mun Tang }
17064687021dSSieu Mun Tang
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)170769254105SSieu Mun Tang int intel_fcs_ecdsa_hash_sign_init(uint32_t session_id, uint32_t context_id,
170869254105SSieu Mun Tang uint32_t key_id, uint32_t param_size,
170969254105SSieu Mun Tang uint64_t param_data, uint32_t *mbox_error)
171069254105SSieu Mun Tang {
171169254105SSieu Mun Tang return intel_fcs_crypto_service_init(session_id, context_id,
171269254105SSieu Mun Tang key_id, param_size, param_data,
171369254105SSieu Mun Tang (void *) &fcs_ecdsa_hash_sign_param,
171469254105SSieu Mun Tang mbox_error);
171569254105SSieu Mun Tang }
171669254105SSieu Mun Tang
intel_fcs_ecdsa_hash_sign_finalize(uint32_t smc_fid,uint32_t trans_id,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)1717597fff5fSGirisha Dengi int intel_fcs_ecdsa_hash_sign_finalize(uint32_t smc_fid, uint32_t trans_id,
1718597fff5fSGirisha Dengi uint32_t session_id, uint32_t context_id,
171969254105SSieu Mun Tang uint32_t src_addr, uint32_t src_size,
172069254105SSieu Mun Tang uint64_t dst_addr, uint32_t *dst_size,
172169254105SSieu Mun Tang uint32_t *mbox_error)
172269254105SSieu Mun Tang {
172369254105SSieu Mun Tang int status;
172469254105SSieu Mun Tang uint32_t i;
172569254105SSieu Mun Tang uint32_t payload[FCS_ECDSA_HASH_SIGN_CMD_MAX_WORD_SIZE] = {0U};
1726fe5637f2SBoon Khai Ng uint32_t resp_len;
172769254105SSieu Mun Tang uintptr_t hash_data_addr;
1728c418064eSJit Loon Lim uint32_t dst_size_check = 0;
172969254105SSieu Mun Tang
173069254105SSieu Mun Tang if ((dst_size == NULL) || (mbox_error == NULL)) {
173169254105SSieu Mun Tang return INTEL_SIP_SMC_STATUS_REJECTED;
173269254105SSieu Mun Tang }
173369254105SSieu Mun Tang
173469254105SSieu Mun Tang if (fcs_ecdsa_hash_sign_param.session_id != session_id ||
173569254105SSieu Mun Tang fcs_ecdsa_hash_sign_param.context_id != context_id) {
173669254105SSieu Mun Tang return INTEL_SIP_SMC_STATUS_REJECTED;
173769254105SSieu Mun Tang }
173869254105SSieu Mun Tang
173969254105SSieu Mun Tang if (!is_address_in_ddr_range(src_addr, src_size) ||
174069254105SSieu Mun Tang !is_address_in_ddr_range(dst_addr, *dst_size)) {
174169254105SSieu Mun Tang return INTEL_SIP_SMC_STATUS_REJECTED;
174269254105SSieu Mun Tang }
174369254105SSieu Mun Tang
1744c418064eSJit Loon Lim dst_size_check = *dst_size;
1745c418064eSJit Loon Lim if ((dst_size_check > FCS_MAX_DATA_SIZE ||
1746c418064eSJit Loon Lim dst_size_check < FCS_MIN_DATA_SIZE) ||
1747c418064eSJit Loon Lim (src_size > FCS_MAX_DATA_SIZE ||
1748c418064eSJit Loon Lim src_size < FCS_MIN_DATA_SIZE)) {
1749c418064eSJit Loon Lim return INTEL_SIP_SMC_STATUS_REJECTED;
1750c418064eSJit Loon Lim }
1751c418064eSJit Loon Lim
1752fe5637f2SBoon Khai Ng resp_len = *dst_size / MBOX_WORD_BYTE;
1753fe5637f2SBoon Khai Ng
175469254105SSieu Mun Tang /* Prepare command payload */
175569254105SSieu Mun Tang /* Crypto header */
175669254105SSieu Mun Tang i = 0;
175769254105SSieu Mun Tang payload[i] = fcs_ecdsa_hash_sign_param.session_id;
175869254105SSieu Mun Tang i++;
175969254105SSieu Mun Tang payload[i] = fcs_ecdsa_hash_sign_param.context_id;
176069254105SSieu Mun Tang
176169254105SSieu Mun Tang i++;
176269254105SSieu Mun Tang payload[i] = fcs_ecdsa_hash_sign_param.crypto_param_size
176369254105SSieu Mun Tang & FCS_CS_FIELD_SIZE_MASK;
176469254105SSieu Mun Tang payload[i] |= (FCS_CS_FIELD_FLAG_INIT | FCS_CS_FIELD_FLAG_UPDATE
176569254105SSieu Mun Tang | FCS_CS_FIELD_FLAG_FINALIZE)
176669254105SSieu Mun Tang << FCS_CS_FIELD_FLAG_OFFSET;
176769254105SSieu Mun Tang i++;
176869254105SSieu Mun Tang payload[i] = fcs_ecdsa_hash_sign_param.key_id;
176969254105SSieu Mun Tang
177069254105SSieu Mun Tang /* Crypto parameters */
177169254105SSieu Mun Tang i++;
177269254105SSieu Mun Tang payload[i] = fcs_ecdsa_hash_sign_param.crypto_param
177369254105SSieu Mun Tang & INTEL_SIP_SMC_FCS_ECC_ALGO_MASK;
177469254105SSieu Mun Tang
177569254105SSieu Mun Tang /* Hash Data */
177669254105SSieu Mun Tang i++;
177769254105SSieu Mun Tang hash_data_addr = src_addr;
1778c418064eSJit Loon Lim
1779c418064eSJit Loon Lim if ((i + ((src_size) / MBOX_WORD_BYTE)) >
1780c418064eSJit Loon Lim FCS_ECDSA_HASH_SIGN_CMD_MAX_WORD_SIZE) {
1781c418064eSJit Loon Lim return INTEL_SIP_SMC_STATUS_REJECTED;
1782c418064eSJit Loon Lim }
1783c418064eSJit Loon Lim
1784e264b557SSieu Mun Tang memcpy_s(&payload[i], src_size / MBOX_WORD_BYTE,
1785e264b557SSieu Mun Tang (void *) hash_data_addr, src_size / MBOX_WORD_BYTE);
178669254105SSieu Mun Tang
178769254105SSieu Mun Tang i += src_size / MBOX_WORD_BYTE;
178869254105SSieu Mun Tang
1789597fff5fSGirisha Dengi status = (smc_fid == ALTERA_SIP_SMC_ASYNC_FCS_ECDSA_HASH_SIGN_FINALIZE) ?
1790597fff5fSGirisha Dengi mailbox_send_cmd_async_v3(GET_CLIENT_ID(trans_id),
1791597fff5fSGirisha Dengi GET_JOB_ID(trans_id),
1792597fff5fSGirisha Dengi MBOX_FCS_ECDSA_HASH_SIGN_REQ,
1793597fff5fSGirisha Dengi payload,
1794597fff5fSGirisha Dengi i,
1795597fff5fSGirisha Dengi MBOX_CMD_FLAG_CASUAL,
1796597fff5fSGirisha Dengi fcs_cs_hash_sign_req_cb,
1797597fff5fSGirisha Dengi (uint32_t *)dst_addr,
1798597fff5fSGirisha Dengi 2U) :
1799597fff5fSGirisha Dengi mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_ECDSA_HASH_SIGN_REQ,
180069254105SSieu Mun Tang payload, i, CMD_CASUAL, (uint32_t *) dst_addr,
180169254105SSieu Mun Tang &resp_len);
180269254105SSieu Mun Tang
180369254105SSieu Mun Tang memset((void *) &fcs_ecdsa_hash_sign_param,
180469254105SSieu Mun Tang 0, sizeof(fcs_crypto_service_data));
180569254105SSieu Mun Tang
180669254105SSieu Mun Tang if (status < 0) {
180769254105SSieu Mun Tang *mbox_error = -status;
180869254105SSieu Mun Tang return INTEL_SIP_SMC_STATUS_ERROR;
180969254105SSieu Mun Tang }
181069254105SSieu Mun Tang
181169254105SSieu Mun Tang *dst_size = resp_len * MBOX_WORD_BYTE;
181269254105SSieu Mun Tang flush_dcache_range(dst_addr, *dst_size);
181369254105SSieu Mun Tang
181469254105SSieu Mun Tang return INTEL_SIP_SMC_STATUS_OK;
181569254105SSieu Mun Tang }
181669254105SSieu Mun Tang
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)18177e25eb87SSieu Mun Tang int intel_fcs_ecdsa_hash_sig_verify_init(uint32_t session_id, uint32_t context_id,
18187e25eb87SSieu Mun Tang uint32_t key_id, uint32_t param_size,
18197e25eb87SSieu Mun Tang uint64_t param_data, uint32_t *mbox_error)
18207e25eb87SSieu Mun Tang {
18217e25eb87SSieu Mun Tang return intel_fcs_crypto_service_init(session_id, context_id,
18227e25eb87SSieu Mun Tang key_id, param_size, param_data,
18237e25eb87SSieu Mun Tang (void *) &fcs_ecdsa_hash_sig_verify_param,
18247e25eb87SSieu Mun Tang mbox_error);
18257e25eb87SSieu Mun Tang }
18267e25eb87SSieu Mun Tang
intel_fcs_ecdsa_hash_sig_verify_finalize(uint32_t smc_fid,uint32_t trans_id,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)1827597fff5fSGirisha Dengi int intel_fcs_ecdsa_hash_sig_verify_finalize(uint32_t smc_fid, uint32_t trans_id,
1828597fff5fSGirisha Dengi uint32_t session_id, uint32_t context_id,
18297e25eb87SSieu Mun Tang uint32_t src_addr, uint32_t src_size,
18307e25eb87SSieu Mun Tang uint64_t dst_addr, uint32_t *dst_size,
18317e25eb87SSieu Mun Tang uint32_t *mbox_error)
18327e25eb87SSieu Mun Tang {
18337e25eb87SSieu Mun Tang int status;
18347e25eb87SSieu Mun Tang uint32_t i = 0;
18357e25eb87SSieu Mun Tang uint32_t payload[FCS_ECDSA_HASH_SIG_VERIFY_CMD_MAX_WORD_SIZE] = {0U};
1836fe5637f2SBoon Khai Ng uint32_t resp_len;
18377e25eb87SSieu Mun Tang uintptr_t hash_sig_pubkey_addr;
1838c418064eSJit Loon Lim uint32_t dst_size_check = 0;
18397e25eb87SSieu Mun Tang
18407e25eb87SSieu Mun Tang if ((dst_size == NULL) || (mbox_error == NULL)) {
18417e25eb87SSieu Mun Tang return INTEL_SIP_SMC_STATUS_REJECTED;
18427e25eb87SSieu Mun Tang }
18437e25eb87SSieu Mun Tang
1844597fff5fSGirisha Dengi if ((fcs_ecdsa_hash_sig_verify_param.session_id != session_id) ||
1845597fff5fSGirisha Dengi (fcs_ecdsa_hash_sig_verify_param.context_id != context_id)) {
18467e25eb87SSieu Mun Tang return INTEL_SIP_SMC_STATUS_REJECTED;
18477e25eb87SSieu Mun Tang }
18487e25eb87SSieu Mun Tang
18497e25eb87SSieu Mun Tang if (!is_address_in_ddr_range(src_addr, src_size) ||
18507e25eb87SSieu Mun Tang !is_address_in_ddr_range(dst_addr, *dst_size)) {
18517e25eb87SSieu Mun Tang return INTEL_SIP_SMC_STATUS_REJECTED;
18527e25eb87SSieu Mun Tang }
18537e25eb87SSieu Mun Tang
1854c418064eSJit Loon Lim dst_size_check = *dst_size;
1855c418064eSJit Loon Lim if ((dst_size_check > FCS_MAX_DATA_SIZE ||
1856c418064eSJit Loon Lim dst_size_check < FCS_MIN_DATA_SIZE) ||
1857c418064eSJit Loon Lim (src_size > FCS_MAX_DATA_SIZE ||
1858c418064eSJit Loon Lim src_size < FCS_MIN_DATA_SIZE)) {
1859c418064eSJit Loon Lim return INTEL_SIP_SMC_STATUS_REJECTED;
1860c418064eSJit Loon Lim }
1861c418064eSJit Loon Lim
1862fe5637f2SBoon Khai Ng resp_len = *dst_size / MBOX_WORD_BYTE;
1863fe5637f2SBoon Khai Ng
18647e25eb87SSieu Mun Tang /* Prepare command payload */
18657e25eb87SSieu Mun Tang /* Crypto header */
18667e25eb87SSieu Mun Tang i = 0;
18677e25eb87SSieu Mun Tang payload[i] = fcs_ecdsa_hash_sig_verify_param.session_id;
18687e25eb87SSieu Mun Tang
18697e25eb87SSieu Mun Tang i++;
18707e25eb87SSieu Mun Tang payload[i] = fcs_ecdsa_hash_sig_verify_param.context_id;
18717e25eb87SSieu Mun Tang
18727e25eb87SSieu Mun Tang i++;
18737e25eb87SSieu Mun Tang payload[i] = fcs_ecdsa_hash_sig_verify_param.crypto_param_size
18747e25eb87SSieu Mun Tang & FCS_CS_FIELD_SIZE_MASK;
18757e25eb87SSieu Mun Tang payload[i] |= (FCS_CS_FIELD_FLAG_INIT | FCS_CS_FIELD_FLAG_UPDATE
18767e25eb87SSieu Mun Tang | FCS_CS_FIELD_FLAG_FINALIZE)
18777e25eb87SSieu Mun Tang << FCS_CS_FIELD_FLAG_OFFSET;
18787e25eb87SSieu Mun Tang
18797e25eb87SSieu Mun Tang i++;
18807e25eb87SSieu Mun Tang payload[i] = fcs_ecdsa_hash_sig_verify_param.key_id;
18817e25eb87SSieu Mun Tang
18827e25eb87SSieu Mun Tang /* Crypto parameters */
18837e25eb87SSieu Mun Tang i++;
18847e25eb87SSieu Mun Tang payload[i] = fcs_ecdsa_hash_sig_verify_param.crypto_param
18857e25eb87SSieu Mun Tang & INTEL_SIP_SMC_FCS_ECC_ALGO_MASK;
18867e25eb87SSieu Mun Tang
18877e25eb87SSieu Mun Tang /* Hash Data Word, Signature Data Word and Public Key Data word */
18887e25eb87SSieu Mun Tang i++;
18897e25eb87SSieu Mun Tang hash_sig_pubkey_addr = src_addr;
1890c418064eSJit Loon Lim
1891c418064eSJit Loon Lim if ((i + ((src_size) / MBOX_WORD_BYTE)) >
1892c418064eSJit Loon Lim FCS_ECDSA_HASH_SIG_VERIFY_CMD_MAX_WORD_SIZE) {
1893c418064eSJit Loon Lim return INTEL_SIP_SMC_STATUS_REJECTED;
1894c418064eSJit Loon Lim }
1895c418064eSJit Loon Lim
1896e264b557SSieu Mun Tang memcpy_s(&payload[i], src_size / MBOX_WORD_BYTE,
1897e264b557SSieu Mun Tang (void *) hash_sig_pubkey_addr, src_size / MBOX_WORD_BYTE);
18987e25eb87SSieu Mun Tang
18997e25eb87SSieu Mun Tang i += (src_size / MBOX_WORD_BYTE);
19007e25eb87SSieu Mun Tang
1901597fff5fSGirisha Dengi status = (smc_fid == ALTERA_SIP_SMC_ASYNC_FCS_ECDSA_HASH_SIG_VERIFY_FINALIZE) ?
1902597fff5fSGirisha Dengi mailbox_send_cmd_async_v3(GET_CLIENT_ID(trans_id),
1903597fff5fSGirisha Dengi GET_JOB_ID(trans_id),
1904597fff5fSGirisha Dengi MBOX_FCS_ECDSA_HASH_SIG_VERIFY,
1905597fff5fSGirisha Dengi payload,
1906597fff5fSGirisha Dengi i,
1907597fff5fSGirisha Dengi MBOX_CMD_FLAG_CASUAL,
1908597fff5fSGirisha Dengi fcs_cs_hash_sig_verify_req_cb,
1909597fff5fSGirisha Dengi (uint32_t *)dst_addr,
1910597fff5fSGirisha Dengi 2U) :
1911597fff5fSGirisha Dengi
1912597fff5fSGirisha Dengi mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_ECDSA_HASH_SIG_VERIFY,
19137e25eb87SSieu Mun Tang payload, i, CMD_CASUAL, (uint32_t *) dst_addr,
19147e25eb87SSieu Mun Tang &resp_len);
19157e25eb87SSieu Mun Tang
19167e25eb87SSieu Mun Tang memset((void *)&fcs_ecdsa_hash_sig_verify_param,
19177e25eb87SSieu Mun Tang 0, sizeof(fcs_crypto_service_data));
19187e25eb87SSieu Mun Tang
19197e25eb87SSieu Mun Tang if (status < 0) {
19207e25eb87SSieu Mun Tang *mbox_error = -status;
19217e25eb87SSieu Mun Tang return INTEL_SIP_SMC_STATUS_ERROR;
19227e25eb87SSieu Mun Tang }
19237e25eb87SSieu Mun Tang
19247e25eb87SSieu Mun Tang *dst_size = resp_len * MBOX_WORD_BYTE;
19257e25eb87SSieu Mun Tang flush_dcache_range(dst_addr, *dst_size);
19267e25eb87SSieu Mun Tang
19277e25eb87SSieu Mun Tang return INTEL_SIP_SMC_STATUS_OK;
19287e25eb87SSieu Mun Tang }
19297e25eb87SSieu Mun Tang
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)193007912da1SSieu Mun Tang int intel_fcs_ecdsa_sha2_data_sign_init(uint32_t session_id,
193107912da1SSieu Mun Tang uint32_t context_id, uint32_t key_id,
193207912da1SSieu Mun Tang uint32_t param_size, uint64_t param_data,
193307912da1SSieu Mun Tang uint32_t *mbox_error)
193407912da1SSieu Mun Tang {
193507912da1SSieu Mun Tang return intel_fcs_crypto_service_init(session_id, context_id,
193607912da1SSieu Mun Tang key_id, param_size, param_data,
193707912da1SSieu Mun Tang (void *) &fcs_sha2_data_sign_param,
193807912da1SSieu Mun Tang mbox_error);
193907912da1SSieu Mun Tang }
194007912da1SSieu Mun Tang
intel_fcs_ecdsa_sha2_data_sign_update_finalize(uint32_t smc_fid,uint32_t trans_id,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,uint64_t smmu_src_addr)1941597fff5fSGirisha Dengi int intel_fcs_ecdsa_sha2_data_sign_update_finalize(uint32_t smc_fid, uint32_t trans_id,
1942597fff5fSGirisha Dengi uint32_t session_id, uint32_t context_id,
1943597fff5fSGirisha Dengi uint32_t src_addr, uint32_t src_size,
1944597fff5fSGirisha Dengi uint64_t dst_addr, uint32_t *dst_size,
1945597fff5fSGirisha Dengi uint8_t is_finalised, uint32_t *mbox_error,
1946597fff5fSGirisha Dengi uint64_t smmu_src_addr)
194707912da1SSieu Mun Tang {
194807912da1SSieu Mun Tang int status;
194907912da1SSieu Mun Tang int i;
19501d97dd74SSieu Mun Tang uint32_t flag;
19511d97dd74SSieu Mun Tang uint32_t crypto_header;
195207912da1SSieu Mun Tang uint32_t payload[FCS_ECDSA_SHA2_DATA_SIGN_CMD_MAX_WORD_SIZE] = {0U};
1953fe5637f2SBoon Khai Ng uint32_t resp_len;
195407912da1SSieu Mun Tang
195507912da1SSieu Mun Tang if ((dst_size == NULL) || (mbox_error == NULL)) {
195607912da1SSieu Mun Tang return INTEL_SIP_SMC_STATUS_REJECTED;
195707912da1SSieu Mun Tang }
195807912da1SSieu Mun Tang
195907912da1SSieu Mun Tang if (fcs_sha2_data_sign_param.session_id != session_id ||
196007912da1SSieu Mun Tang fcs_sha2_data_sign_param.context_id != context_id) {
196107912da1SSieu Mun Tang return INTEL_SIP_SMC_STATUS_REJECTED;
196207912da1SSieu Mun Tang }
196307912da1SSieu Mun Tang
196407912da1SSieu Mun Tang /* Source data must be 8 bytes aligned */
196507912da1SSieu Mun Tang if (!is_8_bytes_aligned(src_size)) {
196607912da1SSieu Mun Tang return INTEL_SIP_SMC_STATUS_REJECTED;
196707912da1SSieu Mun Tang }
196807912da1SSieu Mun Tang
196907912da1SSieu Mun Tang if (!is_address_in_ddr_range(src_addr, src_size) ||
197007912da1SSieu Mun Tang !is_address_in_ddr_range(dst_addr, *dst_size)) {
197107912da1SSieu Mun Tang return INTEL_SIP_SMC_STATUS_REJECTED;
197207912da1SSieu Mun Tang }
197307912da1SSieu Mun Tang
1974fe5637f2SBoon Khai Ng resp_len = *dst_size / MBOX_WORD_BYTE;
1975fe5637f2SBoon Khai Ng
19761d97dd74SSieu Mun Tang /* Prepare crypto header */
19771d97dd74SSieu Mun Tang flag = 0;
19781d97dd74SSieu Mun Tang if (fcs_sha2_data_sign_param.is_updated) {
19791d97dd74SSieu Mun Tang fcs_sha2_data_sign_param.crypto_param_size = 0;
19801d97dd74SSieu Mun Tang } else {
19811d97dd74SSieu Mun Tang flag |= FCS_CS_FIELD_FLAG_INIT;
19821d97dd74SSieu Mun Tang }
19831d97dd74SSieu Mun Tang
19841d97dd74SSieu Mun Tang if (is_finalised != 0U) {
19851d97dd74SSieu Mun Tang flag |= FCS_CS_FIELD_FLAG_FINALIZE;
19861d97dd74SSieu Mun Tang } else {
19871d97dd74SSieu Mun Tang flag |= FCS_CS_FIELD_FLAG_UPDATE;
19881d97dd74SSieu Mun Tang fcs_sha2_data_sign_param.is_updated = 1;
19891d97dd74SSieu Mun Tang }
19901d97dd74SSieu Mun Tang crypto_header = (flag << FCS_CS_FIELD_FLAG_OFFSET) |
19911d97dd74SSieu Mun Tang fcs_sha2_data_sign_param.crypto_param_size;
19921d97dd74SSieu Mun Tang
199307912da1SSieu Mun Tang /* Prepare command payload */
199407912da1SSieu Mun Tang i = 0;
199507912da1SSieu Mun Tang payload[i] = fcs_sha2_data_sign_param.session_id;
199607912da1SSieu Mun Tang i++;
199707912da1SSieu Mun Tang payload[i] = fcs_sha2_data_sign_param.context_id;
199807912da1SSieu Mun Tang i++;
19991d97dd74SSieu Mun Tang payload[i] = crypto_header;
200007912da1SSieu Mun Tang i++;
20011d97dd74SSieu Mun Tang
20021d97dd74SSieu Mun Tang if ((crypto_header >> FCS_CS_FIELD_FLAG_OFFSET) &
20031d97dd74SSieu Mun Tang FCS_CS_FIELD_FLAG_INIT) {
200407912da1SSieu Mun Tang payload[i] = fcs_sha2_data_sign_param.key_id;
200507912da1SSieu Mun Tang /* Crypto parameters */
200607912da1SSieu Mun Tang i++;
200707912da1SSieu Mun Tang payload[i] = fcs_sha2_data_sign_param.crypto_param
200807912da1SSieu Mun Tang & INTEL_SIP_SMC_FCS_ECC_ALGO_MASK;
200907912da1SSieu Mun Tang i++;
20101d97dd74SSieu Mun Tang }
20111d97dd74SSieu Mun Tang
20121d97dd74SSieu Mun Tang /* Data source address and size */
2013597fff5fSGirisha Dengi #if PLATFORM_MODEL == PLAT_SOCFPGA_AGILEX5
2014597fff5fSGirisha Dengi payload[i] = (uint32_t)smmu_src_addr;
2015597fff5fSGirisha Dengi #else
201607912da1SSieu Mun Tang payload[i] = src_addr;
2017597fff5fSGirisha Dengi #endif
201807912da1SSieu Mun Tang i++;
201907912da1SSieu Mun Tang payload[i] = src_size;
202007912da1SSieu Mun Tang i++;
2021597fff5fSGirisha Dengi
2022597fff5fSGirisha Dengi status = ((smc_fid == ALTERA_SIP_SMC_ASYNC_FCS_ECDSA_SHA2_DATA_SIGN_UPDATE) ||
2023597fff5fSGirisha Dengi (smc_fid == ALTERA_SIP_SMC_ASYNC_FCS_ECDSA_SHA2_DATA_SIGN_FINALIZE)) ?
2024597fff5fSGirisha Dengi mailbox_send_cmd_async_v3(GET_CLIENT_ID(trans_id),
2025597fff5fSGirisha Dengi GET_JOB_ID(trans_id),
2026597fff5fSGirisha Dengi MBOX_FCS_ECDSA_SHA2_DATA_SIGN_REQ,
2027597fff5fSGirisha Dengi payload,
2028597fff5fSGirisha Dengi i,
2029597fff5fSGirisha Dengi MBOX_CMD_FLAG_CASUAL,
2030597fff5fSGirisha Dengi fcs_cs_data_sign_req_cb,
2031597fff5fSGirisha Dengi (uint32_t *)dst_addr,
2032597fff5fSGirisha Dengi 2U) :
2033597fff5fSGirisha Dengi mailbox_send_cmd(MBOX_JOB_ID,
203407912da1SSieu Mun Tang MBOX_FCS_ECDSA_SHA2_DATA_SIGN_REQ, payload,
203507912da1SSieu Mun Tang i, CMD_CASUAL, (uint32_t *) dst_addr,
203607912da1SSieu Mun Tang &resp_len);
203707912da1SSieu Mun Tang
20381d97dd74SSieu Mun Tang if (is_finalised != 0U) {
203907912da1SSieu Mun Tang memset((void *)&fcs_sha2_data_sign_param, 0,
204007912da1SSieu Mun Tang sizeof(fcs_crypto_service_data));
20411d97dd74SSieu Mun Tang }
204207912da1SSieu Mun Tang
204307912da1SSieu Mun Tang if (status < 0) {
204407912da1SSieu Mun Tang *mbox_error = -status;
204507912da1SSieu Mun Tang return INTEL_SIP_SMC_STATUS_ERROR;
204607912da1SSieu Mun Tang }
204707912da1SSieu Mun Tang
204807912da1SSieu Mun Tang *dst_size = resp_len * MBOX_WORD_BYTE;
204907912da1SSieu Mun Tang flush_dcache_range(dst_addr, *dst_size);
205007912da1SSieu Mun Tang
205107912da1SSieu Mun Tang return INTEL_SIP_SMC_STATUS_OK;
205207912da1SSieu Mun Tang }
205307912da1SSieu Mun Tang
intel_fcs_ecdsa_sha2_data_sign_smmu_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,uint32_t * send_id)20544687021dSSieu Mun Tang int intel_fcs_ecdsa_sha2_data_sign_smmu_update_finalize(uint32_t session_id,
20554687021dSSieu Mun Tang uint32_t context_id, uint32_t src_addr,
20564687021dSSieu Mun Tang uint32_t src_size, uint64_t dst_addr,
20574687021dSSieu Mun Tang uint32_t *dst_size, uint8_t is_finalised,
20584687021dSSieu Mun Tang uint32_t *mbox_error, uint32_t *send_id)
20594687021dSSieu Mun Tang {
20604687021dSSieu Mun Tang int status;
20614687021dSSieu Mun Tang int i;
20624687021dSSieu Mun Tang uint32_t flag;
20634687021dSSieu Mun Tang uint32_t crypto_header;
20644687021dSSieu Mun Tang uint32_t payload[FCS_ECDSA_SHA2_DATA_SIGN_CMD_MAX_WORD_SIZE] = {0U};
20654687021dSSieu Mun Tang uint32_t resp_len;
20664687021dSSieu Mun Tang
20674687021dSSieu Mun Tang /* Source data must be 8 bytes aligned */
20684687021dSSieu Mun Tang if ((dst_size == NULL) || (mbox_error == NULL ||
20694687021dSSieu Mun Tang !is_8_bytes_aligned(src_size))) {
20704687021dSSieu Mun Tang return INTEL_SIP_SMC_STATUS_REJECTED;
20714687021dSSieu Mun Tang }
20724687021dSSieu Mun Tang
20734687021dSSieu Mun Tang if (fcs_sha2_data_sign_param.session_id != session_id ||
20744687021dSSieu Mun Tang fcs_sha2_data_sign_param.context_id != context_id) {
20754687021dSSieu Mun Tang return INTEL_SIP_SMC_STATUS_REJECTED;
20764687021dSSieu Mun Tang }
20774687021dSSieu Mun Tang
20784687021dSSieu Mun Tang if (!is_address_in_ddr_range(src_addr, src_size) ||
20794687021dSSieu Mun Tang !is_address_in_ddr_range(dst_addr, *dst_size)) {
20804687021dSSieu Mun Tang return INTEL_SIP_SMC_STATUS_REJECTED;
20814687021dSSieu Mun Tang }
20824687021dSSieu Mun Tang
20834687021dSSieu Mun Tang resp_len = *dst_size / MBOX_WORD_BYTE;
20844687021dSSieu Mun Tang
20854687021dSSieu Mun Tang /* Prepare crypto header */
20864687021dSSieu Mun Tang flag = 0;
20874687021dSSieu Mun Tang if (fcs_sha2_data_sign_param.is_updated) {
20884687021dSSieu Mun Tang fcs_sha2_data_sign_param.crypto_param_size = 0;
20894687021dSSieu Mun Tang } else {
20904687021dSSieu Mun Tang flag |= FCS_CS_FIELD_FLAG_INIT;
20914687021dSSieu Mun Tang }
20924687021dSSieu Mun Tang
20934687021dSSieu Mun Tang if (is_finalised != 0U) {
20944687021dSSieu Mun Tang flag |= FCS_CS_FIELD_FLAG_FINALIZE;
20954687021dSSieu Mun Tang } else {
20964687021dSSieu Mun Tang flag |= FCS_CS_FIELD_FLAG_UPDATE;
20974687021dSSieu Mun Tang fcs_sha2_data_sign_param.is_updated = 1;
20984687021dSSieu Mun Tang }
20994687021dSSieu Mun Tang crypto_header = (flag << FCS_CS_FIELD_FLAG_OFFSET) |
21004687021dSSieu Mun Tang fcs_sha2_data_sign_param.crypto_param_size;
21014687021dSSieu Mun Tang
21024687021dSSieu Mun Tang /* Prepare command payload */
21034687021dSSieu Mun Tang i = 0;
21044687021dSSieu Mun Tang payload[i] = fcs_sha2_data_sign_param.session_id;
21054687021dSSieu Mun Tang i++;
21064687021dSSieu Mun Tang payload[i] = fcs_sha2_data_sign_param.context_id;
21074687021dSSieu Mun Tang i++;
21084687021dSSieu Mun Tang payload[i] = crypto_header;
21094687021dSSieu Mun Tang i++;
21104687021dSSieu Mun Tang
21114687021dSSieu Mun Tang if ((crypto_header >> FCS_CS_FIELD_FLAG_OFFSET) &
21124687021dSSieu Mun Tang FCS_CS_FIELD_FLAG_INIT) {
21134687021dSSieu Mun Tang payload[i] = fcs_sha2_data_sign_param.key_id;
21144687021dSSieu Mun Tang /* Crypto parameters */
21154687021dSSieu Mun Tang i++;
21164687021dSSieu Mun Tang payload[i] = fcs_sha2_data_sign_param.crypto_param
21174687021dSSieu Mun Tang & INTEL_SIP_SMC_FCS_ECC_ALGO_MASK;
21184687021dSSieu Mun Tang i++;
21194687021dSSieu Mun Tang }
21204687021dSSieu Mun Tang
21214687021dSSieu Mun Tang /* Data source address and size */
21224687021dSSieu Mun Tang payload[i] = src_addr;
21234687021dSSieu Mun Tang i++;
21244687021dSSieu Mun Tang payload[i] = src_size;
21254687021dSSieu Mun Tang i++;
21264687021dSSieu Mun Tang
21274687021dSSieu Mun Tang status = mailbox_send_cmd_async(send_id,
21284687021dSSieu Mun Tang MBOX_FCS_ECDSA_SHA2_DATA_SIGN_REQ,
21294687021dSSieu Mun Tang payload, i, CMD_INDIRECT);
21304687021dSSieu Mun Tang
21314687021dSSieu Mun Tang if (is_finalised != 0U) {
21324687021dSSieu Mun Tang memset((void *)&fcs_sha2_data_sign_param, 0,
21334687021dSSieu Mun Tang sizeof(fcs_crypto_service_data));
21344687021dSSieu Mun Tang }
21354687021dSSieu Mun Tang
21364687021dSSieu Mun Tang if (status < 0) {
21374687021dSSieu Mun Tang *mbox_error = -status;
21384687021dSSieu Mun Tang return INTEL_SIP_SMC_STATUS_ERROR;
21394687021dSSieu Mun Tang }
21404687021dSSieu Mun Tang
21414687021dSSieu Mun Tang *dst_size = resp_len * MBOX_WORD_BYTE;
21424687021dSSieu Mun Tang flush_dcache_range(dst_addr, *dst_size);
21434687021dSSieu Mun Tang
21444687021dSSieu Mun Tang return INTEL_SIP_SMC_STATUS_OK;
21454687021dSSieu Mun Tang }
21464687021dSSieu Mun Tang
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)214758305060SSieu Mun Tang int intel_fcs_ecdsa_sha2_data_sig_verify_init(uint32_t session_id,
214858305060SSieu Mun Tang uint32_t context_id, uint32_t key_id,
214958305060SSieu Mun Tang uint32_t param_size, uint64_t param_data,
215058305060SSieu Mun Tang uint32_t *mbox_error)
215158305060SSieu Mun Tang {
215258305060SSieu Mun Tang return intel_fcs_crypto_service_init(session_id, context_id,
215358305060SSieu Mun Tang key_id, param_size, param_data,
215458305060SSieu Mun Tang (void *) &fcs_sha2_data_sig_verify_param,
215558305060SSieu Mun Tang mbox_error);
215658305060SSieu Mun Tang }
215758305060SSieu Mun Tang
intel_fcs_ecdsa_sha2_data_sig_verify_update_finalize(uint32_t smc_fid,uint32_t trans_id,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,uint64_t smmu_src_addr)2158597fff5fSGirisha Dengi int intel_fcs_ecdsa_sha2_data_sig_verify_update_finalize(uint32_t smc_fid, uint32_t trans_id,
2159597fff5fSGirisha Dengi uint32_t session_id, uint32_t context_id,
2160597fff5fSGirisha Dengi uint32_t src_addr, uint32_t src_size,
2161597fff5fSGirisha Dengi uint64_t dst_addr, uint32_t *dst_size,
2162597fff5fSGirisha Dengi uint32_t data_size, uint8_t is_finalised,
2163597fff5fSGirisha Dengi uint32_t *mbox_error, uint64_t smmu_src_addr)
216458305060SSieu Mun Tang {
216558305060SSieu Mun Tang int status;
216658305060SSieu Mun Tang uint32_t i;
21671d97dd74SSieu Mun Tang uint32_t flag;
21681d97dd74SSieu Mun Tang uint32_t crypto_header;
216958305060SSieu Mun Tang uint32_t payload[FCS_ECDSA_SHA2_DATA_SIG_VERIFY_CMD_MAX_WORD_SIZE] = {0U};
2170fe5637f2SBoon Khai Ng uint32_t resp_len;
217158305060SSieu Mun Tang uintptr_t sig_pubkey_offset;
2172c418064eSJit Loon Lim uint32_t dst_size_check = 0;
217358305060SSieu Mun Tang
217458305060SSieu Mun Tang if ((dst_size == NULL) || (mbox_error == NULL)) {
217558305060SSieu Mun Tang return INTEL_SIP_SMC_STATUS_REJECTED;
217658305060SSieu Mun Tang }
217758305060SSieu Mun Tang
217858305060SSieu Mun Tang if (fcs_sha2_data_sig_verify_param.session_id != session_id ||
217958305060SSieu Mun Tang fcs_sha2_data_sig_verify_param.context_id != context_id) {
218058305060SSieu Mun Tang return INTEL_SIP_SMC_STATUS_REJECTED;
218158305060SSieu Mun Tang }
218258305060SSieu Mun Tang
2183c418064eSJit Loon Lim if (data_size > src_size) {
2184c418064eSJit Loon Lim return INTEL_SIP_SMC_STATUS_REJECTED;
2185c418064eSJit Loon Lim }
2186c418064eSJit Loon Lim
218758305060SSieu Mun Tang if (!is_size_4_bytes_aligned(src_size)) {
218858305060SSieu Mun Tang return INTEL_SIP_SMC_STATUS_REJECTED;
218958305060SSieu Mun Tang }
219058305060SSieu Mun Tang
219158305060SSieu Mun Tang if (!is_8_bytes_aligned(data_size) ||
219258305060SSieu Mun Tang !is_8_bytes_aligned(src_addr)) {
219358305060SSieu Mun Tang return INTEL_SIP_SMC_STATUS_REJECTED;
219458305060SSieu Mun Tang }
219558305060SSieu Mun Tang
219658305060SSieu Mun Tang if (!is_address_in_ddr_range(src_addr, src_size) ||
219758305060SSieu Mun Tang !is_address_in_ddr_range(dst_addr, *dst_size)) {
219858305060SSieu Mun Tang return INTEL_SIP_SMC_STATUS_REJECTED;
219958305060SSieu Mun Tang }
220058305060SSieu Mun Tang
2201c418064eSJit Loon Lim dst_size_check = *dst_size;
2202c418064eSJit Loon Lim if ((dst_size_check > FCS_MAX_DATA_SIZE ||
2203c418064eSJit Loon Lim dst_size_check < FCS_MIN_DATA_SIZE) ||
2204c418064eSJit Loon Lim (src_size > FCS_MAX_DATA_SIZE ||
2205c418064eSJit Loon Lim src_size < FCS_MIN_DATA_SIZE)) {
2206c418064eSJit Loon Lim return INTEL_SIP_SMC_STATUS_REJECTED;
2207c418064eSJit Loon Lim }
2208c418064eSJit Loon Lim
2209fe5637f2SBoon Khai Ng resp_len = *dst_size / MBOX_WORD_BYTE;
2210fe5637f2SBoon Khai Ng
22111d97dd74SSieu Mun Tang /* Prepare crypto header */
22121d97dd74SSieu Mun Tang flag = 0;
22131d97dd74SSieu Mun Tang if (fcs_sha2_data_sig_verify_param.is_updated)
22141d97dd74SSieu Mun Tang fcs_sha2_data_sig_verify_param.crypto_param_size = 0;
22151d97dd74SSieu Mun Tang else
22161d97dd74SSieu Mun Tang flag |= FCS_CS_FIELD_FLAG_INIT;
22171d97dd74SSieu Mun Tang
22181d97dd74SSieu Mun Tang if (is_finalised != 0U)
22191d97dd74SSieu Mun Tang flag |= FCS_CS_FIELD_FLAG_FINALIZE;
22201d97dd74SSieu Mun Tang else {
22211d97dd74SSieu Mun Tang flag |= FCS_CS_FIELD_FLAG_UPDATE;
22221d97dd74SSieu Mun Tang fcs_sha2_data_sig_verify_param.is_updated = 1;
22231d97dd74SSieu Mun Tang }
22241d97dd74SSieu Mun Tang crypto_header = (flag << FCS_CS_FIELD_FLAG_OFFSET) |
22251d97dd74SSieu Mun Tang fcs_sha2_data_sig_verify_param.crypto_param_size;
22261d97dd74SSieu Mun Tang
222758305060SSieu Mun Tang /* Prepare command payload */
222858305060SSieu Mun Tang i = 0;
222958305060SSieu Mun Tang payload[i] = fcs_sha2_data_sig_verify_param.session_id;
223058305060SSieu Mun Tang i++;
223158305060SSieu Mun Tang payload[i] = fcs_sha2_data_sig_verify_param.context_id;
223258305060SSieu Mun Tang i++;
22331d97dd74SSieu Mun Tang payload[i] = crypto_header;
223458305060SSieu Mun Tang i++;
22351d97dd74SSieu Mun Tang
22361d97dd74SSieu Mun Tang if ((crypto_header >> FCS_CS_FIELD_FLAG_OFFSET) &
22371d97dd74SSieu Mun Tang FCS_CS_FIELD_FLAG_INIT) {
223858305060SSieu Mun Tang payload[i] = fcs_sha2_data_sig_verify_param.key_id;
223958305060SSieu Mun Tang i++;
224058305060SSieu Mun Tang /* Crypto parameters */
224158305060SSieu Mun Tang payload[i] = fcs_sha2_data_sig_verify_param.crypto_param
224258305060SSieu Mun Tang & INTEL_SIP_SMC_FCS_ECC_ALGO_MASK;
224358305060SSieu Mun Tang i++;
22441d97dd74SSieu Mun Tang }
22451d97dd74SSieu Mun Tang
224658305060SSieu Mun Tang /* Data source address and size */
2247597fff5fSGirisha Dengi /* On the Agilex5 platform, the SMMU remapped address is used */
2248597fff5fSGirisha Dengi #if PLATFORM_MODEL == PLAT_SOCFPGA_AGILEX5
2249597fff5fSGirisha Dengi payload[i] = smmu_src_addr;
2250597fff5fSGirisha Dengi #else
225158305060SSieu Mun Tang payload[i] = src_addr;
2252597fff5fSGirisha Dengi #endif
225358305060SSieu Mun Tang i++;
225458305060SSieu Mun Tang payload[i] = data_size;
225558305060SSieu Mun Tang i++;
22561d97dd74SSieu Mun Tang
22571d97dd74SSieu Mun Tang if ((crypto_header >> FCS_CS_FIELD_FLAG_OFFSET) &
22581d97dd74SSieu Mun Tang FCS_CS_FIELD_FLAG_FINALIZE) {
225958305060SSieu Mun Tang /* Signature + Public Key Data */
226058305060SSieu Mun Tang sig_pubkey_offset = src_addr + data_size;
2261c418064eSJit Loon Lim
2262c418064eSJit Loon Lim if ((i + ((src_size - data_size) / MBOX_WORD_BYTE)) >
2263c418064eSJit Loon Lim FCS_ECDSA_SHA2_DATA_SIG_VERIFY_CMD_MAX_WORD_SIZE) {
2264c418064eSJit Loon Lim return INTEL_SIP_SMC_STATUS_REJECTED;
2265c418064eSJit Loon Lim }
2266c418064eSJit Loon Lim
2267e264b557SSieu Mun Tang memcpy_s(&payload[i], (src_size - data_size) / MBOX_WORD_BYTE,
2268e264b557SSieu Mun Tang (void *) sig_pubkey_offset, (src_size - data_size) / MBOX_WORD_BYTE);
226958305060SSieu Mun Tang
227058305060SSieu Mun Tang i += (src_size - data_size) / MBOX_WORD_BYTE;
22711d97dd74SSieu Mun Tang }
227258305060SSieu Mun Tang
2273597fff5fSGirisha Dengi status = ((smc_fid == ALTERA_SIP_SMC_ASYNC_FCS_ECDSA_SHA2_DATA_SIG_VERIFY_UPDATE) ||
2274597fff5fSGirisha Dengi (smc_fid == ALTERA_SIP_SMC_ASYNC_FCS_ECDSA_SHA2_DATA_SIG_VERIFY_FINALIZE)) ?
2275597fff5fSGirisha Dengi mailbox_send_cmd_async_v3(GET_CLIENT_ID(trans_id),
2276597fff5fSGirisha Dengi GET_JOB_ID(trans_id),
2277597fff5fSGirisha Dengi MBOX_FCS_ECDSA_SHA2_DATA_SIGN_VERIFY,
2278597fff5fSGirisha Dengi payload,
2279597fff5fSGirisha Dengi i,
2280597fff5fSGirisha Dengi MBOX_CMD_FLAG_CASUAL,
2281597fff5fSGirisha Dengi fcs_cs_data_sig_verify_req_cb,
2282597fff5fSGirisha Dengi (uint32_t *)dst_addr,
2283597fff5fSGirisha Dengi 2U) :
2284597fff5fSGirisha Dengi mailbox_send_cmd(MBOX_JOB_ID,
228558305060SSieu Mun Tang MBOX_FCS_ECDSA_SHA2_DATA_SIGN_VERIFY, payload, i,
228658305060SSieu Mun Tang CMD_CASUAL, (uint32_t *) dst_addr, &resp_len);
228758305060SSieu Mun Tang
22881d97dd74SSieu Mun Tang if (is_finalised != 0U) {
228958305060SSieu Mun Tang memset((void *) &fcs_sha2_data_sig_verify_param, 0,
229058305060SSieu Mun Tang sizeof(fcs_crypto_service_data));
22911d97dd74SSieu Mun Tang }
229258305060SSieu Mun Tang
229358305060SSieu Mun Tang if (status < 0) {
229458305060SSieu Mun Tang *mbox_error = -status;
229558305060SSieu Mun Tang return INTEL_SIP_SMC_STATUS_ERROR;
229658305060SSieu Mun Tang }
229758305060SSieu Mun Tang
229858305060SSieu Mun Tang *dst_size = resp_len * MBOX_WORD_BYTE;
229958305060SSieu Mun Tang flush_dcache_range(dst_addr, *dst_size);
230058305060SSieu Mun Tang
230158305060SSieu Mun Tang return INTEL_SIP_SMC_STATUS_OK;
230258305060SSieu Mun Tang }
230358305060SSieu Mun Tang
intel_fcs_ecdsa_sha2_data_sig_verify_smmu_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,uint32_t * send_id)23044687021dSSieu Mun Tang int intel_fcs_ecdsa_sha2_data_sig_verify_smmu_update_finalize(uint32_t session_id,
23054687021dSSieu Mun Tang uint32_t context_id, uint32_t src_addr,
23064687021dSSieu Mun Tang uint32_t src_size, uint64_t dst_addr,
23074687021dSSieu Mun Tang uint32_t *dst_size, uint32_t data_size,
23084687021dSSieu Mun Tang uint8_t is_finalised, uint32_t *mbox_error,
23094687021dSSieu Mun Tang uint32_t *send_id)
23104687021dSSieu Mun Tang {
23114687021dSSieu Mun Tang int status;
23124687021dSSieu Mun Tang uint32_t i;
23134687021dSSieu Mun Tang uint32_t flag;
23144687021dSSieu Mun Tang uint32_t crypto_header;
23154687021dSSieu Mun Tang uint32_t payload[FCS_ECDSA_SHA2_DATA_SIG_VERIFY_CMD_MAX_WORD_SIZE] = {0U};
23164687021dSSieu Mun Tang uint32_t resp_len;
23174687021dSSieu Mun Tang uintptr_t sig_pubkey_offset;
2318c418064eSJit Loon Lim uint32_t dst_size_check = 0;
23194687021dSSieu Mun Tang
23204687021dSSieu Mun Tang /*
23214687021dSSieu Mun Tang * Source data must be 4 bytes aligned
23221b491eeaSElyes Haouas * Source address must be 8 bytes aligned
23234687021dSSieu Mun Tang * User data must be 8 bytes aligned
23244687021dSSieu Mun Tang */
23254687021dSSieu Mun Tang if ((dst_size == NULL) || (mbox_error == NULL) ||
23264687021dSSieu Mun Tang !is_size_4_bytes_aligned(src_size) ||
23274687021dSSieu Mun Tang !is_8_bytes_aligned(src_addr) ||
23284687021dSSieu Mun Tang !is_8_bytes_aligned(data_size)) {
23294687021dSSieu Mun Tang return INTEL_SIP_SMC_STATUS_REJECTED;
23304687021dSSieu Mun Tang }
23314687021dSSieu Mun Tang
23324687021dSSieu Mun Tang if (fcs_sha2_data_sig_verify_param.session_id != session_id ||
23334687021dSSieu Mun Tang fcs_sha2_data_sig_verify_param.context_id != context_id) {
23344687021dSSieu Mun Tang return INTEL_SIP_SMC_STATUS_REJECTED;
23354687021dSSieu Mun Tang }
23364687021dSSieu Mun Tang
2337c418064eSJit Loon Lim if (data_size > src_size) {
2338c418064eSJit Loon Lim return INTEL_SIP_SMC_STATUS_REJECTED;
2339c418064eSJit Loon Lim }
2340c418064eSJit Loon Lim
23414687021dSSieu Mun Tang if (!is_address_in_ddr_range(src_addr, src_size) ||
23424687021dSSieu Mun Tang !is_address_in_ddr_range(dst_addr, *dst_size)) {
23434687021dSSieu Mun Tang return INTEL_SIP_SMC_STATUS_REJECTED;
23444687021dSSieu Mun Tang }
23454687021dSSieu Mun Tang
2346c418064eSJit Loon Lim dst_size_check = *dst_size;
2347c418064eSJit Loon Lim if ((dst_size_check > FCS_MAX_DATA_SIZE ||
2348c418064eSJit Loon Lim dst_size_check < FCS_MIN_DATA_SIZE) ||
2349c418064eSJit Loon Lim (src_size > FCS_MAX_DATA_SIZE ||
2350c418064eSJit Loon Lim src_size < FCS_MIN_DATA_SIZE)) {
2351c418064eSJit Loon Lim return INTEL_SIP_SMC_STATUS_REJECTED;
2352c418064eSJit Loon Lim }
2353c418064eSJit Loon Lim
23544687021dSSieu Mun Tang resp_len = *dst_size / MBOX_WORD_BYTE;
23554687021dSSieu Mun Tang
23564687021dSSieu Mun Tang /* Prepare crypto header */
23574687021dSSieu Mun Tang flag = 0;
23584687021dSSieu Mun Tang if (fcs_sha2_data_sig_verify_param.is_updated)
23594687021dSSieu Mun Tang fcs_sha2_data_sig_verify_param.crypto_param_size = 0;
23604687021dSSieu Mun Tang else
23614687021dSSieu Mun Tang flag |= FCS_CS_FIELD_FLAG_INIT;
23624687021dSSieu Mun Tang
23634687021dSSieu Mun Tang if (is_finalised != 0U)
23644687021dSSieu Mun Tang flag |= FCS_CS_FIELD_FLAG_FINALIZE;
23654687021dSSieu Mun Tang else {
23664687021dSSieu Mun Tang flag |= FCS_CS_FIELD_FLAG_UPDATE;
23674687021dSSieu Mun Tang fcs_sha2_data_sig_verify_param.is_updated = 1;
23684687021dSSieu Mun Tang }
23694687021dSSieu Mun Tang crypto_header = (flag << FCS_CS_FIELD_FLAG_OFFSET) |
23704687021dSSieu Mun Tang fcs_sha2_data_sig_verify_param.crypto_param_size;
23714687021dSSieu Mun Tang
23724687021dSSieu Mun Tang /* Prepare command payload */
23734687021dSSieu Mun Tang i = 0;
23744687021dSSieu Mun Tang payload[i] = fcs_sha2_data_sig_verify_param.session_id;
23754687021dSSieu Mun Tang i++;
23764687021dSSieu Mun Tang payload[i] = fcs_sha2_data_sig_verify_param.context_id;
23774687021dSSieu Mun Tang i++;
23784687021dSSieu Mun Tang payload[i] = crypto_header;
23794687021dSSieu Mun Tang i++;
23804687021dSSieu Mun Tang
23814687021dSSieu Mun Tang if ((crypto_header >> FCS_CS_FIELD_FLAG_OFFSET) &
23824687021dSSieu Mun Tang FCS_CS_FIELD_FLAG_INIT) {
23834687021dSSieu Mun Tang payload[i] = fcs_sha2_data_sig_verify_param.key_id;
23844687021dSSieu Mun Tang i++;
23854687021dSSieu Mun Tang /* Crypto parameters */
23864687021dSSieu Mun Tang payload[i] = fcs_sha2_data_sig_verify_param.crypto_param
23874687021dSSieu Mun Tang & INTEL_SIP_SMC_FCS_ECC_ALGO_MASK;
23884687021dSSieu Mun Tang i++;
23894687021dSSieu Mun Tang }
23904687021dSSieu Mun Tang
23914687021dSSieu Mun Tang /* Data source address and size */
23924687021dSSieu Mun Tang payload[i] = src_addr;
23934687021dSSieu Mun Tang i++;
23944687021dSSieu Mun Tang payload[i] = data_size;
23954687021dSSieu Mun Tang i++;
23964687021dSSieu Mun Tang
23974687021dSSieu Mun Tang if ((crypto_header >> FCS_CS_FIELD_FLAG_OFFSET) &
23984687021dSSieu Mun Tang FCS_CS_FIELD_FLAG_FINALIZE) {
23994687021dSSieu Mun Tang /* Copy mac data to command
24004687021dSSieu Mun Tang * Using dst_addr (physical address) to store sig_pubkey_offset
24014687021dSSieu Mun Tang * sig_pubkey_offset is Signature + Public Key Data
24024687021dSSieu Mun Tang */
24034687021dSSieu Mun Tang sig_pubkey_offset = dst_addr;
2404c418064eSJit Loon Lim
2405c418064eSJit Loon Lim if ((i + ((src_size - data_size) / MBOX_WORD_BYTE)) >
2406c418064eSJit Loon Lim FCS_ECDSA_SHA2_DATA_SIG_VERIFY_CMD_MAX_WORD_SIZE) {
2407c418064eSJit Loon Lim return INTEL_SIP_SMC_STATUS_REJECTED;
2408c418064eSJit Loon Lim }
2409c418064eSJit Loon Lim
2410e264b557SSieu Mun Tang memcpy_s(&payload[i], (src_size - data_size) / MBOX_WORD_BYTE,
2411e264b557SSieu Mun Tang (void *) sig_pubkey_offset, (src_size - data_size) / MBOX_WORD_BYTE);
24124687021dSSieu Mun Tang
2413afe9fcc3SSieu Mun Tang memset((void *) dst_addr, 0, *dst_size);
24144687021dSSieu Mun Tang
24154687021dSSieu Mun Tang i += (src_size - data_size) / MBOX_WORD_BYTE;
24164687021dSSieu Mun Tang }
24174687021dSSieu Mun Tang
24184687021dSSieu Mun Tang status = mailbox_send_cmd_async(send_id,
24194687021dSSieu Mun Tang MBOX_FCS_ECDSA_SHA2_DATA_SIGN_VERIFY,
24204687021dSSieu Mun Tang payload, i, CMD_INDIRECT);
24214687021dSSieu Mun Tang
24224687021dSSieu Mun Tang if (is_finalised != 0U) {
24234687021dSSieu Mun Tang memset((void *) &fcs_sha2_data_sig_verify_param, 0,
24244687021dSSieu Mun Tang sizeof(fcs_crypto_service_data));
24254687021dSSieu Mun Tang }
24264687021dSSieu Mun Tang
24274687021dSSieu Mun Tang if (status < 0) {
24284687021dSSieu Mun Tang *mbox_error = -status;
24294687021dSSieu Mun Tang return INTEL_SIP_SMC_STATUS_ERROR;
24304687021dSSieu Mun Tang }
24314687021dSSieu Mun Tang
24324687021dSSieu Mun Tang *dst_size = resp_len * MBOX_WORD_BYTE;
24334687021dSSieu Mun Tang flush_dcache_range(dst_addr, *dst_size);
24344687021dSSieu Mun Tang
24354687021dSSieu Mun Tang return INTEL_SIP_SMC_STATUS_OK;
24364687021dSSieu Mun Tang }
24374687021dSSieu Mun Tang
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)2438d2fee94aSSieu Mun Tang int intel_fcs_ecdsa_get_pubkey_init(uint32_t session_id, uint32_t context_id,
2439d2fee94aSSieu Mun Tang uint32_t key_id, uint32_t param_size,
2440d2fee94aSSieu Mun Tang uint64_t param_data, uint32_t *mbox_error)
2441d2fee94aSSieu Mun Tang {
2442d2fee94aSSieu Mun Tang return intel_fcs_crypto_service_init(session_id, context_id,
2443d2fee94aSSieu Mun Tang key_id, param_size, param_data,
2444d2fee94aSSieu Mun Tang (void *) &fcs_ecdsa_get_pubkey_param,
2445d2fee94aSSieu Mun Tang mbox_error);
2446d2fee94aSSieu Mun Tang }
2447d2fee94aSSieu Mun Tang
intel_fcs_ecdsa_get_pubkey_finalize(uint32_t smc_fid,uint32_t trans_id,uint32_t session_id,uint32_t context_id,uint64_t dst_addr,uint32_t * dst_size,uint32_t * mbox_error)2448597fff5fSGirisha Dengi int intel_fcs_ecdsa_get_pubkey_finalize(uint32_t smc_fid, uint32_t trans_id,
2449597fff5fSGirisha Dengi uint32_t session_id, uint32_t context_id,
2450d2fee94aSSieu Mun Tang uint64_t dst_addr, uint32_t *dst_size,
2451d2fee94aSSieu Mun Tang uint32_t *mbox_error)
2452d2fee94aSSieu Mun Tang {
2453d2fee94aSSieu Mun Tang int status;
2454d2fee94aSSieu Mun Tang int i;
2455d2fee94aSSieu Mun Tang uint32_t crypto_header;
2456fe5637f2SBoon Khai Ng uint32_t ret_size;
2457d2fee94aSSieu Mun Tang uint32_t payload[FCS_ECDSA_GET_PUBKEY_MAX_WORD_SIZE] = {0U};
2458d2fee94aSSieu Mun Tang
2459d2fee94aSSieu Mun Tang if ((dst_size == NULL) || (mbox_error == NULL)) {
2460d2fee94aSSieu Mun Tang return INTEL_SIP_SMC_STATUS_REJECTED;
2461d2fee94aSSieu Mun Tang }
2462d2fee94aSSieu Mun Tang
2463e8a3454cSJit Loon Lim if (!is_address_in_ddr_range(dst_addr, *dst_size)) {
2464e8a3454cSJit Loon Lim return INTEL_SIP_SMC_STATUS_REJECTED;
2465e8a3454cSJit Loon Lim }
2466e8a3454cSJit Loon Lim
2467d2fee94aSSieu Mun Tang if (fcs_ecdsa_get_pubkey_param.session_id != session_id ||
2468d2fee94aSSieu Mun Tang fcs_ecdsa_get_pubkey_param.context_id != context_id) {
2469d2fee94aSSieu Mun Tang return INTEL_SIP_SMC_STATUS_REJECTED;
2470d2fee94aSSieu Mun Tang }
2471d2fee94aSSieu Mun Tang
2472fe5637f2SBoon Khai Ng ret_size = *dst_size / MBOX_WORD_BYTE;
2473fe5637f2SBoon Khai Ng
2474d2fee94aSSieu Mun Tang crypto_header = ((FCS_CS_FIELD_FLAG_INIT |
2475d2fee94aSSieu Mun Tang FCS_CS_FIELD_FLAG_UPDATE |
2476d2fee94aSSieu Mun Tang FCS_CS_FIELD_FLAG_FINALIZE) <<
2477d2fee94aSSieu Mun Tang FCS_CS_FIELD_FLAG_OFFSET) |
2478d2fee94aSSieu Mun Tang fcs_ecdsa_get_pubkey_param.crypto_param_size;
2479d2fee94aSSieu Mun Tang i = 0;
2480d2fee94aSSieu Mun Tang /* Prepare command payload */
2481d2fee94aSSieu Mun Tang payload[i] = session_id;
2482d2fee94aSSieu Mun Tang i++;
2483d2fee94aSSieu Mun Tang payload[i] = context_id;
2484d2fee94aSSieu Mun Tang i++;
2485d2fee94aSSieu Mun Tang payload[i] = crypto_header;
2486d2fee94aSSieu Mun Tang i++;
2487d2fee94aSSieu Mun Tang payload[i] = fcs_ecdsa_get_pubkey_param.key_id;
2488d2fee94aSSieu Mun Tang i++;
2489d2fee94aSSieu Mun Tang payload[i] = (uint32_t) fcs_ecdsa_get_pubkey_param.crypto_param &
2490d2fee94aSSieu Mun Tang INTEL_SIP_SMC_FCS_ECC_ALGO_MASK;
2491d2fee94aSSieu Mun Tang i++;
2492d2fee94aSSieu Mun Tang
2493597fff5fSGirisha Dengi status = (smc_fid == ALTERA_SIP_SMC_ASYNC_FCS_ECDSA_GET_PUBKEY_FINALIZE) ?
2494597fff5fSGirisha Dengi mailbox_send_cmd_async_v3(GET_CLIENT_ID(trans_id),
2495597fff5fSGirisha Dengi GET_JOB_ID(trans_id),
2496597fff5fSGirisha Dengi MBOX_FCS_ECDSA_GET_PUBKEY,
2497597fff5fSGirisha Dengi payload,
2498597fff5fSGirisha Dengi i,
2499597fff5fSGirisha Dengi MBOX_CMD_FLAG_CASUAL,
2500597fff5fSGirisha Dengi fcs_cs_get_public_key_cb,
2501597fff5fSGirisha Dengi (uint32_t *)dst_addr,
2502597fff5fSGirisha Dengi 2U) :
2503597fff5fSGirisha Dengi mailbox_send_cmd(MBOX_JOB_ID,
2504597fff5fSGirisha Dengi MBOX_FCS_ECDSA_GET_PUBKEY,
2505d2fee94aSSieu Mun Tang payload, i, CMD_CASUAL,
2506d2fee94aSSieu Mun Tang (uint32_t *) dst_addr, &ret_size);
2507d2fee94aSSieu Mun Tang
2508d2fee94aSSieu Mun Tang memset((void *) &fcs_ecdsa_get_pubkey_param, 0,
2509d2fee94aSSieu Mun Tang sizeof(fcs_crypto_service_data));
2510d2fee94aSSieu Mun Tang
2511d2fee94aSSieu Mun Tang if (status < 0) {
2512d2fee94aSSieu Mun Tang *mbox_error = -status;
2513d2fee94aSSieu Mun Tang return INTEL_SIP_SMC_STATUS_ERROR;
2514d2fee94aSSieu Mun Tang }
2515d2fee94aSSieu Mun Tang
2516d2fee94aSSieu Mun Tang *dst_size = ret_size * MBOX_WORD_BYTE;
2517d2fee94aSSieu Mun Tang flush_dcache_range(dst_addr, *dst_size);
2518d2fee94aSSieu Mun Tang
2519d2fee94aSSieu Mun Tang return INTEL_SIP_SMC_STATUS_OK;
2520d2fee94aSSieu Mun Tang }
2521d2fee94aSSieu Mun Tang
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)252249446866SSieu Mun Tang int intel_fcs_ecdh_request_init(uint32_t session_id, uint32_t context_id,
252349446866SSieu Mun Tang uint32_t key_id, uint32_t param_size,
252449446866SSieu Mun Tang uint64_t param_data, uint32_t *mbox_error)
252549446866SSieu Mun Tang {
252649446866SSieu Mun Tang return intel_fcs_crypto_service_init(session_id, context_id,
252749446866SSieu Mun Tang key_id, param_size, param_data,
252849446866SSieu Mun Tang (void *) &fcs_ecdh_request_param,
252949446866SSieu Mun Tang mbox_error);
253049446866SSieu Mun Tang }
253149446866SSieu Mun Tang
intel_fcs_ecdh_request_finalize(uint32_t smc_fid,uint32_t trans_id,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)2532597fff5fSGirisha Dengi int intel_fcs_ecdh_request_finalize(uint32_t smc_fid, uint32_t trans_id,
2533597fff5fSGirisha Dengi uint32_t session_id, uint32_t context_id,
253449446866SSieu Mun Tang uint32_t src_addr, uint32_t src_size,
253549446866SSieu Mun Tang uint64_t dst_addr, uint32_t *dst_size,
253649446866SSieu Mun Tang uint32_t *mbox_error)
253749446866SSieu Mun Tang {
253849446866SSieu Mun Tang int status;
253949446866SSieu Mun Tang uint32_t i;
254049446866SSieu Mun Tang uint32_t payload[FCS_ECDH_REQUEST_CMD_MAX_WORD_SIZE] = {0U};
2541fe5637f2SBoon Khai Ng uint32_t resp_len;
254249446866SSieu Mun Tang uintptr_t pubkey;
2543c418064eSJit Loon Lim uint32_t dst_size_check = 0;
254449446866SSieu Mun Tang
254549446866SSieu Mun Tang if ((dst_size == NULL) || (mbox_error == NULL)) {
254649446866SSieu Mun Tang return INTEL_SIP_SMC_STATUS_REJECTED;
254749446866SSieu Mun Tang }
254849446866SSieu Mun Tang
254949446866SSieu Mun Tang if (fcs_ecdh_request_param.session_id != session_id ||
255049446866SSieu Mun Tang fcs_ecdh_request_param.context_id != context_id) {
255149446866SSieu Mun Tang return INTEL_SIP_SMC_STATUS_REJECTED;
255249446866SSieu Mun Tang }
255349446866SSieu Mun Tang
255449446866SSieu Mun Tang if (!is_address_in_ddr_range(src_addr, src_size) ||
255549446866SSieu Mun Tang !is_address_in_ddr_range(dst_addr, *dst_size)) {
255649446866SSieu Mun Tang return INTEL_SIP_SMC_STATUS_REJECTED;
255749446866SSieu Mun Tang }
255849446866SSieu Mun Tang
2559c418064eSJit Loon Lim dst_size_check = *dst_size;
2560597fff5fSGirisha Dengi
2561597fff5fSGirisha Dengi if ((dst_size_check > FCS_MAX_DATA_SIZE || dst_size_check < FCS_MIN_DATA_SIZE) ||
2562597fff5fSGirisha Dengi (src_size > FCS_MAX_DATA_SIZE || src_size < FCS_MIN_DATA_SIZE)) {
2563c418064eSJit Loon Lim return INTEL_SIP_SMC_STATUS_REJECTED;
2564c418064eSJit Loon Lim }
2565c418064eSJit Loon Lim
2566fe5637f2SBoon Khai Ng resp_len = *dst_size / MBOX_WORD_BYTE;
2567fe5637f2SBoon Khai Ng
256849446866SSieu Mun Tang /* Prepare command payload */
256949446866SSieu Mun Tang i = 0;
257049446866SSieu Mun Tang /* Crypto header */
257149446866SSieu Mun Tang payload[i] = fcs_ecdh_request_param.session_id;
257249446866SSieu Mun Tang i++;
257349446866SSieu Mun Tang payload[i] = fcs_ecdh_request_param.context_id;
257449446866SSieu Mun Tang i++;
257549446866SSieu Mun Tang payload[i] = fcs_ecdh_request_param.crypto_param_size
257649446866SSieu Mun Tang & FCS_CS_FIELD_SIZE_MASK;
257749446866SSieu Mun Tang payload[i] |= (FCS_CS_FIELD_FLAG_INIT | FCS_CS_FIELD_FLAG_UPDATE
257849446866SSieu Mun Tang | FCS_CS_FIELD_FLAG_FINALIZE)
257949446866SSieu Mun Tang << FCS_CS_FIELD_FLAG_OFFSET;
258049446866SSieu Mun Tang i++;
258149446866SSieu Mun Tang payload[i] = fcs_ecdh_request_param.key_id;
258249446866SSieu Mun Tang i++;
258349446866SSieu Mun Tang /* Crypto parameters */
258449446866SSieu Mun Tang payload[i] = fcs_ecdh_request_param.crypto_param
258549446866SSieu Mun Tang & INTEL_SIP_SMC_FCS_ECC_ALGO_MASK;
258649446866SSieu Mun Tang i++;
258749446866SSieu Mun Tang /* Public key data */
258849446866SSieu Mun Tang pubkey = src_addr;
2589c418064eSJit Loon Lim
2590c418064eSJit Loon Lim if ((i + ((src_size) / MBOX_WORD_BYTE)) >
2591c418064eSJit Loon Lim FCS_ECDH_REQUEST_CMD_MAX_WORD_SIZE) {
2592c418064eSJit Loon Lim return INTEL_SIP_SMC_STATUS_REJECTED;
2593c418064eSJit Loon Lim }
2594c418064eSJit Loon Lim
2595e264b557SSieu Mun Tang memcpy_s(&payload[i], src_size / MBOX_WORD_BYTE,
2596e264b557SSieu Mun Tang (void *) pubkey, src_size / MBOX_WORD_BYTE);
259749446866SSieu Mun Tang i += src_size / MBOX_WORD_BYTE;
259849446866SSieu Mun Tang
2599597fff5fSGirisha Dengi status = (smc_fid == ALTERA_SIP_SMC_ASYNC_FCS_ECDH_REQUEST_FINALIZE) ?
2600597fff5fSGirisha Dengi mailbox_send_cmd_async_v3(GET_CLIENT_ID(trans_id),
2601597fff5fSGirisha Dengi GET_JOB_ID(trans_id),
2602597fff5fSGirisha Dengi MBOX_FCS_ECDH_REQUEST,
2603597fff5fSGirisha Dengi payload,
2604597fff5fSGirisha Dengi i,
2605597fff5fSGirisha Dengi MBOX_CMD_FLAG_CASUAL,
2606597fff5fSGirisha Dengi fcs_cs_ecdh_request_cb,
2607597fff5fSGirisha Dengi (uint32_t *)dst_addr,
2608597fff5fSGirisha Dengi 2U) :
2609597fff5fSGirisha Dengi mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_ECDH_REQUEST,
261049446866SSieu Mun Tang payload, i, CMD_CASUAL, (uint32_t *) dst_addr,
261149446866SSieu Mun Tang &resp_len);
261249446866SSieu Mun Tang
261349446866SSieu Mun Tang memset((void *)&fcs_ecdh_request_param, 0,
261449446866SSieu Mun Tang sizeof(fcs_crypto_service_data));
261549446866SSieu Mun Tang
261649446866SSieu Mun Tang if (status < 0) {
261749446866SSieu Mun Tang *mbox_error = -status;
261849446866SSieu Mun Tang return INTEL_SIP_SMC_STATUS_ERROR;
261949446866SSieu Mun Tang }
262049446866SSieu Mun Tang
262149446866SSieu Mun Tang *dst_size = resp_len * MBOX_WORD_BYTE;
262249446866SSieu Mun Tang flush_dcache_range(dst_addr, *dst_size);
262349446866SSieu Mun Tang
262449446866SSieu Mun Tang return INTEL_SIP_SMC_STATUS_OK;
262549446866SSieu Mun Tang }
262649446866SSieu Mun Tang
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)26276726390eSSieu Mun Tang int intel_fcs_aes_crypt_init(uint32_t session_id, uint32_t context_id,
26286726390eSSieu Mun Tang uint32_t key_id, uint64_t param_addr,
26296726390eSSieu Mun Tang uint32_t param_size, uint32_t *mbox_error)
26306726390eSSieu Mun Tang {
2631c42402cdSJit Loon Lim /* ptr to get param_addr value */
2632c42402cdSJit Loon Lim uint64_t *param_addr_ptr;
2633c42402cdSJit Loon Lim
2634c42402cdSJit Loon Lim param_addr_ptr = (uint64_t *) param_addr;
2635c42402cdSJit Loon Lim
2636b0f44789SJit Loon Lim /* Check if mbox_error is not NULL or 0xF or 0x3FF */
2637b0f44789SJit Loon Lim if (mbox_error == NULL || *mbox_error > 0xF ||
2638b0f44789SJit Loon Lim (*mbox_error != 0 && *mbox_error != 0x3FF)) {
2639c42402cdSJit Loon Lim return INTEL_SIP_SMC_STATUS_REJECTED;
2640c42402cdSJit Loon Lim }
2641b0f44789SJit Loon Lim
2642b0f44789SJit Loon Lim /* Check if param_addr is not 0 or larger that 0xFFFFFFFFFF */
2643b0f44789SJit Loon Lim if (param_addr == 0 || param_addr > 0xFFFFFFFFFF) {
2644b0f44789SJit Loon Lim return INTEL_SIP_SMC_STATUS_REJECTED;
2645b0f44789SJit Loon Lim }
2646b0f44789SJit Loon Lim
2647b0f44789SJit Loon Lim /*
2648597fff5fSGirisha Dengi * Check if not ECB, CBC and CTR, GCM and GCM-GHASH mode (only for Agilex5),
2649597fff5fSGirisha Dengi * addr ptr is NULL. Return "Reject" status
2650b0f44789SJit Loon Lim */
2651b0f44789SJit Loon Lim if ((param_addr_ptr == NULL) ||
2652b0f44789SJit Loon Lim (((*param_addr_ptr & FCS_CRYPTO_BLOCK_MODE_MASK) != FCS_CRYPTO_ECB_MODE) &&
2653b0f44789SJit Loon Lim ((*param_addr_ptr & FCS_CRYPTO_BLOCK_MODE_MASK) != FCS_CRYPTO_CBC_MODE) &&
2654597fff5fSGirisha Dengi ((*param_addr_ptr & FCS_CRYPTO_BLOCK_MODE_MASK) != FCS_CRYPTO_CTR_MODE)
2655597fff5fSGirisha Dengi #if PLATFORM_MODEL == PLAT_SOCFPGA_AGILEX5
2656597fff5fSGirisha Dengi &&
2657597fff5fSGirisha Dengi ((*param_addr_ptr & FCS_CRYPTO_BLOCK_MODE_MASK) != FCS_CRYPTO_GCM_MODE) &&
2658597fff5fSGirisha Dengi ((*param_addr_ptr & FCS_CRYPTO_BLOCK_MODE_MASK) != FCS_CRYPTO_GCM_GHASH_MODE)
2659597fff5fSGirisha Dengi #endif
2660597fff5fSGirisha Dengi )){
2661b0f44789SJit Loon Lim return INTEL_SIP_SMC_STATUS_REJECTED;
2662b0f44789SJit Loon Lim }
2663b0f44789SJit Loon Lim
2664c42402cdSJit Loon Lim /*
2665c42402cdSJit Loon Lim * Since crypto param size vary between mode.
2666c42402cdSJit Loon Lim * Check CBC/CTR here and limit to size 28 bytes
2667c42402cdSJit Loon Lim */
2668c42402cdSJit Loon Lim if ((((*param_addr_ptr & FCS_CRYPTO_BLOCK_MODE_MASK) == FCS_CRYPTO_CBC_MODE) ||
2669597fff5fSGirisha Dengi ((*param_addr_ptr & FCS_CRYPTO_BLOCK_MODE_MASK) == FCS_CRYPTO_CTR_MODE) ||
2670597fff5fSGirisha Dengi ((*param_addr_ptr & FCS_CRYPTO_BLOCK_MODE_MASK) == FCS_CRYPTO_GCM_MODE) ||
2671597fff5fSGirisha Dengi ((*param_addr_ptr & FCS_CRYPTO_BLOCK_MODE_MASK) == FCS_CRYPTO_GCM_GHASH_MODE)) &&
2672c42402cdSJit Loon Lim (param_size > FCS_CRYPTO_CBC_CTR_BUFFER_SIZE)) {
2673c42402cdSJit Loon Lim return INTEL_SIP_SMC_STATUS_REJECTED;
2674c42402cdSJit Loon Lim }
2675c42402cdSJit Loon Lim
2676b0f44789SJit Loon Lim /*
2677b0f44789SJit Loon Lim * Since crypto param size vary between mode.
2678b0f44789SJit Loon Lim * Check ECB here and limit to size 12 bytes
2679b0f44789SJit Loon Lim */
2680b0f44789SJit Loon Lim if (((*param_addr_ptr & FCS_CRYPTO_BLOCK_MODE_MASK) == FCS_CRYPTO_ECB_MODE) &&
2681b0f44789SJit Loon Lim (param_size > FCS_CRYPTO_ECB_BUFFER_SIZE)) {
26826726390eSSieu Mun Tang return INTEL_SIP_SMC_STATUS_REJECTED;
26836726390eSSieu Mun Tang }
26846726390eSSieu Mun Tang
26856726390eSSieu Mun Tang memset((void *)&fcs_aes_init_payload, 0U, sizeof(fcs_aes_init_payload));
26866726390eSSieu Mun Tang
26876726390eSSieu Mun Tang fcs_aes_init_payload.session_id = session_id;
26886726390eSSieu Mun Tang fcs_aes_init_payload.context_id = context_id;
26896726390eSSieu Mun Tang fcs_aes_init_payload.param_size = param_size;
26906726390eSSieu Mun Tang fcs_aes_init_payload.key_id = key_id;
26916726390eSSieu Mun Tang
2692e264b557SSieu Mun Tang memcpy_s(fcs_aes_init_payload.crypto_param, param_size / MBOX_WORD_BYTE,
2693e264b557SSieu Mun Tang (void *) param_addr, param_size / MBOX_WORD_BYTE);
26946726390eSSieu Mun Tang
2695dcb144f1SSieu Mun Tang fcs_aes_init_payload.is_updated = 0;
2696dcb144f1SSieu Mun Tang
26976726390eSSieu Mun Tang *mbox_error = 0;
26986726390eSSieu Mun Tang
26996726390eSSieu Mun Tang return INTEL_SIP_SMC_STATUS_OK;
27006726390eSSieu Mun Tang }
27016726390eSSieu Mun Tang
intel_fcs_aes_crypt_update_finalize(uint32_t smc_fid,uint32_t trans_id,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 padding_size,uint8_t is_finalised,uint32_t * send_id,uint64_t smmu_src_addr,uint64_t smmu_dst_addr)2702597fff5fSGirisha Dengi int intel_fcs_aes_crypt_update_finalize(uint32_t smc_fid, uint32_t trans_id,
2703597fff5fSGirisha Dengi uint32_t session_id, uint32_t context_id,
2704597fff5fSGirisha Dengi uint64_t src_addr, uint32_t src_size,
2705597fff5fSGirisha Dengi uint64_t dst_addr, uint32_t dst_size,
27061e1dbad0SGirisha Dengi uint32_t padding_size, uint8_t is_finalised,
2707597fff5fSGirisha Dengi uint32_t *send_id, uint64_t smmu_src_addr,
2708597fff5fSGirisha Dengi uint64_t smmu_dst_addr)
27096726390eSSieu Mun Tang {
27106726390eSSieu Mun Tang int status;
27116726390eSSieu Mun Tang int i;
2712dcb144f1SSieu Mun Tang uint32_t flag;
27136726390eSSieu Mun Tang uint32_t crypto_header;
27146726390eSSieu Mun Tang uint32_t fcs_aes_crypt_payload[FCS_AES_CMD_MAX_WORD_SIZE];
2715597fff5fSGirisha Dengi uint32_t src_addr_sdm = (uint32_t)src_addr;
2716597fff5fSGirisha Dengi uint32_t dst_addr_sdm = (uint32_t)dst_addr;
27171e1dbad0SGirisha Dengi bool is_src_size_aligned;
27181e1dbad0SGirisha Dengi bool is_dst_size_aligned;
271934f092a1SGirisha Dengi bool is_src_size_valid;
272034f092a1SGirisha Dengi bool is_dst_size_valid;
27216726390eSSieu Mun Tang
27226726390eSSieu Mun Tang if (fcs_aes_init_payload.session_id != session_id ||
27236726390eSSieu Mun Tang fcs_aes_init_payload.context_id != context_id) {
27246726390eSSieu Mun Tang return INTEL_SIP_SMC_STATUS_REJECTED;
27256726390eSSieu Mun Tang }
27266726390eSSieu Mun Tang
27271e1dbad0SGirisha Dengi /* Default source and destination size align check, 32 bytes alignment. */
27281e1dbad0SGirisha Dengi is_src_size_aligned = is_32_bytes_aligned(src_size);
27291e1dbad0SGirisha Dengi is_dst_size_aligned = is_32_bytes_aligned(dst_size);
273034f092a1SGirisha Dengi is_src_size_valid = FCS_AES_DATA_SIZE_CHECK(src_size);
273134f092a1SGirisha Dengi is_dst_size_valid = FCS_AES_DATA_SIZE_CHECK(dst_size);
27321e1dbad0SGirisha Dengi
27331e1dbad0SGirisha Dengi /*
27341e1dbad0SGirisha Dengi * Get the requested block mode.
27351e1dbad0SGirisha Dengi * On the Agilex5 platform with GCM and GCM-GHASH modes, the source and destination size
27361e1dbad0SGirisha Dengi * should be in multiples of 16 bytes. For other platforms and other modes, it should be
27371e1dbad0SGirisha Dengi * in multiples of 32 bytes.
27381e1dbad0SGirisha Dengi */
27391e1dbad0SGirisha Dengi #if PLATFORM_MODEL == PLAT_SOCFPGA_AGILEX5
27401e1dbad0SGirisha Dengi uint32_t block_mode = fcs_aes_init_payload.crypto_param[0] & FCS_CRYPTO_BLOCK_MODE_MASK;
27411e1dbad0SGirisha Dengi
27421e1dbad0SGirisha Dengi if ((block_mode == FCS_CRYPTO_GCM_MODE) ||
27431e1dbad0SGirisha Dengi (block_mode == FCS_CRYPTO_GCM_GHASH_MODE)) {
27441e1dbad0SGirisha Dengi is_src_size_aligned = is_16_bytes_aligned(src_size);
27451e1dbad0SGirisha Dengi is_dst_size_aligned = is_16_bytes_aligned(dst_size);
274634f092a1SGirisha Dengi /* The size validity here is, should be 0 or multiples of 16 bytes. */
274734f092a1SGirisha Dengi is_src_size_valid = is_16_bytes_aligned(src_size);
274834f092a1SGirisha Dengi is_dst_size_valid = is_16_bytes_aligned(dst_size);
27491e1dbad0SGirisha Dengi }
27501e1dbad0SGirisha Dengi #endif
27511e1dbad0SGirisha Dengi
27526726390eSSieu Mun Tang if ((!is_8_bytes_aligned(src_addr)) ||
27531e1dbad0SGirisha Dengi (!is_src_size_aligned) ||
27546726390eSSieu Mun Tang (!is_address_in_ddr_range(src_addr, src_size))) {
27556726390eSSieu Mun Tang return INTEL_SIP_SMC_STATUS_REJECTED;
27566726390eSSieu Mun Tang }
27576726390eSSieu Mun Tang
27586726390eSSieu Mun Tang if ((!is_8_bytes_aligned(dst_addr)) ||
27591e1dbad0SGirisha Dengi (!is_dst_size_aligned) ||
2760e8a3454cSJit Loon Lim (!is_address_in_ddr_range(dst_addr, dst_size))) {
27616726390eSSieu Mun Tang return INTEL_SIP_SMC_STATUS_REJECTED;
27626726390eSSieu Mun Tang }
27636726390eSSieu Mun Tang
276434f092a1SGirisha Dengi if (!is_src_size_valid || !is_dst_size_valid)
27656726390eSSieu Mun Tang return INTEL_SIP_SMC_STATUS_REJECTED;
27666726390eSSieu Mun Tang
2767dcb144f1SSieu Mun Tang /* Prepare crypto header*/
2768dcb144f1SSieu Mun Tang flag = 0;
2769dcb144f1SSieu Mun Tang if (fcs_aes_init_payload.is_updated) {
2770dcb144f1SSieu Mun Tang fcs_aes_init_payload.param_size = 0;
2771dcb144f1SSieu Mun Tang } else {
2772dcb144f1SSieu Mun Tang flag |= FCS_CS_FIELD_FLAG_INIT;
2773dcb144f1SSieu Mun Tang }
2774dcb144f1SSieu Mun Tang
2775dcb144f1SSieu Mun Tang if (is_finalised != 0U) {
2776dcb144f1SSieu Mun Tang flag |= FCS_CS_FIELD_FLAG_FINALIZE;
2777dcb144f1SSieu Mun Tang } else {
2778dcb144f1SSieu Mun Tang flag |= FCS_CS_FIELD_FLAG_UPDATE;
2779dcb144f1SSieu Mun Tang fcs_aes_init_payload.is_updated = 1;
2780dcb144f1SSieu Mun Tang }
2781dcb144f1SSieu Mun Tang crypto_header = (flag << FCS_CS_FIELD_FLAG_OFFSET) |
27826726390eSSieu Mun Tang fcs_aes_init_payload.param_size;
2783dcb144f1SSieu Mun Tang
27846726390eSSieu Mun Tang i = 0U;
27856726390eSSieu Mun Tang fcs_aes_crypt_payload[i] = session_id;
27866726390eSSieu Mun Tang i++;
27876726390eSSieu Mun Tang fcs_aes_crypt_payload[i] = context_id;
27886726390eSSieu Mun Tang i++;
27896726390eSSieu Mun Tang fcs_aes_crypt_payload[i] = crypto_header;
27906726390eSSieu Mun Tang i++;
27916726390eSSieu Mun Tang
2792dcb144f1SSieu Mun Tang if ((crypto_header >> FCS_CS_FIELD_FLAG_OFFSET) &
2793597fff5fSGirisha Dengi (FCS_CS_FIELD_FLAG_INIT)) {
2794dcb144f1SSieu Mun Tang fcs_aes_crypt_payload[i] = fcs_aes_init_payload.key_id;
27956726390eSSieu Mun Tang i++;
2796dcb144f1SSieu Mun Tang
2797c418064eSJit Loon Lim if ((i + ((fcs_aes_init_payload.param_size) / MBOX_WORD_BYTE)) >
2798c418064eSJit Loon Lim FCS_AES_CMD_MAX_WORD_SIZE) {
2799c418064eSJit Loon Lim return INTEL_SIP_SMC_STATUS_REJECTED;
2800c418064eSJit Loon Lim }
2801c418064eSJit Loon Lim
2802e264b557SSieu Mun Tang memcpy_s(&fcs_aes_crypt_payload[i],
2803e264b557SSieu Mun Tang fcs_aes_init_payload.param_size / MBOX_WORD_BYTE,
2804e264b557SSieu Mun Tang (void *) fcs_aes_init_payload.crypto_param,
2805e264b557SSieu Mun Tang fcs_aes_init_payload.param_size / MBOX_WORD_BYTE);
28066726390eSSieu Mun Tang
28076726390eSSieu Mun Tang i += fcs_aes_init_payload.param_size / MBOX_WORD_BYTE;
2808dcb144f1SSieu Mun Tang }
28096726390eSSieu Mun Tang
2810597fff5fSGirisha Dengi /* On the Agilex5 platform, we will use the SMMU payload address */
2811597fff5fSGirisha Dengi #if PLATFORM_MODEL == PLAT_SOCFPGA_AGILEX5
2812597fff5fSGirisha Dengi src_addr_sdm = (uint32_t)smmu_src_addr;
2813597fff5fSGirisha Dengi dst_addr_sdm = (uint32_t)smmu_dst_addr;
2814597fff5fSGirisha Dengi #endif
2815597fff5fSGirisha Dengi
2816597fff5fSGirisha Dengi fcs_aes_crypt_payload[i] = src_addr_sdm;
28176726390eSSieu Mun Tang i++;
28186726390eSSieu Mun Tang fcs_aes_crypt_payload[i] = src_size;
28196726390eSSieu Mun Tang i++;
2820597fff5fSGirisha Dengi fcs_aes_crypt_payload[i] = dst_addr_sdm;
28216726390eSSieu Mun Tang i++;
28226726390eSSieu Mun Tang fcs_aes_crypt_payload[i] = dst_size;
28236726390eSSieu Mun Tang i++;
28246726390eSSieu Mun Tang
28251e1dbad0SGirisha Dengi /* Padding data size, only on Agilex5 with GCM and GCM-GHASH modes. */
28261e1dbad0SGirisha Dengi #if PLATFORM_MODEL == PLAT_SOCFPGA_AGILEX5
28271e1dbad0SGirisha Dengi if ((block_mode == FCS_CRYPTO_GCM_MODE) ||
28281e1dbad0SGirisha Dengi (block_mode == FCS_CRYPTO_GCM_GHASH_MODE)) {
28291e1dbad0SGirisha Dengi fcs_aes_crypt_payload[i] = padding_size;
2830597fff5fSGirisha Dengi i++;
2831597fff5fSGirisha Dengi }
28321e1dbad0SGirisha Dengi #endif
2833597fff5fSGirisha Dengi
2834597fff5fSGirisha Dengi status = ((smc_fid == ALTERA_SIP_SMC_ASYNC_FCS_AES_CRYPT_UPDATE) ||
2835597fff5fSGirisha Dengi (smc_fid == ALTERA_SIP_SMC_ASYNC_FCS_AES_CRYPT_FINALIZE)) ?
2836597fff5fSGirisha Dengi mailbox_send_cmd_async_v3(GET_CLIENT_ID(trans_id),
2837597fff5fSGirisha Dengi GET_JOB_ID(trans_id),
2838597fff5fSGirisha Dengi MBOX_FCS_AES_CRYPT_REQ,
2839597fff5fSGirisha Dengi fcs_aes_crypt_payload,
2840597fff5fSGirisha Dengi i,
2841597fff5fSGirisha Dengi MBOX_CMD_FLAG_INDIRECT,
2842597fff5fSGirisha Dengi fcs_cs_aes_cb,
2843597fff5fSGirisha Dengi NULL,
2844597fff5fSGirisha Dengi 0U) :
2845597fff5fSGirisha Dengi mailbox_send_cmd_async(send_id, MBOX_FCS_AES_CRYPT_REQ,
2846597fff5fSGirisha Dengi fcs_aes_crypt_payload, i, CMD_INDIRECT);
2847597fff5fSGirisha Dengi
28486726390eSSieu Mun Tang
2849dcb144f1SSieu Mun Tang if (is_finalised != 0U) {
2850dcb144f1SSieu Mun Tang memset((void *)&fcs_aes_init_payload, 0,
2851dcb144f1SSieu Mun Tang sizeof(fcs_aes_init_payload));
2852dcb144f1SSieu Mun Tang }
28536726390eSSieu Mun Tang
28541e1dbad0SGirisha Dengi if (status < 0) {
28556726390eSSieu Mun Tang return INTEL_SIP_SMC_STATUS_ERROR;
28566726390eSSieu Mun Tang }
28576726390eSSieu Mun Tang
28586726390eSSieu Mun Tang return INTEL_SIP_SMC_STATUS_OK;
28596726390eSSieu Mun Tang }
2860597fff5fSGirisha Dengi
intel_fcs_hkdf_request(uint32_t smc_fid,uint32_t trans_id,uint32_t session_id,uint32_t step_type,uint32_t mac_mode,uint32_t src_addr,uint32_t key_uid,uint32_t op_key_size)2861597fff5fSGirisha Dengi int intel_fcs_hkdf_request(uint32_t smc_fid, uint32_t trans_id,
2862597fff5fSGirisha Dengi uint32_t session_id, uint32_t step_type,
2863597fff5fSGirisha Dengi uint32_t mac_mode, uint32_t src_addr,
2864597fff5fSGirisha Dengi uint32_t key_uid, uint32_t op_key_size)
2865597fff5fSGirisha Dengi {
2866597fff5fSGirisha Dengi int status;
2867597fff5fSGirisha Dengi uint32_t i = 0;
2868597fff5fSGirisha Dengi uintptr_t inputdata;
2869597fff5fSGirisha Dengi uint32_t payload[FCS_HKDF_REQUEST_DATA_SIZE] = {0U};
2870597fff5fSGirisha Dengi
2871597fff5fSGirisha Dengi if (!is_address_in_ddr_range(src_addr, FCS_HKDF_REQUEST_DATA_SIZE)) {
2872597fff5fSGirisha Dengi ERROR("MBOX: %s: source addr not in the DDR range\n", __func__);
2873597fff5fSGirisha Dengi return INTEL_SIP_SMC_STATUS_REJECTED;
2874597fff5fSGirisha Dengi }
2875597fff5fSGirisha Dengi
2876597fff5fSGirisha Dengi /* Prepare command payload */
2877597fff5fSGirisha Dengi
2878597fff5fSGirisha Dengi /* Session ID */
2879597fff5fSGirisha Dengi payload[i] = session_id;
2880597fff5fSGirisha Dengi i++;
2881597fff5fSGirisha Dengi
2882597fff5fSGirisha Dengi /* Reserved, 8 bytes */
2883597fff5fSGirisha Dengi payload[i] = 0;
2884597fff5fSGirisha Dengi i++;
2885597fff5fSGirisha Dengi
2886597fff5fSGirisha Dengi payload[i] = 0;
2887597fff5fSGirisha Dengi i++;
2888597fff5fSGirisha Dengi
2889597fff5fSGirisha Dengi /* HKDF step type */
2890597fff5fSGirisha Dengi payload[i] = step_type;
2891597fff5fSGirisha Dengi i++;
2892597fff5fSGirisha Dengi
2893597fff5fSGirisha Dengi /* MAC mode/PRF */
2894597fff5fSGirisha Dengi payload[i] = mac_mode;
2895597fff5fSGirisha Dengi i++;
2896597fff5fSGirisha Dengi
2897597fff5fSGirisha Dengi /* Complete input data, 1st input data len + its data + 2nd input data len + its data. */
2898597fff5fSGirisha Dengi inputdata = src_addr;
2899597fff5fSGirisha Dengi memcpy_s((uint8_t *)&payload[i], FCS_HKDF_KEY_DATA_SIZE / sizeof(uint32_t),
2900597fff5fSGirisha Dengi (uint8_t *)inputdata, FCS_HKDF_KEY_DATA_SIZE / sizeof(uint32_t));
2901597fff5fSGirisha Dengi
2902597fff5fSGirisha Dengi i += FCS_HKDF_KEY_DATA_SIZE / sizeof(uint32_t);
2903597fff5fSGirisha Dengi
2904597fff5fSGirisha Dengi /* Key UID */
2905597fff5fSGirisha Dengi payload[i] = key_uid;
2906597fff5fSGirisha Dengi i++;
2907597fff5fSGirisha Dengi
2908597fff5fSGirisha Dengi /* Pointer to size of output key object */
2909597fff5fSGirisha Dengi inputdata = inputdata + FCS_HKDF_KEY_DATA_SIZE;
2910597fff5fSGirisha Dengi
2911597fff5fSGirisha Dengi /* Output Key object */
2912597fff5fSGirisha Dengi memcpy_s(&payload[i], op_key_size / sizeof(uint32_t), (void *)inputdata,
2913597fff5fSGirisha Dengi op_key_size / sizeof(uint32_t));
2914597fff5fSGirisha Dengi
2915597fff5fSGirisha Dengi i += op_key_size / sizeof(uint32_t);
2916597fff5fSGirisha Dengi
2917597fff5fSGirisha Dengi status = mailbox_send_cmd_async_v3(GET_CLIENT_ID(trans_id),
2918597fff5fSGirisha Dengi GET_JOB_ID(trans_id),
2919597fff5fSGirisha Dengi MBOX_FCS_HKDF_REQUEST,
2920597fff5fSGirisha Dengi payload,
2921597fff5fSGirisha Dengi i,
2922597fff5fSGirisha Dengi MBOX_CMD_FLAG_CASUAL,
2923597fff5fSGirisha Dengi fcs_hkdf_request_cb,
2924597fff5fSGirisha Dengi NULL,
2925597fff5fSGirisha Dengi 0U);
2926597fff5fSGirisha Dengi
2927597fff5fSGirisha Dengi if (status < 0) {
2928597fff5fSGirisha Dengi ERROR("MBOX: %s: status %d\n", __func__, status);
2929597fff5fSGirisha Dengi return INTEL_SIP_SMC_STATUS_ERROR;
2930597fff5fSGirisha Dengi }
2931597fff5fSGirisha Dengi
2932597fff5fSGirisha Dengi return INTEL_SIP_SMC_STATUS_OK;
2933597fff5fSGirisha Dengi }
2934