xref: /rk3399_ARM-atf/plat/intel/soc/common/sip/socfpga_sip_fcs.c (revision 7e25eb87016ba8355cf0a3a5f71fb8b8785de044)
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_ALIAS_CERT ||
573 		cert_request >
574 			(FCS_ALIAS_CERT |
575 			FCS_DEV_ID_SELF_SIGN_CERT |
576 			FCS_DEV_ID_ENROLL_CERT |
577 			FCS_ENROLL_SELF_SIGN_CERT |
578 			FCS_PLAT_KEY_CERT)) {
579 		return INTEL_SIP_SMC_STATUS_REJECTED;
580 	}
581 
582 	if (!is_address_in_ddr_range(dst_addr, *dst_size)) {
583 		return INTEL_SIP_SMC_STATUS_REJECTED;
584 	}
585 
586 	status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_GET_ATTESTATION_CERT,
587 			(uint32_t *) &cert_request, 1U, CMD_CASUAL,
588 			(uint32_t *) dst_addr, &ret_size);
589 
590 	if (status < 0) {
591 		*mbox_error = -status;
592 		return INTEL_SIP_SMC_STATUS_ERROR;
593 	}
594 
595 	*dst_size = ret_size * MBOX_WORD_BYTE;
596 	flush_dcache_range(dst_addr, *dst_size);
597 
598 	return INTEL_SIP_SMC_STATUS_OK;
599 }
600 
601 int intel_fcs_create_cert_on_reload(uint32_t cert_request,
602 			uint32_t *mbox_error)
603 {
604 	int status;
605 
606 	if (mbox_error == NULL) {
607 		return INTEL_SIP_SMC_STATUS_REJECTED;
608 	}
609 
610 	if (cert_request < FCS_ALIAS_CERT ||
611 		cert_request >
612 			(FCS_ALIAS_CERT |
613 			FCS_DEV_ID_SELF_SIGN_CERT |
614 			FCS_DEV_ID_ENROLL_CERT |
615 			FCS_ENROLL_SELF_SIGN_CERT |
616 			FCS_PLAT_KEY_CERT)) {
617 		return INTEL_SIP_SMC_STATUS_REJECTED;
618 	}
619 
620 	status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_CREATE_CERT_ON_RELOAD,
621 			(uint32_t *) &cert_request, 1U, CMD_CASUAL,
622 			NULL, NULL);
623 
624 	if (status < 0) {
625 		*mbox_error = -status;
626 		return INTEL_SIP_SMC_STATUS_ERROR;
627 	}
628 
629 	return INTEL_SIP_SMC_STATUS_OK;
630 }
631 
632 int intel_fcs_open_crypto_service_session(uint32_t *session_id,
633 			uint32_t *mbox_error)
634 {
635 	int status;
636 	uint32_t resp_len = 1U;
637 
638 	if ((session_id == NULL) || (mbox_error == NULL)) {
639 		return INTEL_SIP_SMC_STATUS_REJECTED;
640 	}
641 
642 	status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_OPEN_CS_SESSION,
643 			NULL, 0U, CMD_CASUAL, session_id, &resp_len);
644 
645 	if (status < 0) {
646 		*mbox_error = -status;
647 		return INTEL_SIP_SMC_STATUS_ERROR;
648 	}
649 
650 	return INTEL_SIP_SMC_STATUS_OK;
651 }
652 
653 int intel_fcs_close_crypto_service_session(uint32_t session_id,
654 			uint32_t *mbox_error)
655 {
656 	int status;
657 
658 	if (mbox_error == NULL) {
659 		return INTEL_SIP_SMC_STATUS_REJECTED;
660 	}
661 
662 	status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_CLOSE_CS_SESSION,
663 			&session_id, 1U, CMD_CASUAL, NULL, NULL);
664 
665 	if (status < 0) {
666 		*mbox_error = -status;
667 		return INTEL_SIP_SMC_STATUS_ERROR;
668 	}
669 
670 	return INTEL_SIP_SMC_STATUS_OK;
671 }
672 
673 int intel_fcs_import_crypto_service_key(uint64_t src_addr, uint32_t src_size,
674 		uint32_t *send_id)
675 {
676 	int status;
677 
678 	if (src_size > (FCS_CS_KEY_OBJ_MAX_WORD_SIZE *
679 		MBOX_WORD_BYTE)) {
680 		return INTEL_SIP_SMC_STATUS_REJECTED;
681 	}
682 
683 	if (!is_address_in_ddr_range(src_addr, src_size)) {
684 		return INTEL_SIP_SMC_STATUS_REJECTED;
685 	}
686 
687 	status = mailbox_send_cmd_async(send_id, MBOX_FCS_IMPORT_CS_KEY,
688 				(uint32_t *)src_addr, src_size / MBOX_WORD_BYTE,
689 				CMD_INDIRECT);
690 
691 	if (status < 0) {
692 		return INTEL_SIP_SMC_STATUS_ERROR;
693 	}
694 
695 	return INTEL_SIP_SMC_STATUS_OK;
696 }
697 
698 int intel_fcs_export_crypto_service_key(uint32_t session_id, uint32_t key_id,
699 		uint64_t dst_addr, uint32_t *dst_size,
700 		uint32_t *mbox_error)
701 {
702 	int status;
703 	uint32_t i;
704 	uint32_t payload_size;
705 	uint32_t resp_len = FCS_CS_KEY_OBJ_MAX_WORD_SIZE;
706 	uint32_t resp_data[FCS_CS_KEY_OBJ_MAX_WORD_SIZE] = {0U};
707 	uint32_t op_status = 0U;
708 
709 	if ((dst_size == NULL) || (mbox_error == NULL)) {
710 		return INTEL_SIP_SMC_STATUS_REJECTED;
711 	}
712 
713 	if (!is_address_in_ddr_range(dst_addr, *dst_size)) {
714 		return INTEL_SIP_SMC_STATUS_REJECTED;
715 	}
716 
717 	fcs_cs_key_payload payload = {
718 		session_id,
719 		RESERVED_AS_ZERO,
720 		RESERVED_AS_ZERO,
721 		key_id
722 	};
723 
724 	payload_size = sizeof(payload) / MBOX_WORD_BYTE;
725 
726 	status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_EXPORT_CS_KEY,
727 			(uint32_t *) &payload, payload_size,
728 			CMD_CASUAL, resp_data, &resp_len);
729 
730 	if (resp_len > 0) {
731 		op_status = resp_data[0] & FCS_CS_KEY_RESP_STATUS_MASK;
732 	}
733 
734 	if (status < 0) {
735 		*mbox_error = (-status) | (op_status << FCS_CS_KEY_RESP_STATUS_OFFSET);
736 		return INTEL_SIP_SMC_STATUS_ERROR;
737 	}
738 
739 	if (resp_len > 1) {
740 
741 		/* Export key object is start at second response data */
742 		*dst_size = (resp_len - 1) * MBOX_WORD_BYTE;
743 
744 		for (i = 1U; i < resp_len; i++) {
745 			mmio_write_32(dst_addr, resp_data[i]);
746 			dst_addr += MBOX_WORD_BYTE;
747 		}
748 
749 		flush_dcache_range(dst_addr - *dst_size, *dst_size);
750 
751 	} else {
752 
753 		/* Unexpected response, missing key object in response */
754 		*mbox_error = MBOX_RET_ERROR;
755 		return INTEL_SIP_SMC_STATUS_ERROR;
756 	}
757 
758 	return INTEL_SIP_SMC_STATUS_OK;
759 }
760 
761 int intel_fcs_remove_crypto_service_key(uint32_t session_id, uint32_t key_id,
762 		uint32_t *mbox_error)
763 {
764 	int status;
765 	uint32_t payload_size;
766 	uint32_t resp_len = 1U;
767 	uint32_t resp_data = 0U;
768 	uint32_t op_status = 0U;
769 
770 	if (mbox_error == NULL) {
771 		return INTEL_SIP_SMC_STATUS_REJECTED;
772 	}
773 
774 	fcs_cs_key_payload payload = {
775 		session_id,
776 		RESERVED_AS_ZERO,
777 		RESERVED_AS_ZERO,
778 		key_id
779 	};
780 
781 	payload_size = sizeof(payload) / MBOX_WORD_BYTE;
782 
783 	status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_REMOVE_CS_KEY,
784 			(uint32_t *) &payload, payload_size,
785 			CMD_CASUAL, &resp_data, &resp_len);
786 
787 	if (resp_len > 0) {
788 		op_status = resp_data & FCS_CS_KEY_RESP_STATUS_MASK;
789 	}
790 
791 	if (status < 0) {
792 		*mbox_error = (-status) | (op_status << FCS_CS_KEY_RESP_STATUS_OFFSET);
793 		return INTEL_SIP_SMC_STATUS_ERROR;
794 	}
795 
796 	return INTEL_SIP_SMC_STATUS_OK;
797 }
798 
799 int intel_fcs_get_crypto_service_key_info(uint32_t session_id, uint32_t key_id,
800 		uint64_t dst_addr, uint32_t *dst_size,
801 		uint32_t *mbox_error)
802 {
803 	int status;
804 	uint32_t payload_size;
805 	uint32_t resp_len = FCS_CS_KEY_INFO_MAX_WORD_SIZE;
806 	uint32_t op_status = 0U;
807 
808 	if ((dst_size == NULL) || (mbox_error == NULL)) {
809 		return INTEL_SIP_SMC_STATUS_REJECTED;
810 	}
811 
812 	if (!is_address_in_ddr_range(dst_addr, *dst_size)) {
813 		return INTEL_SIP_SMC_STATUS_REJECTED;
814 	}
815 
816 	fcs_cs_key_payload payload = {
817 		session_id,
818 		RESERVED_AS_ZERO,
819 		RESERVED_AS_ZERO,
820 		key_id
821 	};
822 
823 	payload_size = sizeof(payload) / MBOX_WORD_BYTE;
824 
825 	status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_GET_CS_KEY_INFO,
826 				(uint32_t *) &payload, payload_size,
827 				CMD_CASUAL, (uint32_t *) dst_addr, &resp_len);
828 
829 	if (resp_len > 0) {
830 		op_status = mmio_read_32(dst_addr) &
831 			FCS_CS_KEY_RESP_STATUS_MASK;
832 	}
833 
834 	if (status < 0) {
835 		*mbox_error = (-status) | (op_status << FCS_CS_KEY_RESP_STATUS_OFFSET);
836 		return INTEL_SIP_SMC_STATUS_ERROR;
837 	}
838 
839 	*dst_size = resp_len * MBOX_WORD_BYTE;
840 	flush_dcache_range(dst_addr, *dst_size);
841 
842 	return INTEL_SIP_SMC_STATUS_OK;
843 }
844 
845 int intel_fcs_get_digest_init(uint32_t session_id, uint32_t context_id,
846 				uint32_t key_id, uint32_t param_size,
847 				uint64_t param_data, uint32_t *mbox_error)
848 {
849 	return intel_fcs_crypto_service_init(session_id, context_id,
850 				key_id, param_size, param_data,
851 				(void *) &fcs_sha_get_digest_param,
852 				mbox_error);
853 }
854 
855 int intel_fcs_get_digest_finalize(uint32_t session_id, uint32_t context_id,
856 				uint32_t src_addr, uint32_t src_size,
857 				uint64_t dst_addr, uint32_t *dst_size,
858 				uint32_t *mbox_error)
859 {
860 	int status;
861 	uint32_t i;
862 	uint32_t resp_len = *dst_size / MBOX_WORD_BYTE;
863 	uint32_t payload[FCS_GET_DIGEST_CMD_MAX_WORD_SIZE] = {0U};
864 
865 	if (dst_size == NULL || mbox_error == NULL) {
866 		return INTEL_SIP_SMC_STATUS_REJECTED;
867 	}
868 
869 	if (fcs_sha_get_digest_param.session_id != session_id ||
870 	    fcs_sha_get_digest_param.context_id != context_id) {
871 		return INTEL_SIP_SMC_STATUS_REJECTED;
872 	}
873 
874 	/* Source data must be 8 bytes aligned */
875 	if (!is_8_bytes_aligned(src_size)) {
876 		return INTEL_SIP_SMC_STATUS_REJECTED;
877 	}
878 
879 	if (!is_address_in_ddr_range(src_addr, src_size) ||
880 		 !is_address_in_ddr_range(dst_addr, *dst_size)) {
881 		return INTEL_SIP_SMC_STATUS_REJECTED;
882 	}
883 
884 	/* Prepare command payload */
885 	i = 0;
886 	/* Crypto header */
887 	payload[i] = fcs_sha_get_digest_param.session_id;
888 	i++;
889 	payload[i] = fcs_sha_get_digest_param.context_id;
890 	i++;
891 	payload[i] = fcs_sha_get_digest_param.crypto_param_size
892 			& FCS_CS_FIELD_SIZE_MASK;
893 	payload[i] |= (FCS_CS_FIELD_FLAG_INIT | FCS_CS_FIELD_FLAG_UPDATE
894 			| FCS_CS_FIELD_FLAG_FINALIZE)
895 			<< FCS_CS_FIELD_FLAG_OFFSET;
896 	i++;
897 	payload[i] = fcs_sha_get_digest_param.key_id;
898 	i++;
899 	/* Crypto parameters */
900 	payload[i] = fcs_sha_get_digest_param.crypto_param
901 			& INTEL_SIP_SMC_FCS_SHA_MODE_MASK;
902 	payload[i] |= ((fcs_sha_get_digest_param.crypto_param
903 			>> INTEL_SIP_SMC_FCS_DIGEST_SIZE_OFFSET)
904 			& INTEL_SIP_SMC_FCS_DIGEST_SIZE_MASK)
905 			<< FCS_SHA_HMAC_CRYPTO_PARAM_SIZE_OFFSET;
906 	i++;
907 	/* Data source address and size */
908 	payload[i] = src_addr;
909 	i++;
910 	payload[i] = src_size;
911 	i++;
912 
913 	status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_GET_DIGEST_REQ,
914 				payload, i, CMD_CASUAL,
915 				(uint32_t *) dst_addr, &resp_len);
916 
917 	memset((void *)&fcs_sha_get_digest_param, 0, sizeof(fcs_crypto_service_data));
918 
919 	if (status < 0) {
920 		*mbox_error = -status;
921 		return INTEL_SIP_SMC_STATUS_ERROR;
922 	}
923 
924 	*dst_size = resp_len * MBOX_WORD_BYTE;
925 	flush_dcache_range(dst_addr, *dst_size);
926 
927 	return INTEL_SIP_SMC_STATUS_OK;
928 }
929 
930 int intel_fcs_mac_verify_init(uint32_t session_id, uint32_t context_id,
931 				uint32_t key_id, uint32_t param_size,
932 				uint64_t param_data, uint32_t *mbox_error)
933 {
934 	return intel_fcs_crypto_service_init(session_id, context_id,
935 				key_id, param_size, param_data,
936 				(void *) &fcs_sha_mac_verify_param,
937 				mbox_error);
938 }
939 
940 int intel_fcs_mac_verify_finalize(uint32_t session_id, uint32_t context_id,
941 				uint32_t src_addr, uint32_t src_size,
942 				uint64_t dst_addr, uint32_t *dst_size,
943 				uint32_t data_size, uint32_t *mbox_error)
944 {
945 	int status;
946 	uint32_t i;
947 	uint32_t resp_len = *dst_size / MBOX_WORD_BYTE;
948 	uint32_t payload[FCS_MAC_VERIFY_CMD_MAX_WORD_SIZE] = {0U};
949 	uintptr_t mac_offset;
950 
951 	if (dst_size == NULL || mbox_error == NULL) {
952 		return INTEL_SIP_SMC_STATUS_REJECTED;
953 	}
954 
955 	if (fcs_sha_mac_verify_param.session_id != session_id ||
956 		fcs_sha_mac_verify_param.context_id != context_id) {
957 		return INTEL_SIP_SMC_STATUS_REJECTED;
958 	}
959 
960 	if (data_size >= src_size) {
961 		return INTEL_SIP_SMC_STATUS_REJECTED;
962 	}
963 
964 	if (!is_size_4_bytes_aligned(src_size) ||
965 		!is_8_bytes_aligned(data_size)) {
966 		return INTEL_SIP_SMC_STATUS_REJECTED;
967 	}
968 
969 	if (!is_address_in_ddr_range(src_addr, src_size) ||
970 		!is_address_in_ddr_range(dst_addr, *dst_size)) {
971 		return INTEL_SIP_SMC_STATUS_REJECTED;
972 	}
973 
974 	/* Prepare command payload */
975 	i = 0;
976 	/* Crypto header */
977 	payload[i] = fcs_sha_mac_verify_param.session_id;
978 	i++;
979 	payload[i] = fcs_sha_mac_verify_param.context_id;
980 	i++;
981 	payload[i] = fcs_sha_mac_verify_param.crypto_param_size
982 			& FCS_CS_FIELD_SIZE_MASK;
983 	payload[i] |= (FCS_CS_FIELD_FLAG_INIT | FCS_CS_FIELD_FLAG_UPDATE
984 			| FCS_CS_FIELD_FLAG_FINALIZE)
985 			<< FCS_CS_FIELD_FLAG_OFFSET;
986 	i++;
987 	payload[i] = fcs_sha_mac_verify_param.key_id;
988 	i++;
989 	/* Crypto parameters */
990 	payload[i] = ((fcs_sha_mac_verify_param.crypto_param
991 			>> INTEL_SIP_SMC_FCS_DIGEST_SIZE_OFFSET)
992 			& INTEL_SIP_SMC_FCS_DIGEST_SIZE_MASK)
993 			<< FCS_SHA_HMAC_CRYPTO_PARAM_SIZE_OFFSET;
994 	i++;
995 	/* Data source address and size */
996 	payload[i] = src_addr;
997 	i++;
998 	payload[i] = data_size;
999 	i++;
1000 	/* Copy mac data to command */
1001 	mac_offset = src_addr + data_size;
1002 	memcpy((uint8_t *) &payload[i], (uint8_t *) mac_offset,
1003 				src_size - data_size);
1004 
1005 	i += (src_size - data_size) / MBOX_WORD_BYTE;
1006 
1007 	status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_MAC_VERIFY_REQ,
1008 				payload, i, CMD_CASUAL,
1009 				(uint32_t *) dst_addr, &resp_len);
1010 
1011 	memset((void *)&fcs_sha_mac_verify_param, 0,
1012 				sizeof(fcs_crypto_service_data));
1013 
1014 	if (status < 0) {
1015 		*mbox_error = -status;
1016 		return INTEL_SIP_SMC_STATUS_ERROR;
1017 	}
1018 
1019 	*dst_size = resp_len * MBOX_WORD_BYTE;
1020 	flush_dcache_range(dst_addr, *dst_size);
1021 
1022 	return INTEL_SIP_SMC_STATUS_OK;
1023 }
1024 
1025 int intel_fcs_ecdsa_hash_sign_init(uint32_t session_id, uint32_t context_id,
1026 				uint32_t key_id, uint32_t param_size,
1027 				uint64_t param_data, uint32_t *mbox_error)
1028 {
1029 	return intel_fcs_crypto_service_init(session_id, context_id,
1030 				key_id, param_size, param_data,
1031 				(void *) &fcs_ecdsa_hash_sign_param,
1032 				mbox_error);
1033 }
1034 
1035 int intel_fcs_ecdsa_hash_sign_finalize(uint32_t session_id, uint32_t context_id,
1036 				uint32_t src_addr, uint32_t src_size,
1037 				uint64_t dst_addr, uint32_t *dst_size,
1038 				uint32_t *mbox_error)
1039 {
1040 	int status;
1041 	uint32_t i;
1042 	uint32_t payload[FCS_ECDSA_HASH_SIGN_CMD_MAX_WORD_SIZE] = {0U};
1043 	uint32_t resp_len = *dst_size / MBOX_WORD_BYTE;
1044 	uintptr_t hash_data_addr;
1045 
1046 	if ((dst_size == NULL) || (mbox_error == NULL)) {
1047 		return INTEL_SIP_SMC_STATUS_REJECTED;
1048 	}
1049 
1050 	if (fcs_ecdsa_hash_sign_param.session_id != session_id ||
1051 		fcs_ecdsa_hash_sign_param.context_id != context_id) {
1052 		return INTEL_SIP_SMC_STATUS_REJECTED;
1053 	}
1054 
1055 	if (!is_address_in_ddr_range(src_addr, src_size) ||
1056 		!is_address_in_ddr_range(dst_addr, *dst_size)) {
1057 		return INTEL_SIP_SMC_STATUS_REJECTED;
1058 	}
1059 
1060 	/* Prepare command payload */
1061 	/* Crypto header */
1062 	i = 0;
1063 	payload[i] = fcs_ecdsa_hash_sign_param.session_id;
1064 	i++;
1065 	payload[i] = fcs_ecdsa_hash_sign_param.context_id;
1066 
1067 	i++;
1068 	payload[i] = fcs_ecdsa_hash_sign_param.crypto_param_size
1069 			& FCS_CS_FIELD_SIZE_MASK;
1070 	payload[i] |= (FCS_CS_FIELD_FLAG_INIT | FCS_CS_FIELD_FLAG_UPDATE
1071 			| FCS_CS_FIELD_FLAG_FINALIZE)
1072 			<< FCS_CS_FIELD_FLAG_OFFSET;
1073 	i++;
1074 	payload[i] = fcs_ecdsa_hash_sign_param.key_id;
1075 
1076 	/* Crypto parameters */
1077 	i++;
1078 	payload[i] = fcs_ecdsa_hash_sign_param.crypto_param
1079 			& INTEL_SIP_SMC_FCS_ECC_ALGO_MASK;
1080 
1081 	/* Hash Data */
1082 	i++;
1083 	hash_data_addr = src_addr;
1084 	memcpy((uint8_t *) &payload[i], (uint8_t *) hash_data_addr,
1085 			src_size);
1086 
1087 	i += src_size / MBOX_WORD_BYTE;
1088 
1089 	status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_ECDSA_HASH_SIGN_REQ,
1090 			payload, i, CMD_CASUAL, (uint32_t *) dst_addr,
1091 			&resp_len);
1092 
1093 	memset((void *) &fcs_ecdsa_hash_sign_param,
1094 			0, sizeof(fcs_crypto_service_data));
1095 
1096 	if (status < 0) {
1097 		*mbox_error = -status;
1098 		return INTEL_SIP_SMC_STATUS_ERROR;
1099 	}
1100 
1101 	*dst_size = resp_len * MBOX_WORD_BYTE;
1102 	flush_dcache_range(dst_addr, *dst_size);
1103 
1104 	return INTEL_SIP_SMC_STATUS_OK;
1105 }
1106 
1107 int intel_fcs_ecdsa_hash_sig_verify_init(uint32_t session_id, uint32_t context_id,
1108 				uint32_t key_id, uint32_t param_size,
1109 				uint64_t param_data, uint32_t *mbox_error)
1110 {
1111 	return intel_fcs_crypto_service_init(session_id, context_id,
1112 				key_id, param_size, param_data,
1113 				(void *) &fcs_ecdsa_hash_sig_verify_param,
1114 				mbox_error);
1115 }
1116 
1117 int intel_fcs_ecdsa_hash_sig_verify_finalize(uint32_t session_id, uint32_t context_id,
1118 				uint32_t src_addr, uint32_t src_size,
1119 				uint64_t dst_addr, uint32_t *dst_size,
1120 				uint32_t *mbox_error)
1121 {
1122 	int status;
1123 	uint32_t i = 0;
1124 	uint32_t payload[FCS_ECDSA_HASH_SIG_VERIFY_CMD_MAX_WORD_SIZE] = {0U};
1125 	uint32_t resp_len = *dst_size / MBOX_WORD_BYTE;
1126 	uintptr_t hash_sig_pubkey_addr;
1127 
1128 	if ((dst_size == NULL) || (mbox_error == NULL)) {
1129 		return INTEL_SIP_SMC_STATUS_REJECTED;
1130 	}
1131 
1132 	if (fcs_ecdsa_hash_sig_verify_param.session_id != session_id ||
1133 	fcs_ecdsa_hash_sig_verify_param.context_id != context_id) {
1134 		return INTEL_SIP_SMC_STATUS_REJECTED;
1135 	}
1136 
1137 	if (!is_address_in_ddr_range(src_addr, src_size) ||
1138 		!is_address_in_ddr_range(dst_addr, *dst_size)) {
1139 		return INTEL_SIP_SMC_STATUS_REJECTED;
1140 	}
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_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, uint32_t *mbox_error)
1206 {
1207 	int status;
1208 	int i;
1209 	uint32_t payload[FCS_ECDSA_SHA2_DATA_SIGN_CMD_MAX_WORD_SIZE] = {0U};
1210 	uint32_t resp_len = *dst_size / MBOX_WORD_BYTE;
1211 
1212 	if ((dst_size == NULL) || (mbox_error == NULL)) {
1213 		return INTEL_SIP_SMC_STATUS_REJECTED;
1214 	}
1215 
1216 	if (fcs_sha2_data_sign_param.session_id != session_id ||
1217 		fcs_sha2_data_sign_param.context_id != context_id) {
1218 		return INTEL_SIP_SMC_STATUS_REJECTED;
1219 	}
1220 
1221 	/* Source data must be 8 bytes aligned */
1222 	if (!is_8_bytes_aligned(src_size)) {
1223 		return INTEL_SIP_SMC_STATUS_REJECTED;
1224 	}
1225 
1226 	if (!is_address_in_ddr_range(src_addr, src_size) ||
1227 		!is_address_in_ddr_range(dst_addr, *dst_size)) {
1228 		return INTEL_SIP_SMC_STATUS_REJECTED;
1229 	}
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 = *dst_size / MBOX_WORD_BYTE;
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 	/* Prepare command payload */
1321 	/* Crypto header */
1322 	i = 0;
1323 	payload[i] = fcs_sha2_data_sig_verify_param.session_id;
1324 	i++;
1325 	payload[i] = fcs_sha2_data_sig_verify_param.context_id;
1326 	i++;
1327 
1328 	payload[i] = fcs_sha2_data_sig_verify_param.crypto_param_size
1329 			& FCS_CS_FIELD_SIZE_MASK;
1330 	payload[i] |= (FCS_CS_FIELD_FLAG_INIT | FCS_CS_FIELD_FLAG_UPDATE
1331 			| FCS_CS_FIELD_FLAG_FINALIZE)
1332 			<< FCS_CS_FIELD_FLAG_OFFSET;
1333 	i++;
1334 	payload[i] = fcs_sha2_data_sig_verify_param.key_id;
1335 	i++;
1336 	/* Crypto parameters */
1337 	payload[i] = fcs_sha2_data_sig_verify_param.crypto_param
1338 			& INTEL_SIP_SMC_FCS_ECC_ALGO_MASK;
1339 	i++;
1340 	/* Data source address and size */
1341 	payload[i] = src_addr;
1342 	i++;
1343 	payload[i] = data_size;
1344 	i++;
1345 	/* Signature + Public Key Data */
1346 	sig_pubkey_offset = src_addr + data_size;
1347 	memcpy((uint8_t *) &payload[i], (uint8_t *) sig_pubkey_offset,
1348 		src_size - data_size);
1349 
1350 	i += (src_size - data_size) / MBOX_WORD_BYTE;
1351 
1352 	status = mailbox_send_cmd(MBOX_JOB_ID,
1353 			MBOX_FCS_ECDSA_SHA2_DATA_SIGN_VERIFY, payload, i,
1354 			CMD_CASUAL, (uint32_t *) dst_addr, &resp_len);
1355 
1356 	memset((void *) &fcs_sha2_data_sig_verify_param, 0,
1357 			sizeof(fcs_crypto_service_data));
1358 
1359 	if (status < 0) {
1360 		*mbox_error = -status;
1361 		return INTEL_SIP_SMC_STATUS_ERROR;
1362 	}
1363 
1364 	*dst_size = resp_len * MBOX_WORD_BYTE;
1365 	flush_dcache_range(dst_addr, *dst_size);
1366 
1367 	return INTEL_SIP_SMC_STATUS_OK;
1368 }
1369 
1370 int intel_fcs_ecdsa_get_pubkey_init(uint32_t session_id, uint32_t context_id,
1371 				uint32_t key_id, uint32_t param_size,
1372 				uint64_t param_data, uint32_t *mbox_error)
1373 {
1374 	return intel_fcs_crypto_service_init(session_id, context_id,
1375 				key_id, param_size, param_data,
1376 				(void *) &fcs_ecdsa_get_pubkey_param,
1377 				mbox_error);
1378 }
1379 
1380 int intel_fcs_ecdsa_get_pubkey_finalize(uint32_t session_id, uint32_t context_id,
1381 				uint64_t dst_addr, uint32_t *dst_size,
1382 				uint32_t *mbox_error)
1383 {
1384 	int status;
1385 	int i;
1386 	uint32_t crypto_header;
1387 	uint32_t ret_size = *dst_size / MBOX_WORD_BYTE;
1388 	uint32_t payload[FCS_ECDSA_GET_PUBKEY_MAX_WORD_SIZE] = {0U};
1389 
1390 	if ((dst_size == NULL) || (mbox_error == NULL)) {
1391 		return INTEL_SIP_SMC_STATUS_REJECTED;
1392 	}
1393 
1394 	if (fcs_ecdsa_get_pubkey_param.session_id != session_id ||
1395 		fcs_ecdsa_get_pubkey_param.context_id != context_id) {
1396 		return INTEL_SIP_SMC_STATUS_REJECTED;
1397 	}
1398 
1399 	crypto_header = ((FCS_CS_FIELD_FLAG_INIT |
1400 			FCS_CS_FIELD_FLAG_UPDATE |
1401 			FCS_CS_FIELD_FLAG_FINALIZE) <<
1402 			FCS_CS_FIELD_FLAG_OFFSET) |
1403 			fcs_ecdsa_get_pubkey_param.crypto_param_size;
1404 	i = 0;
1405 	/* Prepare command payload */
1406 	payload[i] = session_id;
1407 	i++;
1408 	payload[i] = context_id;
1409 	i++;
1410 	payload[i] = crypto_header;
1411 	i++;
1412 	payload[i] = fcs_ecdsa_get_pubkey_param.key_id;
1413 	i++;
1414 	payload[i] = (uint32_t) fcs_ecdsa_get_pubkey_param.crypto_param &
1415 			INTEL_SIP_SMC_FCS_ECC_ALGO_MASK;
1416 	i++;
1417 
1418 	status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_ECDSA_GET_PUBKEY,
1419 			payload, i, CMD_CASUAL,
1420 			(uint32_t *) dst_addr, &ret_size);
1421 
1422 	memset((void *) &fcs_ecdsa_get_pubkey_param, 0,
1423 		sizeof(fcs_crypto_service_data));
1424 
1425 	if (status < 0) {
1426 		*mbox_error = -status;
1427 		return INTEL_SIP_SMC_STATUS_ERROR;
1428 	}
1429 
1430 	*dst_size = ret_size * MBOX_WORD_BYTE;
1431 	flush_dcache_range(dst_addr, *dst_size);
1432 
1433 	return INTEL_SIP_SMC_STATUS_OK;
1434 }
1435 
1436 int intel_fcs_ecdh_request_init(uint32_t session_id, uint32_t context_id,
1437 				uint32_t key_id, uint32_t param_size,
1438 				uint64_t param_data, uint32_t *mbox_error)
1439 {
1440 	return intel_fcs_crypto_service_init(session_id, context_id,
1441 				key_id, param_size, param_data,
1442 				(void *) &fcs_ecdh_request_param,
1443 				mbox_error);
1444 }
1445 
1446 int intel_fcs_ecdh_request_finalize(uint32_t session_id, uint32_t context_id,
1447 				uint32_t src_addr, uint32_t src_size,
1448 				uint64_t dst_addr, uint32_t *dst_size,
1449 				uint32_t *mbox_error)
1450 {
1451 	int status;
1452 	uint32_t i;
1453 	uint32_t payload[FCS_ECDH_REQUEST_CMD_MAX_WORD_SIZE] = {0U};
1454 	uint32_t resp_len = *dst_size / MBOX_WORD_BYTE;
1455 	uintptr_t pubkey;
1456 
1457 	if ((dst_size == NULL) || (mbox_error == NULL)) {
1458 		return INTEL_SIP_SMC_STATUS_REJECTED;
1459 	}
1460 
1461 	if (fcs_ecdh_request_param.session_id != session_id ||
1462 		fcs_ecdh_request_param.context_id != context_id) {
1463 		return INTEL_SIP_SMC_STATUS_REJECTED;
1464 	}
1465 
1466 	if (!is_address_in_ddr_range(src_addr, src_size) ||
1467 		!is_address_in_ddr_range(dst_addr, *dst_size)) {
1468 		return INTEL_SIP_SMC_STATUS_REJECTED;
1469 	}
1470 
1471 	/* Prepare command payload */
1472 	i = 0;
1473 	/* Crypto header */
1474 	payload[i] = fcs_ecdh_request_param.session_id;
1475 	i++;
1476 	payload[i] = fcs_ecdh_request_param.context_id;
1477 	i++;
1478 	payload[i] = fcs_ecdh_request_param.crypto_param_size
1479 			& FCS_CS_FIELD_SIZE_MASK;
1480 	payload[i] |= (FCS_CS_FIELD_FLAG_INIT | FCS_CS_FIELD_FLAG_UPDATE
1481 			| FCS_CS_FIELD_FLAG_FINALIZE)
1482 			<< FCS_CS_FIELD_FLAG_OFFSET;
1483 	i++;
1484 	payload[i] = fcs_ecdh_request_param.key_id;
1485 	i++;
1486 	/* Crypto parameters */
1487 	payload[i] = fcs_ecdh_request_param.crypto_param
1488 			& INTEL_SIP_SMC_FCS_ECC_ALGO_MASK;
1489 	i++;
1490 	/* Public key data */
1491 	pubkey = src_addr;
1492 	memcpy((uint8_t *) &payload[i], (uint8_t *) pubkey, src_size);
1493 	i += src_size / MBOX_WORD_BYTE;
1494 
1495 	status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_ECDH_REQUEST,
1496 			payload, i, CMD_CASUAL, (uint32_t *) dst_addr,
1497 			&resp_len);
1498 
1499 	memset((void *)&fcs_ecdh_request_param, 0,
1500 			sizeof(fcs_crypto_service_data));
1501 
1502 	if (status < 0) {
1503 		*mbox_error = -status;
1504 		return INTEL_SIP_SMC_STATUS_ERROR;
1505 	}
1506 
1507 	*dst_size = resp_len * MBOX_WORD_BYTE;
1508 	flush_dcache_range(dst_addr, *dst_size);
1509 
1510 	return INTEL_SIP_SMC_STATUS_OK;
1511 }
1512 
1513 int intel_fcs_aes_crypt_init(uint32_t session_id, uint32_t context_id,
1514 				uint32_t key_id, uint64_t param_addr,
1515 				uint32_t param_size, uint32_t *mbox_error)
1516 {
1517 	if (mbox_error == NULL) {
1518 		return INTEL_SIP_SMC_STATUS_REJECTED;
1519 	}
1520 
1521 	memset((void *)&fcs_aes_init_payload, 0U, sizeof(fcs_aes_init_payload));
1522 
1523 	fcs_aes_init_payload.session_id = session_id;
1524 	fcs_aes_init_payload.context_id = context_id;
1525 	fcs_aes_init_payload.param_size = param_size;
1526 	fcs_aes_init_payload.key_id	= key_id;
1527 
1528 	memcpy((uint8_t *) fcs_aes_init_payload.crypto_param,
1529 		(uint8_t *) param_addr, param_size);
1530 
1531 	*mbox_error = 0;
1532 
1533 	return INTEL_SIP_SMC_STATUS_OK;
1534 }
1535 
1536 int intel_fcs_aes_crypt_finalize(uint32_t session_id, uint32_t context_id,
1537 				uint64_t src_addr, uint32_t src_size,
1538 				uint64_t dst_addr, uint32_t dst_size,
1539 				uint32_t *send_id)
1540 {
1541 	int status;
1542 	int i;
1543 	uint32_t crypto_header;
1544 	uint32_t fcs_aes_crypt_payload[FCS_AES_CMD_MAX_WORD_SIZE];
1545 
1546 	if (fcs_aes_init_payload.session_id != session_id ||
1547 		fcs_aes_init_payload.context_id != context_id) {
1548 		return INTEL_SIP_SMC_STATUS_REJECTED;
1549 	}
1550 
1551 	if ((!is_8_bytes_aligned(src_addr)) ||
1552 		(!is_32_bytes_aligned(src_size)) ||
1553 		(!is_address_in_ddr_range(src_addr, src_size))) {
1554 		return INTEL_SIP_SMC_STATUS_REJECTED;
1555 	}
1556 
1557 	if ((!is_8_bytes_aligned(dst_addr)) ||
1558 		(!is_32_bytes_aligned(dst_size))) {
1559 		return INTEL_SIP_SMC_STATUS_REJECTED;
1560 	}
1561 
1562 	if ((dst_size > FCS_AES_MAX_DATA_SIZE ||
1563 		dst_size < FCS_AES_MIN_DATA_SIZE) ||
1564 		(src_size > FCS_AES_MAX_DATA_SIZE ||
1565 		src_size < FCS_AES_MIN_DATA_SIZE)) {
1566 		return INTEL_SIP_SMC_STATUS_REJECTED;
1567 	}
1568 
1569 	crypto_header = ((FCS_CS_FIELD_FLAG_INIT |
1570 			FCS_CS_FIELD_FLAG_UPDATE |
1571 			FCS_CS_FIELD_FLAG_FINALIZE) <<
1572 			FCS_CS_FIELD_FLAG_OFFSET) |
1573 			fcs_aes_init_payload.param_size;
1574 	i = 0U;
1575 	fcs_aes_crypt_payload[i] = session_id;
1576 	i++;
1577 	fcs_aes_crypt_payload[i] = context_id;
1578 	i++;
1579 	fcs_aes_crypt_payload[i] = crypto_header;
1580 	i++;
1581 	fcs_aes_crypt_payload[i] = fcs_aes_init_payload.key_id;
1582 
1583 	i++;
1584 	memcpy((uint8_t *) &fcs_aes_crypt_payload[i],
1585 		(uint8_t *) fcs_aes_init_payload.crypto_param,
1586 		fcs_aes_init_payload.param_size);
1587 
1588 	i += fcs_aes_init_payload.param_size / MBOX_WORD_BYTE;
1589 
1590 	fcs_aes_crypt_payload[i] = (uint32_t) src_addr;
1591 	i++;
1592 	fcs_aes_crypt_payload[i] = src_size;
1593 	i++;
1594 	fcs_aes_crypt_payload[i] = (uint32_t) dst_addr;
1595 	i++;
1596 	fcs_aes_crypt_payload[i] = dst_size;
1597 	i++;
1598 
1599 	status = mailbox_send_cmd_async(send_id, MBOX_FCS_AES_CRYPT_REQ,
1600 					fcs_aes_crypt_payload, i,
1601 					CMD_INDIRECT);
1602 
1603 	memset((void *)&fcs_aes_init_payload, 0U, sizeof(fcs_aes_init_payload));
1604 
1605 	if (status < 0U) {
1606 		return INTEL_SIP_SMC_STATUS_ERROR;
1607 	}
1608 
1609 	return INTEL_SIP_SMC_STATUS_OK;
1610 }
1611