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