xref: /rk3399_ARM-atf/plat/intel/soc/common/sip/socfpga_sip_fcs.c (revision d1aecd465faff50b245232f27501c7d8023be4f5)
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