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