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