xref: /rk3399_ARM-atf/plat/intel/soc/common/sip/socfpga_sip_fcs.c (revision 583050607e43cef8b544a5700386a019e54c422f)
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_sha2_data_sign_param;
19 static fcs_crypto_service_data fcs_sha2_data_sig_verify_param;
20 static fcs_crypto_service_data fcs_ecdsa_get_pubkey_param;
21 
22 bool is_size_4_bytes_aligned(uint32_t size)
23 {
24 	if ((size % MBOX_WORD_BYTE) != 0U) {
25 		return false;
26 	} else {
27 		return true;
28 	}
29 }
30 
31 static bool is_8_bytes_aligned(uint32_t data)
32 {
33 	if ((data % (MBOX_WORD_BYTE * 2U)) != 0U) {
34 		return false;
35 	} else {
36 		return true;
37 	}
38 }
39 
40 static bool is_32_bytes_aligned(uint32_t data)
41 {
42 	if ((data % (8U * MBOX_WORD_BYTE)) != 0U) {
43 		return false;
44 	} else {
45 		return true;
46 	}
47 }
48 
49 static int intel_fcs_crypto_service_init(uint32_t session_id,
50 			uint32_t context_id, uint32_t key_id,
51 			uint32_t param_size, uint64_t param_data,
52 			fcs_crypto_service_data *data_addr,
53 			uint32_t *mbox_error)
54 {
55 	if (mbox_error == NULL) {
56 		return INTEL_SIP_SMC_STATUS_REJECTED;
57 	}
58 
59 	if (param_size != 4) {
60 		return INTEL_SIP_SMC_STATUS_REJECTED;
61 	}
62 
63 	memset(data_addr, 0, sizeof(fcs_crypto_service_data));
64 
65 	data_addr->session_id = session_id;
66 	data_addr->context_id = context_id;
67 	data_addr->key_id = key_id;
68 	data_addr->crypto_param_size = param_size;
69 	data_addr->crypto_param = param_data;
70 
71 	*mbox_error = 0;
72 
73 	return INTEL_SIP_SMC_STATUS_OK;
74 }
75 
76 uint32_t intel_fcs_random_number_gen(uint64_t addr, uint64_t *ret_size,
77 					uint32_t *mbox_error)
78 {
79 	int status;
80 	unsigned int i;
81 	unsigned int resp_len = FCS_RANDOM_WORD_SIZE;
82 	uint32_t random_data[FCS_RANDOM_WORD_SIZE] = {0U};
83 
84 	if (!is_address_in_ddr_range(addr, FCS_RANDOM_BYTE_SIZE)) {
85 		return INTEL_SIP_SMC_STATUS_REJECTED;
86 	}
87 
88 	status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_RANDOM_GEN, NULL, 0U,
89 			CMD_CASUAL, random_data, &resp_len);
90 
91 	if (status < 0) {
92 		*mbox_error = -status;
93 		return INTEL_SIP_SMC_STATUS_ERROR;
94 	}
95 
96 	if (resp_len != FCS_RANDOM_WORD_SIZE) {
97 		*mbox_error = GENERIC_RESPONSE_ERROR;
98 		return INTEL_SIP_SMC_STATUS_ERROR;
99 	}
100 
101 	*ret_size = FCS_RANDOM_BYTE_SIZE;
102 
103 	for (i = 0U; i < FCS_RANDOM_WORD_SIZE; i++) {
104 		mmio_write_32(addr, random_data[i]);
105 		addr += MBOX_WORD_BYTE;
106 	}
107 
108 	flush_dcache_range(addr - *ret_size, *ret_size);
109 
110 	return INTEL_SIP_SMC_STATUS_OK;
111 }
112 
113 int intel_fcs_random_number_gen_ext(uint32_t session_id, uint32_t context_id,
114 				uint32_t size, uint32_t *send_id)
115 {
116 	int status;
117 	uint32_t payload_size;
118 	uint32_t crypto_header;
119 
120 	if (size > (FCS_RANDOM_EXT_MAX_WORD_SIZE *
121 		MBOX_WORD_BYTE) || size == 0U) {
122 		return INTEL_SIP_SMC_STATUS_REJECTED;
123 	}
124 
125 	if (!is_size_4_bytes_aligned(size)) {
126 		return INTEL_SIP_SMC_STATUS_REJECTED;
127 	}
128 
129 	crypto_header = (FCS_CS_FIELD_FLAG_INIT | FCS_CS_FIELD_FLAG_FINALIZE) <<
130 			FCS_CS_FIELD_FLAG_OFFSET;
131 
132 	fcs_rng_payload payload = {
133 		session_id,
134 		context_id,
135 		crypto_header,
136 		size
137 	};
138 
139 	payload_size = sizeof(payload) / MBOX_WORD_BYTE;
140 
141 	status = mailbox_send_cmd_async(send_id, MBOX_FCS_RANDOM_GEN,
142 					(uint32_t *) &payload, payload_size,
143 					CMD_INDIRECT);
144 
145 	if (status < 0) {
146 		return INTEL_SIP_SMC_STATUS_ERROR;
147 	}
148 
149 	return INTEL_SIP_SMC_STATUS_OK;
150 }
151 
152 uint32_t intel_fcs_send_cert(uint64_t addr, uint64_t size,
153 					uint32_t *send_id)
154 {
155 	int status;
156 
157 	if (!is_address_in_ddr_range(addr, size)) {
158 		return INTEL_SIP_SMC_STATUS_REJECTED;
159 	}
160 
161 	if (!is_size_4_bytes_aligned(size)) {
162 		return INTEL_SIP_SMC_STATUS_REJECTED;
163 	}
164 
165 	status = mailbox_send_cmd_async(send_id, MBOX_CMD_VAB_SRC_CERT,
166 				(uint32_t *)addr, size / MBOX_WORD_BYTE,
167 				CMD_DIRECT);
168 
169 	flush_dcache_range(addr, size);
170 
171 	if (status < 0) {
172 		return INTEL_SIP_SMC_STATUS_ERROR;
173 	}
174 
175 	return INTEL_SIP_SMC_STATUS_OK;
176 }
177 
178 uint32_t intel_fcs_get_provision_data(uint32_t *send_id)
179 {
180 	int status;
181 
182 	status = mailbox_send_cmd_async(send_id, MBOX_FCS_GET_PROVISION,
183 				NULL, 0U, CMD_DIRECT);
184 
185 	if (status < 0) {
186 		return INTEL_SIP_SMC_STATUS_ERROR;
187 	}
188 
189 	return INTEL_SIP_SMC_STATUS_OK;
190 }
191 
192 uint32_t intel_fcs_cntr_set_preauth(uint8_t counter_type, int32_t counter_value,
193 					uint32_t test_bit, uint32_t *mbox_error)
194 {
195 	int status;
196 	uint32_t first_word;
197 	uint32_t payload_size;
198 
199 	if ((test_bit != MBOX_TEST_BIT) &&
200 		(test_bit != 0)) {
201 		return INTEL_SIP_SMC_STATUS_REJECTED;
202 	}
203 
204 	if ((counter_type < FCS_BIG_CNTR_SEL) ||
205 		(counter_type > FCS_SVN_CNTR_3_SEL)) {
206 		return INTEL_SIP_SMC_STATUS_REJECTED;
207 	}
208 
209 	if ((counter_type == FCS_BIG_CNTR_SEL) &&
210 		(counter_value > FCS_BIG_CNTR_VAL_MAX)) {
211 		return INTEL_SIP_SMC_STATUS_REJECTED;
212 	}
213 
214 	if ((counter_type >= FCS_SVN_CNTR_0_SEL) &&
215 		(counter_type <= FCS_SVN_CNTR_3_SEL) &&
216 		(counter_value > FCS_SVN_CNTR_VAL_MAX)) {
217 		return INTEL_SIP_SMC_STATUS_REJECTED;
218 	}
219 
220 	first_word = test_bit | counter_type;
221 	fcs_cntr_set_preauth_payload payload = {
222 		first_word,
223 		counter_value
224 	};
225 
226 	payload_size = sizeof(payload) / MBOX_WORD_BYTE;
227 	status =  mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_CNTR_SET_PREAUTH,
228 				  (uint32_t *) &payload, payload_size,
229 				  CMD_CASUAL, NULL, NULL);
230 
231 	if (status < 0) {
232 		*mbox_error = -status;
233 		return INTEL_SIP_SMC_STATUS_ERROR;
234 	}
235 
236 	return INTEL_SIP_SMC_STATUS_OK;
237 }
238 
239 uint32_t intel_fcs_encryption(uint32_t src_addr, uint32_t src_size,
240 		uint32_t dst_addr, uint32_t dst_size, uint32_t *send_id)
241 {
242 	int status;
243 	uint32_t load_size;
244 
245 	fcs_encrypt_payload payload = {
246 		FCS_ENCRYPTION_DATA_0,
247 		src_addr,
248 		src_size,
249 		dst_addr,
250 		dst_size };
251 	load_size = sizeof(payload) / MBOX_WORD_BYTE;
252 
253 	if (!is_address_in_ddr_range(src_addr, src_size) ||
254 		!is_address_in_ddr_range(dst_addr, dst_size)) {
255 		return INTEL_SIP_SMC_STATUS_REJECTED;
256 	}
257 
258 	if (!is_size_4_bytes_aligned(src_size)) {
259 		return INTEL_SIP_SMC_STATUS_REJECTED;
260 	}
261 
262 	status = mailbox_send_cmd_async(send_id, MBOX_FCS_ENCRYPT_REQ,
263 				(uint32_t *) &payload, load_size,
264 				CMD_INDIRECT);
265 	inv_dcache_range(dst_addr, dst_size);
266 
267 	if (status < 0) {
268 		return INTEL_SIP_SMC_STATUS_REJECTED;
269 	}
270 
271 	return INTEL_SIP_SMC_STATUS_OK;
272 }
273 
274 uint32_t intel_fcs_decryption(uint32_t src_addr, uint32_t src_size,
275 		uint32_t dst_addr, uint32_t dst_size, uint32_t *send_id)
276 {
277 	int status;
278 	uint32_t load_size;
279 	uintptr_t id_offset;
280 
281 	id_offset = src_addr + FCS_OWNER_ID_OFFSET;
282 	fcs_decrypt_payload payload = {
283 		FCS_DECRYPTION_DATA_0,
284 		{mmio_read_32(id_offset),
285 		mmio_read_32(id_offset + MBOX_WORD_BYTE)},
286 		src_addr,
287 		src_size,
288 		dst_addr,
289 		dst_size };
290 	load_size = sizeof(payload) / MBOX_WORD_BYTE;
291 
292 	if (!is_address_in_ddr_range(src_addr, src_size) ||
293 		!is_address_in_ddr_range(dst_addr, dst_size)) {
294 		return INTEL_SIP_SMC_STATUS_REJECTED;
295 	}
296 
297 	if (!is_size_4_bytes_aligned(src_size)) {
298 		return INTEL_SIP_SMC_STATUS_REJECTED;
299 	}
300 
301 	status = mailbox_send_cmd_async(send_id, MBOX_FCS_DECRYPT_REQ,
302 				(uint32_t *) &payload, load_size,
303 				CMD_INDIRECT);
304 	inv_dcache_range(dst_addr, dst_size);
305 
306 	if (status < 0) {
307 		return INTEL_SIP_SMC_STATUS_REJECTED;
308 	}
309 
310 	return INTEL_SIP_SMC_STATUS_OK;
311 }
312 
313 uint32_t intel_fcs_get_rom_patch_sha384(uint64_t addr, uint64_t *ret_size,
314 					uint32_t *mbox_error)
315 {
316 	int status;
317 	unsigned int resp_len = FCS_SHA384_WORD_SIZE;
318 
319 	if (!is_address_in_ddr_range(addr, FCS_SHA384_BYTE_SIZE)) {
320 		return INTEL_SIP_SMC_STATUS_REJECTED;
321 	}
322 
323 	status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_GET_ROM_PATCH_SHA384, NULL, 0U,
324 			CMD_CASUAL, (uint32_t *) addr, &resp_len);
325 
326 	if (status < 0) {
327 		*mbox_error = -status;
328 		return INTEL_SIP_SMC_STATUS_ERROR;
329 	}
330 
331 	if (resp_len != FCS_SHA384_WORD_SIZE) {
332 		*mbox_error = GENERIC_RESPONSE_ERROR;
333 		return INTEL_SIP_SMC_STATUS_ERROR;
334 	}
335 
336 	*ret_size = FCS_SHA384_BYTE_SIZE;
337 
338 	flush_dcache_range(addr, *ret_size);
339 
340 	return INTEL_SIP_SMC_STATUS_OK;
341 }
342 
343 int intel_fcs_encryption_ext(uint32_t session_id, uint32_t context_id,
344 		uint32_t src_addr, uint32_t src_size,
345 		uint32_t dst_addr, uint32_t *dst_size, uint32_t *mbox_error)
346 {
347 	int status;
348 	uint32_t payload_size;
349 	uint32_t resp_len = FCS_CRYPTION_RESP_WORD_SIZE;
350 	uint32_t resp_data[FCS_CRYPTION_RESP_WORD_SIZE] = {0U};
351 
352 	if ((dst_size == NULL) || (mbox_error == NULL)) {
353 		return INTEL_SIP_SMC_STATUS_REJECTED;
354 	}
355 
356 	if (!is_address_in_ddr_range(src_addr, src_size) ||
357 		!is_address_in_ddr_range(dst_addr, *dst_size)) {
358 		return INTEL_SIP_SMC_STATUS_REJECTED;
359 	}
360 
361 	if (!is_size_4_bytes_aligned(src_size)) {
362 		return INTEL_SIP_SMC_STATUS_REJECTED;
363 	}
364 
365 	fcs_encrypt_ext_payload payload = {
366 		session_id,
367 		context_id,
368 		FCS_CRYPTION_CRYPTO_HEADER,
369 		src_addr,
370 		src_size,
371 		dst_addr,
372 		*dst_size
373 	};
374 
375 	payload_size = sizeof(payload) / MBOX_WORD_BYTE;
376 
377 	status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_ENCRYPT_REQ,
378 				(uint32_t *) &payload, payload_size,
379 				CMD_CASUAL, resp_data, &resp_len);
380 
381 	if (status < 0) {
382 		*mbox_error = -status;
383 		return INTEL_SIP_SMC_STATUS_ERROR;
384 	}
385 
386 	if (resp_len != FCS_CRYPTION_RESP_WORD_SIZE) {
387 		*mbox_error = MBOX_RET_ERROR;
388 		return INTEL_SIP_SMC_STATUS_ERROR;
389 	}
390 
391 	*dst_size = resp_data[FCS_CRYPTION_RESP_SIZE_OFFSET];
392 	inv_dcache_range(dst_addr, *dst_size);
393 
394 	return INTEL_SIP_SMC_STATUS_OK;
395 }
396 
397 int intel_fcs_decryption_ext(uint32_t session_id, uint32_t context_id,
398 		uint32_t src_addr, uint32_t src_size,
399 		uint32_t dst_addr, uint32_t *dst_size, uint32_t *mbox_error)
400 {
401 	int status;
402 	uintptr_t id_offset;
403 	uint32_t payload_size;
404 	uint32_t resp_len = FCS_CRYPTION_RESP_WORD_SIZE;
405 	uint32_t resp_data[FCS_CRYPTION_RESP_WORD_SIZE] = {0U};
406 
407 	if ((dst_size == NULL) || (mbox_error == NULL)) {
408 		return INTEL_SIP_SMC_STATUS_REJECTED;
409 	}
410 
411 	if (!is_address_in_ddr_range(src_addr, src_size) ||
412 		!is_address_in_ddr_range(dst_addr, *dst_size)) {
413 		return INTEL_SIP_SMC_STATUS_REJECTED;
414 	}
415 
416 	if (!is_size_4_bytes_aligned(src_size)) {
417 		return INTEL_SIP_SMC_STATUS_REJECTED;
418 	}
419 
420 	id_offset = src_addr + FCS_OWNER_ID_OFFSET;
421 	fcs_decrypt_ext_payload payload = {
422 		session_id,
423 		context_id,
424 		FCS_CRYPTION_CRYPTO_HEADER,
425 		{mmio_read_32(id_offset),
426 		mmio_read_32(id_offset + MBOX_WORD_BYTE)},
427 		src_addr,
428 		src_size,
429 		dst_addr,
430 		*dst_size
431 	};
432 
433 	payload_size = sizeof(payload) / MBOX_WORD_BYTE;
434 
435 	status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_DECRYPT_REQ,
436 				(uint32_t *) &payload, payload_size,
437 				CMD_CASUAL, resp_data, &resp_len);
438 
439 	if (status < 0) {
440 		*mbox_error = -status;
441 		return INTEL_SIP_SMC_STATUS_ERROR;
442 	}
443 
444 	if (resp_len != FCS_CRYPTION_RESP_WORD_SIZE) {
445 		*mbox_error = MBOX_RET_ERROR;
446 		return INTEL_SIP_SMC_STATUS_ERROR;
447 	}
448 
449 	*dst_size = resp_data[FCS_CRYPTION_RESP_SIZE_OFFSET];
450 	inv_dcache_range(dst_addr, *dst_size);
451 
452 	return INTEL_SIP_SMC_STATUS_OK;
453 }
454 
455 int intel_fcs_sigma_teardown(uint32_t session_id, uint32_t *mbox_error)
456 {
457 	int status;
458 
459 	if ((session_id != PSGSIGMA_SESSION_ID_ONE) &&
460 		(session_id != PSGSIGMA_UNKNOWN_SESSION)) {
461 		return INTEL_SIP_SMC_STATUS_REJECTED;
462 	}
463 
464 	psgsigma_teardown_msg message = {
465 		RESERVED_AS_ZERO,
466 		PSGSIGMA_TEARDOWN_MAGIC,
467 		session_id
468 	};
469 
470 	status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_PSG_SIGMA_TEARDOWN,
471 			(uint32_t *) &message, sizeof(message) / MBOX_WORD_BYTE,
472 			CMD_CASUAL, NULL, NULL);
473 
474 	if (status < 0) {
475 		*mbox_error = -status;
476 		return INTEL_SIP_SMC_STATUS_ERROR;
477 	}
478 
479 	return INTEL_SIP_SMC_STATUS_OK;
480 }
481 
482 int intel_fcs_chip_id(uint32_t *id_low, uint32_t *id_high, uint32_t *mbox_error)
483 {
484 	int status;
485 	uint32_t load_size;
486 	uint32_t chip_id[2];
487 
488 	load_size = sizeof(chip_id) / MBOX_WORD_BYTE;
489 
490 	status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_CMD_GET_CHIPID, NULL,
491 			0U, CMD_CASUAL, (uint32_t *) chip_id, &load_size);
492 
493 	if (status < 0) {
494 		*mbox_error = -status;
495 		return INTEL_SIP_SMC_STATUS_ERROR;
496 	}
497 
498 	*id_low = chip_id[0];
499 	*id_high = chip_id[1];
500 
501 	return INTEL_SIP_SMC_STATUS_OK;
502 }
503 
504 int intel_fcs_attestation_subkey(uint64_t src_addr, uint32_t src_size,
505 		uint64_t dst_addr, uint32_t *dst_size, uint32_t *mbox_error)
506 {
507 	int status;
508 	uint32_t send_size = src_size / MBOX_WORD_BYTE;
509 	uint32_t ret_size = *dst_size / MBOX_WORD_BYTE;
510 
511 
512 	if (!is_address_in_ddr_range(src_addr, src_size) ||
513 		!is_address_in_ddr_range(dst_addr, *dst_size)) {
514 		return INTEL_SIP_SMC_STATUS_REJECTED;
515 	}
516 
517 	status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_ATTESTATION_SUBKEY,
518 			(uint32_t *) src_addr, send_size, CMD_CASUAL,
519 			(uint32_t *) dst_addr, &ret_size);
520 
521 	if (status < 0) {
522 		*mbox_error = -status;
523 		return INTEL_SIP_SMC_STATUS_ERROR;
524 	}
525 
526 	*dst_size = ret_size * MBOX_WORD_BYTE;
527 	flush_dcache_range(dst_addr, *dst_size);
528 
529 	return INTEL_SIP_SMC_STATUS_OK;
530 }
531 
532 int intel_fcs_get_measurement(uint64_t src_addr, uint32_t src_size,
533 		uint64_t dst_addr, uint32_t *dst_size, uint32_t *mbox_error)
534 {
535 	int status;
536 	uint32_t send_size = src_size / MBOX_WORD_BYTE;
537 	uint32_t ret_size = *dst_size / MBOX_WORD_BYTE;
538 
539 	if (!is_address_in_ddr_range(src_addr, src_size) ||
540 		!is_address_in_ddr_range(dst_addr, *dst_size)) {
541 		return INTEL_SIP_SMC_STATUS_REJECTED;
542 	}
543 
544 	status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_GET_MEASUREMENT,
545 			(uint32_t *) src_addr, send_size, CMD_CASUAL,
546 			(uint32_t *) dst_addr, &ret_size);
547 
548 	if (status < 0) {
549 		*mbox_error = -status;
550 		return INTEL_SIP_SMC_STATUS_ERROR;
551 	}
552 
553 	*dst_size = ret_size * MBOX_WORD_BYTE;
554 	flush_dcache_range(dst_addr, *dst_size);
555 
556 	return INTEL_SIP_SMC_STATUS_OK;
557 }
558 
559 int intel_fcs_get_attestation_cert(uint32_t cert_request, uint64_t dst_addr,
560 			uint32_t *dst_size, uint32_t *mbox_error)
561 {
562 	int status;
563 	uint32_t ret_size = *dst_size / MBOX_WORD_BYTE;
564 
565 	if (mbox_error == NULL) {
566 		return INTEL_SIP_SMC_STATUS_REJECTED;
567 	}
568 
569 	if (cert_request < FCS_ALIAS_CERT ||
570 		cert_request >
571 			(FCS_ALIAS_CERT |
572 			FCS_DEV_ID_SELF_SIGN_CERT |
573 			FCS_DEV_ID_ENROLL_CERT |
574 			FCS_ENROLL_SELF_SIGN_CERT |
575 			FCS_PLAT_KEY_CERT)) {
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_ALIAS_CERT ||
608 		cert_request >
609 			(FCS_ALIAS_CERT |
610 			FCS_DEV_ID_SELF_SIGN_CERT |
611 			FCS_DEV_ID_ENROLL_CERT |
612 			FCS_ENROLL_SELF_SIGN_CERT |
613 			FCS_PLAT_KEY_CERT)) {
614 		return INTEL_SIP_SMC_STATUS_REJECTED;
615 	}
616 
617 	status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_CREATE_CERT_ON_RELOAD,
618 			(uint32_t *) &cert_request, 1U, CMD_CASUAL,
619 			NULL, NULL);
620 
621 	if (status < 0) {
622 		*mbox_error = -status;
623 		return INTEL_SIP_SMC_STATUS_ERROR;
624 	}
625 
626 	return INTEL_SIP_SMC_STATUS_OK;
627 }
628 
629 int intel_fcs_open_crypto_service_session(uint32_t *session_id,
630 			uint32_t *mbox_error)
631 {
632 	int status;
633 	uint32_t resp_len = 1U;
634 
635 	if ((session_id == NULL) || (mbox_error == NULL)) {
636 		return INTEL_SIP_SMC_STATUS_REJECTED;
637 	}
638 
639 	status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_OPEN_CS_SESSION,
640 			NULL, 0U, CMD_CASUAL, session_id, &resp_len);
641 
642 	if (status < 0) {
643 		*mbox_error = -status;
644 		return INTEL_SIP_SMC_STATUS_ERROR;
645 	}
646 
647 	return INTEL_SIP_SMC_STATUS_OK;
648 }
649 
650 int intel_fcs_close_crypto_service_session(uint32_t session_id,
651 			uint32_t *mbox_error)
652 {
653 	int status;
654 
655 	if (mbox_error == NULL) {
656 		return INTEL_SIP_SMC_STATUS_REJECTED;
657 	}
658 
659 	status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_CLOSE_CS_SESSION,
660 			&session_id, 1U, CMD_CASUAL, NULL, NULL);
661 
662 	if (status < 0) {
663 		*mbox_error = -status;
664 		return INTEL_SIP_SMC_STATUS_ERROR;
665 	}
666 
667 	return INTEL_SIP_SMC_STATUS_OK;
668 }
669 
670 int intel_fcs_import_crypto_service_key(uint64_t src_addr, uint32_t src_size,
671 		uint32_t *send_id)
672 {
673 	int status;
674 
675 	if (src_size > (FCS_CS_KEY_OBJ_MAX_WORD_SIZE *
676 		MBOX_WORD_BYTE)) {
677 		return INTEL_SIP_SMC_STATUS_REJECTED;
678 	}
679 
680 	if (!is_address_in_ddr_range(src_addr, src_size)) {
681 		return INTEL_SIP_SMC_STATUS_REJECTED;
682 	}
683 
684 	status = mailbox_send_cmd_async(send_id, MBOX_FCS_IMPORT_CS_KEY,
685 				(uint32_t *)src_addr, src_size / MBOX_WORD_BYTE,
686 				CMD_INDIRECT);
687 
688 	if (status < 0) {
689 		return INTEL_SIP_SMC_STATUS_ERROR;
690 	}
691 
692 	return INTEL_SIP_SMC_STATUS_OK;
693 }
694 
695 int intel_fcs_export_crypto_service_key(uint32_t session_id, uint32_t key_id,
696 		uint64_t dst_addr, uint32_t *dst_size,
697 		uint32_t *mbox_error)
698 {
699 	int status;
700 	uint32_t i;
701 	uint32_t payload_size;
702 	uint32_t resp_len = FCS_CS_KEY_OBJ_MAX_WORD_SIZE;
703 	uint32_t resp_data[FCS_CS_KEY_OBJ_MAX_WORD_SIZE] = {0U};
704 	uint32_t op_status = 0U;
705 
706 	if ((dst_size == NULL) || (mbox_error == NULL)) {
707 		return INTEL_SIP_SMC_STATUS_REJECTED;
708 	}
709 
710 	if (!is_address_in_ddr_range(dst_addr, *dst_size)) {
711 		return INTEL_SIP_SMC_STATUS_REJECTED;
712 	}
713 
714 	fcs_cs_key_payload payload = {
715 		session_id,
716 		RESERVED_AS_ZERO,
717 		RESERVED_AS_ZERO,
718 		key_id
719 	};
720 
721 	payload_size = sizeof(payload) / MBOX_WORD_BYTE;
722 
723 	status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_EXPORT_CS_KEY,
724 			(uint32_t *) &payload, payload_size,
725 			CMD_CASUAL, resp_data, &resp_len);
726 
727 	if (resp_len > 0) {
728 		op_status = resp_data[0] & FCS_CS_KEY_RESP_STATUS_MASK;
729 	}
730 
731 	if (status < 0) {
732 		*mbox_error = (-status) | (op_status << FCS_CS_KEY_RESP_STATUS_OFFSET);
733 		return INTEL_SIP_SMC_STATUS_ERROR;
734 	}
735 
736 	if (resp_len > 1) {
737 
738 		/* Export key object is start at second response data */
739 		*dst_size = (resp_len - 1) * MBOX_WORD_BYTE;
740 
741 		for (i = 1U; i < resp_len; i++) {
742 			mmio_write_32(dst_addr, resp_data[i]);
743 			dst_addr += MBOX_WORD_BYTE;
744 		}
745 
746 		flush_dcache_range(dst_addr - *dst_size, *dst_size);
747 
748 	} else {
749 
750 		/* Unexpected response, missing key object in response */
751 		*mbox_error = MBOX_RET_ERROR;
752 		return INTEL_SIP_SMC_STATUS_ERROR;
753 	}
754 
755 	return INTEL_SIP_SMC_STATUS_OK;
756 }
757 
758 int intel_fcs_remove_crypto_service_key(uint32_t session_id, uint32_t key_id,
759 		uint32_t *mbox_error)
760 {
761 	int status;
762 	uint32_t payload_size;
763 	uint32_t resp_len = 1U;
764 	uint32_t resp_data = 0U;
765 	uint32_t op_status = 0U;
766 
767 	if (mbox_error == NULL) {
768 		return INTEL_SIP_SMC_STATUS_REJECTED;
769 	}
770 
771 	fcs_cs_key_payload payload = {
772 		session_id,
773 		RESERVED_AS_ZERO,
774 		RESERVED_AS_ZERO,
775 		key_id
776 	};
777 
778 	payload_size = sizeof(payload) / MBOX_WORD_BYTE;
779 
780 	status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_REMOVE_CS_KEY,
781 			(uint32_t *) &payload, payload_size,
782 			CMD_CASUAL, &resp_data, &resp_len);
783 
784 	if (resp_len > 0) {
785 		op_status = resp_data & FCS_CS_KEY_RESP_STATUS_MASK;
786 	}
787 
788 	if (status < 0) {
789 		*mbox_error = (-status) | (op_status << FCS_CS_KEY_RESP_STATUS_OFFSET);
790 		return INTEL_SIP_SMC_STATUS_ERROR;
791 	}
792 
793 	return INTEL_SIP_SMC_STATUS_OK;
794 }
795 
796 int intel_fcs_get_crypto_service_key_info(uint32_t session_id, uint32_t key_id,
797 		uint64_t dst_addr, uint32_t *dst_size,
798 		uint32_t *mbox_error)
799 {
800 	int status;
801 	uint32_t payload_size;
802 	uint32_t resp_len = FCS_CS_KEY_INFO_MAX_WORD_SIZE;
803 	uint32_t op_status = 0U;
804 
805 	if ((dst_size == NULL) || (mbox_error == NULL)) {
806 		return INTEL_SIP_SMC_STATUS_REJECTED;
807 	}
808 
809 	if (!is_address_in_ddr_range(dst_addr, *dst_size)) {
810 		return INTEL_SIP_SMC_STATUS_REJECTED;
811 	}
812 
813 	fcs_cs_key_payload payload = {
814 		session_id,
815 		RESERVED_AS_ZERO,
816 		RESERVED_AS_ZERO,
817 		key_id
818 	};
819 
820 	payload_size = sizeof(payload) / MBOX_WORD_BYTE;
821 
822 	status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_GET_CS_KEY_INFO,
823 				(uint32_t *) &payload, payload_size,
824 				CMD_CASUAL, (uint32_t *) dst_addr, &resp_len);
825 
826 	if (resp_len > 0) {
827 		op_status = mmio_read_32(dst_addr) &
828 			FCS_CS_KEY_RESP_STATUS_MASK;
829 	}
830 
831 	if (status < 0) {
832 		*mbox_error = (-status) | (op_status << FCS_CS_KEY_RESP_STATUS_OFFSET);
833 		return INTEL_SIP_SMC_STATUS_ERROR;
834 	}
835 
836 	*dst_size = resp_len * MBOX_WORD_BYTE;
837 	flush_dcache_range(dst_addr, *dst_size);
838 
839 	return INTEL_SIP_SMC_STATUS_OK;
840 }
841 
842 int intel_fcs_get_digest_init(uint32_t session_id, uint32_t context_id,
843 				uint32_t key_id, uint32_t param_size,
844 				uint64_t param_data, uint32_t *mbox_error)
845 {
846 	return intel_fcs_crypto_service_init(session_id, context_id,
847 				key_id, param_size, param_data,
848 				(void *) &fcs_sha_get_digest_param,
849 				mbox_error);
850 }
851 
852 int intel_fcs_get_digest_finalize(uint32_t session_id, uint32_t context_id,
853 				uint32_t src_addr, uint32_t src_size,
854 				uint64_t dst_addr, uint32_t *dst_size,
855 				uint32_t *mbox_error)
856 {
857 	int status;
858 	uint32_t i;
859 	uint32_t resp_len = *dst_size / MBOX_WORD_BYTE;
860 	uint32_t payload[FCS_GET_DIGEST_CMD_MAX_WORD_SIZE] = {0U};
861 
862 	if (dst_size == NULL || mbox_error == NULL) {
863 		return INTEL_SIP_SMC_STATUS_REJECTED;
864 	}
865 
866 	if (fcs_sha_get_digest_param.session_id != session_id ||
867 	    fcs_sha_get_digest_param.context_id != context_id) {
868 		return INTEL_SIP_SMC_STATUS_REJECTED;
869 	}
870 
871 	/* Source data must be 8 bytes aligned */
872 	if (!is_8_bytes_aligned(src_size)) {
873 		return INTEL_SIP_SMC_STATUS_REJECTED;
874 	}
875 
876 	if (!is_address_in_ddr_range(src_addr, src_size) ||
877 		 !is_address_in_ddr_range(dst_addr, *dst_size)) {
878 		return INTEL_SIP_SMC_STATUS_REJECTED;
879 	}
880 
881 	/* Prepare command payload */
882 	i = 0;
883 	/* Crypto header */
884 	payload[i] = fcs_sha_get_digest_param.session_id;
885 	i++;
886 	payload[i] = fcs_sha_get_digest_param.context_id;
887 	i++;
888 	payload[i] = fcs_sha_get_digest_param.crypto_param_size
889 			& FCS_CS_FIELD_SIZE_MASK;
890 	payload[i] |= (FCS_CS_FIELD_FLAG_INIT | FCS_CS_FIELD_FLAG_UPDATE
891 			| FCS_CS_FIELD_FLAG_FINALIZE)
892 			<< FCS_CS_FIELD_FLAG_OFFSET;
893 	i++;
894 	payload[i] = fcs_sha_get_digest_param.key_id;
895 	i++;
896 	/* Crypto parameters */
897 	payload[i] = fcs_sha_get_digest_param.crypto_param
898 			& INTEL_SIP_SMC_FCS_SHA_MODE_MASK;
899 	payload[i] |= ((fcs_sha_get_digest_param.crypto_param
900 			>> INTEL_SIP_SMC_FCS_DIGEST_SIZE_OFFSET)
901 			& INTEL_SIP_SMC_FCS_DIGEST_SIZE_MASK)
902 			<< FCS_SHA_HMAC_CRYPTO_PARAM_SIZE_OFFSET;
903 	i++;
904 	/* Data source address and size */
905 	payload[i] = src_addr;
906 	i++;
907 	payload[i] = src_size;
908 	i++;
909 
910 	status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_GET_DIGEST_REQ,
911 				payload, i, CMD_CASUAL,
912 				(uint32_t *) dst_addr, &resp_len);
913 
914 	memset((void *)&fcs_sha_get_digest_param, 0, sizeof(fcs_crypto_service_data));
915 
916 	if (status < 0) {
917 		*mbox_error = -status;
918 		return INTEL_SIP_SMC_STATUS_ERROR;
919 	}
920 
921 	*dst_size = resp_len * MBOX_WORD_BYTE;
922 	flush_dcache_range(dst_addr, *dst_size);
923 
924 	return INTEL_SIP_SMC_STATUS_OK;
925 }
926 
927 int intel_fcs_mac_verify_init(uint32_t session_id, uint32_t context_id,
928 				uint32_t key_id, uint32_t param_size,
929 				uint64_t param_data, uint32_t *mbox_error)
930 {
931 	return intel_fcs_crypto_service_init(session_id, context_id,
932 				key_id, param_size, param_data,
933 				(void *) &fcs_sha_mac_verify_param,
934 				mbox_error);
935 }
936 
937 int intel_fcs_mac_verify_finalize(uint32_t session_id, uint32_t context_id,
938 				uint32_t src_addr, uint32_t src_size,
939 				uint64_t dst_addr, uint32_t *dst_size,
940 				uint32_t data_size, uint32_t *mbox_error)
941 {
942 	int status;
943 	uint32_t i;
944 	uint32_t resp_len = *dst_size / MBOX_WORD_BYTE;
945 	uint32_t payload[FCS_MAC_VERIFY_CMD_MAX_WORD_SIZE] = {0U};
946 	uintptr_t mac_offset;
947 
948 	if (dst_size == NULL || mbox_error == NULL) {
949 		return INTEL_SIP_SMC_STATUS_REJECTED;
950 	}
951 
952 	if (fcs_sha_mac_verify_param.session_id != session_id ||
953 		fcs_sha_mac_verify_param.context_id != context_id) {
954 		return INTEL_SIP_SMC_STATUS_REJECTED;
955 	}
956 
957 	if (data_size >= src_size) {
958 		return INTEL_SIP_SMC_STATUS_REJECTED;
959 	}
960 
961 	if (!is_size_4_bytes_aligned(src_size) ||
962 		!is_8_bytes_aligned(data_size)) {
963 		return INTEL_SIP_SMC_STATUS_REJECTED;
964 	}
965 
966 	if (!is_address_in_ddr_range(src_addr, src_size) ||
967 		!is_address_in_ddr_range(dst_addr, *dst_size)) {
968 		return INTEL_SIP_SMC_STATUS_REJECTED;
969 	}
970 
971 	/* Prepare command payload */
972 	i = 0;
973 	/* Crypto header */
974 	payload[i] = fcs_sha_mac_verify_param.session_id;
975 	i++;
976 	payload[i] = fcs_sha_mac_verify_param.context_id;
977 	i++;
978 	payload[i] = fcs_sha_mac_verify_param.crypto_param_size
979 			& FCS_CS_FIELD_SIZE_MASK;
980 	payload[i] |= (FCS_CS_FIELD_FLAG_INIT | FCS_CS_FIELD_FLAG_UPDATE
981 			| FCS_CS_FIELD_FLAG_FINALIZE)
982 			<< FCS_CS_FIELD_FLAG_OFFSET;
983 	i++;
984 	payload[i] = fcs_sha_mac_verify_param.key_id;
985 	i++;
986 	/* Crypto parameters */
987 	payload[i] = ((fcs_sha_mac_verify_param.crypto_param
988 			>> INTEL_SIP_SMC_FCS_DIGEST_SIZE_OFFSET)
989 			& INTEL_SIP_SMC_FCS_DIGEST_SIZE_MASK)
990 			<< FCS_SHA_HMAC_CRYPTO_PARAM_SIZE_OFFSET;
991 	i++;
992 	/* Data source address and size */
993 	payload[i] = src_addr;
994 	i++;
995 	payload[i] = data_size;
996 	i++;
997 	/* Copy mac data to command */
998 	mac_offset = src_addr + data_size;
999 	memcpy((uint8_t *) &payload[i], (uint8_t *) mac_offset,
1000 				src_size - data_size);
1001 
1002 	i += (src_size - data_size) / MBOX_WORD_BYTE;
1003 
1004 	status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_MAC_VERIFY_REQ,
1005 				payload, i, CMD_CASUAL,
1006 				(uint32_t *) dst_addr, &resp_len);
1007 
1008 	memset((void *)&fcs_sha_mac_verify_param, 0,
1009 				sizeof(fcs_crypto_service_data));
1010 
1011 	if (status < 0) {
1012 		*mbox_error = -status;
1013 		return INTEL_SIP_SMC_STATUS_ERROR;
1014 	}
1015 
1016 	*dst_size = resp_len * MBOX_WORD_BYTE;
1017 	flush_dcache_range(dst_addr, *dst_size);
1018 
1019 	return INTEL_SIP_SMC_STATUS_OK;
1020 }
1021 
1022 int intel_fcs_ecdsa_sha2_data_sign_init(uint32_t session_id,
1023 				uint32_t context_id, uint32_t key_id,
1024 				uint32_t param_size, uint64_t param_data,
1025 				uint32_t *mbox_error)
1026 {
1027 	return intel_fcs_crypto_service_init(session_id, context_id,
1028 				key_id, param_size, param_data,
1029 				(void *) &fcs_sha2_data_sign_param,
1030 				mbox_error);
1031 }
1032 
1033 int intel_fcs_ecdsa_sha2_data_sign_finalize(uint32_t session_id,
1034 				uint32_t context_id, uint32_t src_addr,
1035 				uint32_t src_size, uint64_t dst_addr,
1036 				uint32_t *dst_size, uint32_t *mbox_error)
1037 {
1038 	int status;
1039 	int i;
1040 	uint32_t payload[FCS_ECDSA_SHA2_DATA_SIGN_CMD_MAX_WORD_SIZE] = {0U};
1041 	uint32_t resp_len = *dst_size / MBOX_WORD_BYTE;
1042 
1043 	if ((dst_size == NULL) || (mbox_error == NULL)) {
1044 		return INTEL_SIP_SMC_STATUS_REJECTED;
1045 	}
1046 
1047 	if (fcs_sha2_data_sign_param.session_id != session_id ||
1048 		fcs_sha2_data_sign_param.context_id != context_id) {
1049 		return INTEL_SIP_SMC_STATUS_REJECTED;
1050 	}
1051 
1052 	/* Source data must be 8 bytes aligned */
1053 	if (!is_8_bytes_aligned(src_size)) {
1054 		return INTEL_SIP_SMC_STATUS_REJECTED;
1055 	}
1056 
1057 	if (!is_address_in_ddr_range(src_addr, src_size) ||
1058 		!is_address_in_ddr_range(dst_addr, *dst_size)) {
1059 		return INTEL_SIP_SMC_STATUS_REJECTED;
1060 	}
1061 
1062 	/* Prepare command payload */
1063 	/* Crypto header */
1064 	i = 0;
1065 	payload[i] = fcs_sha2_data_sign_param.session_id;
1066 	i++;
1067 	payload[i] = fcs_sha2_data_sign_param.context_id;
1068 	i++;
1069 	payload[i] = fcs_sha2_data_sign_param.crypto_param_size
1070 			& FCS_CS_FIELD_SIZE_MASK;
1071 	payload[i] |= (FCS_CS_FIELD_FLAG_INIT | FCS_CS_FIELD_FLAG_UPDATE
1072 			| FCS_CS_FIELD_FLAG_FINALIZE)
1073 			<< FCS_CS_FIELD_FLAG_OFFSET;
1074 	i++;
1075 	payload[i] = fcs_sha2_data_sign_param.key_id;
1076 	/* Crypto parameters */
1077 	i++;
1078 	payload[i] = fcs_sha2_data_sign_param.crypto_param
1079 			& INTEL_SIP_SMC_FCS_ECC_ALGO_MASK;
1080 	/* Data source address and size */
1081 	i++;
1082 	payload[i] = src_addr;
1083 	i++;
1084 	payload[i] = src_size;
1085 	i++;
1086 	status = mailbox_send_cmd(MBOX_JOB_ID,
1087 			MBOX_FCS_ECDSA_SHA2_DATA_SIGN_REQ, payload,
1088 			i, CMD_CASUAL, (uint32_t *) dst_addr,
1089 			&resp_len);
1090 
1091 	memset((void *)&fcs_sha2_data_sign_param, 0,
1092 			sizeof(fcs_crypto_service_data));
1093 
1094 	if (status < 0) {
1095 		*mbox_error = -status;
1096 		return INTEL_SIP_SMC_STATUS_ERROR;
1097 	}
1098 
1099 	*dst_size = resp_len * MBOX_WORD_BYTE;
1100 	flush_dcache_range(dst_addr, *dst_size);
1101 
1102 	return INTEL_SIP_SMC_STATUS_OK;
1103 }
1104 
1105 int intel_fcs_ecdsa_sha2_data_sig_verify_init(uint32_t session_id,
1106 				uint32_t context_id, uint32_t key_id,
1107 				uint32_t param_size, uint64_t param_data,
1108 				uint32_t *mbox_error)
1109 {
1110 	return intel_fcs_crypto_service_init(session_id, context_id,
1111 				key_id, param_size, param_data,
1112 				(void *) &fcs_sha2_data_sig_verify_param,
1113 				mbox_error);
1114 }
1115 
1116 int intel_fcs_ecdsa_sha2_data_sig_verify_finalize(uint32_t session_id,
1117 				uint32_t context_id, uint32_t src_addr,
1118 				uint32_t src_size, uint64_t dst_addr,
1119 				uint32_t *dst_size, uint32_t data_size,
1120 				uint32_t *mbox_error)
1121 {
1122 	int status;
1123 	uint32_t i;
1124 	uint32_t payload[FCS_ECDSA_SHA2_DATA_SIG_VERIFY_CMD_MAX_WORD_SIZE] = {0U};
1125 	uint32_t resp_len = *dst_size / MBOX_WORD_BYTE;
1126 	uintptr_t sig_pubkey_offset;
1127 
1128 	if ((dst_size == NULL) || (mbox_error == NULL)) {
1129 		return INTEL_SIP_SMC_STATUS_REJECTED;
1130 	}
1131 
1132 	if (fcs_sha2_data_sig_verify_param.session_id != session_id ||
1133 		fcs_sha2_data_sig_verify_param.context_id != context_id) {
1134 		return INTEL_SIP_SMC_STATUS_REJECTED;
1135 	}
1136 
1137 	if (!is_size_4_bytes_aligned(src_size)) {
1138 		return INTEL_SIP_SMC_STATUS_REJECTED;
1139 	}
1140 
1141 	if (!is_8_bytes_aligned(data_size) ||
1142 		!is_8_bytes_aligned(src_addr)) {
1143 		return INTEL_SIP_SMC_STATUS_REJECTED;
1144 	}
1145 
1146 	if (!is_address_in_ddr_range(src_addr, src_size) ||
1147 		!is_address_in_ddr_range(dst_addr, *dst_size)) {
1148 		return INTEL_SIP_SMC_STATUS_REJECTED;
1149 	}
1150 
1151 	/* Prepare command payload */
1152 	/* Crypto header */
1153 	i = 0;
1154 	payload[i] = fcs_sha2_data_sig_verify_param.session_id;
1155 	i++;
1156 	payload[i] = fcs_sha2_data_sig_verify_param.context_id;
1157 	i++;
1158 
1159 	payload[i] = fcs_sha2_data_sig_verify_param.crypto_param_size
1160 			& FCS_CS_FIELD_SIZE_MASK;
1161 	payload[i] |= (FCS_CS_FIELD_FLAG_INIT | FCS_CS_FIELD_FLAG_UPDATE
1162 			| FCS_CS_FIELD_FLAG_FINALIZE)
1163 			<< FCS_CS_FIELD_FLAG_OFFSET;
1164 	i++;
1165 	payload[i] = fcs_sha2_data_sig_verify_param.key_id;
1166 	i++;
1167 	/* Crypto parameters */
1168 	payload[i] = fcs_sha2_data_sig_verify_param.crypto_param
1169 			& INTEL_SIP_SMC_FCS_ECC_ALGO_MASK;
1170 	i++;
1171 	/* Data source address and size */
1172 	payload[i] = src_addr;
1173 	i++;
1174 	payload[i] = data_size;
1175 	i++;
1176 	/* Signature + Public Key Data */
1177 	sig_pubkey_offset = src_addr + data_size;
1178 	memcpy((uint8_t *) &payload[i], (uint8_t *) sig_pubkey_offset,
1179 		src_size - data_size);
1180 
1181 	i += (src_size - data_size) / MBOX_WORD_BYTE;
1182 
1183 	status = mailbox_send_cmd(MBOX_JOB_ID,
1184 			MBOX_FCS_ECDSA_SHA2_DATA_SIGN_VERIFY, payload, i,
1185 			CMD_CASUAL, (uint32_t *) dst_addr, &resp_len);
1186 
1187 	memset((void *) &fcs_sha2_data_sig_verify_param, 0,
1188 			sizeof(fcs_crypto_service_data));
1189 
1190 	if (status < 0) {
1191 		*mbox_error = -status;
1192 		return INTEL_SIP_SMC_STATUS_ERROR;
1193 	}
1194 
1195 	*dst_size = resp_len * MBOX_WORD_BYTE;
1196 	flush_dcache_range(dst_addr, *dst_size);
1197 
1198 	return INTEL_SIP_SMC_STATUS_OK;
1199 }
1200 
1201 int intel_fcs_ecdsa_get_pubkey_init(uint32_t session_id, uint32_t context_id,
1202 				uint32_t key_id, uint32_t param_size,
1203 				uint64_t param_data, uint32_t *mbox_error)
1204 {
1205 	return intel_fcs_crypto_service_init(session_id, context_id,
1206 				key_id, param_size, param_data,
1207 				(void *) &fcs_ecdsa_get_pubkey_param,
1208 				mbox_error);
1209 }
1210 
1211 int intel_fcs_ecdsa_get_pubkey_finalize(uint32_t session_id, uint32_t context_id,
1212 				uint64_t dst_addr, uint32_t *dst_size,
1213 				uint32_t *mbox_error)
1214 {
1215 	int status;
1216 	int i;
1217 	uint32_t crypto_header;
1218 	uint32_t ret_size = *dst_size / MBOX_WORD_BYTE;
1219 	uint32_t payload[FCS_ECDSA_GET_PUBKEY_MAX_WORD_SIZE] = {0U};
1220 
1221 	if ((dst_size == NULL) || (mbox_error == NULL)) {
1222 		return INTEL_SIP_SMC_STATUS_REJECTED;
1223 	}
1224 
1225 	if (fcs_ecdsa_get_pubkey_param.session_id != session_id ||
1226 		fcs_ecdsa_get_pubkey_param.context_id != context_id) {
1227 		return INTEL_SIP_SMC_STATUS_REJECTED;
1228 	}
1229 
1230 	crypto_header = ((FCS_CS_FIELD_FLAG_INIT |
1231 			FCS_CS_FIELD_FLAG_UPDATE |
1232 			FCS_CS_FIELD_FLAG_FINALIZE) <<
1233 			FCS_CS_FIELD_FLAG_OFFSET) |
1234 			fcs_ecdsa_get_pubkey_param.crypto_param_size;
1235 	i = 0;
1236 	/* Prepare command payload */
1237 	payload[i] = session_id;
1238 	i++;
1239 	payload[i] = context_id;
1240 	i++;
1241 	payload[i] = crypto_header;
1242 	i++;
1243 	payload[i] = fcs_ecdsa_get_pubkey_param.key_id;
1244 	i++;
1245 	payload[i] = (uint32_t) fcs_ecdsa_get_pubkey_param.crypto_param &
1246 			INTEL_SIP_SMC_FCS_ECC_ALGO_MASK;
1247 	i++;
1248 
1249 	status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_ECDSA_GET_PUBKEY,
1250 			payload, i, CMD_CASUAL,
1251 			(uint32_t *) dst_addr, &ret_size);
1252 
1253 	memset((void *) &fcs_ecdsa_get_pubkey_param, 0,
1254 		sizeof(fcs_crypto_service_data));
1255 
1256 	if (status < 0) {
1257 		*mbox_error = -status;
1258 		return INTEL_SIP_SMC_STATUS_ERROR;
1259 	}
1260 
1261 	*dst_size = ret_size * MBOX_WORD_BYTE;
1262 	flush_dcache_range(dst_addr, *dst_size);
1263 
1264 	return INTEL_SIP_SMC_STATUS_OK;
1265 }
1266 
1267 int intel_fcs_aes_crypt_init(uint32_t session_id, uint32_t context_id,
1268 				uint32_t key_id, uint64_t param_addr,
1269 				uint32_t param_size, uint32_t *mbox_error)
1270 {
1271 	if (mbox_error == NULL) {
1272 		return INTEL_SIP_SMC_STATUS_REJECTED;
1273 	}
1274 
1275 	memset((void *)&fcs_aes_init_payload, 0U, sizeof(fcs_aes_init_payload));
1276 
1277 	fcs_aes_init_payload.session_id = session_id;
1278 	fcs_aes_init_payload.context_id = context_id;
1279 	fcs_aes_init_payload.param_size = param_size;
1280 	fcs_aes_init_payload.key_id	= key_id;
1281 
1282 	memcpy((uint8_t *) fcs_aes_init_payload.crypto_param,
1283 		(uint8_t *) param_addr, param_size);
1284 
1285 	*mbox_error = 0;
1286 
1287 	return INTEL_SIP_SMC_STATUS_OK;
1288 }
1289 
1290 int intel_fcs_aes_crypt_finalize(uint32_t session_id, uint32_t context_id,
1291 				uint64_t src_addr, uint32_t src_size,
1292 				uint64_t dst_addr, uint32_t dst_size,
1293 				uint32_t *send_id)
1294 {
1295 	int status;
1296 	int i;
1297 	uint32_t crypto_header;
1298 	uint32_t fcs_aes_crypt_payload[FCS_AES_CMD_MAX_WORD_SIZE];
1299 
1300 	if (fcs_aes_init_payload.session_id != session_id ||
1301 		fcs_aes_init_payload.context_id != context_id) {
1302 		return INTEL_SIP_SMC_STATUS_REJECTED;
1303 	}
1304 
1305 	if ((!is_8_bytes_aligned(src_addr)) ||
1306 		(!is_32_bytes_aligned(src_size)) ||
1307 		(!is_address_in_ddr_range(src_addr, src_size))) {
1308 		return INTEL_SIP_SMC_STATUS_REJECTED;
1309 	}
1310 
1311 	if ((!is_8_bytes_aligned(dst_addr)) ||
1312 		(!is_32_bytes_aligned(dst_size))) {
1313 		return INTEL_SIP_SMC_STATUS_REJECTED;
1314 	}
1315 
1316 	if ((dst_size > FCS_AES_MAX_DATA_SIZE ||
1317 		dst_size < FCS_AES_MIN_DATA_SIZE) ||
1318 		(src_size > FCS_AES_MAX_DATA_SIZE ||
1319 		src_size < FCS_AES_MIN_DATA_SIZE)) {
1320 		return INTEL_SIP_SMC_STATUS_REJECTED;
1321 	}
1322 
1323 	crypto_header = ((FCS_CS_FIELD_FLAG_INIT |
1324 			FCS_CS_FIELD_FLAG_UPDATE |
1325 			FCS_CS_FIELD_FLAG_FINALIZE) <<
1326 			FCS_CS_FIELD_FLAG_OFFSET) |
1327 			fcs_aes_init_payload.param_size;
1328 	i = 0U;
1329 	fcs_aes_crypt_payload[i] = session_id;
1330 	i++;
1331 	fcs_aes_crypt_payload[i] = context_id;
1332 	i++;
1333 	fcs_aes_crypt_payload[i] = crypto_header;
1334 	i++;
1335 	fcs_aes_crypt_payload[i] = fcs_aes_init_payload.key_id;
1336 
1337 	i++;
1338 	memcpy((uint8_t *) &fcs_aes_crypt_payload[i],
1339 		(uint8_t *) fcs_aes_init_payload.crypto_param,
1340 		fcs_aes_init_payload.param_size);
1341 
1342 	i += fcs_aes_init_payload.param_size / MBOX_WORD_BYTE;
1343 
1344 	fcs_aes_crypt_payload[i] = (uint32_t) src_addr;
1345 	i++;
1346 	fcs_aes_crypt_payload[i] = src_size;
1347 	i++;
1348 	fcs_aes_crypt_payload[i] = (uint32_t) dst_addr;
1349 	i++;
1350 	fcs_aes_crypt_payload[i] = dst_size;
1351 	i++;
1352 
1353 	status = mailbox_send_cmd_async(send_id, MBOX_FCS_AES_CRYPT_REQ,
1354 					fcs_aes_crypt_payload, i,
1355 					CMD_INDIRECT);
1356 
1357 	memset((void *)&fcs_aes_init_payload, 0U, sizeof(fcs_aes_init_payload));
1358 
1359 	if (status < 0U) {
1360 		return INTEL_SIP_SMC_STATUS_ERROR;
1361 	}
1362 
1363 	return INTEL_SIP_SMC_STATUS_OK;
1364 }
1365