xref: /rk3399_ARM-atf/plat/intel/soc/common/sip/socfpga_sip_fcs.c (revision 537ff052579862a4865d36d06940feaa796d16da)
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 
19 bool is_size_4_bytes_aligned(uint32_t size)
20 {
21 	if ((size % MBOX_WORD_BYTE) != 0U) {
22 		return false;
23 	} else {
24 		return true;
25 	}
26 }
27 
28 static bool is_8_bytes_aligned(uint32_t data)
29 {
30 	if ((data % (MBOX_WORD_BYTE * 2U)) != 0U) {
31 		return false;
32 	} else {
33 		return true;
34 	}
35 }
36 
37 static bool is_32_bytes_aligned(uint32_t data)
38 {
39 	if ((data % (8U * MBOX_WORD_BYTE)) != 0U) {
40 		return false;
41 	} else {
42 		return true;
43 	}
44 }
45 
46 static int intel_fcs_crypto_service_init(uint32_t session_id,
47 			uint32_t context_id, uint32_t key_id,
48 			uint32_t param_size, uint64_t param_data,
49 			fcs_crypto_service_data *data_addr,
50 			uint32_t *mbox_error)
51 {
52 	if (mbox_error == NULL) {
53 		return INTEL_SIP_SMC_STATUS_REJECTED;
54 	}
55 
56 	if (param_size != 4) {
57 		return INTEL_SIP_SMC_STATUS_REJECTED;
58 	}
59 
60 	memset(data_addr, 0, sizeof(fcs_crypto_service_data));
61 
62 	data_addr->session_id = session_id;
63 	data_addr->context_id = context_id;
64 	data_addr->key_id = key_id;
65 	data_addr->crypto_param_size = param_size;
66 	data_addr->crypto_param = param_data;
67 
68 	*mbox_error = 0;
69 
70 	return INTEL_SIP_SMC_STATUS_OK;
71 }
72 
73 uint32_t intel_fcs_random_number_gen(uint64_t addr, uint64_t *ret_size,
74 					uint32_t *mbox_error)
75 {
76 	int status;
77 	unsigned int i;
78 	unsigned int resp_len = FCS_RANDOM_WORD_SIZE;
79 	uint32_t random_data[FCS_RANDOM_WORD_SIZE] = {0U};
80 
81 	if (!is_address_in_ddr_range(addr, FCS_RANDOM_BYTE_SIZE)) {
82 		return INTEL_SIP_SMC_STATUS_REJECTED;
83 	}
84 
85 	status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_RANDOM_GEN, NULL, 0U,
86 			CMD_CASUAL, random_data, &resp_len);
87 
88 	if (status < 0) {
89 		*mbox_error = -status;
90 		return INTEL_SIP_SMC_STATUS_ERROR;
91 	}
92 
93 	if (resp_len != FCS_RANDOM_WORD_SIZE) {
94 		*mbox_error = GENERIC_RESPONSE_ERROR;
95 		return INTEL_SIP_SMC_STATUS_ERROR;
96 	}
97 
98 	*ret_size = FCS_RANDOM_BYTE_SIZE;
99 
100 	for (i = 0U; i < FCS_RANDOM_WORD_SIZE; i++) {
101 		mmio_write_32(addr, random_data[i]);
102 		addr += MBOX_WORD_BYTE;
103 	}
104 
105 	flush_dcache_range(addr - *ret_size, *ret_size);
106 
107 	return INTEL_SIP_SMC_STATUS_OK;
108 }
109 
110 int intel_fcs_random_number_gen_ext(uint32_t session_id, uint32_t context_id,
111 				uint32_t size, uint32_t *send_id)
112 {
113 	int status;
114 	uint32_t payload_size;
115 	uint32_t crypto_header;
116 
117 	if (size > (FCS_RANDOM_EXT_MAX_WORD_SIZE *
118 		MBOX_WORD_BYTE) || size == 0U) {
119 		return INTEL_SIP_SMC_STATUS_REJECTED;
120 	}
121 
122 	if (!is_size_4_bytes_aligned(size)) {
123 		return INTEL_SIP_SMC_STATUS_REJECTED;
124 	}
125 
126 	crypto_header = (FCS_CS_FIELD_FLAG_INIT | FCS_CS_FIELD_FLAG_FINALIZE) <<
127 			FCS_CS_FIELD_FLAG_OFFSET;
128 
129 	fcs_rng_payload payload = {
130 		session_id,
131 		context_id,
132 		crypto_header,
133 		size
134 	};
135 
136 	payload_size = sizeof(payload) / MBOX_WORD_BYTE;
137 
138 	status = mailbox_send_cmd_async(send_id, MBOX_FCS_RANDOM_GEN,
139 					(uint32_t *) &payload, payload_size,
140 					CMD_INDIRECT);
141 
142 	if (status < 0) {
143 		return INTEL_SIP_SMC_STATUS_ERROR;
144 	}
145 
146 	return INTEL_SIP_SMC_STATUS_OK;
147 }
148 
149 uint32_t intel_fcs_send_cert(uint64_t addr, uint64_t size,
150 					uint32_t *send_id)
151 {
152 	int status;
153 
154 	if (!is_address_in_ddr_range(addr, size)) {
155 		return INTEL_SIP_SMC_STATUS_REJECTED;
156 	}
157 
158 	if (!is_size_4_bytes_aligned(size)) {
159 		return INTEL_SIP_SMC_STATUS_REJECTED;
160 	}
161 
162 	status = mailbox_send_cmd_async(send_id, MBOX_CMD_VAB_SRC_CERT,
163 				(uint32_t *)addr, size / MBOX_WORD_BYTE,
164 				CMD_DIRECT);
165 
166 	flush_dcache_range(addr, size);
167 
168 	if (status < 0) {
169 		return INTEL_SIP_SMC_STATUS_ERROR;
170 	}
171 
172 	return INTEL_SIP_SMC_STATUS_OK;
173 }
174 
175 uint32_t intel_fcs_get_provision_data(uint32_t *send_id)
176 {
177 	int status;
178 
179 	status = mailbox_send_cmd_async(send_id, MBOX_FCS_GET_PROVISION,
180 				NULL, 0U, CMD_DIRECT);
181 
182 	if (status < 0) {
183 		return INTEL_SIP_SMC_STATUS_ERROR;
184 	}
185 
186 	return INTEL_SIP_SMC_STATUS_OK;
187 }
188 
189 uint32_t intel_fcs_cntr_set_preauth(uint8_t counter_type, int32_t counter_value,
190 					uint32_t test_bit, uint32_t *mbox_error)
191 {
192 	int status;
193 	uint32_t first_word;
194 	uint32_t payload_size;
195 
196 	if ((test_bit != MBOX_TEST_BIT) &&
197 		(test_bit != 0)) {
198 		return INTEL_SIP_SMC_STATUS_REJECTED;
199 	}
200 
201 	if ((counter_type < FCS_BIG_CNTR_SEL) ||
202 		(counter_type > FCS_SVN_CNTR_3_SEL)) {
203 		return INTEL_SIP_SMC_STATUS_REJECTED;
204 	}
205 
206 	if ((counter_type == FCS_BIG_CNTR_SEL) &&
207 		(counter_value > FCS_BIG_CNTR_VAL_MAX)) {
208 		return INTEL_SIP_SMC_STATUS_REJECTED;
209 	}
210 
211 	if ((counter_type >= FCS_SVN_CNTR_0_SEL) &&
212 		(counter_type <= FCS_SVN_CNTR_3_SEL) &&
213 		(counter_value > FCS_SVN_CNTR_VAL_MAX)) {
214 		return INTEL_SIP_SMC_STATUS_REJECTED;
215 	}
216 
217 	first_word = test_bit | counter_type;
218 	fcs_cntr_set_preauth_payload payload = {
219 		first_word,
220 		counter_value
221 	};
222 
223 	payload_size = sizeof(payload) / MBOX_WORD_BYTE;
224 	status =  mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_CNTR_SET_PREAUTH,
225 				  (uint32_t *) &payload, payload_size,
226 				  CMD_CASUAL, NULL, NULL);
227 
228 	if (status < 0) {
229 		*mbox_error = -status;
230 		return INTEL_SIP_SMC_STATUS_ERROR;
231 	}
232 
233 	return INTEL_SIP_SMC_STATUS_OK;
234 }
235 
236 uint32_t intel_fcs_encryption(uint32_t src_addr, uint32_t src_size,
237 		uint32_t dst_addr, uint32_t dst_size, uint32_t *send_id)
238 {
239 	int status;
240 	uint32_t load_size;
241 
242 	fcs_encrypt_payload payload = {
243 		FCS_ENCRYPTION_DATA_0,
244 		src_addr,
245 		src_size,
246 		dst_addr,
247 		dst_size };
248 	load_size = sizeof(payload) / MBOX_WORD_BYTE;
249 
250 	if (!is_address_in_ddr_range(src_addr, src_size) ||
251 		!is_address_in_ddr_range(dst_addr, dst_size)) {
252 		return INTEL_SIP_SMC_STATUS_REJECTED;
253 	}
254 
255 	if (!is_size_4_bytes_aligned(src_size)) {
256 		return INTEL_SIP_SMC_STATUS_REJECTED;
257 	}
258 
259 	status = mailbox_send_cmd_async(send_id, MBOX_FCS_ENCRYPT_REQ,
260 				(uint32_t *) &payload, load_size,
261 				CMD_INDIRECT);
262 	inv_dcache_range(dst_addr, dst_size);
263 
264 	if (status < 0) {
265 		return INTEL_SIP_SMC_STATUS_REJECTED;
266 	}
267 
268 	return INTEL_SIP_SMC_STATUS_OK;
269 }
270 
271 uint32_t intel_fcs_decryption(uint32_t src_addr, uint32_t src_size,
272 		uint32_t dst_addr, uint32_t dst_size, uint32_t *send_id)
273 {
274 	int status;
275 	uint32_t load_size;
276 	uintptr_t id_offset;
277 
278 	id_offset = src_addr + FCS_OWNER_ID_OFFSET;
279 	fcs_decrypt_payload payload = {
280 		FCS_DECRYPTION_DATA_0,
281 		{mmio_read_32(id_offset),
282 		mmio_read_32(id_offset + MBOX_WORD_BYTE)},
283 		src_addr,
284 		src_size,
285 		dst_addr,
286 		dst_size };
287 	load_size = sizeof(payload) / MBOX_WORD_BYTE;
288 
289 	if (!is_address_in_ddr_range(src_addr, src_size) ||
290 		!is_address_in_ddr_range(dst_addr, dst_size)) {
291 		return INTEL_SIP_SMC_STATUS_REJECTED;
292 	}
293 
294 	if (!is_size_4_bytes_aligned(src_size)) {
295 		return INTEL_SIP_SMC_STATUS_REJECTED;
296 	}
297 
298 	status = mailbox_send_cmd_async(send_id, MBOX_FCS_DECRYPT_REQ,
299 				(uint32_t *) &payload, load_size,
300 				CMD_INDIRECT);
301 	inv_dcache_range(dst_addr, dst_size);
302 
303 	if (status < 0) {
304 		return INTEL_SIP_SMC_STATUS_REJECTED;
305 	}
306 
307 	return INTEL_SIP_SMC_STATUS_OK;
308 }
309 
310 uint32_t intel_fcs_get_rom_patch_sha384(uint64_t addr, uint64_t *ret_size,
311 					uint32_t *mbox_error)
312 {
313 	int status;
314 	unsigned int resp_len = FCS_SHA384_WORD_SIZE;
315 
316 	if (!is_address_in_ddr_range(addr, FCS_SHA384_BYTE_SIZE)) {
317 		return INTEL_SIP_SMC_STATUS_REJECTED;
318 	}
319 
320 	status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_GET_ROM_PATCH_SHA384, NULL, 0U,
321 			CMD_CASUAL, (uint32_t *) addr, &resp_len);
322 
323 	if (status < 0) {
324 		*mbox_error = -status;
325 		return INTEL_SIP_SMC_STATUS_ERROR;
326 	}
327 
328 	if (resp_len != FCS_SHA384_WORD_SIZE) {
329 		*mbox_error = GENERIC_RESPONSE_ERROR;
330 		return INTEL_SIP_SMC_STATUS_ERROR;
331 	}
332 
333 	*ret_size = FCS_SHA384_BYTE_SIZE;
334 
335 	flush_dcache_range(addr, *ret_size);
336 
337 	return INTEL_SIP_SMC_STATUS_OK;
338 }
339 
340 int intel_fcs_encryption_ext(uint32_t session_id, uint32_t context_id,
341 		uint32_t src_addr, uint32_t src_size,
342 		uint32_t dst_addr, uint32_t *dst_size, uint32_t *mbox_error)
343 {
344 	int status;
345 	uint32_t payload_size;
346 	uint32_t resp_len = FCS_CRYPTION_RESP_WORD_SIZE;
347 	uint32_t resp_data[FCS_CRYPTION_RESP_WORD_SIZE] = {0U};
348 
349 	if ((dst_size == NULL) || (mbox_error == NULL)) {
350 		return INTEL_SIP_SMC_STATUS_REJECTED;
351 	}
352 
353 	if (!is_address_in_ddr_range(src_addr, src_size) ||
354 		!is_address_in_ddr_range(dst_addr, *dst_size)) {
355 		return INTEL_SIP_SMC_STATUS_REJECTED;
356 	}
357 
358 	if (!is_size_4_bytes_aligned(src_size)) {
359 		return INTEL_SIP_SMC_STATUS_REJECTED;
360 	}
361 
362 	fcs_encrypt_ext_payload payload = {
363 		session_id,
364 		context_id,
365 		FCS_CRYPTION_CRYPTO_HEADER,
366 		src_addr,
367 		src_size,
368 		dst_addr,
369 		*dst_size
370 	};
371 
372 	payload_size = sizeof(payload) / MBOX_WORD_BYTE;
373 
374 	status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_ENCRYPT_REQ,
375 				(uint32_t *) &payload, payload_size,
376 				CMD_CASUAL, resp_data, &resp_len);
377 
378 	if (status < 0) {
379 		*mbox_error = -status;
380 		return INTEL_SIP_SMC_STATUS_ERROR;
381 	}
382 
383 	if (resp_len != FCS_CRYPTION_RESP_WORD_SIZE) {
384 		*mbox_error = MBOX_RET_ERROR;
385 		return INTEL_SIP_SMC_STATUS_ERROR;
386 	}
387 
388 	*dst_size = resp_data[FCS_CRYPTION_RESP_SIZE_OFFSET];
389 	inv_dcache_range(dst_addr, *dst_size);
390 
391 	return INTEL_SIP_SMC_STATUS_OK;
392 }
393 
394 int intel_fcs_decryption_ext(uint32_t session_id, uint32_t context_id,
395 		uint32_t src_addr, uint32_t src_size,
396 		uint32_t dst_addr, uint32_t *dst_size, uint32_t *mbox_error)
397 {
398 	int status;
399 	uintptr_t id_offset;
400 	uint32_t payload_size;
401 	uint32_t resp_len = FCS_CRYPTION_RESP_WORD_SIZE;
402 	uint32_t resp_data[FCS_CRYPTION_RESP_WORD_SIZE] = {0U};
403 
404 	if ((dst_size == NULL) || (mbox_error == NULL)) {
405 		return INTEL_SIP_SMC_STATUS_REJECTED;
406 	}
407 
408 	if (!is_address_in_ddr_range(src_addr, src_size) ||
409 		!is_address_in_ddr_range(dst_addr, *dst_size)) {
410 		return INTEL_SIP_SMC_STATUS_REJECTED;
411 	}
412 
413 	if (!is_size_4_bytes_aligned(src_size)) {
414 		return INTEL_SIP_SMC_STATUS_REJECTED;
415 	}
416 
417 	id_offset = src_addr + FCS_OWNER_ID_OFFSET;
418 	fcs_decrypt_ext_payload payload = {
419 		session_id,
420 		context_id,
421 		FCS_CRYPTION_CRYPTO_HEADER,
422 		{mmio_read_32(id_offset),
423 		mmio_read_32(id_offset + MBOX_WORD_BYTE)},
424 		src_addr,
425 		src_size,
426 		dst_addr,
427 		*dst_size
428 	};
429 
430 	payload_size = sizeof(payload) / MBOX_WORD_BYTE;
431 
432 	status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_DECRYPT_REQ,
433 				(uint32_t *) &payload, payload_size,
434 				CMD_CASUAL, resp_data, &resp_len);
435 
436 	if (status < 0) {
437 		*mbox_error = -status;
438 		return INTEL_SIP_SMC_STATUS_ERROR;
439 	}
440 
441 	if (resp_len != FCS_CRYPTION_RESP_WORD_SIZE) {
442 		*mbox_error = MBOX_RET_ERROR;
443 		return INTEL_SIP_SMC_STATUS_ERROR;
444 	}
445 
446 	*dst_size = resp_data[FCS_CRYPTION_RESP_SIZE_OFFSET];
447 	inv_dcache_range(dst_addr, *dst_size);
448 
449 	return INTEL_SIP_SMC_STATUS_OK;
450 }
451 
452 int intel_fcs_sigma_teardown(uint32_t session_id, uint32_t *mbox_error)
453 {
454 	int status;
455 
456 	if ((session_id != PSGSIGMA_SESSION_ID_ONE) &&
457 		(session_id != PSGSIGMA_UNKNOWN_SESSION)) {
458 		return INTEL_SIP_SMC_STATUS_REJECTED;
459 	}
460 
461 	psgsigma_teardown_msg message = {
462 		RESERVED_AS_ZERO,
463 		PSGSIGMA_TEARDOWN_MAGIC,
464 		session_id
465 	};
466 
467 	status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_PSG_SIGMA_TEARDOWN,
468 			(uint32_t *) &message, sizeof(message) / MBOX_WORD_BYTE,
469 			CMD_CASUAL, NULL, NULL);
470 
471 	if (status < 0) {
472 		*mbox_error = -status;
473 		return INTEL_SIP_SMC_STATUS_ERROR;
474 	}
475 
476 	return INTEL_SIP_SMC_STATUS_OK;
477 }
478 
479 int intel_fcs_chip_id(uint32_t *id_low, uint32_t *id_high, uint32_t *mbox_error)
480 {
481 	int status;
482 	uint32_t load_size;
483 	uint32_t chip_id[2];
484 
485 	load_size = sizeof(chip_id) / MBOX_WORD_BYTE;
486 
487 	status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_CMD_GET_CHIPID, NULL,
488 			0U, CMD_CASUAL, (uint32_t *) chip_id, &load_size);
489 
490 	if (status < 0) {
491 		*mbox_error = -status;
492 		return INTEL_SIP_SMC_STATUS_ERROR;
493 	}
494 
495 	*id_low = chip_id[0];
496 	*id_high = chip_id[1];
497 
498 	return INTEL_SIP_SMC_STATUS_OK;
499 }
500 
501 int intel_fcs_attestation_subkey(uint64_t src_addr, uint32_t src_size,
502 		uint64_t dst_addr, uint32_t *dst_size, uint32_t *mbox_error)
503 {
504 	int status;
505 	uint32_t send_size = src_size / MBOX_WORD_BYTE;
506 	uint32_t ret_size = *dst_size / MBOX_WORD_BYTE;
507 
508 
509 	if (!is_address_in_ddr_range(src_addr, src_size) ||
510 		!is_address_in_ddr_range(dst_addr, *dst_size)) {
511 		return INTEL_SIP_SMC_STATUS_REJECTED;
512 	}
513 
514 	status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_ATTESTATION_SUBKEY,
515 			(uint32_t *) src_addr, send_size, CMD_CASUAL,
516 			(uint32_t *) dst_addr, &ret_size);
517 
518 	if (status < 0) {
519 		*mbox_error = -status;
520 		return INTEL_SIP_SMC_STATUS_ERROR;
521 	}
522 
523 	*dst_size = ret_size * MBOX_WORD_BYTE;
524 	flush_dcache_range(dst_addr, *dst_size);
525 
526 	return INTEL_SIP_SMC_STATUS_OK;
527 }
528 
529 int intel_fcs_get_measurement(uint64_t src_addr, uint32_t src_size,
530 		uint64_t dst_addr, uint32_t *dst_size, uint32_t *mbox_error)
531 {
532 	int status;
533 	uint32_t send_size = src_size / MBOX_WORD_BYTE;
534 	uint32_t ret_size = *dst_size / MBOX_WORD_BYTE;
535 
536 	if (!is_address_in_ddr_range(src_addr, src_size) ||
537 		!is_address_in_ddr_range(dst_addr, *dst_size)) {
538 		return INTEL_SIP_SMC_STATUS_REJECTED;
539 	}
540 
541 	status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_GET_MEASUREMENT,
542 			(uint32_t *) src_addr, send_size, CMD_CASUAL,
543 			(uint32_t *) dst_addr, &ret_size);
544 
545 	if (status < 0) {
546 		*mbox_error = -status;
547 		return INTEL_SIP_SMC_STATUS_ERROR;
548 	}
549 
550 	*dst_size = ret_size * MBOX_WORD_BYTE;
551 	flush_dcache_range(dst_addr, *dst_size);
552 
553 	return INTEL_SIP_SMC_STATUS_OK;
554 }
555 
556 int intel_fcs_get_attestation_cert(uint32_t cert_request, uint64_t dst_addr,
557 			uint32_t *dst_size, uint32_t *mbox_error)
558 {
559 	int status;
560 	uint32_t ret_size = *dst_size / MBOX_WORD_BYTE;
561 
562 	if (mbox_error == NULL) {
563 		return INTEL_SIP_SMC_STATUS_REJECTED;
564 	}
565 
566 	if (cert_request < FCS_ALIAS_CERT ||
567 		cert_request >
568 			(FCS_ALIAS_CERT |
569 			FCS_DEV_ID_SELF_SIGN_CERT |
570 			FCS_DEV_ID_ENROLL_CERT |
571 			FCS_ENROLL_SELF_SIGN_CERT |
572 			FCS_PLAT_KEY_CERT)) {
573 		return INTEL_SIP_SMC_STATUS_REJECTED;
574 	}
575 
576 	if (!is_address_in_ddr_range(dst_addr, *dst_size)) {
577 		return INTEL_SIP_SMC_STATUS_REJECTED;
578 	}
579 
580 	status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_GET_ATTESTATION_CERT,
581 			(uint32_t *) &cert_request, 1U, CMD_CASUAL,
582 			(uint32_t *) dst_addr, &ret_size);
583 
584 	if (status < 0) {
585 		*mbox_error = -status;
586 		return INTEL_SIP_SMC_STATUS_ERROR;
587 	}
588 
589 	*dst_size = ret_size * MBOX_WORD_BYTE;
590 	flush_dcache_range(dst_addr, *dst_size);
591 
592 	return INTEL_SIP_SMC_STATUS_OK;
593 }
594 
595 int intel_fcs_create_cert_on_reload(uint32_t cert_request,
596 			uint32_t *mbox_error)
597 {
598 	int status;
599 
600 	if (mbox_error == NULL) {
601 		return INTEL_SIP_SMC_STATUS_REJECTED;
602 	}
603 
604 	if (cert_request < FCS_ALIAS_CERT ||
605 		cert_request >
606 			(FCS_ALIAS_CERT |
607 			FCS_DEV_ID_SELF_SIGN_CERT |
608 			FCS_DEV_ID_ENROLL_CERT |
609 			FCS_ENROLL_SELF_SIGN_CERT |
610 			FCS_PLAT_KEY_CERT)) {
611 		return INTEL_SIP_SMC_STATUS_REJECTED;
612 	}
613 
614 	status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_CREATE_CERT_ON_RELOAD,
615 			(uint32_t *) &cert_request, 1U, CMD_CASUAL,
616 			NULL, NULL);
617 
618 	if (status < 0) {
619 		*mbox_error = -status;
620 		return INTEL_SIP_SMC_STATUS_ERROR;
621 	}
622 
623 	return INTEL_SIP_SMC_STATUS_OK;
624 }
625 
626 int intel_fcs_open_crypto_service_session(uint32_t *session_id,
627 			uint32_t *mbox_error)
628 {
629 	int status;
630 	uint32_t resp_len = 1U;
631 
632 	if ((session_id == NULL) || (mbox_error == NULL)) {
633 		return INTEL_SIP_SMC_STATUS_REJECTED;
634 	}
635 
636 	status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_OPEN_CS_SESSION,
637 			NULL, 0U, CMD_CASUAL, session_id, &resp_len);
638 
639 	if (status < 0) {
640 		*mbox_error = -status;
641 		return INTEL_SIP_SMC_STATUS_ERROR;
642 	}
643 
644 	return INTEL_SIP_SMC_STATUS_OK;
645 }
646 
647 int intel_fcs_close_crypto_service_session(uint32_t session_id,
648 			uint32_t *mbox_error)
649 {
650 	int status;
651 
652 	if (mbox_error == NULL) {
653 		return INTEL_SIP_SMC_STATUS_REJECTED;
654 	}
655 
656 	status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_CLOSE_CS_SESSION,
657 			&session_id, 1U, CMD_CASUAL, NULL, NULL);
658 
659 	if (status < 0) {
660 		*mbox_error = -status;
661 		return INTEL_SIP_SMC_STATUS_ERROR;
662 	}
663 
664 	return INTEL_SIP_SMC_STATUS_OK;
665 }
666 
667 int intel_fcs_import_crypto_service_key(uint64_t src_addr, uint32_t src_size,
668 		uint32_t *send_id)
669 {
670 	int status;
671 
672 	if (src_size > (FCS_CS_KEY_OBJ_MAX_WORD_SIZE *
673 		MBOX_WORD_BYTE)) {
674 		return INTEL_SIP_SMC_STATUS_REJECTED;
675 	}
676 
677 	if (!is_address_in_ddr_range(src_addr, src_size)) {
678 		return INTEL_SIP_SMC_STATUS_REJECTED;
679 	}
680 
681 	status = mailbox_send_cmd_async(send_id, MBOX_FCS_IMPORT_CS_KEY,
682 				(uint32_t *)src_addr, src_size / MBOX_WORD_BYTE,
683 				CMD_INDIRECT);
684 
685 	if (status < 0) {
686 		return INTEL_SIP_SMC_STATUS_ERROR;
687 	}
688 
689 	return INTEL_SIP_SMC_STATUS_OK;
690 }
691 
692 int intel_fcs_export_crypto_service_key(uint32_t session_id, uint32_t key_id,
693 		uint64_t dst_addr, uint32_t *dst_size,
694 		uint32_t *mbox_error)
695 {
696 	int status;
697 	uint32_t i;
698 	uint32_t payload_size;
699 	uint32_t resp_len = FCS_CS_KEY_OBJ_MAX_WORD_SIZE;
700 	uint32_t resp_data[FCS_CS_KEY_OBJ_MAX_WORD_SIZE] = {0U};
701 	uint32_t op_status = 0U;
702 
703 	if ((dst_size == NULL) || (mbox_error == NULL)) {
704 		return INTEL_SIP_SMC_STATUS_REJECTED;
705 	}
706 
707 	if (!is_address_in_ddr_range(dst_addr, *dst_size)) {
708 		return INTEL_SIP_SMC_STATUS_REJECTED;
709 	}
710 
711 	fcs_cs_key_payload payload = {
712 		session_id,
713 		RESERVED_AS_ZERO,
714 		RESERVED_AS_ZERO,
715 		key_id
716 	};
717 
718 	payload_size = sizeof(payload) / MBOX_WORD_BYTE;
719 
720 	status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_EXPORT_CS_KEY,
721 			(uint32_t *) &payload, payload_size,
722 			CMD_CASUAL, resp_data, &resp_len);
723 
724 	if (resp_len > 0) {
725 		op_status = resp_data[0] & FCS_CS_KEY_RESP_STATUS_MASK;
726 	}
727 
728 	if (status < 0) {
729 		*mbox_error = (-status) | (op_status << FCS_CS_KEY_RESP_STATUS_OFFSET);
730 		return INTEL_SIP_SMC_STATUS_ERROR;
731 	}
732 
733 	if (resp_len > 1) {
734 
735 		/* Export key object is start at second response data */
736 		*dst_size = (resp_len - 1) * MBOX_WORD_BYTE;
737 
738 		for (i = 1U; i < resp_len; i++) {
739 			mmio_write_32(dst_addr, resp_data[i]);
740 			dst_addr += MBOX_WORD_BYTE;
741 		}
742 
743 		flush_dcache_range(dst_addr - *dst_size, *dst_size);
744 
745 	} else {
746 
747 		/* Unexpected response, missing key object in response */
748 		*mbox_error = MBOX_RET_ERROR;
749 		return INTEL_SIP_SMC_STATUS_ERROR;
750 	}
751 
752 	return INTEL_SIP_SMC_STATUS_OK;
753 }
754 
755 int intel_fcs_remove_crypto_service_key(uint32_t session_id, uint32_t key_id,
756 		uint32_t *mbox_error)
757 {
758 	int status;
759 	uint32_t payload_size;
760 	uint32_t resp_len = 1U;
761 	uint32_t resp_data = 0U;
762 	uint32_t op_status = 0U;
763 
764 	if (mbox_error == NULL) {
765 		return INTEL_SIP_SMC_STATUS_REJECTED;
766 	}
767 
768 	fcs_cs_key_payload payload = {
769 		session_id,
770 		RESERVED_AS_ZERO,
771 		RESERVED_AS_ZERO,
772 		key_id
773 	};
774 
775 	payload_size = sizeof(payload) / MBOX_WORD_BYTE;
776 
777 	status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_REMOVE_CS_KEY,
778 			(uint32_t *) &payload, payload_size,
779 			CMD_CASUAL, &resp_data, &resp_len);
780 
781 	if (resp_len > 0) {
782 		op_status = resp_data & FCS_CS_KEY_RESP_STATUS_MASK;
783 	}
784 
785 	if (status < 0) {
786 		*mbox_error = (-status) | (op_status << FCS_CS_KEY_RESP_STATUS_OFFSET);
787 		return INTEL_SIP_SMC_STATUS_ERROR;
788 	}
789 
790 	return INTEL_SIP_SMC_STATUS_OK;
791 }
792 
793 int intel_fcs_get_crypto_service_key_info(uint32_t session_id, uint32_t key_id,
794 		uint64_t dst_addr, uint32_t *dst_size,
795 		uint32_t *mbox_error)
796 {
797 	int status;
798 	uint32_t payload_size;
799 	uint32_t resp_len = FCS_CS_KEY_INFO_MAX_WORD_SIZE;
800 	uint32_t op_status = 0U;
801 
802 	if ((dst_size == NULL) || (mbox_error == NULL)) {
803 		return INTEL_SIP_SMC_STATUS_REJECTED;
804 	}
805 
806 	if (!is_address_in_ddr_range(dst_addr, *dst_size)) {
807 		return INTEL_SIP_SMC_STATUS_REJECTED;
808 	}
809 
810 	fcs_cs_key_payload payload = {
811 		session_id,
812 		RESERVED_AS_ZERO,
813 		RESERVED_AS_ZERO,
814 		key_id
815 	};
816 
817 	payload_size = sizeof(payload) / MBOX_WORD_BYTE;
818 
819 	status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_GET_CS_KEY_INFO,
820 				(uint32_t *) &payload, payload_size,
821 				CMD_CASUAL, (uint32_t *) dst_addr, &resp_len);
822 
823 	if (resp_len > 0) {
824 		op_status = mmio_read_32(dst_addr) &
825 			FCS_CS_KEY_RESP_STATUS_MASK;
826 	}
827 
828 	if (status < 0) {
829 		*mbox_error = (-status) | (op_status << FCS_CS_KEY_RESP_STATUS_OFFSET);
830 		return INTEL_SIP_SMC_STATUS_ERROR;
831 	}
832 
833 	*dst_size = resp_len * MBOX_WORD_BYTE;
834 	flush_dcache_range(dst_addr, *dst_size);
835 
836 	return INTEL_SIP_SMC_STATUS_OK;
837 }
838 
839 int intel_fcs_get_digest_init(uint32_t session_id, uint32_t context_id,
840 				uint32_t key_id, uint32_t param_size,
841 				uint64_t param_data, uint32_t *mbox_error)
842 {
843 	return intel_fcs_crypto_service_init(session_id, context_id,
844 				key_id, param_size, param_data,
845 				(void *) &fcs_sha_get_digest_param,
846 				mbox_error);
847 }
848 
849 int intel_fcs_get_digest_finalize(uint32_t session_id, uint32_t context_id,
850 				uint32_t src_addr, uint32_t src_size,
851 				uint64_t dst_addr, uint32_t *dst_size,
852 				uint32_t *mbox_error)
853 {
854 	int status;
855 	uint32_t i;
856 	uint32_t resp_len = *dst_size / MBOX_WORD_BYTE;
857 	uint32_t payload[FCS_GET_DIGEST_CMD_MAX_WORD_SIZE] = {0U};
858 
859 	if (dst_size == NULL || mbox_error == NULL) {
860 		return INTEL_SIP_SMC_STATUS_REJECTED;
861 	}
862 
863 	if (fcs_sha_get_digest_param.session_id != session_id ||
864 	    fcs_sha_get_digest_param.context_id != context_id) {
865 		return INTEL_SIP_SMC_STATUS_REJECTED;
866 	}
867 
868 	/* Source data must be 8 bytes aligned */
869 	if (!is_8_bytes_aligned(src_size)) {
870 		return INTEL_SIP_SMC_STATUS_REJECTED;
871 	}
872 
873 	if (!is_address_in_ddr_range(src_addr, src_size) ||
874 		 !is_address_in_ddr_range(dst_addr, *dst_size)) {
875 		return INTEL_SIP_SMC_STATUS_REJECTED;
876 	}
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 = *dst_size / MBOX_WORD_BYTE;
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 	/* Prepare command payload */
969 	i = 0;
970 	/* Crypto header */
971 	payload[i] = fcs_sha_mac_verify_param.session_id;
972 	i++;
973 	payload[i] = fcs_sha_mac_verify_param.context_id;
974 	i++;
975 	payload[i] = fcs_sha_mac_verify_param.crypto_param_size
976 			& FCS_CS_FIELD_SIZE_MASK;
977 	payload[i] |= (FCS_CS_FIELD_FLAG_INIT | FCS_CS_FIELD_FLAG_UPDATE
978 			| FCS_CS_FIELD_FLAG_FINALIZE)
979 			<< FCS_CS_FIELD_FLAG_OFFSET;
980 	i++;
981 	payload[i] = fcs_sha_mac_verify_param.key_id;
982 	i++;
983 	/* Crypto parameters */
984 	payload[i] = ((fcs_sha_mac_verify_param.crypto_param
985 			>> INTEL_SIP_SMC_FCS_DIGEST_SIZE_OFFSET)
986 			& INTEL_SIP_SMC_FCS_DIGEST_SIZE_MASK)
987 			<< FCS_SHA_HMAC_CRYPTO_PARAM_SIZE_OFFSET;
988 	i++;
989 	/* Data source address and size */
990 	payload[i] = src_addr;
991 	i++;
992 	payload[i] = data_size;
993 	i++;
994 	/* Copy mac data to command */
995 	mac_offset = src_addr + data_size;
996 	memcpy((uint8_t *) &payload[i], (uint8_t *) mac_offset,
997 				src_size - data_size);
998 
999 	i += (src_size - data_size) / MBOX_WORD_BYTE;
1000 
1001 	status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_MAC_VERIFY_REQ,
1002 				payload, i, CMD_CASUAL,
1003 				(uint32_t *) dst_addr, &resp_len);
1004 
1005 	memset((void *)&fcs_sha_mac_verify_param, 0,
1006 				sizeof(fcs_crypto_service_data));
1007 
1008 	if (status < 0) {
1009 		*mbox_error = -status;
1010 		return INTEL_SIP_SMC_STATUS_ERROR;
1011 	}
1012 
1013 	*dst_size = resp_len * MBOX_WORD_BYTE;
1014 	flush_dcache_range(dst_addr, *dst_size);
1015 
1016 	return INTEL_SIP_SMC_STATUS_OK;
1017 }
1018 
1019 int intel_fcs_aes_crypt_init(uint32_t session_id, uint32_t context_id,
1020 				uint32_t key_id, uint64_t param_addr,
1021 				uint32_t param_size, uint32_t *mbox_error)
1022 {
1023 	if (mbox_error == NULL) {
1024 		return INTEL_SIP_SMC_STATUS_REJECTED;
1025 	}
1026 
1027 	memset((void *)&fcs_aes_init_payload, 0U, sizeof(fcs_aes_init_payload));
1028 
1029 	fcs_aes_init_payload.session_id = session_id;
1030 	fcs_aes_init_payload.context_id = context_id;
1031 	fcs_aes_init_payload.param_size = param_size;
1032 	fcs_aes_init_payload.key_id	= key_id;
1033 
1034 	memcpy((uint8_t *) fcs_aes_init_payload.crypto_param,
1035 		(uint8_t *) param_addr, param_size);
1036 
1037 	*mbox_error = 0;
1038 
1039 	return INTEL_SIP_SMC_STATUS_OK;
1040 }
1041 
1042 int intel_fcs_aes_crypt_finalize(uint32_t session_id, uint32_t context_id,
1043 				uint64_t src_addr, uint32_t src_size,
1044 				uint64_t dst_addr, uint32_t dst_size,
1045 				uint32_t *send_id)
1046 {
1047 	int status;
1048 	int i;
1049 	uint32_t crypto_header;
1050 	uint32_t fcs_aes_crypt_payload[FCS_AES_CMD_MAX_WORD_SIZE];
1051 
1052 	if (fcs_aes_init_payload.session_id != session_id ||
1053 		fcs_aes_init_payload.context_id != context_id) {
1054 		return INTEL_SIP_SMC_STATUS_REJECTED;
1055 	}
1056 
1057 	if ((!is_8_bytes_aligned(src_addr)) ||
1058 		(!is_32_bytes_aligned(src_size)) ||
1059 		(!is_address_in_ddr_range(src_addr, src_size))) {
1060 		return INTEL_SIP_SMC_STATUS_REJECTED;
1061 	}
1062 
1063 	if ((!is_8_bytes_aligned(dst_addr)) ||
1064 		(!is_32_bytes_aligned(dst_size))) {
1065 		return INTEL_SIP_SMC_STATUS_REJECTED;
1066 	}
1067 
1068 	if ((dst_size > FCS_AES_MAX_DATA_SIZE ||
1069 		dst_size < FCS_AES_MIN_DATA_SIZE) ||
1070 		(src_size > FCS_AES_MAX_DATA_SIZE ||
1071 		src_size < FCS_AES_MIN_DATA_SIZE)) {
1072 		return INTEL_SIP_SMC_STATUS_REJECTED;
1073 	}
1074 
1075 	crypto_header = ((FCS_CS_FIELD_FLAG_INIT |
1076 			FCS_CS_FIELD_FLAG_UPDATE |
1077 			FCS_CS_FIELD_FLAG_FINALIZE) <<
1078 			FCS_CS_FIELD_FLAG_OFFSET) |
1079 			fcs_aes_init_payload.param_size;
1080 	i = 0U;
1081 	fcs_aes_crypt_payload[i] = session_id;
1082 	i++;
1083 	fcs_aes_crypt_payload[i] = context_id;
1084 	i++;
1085 	fcs_aes_crypt_payload[i] = crypto_header;
1086 	i++;
1087 	fcs_aes_crypt_payload[i] = fcs_aes_init_payload.key_id;
1088 
1089 	i++;
1090 	memcpy((uint8_t *) &fcs_aes_crypt_payload[i],
1091 		(uint8_t *) fcs_aes_init_payload.crypto_param,
1092 		fcs_aes_init_payload.param_size);
1093 
1094 	i += fcs_aes_init_payload.param_size / MBOX_WORD_BYTE;
1095 
1096 	fcs_aes_crypt_payload[i] = (uint32_t) src_addr;
1097 	i++;
1098 	fcs_aes_crypt_payload[i] = src_size;
1099 	i++;
1100 	fcs_aes_crypt_payload[i] = (uint32_t) dst_addr;
1101 	i++;
1102 	fcs_aes_crypt_payload[i] = dst_size;
1103 	i++;
1104 
1105 	status = mailbox_send_cmd_async(send_id, MBOX_FCS_AES_CRYPT_REQ,
1106 					fcs_aes_crypt_payload, i,
1107 					CMD_INDIRECT);
1108 
1109 	memset((void *)&fcs_aes_init_payload, 0U, sizeof(fcs_aes_init_payload));
1110 
1111 	if (status < 0U) {
1112 		return INTEL_SIP_SMC_STATUS_ERROR;
1113 	}
1114 
1115 	return INTEL_SIP_SMC_STATUS_OK;
1116 }
1117