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