xref: /rk3399_ARM-atf/plat/intel/soc/common/sip/socfpga_sip_fcs.c (revision 80684b7e9e9ed4574bc64948740b99cb31d1e10a)
1 /*
2  * Copyright (c) 2020-2023, Intel Corporation. All rights reserved.
3  * Copyright (c) 2024-2025, Altera Corporation. All rights reserved.
4  *
5  * SPDX-License-Identifier: BSD-3-Clause
6  */
7 
8 #include <arch_helpers.h>
9 #include <common/debug.h>
10 #include <lib/mmio.h>
11 
12 #include "../lib/utils/alignment_utils.h"
13 #include "socfpga_plat_def.h"
14 #include "socfpga_fcs.h"
15 #include "socfpga_mailbox.h"
16 #include "socfpga_sip_svc.h"
17 
18 /* FCS static variables */
19 static fcs_crypto_service_aes_data fcs_aes_init_payload;
20 static fcs_crypto_service_data fcs_sha_get_digest_param;
21 static fcs_crypto_service_data fcs_sha_mac_verify_param;
22 static fcs_crypto_service_data fcs_ecdsa_hash_sign_param;
23 static fcs_crypto_service_data fcs_ecdsa_hash_sig_verify_param;
24 static fcs_crypto_service_data fcs_sha2_data_sign_param;
25 static fcs_crypto_service_data fcs_sha2_data_sig_verify_param;
26 static fcs_crypto_service_data fcs_ecdsa_get_pubkey_param;
27 static fcs_crypto_service_data fcs_ecdh_request_param;
28 
29 uint8_t fcs_send_cert_cb(void *resp_desc, void *cmd_desc, uint64_t *ret_args)
30 {
31 	uint8_t ret_args_len = 0U;
32 	sdm_response_t *resp = (sdm_response_t *)resp_desc;
33 	sdm_command_t *cmd = (sdm_command_t *)cmd_desc;
34 
35 	(void)cmd;
36 	INFO("MBOX: %s: mailbox_err 0x%x, status_word %d\n",
37 		__func__, resp->err_code, resp->resp_data[0]);
38 
39 	ret_args[ret_args_len++] = INTEL_SIP_SMC_STATUS_OK;
40 	ret_args[ret_args_len++] = resp->err_code;
41 	ret_args[ret_args_len++] = resp->resp_data[0];
42 
43 	return ret_args_len;
44 }
45 
46 uint8_t fcs_cntr_set_preauth_cb(void *resp_desc, void *cmd_desc, uint64_t *ret_args)
47 {
48 	uint8_t ret_args_len = 0U;
49 	sdm_response_t *resp = (sdm_response_t *)resp_desc;
50 	sdm_command_t *cmd = (sdm_command_t *)cmd_desc;
51 
52 	(void)cmd;
53 	INFO("MBOX: %s: mailbox_err 0x%x\n", __func__, resp->err_code);
54 
55 	ret_args[ret_args_len++] = INTEL_SIP_SMC_STATUS_OK;
56 	ret_args[ret_args_len++] = resp->err_code;
57 
58 	return ret_args_len;
59 }
60 
61 uint8_t fcs_get_attest_cert_cb(void *resp_desc, void *cmd_desc, uint64_t *ret_args)
62 {
63 	uint8_t ret_args_len = 0U;
64 	sdm_response_t *resp = (sdm_response_t *)resp_desc;
65 	sdm_command_t *cmd = (sdm_command_t *)cmd_desc;
66 
67 	INFO("MBOX: %s: mailbox_err 0x%x, nbytes_ret %d\n",
68 		__func__, resp->err_code, resp->rcvd_resp_len * MBOX_WORD_BYTE);
69 
70 	ret_args[ret_args_len++] = INTEL_SIP_SMC_STATUS_OK;
71 	ret_args[ret_args_len++] = resp->err_code;
72 	ret_args[ret_args_len++] = resp->rcvd_resp_len * MBOX_WORD_BYTE;
73 
74 	/* Flush the response data buffer. */
75 	flush_dcache_range((uintptr_t)cmd->cb_args, resp->rcvd_resp_len * MBOX_WORD_BYTE);
76 
77 	return ret_args_len;
78 }
79 
80 uint8_t fcs_hkdf_request_cb(void *resp_desc, void *cmd_desc, uint64_t *ret_args)
81 {
82 	uint8_t ret_args_len = 0U;
83 	sdm_response_t *resp = (sdm_response_t *)resp_desc;
84 	sdm_command_t *cmd = (sdm_command_t *)cmd_desc;
85 
86 	(void)cmd;
87 
88 	INFO("MBOX: %s: mbox_err 0x%x, hkdf_status 0x%x\n", __func__,
89 		resp->err_code, resp->resp_data[0]);
90 
91 	ret_args[ret_args_len++] = INTEL_SIP_SMC_STATUS_OK;
92 	ret_args[ret_args_len++] = resp->err_code;
93 	ret_args[ret_args_len++] = resp->resp_data[0];
94 
95 	return ret_args_len;
96 }
97 
98 uint8_t fcs_create_cert_reload_cb(void *resp_desc, void *cmd_desc, uint64_t *ret_args)
99 {
100 	uint8_t ret_args_len = 0U;
101 	sdm_response_t *resp = (sdm_response_t *)resp_desc;
102 	sdm_command_t *cmd = (sdm_command_t *)cmd_desc;
103 
104 	(void)cmd;
105 	INFO("MBOX: %s: mailbox_err 0x%x\n", __func__, resp->err_code);
106 
107 	ret_args[ret_args_len++] = INTEL_SIP_SMC_STATUS_OK;
108 	ret_args[ret_args_len++] = resp->err_code;
109 
110 	return ret_args_len;
111 }
112 
113 uint8_t fcs_cs_get_digest_cb(void *resp_desc, void *cmd_desc, uint64_t *ret_args)
114 {
115 	uint8_t ret_args_len = 0U;
116 	sdm_response_t *resp = (sdm_response_t *)resp_desc;
117 	sdm_command_t *cmd = (sdm_command_t *)cmd_desc;
118 
119 	INFO("MBOX: %s: mbox_err  0x%x, nbytes_ret %d\n", __func__,
120 		resp->err_code, resp->rcvd_resp_len * MBOX_WORD_BYTE);
121 
122 	ret_args[ret_args_len++] = INTEL_SIP_SMC_STATUS_OK;
123 	ret_args[ret_args_len++] = resp->err_code;
124 	ret_args[ret_args_len++] = resp->rcvd_resp_len * MBOX_WORD_BYTE;
125 
126 	/* Flush the response data buffer. */
127 	flush_dcache_range((uintptr_t)cmd->cb_args, resp->rcvd_resp_len * MBOX_WORD_BYTE);
128 
129 	return ret_args_len;
130 }
131 
132 uint8_t fcs_cs_mac_verify_cb(void *resp_desc, void *cmd_desc, uint64_t *ret_args)
133 {
134 	uint8_t ret_args_len = 0U;
135 	sdm_response_t *resp = (sdm_response_t *)resp_desc;
136 	sdm_command_t *cmd = (sdm_command_t *)cmd_desc;
137 
138 	INFO("MBOX: %s: mbox_err 0x%x, nbytes_ret %d, verify_result 0x%x\n",
139 		__func__, resp->err_code,
140 		resp->rcvd_resp_len * MBOX_WORD_BYTE,
141 		cmd->cb_args[3]);
142 
143 	ret_args[ret_args_len++] = INTEL_SIP_SMC_STATUS_OK;
144 	ret_args[ret_args_len++] = resp->err_code;
145 	ret_args[ret_args_len++] = resp->rcvd_resp_len * MBOX_WORD_BYTE;
146 	ret_args[ret_args_len++] = cmd->cb_args[3];
147 
148 	/* Flush the response data buffer. */
149 	flush_dcache_range((uintptr_t)cmd->cb_args, resp->rcvd_resp_len * MBOX_WORD_BYTE);
150 
151 	return ret_args_len;
152 }
153 
154 uint8_t fcs_cs_hash_sign_req_cb(void *resp_desc, void *cmd_desc, uint64_t *ret_args)
155 {
156 	uint8_t ret_args_len = 0U;
157 	sdm_response_t *resp = (sdm_response_t *)resp_desc;
158 	sdm_command_t *cmd = (sdm_command_t *)cmd_desc;
159 
160 	INFO("MBOX: %s: [0] 0%x, [1] 0x%x, [2] 0x%x, len_words %d\n",
161 			__func__, resp->resp_data[0], resp->resp_data[1],
162 			resp->resp_data[2], resp->rcvd_resp_len);
163 
164 	ret_args[ret_args_len++] = INTEL_SIP_SMC_STATUS_OK;
165 	ret_args[ret_args_len++] = resp->err_code;
166 	ret_args[ret_args_len++] = resp->rcvd_resp_len * MBOX_WORD_BYTE;
167 
168 	/* Flush the response data buffer. */
169 	flush_dcache_range((uintptr_t)cmd->cb_args, resp->rcvd_resp_len * MBOX_WORD_BYTE);
170 
171 	return ret_args_len;
172 }
173 
174 uint8_t fcs_cs_hash_sig_verify_req_cb(void *resp_desc, void *cmd_desc, uint64_t *ret_args)
175 {
176 	uint8_t ret_args_len = 0U;
177 	sdm_response_t *resp = (sdm_response_t *)resp_desc;
178 	sdm_command_t *cmd = (sdm_command_t *)cmd_desc;
179 
180 	INFO("MBOX: %s: [0] 0%x, [1] 0x%x, [2] 0x%x, [3] 0x%x\n",
181 			__func__, resp->resp_data[0], resp->resp_data[1],
182 			resp->resp_data[2], resp->resp_data[3]);
183 
184 	ret_args[ret_args_len++] = INTEL_SIP_SMC_STATUS_OK;
185 	ret_args[ret_args_len++] = resp->err_code;
186 	ret_args[ret_args_len++] = resp->rcvd_resp_len * MBOX_WORD_BYTE;
187 
188 	/* Flush the response data buffer. */
189 	flush_dcache_range((uintptr_t)cmd->cb_args, resp->rcvd_resp_len * MBOX_WORD_BYTE);
190 
191 	return ret_args_len;
192 }
193 
194 uint8_t fcs_cs_aes_cb(void *resp_desc, void *cmd_desc, uint64_t *ret_args)
195 {
196 	uint8_t ret_args_len = 0U;
197 	uint32_t nbytes_ret = 0U;
198 	sdm_response_t *resp = (sdm_response_t *)resp_desc;
199 	sdm_command_t *cmd = (sdm_command_t *)cmd_desc;
200 
201 	(void)cmd;
202 
203 	/* Data size written to the destination is always at last index of the response data. */
204 	nbytes_ret = resp->resp_data[resp->rcvd_resp_len - 1];
205 
206 	INFO("MBOX: %s: mbox_err 0x%x, nbytes_ret %d\n", __func__,
207 		resp->err_code, nbytes_ret);
208 
209 	ret_args[ret_args_len++] = INTEL_SIP_SMC_STATUS_OK;
210 	ret_args[ret_args_len++] = resp->err_code;
211 	ret_args[ret_args_len++] = nbytes_ret;
212 
213 	return ret_args_len;
214 }
215 
216 uint8_t fcs_cs_data_sign_req_cb(void *resp_desc, void *cmd_desc, uint64_t *ret_args)
217 {
218 	uint8_t ret_args_len = 0U;
219 	sdm_response_t *resp = (sdm_response_t *)resp_desc;
220 	sdm_command_t *cmd = (sdm_command_t *)cmd_desc;
221 
222 	INFO("MBOX: %s: mbox_err 0x%x, nbytes_ret %d\n", __func__,
223 		resp->err_code, resp->rcvd_resp_len * MBOX_WORD_BYTE);
224 
225 	ret_args[ret_args_len++] = INTEL_SIP_SMC_STATUS_OK;
226 	ret_args[ret_args_len++] = resp->err_code;
227 	ret_args[ret_args_len++] = resp->rcvd_resp_len * MBOX_WORD_BYTE;
228 
229 	/* Flush the response data buffer. */
230 	flush_dcache_range((uintptr_t)cmd->cb_args, resp->rcvd_resp_len * MBOX_WORD_BYTE);
231 	return ret_args_len;
232 }
233 
234 uint8_t fcs_sdos_crypto_request_cb(void *resp_desc, void *cmd_desc, uint64_t *ret_args)
235 {
236 	uint8_t ret_args_len = 0U;
237 	sdm_response_t *resp = (sdm_response_t *)resp_desc;
238 	sdm_command_t *cmd = (sdm_command_t *)cmd_desc;
239 
240 	(void)cmd;
241 	INFO("MBOX: %s: mailbox_err 0x%x, nbytes_ret %d\n",
242 		__func__, resp->err_code, resp->resp_data[3]);
243 
244 	ret_args[ret_args_len++] = INTEL_SIP_SMC_STATUS_OK;
245 	ret_args[ret_args_len++] = resp->err_code;
246 	/* Encrypted/Decrypted data size written to the destination buffer */
247 	ret_args[ret_args_len++] = resp->resp_data[3];
248 
249 	return ret_args_len;
250 }
251 
252 uint8_t fcs_cs_get_public_key_cb(void *resp_desc, void *cmd_desc, uint64_t *ret_args)
253 {
254 	uint8_t ret_args_len = 0U;
255 	sdm_response_t *resp = (sdm_response_t *)resp_desc;
256 	sdm_command_t *cmd = (sdm_command_t *)cmd_desc;
257 
258 	INFO("MBOX: %s: mbox_err 0x%x, nbytes_ret %u\n",
259 			__func__, resp->err_code,
260 			resp->rcvd_resp_len * MBOX_WORD_BYTE);
261 
262 	ret_args[ret_args_len++] = INTEL_SIP_SMC_STATUS_OK;
263 	ret_args[ret_args_len++] = resp->err_code;
264 	ret_args[ret_args_len++] = resp->rcvd_resp_len * MBOX_WORD_BYTE;
265 
266 	/* Flush the response data buffer. */
267 	flush_dcache_range((uintptr_t)cmd->cb_args, resp->rcvd_resp_len * MBOX_WORD_BYTE);
268 
269 	return ret_args_len;
270 }
271 
272 uint8_t fcs_cs_data_sig_verify_req_cb(void *resp_desc, void *cmd_desc, uint64_t *ret_args)
273 {
274 	uint8_t ret_args_len = 0U;
275 	sdm_response_t *resp = (sdm_response_t *)resp_desc;
276 	sdm_command_t *cmd = (sdm_command_t *)cmd_desc;
277 
278 	INFO("MBOX: %s: mbox_err 0x%x, nbytes_ret 0x%x\n",
279 			__func__, resp->err_code, resp->rcvd_resp_len);
280 
281 	ret_args[ret_args_len++] = INTEL_SIP_SMC_STATUS_OK;
282 	ret_args[ret_args_len++] = resp->err_code;
283 	ret_args[ret_args_len++] = resp->rcvd_resp_len * MBOX_WORD_BYTE;
284 
285 	/* Flush the response data buffer. */
286 	flush_dcache_range((uintptr_t)cmd->cb_args, resp->rcvd_resp_len * MBOX_WORD_BYTE);
287 
288 	return ret_args_len;
289 }
290 
291 uint8_t fcs_cs_ecdh_request_cb(void *resp_desc, void *cmd_desc, uint64_t *ret_args)
292 {
293 	uint8_t ret_args_len = 0U;
294 	sdm_response_t *resp = (sdm_response_t *)resp_desc;
295 	sdm_command_t *cmd = (sdm_command_t *)cmd_desc;
296 
297 	INFO("MBOX: %s: [0] 0%x, [1] 0x%x, [2] 0x%x, len_words %d\n",
298 			__func__, resp->resp_data[0], resp->resp_data[1],
299 			resp->resp_data[2], resp->rcvd_resp_len);
300 
301 	ret_args[ret_args_len++] = INTEL_SIP_SMC_STATUS_OK;
302 	ret_args[ret_args_len++] = resp->err_code;
303 	ret_args[ret_args_len++] = resp->rcvd_resp_len * MBOX_WORD_BYTE;
304 
305 	/* Flush the response data buffer. */
306 	flush_dcache_range((uintptr_t)cmd->cb_args, resp->rcvd_resp_len * MBOX_WORD_BYTE);
307 
308 	return ret_args_len;
309 }
310 
311 static int intel_fcs_crypto_service_init(uint32_t session_id,
312 			uint32_t context_id, uint32_t key_id,
313 			uint32_t param_size, uint64_t param_data,
314 			fcs_crypto_service_data *data_addr,
315 			uint32_t *mbox_error)
316 {
317 	if (mbox_error == NULL) {
318 		return INTEL_SIP_SMC_STATUS_REJECTED;
319 	}
320 
321 	if (param_size != 4) {
322 		return INTEL_SIP_SMC_STATUS_REJECTED;
323 	}
324 
325 	memset(data_addr, 0, sizeof(fcs_crypto_service_data));
326 
327 	data_addr->session_id = session_id;
328 	data_addr->context_id = context_id;
329 	data_addr->key_id = key_id;
330 	data_addr->crypto_param_size = param_size;
331 	data_addr->crypto_param = param_data;
332 
333 	data_addr->is_updated = 0;
334 
335 	*mbox_error = 0;
336 
337 	return INTEL_SIP_SMC_STATUS_OK;
338 }
339 
340 uint32_t intel_fcs_random_number_gen(uint64_t addr, uint64_t *ret_size,
341 					uint32_t *mbox_error)
342 {
343 	int status;
344 	unsigned int i;
345 	unsigned int resp_len = FCS_RANDOM_WORD_SIZE;
346 	uint32_t random_data[FCS_RANDOM_WORD_SIZE] = {0U};
347 
348 	if (!is_address_in_ddr_range(addr, FCS_RANDOM_BYTE_SIZE)) {
349 		return INTEL_SIP_SMC_STATUS_REJECTED;
350 	}
351 
352 	status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_RANDOM_GEN, NULL, 0U,
353 			CMD_CASUAL, random_data, &resp_len);
354 
355 	if (status < 0) {
356 		*mbox_error = -status;
357 		return INTEL_SIP_SMC_STATUS_ERROR;
358 	}
359 
360 	if (resp_len != FCS_RANDOM_WORD_SIZE) {
361 		*mbox_error = GENERIC_RESPONSE_ERROR;
362 		return INTEL_SIP_SMC_STATUS_ERROR;
363 	}
364 
365 	*ret_size = FCS_RANDOM_BYTE_SIZE;
366 
367 	for (i = 0U; i < FCS_RANDOM_WORD_SIZE; i++) {
368 		mmio_write_32(addr, random_data[i]);
369 		addr += MBOX_WORD_BYTE;
370 	}
371 
372 	flush_dcache_range(addr - *ret_size, *ret_size);
373 
374 	return INTEL_SIP_SMC_STATUS_OK;
375 }
376 
377 int intel_fcs_random_number_gen_ext(uint32_t session_id, uint32_t context_id,
378 				uint32_t size, uint32_t *send_id)
379 {
380 	int status;
381 	uint32_t payload_size;
382 	uint32_t crypto_header;
383 
384 	if (size > (FCS_RANDOM_EXT_MAX_WORD_SIZE *
385 		MBOX_WORD_BYTE) || size == 0U) {
386 		return INTEL_SIP_SMC_STATUS_REJECTED;
387 	}
388 
389 	if (!is_size_4_bytes_aligned(size)) {
390 		return INTEL_SIP_SMC_STATUS_REJECTED;
391 	}
392 
393 	crypto_header = (FCS_CS_FIELD_FLAG_INIT | FCS_CS_FIELD_FLAG_FINALIZE) <<
394 			FCS_CS_FIELD_FLAG_OFFSET;
395 
396 	fcs_rng_payload payload = {
397 		session_id,
398 		context_id,
399 		crypto_header,
400 		size
401 	};
402 
403 	payload_size = sizeof(payload) / MBOX_WORD_BYTE;
404 
405 	status = mailbox_send_cmd_async(send_id, MBOX_FCS_RANDOM_GEN,
406 					(uint32_t *) &payload, payload_size,
407 					CMD_INDIRECT);
408 
409 	if (status < 0) {
410 		return INTEL_SIP_SMC_STATUS_ERROR;
411 	}
412 
413 	return INTEL_SIP_SMC_STATUS_OK;
414 }
415 
416 uint32_t intel_fcs_send_cert(uint32_t smc_fid, uint32_t trans_id,
417 			     uint64_t addr, uint64_t size,
418 					uint32_t *send_id)
419 {
420 	int status;
421 
422 	if (!is_address_in_ddr_range(addr, size)) {
423 		return INTEL_SIP_SMC_STATUS_REJECTED;
424 	}
425 
426 	if (!is_size_4_bytes_aligned(size)) {
427 		return INTEL_SIP_SMC_STATUS_REJECTED;
428 	}
429 
430 	status = (smc_fid == ALTERA_SIP_SMC_ASYNC_FCS_SEND_CERTIFICATE) ?
431 		mailbox_send_cmd_async_v3(GET_CLIENT_ID(trans_id),
432 					GET_JOB_ID(trans_id),
433 					MBOX_CMD_VAB_SRC_CERT,
434 					(uint32_t *) addr,
435 					size / MBOX_WORD_BYTE,
436 					MBOX_CMD_FLAG_CASUAL,
437 					fcs_send_cert_cb,
438 					NULL,
439 					0U) :
440 		mailbox_send_cmd_async(send_id, MBOX_CMD_VAB_SRC_CERT,
441 				(uint32_t *)addr, size / MBOX_WORD_BYTE,
442 				CMD_DIRECT);
443 
444 	flush_dcache_range(addr, size);
445 
446 	if (status < 0) {
447 		return INTEL_SIP_SMC_STATUS_ERROR;
448 	}
449 
450 	return INTEL_SIP_SMC_STATUS_OK;
451 }
452 
453 uint32_t intel_fcs_get_provision_data(uint32_t *send_id)
454 {
455 	int status;
456 
457 	status = mailbox_send_cmd_async(send_id, MBOX_FCS_GET_PROVISION,
458 				NULL, 0U, CMD_DIRECT);
459 
460 	if (status < 0) {
461 		return INTEL_SIP_SMC_STATUS_ERROR;
462 	}
463 
464 	return INTEL_SIP_SMC_STATUS_OK;
465 }
466 
467 uint32_t intel_fcs_cntr_set_preauth(uint32_t smc_fid, uint32_t trans_id,
468 				    uint8_t counter_type, int32_t counter_value,
469 					uint32_t test_bit, uint32_t *mbox_error)
470 {
471 	int status;
472 	uint32_t first_word;
473 	uint32_t payload_size;
474 
475 	if ((test_bit != MBOX_TEST_BIT) &&
476 		(test_bit != 0)) {
477 		return INTEL_SIP_SMC_STATUS_REJECTED;
478 	}
479 
480 	if ((counter_type < FCS_BIG_CNTR_SEL) ||
481 		(counter_type > FCS_SVN_CNTR_3_SEL)) {
482 		return INTEL_SIP_SMC_STATUS_REJECTED;
483 	}
484 
485 	if ((counter_type == FCS_BIG_CNTR_SEL) &&
486 		(counter_value > FCS_BIG_CNTR_VAL_MAX)) {
487 		return INTEL_SIP_SMC_STATUS_REJECTED;
488 	}
489 
490 	if ((counter_type >= FCS_SVN_CNTR_0_SEL) &&
491 		(counter_type <= FCS_SVN_CNTR_3_SEL) &&
492 		(counter_value > FCS_SVN_CNTR_VAL_MAX)) {
493 		return INTEL_SIP_SMC_STATUS_REJECTED;
494 	}
495 
496 	first_word = test_bit | counter_type;
497 	fcs_cntr_set_preauth_payload payload = {
498 		first_word,
499 		counter_value
500 	};
501 
502 	payload_size = sizeof(payload) / MBOX_WORD_BYTE;
503 
504 	status = (smc_fid == ALTERA_SIP_SMC_ASYNC_FCS_CNTR_SET_PREAUTH) ?
505 			mailbox_send_cmd_async_v3(GET_CLIENT_ID(trans_id),
506 						  GET_JOB_ID(trans_id),
507 						  MBOX_FCS_CNTR_SET_PREAUTH,
508 						  (uint32_t *) &payload,
509 						  payload_size,
510 						  MBOX_CMD_FLAG_CASUAL,
511 						  fcs_cntr_set_preauth_cb,
512 						  NULL,
513 						  0U) :
514 			mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_CNTR_SET_PREAUTH,
515 				  (uint32_t *) &payload, payload_size,
516 				  CMD_CASUAL, NULL, NULL);
517 
518 	if (status < 0) {
519 		*mbox_error = -status;
520 		return INTEL_SIP_SMC_STATUS_ERROR;
521 	}
522 
523 	return INTEL_SIP_SMC_STATUS_OK;
524 }
525 
526 uint32_t intel_fcs_encryption(uint32_t src_addr, uint32_t src_size,
527 		uint32_t dst_addr, uint32_t dst_size, uint32_t *send_id)
528 {
529 	int status;
530 	uint32_t load_size;
531 
532 	if (!is_address_in_ddr_range(src_addr, src_size) ||
533 		!is_address_in_ddr_range(dst_addr, dst_size)) {
534 		return INTEL_SIP_SMC_STATUS_REJECTED;
535 	}
536 
537 	if (!is_size_4_bytes_aligned(src_size)) {
538 		return INTEL_SIP_SMC_STATUS_REJECTED;
539 	}
540 
541 	fcs_encrypt_payload payload = {
542 		FCS_ENCRYPTION_DATA_0,
543 		src_addr,
544 		src_size,
545 		dst_addr,
546 		dst_size };
547 	load_size = sizeof(payload) / MBOX_WORD_BYTE;
548 
549 	status = mailbox_send_cmd_async(send_id, MBOX_FCS_ENCRYPT_REQ,
550 				(uint32_t *) &payload, load_size,
551 				CMD_INDIRECT);
552 	inv_dcache_range(dst_addr, dst_size);
553 
554 	if (status < 0) {
555 		return INTEL_SIP_SMC_STATUS_REJECTED;
556 	}
557 
558 	return INTEL_SIP_SMC_STATUS_OK;
559 }
560 
561 uint32_t intel_fcs_decryption(uint32_t src_addr, uint32_t src_size,
562 		uint32_t dst_addr, uint32_t dst_size, uint32_t *send_id)
563 {
564 	int status;
565 	uint32_t load_size;
566 	uintptr_t id_offset;
567 
568 	if (!is_address_in_ddr_range(src_addr, src_size) ||
569 		!is_address_in_ddr_range(dst_addr, dst_size)) {
570 		return INTEL_SIP_SMC_STATUS_REJECTED;
571 	}
572 
573 	if (!is_size_4_bytes_aligned(src_size)) {
574 		return INTEL_SIP_SMC_STATUS_REJECTED;
575 	}
576 
577 	inv_dcache_range(src_addr, src_size); /* flush cache before mmio read to avoid reading old values */
578 	id_offset = src_addr + FCS_OWNER_ID_OFFSET;
579 	fcs_decrypt_payload payload = {
580 		FCS_DECRYPTION_DATA_0,
581 		{mmio_read_32(id_offset),
582 		mmio_read_32(id_offset + MBOX_WORD_BYTE)},
583 		src_addr,
584 		src_size,
585 		dst_addr,
586 		dst_size };
587 	load_size = sizeof(payload) / MBOX_WORD_BYTE;
588 
589 	status = mailbox_send_cmd_async(send_id, MBOX_FCS_DECRYPT_REQ,
590 				(uint32_t *) &payload, load_size,
591 				CMD_INDIRECT);
592 	inv_dcache_range(dst_addr, dst_size);
593 
594 	if (status < 0) {
595 		return INTEL_SIP_SMC_STATUS_REJECTED;
596 	}
597 
598 	return INTEL_SIP_SMC_STATUS_OK;
599 }
600 
601 int intel_fcs_encryption_ext(uint32_t smc_fid, uint32_t trans_id,
602 		uint32_t session_id, uint32_t context_id,
603 		uint32_t src_addr, uint32_t src_size,
604 		uint32_t dst_addr, uint32_t *dst_size, uint32_t *mbox_error,
605 		uint32_t smmu_src_addr, uint32_t smmu_dst_addr)
606 {
607 	int status;
608 	uint32_t payload_size;
609 	uint32_t resp_len = FCS_CRYPTION_RESP_WORD_SIZE;
610 	uint32_t resp_data[FCS_CRYPTION_RESP_WORD_SIZE] = {0U};
611 	uint32_t src_addr_sdm = src_addr;
612 	uint32_t dst_addr_sdm = dst_addr;
613 
614 	if ((dst_size == NULL) || (mbox_error == NULL)) {
615 		return INTEL_SIP_SMC_STATUS_REJECTED;
616 	}
617 
618 	if (!is_address_in_ddr_range(src_addr, src_size) ||
619 		!is_address_in_ddr_range(dst_addr, *dst_size)) {
620 		return INTEL_SIP_SMC_STATUS_REJECTED;
621 	}
622 
623 	if (!is_size_4_bytes_aligned(src_size)) {
624 		return INTEL_SIP_SMC_STATUS_REJECTED;
625 	}
626 
627 	/* On the Agilex5 platform, we will use the SMMU payload address */
628 #if PLATFORM_MODEL == PLAT_SOCFPGA_AGILEX5
629 	src_addr_sdm = smmu_src_addr;
630 	dst_addr_sdm = smmu_dst_addr;
631 #endif
632 
633 	fcs_encrypt_ext_payload payload = {
634 		session_id,
635 		context_id,
636 		FCS_CRYPTION_CRYPTO_HEADER,
637 		src_addr_sdm,
638 		src_size,
639 		dst_addr_sdm,
640 		*dst_size
641 	};
642 
643 	payload_size = sizeof(payload) / MBOX_WORD_BYTE;
644 
645 	status = (smc_fid == ALTERA_SIP_SMC_ASYNC_FCS_CRYPTION_EXT) ?
646 		mailbox_send_cmd_async_v3(GET_CLIENT_ID(trans_id),
647 					GET_JOB_ID(trans_id),
648 					MBOX_FCS_ENCRYPT_REQ,
649 					(uint32_t *) &payload,
650 					payload_size,
651 					MBOX_CMD_FLAG_INDIRECT,
652 					fcs_sdos_crypto_request_cb,
653 					NULL,
654 					0U) :
655 		mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_ENCRYPT_REQ,
656 				(uint32_t *) &payload, payload_size,
657 				CMD_CASUAL, resp_data, &resp_len);
658 
659 	if (status < 0) {
660 		*mbox_error = -status;
661 		return INTEL_SIP_SMC_STATUS_ERROR;
662 	}
663 
664 	if (resp_len != FCS_CRYPTION_RESP_WORD_SIZE) {
665 		*mbox_error = MBOX_RET_ERROR;
666 		return INTEL_SIP_SMC_STATUS_ERROR;
667 	}
668 
669 	*dst_size = resp_data[FCS_CRYPTION_RESP_SIZE_OFFSET];
670 	inv_dcache_range(dst_addr, *dst_size);
671 
672 	return INTEL_SIP_SMC_STATUS_OK;
673 }
674 
675 int intel_fcs_decryption_ext(uint32_t smc_fid, uint32_t trans_id,
676 		uint32_t session_id, uint32_t context_id,
677 		uint32_t src_addr, uint32_t src_size,
678 		uint32_t dst_addr, uint32_t *dst_size,
679 		uint32_t *mbox_error, uint64_t owner_id,
680 		uint32_t smmu_src_addr, uint32_t smmu_dst_addr)
681 {
682 	int status;
683 	uintptr_t id_offset;
684 	uint32_t payload_size;
685 	uint32_t resp_len = FCS_CRYPTION_RESP_WORD_SIZE;
686 	uint32_t resp_data[FCS_CRYPTION_RESP_WORD_SIZE] = {0U};
687 	uint32_t src_addr_sdm = src_addr;
688 	uint32_t dst_addr_sdm = dst_addr;
689 
690 	if ((dst_size == NULL) || (mbox_error == NULL)) {
691 		return INTEL_SIP_SMC_STATUS_REJECTED;
692 	}
693 
694 	if (!is_address_in_ddr_range(src_addr, src_size) ||
695 		!is_address_in_ddr_range(dst_addr, *dst_size)) {
696 		return INTEL_SIP_SMC_STATUS_REJECTED;
697 	}
698 
699 	if (!is_size_4_bytes_aligned(src_size)) {
700 		return INTEL_SIP_SMC_STATUS_REJECTED;
701 	}
702 
703 	/* On the Agilex5 platform, we will use the SMMU payload address */
704 #if PLATFORM_MODEL == PLAT_SOCFPGA_AGILEX5
705 	src_addr_sdm = smmu_src_addr;
706 	dst_addr_sdm = smmu_dst_addr;
707 #endif
708 
709 	inv_dcache_range(src_addr, src_size); /* flush cache before mmio read to avoid reading old values */
710 	id_offset = src_addr + FCS_OWNER_ID_OFFSET;
711 	fcs_decrypt_ext_payload payload = {
712 		session_id,
713 		context_id,
714 		FCS_CRYPTION_CRYPTO_HEADER,
715 		{mmio_read_32(id_offset),
716 		mmio_read_32(id_offset + MBOX_WORD_BYTE)},
717 		src_addr_sdm,
718 		src_size,
719 		dst_addr_sdm,
720 		*dst_size
721 	};
722 
723 	payload_size = sizeof(payload) / MBOX_WORD_BYTE;
724 
725 	status = (smc_fid == ALTERA_SIP_SMC_ASYNC_FCS_CRYPTION_EXT) ?
726 		mailbox_send_cmd_async_v3(GET_CLIENT_ID(trans_id),
727 					GET_JOB_ID(trans_id),
728 					MBOX_FCS_DECRYPT_REQ,
729 					(uint32_t *) &payload,
730 					payload_size,
731 					MBOX_CMD_FLAG_INDIRECT,
732 					fcs_sdos_crypto_request_cb,
733 					NULL,
734 					0U) :
735 		mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_DECRYPT_REQ,
736 				(uint32_t *) &payload, payload_size,
737 				CMD_CASUAL, resp_data, &resp_len);
738 
739 	if (status == MBOX_RET_SDOS_DECRYPTION_ERROR_102 ||
740 		status == MBOX_RET_SDOS_DECRYPTION_ERROR_103) {
741 		*mbox_error = -status;
742 	} else if (status < 0) {
743 		*mbox_error = -status;
744 		return INTEL_SIP_SMC_STATUS_ERROR;
745 	}
746 
747 	if (resp_len != FCS_CRYPTION_RESP_WORD_SIZE) {
748 		*mbox_error = MBOX_RET_ERROR;
749 		return INTEL_SIP_SMC_STATUS_ERROR;
750 	}
751 
752 	*dst_size = resp_data[FCS_CRYPTION_RESP_SIZE_OFFSET];
753 	inv_dcache_range(dst_addr, *dst_size);
754 
755 	return INTEL_SIP_SMC_STATUS_OK;
756 }
757 
758 int intel_fcs_sigma_teardown(uint32_t session_id, uint32_t *mbox_error)
759 {
760 	int status;
761 
762 	if ((session_id != PSGSIGMA_SESSION_ID_ONE) &&
763 		(session_id != PSGSIGMA_UNKNOWN_SESSION)) {
764 		return INTEL_SIP_SMC_STATUS_REJECTED;
765 	}
766 
767 	psgsigma_teardown_msg message = {
768 		RESERVED_AS_ZERO,
769 		PSGSIGMA_TEARDOWN_MAGIC,
770 		session_id
771 	};
772 
773 	status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_PSG_SIGMA_TEARDOWN,
774 			(uint32_t *) &message, sizeof(message) / MBOX_WORD_BYTE,
775 			CMD_CASUAL, NULL, NULL);
776 
777 	if (status < 0) {
778 		*mbox_error = -status;
779 		return INTEL_SIP_SMC_STATUS_ERROR;
780 	}
781 
782 	return INTEL_SIP_SMC_STATUS_OK;
783 }
784 
785 int intel_fcs_chip_id(uint32_t *id_low, uint32_t *id_high, uint32_t *mbox_error)
786 {
787 	int status;
788 	uint32_t load_size;
789 	uint32_t chip_id[2];
790 
791 	load_size = sizeof(chip_id) / MBOX_WORD_BYTE;
792 
793 	status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_CMD_GET_CHIPID, NULL,
794 			0U, CMD_CASUAL, (uint32_t *) chip_id, &load_size);
795 
796 	if (status < 0) {
797 		*mbox_error = -status;
798 		return INTEL_SIP_SMC_STATUS_ERROR;
799 	}
800 
801 	*id_low = chip_id[0];
802 	*id_high = chip_id[1];
803 
804 	return INTEL_SIP_SMC_STATUS_OK;
805 }
806 
807 int intel_fcs_attestation_subkey(uint64_t src_addr, uint32_t src_size,
808 		uint64_t dst_addr, uint32_t *dst_size, uint32_t *mbox_error)
809 {
810 	int status;
811 	uint32_t send_size = src_size / MBOX_WORD_BYTE;
812 	uint32_t ret_size = *dst_size / MBOX_WORD_BYTE;
813 
814 
815 	if (!is_address_in_ddr_range(src_addr, src_size) ||
816 		!is_address_in_ddr_range(dst_addr, *dst_size)) {
817 		return INTEL_SIP_SMC_STATUS_REJECTED;
818 	}
819 
820 	status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_ATTESTATION_SUBKEY,
821 			(uint32_t *) src_addr, send_size, CMD_CASUAL,
822 			(uint32_t *) dst_addr, &ret_size);
823 
824 	if (status < 0) {
825 		*mbox_error = -status;
826 		return INTEL_SIP_SMC_STATUS_ERROR;
827 	}
828 
829 	*dst_size = ret_size * MBOX_WORD_BYTE;
830 	flush_dcache_range(dst_addr, *dst_size);
831 
832 	return INTEL_SIP_SMC_STATUS_OK;
833 }
834 
835 int intel_fcs_get_measurement(uint64_t src_addr, uint32_t src_size,
836 		uint64_t dst_addr, uint32_t *dst_size, uint32_t *mbox_error)
837 {
838 	int status;
839 	uint32_t send_size = src_size / MBOX_WORD_BYTE;
840 	uint32_t ret_size = *dst_size / MBOX_WORD_BYTE;
841 
842 	if (!is_address_in_ddr_range(src_addr, src_size) ||
843 		!is_address_in_ddr_range(dst_addr, *dst_size)) {
844 		return INTEL_SIP_SMC_STATUS_REJECTED;
845 	}
846 
847 	status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_GET_MEASUREMENT,
848 			(uint32_t *) src_addr, send_size, CMD_CASUAL,
849 			(uint32_t *) dst_addr, &ret_size);
850 
851 	if (status < 0) {
852 		*mbox_error = -status;
853 		return INTEL_SIP_SMC_STATUS_ERROR;
854 	}
855 
856 	*dst_size = ret_size * MBOX_WORD_BYTE;
857 	flush_dcache_range(dst_addr, *dst_size);
858 
859 	return INTEL_SIP_SMC_STATUS_OK;
860 }
861 
862 uint32_t intel_fcs_get_rom_patch_sha384(uint64_t addr, uint64_t *ret_size,
863 					uint32_t *mbox_error)
864 {
865 	int status;
866 	unsigned int resp_len = FCS_SHA384_WORD_SIZE;
867 
868 	if (!is_address_in_ddr_range(addr, FCS_SHA384_BYTE_SIZE)) {
869 		return INTEL_SIP_SMC_STATUS_REJECTED;
870 	}
871 
872 	status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_GET_ROM_PATCH_SHA384, NULL, 0U,
873 			CMD_CASUAL, (uint32_t *) addr, &resp_len);
874 
875 	if (status < 0) {
876 		*mbox_error = -status;
877 		return INTEL_SIP_SMC_STATUS_ERROR;
878 	}
879 
880 	if (resp_len != FCS_SHA384_WORD_SIZE) {
881 		*mbox_error = GENERIC_RESPONSE_ERROR;
882 		return INTEL_SIP_SMC_STATUS_ERROR;
883 	}
884 
885 	*ret_size = FCS_SHA384_BYTE_SIZE;
886 
887 	flush_dcache_range(addr, *ret_size);
888 
889 	return INTEL_SIP_SMC_STATUS_OK;
890 }
891 
892 int intel_fcs_get_attestation_cert(uint32_t smc_fid, uint32_t trans_id,
893 			uint32_t cert_request, uint64_t dst_addr,
894 			uint32_t *dst_size, uint32_t *mbox_error)
895 {
896 	int status;
897 	uint32_t ret_size = *dst_size / MBOX_WORD_BYTE;
898 
899 	if (mbox_error == NULL) {
900 		return INTEL_SIP_SMC_STATUS_REJECTED;
901 	}
902 
903 	if (cert_request < FCS_ATTEST_FIRMWARE_CERT ||
904 		cert_request > FCS_ATTEST_CERT_MAX_REQ_PARAM) {
905 		return INTEL_SIP_SMC_STATUS_REJECTED;
906 	}
907 
908 	if (!is_address_in_ddr_range(dst_addr, *dst_size)) {
909 		return INTEL_SIP_SMC_STATUS_REJECTED;
910 	}
911 
912 	status = (smc_fid == ALTERA_SIP_SMC_ASYNC_FCS_GET_ATTESTATION_CERT) ?
913 		mailbox_send_cmd_async_v3(GET_CLIENT_ID(trans_id),
914 					GET_JOB_ID(trans_id),
915 					MBOX_GET_ATTESTATION_CERT,
916 					(uint32_t *) &cert_request,
917 					1U,
918 					MBOX_CMD_FLAG_CASUAL,
919 					fcs_get_attest_cert_cb,
920 					(uint32_t *)dst_addr,
921 					2U) :
922 		mailbox_send_cmd(MBOX_JOB_ID, MBOX_GET_ATTESTATION_CERT,
923 			(uint32_t *) &cert_request, 1U, CMD_CASUAL,
924 			(uint32_t *) dst_addr, &ret_size);
925 
926 	if (status < 0) {
927 		*mbox_error = -status;
928 		return INTEL_SIP_SMC_STATUS_ERROR;
929 	}
930 
931 	*dst_size = ret_size * MBOX_WORD_BYTE;
932 	flush_dcache_range(dst_addr, *dst_size);
933 
934 	return INTEL_SIP_SMC_STATUS_OK;
935 }
936 
937 int intel_fcs_create_cert_on_reload(uint32_t smc_fid, uint32_t trans_id,
938 				uint32_t cert_request, uint32_t *mbox_error)
939 {
940 	int status;
941 
942 	if (mbox_error == NULL) {
943 		return INTEL_SIP_SMC_STATUS_REJECTED;
944 	}
945 
946 	if (cert_request < FCS_ATTEST_FIRMWARE_CERT ||
947 		cert_request > FCS_ATTEST_CERT_MAX_REQ_PARAM) {
948 		return INTEL_SIP_SMC_STATUS_REJECTED;
949 	}
950 
951 	status = (smc_fid == ALTERA_SIP_SMC_ASYNC_FCS_CREATE_CERT_ON_RELOAD) ?
952 		mailbox_send_cmd_async_v3(GET_CLIENT_ID(trans_id),
953 					GET_JOB_ID(trans_id),
954 					MBOX_CREATE_CERT_ON_RELOAD,
955 					(uint32_t *) &cert_request,
956 					1U,
957 					MBOX_CMD_FLAG_CASUAL,
958 					fcs_create_cert_reload_cb,
959 					NULL,
960 					0U) :
961 		mailbox_send_cmd(MBOX_JOB_ID, MBOX_CREATE_CERT_ON_RELOAD,
962 			(uint32_t *) &cert_request, 1U, CMD_CASUAL,
963 			NULL, NULL);
964 
965 	if (status < 0) {
966 		*mbox_error = -status;
967 		return INTEL_SIP_SMC_STATUS_ERROR;
968 	}
969 
970 	return INTEL_SIP_SMC_STATUS_OK;
971 }
972 
973 int intel_fcs_open_crypto_service_session(uint32_t *session_id,
974 			uint32_t *mbox_error)
975 {
976 	int status;
977 	uint32_t resp_len = 1U;
978 
979 	if ((session_id == NULL) || (mbox_error == NULL)) {
980 		return INTEL_SIP_SMC_STATUS_REJECTED;
981 	}
982 
983 	status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_OPEN_CS_SESSION,
984 			NULL, 0U, CMD_CASUAL, session_id, &resp_len);
985 
986 	if (status < 0) {
987 		*mbox_error = -status;
988 		return INTEL_SIP_SMC_STATUS_ERROR;
989 	}
990 
991 	return INTEL_SIP_SMC_STATUS_OK;
992 }
993 
994 int intel_fcs_close_crypto_service_session(uint32_t session_id,
995 			uint32_t *mbox_error)
996 {
997 	int status;
998 
999 	if (mbox_error == NULL) {
1000 		return INTEL_SIP_SMC_STATUS_REJECTED;
1001 	}
1002 
1003 	status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_CLOSE_CS_SESSION,
1004 			&session_id, 1U, CMD_CASUAL, NULL, NULL);
1005 
1006 	if (status < 0) {
1007 		*mbox_error = -status;
1008 		return INTEL_SIP_SMC_STATUS_ERROR;
1009 	}
1010 
1011 	return INTEL_SIP_SMC_STATUS_OK;
1012 }
1013 
1014 int intel_fcs_import_crypto_service_key(uint64_t src_addr, uint32_t src_size,
1015 		uint32_t *send_id)
1016 {
1017 	int status;
1018 
1019 	if (src_size > (FCS_CS_KEY_OBJ_MAX_WORD_SIZE *
1020 		MBOX_WORD_BYTE)) {
1021 		return INTEL_SIP_SMC_STATUS_REJECTED;
1022 	}
1023 
1024 	if (!is_address_in_ddr_range(src_addr, src_size)) {
1025 		return INTEL_SIP_SMC_STATUS_REJECTED;
1026 	}
1027 
1028 	status = mailbox_send_cmd_async(send_id, MBOX_FCS_IMPORT_CS_KEY,
1029 				(uint32_t *)src_addr, src_size / MBOX_WORD_BYTE,
1030 				CMD_INDIRECT);
1031 
1032 	if (status < 0) {
1033 		return INTEL_SIP_SMC_STATUS_ERROR;
1034 	}
1035 
1036 	return INTEL_SIP_SMC_STATUS_OK;
1037 }
1038 
1039 int intel_fcs_export_crypto_service_key(uint32_t session_id, uint32_t key_id,
1040 		uint64_t dst_addr, uint32_t *dst_size,
1041 		uint32_t *mbox_error)
1042 {
1043 	int status;
1044 	uint32_t i;
1045 	uint32_t payload_size;
1046 	uint32_t resp_len = FCS_CS_KEY_OBJ_MAX_WORD_SIZE;
1047 	uint32_t resp_data[FCS_CS_KEY_OBJ_MAX_WORD_SIZE] = {0U};
1048 	uint32_t op_status = 0U;
1049 
1050 	if ((dst_size == NULL) || (mbox_error == NULL)) {
1051 		return INTEL_SIP_SMC_STATUS_REJECTED;
1052 	}
1053 
1054 	if (!is_address_in_ddr_range(dst_addr, *dst_size)) {
1055 		return INTEL_SIP_SMC_STATUS_REJECTED;
1056 	}
1057 
1058 	fcs_cs_key_payload payload = {
1059 		session_id,
1060 		RESERVED_AS_ZERO,
1061 		RESERVED_AS_ZERO,
1062 		key_id
1063 	};
1064 
1065 	payload_size = sizeof(payload) / MBOX_WORD_BYTE;
1066 
1067 	status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_EXPORT_CS_KEY,
1068 			(uint32_t *) &payload, payload_size,
1069 			CMD_CASUAL, resp_data, &resp_len);
1070 
1071 	if (resp_len > 0) {
1072 		op_status = resp_data[0] & FCS_CS_KEY_RESP_STATUS_MASK;
1073 	}
1074 
1075 	if (status < 0) {
1076 		*mbox_error = (-status) | (op_status << FCS_CS_KEY_RESP_STATUS_OFFSET);
1077 		return INTEL_SIP_SMC_STATUS_ERROR;
1078 	}
1079 
1080 	if (resp_len > 1) {
1081 
1082 		/* Export key object is start at second response data */
1083 		*dst_size = (resp_len - 1) * MBOX_WORD_BYTE;
1084 
1085 		for (i = 1U; i < resp_len; i++) {
1086 			mmio_write_32(dst_addr, resp_data[i]);
1087 			dst_addr += MBOX_WORD_BYTE;
1088 		}
1089 
1090 		flush_dcache_range(dst_addr - *dst_size, *dst_size);
1091 
1092 	} else {
1093 
1094 		/* Unexpected response, missing key object in response */
1095 		*mbox_error = MBOX_RET_ERROR;
1096 		return INTEL_SIP_SMC_STATUS_ERROR;
1097 	}
1098 
1099 	return INTEL_SIP_SMC_STATUS_OK;
1100 }
1101 
1102 int intel_fcs_remove_crypto_service_key(uint32_t session_id, uint32_t key_id,
1103 		uint32_t *mbox_error)
1104 {
1105 	int status;
1106 	uint32_t payload_size;
1107 	uint32_t resp_len = 1U;
1108 	uint32_t resp_data = 0U;
1109 	uint32_t op_status = 0U;
1110 
1111 	if (mbox_error == NULL) {
1112 		return INTEL_SIP_SMC_STATUS_REJECTED;
1113 	}
1114 
1115 	fcs_cs_key_payload payload = {
1116 		session_id,
1117 		RESERVED_AS_ZERO,
1118 		RESERVED_AS_ZERO,
1119 		key_id
1120 	};
1121 
1122 	payload_size = sizeof(payload) / MBOX_WORD_BYTE;
1123 
1124 	status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_REMOVE_CS_KEY,
1125 			(uint32_t *) &payload, payload_size,
1126 			CMD_CASUAL, &resp_data, &resp_len);
1127 
1128 	if (resp_len > 0) {
1129 		op_status = resp_data & FCS_CS_KEY_RESP_STATUS_MASK;
1130 	}
1131 
1132 	if (status < 0) {
1133 		*mbox_error = (-status) | (op_status << FCS_CS_KEY_RESP_STATUS_OFFSET);
1134 		return INTEL_SIP_SMC_STATUS_ERROR;
1135 	}
1136 
1137 	return INTEL_SIP_SMC_STATUS_OK;
1138 }
1139 
1140 int intel_fcs_get_crypto_service_key_info(uint32_t session_id, uint32_t key_id,
1141 		uint64_t dst_addr, uint32_t *dst_size,
1142 		uint32_t *mbox_error)
1143 {
1144 	int status;
1145 	uint32_t payload_size;
1146 	uint32_t resp_len = FCS_CS_KEY_INFO_MAX_WORD_SIZE;
1147 	uint32_t op_status = 0U;
1148 
1149 	if ((dst_size == NULL) || (mbox_error == NULL)) {
1150 		return INTEL_SIP_SMC_STATUS_REJECTED;
1151 	}
1152 
1153 	if (!is_address_in_ddr_range(dst_addr, *dst_size)) {
1154 		return INTEL_SIP_SMC_STATUS_REJECTED;
1155 	}
1156 
1157 	fcs_cs_key_payload payload = {
1158 		session_id,
1159 		RESERVED_AS_ZERO,
1160 		RESERVED_AS_ZERO,
1161 		key_id
1162 	};
1163 
1164 	payload_size = sizeof(payload) / MBOX_WORD_BYTE;
1165 
1166 	status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_GET_CS_KEY_INFO,
1167 				(uint32_t *) &payload, payload_size,
1168 				CMD_CASUAL, (uint32_t *) dst_addr, &resp_len);
1169 
1170 	if (resp_len > 0) {
1171 		inv_dcache_range(dst_addr, (resp_len * MBOX_WORD_BYTE)); /* flush cache before mmio read to avoid reading old values */
1172 		op_status = mmio_read_32(dst_addr) &
1173 			FCS_CS_KEY_RESP_STATUS_MASK;
1174 	}
1175 
1176 	if (status < 0) {
1177 		*mbox_error = (-status) | (op_status << FCS_CS_KEY_RESP_STATUS_OFFSET);
1178 		return INTEL_SIP_SMC_STATUS_ERROR;
1179 	}
1180 
1181 	*dst_size = resp_len * MBOX_WORD_BYTE;
1182 	flush_dcache_range(dst_addr, *dst_size);
1183 
1184 	return INTEL_SIP_SMC_STATUS_OK;
1185 }
1186 
1187 int intel_fcs_get_digest_init(uint32_t session_id, uint32_t context_id,
1188 				uint32_t key_id, uint32_t param_size,
1189 				uint64_t param_data, uint32_t *mbox_error)
1190 {
1191 	return intel_fcs_crypto_service_init(session_id, context_id,
1192 				key_id, param_size, param_data,
1193 				(void *) &fcs_sha_get_digest_param,
1194 				mbox_error);
1195 }
1196 
1197 int intel_fcs_get_digest_update_finalize(uint32_t smc_fid, uint32_t trans_id,
1198 				uint32_t session_id, uint32_t context_id,
1199 				uint32_t src_addr, uint32_t src_size,
1200 				uint64_t dst_addr, uint32_t *dst_size,
1201 				uint8_t is_finalised, uint32_t *mbox_error,
1202 				uint32_t smmu_src_addr)
1203 {
1204 	int status;
1205 	uint32_t i;
1206 	uint32_t flag;
1207 	uint32_t crypto_header;
1208 	uint32_t resp_len;
1209 	uint32_t payload[FCS_GET_DIGEST_CMD_MAX_WORD_SIZE] = {0U};
1210 
1211 	if (dst_size == NULL || mbox_error == NULL) {
1212 		return INTEL_SIP_SMC_STATUS_REJECTED;
1213 	}
1214 
1215 	if (fcs_sha_get_digest_param.session_id != session_id ||
1216 	    fcs_sha_get_digest_param.context_id != context_id) {
1217 		return INTEL_SIP_SMC_STATUS_REJECTED;
1218 	}
1219 
1220 	/* Source data must be 8 bytes aligned */
1221 	if (!is_8_bytes_aligned(src_size)) {
1222 		return INTEL_SIP_SMC_STATUS_REJECTED;
1223 	}
1224 
1225 	if (!is_address_in_ddr_range(src_addr, src_size) ||
1226 		 !is_address_in_ddr_range(dst_addr, *dst_size)) {
1227 		return INTEL_SIP_SMC_STATUS_REJECTED;
1228 	}
1229 
1230 	resp_len = *dst_size / MBOX_WORD_BYTE;
1231 
1232 	/* Prepare crypto header */
1233 	flag = 0;
1234 
1235 	if (fcs_sha_get_digest_param.is_updated) {
1236 		fcs_sha_get_digest_param.crypto_param_size = 0;
1237 	} else {
1238 		flag |=  FCS_CS_FIELD_FLAG_INIT;
1239 	}
1240 
1241 	if (is_finalised != 0U) {
1242 		flag |=  FCS_CS_FIELD_FLAG_FINALIZE;
1243 	} else {
1244 		flag |=  FCS_CS_FIELD_FLAG_UPDATE;
1245 		fcs_sha_get_digest_param.is_updated = 1;
1246 	}
1247 
1248 	crypto_header = ((flag << FCS_CS_FIELD_FLAG_OFFSET) |
1249 			(fcs_sha_get_digest_param.crypto_param_size &
1250 			FCS_CS_FIELD_SIZE_MASK));
1251 
1252 	/* Prepare command payload */
1253 	i = 0;
1254 	payload[i] = fcs_sha_get_digest_param.session_id;
1255 	i++;
1256 	payload[i] = fcs_sha_get_digest_param.context_id;
1257 	i++;
1258 	payload[i] = crypto_header;
1259 	i++;
1260 
1261 	if ((crypto_header >> FCS_CS_FIELD_FLAG_OFFSET) &
1262 		FCS_CS_FIELD_FLAG_INIT) {
1263 		payload[i] = fcs_sha_get_digest_param.key_id;
1264 		i++;
1265 		/* Crypto parameters */
1266 		payload[i] = fcs_sha_get_digest_param.crypto_param
1267 				& INTEL_SIP_SMC_FCS_SHA_MODE_MASK;
1268 		payload[i] |= ((fcs_sha_get_digest_param.crypto_param
1269 				>> INTEL_SIP_SMC_FCS_DIGEST_SIZE_OFFSET)
1270 				& INTEL_SIP_SMC_FCS_DIGEST_SIZE_MASK)
1271 				<< FCS_SHA_HMAC_CRYPTO_PARAM_SIZE_OFFSET;
1272 		i++;
1273 	}
1274 	/* Data source address and size */
1275 
1276 	/* On the Agilex5 platform, we will use the SMMU payload address */
1277 #if PLATFORM_MODEL == PLAT_SOCFPGA_AGILEX5
1278 	payload[i] = smmu_src_addr;
1279 #else
1280 	payload[i] = src_addr;
1281 #endif
1282 	i++;
1283 	payload[i] = src_size;
1284 	i++;
1285 
1286 	status = ((smc_fid == ALTERA_SIP_SMC_ASYNC_FCS_GET_DIGEST_UPDATE) ||
1287 		  (smc_fid == ALTERA_SIP_SMC_ASYNC_FCS_GET_DIGEST_FINALIZE)) ?
1288 			mailbox_send_cmd_async_v3(GET_CLIENT_ID(trans_id),
1289 						   GET_JOB_ID(trans_id),
1290 						   MBOX_FCS_GET_DIGEST_REQ,
1291 						   payload,
1292 						   i,
1293 						   MBOX_CMD_FLAG_CASUAL,
1294 						   fcs_cs_get_digest_cb,
1295 						   (uint32_t *)dst_addr,
1296 						   2U) :
1297 			mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_GET_DIGEST_REQ,
1298 				payload, i, CMD_CASUAL,
1299 				(uint32_t *) dst_addr, &resp_len);
1300 
1301 	if (is_finalised != 0U) {
1302 		memset((void *)&fcs_sha_get_digest_param, 0,
1303 		sizeof(fcs_crypto_service_data));
1304 	}
1305 
1306 	if (status < 0) {
1307 		*mbox_error = -status;
1308 		return INTEL_SIP_SMC_STATUS_ERROR;
1309 	}
1310 
1311 	*dst_size = resp_len * MBOX_WORD_BYTE;
1312 	flush_dcache_range(dst_addr, *dst_size);
1313 
1314 	return INTEL_SIP_SMC_STATUS_OK;
1315 }
1316 
1317 int intel_fcs_get_digest_smmu_update_finalize(uint32_t session_id,
1318 				uint32_t context_id, uint32_t src_addr,
1319 				uint32_t src_size, uint64_t dst_addr,
1320 				uint32_t *dst_size, uint8_t is_finalised,
1321 				uint32_t *mbox_error, uint32_t *send_id)
1322 {
1323 	int status;
1324 	uint32_t i;
1325 	uint32_t flag;
1326 	uint32_t crypto_header;
1327 	uint32_t resp_len;
1328 	uint32_t payload[FCS_GET_DIGEST_CMD_MAX_WORD_SIZE] = {0U};
1329 
1330 	/* Source data must be 8 bytes aligned */
1331 	if (dst_size == NULL || mbox_error == NULL ||
1332 		!is_8_bytes_aligned(src_size)) {
1333 		return INTEL_SIP_SMC_STATUS_REJECTED;
1334 	}
1335 
1336 	if (fcs_sha_get_digest_param.session_id != session_id ||
1337 	    fcs_sha_get_digest_param.context_id != context_id) {
1338 		return INTEL_SIP_SMC_STATUS_REJECTED;
1339 	}
1340 
1341 	if (!is_address_in_ddr_range(src_addr, src_size) ||
1342 		 !is_address_in_ddr_range(dst_addr, *dst_size)) {
1343 		return INTEL_SIP_SMC_STATUS_REJECTED;
1344 	}
1345 
1346 	resp_len = *dst_size / MBOX_WORD_BYTE;
1347 
1348 	/* Prepare crypto header */
1349 	flag = 0;
1350 
1351 	if (fcs_sha_get_digest_param.is_updated) {
1352 		fcs_sha_get_digest_param.crypto_param_size = 0;
1353 	} else {
1354 		flag |=  FCS_CS_FIELD_FLAG_INIT;
1355 	}
1356 
1357 	if (is_finalised != 0U) {
1358 		flag |=  FCS_CS_FIELD_FLAG_FINALIZE;
1359 	} else {
1360 		flag |=  FCS_CS_FIELD_FLAG_UPDATE;
1361 		fcs_sha_get_digest_param.is_updated = 1;
1362 	}
1363 
1364 	crypto_header = ((flag << FCS_CS_FIELD_FLAG_OFFSET) |
1365 			(fcs_sha_get_digest_param.crypto_param_size &
1366 			FCS_CS_FIELD_SIZE_MASK));
1367 
1368 	/* Prepare command payload */
1369 	i = 0;
1370 	payload[i] = fcs_sha_get_digest_param.session_id;
1371 	i++;
1372 	payload[i] = fcs_sha_get_digest_param.context_id;
1373 	i++;
1374 	payload[i] = crypto_header;
1375 	i++;
1376 
1377 	if ((crypto_header >> FCS_CS_FIELD_FLAG_OFFSET) &
1378 		FCS_CS_FIELD_FLAG_INIT) {
1379 		payload[i] = fcs_sha_get_digest_param.key_id;
1380 		i++;
1381 		/* Crypto parameters */
1382 		payload[i] = fcs_sha_get_digest_param.crypto_param
1383 				& INTEL_SIP_SMC_FCS_SHA_MODE_MASK;
1384 		payload[i] |= ((fcs_sha_get_digest_param.crypto_param
1385 				>> INTEL_SIP_SMC_FCS_DIGEST_SIZE_OFFSET)
1386 				& INTEL_SIP_SMC_FCS_DIGEST_SIZE_MASK)
1387 				<< FCS_SHA_HMAC_CRYPTO_PARAM_SIZE_OFFSET;
1388 		i++;
1389 	}
1390 	/* Data source address and size */
1391 	payload[i] = src_addr;
1392 	i++;
1393 	payload[i] = src_size;
1394 	i++;
1395 
1396 	status = mailbox_send_cmd_async(send_id, MBOX_FCS_GET_DIGEST_REQ,
1397 					payload, i, CMD_INDIRECT);
1398 
1399 	if (is_finalised != 0U) {
1400 		memset((void *)&fcs_sha_get_digest_param, 0,
1401 		sizeof(fcs_crypto_service_data));
1402 	}
1403 
1404 	if (status < 0) {
1405 		*mbox_error = -status;
1406 		return INTEL_SIP_SMC_STATUS_ERROR;
1407 	}
1408 
1409 	*dst_size = resp_len * MBOX_WORD_BYTE;
1410 	flush_dcache_range(dst_addr, *dst_size);
1411 
1412 	return INTEL_SIP_SMC_STATUS_OK;
1413 }
1414 
1415 int intel_fcs_mac_verify_init(uint32_t session_id, uint32_t context_id,
1416 				uint32_t key_id, uint32_t param_size,
1417 				uint64_t param_data, uint32_t *mbox_error)
1418 {
1419 	return intel_fcs_crypto_service_init(session_id, context_id,
1420 				key_id, param_size, param_data,
1421 				(void *) &fcs_sha_mac_verify_param,
1422 				mbox_error);
1423 }
1424 
1425 int intel_fcs_mac_verify_update_finalize(uint32_t smc_fid, uint32_t trans_id,
1426 				uint32_t session_id, uint32_t context_id,
1427 				uint32_t src_addr, uint32_t src_size,
1428 				uint64_t dst_addr, uint32_t *dst_size,
1429 				uint32_t data_size, uint8_t is_finalised,
1430 				uint32_t *mbox_error, uint64_t smmu_src_addr)
1431 {
1432 	int status;
1433 	uint32_t i;
1434 	uint32_t flag;
1435 	uint32_t crypto_header;
1436 	uint32_t resp_len;
1437 	uint32_t payload[FCS_MAC_VERIFY_CMD_MAX_WORD_SIZE] = {0U};
1438 	uintptr_t mac_offset;
1439 	uint32_t dst_size_check = 0;
1440 
1441 	if (dst_size == NULL || mbox_error == NULL) {
1442 		return INTEL_SIP_SMC_STATUS_REJECTED;
1443 	}
1444 
1445 	if (fcs_sha_mac_verify_param.session_id != session_id ||
1446 		fcs_sha_mac_verify_param.context_id != context_id) {
1447 		return INTEL_SIP_SMC_STATUS_REJECTED;
1448 	}
1449 
1450 	if (data_size > src_size) {
1451 		return INTEL_SIP_SMC_STATUS_REJECTED;
1452 	}
1453 
1454 	if (!is_size_4_bytes_aligned(src_size) ||
1455 		!is_8_bytes_aligned(data_size)) {
1456 		return INTEL_SIP_SMC_STATUS_REJECTED;
1457 	}
1458 
1459 	if (!is_address_in_ddr_range(src_addr, src_size) ||
1460 		!is_address_in_ddr_range(dst_addr, *dst_size)) {
1461 		return INTEL_SIP_SMC_STATUS_REJECTED;
1462 	}
1463 
1464 	dst_size_check = *dst_size;
1465 	if ((dst_size_check > FCS_MAX_DATA_SIZE ||
1466 		dst_size_check < FCS_MIN_DATA_SIZE) ||
1467 		(src_size > FCS_MAX_DATA_SIZE ||
1468 		src_size < FCS_MIN_DATA_SIZE)) {
1469 		return INTEL_SIP_SMC_STATUS_REJECTED;
1470 	}
1471 
1472 	resp_len = *dst_size / MBOX_WORD_BYTE;
1473 
1474 	/* Prepare crypto header */
1475 	flag = 0;
1476 
1477 	if (fcs_sha_mac_verify_param.is_updated) {
1478 		fcs_sha_mac_verify_param.crypto_param_size = 0;
1479 	} else {
1480 		flag |=  FCS_CS_FIELD_FLAG_INIT;
1481 	}
1482 
1483 	if (is_finalised) {
1484 		flag |=  FCS_CS_FIELD_FLAG_FINALIZE;
1485 	} else {
1486 		flag |=  FCS_CS_FIELD_FLAG_UPDATE;
1487 		fcs_sha_mac_verify_param.is_updated = 1;
1488 	}
1489 
1490 	crypto_header = ((flag << FCS_CS_FIELD_FLAG_OFFSET) |
1491 			(fcs_sha_mac_verify_param.crypto_param_size &
1492 			FCS_CS_FIELD_SIZE_MASK));
1493 
1494 	/* Prepare command payload */
1495 	i = 0;
1496 	payload[i] = fcs_sha_mac_verify_param.session_id;
1497 	i++;
1498 	payload[i] = fcs_sha_mac_verify_param.context_id;
1499 	i++;
1500 	payload[i] = crypto_header;
1501 	i++;
1502 
1503 	if ((crypto_header >> FCS_CS_FIELD_FLAG_OFFSET) &
1504 		FCS_CS_FIELD_FLAG_INIT) {
1505 		payload[i] = fcs_sha_mac_verify_param.key_id;
1506 		i++;
1507 		/* Crypto parameters */
1508 		payload[i] = ((fcs_sha_mac_verify_param.crypto_param
1509 				>> INTEL_SIP_SMC_FCS_DIGEST_SIZE_OFFSET)
1510 				& INTEL_SIP_SMC_FCS_DIGEST_SIZE_MASK)
1511 				<< FCS_SHA_HMAC_CRYPTO_PARAM_SIZE_OFFSET;
1512 		i++;
1513 	}
1514 
1515 	/* Data source address and size */
1516 #if PLATFORM_MODEL == PLAT_SOCFPGA_AGILEX5
1517 	payload[i] = (uint32_t)smmu_src_addr;
1518 #else
1519 	payload[i] = src_addr;
1520 #endif
1521 	i++;
1522 	payload[i] = data_size;
1523 	i++;
1524 
1525 	if ((crypto_header >> FCS_CS_FIELD_FLAG_OFFSET) &
1526 		FCS_CS_FIELD_FLAG_FINALIZE) {
1527 		/* Copy mac data to command */
1528 		mac_offset = src_addr + data_size;
1529 
1530 		if ((i + ((src_size - data_size) / MBOX_WORD_BYTE)) >
1531 			FCS_MAC_VERIFY_CMD_MAX_WORD_SIZE) {
1532 			return INTEL_SIP_SMC_STATUS_REJECTED;
1533 		}
1534 
1535 		memcpy_s(&payload[i], (src_size - data_size) / MBOX_WORD_BYTE,
1536 			(void *) mac_offset, (src_size - data_size) / MBOX_WORD_BYTE);
1537 
1538 		i += (src_size - data_size) / MBOX_WORD_BYTE;
1539 	}
1540 
1541 	status = ((smc_fid == ALTERA_SIP_SMC_ASYNC_FCS_MAC_VERIFY_UPDATE) ||
1542 		  (smc_fid == ALTERA_SIP_SMC_ASYNC_FCS_MAC_VERIFY_FINALIZE)) ?
1543 			mailbox_send_cmd_async_v3(GET_CLIENT_ID(trans_id),
1544 						   GET_JOB_ID(trans_id),
1545 						   MBOX_FCS_MAC_VERIFY_REQ,
1546 						   payload,
1547 						   i,
1548 						   MBOX_CMD_FLAG_CASUAL,
1549 						   fcs_cs_mac_verify_cb,
1550 						   (uint32_t *)dst_addr,
1551 						   2U) :
1552 			mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_MAC_VERIFY_REQ,
1553 				payload, i, CMD_CASUAL,
1554 				(uint32_t *) dst_addr, &resp_len);
1555 
1556 	if (is_finalised) {
1557 		memset((void *)&fcs_sha_mac_verify_param, 0,
1558 		sizeof(fcs_crypto_service_data));
1559 	}
1560 
1561 	if (status < 0) {
1562 		*mbox_error = -status;
1563 		return INTEL_SIP_SMC_STATUS_ERROR;
1564 	}
1565 
1566 	*dst_size = resp_len * MBOX_WORD_BYTE;
1567 	flush_dcache_range(dst_addr, *dst_size);
1568 
1569 	return INTEL_SIP_SMC_STATUS_OK;
1570 }
1571 
1572 int intel_fcs_mac_verify_smmu_update_finalize(uint32_t session_id,
1573 				uint32_t context_id, uint32_t src_addr,
1574 				uint32_t src_size, uint64_t dst_addr,
1575 				uint32_t *dst_size, uint32_t data_size,
1576 				uint8_t is_finalised, uint32_t *mbox_error,
1577 				uint32_t *send_id)
1578 {
1579 	int status;
1580 	uint32_t i;
1581 	uint32_t flag;
1582 	uint32_t crypto_header;
1583 	uint32_t resp_len;
1584 	uint32_t payload[FCS_MAC_VERIFY_CMD_MAX_WORD_SIZE] = {0U};
1585 	uintptr_t mac_offset;
1586 	uint32_t dst_size_check = 0;
1587 	/*
1588 	 * Source data must be 4 bytes aligned
1589 	 * User data must be 8 bytes aligned
1590 	 */
1591 	if (dst_size == NULL || mbox_error == NULL ||
1592 		!is_size_4_bytes_aligned(src_size) ||
1593 		!is_8_bytes_aligned(data_size)) {
1594 		return INTEL_SIP_SMC_STATUS_REJECTED;
1595 	}
1596 
1597 	if (data_size > src_size) {
1598 		return INTEL_SIP_SMC_STATUS_REJECTED;
1599 	}
1600 
1601 	if (fcs_sha_mac_verify_param.session_id != session_id ||
1602 		fcs_sha_mac_verify_param.context_id != context_id) {
1603 		return INTEL_SIP_SMC_STATUS_REJECTED;
1604 	}
1605 
1606 	if (!is_address_in_ddr_range(src_addr, src_size) ||
1607 		!is_address_in_ddr_range(dst_addr, *dst_size)) {
1608 		return INTEL_SIP_SMC_STATUS_REJECTED;
1609 	}
1610 
1611 	dst_size_check = *dst_size;
1612 	if ((dst_size_check > FCS_MAX_DATA_SIZE ||
1613 		dst_size_check < FCS_MIN_DATA_SIZE) ||
1614 		(src_size > FCS_MAX_DATA_SIZE ||
1615 		src_size < FCS_MIN_DATA_SIZE)) {
1616 		return INTEL_SIP_SMC_STATUS_REJECTED;
1617 	}
1618 
1619 	resp_len = *dst_size / MBOX_WORD_BYTE;
1620 
1621 	/* Prepare crypto header */
1622 	flag = 0;
1623 
1624 	if (fcs_sha_mac_verify_param.is_updated) {
1625 		fcs_sha_mac_verify_param.crypto_param_size = 0;
1626 	} else {
1627 		flag |=  FCS_CS_FIELD_FLAG_INIT;
1628 	}
1629 
1630 	if (is_finalised) {
1631 		flag |=  FCS_CS_FIELD_FLAG_FINALIZE;
1632 	} else {
1633 		flag |=  FCS_CS_FIELD_FLAG_UPDATE;
1634 		fcs_sha_mac_verify_param.is_updated = 1;
1635 	}
1636 
1637 	crypto_header = ((flag << FCS_CS_FIELD_FLAG_OFFSET) |
1638 			(fcs_sha_mac_verify_param.crypto_param_size &
1639 			FCS_CS_FIELD_SIZE_MASK));
1640 
1641 	/* Prepare command payload */
1642 	i = 0;
1643 	payload[i] = fcs_sha_mac_verify_param.session_id;
1644 	i++;
1645 	payload[i] = fcs_sha_mac_verify_param.context_id;
1646 	i++;
1647 	payload[i] = crypto_header;
1648 	i++;
1649 
1650 	if ((crypto_header >> FCS_CS_FIELD_FLAG_OFFSET) &
1651 		FCS_CS_FIELD_FLAG_INIT) {
1652 		payload[i] = fcs_sha_mac_verify_param.key_id;
1653 		i++;
1654 		/* Crypto parameters */
1655 		payload[i] = ((fcs_sha_mac_verify_param.crypto_param
1656 				>> INTEL_SIP_SMC_FCS_DIGEST_SIZE_OFFSET)
1657 				& INTEL_SIP_SMC_FCS_DIGEST_SIZE_MASK)
1658 				<< FCS_SHA_HMAC_CRYPTO_PARAM_SIZE_OFFSET;
1659 		i++;
1660 	}
1661 	/* Data source address and size */
1662 	payload[i] = src_addr;
1663 	i++;
1664 	payload[i] = data_size;
1665 	i++;
1666 
1667 	if ((crypto_header >> FCS_CS_FIELD_FLAG_OFFSET) &
1668 		FCS_CS_FIELD_FLAG_FINALIZE) {
1669 		/* Copy mac data to command
1670 		 * Using dst_addr (physical address) to store mac_offset
1671 		 * mac_offset = MAC data
1672 		 */
1673 		mac_offset = dst_addr;
1674 
1675 		if ((i + ((src_size - data_size) / MBOX_WORD_BYTE)) >
1676 			FCS_MAC_VERIFY_CMD_MAX_WORD_SIZE) {
1677 			return INTEL_SIP_SMC_STATUS_REJECTED;
1678 		}
1679 
1680 		memcpy_s(&payload[i], (src_size - data_size) / MBOX_WORD_BYTE,
1681 			(void *) mac_offset, (src_size - data_size) / MBOX_WORD_BYTE);
1682 
1683 		memset((void *) dst_addr, 0, *dst_size);
1684 
1685 		i += (src_size - data_size) / MBOX_WORD_BYTE;
1686 	}
1687 
1688 	status = mailbox_send_cmd_async(send_id, MBOX_FCS_MAC_VERIFY_REQ,
1689 					payload, i, CMD_INDIRECT);
1690 
1691 	if (is_finalised) {
1692 		memset((void *)&fcs_sha_mac_verify_param, 0,
1693 		sizeof(fcs_crypto_service_data));
1694 	}
1695 
1696 	if (status < 0) {
1697 		*mbox_error = -status;
1698 		return INTEL_SIP_SMC_STATUS_ERROR;
1699 	}
1700 
1701 	*dst_size = resp_len * MBOX_WORD_BYTE;
1702 	flush_dcache_range(dst_addr, *dst_size);
1703 
1704 	return INTEL_SIP_SMC_STATUS_OK;
1705 }
1706 
1707 int intel_fcs_ecdsa_hash_sign_init(uint32_t session_id, uint32_t context_id,
1708 				uint32_t key_id, uint32_t param_size,
1709 				uint64_t param_data, uint32_t *mbox_error)
1710 {
1711 	return intel_fcs_crypto_service_init(session_id, context_id,
1712 				key_id, param_size, param_data,
1713 				(void *) &fcs_ecdsa_hash_sign_param,
1714 				mbox_error);
1715 }
1716 
1717 int intel_fcs_ecdsa_hash_sign_finalize(uint32_t smc_fid, uint32_t trans_id,
1718 				uint32_t session_id, uint32_t context_id,
1719 				uint32_t src_addr, uint32_t src_size,
1720 				uint64_t dst_addr, uint32_t *dst_size,
1721 				uint32_t *mbox_error)
1722 {
1723 	int status;
1724 	uint32_t i;
1725 	uint32_t payload[FCS_ECDSA_HASH_SIGN_CMD_MAX_WORD_SIZE] = {0U};
1726 	uint32_t resp_len;
1727 	uintptr_t hash_data_addr;
1728 	uint32_t dst_size_check = 0;
1729 
1730 	if ((dst_size == NULL) || (mbox_error == NULL)) {
1731 		return INTEL_SIP_SMC_STATUS_REJECTED;
1732 	}
1733 
1734 	if (fcs_ecdsa_hash_sign_param.session_id != session_id ||
1735 		fcs_ecdsa_hash_sign_param.context_id != context_id) {
1736 		return INTEL_SIP_SMC_STATUS_REJECTED;
1737 	}
1738 
1739 	if (!is_address_in_ddr_range(src_addr, src_size) ||
1740 		!is_address_in_ddr_range(dst_addr, *dst_size)) {
1741 		return INTEL_SIP_SMC_STATUS_REJECTED;
1742 	}
1743 
1744 	dst_size_check = *dst_size;
1745 	if ((dst_size_check > FCS_MAX_DATA_SIZE ||
1746 		dst_size_check < FCS_MIN_DATA_SIZE) ||
1747 		(src_size > FCS_MAX_DATA_SIZE ||
1748 		src_size < FCS_MIN_DATA_SIZE)) {
1749 		return INTEL_SIP_SMC_STATUS_REJECTED;
1750 	}
1751 
1752 	resp_len = *dst_size / MBOX_WORD_BYTE;
1753 
1754 	/* Prepare command payload */
1755 	/* Crypto header */
1756 	i = 0;
1757 	payload[i] = fcs_ecdsa_hash_sign_param.session_id;
1758 	i++;
1759 	payload[i] = fcs_ecdsa_hash_sign_param.context_id;
1760 
1761 	i++;
1762 	payload[i] = fcs_ecdsa_hash_sign_param.crypto_param_size
1763 			& FCS_CS_FIELD_SIZE_MASK;
1764 	payload[i] |= (FCS_CS_FIELD_FLAG_INIT | FCS_CS_FIELD_FLAG_UPDATE
1765 			| FCS_CS_FIELD_FLAG_FINALIZE)
1766 			<< FCS_CS_FIELD_FLAG_OFFSET;
1767 	i++;
1768 	payload[i] = fcs_ecdsa_hash_sign_param.key_id;
1769 
1770 	/* Crypto parameters */
1771 	i++;
1772 	payload[i] = fcs_ecdsa_hash_sign_param.crypto_param
1773 			& INTEL_SIP_SMC_FCS_ECC_ALGO_MASK;
1774 
1775 	/* Hash Data */
1776 	i++;
1777 	hash_data_addr = src_addr;
1778 
1779 	if ((i + ((src_size) / MBOX_WORD_BYTE)) >
1780 		FCS_ECDSA_HASH_SIGN_CMD_MAX_WORD_SIZE) {
1781 		return INTEL_SIP_SMC_STATUS_REJECTED;
1782 	}
1783 
1784 	memcpy_s(&payload[i], src_size / MBOX_WORD_BYTE,
1785 		(void *) hash_data_addr, src_size / MBOX_WORD_BYTE);
1786 
1787 	i += src_size / MBOX_WORD_BYTE;
1788 
1789 	status = (smc_fid == ALTERA_SIP_SMC_ASYNC_FCS_ECDSA_HASH_SIGN_FINALIZE) ?
1790 			mailbox_send_cmd_async_v3(GET_CLIENT_ID(trans_id),
1791 						   GET_JOB_ID(trans_id),
1792 						   MBOX_FCS_ECDSA_HASH_SIGN_REQ,
1793 						   payload,
1794 						   i,
1795 						   MBOX_CMD_FLAG_CASUAL,
1796 						   fcs_cs_hash_sign_req_cb,
1797 						   (uint32_t *)dst_addr,
1798 						   2U) :
1799 			mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_ECDSA_HASH_SIGN_REQ,
1800 			payload, i, CMD_CASUAL, (uint32_t *) dst_addr,
1801 			&resp_len);
1802 
1803 	memset((void *) &fcs_ecdsa_hash_sign_param,
1804 			0, sizeof(fcs_crypto_service_data));
1805 
1806 	if (status < 0) {
1807 		*mbox_error = -status;
1808 		return INTEL_SIP_SMC_STATUS_ERROR;
1809 	}
1810 
1811 	*dst_size = resp_len * MBOX_WORD_BYTE;
1812 	flush_dcache_range(dst_addr, *dst_size);
1813 
1814 	return INTEL_SIP_SMC_STATUS_OK;
1815 }
1816 
1817 int intel_fcs_ecdsa_hash_sig_verify_init(uint32_t session_id, uint32_t context_id,
1818 				uint32_t key_id, uint32_t param_size,
1819 				uint64_t param_data, uint32_t *mbox_error)
1820 {
1821 	return intel_fcs_crypto_service_init(session_id, context_id,
1822 				key_id, param_size, param_data,
1823 				(void *) &fcs_ecdsa_hash_sig_verify_param,
1824 				mbox_error);
1825 }
1826 
1827 int intel_fcs_ecdsa_hash_sig_verify_finalize(uint32_t smc_fid, uint32_t trans_id,
1828 					uint32_t session_id, uint32_t context_id,
1829 				uint32_t src_addr, uint32_t src_size,
1830 				uint64_t dst_addr, uint32_t *dst_size,
1831 				uint32_t *mbox_error)
1832 {
1833 	int status;
1834 	uint32_t i = 0;
1835 	uint32_t payload[FCS_ECDSA_HASH_SIG_VERIFY_CMD_MAX_WORD_SIZE] = {0U};
1836 	uint32_t resp_len;
1837 	uintptr_t hash_sig_pubkey_addr;
1838 	uint32_t dst_size_check = 0;
1839 
1840 	if ((dst_size == NULL) || (mbox_error == NULL)) {
1841 		return INTEL_SIP_SMC_STATUS_REJECTED;
1842 	}
1843 
1844 	if ((fcs_ecdsa_hash_sig_verify_param.session_id != session_id) ||
1845 	    (fcs_ecdsa_hash_sig_verify_param.context_id != context_id)) {
1846 		return INTEL_SIP_SMC_STATUS_REJECTED;
1847 	}
1848 
1849 	if (!is_address_in_ddr_range(src_addr, src_size) ||
1850 		!is_address_in_ddr_range(dst_addr, *dst_size)) {
1851 		return INTEL_SIP_SMC_STATUS_REJECTED;
1852 	}
1853 
1854 	dst_size_check = *dst_size;
1855 	if ((dst_size_check > FCS_MAX_DATA_SIZE ||
1856 		dst_size_check < FCS_MIN_DATA_SIZE) ||
1857 		(src_size > FCS_MAX_DATA_SIZE ||
1858 		src_size < FCS_MIN_DATA_SIZE)) {
1859 		return INTEL_SIP_SMC_STATUS_REJECTED;
1860 	}
1861 
1862 	resp_len = *dst_size / MBOX_WORD_BYTE;
1863 
1864 	/* Prepare command payload */
1865 	/* Crypto header */
1866 	i = 0;
1867 	payload[i] = fcs_ecdsa_hash_sig_verify_param.session_id;
1868 
1869 	i++;
1870 	payload[i] = fcs_ecdsa_hash_sig_verify_param.context_id;
1871 
1872 	i++;
1873 	payload[i] = fcs_ecdsa_hash_sig_verify_param.crypto_param_size
1874 			& FCS_CS_FIELD_SIZE_MASK;
1875 	payload[i] |= (FCS_CS_FIELD_FLAG_INIT | FCS_CS_FIELD_FLAG_UPDATE
1876 			| FCS_CS_FIELD_FLAG_FINALIZE)
1877 			<< FCS_CS_FIELD_FLAG_OFFSET;
1878 
1879 	i++;
1880 	payload[i] = fcs_ecdsa_hash_sig_verify_param.key_id;
1881 
1882 	/* Crypto parameters */
1883 	i++;
1884 	payload[i] = fcs_ecdsa_hash_sig_verify_param.crypto_param
1885 			& INTEL_SIP_SMC_FCS_ECC_ALGO_MASK;
1886 
1887 	/* Hash Data Word, Signature Data Word and Public Key Data word */
1888 	i++;
1889 	hash_sig_pubkey_addr = src_addr;
1890 
1891 	if ((i + ((src_size) / MBOX_WORD_BYTE)) >
1892 		FCS_ECDSA_HASH_SIG_VERIFY_CMD_MAX_WORD_SIZE) {
1893 		return INTEL_SIP_SMC_STATUS_REJECTED;
1894 	}
1895 
1896 	memcpy_s(&payload[i], src_size / MBOX_WORD_BYTE,
1897 		(void *) hash_sig_pubkey_addr, src_size / MBOX_WORD_BYTE);
1898 
1899 	i += (src_size / MBOX_WORD_BYTE);
1900 
1901 	status = (smc_fid == ALTERA_SIP_SMC_ASYNC_FCS_ECDSA_HASH_SIG_VERIFY_FINALIZE) ?
1902 		mailbox_send_cmd_async_v3(GET_CLIENT_ID(trans_id),
1903 					GET_JOB_ID(trans_id),
1904 					MBOX_FCS_ECDSA_HASH_SIG_VERIFY,
1905 					payload,
1906 					i,
1907 					MBOX_CMD_FLAG_CASUAL,
1908 					fcs_cs_hash_sig_verify_req_cb,
1909 					(uint32_t *)dst_addr,
1910 					2U) :
1911 
1912 		mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_ECDSA_HASH_SIG_VERIFY,
1913 			payload, i, CMD_CASUAL, (uint32_t *) dst_addr,
1914 			&resp_len);
1915 
1916 	memset((void *)&fcs_ecdsa_hash_sig_verify_param,
1917 			0, sizeof(fcs_crypto_service_data));
1918 
1919 	if (status < 0) {
1920 		*mbox_error = -status;
1921 		return INTEL_SIP_SMC_STATUS_ERROR;
1922 	}
1923 
1924 	*dst_size = resp_len * MBOX_WORD_BYTE;
1925 	flush_dcache_range(dst_addr, *dst_size);
1926 
1927 	return INTEL_SIP_SMC_STATUS_OK;
1928 }
1929 
1930 int intel_fcs_ecdsa_sha2_data_sign_init(uint32_t session_id,
1931 				uint32_t context_id, uint32_t key_id,
1932 				uint32_t param_size, uint64_t param_data,
1933 				uint32_t *mbox_error)
1934 {
1935 	return intel_fcs_crypto_service_init(session_id, context_id,
1936 				key_id, param_size, param_data,
1937 				(void *) &fcs_sha2_data_sign_param,
1938 				mbox_error);
1939 }
1940 
1941 int intel_fcs_ecdsa_sha2_data_sign_update_finalize(uint32_t smc_fid, uint32_t trans_id,
1942 				uint32_t session_id, uint32_t context_id,
1943 				uint32_t src_addr, uint32_t src_size,
1944 				uint64_t dst_addr, uint32_t *dst_size,
1945 				uint8_t is_finalised, uint32_t *mbox_error,
1946 				uint64_t smmu_src_addr)
1947 {
1948 	int status;
1949 	int i;
1950 	uint32_t flag;
1951 	uint32_t crypto_header;
1952 	uint32_t payload[FCS_ECDSA_SHA2_DATA_SIGN_CMD_MAX_WORD_SIZE] = {0U};
1953 	uint32_t resp_len;
1954 
1955 	if ((dst_size == NULL) || (mbox_error == NULL)) {
1956 		return INTEL_SIP_SMC_STATUS_REJECTED;
1957 	}
1958 
1959 	if (fcs_sha2_data_sign_param.session_id != session_id ||
1960 		fcs_sha2_data_sign_param.context_id != context_id) {
1961 		return INTEL_SIP_SMC_STATUS_REJECTED;
1962 	}
1963 
1964 	/* Source data must be 8 bytes aligned */
1965 	if (!is_8_bytes_aligned(src_size)) {
1966 		return INTEL_SIP_SMC_STATUS_REJECTED;
1967 	}
1968 
1969 	if (!is_address_in_ddr_range(src_addr, src_size) ||
1970 		!is_address_in_ddr_range(dst_addr, *dst_size)) {
1971 		return INTEL_SIP_SMC_STATUS_REJECTED;
1972 	}
1973 
1974 	resp_len = *dst_size / MBOX_WORD_BYTE;
1975 
1976 	/* Prepare crypto header */
1977 	flag = 0;
1978 	if (fcs_sha2_data_sign_param.is_updated) {
1979 		fcs_sha2_data_sign_param.crypto_param_size = 0;
1980 	} else {
1981 		flag |= FCS_CS_FIELD_FLAG_INIT;
1982 	}
1983 
1984 	if (is_finalised != 0U) {
1985 		flag |= FCS_CS_FIELD_FLAG_FINALIZE;
1986 	} else {
1987 		flag |= FCS_CS_FIELD_FLAG_UPDATE;
1988 		fcs_sha2_data_sign_param.is_updated = 1;
1989 	}
1990 	crypto_header = (flag << FCS_CS_FIELD_FLAG_OFFSET) |
1991 			fcs_sha2_data_sign_param.crypto_param_size;
1992 
1993 	/* Prepare command payload */
1994 	i = 0;
1995 	payload[i] = fcs_sha2_data_sign_param.session_id;
1996 	i++;
1997 	payload[i] = fcs_sha2_data_sign_param.context_id;
1998 	i++;
1999 	payload[i] = crypto_header;
2000 	i++;
2001 
2002 	if ((crypto_header >> FCS_CS_FIELD_FLAG_OFFSET) &
2003 		FCS_CS_FIELD_FLAG_INIT) {
2004 		payload[i] = fcs_sha2_data_sign_param.key_id;
2005 		/* Crypto parameters */
2006 		i++;
2007 		payload[i] = fcs_sha2_data_sign_param.crypto_param
2008 				& INTEL_SIP_SMC_FCS_ECC_ALGO_MASK;
2009 		i++;
2010 	}
2011 
2012 	/* Data source address and size */
2013 #if PLATFORM_MODEL == PLAT_SOCFPGA_AGILEX5
2014 	payload[i] = (uint32_t)smmu_src_addr;
2015 #else
2016 	payload[i] = src_addr;
2017 #endif
2018 	i++;
2019 	payload[i] = src_size;
2020 	i++;
2021 
2022 	status = ((smc_fid == ALTERA_SIP_SMC_ASYNC_FCS_ECDSA_SHA2_DATA_SIGN_UPDATE) ||
2023 		  (smc_fid == ALTERA_SIP_SMC_ASYNC_FCS_ECDSA_SHA2_DATA_SIGN_FINALIZE)) ?
2024 			mailbox_send_cmd_async_v3(GET_CLIENT_ID(trans_id),
2025 						GET_JOB_ID(trans_id),
2026 						MBOX_FCS_ECDSA_SHA2_DATA_SIGN_REQ,
2027 						payload,
2028 						i,
2029 						MBOX_CMD_FLAG_CASUAL,
2030 						fcs_cs_data_sign_req_cb,
2031 						(uint32_t *)dst_addr,
2032 						2U) :
2033 			mailbox_send_cmd(MBOX_JOB_ID,
2034 			MBOX_FCS_ECDSA_SHA2_DATA_SIGN_REQ, payload,
2035 			i, CMD_CASUAL, (uint32_t *) dst_addr,
2036 			&resp_len);
2037 
2038 	if (is_finalised != 0U) {
2039 		memset((void *)&fcs_sha2_data_sign_param, 0,
2040 			sizeof(fcs_crypto_service_data));
2041 	}
2042 
2043 	if (status < 0) {
2044 		*mbox_error = -status;
2045 		return INTEL_SIP_SMC_STATUS_ERROR;
2046 	}
2047 
2048 	*dst_size = resp_len * MBOX_WORD_BYTE;
2049 	flush_dcache_range(dst_addr, *dst_size);
2050 
2051 	return INTEL_SIP_SMC_STATUS_OK;
2052 }
2053 
2054 int intel_fcs_ecdsa_sha2_data_sign_smmu_update_finalize(uint32_t session_id,
2055 				uint32_t context_id, uint32_t src_addr,
2056 				uint32_t src_size, uint64_t dst_addr,
2057 				uint32_t *dst_size, uint8_t is_finalised,
2058 				uint32_t *mbox_error, uint32_t *send_id)
2059 {
2060 	int status;
2061 	int i;
2062 	uint32_t flag;
2063 	uint32_t crypto_header;
2064 	uint32_t payload[FCS_ECDSA_SHA2_DATA_SIGN_CMD_MAX_WORD_SIZE] = {0U};
2065 	uint32_t resp_len;
2066 
2067 	/* Source data must be 8 bytes aligned */
2068 	if ((dst_size == NULL) || (mbox_error == NULL ||
2069 		!is_8_bytes_aligned(src_size))) {
2070 		return INTEL_SIP_SMC_STATUS_REJECTED;
2071 	}
2072 
2073 	if (fcs_sha2_data_sign_param.session_id != session_id ||
2074 		fcs_sha2_data_sign_param.context_id != context_id) {
2075 		return INTEL_SIP_SMC_STATUS_REJECTED;
2076 	}
2077 
2078 	if (!is_address_in_ddr_range(src_addr, src_size) ||
2079 		!is_address_in_ddr_range(dst_addr, *dst_size)) {
2080 		return INTEL_SIP_SMC_STATUS_REJECTED;
2081 	}
2082 
2083 	resp_len = *dst_size / MBOX_WORD_BYTE;
2084 
2085 	/* Prepare crypto header */
2086 	flag = 0;
2087 	if (fcs_sha2_data_sign_param.is_updated) {
2088 		fcs_sha2_data_sign_param.crypto_param_size = 0;
2089 	} else {
2090 		flag |= FCS_CS_FIELD_FLAG_INIT;
2091 	}
2092 
2093 	if (is_finalised != 0U) {
2094 		flag |= FCS_CS_FIELD_FLAG_FINALIZE;
2095 	} else {
2096 		flag |= FCS_CS_FIELD_FLAG_UPDATE;
2097 		fcs_sha2_data_sign_param.is_updated = 1;
2098 	}
2099 	crypto_header = (flag << FCS_CS_FIELD_FLAG_OFFSET) |
2100 			fcs_sha2_data_sign_param.crypto_param_size;
2101 
2102 	/* Prepare command payload */
2103 	i = 0;
2104 	payload[i] = fcs_sha2_data_sign_param.session_id;
2105 	i++;
2106 	payload[i] = fcs_sha2_data_sign_param.context_id;
2107 	i++;
2108 	payload[i] = crypto_header;
2109 	i++;
2110 
2111 	if ((crypto_header >> FCS_CS_FIELD_FLAG_OFFSET) &
2112 		FCS_CS_FIELD_FLAG_INIT) {
2113 		payload[i] = fcs_sha2_data_sign_param.key_id;
2114 		/* Crypto parameters */
2115 		i++;
2116 		payload[i] = fcs_sha2_data_sign_param.crypto_param
2117 				& INTEL_SIP_SMC_FCS_ECC_ALGO_MASK;
2118 		i++;
2119 	}
2120 
2121 	/* Data source address and size */
2122 	payload[i] = src_addr;
2123 	i++;
2124 	payload[i] = src_size;
2125 	i++;
2126 
2127 	status = mailbox_send_cmd_async(send_id,
2128 					MBOX_FCS_ECDSA_SHA2_DATA_SIGN_REQ,
2129 					payload, i, CMD_INDIRECT);
2130 
2131 	if (is_finalised != 0U) {
2132 		memset((void *)&fcs_sha2_data_sign_param, 0,
2133 			sizeof(fcs_crypto_service_data));
2134 	}
2135 
2136 	if (status < 0) {
2137 		*mbox_error = -status;
2138 		return INTEL_SIP_SMC_STATUS_ERROR;
2139 	}
2140 
2141 	*dst_size = resp_len * MBOX_WORD_BYTE;
2142 	flush_dcache_range(dst_addr, *dst_size);
2143 
2144 	return INTEL_SIP_SMC_STATUS_OK;
2145 }
2146 
2147 int intel_fcs_ecdsa_sha2_data_sig_verify_init(uint32_t session_id,
2148 				uint32_t context_id, uint32_t key_id,
2149 				uint32_t param_size, uint64_t param_data,
2150 				uint32_t *mbox_error)
2151 {
2152 	return intel_fcs_crypto_service_init(session_id, context_id,
2153 				key_id, param_size, param_data,
2154 				(void *) &fcs_sha2_data_sig_verify_param,
2155 				mbox_error);
2156 }
2157 
2158 int intel_fcs_ecdsa_sha2_data_sig_verify_update_finalize(uint32_t smc_fid, uint32_t trans_id,
2159 				uint32_t session_id, uint32_t context_id,
2160 				uint32_t src_addr, uint32_t src_size,
2161 				uint64_t dst_addr, uint32_t *dst_size,
2162 				uint32_t data_size, uint8_t is_finalised,
2163 				uint32_t *mbox_error, uint64_t smmu_src_addr)
2164 {
2165 	int status;
2166 	uint32_t i;
2167 	uint32_t flag;
2168 	uint32_t crypto_header;
2169 	uint32_t payload[FCS_ECDSA_SHA2_DATA_SIG_VERIFY_CMD_MAX_WORD_SIZE] = {0U};
2170 	uint32_t resp_len;
2171 	uintptr_t sig_pubkey_offset;
2172 	uint32_t dst_size_check = 0;
2173 
2174 	if ((dst_size == NULL) || (mbox_error == NULL)) {
2175 		return INTEL_SIP_SMC_STATUS_REJECTED;
2176 	}
2177 
2178 	if (fcs_sha2_data_sig_verify_param.session_id != session_id ||
2179 		fcs_sha2_data_sig_verify_param.context_id != context_id) {
2180 		return INTEL_SIP_SMC_STATUS_REJECTED;
2181 	}
2182 
2183 	if (data_size > src_size) {
2184 		return INTEL_SIP_SMC_STATUS_REJECTED;
2185 	}
2186 
2187 	if (!is_size_4_bytes_aligned(src_size)) {
2188 		return INTEL_SIP_SMC_STATUS_REJECTED;
2189 	}
2190 
2191 	if (!is_8_bytes_aligned(data_size) ||
2192 		!is_8_bytes_aligned(src_addr)) {
2193 		return INTEL_SIP_SMC_STATUS_REJECTED;
2194 	}
2195 
2196 	if (!is_address_in_ddr_range(src_addr, src_size) ||
2197 		!is_address_in_ddr_range(dst_addr, *dst_size)) {
2198 		return INTEL_SIP_SMC_STATUS_REJECTED;
2199 	}
2200 
2201 	dst_size_check = *dst_size;
2202 	if ((dst_size_check > FCS_MAX_DATA_SIZE ||
2203 		dst_size_check < FCS_MIN_DATA_SIZE) ||
2204 		(src_size > FCS_MAX_DATA_SIZE ||
2205 		src_size < FCS_MIN_DATA_SIZE)) {
2206 		return INTEL_SIP_SMC_STATUS_REJECTED;
2207 	}
2208 
2209 	resp_len = *dst_size / MBOX_WORD_BYTE;
2210 
2211 	/* Prepare crypto header */
2212 	flag = 0;
2213 	if (fcs_sha2_data_sig_verify_param.is_updated)
2214 		fcs_sha2_data_sig_verify_param.crypto_param_size = 0;
2215 	else
2216 		flag |= FCS_CS_FIELD_FLAG_INIT;
2217 
2218 	if (is_finalised != 0U)
2219 		flag |= FCS_CS_FIELD_FLAG_FINALIZE;
2220 	else {
2221 		flag |= FCS_CS_FIELD_FLAG_UPDATE;
2222 		fcs_sha2_data_sig_verify_param.is_updated = 1;
2223 	}
2224 	crypto_header = (flag << FCS_CS_FIELD_FLAG_OFFSET) |
2225 			fcs_sha2_data_sig_verify_param.crypto_param_size;
2226 
2227 	/* Prepare command payload */
2228 	i = 0;
2229 	payload[i] = fcs_sha2_data_sig_verify_param.session_id;
2230 	i++;
2231 	payload[i] = fcs_sha2_data_sig_verify_param.context_id;
2232 	i++;
2233 	payload[i] = crypto_header;
2234 	i++;
2235 
2236 	if ((crypto_header >> FCS_CS_FIELD_FLAG_OFFSET) &
2237 		FCS_CS_FIELD_FLAG_INIT) {
2238 		payload[i] = fcs_sha2_data_sig_verify_param.key_id;
2239 		i++;
2240 		/* Crypto parameters */
2241 		payload[i] = fcs_sha2_data_sig_verify_param.crypto_param
2242 				& INTEL_SIP_SMC_FCS_ECC_ALGO_MASK;
2243 		i++;
2244 	}
2245 
2246 	/* Data source address and size */
2247 	/* On the Agilex5 platform, the SMMU remapped address is used */
2248 #if PLATFORM_MODEL == PLAT_SOCFPGA_AGILEX5
2249 	payload[i] = smmu_src_addr;
2250 #else
2251 	payload[i] = src_addr;
2252 #endif
2253 	i++;
2254 	payload[i] = data_size;
2255 	i++;
2256 
2257 	if ((crypto_header >> FCS_CS_FIELD_FLAG_OFFSET) &
2258 		FCS_CS_FIELD_FLAG_FINALIZE) {
2259 		/* Signature + Public Key Data */
2260 		sig_pubkey_offset = src_addr + data_size;
2261 
2262 		if ((i + ((src_size - data_size) / MBOX_WORD_BYTE)) >
2263 			FCS_ECDSA_SHA2_DATA_SIG_VERIFY_CMD_MAX_WORD_SIZE) {
2264 			return INTEL_SIP_SMC_STATUS_REJECTED;
2265 		}
2266 
2267 		memcpy_s(&payload[i], (src_size - data_size) / MBOX_WORD_BYTE,
2268 			(void *) sig_pubkey_offset, (src_size - data_size) / MBOX_WORD_BYTE);
2269 
2270 		i += (src_size - data_size) / MBOX_WORD_BYTE;
2271 	}
2272 
2273 	status = ((smc_fid == ALTERA_SIP_SMC_ASYNC_FCS_ECDSA_SHA2_DATA_SIG_VERIFY_UPDATE) ||
2274 		  (smc_fid == ALTERA_SIP_SMC_ASYNC_FCS_ECDSA_SHA2_DATA_SIG_VERIFY_FINALIZE)) ?
2275 			mailbox_send_cmd_async_v3(GET_CLIENT_ID(trans_id),
2276 						GET_JOB_ID(trans_id),
2277 						MBOX_FCS_ECDSA_SHA2_DATA_SIGN_VERIFY,
2278 						payload,
2279 						i,
2280 						MBOX_CMD_FLAG_CASUAL,
2281 						fcs_cs_data_sig_verify_req_cb,
2282 						(uint32_t *)dst_addr,
2283 						2U) :
2284 			mailbox_send_cmd(MBOX_JOB_ID,
2285 			MBOX_FCS_ECDSA_SHA2_DATA_SIGN_VERIFY, payload, i,
2286 			CMD_CASUAL, (uint32_t *) dst_addr, &resp_len);
2287 
2288 	if (is_finalised != 0U) {
2289 		memset((void *) &fcs_sha2_data_sig_verify_param, 0,
2290 			sizeof(fcs_crypto_service_data));
2291 	}
2292 
2293 	if (status < 0) {
2294 		*mbox_error = -status;
2295 		return INTEL_SIP_SMC_STATUS_ERROR;
2296 	}
2297 
2298 	*dst_size = resp_len * MBOX_WORD_BYTE;
2299 	flush_dcache_range(dst_addr, *dst_size);
2300 
2301 	return INTEL_SIP_SMC_STATUS_OK;
2302 }
2303 
2304 int intel_fcs_ecdsa_sha2_data_sig_verify_smmu_update_finalize(uint32_t session_id,
2305 				uint32_t context_id, uint32_t src_addr,
2306 				uint32_t src_size, uint64_t dst_addr,
2307 				uint32_t *dst_size, uint32_t data_size,
2308 				uint8_t is_finalised, uint32_t *mbox_error,
2309 				uint32_t *send_id)
2310 {
2311 	int status;
2312 	uint32_t i;
2313 	uint32_t flag;
2314 	uint32_t crypto_header;
2315 	uint32_t payload[FCS_ECDSA_SHA2_DATA_SIG_VERIFY_CMD_MAX_WORD_SIZE] = {0U};
2316 	uint32_t resp_len;
2317 	uintptr_t sig_pubkey_offset;
2318 	uint32_t dst_size_check = 0;
2319 
2320 	/*
2321 	 * Source data must be 4 bytes aligned
2322 	 * Source address must be 8 bytes aligned
2323 	 * User data must be 8 bytes aligned
2324 	 */
2325 	if ((dst_size == NULL) || (mbox_error == NULL) ||
2326 		!is_size_4_bytes_aligned(src_size) ||
2327 		!is_8_bytes_aligned(src_addr) ||
2328 		!is_8_bytes_aligned(data_size)) {
2329 		return INTEL_SIP_SMC_STATUS_REJECTED;
2330 	}
2331 
2332 	if (fcs_sha2_data_sig_verify_param.session_id != session_id ||
2333 		fcs_sha2_data_sig_verify_param.context_id != context_id) {
2334 		return INTEL_SIP_SMC_STATUS_REJECTED;
2335 	}
2336 
2337 	if (data_size > src_size) {
2338 		return INTEL_SIP_SMC_STATUS_REJECTED;
2339 	}
2340 
2341 	if (!is_address_in_ddr_range(src_addr, src_size) ||
2342 		!is_address_in_ddr_range(dst_addr, *dst_size)) {
2343 		return INTEL_SIP_SMC_STATUS_REJECTED;
2344 	}
2345 
2346 	dst_size_check = *dst_size;
2347 	if ((dst_size_check > FCS_MAX_DATA_SIZE ||
2348 		dst_size_check < FCS_MIN_DATA_SIZE) ||
2349 		(src_size > FCS_MAX_DATA_SIZE ||
2350 		src_size < FCS_MIN_DATA_SIZE)) {
2351 		return INTEL_SIP_SMC_STATUS_REJECTED;
2352 	}
2353 
2354 	resp_len = *dst_size / MBOX_WORD_BYTE;
2355 
2356 	/* Prepare crypto header */
2357 	flag = 0;
2358 	if (fcs_sha2_data_sig_verify_param.is_updated)
2359 		fcs_sha2_data_sig_verify_param.crypto_param_size = 0;
2360 	else
2361 		flag |= FCS_CS_FIELD_FLAG_INIT;
2362 
2363 	if (is_finalised != 0U)
2364 		flag |= FCS_CS_FIELD_FLAG_FINALIZE;
2365 	else {
2366 		flag |= FCS_CS_FIELD_FLAG_UPDATE;
2367 		fcs_sha2_data_sig_verify_param.is_updated = 1;
2368 	}
2369 	crypto_header = (flag << FCS_CS_FIELD_FLAG_OFFSET) |
2370 			fcs_sha2_data_sig_verify_param.crypto_param_size;
2371 
2372 	/* Prepare command payload */
2373 	i = 0;
2374 	payload[i] = fcs_sha2_data_sig_verify_param.session_id;
2375 	i++;
2376 	payload[i] = fcs_sha2_data_sig_verify_param.context_id;
2377 	i++;
2378 	payload[i] = crypto_header;
2379 	i++;
2380 
2381 	if ((crypto_header >> FCS_CS_FIELD_FLAG_OFFSET) &
2382 		FCS_CS_FIELD_FLAG_INIT) {
2383 		payload[i] = fcs_sha2_data_sig_verify_param.key_id;
2384 		i++;
2385 		/* Crypto parameters */
2386 		payload[i] = fcs_sha2_data_sig_verify_param.crypto_param
2387 				& INTEL_SIP_SMC_FCS_ECC_ALGO_MASK;
2388 		i++;
2389 	}
2390 
2391 	/* Data source address and size */
2392 	payload[i] = src_addr;
2393 	i++;
2394 	payload[i] = data_size;
2395 	i++;
2396 
2397 	if ((crypto_header >> FCS_CS_FIELD_FLAG_OFFSET) &
2398 		FCS_CS_FIELD_FLAG_FINALIZE) {
2399 		/* Copy mac data to command
2400 		 * Using dst_addr (physical address) to store sig_pubkey_offset
2401 		 * sig_pubkey_offset is Signature + Public Key Data
2402 		 */
2403 		sig_pubkey_offset = dst_addr;
2404 
2405 		if ((i + ((src_size - data_size) / MBOX_WORD_BYTE)) >
2406 			FCS_ECDSA_SHA2_DATA_SIG_VERIFY_CMD_MAX_WORD_SIZE) {
2407 			return INTEL_SIP_SMC_STATUS_REJECTED;
2408 		}
2409 
2410 		memcpy_s(&payload[i], (src_size - data_size) / MBOX_WORD_BYTE,
2411 			(void *) sig_pubkey_offset, (src_size - data_size) / MBOX_WORD_BYTE);
2412 
2413 		memset((void *) dst_addr, 0, *dst_size);
2414 
2415 		i += (src_size - data_size) / MBOX_WORD_BYTE;
2416 	}
2417 
2418 	status = mailbox_send_cmd_async(send_id,
2419 					MBOX_FCS_ECDSA_SHA2_DATA_SIGN_VERIFY,
2420 					payload, i, CMD_INDIRECT);
2421 
2422 	if (is_finalised != 0U) {
2423 		memset((void *) &fcs_sha2_data_sig_verify_param, 0,
2424 			sizeof(fcs_crypto_service_data));
2425 	}
2426 
2427 	if (status < 0) {
2428 		*mbox_error = -status;
2429 		return INTEL_SIP_SMC_STATUS_ERROR;
2430 	}
2431 
2432 	*dst_size = resp_len * MBOX_WORD_BYTE;
2433 	flush_dcache_range(dst_addr, *dst_size);
2434 
2435 	return INTEL_SIP_SMC_STATUS_OK;
2436 }
2437 
2438 int intel_fcs_ecdsa_get_pubkey_init(uint32_t session_id, uint32_t context_id,
2439 				uint32_t key_id, uint32_t param_size,
2440 				uint64_t param_data, uint32_t *mbox_error)
2441 {
2442 	return intel_fcs_crypto_service_init(session_id, context_id,
2443 				key_id, param_size, param_data,
2444 				(void *) &fcs_ecdsa_get_pubkey_param,
2445 				mbox_error);
2446 }
2447 
2448 int intel_fcs_ecdsa_get_pubkey_finalize(uint32_t smc_fid, uint32_t trans_id,
2449 				uint32_t session_id, uint32_t context_id,
2450 				uint64_t dst_addr, uint32_t *dst_size,
2451 				uint32_t *mbox_error)
2452 {
2453 	int status;
2454 	int i;
2455 	uint32_t crypto_header;
2456 	uint32_t ret_size;
2457 	uint32_t payload[FCS_ECDSA_GET_PUBKEY_MAX_WORD_SIZE] = {0U};
2458 
2459 	if ((dst_size == NULL) || (mbox_error == NULL)) {
2460 		return INTEL_SIP_SMC_STATUS_REJECTED;
2461 	}
2462 
2463 	if (!is_address_in_ddr_range(dst_addr, *dst_size)) {
2464 		return INTEL_SIP_SMC_STATUS_REJECTED;
2465 	}
2466 
2467 	if (fcs_ecdsa_get_pubkey_param.session_id != session_id ||
2468 		fcs_ecdsa_get_pubkey_param.context_id != context_id) {
2469 		return INTEL_SIP_SMC_STATUS_REJECTED;
2470 	}
2471 
2472 	ret_size = *dst_size / MBOX_WORD_BYTE;
2473 
2474 	crypto_header = ((FCS_CS_FIELD_FLAG_INIT |
2475 			FCS_CS_FIELD_FLAG_UPDATE |
2476 			FCS_CS_FIELD_FLAG_FINALIZE) <<
2477 			FCS_CS_FIELD_FLAG_OFFSET) |
2478 			fcs_ecdsa_get_pubkey_param.crypto_param_size;
2479 	i = 0;
2480 	/* Prepare command payload */
2481 	payload[i] = session_id;
2482 	i++;
2483 	payload[i] = context_id;
2484 	i++;
2485 	payload[i] = crypto_header;
2486 	i++;
2487 	payload[i] = fcs_ecdsa_get_pubkey_param.key_id;
2488 	i++;
2489 	payload[i] = (uint32_t) fcs_ecdsa_get_pubkey_param.crypto_param &
2490 			INTEL_SIP_SMC_FCS_ECC_ALGO_MASK;
2491 	i++;
2492 
2493 	status = (smc_fid == ALTERA_SIP_SMC_ASYNC_FCS_ECDSA_GET_PUBKEY_FINALIZE) ?
2494 			mailbox_send_cmd_async_v3(GET_CLIENT_ID(trans_id),
2495 						GET_JOB_ID(trans_id),
2496 						MBOX_FCS_ECDSA_GET_PUBKEY,
2497 						payload,
2498 						i,
2499 						MBOX_CMD_FLAG_CASUAL,
2500 						fcs_cs_get_public_key_cb,
2501 						(uint32_t *)dst_addr,
2502 						2U) :
2503 			mailbox_send_cmd(MBOX_JOB_ID,
2504 					 MBOX_FCS_ECDSA_GET_PUBKEY,
2505 			payload, i, CMD_CASUAL,
2506 			(uint32_t *) dst_addr, &ret_size);
2507 
2508 	memset((void *) &fcs_ecdsa_get_pubkey_param, 0,
2509 		sizeof(fcs_crypto_service_data));
2510 
2511 	if (status < 0) {
2512 		*mbox_error = -status;
2513 		return INTEL_SIP_SMC_STATUS_ERROR;
2514 	}
2515 
2516 	*dst_size = ret_size * MBOX_WORD_BYTE;
2517 	flush_dcache_range(dst_addr, *dst_size);
2518 
2519 	return INTEL_SIP_SMC_STATUS_OK;
2520 }
2521 
2522 int intel_fcs_ecdh_request_init(uint32_t session_id, uint32_t context_id,
2523 				uint32_t key_id, uint32_t param_size,
2524 				uint64_t param_data, uint32_t *mbox_error)
2525 {
2526 	return intel_fcs_crypto_service_init(session_id, context_id,
2527 				key_id, param_size, param_data,
2528 				(void *) &fcs_ecdh_request_param,
2529 				mbox_error);
2530 }
2531 
2532 int intel_fcs_ecdh_request_finalize(uint32_t smc_fid, uint32_t trans_id,
2533 				uint32_t session_id, uint32_t context_id,
2534 				uint32_t src_addr, uint32_t src_size,
2535 				uint64_t dst_addr, uint32_t *dst_size,
2536 				uint32_t *mbox_error)
2537 {
2538 	int status;
2539 	uint32_t i;
2540 	uint32_t payload[FCS_ECDH_REQUEST_CMD_MAX_WORD_SIZE] = {0U};
2541 	uint32_t resp_len;
2542 	uintptr_t pubkey;
2543 	uint32_t dst_size_check = 0;
2544 
2545 	if ((dst_size == NULL) || (mbox_error == NULL)) {
2546 		return INTEL_SIP_SMC_STATUS_REJECTED;
2547 	}
2548 
2549 	if (fcs_ecdh_request_param.session_id != session_id ||
2550 		fcs_ecdh_request_param.context_id != context_id) {
2551 		return INTEL_SIP_SMC_STATUS_REJECTED;
2552 	}
2553 
2554 	if (!is_address_in_ddr_range(src_addr, src_size) ||
2555 		!is_address_in_ddr_range(dst_addr, *dst_size)) {
2556 		return INTEL_SIP_SMC_STATUS_REJECTED;
2557 	}
2558 
2559 	dst_size_check = *dst_size;
2560 
2561 	if ((dst_size_check > FCS_MAX_DATA_SIZE || dst_size_check < FCS_MIN_DATA_SIZE) ||
2562 	    (src_size > FCS_MAX_DATA_SIZE || src_size < FCS_MIN_DATA_SIZE)) {
2563 		return INTEL_SIP_SMC_STATUS_REJECTED;
2564 	}
2565 
2566 	resp_len = *dst_size / MBOX_WORD_BYTE;
2567 
2568 	/* Prepare command payload */
2569 	i = 0;
2570 	/* Crypto header */
2571 	payload[i] = fcs_ecdh_request_param.session_id;
2572 	i++;
2573 	payload[i] = fcs_ecdh_request_param.context_id;
2574 	i++;
2575 	payload[i] = fcs_ecdh_request_param.crypto_param_size
2576 			& FCS_CS_FIELD_SIZE_MASK;
2577 	payload[i] |= (FCS_CS_FIELD_FLAG_INIT | FCS_CS_FIELD_FLAG_UPDATE
2578 			| FCS_CS_FIELD_FLAG_FINALIZE)
2579 			<< FCS_CS_FIELD_FLAG_OFFSET;
2580 	i++;
2581 	payload[i] = fcs_ecdh_request_param.key_id;
2582 	i++;
2583 	/* Crypto parameters */
2584 	payload[i] = fcs_ecdh_request_param.crypto_param
2585 			& INTEL_SIP_SMC_FCS_ECC_ALGO_MASK;
2586 	i++;
2587 	/* Public key data */
2588 	pubkey = src_addr;
2589 
2590 	if ((i + ((src_size) / MBOX_WORD_BYTE)) >
2591 		FCS_ECDH_REQUEST_CMD_MAX_WORD_SIZE) {
2592 		return INTEL_SIP_SMC_STATUS_REJECTED;
2593 	}
2594 
2595 	memcpy_s(&payload[i], src_size / MBOX_WORD_BYTE,
2596 		(void *) pubkey, src_size / MBOX_WORD_BYTE);
2597 	i += src_size / MBOX_WORD_BYTE;
2598 
2599 	status = (smc_fid == ALTERA_SIP_SMC_ASYNC_FCS_ECDH_REQUEST_FINALIZE) ?
2600 			mailbox_send_cmd_async_v3(GET_CLIENT_ID(trans_id),
2601 						  GET_JOB_ID(trans_id),
2602 						  MBOX_FCS_ECDH_REQUEST,
2603 						  payload,
2604 						  i,
2605 						  MBOX_CMD_FLAG_CASUAL,
2606 						  fcs_cs_ecdh_request_cb,
2607 						  (uint32_t *)dst_addr,
2608 						  2U) :
2609 			mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_ECDH_REQUEST,
2610 			payload, i, CMD_CASUAL, (uint32_t *) dst_addr,
2611 			&resp_len);
2612 
2613 	memset((void *)&fcs_ecdh_request_param, 0,
2614 			sizeof(fcs_crypto_service_data));
2615 
2616 	if (status < 0) {
2617 		*mbox_error = -status;
2618 		return INTEL_SIP_SMC_STATUS_ERROR;
2619 	}
2620 
2621 	*dst_size = resp_len * MBOX_WORD_BYTE;
2622 	flush_dcache_range(dst_addr, *dst_size);
2623 
2624 	return INTEL_SIP_SMC_STATUS_OK;
2625 }
2626 
2627 int intel_fcs_aes_crypt_init(uint32_t session_id, uint32_t context_id,
2628 				uint32_t key_id, uint64_t param_addr,
2629 				uint32_t param_size, uint32_t *mbox_error)
2630 {
2631 	/* ptr to get param_addr value */
2632 	uint64_t *param_addr_ptr;
2633 
2634 	param_addr_ptr = (uint64_t *) param_addr;
2635 
2636 	/* Check if mbox_error is not NULL or 0xF or 0x3FF */
2637 	if (mbox_error == NULL || *mbox_error > 0xF ||
2638 		(*mbox_error != 0 && *mbox_error != 0x3FF)) {
2639 		return INTEL_SIP_SMC_STATUS_REJECTED;
2640 	}
2641 
2642 	/* Check if param_addr is not 0 or larger that 0xFFFFFFFFFF */
2643 	if (param_addr == 0 || param_addr > 0xFFFFFFFFFF) {
2644 		return INTEL_SIP_SMC_STATUS_REJECTED;
2645 	}
2646 
2647 	/*
2648 	 * Check if not ECB, CBC and CTR, GCM and GCM-GHASH mode (only for Agilex5),
2649 	 * addr ptr is NULL. Return "Reject" status
2650 	 */
2651 	if ((param_addr_ptr == NULL) ||
2652 	    (((*param_addr_ptr & FCS_CRYPTO_BLOCK_MODE_MASK) != FCS_CRYPTO_ECB_MODE) &&
2653 	    ((*param_addr_ptr & FCS_CRYPTO_BLOCK_MODE_MASK) != FCS_CRYPTO_CBC_MODE) &&
2654 	    ((*param_addr_ptr & FCS_CRYPTO_BLOCK_MODE_MASK) != FCS_CRYPTO_CTR_MODE)
2655 #if PLATFORM_MODEL == PLAT_SOCFPGA_AGILEX5
2656 	    &&
2657 	    ((*param_addr_ptr & FCS_CRYPTO_BLOCK_MODE_MASK) != FCS_CRYPTO_GCM_MODE) &&
2658 	    ((*param_addr_ptr & FCS_CRYPTO_BLOCK_MODE_MASK) != FCS_CRYPTO_GCM_GHASH_MODE)
2659 #endif
2660 	    )){
2661 		return INTEL_SIP_SMC_STATUS_REJECTED;
2662 	}
2663 
2664 	/*
2665 	 * Since crypto param size vary between mode.
2666 	 * Check CBC/CTR here and limit to size 28 bytes
2667 	 */
2668 	if ((((*param_addr_ptr & FCS_CRYPTO_BLOCK_MODE_MASK) == FCS_CRYPTO_CBC_MODE) ||
2669 		((*param_addr_ptr & FCS_CRYPTO_BLOCK_MODE_MASK) == FCS_CRYPTO_CTR_MODE) ||
2670 		((*param_addr_ptr & FCS_CRYPTO_BLOCK_MODE_MASK) == FCS_CRYPTO_GCM_MODE) ||
2671 		((*param_addr_ptr & FCS_CRYPTO_BLOCK_MODE_MASK) == FCS_CRYPTO_GCM_GHASH_MODE)) &&
2672 		(param_size > FCS_CRYPTO_CBC_CTR_BUFFER_SIZE)) {
2673 		return INTEL_SIP_SMC_STATUS_REJECTED;
2674 	}
2675 
2676 	/*
2677 	 * Since crypto param size vary between mode.
2678 	 * Check ECB here and limit to size 12 bytes
2679 	 */
2680 	if (((*param_addr_ptr & FCS_CRYPTO_BLOCK_MODE_MASK) == FCS_CRYPTO_ECB_MODE) &&
2681 		(param_size > FCS_CRYPTO_ECB_BUFFER_SIZE)) {
2682 		return INTEL_SIP_SMC_STATUS_REJECTED;
2683 	}
2684 
2685 	memset((void *)&fcs_aes_init_payload, 0U, sizeof(fcs_aes_init_payload));
2686 
2687 	fcs_aes_init_payload.session_id = session_id;
2688 	fcs_aes_init_payload.context_id = context_id;
2689 	fcs_aes_init_payload.param_size = param_size;
2690 	fcs_aes_init_payload.key_id	= key_id;
2691 
2692 	memcpy_s(fcs_aes_init_payload.crypto_param, param_size / MBOX_WORD_BYTE,
2693 		(void *) param_addr, param_size / MBOX_WORD_BYTE);
2694 
2695 	fcs_aes_init_payload.is_updated = 0;
2696 
2697 	*mbox_error = 0;
2698 
2699 	return INTEL_SIP_SMC_STATUS_OK;
2700 }
2701 
2702 int intel_fcs_aes_crypt_update_finalize(uint32_t smc_fid, uint32_t trans_id,
2703 				uint32_t session_id, uint32_t context_id,
2704 				uint64_t src_addr, uint32_t src_size,
2705 				uint64_t dst_addr, uint32_t dst_size,
2706 				uint32_t padding_size, uint8_t is_finalised,
2707 				uint32_t *send_id, uint64_t smmu_src_addr,
2708 				uint64_t smmu_dst_addr)
2709 {
2710 	int status;
2711 	int i;
2712 	uint32_t flag;
2713 	uint32_t crypto_header;
2714 	uint32_t fcs_aes_crypt_payload[FCS_AES_CMD_MAX_WORD_SIZE];
2715 	uint32_t src_addr_sdm = (uint32_t)src_addr;
2716 	uint32_t dst_addr_sdm = (uint32_t)dst_addr;
2717 	bool is_src_size_aligned;
2718 	bool is_dst_size_aligned;
2719 	bool is_src_size_valid;
2720 	bool is_dst_size_valid;
2721 
2722 	if (fcs_aes_init_payload.session_id != session_id ||
2723 		fcs_aes_init_payload.context_id != context_id) {
2724 		return INTEL_SIP_SMC_STATUS_REJECTED;
2725 	}
2726 
2727 	/* Default source and destination size align check, 32 bytes alignment. */
2728 	is_src_size_aligned = is_32_bytes_aligned(src_size);
2729 	is_dst_size_aligned = is_32_bytes_aligned(dst_size);
2730 	is_src_size_valid = FCS_AES_DATA_SIZE_CHECK(src_size);
2731 	is_dst_size_valid = FCS_AES_DATA_SIZE_CHECK(dst_size);
2732 
2733 	/*
2734 	 * Get the requested block mode.
2735 	 * On the Agilex5 platform with GCM and GCM-GHASH modes, the source and destination size
2736 	 * should be in multiples of 16 bytes. For other platforms and other modes, it should be
2737 	 * in multiples of 32 bytes.
2738 	 */
2739 #if PLATFORM_MODEL == PLAT_SOCFPGA_AGILEX5
2740 	uint32_t block_mode = fcs_aes_init_payload.crypto_param[0] & FCS_CRYPTO_BLOCK_MODE_MASK;
2741 
2742 	if ((block_mode == FCS_CRYPTO_GCM_MODE) ||
2743 	    (block_mode == FCS_CRYPTO_GCM_GHASH_MODE)) {
2744 		is_src_size_aligned = is_16_bytes_aligned(src_size);
2745 		is_dst_size_aligned = is_16_bytes_aligned(dst_size);
2746 		/* The size validity here is, should be 0 or multiples of 16 bytes. */
2747 		is_src_size_valid = is_16_bytes_aligned(src_size);
2748 		is_dst_size_valid = is_16_bytes_aligned(dst_size);
2749 	}
2750 #endif
2751 
2752 	if ((!is_8_bytes_aligned(src_addr)) ||
2753 		(!is_src_size_aligned) ||
2754 		(!is_address_in_ddr_range(src_addr, src_size))) {
2755 		return INTEL_SIP_SMC_STATUS_REJECTED;
2756 	}
2757 
2758 	if ((!is_8_bytes_aligned(dst_addr)) ||
2759 		(!is_dst_size_aligned) ||
2760 		(!is_address_in_ddr_range(dst_addr, dst_size))) {
2761 		return INTEL_SIP_SMC_STATUS_REJECTED;
2762 	}
2763 
2764 	if (!is_src_size_valid || !is_dst_size_valid)
2765 		return INTEL_SIP_SMC_STATUS_REJECTED;
2766 
2767 	/* Prepare crypto header*/
2768 	flag = 0;
2769 	if (fcs_aes_init_payload.is_updated) {
2770 		fcs_aes_init_payload.param_size = 0;
2771 	} else {
2772 		flag |= FCS_CS_FIELD_FLAG_INIT;
2773 	}
2774 
2775 	if (is_finalised != 0U) {
2776 		flag |= FCS_CS_FIELD_FLAG_FINALIZE;
2777 	} else {
2778 		flag |= FCS_CS_FIELD_FLAG_UPDATE;
2779 		fcs_aes_init_payload.is_updated = 1;
2780 	}
2781 	crypto_header = (flag << FCS_CS_FIELD_FLAG_OFFSET) |
2782 			fcs_aes_init_payload.param_size;
2783 
2784 	i = 0U;
2785 	fcs_aes_crypt_payload[i] = session_id;
2786 	i++;
2787 	fcs_aes_crypt_payload[i] = context_id;
2788 	i++;
2789 	fcs_aes_crypt_payload[i] = crypto_header;
2790 	i++;
2791 
2792 	if ((crypto_header >> FCS_CS_FIELD_FLAG_OFFSET) &
2793 	    (FCS_CS_FIELD_FLAG_INIT)) {
2794 		fcs_aes_crypt_payload[i] = fcs_aes_init_payload.key_id;
2795 		i++;
2796 
2797 		if ((i + ((fcs_aes_init_payload.param_size) / MBOX_WORD_BYTE)) >
2798 			FCS_AES_CMD_MAX_WORD_SIZE) {
2799 			return INTEL_SIP_SMC_STATUS_REJECTED;
2800 		}
2801 
2802 		memcpy_s(&fcs_aes_crypt_payload[i],
2803 			fcs_aes_init_payload.param_size / MBOX_WORD_BYTE,
2804 			(void *) fcs_aes_init_payload.crypto_param,
2805 			fcs_aes_init_payload.param_size / MBOX_WORD_BYTE);
2806 
2807 		i += fcs_aes_init_payload.param_size / MBOX_WORD_BYTE;
2808 	}
2809 
2810 	/* On the Agilex5 platform, we will use the SMMU payload address */
2811 #if PLATFORM_MODEL == PLAT_SOCFPGA_AGILEX5
2812 	src_addr_sdm = (uint32_t)smmu_src_addr;
2813 	dst_addr_sdm = (uint32_t)smmu_dst_addr;
2814 #endif
2815 
2816 	fcs_aes_crypt_payload[i] = src_addr_sdm;
2817 	i++;
2818 	fcs_aes_crypt_payload[i] = src_size;
2819 	i++;
2820 	fcs_aes_crypt_payload[i] = dst_addr_sdm;
2821 	i++;
2822 	fcs_aes_crypt_payload[i] = dst_size;
2823 	i++;
2824 
2825 	/* Padding data size, only on Agilex5 with GCM and GCM-GHASH modes. */
2826 #if PLATFORM_MODEL == PLAT_SOCFPGA_AGILEX5
2827 	if ((block_mode == FCS_CRYPTO_GCM_MODE) ||
2828 	    (block_mode == FCS_CRYPTO_GCM_GHASH_MODE)) {
2829 		fcs_aes_crypt_payload[i] = padding_size;
2830 		i++;
2831 	}
2832 #endif
2833 
2834 	status = ((smc_fid == ALTERA_SIP_SMC_ASYNC_FCS_AES_CRYPT_UPDATE) ||
2835 		  (smc_fid == ALTERA_SIP_SMC_ASYNC_FCS_AES_CRYPT_FINALIZE)) ?
2836 			mailbox_send_cmd_async_v3(GET_CLIENT_ID(trans_id),
2837 						   GET_JOB_ID(trans_id),
2838 						   MBOX_FCS_AES_CRYPT_REQ,
2839 						   fcs_aes_crypt_payload,
2840 						   i,
2841 						   MBOX_CMD_FLAG_INDIRECT,
2842 						   fcs_cs_aes_cb,
2843 						   NULL,
2844 						   0U) :
2845 			mailbox_send_cmd_async(send_id, MBOX_FCS_AES_CRYPT_REQ,
2846 					fcs_aes_crypt_payload, i, CMD_INDIRECT);
2847 
2848 
2849 	if (is_finalised != 0U) {
2850 		memset((void *)&fcs_aes_init_payload, 0,
2851 			sizeof(fcs_aes_init_payload));
2852 	}
2853 
2854 	if (status < 0) {
2855 		return INTEL_SIP_SMC_STATUS_ERROR;
2856 	}
2857 
2858 	return INTEL_SIP_SMC_STATUS_OK;
2859 }
2860 
2861 int intel_fcs_hkdf_request(uint32_t smc_fid, uint32_t trans_id,
2862 			   uint32_t session_id, uint32_t step_type,
2863 			   uint32_t mac_mode, uint32_t src_addr,
2864 			   uint32_t key_uid, uint32_t op_key_size)
2865 {
2866 	int status;
2867 	uint32_t i = 0;
2868 	uintptr_t inputdata;
2869 	uint32_t payload[FCS_HKDF_REQUEST_DATA_SIZE] = {0U};
2870 
2871 	if (!is_address_in_ddr_range(src_addr, FCS_HKDF_REQUEST_DATA_SIZE)) {
2872 		ERROR("MBOX: %s: source addr not in the DDR range\n", __func__);
2873 		return INTEL_SIP_SMC_STATUS_REJECTED;
2874 	}
2875 
2876 	/* Prepare command payload */
2877 
2878 	/* Session ID */
2879 	payload[i] = session_id;
2880 	i++;
2881 
2882 	/* Reserved, 8 bytes */
2883 	payload[i] = 0;
2884 	i++;
2885 
2886 	payload[i] = 0;
2887 	i++;
2888 
2889 	/* HKDF step type */
2890 	payload[i] = step_type;
2891 	i++;
2892 
2893 	/* MAC mode/PRF */
2894 	payload[i] = mac_mode;
2895 	i++;
2896 
2897 	/* Complete input data, 1st input data len + its data + 2nd input data len + its data. */
2898 	inputdata = src_addr;
2899 	memcpy_s((uint8_t *)&payload[i], FCS_HKDF_KEY_DATA_SIZE / sizeof(uint32_t),
2900 		(uint8_t *)inputdata, FCS_HKDF_KEY_DATA_SIZE / sizeof(uint32_t));
2901 
2902 	i += FCS_HKDF_KEY_DATA_SIZE / sizeof(uint32_t);
2903 
2904 	/* Key UID */
2905 	payload[i] = key_uid;
2906 	i++;
2907 
2908 	/* Pointer to size of output key object */
2909 	inputdata = inputdata + FCS_HKDF_KEY_DATA_SIZE;
2910 
2911 	/* Output Key object */
2912 	memcpy_s(&payload[i], op_key_size / sizeof(uint32_t), (void *)inputdata,
2913 		op_key_size / sizeof(uint32_t));
2914 
2915 	i += op_key_size / sizeof(uint32_t);
2916 
2917 	status = mailbox_send_cmd_async_v3(GET_CLIENT_ID(trans_id),
2918 					GET_JOB_ID(trans_id),
2919 					MBOX_FCS_HKDF_REQUEST,
2920 					payload,
2921 					i,
2922 					MBOX_CMD_FLAG_CASUAL,
2923 					fcs_hkdf_request_cb,
2924 					NULL,
2925 					0U);
2926 
2927 	if (status < 0) {
2928 		ERROR("MBOX: %s: status %d\n", __func__, status);
2929 		return INTEL_SIP_SMC_STATUS_ERROR;
2930 	}
2931 
2932 	return INTEL_SIP_SMC_STATUS_OK;
2933 }
2934