xref: /rk3399_ARM-atf/plat/intel/soc/common/sip/socfpga_sip_fcs.c (revision f6088168f0608604bc1cd57d8ab52d848fdb835b)
1 /*
2  * Copyright (c) 2020-2022, Intel Corporation. All rights reserved.
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  */
6 
7 #include <arch_helpers.h>
8 #include <lib/mmio.h>
9 
10 #include "socfpga_fcs.h"
11 #include "socfpga_mailbox.h"
12 #include "socfpga_sip_svc.h"
13 
14 /* FCS static variables */
15 static fcs_crypto_service_aes_data fcs_aes_init_payload;
16 static fcs_crypto_service_data fcs_sha_get_digest_param;
17 static fcs_crypto_service_data fcs_sha_mac_verify_param;
18 static fcs_crypto_service_data fcs_ecdsa_hash_sign_param;
19 static fcs_crypto_service_data fcs_ecdsa_hash_sig_verify_param;
20 static fcs_crypto_service_data fcs_sha2_data_sign_param;
21 static fcs_crypto_service_data fcs_sha2_data_sig_verify_param;
22 static fcs_crypto_service_data fcs_ecdsa_get_pubkey_param;
23 static fcs_crypto_service_data fcs_ecdh_request_param;
24 
25 bool is_size_4_bytes_aligned(uint32_t size)
26 {
27 	if ((size % MBOX_WORD_BYTE) != 0U) {
28 		return false;
29 	} else {
30 		return true;
31 	}
32 }
33 
34 static bool is_8_bytes_aligned(uint32_t data)
35 {
36 	if ((data % (MBOX_WORD_BYTE * 2U)) != 0U) {
37 		return false;
38 	} else {
39 		return true;
40 	}
41 }
42 
43 static bool is_32_bytes_aligned(uint32_t data)
44 {
45 	if ((data % (8U * MBOX_WORD_BYTE)) != 0U) {
46 		return false;
47 	} else {
48 		return true;
49 	}
50 }
51 
52 static int intel_fcs_crypto_service_init(uint32_t session_id,
53 			uint32_t context_id, uint32_t key_id,
54 			uint32_t param_size, uint64_t param_data,
55 			fcs_crypto_service_data *data_addr,
56 			uint32_t *mbox_error)
57 {
58 	if (mbox_error == NULL) {
59 		return INTEL_SIP_SMC_STATUS_REJECTED;
60 	}
61 
62 	if (param_size != 4) {
63 		return INTEL_SIP_SMC_STATUS_REJECTED;
64 	}
65 
66 	memset(data_addr, 0, sizeof(fcs_crypto_service_data));
67 
68 	data_addr->session_id = session_id;
69 	data_addr->context_id = context_id;
70 	data_addr->key_id = key_id;
71 	data_addr->crypto_param_size = param_size;
72 	data_addr->crypto_param = param_data;
73 
74 	data_addr->is_updated = 0;
75 
76 	*mbox_error = 0;
77 
78 	return INTEL_SIP_SMC_STATUS_OK;
79 }
80 
81 uint32_t intel_fcs_random_number_gen(uint64_t addr, uint64_t *ret_size,
82 					uint32_t *mbox_error)
83 {
84 	int status;
85 	unsigned int i;
86 	unsigned int resp_len = FCS_RANDOM_WORD_SIZE;
87 	uint32_t random_data[FCS_RANDOM_WORD_SIZE] = {0U};
88 
89 	if (!is_address_in_ddr_range(addr, FCS_RANDOM_BYTE_SIZE)) {
90 		return INTEL_SIP_SMC_STATUS_REJECTED;
91 	}
92 
93 	status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_RANDOM_GEN, NULL, 0U,
94 			CMD_CASUAL, random_data, &resp_len);
95 
96 	if (status < 0) {
97 		*mbox_error = -status;
98 		return INTEL_SIP_SMC_STATUS_ERROR;
99 	}
100 
101 	if (resp_len != FCS_RANDOM_WORD_SIZE) {
102 		*mbox_error = GENERIC_RESPONSE_ERROR;
103 		return INTEL_SIP_SMC_STATUS_ERROR;
104 	}
105 
106 	*ret_size = FCS_RANDOM_BYTE_SIZE;
107 
108 	for (i = 0U; i < FCS_RANDOM_WORD_SIZE; i++) {
109 		mmio_write_32(addr, random_data[i]);
110 		addr += MBOX_WORD_BYTE;
111 	}
112 
113 	flush_dcache_range(addr - *ret_size, *ret_size);
114 
115 	return INTEL_SIP_SMC_STATUS_OK;
116 }
117 
118 int intel_fcs_random_number_gen_ext(uint32_t session_id, uint32_t context_id,
119 				uint32_t size, uint32_t *send_id)
120 {
121 	int status;
122 	uint32_t payload_size;
123 	uint32_t crypto_header;
124 
125 	if (size > (FCS_RANDOM_EXT_MAX_WORD_SIZE *
126 		MBOX_WORD_BYTE) || size == 0U) {
127 		return INTEL_SIP_SMC_STATUS_REJECTED;
128 	}
129 
130 	if (!is_size_4_bytes_aligned(size)) {
131 		return INTEL_SIP_SMC_STATUS_REJECTED;
132 	}
133 
134 	crypto_header = (FCS_CS_FIELD_FLAG_INIT | FCS_CS_FIELD_FLAG_FINALIZE) <<
135 			FCS_CS_FIELD_FLAG_OFFSET;
136 
137 	fcs_rng_payload payload = {
138 		session_id,
139 		context_id,
140 		crypto_header,
141 		size
142 	};
143 
144 	payload_size = sizeof(payload) / MBOX_WORD_BYTE;
145 
146 	status = mailbox_send_cmd_async(send_id, MBOX_FCS_RANDOM_GEN,
147 					(uint32_t *) &payload, payload_size,
148 					CMD_INDIRECT);
149 
150 	if (status < 0) {
151 		return INTEL_SIP_SMC_STATUS_ERROR;
152 	}
153 
154 	return INTEL_SIP_SMC_STATUS_OK;
155 }
156 
157 uint32_t intel_fcs_send_cert(uint64_t addr, uint64_t size,
158 					uint32_t *send_id)
159 {
160 	int status;
161 
162 	if (!is_address_in_ddr_range(addr, size)) {
163 		return INTEL_SIP_SMC_STATUS_REJECTED;
164 	}
165 
166 	if (!is_size_4_bytes_aligned(size)) {
167 		return INTEL_SIP_SMC_STATUS_REJECTED;
168 	}
169 
170 	status = mailbox_send_cmd_async(send_id, MBOX_CMD_VAB_SRC_CERT,
171 				(uint32_t *)addr, size / MBOX_WORD_BYTE,
172 				CMD_DIRECT);
173 
174 	flush_dcache_range(addr, size);
175 
176 	if (status < 0) {
177 		return INTEL_SIP_SMC_STATUS_ERROR;
178 	}
179 
180 	return INTEL_SIP_SMC_STATUS_OK;
181 }
182 
183 uint32_t intel_fcs_get_provision_data(uint32_t *send_id)
184 {
185 	int status;
186 
187 	status = mailbox_send_cmd_async(send_id, MBOX_FCS_GET_PROVISION,
188 				NULL, 0U, CMD_DIRECT);
189 
190 	if (status < 0) {
191 		return INTEL_SIP_SMC_STATUS_ERROR;
192 	}
193 
194 	return INTEL_SIP_SMC_STATUS_OK;
195 }
196 
197 uint32_t intel_fcs_cntr_set_preauth(uint8_t counter_type, int32_t counter_value,
198 					uint32_t test_bit, uint32_t *mbox_error)
199 {
200 	int status;
201 	uint32_t first_word;
202 	uint32_t payload_size;
203 
204 	if ((test_bit != MBOX_TEST_BIT) &&
205 		(test_bit != 0)) {
206 		return INTEL_SIP_SMC_STATUS_REJECTED;
207 	}
208 
209 	if ((counter_type < FCS_BIG_CNTR_SEL) ||
210 		(counter_type > FCS_SVN_CNTR_3_SEL)) {
211 		return INTEL_SIP_SMC_STATUS_REJECTED;
212 	}
213 
214 	if ((counter_type == FCS_BIG_CNTR_SEL) &&
215 		(counter_value > FCS_BIG_CNTR_VAL_MAX)) {
216 		return INTEL_SIP_SMC_STATUS_REJECTED;
217 	}
218 
219 	if ((counter_type >= FCS_SVN_CNTR_0_SEL) &&
220 		(counter_type <= FCS_SVN_CNTR_3_SEL) &&
221 		(counter_value > FCS_SVN_CNTR_VAL_MAX)) {
222 		return INTEL_SIP_SMC_STATUS_REJECTED;
223 	}
224 
225 	first_word = test_bit | counter_type;
226 	fcs_cntr_set_preauth_payload payload = {
227 		first_word,
228 		counter_value
229 	};
230 
231 	payload_size = sizeof(payload) / MBOX_WORD_BYTE;
232 	status =  mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_CNTR_SET_PREAUTH,
233 				  (uint32_t *) &payload, payload_size,
234 				  CMD_CASUAL, NULL, NULL);
235 
236 	if (status < 0) {
237 		*mbox_error = -status;
238 		return INTEL_SIP_SMC_STATUS_ERROR;
239 	}
240 
241 	return INTEL_SIP_SMC_STATUS_OK;
242 }
243 
244 uint32_t intel_fcs_encryption(uint32_t src_addr, uint32_t src_size,
245 		uint32_t dst_addr, uint32_t dst_size, uint32_t *send_id)
246 {
247 	int status;
248 	uint32_t load_size;
249 
250 	fcs_encrypt_payload payload = {
251 		FCS_ENCRYPTION_DATA_0,
252 		src_addr,
253 		src_size,
254 		dst_addr,
255 		dst_size };
256 	load_size = sizeof(payload) / MBOX_WORD_BYTE;
257 
258 	if (!is_address_in_ddr_range(src_addr, src_size) ||
259 		!is_address_in_ddr_range(dst_addr, dst_size)) {
260 		return INTEL_SIP_SMC_STATUS_REJECTED;
261 	}
262 
263 	if (!is_size_4_bytes_aligned(src_size)) {
264 		return INTEL_SIP_SMC_STATUS_REJECTED;
265 	}
266 
267 	status = mailbox_send_cmd_async(send_id, MBOX_FCS_ENCRYPT_REQ,
268 				(uint32_t *) &payload, load_size,
269 				CMD_INDIRECT);
270 	inv_dcache_range(dst_addr, dst_size);
271 
272 	if (status < 0) {
273 		return INTEL_SIP_SMC_STATUS_REJECTED;
274 	}
275 
276 	return INTEL_SIP_SMC_STATUS_OK;
277 }
278 
279 uint32_t intel_fcs_decryption(uint32_t src_addr, uint32_t src_size,
280 		uint32_t dst_addr, uint32_t dst_size, uint32_t *send_id)
281 {
282 	int status;
283 	uint32_t load_size;
284 	uintptr_t id_offset;
285 
286 	inv_dcache_range(src_addr, src_size); /* flush cache before mmio read to avoid reading old values */
287 	id_offset = src_addr + FCS_OWNER_ID_OFFSET;
288 	fcs_decrypt_payload payload = {
289 		FCS_DECRYPTION_DATA_0,
290 		{mmio_read_32(id_offset),
291 		mmio_read_32(id_offset + MBOX_WORD_BYTE)},
292 		src_addr,
293 		src_size,
294 		dst_addr,
295 		dst_size };
296 	load_size = sizeof(payload) / MBOX_WORD_BYTE;
297 
298 	if (!is_address_in_ddr_range(src_addr, src_size) ||
299 		!is_address_in_ddr_range(dst_addr, dst_size)) {
300 		return INTEL_SIP_SMC_STATUS_REJECTED;
301 	}
302 
303 	if (!is_size_4_bytes_aligned(src_size)) {
304 		return INTEL_SIP_SMC_STATUS_REJECTED;
305 	}
306 
307 	status = mailbox_send_cmd_async(send_id, MBOX_FCS_DECRYPT_REQ,
308 				(uint32_t *) &payload, load_size,
309 				CMD_INDIRECT);
310 	inv_dcache_range(dst_addr, dst_size);
311 
312 	if (status < 0) {
313 		return INTEL_SIP_SMC_STATUS_REJECTED;
314 	}
315 
316 	return INTEL_SIP_SMC_STATUS_OK;
317 }
318 
319 int intel_fcs_encryption_ext(uint32_t session_id, uint32_t context_id,
320 		uint32_t src_addr, uint32_t src_size,
321 		uint32_t dst_addr, uint32_t *dst_size, uint32_t *mbox_error)
322 {
323 	int status;
324 	uint32_t payload_size;
325 	uint32_t resp_len = FCS_CRYPTION_RESP_WORD_SIZE;
326 	uint32_t resp_data[FCS_CRYPTION_RESP_WORD_SIZE] = {0U};
327 
328 	if ((dst_size == NULL) || (mbox_error == NULL)) {
329 		return INTEL_SIP_SMC_STATUS_REJECTED;
330 	}
331 
332 	if (!is_address_in_ddr_range(src_addr, src_size) ||
333 		!is_address_in_ddr_range(dst_addr, *dst_size)) {
334 		return INTEL_SIP_SMC_STATUS_REJECTED;
335 	}
336 
337 	if (!is_size_4_bytes_aligned(src_size)) {
338 		return INTEL_SIP_SMC_STATUS_REJECTED;
339 	}
340 
341 	fcs_encrypt_ext_payload payload = {
342 		session_id,
343 		context_id,
344 		FCS_CRYPTION_CRYPTO_HEADER,
345 		src_addr,
346 		src_size,
347 		dst_addr,
348 		*dst_size
349 	};
350 
351 	payload_size = sizeof(payload) / MBOX_WORD_BYTE;
352 
353 	status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_ENCRYPT_REQ,
354 				(uint32_t *) &payload, payload_size,
355 				CMD_CASUAL, resp_data, &resp_len);
356 
357 	if (status < 0) {
358 		*mbox_error = -status;
359 		return INTEL_SIP_SMC_STATUS_ERROR;
360 	}
361 
362 	if (resp_len != FCS_CRYPTION_RESP_WORD_SIZE) {
363 		*mbox_error = MBOX_RET_ERROR;
364 		return INTEL_SIP_SMC_STATUS_ERROR;
365 	}
366 
367 	*dst_size = resp_data[FCS_CRYPTION_RESP_SIZE_OFFSET];
368 	inv_dcache_range(dst_addr, *dst_size);
369 
370 	return INTEL_SIP_SMC_STATUS_OK;
371 }
372 
373 int intel_fcs_decryption_ext(uint32_t session_id, uint32_t context_id,
374 		uint32_t src_addr, uint32_t src_size,
375 		uint32_t dst_addr, uint32_t *dst_size, uint32_t *mbox_error)
376 {
377 	int status;
378 	uintptr_t id_offset;
379 	uint32_t payload_size;
380 	uint32_t resp_len = FCS_CRYPTION_RESP_WORD_SIZE;
381 	uint32_t resp_data[FCS_CRYPTION_RESP_WORD_SIZE] = {0U};
382 
383 	if ((dst_size == NULL) || (mbox_error == NULL)) {
384 		return INTEL_SIP_SMC_STATUS_REJECTED;
385 	}
386 
387 	if (!is_address_in_ddr_range(src_addr, src_size) ||
388 		!is_address_in_ddr_range(dst_addr, *dst_size)) {
389 		return INTEL_SIP_SMC_STATUS_REJECTED;
390 	}
391 
392 	if (!is_size_4_bytes_aligned(src_size)) {
393 		return INTEL_SIP_SMC_STATUS_REJECTED;
394 	}
395 
396 	inv_dcache_range(src_addr, src_size); /* flush cache before mmio read to avoid reading old values */
397 	id_offset = src_addr + FCS_OWNER_ID_OFFSET;
398 	fcs_decrypt_ext_payload payload = {
399 		session_id,
400 		context_id,
401 		FCS_CRYPTION_CRYPTO_HEADER,
402 		{mmio_read_32(id_offset),
403 		mmio_read_32(id_offset + MBOX_WORD_BYTE)},
404 		src_addr,
405 		src_size,
406 		dst_addr,
407 		*dst_size
408 	};
409 
410 	payload_size = sizeof(payload) / MBOX_WORD_BYTE;
411 
412 	status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_DECRYPT_REQ,
413 				(uint32_t *) &payload, payload_size,
414 				CMD_CASUAL, resp_data, &resp_len);
415 
416 	if (status == MBOX_RET_SDOS_DECRYPTION_ERROR_102 ||
417 		status == MBOX_RET_SDOS_DECRYPTION_ERROR_103) {
418 		*mbox_error = -status;
419 	} else if (status < 0) {
420 		*mbox_error = -status;
421 		return INTEL_SIP_SMC_STATUS_ERROR;
422 	}
423 
424 	if (resp_len != FCS_CRYPTION_RESP_WORD_SIZE) {
425 		*mbox_error = MBOX_RET_ERROR;
426 		return INTEL_SIP_SMC_STATUS_ERROR;
427 	}
428 
429 	*dst_size = resp_data[FCS_CRYPTION_RESP_SIZE_OFFSET];
430 	inv_dcache_range(dst_addr, *dst_size);
431 
432 	return INTEL_SIP_SMC_STATUS_OK;
433 }
434 
435 int intel_fcs_sigma_teardown(uint32_t session_id, uint32_t *mbox_error)
436 {
437 	int status;
438 
439 	if ((session_id != PSGSIGMA_SESSION_ID_ONE) &&
440 		(session_id != PSGSIGMA_UNKNOWN_SESSION)) {
441 		return INTEL_SIP_SMC_STATUS_REJECTED;
442 	}
443 
444 	psgsigma_teardown_msg message = {
445 		RESERVED_AS_ZERO,
446 		PSGSIGMA_TEARDOWN_MAGIC,
447 		session_id
448 	};
449 
450 	status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_PSG_SIGMA_TEARDOWN,
451 			(uint32_t *) &message, sizeof(message) / MBOX_WORD_BYTE,
452 			CMD_CASUAL, NULL, NULL);
453 
454 	if (status < 0) {
455 		*mbox_error = -status;
456 		return INTEL_SIP_SMC_STATUS_ERROR;
457 	}
458 
459 	return INTEL_SIP_SMC_STATUS_OK;
460 }
461 
462 int intel_fcs_chip_id(uint32_t *id_low, uint32_t *id_high, uint32_t *mbox_error)
463 {
464 	int status;
465 	uint32_t load_size;
466 	uint32_t chip_id[2];
467 
468 	load_size = sizeof(chip_id) / MBOX_WORD_BYTE;
469 
470 	status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_CMD_GET_CHIPID, NULL,
471 			0U, CMD_CASUAL, (uint32_t *) chip_id, &load_size);
472 
473 	if (status < 0) {
474 		*mbox_error = -status;
475 		return INTEL_SIP_SMC_STATUS_ERROR;
476 	}
477 
478 	*id_low = chip_id[0];
479 	*id_high = chip_id[1];
480 
481 	return INTEL_SIP_SMC_STATUS_OK;
482 }
483 
484 int intel_fcs_attestation_subkey(uint64_t src_addr, uint32_t src_size,
485 		uint64_t dst_addr, uint32_t *dst_size, uint32_t *mbox_error)
486 {
487 	int status;
488 	uint32_t send_size = src_size / MBOX_WORD_BYTE;
489 	uint32_t ret_size = *dst_size / MBOX_WORD_BYTE;
490 
491 
492 	if (!is_address_in_ddr_range(src_addr, src_size) ||
493 		!is_address_in_ddr_range(dst_addr, *dst_size)) {
494 		return INTEL_SIP_SMC_STATUS_REJECTED;
495 	}
496 
497 	status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_ATTESTATION_SUBKEY,
498 			(uint32_t *) src_addr, send_size, CMD_CASUAL,
499 			(uint32_t *) dst_addr, &ret_size);
500 
501 	if (status < 0) {
502 		*mbox_error = -status;
503 		return INTEL_SIP_SMC_STATUS_ERROR;
504 	}
505 
506 	*dst_size = ret_size * MBOX_WORD_BYTE;
507 	flush_dcache_range(dst_addr, *dst_size);
508 
509 	return INTEL_SIP_SMC_STATUS_OK;
510 }
511 
512 int intel_fcs_get_measurement(uint64_t src_addr, uint32_t src_size,
513 		uint64_t dst_addr, uint32_t *dst_size, uint32_t *mbox_error)
514 {
515 	int status;
516 	uint32_t send_size = src_size / MBOX_WORD_BYTE;
517 	uint32_t ret_size = *dst_size / MBOX_WORD_BYTE;
518 
519 	if (!is_address_in_ddr_range(src_addr, src_size) ||
520 		!is_address_in_ddr_range(dst_addr, *dst_size)) {
521 		return INTEL_SIP_SMC_STATUS_REJECTED;
522 	}
523 
524 	status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_GET_MEASUREMENT,
525 			(uint32_t *) src_addr, send_size, CMD_CASUAL,
526 			(uint32_t *) dst_addr, &ret_size);
527 
528 	if (status < 0) {
529 		*mbox_error = -status;
530 		return INTEL_SIP_SMC_STATUS_ERROR;
531 	}
532 
533 	*dst_size = ret_size * MBOX_WORD_BYTE;
534 	flush_dcache_range(dst_addr, *dst_size);
535 
536 	return INTEL_SIP_SMC_STATUS_OK;
537 }
538 
539 uint32_t intel_fcs_get_rom_patch_sha384(uint64_t addr, uint64_t *ret_size,
540 					uint32_t *mbox_error)
541 {
542 	int status;
543 	unsigned int resp_len = FCS_SHA384_WORD_SIZE;
544 
545 	if (!is_address_in_ddr_range(addr, FCS_SHA384_BYTE_SIZE)) {
546 		return INTEL_SIP_SMC_STATUS_REJECTED;
547 	}
548 
549 	status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_GET_ROM_PATCH_SHA384, NULL, 0U,
550 			CMD_CASUAL, (uint32_t *) addr, &resp_len);
551 
552 	if (status < 0) {
553 		*mbox_error = -status;
554 		return INTEL_SIP_SMC_STATUS_ERROR;
555 	}
556 
557 	if (resp_len != FCS_SHA384_WORD_SIZE) {
558 		*mbox_error = GENERIC_RESPONSE_ERROR;
559 		return INTEL_SIP_SMC_STATUS_ERROR;
560 	}
561 
562 	*ret_size = FCS_SHA384_BYTE_SIZE;
563 
564 	flush_dcache_range(addr, *ret_size);
565 
566 	return INTEL_SIP_SMC_STATUS_OK;
567 }
568 
569 int intel_fcs_get_attestation_cert(uint32_t cert_request, uint64_t dst_addr,
570 			uint32_t *dst_size, uint32_t *mbox_error)
571 {
572 	int status;
573 	uint32_t ret_size = *dst_size / MBOX_WORD_BYTE;
574 
575 	if (mbox_error == NULL) {
576 		return INTEL_SIP_SMC_STATUS_REJECTED;
577 	}
578 
579 	if (cert_request < FCS_ATTEST_FIRMWARE_CERT ||
580 		cert_request > FCS_ATTEST_CERT_MAX_REQ_PARAM) {
581 		return INTEL_SIP_SMC_STATUS_REJECTED;
582 	}
583 
584 	if (!is_address_in_ddr_range(dst_addr, *dst_size)) {
585 		return INTEL_SIP_SMC_STATUS_REJECTED;
586 	}
587 
588 	status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_GET_ATTESTATION_CERT,
589 			(uint32_t *) &cert_request, 1U, CMD_CASUAL,
590 			(uint32_t *) dst_addr, &ret_size);
591 
592 	if (status < 0) {
593 		*mbox_error = -status;
594 		return INTEL_SIP_SMC_STATUS_ERROR;
595 	}
596 
597 	*dst_size = ret_size * MBOX_WORD_BYTE;
598 	flush_dcache_range(dst_addr, *dst_size);
599 
600 	return INTEL_SIP_SMC_STATUS_OK;
601 }
602 
603 int intel_fcs_create_cert_on_reload(uint32_t cert_request,
604 			uint32_t *mbox_error)
605 {
606 	int status;
607 
608 	if (mbox_error == NULL) {
609 		return INTEL_SIP_SMC_STATUS_REJECTED;
610 	}
611 
612 	if (cert_request < FCS_ATTEST_FIRMWARE_CERT ||
613 		cert_request > FCS_ATTEST_CERT_MAX_REQ_PARAM) {
614 		return INTEL_SIP_SMC_STATUS_REJECTED;
615 	}
616 
617 	status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_CREATE_CERT_ON_RELOAD,
618 			(uint32_t *) &cert_request, 1U, CMD_CASUAL,
619 			NULL, NULL);
620 
621 	if (status < 0) {
622 		*mbox_error = -status;
623 		return INTEL_SIP_SMC_STATUS_ERROR;
624 	}
625 
626 	return INTEL_SIP_SMC_STATUS_OK;
627 }
628 
629 int intel_fcs_open_crypto_service_session(uint32_t *session_id,
630 			uint32_t *mbox_error)
631 {
632 	int status;
633 	uint32_t resp_len = 1U;
634 
635 	if ((session_id == NULL) || (mbox_error == NULL)) {
636 		return INTEL_SIP_SMC_STATUS_REJECTED;
637 	}
638 
639 	status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_OPEN_CS_SESSION,
640 			NULL, 0U, CMD_CASUAL, session_id, &resp_len);
641 
642 	if (status < 0) {
643 		*mbox_error = -status;
644 		return INTEL_SIP_SMC_STATUS_ERROR;
645 	}
646 
647 	return INTEL_SIP_SMC_STATUS_OK;
648 }
649 
650 int intel_fcs_close_crypto_service_session(uint32_t session_id,
651 			uint32_t *mbox_error)
652 {
653 	int status;
654 
655 	if (mbox_error == NULL) {
656 		return INTEL_SIP_SMC_STATUS_REJECTED;
657 	}
658 
659 	status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_CLOSE_CS_SESSION,
660 			&session_id, 1U, CMD_CASUAL, NULL, NULL);
661 
662 	if (status < 0) {
663 		*mbox_error = -status;
664 		return INTEL_SIP_SMC_STATUS_ERROR;
665 	}
666 
667 	return INTEL_SIP_SMC_STATUS_OK;
668 }
669 
670 int intel_fcs_import_crypto_service_key(uint64_t src_addr, uint32_t src_size,
671 		uint32_t *send_id)
672 {
673 	int status;
674 
675 	if (src_size > (FCS_CS_KEY_OBJ_MAX_WORD_SIZE *
676 		MBOX_WORD_BYTE)) {
677 		return INTEL_SIP_SMC_STATUS_REJECTED;
678 	}
679 
680 	if (!is_address_in_ddr_range(src_addr, src_size)) {
681 		return INTEL_SIP_SMC_STATUS_REJECTED;
682 	}
683 
684 	status = mailbox_send_cmd_async(send_id, MBOX_FCS_IMPORT_CS_KEY,
685 				(uint32_t *)src_addr, src_size / MBOX_WORD_BYTE,
686 				CMD_INDIRECT);
687 
688 	if (status < 0) {
689 		return INTEL_SIP_SMC_STATUS_ERROR;
690 	}
691 
692 	return INTEL_SIP_SMC_STATUS_OK;
693 }
694 
695 int intel_fcs_export_crypto_service_key(uint32_t session_id, uint32_t key_id,
696 		uint64_t dst_addr, uint32_t *dst_size,
697 		uint32_t *mbox_error)
698 {
699 	int status;
700 	uint32_t i;
701 	uint32_t payload_size;
702 	uint32_t resp_len = FCS_CS_KEY_OBJ_MAX_WORD_SIZE;
703 	uint32_t resp_data[FCS_CS_KEY_OBJ_MAX_WORD_SIZE] = {0U};
704 	uint32_t op_status = 0U;
705 
706 	if ((dst_size == NULL) || (mbox_error == NULL)) {
707 		return INTEL_SIP_SMC_STATUS_REJECTED;
708 	}
709 
710 	if (!is_address_in_ddr_range(dst_addr, *dst_size)) {
711 		return INTEL_SIP_SMC_STATUS_REJECTED;
712 	}
713 
714 	fcs_cs_key_payload payload = {
715 		session_id,
716 		RESERVED_AS_ZERO,
717 		RESERVED_AS_ZERO,
718 		key_id
719 	};
720 
721 	payload_size = sizeof(payload) / MBOX_WORD_BYTE;
722 
723 	status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_EXPORT_CS_KEY,
724 			(uint32_t *) &payload, payload_size,
725 			CMD_CASUAL, resp_data, &resp_len);
726 
727 	if (resp_len > 0) {
728 		op_status = resp_data[0] & FCS_CS_KEY_RESP_STATUS_MASK;
729 	}
730 
731 	if (status < 0) {
732 		*mbox_error = (-status) | (op_status << FCS_CS_KEY_RESP_STATUS_OFFSET);
733 		return INTEL_SIP_SMC_STATUS_ERROR;
734 	}
735 
736 	if (resp_len > 1) {
737 
738 		/* Export key object is start at second response data */
739 		*dst_size = (resp_len - 1) * MBOX_WORD_BYTE;
740 
741 		for (i = 1U; i < resp_len; i++) {
742 			mmio_write_32(dst_addr, resp_data[i]);
743 			dst_addr += MBOX_WORD_BYTE;
744 		}
745 
746 		flush_dcache_range(dst_addr - *dst_size, *dst_size);
747 
748 	} else {
749 
750 		/* Unexpected response, missing key object in response */
751 		*mbox_error = MBOX_RET_ERROR;
752 		return INTEL_SIP_SMC_STATUS_ERROR;
753 	}
754 
755 	return INTEL_SIP_SMC_STATUS_OK;
756 }
757 
758 int intel_fcs_remove_crypto_service_key(uint32_t session_id, uint32_t key_id,
759 		uint32_t *mbox_error)
760 {
761 	int status;
762 	uint32_t payload_size;
763 	uint32_t resp_len = 1U;
764 	uint32_t resp_data = 0U;
765 	uint32_t op_status = 0U;
766 
767 	if (mbox_error == NULL) {
768 		return INTEL_SIP_SMC_STATUS_REJECTED;
769 	}
770 
771 	fcs_cs_key_payload payload = {
772 		session_id,
773 		RESERVED_AS_ZERO,
774 		RESERVED_AS_ZERO,
775 		key_id
776 	};
777 
778 	payload_size = sizeof(payload) / MBOX_WORD_BYTE;
779 
780 	status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_REMOVE_CS_KEY,
781 			(uint32_t *) &payload, payload_size,
782 			CMD_CASUAL, &resp_data, &resp_len);
783 
784 	if (resp_len > 0) {
785 		op_status = resp_data & FCS_CS_KEY_RESP_STATUS_MASK;
786 	}
787 
788 	if (status < 0) {
789 		*mbox_error = (-status) | (op_status << FCS_CS_KEY_RESP_STATUS_OFFSET);
790 		return INTEL_SIP_SMC_STATUS_ERROR;
791 	}
792 
793 	return INTEL_SIP_SMC_STATUS_OK;
794 }
795 
796 int intel_fcs_get_crypto_service_key_info(uint32_t session_id, uint32_t key_id,
797 		uint64_t dst_addr, uint32_t *dst_size,
798 		uint32_t *mbox_error)
799 {
800 	int status;
801 	uint32_t payload_size;
802 	uint32_t resp_len = FCS_CS_KEY_INFO_MAX_WORD_SIZE;
803 	uint32_t op_status = 0U;
804 
805 	if ((dst_size == NULL) || (mbox_error == NULL)) {
806 		return INTEL_SIP_SMC_STATUS_REJECTED;
807 	}
808 
809 	if (!is_address_in_ddr_range(dst_addr, *dst_size)) {
810 		return INTEL_SIP_SMC_STATUS_REJECTED;
811 	}
812 
813 	fcs_cs_key_payload payload = {
814 		session_id,
815 		RESERVED_AS_ZERO,
816 		RESERVED_AS_ZERO,
817 		key_id
818 	};
819 
820 	payload_size = sizeof(payload) / MBOX_WORD_BYTE;
821 
822 	status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_GET_CS_KEY_INFO,
823 				(uint32_t *) &payload, payload_size,
824 				CMD_CASUAL, (uint32_t *) dst_addr, &resp_len);
825 
826 	if (resp_len > 0) {
827 		inv_dcache_range(dst_addr, (resp_len * MBOX_WORD_BYTE)); /* flush cache before mmio read to avoid reading old values */
828 		op_status = mmio_read_32(dst_addr) &
829 			FCS_CS_KEY_RESP_STATUS_MASK;
830 	}
831 
832 	if (status < 0) {
833 		*mbox_error = (-status) | (op_status << FCS_CS_KEY_RESP_STATUS_OFFSET);
834 		return INTEL_SIP_SMC_STATUS_ERROR;
835 	}
836 
837 	*dst_size = resp_len * MBOX_WORD_BYTE;
838 	flush_dcache_range(dst_addr, *dst_size);
839 
840 	return INTEL_SIP_SMC_STATUS_OK;
841 }
842 
843 int intel_fcs_get_digest_init(uint32_t session_id, uint32_t context_id,
844 				uint32_t key_id, uint32_t param_size,
845 				uint64_t param_data, uint32_t *mbox_error)
846 {
847 	return intel_fcs_crypto_service_init(session_id, context_id,
848 				key_id, param_size, param_data,
849 				(void *) &fcs_sha_get_digest_param,
850 				mbox_error);
851 }
852 
853 int intel_fcs_get_digest_update_finalize(uint32_t session_id,
854 				uint32_t context_id, uint32_t src_addr,
855 				uint32_t src_size, uint64_t dst_addr,
856 				uint32_t *dst_size, uint8_t is_finalised,
857 				uint32_t *mbox_error)
858 {
859 	int status;
860 	uint32_t i;
861 	uint32_t flag;
862 	uint32_t crypto_header;
863 	uint32_t resp_len;
864 	uint32_t payload[FCS_GET_DIGEST_CMD_MAX_WORD_SIZE] = {0U};
865 
866 	if (dst_size == NULL || mbox_error == NULL) {
867 		return INTEL_SIP_SMC_STATUS_REJECTED;
868 	}
869 
870 	if (fcs_sha_get_digest_param.session_id != session_id ||
871 	    fcs_sha_get_digest_param.context_id != context_id) {
872 		return INTEL_SIP_SMC_STATUS_REJECTED;
873 	}
874 
875 	/* Source data must be 8 bytes aligned */
876 	if (!is_8_bytes_aligned(src_size)) {
877 		return INTEL_SIP_SMC_STATUS_REJECTED;
878 	}
879 
880 	if (!is_address_in_ddr_range(src_addr, src_size) ||
881 		 !is_address_in_ddr_range(dst_addr, *dst_size)) {
882 		return INTEL_SIP_SMC_STATUS_REJECTED;
883 	}
884 
885 	resp_len = *dst_size / MBOX_WORD_BYTE;
886 
887 	/* Prepare crypto header */
888 	flag = 0;
889 
890 	if (fcs_sha_get_digest_param.is_updated) {
891 		fcs_sha_get_digest_param.crypto_param_size = 0;
892 	} else {
893 		flag |=  FCS_CS_FIELD_FLAG_INIT;
894 	}
895 
896 	if (is_finalised != 0U) {
897 		flag |=  FCS_CS_FIELD_FLAG_FINALIZE;
898 	} else {
899 		flag |=  FCS_CS_FIELD_FLAG_UPDATE;
900 		fcs_sha_get_digest_param.is_updated = 1;
901 	}
902 
903 	crypto_header = ((flag << FCS_CS_FIELD_FLAG_OFFSET) |
904 			(fcs_sha_get_digest_param.crypto_param_size &
905 			FCS_CS_FIELD_SIZE_MASK));
906 
907 	/* Prepare command payload */
908 	i = 0;
909 	payload[i] = fcs_sha_get_digest_param.session_id;
910 	i++;
911 	payload[i] = fcs_sha_get_digest_param.context_id;
912 	i++;
913 	payload[i] = crypto_header;
914 	i++;
915 
916 	if ((crypto_header >> FCS_CS_FIELD_FLAG_OFFSET) &
917 		FCS_CS_FIELD_FLAG_INIT) {
918 		payload[i] = fcs_sha_get_digest_param.key_id;
919 		i++;
920 		/* Crypto parameters */
921 		payload[i] = fcs_sha_get_digest_param.crypto_param
922 				& INTEL_SIP_SMC_FCS_SHA_MODE_MASK;
923 		payload[i] |= ((fcs_sha_get_digest_param.crypto_param
924 				>> INTEL_SIP_SMC_FCS_DIGEST_SIZE_OFFSET)
925 				& INTEL_SIP_SMC_FCS_DIGEST_SIZE_MASK)
926 				<< FCS_SHA_HMAC_CRYPTO_PARAM_SIZE_OFFSET;
927 		i++;
928 	}
929 	/* Data source address and size */
930 	payload[i] = src_addr;
931 	i++;
932 	payload[i] = src_size;
933 	i++;
934 
935 	status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_GET_DIGEST_REQ,
936 				payload, i, CMD_CASUAL,
937 				(uint32_t *) dst_addr, &resp_len);
938 
939 	if (is_finalised != 0U) {
940 		memset((void *)&fcs_sha_get_digest_param, 0,
941 		sizeof(fcs_crypto_service_data));
942 	}
943 
944 	if (status < 0) {
945 		*mbox_error = -status;
946 		return INTEL_SIP_SMC_STATUS_ERROR;
947 	}
948 
949 	*dst_size = resp_len * MBOX_WORD_BYTE;
950 	flush_dcache_range(dst_addr, *dst_size);
951 
952 	return INTEL_SIP_SMC_STATUS_OK;
953 }
954 
955 int intel_fcs_get_digest_smmu_update_finalize(uint32_t session_id,
956 				uint32_t context_id, uint32_t src_addr,
957 				uint32_t src_size, uint64_t dst_addr,
958 				uint32_t *dst_size, uint8_t is_finalised,
959 				uint32_t *mbox_error, uint32_t *send_id)
960 {
961 	int status;
962 	uint32_t i;
963 	uint32_t flag;
964 	uint32_t crypto_header;
965 	uint32_t resp_len;
966 	uint32_t payload[FCS_GET_DIGEST_CMD_MAX_WORD_SIZE] = {0U};
967 
968 	/* Source data must be 8 bytes aligned */
969 	if (dst_size == NULL || mbox_error == NULL ||
970 		!is_8_bytes_aligned(src_size)) {
971 		return INTEL_SIP_SMC_STATUS_REJECTED;
972 	}
973 
974 	if (fcs_sha_get_digest_param.session_id != session_id ||
975 	    fcs_sha_get_digest_param.context_id != context_id) {
976 		return INTEL_SIP_SMC_STATUS_REJECTED;
977 	}
978 
979 	if (!is_address_in_ddr_range(src_addr, src_size) ||
980 		 !is_address_in_ddr_range(dst_addr, *dst_size)) {
981 		return INTEL_SIP_SMC_STATUS_REJECTED;
982 	}
983 
984 	resp_len = *dst_size / MBOX_WORD_BYTE;
985 
986 	/* Prepare crypto header */
987 	flag = 0;
988 
989 	if (fcs_sha_get_digest_param.is_updated) {
990 		fcs_sha_get_digest_param.crypto_param_size = 0;
991 	} else {
992 		flag |=  FCS_CS_FIELD_FLAG_INIT;
993 	}
994 
995 	if (is_finalised != 0U) {
996 		flag |=  FCS_CS_FIELD_FLAG_FINALIZE;
997 	} else {
998 		flag |=  FCS_CS_FIELD_FLAG_UPDATE;
999 		fcs_sha_get_digest_param.is_updated = 1;
1000 	}
1001 
1002 	crypto_header = ((flag << FCS_CS_FIELD_FLAG_OFFSET) |
1003 			(fcs_sha_get_digest_param.crypto_param_size &
1004 			FCS_CS_FIELD_SIZE_MASK));
1005 
1006 	/* Prepare command payload */
1007 	i = 0;
1008 	payload[i] = fcs_sha_get_digest_param.session_id;
1009 	i++;
1010 	payload[i] = fcs_sha_get_digest_param.context_id;
1011 	i++;
1012 	payload[i] = crypto_header;
1013 	i++;
1014 
1015 	if ((crypto_header >> FCS_CS_FIELD_FLAG_OFFSET) &
1016 		FCS_CS_FIELD_FLAG_INIT) {
1017 		payload[i] = fcs_sha_get_digest_param.key_id;
1018 		i++;
1019 		/* Crypto parameters */
1020 		payload[i] = fcs_sha_get_digest_param.crypto_param
1021 				& INTEL_SIP_SMC_FCS_SHA_MODE_MASK;
1022 		payload[i] |= ((fcs_sha_get_digest_param.crypto_param
1023 				>> INTEL_SIP_SMC_FCS_DIGEST_SIZE_OFFSET)
1024 				& INTEL_SIP_SMC_FCS_DIGEST_SIZE_MASK)
1025 				<< FCS_SHA_HMAC_CRYPTO_PARAM_SIZE_OFFSET;
1026 		i++;
1027 	}
1028 	/* Data source address and size */
1029 	payload[i] = src_addr;
1030 	i++;
1031 	payload[i] = src_size;
1032 	i++;
1033 
1034 	status = mailbox_send_cmd_async(send_id, MBOX_FCS_GET_DIGEST_REQ,
1035 					payload, i, CMD_INDIRECT);
1036 
1037 	if (is_finalised != 0U) {
1038 		memset((void *)&fcs_sha_get_digest_param, 0,
1039 		sizeof(fcs_crypto_service_data));
1040 	}
1041 
1042 	if (status < 0) {
1043 		*mbox_error = -status;
1044 		return INTEL_SIP_SMC_STATUS_ERROR;
1045 	}
1046 
1047 	*dst_size = resp_len * MBOX_WORD_BYTE;
1048 	flush_dcache_range(dst_addr, *dst_size);
1049 
1050 	return INTEL_SIP_SMC_STATUS_OK;
1051 }
1052 
1053 int intel_fcs_mac_verify_init(uint32_t session_id, uint32_t context_id,
1054 				uint32_t key_id, uint32_t param_size,
1055 				uint64_t param_data, uint32_t *mbox_error)
1056 {
1057 	return intel_fcs_crypto_service_init(session_id, context_id,
1058 				key_id, param_size, param_data,
1059 				(void *) &fcs_sha_mac_verify_param,
1060 				mbox_error);
1061 }
1062 
1063 int intel_fcs_mac_verify_update_finalize(uint32_t session_id,
1064 				uint32_t context_id, uint32_t src_addr,
1065 				uint32_t src_size, uint64_t dst_addr,
1066 				uint32_t *dst_size, uint32_t data_size,
1067 				uint8_t is_finalised, uint32_t *mbox_error)
1068 {
1069 	int status;
1070 	uint32_t i;
1071 	uint32_t flag;
1072 	uint32_t crypto_header;
1073 	uint32_t resp_len;
1074 	uint32_t payload[FCS_MAC_VERIFY_CMD_MAX_WORD_SIZE] = {0U};
1075 	uintptr_t mac_offset;
1076 
1077 	if (dst_size == NULL || mbox_error == NULL) {
1078 		return INTEL_SIP_SMC_STATUS_REJECTED;
1079 	}
1080 
1081 	if (fcs_sha_mac_verify_param.session_id != session_id ||
1082 		fcs_sha_mac_verify_param.context_id != context_id) {
1083 		return INTEL_SIP_SMC_STATUS_REJECTED;
1084 	}
1085 
1086 	if (data_size > src_size) {
1087 		return INTEL_SIP_SMC_STATUS_REJECTED;
1088 	}
1089 
1090 	if (!is_size_4_bytes_aligned(src_size) ||
1091 		!is_8_bytes_aligned(data_size)) {
1092 		return INTEL_SIP_SMC_STATUS_REJECTED;
1093 	}
1094 
1095 	if (!is_address_in_ddr_range(src_addr, src_size) ||
1096 		!is_address_in_ddr_range(dst_addr, *dst_size)) {
1097 		return INTEL_SIP_SMC_STATUS_REJECTED;
1098 	}
1099 
1100 	resp_len = *dst_size / MBOX_WORD_BYTE;
1101 
1102 	/* Prepare crypto header */
1103 	flag = 0;
1104 
1105 	if (fcs_sha_mac_verify_param.is_updated) {
1106 		fcs_sha_mac_verify_param.crypto_param_size = 0;
1107 	} else {
1108 		flag |=  FCS_CS_FIELD_FLAG_INIT;
1109 	}
1110 
1111 	if (is_finalised) {
1112 		flag |=  FCS_CS_FIELD_FLAG_FINALIZE;
1113 	} else {
1114 		flag |=  FCS_CS_FIELD_FLAG_UPDATE;
1115 		fcs_sha_mac_verify_param.is_updated = 1;
1116 	}
1117 
1118 	crypto_header = ((flag << FCS_CS_FIELD_FLAG_OFFSET) |
1119 			(fcs_sha_mac_verify_param.crypto_param_size &
1120 			FCS_CS_FIELD_SIZE_MASK));
1121 
1122 	/* Prepare command payload */
1123 	i = 0;
1124 	payload[i] = fcs_sha_mac_verify_param.session_id;
1125 	i++;
1126 	payload[i] = fcs_sha_mac_verify_param.context_id;
1127 	i++;
1128 	payload[i] = crypto_header;
1129 	i++;
1130 
1131 	if ((crypto_header >> FCS_CS_FIELD_FLAG_OFFSET) &
1132 		FCS_CS_FIELD_FLAG_INIT) {
1133 		payload[i] = fcs_sha_mac_verify_param.key_id;
1134 		i++;
1135 		/* Crypto parameters */
1136 		payload[i] = ((fcs_sha_mac_verify_param.crypto_param
1137 				>> INTEL_SIP_SMC_FCS_DIGEST_SIZE_OFFSET)
1138 				& INTEL_SIP_SMC_FCS_DIGEST_SIZE_MASK)
1139 				<< FCS_SHA_HMAC_CRYPTO_PARAM_SIZE_OFFSET;
1140 		i++;
1141 	}
1142 	/* Data source address and size */
1143 	payload[i] = src_addr;
1144 	i++;
1145 	payload[i] = data_size;
1146 	i++;
1147 
1148 	if ((crypto_header >> FCS_CS_FIELD_FLAG_OFFSET) &
1149 		FCS_CS_FIELD_FLAG_FINALIZE) {
1150 		/* Copy mac data to command */
1151 		mac_offset = src_addr + data_size;
1152 		memcpy((uint8_t *) &payload[i], (uint8_t *) mac_offset,
1153 		src_size - data_size);
1154 
1155 		i += (src_size - data_size) / MBOX_WORD_BYTE;
1156 	}
1157 
1158 	status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_MAC_VERIFY_REQ,
1159 				payload, i, CMD_CASUAL,
1160 				(uint32_t *) dst_addr, &resp_len);
1161 
1162 	if (is_finalised) {
1163 		memset((void *)&fcs_sha_mac_verify_param, 0,
1164 		sizeof(fcs_crypto_service_data));
1165 	}
1166 
1167 	if (status < 0) {
1168 		*mbox_error = -status;
1169 		return INTEL_SIP_SMC_STATUS_ERROR;
1170 	}
1171 
1172 	*dst_size = resp_len * MBOX_WORD_BYTE;
1173 	flush_dcache_range(dst_addr, *dst_size);
1174 
1175 	return INTEL_SIP_SMC_STATUS_OK;
1176 }
1177 
1178 int intel_fcs_mac_verify_smmu_update_finalize(uint32_t session_id,
1179 				uint32_t context_id, uint32_t src_addr,
1180 				uint32_t src_size, uint64_t dst_addr,
1181 				uint32_t *dst_size, uint32_t data_size,
1182 				uint8_t is_finalised, uint32_t *mbox_error,
1183 				uint32_t *send_id)
1184 {
1185 	int status;
1186 	uint32_t i;
1187 	uint32_t flag;
1188 	uint32_t crypto_header;
1189 	uint32_t resp_len;
1190 	uint32_t payload[FCS_MAC_VERIFY_CMD_MAX_WORD_SIZE] = {0U};
1191 	uintptr_t mac_offset;
1192 
1193 	/*
1194 	 * Source data must be 4 bytes aligned
1195 	 * User data must be 8 bytes aligned
1196 	 */
1197 	if (dst_size == NULL || mbox_error == NULL ||
1198 		!is_size_4_bytes_aligned(src_size) ||
1199 		!is_8_bytes_aligned(data_size)) {
1200 		return INTEL_SIP_SMC_STATUS_REJECTED;
1201 	}
1202 
1203 	if (data_size > src_size) {
1204 		return INTEL_SIP_SMC_STATUS_REJECTED;
1205 	}
1206 
1207 	if (fcs_sha_mac_verify_param.session_id != session_id ||
1208 		fcs_sha_mac_verify_param.context_id != context_id) {
1209 		return INTEL_SIP_SMC_STATUS_REJECTED;
1210 	}
1211 
1212 	if (!is_address_in_ddr_range(src_addr, src_size) ||
1213 		!is_address_in_ddr_range(dst_addr, *dst_size)) {
1214 		return INTEL_SIP_SMC_STATUS_REJECTED;
1215 	}
1216 
1217 	resp_len = *dst_size / MBOX_WORD_BYTE;
1218 
1219 	/* Prepare crypto header */
1220 	flag = 0;
1221 
1222 	if (fcs_sha_mac_verify_param.is_updated) {
1223 		fcs_sha_mac_verify_param.crypto_param_size = 0;
1224 	} else {
1225 		flag |=  FCS_CS_FIELD_FLAG_INIT;
1226 	}
1227 
1228 	if (is_finalised) {
1229 		flag |=  FCS_CS_FIELD_FLAG_FINALIZE;
1230 	} else {
1231 		flag |=  FCS_CS_FIELD_FLAG_UPDATE;
1232 		fcs_sha_mac_verify_param.is_updated = 1;
1233 	}
1234 
1235 	crypto_header = ((flag << FCS_CS_FIELD_FLAG_OFFSET) |
1236 			(fcs_sha_mac_verify_param.crypto_param_size &
1237 			FCS_CS_FIELD_SIZE_MASK));
1238 
1239 	/* Prepare command payload */
1240 	i = 0;
1241 	payload[i] = fcs_sha_mac_verify_param.session_id;
1242 	i++;
1243 	payload[i] = fcs_sha_mac_verify_param.context_id;
1244 	i++;
1245 	payload[i] = crypto_header;
1246 	i++;
1247 
1248 	if ((crypto_header >> FCS_CS_FIELD_FLAG_OFFSET) &
1249 		FCS_CS_FIELD_FLAG_INIT) {
1250 		payload[i] = fcs_sha_mac_verify_param.key_id;
1251 		i++;
1252 		/* Crypto parameters */
1253 		payload[i] = ((fcs_sha_mac_verify_param.crypto_param
1254 				>> INTEL_SIP_SMC_FCS_DIGEST_SIZE_OFFSET)
1255 				& INTEL_SIP_SMC_FCS_DIGEST_SIZE_MASK)
1256 				<< FCS_SHA_HMAC_CRYPTO_PARAM_SIZE_OFFSET;
1257 		i++;
1258 	}
1259 	/* Data source address and size */
1260 	payload[i] = src_addr;
1261 	i++;
1262 	payload[i] = data_size;
1263 	i++;
1264 
1265 	if ((crypto_header >> FCS_CS_FIELD_FLAG_OFFSET) &
1266 		FCS_CS_FIELD_FLAG_FINALIZE) {
1267 		/* Copy mac data to command
1268 		 * Using dst_addr (physical address) to store mac_offset
1269 		 * mac_offset = MAC data
1270 		 */
1271 		mac_offset = dst_addr;
1272 		memcpy((uint8_t *) &payload[i], (uint8_t *) mac_offset,
1273 		src_size - data_size);
1274 
1275 		memset((void *) dst_addr, 0, *dst_size);
1276 
1277 		i += (src_size - data_size) / MBOX_WORD_BYTE;
1278 	}
1279 
1280 	status = mailbox_send_cmd_async(send_id, MBOX_FCS_MAC_VERIFY_REQ,
1281 					payload, i, CMD_INDIRECT);
1282 
1283 	if (is_finalised) {
1284 		memset((void *)&fcs_sha_mac_verify_param, 0,
1285 		sizeof(fcs_crypto_service_data));
1286 	}
1287 
1288 	if (status < 0) {
1289 		*mbox_error = -status;
1290 		return INTEL_SIP_SMC_STATUS_ERROR;
1291 	}
1292 
1293 	*dst_size = resp_len * MBOX_WORD_BYTE;
1294 	flush_dcache_range(dst_addr, *dst_size);
1295 
1296 	return INTEL_SIP_SMC_STATUS_OK;
1297 }
1298 
1299 int intel_fcs_ecdsa_hash_sign_init(uint32_t session_id, uint32_t context_id,
1300 				uint32_t key_id, uint32_t param_size,
1301 				uint64_t param_data, uint32_t *mbox_error)
1302 {
1303 	return intel_fcs_crypto_service_init(session_id, context_id,
1304 				key_id, param_size, param_data,
1305 				(void *) &fcs_ecdsa_hash_sign_param,
1306 				mbox_error);
1307 }
1308 
1309 int intel_fcs_ecdsa_hash_sign_finalize(uint32_t session_id, uint32_t context_id,
1310 				uint32_t src_addr, uint32_t src_size,
1311 				uint64_t dst_addr, uint32_t *dst_size,
1312 				uint32_t *mbox_error)
1313 {
1314 	int status;
1315 	uint32_t i;
1316 	uint32_t payload[FCS_ECDSA_HASH_SIGN_CMD_MAX_WORD_SIZE] = {0U};
1317 	uint32_t resp_len;
1318 	uintptr_t hash_data_addr;
1319 
1320 	if ((dst_size == NULL) || (mbox_error == NULL)) {
1321 		return INTEL_SIP_SMC_STATUS_REJECTED;
1322 	}
1323 
1324 	if (fcs_ecdsa_hash_sign_param.session_id != session_id ||
1325 		fcs_ecdsa_hash_sign_param.context_id != context_id) {
1326 		return INTEL_SIP_SMC_STATUS_REJECTED;
1327 	}
1328 
1329 	if (!is_address_in_ddr_range(src_addr, src_size) ||
1330 		!is_address_in_ddr_range(dst_addr, *dst_size)) {
1331 		return INTEL_SIP_SMC_STATUS_REJECTED;
1332 	}
1333 
1334 	resp_len = *dst_size / MBOX_WORD_BYTE;
1335 
1336 	/* Prepare command payload */
1337 	/* Crypto header */
1338 	i = 0;
1339 	payload[i] = fcs_ecdsa_hash_sign_param.session_id;
1340 	i++;
1341 	payload[i] = fcs_ecdsa_hash_sign_param.context_id;
1342 
1343 	i++;
1344 	payload[i] = fcs_ecdsa_hash_sign_param.crypto_param_size
1345 			& FCS_CS_FIELD_SIZE_MASK;
1346 	payload[i] |= (FCS_CS_FIELD_FLAG_INIT | FCS_CS_FIELD_FLAG_UPDATE
1347 			| FCS_CS_FIELD_FLAG_FINALIZE)
1348 			<< FCS_CS_FIELD_FLAG_OFFSET;
1349 	i++;
1350 	payload[i] = fcs_ecdsa_hash_sign_param.key_id;
1351 
1352 	/* Crypto parameters */
1353 	i++;
1354 	payload[i] = fcs_ecdsa_hash_sign_param.crypto_param
1355 			& INTEL_SIP_SMC_FCS_ECC_ALGO_MASK;
1356 
1357 	/* Hash Data */
1358 	i++;
1359 	hash_data_addr = src_addr;
1360 	memcpy((uint8_t *) &payload[i], (uint8_t *) hash_data_addr,
1361 			src_size);
1362 
1363 	i += src_size / MBOX_WORD_BYTE;
1364 
1365 	status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_ECDSA_HASH_SIGN_REQ,
1366 			payload, i, CMD_CASUAL, (uint32_t *) dst_addr,
1367 			&resp_len);
1368 
1369 	memset((void *) &fcs_ecdsa_hash_sign_param,
1370 			0, sizeof(fcs_crypto_service_data));
1371 
1372 	if (status < 0) {
1373 		*mbox_error = -status;
1374 		return INTEL_SIP_SMC_STATUS_ERROR;
1375 	}
1376 
1377 	*dst_size = resp_len * MBOX_WORD_BYTE;
1378 	flush_dcache_range(dst_addr, *dst_size);
1379 
1380 	return INTEL_SIP_SMC_STATUS_OK;
1381 }
1382 
1383 int intel_fcs_ecdsa_hash_sig_verify_init(uint32_t session_id, uint32_t context_id,
1384 				uint32_t key_id, uint32_t param_size,
1385 				uint64_t param_data, uint32_t *mbox_error)
1386 {
1387 	return intel_fcs_crypto_service_init(session_id, context_id,
1388 				key_id, param_size, param_data,
1389 				(void *) &fcs_ecdsa_hash_sig_verify_param,
1390 				mbox_error);
1391 }
1392 
1393 int intel_fcs_ecdsa_hash_sig_verify_finalize(uint32_t session_id, uint32_t context_id,
1394 				uint32_t src_addr, uint32_t src_size,
1395 				uint64_t dst_addr, uint32_t *dst_size,
1396 				uint32_t *mbox_error)
1397 {
1398 	int status;
1399 	uint32_t i = 0;
1400 	uint32_t payload[FCS_ECDSA_HASH_SIG_VERIFY_CMD_MAX_WORD_SIZE] = {0U};
1401 	uint32_t resp_len;
1402 	uintptr_t hash_sig_pubkey_addr;
1403 
1404 	if ((dst_size == NULL) || (mbox_error == NULL)) {
1405 		return INTEL_SIP_SMC_STATUS_REJECTED;
1406 	}
1407 
1408 	if (fcs_ecdsa_hash_sig_verify_param.session_id != session_id ||
1409 	fcs_ecdsa_hash_sig_verify_param.context_id != context_id) {
1410 		return INTEL_SIP_SMC_STATUS_REJECTED;
1411 	}
1412 
1413 	if (!is_address_in_ddr_range(src_addr, src_size) ||
1414 		!is_address_in_ddr_range(dst_addr, *dst_size)) {
1415 		return INTEL_SIP_SMC_STATUS_REJECTED;
1416 	}
1417 
1418 	resp_len = *dst_size / MBOX_WORD_BYTE;
1419 
1420 	/* Prepare command payload */
1421 	/* Crypto header */
1422 	i = 0;
1423 	payload[i] = fcs_ecdsa_hash_sig_verify_param.session_id;
1424 
1425 	i++;
1426 	payload[i] = fcs_ecdsa_hash_sig_verify_param.context_id;
1427 
1428 	i++;
1429 	payload[i] = fcs_ecdsa_hash_sig_verify_param.crypto_param_size
1430 			& FCS_CS_FIELD_SIZE_MASK;
1431 	payload[i] |= (FCS_CS_FIELD_FLAG_INIT | FCS_CS_FIELD_FLAG_UPDATE
1432 			| FCS_CS_FIELD_FLAG_FINALIZE)
1433 			<< FCS_CS_FIELD_FLAG_OFFSET;
1434 
1435 	i++;
1436 	payload[i] = fcs_ecdsa_hash_sig_verify_param.key_id;
1437 
1438 	/* Crypto parameters */
1439 	i++;
1440 	payload[i] = fcs_ecdsa_hash_sig_verify_param.crypto_param
1441 			& INTEL_SIP_SMC_FCS_ECC_ALGO_MASK;
1442 
1443 	/* Hash Data Word, Signature Data Word and Public Key Data word */
1444 	i++;
1445 	hash_sig_pubkey_addr = src_addr;
1446 	memcpy((uint8_t *) &payload[i],
1447 			(uint8_t *) hash_sig_pubkey_addr, src_size);
1448 
1449 	i += (src_size / MBOX_WORD_BYTE);
1450 
1451 	status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_ECDSA_HASH_SIG_VERIFY,
1452 			payload, i, CMD_CASUAL, (uint32_t *) dst_addr,
1453 			&resp_len);
1454 
1455 	memset((void *)&fcs_ecdsa_hash_sig_verify_param,
1456 			0, sizeof(fcs_crypto_service_data));
1457 
1458 	if (status < 0) {
1459 		*mbox_error = -status;
1460 		return INTEL_SIP_SMC_STATUS_ERROR;
1461 	}
1462 
1463 	*dst_size = resp_len * MBOX_WORD_BYTE;
1464 	flush_dcache_range(dst_addr, *dst_size);
1465 
1466 	return INTEL_SIP_SMC_STATUS_OK;
1467 }
1468 
1469 int intel_fcs_ecdsa_sha2_data_sign_init(uint32_t session_id,
1470 				uint32_t context_id, uint32_t key_id,
1471 				uint32_t param_size, uint64_t param_data,
1472 				uint32_t *mbox_error)
1473 {
1474 	return intel_fcs_crypto_service_init(session_id, context_id,
1475 				key_id, param_size, param_data,
1476 				(void *) &fcs_sha2_data_sign_param,
1477 				mbox_error);
1478 }
1479 
1480 int intel_fcs_ecdsa_sha2_data_sign_update_finalize(uint32_t session_id,
1481 				uint32_t context_id, uint32_t src_addr,
1482 				uint32_t src_size, uint64_t dst_addr,
1483 				uint32_t *dst_size, uint8_t is_finalised,
1484 				uint32_t *mbox_error)
1485 {
1486 	int status;
1487 	int i;
1488 	uint32_t flag;
1489 	uint32_t crypto_header;
1490 	uint32_t payload[FCS_ECDSA_SHA2_DATA_SIGN_CMD_MAX_WORD_SIZE] = {0U};
1491 	uint32_t resp_len;
1492 
1493 	if ((dst_size == NULL) || (mbox_error == NULL)) {
1494 		return INTEL_SIP_SMC_STATUS_REJECTED;
1495 	}
1496 
1497 	if (fcs_sha2_data_sign_param.session_id != session_id ||
1498 		fcs_sha2_data_sign_param.context_id != context_id) {
1499 		return INTEL_SIP_SMC_STATUS_REJECTED;
1500 	}
1501 
1502 	/* Source data must be 8 bytes aligned */
1503 	if (!is_8_bytes_aligned(src_size)) {
1504 		return INTEL_SIP_SMC_STATUS_REJECTED;
1505 	}
1506 
1507 	if (!is_address_in_ddr_range(src_addr, src_size) ||
1508 		!is_address_in_ddr_range(dst_addr, *dst_size)) {
1509 		return INTEL_SIP_SMC_STATUS_REJECTED;
1510 	}
1511 
1512 	resp_len = *dst_size / MBOX_WORD_BYTE;
1513 
1514 	/* Prepare crypto header */
1515 	flag = 0;
1516 	if (fcs_sha2_data_sign_param.is_updated) {
1517 		fcs_sha2_data_sign_param.crypto_param_size = 0;
1518 	} else {
1519 		flag |= FCS_CS_FIELD_FLAG_INIT;
1520 	}
1521 
1522 	if (is_finalised != 0U) {
1523 		flag |= FCS_CS_FIELD_FLAG_FINALIZE;
1524 	} else {
1525 		flag |= FCS_CS_FIELD_FLAG_UPDATE;
1526 		fcs_sha2_data_sign_param.is_updated = 1;
1527 	}
1528 	crypto_header = (flag << FCS_CS_FIELD_FLAG_OFFSET) |
1529 			fcs_sha2_data_sign_param.crypto_param_size;
1530 
1531 	/* Prepare command payload */
1532 	i = 0;
1533 	payload[i] = fcs_sha2_data_sign_param.session_id;
1534 	i++;
1535 	payload[i] = fcs_sha2_data_sign_param.context_id;
1536 	i++;
1537 	payload[i] = crypto_header;
1538 	i++;
1539 
1540 	if ((crypto_header >> FCS_CS_FIELD_FLAG_OFFSET) &
1541 		FCS_CS_FIELD_FLAG_INIT) {
1542 		payload[i] = fcs_sha2_data_sign_param.key_id;
1543 		/* Crypto parameters */
1544 		i++;
1545 		payload[i] = fcs_sha2_data_sign_param.crypto_param
1546 				& INTEL_SIP_SMC_FCS_ECC_ALGO_MASK;
1547 		i++;
1548 	}
1549 
1550 	/* Data source address and size */
1551 	payload[i] = src_addr;
1552 	i++;
1553 	payload[i] = src_size;
1554 	i++;
1555 	status = mailbox_send_cmd(MBOX_JOB_ID,
1556 			MBOX_FCS_ECDSA_SHA2_DATA_SIGN_REQ, payload,
1557 			i, CMD_CASUAL, (uint32_t *) dst_addr,
1558 			&resp_len);
1559 
1560 	if (is_finalised != 0U) {
1561 		memset((void *)&fcs_sha2_data_sign_param, 0,
1562 			sizeof(fcs_crypto_service_data));
1563 	}
1564 
1565 	if (status < 0) {
1566 		*mbox_error = -status;
1567 		return INTEL_SIP_SMC_STATUS_ERROR;
1568 	}
1569 
1570 	*dst_size = resp_len * MBOX_WORD_BYTE;
1571 	flush_dcache_range(dst_addr, *dst_size);
1572 
1573 	return INTEL_SIP_SMC_STATUS_OK;
1574 }
1575 
1576 int intel_fcs_ecdsa_sha2_data_sign_smmu_update_finalize(uint32_t session_id,
1577 				uint32_t context_id, uint32_t src_addr,
1578 				uint32_t src_size, uint64_t dst_addr,
1579 				uint32_t *dst_size, uint8_t is_finalised,
1580 				uint32_t *mbox_error, uint32_t *send_id)
1581 {
1582 	int status;
1583 	int i;
1584 	uint32_t flag;
1585 	uint32_t crypto_header;
1586 	uint32_t payload[FCS_ECDSA_SHA2_DATA_SIGN_CMD_MAX_WORD_SIZE] = {0U};
1587 	uint32_t resp_len;
1588 
1589 	/* Source data must be 8 bytes aligned */
1590 	if ((dst_size == NULL) || (mbox_error == NULL ||
1591 		!is_8_bytes_aligned(src_size))) {
1592 		return INTEL_SIP_SMC_STATUS_REJECTED;
1593 	}
1594 
1595 	if (fcs_sha2_data_sign_param.session_id != session_id ||
1596 		fcs_sha2_data_sign_param.context_id != context_id) {
1597 		return INTEL_SIP_SMC_STATUS_REJECTED;
1598 	}
1599 
1600 	if (!is_address_in_ddr_range(src_addr, src_size) ||
1601 		!is_address_in_ddr_range(dst_addr, *dst_size)) {
1602 		return INTEL_SIP_SMC_STATUS_REJECTED;
1603 	}
1604 
1605 	resp_len = *dst_size / MBOX_WORD_BYTE;
1606 
1607 	/* Prepare crypto header */
1608 	flag = 0;
1609 	if (fcs_sha2_data_sign_param.is_updated) {
1610 		fcs_sha2_data_sign_param.crypto_param_size = 0;
1611 	} else {
1612 		flag |= FCS_CS_FIELD_FLAG_INIT;
1613 	}
1614 
1615 	if (is_finalised != 0U) {
1616 		flag |= FCS_CS_FIELD_FLAG_FINALIZE;
1617 	} else {
1618 		flag |= FCS_CS_FIELD_FLAG_UPDATE;
1619 		fcs_sha2_data_sign_param.is_updated = 1;
1620 	}
1621 	crypto_header = (flag << FCS_CS_FIELD_FLAG_OFFSET) |
1622 			fcs_sha2_data_sign_param.crypto_param_size;
1623 
1624 	/* Prepare command payload */
1625 	i = 0;
1626 	payload[i] = fcs_sha2_data_sign_param.session_id;
1627 	i++;
1628 	payload[i] = fcs_sha2_data_sign_param.context_id;
1629 	i++;
1630 	payload[i] = crypto_header;
1631 	i++;
1632 
1633 	if ((crypto_header >> FCS_CS_FIELD_FLAG_OFFSET) &
1634 		FCS_CS_FIELD_FLAG_INIT) {
1635 		payload[i] = fcs_sha2_data_sign_param.key_id;
1636 		/* Crypto parameters */
1637 		i++;
1638 		payload[i] = fcs_sha2_data_sign_param.crypto_param
1639 				& INTEL_SIP_SMC_FCS_ECC_ALGO_MASK;
1640 		i++;
1641 	}
1642 
1643 	/* Data source address and size */
1644 	payload[i] = src_addr;
1645 	i++;
1646 	payload[i] = src_size;
1647 	i++;
1648 
1649 	status = mailbox_send_cmd_async(send_id,
1650 					MBOX_FCS_ECDSA_SHA2_DATA_SIGN_REQ,
1651 					payload, i, CMD_INDIRECT);
1652 
1653 	if (is_finalised != 0U) {
1654 		memset((void *)&fcs_sha2_data_sign_param, 0,
1655 			sizeof(fcs_crypto_service_data));
1656 	}
1657 
1658 	if (status < 0) {
1659 		*mbox_error = -status;
1660 		return INTEL_SIP_SMC_STATUS_ERROR;
1661 	}
1662 
1663 	*dst_size = resp_len * MBOX_WORD_BYTE;
1664 	flush_dcache_range(dst_addr, *dst_size);
1665 
1666 	return INTEL_SIP_SMC_STATUS_OK;
1667 }
1668 
1669 int intel_fcs_ecdsa_sha2_data_sig_verify_init(uint32_t session_id,
1670 				uint32_t context_id, uint32_t key_id,
1671 				uint32_t param_size, uint64_t param_data,
1672 				uint32_t *mbox_error)
1673 {
1674 	return intel_fcs_crypto_service_init(session_id, context_id,
1675 				key_id, param_size, param_data,
1676 				(void *) &fcs_sha2_data_sig_verify_param,
1677 				mbox_error);
1678 }
1679 
1680 int intel_fcs_ecdsa_sha2_data_sig_verify_update_finalize(uint32_t session_id,
1681 				uint32_t context_id, uint32_t src_addr,
1682 				uint32_t src_size, uint64_t dst_addr,
1683 				uint32_t *dst_size, uint32_t data_size,
1684 				uint8_t is_finalised, uint32_t *mbox_error)
1685 {
1686 	int status;
1687 	uint32_t i;
1688 	uint32_t flag;
1689 	uint32_t crypto_header;
1690 	uint32_t payload[FCS_ECDSA_SHA2_DATA_SIG_VERIFY_CMD_MAX_WORD_SIZE] = {0U};
1691 	uint32_t resp_len;
1692 	uintptr_t sig_pubkey_offset;
1693 
1694 	if ((dst_size == NULL) || (mbox_error == NULL)) {
1695 		return INTEL_SIP_SMC_STATUS_REJECTED;
1696 	}
1697 
1698 	if (fcs_sha2_data_sig_verify_param.session_id != session_id ||
1699 		fcs_sha2_data_sig_verify_param.context_id != context_id) {
1700 		return INTEL_SIP_SMC_STATUS_REJECTED;
1701 	}
1702 
1703 	if (!is_size_4_bytes_aligned(src_size)) {
1704 		return INTEL_SIP_SMC_STATUS_REJECTED;
1705 	}
1706 
1707 	if (!is_8_bytes_aligned(data_size) ||
1708 		!is_8_bytes_aligned(src_addr)) {
1709 		return INTEL_SIP_SMC_STATUS_REJECTED;
1710 	}
1711 
1712 	if (!is_address_in_ddr_range(src_addr, src_size) ||
1713 		!is_address_in_ddr_range(dst_addr, *dst_size)) {
1714 		return INTEL_SIP_SMC_STATUS_REJECTED;
1715 	}
1716 
1717 	resp_len = *dst_size / MBOX_WORD_BYTE;
1718 
1719 	/* Prepare crypto header */
1720 	flag = 0;
1721 	if (fcs_sha2_data_sig_verify_param.is_updated)
1722 		fcs_sha2_data_sig_verify_param.crypto_param_size = 0;
1723 	else
1724 		flag |= FCS_CS_FIELD_FLAG_INIT;
1725 
1726 	if (is_finalised != 0U)
1727 		flag |= FCS_CS_FIELD_FLAG_FINALIZE;
1728 	else {
1729 		flag |= FCS_CS_FIELD_FLAG_UPDATE;
1730 		fcs_sha2_data_sig_verify_param.is_updated = 1;
1731 	}
1732 	crypto_header = (flag << FCS_CS_FIELD_FLAG_OFFSET) |
1733 			fcs_sha2_data_sig_verify_param.crypto_param_size;
1734 
1735 	/* Prepare command payload */
1736 	i = 0;
1737 	payload[i] = fcs_sha2_data_sig_verify_param.session_id;
1738 	i++;
1739 	payload[i] = fcs_sha2_data_sig_verify_param.context_id;
1740 	i++;
1741 	payload[i] = crypto_header;
1742 	i++;
1743 
1744 	if ((crypto_header >> FCS_CS_FIELD_FLAG_OFFSET) &
1745 		FCS_CS_FIELD_FLAG_INIT) {
1746 		payload[i] = fcs_sha2_data_sig_verify_param.key_id;
1747 		i++;
1748 		/* Crypto parameters */
1749 		payload[i] = fcs_sha2_data_sig_verify_param.crypto_param
1750 				& INTEL_SIP_SMC_FCS_ECC_ALGO_MASK;
1751 		i++;
1752 	}
1753 
1754 	/* Data source address and size */
1755 	payload[i] = src_addr;
1756 	i++;
1757 	payload[i] = data_size;
1758 	i++;
1759 
1760 	if ((crypto_header >> FCS_CS_FIELD_FLAG_OFFSET) &
1761 		FCS_CS_FIELD_FLAG_FINALIZE) {
1762 		/* Signature + Public Key Data */
1763 		sig_pubkey_offset = src_addr + data_size;
1764 		memcpy((uint8_t *) &payload[i], (uint8_t *) sig_pubkey_offset,
1765 			src_size - data_size);
1766 
1767 		i += (src_size - data_size) / MBOX_WORD_BYTE;
1768 	}
1769 
1770 	status = mailbox_send_cmd(MBOX_JOB_ID,
1771 			MBOX_FCS_ECDSA_SHA2_DATA_SIGN_VERIFY, payload, i,
1772 			CMD_CASUAL, (uint32_t *) dst_addr, &resp_len);
1773 
1774 	if (is_finalised != 0U) {
1775 		memset((void *) &fcs_sha2_data_sig_verify_param, 0,
1776 			sizeof(fcs_crypto_service_data));
1777 	}
1778 
1779 	if (status < 0) {
1780 		*mbox_error = -status;
1781 		return INTEL_SIP_SMC_STATUS_ERROR;
1782 	}
1783 
1784 	*dst_size = resp_len * MBOX_WORD_BYTE;
1785 	flush_dcache_range(dst_addr, *dst_size);
1786 
1787 	return INTEL_SIP_SMC_STATUS_OK;
1788 }
1789 
1790 int intel_fcs_ecdsa_sha2_data_sig_verify_smmu_update_finalize(uint32_t session_id,
1791 				uint32_t context_id, uint32_t src_addr,
1792 				uint32_t src_size, uint64_t dst_addr,
1793 				uint32_t *dst_size, uint32_t data_size,
1794 				uint8_t is_finalised, uint32_t *mbox_error,
1795 				uint32_t *send_id)
1796 {
1797 	int status;
1798 	uint32_t i;
1799 	uint32_t flag;
1800 	uint32_t crypto_header;
1801 	uint32_t payload[FCS_ECDSA_SHA2_DATA_SIG_VERIFY_CMD_MAX_WORD_SIZE] = {0U};
1802 	uint32_t resp_len;
1803 	uintptr_t sig_pubkey_offset;
1804 
1805 	/*
1806 	 * Source data must be 4 bytes aligned
1807 	 * Source address must be 8 bytes aligned
1808 	 * User data must be 8 bytes aligned
1809 	 */
1810 	if ((dst_size == NULL) || (mbox_error == NULL) ||
1811 		!is_size_4_bytes_aligned(src_size) ||
1812 		!is_8_bytes_aligned(src_addr) ||
1813 		!is_8_bytes_aligned(data_size)) {
1814 		return INTEL_SIP_SMC_STATUS_REJECTED;
1815 	}
1816 
1817 	if (fcs_sha2_data_sig_verify_param.session_id != session_id ||
1818 		fcs_sha2_data_sig_verify_param.context_id != context_id) {
1819 		return INTEL_SIP_SMC_STATUS_REJECTED;
1820 	}
1821 
1822 	if (!is_address_in_ddr_range(src_addr, src_size) ||
1823 		!is_address_in_ddr_range(dst_addr, *dst_size)) {
1824 		return INTEL_SIP_SMC_STATUS_REJECTED;
1825 	}
1826 
1827 	resp_len = *dst_size / MBOX_WORD_BYTE;
1828 
1829 	/* Prepare crypto header */
1830 	flag = 0;
1831 	if (fcs_sha2_data_sig_verify_param.is_updated)
1832 		fcs_sha2_data_sig_verify_param.crypto_param_size = 0;
1833 	else
1834 		flag |= FCS_CS_FIELD_FLAG_INIT;
1835 
1836 	if (is_finalised != 0U)
1837 		flag |= FCS_CS_FIELD_FLAG_FINALIZE;
1838 	else {
1839 		flag |= FCS_CS_FIELD_FLAG_UPDATE;
1840 		fcs_sha2_data_sig_verify_param.is_updated = 1;
1841 	}
1842 	crypto_header = (flag << FCS_CS_FIELD_FLAG_OFFSET) |
1843 			fcs_sha2_data_sig_verify_param.crypto_param_size;
1844 
1845 	/* Prepare command payload */
1846 	i = 0;
1847 	payload[i] = fcs_sha2_data_sig_verify_param.session_id;
1848 	i++;
1849 	payload[i] = fcs_sha2_data_sig_verify_param.context_id;
1850 	i++;
1851 	payload[i] = crypto_header;
1852 	i++;
1853 
1854 	if ((crypto_header >> FCS_CS_FIELD_FLAG_OFFSET) &
1855 		FCS_CS_FIELD_FLAG_INIT) {
1856 		payload[i] = fcs_sha2_data_sig_verify_param.key_id;
1857 		i++;
1858 		/* Crypto parameters */
1859 		payload[i] = fcs_sha2_data_sig_verify_param.crypto_param
1860 				& INTEL_SIP_SMC_FCS_ECC_ALGO_MASK;
1861 		i++;
1862 	}
1863 
1864 	/* Data source address and size */
1865 	payload[i] = src_addr;
1866 	i++;
1867 	payload[i] = data_size;
1868 	i++;
1869 
1870 	if ((crypto_header >> FCS_CS_FIELD_FLAG_OFFSET) &
1871 		FCS_CS_FIELD_FLAG_FINALIZE) {
1872 		/* Copy mac data to command
1873 		 * Using dst_addr (physical address) to store sig_pubkey_offset
1874 		 * sig_pubkey_offset is Signature + Public Key Data
1875 		 */
1876 		sig_pubkey_offset = dst_addr;
1877 		memcpy((uint8_t *) &payload[i], (uint8_t *) sig_pubkey_offset,
1878 			src_size - data_size);
1879 
1880 		memset((void *) dst_addr, 0, *dst_size);
1881 
1882 		i += (src_size - data_size) / MBOX_WORD_BYTE;
1883 	}
1884 
1885 	status = mailbox_send_cmd_async(send_id,
1886 					MBOX_FCS_ECDSA_SHA2_DATA_SIGN_VERIFY,
1887 					payload, i, CMD_INDIRECT);
1888 
1889 	if (is_finalised != 0U) {
1890 		memset((void *) &fcs_sha2_data_sig_verify_param, 0,
1891 			sizeof(fcs_crypto_service_data));
1892 	}
1893 
1894 	if (status < 0) {
1895 		*mbox_error = -status;
1896 		return INTEL_SIP_SMC_STATUS_ERROR;
1897 	}
1898 
1899 	*dst_size = resp_len * MBOX_WORD_BYTE;
1900 	flush_dcache_range(dst_addr, *dst_size);
1901 
1902 	return INTEL_SIP_SMC_STATUS_OK;
1903 }
1904 
1905 int intel_fcs_ecdsa_get_pubkey_init(uint32_t session_id, uint32_t context_id,
1906 				uint32_t key_id, uint32_t param_size,
1907 				uint64_t param_data, uint32_t *mbox_error)
1908 {
1909 	return intel_fcs_crypto_service_init(session_id, context_id,
1910 				key_id, param_size, param_data,
1911 				(void *) &fcs_ecdsa_get_pubkey_param,
1912 				mbox_error);
1913 }
1914 
1915 int intel_fcs_ecdsa_get_pubkey_finalize(uint32_t session_id, uint32_t context_id,
1916 				uint64_t dst_addr, uint32_t *dst_size,
1917 				uint32_t *mbox_error)
1918 {
1919 	int status;
1920 	int i;
1921 	uint32_t crypto_header;
1922 	uint32_t ret_size;
1923 	uint32_t payload[FCS_ECDSA_GET_PUBKEY_MAX_WORD_SIZE] = {0U};
1924 
1925 	if ((dst_size == NULL) || (mbox_error == NULL)) {
1926 		return INTEL_SIP_SMC_STATUS_REJECTED;
1927 	}
1928 
1929 	if (fcs_ecdsa_get_pubkey_param.session_id != session_id ||
1930 		fcs_ecdsa_get_pubkey_param.context_id != context_id) {
1931 		return INTEL_SIP_SMC_STATUS_REJECTED;
1932 	}
1933 
1934 	ret_size = *dst_size / MBOX_WORD_BYTE;
1935 
1936 	crypto_header = ((FCS_CS_FIELD_FLAG_INIT |
1937 			FCS_CS_FIELD_FLAG_UPDATE |
1938 			FCS_CS_FIELD_FLAG_FINALIZE) <<
1939 			FCS_CS_FIELD_FLAG_OFFSET) |
1940 			fcs_ecdsa_get_pubkey_param.crypto_param_size;
1941 	i = 0;
1942 	/* Prepare command payload */
1943 	payload[i] = session_id;
1944 	i++;
1945 	payload[i] = context_id;
1946 	i++;
1947 	payload[i] = crypto_header;
1948 	i++;
1949 	payload[i] = fcs_ecdsa_get_pubkey_param.key_id;
1950 	i++;
1951 	payload[i] = (uint32_t) fcs_ecdsa_get_pubkey_param.crypto_param &
1952 			INTEL_SIP_SMC_FCS_ECC_ALGO_MASK;
1953 	i++;
1954 
1955 	status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_ECDSA_GET_PUBKEY,
1956 			payload, i, CMD_CASUAL,
1957 			(uint32_t *) dst_addr, &ret_size);
1958 
1959 	memset((void *) &fcs_ecdsa_get_pubkey_param, 0,
1960 		sizeof(fcs_crypto_service_data));
1961 
1962 	if (status < 0) {
1963 		*mbox_error = -status;
1964 		return INTEL_SIP_SMC_STATUS_ERROR;
1965 	}
1966 
1967 	*dst_size = ret_size * MBOX_WORD_BYTE;
1968 	flush_dcache_range(dst_addr, *dst_size);
1969 
1970 	return INTEL_SIP_SMC_STATUS_OK;
1971 }
1972 
1973 int intel_fcs_ecdh_request_init(uint32_t session_id, uint32_t context_id,
1974 				uint32_t key_id, uint32_t param_size,
1975 				uint64_t param_data, uint32_t *mbox_error)
1976 {
1977 	return intel_fcs_crypto_service_init(session_id, context_id,
1978 				key_id, param_size, param_data,
1979 				(void *) &fcs_ecdh_request_param,
1980 				mbox_error);
1981 }
1982 
1983 int intel_fcs_ecdh_request_finalize(uint32_t session_id, uint32_t context_id,
1984 				uint32_t src_addr, uint32_t src_size,
1985 				uint64_t dst_addr, uint32_t *dst_size,
1986 				uint32_t *mbox_error)
1987 {
1988 	int status;
1989 	uint32_t i;
1990 	uint32_t payload[FCS_ECDH_REQUEST_CMD_MAX_WORD_SIZE] = {0U};
1991 	uint32_t resp_len;
1992 	uintptr_t pubkey;
1993 
1994 	if ((dst_size == NULL) || (mbox_error == NULL)) {
1995 		return INTEL_SIP_SMC_STATUS_REJECTED;
1996 	}
1997 
1998 	if (fcs_ecdh_request_param.session_id != session_id ||
1999 		fcs_ecdh_request_param.context_id != context_id) {
2000 		return INTEL_SIP_SMC_STATUS_REJECTED;
2001 	}
2002 
2003 	if (!is_address_in_ddr_range(src_addr, src_size) ||
2004 		!is_address_in_ddr_range(dst_addr, *dst_size)) {
2005 		return INTEL_SIP_SMC_STATUS_REJECTED;
2006 	}
2007 
2008 	resp_len = *dst_size / MBOX_WORD_BYTE;
2009 
2010 	/* Prepare command payload */
2011 	i = 0;
2012 	/* Crypto header */
2013 	payload[i] = fcs_ecdh_request_param.session_id;
2014 	i++;
2015 	payload[i] = fcs_ecdh_request_param.context_id;
2016 	i++;
2017 	payload[i] = fcs_ecdh_request_param.crypto_param_size
2018 			& FCS_CS_FIELD_SIZE_MASK;
2019 	payload[i] |= (FCS_CS_FIELD_FLAG_INIT | FCS_CS_FIELD_FLAG_UPDATE
2020 			| FCS_CS_FIELD_FLAG_FINALIZE)
2021 			<< FCS_CS_FIELD_FLAG_OFFSET;
2022 	i++;
2023 	payload[i] = fcs_ecdh_request_param.key_id;
2024 	i++;
2025 	/* Crypto parameters */
2026 	payload[i] = fcs_ecdh_request_param.crypto_param
2027 			& INTEL_SIP_SMC_FCS_ECC_ALGO_MASK;
2028 	i++;
2029 	/* Public key data */
2030 	pubkey = src_addr;
2031 	memcpy((uint8_t *) &payload[i], (uint8_t *) pubkey, src_size);
2032 	i += src_size / MBOX_WORD_BYTE;
2033 
2034 	status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_ECDH_REQUEST,
2035 			payload, i, CMD_CASUAL, (uint32_t *) dst_addr,
2036 			&resp_len);
2037 
2038 	memset((void *)&fcs_ecdh_request_param, 0,
2039 			sizeof(fcs_crypto_service_data));
2040 
2041 	if (status < 0) {
2042 		*mbox_error = -status;
2043 		return INTEL_SIP_SMC_STATUS_ERROR;
2044 	}
2045 
2046 	*dst_size = resp_len * MBOX_WORD_BYTE;
2047 	flush_dcache_range(dst_addr, *dst_size);
2048 
2049 	return INTEL_SIP_SMC_STATUS_OK;
2050 }
2051 
2052 int intel_fcs_aes_crypt_init(uint32_t session_id, uint32_t context_id,
2053 				uint32_t key_id, uint64_t param_addr,
2054 				uint32_t param_size, uint32_t *mbox_error)
2055 {
2056 	/* ptr to get param_addr value */
2057 	uint64_t *param_addr_ptr;
2058 
2059 	param_addr_ptr = (uint64_t *) param_addr;
2060 
2061 	/*
2062 	 * Since crypto param size vary between mode.
2063 	 * Check ECB here and limit to size 12 bytes
2064 	 */
2065 	if (((*param_addr_ptr & FCS_CRYPTO_BLOCK_MODE_MASK) == FCS_CRYPTO_ECB_MODE) &&
2066 		(param_size > FCS_CRYPTO_ECB_BUFFER_SIZE)) {
2067 		return INTEL_SIP_SMC_STATUS_REJECTED;
2068 	}
2069 	/*
2070 	 * Since crypto param size vary between mode.
2071 	 * Check CBC/CTR here and limit to size 28 bytes
2072 	 */
2073 	if ((((*param_addr_ptr & FCS_CRYPTO_BLOCK_MODE_MASK) == FCS_CRYPTO_CBC_MODE) ||
2074 		((*param_addr_ptr & FCS_CRYPTO_BLOCK_MODE_MASK) == FCS_CRYPTO_CTR_MODE)) &&
2075 		(param_size > FCS_CRYPTO_CBC_CTR_BUFFER_SIZE)) {
2076 		return INTEL_SIP_SMC_STATUS_REJECTED;
2077 	}
2078 
2079 	if (mbox_error == NULL) {
2080 		return INTEL_SIP_SMC_STATUS_REJECTED;
2081 	}
2082 
2083 	memset((void *)&fcs_aes_init_payload, 0U, sizeof(fcs_aes_init_payload));
2084 
2085 	fcs_aes_init_payload.session_id = session_id;
2086 	fcs_aes_init_payload.context_id = context_id;
2087 	fcs_aes_init_payload.param_size = param_size;
2088 	fcs_aes_init_payload.key_id	= key_id;
2089 
2090 	memcpy((uint8_t *) fcs_aes_init_payload.crypto_param,
2091 		(uint8_t *) param_addr, param_size);
2092 
2093 	fcs_aes_init_payload.is_updated = 0;
2094 
2095 	*mbox_error = 0;
2096 
2097 	return INTEL_SIP_SMC_STATUS_OK;
2098 }
2099 
2100 int intel_fcs_aes_crypt_update_finalize(uint32_t session_id,
2101 				uint32_t context_id, uint64_t src_addr,
2102 				uint32_t src_size, uint64_t dst_addr,
2103 				uint32_t dst_size, uint8_t is_finalised,
2104 				uint32_t *send_id)
2105 {
2106 	int status;
2107 	int i;
2108 	uint32_t flag;
2109 	uint32_t crypto_header;
2110 	uint32_t fcs_aes_crypt_payload[FCS_AES_CMD_MAX_WORD_SIZE];
2111 
2112 	if (fcs_aes_init_payload.session_id != session_id ||
2113 		fcs_aes_init_payload.context_id != context_id) {
2114 		return INTEL_SIP_SMC_STATUS_REJECTED;
2115 	}
2116 
2117 	if ((!is_8_bytes_aligned(src_addr)) ||
2118 		(!is_32_bytes_aligned(src_size)) ||
2119 		(!is_address_in_ddr_range(src_addr, src_size))) {
2120 		return INTEL_SIP_SMC_STATUS_REJECTED;
2121 	}
2122 
2123 	if ((!is_8_bytes_aligned(dst_addr)) ||
2124 		(!is_32_bytes_aligned(dst_size))) {
2125 		return INTEL_SIP_SMC_STATUS_REJECTED;
2126 	}
2127 
2128 	if ((dst_size > FCS_AES_MAX_DATA_SIZE ||
2129 		dst_size < FCS_AES_MIN_DATA_SIZE) ||
2130 		(src_size > FCS_AES_MAX_DATA_SIZE ||
2131 		src_size < FCS_AES_MIN_DATA_SIZE)) {
2132 		return INTEL_SIP_SMC_STATUS_REJECTED;
2133 	}
2134 
2135 	/* Prepare crypto header*/
2136 	flag = 0;
2137 	if (fcs_aes_init_payload.is_updated) {
2138 		fcs_aes_init_payload.param_size = 0;
2139 	} else {
2140 		flag |= FCS_CS_FIELD_FLAG_INIT;
2141 	}
2142 
2143 	if (is_finalised != 0U) {
2144 		flag |= FCS_CS_FIELD_FLAG_FINALIZE;
2145 	} else {
2146 		flag |= FCS_CS_FIELD_FLAG_UPDATE;
2147 		fcs_aes_init_payload.is_updated = 1;
2148 	}
2149 	crypto_header = (flag << FCS_CS_FIELD_FLAG_OFFSET) |
2150 			fcs_aes_init_payload.param_size;
2151 
2152 	i = 0U;
2153 	fcs_aes_crypt_payload[i] = session_id;
2154 	i++;
2155 	fcs_aes_crypt_payload[i] = context_id;
2156 	i++;
2157 	fcs_aes_crypt_payload[i] = crypto_header;
2158 	i++;
2159 
2160 	if ((crypto_header >> FCS_CS_FIELD_FLAG_OFFSET) &
2161 		FCS_CS_FIELD_FLAG_INIT) {
2162 		fcs_aes_crypt_payload[i] = fcs_aes_init_payload.key_id;
2163 		i++;
2164 
2165 		memcpy((uint8_t *) &fcs_aes_crypt_payload[i],
2166 			(uint8_t *) fcs_aes_init_payload.crypto_param,
2167 			fcs_aes_init_payload.param_size);
2168 
2169 		i += fcs_aes_init_payload.param_size / MBOX_WORD_BYTE;
2170 	}
2171 
2172 	fcs_aes_crypt_payload[i] = (uint32_t) src_addr;
2173 	i++;
2174 	fcs_aes_crypt_payload[i] = src_size;
2175 	i++;
2176 	fcs_aes_crypt_payload[i] = (uint32_t) dst_addr;
2177 	i++;
2178 	fcs_aes_crypt_payload[i] = dst_size;
2179 	i++;
2180 
2181 	status = mailbox_send_cmd_async(send_id, MBOX_FCS_AES_CRYPT_REQ,
2182 					fcs_aes_crypt_payload, i,
2183 					CMD_INDIRECT);
2184 
2185 	if (is_finalised != 0U) {
2186 		memset((void *)&fcs_aes_init_payload, 0,
2187 			sizeof(fcs_aes_init_payload));
2188 	}
2189 
2190 	if (status < 0U) {
2191 		return INTEL_SIP_SMC_STATUS_ERROR;
2192 	}
2193 
2194 	return INTEL_SIP_SMC_STATUS_OK;
2195 }
2196