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