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