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