xref: /rk3399_ARM-atf/plat/intel/soc/common/sip/socfpga_sip_fcs.c (revision 6726390eb02e9659cfaf2d3598be9bf12fbc5901)
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_sigma_teardown(uint32_t session_id, uint32_t *mbox_error)
341 {
342 	int status;
343 
344 	if ((session_id != PSGSIGMA_SESSION_ID_ONE) &&
345 		(session_id != PSGSIGMA_UNKNOWN_SESSION)) {
346 		return INTEL_SIP_SMC_STATUS_REJECTED;
347 	}
348 
349 	psgsigma_teardown_msg message = {
350 		RESERVED_AS_ZERO,
351 		PSGSIGMA_TEARDOWN_MAGIC,
352 		session_id
353 	};
354 
355 	status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_PSG_SIGMA_TEARDOWN,
356 			(uint32_t *) &message, sizeof(message) / MBOX_WORD_BYTE,
357 			CMD_CASUAL, NULL, NULL);
358 
359 	if (status < 0) {
360 		*mbox_error = -status;
361 		return INTEL_SIP_SMC_STATUS_ERROR;
362 	}
363 
364 	return INTEL_SIP_SMC_STATUS_OK;
365 }
366 
367 int intel_fcs_chip_id(uint32_t *id_low, uint32_t *id_high, uint32_t *mbox_error)
368 {
369 	int status;
370 	uint32_t load_size;
371 	uint32_t chip_id[2];
372 
373 	load_size = sizeof(chip_id) / MBOX_WORD_BYTE;
374 
375 	status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_CMD_GET_CHIPID, NULL,
376 			0U, CMD_CASUAL, (uint32_t *) chip_id, &load_size);
377 
378 	if (status < 0) {
379 		*mbox_error = -status;
380 		return INTEL_SIP_SMC_STATUS_ERROR;
381 	}
382 
383 	*id_low = chip_id[0];
384 	*id_high = chip_id[1];
385 
386 	return INTEL_SIP_SMC_STATUS_OK;
387 }
388 
389 int intel_fcs_attestation_subkey(uint64_t src_addr, uint32_t src_size,
390 		uint64_t dst_addr, uint32_t *dst_size, uint32_t *mbox_error)
391 {
392 	int status;
393 	uint32_t send_size = src_size / MBOX_WORD_BYTE;
394 	uint32_t ret_size = *dst_size / MBOX_WORD_BYTE;
395 
396 
397 	if (!is_address_in_ddr_range(src_addr, src_size) ||
398 		!is_address_in_ddr_range(dst_addr, *dst_size)) {
399 		return INTEL_SIP_SMC_STATUS_REJECTED;
400 	}
401 
402 	status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_ATTESTATION_SUBKEY,
403 			(uint32_t *) src_addr, send_size, CMD_CASUAL,
404 			(uint32_t *) dst_addr, &ret_size);
405 
406 	if (status < 0) {
407 		*mbox_error = -status;
408 		return INTEL_SIP_SMC_STATUS_ERROR;
409 	}
410 
411 	*dst_size = ret_size * MBOX_WORD_BYTE;
412 	flush_dcache_range(dst_addr, *dst_size);
413 
414 	return INTEL_SIP_SMC_STATUS_OK;
415 }
416 
417 int intel_fcs_get_measurement(uint64_t src_addr, uint32_t src_size,
418 		uint64_t dst_addr, uint32_t *dst_size, uint32_t *mbox_error)
419 {
420 	int status;
421 	uint32_t send_size = src_size / MBOX_WORD_BYTE;
422 	uint32_t ret_size = *dst_size / MBOX_WORD_BYTE;
423 
424 	if (!is_address_in_ddr_range(src_addr, src_size) ||
425 		!is_address_in_ddr_range(dst_addr, *dst_size)) {
426 		return INTEL_SIP_SMC_STATUS_REJECTED;
427 	}
428 
429 	status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_GET_MEASUREMENT,
430 			(uint32_t *) src_addr, send_size, CMD_CASUAL,
431 			(uint32_t *) dst_addr, &ret_size);
432 
433 	if (status < 0) {
434 		*mbox_error = -status;
435 		return INTEL_SIP_SMC_STATUS_ERROR;
436 	}
437 
438 	*dst_size = ret_size * MBOX_WORD_BYTE;
439 	flush_dcache_range(dst_addr, *dst_size);
440 
441 	return INTEL_SIP_SMC_STATUS_OK;
442 }
443 
444 int intel_fcs_get_attestation_cert(uint32_t cert_request, uint64_t dst_addr,
445 			uint32_t *dst_size, uint32_t *mbox_error)
446 {
447 	int status;
448 	uint32_t ret_size = *dst_size / MBOX_WORD_BYTE;
449 
450 	if (mbox_error == NULL) {
451 		return INTEL_SIP_SMC_STATUS_REJECTED;
452 	}
453 
454 	if (cert_request < FCS_ALIAS_CERT ||
455 		cert_request >
456 			(FCS_ALIAS_CERT |
457 			FCS_DEV_ID_SELF_SIGN_CERT |
458 			FCS_DEV_ID_ENROLL_CERT |
459 			FCS_ENROLL_SELF_SIGN_CERT |
460 			FCS_PLAT_KEY_CERT)) {
461 		return INTEL_SIP_SMC_STATUS_REJECTED;
462 	}
463 
464 	if (!is_address_in_ddr_range(dst_addr, *dst_size)) {
465 		return INTEL_SIP_SMC_STATUS_REJECTED;
466 	}
467 
468 	status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_GET_ATTESTATION_CERT,
469 			(uint32_t *) &cert_request, 1U, CMD_CASUAL,
470 			(uint32_t *) dst_addr, &ret_size);
471 
472 	if (status < 0) {
473 		*mbox_error = -status;
474 		return INTEL_SIP_SMC_STATUS_ERROR;
475 	}
476 
477 	*dst_size = ret_size * MBOX_WORD_BYTE;
478 	flush_dcache_range(dst_addr, *dst_size);
479 
480 	return INTEL_SIP_SMC_STATUS_OK;
481 }
482 
483 int intel_fcs_create_cert_on_reload(uint32_t cert_request,
484 			uint32_t *mbox_error)
485 {
486 	int status;
487 
488 	if (mbox_error == NULL) {
489 		return INTEL_SIP_SMC_STATUS_REJECTED;
490 	}
491 
492 	if (cert_request < FCS_ALIAS_CERT ||
493 		cert_request >
494 			(FCS_ALIAS_CERT |
495 			FCS_DEV_ID_SELF_SIGN_CERT |
496 			FCS_DEV_ID_ENROLL_CERT |
497 			FCS_ENROLL_SELF_SIGN_CERT |
498 			FCS_PLAT_KEY_CERT)) {
499 		return INTEL_SIP_SMC_STATUS_REJECTED;
500 	}
501 
502 	status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_CREATE_CERT_ON_RELOAD,
503 			(uint32_t *) &cert_request, 1U, CMD_CASUAL,
504 			NULL, NULL);
505 
506 	if (status < 0) {
507 		*mbox_error = -status;
508 		return INTEL_SIP_SMC_STATUS_ERROR;
509 	}
510 
511 	return INTEL_SIP_SMC_STATUS_OK;
512 }
513 
514 int intel_fcs_open_crypto_service_session(uint32_t *session_id,
515 			uint32_t *mbox_error)
516 {
517 	int status;
518 	uint32_t resp_len = 1U;
519 
520 	if ((session_id == NULL) || (mbox_error == NULL)) {
521 		return INTEL_SIP_SMC_STATUS_REJECTED;
522 	}
523 
524 	status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_OPEN_CS_SESSION,
525 			NULL, 0U, CMD_CASUAL, session_id, &resp_len);
526 
527 	if (status < 0) {
528 		*mbox_error = -status;
529 		return INTEL_SIP_SMC_STATUS_ERROR;
530 	}
531 
532 	return INTEL_SIP_SMC_STATUS_OK;
533 }
534 
535 int intel_fcs_close_crypto_service_session(uint32_t session_id,
536 			uint32_t *mbox_error)
537 {
538 	int status;
539 
540 	if (mbox_error == NULL) {
541 		return INTEL_SIP_SMC_STATUS_REJECTED;
542 	}
543 
544 	status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_CLOSE_CS_SESSION,
545 			&session_id, 1U, CMD_CASUAL, NULL, NULL);
546 
547 	if (status < 0) {
548 		*mbox_error = -status;
549 		return INTEL_SIP_SMC_STATUS_ERROR;
550 	}
551 
552 	return INTEL_SIP_SMC_STATUS_OK;
553 }
554 
555 int intel_fcs_import_crypto_service_key(uint64_t src_addr, uint32_t src_size,
556 		uint32_t *send_id)
557 {
558 	int status;
559 
560 	if (src_size > (FCS_CS_KEY_OBJ_MAX_WORD_SIZE *
561 		MBOX_WORD_BYTE)) {
562 		return INTEL_SIP_SMC_STATUS_REJECTED;
563 	}
564 
565 	if (!is_address_in_ddr_range(src_addr, src_size)) {
566 		return INTEL_SIP_SMC_STATUS_REJECTED;
567 	}
568 
569 	status = mailbox_send_cmd_async(send_id, MBOX_FCS_IMPORT_CS_KEY,
570 				(uint32_t *)src_addr, src_size / MBOX_WORD_BYTE,
571 				CMD_INDIRECT);
572 
573 	if (status < 0) {
574 		return INTEL_SIP_SMC_STATUS_ERROR;
575 	}
576 
577 	return INTEL_SIP_SMC_STATUS_OK;
578 }
579 
580 int intel_fcs_export_crypto_service_key(uint32_t session_id, uint32_t key_id,
581 		uint64_t dst_addr, uint32_t *dst_size,
582 		uint32_t *mbox_error)
583 {
584 	int status;
585 	uint32_t i;
586 	uint32_t payload_size;
587 	uint32_t resp_len = FCS_CS_KEY_OBJ_MAX_WORD_SIZE;
588 	uint32_t resp_data[FCS_CS_KEY_OBJ_MAX_WORD_SIZE] = {0U};
589 	uint32_t op_status = 0U;
590 
591 	if ((dst_size == NULL) || (mbox_error == NULL)) {
592 		return INTEL_SIP_SMC_STATUS_REJECTED;
593 	}
594 
595 	if (!is_address_in_ddr_range(dst_addr, *dst_size)) {
596 		return INTEL_SIP_SMC_STATUS_REJECTED;
597 	}
598 
599 	fcs_cs_key_payload payload = {
600 		session_id,
601 		RESERVED_AS_ZERO,
602 		RESERVED_AS_ZERO,
603 		key_id
604 	};
605 
606 	payload_size = sizeof(payload) / MBOX_WORD_BYTE;
607 
608 	status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_EXPORT_CS_KEY,
609 			(uint32_t *) &payload, payload_size,
610 			CMD_CASUAL, resp_data, &resp_len);
611 
612 	if (resp_len > 0) {
613 		op_status = resp_data[0] & FCS_CS_KEY_RESP_STATUS_MASK;
614 	}
615 
616 	if (status < 0) {
617 		*mbox_error = (-status) | (op_status << FCS_CS_KEY_RESP_STATUS_OFFSET);
618 		return INTEL_SIP_SMC_STATUS_ERROR;
619 	}
620 
621 	if (resp_len > 1) {
622 
623 		/* Export key object is start at second response data */
624 		*dst_size = (resp_len - 1) * MBOX_WORD_BYTE;
625 
626 		for (i = 1U; i < resp_len; i++) {
627 			mmio_write_32(dst_addr, resp_data[i]);
628 			dst_addr += MBOX_WORD_BYTE;
629 		}
630 
631 		flush_dcache_range(dst_addr - *dst_size, *dst_size);
632 
633 	} else {
634 
635 		/* Unexpected response, missing key object in response */
636 		*mbox_error = MBOX_RET_ERROR;
637 		return INTEL_SIP_SMC_STATUS_ERROR;
638 	}
639 
640 	return INTEL_SIP_SMC_STATUS_OK;
641 }
642 
643 int intel_fcs_remove_crypto_service_key(uint32_t session_id, uint32_t key_id,
644 		uint32_t *mbox_error)
645 {
646 	int status;
647 	uint32_t payload_size;
648 	uint32_t resp_len = 1U;
649 	uint32_t resp_data = 0U;
650 	uint32_t op_status = 0U;
651 
652 	if (mbox_error == NULL) {
653 		return INTEL_SIP_SMC_STATUS_REJECTED;
654 	}
655 
656 	fcs_cs_key_payload payload = {
657 		session_id,
658 		RESERVED_AS_ZERO,
659 		RESERVED_AS_ZERO,
660 		key_id
661 	};
662 
663 	payload_size = sizeof(payload) / MBOX_WORD_BYTE;
664 
665 	status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_REMOVE_CS_KEY,
666 			(uint32_t *) &payload, payload_size,
667 			CMD_CASUAL, &resp_data, &resp_len);
668 
669 	if (resp_len > 0) {
670 		op_status = resp_data & FCS_CS_KEY_RESP_STATUS_MASK;
671 	}
672 
673 	if (status < 0) {
674 		*mbox_error = (-status) | (op_status << FCS_CS_KEY_RESP_STATUS_OFFSET);
675 		return INTEL_SIP_SMC_STATUS_ERROR;
676 	}
677 
678 	return INTEL_SIP_SMC_STATUS_OK;
679 }
680 
681 int intel_fcs_get_crypto_service_key_info(uint32_t session_id, uint32_t key_id,
682 		uint64_t dst_addr, uint32_t *dst_size,
683 		uint32_t *mbox_error)
684 {
685 	int status;
686 	uint32_t payload_size;
687 	uint32_t resp_len = FCS_CS_KEY_INFO_MAX_WORD_SIZE;
688 	uint32_t op_status = 0U;
689 
690 	if ((dst_size == NULL) || (mbox_error == NULL)) {
691 		return INTEL_SIP_SMC_STATUS_REJECTED;
692 	}
693 
694 	if (!is_address_in_ddr_range(dst_addr, *dst_size)) {
695 		return INTEL_SIP_SMC_STATUS_REJECTED;
696 	}
697 
698 	fcs_cs_key_payload payload = {
699 		session_id,
700 		RESERVED_AS_ZERO,
701 		RESERVED_AS_ZERO,
702 		key_id
703 	};
704 
705 	payload_size = sizeof(payload) / MBOX_WORD_BYTE;
706 
707 	status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_GET_CS_KEY_INFO,
708 				(uint32_t *) &payload, payload_size,
709 				CMD_CASUAL, (uint32_t *) dst_addr, &resp_len);
710 
711 	if (resp_len > 0) {
712 		op_status = mmio_read_32(dst_addr) &
713 			FCS_CS_KEY_RESP_STATUS_MASK;
714 	}
715 
716 	if (status < 0) {
717 		*mbox_error = (-status) | (op_status << FCS_CS_KEY_RESP_STATUS_OFFSET);
718 		return INTEL_SIP_SMC_STATUS_ERROR;
719 	}
720 
721 	*dst_size = resp_len * MBOX_WORD_BYTE;
722 	flush_dcache_range(dst_addr, *dst_size);
723 
724 	return INTEL_SIP_SMC_STATUS_OK;
725 }
726 
727 int intel_fcs_get_digest_init(uint32_t session_id, uint32_t context_id,
728 				uint32_t key_id, uint32_t param_size,
729 				uint64_t param_data, uint32_t *mbox_error)
730 {
731 	return intel_fcs_crypto_service_init(session_id, context_id,
732 				key_id, param_size, param_data,
733 				(void *) &fcs_sha_get_digest_param,
734 				mbox_error);
735 }
736 
737 int intel_fcs_get_digest_finalize(uint32_t session_id, uint32_t context_id,
738 				uint32_t src_addr, uint32_t src_size,
739 				uint64_t dst_addr, uint32_t *dst_size,
740 				uint32_t *mbox_error)
741 {
742 	int status;
743 	uint32_t i;
744 	uint32_t resp_len = *dst_size / MBOX_WORD_BYTE;
745 	uint32_t payload[FCS_GET_DIGEST_CMD_MAX_WORD_SIZE] = {0U};
746 
747 	if (dst_size == NULL || mbox_error == NULL) {
748 		return INTEL_SIP_SMC_STATUS_REJECTED;
749 	}
750 
751 	if (fcs_sha_get_digest_param.session_id != session_id ||
752 	    fcs_sha_get_digest_param.context_id != context_id) {
753 		return INTEL_SIP_SMC_STATUS_REJECTED;
754 	}
755 
756 	/* Source data must be 8 bytes aligned */
757 	if (!is_8_bytes_aligned(src_size)) {
758 		return INTEL_SIP_SMC_STATUS_REJECTED;
759 	}
760 
761 	if (!is_address_in_ddr_range(src_addr, src_size) ||
762 		 !is_address_in_ddr_range(dst_addr, *dst_size)) {
763 		return INTEL_SIP_SMC_STATUS_REJECTED;
764 	}
765 
766 	/* Prepare command payload */
767 	i = 0;
768 	/* Crypto header */
769 	payload[i] = fcs_sha_get_digest_param.session_id;
770 	i++;
771 	payload[i] = fcs_sha_get_digest_param.context_id;
772 	i++;
773 	payload[i] = fcs_sha_get_digest_param.crypto_param_size
774 			& FCS_CS_FIELD_SIZE_MASK;
775 	payload[i] |= (FCS_CS_FIELD_FLAG_INIT | FCS_CS_FIELD_FLAG_UPDATE
776 			| FCS_CS_FIELD_FLAG_FINALIZE)
777 			<< FCS_CS_FIELD_FLAG_OFFSET;
778 	i++;
779 	payload[i] = fcs_sha_get_digest_param.key_id;
780 	i++;
781 	/* Crypto parameters */
782 	payload[i] = fcs_sha_get_digest_param.crypto_param
783 			& INTEL_SIP_SMC_FCS_SHA_MODE_MASK;
784 	payload[i] |= ((fcs_sha_get_digest_param.crypto_param
785 			>> INTEL_SIP_SMC_FCS_DIGEST_SIZE_OFFSET)
786 			& INTEL_SIP_SMC_FCS_DIGEST_SIZE_MASK)
787 			<< FCS_SHA_HMAC_CRYPTO_PARAM_SIZE_OFFSET;
788 	i++;
789 	/* Data source address and size */
790 	payload[i] = src_addr;
791 	i++;
792 	payload[i] = src_size;
793 	i++;
794 
795 	status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_GET_DIGEST_REQ,
796 				payload, i, CMD_CASUAL,
797 				(uint32_t *) dst_addr, &resp_len);
798 
799 	memset((void *)&fcs_sha_get_digest_param, 0, sizeof(fcs_crypto_service_data));
800 
801 	if (status < 0) {
802 		*mbox_error = -status;
803 		return INTEL_SIP_SMC_STATUS_ERROR;
804 	}
805 
806 	*dst_size = resp_len * MBOX_WORD_BYTE;
807 	flush_dcache_range(dst_addr, *dst_size);
808 
809 	return INTEL_SIP_SMC_STATUS_OK;
810 }
811 
812 int intel_fcs_mac_verify_init(uint32_t session_id, uint32_t context_id,
813 				uint32_t key_id, uint32_t param_size,
814 				uint64_t param_data, uint32_t *mbox_error)
815 {
816 	return intel_fcs_crypto_service_init(session_id, context_id,
817 				key_id, param_size, param_data,
818 				(void *) &fcs_sha_mac_verify_param,
819 				mbox_error);
820 }
821 
822 int intel_fcs_mac_verify_finalize(uint32_t session_id, uint32_t context_id,
823 				uint32_t src_addr, uint32_t src_size,
824 				uint64_t dst_addr, uint32_t *dst_size,
825 				uint32_t data_size, uint32_t *mbox_error)
826 {
827 	int status;
828 	uint32_t i;
829 	uint32_t resp_len = *dst_size / MBOX_WORD_BYTE;
830 	uint32_t payload[FCS_MAC_VERIFY_CMD_MAX_WORD_SIZE] = {0U};
831 	uintptr_t mac_offset;
832 
833 	if (dst_size == NULL || mbox_error == NULL) {
834 		return INTEL_SIP_SMC_STATUS_REJECTED;
835 	}
836 
837 	if (fcs_sha_mac_verify_param.session_id != session_id ||
838 		fcs_sha_mac_verify_param.context_id != context_id) {
839 		return INTEL_SIP_SMC_STATUS_REJECTED;
840 	}
841 
842 	if (data_size >= src_size) {
843 		return INTEL_SIP_SMC_STATUS_REJECTED;
844 	}
845 
846 	if (!is_size_4_bytes_aligned(src_size) ||
847 		!is_8_bytes_aligned(data_size)) {
848 		return INTEL_SIP_SMC_STATUS_REJECTED;
849 	}
850 
851 	if (!is_address_in_ddr_range(src_addr, src_size) ||
852 		!is_address_in_ddr_range(dst_addr, *dst_size)) {
853 		return INTEL_SIP_SMC_STATUS_REJECTED;
854 	}
855 
856 	/* Prepare command payload */
857 	i = 0;
858 	/* Crypto header */
859 	payload[i] = fcs_sha_mac_verify_param.session_id;
860 	i++;
861 	payload[i] = fcs_sha_mac_verify_param.context_id;
862 	i++;
863 	payload[i] = fcs_sha_mac_verify_param.crypto_param_size
864 			& FCS_CS_FIELD_SIZE_MASK;
865 	payload[i] |= (FCS_CS_FIELD_FLAG_INIT | FCS_CS_FIELD_FLAG_UPDATE
866 			| FCS_CS_FIELD_FLAG_FINALIZE)
867 			<< FCS_CS_FIELD_FLAG_OFFSET;
868 	i++;
869 	payload[i] = fcs_sha_mac_verify_param.key_id;
870 	i++;
871 	/* Crypto parameters */
872 	payload[i] = ((fcs_sha_mac_verify_param.crypto_param
873 			>> INTEL_SIP_SMC_FCS_DIGEST_SIZE_OFFSET)
874 			& INTEL_SIP_SMC_FCS_DIGEST_SIZE_MASK)
875 			<< FCS_SHA_HMAC_CRYPTO_PARAM_SIZE_OFFSET;
876 	i++;
877 	/* Data source address and size */
878 	payload[i] = src_addr;
879 	i++;
880 	payload[i] = data_size;
881 	i++;
882 	/* Copy mac data to command */
883 	mac_offset = src_addr + data_size;
884 	memcpy((uint8_t *) &payload[i], (uint8_t *) mac_offset,
885 				src_size - data_size);
886 
887 	i += (src_size - data_size) / MBOX_WORD_BYTE;
888 
889 	status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_MAC_VERIFY_REQ,
890 				payload, i, CMD_CASUAL,
891 				(uint32_t *) dst_addr, &resp_len);
892 
893 	memset((void *)&fcs_sha_mac_verify_param, 0,
894 				sizeof(fcs_crypto_service_data));
895 
896 	if (status < 0) {
897 		*mbox_error = -status;
898 		return INTEL_SIP_SMC_STATUS_ERROR;
899 	}
900 
901 	*dst_size = resp_len * MBOX_WORD_BYTE;
902 	flush_dcache_range(dst_addr, *dst_size);
903 
904 	return INTEL_SIP_SMC_STATUS_OK;
905 }
906 
907 int intel_fcs_aes_crypt_init(uint32_t session_id, uint32_t context_id,
908 				uint32_t key_id, uint64_t param_addr,
909 				uint32_t param_size, uint32_t *mbox_error)
910 {
911 	if (mbox_error == NULL) {
912 		return INTEL_SIP_SMC_STATUS_REJECTED;
913 	}
914 
915 	memset((void *)&fcs_aes_init_payload, 0U, sizeof(fcs_aes_init_payload));
916 
917 	fcs_aes_init_payload.session_id = session_id;
918 	fcs_aes_init_payload.context_id = context_id;
919 	fcs_aes_init_payload.param_size = param_size;
920 	fcs_aes_init_payload.key_id	= key_id;
921 
922 	memcpy((uint8_t *) fcs_aes_init_payload.crypto_param,
923 		(uint8_t *) param_addr, param_size);
924 
925 	*mbox_error = 0;
926 
927 	return INTEL_SIP_SMC_STATUS_OK;
928 }
929 
930 int intel_fcs_aes_crypt_finalize(uint32_t session_id, uint32_t context_id,
931 				uint64_t src_addr, uint32_t src_size,
932 				uint64_t dst_addr, uint32_t dst_size,
933 				uint32_t *send_id)
934 {
935 	int status;
936 	int i;
937 	uint32_t crypto_header;
938 	uint32_t fcs_aes_crypt_payload[FCS_AES_CMD_MAX_WORD_SIZE];
939 
940 	if (fcs_aes_init_payload.session_id != session_id ||
941 		fcs_aes_init_payload.context_id != context_id) {
942 		return INTEL_SIP_SMC_STATUS_REJECTED;
943 	}
944 
945 	if ((!is_8_bytes_aligned(src_addr)) ||
946 		(!is_32_bytes_aligned(src_size)) ||
947 		(!is_address_in_ddr_range(src_addr, src_size))) {
948 		return INTEL_SIP_SMC_STATUS_REJECTED;
949 	}
950 
951 	if ((!is_8_bytes_aligned(dst_addr)) ||
952 		(!is_32_bytes_aligned(dst_size))) {
953 		return INTEL_SIP_SMC_STATUS_REJECTED;
954 	}
955 
956 	if ((dst_size > FCS_AES_MAX_DATA_SIZE ||
957 		dst_size < FCS_AES_MIN_DATA_SIZE) ||
958 		(src_size > FCS_AES_MAX_DATA_SIZE ||
959 		src_size < FCS_AES_MIN_DATA_SIZE)) {
960 		return INTEL_SIP_SMC_STATUS_REJECTED;
961 	}
962 
963 	crypto_header = ((FCS_CS_FIELD_FLAG_INIT |
964 			FCS_CS_FIELD_FLAG_UPDATE |
965 			FCS_CS_FIELD_FLAG_FINALIZE) <<
966 			FCS_CS_FIELD_FLAG_OFFSET) |
967 			fcs_aes_init_payload.param_size;
968 	i = 0U;
969 	fcs_aes_crypt_payload[i] = session_id;
970 	i++;
971 	fcs_aes_crypt_payload[i] = context_id;
972 	i++;
973 	fcs_aes_crypt_payload[i] = crypto_header;
974 	i++;
975 	fcs_aes_crypt_payload[i] = fcs_aes_init_payload.key_id;
976 
977 	i++;
978 	memcpy((uint8_t *) &fcs_aes_crypt_payload[i],
979 		(uint8_t *) fcs_aes_init_payload.crypto_param,
980 		fcs_aes_init_payload.param_size);
981 
982 	i += fcs_aes_init_payload.param_size / MBOX_WORD_BYTE;
983 
984 	fcs_aes_crypt_payload[i] = (uint32_t) src_addr;
985 	i++;
986 	fcs_aes_crypt_payload[i] = src_size;
987 	i++;
988 	fcs_aes_crypt_payload[i] = (uint32_t) dst_addr;
989 	i++;
990 	fcs_aes_crypt_payload[i] = dst_size;
991 	i++;
992 
993 	status = mailbox_send_cmd_async(send_id, MBOX_FCS_AES_CRYPT_REQ,
994 					fcs_aes_crypt_payload, i,
995 					CMD_INDIRECT);
996 
997 	memset((void *)&fcs_aes_init_payload, 0U, sizeof(fcs_aes_init_payload));
998 
999 	if (status < 0U) {
1000 		return INTEL_SIP_SMC_STATUS_ERROR;
1001 	}
1002 
1003 	return INTEL_SIP_SMC_STATUS_OK;
1004 }
1005