blob: d99026bcc511368ca8082dd3b2312a642d69b208 [file] [log] [blame]
Sieu Mun Tang9f22cbf2022-03-02 11:04:09 +08001/*
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
Sieu Mun Tangd907cc32022-05-10 17:24:05 +080014/* FCS static variables */
Sieu Mun Tangb0c1d112022-05-10 17:30:00 +080015static fcs_crypto_service_aes_data fcs_aes_init_payload;
Sieu Mun Tangd907cc32022-05-10 17:24:05 +080016static fcs_crypto_service_data fcs_sha_get_digest_param;
Sieu Mun Tang583149a2022-05-10 17:27:12 +080017static fcs_crypto_service_data fcs_sha_mac_verify_param;
Sieu Mun Tang8aa05ad2022-05-10 17:50:30 +080018static fcs_crypto_service_data fcs_ecdsa_hash_sign_param;
Sieu Mun Tang59357e82022-05-10 17:53:32 +080019static fcs_crypto_service_data fcs_ecdsa_hash_sig_verify_param;
Sieu Mun Tang153ecfb2022-05-10 17:39:26 +080020static fcs_crypto_service_data fcs_sha2_data_sign_param;
Sieu Mun Tangdcaab772022-05-11 10:16:40 +080021static fcs_crypto_service_data fcs_sha2_data_sig_verify_param;
22static fcs_crypto_service_data fcs_ecdsa_get_pubkey_param;
Sieu Mun Tang0675c222022-05-10 17:48:11 +080023static fcs_crypto_service_data fcs_ecdh_request_param;
Sieu Mun Tangd907cc32022-05-10 17:24:05 +080024
Sieu Mun Tang128d2a72022-05-11 09:49:25 +080025bool is_size_4_bytes_aligned(uint32_t size)
Sieu Mun Tangdb79fa52022-03-20 00:49:57 +080026{
27 if ((size % MBOX_WORD_BYTE) != 0U) {
28 return false;
29 } else {
30 return true;
31 }
Sieu Mun Tangd907cc32022-05-10 17:24:05 +080032}
33
34static 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
Sieu Mun Tangb0c1d112022-05-10 17:30:00 +080043static 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
Sieu Mun Tangd907cc32022-05-10 17:24:05 +080052static 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
Sieu Mun Tange77d37d2022-04-28 16:23:20 +080074 data_addr->is_updated = 0;
75
Sieu Mun Tangd907cc32022-05-10 17:24:05 +080076 *mbox_error = 0;
77
78 return INTEL_SIP_SMC_STATUS_OK;
Sieu Mun Tangdb79fa52022-03-20 00:49:57 +080079}
80
Sieu Mun Tang9f22cbf2022-03-02 11:04:09 +080081uint32_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
Sieu Mun Tange7a037f2022-05-10 17:18:19 +0800118int 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
Sieu Mun Tang9f22cbf2022-03-02 11:04:09 +0800157uint32_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
Sieu Mun Tangdb79fa52022-03-20 00:49:57 +0800166 if (!is_size_4_bytes_aligned(size)) {
167 return INTEL_SIP_SMC_STATUS_REJECTED;
168 }
169
Sieu Mun Tang9f22cbf2022-03-02 11:04:09 +0800170 status = mailbox_send_cmd_async(send_id, MBOX_CMD_VAB_SRC_CERT,
171 (uint32_t *)addr, size / MBOX_WORD_BYTE,
172 CMD_DIRECT);
173
Boon Khai Ngcac786d2021-05-26 01:50:34 +0800174 flush_dcache_range(addr, size);
175
Sieu Mun Tang9f22cbf2022-03-02 11:04:09 +0800176 if (status < 0) {
177 return INTEL_SIP_SMC_STATUS_ERROR;
178 }
179
180 return INTEL_SIP_SMC_STATUS_OK;
181}
182
183uint32_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
Sieu Mun Tanga068fdf2022-05-11 10:01:54 +0800197uint32_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
Sieu Mun Tang128d2a72022-05-11 09:49:25 +0800244uint32_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)
Sieu Mun Tang9f22cbf2022-03-02 11:04:09 +0800246{
247 int status;
Sieu Mun Tang128d2a72022-05-11 09:49:25 +0800248 uint32_t load_size;
Sieu Mun Tang9f22cbf2022-03-02 11:04:09 +0800249
Sieu Mun Tang128d2a72022-05-11 09:49:25 +0800250 fcs_encrypt_payload payload = {
251 FCS_ENCRYPTION_DATA_0,
Sieu Mun Tang9f22cbf2022-03-02 11:04:09 +0800252 src_addr,
253 src_size,
254 dst_addr,
255 dst_size };
Sieu Mun Tang128d2a72022-05-11 09:49:25 +0800256 load_size = sizeof(payload) / MBOX_WORD_BYTE;
Sieu Mun Tang9f22cbf2022-03-02 11:04:09 +0800257
Sieu Mun Tangdb79fa52022-03-20 00:49:57 +0800258 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
Sieu Mun Tang128d2a72022-05-11 09:49:25 +0800263 if (!is_size_4_bytes_aligned(src_size)) {
Sieu Mun Tangdb79fa52022-03-20 00:49:57 +0800264 return INTEL_SIP_SMC_STATUS_REJECTED;
265 }
266
Sieu Mun Tang128d2a72022-05-11 09:49:25 +0800267 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
279uint32_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
Jit Loon Lim21165ab2023-03-27 15:19:53 +0800286 inv_dcache_range(src_addr, src_size); /* flush cache before mmio read to avoid reading old values */
Sieu Mun Tang128d2a72022-05-11 09:49:25 +0800287 id_offset = src_addr + FCS_OWNER_ID_OFFSET;
288 fcs_decrypt_payload payload = {
289 FCS_DECRYPTION_DATA_0,
290 {mmio_read_32(id_offset),
291 mmio_read_32(id_offset + MBOX_WORD_BYTE)},
292 src_addr,
293 src_size,
294 dst_addr,
295 dst_size };
296 load_size = sizeof(payload) / MBOX_WORD_BYTE;
297
298 if (!is_address_in_ddr_range(src_addr, src_size) ||
299 !is_address_in_ddr_range(dst_addr, dst_size)) {
300 return INTEL_SIP_SMC_STATUS_REJECTED;
301 }
302
303 if (!is_size_4_bytes_aligned(src_size)) {
304 return INTEL_SIP_SMC_STATUS_REJECTED;
Sieu Mun Tang9f22cbf2022-03-02 11:04:09 +0800305 }
306
Sieu Mun Tang128d2a72022-05-11 09:49:25 +0800307 status = mailbox_send_cmd_async(send_id, MBOX_FCS_DECRYPT_REQ,
308 (uint32_t *) &payload, load_size,
Sieu Mun Tang9f22cbf2022-03-02 11:04:09 +0800309 CMD_INDIRECT);
310 inv_dcache_range(dst_addr, dst_size);
311
312 if (status < 0) {
313 return INTEL_SIP_SMC_STATUS_REJECTED;
314 }
315
316 return INTEL_SIP_SMC_STATUS_OK;
317}
Sieu Mun Tanga34b8812022-03-17 03:11:55 +0800318
Sieu Mun Tang22322fb2022-05-09 16:05:58 +0800319int intel_fcs_encryption_ext(uint32_t session_id, uint32_t context_id,
320 uint32_t src_addr, uint32_t src_size,
321 uint32_t dst_addr, uint32_t *dst_size, uint32_t *mbox_error)
322{
323 int status;
324 uint32_t payload_size;
325 uint32_t resp_len = FCS_CRYPTION_RESP_WORD_SIZE;
326 uint32_t resp_data[FCS_CRYPTION_RESP_WORD_SIZE] = {0U};
327
328 if ((dst_size == NULL) || (mbox_error == NULL)) {
329 return INTEL_SIP_SMC_STATUS_REJECTED;
330 }
331
332 if (!is_address_in_ddr_range(src_addr, src_size) ||
333 !is_address_in_ddr_range(dst_addr, *dst_size)) {
334 return INTEL_SIP_SMC_STATUS_REJECTED;
335 }
336
337 if (!is_size_4_bytes_aligned(src_size)) {
338 return INTEL_SIP_SMC_STATUS_REJECTED;
339 }
340
341 fcs_encrypt_ext_payload payload = {
342 session_id,
343 context_id,
344 FCS_CRYPTION_CRYPTO_HEADER,
345 src_addr,
346 src_size,
347 dst_addr,
348 *dst_size
349 };
350
351 payload_size = sizeof(payload) / MBOX_WORD_BYTE;
352
353 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_ENCRYPT_REQ,
354 (uint32_t *) &payload, payload_size,
355 CMD_CASUAL, resp_data, &resp_len);
356
357 if (status < 0) {
358 *mbox_error = -status;
359 return INTEL_SIP_SMC_STATUS_ERROR;
360 }
361
362 if (resp_len != FCS_CRYPTION_RESP_WORD_SIZE) {
363 *mbox_error = MBOX_RET_ERROR;
364 return INTEL_SIP_SMC_STATUS_ERROR;
365 }
366
367 *dst_size = resp_data[FCS_CRYPTION_RESP_SIZE_OFFSET];
368 inv_dcache_range(dst_addr, *dst_size);
369
370 return INTEL_SIP_SMC_STATUS_OK;
371}
372
373int intel_fcs_decryption_ext(uint32_t session_id, uint32_t context_id,
374 uint32_t src_addr, uint32_t src_size,
375 uint32_t dst_addr, uint32_t *dst_size, uint32_t *mbox_error)
376{
377 int status;
378 uintptr_t id_offset;
379 uint32_t payload_size;
380 uint32_t resp_len = FCS_CRYPTION_RESP_WORD_SIZE;
381 uint32_t resp_data[FCS_CRYPTION_RESP_WORD_SIZE] = {0U};
382
383 if ((dst_size == NULL) || (mbox_error == NULL)) {
384 return INTEL_SIP_SMC_STATUS_REJECTED;
385 }
386
387 if (!is_address_in_ddr_range(src_addr, src_size) ||
388 !is_address_in_ddr_range(dst_addr, *dst_size)) {
389 return INTEL_SIP_SMC_STATUS_REJECTED;
390 }
391
392 if (!is_size_4_bytes_aligned(src_size)) {
393 return INTEL_SIP_SMC_STATUS_REJECTED;
394 }
395
Jit Loon Lim21165ab2023-03-27 15:19:53 +0800396 inv_dcache_range(src_addr, src_size); /* flush cache before mmio read to avoid reading old values */
Sieu Mun Tang22322fb2022-05-09 16:05:58 +0800397 id_offset = src_addr + FCS_OWNER_ID_OFFSET;
398 fcs_decrypt_ext_payload payload = {
399 session_id,
400 context_id,
401 FCS_CRYPTION_CRYPTO_HEADER,
402 {mmio_read_32(id_offset),
403 mmio_read_32(id_offset + MBOX_WORD_BYTE)},
404 src_addr,
405 src_size,
406 dst_addr,
407 *dst_size
408 };
409
410 payload_size = sizeof(payload) / MBOX_WORD_BYTE;
411
412 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_DECRYPT_REQ,
413 (uint32_t *) &payload, payload_size,
414 CMD_CASUAL, resp_data, &resp_len);
415
Sieu Mun Tang6c7f0c72022-12-04 01:43:35 +0800416 if (status == MBOX_RET_SDOS_DECRYPTION_ERROR_102 ||
417 status == MBOX_RET_SDOS_DECRYPTION_ERROR_103) {
418 *mbox_error = -status;
419 } else if (status < 0) {
Sieu Mun Tang22322fb2022-05-09 16:05:58 +0800420 *mbox_error = -status;
421 return INTEL_SIP_SMC_STATUS_ERROR;
422 }
423
424 if (resp_len != FCS_CRYPTION_RESP_WORD_SIZE) {
425 *mbox_error = MBOX_RET_ERROR;
426 return INTEL_SIP_SMC_STATUS_ERROR;
427 }
428
429 *dst_size = resp_data[FCS_CRYPTION_RESP_SIZE_OFFSET];
430 inv_dcache_range(dst_addr, *dst_size);
431
432 return INTEL_SIP_SMC_STATUS_OK;
433}
434
Sieu Mun Tang2a820b92022-05-11 09:59:55 +0800435int intel_fcs_sigma_teardown(uint32_t session_id, uint32_t *mbox_error)
436{
437 int status;
438
439 if ((session_id != PSGSIGMA_SESSION_ID_ONE) &&
440 (session_id != PSGSIGMA_UNKNOWN_SESSION)) {
441 return INTEL_SIP_SMC_STATUS_REJECTED;
442 }
443
444 psgsigma_teardown_msg message = {
445 RESERVED_AS_ZERO,
446 PSGSIGMA_TEARDOWN_MAGIC,
447 session_id
448 };
449
450 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_PSG_SIGMA_TEARDOWN,
451 (uint32_t *) &message, sizeof(message) / MBOX_WORD_BYTE,
452 CMD_CASUAL, NULL, NULL);
453
454 if (status < 0) {
455 *mbox_error = -status;
456 return INTEL_SIP_SMC_STATUS_ERROR;
457 }
458
459 return INTEL_SIP_SMC_STATUS_OK;
460}
461
462int intel_fcs_chip_id(uint32_t *id_low, uint32_t *id_high, uint32_t *mbox_error)
463{
464 int status;
465 uint32_t load_size;
466 uint32_t chip_id[2];
467
468 load_size = sizeof(chip_id) / MBOX_WORD_BYTE;
469
470 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_CMD_GET_CHIPID, NULL,
471 0U, CMD_CASUAL, (uint32_t *) chip_id, &load_size);
472
473 if (status < 0) {
474 *mbox_error = -status;
475 return INTEL_SIP_SMC_STATUS_ERROR;
476 }
477
478 *id_low = chip_id[0];
479 *id_high = chip_id[1];
480
481 return INTEL_SIP_SMC_STATUS_OK;
482}
483
484int intel_fcs_attestation_subkey(uint64_t src_addr, uint32_t src_size,
485 uint64_t dst_addr, uint32_t *dst_size, uint32_t *mbox_error)
486{
487 int status;
488 uint32_t send_size = src_size / MBOX_WORD_BYTE;
489 uint32_t ret_size = *dst_size / MBOX_WORD_BYTE;
490
491
492 if (!is_address_in_ddr_range(src_addr, src_size) ||
493 !is_address_in_ddr_range(dst_addr, *dst_size)) {
494 return INTEL_SIP_SMC_STATUS_REJECTED;
495 }
496
497 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_ATTESTATION_SUBKEY,
498 (uint32_t *) src_addr, send_size, CMD_CASUAL,
499 (uint32_t *) dst_addr, &ret_size);
500
501 if (status < 0) {
502 *mbox_error = -status;
503 return INTEL_SIP_SMC_STATUS_ERROR;
504 }
505
506 *dst_size = ret_size * MBOX_WORD_BYTE;
507 flush_dcache_range(dst_addr, *dst_size);
508
509 return INTEL_SIP_SMC_STATUS_OK;
510}
511
512int intel_fcs_get_measurement(uint64_t src_addr, uint32_t src_size,
513 uint64_t dst_addr, uint32_t *dst_size, uint32_t *mbox_error)
514{
515 int status;
516 uint32_t send_size = src_size / MBOX_WORD_BYTE;
517 uint32_t ret_size = *dst_size / MBOX_WORD_BYTE;
518
519 if (!is_address_in_ddr_range(src_addr, src_size) ||
520 !is_address_in_ddr_range(dst_addr, *dst_size)) {
521 return INTEL_SIP_SMC_STATUS_REJECTED;
522 }
523
524 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_GET_MEASUREMENT,
525 (uint32_t *) src_addr, send_size, CMD_CASUAL,
526 (uint32_t *) dst_addr, &ret_size);
527
528 if (status < 0) {
529 *mbox_error = -status;
530 return INTEL_SIP_SMC_STATUS_ERROR;
531 }
532
533 *dst_size = ret_size * MBOX_WORD_BYTE;
534 flush_dcache_range(dst_addr, *dst_size);
535
536 return INTEL_SIP_SMC_STATUS_OK;
537}
Sieu Mun Tang28af1652022-05-09 10:48:53 +0800538
Sieu Mun Tang4f5554c2022-05-13 14:36:32 +0800539uint32_t intel_fcs_get_rom_patch_sha384(uint64_t addr, uint64_t *ret_size,
540 uint32_t *mbox_error)
541{
542 int status;
543 unsigned int resp_len = FCS_SHA384_WORD_SIZE;
544
545 if (!is_address_in_ddr_range(addr, FCS_SHA384_BYTE_SIZE)) {
546 return INTEL_SIP_SMC_STATUS_REJECTED;
547 }
548
549 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_GET_ROM_PATCH_SHA384, NULL, 0U,
550 CMD_CASUAL, (uint32_t *) addr, &resp_len);
551
552 if (status < 0) {
553 *mbox_error = -status;
554 return INTEL_SIP_SMC_STATUS_ERROR;
555 }
556
557 if (resp_len != FCS_SHA384_WORD_SIZE) {
558 *mbox_error = GENERIC_RESPONSE_ERROR;
559 return INTEL_SIP_SMC_STATUS_ERROR;
560 }
561
562 *ret_size = FCS_SHA384_BYTE_SIZE;
563
564 flush_dcache_range(addr, *ret_size);
565
566 return INTEL_SIP_SMC_STATUS_OK;
567}
568
Sieu Mun Tang28af1652022-05-09 10:48:53 +0800569int intel_fcs_get_attestation_cert(uint32_t cert_request, uint64_t dst_addr,
570 uint32_t *dst_size, uint32_t *mbox_error)
571{
572 int status;
573 uint32_t ret_size = *dst_size / MBOX_WORD_BYTE;
574
575 if (mbox_error == NULL) {
576 return INTEL_SIP_SMC_STATUS_REJECTED;
577 }
578
Boon Khai Ngd2df2042021-08-30 15:05:49 +0800579 if (cert_request < FCS_ATTEST_FIRMWARE_CERT ||
580 cert_request > FCS_ATTEST_CERT_MAX_REQ_PARAM) {
Sieu Mun Tang28af1652022-05-09 10:48:53 +0800581 return INTEL_SIP_SMC_STATUS_REJECTED;
582 }
583
584 if (!is_address_in_ddr_range(dst_addr, *dst_size)) {
585 return INTEL_SIP_SMC_STATUS_REJECTED;
586 }
587
588 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_GET_ATTESTATION_CERT,
589 (uint32_t *) &cert_request, 1U, CMD_CASUAL,
590 (uint32_t *) dst_addr, &ret_size);
591
592 if (status < 0) {
593 *mbox_error = -status;
594 return INTEL_SIP_SMC_STATUS_ERROR;
595 }
596
597 *dst_size = ret_size * MBOX_WORD_BYTE;
598 flush_dcache_range(dst_addr, *dst_size);
599
600 return INTEL_SIP_SMC_STATUS_OK;
601}
602
603int intel_fcs_create_cert_on_reload(uint32_t cert_request,
604 uint32_t *mbox_error)
605{
606 int status;
607
608 if (mbox_error == NULL) {
609 return INTEL_SIP_SMC_STATUS_REJECTED;
610 }
611
Boon Khai Ngd2df2042021-08-30 15:05:49 +0800612 if (cert_request < FCS_ATTEST_FIRMWARE_CERT ||
613 cert_request > FCS_ATTEST_CERT_MAX_REQ_PARAM) {
Sieu Mun Tang28af1652022-05-09 10:48:53 +0800614 return INTEL_SIP_SMC_STATUS_REJECTED;
615 }
616
617 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_CREATE_CERT_ON_RELOAD,
618 (uint32_t *) &cert_request, 1U, CMD_CASUAL,
619 NULL, NULL);
620
621 if (status < 0) {
622 *mbox_error = -status;
623 return INTEL_SIP_SMC_STATUS_ERROR;
624 }
625
626 return INTEL_SIP_SMC_STATUS_OK;
627}
Sieu Mun Tang16754e12022-05-09 12:08:42 +0800628
629int intel_fcs_open_crypto_service_session(uint32_t *session_id,
630 uint32_t *mbox_error)
631{
632 int status;
633 uint32_t resp_len = 1U;
634
635 if ((session_id == NULL) || (mbox_error == NULL)) {
636 return INTEL_SIP_SMC_STATUS_REJECTED;
637 }
638
639 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_OPEN_CS_SESSION,
640 NULL, 0U, CMD_CASUAL, session_id, &resp_len);
641
642 if (status < 0) {
643 *mbox_error = -status;
644 return INTEL_SIP_SMC_STATUS_ERROR;
645 }
646
647 return INTEL_SIP_SMC_STATUS_OK;
648}
649
650int intel_fcs_close_crypto_service_session(uint32_t session_id,
651 uint32_t *mbox_error)
652{
653 int status;
654
655 if (mbox_error == NULL) {
656 return INTEL_SIP_SMC_STATUS_REJECTED;
657 }
658
659 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_CLOSE_CS_SESSION,
660 &session_id, 1U, CMD_CASUAL, NULL, NULL);
661
662 if (status < 0) {
663 *mbox_error = -status;
664 return INTEL_SIP_SMC_STATUS_ERROR;
665 }
666
667 return INTEL_SIP_SMC_STATUS_OK;
668}
Sieu Mun Tangfb1f6e92022-05-09 14:16:14 +0800669
670int intel_fcs_import_crypto_service_key(uint64_t src_addr, uint32_t src_size,
671 uint32_t *send_id)
672{
673 int status;
674
675 if (src_size > (FCS_CS_KEY_OBJ_MAX_WORD_SIZE *
676 MBOX_WORD_BYTE)) {
677 return INTEL_SIP_SMC_STATUS_REJECTED;
678 }
679
680 if (!is_address_in_ddr_range(src_addr, src_size)) {
681 return INTEL_SIP_SMC_STATUS_REJECTED;
682 }
683
684 status = mailbox_send_cmd_async(send_id, MBOX_FCS_IMPORT_CS_KEY,
685 (uint32_t *)src_addr, src_size / MBOX_WORD_BYTE,
686 CMD_INDIRECT);
687
688 if (status < 0) {
689 return INTEL_SIP_SMC_STATUS_ERROR;
690 }
691
692 return INTEL_SIP_SMC_STATUS_OK;
693}
694
695int intel_fcs_export_crypto_service_key(uint32_t session_id, uint32_t key_id,
696 uint64_t dst_addr, uint32_t *dst_size,
697 uint32_t *mbox_error)
698{
699 int status;
700 uint32_t i;
701 uint32_t payload_size;
702 uint32_t resp_len = FCS_CS_KEY_OBJ_MAX_WORD_SIZE;
703 uint32_t resp_data[FCS_CS_KEY_OBJ_MAX_WORD_SIZE] = {0U};
704 uint32_t op_status = 0U;
705
706 if ((dst_size == NULL) || (mbox_error == NULL)) {
707 return INTEL_SIP_SMC_STATUS_REJECTED;
708 }
709
710 if (!is_address_in_ddr_range(dst_addr, *dst_size)) {
711 return INTEL_SIP_SMC_STATUS_REJECTED;
712 }
713
714 fcs_cs_key_payload payload = {
715 session_id,
716 RESERVED_AS_ZERO,
717 RESERVED_AS_ZERO,
718 key_id
719 };
720
721 payload_size = sizeof(payload) / MBOX_WORD_BYTE;
722
723 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_EXPORT_CS_KEY,
724 (uint32_t *) &payload, payload_size,
725 CMD_CASUAL, resp_data, &resp_len);
726
727 if (resp_len > 0) {
728 op_status = resp_data[0] & FCS_CS_KEY_RESP_STATUS_MASK;
729 }
730
731 if (status < 0) {
732 *mbox_error = (-status) | (op_status << FCS_CS_KEY_RESP_STATUS_OFFSET);
733 return INTEL_SIP_SMC_STATUS_ERROR;
734 }
735
736 if (resp_len > 1) {
737
738 /* Export key object is start at second response data */
739 *dst_size = (resp_len - 1) * MBOX_WORD_BYTE;
740
741 for (i = 1U; i < resp_len; i++) {
742 mmio_write_32(dst_addr, resp_data[i]);
743 dst_addr += MBOX_WORD_BYTE;
744 }
745
746 flush_dcache_range(dst_addr - *dst_size, *dst_size);
747
748 } else {
749
750 /* Unexpected response, missing key object in response */
751 *mbox_error = MBOX_RET_ERROR;
752 return INTEL_SIP_SMC_STATUS_ERROR;
753 }
754
755 return INTEL_SIP_SMC_STATUS_OK;
756}
757
758int intel_fcs_remove_crypto_service_key(uint32_t session_id, uint32_t key_id,
759 uint32_t *mbox_error)
760{
761 int status;
762 uint32_t payload_size;
763 uint32_t resp_len = 1U;
764 uint32_t resp_data = 0U;
765 uint32_t op_status = 0U;
766
767 if (mbox_error == NULL) {
768 return INTEL_SIP_SMC_STATUS_REJECTED;
769 }
770
771 fcs_cs_key_payload payload = {
772 session_id,
773 RESERVED_AS_ZERO,
774 RESERVED_AS_ZERO,
775 key_id
776 };
777
778 payload_size = sizeof(payload) / MBOX_WORD_BYTE;
779
780 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_REMOVE_CS_KEY,
781 (uint32_t *) &payload, payload_size,
782 CMD_CASUAL, &resp_data, &resp_len);
783
784 if (resp_len > 0) {
785 op_status = resp_data & FCS_CS_KEY_RESP_STATUS_MASK;
786 }
787
788 if (status < 0) {
789 *mbox_error = (-status) | (op_status << FCS_CS_KEY_RESP_STATUS_OFFSET);
790 return INTEL_SIP_SMC_STATUS_ERROR;
791 }
792
793 return INTEL_SIP_SMC_STATUS_OK;
794}
795
796int intel_fcs_get_crypto_service_key_info(uint32_t session_id, uint32_t key_id,
797 uint64_t dst_addr, uint32_t *dst_size,
798 uint32_t *mbox_error)
799{
800 int status;
801 uint32_t payload_size;
802 uint32_t resp_len = FCS_CS_KEY_INFO_MAX_WORD_SIZE;
803 uint32_t op_status = 0U;
804
805 if ((dst_size == NULL) || (mbox_error == NULL)) {
806 return INTEL_SIP_SMC_STATUS_REJECTED;
807 }
808
809 if (!is_address_in_ddr_range(dst_addr, *dst_size)) {
810 return INTEL_SIP_SMC_STATUS_REJECTED;
811 }
812
813 fcs_cs_key_payload payload = {
814 session_id,
815 RESERVED_AS_ZERO,
816 RESERVED_AS_ZERO,
817 key_id
818 };
819
820 payload_size = sizeof(payload) / MBOX_WORD_BYTE;
821
822 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_GET_CS_KEY_INFO,
823 (uint32_t *) &payload, payload_size,
824 CMD_CASUAL, (uint32_t *) dst_addr, &resp_len);
825
826 if (resp_len > 0) {
Jit Loon Lim21165ab2023-03-27 15:19:53 +0800827 inv_dcache_range(dst_addr, (resp_len * MBOX_WORD_BYTE)); /* flush cache before mmio read to avoid reading old values */
Sieu Mun Tangfb1f6e92022-05-09 14:16:14 +0800828 op_status = mmio_read_32(dst_addr) &
829 FCS_CS_KEY_RESP_STATUS_MASK;
830 }
831
832 if (status < 0) {
833 *mbox_error = (-status) | (op_status << FCS_CS_KEY_RESP_STATUS_OFFSET);
834 return INTEL_SIP_SMC_STATUS_ERROR;
835 }
836
837 *dst_size = resp_len * MBOX_WORD_BYTE;
838 flush_dcache_range(dst_addr, *dst_size);
839
840 return INTEL_SIP_SMC_STATUS_OK;
841}
Sieu Mun Tangd907cc32022-05-10 17:24:05 +0800842
843int intel_fcs_get_digest_init(uint32_t session_id, uint32_t context_id,
844 uint32_t key_id, uint32_t param_size,
845 uint64_t param_data, uint32_t *mbox_error)
846{
847 return intel_fcs_crypto_service_init(session_id, context_id,
848 key_id, param_size, param_data,
849 (void *) &fcs_sha_get_digest_param,
850 mbox_error);
851}
852
Sieu Mun Tang527df9f2022-04-28 16:28:48 +0800853int intel_fcs_get_digest_update_finalize(uint32_t session_id,
854 uint32_t context_id, uint32_t src_addr,
855 uint32_t src_size, uint64_t dst_addr,
856 uint32_t *dst_size, uint8_t is_finalised,
Sieu Mun Tangd907cc32022-05-10 17:24:05 +0800857 uint32_t *mbox_error)
858{
859 int status;
860 uint32_t i;
Sieu Mun Tang527df9f2022-04-28 16:28:48 +0800861 uint32_t flag;
862 uint32_t crypto_header;
Boon Khai Ngd2df2042021-08-30 15:05:49 +0800863 uint32_t resp_len;
Sieu Mun Tangd907cc32022-05-10 17:24:05 +0800864 uint32_t payload[FCS_GET_DIGEST_CMD_MAX_WORD_SIZE] = {0U};
865
866 if (dst_size == NULL || mbox_error == NULL) {
867 return INTEL_SIP_SMC_STATUS_REJECTED;
868 }
869
870 if (fcs_sha_get_digest_param.session_id != session_id ||
871 fcs_sha_get_digest_param.context_id != context_id) {
872 return INTEL_SIP_SMC_STATUS_REJECTED;
873 }
874
875 /* Source data must be 8 bytes aligned */
876 if (!is_8_bytes_aligned(src_size)) {
877 return INTEL_SIP_SMC_STATUS_REJECTED;
878 }
879
880 if (!is_address_in_ddr_range(src_addr, src_size) ||
881 !is_address_in_ddr_range(dst_addr, *dst_size)) {
882 return INTEL_SIP_SMC_STATUS_REJECTED;
883 }
884
Boon Khai Ngd2df2042021-08-30 15:05:49 +0800885 resp_len = *dst_size / MBOX_WORD_BYTE;
886
Sieu Mun Tang527df9f2022-04-28 16:28:48 +0800887 /* Prepare crypto header */
888 flag = 0;
889
890 if (fcs_sha_get_digest_param.is_updated) {
891 fcs_sha_get_digest_param.crypto_param_size = 0;
892 } else {
893 flag |= FCS_CS_FIELD_FLAG_INIT;
894 }
895
896 if (is_finalised != 0U) {
897 flag |= FCS_CS_FIELD_FLAG_FINALIZE;
898 } else {
899 flag |= FCS_CS_FIELD_FLAG_UPDATE;
900 fcs_sha_get_digest_param.is_updated = 1;
901 }
902
903 crypto_header = ((flag << FCS_CS_FIELD_FLAG_OFFSET) |
904 (fcs_sha_get_digest_param.crypto_param_size &
905 FCS_CS_FIELD_SIZE_MASK));
906
Sieu Mun Tangd907cc32022-05-10 17:24:05 +0800907 /* Prepare command payload */
908 i = 0;
Sieu Mun Tangd907cc32022-05-10 17:24:05 +0800909 payload[i] = fcs_sha_get_digest_param.session_id;
910 i++;
911 payload[i] = fcs_sha_get_digest_param.context_id;
912 i++;
Sieu Mun Tang527df9f2022-04-28 16:28:48 +0800913 payload[i] = crypto_header;
Sieu Mun Tangd907cc32022-05-10 17:24:05 +0800914 i++;
Sieu Mun Tang527df9f2022-04-28 16:28:48 +0800915
916 if ((crypto_header >> FCS_CS_FIELD_FLAG_OFFSET) &
917 FCS_CS_FIELD_FLAG_INIT) {
918 payload[i] = fcs_sha_get_digest_param.key_id;
919 i++;
920 /* Crypto parameters */
921 payload[i] = fcs_sha_get_digest_param.crypto_param
922 & INTEL_SIP_SMC_FCS_SHA_MODE_MASK;
923 payload[i] |= ((fcs_sha_get_digest_param.crypto_param
924 >> INTEL_SIP_SMC_FCS_DIGEST_SIZE_OFFSET)
925 & INTEL_SIP_SMC_FCS_DIGEST_SIZE_MASK)
926 << FCS_SHA_HMAC_CRYPTO_PARAM_SIZE_OFFSET;
927 i++;
928 }
Sieu Mun Tangd907cc32022-05-10 17:24:05 +0800929 /* Data source address and size */
930 payload[i] = src_addr;
931 i++;
932 payload[i] = src_size;
933 i++;
934
935 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_GET_DIGEST_REQ,
936 payload, i, CMD_CASUAL,
937 (uint32_t *) dst_addr, &resp_len);
938
Sieu Mun Tang527df9f2022-04-28 16:28:48 +0800939 if (is_finalised != 0U) {
940 memset((void *)&fcs_sha_get_digest_param, 0,
941 sizeof(fcs_crypto_service_data));
942 }
Sieu Mun Tangd907cc32022-05-10 17:24:05 +0800943
944 if (status < 0) {
945 *mbox_error = -status;
946 return INTEL_SIP_SMC_STATUS_ERROR;
947 }
948
949 *dst_size = resp_len * MBOX_WORD_BYTE;
950 flush_dcache_range(dst_addr, *dst_size);
951
952 return INTEL_SIP_SMC_STATUS_OK;
953}
Sieu Mun Tang583149a2022-05-10 17:27:12 +0800954
Sieu Mun Tangbd8da632022-09-28 15:58:28 +0800955int intel_fcs_get_digest_smmu_update_finalize(uint32_t session_id,
956 uint32_t context_id, uint32_t src_addr,
957 uint32_t src_size, uint64_t dst_addr,
958 uint32_t *dst_size, uint8_t is_finalised,
959 uint32_t *mbox_error, uint32_t *send_id)
960{
961 int status;
962 uint32_t i;
963 uint32_t flag;
964 uint32_t crypto_header;
965 uint32_t resp_len;
966 uint32_t payload[FCS_GET_DIGEST_CMD_MAX_WORD_SIZE] = {0U};
967
968 /* Source data must be 8 bytes aligned */
969 if (dst_size == NULL || mbox_error == NULL ||
970 !is_8_bytes_aligned(src_size)) {
971 return INTEL_SIP_SMC_STATUS_REJECTED;
972 }
973
974 if (fcs_sha_get_digest_param.session_id != session_id ||
975 fcs_sha_get_digest_param.context_id != context_id) {
976 return INTEL_SIP_SMC_STATUS_REJECTED;
977 }
978
979 if (!is_address_in_ddr_range(src_addr, src_size) ||
980 !is_address_in_ddr_range(dst_addr, *dst_size)) {
981 return INTEL_SIP_SMC_STATUS_REJECTED;
982 }
983
984 resp_len = *dst_size / MBOX_WORD_BYTE;
985
986 /* Prepare crypto header */
987 flag = 0;
988
989 if (fcs_sha_get_digest_param.is_updated) {
990 fcs_sha_get_digest_param.crypto_param_size = 0;
991 } else {
992 flag |= FCS_CS_FIELD_FLAG_INIT;
993 }
994
995 if (is_finalised != 0U) {
996 flag |= FCS_CS_FIELD_FLAG_FINALIZE;
997 } else {
998 flag |= FCS_CS_FIELD_FLAG_UPDATE;
999 fcs_sha_get_digest_param.is_updated = 1;
1000 }
1001
1002 crypto_header = ((flag << FCS_CS_FIELD_FLAG_OFFSET) |
1003 (fcs_sha_get_digest_param.crypto_param_size &
1004 FCS_CS_FIELD_SIZE_MASK));
1005
1006 /* Prepare command payload */
1007 i = 0;
1008 payload[i] = fcs_sha_get_digest_param.session_id;
1009 i++;
1010 payload[i] = fcs_sha_get_digest_param.context_id;
1011 i++;
1012 payload[i] = crypto_header;
1013 i++;
1014
1015 if ((crypto_header >> FCS_CS_FIELD_FLAG_OFFSET) &
1016 FCS_CS_FIELD_FLAG_INIT) {
1017 payload[i] = fcs_sha_get_digest_param.key_id;
1018 i++;
1019 /* Crypto parameters */
1020 payload[i] = fcs_sha_get_digest_param.crypto_param
1021 & INTEL_SIP_SMC_FCS_SHA_MODE_MASK;
1022 payload[i] |= ((fcs_sha_get_digest_param.crypto_param
1023 >> INTEL_SIP_SMC_FCS_DIGEST_SIZE_OFFSET)
1024 & INTEL_SIP_SMC_FCS_DIGEST_SIZE_MASK)
1025 << FCS_SHA_HMAC_CRYPTO_PARAM_SIZE_OFFSET;
1026 i++;
1027 }
1028 /* Data source address and size */
1029 payload[i] = src_addr;
1030 i++;
1031 payload[i] = src_size;
1032 i++;
1033
1034 status = mailbox_send_cmd_async(send_id, MBOX_FCS_GET_DIGEST_REQ,
1035 payload, i, CMD_INDIRECT);
1036
1037 if (is_finalised != 0U) {
1038 memset((void *)&fcs_sha_get_digest_param, 0,
1039 sizeof(fcs_crypto_service_data));
1040 }
1041
1042 if (status < 0) {
1043 *mbox_error = -status;
1044 return INTEL_SIP_SMC_STATUS_ERROR;
1045 }
1046
1047 *dst_size = resp_len * MBOX_WORD_BYTE;
1048 flush_dcache_range(dst_addr, *dst_size);
1049
1050 return INTEL_SIP_SMC_STATUS_OK;
1051}
1052
Sieu Mun Tang583149a2022-05-10 17:27:12 +08001053int intel_fcs_mac_verify_init(uint32_t session_id, uint32_t context_id,
1054 uint32_t key_id, uint32_t param_size,
1055 uint64_t param_data, uint32_t *mbox_error)
1056{
1057 return intel_fcs_crypto_service_init(session_id, context_id,
1058 key_id, param_size, param_data,
1059 (void *) &fcs_sha_mac_verify_param,
1060 mbox_error);
1061}
1062
Sieu Mun Tang527df9f2022-04-28 16:28:48 +08001063int intel_fcs_mac_verify_update_finalize(uint32_t session_id,
1064 uint32_t context_id, uint32_t src_addr,
1065 uint32_t src_size, uint64_t dst_addr,
1066 uint32_t *dst_size, uint32_t data_size,
1067 uint8_t is_finalised, uint32_t *mbox_error)
Sieu Mun Tang583149a2022-05-10 17:27:12 +08001068{
1069 int status;
1070 uint32_t i;
Sieu Mun Tang527df9f2022-04-28 16:28:48 +08001071 uint32_t flag;
1072 uint32_t crypto_header;
Boon Khai Ngd2df2042021-08-30 15:05:49 +08001073 uint32_t resp_len;
Sieu Mun Tang583149a2022-05-10 17:27:12 +08001074 uint32_t payload[FCS_MAC_VERIFY_CMD_MAX_WORD_SIZE] = {0U};
1075 uintptr_t mac_offset;
1076
1077 if (dst_size == NULL || mbox_error == NULL) {
1078 return INTEL_SIP_SMC_STATUS_REJECTED;
1079 }
1080
1081 if (fcs_sha_mac_verify_param.session_id != session_id ||
1082 fcs_sha_mac_verify_param.context_id != context_id) {
1083 return INTEL_SIP_SMC_STATUS_REJECTED;
1084 }
1085
Sieu Mun Tang8482cb62022-06-24 11:11:41 +08001086 if (data_size > src_size) {
Sieu Mun Tang583149a2022-05-10 17:27:12 +08001087 return INTEL_SIP_SMC_STATUS_REJECTED;
1088 }
1089
1090 if (!is_size_4_bytes_aligned(src_size) ||
1091 !is_8_bytes_aligned(data_size)) {
1092 return INTEL_SIP_SMC_STATUS_REJECTED;
1093 }
1094
1095 if (!is_address_in_ddr_range(src_addr, src_size) ||
1096 !is_address_in_ddr_range(dst_addr, *dst_size)) {
1097 return INTEL_SIP_SMC_STATUS_REJECTED;
1098 }
1099
Boon Khai Ngd2df2042021-08-30 15:05:49 +08001100 resp_len = *dst_size / MBOX_WORD_BYTE;
1101
Sieu Mun Tang527df9f2022-04-28 16:28:48 +08001102 /* Prepare crypto header */
1103 flag = 0;
1104
1105 if (fcs_sha_mac_verify_param.is_updated) {
1106 fcs_sha_mac_verify_param.crypto_param_size = 0;
1107 } else {
1108 flag |= FCS_CS_FIELD_FLAG_INIT;
1109 }
1110
1111 if (is_finalised) {
1112 flag |= FCS_CS_FIELD_FLAG_FINALIZE;
1113 } else {
1114 flag |= FCS_CS_FIELD_FLAG_UPDATE;
1115 fcs_sha_mac_verify_param.is_updated = 1;
1116 }
1117
1118 crypto_header = ((flag << FCS_CS_FIELD_FLAG_OFFSET) |
1119 (fcs_sha_mac_verify_param.crypto_param_size &
1120 FCS_CS_FIELD_SIZE_MASK));
1121
Sieu Mun Tang583149a2022-05-10 17:27:12 +08001122 /* Prepare command payload */
1123 i = 0;
Sieu Mun Tang583149a2022-05-10 17:27:12 +08001124 payload[i] = fcs_sha_mac_verify_param.session_id;
1125 i++;
1126 payload[i] = fcs_sha_mac_verify_param.context_id;
1127 i++;
Sieu Mun Tang527df9f2022-04-28 16:28:48 +08001128 payload[i] = crypto_header;
Sieu Mun Tang583149a2022-05-10 17:27:12 +08001129 i++;
Sieu Mun Tang527df9f2022-04-28 16:28:48 +08001130
1131 if ((crypto_header >> FCS_CS_FIELD_FLAG_OFFSET) &
1132 FCS_CS_FIELD_FLAG_INIT) {
1133 payload[i] = fcs_sha_mac_verify_param.key_id;
1134 i++;
1135 /* Crypto parameters */
1136 payload[i] = ((fcs_sha_mac_verify_param.crypto_param
1137 >> INTEL_SIP_SMC_FCS_DIGEST_SIZE_OFFSET)
1138 & INTEL_SIP_SMC_FCS_DIGEST_SIZE_MASK)
1139 << FCS_SHA_HMAC_CRYPTO_PARAM_SIZE_OFFSET;
1140 i++;
1141 }
Sieu Mun Tang583149a2022-05-10 17:27:12 +08001142 /* Data source address and size */
1143 payload[i] = src_addr;
1144 i++;
1145 payload[i] = data_size;
1146 i++;
Sieu Mun Tang583149a2022-05-10 17:27:12 +08001147
Sieu Mun Tang527df9f2022-04-28 16:28:48 +08001148 if ((crypto_header >> FCS_CS_FIELD_FLAG_OFFSET) &
1149 FCS_CS_FIELD_FLAG_FINALIZE) {
1150 /* Copy mac data to command */
1151 mac_offset = src_addr + data_size;
1152 memcpy((uint8_t *) &payload[i], (uint8_t *) mac_offset,
1153 src_size - data_size);
1154
1155 i += (src_size - data_size) / MBOX_WORD_BYTE;
1156 }
Sieu Mun Tang583149a2022-05-10 17:27:12 +08001157
1158 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_MAC_VERIFY_REQ,
1159 payload, i, CMD_CASUAL,
1160 (uint32_t *) dst_addr, &resp_len);
1161
Sieu Mun Tang527df9f2022-04-28 16:28:48 +08001162 if (is_finalised) {
1163 memset((void *)&fcs_sha_mac_verify_param, 0,
1164 sizeof(fcs_crypto_service_data));
1165 }
Sieu Mun Tang583149a2022-05-10 17:27:12 +08001166
1167 if (status < 0) {
1168 *mbox_error = -status;
1169 return INTEL_SIP_SMC_STATUS_ERROR;
1170 }
1171
1172 *dst_size = resp_len * MBOX_WORD_BYTE;
1173 flush_dcache_range(dst_addr, *dst_size);
1174
1175 return INTEL_SIP_SMC_STATUS_OK;
1176}
Sieu Mun Tangb0c1d112022-05-10 17:30:00 +08001177
Sieu Mun Tangbd8da632022-09-28 15:58:28 +08001178int intel_fcs_mac_verify_smmu_update_finalize(uint32_t session_id,
1179 uint32_t context_id, uint32_t src_addr,
1180 uint32_t src_size, uint64_t dst_addr,
1181 uint32_t *dst_size, uint32_t data_size,
1182 uint8_t is_finalised, uint32_t *mbox_error,
1183 uint32_t *send_id)
1184{
1185 int status;
1186 uint32_t i;
1187 uint32_t flag;
1188 uint32_t crypto_header;
1189 uint32_t resp_len;
1190 uint32_t payload[FCS_MAC_VERIFY_CMD_MAX_WORD_SIZE] = {0U};
1191 uintptr_t mac_offset;
1192
1193 /*
1194 * Source data must be 4 bytes aligned
1195 * User data must be 8 bytes aligned
1196 */
1197 if (dst_size == NULL || mbox_error == NULL ||
1198 !is_size_4_bytes_aligned(src_size) ||
1199 !is_8_bytes_aligned(data_size)) {
1200 return INTEL_SIP_SMC_STATUS_REJECTED;
1201 }
1202
1203 if (data_size > src_size) {
1204 return INTEL_SIP_SMC_STATUS_REJECTED;
1205 }
1206
1207 if (fcs_sha_mac_verify_param.session_id != session_id ||
1208 fcs_sha_mac_verify_param.context_id != context_id) {
1209 return INTEL_SIP_SMC_STATUS_REJECTED;
1210 }
1211
1212 if (!is_address_in_ddr_range(src_addr, src_size) ||
1213 !is_address_in_ddr_range(dst_addr, *dst_size)) {
1214 return INTEL_SIP_SMC_STATUS_REJECTED;
1215 }
1216
1217 resp_len = *dst_size / MBOX_WORD_BYTE;
1218
1219 /* Prepare crypto header */
1220 flag = 0;
1221
1222 if (fcs_sha_mac_verify_param.is_updated) {
1223 fcs_sha_mac_verify_param.crypto_param_size = 0;
1224 } else {
1225 flag |= FCS_CS_FIELD_FLAG_INIT;
1226 }
1227
1228 if (is_finalised) {
1229 flag |= FCS_CS_FIELD_FLAG_FINALIZE;
1230 } else {
1231 flag |= FCS_CS_FIELD_FLAG_UPDATE;
1232 fcs_sha_mac_verify_param.is_updated = 1;
1233 }
1234
1235 crypto_header = ((flag << FCS_CS_FIELD_FLAG_OFFSET) |
1236 (fcs_sha_mac_verify_param.crypto_param_size &
1237 FCS_CS_FIELD_SIZE_MASK));
1238
1239 /* Prepare command payload */
1240 i = 0;
1241 payload[i] = fcs_sha_mac_verify_param.session_id;
1242 i++;
1243 payload[i] = fcs_sha_mac_verify_param.context_id;
1244 i++;
1245 payload[i] = crypto_header;
1246 i++;
1247
1248 if ((crypto_header >> FCS_CS_FIELD_FLAG_OFFSET) &
1249 FCS_CS_FIELD_FLAG_INIT) {
1250 payload[i] = fcs_sha_mac_verify_param.key_id;
1251 i++;
1252 /* Crypto parameters */
1253 payload[i] = ((fcs_sha_mac_verify_param.crypto_param
1254 >> INTEL_SIP_SMC_FCS_DIGEST_SIZE_OFFSET)
1255 & INTEL_SIP_SMC_FCS_DIGEST_SIZE_MASK)
1256 << FCS_SHA_HMAC_CRYPTO_PARAM_SIZE_OFFSET;
1257 i++;
1258 }
1259 /* Data source address and size */
1260 payload[i] = src_addr;
1261 i++;
1262 payload[i] = data_size;
1263 i++;
1264
1265 if ((crypto_header >> FCS_CS_FIELD_FLAG_OFFSET) &
1266 FCS_CS_FIELD_FLAG_FINALIZE) {
1267 /* Copy mac data to command
1268 * Using dst_addr (physical address) to store mac_offset
1269 * mac_offset = MAC data
1270 */
1271 mac_offset = dst_addr;
1272 memcpy((uint8_t *) &payload[i], (uint8_t *) mac_offset,
1273 src_size - data_size);
1274
Sieu Mun Tang73d03842023-03-21 15:11:08 +08001275 memset((void *) dst_addr, 0, *dst_size);
Sieu Mun Tangbd8da632022-09-28 15:58:28 +08001276
1277 i += (src_size - data_size) / MBOX_WORD_BYTE;
1278 }
1279
1280 status = mailbox_send_cmd_async(send_id, MBOX_FCS_MAC_VERIFY_REQ,
1281 payload, i, CMD_INDIRECT);
1282
1283 if (is_finalised) {
1284 memset((void *)&fcs_sha_mac_verify_param, 0,
1285 sizeof(fcs_crypto_service_data));
1286 }
1287
1288 if (status < 0) {
1289 *mbox_error = -status;
1290 return INTEL_SIP_SMC_STATUS_ERROR;
1291 }
1292
1293 *dst_size = resp_len * MBOX_WORD_BYTE;
1294 flush_dcache_range(dst_addr, *dst_size);
1295
1296 return INTEL_SIP_SMC_STATUS_OK;
1297}
1298
Sieu Mun Tang8aa05ad2022-05-10 17:50:30 +08001299int intel_fcs_ecdsa_hash_sign_init(uint32_t session_id, uint32_t context_id,
1300 uint32_t key_id, uint32_t param_size,
1301 uint64_t param_data, uint32_t *mbox_error)
1302{
1303 return intel_fcs_crypto_service_init(session_id, context_id,
1304 key_id, param_size, param_data,
1305 (void *) &fcs_ecdsa_hash_sign_param,
1306 mbox_error);
1307}
1308
1309int intel_fcs_ecdsa_hash_sign_finalize(uint32_t session_id, uint32_t context_id,
1310 uint32_t src_addr, uint32_t src_size,
1311 uint64_t dst_addr, uint32_t *dst_size,
1312 uint32_t *mbox_error)
1313{
1314 int status;
1315 uint32_t i;
1316 uint32_t payload[FCS_ECDSA_HASH_SIGN_CMD_MAX_WORD_SIZE] = {0U};
Boon Khai Ngd2df2042021-08-30 15:05:49 +08001317 uint32_t resp_len;
Sieu Mun Tang8aa05ad2022-05-10 17:50:30 +08001318 uintptr_t hash_data_addr;
1319
1320 if ((dst_size == NULL) || (mbox_error == NULL)) {
1321 return INTEL_SIP_SMC_STATUS_REJECTED;
1322 }
1323
1324 if (fcs_ecdsa_hash_sign_param.session_id != session_id ||
1325 fcs_ecdsa_hash_sign_param.context_id != context_id) {
1326 return INTEL_SIP_SMC_STATUS_REJECTED;
1327 }
1328
1329 if (!is_address_in_ddr_range(src_addr, src_size) ||
1330 !is_address_in_ddr_range(dst_addr, *dst_size)) {
1331 return INTEL_SIP_SMC_STATUS_REJECTED;
1332 }
1333
Boon Khai Ngd2df2042021-08-30 15:05:49 +08001334 resp_len = *dst_size / MBOX_WORD_BYTE;
1335
Sieu Mun Tang8aa05ad2022-05-10 17:50:30 +08001336 /* Prepare command payload */
1337 /* Crypto header */
1338 i = 0;
1339 payload[i] = fcs_ecdsa_hash_sign_param.session_id;
1340 i++;
1341 payload[i] = fcs_ecdsa_hash_sign_param.context_id;
1342
1343 i++;
1344 payload[i] = fcs_ecdsa_hash_sign_param.crypto_param_size
1345 & FCS_CS_FIELD_SIZE_MASK;
1346 payload[i] |= (FCS_CS_FIELD_FLAG_INIT | FCS_CS_FIELD_FLAG_UPDATE
1347 | FCS_CS_FIELD_FLAG_FINALIZE)
1348 << FCS_CS_FIELD_FLAG_OFFSET;
1349 i++;
1350 payload[i] = fcs_ecdsa_hash_sign_param.key_id;
1351
1352 /* Crypto parameters */
1353 i++;
1354 payload[i] = fcs_ecdsa_hash_sign_param.crypto_param
1355 & INTEL_SIP_SMC_FCS_ECC_ALGO_MASK;
1356
1357 /* Hash Data */
1358 i++;
1359 hash_data_addr = src_addr;
1360 memcpy((uint8_t *) &payload[i], (uint8_t *) hash_data_addr,
1361 src_size);
1362
1363 i += src_size / MBOX_WORD_BYTE;
1364
1365 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_ECDSA_HASH_SIGN_REQ,
1366 payload, i, CMD_CASUAL, (uint32_t *) dst_addr,
1367 &resp_len);
1368
1369 memset((void *) &fcs_ecdsa_hash_sign_param,
1370 0, sizeof(fcs_crypto_service_data));
1371
1372 if (status < 0) {
1373 *mbox_error = -status;
1374 return INTEL_SIP_SMC_STATUS_ERROR;
1375 }
1376
1377 *dst_size = resp_len * MBOX_WORD_BYTE;
1378 flush_dcache_range(dst_addr, *dst_size);
1379
1380 return INTEL_SIP_SMC_STATUS_OK;
1381}
1382
Sieu Mun Tang59357e82022-05-10 17:53:32 +08001383int intel_fcs_ecdsa_hash_sig_verify_init(uint32_t session_id, uint32_t context_id,
1384 uint32_t key_id, uint32_t param_size,
1385 uint64_t param_data, uint32_t *mbox_error)
1386{
1387 return intel_fcs_crypto_service_init(session_id, context_id,
1388 key_id, param_size, param_data,
1389 (void *) &fcs_ecdsa_hash_sig_verify_param,
1390 mbox_error);
1391}
1392
1393int intel_fcs_ecdsa_hash_sig_verify_finalize(uint32_t session_id, uint32_t context_id,
1394 uint32_t src_addr, uint32_t src_size,
1395 uint64_t dst_addr, uint32_t *dst_size,
1396 uint32_t *mbox_error)
1397{
1398 int status;
1399 uint32_t i = 0;
1400 uint32_t payload[FCS_ECDSA_HASH_SIG_VERIFY_CMD_MAX_WORD_SIZE] = {0U};
Boon Khai Ngd2df2042021-08-30 15:05:49 +08001401 uint32_t resp_len;
Sieu Mun Tang59357e82022-05-10 17:53:32 +08001402 uintptr_t hash_sig_pubkey_addr;
1403
1404 if ((dst_size == NULL) || (mbox_error == NULL)) {
1405 return INTEL_SIP_SMC_STATUS_REJECTED;
1406 }
1407
1408 if (fcs_ecdsa_hash_sig_verify_param.session_id != session_id ||
1409 fcs_ecdsa_hash_sig_verify_param.context_id != context_id) {
1410 return INTEL_SIP_SMC_STATUS_REJECTED;
1411 }
1412
1413 if (!is_address_in_ddr_range(src_addr, src_size) ||
1414 !is_address_in_ddr_range(dst_addr, *dst_size)) {
1415 return INTEL_SIP_SMC_STATUS_REJECTED;
1416 }
1417
Boon Khai Ngd2df2042021-08-30 15:05:49 +08001418 resp_len = *dst_size / MBOX_WORD_BYTE;
1419
Sieu Mun Tang59357e82022-05-10 17:53:32 +08001420 /* Prepare command payload */
1421 /* Crypto header */
1422 i = 0;
1423 payload[i] = fcs_ecdsa_hash_sig_verify_param.session_id;
1424
1425 i++;
1426 payload[i] = fcs_ecdsa_hash_sig_verify_param.context_id;
1427
1428 i++;
1429 payload[i] = fcs_ecdsa_hash_sig_verify_param.crypto_param_size
1430 & FCS_CS_FIELD_SIZE_MASK;
1431 payload[i] |= (FCS_CS_FIELD_FLAG_INIT | FCS_CS_FIELD_FLAG_UPDATE
1432 | FCS_CS_FIELD_FLAG_FINALIZE)
1433 << FCS_CS_FIELD_FLAG_OFFSET;
1434
1435 i++;
1436 payload[i] = fcs_ecdsa_hash_sig_verify_param.key_id;
1437
1438 /* Crypto parameters */
1439 i++;
1440 payload[i] = fcs_ecdsa_hash_sig_verify_param.crypto_param
1441 & INTEL_SIP_SMC_FCS_ECC_ALGO_MASK;
1442
1443 /* Hash Data Word, Signature Data Word and Public Key Data word */
1444 i++;
1445 hash_sig_pubkey_addr = src_addr;
1446 memcpy((uint8_t *) &payload[i],
1447 (uint8_t *) hash_sig_pubkey_addr, src_size);
1448
1449 i += (src_size / MBOX_WORD_BYTE);
1450
1451 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_ECDSA_HASH_SIG_VERIFY,
1452 payload, i, CMD_CASUAL, (uint32_t *) dst_addr,
1453 &resp_len);
1454
1455 memset((void *)&fcs_ecdsa_hash_sig_verify_param,
1456 0, sizeof(fcs_crypto_service_data));
1457
1458 if (status < 0) {
1459 *mbox_error = -status;
1460 return INTEL_SIP_SMC_STATUS_ERROR;
1461 }
1462
1463 *dst_size = resp_len * MBOX_WORD_BYTE;
1464 flush_dcache_range(dst_addr, *dst_size);
1465
1466 return INTEL_SIP_SMC_STATUS_OK;
1467}
1468
Sieu Mun Tang153ecfb2022-05-10 17:39:26 +08001469int intel_fcs_ecdsa_sha2_data_sign_init(uint32_t session_id,
1470 uint32_t context_id, uint32_t key_id,
1471 uint32_t param_size, uint64_t param_data,
1472 uint32_t *mbox_error)
1473{
1474 return intel_fcs_crypto_service_init(session_id, context_id,
1475 key_id, param_size, param_data,
1476 (void *) &fcs_sha2_data_sign_param,
1477 mbox_error);
1478}
1479
Sieu Mun Tange77d37d2022-04-28 16:23:20 +08001480int intel_fcs_ecdsa_sha2_data_sign_update_finalize(uint32_t session_id,
Sieu Mun Tang153ecfb2022-05-10 17:39:26 +08001481 uint32_t context_id, uint32_t src_addr,
1482 uint32_t src_size, uint64_t dst_addr,
Sieu Mun Tange77d37d2022-04-28 16:23:20 +08001483 uint32_t *dst_size, uint8_t is_finalised,
1484 uint32_t *mbox_error)
Sieu Mun Tang153ecfb2022-05-10 17:39:26 +08001485{
1486 int status;
1487 int i;
Sieu Mun Tange77d37d2022-04-28 16:23:20 +08001488 uint32_t flag;
1489 uint32_t crypto_header;
Sieu Mun Tang153ecfb2022-05-10 17:39:26 +08001490 uint32_t payload[FCS_ECDSA_SHA2_DATA_SIGN_CMD_MAX_WORD_SIZE] = {0U};
Boon Khai Ngd2df2042021-08-30 15:05:49 +08001491 uint32_t resp_len;
Sieu Mun Tang153ecfb2022-05-10 17:39:26 +08001492
1493 if ((dst_size == NULL) || (mbox_error == NULL)) {
1494 return INTEL_SIP_SMC_STATUS_REJECTED;
1495 }
1496
1497 if (fcs_sha2_data_sign_param.session_id != session_id ||
1498 fcs_sha2_data_sign_param.context_id != context_id) {
1499 return INTEL_SIP_SMC_STATUS_REJECTED;
1500 }
1501
1502 /* Source data must be 8 bytes aligned */
1503 if (!is_8_bytes_aligned(src_size)) {
1504 return INTEL_SIP_SMC_STATUS_REJECTED;
1505 }
1506
1507 if (!is_address_in_ddr_range(src_addr, src_size) ||
1508 !is_address_in_ddr_range(dst_addr, *dst_size)) {
1509 return INTEL_SIP_SMC_STATUS_REJECTED;
1510 }
1511
Boon Khai Ngd2df2042021-08-30 15:05:49 +08001512 resp_len = *dst_size / MBOX_WORD_BYTE;
1513
Sieu Mun Tange77d37d2022-04-28 16:23:20 +08001514 /* Prepare crypto header */
1515 flag = 0;
1516 if (fcs_sha2_data_sign_param.is_updated) {
1517 fcs_sha2_data_sign_param.crypto_param_size = 0;
1518 } else {
1519 flag |= FCS_CS_FIELD_FLAG_INIT;
1520 }
1521
1522 if (is_finalised != 0U) {
1523 flag |= FCS_CS_FIELD_FLAG_FINALIZE;
1524 } else {
1525 flag |= FCS_CS_FIELD_FLAG_UPDATE;
1526 fcs_sha2_data_sign_param.is_updated = 1;
1527 }
1528 crypto_header = (flag << FCS_CS_FIELD_FLAG_OFFSET) |
1529 fcs_sha2_data_sign_param.crypto_param_size;
1530
Sieu Mun Tang153ecfb2022-05-10 17:39:26 +08001531 /* Prepare command payload */
Sieu Mun Tang153ecfb2022-05-10 17:39:26 +08001532 i = 0;
1533 payload[i] = fcs_sha2_data_sign_param.session_id;
1534 i++;
1535 payload[i] = fcs_sha2_data_sign_param.context_id;
1536 i++;
Sieu Mun Tange77d37d2022-04-28 16:23:20 +08001537 payload[i] = crypto_header;
Sieu Mun Tang153ecfb2022-05-10 17:39:26 +08001538 i++;
Sieu Mun Tange77d37d2022-04-28 16:23:20 +08001539
1540 if ((crypto_header >> FCS_CS_FIELD_FLAG_OFFSET) &
1541 FCS_CS_FIELD_FLAG_INIT) {
1542 payload[i] = fcs_sha2_data_sign_param.key_id;
1543 /* Crypto parameters */
1544 i++;
1545 payload[i] = fcs_sha2_data_sign_param.crypto_param
1546 & INTEL_SIP_SMC_FCS_ECC_ALGO_MASK;
1547 i++;
1548 }
1549
Sieu Mun Tang153ecfb2022-05-10 17:39:26 +08001550 /* Data source address and size */
Sieu Mun Tang153ecfb2022-05-10 17:39:26 +08001551 payload[i] = src_addr;
1552 i++;
1553 payload[i] = src_size;
1554 i++;
1555 status = mailbox_send_cmd(MBOX_JOB_ID,
1556 MBOX_FCS_ECDSA_SHA2_DATA_SIGN_REQ, payload,
1557 i, CMD_CASUAL, (uint32_t *) dst_addr,
1558 &resp_len);
1559
Sieu Mun Tange77d37d2022-04-28 16:23:20 +08001560 if (is_finalised != 0U) {
1561 memset((void *)&fcs_sha2_data_sign_param, 0,
Sieu Mun Tang153ecfb2022-05-10 17:39:26 +08001562 sizeof(fcs_crypto_service_data));
Sieu Mun Tange77d37d2022-04-28 16:23:20 +08001563 }
Sieu Mun Tang153ecfb2022-05-10 17:39:26 +08001564
1565 if (status < 0) {
1566 *mbox_error = -status;
1567 return INTEL_SIP_SMC_STATUS_ERROR;
1568 }
1569
1570 *dst_size = resp_len * MBOX_WORD_BYTE;
1571 flush_dcache_range(dst_addr, *dst_size);
1572
1573 return INTEL_SIP_SMC_STATUS_OK;
1574}
1575
Sieu Mun Tangbd8da632022-09-28 15:58:28 +08001576int intel_fcs_ecdsa_sha2_data_sign_smmu_update_finalize(uint32_t session_id,
1577 uint32_t context_id, uint32_t src_addr,
1578 uint32_t src_size, uint64_t dst_addr,
1579 uint32_t *dst_size, uint8_t is_finalised,
1580 uint32_t *mbox_error, uint32_t *send_id)
1581{
1582 int status;
1583 int i;
1584 uint32_t flag;
1585 uint32_t crypto_header;
1586 uint32_t payload[FCS_ECDSA_SHA2_DATA_SIGN_CMD_MAX_WORD_SIZE] = {0U};
1587 uint32_t resp_len;
1588
1589 /* Source data must be 8 bytes aligned */
1590 if ((dst_size == NULL) || (mbox_error == NULL ||
1591 !is_8_bytes_aligned(src_size))) {
1592 return INTEL_SIP_SMC_STATUS_REJECTED;
1593 }
1594
1595 if (fcs_sha2_data_sign_param.session_id != session_id ||
1596 fcs_sha2_data_sign_param.context_id != context_id) {
1597 return INTEL_SIP_SMC_STATUS_REJECTED;
1598 }
1599
1600 if (!is_address_in_ddr_range(src_addr, src_size) ||
1601 !is_address_in_ddr_range(dst_addr, *dst_size)) {
1602 return INTEL_SIP_SMC_STATUS_REJECTED;
1603 }
1604
1605 resp_len = *dst_size / MBOX_WORD_BYTE;
1606
1607 /* Prepare crypto header */
1608 flag = 0;
1609 if (fcs_sha2_data_sign_param.is_updated) {
1610 fcs_sha2_data_sign_param.crypto_param_size = 0;
1611 } else {
1612 flag |= FCS_CS_FIELD_FLAG_INIT;
1613 }
1614
1615 if (is_finalised != 0U) {
1616 flag |= FCS_CS_FIELD_FLAG_FINALIZE;
1617 } else {
1618 flag |= FCS_CS_FIELD_FLAG_UPDATE;
1619 fcs_sha2_data_sign_param.is_updated = 1;
1620 }
1621 crypto_header = (flag << FCS_CS_FIELD_FLAG_OFFSET) |
1622 fcs_sha2_data_sign_param.crypto_param_size;
1623
1624 /* Prepare command payload */
1625 i = 0;
1626 payload[i] = fcs_sha2_data_sign_param.session_id;
1627 i++;
1628 payload[i] = fcs_sha2_data_sign_param.context_id;
1629 i++;
1630 payload[i] = crypto_header;
1631 i++;
1632
1633 if ((crypto_header >> FCS_CS_FIELD_FLAG_OFFSET) &
1634 FCS_CS_FIELD_FLAG_INIT) {
1635 payload[i] = fcs_sha2_data_sign_param.key_id;
1636 /* Crypto parameters */
1637 i++;
1638 payload[i] = fcs_sha2_data_sign_param.crypto_param
1639 & INTEL_SIP_SMC_FCS_ECC_ALGO_MASK;
1640 i++;
1641 }
1642
1643 /* Data source address and size */
1644 payload[i] = src_addr;
1645 i++;
1646 payload[i] = src_size;
1647 i++;
1648
1649 status = mailbox_send_cmd_async(send_id,
1650 MBOX_FCS_ECDSA_SHA2_DATA_SIGN_REQ,
1651 payload, i, CMD_INDIRECT);
1652
1653 if (is_finalised != 0U) {
1654 memset((void *)&fcs_sha2_data_sign_param, 0,
1655 sizeof(fcs_crypto_service_data));
1656 }
1657
1658 if (status < 0) {
1659 *mbox_error = -status;
1660 return INTEL_SIP_SMC_STATUS_ERROR;
1661 }
1662
1663 *dst_size = resp_len * MBOX_WORD_BYTE;
1664 flush_dcache_range(dst_addr, *dst_size);
1665
1666 return INTEL_SIP_SMC_STATUS_OK;
1667}
1668
Sieu Mun Tangdcaab772022-05-11 10:16:40 +08001669int intel_fcs_ecdsa_sha2_data_sig_verify_init(uint32_t session_id,
1670 uint32_t context_id, uint32_t key_id,
1671 uint32_t param_size, uint64_t param_data,
1672 uint32_t *mbox_error)
1673{
1674 return intel_fcs_crypto_service_init(session_id, context_id,
1675 key_id, param_size, param_data,
1676 (void *) &fcs_sha2_data_sig_verify_param,
1677 mbox_error);
1678}
1679
Sieu Mun Tange77d37d2022-04-28 16:23:20 +08001680int intel_fcs_ecdsa_sha2_data_sig_verify_update_finalize(uint32_t session_id,
Sieu Mun Tangdcaab772022-05-11 10:16:40 +08001681 uint32_t context_id, uint32_t src_addr,
1682 uint32_t src_size, uint64_t dst_addr,
1683 uint32_t *dst_size, uint32_t data_size,
Sieu Mun Tange77d37d2022-04-28 16:23:20 +08001684 uint8_t is_finalised, uint32_t *mbox_error)
Sieu Mun Tangdcaab772022-05-11 10:16:40 +08001685{
1686 int status;
1687 uint32_t i;
Sieu Mun Tange77d37d2022-04-28 16:23:20 +08001688 uint32_t flag;
1689 uint32_t crypto_header;
Sieu Mun Tangdcaab772022-05-11 10:16:40 +08001690 uint32_t payload[FCS_ECDSA_SHA2_DATA_SIG_VERIFY_CMD_MAX_WORD_SIZE] = {0U};
Boon Khai Ngd2df2042021-08-30 15:05:49 +08001691 uint32_t resp_len;
Sieu Mun Tangdcaab772022-05-11 10:16:40 +08001692 uintptr_t sig_pubkey_offset;
1693
1694 if ((dst_size == NULL) || (mbox_error == NULL)) {
1695 return INTEL_SIP_SMC_STATUS_REJECTED;
1696 }
1697
1698 if (fcs_sha2_data_sig_verify_param.session_id != session_id ||
1699 fcs_sha2_data_sig_verify_param.context_id != context_id) {
1700 return INTEL_SIP_SMC_STATUS_REJECTED;
1701 }
1702
1703 if (!is_size_4_bytes_aligned(src_size)) {
1704 return INTEL_SIP_SMC_STATUS_REJECTED;
1705 }
1706
1707 if (!is_8_bytes_aligned(data_size) ||
1708 !is_8_bytes_aligned(src_addr)) {
1709 return INTEL_SIP_SMC_STATUS_REJECTED;
1710 }
1711
1712 if (!is_address_in_ddr_range(src_addr, src_size) ||
1713 !is_address_in_ddr_range(dst_addr, *dst_size)) {
1714 return INTEL_SIP_SMC_STATUS_REJECTED;
1715 }
1716
Boon Khai Ngd2df2042021-08-30 15:05:49 +08001717 resp_len = *dst_size / MBOX_WORD_BYTE;
1718
Sieu Mun Tange77d37d2022-04-28 16:23:20 +08001719 /* Prepare crypto header */
1720 flag = 0;
1721 if (fcs_sha2_data_sig_verify_param.is_updated)
1722 fcs_sha2_data_sig_verify_param.crypto_param_size = 0;
1723 else
1724 flag |= FCS_CS_FIELD_FLAG_INIT;
1725
1726 if (is_finalised != 0U)
1727 flag |= FCS_CS_FIELD_FLAG_FINALIZE;
1728 else {
1729 flag |= FCS_CS_FIELD_FLAG_UPDATE;
1730 fcs_sha2_data_sig_verify_param.is_updated = 1;
1731 }
1732 crypto_header = (flag << FCS_CS_FIELD_FLAG_OFFSET) |
1733 fcs_sha2_data_sig_verify_param.crypto_param_size;
1734
Sieu Mun Tangdcaab772022-05-11 10:16:40 +08001735 /* Prepare command payload */
Sieu Mun Tangdcaab772022-05-11 10:16:40 +08001736 i = 0;
1737 payload[i] = fcs_sha2_data_sig_verify_param.session_id;
1738 i++;
1739 payload[i] = fcs_sha2_data_sig_verify_param.context_id;
1740 i++;
Sieu Mun Tange77d37d2022-04-28 16:23:20 +08001741 payload[i] = crypto_header;
Sieu Mun Tangdcaab772022-05-11 10:16:40 +08001742 i++;
Sieu Mun Tange77d37d2022-04-28 16:23:20 +08001743
1744 if ((crypto_header >> FCS_CS_FIELD_FLAG_OFFSET) &
1745 FCS_CS_FIELD_FLAG_INIT) {
1746 payload[i] = fcs_sha2_data_sig_verify_param.key_id;
1747 i++;
1748 /* Crypto parameters */
1749 payload[i] = fcs_sha2_data_sig_verify_param.crypto_param
1750 & INTEL_SIP_SMC_FCS_ECC_ALGO_MASK;
1751 i++;
1752 }
1753
Sieu Mun Tangdcaab772022-05-11 10:16:40 +08001754 /* Data source address and size */
1755 payload[i] = src_addr;
1756 i++;
1757 payload[i] = data_size;
1758 i++;
Sieu Mun Tangdcaab772022-05-11 10:16:40 +08001759
Sieu Mun Tange77d37d2022-04-28 16:23:20 +08001760 if ((crypto_header >> FCS_CS_FIELD_FLAG_OFFSET) &
1761 FCS_CS_FIELD_FLAG_FINALIZE) {
1762 /* Signature + Public Key Data */
1763 sig_pubkey_offset = src_addr + data_size;
1764 memcpy((uint8_t *) &payload[i], (uint8_t *) sig_pubkey_offset,
1765 src_size - data_size);
1766
1767 i += (src_size - data_size) / MBOX_WORD_BYTE;
1768 }
Sieu Mun Tangdcaab772022-05-11 10:16:40 +08001769
1770 status = mailbox_send_cmd(MBOX_JOB_ID,
1771 MBOX_FCS_ECDSA_SHA2_DATA_SIGN_VERIFY, payload, i,
1772 CMD_CASUAL, (uint32_t *) dst_addr, &resp_len);
1773
Sieu Mun Tange77d37d2022-04-28 16:23:20 +08001774 if (is_finalised != 0U) {
1775 memset((void *) &fcs_sha2_data_sig_verify_param, 0,
Sieu Mun Tangdcaab772022-05-11 10:16:40 +08001776 sizeof(fcs_crypto_service_data));
Sieu Mun Tange77d37d2022-04-28 16:23:20 +08001777 }
Sieu Mun Tangdcaab772022-05-11 10:16:40 +08001778
1779 if (status < 0) {
1780 *mbox_error = -status;
1781 return INTEL_SIP_SMC_STATUS_ERROR;
1782 }
1783
1784 *dst_size = resp_len * MBOX_WORD_BYTE;
1785 flush_dcache_range(dst_addr, *dst_size);
1786
1787 return INTEL_SIP_SMC_STATUS_OK;
1788}
1789
Sieu Mun Tangbd8da632022-09-28 15:58:28 +08001790int intel_fcs_ecdsa_sha2_data_sig_verify_smmu_update_finalize(uint32_t session_id,
1791 uint32_t context_id, uint32_t src_addr,
1792 uint32_t src_size, uint64_t dst_addr,
1793 uint32_t *dst_size, uint32_t data_size,
1794 uint8_t is_finalised, uint32_t *mbox_error,
1795 uint32_t *send_id)
1796{
1797 int status;
1798 uint32_t i;
1799 uint32_t flag;
1800 uint32_t crypto_header;
1801 uint32_t payload[FCS_ECDSA_SHA2_DATA_SIG_VERIFY_CMD_MAX_WORD_SIZE] = {0U};
1802 uint32_t resp_len;
1803 uintptr_t sig_pubkey_offset;
1804
1805 /*
1806 * Source data must be 4 bytes aligned
Elyes Haouas2be03c02023-02-13 09:14:48 +01001807 * Source address must be 8 bytes aligned
Sieu Mun Tangbd8da632022-09-28 15:58:28 +08001808 * User data must be 8 bytes aligned
1809 */
1810 if ((dst_size == NULL) || (mbox_error == NULL) ||
1811 !is_size_4_bytes_aligned(src_size) ||
1812 !is_8_bytes_aligned(src_addr) ||
1813 !is_8_bytes_aligned(data_size)) {
1814 return INTEL_SIP_SMC_STATUS_REJECTED;
1815 }
1816
1817 if (fcs_sha2_data_sig_verify_param.session_id != session_id ||
1818 fcs_sha2_data_sig_verify_param.context_id != context_id) {
1819 return INTEL_SIP_SMC_STATUS_REJECTED;
1820 }
1821
1822 if (!is_address_in_ddr_range(src_addr, src_size) ||
1823 !is_address_in_ddr_range(dst_addr, *dst_size)) {
1824 return INTEL_SIP_SMC_STATUS_REJECTED;
1825 }
1826
1827 resp_len = *dst_size / MBOX_WORD_BYTE;
1828
1829 /* Prepare crypto header */
1830 flag = 0;
1831 if (fcs_sha2_data_sig_verify_param.is_updated)
1832 fcs_sha2_data_sig_verify_param.crypto_param_size = 0;
1833 else
1834 flag |= FCS_CS_FIELD_FLAG_INIT;
1835
1836 if (is_finalised != 0U)
1837 flag |= FCS_CS_FIELD_FLAG_FINALIZE;
1838 else {
1839 flag |= FCS_CS_FIELD_FLAG_UPDATE;
1840 fcs_sha2_data_sig_verify_param.is_updated = 1;
1841 }
1842 crypto_header = (flag << FCS_CS_FIELD_FLAG_OFFSET) |
1843 fcs_sha2_data_sig_verify_param.crypto_param_size;
1844
1845 /* Prepare command payload */
1846 i = 0;
1847 payload[i] = fcs_sha2_data_sig_verify_param.session_id;
1848 i++;
1849 payload[i] = fcs_sha2_data_sig_verify_param.context_id;
1850 i++;
1851 payload[i] = crypto_header;
1852 i++;
1853
1854 if ((crypto_header >> FCS_CS_FIELD_FLAG_OFFSET) &
1855 FCS_CS_FIELD_FLAG_INIT) {
1856 payload[i] = fcs_sha2_data_sig_verify_param.key_id;
1857 i++;
1858 /* Crypto parameters */
1859 payload[i] = fcs_sha2_data_sig_verify_param.crypto_param
1860 & INTEL_SIP_SMC_FCS_ECC_ALGO_MASK;
1861 i++;
1862 }
1863
1864 /* Data source address and size */
1865 payload[i] = src_addr;
1866 i++;
1867 payload[i] = data_size;
1868 i++;
1869
1870 if ((crypto_header >> FCS_CS_FIELD_FLAG_OFFSET) &
1871 FCS_CS_FIELD_FLAG_FINALIZE) {
1872 /* Copy mac data to command
1873 * Using dst_addr (physical address) to store sig_pubkey_offset
1874 * sig_pubkey_offset is Signature + Public Key Data
1875 */
1876 sig_pubkey_offset = dst_addr;
1877 memcpy((uint8_t *) &payload[i], (uint8_t *) sig_pubkey_offset,
1878 src_size - data_size);
1879
Sieu Mun Tang73d03842023-03-21 15:11:08 +08001880 memset((void *) dst_addr, 0, *dst_size);
Sieu Mun Tangbd8da632022-09-28 15:58:28 +08001881
1882 i += (src_size - data_size) / MBOX_WORD_BYTE;
1883 }
1884
1885 status = mailbox_send_cmd_async(send_id,
1886 MBOX_FCS_ECDSA_SHA2_DATA_SIGN_VERIFY,
1887 payload, i, CMD_INDIRECT);
1888
1889 if (is_finalised != 0U) {
1890 memset((void *) &fcs_sha2_data_sig_verify_param, 0,
1891 sizeof(fcs_crypto_service_data));
1892 }
1893
1894 if (status < 0) {
1895 *mbox_error = -status;
1896 return INTEL_SIP_SMC_STATUS_ERROR;
1897 }
1898
1899 *dst_size = resp_len * MBOX_WORD_BYTE;
1900 flush_dcache_range(dst_addr, *dst_size);
1901
1902 return INTEL_SIP_SMC_STATUS_OK;
1903}
1904
Sieu Mun Tange2f3ede2022-05-10 17:36:32 +08001905int intel_fcs_ecdsa_get_pubkey_init(uint32_t session_id, uint32_t context_id,
1906 uint32_t key_id, uint32_t param_size,
1907 uint64_t param_data, uint32_t *mbox_error)
1908{
1909 return intel_fcs_crypto_service_init(session_id, context_id,
1910 key_id, param_size, param_data,
1911 (void *) &fcs_ecdsa_get_pubkey_param,
1912 mbox_error);
1913}
1914
1915int intel_fcs_ecdsa_get_pubkey_finalize(uint32_t session_id, uint32_t context_id,
1916 uint64_t dst_addr, uint32_t *dst_size,
1917 uint32_t *mbox_error)
1918{
1919 int status;
1920 int i;
1921 uint32_t crypto_header;
Boon Khai Ngd2df2042021-08-30 15:05:49 +08001922 uint32_t ret_size;
Sieu Mun Tange2f3ede2022-05-10 17:36:32 +08001923 uint32_t payload[FCS_ECDSA_GET_PUBKEY_MAX_WORD_SIZE] = {0U};
1924
1925 if ((dst_size == NULL) || (mbox_error == NULL)) {
1926 return INTEL_SIP_SMC_STATUS_REJECTED;
1927 }
1928
1929 if (fcs_ecdsa_get_pubkey_param.session_id != session_id ||
1930 fcs_ecdsa_get_pubkey_param.context_id != context_id) {
1931 return INTEL_SIP_SMC_STATUS_REJECTED;
1932 }
1933
Boon Khai Ngd2df2042021-08-30 15:05:49 +08001934 ret_size = *dst_size / MBOX_WORD_BYTE;
1935
Sieu Mun Tange2f3ede2022-05-10 17:36:32 +08001936 crypto_header = ((FCS_CS_FIELD_FLAG_INIT |
1937 FCS_CS_FIELD_FLAG_UPDATE |
1938 FCS_CS_FIELD_FLAG_FINALIZE) <<
1939 FCS_CS_FIELD_FLAG_OFFSET) |
1940 fcs_ecdsa_get_pubkey_param.crypto_param_size;
1941 i = 0;
1942 /* Prepare command payload */
1943 payload[i] = session_id;
1944 i++;
1945 payload[i] = context_id;
1946 i++;
1947 payload[i] = crypto_header;
1948 i++;
1949 payload[i] = fcs_ecdsa_get_pubkey_param.key_id;
1950 i++;
1951 payload[i] = (uint32_t) fcs_ecdsa_get_pubkey_param.crypto_param &
1952 INTEL_SIP_SMC_FCS_ECC_ALGO_MASK;
1953 i++;
1954
1955 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_ECDSA_GET_PUBKEY,
1956 payload, i, CMD_CASUAL,
1957 (uint32_t *) dst_addr, &ret_size);
1958
1959 memset((void *) &fcs_ecdsa_get_pubkey_param, 0,
1960 sizeof(fcs_crypto_service_data));
1961
1962 if (status < 0) {
1963 *mbox_error = -status;
1964 return INTEL_SIP_SMC_STATUS_ERROR;
1965 }
1966
1967 *dst_size = ret_size * MBOX_WORD_BYTE;
1968 flush_dcache_range(dst_addr, *dst_size);
1969
1970 return INTEL_SIP_SMC_STATUS_OK;
1971}
1972
Sieu Mun Tang0675c222022-05-10 17:48:11 +08001973int intel_fcs_ecdh_request_init(uint32_t session_id, uint32_t context_id,
1974 uint32_t key_id, uint32_t param_size,
1975 uint64_t param_data, uint32_t *mbox_error)
1976{
1977 return intel_fcs_crypto_service_init(session_id, context_id,
1978 key_id, param_size, param_data,
1979 (void *) &fcs_ecdh_request_param,
1980 mbox_error);
1981}
1982
1983int intel_fcs_ecdh_request_finalize(uint32_t session_id, uint32_t context_id,
1984 uint32_t src_addr, uint32_t src_size,
1985 uint64_t dst_addr, uint32_t *dst_size,
1986 uint32_t *mbox_error)
1987{
1988 int status;
1989 uint32_t i;
1990 uint32_t payload[FCS_ECDH_REQUEST_CMD_MAX_WORD_SIZE] = {0U};
Boon Khai Ngd2df2042021-08-30 15:05:49 +08001991 uint32_t resp_len;
Sieu Mun Tang0675c222022-05-10 17:48:11 +08001992 uintptr_t pubkey;
1993
1994 if ((dst_size == NULL) || (mbox_error == NULL)) {
1995 return INTEL_SIP_SMC_STATUS_REJECTED;
1996 }
1997
1998 if (fcs_ecdh_request_param.session_id != session_id ||
1999 fcs_ecdh_request_param.context_id != context_id) {
2000 return INTEL_SIP_SMC_STATUS_REJECTED;
2001 }
2002
2003 if (!is_address_in_ddr_range(src_addr, src_size) ||
2004 !is_address_in_ddr_range(dst_addr, *dst_size)) {
2005 return INTEL_SIP_SMC_STATUS_REJECTED;
2006 }
2007
Boon Khai Ngd2df2042021-08-30 15:05:49 +08002008 resp_len = *dst_size / MBOX_WORD_BYTE;
2009
Sieu Mun Tang0675c222022-05-10 17:48:11 +08002010 /* Prepare command payload */
2011 i = 0;
2012 /* Crypto header */
2013 payload[i] = fcs_ecdh_request_param.session_id;
2014 i++;
2015 payload[i] = fcs_ecdh_request_param.context_id;
2016 i++;
2017 payload[i] = fcs_ecdh_request_param.crypto_param_size
2018 & FCS_CS_FIELD_SIZE_MASK;
2019 payload[i] |= (FCS_CS_FIELD_FLAG_INIT | FCS_CS_FIELD_FLAG_UPDATE
2020 | FCS_CS_FIELD_FLAG_FINALIZE)
2021 << FCS_CS_FIELD_FLAG_OFFSET;
2022 i++;
2023 payload[i] = fcs_ecdh_request_param.key_id;
2024 i++;
2025 /* Crypto parameters */
2026 payload[i] = fcs_ecdh_request_param.crypto_param
2027 & INTEL_SIP_SMC_FCS_ECC_ALGO_MASK;
2028 i++;
2029 /* Public key data */
2030 pubkey = src_addr;
2031 memcpy((uint8_t *) &payload[i], (uint8_t *) pubkey, src_size);
2032 i += src_size / MBOX_WORD_BYTE;
2033
2034 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_ECDH_REQUEST,
2035 payload, i, CMD_CASUAL, (uint32_t *) dst_addr,
2036 &resp_len);
2037
2038 memset((void *)&fcs_ecdh_request_param, 0,
2039 sizeof(fcs_crypto_service_data));
2040
2041 if (status < 0) {
2042 *mbox_error = -status;
2043 return INTEL_SIP_SMC_STATUS_ERROR;
2044 }
2045
2046 *dst_size = resp_len * MBOX_WORD_BYTE;
2047 flush_dcache_range(dst_addr, *dst_size);
2048
2049 return INTEL_SIP_SMC_STATUS_OK;
2050}
2051
Sieu Mun Tangb0c1d112022-05-10 17:30:00 +08002052int intel_fcs_aes_crypt_init(uint32_t session_id, uint32_t context_id,
2053 uint32_t key_id, uint64_t param_addr,
2054 uint32_t param_size, uint32_t *mbox_error)
2055{
Jit Loon Lim6f9a4cc2022-09-13 10:24:04 +08002056 /* ptr to get param_addr value */
2057 uint64_t *param_addr_ptr;
2058
2059 param_addr_ptr = (uint64_t *) param_addr;
2060
2061 /*
2062 * Since crypto param size vary between mode.
2063 * Check ECB here and limit to size 12 bytes
2064 */
2065 if (((*param_addr_ptr & FCS_CRYPTO_BLOCK_MODE_MASK) == FCS_CRYPTO_ECB_MODE) &&
2066 (param_size > FCS_CRYPTO_ECB_BUFFER_SIZE)) {
2067 return INTEL_SIP_SMC_STATUS_REJECTED;
2068 }
2069 /*
2070 * Since crypto param size vary between mode.
2071 * Check CBC/CTR here and limit to size 28 bytes
2072 */
2073 if ((((*param_addr_ptr & FCS_CRYPTO_BLOCK_MODE_MASK) == FCS_CRYPTO_CBC_MODE) ||
2074 ((*param_addr_ptr & FCS_CRYPTO_BLOCK_MODE_MASK) == FCS_CRYPTO_CTR_MODE)) &&
2075 (param_size > FCS_CRYPTO_CBC_CTR_BUFFER_SIZE)) {
2076 return INTEL_SIP_SMC_STATUS_REJECTED;
2077 }
2078
Sieu Mun Tangb0c1d112022-05-10 17:30:00 +08002079 if (mbox_error == NULL) {
2080 return INTEL_SIP_SMC_STATUS_REJECTED;
2081 }
2082
2083 memset((void *)&fcs_aes_init_payload, 0U, sizeof(fcs_aes_init_payload));
2084
2085 fcs_aes_init_payload.session_id = session_id;
2086 fcs_aes_init_payload.context_id = context_id;
2087 fcs_aes_init_payload.param_size = param_size;
2088 fcs_aes_init_payload.key_id = key_id;
2089
2090 memcpy((uint8_t *) fcs_aes_init_payload.crypto_param,
2091 (uint8_t *) param_addr, param_size);
2092
Sieu Mun Tang9bea8152022-04-28 16:15:54 +08002093 fcs_aes_init_payload.is_updated = 0;
2094
Sieu Mun Tangb0c1d112022-05-10 17:30:00 +08002095 *mbox_error = 0;
2096
2097 return INTEL_SIP_SMC_STATUS_OK;
2098}
2099
Sieu Mun Tang9bea8152022-04-28 16:15:54 +08002100int intel_fcs_aes_crypt_update_finalize(uint32_t session_id,
2101 uint32_t context_id, uint64_t src_addr,
2102 uint32_t src_size, uint64_t dst_addr,
2103 uint32_t dst_size, uint8_t is_finalised,
Sieu Mun Tangb0c1d112022-05-10 17:30:00 +08002104 uint32_t *send_id)
2105{
2106 int status;
2107 int i;
Sieu Mun Tang9bea8152022-04-28 16:15:54 +08002108 uint32_t flag;
Sieu Mun Tangb0c1d112022-05-10 17:30:00 +08002109 uint32_t crypto_header;
2110 uint32_t fcs_aes_crypt_payload[FCS_AES_CMD_MAX_WORD_SIZE];
2111
2112 if (fcs_aes_init_payload.session_id != session_id ||
2113 fcs_aes_init_payload.context_id != context_id) {
2114 return INTEL_SIP_SMC_STATUS_REJECTED;
2115 }
2116
2117 if ((!is_8_bytes_aligned(src_addr)) ||
2118 (!is_32_bytes_aligned(src_size)) ||
2119 (!is_address_in_ddr_range(src_addr, src_size))) {
2120 return INTEL_SIP_SMC_STATUS_REJECTED;
2121 }
2122
2123 if ((!is_8_bytes_aligned(dst_addr)) ||
2124 (!is_32_bytes_aligned(dst_size))) {
2125 return INTEL_SIP_SMC_STATUS_REJECTED;
2126 }
2127
2128 if ((dst_size > FCS_AES_MAX_DATA_SIZE ||
2129 dst_size < FCS_AES_MIN_DATA_SIZE) ||
2130 (src_size > FCS_AES_MAX_DATA_SIZE ||
2131 src_size < FCS_AES_MIN_DATA_SIZE)) {
2132 return INTEL_SIP_SMC_STATUS_REJECTED;
2133 }
2134
Sieu Mun Tang9bea8152022-04-28 16:15:54 +08002135 /* Prepare crypto header*/
2136 flag = 0;
2137 if (fcs_aes_init_payload.is_updated) {
2138 fcs_aes_init_payload.param_size = 0;
2139 } else {
2140 flag |= FCS_CS_FIELD_FLAG_INIT;
2141 }
2142
2143 if (is_finalised != 0U) {
2144 flag |= FCS_CS_FIELD_FLAG_FINALIZE;
2145 } else {
2146 flag |= FCS_CS_FIELD_FLAG_UPDATE;
2147 fcs_aes_init_payload.is_updated = 1;
2148 }
2149 crypto_header = (flag << FCS_CS_FIELD_FLAG_OFFSET) |
Sieu Mun Tangb0c1d112022-05-10 17:30:00 +08002150 fcs_aes_init_payload.param_size;
Sieu Mun Tang9bea8152022-04-28 16:15:54 +08002151
Sieu Mun Tangb0c1d112022-05-10 17:30:00 +08002152 i = 0U;
2153 fcs_aes_crypt_payload[i] = session_id;
2154 i++;
2155 fcs_aes_crypt_payload[i] = context_id;
2156 i++;
2157 fcs_aes_crypt_payload[i] = crypto_header;
2158 i++;
Sieu Mun Tangb0c1d112022-05-10 17:30:00 +08002159
Sieu Mun Tang9bea8152022-04-28 16:15:54 +08002160 if ((crypto_header >> FCS_CS_FIELD_FLAG_OFFSET) &
2161 FCS_CS_FIELD_FLAG_INIT) {
2162 fcs_aes_crypt_payload[i] = fcs_aes_init_payload.key_id;
2163 i++;
2164
2165 memcpy((uint8_t *) &fcs_aes_crypt_payload[i],
2166 (uint8_t *) fcs_aes_init_payload.crypto_param,
2167 fcs_aes_init_payload.param_size);
Sieu Mun Tangb0c1d112022-05-10 17:30:00 +08002168
Sieu Mun Tang9bea8152022-04-28 16:15:54 +08002169 i += fcs_aes_init_payload.param_size / MBOX_WORD_BYTE;
2170 }
Sieu Mun Tangb0c1d112022-05-10 17:30:00 +08002171
2172 fcs_aes_crypt_payload[i] = (uint32_t) src_addr;
2173 i++;
2174 fcs_aes_crypt_payload[i] = src_size;
2175 i++;
2176 fcs_aes_crypt_payload[i] = (uint32_t) dst_addr;
2177 i++;
2178 fcs_aes_crypt_payload[i] = dst_size;
2179 i++;
2180
2181 status = mailbox_send_cmd_async(send_id, MBOX_FCS_AES_CRYPT_REQ,
2182 fcs_aes_crypt_payload, i,
2183 CMD_INDIRECT);
2184
Sieu Mun Tang9bea8152022-04-28 16:15:54 +08002185 if (is_finalised != 0U) {
2186 memset((void *)&fcs_aes_init_payload, 0,
2187 sizeof(fcs_aes_init_payload));
2188 }
Sieu Mun Tangb0c1d112022-05-10 17:30:00 +08002189
2190 if (status < 0U) {
2191 return INTEL_SIP_SMC_STATUS_ERROR;
2192 }
2193
2194 return INTEL_SIP_SMC_STATUS_OK;
2195}