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