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