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