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