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