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