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