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 	fcs_encrypt_payload payload = {
251 		FCS_ENCRYPTION_DATA_0,
252 		src_addr,
253 		src_size,
254 		dst_addr,
255 		dst_size };
256 	load_size = sizeof(payload) / MBOX_WORD_BYTE;
257 
258 	if (!is_address_in_ddr_range(src_addr, src_size) ||
259 		!is_address_in_ddr_range(dst_addr, dst_size)) {
260 		return INTEL_SIP_SMC_STATUS_REJECTED;
261 	}
262 
263 	if (!is_size_4_bytes_aligned(src_size)) {
264 		return INTEL_SIP_SMC_STATUS_REJECTED;
265 	}
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 	id_offset = src_addr + FCS_OWNER_ID_OFFSET;
287 	fcs_decrypt_payload payload = {
288 		FCS_DECRYPTION_DATA_0,
289 		{mmio_read_32(id_offset),
290 		mmio_read_32(id_offset + MBOX_WORD_BYTE)},
291 		src_addr,
292 		src_size,
293 		dst_addr,
294 		dst_size };
295 	load_size = sizeof(payload) / MBOX_WORD_BYTE;
296 
297 	if (!is_address_in_ddr_range(src_addr, src_size) ||
298 		!is_address_in_ddr_range(dst_addr, dst_size)) {
299 		return INTEL_SIP_SMC_STATUS_REJECTED;
300 	}
301 
302 	if (!is_size_4_bytes_aligned(src_size)) {
303 		return INTEL_SIP_SMC_STATUS_REJECTED;
304 	}
305 
306 	status = mailbox_send_cmd_async(send_id, MBOX_FCS_DECRYPT_REQ,
307 				(uint32_t *) &payload, load_size,
308 				CMD_INDIRECT);
309 	inv_dcache_range(dst_addr, dst_size);
310 
311 	if (status < 0) {
312 		return INTEL_SIP_SMC_STATUS_REJECTED;
313 	}
314 
315 	return INTEL_SIP_SMC_STATUS_OK;
316 }
317 
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)318 int intel_fcs_encryption_ext(uint32_t session_id, uint32_t context_id,
319 		uint32_t src_addr, uint32_t src_size,
320 		uint32_t dst_addr, uint32_t *dst_size, uint32_t *mbox_error)
321 {
322 	int status;
323 	uint32_t payload_size;
324 	uint32_t resp_len = FCS_CRYPTION_RESP_WORD_SIZE;
325 	uint32_t resp_data[FCS_CRYPTION_RESP_WORD_SIZE] = {0U};
326 
327 	if ((dst_size == NULL) || (mbox_error == NULL)) {
328 		return INTEL_SIP_SMC_STATUS_REJECTED;
329 	}
330 
331 	if (!is_address_in_ddr_range(src_addr, src_size) ||
332 		!is_address_in_ddr_range(dst_addr, *dst_size)) {
333 		return INTEL_SIP_SMC_STATUS_REJECTED;
334 	}
335 
336 	if (!is_size_4_bytes_aligned(src_size)) {
337 		return INTEL_SIP_SMC_STATUS_REJECTED;
338 	}
339 
340 	fcs_encrypt_ext_payload payload = {
341 		session_id,
342 		context_id,
343 		FCS_CRYPTION_CRYPTO_HEADER,
344 		src_addr,
345 		src_size,
346 		dst_addr,
347 		*dst_size
348 	};
349 
350 	payload_size = sizeof(payload) / MBOX_WORD_BYTE;
351 
352 	status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_ENCRYPT_REQ,
353 				(uint32_t *) &payload, payload_size,
354 				CMD_CASUAL, resp_data, &resp_len);
355 
356 	if (status < 0) {
357 		*mbox_error = -status;
358 		return INTEL_SIP_SMC_STATUS_ERROR;
359 	}
360 
361 	if (resp_len != FCS_CRYPTION_RESP_WORD_SIZE) {
362 		*mbox_error = MBOX_RET_ERROR;
363 		return INTEL_SIP_SMC_STATUS_ERROR;
364 	}
365 
366 	*dst_size = resp_data[FCS_CRYPTION_RESP_SIZE_OFFSET];
367 	inv_dcache_range(dst_addr, *dst_size);
368 
369 	return INTEL_SIP_SMC_STATUS_OK;
370 }
371 
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)372 int intel_fcs_decryption_ext(uint32_t session_id, uint32_t context_id,
373 		uint32_t src_addr, uint32_t src_size,
374 		uint32_t dst_addr, uint32_t *dst_size, uint32_t *mbox_error)
375 {
376 	int status;
377 	uintptr_t id_offset;
378 	uint32_t payload_size;
379 	uint32_t resp_len = FCS_CRYPTION_RESP_WORD_SIZE;
380 	uint32_t resp_data[FCS_CRYPTION_RESP_WORD_SIZE] = {0U};
381 
382 	if ((dst_size == NULL) || (mbox_error == NULL)) {
383 		return INTEL_SIP_SMC_STATUS_REJECTED;
384 	}
385 
386 	if (!is_address_in_ddr_range(src_addr, src_size) ||
387 		!is_address_in_ddr_range(dst_addr, *dst_size)) {
388 		return INTEL_SIP_SMC_STATUS_REJECTED;
389 	}
390 
391 	if (!is_size_4_bytes_aligned(src_size)) {
392 		return INTEL_SIP_SMC_STATUS_REJECTED;
393 	}
394 
395 	id_offset = src_addr + FCS_OWNER_ID_OFFSET;
396 	fcs_decrypt_ext_payload payload = {
397 		session_id,
398 		context_id,
399 		FCS_CRYPTION_CRYPTO_HEADER,
400 		{mmio_read_32(id_offset),
401 		mmio_read_32(id_offset + MBOX_WORD_BYTE)},
402 		src_addr,
403 		src_size,
404 		dst_addr,
405 		*dst_size
406 	};
407 
408 	payload_size = sizeof(payload) / MBOX_WORD_BYTE;
409 
410 	status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_DECRYPT_REQ,
411 				(uint32_t *) &payload, payload_size,
412 				CMD_CASUAL, resp_data, &resp_len);
413 
414 	if (status < 0) {
415 		*mbox_error = -status;
416 		return INTEL_SIP_SMC_STATUS_ERROR;
417 	}
418 
419 	if (resp_len != FCS_CRYPTION_RESP_WORD_SIZE) {
420 		*mbox_error = MBOX_RET_ERROR;
421 		return INTEL_SIP_SMC_STATUS_ERROR;
422 	}
423 
424 	*dst_size = resp_data[FCS_CRYPTION_RESP_SIZE_OFFSET];
425 	inv_dcache_range(dst_addr, *dst_size);
426 
427 	return INTEL_SIP_SMC_STATUS_OK;
428 }
429 
intel_fcs_sigma_teardown(uint32_t session_id,uint32_t * mbox_error)430 int intel_fcs_sigma_teardown(uint32_t session_id, uint32_t *mbox_error)
431 {
432 	int status;
433 
434 	if ((session_id != PSGSIGMA_SESSION_ID_ONE) &&
435 		(session_id != PSGSIGMA_UNKNOWN_SESSION)) {
436 		return INTEL_SIP_SMC_STATUS_REJECTED;
437 	}
438 
439 	psgsigma_teardown_msg message = {
440 		RESERVED_AS_ZERO,
441 		PSGSIGMA_TEARDOWN_MAGIC,
442 		session_id
443 	};
444 
445 	status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_PSG_SIGMA_TEARDOWN,
446 			(uint32_t *) &message, sizeof(message) / MBOX_WORD_BYTE,
447 			CMD_CASUAL, NULL, NULL);
448 
449 	if (status < 0) {
450 		*mbox_error = -status;
451 		return INTEL_SIP_SMC_STATUS_ERROR;
452 	}
453 
454 	return INTEL_SIP_SMC_STATUS_OK;
455 }
456 
intel_fcs_chip_id(uint32_t * id_low,uint32_t * id_high,uint32_t * mbox_error)457 int intel_fcs_chip_id(uint32_t *id_low, uint32_t *id_high, uint32_t *mbox_error)
458 {
459 	int status;
460 	uint32_t load_size;
461 	uint32_t chip_id[2];
462 
463 	load_size = sizeof(chip_id) / MBOX_WORD_BYTE;
464 
465 	status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_CMD_GET_CHIPID, NULL,
466 			0U, CMD_CASUAL, (uint32_t *) chip_id, &load_size);
467 
468 	if (status < 0) {
469 		*mbox_error = -status;
470 		return INTEL_SIP_SMC_STATUS_ERROR;
471 	}
472 
473 	*id_low = chip_id[0];
474 	*id_high = chip_id[1];
475 
476 	return INTEL_SIP_SMC_STATUS_OK;
477 }
478 
intel_fcs_attestation_subkey(uint64_t src_addr,uint32_t src_size,uint64_t dst_addr,uint32_t * dst_size,uint32_t * mbox_error)479 int intel_fcs_attestation_subkey(uint64_t src_addr, uint32_t src_size,
480 		uint64_t dst_addr, uint32_t *dst_size, uint32_t *mbox_error)
481 {
482 	int status;
483 	uint32_t send_size = src_size / MBOX_WORD_BYTE;
484 	uint32_t ret_size = *dst_size / MBOX_WORD_BYTE;
485 
486 
487 	if (!is_address_in_ddr_range(src_addr, src_size) ||
488 		!is_address_in_ddr_range(dst_addr, *dst_size)) {
489 		return INTEL_SIP_SMC_STATUS_REJECTED;
490 	}
491 
492 	status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_ATTESTATION_SUBKEY,
493 			(uint32_t *) src_addr, send_size, CMD_CASUAL,
494 			(uint32_t *) dst_addr, &ret_size);
495 
496 	if (status < 0) {
497 		*mbox_error = -status;
498 		return INTEL_SIP_SMC_STATUS_ERROR;
499 	}
500 
501 	*dst_size = ret_size * MBOX_WORD_BYTE;
502 	flush_dcache_range(dst_addr, *dst_size);
503 
504 	return INTEL_SIP_SMC_STATUS_OK;
505 }
506 
intel_fcs_get_measurement(uint64_t src_addr,uint32_t src_size,uint64_t dst_addr,uint32_t * dst_size,uint32_t * mbox_error)507 int intel_fcs_get_measurement(uint64_t src_addr, uint32_t src_size,
508 		uint64_t dst_addr, uint32_t *dst_size, uint32_t *mbox_error)
509 {
510 	int status;
511 	uint32_t send_size = src_size / MBOX_WORD_BYTE;
512 	uint32_t ret_size = *dst_size / MBOX_WORD_BYTE;
513 
514 	if (!is_address_in_ddr_range(src_addr, src_size) ||
515 		!is_address_in_ddr_range(dst_addr, *dst_size)) {
516 		return INTEL_SIP_SMC_STATUS_REJECTED;
517 	}
518 
519 	status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_GET_MEASUREMENT,
520 			(uint32_t *) src_addr, send_size, CMD_CASUAL,
521 			(uint32_t *) dst_addr, &ret_size);
522 
523 	if (status < 0) {
524 		*mbox_error = -status;
525 		return INTEL_SIP_SMC_STATUS_ERROR;
526 	}
527 
528 	*dst_size = ret_size * MBOX_WORD_BYTE;
529 	flush_dcache_range(dst_addr, *dst_size);
530 
531 	return INTEL_SIP_SMC_STATUS_OK;
532 }
533 
intel_fcs_get_rom_patch_sha384(uint64_t addr,uint64_t * ret_size,uint32_t * mbox_error)534 uint32_t intel_fcs_get_rom_patch_sha384(uint64_t addr, uint64_t *ret_size,
535 					uint32_t *mbox_error)
536 {
537 	int status;
538 	unsigned int resp_len = FCS_SHA384_WORD_SIZE;
539 
540 	if (!is_address_in_ddr_range(addr, FCS_SHA384_BYTE_SIZE)) {
541 		return INTEL_SIP_SMC_STATUS_REJECTED;
542 	}
543 
544 	status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_GET_ROM_PATCH_SHA384, NULL, 0U,
545 			CMD_CASUAL, (uint32_t *) addr, &resp_len);
546 
547 	if (status < 0) {
548 		*mbox_error = -status;
549 		return INTEL_SIP_SMC_STATUS_ERROR;
550 	}
551 
552 	if (resp_len != FCS_SHA384_WORD_SIZE) {
553 		*mbox_error = GENERIC_RESPONSE_ERROR;
554 		return INTEL_SIP_SMC_STATUS_ERROR;
555 	}
556 
557 	*ret_size = FCS_SHA384_BYTE_SIZE;
558 
559 	flush_dcache_range(addr, *ret_size);
560 
561 	return INTEL_SIP_SMC_STATUS_OK;
562 }
563 
intel_fcs_get_attestation_cert(uint32_t cert_request,uint64_t dst_addr,uint32_t * dst_size,uint32_t * mbox_error)564 int intel_fcs_get_attestation_cert(uint32_t cert_request, uint64_t dst_addr,
565 			uint32_t *dst_size, uint32_t *mbox_error)
566 {
567 	int status;
568 	uint32_t ret_size = *dst_size / MBOX_WORD_BYTE;
569 
570 	if (mbox_error == NULL) {
571 		return INTEL_SIP_SMC_STATUS_REJECTED;
572 	}
573 
574 	if (cert_request < FCS_ATTEST_FIRMWARE_CERT ||
575 		cert_request > FCS_ATTEST_CERT_MAX_REQ_PARAM) {
576 		return INTEL_SIP_SMC_STATUS_REJECTED;
577 	}
578 
579 	if (!is_address_in_ddr_range(dst_addr, *dst_size)) {
580 		return INTEL_SIP_SMC_STATUS_REJECTED;
581 	}
582 
583 	status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_GET_ATTESTATION_CERT,
584 			(uint32_t *) &cert_request, 1U, CMD_CASUAL,
585 			(uint32_t *) dst_addr, &ret_size);
586 
587 	if (status < 0) {
588 		*mbox_error = -status;
589 		return INTEL_SIP_SMC_STATUS_ERROR;
590 	}
591 
592 	*dst_size = ret_size * MBOX_WORD_BYTE;
593 	flush_dcache_range(dst_addr, *dst_size);
594 
595 	return INTEL_SIP_SMC_STATUS_OK;
596 }
597 
intel_fcs_create_cert_on_reload(uint32_t cert_request,uint32_t * mbox_error)598 int intel_fcs_create_cert_on_reload(uint32_t cert_request,
599 			uint32_t *mbox_error)
600 {
601 	int status;
602 
603 	if (mbox_error == NULL) {
604 		return INTEL_SIP_SMC_STATUS_REJECTED;
605 	}
606 
607 	if (cert_request < FCS_ATTEST_FIRMWARE_CERT ||
608 		cert_request > FCS_ATTEST_CERT_MAX_REQ_PARAM) {
609 		return INTEL_SIP_SMC_STATUS_REJECTED;
610 	}
611 
612 	status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_CREATE_CERT_ON_RELOAD,
613 			(uint32_t *) &cert_request, 1U, CMD_CASUAL,
614 			NULL, NULL);
615 
616 	if (status < 0) {
617 		*mbox_error = -status;
618 		return INTEL_SIP_SMC_STATUS_ERROR;
619 	}
620 
621 	return INTEL_SIP_SMC_STATUS_OK;
622 }
623 
intel_fcs_open_crypto_service_session(uint32_t * session_id,uint32_t * mbox_error)624 int intel_fcs_open_crypto_service_session(uint32_t *session_id,
625 			uint32_t *mbox_error)
626 {
627 	int status;
628 	uint32_t resp_len = 1U;
629 
630 	if ((session_id == NULL) || (mbox_error == NULL)) {
631 		return INTEL_SIP_SMC_STATUS_REJECTED;
632 	}
633 
634 	status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_OPEN_CS_SESSION,
635 			NULL, 0U, CMD_CASUAL, session_id, &resp_len);
636 
637 	if (status < 0) {
638 		*mbox_error = -status;
639 		return INTEL_SIP_SMC_STATUS_ERROR;
640 	}
641 
642 	return INTEL_SIP_SMC_STATUS_OK;
643 }
644 
intel_fcs_close_crypto_service_session(uint32_t session_id,uint32_t * mbox_error)645 int intel_fcs_close_crypto_service_session(uint32_t session_id,
646 			uint32_t *mbox_error)
647 {
648 	int status;
649 
650 	if (mbox_error == NULL) {
651 		return INTEL_SIP_SMC_STATUS_REJECTED;
652 	}
653 
654 	status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_CLOSE_CS_SESSION,
655 			&session_id, 1U, CMD_CASUAL, NULL, NULL);
656 
657 	if (status < 0) {
658 		*mbox_error = -status;
659 		return INTEL_SIP_SMC_STATUS_ERROR;
660 	}
661 
662 	return INTEL_SIP_SMC_STATUS_OK;
663 }
664 
intel_fcs_import_crypto_service_key(uint64_t src_addr,uint32_t src_size,uint32_t * send_id)665 int intel_fcs_import_crypto_service_key(uint64_t src_addr, uint32_t src_size,
666 		uint32_t *send_id)
667 {
668 	int status;
669 
670 	if (src_size > (FCS_CS_KEY_OBJ_MAX_WORD_SIZE *
671 		MBOX_WORD_BYTE)) {
672 		return INTEL_SIP_SMC_STATUS_REJECTED;
673 	}
674 
675 	if (!is_address_in_ddr_range(src_addr, src_size)) {
676 		return INTEL_SIP_SMC_STATUS_REJECTED;
677 	}
678 
679 	status = mailbox_send_cmd_async(send_id, MBOX_FCS_IMPORT_CS_KEY,
680 				(uint32_t *)src_addr, src_size / MBOX_WORD_BYTE,
681 				CMD_INDIRECT);
682 
683 	if (status < 0) {
684 		return INTEL_SIP_SMC_STATUS_ERROR;
685 	}
686 
687 	return INTEL_SIP_SMC_STATUS_OK;
688 }
689 
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)690 int intel_fcs_export_crypto_service_key(uint32_t session_id, uint32_t key_id,
691 		uint64_t dst_addr, uint32_t *dst_size,
692 		uint32_t *mbox_error)
693 {
694 	int status;
695 	uint32_t i;
696 	uint32_t payload_size;
697 	uint32_t resp_len = FCS_CS_KEY_OBJ_MAX_WORD_SIZE;
698 	uint32_t resp_data[FCS_CS_KEY_OBJ_MAX_WORD_SIZE] = {0U};
699 	uint32_t op_status = 0U;
700 
701 	if ((dst_size == NULL) || (mbox_error == NULL)) {
702 		return INTEL_SIP_SMC_STATUS_REJECTED;
703 	}
704 
705 	if (!is_address_in_ddr_range(dst_addr, *dst_size)) {
706 		return INTEL_SIP_SMC_STATUS_REJECTED;
707 	}
708 
709 	fcs_cs_key_payload payload = {
710 		session_id,
711 		RESERVED_AS_ZERO,
712 		RESERVED_AS_ZERO,
713 		key_id
714 	};
715 
716 	payload_size = sizeof(payload) / MBOX_WORD_BYTE;
717 
718 	status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_EXPORT_CS_KEY,
719 			(uint32_t *) &payload, payload_size,
720 			CMD_CASUAL, resp_data, &resp_len);
721 
722 	if (resp_len > 0) {
723 		op_status = resp_data[0] & FCS_CS_KEY_RESP_STATUS_MASK;
724 	}
725 
726 	if (status < 0) {
727 		*mbox_error = (-status) | (op_status << FCS_CS_KEY_RESP_STATUS_OFFSET);
728 		return INTEL_SIP_SMC_STATUS_ERROR;
729 	}
730 
731 	if (resp_len > 1) {
732 
733 		/* Export key object is start at second response data */
734 		*dst_size = (resp_len - 1) * MBOX_WORD_BYTE;
735 
736 		for (i = 1U; i < resp_len; i++) {
737 			mmio_write_32(dst_addr, resp_data[i]);
738 			dst_addr += MBOX_WORD_BYTE;
739 		}
740 
741 		flush_dcache_range(dst_addr - *dst_size, *dst_size);
742 
743 	} else {
744 
745 		/* Unexpected response, missing key object in response */
746 		*mbox_error = MBOX_RET_ERROR;
747 		return INTEL_SIP_SMC_STATUS_ERROR;
748 	}
749 
750 	return INTEL_SIP_SMC_STATUS_OK;
751 }
752 
intel_fcs_remove_crypto_service_key(uint32_t session_id,uint32_t key_id,uint32_t * mbox_error)753 int intel_fcs_remove_crypto_service_key(uint32_t session_id, uint32_t key_id,
754 		uint32_t *mbox_error)
755 {
756 	int status;
757 	uint32_t payload_size;
758 	uint32_t resp_len = 1U;
759 	uint32_t resp_data = 0U;
760 	uint32_t op_status = 0U;
761 
762 	if (mbox_error == NULL) {
763 		return INTEL_SIP_SMC_STATUS_REJECTED;
764 	}
765 
766 	fcs_cs_key_payload payload = {
767 		session_id,
768 		RESERVED_AS_ZERO,
769 		RESERVED_AS_ZERO,
770 		key_id
771 	};
772 
773 	payload_size = sizeof(payload) / MBOX_WORD_BYTE;
774 
775 	status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_REMOVE_CS_KEY,
776 			(uint32_t *) &payload, payload_size,
777 			CMD_CASUAL, &resp_data, &resp_len);
778 
779 	if (resp_len > 0) {
780 		op_status = resp_data & FCS_CS_KEY_RESP_STATUS_MASK;
781 	}
782 
783 	if (status < 0) {
784 		*mbox_error = (-status) | (op_status << FCS_CS_KEY_RESP_STATUS_OFFSET);
785 		return INTEL_SIP_SMC_STATUS_ERROR;
786 	}
787 
788 	return INTEL_SIP_SMC_STATUS_OK;
789 }
790 
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)791 int intel_fcs_get_crypto_service_key_info(uint32_t session_id, uint32_t key_id,
792 		uint64_t dst_addr, uint32_t *dst_size,
793 		uint32_t *mbox_error)
794 {
795 	int status;
796 	uint32_t payload_size;
797 	uint32_t resp_len = FCS_CS_KEY_INFO_MAX_WORD_SIZE;
798 	uint32_t op_status = 0U;
799 
800 	if ((dst_size == NULL) || (mbox_error == NULL)) {
801 		return INTEL_SIP_SMC_STATUS_REJECTED;
802 	}
803 
804 	if (!is_address_in_ddr_range(dst_addr, *dst_size)) {
805 		return INTEL_SIP_SMC_STATUS_REJECTED;
806 	}
807 
808 	fcs_cs_key_payload payload = {
809 		session_id,
810 		RESERVED_AS_ZERO,
811 		RESERVED_AS_ZERO,
812 		key_id
813 	};
814 
815 	payload_size = sizeof(payload) / MBOX_WORD_BYTE;
816 
817 	status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_GET_CS_KEY_INFO,
818 				(uint32_t *) &payload, payload_size,
819 				CMD_CASUAL, (uint32_t *) dst_addr, &resp_len);
820 
821 	if (resp_len > 0) {
822 		op_status = mmio_read_32(dst_addr) &
823 			FCS_CS_KEY_RESP_STATUS_MASK;
824 	}
825 
826 	if (status < 0) {
827 		*mbox_error = (-status) | (op_status << FCS_CS_KEY_RESP_STATUS_OFFSET);
828 		return INTEL_SIP_SMC_STATUS_ERROR;
829 	}
830 
831 	*dst_size = resp_len * MBOX_WORD_BYTE;
832 	flush_dcache_range(dst_addr, *dst_size);
833 
834 	return INTEL_SIP_SMC_STATUS_OK;
835 }
836 
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)837 int intel_fcs_get_digest_init(uint32_t session_id, uint32_t context_id,
838 				uint32_t key_id, uint32_t param_size,
839 				uint64_t param_data, uint32_t *mbox_error)
840 {
841 	return intel_fcs_crypto_service_init(session_id, context_id,
842 				key_id, param_size, param_data,
843 				(void *) &fcs_sha_get_digest_param,
844 				mbox_error);
845 }
846 
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)847 int intel_fcs_get_digest_update_finalize(uint32_t session_id,
848 				uint32_t context_id, uint32_t src_addr,
849 				uint32_t src_size, uint64_t dst_addr,
850 				uint32_t *dst_size, uint8_t is_finalised,
851 				uint32_t *mbox_error)
852 {
853 	int status;
854 	uint32_t i;
855 	uint32_t flag;
856 	uint32_t crypto_header;
857 	uint32_t resp_len;
858 	uint32_t payload[FCS_GET_DIGEST_CMD_MAX_WORD_SIZE] = {0U};
859 
860 	if (dst_size == NULL || mbox_error == NULL) {
861 		return INTEL_SIP_SMC_STATUS_REJECTED;
862 	}
863 
864 	if (fcs_sha_get_digest_param.session_id != session_id ||
865 	    fcs_sha_get_digest_param.context_id != context_id) {
866 		return INTEL_SIP_SMC_STATUS_REJECTED;
867 	}
868 
869 	/* Source data must be 8 bytes aligned */
870 	if (!is_8_bytes_aligned(src_size)) {
871 		return INTEL_SIP_SMC_STATUS_REJECTED;
872 	}
873 
874 	if (!is_address_in_ddr_range(src_addr, src_size) ||
875 		 !is_address_in_ddr_range(dst_addr, *dst_size)) {
876 		return INTEL_SIP_SMC_STATUS_REJECTED;
877 	}
878 
879 	resp_len = *dst_size / MBOX_WORD_BYTE;
880 
881 	/* Prepare crypto header */
882 	flag = 0;
883 
884 	if (fcs_sha_get_digest_param.is_updated) {
885 		fcs_sha_get_digest_param.crypto_param_size = 0;
886 	} else {
887 		flag |=  FCS_CS_FIELD_FLAG_INIT;
888 	}
889 
890 	if (is_finalised != 0U) {
891 		flag |=  FCS_CS_FIELD_FLAG_FINALIZE;
892 	} else {
893 		flag |=  FCS_CS_FIELD_FLAG_UPDATE;
894 		fcs_sha_get_digest_param.is_updated = 1;
895 	}
896 
897 	crypto_header = ((flag << FCS_CS_FIELD_FLAG_OFFSET) |
898 			(fcs_sha_get_digest_param.crypto_param_size &
899 			FCS_CS_FIELD_SIZE_MASK));
900 
901 	/* Prepare command payload */
902 	i = 0;
903 	payload[i] = fcs_sha_get_digest_param.session_id;
904 	i++;
905 	payload[i] = fcs_sha_get_digest_param.context_id;
906 	i++;
907 	payload[i] = crypto_header;
908 	i++;
909 
910 	if ((crypto_header >> FCS_CS_FIELD_FLAG_OFFSET) &
911 		FCS_CS_FIELD_FLAG_INIT) {
912 		payload[i] = fcs_sha_get_digest_param.key_id;
913 		i++;
914 		/* Crypto parameters */
915 		payload[i] = fcs_sha_get_digest_param.crypto_param
916 				& INTEL_SIP_SMC_FCS_SHA_MODE_MASK;
917 		payload[i] |= ((fcs_sha_get_digest_param.crypto_param
918 				>> INTEL_SIP_SMC_FCS_DIGEST_SIZE_OFFSET)
919 				& INTEL_SIP_SMC_FCS_DIGEST_SIZE_MASK)
920 				<< FCS_SHA_HMAC_CRYPTO_PARAM_SIZE_OFFSET;
921 		i++;
922 	}
923 	/* Data source address and size */
924 	payload[i] = src_addr;
925 	i++;
926 	payload[i] = src_size;
927 	i++;
928 
929 	status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_GET_DIGEST_REQ,
930 				payload, i, CMD_CASUAL,
931 				(uint32_t *) dst_addr, &resp_len);
932 
933 	if (is_finalised != 0U) {
934 		memset((void *)&fcs_sha_get_digest_param, 0,
935 		sizeof(fcs_crypto_service_data));
936 	}
937 
938 	if (status < 0) {
939 		*mbox_error = -status;
940 		return INTEL_SIP_SMC_STATUS_ERROR;
941 	}
942 
943 	*dst_size = resp_len * MBOX_WORD_BYTE;
944 	flush_dcache_range(dst_addr, *dst_size);
945 
946 	return INTEL_SIP_SMC_STATUS_OK;
947 }
948 
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)949 int intel_fcs_mac_verify_init(uint32_t session_id, uint32_t context_id,
950 				uint32_t key_id, uint32_t param_size,
951 				uint64_t param_data, uint32_t *mbox_error)
952 {
953 	return intel_fcs_crypto_service_init(session_id, context_id,
954 				key_id, param_size, param_data,
955 				(void *) &fcs_sha_mac_verify_param,
956 				mbox_error);
957 }
958 
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)959 int intel_fcs_mac_verify_update_finalize(uint32_t session_id,
960 				uint32_t context_id, uint32_t src_addr,
961 				uint32_t src_size, uint64_t dst_addr,
962 				uint32_t *dst_size, uint32_t data_size,
963 				uint8_t is_finalised, uint32_t *mbox_error)
964 {
965 	int status;
966 	uint32_t i;
967 	uint32_t flag;
968 	uint32_t crypto_header;
969 	uint32_t resp_len;
970 	uint32_t payload[FCS_MAC_VERIFY_CMD_MAX_WORD_SIZE] = {0U};
971 	uintptr_t mac_offset;
972 
973 	if (dst_size == NULL || mbox_error == NULL) {
974 		return INTEL_SIP_SMC_STATUS_REJECTED;
975 	}
976 
977 	if (fcs_sha_mac_verify_param.session_id != session_id ||
978 		fcs_sha_mac_verify_param.context_id != context_id) {
979 		return INTEL_SIP_SMC_STATUS_REJECTED;
980 	}
981 
982 	if (data_size > src_size) {
983 		return INTEL_SIP_SMC_STATUS_REJECTED;
984 	}
985 
986 	if (!is_size_4_bytes_aligned(src_size) ||
987 		!is_8_bytes_aligned(data_size)) {
988 		return INTEL_SIP_SMC_STATUS_REJECTED;
989 	}
990 
991 	if (!is_address_in_ddr_range(src_addr, src_size) ||
992 		!is_address_in_ddr_range(dst_addr, *dst_size)) {
993 		return INTEL_SIP_SMC_STATUS_REJECTED;
994 	}
995 
996 	resp_len = *dst_size / MBOX_WORD_BYTE;
997 
998 	/* Prepare crypto header */
999 	flag = 0;
1000 
1001 	if (fcs_sha_mac_verify_param.is_updated) {
1002 		fcs_sha_mac_verify_param.crypto_param_size = 0;
1003 	} else {
1004 		flag |=  FCS_CS_FIELD_FLAG_INIT;
1005 	}
1006 
1007 	if (is_finalised) {
1008 		flag |=  FCS_CS_FIELD_FLAG_FINALIZE;
1009 	} else {
1010 		flag |=  FCS_CS_FIELD_FLAG_UPDATE;
1011 		fcs_sha_mac_verify_param.is_updated = 1;
1012 	}
1013 
1014 	crypto_header = ((flag << FCS_CS_FIELD_FLAG_OFFSET) |
1015 			(fcs_sha_mac_verify_param.crypto_param_size &
1016 			FCS_CS_FIELD_SIZE_MASK));
1017 
1018 	/* Prepare command payload */
1019 	i = 0;
1020 	payload[i] = fcs_sha_mac_verify_param.session_id;
1021 	i++;
1022 	payload[i] = fcs_sha_mac_verify_param.context_id;
1023 	i++;
1024 	payload[i] = crypto_header;
1025 	i++;
1026 
1027 	if ((crypto_header >> FCS_CS_FIELD_FLAG_OFFSET) &
1028 		FCS_CS_FIELD_FLAG_INIT) {
1029 		payload[i] = fcs_sha_mac_verify_param.key_id;
1030 		i++;
1031 		/* Crypto parameters */
1032 		payload[i] = ((fcs_sha_mac_verify_param.crypto_param
1033 				>> INTEL_SIP_SMC_FCS_DIGEST_SIZE_OFFSET)
1034 				& INTEL_SIP_SMC_FCS_DIGEST_SIZE_MASK)
1035 				<< FCS_SHA_HMAC_CRYPTO_PARAM_SIZE_OFFSET;
1036 		i++;
1037 	}
1038 	/* Data source address and size */
1039 	payload[i] = src_addr;
1040 	i++;
1041 	payload[i] = data_size;
1042 	i++;
1043 
1044 	if ((crypto_header >> FCS_CS_FIELD_FLAG_OFFSET) &
1045 		FCS_CS_FIELD_FLAG_FINALIZE) {
1046 		/* Copy mac data to command */
1047 		mac_offset = src_addr + data_size;
1048 		memcpy((uint8_t *) &payload[i], (uint8_t *) mac_offset,
1049 		src_size - data_size);
1050 
1051 		i += (src_size - data_size) / MBOX_WORD_BYTE;
1052 	}
1053 
1054 	status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_MAC_VERIFY_REQ,
1055 				payload, i, CMD_CASUAL,
1056 				(uint32_t *) dst_addr, &resp_len);
1057 
1058 	if (is_finalised) {
1059 		memset((void *)&fcs_sha_mac_verify_param, 0,
1060 		sizeof(fcs_crypto_service_data));
1061 	}
1062 
1063 	if (status < 0) {
1064 		*mbox_error = -status;
1065 		return INTEL_SIP_SMC_STATUS_ERROR;
1066 	}
1067 
1068 	*dst_size = resp_len * MBOX_WORD_BYTE;
1069 	flush_dcache_range(dst_addr, *dst_size);
1070 
1071 	return INTEL_SIP_SMC_STATUS_OK;
1072 }
1073 
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)1074 int intel_fcs_ecdsa_hash_sign_init(uint32_t session_id, uint32_t context_id,
1075 				uint32_t key_id, uint32_t param_size,
1076 				uint64_t param_data, uint32_t *mbox_error)
1077 {
1078 	return intel_fcs_crypto_service_init(session_id, context_id,
1079 				key_id, param_size, param_data,
1080 				(void *) &fcs_ecdsa_hash_sign_param,
1081 				mbox_error);
1082 }
1083 
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)1084 int intel_fcs_ecdsa_hash_sign_finalize(uint32_t session_id, uint32_t context_id,
1085 				uint32_t src_addr, uint32_t src_size,
1086 				uint64_t dst_addr, uint32_t *dst_size,
1087 				uint32_t *mbox_error)
1088 {
1089 	int status;
1090 	uint32_t i;
1091 	uint32_t payload[FCS_ECDSA_HASH_SIGN_CMD_MAX_WORD_SIZE] = {0U};
1092 	uint32_t resp_len;
1093 	uintptr_t hash_data_addr;
1094 
1095 	if ((dst_size == NULL) || (mbox_error == NULL)) {
1096 		return INTEL_SIP_SMC_STATUS_REJECTED;
1097 	}
1098 
1099 	if (fcs_ecdsa_hash_sign_param.session_id != session_id ||
1100 		fcs_ecdsa_hash_sign_param.context_id != context_id) {
1101 		return INTEL_SIP_SMC_STATUS_REJECTED;
1102 	}
1103 
1104 	if (!is_address_in_ddr_range(src_addr, src_size) ||
1105 		!is_address_in_ddr_range(dst_addr, *dst_size)) {
1106 		return INTEL_SIP_SMC_STATUS_REJECTED;
1107 	}
1108 
1109 	resp_len = *dst_size / MBOX_WORD_BYTE;
1110 
1111 	/* Prepare command payload */
1112 	/* Crypto header */
1113 	i = 0;
1114 	payload[i] = fcs_ecdsa_hash_sign_param.session_id;
1115 	i++;
1116 	payload[i] = fcs_ecdsa_hash_sign_param.context_id;
1117 
1118 	i++;
1119 	payload[i] = fcs_ecdsa_hash_sign_param.crypto_param_size
1120 			& FCS_CS_FIELD_SIZE_MASK;
1121 	payload[i] |= (FCS_CS_FIELD_FLAG_INIT | FCS_CS_FIELD_FLAG_UPDATE
1122 			| FCS_CS_FIELD_FLAG_FINALIZE)
1123 			<< FCS_CS_FIELD_FLAG_OFFSET;
1124 	i++;
1125 	payload[i] = fcs_ecdsa_hash_sign_param.key_id;
1126 
1127 	/* Crypto parameters */
1128 	i++;
1129 	payload[i] = fcs_ecdsa_hash_sign_param.crypto_param
1130 			& INTEL_SIP_SMC_FCS_ECC_ALGO_MASK;
1131 
1132 	/* Hash Data */
1133 	i++;
1134 	hash_data_addr = src_addr;
1135 	memcpy((uint8_t *) &payload[i], (uint8_t *) hash_data_addr,
1136 			src_size);
1137 
1138 	i += src_size / MBOX_WORD_BYTE;
1139 
1140 	status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_ECDSA_HASH_SIGN_REQ,
1141 			payload, i, CMD_CASUAL, (uint32_t *) dst_addr,
1142 			&resp_len);
1143 
1144 	memset((void *) &fcs_ecdsa_hash_sign_param,
1145 			0, sizeof(fcs_crypto_service_data));
1146 
1147 	if (status < 0) {
1148 		*mbox_error = -status;
1149 		return INTEL_SIP_SMC_STATUS_ERROR;
1150 	}
1151 
1152 	*dst_size = resp_len * MBOX_WORD_BYTE;
1153 	flush_dcache_range(dst_addr, *dst_size);
1154 
1155 	return INTEL_SIP_SMC_STATUS_OK;
1156 }
1157 
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)1158 int intel_fcs_ecdsa_hash_sig_verify_init(uint32_t session_id, uint32_t context_id,
1159 				uint32_t key_id, uint32_t param_size,
1160 				uint64_t param_data, uint32_t *mbox_error)
1161 {
1162 	return intel_fcs_crypto_service_init(session_id, context_id,
1163 				key_id, param_size, param_data,
1164 				(void *) &fcs_ecdsa_hash_sig_verify_param,
1165 				mbox_error);
1166 }
1167 
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)1168 int intel_fcs_ecdsa_hash_sig_verify_finalize(uint32_t session_id, uint32_t context_id,
1169 				uint32_t src_addr, uint32_t src_size,
1170 				uint64_t dst_addr, uint32_t *dst_size,
1171 				uint32_t *mbox_error)
1172 {
1173 	int status;
1174 	uint32_t i = 0;
1175 	uint32_t payload[FCS_ECDSA_HASH_SIG_VERIFY_CMD_MAX_WORD_SIZE] = {0U};
1176 	uint32_t resp_len;
1177 	uintptr_t hash_sig_pubkey_addr;
1178 
1179 	if ((dst_size == NULL) || (mbox_error == NULL)) {
1180 		return INTEL_SIP_SMC_STATUS_REJECTED;
1181 	}
1182 
1183 	if (fcs_ecdsa_hash_sig_verify_param.session_id != session_id ||
1184 	fcs_ecdsa_hash_sig_verify_param.context_id != context_id) {
1185 		return INTEL_SIP_SMC_STATUS_REJECTED;
1186 	}
1187 
1188 	if (!is_address_in_ddr_range(src_addr, src_size) ||
1189 		!is_address_in_ddr_range(dst_addr, *dst_size)) {
1190 		return INTEL_SIP_SMC_STATUS_REJECTED;
1191 	}
1192 
1193 	resp_len = *dst_size / MBOX_WORD_BYTE;
1194 
1195 	/* Prepare command payload */
1196 	/* Crypto header */
1197 	i = 0;
1198 	payload[i] = fcs_ecdsa_hash_sig_verify_param.session_id;
1199 
1200 	i++;
1201 	payload[i] = fcs_ecdsa_hash_sig_verify_param.context_id;
1202 
1203 	i++;
1204 	payload[i] = fcs_ecdsa_hash_sig_verify_param.crypto_param_size
1205 			& FCS_CS_FIELD_SIZE_MASK;
1206 	payload[i] |= (FCS_CS_FIELD_FLAG_INIT | FCS_CS_FIELD_FLAG_UPDATE
1207 			| FCS_CS_FIELD_FLAG_FINALIZE)
1208 			<< FCS_CS_FIELD_FLAG_OFFSET;
1209 
1210 	i++;
1211 	payload[i] = fcs_ecdsa_hash_sig_verify_param.key_id;
1212 
1213 	/* Crypto parameters */
1214 	i++;
1215 	payload[i] = fcs_ecdsa_hash_sig_verify_param.crypto_param
1216 			& INTEL_SIP_SMC_FCS_ECC_ALGO_MASK;
1217 
1218 	/* Hash Data Word, Signature Data Word and Public Key Data word */
1219 	i++;
1220 	hash_sig_pubkey_addr = src_addr;
1221 	memcpy((uint8_t *) &payload[i],
1222 			(uint8_t *) hash_sig_pubkey_addr, src_size);
1223 
1224 	i += (src_size / MBOX_WORD_BYTE);
1225 
1226 	status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_ECDSA_HASH_SIG_VERIFY,
1227 			payload, i, CMD_CASUAL, (uint32_t *) dst_addr,
1228 			&resp_len);
1229 
1230 	memset((void *)&fcs_ecdsa_hash_sig_verify_param,
1231 			0, sizeof(fcs_crypto_service_data));
1232 
1233 	if (status < 0) {
1234 		*mbox_error = -status;
1235 		return INTEL_SIP_SMC_STATUS_ERROR;
1236 	}
1237 
1238 	*dst_size = resp_len * MBOX_WORD_BYTE;
1239 	flush_dcache_range(dst_addr, *dst_size);
1240 
1241 	return INTEL_SIP_SMC_STATUS_OK;
1242 }
1243 
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)1244 int intel_fcs_ecdsa_sha2_data_sign_init(uint32_t session_id,
1245 				uint32_t context_id, uint32_t key_id,
1246 				uint32_t param_size, uint64_t param_data,
1247 				uint32_t *mbox_error)
1248 {
1249 	return intel_fcs_crypto_service_init(session_id, context_id,
1250 				key_id, param_size, param_data,
1251 				(void *) &fcs_sha2_data_sign_param,
1252 				mbox_error);
1253 }
1254 
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)1255 int intel_fcs_ecdsa_sha2_data_sign_update_finalize(uint32_t session_id,
1256 				uint32_t context_id, uint32_t src_addr,
1257 				uint32_t src_size, uint64_t dst_addr,
1258 				uint32_t *dst_size, uint8_t is_finalised,
1259 				uint32_t *mbox_error)
1260 {
1261 	int status;
1262 	int i;
1263 	uint32_t flag;
1264 	uint32_t crypto_header;
1265 	uint32_t payload[FCS_ECDSA_SHA2_DATA_SIGN_CMD_MAX_WORD_SIZE] = {0U};
1266 	uint32_t resp_len;
1267 
1268 	if ((dst_size == NULL) || (mbox_error == NULL)) {
1269 		return INTEL_SIP_SMC_STATUS_REJECTED;
1270 	}
1271 
1272 	if (fcs_sha2_data_sign_param.session_id != session_id ||
1273 		fcs_sha2_data_sign_param.context_id != context_id) {
1274 		return INTEL_SIP_SMC_STATUS_REJECTED;
1275 	}
1276 
1277 	/* Source data must be 8 bytes aligned */
1278 	if (!is_8_bytes_aligned(src_size)) {
1279 		return INTEL_SIP_SMC_STATUS_REJECTED;
1280 	}
1281 
1282 	if (!is_address_in_ddr_range(src_addr, src_size) ||
1283 		!is_address_in_ddr_range(dst_addr, *dst_size)) {
1284 		return INTEL_SIP_SMC_STATUS_REJECTED;
1285 	}
1286 
1287 	resp_len = *dst_size / MBOX_WORD_BYTE;
1288 
1289 	/* Prepare crypto header */
1290 	flag = 0;
1291 	if (fcs_sha2_data_sign_param.is_updated) {
1292 		fcs_sha2_data_sign_param.crypto_param_size = 0;
1293 	} else {
1294 		flag |= FCS_CS_FIELD_FLAG_INIT;
1295 	}
1296 
1297 	if (is_finalised != 0U) {
1298 		flag |= FCS_CS_FIELD_FLAG_FINALIZE;
1299 	} else {
1300 		flag |= FCS_CS_FIELD_FLAG_UPDATE;
1301 		fcs_sha2_data_sign_param.is_updated = 1;
1302 	}
1303 	crypto_header = (flag << FCS_CS_FIELD_FLAG_OFFSET) |
1304 			fcs_sha2_data_sign_param.crypto_param_size;
1305 
1306 	/* Prepare command payload */
1307 	i = 0;
1308 	payload[i] = fcs_sha2_data_sign_param.session_id;
1309 	i++;
1310 	payload[i] = fcs_sha2_data_sign_param.context_id;
1311 	i++;
1312 	payload[i] = crypto_header;
1313 	i++;
1314 
1315 	if ((crypto_header >> FCS_CS_FIELD_FLAG_OFFSET) &
1316 		FCS_CS_FIELD_FLAG_INIT) {
1317 		payload[i] = fcs_sha2_data_sign_param.key_id;
1318 		/* Crypto parameters */
1319 		i++;
1320 		payload[i] = fcs_sha2_data_sign_param.crypto_param
1321 				& INTEL_SIP_SMC_FCS_ECC_ALGO_MASK;
1322 		i++;
1323 	}
1324 
1325 	/* Data source address and size */
1326 	payload[i] = src_addr;
1327 	i++;
1328 	payload[i] = src_size;
1329 	i++;
1330 	status = mailbox_send_cmd(MBOX_JOB_ID,
1331 			MBOX_FCS_ECDSA_SHA2_DATA_SIGN_REQ, payload,
1332 			i, CMD_CASUAL, (uint32_t *) dst_addr,
1333 			&resp_len);
1334 
1335 	if (is_finalised != 0U) {
1336 		memset((void *)&fcs_sha2_data_sign_param, 0,
1337 			sizeof(fcs_crypto_service_data));
1338 	}
1339 
1340 	if (status < 0) {
1341 		*mbox_error = -status;
1342 		return INTEL_SIP_SMC_STATUS_ERROR;
1343 	}
1344 
1345 	*dst_size = resp_len * MBOX_WORD_BYTE;
1346 	flush_dcache_range(dst_addr, *dst_size);
1347 
1348 	return INTEL_SIP_SMC_STATUS_OK;
1349 }
1350 
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)1351 int intel_fcs_ecdsa_sha2_data_sig_verify_init(uint32_t session_id,
1352 				uint32_t context_id, uint32_t key_id,
1353 				uint32_t param_size, uint64_t param_data,
1354 				uint32_t *mbox_error)
1355 {
1356 	return intel_fcs_crypto_service_init(session_id, context_id,
1357 				key_id, param_size, param_data,
1358 				(void *) &fcs_sha2_data_sig_verify_param,
1359 				mbox_error);
1360 }
1361 
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)1362 int intel_fcs_ecdsa_sha2_data_sig_verify_update_finalize(uint32_t session_id,
1363 				uint32_t context_id, uint32_t src_addr,
1364 				uint32_t src_size, uint64_t dst_addr,
1365 				uint32_t *dst_size, uint32_t data_size,
1366 				uint8_t is_finalised, uint32_t *mbox_error)
1367 {
1368 	int status;
1369 	uint32_t i;
1370 	uint32_t flag;
1371 	uint32_t crypto_header;
1372 	uint32_t payload[FCS_ECDSA_SHA2_DATA_SIG_VERIFY_CMD_MAX_WORD_SIZE] = {0U};
1373 	uint32_t resp_len;
1374 	uintptr_t sig_pubkey_offset;
1375 
1376 	if ((dst_size == NULL) || (mbox_error == NULL)) {
1377 		return INTEL_SIP_SMC_STATUS_REJECTED;
1378 	}
1379 
1380 	if (fcs_sha2_data_sig_verify_param.session_id != session_id ||
1381 		fcs_sha2_data_sig_verify_param.context_id != context_id) {
1382 		return INTEL_SIP_SMC_STATUS_REJECTED;
1383 	}
1384 
1385 	if (!is_size_4_bytes_aligned(src_size)) {
1386 		return INTEL_SIP_SMC_STATUS_REJECTED;
1387 	}
1388 
1389 	if (!is_8_bytes_aligned(data_size) ||
1390 		!is_8_bytes_aligned(src_addr)) {
1391 		return INTEL_SIP_SMC_STATUS_REJECTED;
1392 	}
1393 
1394 	if (!is_address_in_ddr_range(src_addr, src_size) ||
1395 		!is_address_in_ddr_range(dst_addr, *dst_size)) {
1396 		return INTEL_SIP_SMC_STATUS_REJECTED;
1397 	}
1398 
1399 	resp_len = *dst_size / MBOX_WORD_BYTE;
1400 
1401 	/* Prepare crypto header */
1402 	flag = 0;
1403 	if (fcs_sha2_data_sig_verify_param.is_updated)
1404 		fcs_sha2_data_sig_verify_param.crypto_param_size = 0;
1405 	else
1406 		flag |= FCS_CS_FIELD_FLAG_INIT;
1407 
1408 	if (is_finalised != 0U)
1409 		flag |= FCS_CS_FIELD_FLAG_FINALIZE;
1410 	else {
1411 		flag |= FCS_CS_FIELD_FLAG_UPDATE;
1412 		fcs_sha2_data_sig_verify_param.is_updated = 1;
1413 	}
1414 	crypto_header = (flag << FCS_CS_FIELD_FLAG_OFFSET) |
1415 			fcs_sha2_data_sig_verify_param.crypto_param_size;
1416 
1417 	/* Prepare command payload */
1418 	i = 0;
1419 	payload[i] = fcs_sha2_data_sig_verify_param.session_id;
1420 	i++;
1421 	payload[i] = fcs_sha2_data_sig_verify_param.context_id;
1422 	i++;
1423 	payload[i] = crypto_header;
1424 	i++;
1425 
1426 	if ((crypto_header >> FCS_CS_FIELD_FLAG_OFFSET) &
1427 		FCS_CS_FIELD_FLAG_INIT) {
1428 		payload[i] = fcs_sha2_data_sig_verify_param.key_id;
1429 		i++;
1430 		/* Crypto parameters */
1431 		payload[i] = fcs_sha2_data_sig_verify_param.crypto_param
1432 				& INTEL_SIP_SMC_FCS_ECC_ALGO_MASK;
1433 		i++;
1434 	}
1435 
1436 	/* Data source address and size */
1437 	payload[i] = src_addr;
1438 	i++;
1439 	payload[i] = data_size;
1440 	i++;
1441 
1442 	if ((crypto_header >> FCS_CS_FIELD_FLAG_OFFSET) &
1443 		FCS_CS_FIELD_FLAG_FINALIZE) {
1444 		/* Signature + Public Key Data */
1445 		sig_pubkey_offset = src_addr + data_size;
1446 		memcpy((uint8_t *) &payload[i], (uint8_t *) sig_pubkey_offset,
1447 			src_size - data_size);
1448 
1449 		i += (src_size - data_size) / MBOX_WORD_BYTE;
1450 	}
1451 
1452 	status = mailbox_send_cmd(MBOX_JOB_ID,
1453 			MBOX_FCS_ECDSA_SHA2_DATA_SIGN_VERIFY, payload, i,
1454 			CMD_CASUAL, (uint32_t *) dst_addr, &resp_len);
1455 
1456 	if (is_finalised != 0U) {
1457 		memset((void *) &fcs_sha2_data_sig_verify_param, 0,
1458 			sizeof(fcs_crypto_service_data));
1459 	}
1460 
1461 	if (status < 0) {
1462 		*mbox_error = -status;
1463 		return INTEL_SIP_SMC_STATUS_ERROR;
1464 	}
1465 
1466 	*dst_size = resp_len * MBOX_WORD_BYTE;
1467 	flush_dcache_range(dst_addr, *dst_size);
1468 
1469 	return INTEL_SIP_SMC_STATUS_OK;
1470 }
1471 
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)1472 int intel_fcs_ecdsa_get_pubkey_init(uint32_t session_id, uint32_t context_id,
1473 				uint32_t key_id, uint32_t param_size,
1474 				uint64_t param_data, uint32_t *mbox_error)
1475 {
1476 	return intel_fcs_crypto_service_init(session_id, context_id,
1477 				key_id, param_size, param_data,
1478 				(void *) &fcs_ecdsa_get_pubkey_param,
1479 				mbox_error);
1480 }
1481 
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)1482 int intel_fcs_ecdsa_get_pubkey_finalize(uint32_t session_id, uint32_t context_id,
1483 				uint64_t dst_addr, uint32_t *dst_size,
1484 				uint32_t *mbox_error)
1485 {
1486 	int status;
1487 	int i;
1488 	uint32_t crypto_header;
1489 	uint32_t ret_size;
1490 	uint32_t payload[FCS_ECDSA_GET_PUBKEY_MAX_WORD_SIZE] = {0U};
1491 
1492 	if ((dst_size == NULL) || (mbox_error == NULL)) {
1493 		return INTEL_SIP_SMC_STATUS_REJECTED;
1494 	}
1495 
1496 	if (fcs_ecdsa_get_pubkey_param.session_id != session_id ||
1497 		fcs_ecdsa_get_pubkey_param.context_id != context_id) {
1498 		return INTEL_SIP_SMC_STATUS_REJECTED;
1499 	}
1500 
1501 	ret_size = *dst_size / MBOX_WORD_BYTE;
1502 
1503 	crypto_header = ((FCS_CS_FIELD_FLAG_INIT |
1504 			FCS_CS_FIELD_FLAG_UPDATE |
1505 			FCS_CS_FIELD_FLAG_FINALIZE) <<
1506 			FCS_CS_FIELD_FLAG_OFFSET) |
1507 			fcs_ecdsa_get_pubkey_param.crypto_param_size;
1508 	i = 0;
1509 	/* Prepare command payload */
1510 	payload[i] = session_id;
1511 	i++;
1512 	payload[i] = context_id;
1513 	i++;
1514 	payload[i] = crypto_header;
1515 	i++;
1516 	payload[i] = fcs_ecdsa_get_pubkey_param.key_id;
1517 	i++;
1518 	payload[i] = (uint32_t) fcs_ecdsa_get_pubkey_param.crypto_param &
1519 			INTEL_SIP_SMC_FCS_ECC_ALGO_MASK;
1520 	i++;
1521 
1522 	status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_ECDSA_GET_PUBKEY,
1523 			payload, i, CMD_CASUAL,
1524 			(uint32_t *) dst_addr, &ret_size);
1525 
1526 	memset((void *) &fcs_ecdsa_get_pubkey_param, 0,
1527 		sizeof(fcs_crypto_service_data));
1528 
1529 	if (status < 0) {
1530 		*mbox_error = -status;
1531 		return INTEL_SIP_SMC_STATUS_ERROR;
1532 	}
1533 
1534 	*dst_size = ret_size * MBOX_WORD_BYTE;
1535 	flush_dcache_range(dst_addr, *dst_size);
1536 
1537 	return INTEL_SIP_SMC_STATUS_OK;
1538 }
1539 
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)1540 int intel_fcs_ecdh_request_init(uint32_t session_id, uint32_t context_id,
1541 				uint32_t key_id, uint32_t param_size,
1542 				uint64_t param_data, uint32_t *mbox_error)
1543 {
1544 	return intel_fcs_crypto_service_init(session_id, context_id,
1545 				key_id, param_size, param_data,
1546 				(void *) &fcs_ecdh_request_param,
1547 				mbox_error);
1548 }
1549 
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)1550 int intel_fcs_ecdh_request_finalize(uint32_t session_id, uint32_t context_id,
1551 				uint32_t src_addr, uint32_t src_size,
1552 				uint64_t dst_addr, uint32_t *dst_size,
1553 				uint32_t *mbox_error)
1554 {
1555 	int status;
1556 	uint32_t i;
1557 	uint32_t payload[FCS_ECDH_REQUEST_CMD_MAX_WORD_SIZE] = {0U};
1558 	uint32_t resp_len;
1559 	uintptr_t pubkey;
1560 
1561 	if ((dst_size == NULL) || (mbox_error == NULL)) {
1562 		return INTEL_SIP_SMC_STATUS_REJECTED;
1563 	}
1564 
1565 	if (fcs_ecdh_request_param.session_id != session_id ||
1566 		fcs_ecdh_request_param.context_id != context_id) {
1567 		return INTEL_SIP_SMC_STATUS_REJECTED;
1568 	}
1569 
1570 	if (!is_address_in_ddr_range(src_addr, src_size) ||
1571 		!is_address_in_ddr_range(dst_addr, *dst_size)) {
1572 		return INTEL_SIP_SMC_STATUS_REJECTED;
1573 	}
1574 
1575 	resp_len = *dst_size / MBOX_WORD_BYTE;
1576 
1577 	/* Prepare command payload */
1578 	i = 0;
1579 	/* Crypto header */
1580 	payload[i] = fcs_ecdh_request_param.session_id;
1581 	i++;
1582 	payload[i] = fcs_ecdh_request_param.context_id;
1583 	i++;
1584 	payload[i] = fcs_ecdh_request_param.crypto_param_size
1585 			& FCS_CS_FIELD_SIZE_MASK;
1586 	payload[i] |= (FCS_CS_FIELD_FLAG_INIT | FCS_CS_FIELD_FLAG_UPDATE
1587 			| FCS_CS_FIELD_FLAG_FINALIZE)
1588 			<< FCS_CS_FIELD_FLAG_OFFSET;
1589 	i++;
1590 	payload[i] = fcs_ecdh_request_param.key_id;
1591 	i++;
1592 	/* Crypto parameters */
1593 	payload[i] = fcs_ecdh_request_param.crypto_param
1594 			& INTEL_SIP_SMC_FCS_ECC_ALGO_MASK;
1595 	i++;
1596 	/* Public key data */
1597 	pubkey = src_addr;
1598 	memcpy((uint8_t *) &payload[i], (uint8_t *) pubkey, src_size);
1599 	i += src_size / MBOX_WORD_BYTE;
1600 
1601 	status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_ECDH_REQUEST,
1602 			payload, i, CMD_CASUAL, (uint32_t *) dst_addr,
1603 			&resp_len);
1604 
1605 	memset((void *)&fcs_ecdh_request_param, 0,
1606 			sizeof(fcs_crypto_service_data));
1607 
1608 	if (status < 0) {
1609 		*mbox_error = -status;
1610 		return INTEL_SIP_SMC_STATUS_ERROR;
1611 	}
1612 
1613 	*dst_size = resp_len * MBOX_WORD_BYTE;
1614 	flush_dcache_range(dst_addr, *dst_size);
1615 
1616 	return INTEL_SIP_SMC_STATUS_OK;
1617 }
1618 
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)1619 int intel_fcs_aes_crypt_init(uint32_t session_id, uint32_t context_id,
1620 				uint32_t key_id, uint64_t param_addr,
1621 				uint32_t param_size, uint32_t *mbox_error)
1622 {
1623 	if (mbox_error == NULL) {
1624 		return INTEL_SIP_SMC_STATUS_REJECTED;
1625 	}
1626 
1627 	memset((void *)&fcs_aes_init_payload, 0U, sizeof(fcs_aes_init_payload));
1628 
1629 	fcs_aes_init_payload.session_id = session_id;
1630 	fcs_aes_init_payload.context_id = context_id;
1631 	fcs_aes_init_payload.param_size = param_size;
1632 	fcs_aes_init_payload.key_id	= key_id;
1633 
1634 	memcpy((uint8_t *) fcs_aes_init_payload.crypto_param,
1635 		(uint8_t *) param_addr, param_size);
1636 
1637 	fcs_aes_init_payload.is_updated = 0;
1638 
1639 	*mbox_error = 0;
1640 
1641 	return INTEL_SIP_SMC_STATUS_OK;
1642 }
1643 
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)1644 int intel_fcs_aes_crypt_update_finalize(uint32_t session_id,
1645 				uint32_t context_id, uint64_t src_addr,
1646 				uint32_t src_size, uint64_t dst_addr,
1647 				uint32_t dst_size, uint8_t is_finalised,
1648 				uint32_t *send_id)
1649 {
1650 	int status;
1651 	int i;
1652 	uint32_t flag;
1653 	uint32_t crypto_header;
1654 	uint32_t fcs_aes_crypt_payload[FCS_AES_CMD_MAX_WORD_SIZE];
1655 
1656 	if (fcs_aes_init_payload.session_id != session_id ||
1657 		fcs_aes_init_payload.context_id != context_id) {
1658 		return INTEL_SIP_SMC_STATUS_REJECTED;
1659 	}
1660 
1661 	if ((!is_8_bytes_aligned(src_addr)) ||
1662 		(!is_32_bytes_aligned(src_size)) ||
1663 		(!is_address_in_ddr_range(src_addr, src_size))) {
1664 		return INTEL_SIP_SMC_STATUS_REJECTED;
1665 	}
1666 
1667 	if ((!is_8_bytes_aligned(dst_addr)) ||
1668 		(!is_32_bytes_aligned(dst_size))) {
1669 		return INTEL_SIP_SMC_STATUS_REJECTED;
1670 	}
1671 
1672 	if ((dst_size > FCS_AES_MAX_DATA_SIZE ||
1673 		dst_size < FCS_AES_MIN_DATA_SIZE) ||
1674 		(src_size > FCS_AES_MAX_DATA_SIZE ||
1675 		src_size < FCS_AES_MIN_DATA_SIZE)) {
1676 		return INTEL_SIP_SMC_STATUS_REJECTED;
1677 	}
1678 
1679 	/* Prepare crypto header*/
1680 	flag = 0;
1681 	if (fcs_aes_init_payload.is_updated) {
1682 		fcs_aes_init_payload.param_size = 0;
1683 	} else {
1684 		flag |= FCS_CS_FIELD_FLAG_INIT;
1685 	}
1686 
1687 	if (is_finalised != 0U) {
1688 		flag |= FCS_CS_FIELD_FLAG_FINALIZE;
1689 	} else {
1690 		flag |= FCS_CS_FIELD_FLAG_UPDATE;
1691 		fcs_aes_init_payload.is_updated = 1;
1692 	}
1693 	crypto_header = (flag << FCS_CS_FIELD_FLAG_OFFSET) |
1694 			fcs_aes_init_payload.param_size;
1695 
1696 	i = 0U;
1697 	fcs_aes_crypt_payload[i] = session_id;
1698 	i++;
1699 	fcs_aes_crypt_payload[i] = context_id;
1700 	i++;
1701 	fcs_aes_crypt_payload[i] = crypto_header;
1702 	i++;
1703 
1704 	if ((crypto_header >> FCS_CS_FIELD_FLAG_OFFSET) &
1705 		FCS_CS_FIELD_FLAG_INIT) {
1706 		fcs_aes_crypt_payload[i] = fcs_aes_init_payload.key_id;
1707 		i++;
1708 
1709 		memcpy((uint8_t *) &fcs_aes_crypt_payload[i],
1710 			(uint8_t *) fcs_aes_init_payload.crypto_param,
1711 			fcs_aes_init_payload.param_size);
1712 
1713 		i += fcs_aes_init_payload.param_size / MBOX_WORD_BYTE;
1714 	}
1715 
1716 	fcs_aes_crypt_payload[i] = (uint32_t) src_addr;
1717 	i++;
1718 	fcs_aes_crypt_payload[i] = src_size;
1719 	i++;
1720 	fcs_aes_crypt_payload[i] = (uint32_t) dst_addr;
1721 	i++;
1722 	fcs_aes_crypt_payload[i] = dst_size;
1723 	i++;
1724 
1725 	status = mailbox_send_cmd_async(send_id, MBOX_FCS_AES_CRYPT_REQ,
1726 					fcs_aes_crypt_payload, i,
1727 					CMD_INDIRECT);
1728 
1729 	if (is_finalised != 0U) {
1730 		memset((void *)&fcs_aes_init_payload, 0,
1731 			sizeof(fcs_aes_init_payload));
1732 	}
1733 
1734 	if (status < 0U) {
1735 		return INTEL_SIP_SMC_STATUS_ERROR;
1736 	}
1737 
1738 	return INTEL_SIP_SMC_STATUS_OK;
1739 }
1740