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