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