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