xref: /arm-trusted-firmware/plat/intel/soc/common/sip/socfpga_sip_fcs.c (revision 91f16700b400a8c0651d24a598fc48ee2997a0d7)
1*91f16700Schasinglulu /*
2*91f16700Schasinglulu  * Copyright (c) 2020-2022, Intel Corporation. All rights reserved.
3*91f16700Schasinglulu  *
4*91f16700Schasinglulu  * SPDX-License-Identifier: BSD-3-Clause
5*91f16700Schasinglulu  */
6*91f16700Schasinglulu 
7*91f16700Schasinglulu #include <arch_helpers.h>
8*91f16700Schasinglulu #include <lib/mmio.h>
9*91f16700Schasinglulu 
10*91f16700Schasinglulu #include "socfpga_fcs.h"
11*91f16700Schasinglulu #include "socfpga_mailbox.h"
12*91f16700Schasinglulu #include "socfpga_sip_svc.h"
13*91f16700Schasinglulu 
14*91f16700Schasinglulu /* FCS static variables */
15*91f16700Schasinglulu static fcs_crypto_service_aes_data fcs_aes_init_payload;
16*91f16700Schasinglulu static fcs_crypto_service_data fcs_sha_get_digest_param;
17*91f16700Schasinglulu static fcs_crypto_service_data fcs_sha_mac_verify_param;
18*91f16700Schasinglulu static fcs_crypto_service_data fcs_ecdsa_hash_sign_param;
19*91f16700Schasinglulu static fcs_crypto_service_data fcs_ecdsa_hash_sig_verify_param;
20*91f16700Schasinglulu static fcs_crypto_service_data fcs_sha2_data_sign_param;
21*91f16700Schasinglulu static fcs_crypto_service_data fcs_sha2_data_sig_verify_param;
22*91f16700Schasinglulu static fcs_crypto_service_data fcs_ecdsa_get_pubkey_param;
23*91f16700Schasinglulu static fcs_crypto_service_data fcs_ecdh_request_param;
24*91f16700Schasinglulu 
25*91f16700Schasinglulu bool is_size_4_bytes_aligned(uint32_t size)
26*91f16700Schasinglulu {
27*91f16700Schasinglulu 	if ((size % MBOX_WORD_BYTE) != 0U) {
28*91f16700Schasinglulu 		return false;
29*91f16700Schasinglulu 	} else {
30*91f16700Schasinglulu 		return true;
31*91f16700Schasinglulu 	}
32*91f16700Schasinglulu }
33*91f16700Schasinglulu 
34*91f16700Schasinglulu static bool is_8_bytes_aligned(uint32_t data)
35*91f16700Schasinglulu {
36*91f16700Schasinglulu 	if ((data % (MBOX_WORD_BYTE * 2U)) != 0U) {
37*91f16700Schasinglulu 		return false;
38*91f16700Schasinglulu 	} else {
39*91f16700Schasinglulu 		return true;
40*91f16700Schasinglulu 	}
41*91f16700Schasinglulu }
42*91f16700Schasinglulu 
43*91f16700Schasinglulu static bool is_32_bytes_aligned(uint32_t data)
44*91f16700Schasinglulu {
45*91f16700Schasinglulu 	if ((data % (8U * MBOX_WORD_BYTE)) != 0U) {
46*91f16700Schasinglulu 		return false;
47*91f16700Schasinglulu 	} else {
48*91f16700Schasinglulu 		return true;
49*91f16700Schasinglulu 	}
50*91f16700Schasinglulu }
51*91f16700Schasinglulu 
52*91f16700Schasinglulu static int intel_fcs_crypto_service_init(uint32_t session_id,
53*91f16700Schasinglulu 			uint32_t context_id, uint32_t key_id,
54*91f16700Schasinglulu 			uint32_t param_size, uint64_t param_data,
55*91f16700Schasinglulu 			fcs_crypto_service_data *data_addr,
56*91f16700Schasinglulu 			uint32_t *mbox_error)
57*91f16700Schasinglulu {
58*91f16700Schasinglulu 	if (mbox_error == NULL) {
59*91f16700Schasinglulu 		return INTEL_SIP_SMC_STATUS_REJECTED;
60*91f16700Schasinglulu 	}
61*91f16700Schasinglulu 
62*91f16700Schasinglulu 	if (param_size != 4) {
63*91f16700Schasinglulu 		return INTEL_SIP_SMC_STATUS_REJECTED;
64*91f16700Schasinglulu 	}
65*91f16700Schasinglulu 
66*91f16700Schasinglulu 	memset(data_addr, 0, sizeof(fcs_crypto_service_data));
67*91f16700Schasinglulu 
68*91f16700Schasinglulu 	data_addr->session_id = session_id;
69*91f16700Schasinglulu 	data_addr->context_id = context_id;
70*91f16700Schasinglulu 	data_addr->key_id = key_id;
71*91f16700Schasinglulu 	data_addr->crypto_param_size = param_size;
72*91f16700Schasinglulu 	data_addr->crypto_param = param_data;
73*91f16700Schasinglulu 
74*91f16700Schasinglulu 	data_addr->is_updated = 0;
75*91f16700Schasinglulu 
76*91f16700Schasinglulu 	*mbox_error = 0;
77*91f16700Schasinglulu 
78*91f16700Schasinglulu 	return INTEL_SIP_SMC_STATUS_OK;
79*91f16700Schasinglulu }
80*91f16700Schasinglulu 
81*91f16700Schasinglulu uint32_t intel_fcs_random_number_gen(uint64_t addr, uint64_t *ret_size,
82*91f16700Schasinglulu 					uint32_t *mbox_error)
83*91f16700Schasinglulu {
84*91f16700Schasinglulu 	int status;
85*91f16700Schasinglulu 	unsigned int i;
86*91f16700Schasinglulu 	unsigned int resp_len = FCS_RANDOM_WORD_SIZE;
87*91f16700Schasinglulu 	uint32_t random_data[FCS_RANDOM_WORD_SIZE] = {0U};
88*91f16700Schasinglulu 
89*91f16700Schasinglulu 	if (!is_address_in_ddr_range(addr, FCS_RANDOM_BYTE_SIZE)) {
90*91f16700Schasinglulu 		return INTEL_SIP_SMC_STATUS_REJECTED;
91*91f16700Schasinglulu 	}
92*91f16700Schasinglulu 
93*91f16700Schasinglulu 	status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_RANDOM_GEN, NULL, 0U,
94*91f16700Schasinglulu 			CMD_CASUAL, random_data, &resp_len);
95*91f16700Schasinglulu 
96*91f16700Schasinglulu 	if (status < 0) {
97*91f16700Schasinglulu 		*mbox_error = -status;
98*91f16700Schasinglulu 		return INTEL_SIP_SMC_STATUS_ERROR;
99*91f16700Schasinglulu 	}
100*91f16700Schasinglulu 
101*91f16700Schasinglulu 	if (resp_len != FCS_RANDOM_WORD_SIZE) {
102*91f16700Schasinglulu 		*mbox_error = GENERIC_RESPONSE_ERROR;
103*91f16700Schasinglulu 		return INTEL_SIP_SMC_STATUS_ERROR;
104*91f16700Schasinglulu 	}
105*91f16700Schasinglulu 
106*91f16700Schasinglulu 	*ret_size = FCS_RANDOM_BYTE_SIZE;
107*91f16700Schasinglulu 
108*91f16700Schasinglulu 	for (i = 0U; i < FCS_RANDOM_WORD_SIZE; i++) {
109*91f16700Schasinglulu 		mmio_write_32(addr, random_data[i]);
110*91f16700Schasinglulu 		addr += MBOX_WORD_BYTE;
111*91f16700Schasinglulu 	}
112*91f16700Schasinglulu 
113*91f16700Schasinglulu 	flush_dcache_range(addr - *ret_size, *ret_size);
114*91f16700Schasinglulu 
115*91f16700Schasinglulu 	return INTEL_SIP_SMC_STATUS_OK;
116*91f16700Schasinglulu }
117*91f16700Schasinglulu 
118*91f16700Schasinglulu int intel_fcs_random_number_gen_ext(uint32_t session_id, uint32_t context_id,
119*91f16700Schasinglulu 				uint32_t size, uint32_t *send_id)
120*91f16700Schasinglulu {
121*91f16700Schasinglulu 	int status;
122*91f16700Schasinglulu 	uint32_t payload_size;
123*91f16700Schasinglulu 	uint32_t crypto_header;
124*91f16700Schasinglulu 
125*91f16700Schasinglulu 	if (size > (FCS_RANDOM_EXT_MAX_WORD_SIZE *
126*91f16700Schasinglulu 		MBOX_WORD_BYTE) || size == 0U) {
127*91f16700Schasinglulu 		return INTEL_SIP_SMC_STATUS_REJECTED;
128*91f16700Schasinglulu 	}
129*91f16700Schasinglulu 
130*91f16700Schasinglulu 	if (!is_size_4_bytes_aligned(size)) {
131*91f16700Schasinglulu 		return INTEL_SIP_SMC_STATUS_REJECTED;
132*91f16700Schasinglulu 	}
133*91f16700Schasinglulu 
134*91f16700Schasinglulu 	crypto_header = (FCS_CS_FIELD_FLAG_INIT | FCS_CS_FIELD_FLAG_FINALIZE) <<
135*91f16700Schasinglulu 			FCS_CS_FIELD_FLAG_OFFSET;
136*91f16700Schasinglulu 
137*91f16700Schasinglulu 	fcs_rng_payload payload = {
138*91f16700Schasinglulu 		session_id,
139*91f16700Schasinglulu 		context_id,
140*91f16700Schasinglulu 		crypto_header,
141*91f16700Schasinglulu 		size
142*91f16700Schasinglulu 	};
143*91f16700Schasinglulu 
144*91f16700Schasinglulu 	payload_size = sizeof(payload) / MBOX_WORD_BYTE;
145*91f16700Schasinglulu 
146*91f16700Schasinglulu 	status = mailbox_send_cmd_async(send_id, MBOX_FCS_RANDOM_GEN,
147*91f16700Schasinglulu 					(uint32_t *) &payload, payload_size,
148*91f16700Schasinglulu 					CMD_INDIRECT);
149*91f16700Schasinglulu 
150*91f16700Schasinglulu 	if (status < 0) {
151*91f16700Schasinglulu 		return INTEL_SIP_SMC_STATUS_ERROR;
152*91f16700Schasinglulu 	}
153*91f16700Schasinglulu 
154*91f16700Schasinglulu 	return INTEL_SIP_SMC_STATUS_OK;
155*91f16700Schasinglulu }
156*91f16700Schasinglulu 
157*91f16700Schasinglulu uint32_t intel_fcs_send_cert(uint64_t addr, uint64_t size,
158*91f16700Schasinglulu 					uint32_t *send_id)
159*91f16700Schasinglulu {
160*91f16700Schasinglulu 	int status;
161*91f16700Schasinglulu 
162*91f16700Schasinglulu 	if (!is_address_in_ddr_range(addr, size)) {
163*91f16700Schasinglulu 		return INTEL_SIP_SMC_STATUS_REJECTED;
164*91f16700Schasinglulu 	}
165*91f16700Schasinglulu 
166*91f16700Schasinglulu 	if (!is_size_4_bytes_aligned(size)) {
167*91f16700Schasinglulu 		return INTEL_SIP_SMC_STATUS_REJECTED;
168*91f16700Schasinglulu 	}
169*91f16700Schasinglulu 
170*91f16700Schasinglulu 	status = mailbox_send_cmd_async(send_id, MBOX_CMD_VAB_SRC_CERT,
171*91f16700Schasinglulu 				(uint32_t *)addr, size / MBOX_WORD_BYTE,
172*91f16700Schasinglulu 				CMD_DIRECT);
173*91f16700Schasinglulu 
174*91f16700Schasinglulu 	flush_dcache_range(addr, size);
175*91f16700Schasinglulu 
176*91f16700Schasinglulu 	if (status < 0) {
177*91f16700Schasinglulu 		return INTEL_SIP_SMC_STATUS_ERROR;
178*91f16700Schasinglulu 	}
179*91f16700Schasinglulu 
180*91f16700Schasinglulu 	return INTEL_SIP_SMC_STATUS_OK;
181*91f16700Schasinglulu }
182*91f16700Schasinglulu 
183*91f16700Schasinglulu uint32_t intel_fcs_get_provision_data(uint32_t *send_id)
184*91f16700Schasinglulu {
185*91f16700Schasinglulu 	int status;
186*91f16700Schasinglulu 
187*91f16700Schasinglulu 	status = mailbox_send_cmd_async(send_id, MBOX_FCS_GET_PROVISION,
188*91f16700Schasinglulu 				NULL, 0U, CMD_DIRECT);
189*91f16700Schasinglulu 
190*91f16700Schasinglulu 	if (status < 0) {
191*91f16700Schasinglulu 		return INTEL_SIP_SMC_STATUS_ERROR;
192*91f16700Schasinglulu 	}
193*91f16700Schasinglulu 
194*91f16700Schasinglulu 	return INTEL_SIP_SMC_STATUS_OK;
195*91f16700Schasinglulu }
196*91f16700Schasinglulu 
197*91f16700Schasinglulu uint32_t intel_fcs_cntr_set_preauth(uint8_t counter_type, int32_t counter_value,
198*91f16700Schasinglulu 					uint32_t test_bit, uint32_t *mbox_error)
199*91f16700Schasinglulu {
200*91f16700Schasinglulu 	int status;
201*91f16700Schasinglulu 	uint32_t first_word;
202*91f16700Schasinglulu 	uint32_t payload_size;
203*91f16700Schasinglulu 
204*91f16700Schasinglulu 	if ((test_bit != MBOX_TEST_BIT) &&
205*91f16700Schasinglulu 		(test_bit != 0)) {
206*91f16700Schasinglulu 		return INTEL_SIP_SMC_STATUS_REJECTED;
207*91f16700Schasinglulu 	}
208*91f16700Schasinglulu 
209*91f16700Schasinglulu 	if ((counter_type < FCS_BIG_CNTR_SEL) ||
210*91f16700Schasinglulu 		(counter_type > FCS_SVN_CNTR_3_SEL)) {
211*91f16700Schasinglulu 		return INTEL_SIP_SMC_STATUS_REJECTED;
212*91f16700Schasinglulu 	}
213*91f16700Schasinglulu 
214*91f16700Schasinglulu 	if ((counter_type == FCS_BIG_CNTR_SEL) &&
215*91f16700Schasinglulu 		(counter_value > FCS_BIG_CNTR_VAL_MAX)) {
216*91f16700Schasinglulu 		return INTEL_SIP_SMC_STATUS_REJECTED;
217*91f16700Schasinglulu 	}
218*91f16700Schasinglulu 
219*91f16700Schasinglulu 	if ((counter_type >= FCS_SVN_CNTR_0_SEL) &&
220*91f16700Schasinglulu 		(counter_type <= FCS_SVN_CNTR_3_SEL) &&
221*91f16700Schasinglulu 		(counter_value > FCS_SVN_CNTR_VAL_MAX)) {
222*91f16700Schasinglulu 		return INTEL_SIP_SMC_STATUS_REJECTED;
223*91f16700Schasinglulu 	}
224*91f16700Schasinglulu 
225*91f16700Schasinglulu 	first_word = test_bit | counter_type;
226*91f16700Schasinglulu 	fcs_cntr_set_preauth_payload payload = {
227*91f16700Schasinglulu 		first_word,
228*91f16700Schasinglulu 		counter_value
229*91f16700Schasinglulu 	};
230*91f16700Schasinglulu 
231*91f16700Schasinglulu 	payload_size = sizeof(payload) / MBOX_WORD_BYTE;
232*91f16700Schasinglulu 	status =  mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_CNTR_SET_PREAUTH,
233*91f16700Schasinglulu 				  (uint32_t *) &payload, payload_size,
234*91f16700Schasinglulu 				  CMD_CASUAL, NULL, NULL);
235*91f16700Schasinglulu 
236*91f16700Schasinglulu 	if (status < 0) {
237*91f16700Schasinglulu 		*mbox_error = -status;
238*91f16700Schasinglulu 		return INTEL_SIP_SMC_STATUS_ERROR;
239*91f16700Schasinglulu 	}
240*91f16700Schasinglulu 
241*91f16700Schasinglulu 	return INTEL_SIP_SMC_STATUS_OK;
242*91f16700Schasinglulu }
243*91f16700Schasinglulu 
244*91f16700Schasinglulu uint32_t intel_fcs_encryption(uint32_t src_addr, uint32_t src_size,
245*91f16700Schasinglulu 		uint32_t dst_addr, uint32_t dst_size, uint32_t *send_id)
246*91f16700Schasinglulu {
247*91f16700Schasinglulu 	int status;
248*91f16700Schasinglulu 	uint32_t load_size;
249*91f16700Schasinglulu 
250*91f16700Schasinglulu 	fcs_encrypt_payload payload = {
251*91f16700Schasinglulu 		FCS_ENCRYPTION_DATA_0,
252*91f16700Schasinglulu 		src_addr,
253*91f16700Schasinglulu 		src_size,
254*91f16700Schasinglulu 		dst_addr,
255*91f16700Schasinglulu 		dst_size };
256*91f16700Schasinglulu 	load_size = sizeof(payload) / MBOX_WORD_BYTE;
257*91f16700Schasinglulu 
258*91f16700Schasinglulu 	if (!is_address_in_ddr_range(src_addr, src_size) ||
259*91f16700Schasinglulu 		!is_address_in_ddr_range(dst_addr, dst_size)) {
260*91f16700Schasinglulu 		return INTEL_SIP_SMC_STATUS_REJECTED;
261*91f16700Schasinglulu 	}
262*91f16700Schasinglulu 
263*91f16700Schasinglulu 	if (!is_size_4_bytes_aligned(src_size)) {
264*91f16700Schasinglulu 		return INTEL_SIP_SMC_STATUS_REJECTED;
265*91f16700Schasinglulu 	}
266*91f16700Schasinglulu 
267*91f16700Schasinglulu 	status = mailbox_send_cmd_async(send_id, MBOX_FCS_ENCRYPT_REQ,
268*91f16700Schasinglulu 				(uint32_t *) &payload, load_size,
269*91f16700Schasinglulu 				CMD_INDIRECT);
270*91f16700Schasinglulu 	inv_dcache_range(dst_addr, dst_size);
271*91f16700Schasinglulu 
272*91f16700Schasinglulu 	if (status < 0) {
273*91f16700Schasinglulu 		return INTEL_SIP_SMC_STATUS_REJECTED;
274*91f16700Schasinglulu 	}
275*91f16700Schasinglulu 
276*91f16700Schasinglulu 	return INTEL_SIP_SMC_STATUS_OK;
277*91f16700Schasinglulu }
278*91f16700Schasinglulu 
279*91f16700Schasinglulu uint32_t intel_fcs_decryption(uint32_t src_addr, uint32_t src_size,
280*91f16700Schasinglulu 		uint32_t dst_addr, uint32_t dst_size, uint32_t *send_id)
281*91f16700Schasinglulu {
282*91f16700Schasinglulu 	int status;
283*91f16700Schasinglulu 	uint32_t load_size;
284*91f16700Schasinglulu 	uintptr_t id_offset;
285*91f16700Schasinglulu 
286*91f16700Schasinglulu 	inv_dcache_range(src_addr, src_size); /* flush cache before mmio read to avoid reading old values */
287*91f16700Schasinglulu 	id_offset = src_addr + FCS_OWNER_ID_OFFSET;
288*91f16700Schasinglulu 	fcs_decrypt_payload payload = {
289*91f16700Schasinglulu 		FCS_DECRYPTION_DATA_0,
290*91f16700Schasinglulu 		{mmio_read_32(id_offset),
291*91f16700Schasinglulu 		mmio_read_32(id_offset + MBOX_WORD_BYTE)},
292*91f16700Schasinglulu 		src_addr,
293*91f16700Schasinglulu 		src_size,
294*91f16700Schasinglulu 		dst_addr,
295*91f16700Schasinglulu 		dst_size };
296*91f16700Schasinglulu 	load_size = sizeof(payload) / MBOX_WORD_BYTE;
297*91f16700Schasinglulu 
298*91f16700Schasinglulu 	if (!is_address_in_ddr_range(src_addr, src_size) ||
299*91f16700Schasinglulu 		!is_address_in_ddr_range(dst_addr, dst_size)) {
300*91f16700Schasinglulu 		return INTEL_SIP_SMC_STATUS_REJECTED;
301*91f16700Schasinglulu 	}
302*91f16700Schasinglulu 
303*91f16700Schasinglulu 	if (!is_size_4_bytes_aligned(src_size)) {
304*91f16700Schasinglulu 		return INTEL_SIP_SMC_STATUS_REJECTED;
305*91f16700Schasinglulu 	}
306*91f16700Schasinglulu 
307*91f16700Schasinglulu 	status = mailbox_send_cmd_async(send_id, MBOX_FCS_DECRYPT_REQ,
308*91f16700Schasinglulu 				(uint32_t *) &payload, load_size,
309*91f16700Schasinglulu 				CMD_INDIRECT);
310*91f16700Schasinglulu 	inv_dcache_range(dst_addr, dst_size);
311*91f16700Schasinglulu 
312*91f16700Schasinglulu 	if (status < 0) {
313*91f16700Schasinglulu 		return INTEL_SIP_SMC_STATUS_REJECTED;
314*91f16700Schasinglulu 	}
315*91f16700Schasinglulu 
316*91f16700Schasinglulu 	return INTEL_SIP_SMC_STATUS_OK;
317*91f16700Schasinglulu }
318*91f16700Schasinglulu 
319*91f16700Schasinglulu int intel_fcs_encryption_ext(uint32_t session_id, uint32_t context_id,
320*91f16700Schasinglulu 		uint32_t src_addr, uint32_t src_size,
321*91f16700Schasinglulu 		uint32_t dst_addr, uint32_t *dst_size, uint32_t *mbox_error)
322*91f16700Schasinglulu {
323*91f16700Schasinglulu 	int status;
324*91f16700Schasinglulu 	uint32_t payload_size;
325*91f16700Schasinglulu 	uint32_t resp_len = FCS_CRYPTION_RESP_WORD_SIZE;
326*91f16700Schasinglulu 	uint32_t resp_data[FCS_CRYPTION_RESP_WORD_SIZE] = {0U};
327*91f16700Schasinglulu 
328*91f16700Schasinglulu 	if ((dst_size == NULL) || (mbox_error == NULL)) {
329*91f16700Schasinglulu 		return INTEL_SIP_SMC_STATUS_REJECTED;
330*91f16700Schasinglulu 	}
331*91f16700Schasinglulu 
332*91f16700Schasinglulu 	if (!is_address_in_ddr_range(src_addr, src_size) ||
333*91f16700Schasinglulu 		!is_address_in_ddr_range(dst_addr, *dst_size)) {
334*91f16700Schasinglulu 		return INTEL_SIP_SMC_STATUS_REJECTED;
335*91f16700Schasinglulu 	}
336*91f16700Schasinglulu 
337*91f16700Schasinglulu 	if (!is_size_4_bytes_aligned(src_size)) {
338*91f16700Schasinglulu 		return INTEL_SIP_SMC_STATUS_REJECTED;
339*91f16700Schasinglulu 	}
340*91f16700Schasinglulu 
341*91f16700Schasinglulu 	fcs_encrypt_ext_payload payload = {
342*91f16700Schasinglulu 		session_id,
343*91f16700Schasinglulu 		context_id,
344*91f16700Schasinglulu 		FCS_CRYPTION_CRYPTO_HEADER,
345*91f16700Schasinglulu 		src_addr,
346*91f16700Schasinglulu 		src_size,
347*91f16700Schasinglulu 		dst_addr,
348*91f16700Schasinglulu 		*dst_size
349*91f16700Schasinglulu 	};
350*91f16700Schasinglulu 
351*91f16700Schasinglulu 	payload_size = sizeof(payload) / MBOX_WORD_BYTE;
352*91f16700Schasinglulu 
353*91f16700Schasinglulu 	status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_ENCRYPT_REQ,
354*91f16700Schasinglulu 				(uint32_t *) &payload, payload_size,
355*91f16700Schasinglulu 				CMD_CASUAL, resp_data, &resp_len);
356*91f16700Schasinglulu 
357*91f16700Schasinglulu 	if (status < 0) {
358*91f16700Schasinglulu 		*mbox_error = -status;
359*91f16700Schasinglulu 		return INTEL_SIP_SMC_STATUS_ERROR;
360*91f16700Schasinglulu 	}
361*91f16700Schasinglulu 
362*91f16700Schasinglulu 	if (resp_len != FCS_CRYPTION_RESP_WORD_SIZE) {
363*91f16700Schasinglulu 		*mbox_error = MBOX_RET_ERROR;
364*91f16700Schasinglulu 		return INTEL_SIP_SMC_STATUS_ERROR;
365*91f16700Schasinglulu 	}
366*91f16700Schasinglulu 
367*91f16700Schasinglulu 	*dst_size = resp_data[FCS_CRYPTION_RESP_SIZE_OFFSET];
368*91f16700Schasinglulu 	inv_dcache_range(dst_addr, *dst_size);
369*91f16700Schasinglulu 
370*91f16700Schasinglulu 	return INTEL_SIP_SMC_STATUS_OK;
371*91f16700Schasinglulu }
372*91f16700Schasinglulu 
373*91f16700Schasinglulu int intel_fcs_decryption_ext(uint32_t session_id, uint32_t context_id,
374*91f16700Schasinglulu 		uint32_t src_addr, uint32_t src_size,
375*91f16700Schasinglulu 		uint32_t dst_addr, uint32_t *dst_size, uint32_t *mbox_error)
376*91f16700Schasinglulu {
377*91f16700Schasinglulu 	int status;
378*91f16700Schasinglulu 	uintptr_t id_offset;
379*91f16700Schasinglulu 	uint32_t payload_size;
380*91f16700Schasinglulu 	uint32_t resp_len = FCS_CRYPTION_RESP_WORD_SIZE;
381*91f16700Schasinglulu 	uint32_t resp_data[FCS_CRYPTION_RESP_WORD_SIZE] = {0U};
382*91f16700Schasinglulu 
383*91f16700Schasinglulu 	if ((dst_size == NULL) || (mbox_error == NULL)) {
384*91f16700Schasinglulu 		return INTEL_SIP_SMC_STATUS_REJECTED;
385*91f16700Schasinglulu 	}
386*91f16700Schasinglulu 
387*91f16700Schasinglulu 	if (!is_address_in_ddr_range(src_addr, src_size) ||
388*91f16700Schasinglulu 		!is_address_in_ddr_range(dst_addr, *dst_size)) {
389*91f16700Schasinglulu 		return INTEL_SIP_SMC_STATUS_REJECTED;
390*91f16700Schasinglulu 	}
391*91f16700Schasinglulu 
392*91f16700Schasinglulu 	if (!is_size_4_bytes_aligned(src_size)) {
393*91f16700Schasinglulu 		return INTEL_SIP_SMC_STATUS_REJECTED;
394*91f16700Schasinglulu 	}
395*91f16700Schasinglulu 
396*91f16700Schasinglulu 	inv_dcache_range(src_addr, src_size); /* flush cache before mmio read to avoid reading old values */
397*91f16700Schasinglulu 	id_offset = src_addr + FCS_OWNER_ID_OFFSET;
398*91f16700Schasinglulu 	fcs_decrypt_ext_payload payload = {
399*91f16700Schasinglulu 		session_id,
400*91f16700Schasinglulu 		context_id,
401*91f16700Schasinglulu 		FCS_CRYPTION_CRYPTO_HEADER,
402*91f16700Schasinglulu 		{mmio_read_32(id_offset),
403*91f16700Schasinglulu 		mmio_read_32(id_offset + MBOX_WORD_BYTE)},
404*91f16700Schasinglulu 		src_addr,
405*91f16700Schasinglulu 		src_size,
406*91f16700Schasinglulu 		dst_addr,
407*91f16700Schasinglulu 		*dst_size
408*91f16700Schasinglulu 	};
409*91f16700Schasinglulu 
410*91f16700Schasinglulu 	payload_size = sizeof(payload) / MBOX_WORD_BYTE;
411*91f16700Schasinglulu 
412*91f16700Schasinglulu 	status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_DECRYPT_REQ,
413*91f16700Schasinglulu 				(uint32_t *) &payload, payload_size,
414*91f16700Schasinglulu 				CMD_CASUAL, resp_data, &resp_len);
415*91f16700Schasinglulu 
416*91f16700Schasinglulu 	if (status == MBOX_RET_SDOS_DECRYPTION_ERROR_102 ||
417*91f16700Schasinglulu 		status == MBOX_RET_SDOS_DECRYPTION_ERROR_103) {
418*91f16700Schasinglulu 		*mbox_error = -status;
419*91f16700Schasinglulu 	} else if (status < 0) {
420*91f16700Schasinglulu 		*mbox_error = -status;
421*91f16700Schasinglulu 		return INTEL_SIP_SMC_STATUS_ERROR;
422*91f16700Schasinglulu 	}
423*91f16700Schasinglulu 
424*91f16700Schasinglulu 	if (resp_len != FCS_CRYPTION_RESP_WORD_SIZE) {
425*91f16700Schasinglulu 		*mbox_error = MBOX_RET_ERROR;
426*91f16700Schasinglulu 		return INTEL_SIP_SMC_STATUS_ERROR;
427*91f16700Schasinglulu 	}
428*91f16700Schasinglulu 
429*91f16700Schasinglulu 	*dst_size = resp_data[FCS_CRYPTION_RESP_SIZE_OFFSET];
430*91f16700Schasinglulu 	inv_dcache_range(dst_addr, *dst_size);
431*91f16700Schasinglulu 
432*91f16700Schasinglulu 	return INTEL_SIP_SMC_STATUS_OK;
433*91f16700Schasinglulu }
434*91f16700Schasinglulu 
435*91f16700Schasinglulu int intel_fcs_sigma_teardown(uint32_t session_id, uint32_t *mbox_error)
436*91f16700Schasinglulu {
437*91f16700Schasinglulu 	int status;
438*91f16700Schasinglulu 
439*91f16700Schasinglulu 	if ((session_id != PSGSIGMA_SESSION_ID_ONE) &&
440*91f16700Schasinglulu 		(session_id != PSGSIGMA_UNKNOWN_SESSION)) {
441*91f16700Schasinglulu 		return INTEL_SIP_SMC_STATUS_REJECTED;
442*91f16700Schasinglulu 	}
443*91f16700Schasinglulu 
444*91f16700Schasinglulu 	psgsigma_teardown_msg message = {
445*91f16700Schasinglulu 		RESERVED_AS_ZERO,
446*91f16700Schasinglulu 		PSGSIGMA_TEARDOWN_MAGIC,
447*91f16700Schasinglulu 		session_id
448*91f16700Schasinglulu 	};
449*91f16700Schasinglulu 
450*91f16700Schasinglulu 	status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_PSG_SIGMA_TEARDOWN,
451*91f16700Schasinglulu 			(uint32_t *) &message, sizeof(message) / MBOX_WORD_BYTE,
452*91f16700Schasinglulu 			CMD_CASUAL, NULL, NULL);
453*91f16700Schasinglulu 
454*91f16700Schasinglulu 	if (status < 0) {
455*91f16700Schasinglulu 		*mbox_error = -status;
456*91f16700Schasinglulu 		return INTEL_SIP_SMC_STATUS_ERROR;
457*91f16700Schasinglulu 	}
458*91f16700Schasinglulu 
459*91f16700Schasinglulu 	return INTEL_SIP_SMC_STATUS_OK;
460*91f16700Schasinglulu }
461*91f16700Schasinglulu 
462*91f16700Schasinglulu int intel_fcs_chip_id(uint32_t *id_low, uint32_t *id_high, uint32_t *mbox_error)
463*91f16700Schasinglulu {
464*91f16700Schasinglulu 	int status;
465*91f16700Schasinglulu 	uint32_t load_size;
466*91f16700Schasinglulu 	uint32_t chip_id[2];
467*91f16700Schasinglulu 
468*91f16700Schasinglulu 	load_size = sizeof(chip_id) / MBOX_WORD_BYTE;
469*91f16700Schasinglulu 
470*91f16700Schasinglulu 	status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_CMD_GET_CHIPID, NULL,
471*91f16700Schasinglulu 			0U, CMD_CASUAL, (uint32_t *) chip_id, &load_size);
472*91f16700Schasinglulu 
473*91f16700Schasinglulu 	if (status < 0) {
474*91f16700Schasinglulu 		*mbox_error = -status;
475*91f16700Schasinglulu 		return INTEL_SIP_SMC_STATUS_ERROR;
476*91f16700Schasinglulu 	}
477*91f16700Schasinglulu 
478*91f16700Schasinglulu 	*id_low = chip_id[0];
479*91f16700Schasinglulu 	*id_high = chip_id[1];
480*91f16700Schasinglulu 
481*91f16700Schasinglulu 	return INTEL_SIP_SMC_STATUS_OK;
482*91f16700Schasinglulu }
483*91f16700Schasinglulu 
484*91f16700Schasinglulu int intel_fcs_attestation_subkey(uint64_t src_addr, uint32_t src_size,
485*91f16700Schasinglulu 		uint64_t dst_addr, uint32_t *dst_size, uint32_t *mbox_error)
486*91f16700Schasinglulu {
487*91f16700Schasinglulu 	int status;
488*91f16700Schasinglulu 	uint32_t send_size = src_size / MBOX_WORD_BYTE;
489*91f16700Schasinglulu 	uint32_t ret_size = *dst_size / MBOX_WORD_BYTE;
490*91f16700Schasinglulu 
491*91f16700Schasinglulu 
492*91f16700Schasinglulu 	if (!is_address_in_ddr_range(src_addr, src_size) ||
493*91f16700Schasinglulu 		!is_address_in_ddr_range(dst_addr, *dst_size)) {
494*91f16700Schasinglulu 		return INTEL_SIP_SMC_STATUS_REJECTED;
495*91f16700Schasinglulu 	}
496*91f16700Schasinglulu 
497*91f16700Schasinglulu 	status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_ATTESTATION_SUBKEY,
498*91f16700Schasinglulu 			(uint32_t *) src_addr, send_size, CMD_CASUAL,
499*91f16700Schasinglulu 			(uint32_t *) dst_addr, &ret_size);
500*91f16700Schasinglulu 
501*91f16700Schasinglulu 	if (status < 0) {
502*91f16700Schasinglulu 		*mbox_error = -status;
503*91f16700Schasinglulu 		return INTEL_SIP_SMC_STATUS_ERROR;
504*91f16700Schasinglulu 	}
505*91f16700Schasinglulu 
506*91f16700Schasinglulu 	*dst_size = ret_size * MBOX_WORD_BYTE;
507*91f16700Schasinglulu 	flush_dcache_range(dst_addr, *dst_size);
508*91f16700Schasinglulu 
509*91f16700Schasinglulu 	return INTEL_SIP_SMC_STATUS_OK;
510*91f16700Schasinglulu }
511*91f16700Schasinglulu 
512*91f16700Schasinglulu int intel_fcs_get_measurement(uint64_t src_addr, uint32_t src_size,
513*91f16700Schasinglulu 		uint64_t dst_addr, uint32_t *dst_size, uint32_t *mbox_error)
514*91f16700Schasinglulu {
515*91f16700Schasinglulu 	int status;
516*91f16700Schasinglulu 	uint32_t send_size = src_size / MBOX_WORD_BYTE;
517*91f16700Schasinglulu 	uint32_t ret_size = *dst_size / MBOX_WORD_BYTE;
518*91f16700Schasinglulu 
519*91f16700Schasinglulu 	if (!is_address_in_ddr_range(src_addr, src_size) ||
520*91f16700Schasinglulu 		!is_address_in_ddr_range(dst_addr, *dst_size)) {
521*91f16700Schasinglulu 		return INTEL_SIP_SMC_STATUS_REJECTED;
522*91f16700Schasinglulu 	}
523*91f16700Schasinglulu 
524*91f16700Schasinglulu 	status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_GET_MEASUREMENT,
525*91f16700Schasinglulu 			(uint32_t *) src_addr, send_size, CMD_CASUAL,
526*91f16700Schasinglulu 			(uint32_t *) dst_addr, &ret_size);
527*91f16700Schasinglulu 
528*91f16700Schasinglulu 	if (status < 0) {
529*91f16700Schasinglulu 		*mbox_error = -status;
530*91f16700Schasinglulu 		return INTEL_SIP_SMC_STATUS_ERROR;
531*91f16700Schasinglulu 	}
532*91f16700Schasinglulu 
533*91f16700Schasinglulu 	*dst_size = ret_size * MBOX_WORD_BYTE;
534*91f16700Schasinglulu 	flush_dcache_range(dst_addr, *dst_size);
535*91f16700Schasinglulu 
536*91f16700Schasinglulu 	return INTEL_SIP_SMC_STATUS_OK;
537*91f16700Schasinglulu }
538*91f16700Schasinglulu 
539*91f16700Schasinglulu uint32_t intel_fcs_get_rom_patch_sha384(uint64_t addr, uint64_t *ret_size,
540*91f16700Schasinglulu 					uint32_t *mbox_error)
541*91f16700Schasinglulu {
542*91f16700Schasinglulu 	int status;
543*91f16700Schasinglulu 	unsigned int resp_len = FCS_SHA384_WORD_SIZE;
544*91f16700Schasinglulu 
545*91f16700Schasinglulu 	if (!is_address_in_ddr_range(addr, FCS_SHA384_BYTE_SIZE)) {
546*91f16700Schasinglulu 		return INTEL_SIP_SMC_STATUS_REJECTED;
547*91f16700Schasinglulu 	}
548*91f16700Schasinglulu 
549*91f16700Schasinglulu 	status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_GET_ROM_PATCH_SHA384, NULL, 0U,
550*91f16700Schasinglulu 			CMD_CASUAL, (uint32_t *) addr, &resp_len);
551*91f16700Schasinglulu 
552*91f16700Schasinglulu 	if (status < 0) {
553*91f16700Schasinglulu 		*mbox_error = -status;
554*91f16700Schasinglulu 		return INTEL_SIP_SMC_STATUS_ERROR;
555*91f16700Schasinglulu 	}
556*91f16700Schasinglulu 
557*91f16700Schasinglulu 	if (resp_len != FCS_SHA384_WORD_SIZE) {
558*91f16700Schasinglulu 		*mbox_error = GENERIC_RESPONSE_ERROR;
559*91f16700Schasinglulu 		return INTEL_SIP_SMC_STATUS_ERROR;
560*91f16700Schasinglulu 	}
561*91f16700Schasinglulu 
562*91f16700Schasinglulu 	*ret_size = FCS_SHA384_BYTE_SIZE;
563*91f16700Schasinglulu 
564*91f16700Schasinglulu 	flush_dcache_range(addr, *ret_size);
565*91f16700Schasinglulu 
566*91f16700Schasinglulu 	return INTEL_SIP_SMC_STATUS_OK;
567*91f16700Schasinglulu }
568*91f16700Schasinglulu 
569*91f16700Schasinglulu int intel_fcs_get_attestation_cert(uint32_t cert_request, uint64_t dst_addr,
570*91f16700Schasinglulu 			uint32_t *dst_size, uint32_t *mbox_error)
571*91f16700Schasinglulu {
572*91f16700Schasinglulu 	int status;
573*91f16700Schasinglulu 	uint32_t ret_size = *dst_size / MBOX_WORD_BYTE;
574*91f16700Schasinglulu 
575*91f16700Schasinglulu 	if (mbox_error == NULL) {
576*91f16700Schasinglulu 		return INTEL_SIP_SMC_STATUS_REJECTED;
577*91f16700Schasinglulu 	}
578*91f16700Schasinglulu 
579*91f16700Schasinglulu 	if (cert_request < FCS_ATTEST_FIRMWARE_CERT ||
580*91f16700Schasinglulu 		cert_request > FCS_ATTEST_CERT_MAX_REQ_PARAM) {
581*91f16700Schasinglulu 		return INTEL_SIP_SMC_STATUS_REJECTED;
582*91f16700Schasinglulu 	}
583*91f16700Schasinglulu 
584*91f16700Schasinglulu 	if (!is_address_in_ddr_range(dst_addr, *dst_size)) {
585*91f16700Schasinglulu 		return INTEL_SIP_SMC_STATUS_REJECTED;
586*91f16700Schasinglulu 	}
587*91f16700Schasinglulu 
588*91f16700Schasinglulu 	status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_GET_ATTESTATION_CERT,
589*91f16700Schasinglulu 			(uint32_t *) &cert_request, 1U, CMD_CASUAL,
590*91f16700Schasinglulu 			(uint32_t *) dst_addr, &ret_size);
591*91f16700Schasinglulu 
592*91f16700Schasinglulu 	if (status < 0) {
593*91f16700Schasinglulu 		*mbox_error = -status;
594*91f16700Schasinglulu 		return INTEL_SIP_SMC_STATUS_ERROR;
595*91f16700Schasinglulu 	}
596*91f16700Schasinglulu 
597*91f16700Schasinglulu 	*dst_size = ret_size * MBOX_WORD_BYTE;
598*91f16700Schasinglulu 	flush_dcache_range(dst_addr, *dst_size);
599*91f16700Schasinglulu 
600*91f16700Schasinglulu 	return INTEL_SIP_SMC_STATUS_OK;
601*91f16700Schasinglulu }
602*91f16700Schasinglulu 
603*91f16700Schasinglulu int intel_fcs_create_cert_on_reload(uint32_t cert_request,
604*91f16700Schasinglulu 			uint32_t *mbox_error)
605*91f16700Schasinglulu {
606*91f16700Schasinglulu 	int status;
607*91f16700Schasinglulu 
608*91f16700Schasinglulu 	if (mbox_error == NULL) {
609*91f16700Schasinglulu 		return INTEL_SIP_SMC_STATUS_REJECTED;
610*91f16700Schasinglulu 	}
611*91f16700Schasinglulu 
612*91f16700Schasinglulu 	if (cert_request < FCS_ATTEST_FIRMWARE_CERT ||
613*91f16700Schasinglulu 		cert_request > FCS_ATTEST_CERT_MAX_REQ_PARAM) {
614*91f16700Schasinglulu 		return INTEL_SIP_SMC_STATUS_REJECTED;
615*91f16700Schasinglulu 	}
616*91f16700Schasinglulu 
617*91f16700Schasinglulu 	status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_CREATE_CERT_ON_RELOAD,
618*91f16700Schasinglulu 			(uint32_t *) &cert_request, 1U, CMD_CASUAL,
619*91f16700Schasinglulu 			NULL, NULL);
620*91f16700Schasinglulu 
621*91f16700Schasinglulu 	if (status < 0) {
622*91f16700Schasinglulu 		*mbox_error = -status;
623*91f16700Schasinglulu 		return INTEL_SIP_SMC_STATUS_ERROR;
624*91f16700Schasinglulu 	}
625*91f16700Schasinglulu 
626*91f16700Schasinglulu 	return INTEL_SIP_SMC_STATUS_OK;
627*91f16700Schasinglulu }
628*91f16700Schasinglulu 
629*91f16700Schasinglulu int intel_fcs_open_crypto_service_session(uint32_t *session_id,
630*91f16700Schasinglulu 			uint32_t *mbox_error)
631*91f16700Schasinglulu {
632*91f16700Schasinglulu 	int status;
633*91f16700Schasinglulu 	uint32_t resp_len = 1U;
634*91f16700Schasinglulu 
635*91f16700Schasinglulu 	if ((session_id == NULL) || (mbox_error == NULL)) {
636*91f16700Schasinglulu 		return INTEL_SIP_SMC_STATUS_REJECTED;
637*91f16700Schasinglulu 	}
638*91f16700Schasinglulu 
639*91f16700Schasinglulu 	status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_OPEN_CS_SESSION,
640*91f16700Schasinglulu 			NULL, 0U, CMD_CASUAL, session_id, &resp_len);
641*91f16700Schasinglulu 
642*91f16700Schasinglulu 	if (status < 0) {
643*91f16700Schasinglulu 		*mbox_error = -status;
644*91f16700Schasinglulu 		return INTEL_SIP_SMC_STATUS_ERROR;
645*91f16700Schasinglulu 	}
646*91f16700Schasinglulu 
647*91f16700Schasinglulu 	return INTEL_SIP_SMC_STATUS_OK;
648*91f16700Schasinglulu }
649*91f16700Schasinglulu 
650*91f16700Schasinglulu int intel_fcs_close_crypto_service_session(uint32_t session_id,
651*91f16700Schasinglulu 			uint32_t *mbox_error)
652*91f16700Schasinglulu {
653*91f16700Schasinglulu 	int status;
654*91f16700Schasinglulu 
655*91f16700Schasinglulu 	if (mbox_error == NULL) {
656*91f16700Schasinglulu 		return INTEL_SIP_SMC_STATUS_REJECTED;
657*91f16700Schasinglulu 	}
658*91f16700Schasinglulu 
659*91f16700Schasinglulu 	status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_CLOSE_CS_SESSION,
660*91f16700Schasinglulu 			&session_id, 1U, CMD_CASUAL, NULL, NULL);
661*91f16700Schasinglulu 
662*91f16700Schasinglulu 	if (status < 0) {
663*91f16700Schasinglulu 		*mbox_error = -status;
664*91f16700Schasinglulu 		return INTEL_SIP_SMC_STATUS_ERROR;
665*91f16700Schasinglulu 	}
666*91f16700Schasinglulu 
667*91f16700Schasinglulu 	return INTEL_SIP_SMC_STATUS_OK;
668*91f16700Schasinglulu }
669*91f16700Schasinglulu 
670*91f16700Schasinglulu int intel_fcs_import_crypto_service_key(uint64_t src_addr, uint32_t src_size,
671*91f16700Schasinglulu 		uint32_t *send_id)
672*91f16700Schasinglulu {
673*91f16700Schasinglulu 	int status;
674*91f16700Schasinglulu 
675*91f16700Schasinglulu 	if (src_size > (FCS_CS_KEY_OBJ_MAX_WORD_SIZE *
676*91f16700Schasinglulu 		MBOX_WORD_BYTE)) {
677*91f16700Schasinglulu 		return INTEL_SIP_SMC_STATUS_REJECTED;
678*91f16700Schasinglulu 	}
679*91f16700Schasinglulu 
680*91f16700Schasinglulu 	if (!is_address_in_ddr_range(src_addr, src_size)) {
681*91f16700Schasinglulu 		return INTEL_SIP_SMC_STATUS_REJECTED;
682*91f16700Schasinglulu 	}
683*91f16700Schasinglulu 
684*91f16700Schasinglulu 	status = mailbox_send_cmd_async(send_id, MBOX_FCS_IMPORT_CS_KEY,
685*91f16700Schasinglulu 				(uint32_t *)src_addr, src_size / MBOX_WORD_BYTE,
686*91f16700Schasinglulu 				CMD_INDIRECT);
687*91f16700Schasinglulu 
688*91f16700Schasinglulu 	if (status < 0) {
689*91f16700Schasinglulu 		return INTEL_SIP_SMC_STATUS_ERROR;
690*91f16700Schasinglulu 	}
691*91f16700Schasinglulu 
692*91f16700Schasinglulu 	return INTEL_SIP_SMC_STATUS_OK;
693*91f16700Schasinglulu }
694*91f16700Schasinglulu 
695*91f16700Schasinglulu int intel_fcs_export_crypto_service_key(uint32_t session_id, uint32_t key_id,
696*91f16700Schasinglulu 		uint64_t dst_addr, uint32_t *dst_size,
697*91f16700Schasinglulu 		uint32_t *mbox_error)
698*91f16700Schasinglulu {
699*91f16700Schasinglulu 	int status;
700*91f16700Schasinglulu 	uint32_t i;
701*91f16700Schasinglulu 	uint32_t payload_size;
702*91f16700Schasinglulu 	uint32_t resp_len = FCS_CS_KEY_OBJ_MAX_WORD_SIZE;
703*91f16700Schasinglulu 	uint32_t resp_data[FCS_CS_KEY_OBJ_MAX_WORD_SIZE] = {0U};
704*91f16700Schasinglulu 	uint32_t op_status = 0U;
705*91f16700Schasinglulu 
706*91f16700Schasinglulu 	if ((dst_size == NULL) || (mbox_error == NULL)) {
707*91f16700Schasinglulu 		return INTEL_SIP_SMC_STATUS_REJECTED;
708*91f16700Schasinglulu 	}
709*91f16700Schasinglulu 
710*91f16700Schasinglulu 	if (!is_address_in_ddr_range(dst_addr, *dst_size)) {
711*91f16700Schasinglulu 		return INTEL_SIP_SMC_STATUS_REJECTED;
712*91f16700Schasinglulu 	}
713*91f16700Schasinglulu 
714*91f16700Schasinglulu 	fcs_cs_key_payload payload = {
715*91f16700Schasinglulu 		session_id,
716*91f16700Schasinglulu 		RESERVED_AS_ZERO,
717*91f16700Schasinglulu 		RESERVED_AS_ZERO,
718*91f16700Schasinglulu 		key_id
719*91f16700Schasinglulu 	};
720*91f16700Schasinglulu 
721*91f16700Schasinglulu 	payload_size = sizeof(payload) / MBOX_WORD_BYTE;
722*91f16700Schasinglulu 
723*91f16700Schasinglulu 	status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_EXPORT_CS_KEY,
724*91f16700Schasinglulu 			(uint32_t *) &payload, payload_size,
725*91f16700Schasinglulu 			CMD_CASUAL, resp_data, &resp_len);
726*91f16700Schasinglulu 
727*91f16700Schasinglulu 	if (resp_len > 0) {
728*91f16700Schasinglulu 		op_status = resp_data[0] & FCS_CS_KEY_RESP_STATUS_MASK;
729*91f16700Schasinglulu 	}
730*91f16700Schasinglulu 
731*91f16700Schasinglulu 	if (status < 0) {
732*91f16700Schasinglulu 		*mbox_error = (-status) | (op_status << FCS_CS_KEY_RESP_STATUS_OFFSET);
733*91f16700Schasinglulu 		return INTEL_SIP_SMC_STATUS_ERROR;
734*91f16700Schasinglulu 	}
735*91f16700Schasinglulu 
736*91f16700Schasinglulu 	if (resp_len > 1) {
737*91f16700Schasinglulu 
738*91f16700Schasinglulu 		/* Export key object is start at second response data */
739*91f16700Schasinglulu 		*dst_size = (resp_len - 1) * MBOX_WORD_BYTE;
740*91f16700Schasinglulu 
741*91f16700Schasinglulu 		for (i = 1U; i < resp_len; i++) {
742*91f16700Schasinglulu 			mmio_write_32(dst_addr, resp_data[i]);
743*91f16700Schasinglulu 			dst_addr += MBOX_WORD_BYTE;
744*91f16700Schasinglulu 		}
745*91f16700Schasinglulu 
746*91f16700Schasinglulu 		flush_dcache_range(dst_addr - *dst_size, *dst_size);
747*91f16700Schasinglulu 
748*91f16700Schasinglulu 	} else {
749*91f16700Schasinglulu 
750*91f16700Schasinglulu 		/* Unexpected response, missing key object in response */
751*91f16700Schasinglulu 		*mbox_error = MBOX_RET_ERROR;
752*91f16700Schasinglulu 		return INTEL_SIP_SMC_STATUS_ERROR;
753*91f16700Schasinglulu 	}
754*91f16700Schasinglulu 
755*91f16700Schasinglulu 	return INTEL_SIP_SMC_STATUS_OK;
756*91f16700Schasinglulu }
757*91f16700Schasinglulu 
758*91f16700Schasinglulu int intel_fcs_remove_crypto_service_key(uint32_t session_id, uint32_t key_id,
759*91f16700Schasinglulu 		uint32_t *mbox_error)
760*91f16700Schasinglulu {
761*91f16700Schasinglulu 	int status;
762*91f16700Schasinglulu 	uint32_t payload_size;
763*91f16700Schasinglulu 	uint32_t resp_len = 1U;
764*91f16700Schasinglulu 	uint32_t resp_data = 0U;
765*91f16700Schasinglulu 	uint32_t op_status = 0U;
766*91f16700Schasinglulu 
767*91f16700Schasinglulu 	if (mbox_error == NULL) {
768*91f16700Schasinglulu 		return INTEL_SIP_SMC_STATUS_REJECTED;
769*91f16700Schasinglulu 	}
770*91f16700Schasinglulu 
771*91f16700Schasinglulu 	fcs_cs_key_payload payload = {
772*91f16700Schasinglulu 		session_id,
773*91f16700Schasinglulu 		RESERVED_AS_ZERO,
774*91f16700Schasinglulu 		RESERVED_AS_ZERO,
775*91f16700Schasinglulu 		key_id
776*91f16700Schasinglulu 	};
777*91f16700Schasinglulu 
778*91f16700Schasinglulu 	payload_size = sizeof(payload) / MBOX_WORD_BYTE;
779*91f16700Schasinglulu 
780*91f16700Schasinglulu 	status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_REMOVE_CS_KEY,
781*91f16700Schasinglulu 			(uint32_t *) &payload, payload_size,
782*91f16700Schasinglulu 			CMD_CASUAL, &resp_data, &resp_len);
783*91f16700Schasinglulu 
784*91f16700Schasinglulu 	if (resp_len > 0) {
785*91f16700Schasinglulu 		op_status = resp_data & FCS_CS_KEY_RESP_STATUS_MASK;
786*91f16700Schasinglulu 	}
787*91f16700Schasinglulu 
788*91f16700Schasinglulu 	if (status < 0) {
789*91f16700Schasinglulu 		*mbox_error = (-status) | (op_status << FCS_CS_KEY_RESP_STATUS_OFFSET);
790*91f16700Schasinglulu 		return INTEL_SIP_SMC_STATUS_ERROR;
791*91f16700Schasinglulu 	}
792*91f16700Schasinglulu 
793*91f16700Schasinglulu 	return INTEL_SIP_SMC_STATUS_OK;
794*91f16700Schasinglulu }
795*91f16700Schasinglulu 
796*91f16700Schasinglulu int intel_fcs_get_crypto_service_key_info(uint32_t session_id, uint32_t key_id,
797*91f16700Schasinglulu 		uint64_t dst_addr, uint32_t *dst_size,
798*91f16700Schasinglulu 		uint32_t *mbox_error)
799*91f16700Schasinglulu {
800*91f16700Schasinglulu 	int status;
801*91f16700Schasinglulu 	uint32_t payload_size;
802*91f16700Schasinglulu 	uint32_t resp_len = FCS_CS_KEY_INFO_MAX_WORD_SIZE;
803*91f16700Schasinglulu 	uint32_t op_status = 0U;
804*91f16700Schasinglulu 
805*91f16700Schasinglulu 	if ((dst_size == NULL) || (mbox_error == NULL)) {
806*91f16700Schasinglulu 		return INTEL_SIP_SMC_STATUS_REJECTED;
807*91f16700Schasinglulu 	}
808*91f16700Schasinglulu 
809*91f16700Schasinglulu 	if (!is_address_in_ddr_range(dst_addr, *dst_size)) {
810*91f16700Schasinglulu 		return INTEL_SIP_SMC_STATUS_REJECTED;
811*91f16700Schasinglulu 	}
812*91f16700Schasinglulu 
813*91f16700Schasinglulu 	fcs_cs_key_payload payload = {
814*91f16700Schasinglulu 		session_id,
815*91f16700Schasinglulu 		RESERVED_AS_ZERO,
816*91f16700Schasinglulu 		RESERVED_AS_ZERO,
817*91f16700Schasinglulu 		key_id
818*91f16700Schasinglulu 	};
819*91f16700Schasinglulu 
820*91f16700Schasinglulu 	payload_size = sizeof(payload) / MBOX_WORD_BYTE;
821*91f16700Schasinglulu 
822*91f16700Schasinglulu 	status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_GET_CS_KEY_INFO,
823*91f16700Schasinglulu 				(uint32_t *) &payload, payload_size,
824*91f16700Schasinglulu 				CMD_CASUAL, (uint32_t *) dst_addr, &resp_len);
825*91f16700Schasinglulu 
826*91f16700Schasinglulu 	if (resp_len > 0) {
827*91f16700Schasinglulu 		inv_dcache_range(dst_addr, (resp_len * MBOX_WORD_BYTE)); /* flush cache before mmio read to avoid reading old values */
828*91f16700Schasinglulu 		op_status = mmio_read_32(dst_addr) &
829*91f16700Schasinglulu 			FCS_CS_KEY_RESP_STATUS_MASK;
830*91f16700Schasinglulu 	}
831*91f16700Schasinglulu 
832*91f16700Schasinglulu 	if (status < 0) {
833*91f16700Schasinglulu 		*mbox_error = (-status) | (op_status << FCS_CS_KEY_RESP_STATUS_OFFSET);
834*91f16700Schasinglulu 		return INTEL_SIP_SMC_STATUS_ERROR;
835*91f16700Schasinglulu 	}
836*91f16700Schasinglulu 
837*91f16700Schasinglulu 	*dst_size = resp_len * MBOX_WORD_BYTE;
838*91f16700Schasinglulu 	flush_dcache_range(dst_addr, *dst_size);
839*91f16700Schasinglulu 
840*91f16700Schasinglulu 	return INTEL_SIP_SMC_STATUS_OK;
841*91f16700Schasinglulu }
842*91f16700Schasinglulu 
843*91f16700Schasinglulu int intel_fcs_get_digest_init(uint32_t session_id, uint32_t context_id,
844*91f16700Schasinglulu 				uint32_t key_id, uint32_t param_size,
845*91f16700Schasinglulu 				uint64_t param_data, uint32_t *mbox_error)
846*91f16700Schasinglulu {
847*91f16700Schasinglulu 	return intel_fcs_crypto_service_init(session_id, context_id,
848*91f16700Schasinglulu 				key_id, param_size, param_data,
849*91f16700Schasinglulu 				(void *) &fcs_sha_get_digest_param,
850*91f16700Schasinglulu 				mbox_error);
851*91f16700Schasinglulu }
852*91f16700Schasinglulu 
853*91f16700Schasinglulu int intel_fcs_get_digest_update_finalize(uint32_t session_id,
854*91f16700Schasinglulu 				uint32_t context_id, uint32_t src_addr,
855*91f16700Schasinglulu 				uint32_t src_size, uint64_t dst_addr,
856*91f16700Schasinglulu 				uint32_t *dst_size, uint8_t is_finalised,
857*91f16700Schasinglulu 				uint32_t *mbox_error)
858*91f16700Schasinglulu {
859*91f16700Schasinglulu 	int status;
860*91f16700Schasinglulu 	uint32_t i;
861*91f16700Schasinglulu 	uint32_t flag;
862*91f16700Schasinglulu 	uint32_t crypto_header;
863*91f16700Schasinglulu 	uint32_t resp_len;
864*91f16700Schasinglulu 	uint32_t payload[FCS_GET_DIGEST_CMD_MAX_WORD_SIZE] = {0U};
865*91f16700Schasinglulu 
866*91f16700Schasinglulu 	if (dst_size == NULL || mbox_error == NULL) {
867*91f16700Schasinglulu 		return INTEL_SIP_SMC_STATUS_REJECTED;
868*91f16700Schasinglulu 	}
869*91f16700Schasinglulu 
870*91f16700Schasinglulu 	if (fcs_sha_get_digest_param.session_id != session_id ||
871*91f16700Schasinglulu 	    fcs_sha_get_digest_param.context_id != context_id) {
872*91f16700Schasinglulu 		return INTEL_SIP_SMC_STATUS_REJECTED;
873*91f16700Schasinglulu 	}
874*91f16700Schasinglulu 
875*91f16700Schasinglulu 	/* Source data must be 8 bytes aligned */
876*91f16700Schasinglulu 	if (!is_8_bytes_aligned(src_size)) {
877*91f16700Schasinglulu 		return INTEL_SIP_SMC_STATUS_REJECTED;
878*91f16700Schasinglulu 	}
879*91f16700Schasinglulu 
880*91f16700Schasinglulu 	if (!is_address_in_ddr_range(src_addr, src_size) ||
881*91f16700Schasinglulu 		 !is_address_in_ddr_range(dst_addr, *dst_size)) {
882*91f16700Schasinglulu 		return INTEL_SIP_SMC_STATUS_REJECTED;
883*91f16700Schasinglulu 	}
884*91f16700Schasinglulu 
885*91f16700Schasinglulu 	resp_len = *dst_size / MBOX_WORD_BYTE;
886*91f16700Schasinglulu 
887*91f16700Schasinglulu 	/* Prepare crypto header */
888*91f16700Schasinglulu 	flag = 0;
889*91f16700Schasinglulu 
890*91f16700Schasinglulu 	if (fcs_sha_get_digest_param.is_updated) {
891*91f16700Schasinglulu 		fcs_sha_get_digest_param.crypto_param_size = 0;
892*91f16700Schasinglulu 	} else {
893*91f16700Schasinglulu 		flag |=  FCS_CS_FIELD_FLAG_INIT;
894*91f16700Schasinglulu 	}
895*91f16700Schasinglulu 
896*91f16700Schasinglulu 	if (is_finalised != 0U) {
897*91f16700Schasinglulu 		flag |=  FCS_CS_FIELD_FLAG_FINALIZE;
898*91f16700Schasinglulu 	} else {
899*91f16700Schasinglulu 		flag |=  FCS_CS_FIELD_FLAG_UPDATE;
900*91f16700Schasinglulu 		fcs_sha_get_digest_param.is_updated = 1;
901*91f16700Schasinglulu 	}
902*91f16700Schasinglulu 
903*91f16700Schasinglulu 	crypto_header = ((flag << FCS_CS_FIELD_FLAG_OFFSET) |
904*91f16700Schasinglulu 			(fcs_sha_get_digest_param.crypto_param_size &
905*91f16700Schasinglulu 			FCS_CS_FIELD_SIZE_MASK));
906*91f16700Schasinglulu 
907*91f16700Schasinglulu 	/* Prepare command payload */
908*91f16700Schasinglulu 	i = 0;
909*91f16700Schasinglulu 	payload[i] = fcs_sha_get_digest_param.session_id;
910*91f16700Schasinglulu 	i++;
911*91f16700Schasinglulu 	payload[i] = fcs_sha_get_digest_param.context_id;
912*91f16700Schasinglulu 	i++;
913*91f16700Schasinglulu 	payload[i] = crypto_header;
914*91f16700Schasinglulu 	i++;
915*91f16700Schasinglulu 
916*91f16700Schasinglulu 	if ((crypto_header >> FCS_CS_FIELD_FLAG_OFFSET) &
917*91f16700Schasinglulu 		FCS_CS_FIELD_FLAG_INIT) {
918*91f16700Schasinglulu 		payload[i] = fcs_sha_get_digest_param.key_id;
919*91f16700Schasinglulu 		i++;
920*91f16700Schasinglulu 		/* Crypto parameters */
921*91f16700Schasinglulu 		payload[i] = fcs_sha_get_digest_param.crypto_param
922*91f16700Schasinglulu 				& INTEL_SIP_SMC_FCS_SHA_MODE_MASK;
923*91f16700Schasinglulu 		payload[i] |= ((fcs_sha_get_digest_param.crypto_param
924*91f16700Schasinglulu 				>> INTEL_SIP_SMC_FCS_DIGEST_SIZE_OFFSET)
925*91f16700Schasinglulu 				& INTEL_SIP_SMC_FCS_DIGEST_SIZE_MASK)
926*91f16700Schasinglulu 				<< FCS_SHA_HMAC_CRYPTO_PARAM_SIZE_OFFSET;
927*91f16700Schasinglulu 		i++;
928*91f16700Schasinglulu 	}
929*91f16700Schasinglulu 	/* Data source address and size */
930*91f16700Schasinglulu 	payload[i] = src_addr;
931*91f16700Schasinglulu 	i++;
932*91f16700Schasinglulu 	payload[i] = src_size;
933*91f16700Schasinglulu 	i++;
934*91f16700Schasinglulu 
935*91f16700Schasinglulu 	status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_GET_DIGEST_REQ,
936*91f16700Schasinglulu 				payload, i, CMD_CASUAL,
937*91f16700Schasinglulu 				(uint32_t *) dst_addr, &resp_len);
938*91f16700Schasinglulu 
939*91f16700Schasinglulu 	if (is_finalised != 0U) {
940*91f16700Schasinglulu 		memset((void *)&fcs_sha_get_digest_param, 0,
941*91f16700Schasinglulu 		sizeof(fcs_crypto_service_data));
942*91f16700Schasinglulu 	}
943*91f16700Schasinglulu 
944*91f16700Schasinglulu 	if (status < 0) {
945*91f16700Schasinglulu 		*mbox_error = -status;
946*91f16700Schasinglulu 		return INTEL_SIP_SMC_STATUS_ERROR;
947*91f16700Schasinglulu 	}
948*91f16700Schasinglulu 
949*91f16700Schasinglulu 	*dst_size = resp_len * MBOX_WORD_BYTE;
950*91f16700Schasinglulu 	flush_dcache_range(dst_addr, *dst_size);
951*91f16700Schasinglulu 
952*91f16700Schasinglulu 	return INTEL_SIP_SMC_STATUS_OK;
953*91f16700Schasinglulu }
954*91f16700Schasinglulu 
955*91f16700Schasinglulu int intel_fcs_get_digest_smmu_update_finalize(uint32_t session_id,
956*91f16700Schasinglulu 				uint32_t context_id, uint32_t src_addr,
957*91f16700Schasinglulu 				uint32_t src_size, uint64_t dst_addr,
958*91f16700Schasinglulu 				uint32_t *dst_size, uint8_t is_finalised,
959*91f16700Schasinglulu 				uint32_t *mbox_error, uint32_t *send_id)
960*91f16700Schasinglulu {
961*91f16700Schasinglulu 	int status;
962*91f16700Schasinglulu 	uint32_t i;
963*91f16700Schasinglulu 	uint32_t flag;
964*91f16700Schasinglulu 	uint32_t crypto_header;
965*91f16700Schasinglulu 	uint32_t resp_len;
966*91f16700Schasinglulu 	uint32_t payload[FCS_GET_DIGEST_CMD_MAX_WORD_SIZE] = {0U};
967*91f16700Schasinglulu 
968*91f16700Schasinglulu 	/* Source data must be 8 bytes aligned */
969*91f16700Schasinglulu 	if (dst_size == NULL || mbox_error == NULL ||
970*91f16700Schasinglulu 		!is_8_bytes_aligned(src_size)) {
971*91f16700Schasinglulu 		return INTEL_SIP_SMC_STATUS_REJECTED;
972*91f16700Schasinglulu 	}
973*91f16700Schasinglulu 
974*91f16700Schasinglulu 	if (fcs_sha_get_digest_param.session_id != session_id ||
975*91f16700Schasinglulu 	    fcs_sha_get_digest_param.context_id != context_id) {
976*91f16700Schasinglulu 		return INTEL_SIP_SMC_STATUS_REJECTED;
977*91f16700Schasinglulu 	}
978*91f16700Schasinglulu 
979*91f16700Schasinglulu 	if (!is_address_in_ddr_range(src_addr, src_size) ||
980*91f16700Schasinglulu 		 !is_address_in_ddr_range(dst_addr, *dst_size)) {
981*91f16700Schasinglulu 		return INTEL_SIP_SMC_STATUS_REJECTED;
982*91f16700Schasinglulu 	}
983*91f16700Schasinglulu 
984*91f16700Schasinglulu 	resp_len = *dst_size / MBOX_WORD_BYTE;
985*91f16700Schasinglulu 
986*91f16700Schasinglulu 	/* Prepare crypto header */
987*91f16700Schasinglulu 	flag = 0;
988*91f16700Schasinglulu 
989*91f16700Schasinglulu 	if (fcs_sha_get_digest_param.is_updated) {
990*91f16700Schasinglulu 		fcs_sha_get_digest_param.crypto_param_size = 0;
991*91f16700Schasinglulu 	} else {
992*91f16700Schasinglulu 		flag |=  FCS_CS_FIELD_FLAG_INIT;
993*91f16700Schasinglulu 	}
994*91f16700Schasinglulu 
995*91f16700Schasinglulu 	if (is_finalised != 0U) {
996*91f16700Schasinglulu 		flag |=  FCS_CS_FIELD_FLAG_FINALIZE;
997*91f16700Schasinglulu 	} else {
998*91f16700Schasinglulu 		flag |=  FCS_CS_FIELD_FLAG_UPDATE;
999*91f16700Schasinglulu 		fcs_sha_get_digest_param.is_updated = 1;
1000*91f16700Schasinglulu 	}
1001*91f16700Schasinglulu 
1002*91f16700Schasinglulu 	crypto_header = ((flag << FCS_CS_FIELD_FLAG_OFFSET) |
1003*91f16700Schasinglulu 			(fcs_sha_get_digest_param.crypto_param_size &
1004*91f16700Schasinglulu 			FCS_CS_FIELD_SIZE_MASK));
1005*91f16700Schasinglulu 
1006*91f16700Schasinglulu 	/* Prepare command payload */
1007*91f16700Schasinglulu 	i = 0;
1008*91f16700Schasinglulu 	payload[i] = fcs_sha_get_digest_param.session_id;
1009*91f16700Schasinglulu 	i++;
1010*91f16700Schasinglulu 	payload[i] = fcs_sha_get_digest_param.context_id;
1011*91f16700Schasinglulu 	i++;
1012*91f16700Schasinglulu 	payload[i] = crypto_header;
1013*91f16700Schasinglulu 	i++;
1014*91f16700Schasinglulu 
1015*91f16700Schasinglulu 	if ((crypto_header >> FCS_CS_FIELD_FLAG_OFFSET) &
1016*91f16700Schasinglulu 		FCS_CS_FIELD_FLAG_INIT) {
1017*91f16700Schasinglulu 		payload[i] = fcs_sha_get_digest_param.key_id;
1018*91f16700Schasinglulu 		i++;
1019*91f16700Schasinglulu 		/* Crypto parameters */
1020*91f16700Schasinglulu 		payload[i] = fcs_sha_get_digest_param.crypto_param
1021*91f16700Schasinglulu 				& INTEL_SIP_SMC_FCS_SHA_MODE_MASK;
1022*91f16700Schasinglulu 		payload[i] |= ((fcs_sha_get_digest_param.crypto_param
1023*91f16700Schasinglulu 				>> INTEL_SIP_SMC_FCS_DIGEST_SIZE_OFFSET)
1024*91f16700Schasinglulu 				& INTEL_SIP_SMC_FCS_DIGEST_SIZE_MASK)
1025*91f16700Schasinglulu 				<< FCS_SHA_HMAC_CRYPTO_PARAM_SIZE_OFFSET;
1026*91f16700Schasinglulu 		i++;
1027*91f16700Schasinglulu 	}
1028*91f16700Schasinglulu 	/* Data source address and size */
1029*91f16700Schasinglulu 	payload[i] = src_addr;
1030*91f16700Schasinglulu 	i++;
1031*91f16700Schasinglulu 	payload[i] = src_size;
1032*91f16700Schasinglulu 	i++;
1033*91f16700Schasinglulu 
1034*91f16700Schasinglulu 	status = mailbox_send_cmd_async(send_id, MBOX_FCS_GET_DIGEST_REQ,
1035*91f16700Schasinglulu 					payload, i, CMD_INDIRECT);
1036*91f16700Schasinglulu 
1037*91f16700Schasinglulu 	if (is_finalised != 0U) {
1038*91f16700Schasinglulu 		memset((void *)&fcs_sha_get_digest_param, 0,
1039*91f16700Schasinglulu 		sizeof(fcs_crypto_service_data));
1040*91f16700Schasinglulu 	}
1041*91f16700Schasinglulu 
1042*91f16700Schasinglulu 	if (status < 0) {
1043*91f16700Schasinglulu 		*mbox_error = -status;
1044*91f16700Schasinglulu 		return INTEL_SIP_SMC_STATUS_ERROR;
1045*91f16700Schasinglulu 	}
1046*91f16700Schasinglulu 
1047*91f16700Schasinglulu 	*dst_size = resp_len * MBOX_WORD_BYTE;
1048*91f16700Schasinglulu 	flush_dcache_range(dst_addr, *dst_size);
1049*91f16700Schasinglulu 
1050*91f16700Schasinglulu 	return INTEL_SIP_SMC_STATUS_OK;
1051*91f16700Schasinglulu }
1052*91f16700Schasinglulu 
1053*91f16700Schasinglulu int intel_fcs_mac_verify_init(uint32_t session_id, uint32_t context_id,
1054*91f16700Schasinglulu 				uint32_t key_id, uint32_t param_size,
1055*91f16700Schasinglulu 				uint64_t param_data, uint32_t *mbox_error)
1056*91f16700Schasinglulu {
1057*91f16700Schasinglulu 	return intel_fcs_crypto_service_init(session_id, context_id,
1058*91f16700Schasinglulu 				key_id, param_size, param_data,
1059*91f16700Schasinglulu 				(void *) &fcs_sha_mac_verify_param,
1060*91f16700Schasinglulu 				mbox_error);
1061*91f16700Schasinglulu }
1062*91f16700Schasinglulu 
1063*91f16700Schasinglulu int intel_fcs_mac_verify_update_finalize(uint32_t session_id,
1064*91f16700Schasinglulu 				uint32_t context_id, uint32_t src_addr,
1065*91f16700Schasinglulu 				uint32_t src_size, uint64_t dst_addr,
1066*91f16700Schasinglulu 				uint32_t *dst_size, uint32_t data_size,
1067*91f16700Schasinglulu 				uint8_t is_finalised, uint32_t *mbox_error)
1068*91f16700Schasinglulu {
1069*91f16700Schasinglulu 	int status;
1070*91f16700Schasinglulu 	uint32_t i;
1071*91f16700Schasinglulu 	uint32_t flag;
1072*91f16700Schasinglulu 	uint32_t crypto_header;
1073*91f16700Schasinglulu 	uint32_t resp_len;
1074*91f16700Schasinglulu 	uint32_t payload[FCS_MAC_VERIFY_CMD_MAX_WORD_SIZE] = {0U};
1075*91f16700Schasinglulu 	uintptr_t mac_offset;
1076*91f16700Schasinglulu 	uint32_t dst_size_check = 0;
1077*91f16700Schasinglulu 
1078*91f16700Schasinglulu 	if (dst_size == NULL || mbox_error == NULL) {
1079*91f16700Schasinglulu 		return INTEL_SIP_SMC_STATUS_REJECTED;
1080*91f16700Schasinglulu 	}
1081*91f16700Schasinglulu 
1082*91f16700Schasinglulu 	if (fcs_sha_mac_verify_param.session_id != session_id ||
1083*91f16700Schasinglulu 		fcs_sha_mac_verify_param.context_id != context_id) {
1084*91f16700Schasinglulu 		return INTEL_SIP_SMC_STATUS_REJECTED;
1085*91f16700Schasinglulu 	}
1086*91f16700Schasinglulu 
1087*91f16700Schasinglulu 	if (data_size > src_size) {
1088*91f16700Schasinglulu 		return INTEL_SIP_SMC_STATUS_REJECTED;
1089*91f16700Schasinglulu 	}
1090*91f16700Schasinglulu 
1091*91f16700Schasinglulu 	if (!is_size_4_bytes_aligned(src_size) ||
1092*91f16700Schasinglulu 		!is_8_bytes_aligned(data_size)) {
1093*91f16700Schasinglulu 		return INTEL_SIP_SMC_STATUS_REJECTED;
1094*91f16700Schasinglulu 	}
1095*91f16700Schasinglulu 
1096*91f16700Schasinglulu 	if (!is_address_in_ddr_range(src_addr, src_size) ||
1097*91f16700Schasinglulu 		!is_address_in_ddr_range(dst_addr, *dst_size)) {
1098*91f16700Schasinglulu 		return INTEL_SIP_SMC_STATUS_REJECTED;
1099*91f16700Schasinglulu 	}
1100*91f16700Schasinglulu 
1101*91f16700Schasinglulu 	dst_size_check = *dst_size;
1102*91f16700Schasinglulu 	if ((dst_size_check > FCS_MAX_DATA_SIZE ||
1103*91f16700Schasinglulu 		dst_size_check < FCS_MIN_DATA_SIZE) ||
1104*91f16700Schasinglulu 		(src_size > FCS_MAX_DATA_SIZE ||
1105*91f16700Schasinglulu 		src_size < FCS_MIN_DATA_SIZE)) {
1106*91f16700Schasinglulu 		return INTEL_SIP_SMC_STATUS_REJECTED;
1107*91f16700Schasinglulu 	}
1108*91f16700Schasinglulu 
1109*91f16700Schasinglulu 	resp_len = *dst_size / MBOX_WORD_BYTE;
1110*91f16700Schasinglulu 
1111*91f16700Schasinglulu 	/* Prepare crypto header */
1112*91f16700Schasinglulu 	flag = 0;
1113*91f16700Schasinglulu 
1114*91f16700Schasinglulu 	if (fcs_sha_mac_verify_param.is_updated) {
1115*91f16700Schasinglulu 		fcs_sha_mac_verify_param.crypto_param_size = 0;
1116*91f16700Schasinglulu 	} else {
1117*91f16700Schasinglulu 		flag |=  FCS_CS_FIELD_FLAG_INIT;
1118*91f16700Schasinglulu 	}
1119*91f16700Schasinglulu 
1120*91f16700Schasinglulu 	if (is_finalised) {
1121*91f16700Schasinglulu 		flag |=  FCS_CS_FIELD_FLAG_FINALIZE;
1122*91f16700Schasinglulu 	} else {
1123*91f16700Schasinglulu 		flag |=  FCS_CS_FIELD_FLAG_UPDATE;
1124*91f16700Schasinglulu 		fcs_sha_mac_verify_param.is_updated = 1;
1125*91f16700Schasinglulu 	}
1126*91f16700Schasinglulu 
1127*91f16700Schasinglulu 	crypto_header = ((flag << FCS_CS_FIELD_FLAG_OFFSET) |
1128*91f16700Schasinglulu 			(fcs_sha_mac_verify_param.crypto_param_size &
1129*91f16700Schasinglulu 			FCS_CS_FIELD_SIZE_MASK));
1130*91f16700Schasinglulu 
1131*91f16700Schasinglulu 	/* Prepare command payload */
1132*91f16700Schasinglulu 	i = 0;
1133*91f16700Schasinglulu 	payload[i] = fcs_sha_mac_verify_param.session_id;
1134*91f16700Schasinglulu 	i++;
1135*91f16700Schasinglulu 	payload[i] = fcs_sha_mac_verify_param.context_id;
1136*91f16700Schasinglulu 	i++;
1137*91f16700Schasinglulu 	payload[i] = crypto_header;
1138*91f16700Schasinglulu 	i++;
1139*91f16700Schasinglulu 
1140*91f16700Schasinglulu 	if ((crypto_header >> FCS_CS_FIELD_FLAG_OFFSET) &
1141*91f16700Schasinglulu 		FCS_CS_FIELD_FLAG_INIT) {
1142*91f16700Schasinglulu 		payload[i] = fcs_sha_mac_verify_param.key_id;
1143*91f16700Schasinglulu 		i++;
1144*91f16700Schasinglulu 		/* Crypto parameters */
1145*91f16700Schasinglulu 		payload[i] = ((fcs_sha_mac_verify_param.crypto_param
1146*91f16700Schasinglulu 				>> INTEL_SIP_SMC_FCS_DIGEST_SIZE_OFFSET)
1147*91f16700Schasinglulu 				& INTEL_SIP_SMC_FCS_DIGEST_SIZE_MASK)
1148*91f16700Schasinglulu 				<< FCS_SHA_HMAC_CRYPTO_PARAM_SIZE_OFFSET;
1149*91f16700Schasinglulu 		i++;
1150*91f16700Schasinglulu 	}
1151*91f16700Schasinglulu 	/* Data source address and size */
1152*91f16700Schasinglulu 	payload[i] = src_addr;
1153*91f16700Schasinglulu 	i++;
1154*91f16700Schasinglulu 	payload[i] = data_size;
1155*91f16700Schasinglulu 	i++;
1156*91f16700Schasinglulu 
1157*91f16700Schasinglulu 	if ((crypto_header >> FCS_CS_FIELD_FLAG_OFFSET) &
1158*91f16700Schasinglulu 		FCS_CS_FIELD_FLAG_FINALIZE) {
1159*91f16700Schasinglulu 		/* Copy mac data to command */
1160*91f16700Schasinglulu 		mac_offset = src_addr + data_size;
1161*91f16700Schasinglulu 
1162*91f16700Schasinglulu 		if ((i + ((src_size - data_size) / MBOX_WORD_BYTE)) >
1163*91f16700Schasinglulu 			FCS_MAC_VERIFY_CMD_MAX_WORD_SIZE) {
1164*91f16700Schasinglulu 			return INTEL_SIP_SMC_STATUS_REJECTED;
1165*91f16700Schasinglulu 		}
1166*91f16700Schasinglulu 
1167*91f16700Schasinglulu 		memcpy((uint8_t *) &payload[i], (uint8_t *) mac_offset,
1168*91f16700Schasinglulu 		src_size - data_size);
1169*91f16700Schasinglulu 
1170*91f16700Schasinglulu 		i += (src_size - data_size) / MBOX_WORD_BYTE;
1171*91f16700Schasinglulu 	}
1172*91f16700Schasinglulu 
1173*91f16700Schasinglulu 	status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_MAC_VERIFY_REQ,
1174*91f16700Schasinglulu 				payload, i, CMD_CASUAL,
1175*91f16700Schasinglulu 				(uint32_t *) dst_addr, &resp_len);
1176*91f16700Schasinglulu 
1177*91f16700Schasinglulu 	if (is_finalised) {
1178*91f16700Schasinglulu 		memset((void *)&fcs_sha_mac_verify_param, 0,
1179*91f16700Schasinglulu 		sizeof(fcs_crypto_service_data));
1180*91f16700Schasinglulu 	}
1181*91f16700Schasinglulu 
1182*91f16700Schasinglulu 	if (status < 0) {
1183*91f16700Schasinglulu 		*mbox_error = -status;
1184*91f16700Schasinglulu 		return INTEL_SIP_SMC_STATUS_ERROR;
1185*91f16700Schasinglulu 	}
1186*91f16700Schasinglulu 
1187*91f16700Schasinglulu 	*dst_size = resp_len * MBOX_WORD_BYTE;
1188*91f16700Schasinglulu 	flush_dcache_range(dst_addr, *dst_size);
1189*91f16700Schasinglulu 
1190*91f16700Schasinglulu 	return INTEL_SIP_SMC_STATUS_OK;
1191*91f16700Schasinglulu }
1192*91f16700Schasinglulu 
1193*91f16700Schasinglulu int intel_fcs_mac_verify_smmu_update_finalize(uint32_t session_id,
1194*91f16700Schasinglulu 				uint32_t context_id, uint32_t src_addr,
1195*91f16700Schasinglulu 				uint32_t src_size, uint64_t dst_addr,
1196*91f16700Schasinglulu 				uint32_t *dst_size, uint32_t data_size,
1197*91f16700Schasinglulu 				uint8_t is_finalised, uint32_t *mbox_error,
1198*91f16700Schasinglulu 				uint32_t *send_id)
1199*91f16700Schasinglulu {
1200*91f16700Schasinglulu 	int status;
1201*91f16700Schasinglulu 	uint32_t i;
1202*91f16700Schasinglulu 	uint32_t flag;
1203*91f16700Schasinglulu 	uint32_t crypto_header;
1204*91f16700Schasinglulu 	uint32_t resp_len;
1205*91f16700Schasinglulu 	uint32_t payload[FCS_MAC_VERIFY_CMD_MAX_WORD_SIZE] = {0U};
1206*91f16700Schasinglulu 	uintptr_t mac_offset;
1207*91f16700Schasinglulu 	uint32_t dst_size_check = 0;
1208*91f16700Schasinglulu 	/*
1209*91f16700Schasinglulu 	 * Source data must be 4 bytes aligned
1210*91f16700Schasinglulu 	 * User data must be 8 bytes aligned
1211*91f16700Schasinglulu 	 */
1212*91f16700Schasinglulu 	if (dst_size == NULL || mbox_error == NULL ||
1213*91f16700Schasinglulu 		!is_size_4_bytes_aligned(src_size) ||
1214*91f16700Schasinglulu 		!is_8_bytes_aligned(data_size)) {
1215*91f16700Schasinglulu 		return INTEL_SIP_SMC_STATUS_REJECTED;
1216*91f16700Schasinglulu 	}
1217*91f16700Schasinglulu 
1218*91f16700Schasinglulu 	if (data_size > src_size) {
1219*91f16700Schasinglulu 		return INTEL_SIP_SMC_STATUS_REJECTED;
1220*91f16700Schasinglulu 	}
1221*91f16700Schasinglulu 
1222*91f16700Schasinglulu 	if (fcs_sha_mac_verify_param.session_id != session_id ||
1223*91f16700Schasinglulu 		fcs_sha_mac_verify_param.context_id != context_id) {
1224*91f16700Schasinglulu 		return INTEL_SIP_SMC_STATUS_REJECTED;
1225*91f16700Schasinglulu 	}
1226*91f16700Schasinglulu 
1227*91f16700Schasinglulu 	if (!is_address_in_ddr_range(src_addr, src_size) ||
1228*91f16700Schasinglulu 		!is_address_in_ddr_range(dst_addr, *dst_size)) {
1229*91f16700Schasinglulu 		return INTEL_SIP_SMC_STATUS_REJECTED;
1230*91f16700Schasinglulu 	}
1231*91f16700Schasinglulu 
1232*91f16700Schasinglulu 	dst_size_check = *dst_size;
1233*91f16700Schasinglulu 	if ((dst_size_check > FCS_MAX_DATA_SIZE ||
1234*91f16700Schasinglulu 		dst_size_check < FCS_MIN_DATA_SIZE) ||
1235*91f16700Schasinglulu 		(src_size > FCS_MAX_DATA_SIZE ||
1236*91f16700Schasinglulu 		src_size < FCS_MIN_DATA_SIZE)) {
1237*91f16700Schasinglulu 		return INTEL_SIP_SMC_STATUS_REJECTED;
1238*91f16700Schasinglulu 	}
1239*91f16700Schasinglulu 
1240*91f16700Schasinglulu 	resp_len = *dst_size / MBOX_WORD_BYTE;
1241*91f16700Schasinglulu 
1242*91f16700Schasinglulu 	/* Prepare crypto header */
1243*91f16700Schasinglulu 	flag = 0;
1244*91f16700Schasinglulu 
1245*91f16700Schasinglulu 	if (fcs_sha_mac_verify_param.is_updated) {
1246*91f16700Schasinglulu 		fcs_sha_mac_verify_param.crypto_param_size = 0;
1247*91f16700Schasinglulu 	} else {
1248*91f16700Schasinglulu 		flag |=  FCS_CS_FIELD_FLAG_INIT;
1249*91f16700Schasinglulu 	}
1250*91f16700Schasinglulu 
1251*91f16700Schasinglulu 	if (is_finalised) {
1252*91f16700Schasinglulu 		flag |=  FCS_CS_FIELD_FLAG_FINALIZE;
1253*91f16700Schasinglulu 	} else {
1254*91f16700Schasinglulu 		flag |=  FCS_CS_FIELD_FLAG_UPDATE;
1255*91f16700Schasinglulu 		fcs_sha_mac_verify_param.is_updated = 1;
1256*91f16700Schasinglulu 	}
1257*91f16700Schasinglulu 
1258*91f16700Schasinglulu 	crypto_header = ((flag << FCS_CS_FIELD_FLAG_OFFSET) |
1259*91f16700Schasinglulu 			(fcs_sha_mac_verify_param.crypto_param_size &
1260*91f16700Schasinglulu 			FCS_CS_FIELD_SIZE_MASK));
1261*91f16700Schasinglulu 
1262*91f16700Schasinglulu 	/* Prepare command payload */
1263*91f16700Schasinglulu 	i = 0;
1264*91f16700Schasinglulu 	payload[i] = fcs_sha_mac_verify_param.session_id;
1265*91f16700Schasinglulu 	i++;
1266*91f16700Schasinglulu 	payload[i] = fcs_sha_mac_verify_param.context_id;
1267*91f16700Schasinglulu 	i++;
1268*91f16700Schasinglulu 	payload[i] = crypto_header;
1269*91f16700Schasinglulu 	i++;
1270*91f16700Schasinglulu 
1271*91f16700Schasinglulu 	if ((crypto_header >> FCS_CS_FIELD_FLAG_OFFSET) &
1272*91f16700Schasinglulu 		FCS_CS_FIELD_FLAG_INIT) {
1273*91f16700Schasinglulu 		payload[i] = fcs_sha_mac_verify_param.key_id;
1274*91f16700Schasinglulu 		i++;
1275*91f16700Schasinglulu 		/* Crypto parameters */
1276*91f16700Schasinglulu 		payload[i] = ((fcs_sha_mac_verify_param.crypto_param
1277*91f16700Schasinglulu 				>> INTEL_SIP_SMC_FCS_DIGEST_SIZE_OFFSET)
1278*91f16700Schasinglulu 				& INTEL_SIP_SMC_FCS_DIGEST_SIZE_MASK)
1279*91f16700Schasinglulu 				<< FCS_SHA_HMAC_CRYPTO_PARAM_SIZE_OFFSET;
1280*91f16700Schasinglulu 		i++;
1281*91f16700Schasinglulu 	}
1282*91f16700Schasinglulu 	/* Data source address and size */
1283*91f16700Schasinglulu 	payload[i] = src_addr;
1284*91f16700Schasinglulu 	i++;
1285*91f16700Schasinglulu 	payload[i] = data_size;
1286*91f16700Schasinglulu 	i++;
1287*91f16700Schasinglulu 
1288*91f16700Schasinglulu 	if ((crypto_header >> FCS_CS_FIELD_FLAG_OFFSET) &
1289*91f16700Schasinglulu 		FCS_CS_FIELD_FLAG_FINALIZE) {
1290*91f16700Schasinglulu 		/* Copy mac data to command
1291*91f16700Schasinglulu 		 * Using dst_addr (physical address) to store mac_offset
1292*91f16700Schasinglulu 		 * mac_offset = MAC data
1293*91f16700Schasinglulu 		 */
1294*91f16700Schasinglulu 		mac_offset = dst_addr;
1295*91f16700Schasinglulu 
1296*91f16700Schasinglulu 		if ((i + ((src_size - data_size) / MBOX_WORD_BYTE)) >
1297*91f16700Schasinglulu 			FCS_MAC_VERIFY_CMD_MAX_WORD_SIZE) {
1298*91f16700Schasinglulu 			return INTEL_SIP_SMC_STATUS_REJECTED;
1299*91f16700Schasinglulu 		}
1300*91f16700Schasinglulu 
1301*91f16700Schasinglulu 		memcpy((uint8_t *) &payload[i], (uint8_t *) mac_offset,
1302*91f16700Schasinglulu 		src_size - data_size);
1303*91f16700Schasinglulu 
1304*91f16700Schasinglulu 		memset((void *) dst_addr, 0, *dst_size);
1305*91f16700Schasinglulu 
1306*91f16700Schasinglulu 		i += (src_size - data_size) / MBOX_WORD_BYTE;
1307*91f16700Schasinglulu 	}
1308*91f16700Schasinglulu 
1309*91f16700Schasinglulu 	status = mailbox_send_cmd_async(send_id, MBOX_FCS_MAC_VERIFY_REQ,
1310*91f16700Schasinglulu 					payload, i, CMD_INDIRECT);
1311*91f16700Schasinglulu 
1312*91f16700Schasinglulu 	if (is_finalised) {
1313*91f16700Schasinglulu 		memset((void *)&fcs_sha_mac_verify_param, 0,
1314*91f16700Schasinglulu 		sizeof(fcs_crypto_service_data));
1315*91f16700Schasinglulu 	}
1316*91f16700Schasinglulu 
1317*91f16700Schasinglulu 	if (status < 0) {
1318*91f16700Schasinglulu 		*mbox_error = -status;
1319*91f16700Schasinglulu 		return INTEL_SIP_SMC_STATUS_ERROR;
1320*91f16700Schasinglulu 	}
1321*91f16700Schasinglulu 
1322*91f16700Schasinglulu 	*dst_size = resp_len * MBOX_WORD_BYTE;
1323*91f16700Schasinglulu 	flush_dcache_range(dst_addr, *dst_size);
1324*91f16700Schasinglulu 
1325*91f16700Schasinglulu 	return INTEL_SIP_SMC_STATUS_OK;
1326*91f16700Schasinglulu }
1327*91f16700Schasinglulu 
1328*91f16700Schasinglulu int intel_fcs_ecdsa_hash_sign_init(uint32_t session_id, uint32_t context_id,
1329*91f16700Schasinglulu 				uint32_t key_id, uint32_t param_size,
1330*91f16700Schasinglulu 				uint64_t param_data, uint32_t *mbox_error)
1331*91f16700Schasinglulu {
1332*91f16700Schasinglulu 	return intel_fcs_crypto_service_init(session_id, context_id,
1333*91f16700Schasinglulu 				key_id, param_size, param_data,
1334*91f16700Schasinglulu 				(void *) &fcs_ecdsa_hash_sign_param,
1335*91f16700Schasinglulu 				mbox_error);
1336*91f16700Schasinglulu }
1337*91f16700Schasinglulu 
1338*91f16700Schasinglulu int intel_fcs_ecdsa_hash_sign_finalize(uint32_t session_id, uint32_t context_id,
1339*91f16700Schasinglulu 				uint32_t src_addr, uint32_t src_size,
1340*91f16700Schasinglulu 				uint64_t dst_addr, uint32_t *dst_size,
1341*91f16700Schasinglulu 				uint32_t *mbox_error)
1342*91f16700Schasinglulu {
1343*91f16700Schasinglulu 	int status;
1344*91f16700Schasinglulu 	uint32_t i;
1345*91f16700Schasinglulu 	uint32_t payload[FCS_ECDSA_HASH_SIGN_CMD_MAX_WORD_SIZE] = {0U};
1346*91f16700Schasinglulu 	uint32_t resp_len;
1347*91f16700Schasinglulu 	uintptr_t hash_data_addr;
1348*91f16700Schasinglulu 	uint32_t dst_size_check = 0;
1349*91f16700Schasinglulu 
1350*91f16700Schasinglulu 	if ((dst_size == NULL) || (mbox_error == NULL)) {
1351*91f16700Schasinglulu 		return INTEL_SIP_SMC_STATUS_REJECTED;
1352*91f16700Schasinglulu 	}
1353*91f16700Schasinglulu 
1354*91f16700Schasinglulu 	if (fcs_ecdsa_hash_sign_param.session_id != session_id ||
1355*91f16700Schasinglulu 		fcs_ecdsa_hash_sign_param.context_id != context_id) {
1356*91f16700Schasinglulu 		return INTEL_SIP_SMC_STATUS_REJECTED;
1357*91f16700Schasinglulu 	}
1358*91f16700Schasinglulu 
1359*91f16700Schasinglulu 	if (!is_address_in_ddr_range(src_addr, src_size) ||
1360*91f16700Schasinglulu 		!is_address_in_ddr_range(dst_addr, *dst_size)) {
1361*91f16700Schasinglulu 		return INTEL_SIP_SMC_STATUS_REJECTED;
1362*91f16700Schasinglulu 	}
1363*91f16700Schasinglulu 
1364*91f16700Schasinglulu 	dst_size_check = *dst_size;
1365*91f16700Schasinglulu 	if ((dst_size_check > FCS_MAX_DATA_SIZE ||
1366*91f16700Schasinglulu 		dst_size_check < FCS_MIN_DATA_SIZE) ||
1367*91f16700Schasinglulu 		(src_size > FCS_MAX_DATA_SIZE ||
1368*91f16700Schasinglulu 		src_size < FCS_MIN_DATA_SIZE)) {
1369*91f16700Schasinglulu 		return INTEL_SIP_SMC_STATUS_REJECTED;
1370*91f16700Schasinglulu 	}
1371*91f16700Schasinglulu 
1372*91f16700Schasinglulu 	resp_len = *dst_size / MBOX_WORD_BYTE;
1373*91f16700Schasinglulu 
1374*91f16700Schasinglulu 	/* Prepare command payload */
1375*91f16700Schasinglulu 	/* Crypto header */
1376*91f16700Schasinglulu 	i = 0;
1377*91f16700Schasinglulu 	payload[i] = fcs_ecdsa_hash_sign_param.session_id;
1378*91f16700Schasinglulu 	i++;
1379*91f16700Schasinglulu 	payload[i] = fcs_ecdsa_hash_sign_param.context_id;
1380*91f16700Schasinglulu 
1381*91f16700Schasinglulu 	i++;
1382*91f16700Schasinglulu 	payload[i] = fcs_ecdsa_hash_sign_param.crypto_param_size
1383*91f16700Schasinglulu 			& FCS_CS_FIELD_SIZE_MASK;
1384*91f16700Schasinglulu 	payload[i] |= (FCS_CS_FIELD_FLAG_INIT | FCS_CS_FIELD_FLAG_UPDATE
1385*91f16700Schasinglulu 			| FCS_CS_FIELD_FLAG_FINALIZE)
1386*91f16700Schasinglulu 			<< FCS_CS_FIELD_FLAG_OFFSET;
1387*91f16700Schasinglulu 	i++;
1388*91f16700Schasinglulu 	payload[i] = fcs_ecdsa_hash_sign_param.key_id;
1389*91f16700Schasinglulu 
1390*91f16700Schasinglulu 	/* Crypto parameters */
1391*91f16700Schasinglulu 	i++;
1392*91f16700Schasinglulu 	payload[i] = fcs_ecdsa_hash_sign_param.crypto_param
1393*91f16700Schasinglulu 			& INTEL_SIP_SMC_FCS_ECC_ALGO_MASK;
1394*91f16700Schasinglulu 
1395*91f16700Schasinglulu 	/* Hash Data */
1396*91f16700Schasinglulu 	i++;
1397*91f16700Schasinglulu 	hash_data_addr = src_addr;
1398*91f16700Schasinglulu 
1399*91f16700Schasinglulu 	if ((i + ((src_size) / MBOX_WORD_BYTE)) >
1400*91f16700Schasinglulu 		FCS_ECDSA_HASH_SIGN_CMD_MAX_WORD_SIZE) {
1401*91f16700Schasinglulu 		return INTEL_SIP_SMC_STATUS_REJECTED;
1402*91f16700Schasinglulu 	}
1403*91f16700Schasinglulu 
1404*91f16700Schasinglulu 	memcpy((uint8_t *) &payload[i], (uint8_t *) hash_data_addr,
1405*91f16700Schasinglulu 			src_size);
1406*91f16700Schasinglulu 
1407*91f16700Schasinglulu 	i += src_size / MBOX_WORD_BYTE;
1408*91f16700Schasinglulu 
1409*91f16700Schasinglulu 	status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_ECDSA_HASH_SIGN_REQ,
1410*91f16700Schasinglulu 			payload, i, CMD_CASUAL, (uint32_t *) dst_addr,
1411*91f16700Schasinglulu 			&resp_len);
1412*91f16700Schasinglulu 
1413*91f16700Schasinglulu 	memset((void *) &fcs_ecdsa_hash_sign_param,
1414*91f16700Schasinglulu 			0, sizeof(fcs_crypto_service_data));
1415*91f16700Schasinglulu 
1416*91f16700Schasinglulu 	if (status < 0) {
1417*91f16700Schasinglulu 		*mbox_error = -status;
1418*91f16700Schasinglulu 		return INTEL_SIP_SMC_STATUS_ERROR;
1419*91f16700Schasinglulu 	}
1420*91f16700Schasinglulu 
1421*91f16700Schasinglulu 	*dst_size = resp_len * MBOX_WORD_BYTE;
1422*91f16700Schasinglulu 	flush_dcache_range(dst_addr, *dst_size);
1423*91f16700Schasinglulu 
1424*91f16700Schasinglulu 	return INTEL_SIP_SMC_STATUS_OK;
1425*91f16700Schasinglulu }
1426*91f16700Schasinglulu 
1427*91f16700Schasinglulu int intel_fcs_ecdsa_hash_sig_verify_init(uint32_t session_id, uint32_t context_id,
1428*91f16700Schasinglulu 				uint32_t key_id, uint32_t param_size,
1429*91f16700Schasinglulu 				uint64_t param_data, uint32_t *mbox_error)
1430*91f16700Schasinglulu {
1431*91f16700Schasinglulu 	return intel_fcs_crypto_service_init(session_id, context_id,
1432*91f16700Schasinglulu 				key_id, param_size, param_data,
1433*91f16700Schasinglulu 				(void *) &fcs_ecdsa_hash_sig_verify_param,
1434*91f16700Schasinglulu 				mbox_error);
1435*91f16700Schasinglulu }
1436*91f16700Schasinglulu 
1437*91f16700Schasinglulu int intel_fcs_ecdsa_hash_sig_verify_finalize(uint32_t session_id, uint32_t context_id,
1438*91f16700Schasinglulu 				uint32_t src_addr, uint32_t src_size,
1439*91f16700Schasinglulu 				uint64_t dst_addr, uint32_t *dst_size,
1440*91f16700Schasinglulu 				uint32_t *mbox_error)
1441*91f16700Schasinglulu {
1442*91f16700Schasinglulu 	int status;
1443*91f16700Schasinglulu 	uint32_t i = 0;
1444*91f16700Schasinglulu 	uint32_t payload[FCS_ECDSA_HASH_SIG_VERIFY_CMD_MAX_WORD_SIZE] = {0U};
1445*91f16700Schasinglulu 	uint32_t resp_len;
1446*91f16700Schasinglulu 	uintptr_t hash_sig_pubkey_addr;
1447*91f16700Schasinglulu 	uint32_t dst_size_check = 0;
1448*91f16700Schasinglulu 
1449*91f16700Schasinglulu 	if ((dst_size == NULL) || (mbox_error == NULL)) {
1450*91f16700Schasinglulu 		return INTEL_SIP_SMC_STATUS_REJECTED;
1451*91f16700Schasinglulu 	}
1452*91f16700Schasinglulu 
1453*91f16700Schasinglulu 	if (fcs_ecdsa_hash_sig_verify_param.session_id != session_id ||
1454*91f16700Schasinglulu 	fcs_ecdsa_hash_sig_verify_param.context_id != context_id) {
1455*91f16700Schasinglulu 		return INTEL_SIP_SMC_STATUS_REJECTED;
1456*91f16700Schasinglulu 	}
1457*91f16700Schasinglulu 
1458*91f16700Schasinglulu 	if (!is_address_in_ddr_range(src_addr, src_size) ||
1459*91f16700Schasinglulu 		!is_address_in_ddr_range(dst_addr, *dst_size)) {
1460*91f16700Schasinglulu 		return INTEL_SIP_SMC_STATUS_REJECTED;
1461*91f16700Schasinglulu 	}
1462*91f16700Schasinglulu 
1463*91f16700Schasinglulu 	dst_size_check = *dst_size;
1464*91f16700Schasinglulu 	if ((dst_size_check > FCS_MAX_DATA_SIZE ||
1465*91f16700Schasinglulu 		dst_size_check < FCS_MIN_DATA_SIZE) ||
1466*91f16700Schasinglulu 		(src_size > FCS_MAX_DATA_SIZE ||
1467*91f16700Schasinglulu 		src_size < FCS_MIN_DATA_SIZE)) {
1468*91f16700Schasinglulu 		return INTEL_SIP_SMC_STATUS_REJECTED;
1469*91f16700Schasinglulu 	}
1470*91f16700Schasinglulu 
1471*91f16700Schasinglulu 	resp_len = *dst_size / MBOX_WORD_BYTE;
1472*91f16700Schasinglulu 
1473*91f16700Schasinglulu 	/* Prepare command payload */
1474*91f16700Schasinglulu 	/* Crypto header */
1475*91f16700Schasinglulu 	i = 0;
1476*91f16700Schasinglulu 	payload[i] = fcs_ecdsa_hash_sig_verify_param.session_id;
1477*91f16700Schasinglulu 
1478*91f16700Schasinglulu 	i++;
1479*91f16700Schasinglulu 	payload[i] = fcs_ecdsa_hash_sig_verify_param.context_id;
1480*91f16700Schasinglulu 
1481*91f16700Schasinglulu 	i++;
1482*91f16700Schasinglulu 	payload[i] = fcs_ecdsa_hash_sig_verify_param.crypto_param_size
1483*91f16700Schasinglulu 			& FCS_CS_FIELD_SIZE_MASK;
1484*91f16700Schasinglulu 	payload[i] |= (FCS_CS_FIELD_FLAG_INIT | FCS_CS_FIELD_FLAG_UPDATE
1485*91f16700Schasinglulu 			| FCS_CS_FIELD_FLAG_FINALIZE)
1486*91f16700Schasinglulu 			<< FCS_CS_FIELD_FLAG_OFFSET;
1487*91f16700Schasinglulu 
1488*91f16700Schasinglulu 	i++;
1489*91f16700Schasinglulu 	payload[i] = fcs_ecdsa_hash_sig_verify_param.key_id;
1490*91f16700Schasinglulu 
1491*91f16700Schasinglulu 	/* Crypto parameters */
1492*91f16700Schasinglulu 	i++;
1493*91f16700Schasinglulu 	payload[i] = fcs_ecdsa_hash_sig_verify_param.crypto_param
1494*91f16700Schasinglulu 			& INTEL_SIP_SMC_FCS_ECC_ALGO_MASK;
1495*91f16700Schasinglulu 
1496*91f16700Schasinglulu 	/* Hash Data Word, Signature Data Word and Public Key Data word */
1497*91f16700Schasinglulu 	i++;
1498*91f16700Schasinglulu 	hash_sig_pubkey_addr = src_addr;
1499*91f16700Schasinglulu 
1500*91f16700Schasinglulu 	if ((i + ((src_size) / MBOX_WORD_BYTE)) >
1501*91f16700Schasinglulu 		FCS_ECDSA_HASH_SIG_VERIFY_CMD_MAX_WORD_SIZE) {
1502*91f16700Schasinglulu 		return INTEL_SIP_SMC_STATUS_REJECTED;
1503*91f16700Schasinglulu 	}
1504*91f16700Schasinglulu 
1505*91f16700Schasinglulu 	memcpy((uint8_t *) &payload[i],
1506*91f16700Schasinglulu 			(uint8_t *) hash_sig_pubkey_addr, src_size);
1507*91f16700Schasinglulu 
1508*91f16700Schasinglulu 	i += (src_size / MBOX_WORD_BYTE);
1509*91f16700Schasinglulu 
1510*91f16700Schasinglulu 	status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_ECDSA_HASH_SIG_VERIFY,
1511*91f16700Schasinglulu 			payload, i, CMD_CASUAL, (uint32_t *) dst_addr,
1512*91f16700Schasinglulu 			&resp_len);
1513*91f16700Schasinglulu 
1514*91f16700Schasinglulu 	memset((void *)&fcs_ecdsa_hash_sig_verify_param,
1515*91f16700Schasinglulu 			0, sizeof(fcs_crypto_service_data));
1516*91f16700Schasinglulu 
1517*91f16700Schasinglulu 	if (status < 0) {
1518*91f16700Schasinglulu 		*mbox_error = -status;
1519*91f16700Schasinglulu 		return INTEL_SIP_SMC_STATUS_ERROR;
1520*91f16700Schasinglulu 	}
1521*91f16700Schasinglulu 
1522*91f16700Schasinglulu 	*dst_size = resp_len * MBOX_WORD_BYTE;
1523*91f16700Schasinglulu 	flush_dcache_range(dst_addr, *dst_size);
1524*91f16700Schasinglulu 
1525*91f16700Schasinglulu 	return INTEL_SIP_SMC_STATUS_OK;
1526*91f16700Schasinglulu }
1527*91f16700Schasinglulu 
1528*91f16700Schasinglulu int intel_fcs_ecdsa_sha2_data_sign_init(uint32_t session_id,
1529*91f16700Schasinglulu 				uint32_t context_id, uint32_t key_id,
1530*91f16700Schasinglulu 				uint32_t param_size, uint64_t param_data,
1531*91f16700Schasinglulu 				uint32_t *mbox_error)
1532*91f16700Schasinglulu {
1533*91f16700Schasinglulu 	return intel_fcs_crypto_service_init(session_id, context_id,
1534*91f16700Schasinglulu 				key_id, param_size, param_data,
1535*91f16700Schasinglulu 				(void *) &fcs_sha2_data_sign_param,
1536*91f16700Schasinglulu 				mbox_error);
1537*91f16700Schasinglulu }
1538*91f16700Schasinglulu 
1539*91f16700Schasinglulu int intel_fcs_ecdsa_sha2_data_sign_update_finalize(uint32_t session_id,
1540*91f16700Schasinglulu 				uint32_t context_id, uint32_t src_addr,
1541*91f16700Schasinglulu 				uint32_t src_size, uint64_t dst_addr,
1542*91f16700Schasinglulu 				uint32_t *dst_size, uint8_t is_finalised,
1543*91f16700Schasinglulu 				uint32_t *mbox_error)
1544*91f16700Schasinglulu {
1545*91f16700Schasinglulu 	int status;
1546*91f16700Schasinglulu 	int i;
1547*91f16700Schasinglulu 	uint32_t flag;
1548*91f16700Schasinglulu 	uint32_t crypto_header;
1549*91f16700Schasinglulu 	uint32_t payload[FCS_ECDSA_SHA2_DATA_SIGN_CMD_MAX_WORD_SIZE] = {0U};
1550*91f16700Schasinglulu 	uint32_t resp_len;
1551*91f16700Schasinglulu 
1552*91f16700Schasinglulu 	if ((dst_size == NULL) || (mbox_error == NULL)) {
1553*91f16700Schasinglulu 		return INTEL_SIP_SMC_STATUS_REJECTED;
1554*91f16700Schasinglulu 	}
1555*91f16700Schasinglulu 
1556*91f16700Schasinglulu 	if (fcs_sha2_data_sign_param.session_id != session_id ||
1557*91f16700Schasinglulu 		fcs_sha2_data_sign_param.context_id != context_id) {
1558*91f16700Schasinglulu 		return INTEL_SIP_SMC_STATUS_REJECTED;
1559*91f16700Schasinglulu 	}
1560*91f16700Schasinglulu 
1561*91f16700Schasinglulu 	/* Source data must be 8 bytes aligned */
1562*91f16700Schasinglulu 	if (!is_8_bytes_aligned(src_size)) {
1563*91f16700Schasinglulu 		return INTEL_SIP_SMC_STATUS_REJECTED;
1564*91f16700Schasinglulu 	}
1565*91f16700Schasinglulu 
1566*91f16700Schasinglulu 	if (!is_address_in_ddr_range(src_addr, src_size) ||
1567*91f16700Schasinglulu 		!is_address_in_ddr_range(dst_addr, *dst_size)) {
1568*91f16700Schasinglulu 		return INTEL_SIP_SMC_STATUS_REJECTED;
1569*91f16700Schasinglulu 	}
1570*91f16700Schasinglulu 
1571*91f16700Schasinglulu 	resp_len = *dst_size / MBOX_WORD_BYTE;
1572*91f16700Schasinglulu 
1573*91f16700Schasinglulu 	/* Prepare crypto header */
1574*91f16700Schasinglulu 	flag = 0;
1575*91f16700Schasinglulu 	if (fcs_sha2_data_sign_param.is_updated) {
1576*91f16700Schasinglulu 		fcs_sha2_data_sign_param.crypto_param_size = 0;
1577*91f16700Schasinglulu 	} else {
1578*91f16700Schasinglulu 		flag |= FCS_CS_FIELD_FLAG_INIT;
1579*91f16700Schasinglulu 	}
1580*91f16700Schasinglulu 
1581*91f16700Schasinglulu 	if (is_finalised != 0U) {
1582*91f16700Schasinglulu 		flag |= FCS_CS_FIELD_FLAG_FINALIZE;
1583*91f16700Schasinglulu 	} else {
1584*91f16700Schasinglulu 		flag |= FCS_CS_FIELD_FLAG_UPDATE;
1585*91f16700Schasinglulu 		fcs_sha2_data_sign_param.is_updated = 1;
1586*91f16700Schasinglulu 	}
1587*91f16700Schasinglulu 	crypto_header = (flag << FCS_CS_FIELD_FLAG_OFFSET) |
1588*91f16700Schasinglulu 			fcs_sha2_data_sign_param.crypto_param_size;
1589*91f16700Schasinglulu 
1590*91f16700Schasinglulu 	/* Prepare command payload */
1591*91f16700Schasinglulu 	i = 0;
1592*91f16700Schasinglulu 	payload[i] = fcs_sha2_data_sign_param.session_id;
1593*91f16700Schasinglulu 	i++;
1594*91f16700Schasinglulu 	payload[i] = fcs_sha2_data_sign_param.context_id;
1595*91f16700Schasinglulu 	i++;
1596*91f16700Schasinglulu 	payload[i] = crypto_header;
1597*91f16700Schasinglulu 	i++;
1598*91f16700Schasinglulu 
1599*91f16700Schasinglulu 	if ((crypto_header >> FCS_CS_FIELD_FLAG_OFFSET) &
1600*91f16700Schasinglulu 		FCS_CS_FIELD_FLAG_INIT) {
1601*91f16700Schasinglulu 		payload[i] = fcs_sha2_data_sign_param.key_id;
1602*91f16700Schasinglulu 		/* Crypto parameters */
1603*91f16700Schasinglulu 		i++;
1604*91f16700Schasinglulu 		payload[i] = fcs_sha2_data_sign_param.crypto_param
1605*91f16700Schasinglulu 				& INTEL_SIP_SMC_FCS_ECC_ALGO_MASK;
1606*91f16700Schasinglulu 		i++;
1607*91f16700Schasinglulu 	}
1608*91f16700Schasinglulu 
1609*91f16700Schasinglulu 	/* Data source address and size */
1610*91f16700Schasinglulu 	payload[i] = src_addr;
1611*91f16700Schasinglulu 	i++;
1612*91f16700Schasinglulu 	payload[i] = src_size;
1613*91f16700Schasinglulu 	i++;
1614*91f16700Schasinglulu 	status = mailbox_send_cmd(MBOX_JOB_ID,
1615*91f16700Schasinglulu 			MBOX_FCS_ECDSA_SHA2_DATA_SIGN_REQ, payload,
1616*91f16700Schasinglulu 			i, CMD_CASUAL, (uint32_t *) dst_addr,
1617*91f16700Schasinglulu 			&resp_len);
1618*91f16700Schasinglulu 
1619*91f16700Schasinglulu 	if (is_finalised != 0U) {
1620*91f16700Schasinglulu 		memset((void *)&fcs_sha2_data_sign_param, 0,
1621*91f16700Schasinglulu 			sizeof(fcs_crypto_service_data));
1622*91f16700Schasinglulu 	}
1623*91f16700Schasinglulu 
1624*91f16700Schasinglulu 	if (status < 0) {
1625*91f16700Schasinglulu 		*mbox_error = -status;
1626*91f16700Schasinglulu 		return INTEL_SIP_SMC_STATUS_ERROR;
1627*91f16700Schasinglulu 	}
1628*91f16700Schasinglulu 
1629*91f16700Schasinglulu 	*dst_size = resp_len * MBOX_WORD_BYTE;
1630*91f16700Schasinglulu 	flush_dcache_range(dst_addr, *dst_size);
1631*91f16700Schasinglulu 
1632*91f16700Schasinglulu 	return INTEL_SIP_SMC_STATUS_OK;
1633*91f16700Schasinglulu }
1634*91f16700Schasinglulu 
1635*91f16700Schasinglulu int intel_fcs_ecdsa_sha2_data_sign_smmu_update_finalize(uint32_t session_id,
1636*91f16700Schasinglulu 				uint32_t context_id, uint32_t src_addr,
1637*91f16700Schasinglulu 				uint32_t src_size, uint64_t dst_addr,
1638*91f16700Schasinglulu 				uint32_t *dst_size, uint8_t is_finalised,
1639*91f16700Schasinglulu 				uint32_t *mbox_error, uint32_t *send_id)
1640*91f16700Schasinglulu {
1641*91f16700Schasinglulu 	int status;
1642*91f16700Schasinglulu 	int i;
1643*91f16700Schasinglulu 	uint32_t flag;
1644*91f16700Schasinglulu 	uint32_t crypto_header;
1645*91f16700Schasinglulu 	uint32_t payload[FCS_ECDSA_SHA2_DATA_SIGN_CMD_MAX_WORD_SIZE] = {0U};
1646*91f16700Schasinglulu 	uint32_t resp_len;
1647*91f16700Schasinglulu 
1648*91f16700Schasinglulu 	/* Source data must be 8 bytes aligned */
1649*91f16700Schasinglulu 	if ((dst_size == NULL) || (mbox_error == NULL ||
1650*91f16700Schasinglulu 		!is_8_bytes_aligned(src_size))) {
1651*91f16700Schasinglulu 		return INTEL_SIP_SMC_STATUS_REJECTED;
1652*91f16700Schasinglulu 	}
1653*91f16700Schasinglulu 
1654*91f16700Schasinglulu 	if (fcs_sha2_data_sign_param.session_id != session_id ||
1655*91f16700Schasinglulu 		fcs_sha2_data_sign_param.context_id != context_id) {
1656*91f16700Schasinglulu 		return INTEL_SIP_SMC_STATUS_REJECTED;
1657*91f16700Schasinglulu 	}
1658*91f16700Schasinglulu 
1659*91f16700Schasinglulu 	if (!is_address_in_ddr_range(src_addr, src_size) ||
1660*91f16700Schasinglulu 		!is_address_in_ddr_range(dst_addr, *dst_size)) {
1661*91f16700Schasinglulu 		return INTEL_SIP_SMC_STATUS_REJECTED;
1662*91f16700Schasinglulu 	}
1663*91f16700Schasinglulu 
1664*91f16700Schasinglulu 	resp_len = *dst_size / MBOX_WORD_BYTE;
1665*91f16700Schasinglulu 
1666*91f16700Schasinglulu 	/* Prepare crypto header */
1667*91f16700Schasinglulu 	flag = 0;
1668*91f16700Schasinglulu 	if (fcs_sha2_data_sign_param.is_updated) {
1669*91f16700Schasinglulu 		fcs_sha2_data_sign_param.crypto_param_size = 0;
1670*91f16700Schasinglulu 	} else {
1671*91f16700Schasinglulu 		flag |= FCS_CS_FIELD_FLAG_INIT;
1672*91f16700Schasinglulu 	}
1673*91f16700Schasinglulu 
1674*91f16700Schasinglulu 	if (is_finalised != 0U) {
1675*91f16700Schasinglulu 		flag |= FCS_CS_FIELD_FLAG_FINALIZE;
1676*91f16700Schasinglulu 	} else {
1677*91f16700Schasinglulu 		flag |= FCS_CS_FIELD_FLAG_UPDATE;
1678*91f16700Schasinglulu 		fcs_sha2_data_sign_param.is_updated = 1;
1679*91f16700Schasinglulu 	}
1680*91f16700Schasinglulu 	crypto_header = (flag << FCS_CS_FIELD_FLAG_OFFSET) |
1681*91f16700Schasinglulu 			fcs_sha2_data_sign_param.crypto_param_size;
1682*91f16700Schasinglulu 
1683*91f16700Schasinglulu 	/* Prepare command payload */
1684*91f16700Schasinglulu 	i = 0;
1685*91f16700Schasinglulu 	payload[i] = fcs_sha2_data_sign_param.session_id;
1686*91f16700Schasinglulu 	i++;
1687*91f16700Schasinglulu 	payload[i] = fcs_sha2_data_sign_param.context_id;
1688*91f16700Schasinglulu 	i++;
1689*91f16700Schasinglulu 	payload[i] = crypto_header;
1690*91f16700Schasinglulu 	i++;
1691*91f16700Schasinglulu 
1692*91f16700Schasinglulu 	if ((crypto_header >> FCS_CS_FIELD_FLAG_OFFSET) &
1693*91f16700Schasinglulu 		FCS_CS_FIELD_FLAG_INIT) {
1694*91f16700Schasinglulu 		payload[i] = fcs_sha2_data_sign_param.key_id;
1695*91f16700Schasinglulu 		/* Crypto parameters */
1696*91f16700Schasinglulu 		i++;
1697*91f16700Schasinglulu 		payload[i] = fcs_sha2_data_sign_param.crypto_param
1698*91f16700Schasinglulu 				& INTEL_SIP_SMC_FCS_ECC_ALGO_MASK;
1699*91f16700Schasinglulu 		i++;
1700*91f16700Schasinglulu 	}
1701*91f16700Schasinglulu 
1702*91f16700Schasinglulu 	/* Data source address and size */
1703*91f16700Schasinglulu 	payload[i] = src_addr;
1704*91f16700Schasinglulu 	i++;
1705*91f16700Schasinglulu 	payload[i] = src_size;
1706*91f16700Schasinglulu 	i++;
1707*91f16700Schasinglulu 
1708*91f16700Schasinglulu 	status = mailbox_send_cmd_async(send_id,
1709*91f16700Schasinglulu 					MBOX_FCS_ECDSA_SHA2_DATA_SIGN_REQ,
1710*91f16700Schasinglulu 					payload, i, CMD_INDIRECT);
1711*91f16700Schasinglulu 
1712*91f16700Schasinglulu 	if (is_finalised != 0U) {
1713*91f16700Schasinglulu 		memset((void *)&fcs_sha2_data_sign_param, 0,
1714*91f16700Schasinglulu 			sizeof(fcs_crypto_service_data));
1715*91f16700Schasinglulu 	}
1716*91f16700Schasinglulu 
1717*91f16700Schasinglulu 	if (status < 0) {
1718*91f16700Schasinglulu 		*mbox_error = -status;
1719*91f16700Schasinglulu 		return INTEL_SIP_SMC_STATUS_ERROR;
1720*91f16700Schasinglulu 	}
1721*91f16700Schasinglulu 
1722*91f16700Schasinglulu 	*dst_size = resp_len * MBOX_WORD_BYTE;
1723*91f16700Schasinglulu 	flush_dcache_range(dst_addr, *dst_size);
1724*91f16700Schasinglulu 
1725*91f16700Schasinglulu 	return INTEL_SIP_SMC_STATUS_OK;
1726*91f16700Schasinglulu }
1727*91f16700Schasinglulu 
1728*91f16700Schasinglulu int intel_fcs_ecdsa_sha2_data_sig_verify_init(uint32_t session_id,
1729*91f16700Schasinglulu 				uint32_t context_id, uint32_t key_id,
1730*91f16700Schasinglulu 				uint32_t param_size, uint64_t param_data,
1731*91f16700Schasinglulu 				uint32_t *mbox_error)
1732*91f16700Schasinglulu {
1733*91f16700Schasinglulu 	return intel_fcs_crypto_service_init(session_id, context_id,
1734*91f16700Schasinglulu 				key_id, param_size, param_data,
1735*91f16700Schasinglulu 				(void *) &fcs_sha2_data_sig_verify_param,
1736*91f16700Schasinglulu 				mbox_error);
1737*91f16700Schasinglulu }
1738*91f16700Schasinglulu 
1739*91f16700Schasinglulu int intel_fcs_ecdsa_sha2_data_sig_verify_update_finalize(uint32_t session_id,
1740*91f16700Schasinglulu 				uint32_t context_id, uint32_t src_addr,
1741*91f16700Schasinglulu 				uint32_t src_size, uint64_t dst_addr,
1742*91f16700Schasinglulu 				uint32_t *dst_size, uint32_t data_size,
1743*91f16700Schasinglulu 				uint8_t is_finalised, uint32_t *mbox_error)
1744*91f16700Schasinglulu {
1745*91f16700Schasinglulu 	int status;
1746*91f16700Schasinglulu 	uint32_t i;
1747*91f16700Schasinglulu 	uint32_t flag;
1748*91f16700Schasinglulu 	uint32_t crypto_header;
1749*91f16700Schasinglulu 	uint32_t payload[FCS_ECDSA_SHA2_DATA_SIG_VERIFY_CMD_MAX_WORD_SIZE] = {0U};
1750*91f16700Schasinglulu 	uint32_t resp_len;
1751*91f16700Schasinglulu 	uintptr_t sig_pubkey_offset;
1752*91f16700Schasinglulu 	uint32_t dst_size_check = 0;
1753*91f16700Schasinglulu 
1754*91f16700Schasinglulu 	if ((dst_size == NULL) || (mbox_error == NULL)) {
1755*91f16700Schasinglulu 		return INTEL_SIP_SMC_STATUS_REJECTED;
1756*91f16700Schasinglulu 	}
1757*91f16700Schasinglulu 
1758*91f16700Schasinglulu 	if (fcs_sha2_data_sig_verify_param.session_id != session_id ||
1759*91f16700Schasinglulu 		fcs_sha2_data_sig_verify_param.context_id != context_id) {
1760*91f16700Schasinglulu 		return INTEL_SIP_SMC_STATUS_REJECTED;
1761*91f16700Schasinglulu 	}
1762*91f16700Schasinglulu 
1763*91f16700Schasinglulu 	if (data_size > src_size) {
1764*91f16700Schasinglulu 		return INTEL_SIP_SMC_STATUS_REJECTED;
1765*91f16700Schasinglulu 	}
1766*91f16700Schasinglulu 
1767*91f16700Schasinglulu 	if (!is_size_4_bytes_aligned(src_size)) {
1768*91f16700Schasinglulu 		return INTEL_SIP_SMC_STATUS_REJECTED;
1769*91f16700Schasinglulu 	}
1770*91f16700Schasinglulu 
1771*91f16700Schasinglulu 	if (!is_8_bytes_aligned(data_size) ||
1772*91f16700Schasinglulu 		!is_8_bytes_aligned(src_addr)) {
1773*91f16700Schasinglulu 		return INTEL_SIP_SMC_STATUS_REJECTED;
1774*91f16700Schasinglulu 	}
1775*91f16700Schasinglulu 
1776*91f16700Schasinglulu 	if (!is_address_in_ddr_range(src_addr, src_size) ||
1777*91f16700Schasinglulu 		!is_address_in_ddr_range(dst_addr, *dst_size)) {
1778*91f16700Schasinglulu 		return INTEL_SIP_SMC_STATUS_REJECTED;
1779*91f16700Schasinglulu 	}
1780*91f16700Schasinglulu 
1781*91f16700Schasinglulu 	dst_size_check = *dst_size;
1782*91f16700Schasinglulu 	if ((dst_size_check > FCS_MAX_DATA_SIZE ||
1783*91f16700Schasinglulu 		dst_size_check < FCS_MIN_DATA_SIZE) ||
1784*91f16700Schasinglulu 		(src_size > FCS_MAX_DATA_SIZE ||
1785*91f16700Schasinglulu 		src_size < FCS_MIN_DATA_SIZE)) {
1786*91f16700Schasinglulu 		return INTEL_SIP_SMC_STATUS_REJECTED;
1787*91f16700Schasinglulu 	}
1788*91f16700Schasinglulu 
1789*91f16700Schasinglulu 	resp_len = *dst_size / MBOX_WORD_BYTE;
1790*91f16700Schasinglulu 
1791*91f16700Schasinglulu 	/* Prepare crypto header */
1792*91f16700Schasinglulu 	flag = 0;
1793*91f16700Schasinglulu 	if (fcs_sha2_data_sig_verify_param.is_updated)
1794*91f16700Schasinglulu 		fcs_sha2_data_sig_verify_param.crypto_param_size = 0;
1795*91f16700Schasinglulu 	else
1796*91f16700Schasinglulu 		flag |= FCS_CS_FIELD_FLAG_INIT;
1797*91f16700Schasinglulu 
1798*91f16700Schasinglulu 	if (is_finalised != 0U)
1799*91f16700Schasinglulu 		flag |= FCS_CS_FIELD_FLAG_FINALIZE;
1800*91f16700Schasinglulu 	else {
1801*91f16700Schasinglulu 		flag |= FCS_CS_FIELD_FLAG_UPDATE;
1802*91f16700Schasinglulu 		fcs_sha2_data_sig_verify_param.is_updated = 1;
1803*91f16700Schasinglulu 	}
1804*91f16700Schasinglulu 	crypto_header = (flag << FCS_CS_FIELD_FLAG_OFFSET) |
1805*91f16700Schasinglulu 			fcs_sha2_data_sig_verify_param.crypto_param_size;
1806*91f16700Schasinglulu 
1807*91f16700Schasinglulu 	/* Prepare command payload */
1808*91f16700Schasinglulu 	i = 0;
1809*91f16700Schasinglulu 	payload[i] = fcs_sha2_data_sig_verify_param.session_id;
1810*91f16700Schasinglulu 	i++;
1811*91f16700Schasinglulu 	payload[i] = fcs_sha2_data_sig_verify_param.context_id;
1812*91f16700Schasinglulu 	i++;
1813*91f16700Schasinglulu 	payload[i] = crypto_header;
1814*91f16700Schasinglulu 	i++;
1815*91f16700Schasinglulu 
1816*91f16700Schasinglulu 	if ((crypto_header >> FCS_CS_FIELD_FLAG_OFFSET) &
1817*91f16700Schasinglulu 		FCS_CS_FIELD_FLAG_INIT) {
1818*91f16700Schasinglulu 		payload[i] = fcs_sha2_data_sig_verify_param.key_id;
1819*91f16700Schasinglulu 		i++;
1820*91f16700Schasinglulu 		/* Crypto parameters */
1821*91f16700Schasinglulu 		payload[i] = fcs_sha2_data_sig_verify_param.crypto_param
1822*91f16700Schasinglulu 				& INTEL_SIP_SMC_FCS_ECC_ALGO_MASK;
1823*91f16700Schasinglulu 		i++;
1824*91f16700Schasinglulu 	}
1825*91f16700Schasinglulu 
1826*91f16700Schasinglulu 	/* Data source address and size */
1827*91f16700Schasinglulu 	payload[i] = src_addr;
1828*91f16700Schasinglulu 	i++;
1829*91f16700Schasinglulu 	payload[i] = data_size;
1830*91f16700Schasinglulu 	i++;
1831*91f16700Schasinglulu 
1832*91f16700Schasinglulu 	if ((crypto_header >> FCS_CS_FIELD_FLAG_OFFSET) &
1833*91f16700Schasinglulu 		FCS_CS_FIELD_FLAG_FINALIZE) {
1834*91f16700Schasinglulu 		/* Signature + Public Key Data */
1835*91f16700Schasinglulu 		sig_pubkey_offset = src_addr + data_size;
1836*91f16700Schasinglulu 
1837*91f16700Schasinglulu 		if ((i + ((src_size - data_size) / MBOX_WORD_BYTE)) >
1838*91f16700Schasinglulu 			FCS_ECDSA_SHA2_DATA_SIG_VERIFY_CMD_MAX_WORD_SIZE) {
1839*91f16700Schasinglulu 			return INTEL_SIP_SMC_STATUS_REJECTED;
1840*91f16700Schasinglulu 		}
1841*91f16700Schasinglulu 
1842*91f16700Schasinglulu 		memcpy((uint8_t *) &payload[i], (uint8_t *) sig_pubkey_offset,
1843*91f16700Schasinglulu 			src_size - data_size);
1844*91f16700Schasinglulu 
1845*91f16700Schasinglulu 		i += (src_size - data_size) / MBOX_WORD_BYTE;
1846*91f16700Schasinglulu 	}
1847*91f16700Schasinglulu 
1848*91f16700Schasinglulu 	status = mailbox_send_cmd(MBOX_JOB_ID,
1849*91f16700Schasinglulu 			MBOX_FCS_ECDSA_SHA2_DATA_SIGN_VERIFY, payload, i,
1850*91f16700Schasinglulu 			CMD_CASUAL, (uint32_t *) dst_addr, &resp_len);
1851*91f16700Schasinglulu 
1852*91f16700Schasinglulu 	if (is_finalised != 0U) {
1853*91f16700Schasinglulu 		memset((void *) &fcs_sha2_data_sig_verify_param, 0,
1854*91f16700Schasinglulu 			sizeof(fcs_crypto_service_data));
1855*91f16700Schasinglulu 	}
1856*91f16700Schasinglulu 
1857*91f16700Schasinglulu 	if (status < 0) {
1858*91f16700Schasinglulu 		*mbox_error = -status;
1859*91f16700Schasinglulu 		return INTEL_SIP_SMC_STATUS_ERROR;
1860*91f16700Schasinglulu 	}
1861*91f16700Schasinglulu 
1862*91f16700Schasinglulu 	*dst_size = resp_len * MBOX_WORD_BYTE;
1863*91f16700Schasinglulu 	flush_dcache_range(dst_addr, *dst_size);
1864*91f16700Schasinglulu 
1865*91f16700Schasinglulu 	return INTEL_SIP_SMC_STATUS_OK;
1866*91f16700Schasinglulu }
1867*91f16700Schasinglulu 
1868*91f16700Schasinglulu int intel_fcs_ecdsa_sha2_data_sig_verify_smmu_update_finalize(uint32_t session_id,
1869*91f16700Schasinglulu 				uint32_t context_id, uint32_t src_addr,
1870*91f16700Schasinglulu 				uint32_t src_size, uint64_t dst_addr,
1871*91f16700Schasinglulu 				uint32_t *dst_size, uint32_t data_size,
1872*91f16700Schasinglulu 				uint8_t is_finalised, uint32_t *mbox_error,
1873*91f16700Schasinglulu 				uint32_t *send_id)
1874*91f16700Schasinglulu {
1875*91f16700Schasinglulu 	int status;
1876*91f16700Schasinglulu 	uint32_t i;
1877*91f16700Schasinglulu 	uint32_t flag;
1878*91f16700Schasinglulu 	uint32_t crypto_header;
1879*91f16700Schasinglulu 	uint32_t payload[FCS_ECDSA_SHA2_DATA_SIG_VERIFY_CMD_MAX_WORD_SIZE] = {0U};
1880*91f16700Schasinglulu 	uint32_t resp_len;
1881*91f16700Schasinglulu 	uintptr_t sig_pubkey_offset;
1882*91f16700Schasinglulu 	uint32_t dst_size_check = 0;
1883*91f16700Schasinglulu 
1884*91f16700Schasinglulu 	/*
1885*91f16700Schasinglulu 	 * Source data must be 4 bytes aligned
1886*91f16700Schasinglulu 	 * Source address must be 8 bytes aligned
1887*91f16700Schasinglulu 	 * User data must be 8 bytes aligned
1888*91f16700Schasinglulu 	 */
1889*91f16700Schasinglulu 	if ((dst_size == NULL) || (mbox_error == NULL) ||
1890*91f16700Schasinglulu 		!is_size_4_bytes_aligned(src_size) ||
1891*91f16700Schasinglulu 		!is_8_bytes_aligned(src_addr) ||
1892*91f16700Schasinglulu 		!is_8_bytes_aligned(data_size)) {
1893*91f16700Schasinglulu 		return INTEL_SIP_SMC_STATUS_REJECTED;
1894*91f16700Schasinglulu 	}
1895*91f16700Schasinglulu 
1896*91f16700Schasinglulu 	if (fcs_sha2_data_sig_verify_param.session_id != session_id ||
1897*91f16700Schasinglulu 		fcs_sha2_data_sig_verify_param.context_id != context_id) {
1898*91f16700Schasinglulu 		return INTEL_SIP_SMC_STATUS_REJECTED;
1899*91f16700Schasinglulu 	}
1900*91f16700Schasinglulu 
1901*91f16700Schasinglulu 	if (data_size > src_size) {
1902*91f16700Schasinglulu 		return INTEL_SIP_SMC_STATUS_REJECTED;
1903*91f16700Schasinglulu 	}
1904*91f16700Schasinglulu 
1905*91f16700Schasinglulu 	if (!is_address_in_ddr_range(src_addr, src_size) ||
1906*91f16700Schasinglulu 		!is_address_in_ddr_range(dst_addr, *dst_size)) {
1907*91f16700Schasinglulu 		return INTEL_SIP_SMC_STATUS_REJECTED;
1908*91f16700Schasinglulu 	}
1909*91f16700Schasinglulu 
1910*91f16700Schasinglulu 	dst_size_check = *dst_size;
1911*91f16700Schasinglulu 	if ((dst_size_check > FCS_MAX_DATA_SIZE ||
1912*91f16700Schasinglulu 		dst_size_check < FCS_MIN_DATA_SIZE) ||
1913*91f16700Schasinglulu 		(src_size > FCS_MAX_DATA_SIZE ||
1914*91f16700Schasinglulu 		src_size < FCS_MIN_DATA_SIZE)) {
1915*91f16700Schasinglulu 		return INTEL_SIP_SMC_STATUS_REJECTED;
1916*91f16700Schasinglulu 	}
1917*91f16700Schasinglulu 
1918*91f16700Schasinglulu 	resp_len = *dst_size / MBOX_WORD_BYTE;
1919*91f16700Schasinglulu 
1920*91f16700Schasinglulu 	/* Prepare crypto header */
1921*91f16700Schasinglulu 	flag = 0;
1922*91f16700Schasinglulu 	if (fcs_sha2_data_sig_verify_param.is_updated)
1923*91f16700Schasinglulu 		fcs_sha2_data_sig_verify_param.crypto_param_size = 0;
1924*91f16700Schasinglulu 	else
1925*91f16700Schasinglulu 		flag |= FCS_CS_FIELD_FLAG_INIT;
1926*91f16700Schasinglulu 
1927*91f16700Schasinglulu 	if (is_finalised != 0U)
1928*91f16700Schasinglulu 		flag |= FCS_CS_FIELD_FLAG_FINALIZE;
1929*91f16700Schasinglulu 	else {
1930*91f16700Schasinglulu 		flag |= FCS_CS_FIELD_FLAG_UPDATE;
1931*91f16700Schasinglulu 		fcs_sha2_data_sig_verify_param.is_updated = 1;
1932*91f16700Schasinglulu 	}
1933*91f16700Schasinglulu 	crypto_header = (flag << FCS_CS_FIELD_FLAG_OFFSET) |
1934*91f16700Schasinglulu 			fcs_sha2_data_sig_verify_param.crypto_param_size;
1935*91f16700Schasinglulu 
1936*91f16700Schasinglulu 	/* Prepare command payload */
1937*91f16700Schasinglulu 	i = 0;
1938*91f16700Schasinglulu 	payload[i] = fcs_sha2_data_sig_verify_param.session_id;
1939*91f16700Schasinglulu 	i++;
1940*91f16700Schasinglulu 	payload[i] = fcs_sha2_data_sig_verify_param.context_id;
1941*91f16700Schasinglulu 	i++;
1942*91f16700Schasinglulu 	payload[i] = crypto_header;
1943*91f16700Schasinglulu 	i++;
1944*91f16700Schasinglulu 
1945*91f16700Schasinglulu 	if ((crypto_header >> FCS_CS_FIELD_FLAG_OFFSET) &
1946*91f16700Schasinglulu 		FCS_CS_FIELD_FLAG_INIT) {
1947*91f16700Schasinglulu 		payload[i] = fcs_sha2_data_sig_verify_param.key_id;
1948*91f16700Schasinglulu 		i++;
1949*91f16700Schasinglulu 		/* Crypto parameters */
1950*91f16700Schasinglulu 		payload[i] = fcs_sha2_data_sig_verify_param.crypto_param
1951*91f16700Schasinglulu 				& INTEL_SIP_SMC_FCS_ECC_ALGO_MASK;
1952*91f16700Schasinglulu 		i++;
1953*91f16700Schasinglulu 	}
1954*91f16700Schasinglulu 
1955*91f16700Schasinglulu 	/* Data source address and size */
1956*91f16700Schasinglulu 	payload[i] = src_addr;
1957*91f16700Schasinglulu 	i++;
1958*91f16700Schasinglulu 	payload[i] = data_size;
1959*91f16700Schasinglulu 	i++;
1960*91f16700Schasinglulu 
1961*91f16700Schasinglulu 	if ((crypto_header >> FCS_CS_FIELD_FLAG_OFFSET) &
1962*91f16700Schasinglulu 		FCS_CS_FIELD_FLAG_FINALIZE) {
1963*91f16700Schasinglulu 		/* Copy mac data to command
1964*91f16700Schasinglulu 		 * Using dst_addr (physical address) to store sig_pubkey_offset
1965*91f16700Schasinglulu 		 * sig_pubkey_offset is Signature + Public Key Data
1966*91f16700Schasinglulu 		 */
1967*91f16700Schasinglulu 		sig_pubkey_offset = dst_addr;
1968*91f16700Schasinglulu 
1969*91f16700Schasinglulu 		if ((i + ((src_size - data_size) / MBOX_WORD_BYTE)) >
1970*91f16700Schasinglulu 			FCS_ECDSA_SHA2_DATA_SIG_VERIFY_CMD_MAX_WORD_SIZE) {
1971*91f16700Schasinglulu 			return INTEL_SIP_SMC_STATUS_REJECTED;
1972*91f16700Schasinglulu 		}
1973*91f16700Schasinglulu 
1974*91f16700Schasinglulu 		memcpy((uint8_t *) &payload[i], (uint8_t *) sig_pubkey_offset,
1975*91f16700Schasinglulu 			src_size - data_size);
1976*91f16700Schasinglulu 
1977*91f16700Schasinglulu 		memset((void *) dst_addr, 0, *dst_size);
1978*91f16700Schasinglulu 
1979*91f16700Schasinglulu 		i += (src_size - data_size) / MBOX_WORD_BYTE;
1980*91f16700Schasinglulu 	}
1981*91f16700Schasinglulu 
1982*91f16700Schasinglulu 	status = mailbox_send_cmd_async(send_id,
1983*91f16700Schasinglulu 					MBOX_FCS_ECDSA_SHA2_DATA_SIGN_VERIFY,
1984*91f16700Schasinglulu 					payload, i, CMD_INDIRECT);
1985*91f16700Schasinglulu 
1986*91f16700Schasinglulu 	if (is_finalised != 0U) {
1987*91f16700Schasinglulu 		memset((void *) &fcs_sha2_data_sig_verify_param, 0,
1988*91f16700Schasinglulu 			sizeof(fcs_crypto_service_data));
1989*91f16700Schasinglulu 	}
1990*91f16700Schasinglulu 
1991*91f16700Schasinglulu 	if (status < 0) {
1992*91f16700Schasinglulu 		*mbox_error = -status;
1993*91f16700Schasinglulu 		return INTEL_SIP_SMC_STATUS_ERROR;
1994*91f16700Schasinglulu 	}
1995*91f16700Schasinglulu 
1996*91f16700Schasinglulu 	*dst_size = resp_len * MBOX_WORD_BYTE;
1997*91f16700Schasinglulu 	flush_dcache_range(dst_addr, *dst_size);
1998*91f16700Schasinglulu 
1999*91f16700Schasinglulu 	return INTEL_SIP_SMC_STATUS_OK;
2000*91f16700Schasinglulu }
2001*91f16700Schasinglulu 
2002*91f16700Schasinglulu int intel_fcs_ecdsa_get_pubkey_init(uint32_t session_id, uint32_t context_id,
2003*91f16700Schasinglulu 				uint32_t key_id, uint32_t param_size,
2004*91f16700Schasinglulu 				uint64_t param_data, uint32_t *mbox_error)
2005*91f16700Schasinglulu {
2006*91f16700Schasinglulu 	return intel_fcs_crypto_service_init(session_id, context_id,
2007*91f16700Schasinglulu 				key_id, param_size, param_data,
2008*91f16700Schasinglulu 				(void *) &fcs_ecdsa_get_pubkey_param,
2009*91f16700Schasinglulu 				mbox_error);
2010*91f16700Schasinglulu }
2011*91f16700Schasinglulu 
2012*91f16700Schasinglulu int intel_fcs_ecdsa_get_pubkey_finalize(uint32_t session_id, uint32_t context_id,
2013*91f16700Schasinglulu 				uint64_t dst_addr, uint32_t *dst_size,
2014*91f16700Schasinglulu 				uint32_t *mbox_error)
2015*91f16700Schasinglulu {
2016*91f16700Schasinglulu 	int status;
2017*91f16700Schasinglulu 	int i;
2018*91f16700Schasinglulu 	uint32_t crypto_header;
2019*91f16700Schasinglulu 	uint32_t ret_size;
2020*91f16700Schasinglulu 	uint32_t payload[FCS_ECDSA_GET_PUBKEY_MAX_WORD_SIZE] = {0U};
2021*91f16700Schasinglulu 
2022*91f16700Schasinglulu 	if ((dst_size == NULL) || (mbox_error == NULL)) {
2023*91f16700Schasinglulu 		return INTEL_SIP_SMC_STATUS_REJECTED;
2024*91f16700Schasinglulu 	}
2025*91f16700Schasinglulu 
2026*91f16700Schasinglulu 	if (fcs_ecdsa_get_pubkey_param.session_id != session_id ||
2027*91f16700Schasinglulu 		fcs_ecdsa_get_pubkey_param.context_id != context_id) {
2028*91f16700Schasinglulu 		return INTEL_SIP_SMC_STATUS_REJECTED;
2029*91f16700Schasinglulu 	}
2030*91f16700Schasinglulu 
2031*91f16700Schasinglulu 	ret_size = *dst_size / MBOX_WORD_BYTE;
2032*91f16700Schasinglulu 
2033*91f16700Schasinglulu 	crypto_header = ((FCS_CS_FIELD_FLAG_INIT |
2034*91f16700Schasinglulu 			FCS_CS_FIELD_FLAG_UPDATE |
2035*91f16700Schasinglulu 			FCS_CS_FIELD_FLAG_FINALIZE) <<
2036*91f16700Schasinglulu 			FCS_CS_FIELD_FLAG_OFFSET) |
2037*91f16700Schasinglulu 			fcs_ecdsa_get_pubkey_param.crypto_param_size;
2038*91f16700Schasinglulu 	i = 0;
2039*91f16700Schasinglulu 	/* Prepare command payload */
2040*91f16700Schasinglulu 	payload[i] = session_id;
2041*91f16700Schasinglulu 	i++;
2042*91f16700Schasinglulu 	payload[i] = context_id;
2043*91f16700Schasinglulu 	i++;
2044*91f16700Schasinglulu 	payload[i] = crypto_header;
2045*91f16700Schasinglulu 	i++;
2046*91f16700Schasinglulu 	payload[i] = fcs_ecdsa_get_pubkey_param.key_id;
2047*91f16700Schasinglulu 	i++;
2048*91f16700Schasinglulu 	payload[i] = (uint32_t) fcs_ecdsa_get_pubkey_param.crypto_param &
2049*91f16700Schasinglulu 			INTEL_SIP_SMC_FCS_ECC_ALGO_MASK;
2050*91f16700Schasinglulu 	i++;
2051*91f16700Schasinglulu 
2052*91f16700Schasinglulu 	status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_ECDSA_GET_PUBKEY,
2053*91f16700Schasinglulu 			payload, i, CMD_CASUAL,
2054*91f16700Schasinglulu 			(uint32_t *) dst_addr, &ret_size);
2055*91f16700Schasinglulu 
2056*91f16700Schasinglulu 	memset((void *) &fcs_ecdsa_get_pubkey_param, 0,
2057*91f16700Schasinglulu 		sizeof(fcs_crypto_service_data));
2058*91f16700Schasinglulu 
2059*91f16700Schasinglulu 	if (status < 0) {
2060*91f16700Schasinglulu 		*mbox_error = -status;
2061*91f16700Schasinglulu 		return INTEL_SIP_SMC_STATUS_ERROR;
2062*91f16700Schasinglulu 	}
2063*91f16700Schasinglulu 
2064*91f16700Schasinglulu 	*dst_size = ret_size * MBOX_WORD_BYTE;
2065*91f16700Schasinglulu 	flush_dcache_range(dst_addr, *dst_size);
2066*91f16700Schasinglulu 
2067*91f16700Schasinglulu 	return INTEL_SIP_SMC_STATUS_OK;
2068*91f16700Schasinglulu }
2069*91f16700Schasinglulu 
2070*91f16700Schasinglulu int intel_fcs_ecdh_request_init(uint32_t session_id, uint32_t context_id,
2071*91f16700Schasinglulu 				uint32_t key_id, uint32_t param_size,
2072*91f16700Schasinglulu 				uint64_t param_data, uint32_t *mbox_error)
2073*91f16700Schasinglulu {
2074*91f16700Schasinglulu 	return intel_fcs_crypto_service_init(session_id, context_id,
2075*91f16700Schasinglulu 				key_id, param_size, param_data,
2076*91f16700Schasinglulu 				(void *) &fcs_ecdh_request_param,
2077*91f16700Schasinglulu 				mbox_error);
2078*91f16700Schasinglulu }
2079*91f16700Schasinglulu 
2080*91f16700Schasinglulu int intel_fcs_ecdh_request_finalize(uint32_t session_id, uint32_t context_id,
2081*91f16700Schasinglulu 				uint32_t src_addr, uint32_t src_size,
2082*91f16700Schasinglulu 				uint64_t dst_addr, uint32_t *dst_size,
2083*91f16700Schasinglulu 				uint32_t *mbox_error)
2084*91f16700Schasinglulu {
2085*91f16700Schasinglulu 	int status;
2086*91f16700Schasinglulu 	uint32_t i;
2087*91f16700Schasinglulu 	uint32_t payload[FCS_ECDH_REQUEST_CMD_MAX_WORD_SIZE] = {0U};
2088*91f16700Schasinglulu 	uint32_t resp_len;
2089*91f16700Schasinglulu 	uintptr_t pubkey;
2090*91f16700Schasinglulu 	uint32_t dst_size_check = 0;
2091*91f16700Schasinglulu 
2092*91f16700Schasinglulu 	if ((dst_size == NULL) || (mbox_error == NULL)) {
2093*91f16700Schasinglulu 		return INTEL_SIP_SMC_STATUS_REJECTED;
2094*91f16700Schasinglulu 	}
2095*91f16700Schasinglulu 
2096*91f16700Schasinglulu 
2097*91f16700Schasinglulu 	if (fcs_ecdh_request_param.session_id != session_id ||
2098*91f16700Schasinglulu 		fcs_ecdh_request_param.context_id != context_id) {
2099*91f16700Schasinglulu 		return INTEL_SIP_SMC_STATUS_REJECTED;
2100*91f16700Schasinglulu 	}
2101*91f16700Schasinglulu 
2102*91f16700Schasinglulu 	if (!is_address_in_ddr_range(src_addr, src_size) ||
2103*91f16700Schasinglulu 		!is_address_in_ddr_range(dst_addr, *dst_size)) {
2104*91f16700Schasinglulu 		return INTEL_SIP_SMC_STATUS_REJECTED;
2105*91f16700Schasinglulu 	}
2106*91f16700Schasinglulu 
2107*91f16700Schasinglulu 	dst_size_check = *dst_size;
2108*91f16700Schasinglulu 	if ((dst_size_check > FCS_MAX_DATA_SIZE ||
2109*91f16700Schasinglulu 		dst_size_check < FCS_MIN_DATA_SIZE) ||
2110*91f16700Schasinglulu 		(src_size > FCS_MAX_DATA_SIZE ||
2111*91f16700Schasinglulu 		src_size < FCS_MIN_DATA_SIZE)) {
2112*91f16700Schasinglulu 		return INTEL_SIP_SMC_STATUS_REJECTED;
2113*91f16700Schasinglulu 	}
2114*91f16700Schasinglulu 
2115*91f16700Schasinglulu 	resp_len = *dst_size / MBOX_WORD_BYTE;
2116*91f16700Schasinglulu 
2117*91f16700Schasinglulu 	/* Prepare command payload */
2118*91f16700Schasinglulu 	i = 0;
2119*91f16700Schasinglulu 	/* Crypto header */
2120*91f16700Schasinglulu 	payload[i] = fcs_ecdh_request_param.session_id;
2121*91f16700Schasinglulu 	i++;
2122*91f16700Schasinglulu 	payload[i] = fcs_ecdh_request_param.context_id;
2123*91f16700Schasinglulu 	i++;
2124*91f16700Schasinglulu 	payload[i] = fcs_ecdh_request_param.crypto_param_size
2125*91f16700Schasinglulu 			& FCS_CS_FIELD_SIZE_MASK;
2126*91f16700Schasinglulu 	payload[i] |= (FCS_CS_FIELD_FLAG_INIT | FCS_CS_FIELD_FLAG_UPDATE
2127*91f16700Schasinglulu 			| FCS_CS_FIELD_FLAG_FINALIZE)
2128*91f16700Schasinglulu 			<< FCS_CS_FIELD_FLAG_OFFSET;
2129*91f16700Schasinglulu 	i++;
2130*91f16700Schasinglulu 	payload[i] = fcs_ecdh_request_param.key_id;
2131*91f16700Schasinglulu 	i++;
2132*91f16700Schasinglulu 	/* Crypto parameters */
2133*91f16700Schasinglulu 	payload[i] = fcs_ecdh_request_param.crypto_param
2134*91f16700Schasinglulu 			& INTEL_SIP_SMC_FCS_ECC_ALGO_MASK;
2135*91f16700Schasinglulu 	i++;
2136*91f16700Schasinglulu 	/* Public key data */
2137*91f16700Schasinglulu 	pubkey = src_addr;
2138*91f16700Schasinglulu 
2139*91f16700Schasinglulu 	if ((i + ((src_size) / MBOX_WORD_BYTE)) >
2140*91f16700Schasinglulu 		FCS_ECDH_REQUEST_CMD_MAX_WORD_SIZE) {
2141*91f16700Schasinglulu 		return INTEL_SIP_SMC_STATUS_REJECTED;
2142*91f16700Schasinglulu 	}
2143*91f16700Schasinglulu 
2144*91f16700Schasinglulu 	memcpy((uint8_t *) &payload[i], (uint8_t *) pubkey, src_size);
2145*91f16700Schasinglulu 	i += src_size / MBOX_WORD_BYTE;
2146*91f16700Schasinglulu 
2147*91f16700Schasinglulu 	status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_ECDH_REQUEST,
2148*91f16700Schasinglulu 			payload, i, CMD_CASUAL, (uint32_t *) dst_addr,
2149*91f16700Schasinglulu 			&resp_len);
2150*91f16700Schasinglulu 
2151*91f16700Schasinglulu 	memset((void *)&fcs_ecdh_request_param, 0,
2152*91f16700Schasinglulu 			sizeof(fcs_crypto_service_data));
2153*91f16700Schasinglulu 
2154*91f16700Schasinglulu 	if (status < 0) {
2155*91f16700Schasinglulu 		*mbox_error = -status;
2156*91f16700Schasinglulu 		return INTEL_SIP_SMC_STATUS_ERROR;
2157*91f16700Schasinglulu 	}
2158*91f16700Schasinglulu 
2159*91f16700Schasinglulu 	*dst_size = resp_len * MBOX_WORD_BYTE;
2160*91f16700Schasinglulu 	flush_dcache_range(dst_addr, *dst_size);
2161*91f16700Schasinglulu 
2162*91f16700Schasinglulu 	return INTEL_SIP_SMC_STATUS_OK;
2163*91f16700Schasinglulu }
2164*91f16700Schasinglulu 
2165*91f16700Schasinglulu int intel_fcs_aes_crypt_init(uint32_t session_id, uint32_t context_id,
2166*91f16700Schasinglulu 				uint32_t key_id, uint64_t param_addr,
2167*91f16700Schasinglulu 				uint32_t param_size, uint32_t *mbox_error)
2168*91f16700Schasinglulu {
2169*91f16700Schasinglulu 	/* ptr to get param_addr value */
2170*91f16700Schasinglulu 	uint64_t *param_addr_ptr;
2171*91f16700Schasinglulu 
2172*91f16700Schasinglulu 	param_addr_ptr = (uint64_t *) param_addr;
2173*91f16700Schasinglulu 
2174*91f16700Schasinglulu 	/*
2175*91f16700Schasinglulu 	 * Since crypto param size vary between mode.
2176*91f16700Schasinglulu 	 * Check ECB here and limit to size 12 bytes
2177*91f16700Schasinglulu 	 */
2178*91f16700Schasinglulu 	if (((*param_addr_ptr & FCS_CRYPTO_BLOCK_MODE_MASK) == FCS_CRYPTO_ECB_MODE) &&
2179*91f16700Schasinglulu 		(param_size > FCS_CRYPTO_ECB_BUFFER_SIZE)) {
2180*91f16700Schasinglulu 		return INTEL_SIP_SMC_STATUS_REJECTED;
2181*91f16700Schasinglulu 	}
2182*91f16700Schasinglulu 	/*
2183*91f16700Schasinglulu 	 * Since crypto param size vary between mode.
2184*91f16700Schasinglulu 	 * Check CBC/CTR here and limit to size 28 bytes
2185*91f16700Schasinglulu 	 */
2186*91f16700Schasinglulu 	if ((((*param_addr_ptr & FCS_CRYPTO_BLOCK_MODE_MASK) == FCS_CRYPTO_CBC_MODE) ||
2187*91f16700Schasinglulu 		((*param_addr_ptr & FCS_CRYPTO_BLOCK_MODE_MASK) == FCS_CRYPTO_CTR_MODE)) &&
2188*91f16700Schasinglulu 		(param_size > FCS_CRYPTO_CBC_CTR_BUFFER_SIZE)) {
2189*91f16700Schasinglulu 		return INTEL_SIP_SMC_STATUS_REJECTED;
2190*91f16700Schasinglulu 	}
2191*91f16700Schasinglulu 
2192*91f16700Schasinglulu 	if (mbox_error == NULL) {
2193*91f16700Schasinglulu 		return INTEL_SIP_SMC_STATUS_REJECTED;
2194*91f16700Schasinglulu 	}
2195*91f16700Schasinglulu 
2196*91f16700Schasinglulu 	memset((void *)&fcs_aes_init_payload, 0U, sizeof(fcs_aes_init_payload));
2197*91f16700Schasinglulu 
2198*91f16700Schasinglulu 	fcs_aes_init_payload.session_id = session_id;
2199*91f16700Schasinglulu 	fcs_aes_init_payload.context_id = context_id;
2200*91f16700Schasinglulu 	fcs_aes_init_payload.param_size = param_size;
2201*91f16700Schasinglulu 	fcs_aes_init_payload.key_id	= key_id;
2202*91f16700Schasinglulu 
2203*91f16700Schasinglulu 	memcpy((uint8_t *) fcs_aes_init_payload.crypto_param,
2204*91f16700Schasinglulu 		(uint8_t *) param_addr, param_size);
2205*91f16700Schasinglulu 
2206*91f16700Schasinglulu 	fcs_aes_init_payload.is_updated = 0;
2207*91f16700Schasinglulu 
2208*91f16700Schasinglulu 	*mbox_error = 0;
2209*91f16700Schasinglulu 
2210*91f16700Schasinglulu 	return INTEL_SIP_SMC_STATUS_OK;
2211*91f16700Schasinglulu }
2212*91f16700Schasinglulu 
2213*91f16700Schasinglulu int intel_fcs_aes_crypt_update_finalize(uint32_t session_id,
2214*91f16700Schasinglulu 				uint32_t context_id, uint64_t src_addr,
2215*91f16700Schasinglulu 				uint32_t src_size, uint64_t dst_addr,
2216*91f16700Schasinglulu 				uint32_t dst_size, uint8_t is_finalised,
2217*91f16700Schasinglulu 				uint32_t *send_id)
2218*91f16700Schasinglulu {
2219*91f16700Schasinglulu 	int status;
2220*91f16700Schasinglulu 	int i;
2221*91f16700Schasinglulu 	uint32_t flag;
2222*91f16700Schasinglulu 	uint32_t crypto_header;
2223*91f16700Schasinglulu 	uint32_t fcs_aes_crypt_payload[FCS_AES_CMD_MAX_WORD_SIZE];
2224*91f16700Schasinglulu 
2225*91f16700Schasinglulu 	if (fcs_aes_init_payload.session_id != session_id ||
2226*91f16700Schasinglulu 		fcs_aes_init_payload.context_id != context_id) {
2227*91f16700Schasinglulu 		return INTEL_SIP_SMC_STATUS_REJECTED;
2228*91f16700Schasinglulu 	}
2229*91f16700Schasinglulu 
2230*91f16700Schasinglulu 	if ((!is_8_bytes_aligned(src_addr)) ||
2231*91f16700Schasinglulu 		(!is_32_bytes_aligned(src_size)) ||
2232*91f16700Schasinglulu 		(!is_address_in_ddr_range(src_addr, src_size))) {
2233*91f16700Schasinglulu 		return INTEL_SIP_SMC_STATUS_REJECTED;
2234*91f16700Schasinglulu 	}
2235*91f16700Schasinglulu 
2236*91f16700Schasinglulu 	if ((!is_8_bytes_aligned(dst_addr)) ||
2237*91f16700Schasinglulu 		(!is_32_bytes_aligned(dst_size))) {
2238*91f16700Schasinglulu 		return INTEL_SIP_SMC_STATUS_REJECTED;
2239*91f16700Schasinglulu 	}
2240*91f16700Schasinglulu 
2241*91f16700Schasinglulu 	if ((dst_size > FCS_AES_MAX_DATA_SIZE ||
2242*91f16700Schasinglulu 		dst_size < FCS_AES_MIN_DATA_SIZE) ||
2243*91f16700Schasinglulu 		(src_size > FCS_AES_MAX_DATA_SIZE ||
2244*91f16700Schasinglulu 		src_size < FCS_AES_MIN_DATA_SIZE)) {
2245*91f16700Schasinglulu 		return INTEL_SIP_SMC_STATUS_REJECTED;
2246*91f16700Schasinglulu 	}
2247*91f16700Schasinglulu 
2248*91f16700Schasinglulu 	/* Prepare crypto header*/
2249*91f16700Schasinglulu 	flag = 0;
2250*91f16700Schasinglulu 	if (fcs_aes_init_payload.is_updated) {
2251*91f16700Schasinglulu 		fcs_aes_init_payload.param_size = 0;
2252*91f16700Schasinglulu 	} else {
2253*91f16700Schasinglulu 		flag |= FCS_CS_FIELD_FLAG_INIT;
2254*91f16700Schasinglulu 	}
2255*91f16700Schasinglulu 
2256*91f16700Schasinglulu 	if (is_finalised != 0U) {
2257*91f16700Schasinglulu 		flag |= FCS_CS_FIELD_FLAG_FINALIZE;
2258*91f16700Schasinglulu 	} else {
2259*91f16700Schasinglulu 		flag |= FCS_CS_FIELD_FLAG_UPDATE;
2260*91f16700Schasinglulu 		fcs_aes_init_payload.is_updated = 1;
2261*91f16700Schasinglulu 	}
2262*91f16700Schasinglulu 	crypto_header = (flag << FCS_CS_FIELD_FLAG_OFFSET) |
2263*91f16700Schasinglulu 			fcs_aes_init_payload.param_size;
2264*91f16700Schasinglulu 
2265*91f16700Schasinglulu 	i = 0U;
2266*91f16700Schasinglulu 	fcs_aes_crypt_payload[i] = session_id;
2267*91f16700Schasinglulu 	i++;
2268*91f16700Schasinglulu 	fcs_aes_crypt_payload[i] = context_id;
2269*91f16700Schasinglulu 	i++;
2270*91f16700Schasinglulu 	fcs_aes_crypt_payload[i] = crypto_header;
2271*91f16700Schasinglulu 	i++;
2272*91f16700Schasinglulu 
2273*91f16700Schasinglulu 	if ((crypto_header >> FCS_CS_FIELD_FLAG_OFFSET) &
2274*91f16700Schasinglulu 		FCS_CS_FIELD_FLAG_INIT) {
2275*91f16700Schasinglulu 		fcs_aes_crypt_payload[i] = fcs_aes_init_payload.key_id;
2276*91f16700Schasinglulu 		i++;
2277*91f16700Schasinglulu 
2278*91f16700Schasinglulu 		if ((i + ((fcs_aes_init_payload.param_size) / MBOX_WORD_BYTE)) >
2279*91f16700Schasinglulu 			FCS_AES_CMD_MAX_WORD_SIZE) {
2280*91f16700Schasinglulu 			return INTEL_SIP_SMC_STATUS_REJECTED;
2281*91f16700Schasinglulu 		}
2282*91f16700Schasinglulu 
2283*91f16700Schasinglulu 		memcpy((uint8_t *) &fcs_aes_crypt_payload[i],
2284*91f16700Schasinglulu 			(uint8_t *) fcs_aes_init_payload.crypto_param,
2285*91f16700Schasinglulu 			fcs_aes_init_payload.param_size);
2286*91f16700Schasinglulu 
2287*91f16700Schasinglulu 		i += fcs_aes_init_payload.param_size / MBOX_WORD_BYTE;
2288*91f16700Schasinglulu 	}
2289*91f16700Schasinglulu 
2290*91f16700Schasinglulu 	fcs_aes_crypt_payload[i] = (uint32_t) src_addr;
2291*91f16700Schasinglulu 	i++;
2292*91f16700Schasinglulu 	fcs_aes_crypt_payload[i] = src_size;
2293*91f16700Schasinglulu 	i++;
2294*91f16700Schasinglulu 	fcs_aes_crypt_payload[i] = (uint32_t) dst_addr;
2295*91f16700Schasinglulu 	i++;
2296*91f16700Schasinglulu 	fcs_aes_crypt_payload[i] = dst_size;
2297*91f16700Schasinglulu 	i++;
2298*91f16700Schasinglulu 
2299*91f16700Schasinglulu 	status = mailbox_send_cmd_async(send_id, MBOX_FCS_AES_CRYPT_REQ,
2300*91f16700Schasinglulu 					fcs_aes_crypt_payload, i,
2301*91f16700Schasinglulu 					CMD_INDIRECT);
2302*91f16700Schasinglulu 
2303*91f16700Schasinglulu 	if (is_finalised != 0U) {
2304*91f16700Schasinglulu 		memset((void *)&fcs_aes_init_payload, 0,
2305*91f16700Schasinglulu 			sizeof(fcs_aes_init_payload));
2306*91f16700Schasinglulu 	}
2307*91f16700Schasinglulu 
2308*91f16700Schasinglulu 	if (status < 0U) {
2309*91f16700Schasinglulu 		return INTEL_SIP_SMC_STATUS_ERROR;
2310*91f16700Schasinglulu 	}
2311*91f16700Schasinglulu 
2312*91f16700Schasinglulu 	return INTEL_SIP_SMC_STATUS_OK;
2313*91f16700Schasinglulu }
2314