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