xref: /rk3399_ARM-atf/plat/intel/soc/common/sip/socfpga_sip_fcs.c (revision 24f9dc8a43fea350416ca9312a78ab4e786da8ad)
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 bool is_size_4_bytes_aligned(uint32_t size)
15 {
16 	if ((size % MBOX_WORD_BYTE) != 0U) {
17 		return false;
18 	} else {
19 		return true;
20 	}
21 }
22 
23 uint32_t intel_fcs_random_number_gen(uint64_t addr, uint64_t *ret_size,
24 					uint32_t *mbox_error)
25 {
26 	int status;
27 	unsigned int i;
28 	unsigned int resp_len = FCS_RANDOM_WORD_SIZE;
29 	uint32_t random_data[FCS_RANDOM_WORD_SIZE] = {0U};
30 
31 	if (!is_address_in_ddr_range(addr, FCS_RANDOM_BYTE_SIZE)) {
32 		return INTEL_SIP_SMC_STATUS_REJECTED;
33 	}
34 
35 	status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_RANDOM_GEN, NULL, 0U,
36 			CMD_CASUAL, random_data, &resp_len);
37 
38 	if (status < 0) {
39 		*mbox_error = -status;
40 		return INTEL_SIP_SMC_STATUS_ERROR;
41 	}
42 
43 	if (resp_len != FCS_RANDOM_WORD_SIZE) {
44 		*mbox_error = GENERIC_RESPONSE_ERROR;
45 		return INTEL_SIP_SMC_STATUS_ERROR;
46 	}
47 
48 	*ret_size = FCS_RANDOM_BYTE_SIZE;
49 
50 	for (i = 0U; i < FCS_RANDOM_WORD_SIZE; i++) {
51 		mmio_write_32(addr, random_data[i]);
52 		addr += MBOX_WORD_BYTE;
53 	}
54 
55 	flush_dcache_range(addr - *ret_size, *ret_size);
56 
57 	return INTEL_SIP_SMC_STATUS_OK;
58 }
59 
60 int intel_fcs_random_number_gen_ext(uint32_t session_id, uint32_t context_id,
61 				uint32_t size, uint32_t *send_id)
62 {
63 	int status;
64 	uint32_t payload_size;
65 	uint32_t crypto_header;
66 
67 	if (size > (FCS_RANDOM_EXT_MAX_WORD_SIZE *
68 		MBOX_WORD_BYTE) || size == 0U) {
69 		return INTEL_SIP_SMC_STATUS_REJECTED;
70 	}
71 
72 	if (!is_size_4_bytes_aligned(size)) {
73 		return INTEL_SIP_SMC_STATUS_REJECTED;
74 	}
75 
76 	crypto_header = (FCS_CS_FIELD_FLAG_INIT | FCS_CS_FIELD_FLAG_FINALIZE) <<
77 			FCS_CS_FIELD_FLAG_OFFSET;
78 
79 	fcs_rng_payload payload = {
80 		session_id,
81 		context_id,
82 		crypto_header,
83 		size
84 	};
85 
86 	payload_size = sizeof(payload) / MBOX_WORD_BYTE;
87 
88 	status = mailbox_send_cmd_async(send_id, MBOX_FCS_RANDOM_GEN,
89 					(uint32_t *) &payload, payload_size,
90 					CMD_INDIRECT);
91 
92 	if (status < 0) {
93 		return INTEL_SIP_SMC_STATUS_ERROR;
94 	}
95 
96 	return INTEL_SIP_SMC_STATUS_OK;
97 }
98 
99 uint32_t intel_fcs_send_cert(uint64_t addr, uint64_t size,
100 					uint32_t *send_id)
101 {
102 	int status;
103 
104 	if (!is_address_in_ddr_range(addr, size)) {
105 		return INTEL_SIP_SMC_STATUS_REJECTED;
106 	}
107 
108 	if (!is_size_4_bytes_aligned(size)) {
109 		return INTEL_SIP_SMC_STATUS_REJECTED;
110 	}
111 
112 	status = mailbox_send_cmd_async(send_id, MBOX_CMD_VAB_SRC_CERT,
113 				(uint32_t *)addr, size / MBOX_WORD_BYTE,
114 				CMD_DIRECT);
115 
116 	flush_dcache_range(addr, size);
117 
118 	if (status < 0) {
119 		return INTEL_SIP_SMC_STATUS_ERROR;
120 	}
121 
122 	return INTEL_SIP_SMC_STATUS_OK;
123 }
124 
125 uint32_t intel_fcs_get_provision_data(uint32_t *send_id)
126 {
127 	int status;
128 
129 	status = mailbox_send_cmd_async(send_id, MBOX_FCS_GET_PROVISION,
130 				NULL, 0U, CMD_DIRECT);
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_cntr_set_preauth(uint8_t counter_type, int32_t counter_value,
140 					uint32_t test_bit, uint32_t *mbox_error)
141 {
142 	int status;
143 	uint32_t first_word;
144 	uint32_t payload_size;
145 
146 	if ((test_bit != MBOX_TEST_BIT) &&
147 		(test_bit != 0)) {
148 		return INTEL_SIP_SMC_STATUS_REJECTED;
149 	}
150 
151 	if ((counter_type < FCS_BIG_CNTR_SEL) ||
152 		(counter_type > FCS_SVN_CNTR_3_SEL)) {
153 		return INTEL_SIP_SMC_STATUS_REJECTED;
154 	}
155 
156 	if ((counter_type == FCS_BIG_CNTR_SEL) &&
157 		(counter_value > FCS_BIG_CNTR_VAL_MAX)) {
158 		return INTEL_SIP_SMC_STATUS_REJECTED;
159 	}
160 
161 	if ((counter_type >= FCS_SVN_CNTR_0_SEL) &&
162 		(counter_type <= FCS_SVN_CNTR_3_SEL) &&
163 		(counter_value > FCS_SVN_CNTR_VAL_MAX)) {
164 		return INTEL_SIP_SMC_STATUS_REJECTED;
165 	}
166 
167 	first_word = test_bit | counter_type;
168 	fcs_cntr_set_preauth_payload payload = {
169 		first_word,
170 		counter_value
171 	};
172 
173 	payload_size = sizeof(payload) / MBOX_WORD_BYTE;
174 	status =  mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_CNTR_SET_PREAUTH,
175 				  (uint32_t *) &payload, payload_size,
176 				  CMD_CASUAL, NULL, NULL);
177 
178 	if (status < 0) {
179 		*mbox_error = -status;
180 		return INTEL_SIP_SMC_STATUS_ERROR;
181 	}
182 
183 	return INTEL_SIP_SMC_STATUS_OK;
184 }
185 
186 uint32_t intel_fcs_encryption(uint32_t src_addr, uint32_t src_size,
187 		uint32_t dst_addr, uint32_t dst_size, uint32_t *send_id)
188 {
189 	int status;
190 	uint32_t load_size;
191 
192 	fcs_encrypt_payload payload = {
193 		FCS_ENCRYPTION_DATA_0,
194 		src_addr,
195 		src_size,
196 		dst_addr,
197 		dst_size };
198 	load_size = sizeof(payload) / MBOX_WORD_BYTE;
199 
200 	if (!is_address_in_ddr_range(src_addr, src_size) ||
201 		!is_address_in_ddr_range(dst_addr, dst_size)) {
202 		return INTEL_SIP_SMC_STATUS_REJECTED;
203 	}
204 
205 	if (!is_size_4_bytes_aligned(src_size)) {
206 		return INTEL_SIP_SMC_STATUS_REJECTED;
207 	}
208 
209 	status = mailbox_send_cmd_async(send_id, MBOX_FCS_ENCRYPT_REQ,
210 				(uint32_t *) &payload, load_size,
211 				CMD_INDIRECT);
212 	inv_dcache_range(dst_addr, dst_size);
213 
214 	if (status < 0) {
215 		return INTEL_SIP_SMC_STATUS_REJECTED;
216 	}
217 
218 	return INTEL_SIP_SMC_STATUS_OK;
219 }
220 
221 uint32_t intel_fcs_decryption(uint32_t src_addr, uint32_t src_size,
222 		uint32_t dst_addr, uint32_t dst_size, uint32_t *send_id)
223 {
224 	int status;
225 	uint32_t load_size;
226 	uintptr_t id_offset;
227 
228 	id_offset = src_addr + FCS_OWNER_ID_OFFSET;
229 	fcs_decrypt_payload payload = {
230 		FCS_DECRYPTION_DATA_0,
231 		{mmio_read_32(id_offset),
232 		mmio_read_32(id_offset + MBOX_WORD_BYTE)},
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_DECRYPT_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_get_rom_patch_sha384(uint64_t addr, uint64_t *ret_size,
261 					uint32_t *mbox_error)
262 {
263 	int status;
264 	unsigned int resp_len = FCS_SHA384_WORD_SIZE;
265 
266 	if (!is_address_in_ddr_range(addr, FCS_SHA384_BYTE_SIZE)) {
267 		return INTEL_SIP_SMC_STATUS_REJECTED;
268 	}
269 
270 	status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_GET_ROM_PATCH_SHA384, NULL, 0U,
271 			CMD_CASUAL, (uint32_t *) addr, &resp_len);
272 
273 	if (status < 0) {
274 		*mbox_error = -status;
275 		return INTEL_SIP_SMC_STATUS_ERROR;
276 	}
277 
278 	if (resp_len != FCS_SHA384_WORD_SIZE) {
279 		*mbox_error = GENERIC_RESPONSE_ERROR;
280 		return INTEL_SIP_SMC_STATUS_ERROR;
281 	}
282 
283 	*ret_size = FCS_SHA384_BYTE_SIZE;
284 
285 	flush_dcache_range(addr, *ret_size);
286 
287 	return INTEL_SIP_SMC_STATUS_OK;
288 }
289 
290 int intel_fcs_sigma_teardown(uint32_t session_id, uint32_t *mbox_error)
291 {
292 	int status;
293 
294 	if ((session_id != PSGSIGMA_SESSION_ID_ONE) &&
295 		(session_id != PSGSIGMA_UNKNOWN_SESSION)) {
296 		return INTEL_SIP_SMC_STATUS_REJECTED;
297 	}
298 
299 	psgsigma_teardown_msg message = {
300 		RESERVED_AS_ZERO,
301 		PSGSIGMA_TEARDOWN_MAGIC,
302 		session_id
303 	};
304 
305 	status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_PSG_SIGMA_TEARDOWN,
306 			(uint32_t *) &message, sizeof(message) / MBOX_WORD_BYTE,
307 			CMD_CASUAL, NULL, NULL);
308 
309 	if (status < 0) {
310 		*mbox_error = -status;
311 		return INTEL_SIP_SMC_STATUS_ERROR;
312 	}
313 
314 	return INTEL_SIP_SMC_STATUS_OK;
315 }
316 
317 int intel_fcs_chip_id(uint32_t *id_low, uint32_t *id_high, uint32_t *mbox_error)
318 {
319 	int status;
320 	uint32_t load_size;
321 	uint32_t chip_id[2];
322 
323 	load_size = sizeof(chip_id) / MBOX_WORD_BYTE;
324 
325 	status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_CMD_GET_CHIPID, NULL,
326 			0U, CMD_CASUAL, (uint32_t *) chip_id, &load_size);
327 
328 	if (status < 0) {
329 		*mbox_error = -status;
330 		return INTEL_SIP_SMC_STATUS_ERROR;
331 	}
332 
333 	*id_low = chip_id[0];
334 	*id_high = chip_id[1];
335 
336 	return INTEL_SIP_SMC_STATUS_OK;
337 }
338 
339 int intel_fcs_attestation_subkey(uint64_t src_addr, uint32_t src_size,
340 		uint64_t dst_addr, uint32_t *dst_size, uint32_t *mbox_error)
341 {
342 	int status;
343 	uint32_t send_size = src_size / MBOX_WORD_BYTE;
344 	uint32_t ret_size = *dst_size / MBOX_WORD_BYTE;
345 
346 
347 	if (!is_address_in_ddr_range(src_addr, src_size) ||
348 		!is_address_in_ddr_range(dst_addr, *dst_size)) {
349 		return INTEL_SIP_SMC_STATUS_REJECTED;
350 	}
351 
352 	status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_ATTESTATION_SUBKEY,
353 			(uint32_t *) src_addr, send_size, CMD_CASUAL,
354 			(uint32_t *) dst_addr, &ret_size);
355 
356 	if (status < 0) {
357 		*mbox_error = -status;
358 		return INTEL_SIP_SMC_STATUS_ERROR;
359 	}
360 
361 	*dst_size = ret_size * MBOX_WORD_BYTE;
362 	flush_dcache_range(dst_addr, *dst_size);
363 
364 	return INTEL_SIP_SMC_STATUS_OK;
365 }
366 
367 int intel_fcs_get_measurement(uint64_t src_addr, uint32_t src_size,
368 		uint64_t dst_addr, uint32_t *dst_size, uint32_t *mbox_error)
369 {
370 	int status;
371 	uint32_t send_size = src_size / MBOX_WORD_BYTE;
372 	uint32_t ret_size = *dst_size / MBOX_WORD_BYTE;
373 
374 	if (!is_address_in_ddr_range(src_addr, src_size) ||
375 		!is_address_in_ddr_range(dst_addr, *dst_size)) {
376 		return INTEL_SIP_SMC_STATUS_REJECTED;
377 	}
378 
379 	status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_GET_MEASUREMENT,
380 			(uint32_t *) src_addr, send_size, CMD_CASUAL,
381 			(uint32_t *) dst_addr, &ret_size);
382 
383 	if (status < 0) {
384 		*mbox_error = -status;
385 		return INTEL_SIP_SMC_STATUS_ERROR;
386 	}
387 
388 	*dst_size = ret_size * MBOX_WORD_BYTE;
389 	flush_dcache_range(dst_addr, *dst_size);
390 
391 	return INTEL_SIP_SMC_STATUS_OK;
392 }
393 
394 int intel_fcs_get_attestation_cert(uint32_t cert_request, uint64_t dst_addr,
395 			uint32_t *dst_size, uint32_t *mbox_error)
396 {
397 	int status;
398 	uint32_t ret_size = *dst_size / MBOX_WORD_BYTE;
399 
400 	if (mbox_error == NULL) {
401 		return INTEL_SIP_SMC_STATUS_REJECTED;
402 	}
403 
404 	if (cert_request < FCS_ALIAS_CERT ||
405 		cert_request >
406 			(FCS_ALIAS_CERT |
407 			FCS_DEV_ID_SELF_SIGN_CERT |
408 			FCS_DEV_ID_ENROLL_CERT |
409 			FCS_ENROLL_SELF_SIGN_CERT |
410 			FCS_PLAT_KEY_CERT)) {
411 		return INTEL_SIP_SMC_STATUS_REJECTED;
412 	}
413 
414 	if (!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_ATTESTATION_CERT,
419 			(uint32_t *) &cert_request, 1U, 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_create_cert_on_reload(uint32_t cert_request,
434 			uint32_t *mbox_error)
435 {
436 	int status;
437 
438 	if (mbox_error == NULL) {
439 		return INTEL_SIP_SMC_STATUS_REJECTED;
440 	}
441 
442 	if (cert_request < FCS_ALIAS_CERT ||
443 		cert_request >
444 			(FCS_ALIAS_CERT |
445 			FCS_DEV_ID_SELF_SIGN_CERT |
446 			FCS_DEV_ID_ENROLL_CERT |
447 			FCS_ENROLL_SELF_SIGN_CERT |
448 			FCS_PLAT_KEY_CERT)) {
449 		return INTEL_SIP_SMC_STATUS_REJECTED;
450 	}
451 
452 	status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_CREATE_CERT_ON_RELOAD,
453 			(uint32_t *) &cert_request, 1U, CMD_CASUAL,
454 			NULL, NULL);
455 
456 	if (status < 0) {
457 		*mbox_error = -status;
458 		return INTEL_SIP_SMC_STATUS_ERROR;
459 	}
460 
461 	return INTEL_SIP_SMC_STATUS_OK;
462 }
463 
464 int intel_fcs_open_crypto_service_session(uint32_t *session_id,
465 			uint32_t *mbox_error)
466 {
467 	int status;
468 	uint32_t resp_len = 1U;
469 
470 	if ((session_id == NULL) || (mbox_error == NULL)) {
471 		return INTEL_SIP_SMC_STATUS_REJECTED;
472 	}
473 
474 	status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_OPEN_CS_SESSION,
475 			NULL, 0U, CMD_CASUAL, session_id, &resp_len);
476 
477 	if (status < 0) {
478 		*mbox_error = -status;
479 		return INTEL_SIP_SMC_STATUS_ERROR;
480 	}
481 
482 	return INTEL_SIP_SMC_STATUS_OK;
483 }
484 
485 int intel_fcs_close_crypto_service_session(uint32_t session_id,
486 			uint32_t *mbox_error)
487 {
488 	int status;
489 
490 	if (mbox_error == NULL) {
491 		return INTEL_SIP_SMC_STATUS_REJECTED;
492 	}
493 
494 	status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_CLOSE_CS_SESSION,
495 			&session_id, 1U, CMD_CASUAL, NULL, NULL);
496 
497 	if (status < 0) {
498 		*mbox_error = -status;
499 		return INTEL_SIP_SMC_STATUS_ERROR;
500 	}
501 
502 	return INTEL_SIP_SMC_STATUS_OK;
503 }
504 
505 int intel_fcs_import_crypto_service_key(uint64_t src_addr, uint32_t src_size,
506 		uint32_t *send_id)
507 {
508 	int status;
509 
510 	if (src_size > (FCS_CS_KEY_OBJ_MAX_WORD_SIZE *
511 		MBOX_WORD_BYTE)) {
512 		return INTEL_SIP_SMC_STATUS_REJECTED;
513 	}
514 
515 	if (!is_address_in_ddr_range(src_addr, src_size)) {
516 		return INTEL_SIP_SMC_STATUS_REJECTED;
517 	}
518 
519 	status = mailbox_send_cmd_async(send_id, MBOX_FCS_IMPORT_CS_KEY,
520 				(uint32_t *)src_addr, src_size / MBOX_WORD_BYTE,
521 				CMD_INDIRECT);
522 
523 	if (status < 0) {
524 		return INTEL_SIP_SMC_STATUS_ERROR;
525 	}
526 
527 	return INTEL_SIP_SMC_STATUS_OK;
528 }
529 
530 int intel_fcs_export_crypto_service_key(uint32_t session_id, uint32_t key_id,
531 		uint64_t dst_addr, uint32_t *dst_size,
532 		uint32_t *mbox_error)
533 {
534 	int status;
535 	uint32_t i;
536 	uint32_t payload_size;
537 	uint32_t resp_len = FCS_CS_KEY_OBJ_MAX_WORD_SIZE;
538 	uint32_t resp_data[FCS_CS_KEY_OBJ_MAX_WORD_SIZE] = {0U};
539 	uint32_t op_status = 0U;
540 
541 	if ((dst_size == NULL) || (mbox_error == NULL)) {
542 		return INTEL_SIP_SMC_STATUS_REJECTED;
543 	}
544 
545 	if (!is_address_in_ddr_range(dst_addr, *dst_size)) {
546 		return INTEL_SIP_SMC_STATUS_REJECTED;
547 	}
548 
549 	fcs_cs_key_payload payload = {
550 		session_id,
551 		RESERVED_AS_ZERO,
552 		RESERVED_AS_ZERO,
553 		key_id
554 	};
555 
556 	payload_size = sizeof(payload) / MBOX_WORD_BYTE;
557 
558 	status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_EXPORT_CS_KEY,
559 			(uint32_t *) &payload, payload_size,
560 			CMD_CASUAL, resp_data, &resp_len);
561 
562 	if (resp_len > 0) {
563 		op_status = resp_data[0] & FCS_CS_KEY_RESP_STATUS_MASK;
564 	}
565 
566 	if (status < 0) {
567 		*mbox_error = (-status) | (op_status << FCS_CS_KEY_RESP_STATUS_OFFSET);
568 		return INTEL_SIP_SMC_STATUS_ERROR;
569 	}
570 
571 	if (resp_len > 1) {
572 
573 		/* Export key object is start at second response data */
574 		*dst_size = (resp_len - 1) * MBOX_WORD_BYTE;
575 
576 		for (i = 1U; i < resp_len; i++) {
577 			mmio_write_32(dst_addr, resp_data[i]);
578 			dst_addr += MBOX_WORD_BYTE;
579 		}
580 
581 		flush_dcache_range(dst_addr - *dst_size, *dst_size);
582 
583 	} else {
584 
585 		/* Unexpected response, missing key object in response */
586 		*mbox_error = MBOX_RET_ERROR;
587 		return INTEL_SIP_SMC_STATUS_ERROR;
588 	}
589 
590 	return INTEL_SIP_SMC_STATUS_OK;
591 }
592 
593 int intel_fcs_remove_crypto_service_key(uint32_t session_id, uint32_t key_id,
594 		uint32_t *mbox_error)
595 {
596 	int status;
597 	uint32_t payload_size;
598 	uint32_t resp_len = 1U;
599 	uint32_t resp_data = 0U;
600 	uint32_t op_status = 0U;
601 
602 	if (mbox_error == NULL) {
603 		return INTEL_SIP_SMC_STATUS_REJECTED;
604 	}
605 
606 	fcs_cs_key_payload payload = {
607 		session_id,
608 		RESERVED_AS_ZERO,
609 		RESERVED_AS_ZERO,
610 		key_id
611 	};
612 
613 	payload_size = sizeof(payload) / MBOX_WORD_BYTE;
614 
615 	status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_REMOVE_CS_KEY,
616 			(uint32_t *) &payload, payload_size,
617 			CMD_CASUAL, &resp_data, &resp_len);
618 
619 	if (resp_len > 0) {
620 		op_status = resp_data & FCS_CS_KEY_RESP_STATUS_MASK;
621 	}
622 
623 	if (status < 0) {
624 		*mbox_error = (-status) | (op_status << FCS_CS_KEY_RESP_STATUS_OFFSET);
625 		return INTEL_SIP_SMC_STATUS_ERROR;
626 	}
627 
628 	return INTEL_SIP_SMC_STATUS_OK;
629 }
630 
631 int intel_fcs_get_crypto_service_key_info(uint32_t session_id, uint32_t key_id,
632 		uint64_t dst_addr, uint32_t *dst_size,
633 		uint32_t *mbox_error)
634 {
635 	int status;
636 	uint32_t payload_size;
637 	uint32_t resp_len = FCS_CS_KEY_INFO_MAX_WORD_SIZE;
638 	uint32_t op_status = 0U;
639 
640 	if ((dst_size == NULL) || (mbox_error == NULL)) {
641 		return INTEL_SIP_SMC_STATUS_REJECTED;
642 	}
643 
644 	if (!is_address_in_ddr_range(dst_addr, *dst_size)) {
645 		return INTEL_SIP_SMC_STATUS_REJECTED;
646 	}
647 
648 	fcs_cs_key_payload payload = {
649 		session_id,
650 		RESERVED_AS_ZERO,
651 		RESERVED_AS_ZERO,
652 		key_id
653 	};
654 
655 	payload_size = sizeof(payload) / MBOX_WORD_BYTE;
656 
657 	status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_GET_CS_KEY_INFO,
658 				(uint32_t *) &payload, payload_size,
659 				CMD_CASUAL, (uint32_t *) dst_addr, &resp_len);
660 
661 	if (resp_len > 0) {
662 		op_status = mmio_read_32(dst_addr) &
663 			FCS_CS_KEY_RESP_STATUS_MASK;
664 	}
665 
666 	if (status < 0) {
667 		*mbox_error = (-status) | (op_status << FCS_CS_KEY_RESP_STATUS_OFFSET);
668 		return INTEL_SIP_SMC_STATUS_ERROR;
669 	}
670 
671 	*dst_size = resp_len * MBOX_WORD_BYTE;
672 	flush_dcache_range(dst_addr, *dst_size);
673 
674 	return INTEL_SIP_SMC_STATUS_OK;
675 }
676