blob: beaa7208145d6ab67922e3db9b56cfb2cfc7575f [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;
Jit Loon Lim581ad472023-05-17 12:26:11 +08001076 uint32_t dst_size_check = 0;
Sieu Mun Tang583149a2022-05-10 17:27:12 +08001077
1078 if (dst_size == NULL || mbox_error == NULL) {
1079 return INTEL_SIP_SMC_STATUS_REJECTED;
1080 }
1081
1082 if (fcs_sha_mac_verify_param.session_id != session_id ||
1083 fcs_sha_mac_verify_param.context_id != context_id) {
1084 return INTEL_SIP_SMC_STATUS_REJECTED;
1085 }
1086
Sieu Mun Tang8482cb62022-06-24 11:11:41 +08001087 if (data_size > src_size) {
Sieu Mun Tang583149a2022-05-10 17:27:12 +08001088 return INTEL_SIP_SMC_STATUS_REJECTED;
1089 }
1090
1091 if (!is_size_4_bytes_aligned(src_size) ||
1092 !is_8_bytes_aligned(data_size)) {
1093 return INTEL_SIP_SMC_STATUS_REJECTED;
1094 }
1095
1096 if (!is_address_in_ddr_range(src_addr, src_size) ||
1097 !is_address_in_ddr_range(dst_addr, *dst_size)) {
1098 return INTEL_SIP_SMC_STATUS_REJECTED;
1099 }
1100
Jit Loon Lim581ad472023-05-17 12:26:11 +08001101 dst_size_check = *dst_size;
1102 if ((dst_size_check > FCS_MAX_DATA_SIZE ||
1103 dst_size_check < FCS_MIN_DATA_SIZE) ||
1104 (src_size > FCS_MAX_DATA_SIZE ||
1105 src_size < FCS_MIN_DATA_SIZE)) {
1106 return INTEL_SIP_SMC_STATUS_REJECTED;
1107 }
1108
Boon Khai Ngd2df2042021-08-30 15:05:49 +08001109 resp_len = *dst_size / MBOX_WORD_BYTE;
1110
Sieu Mun Tang527df9f2022-04-28 16:28:48 +08001111 /* Prepare crypto header */
1112 flag = 0;
1113
1114 if (fcs_sha_mac_verify_param.is_updated) {
1115 fcs_sha_mac_verify_param.crypto_param_size = 0;
1116 } else {
1117 flag |= FCS_CS_FIELD_FLAG_INIT;
1118 }
1119
1120 if (is_finalised) {
1121 flag |= FCS_CS_FIELD_FLAG_FINALIZE;
1122 } else {
1123 flag |= FCS_CS_FIELD_FLAG_UPDATE;
1124 fcs_sha_mac_verify_param.is_updated = 1;
1125 }
1126
1127 crypto_header = ((flag << FCS_CS_FIELD_FLAG_OFFSET) |
1128 (fcs_sha_mac_verify_param.crypto_param_size &
1129 FCS_CS_FIELD_SIZE_MASK));
1130
Sieu Mun Tang583149a2022-05-10 17:27:12 +08001131 /* Prepare command payload */
1132 i = 0;
Sieu Mun Tang583149a2022-05-10 17:27:12 +08001133 payload[i] = fcs_sha_mac_verify_param.session_id;
1134 i++;
1135 payload[i] = fcs_sha_mac_verify_param.context_id;
1136 i++;
Sieu Mun Tang527df9f2022-04-28 16:28:48 +08001137 payload[i] = crypto_header;
Sieu Mun Tang583149a2022-05-10 17:27:12 +08001138 i++;
Sieu Mun Tang527df9f2022-04-28 16:28:48 +08001139
1140 if ((crypto_header >> FCS_CS_FIELD_FLAG_OFFSET) &
1141 FCS_CS_FIELD_FLAG_INIT) {
1142 payload[i] = fcs_sha_mac_verify_param.key_id;
1143 i++;
1144 /* Crypto parameters */
1145 payload[i] = ((fcs_sha_mac_verify_param.crypto_param
1146 >> INTEL_SIP_SMC_FCS_DIGEST_SIZE_OFFSET)
1147 & INTEL_SIP_SMC_FCS_DIGEST_SIZE_MASK)
1148 << FCS_SHA_HMAC_CRYPTO_PARAM_SIZE_OFFSET;
1149 i++;
1150 }
Sieu Mun Tang583149a2022-05-10 17:27:12 +08001151 /* Data source address and size */
1152 payload[i] = src_addr;
1153 i++;
1154 payload[i] = data_size;
1155 i++;
Sieu Mun Tang583149a2022-05-10 17:27:12 +08001156
Sieu Mun Tang527df9f2022-04-28 16:28:48 +08001157 if ((crypto_header >> FCS_CS_FIELD_FLAG_OFFSET) &
1158 FCS_CS_FIELD_FLAG_FINALIZE) {
1159 /* Copy mac data to command */
1160 mac_offset = src_addr + data_size;
Jit Loon Lim581ad472023-05-17 12:26:11 +08001161
1162 if ((i + ((src_size - data_size) / MBOX_WORD_BYTE)) >
1163 FCS_MAC_VERIFY_CMD_MAX_WORD_SIZE) {
1164 return INTEL_SIP_SMC_STATUS_REJECTED;
1165 }
1166
Sieu Mun Tang527df9f2022-04-28 16:28:48 +08001167 memcpy((uint8_t *) &payload[i], (uint8_t *) mac_offset,
1168 src_size - data_size);
1169
1170 i += (src_size - data_size) / MBOX_WORD_BYTE;
1171 }
Sieu Mun Tang583149a2022-05-10 17:27:12 +08001172
1173 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_MAC_VERIFY_REQ,
1174 payload, i, CMD_CASUAL,
1175 (uint32_t *) dst_addr, &resp_len);
1176
Sieu Mun Tang527df9f2022-04-28 16:28:48 +08001177 if (is_finalised) {
1178 memset((void *)&fcs_sha_mac_verify_param, 0,
1179 sizeof(fcs_crypto_service_data));
1180 }
Sieu Mun Tang583149a2022-05-10 17:27:12 +08001181
1182 if (status < 0) {
1183 *mbox_error = -status;
1184 return INTEL_SIP_SMC_STATUS_ERROR;
1185 }
1186
1187 *dst_size = resp_len * MBOX_WORD_BYTE;
1188 flush_dcache_range(dst_addr, *dst_size);
1189
1190 return INTEL_SIP_SMC_STATUS_OK;
1191}
Sieu Mun Tangb0c1d112022-05-10 17:30:00 +08001192
Sieu Mun Tangbd8da632022-09-28 15:58:28 +08001193int intel_fcs_mac_verify_smmu_update_finalize(uint32_t session_id,
1194 uint32_t context_id, uint32_t src_addr,
1195 uint32_t src_size, uint64_t dst_addr,
1196 uint32_t *dst_size, uint32_t data_size,
1197 uint8_t is_finalised, uint32_t *mbox_error,
1198 uint32_t *send_id)
1199{
1200 int status;
1201 uint32_t i;
1202 uint32_t flag;
1203 uint32_t crypto_header;
1204 uint32_t resp_len;
1205 uint32_t payload[FCS_MAC_VERIFY_CMD_MAX_WORD_SIZE] = {0U};
1206 uintptr_t mac_offset;
Jit Loon Lim581ad472023-05-17 12:26:11 +08001207 uint32_t dst_size_check = 0;
Sieu Mun Tangbd8da632022-09-28 15:58:28 +08001208 /*
1209 * Source data must be 4 bytes aligned
1210 * User data must be 8 bytes aligned
1211 */
1212 if (dst_size == NULL || mbox_error == NULL ||
1213 !is_size_4_bytes_aligned(src_size) ||
1214 !is_8_bytes_aligned(data_size)) {
1215 return INTEL_SIP_SMC_STATUS_REJECTED;
1216 }
1217
1218 if (data_size > src_size) {
1219 return INTEL_SIP_SMC_STATUS_REJECTED;
1220 }
1221
1222 if (fcs_sha_mac_verify_param.session_id != session_id ||
1223 fcs_sha_mac_verify_param.context_id != context_id) {
1224 return INTEL_SIP_SMC_STATUS_REJECTED;
1225 }
1226
1227 if (!is_address_in_ddr_range(src_addr, src_size) ||
1228 !is_address_in_ddr_range(dst_addr, *dst_size)) {
1229 return INTEL_SIP_SMC_STATUS_REJECTED;
1230 }
1231
Jit Loon Lim581ad472023-05-17 12:26:11 +08001232 dst_size_check = *dst_size;
1233 if ((dst_size_check > FCS_MAX_DATA_SIZE ||
1234 dst_size_check < FCS_MIN_DATA_SIZE) ||
1235 (src_size > FCS_MAX_DATA_SIZE ||
1236 src_size < FCS_MIN_DATA_SIZE)) {
1237 return INTEL_SIP_SMC_STATUS_REJECTED;
1238 }
1239
Sieu Mun Tangbd8da632022-09-28 15:58:28 +08001240 resp_len = *dst_size / MBOX_WORD_BYTE;
1241
1242 /* Prepare crypto header */
1243 flag = 0;
1244
1245 if (fcs_sha_mac_verify_param.is_updated) {
1246 fcs_sha_mac_verify_param.crypto_param_size = 0;
1247 } else {
1248 flag |= FCS_CS_FIELD_FLAG_INIT;
1249 }
1250
1251 if (is_finalised) {
1252 flag |= FCS_CS_FIELD_FLAG_FINALIZE;
1253 } else {
1254 flag |= FCS_CS_FIELD_FLAG_UPDATE;
1255 fcs_sha_mac_verify_param.is_updated = 1;
1256 }
1257
1258 crypto_header = ((flag << FCS_CS_FIELD_FLAG_OFFSET) |
1259 (fcs_sha_mac_verify_param.crypto_param_size &
1260 FCS_CS_FIELD_SIZE_MASK));
1261
1262 /* Prepare command payload */
1263 i = 0;
1264 payload[i] = fcs_sha_mac_verify_param.session_id;
1265 i++;
1266 payload[i] = fcs_sha_mac_verify_param.context_id;
1267 i++;
1268 payload[i] = crypto_header;
1269 i++;
1270
1271 if ((crypto_header >> FCS_CS_FIELD_FLAG_OFFSET) &
1272 FCS_CS_FIELD_FLAG_INIT) {
1273 payload[i] = fcs_sha_mac_verify_param.key_id;
1274 i++;
1275 /* Crypto parameters */
1276 payload[i] = ((fcs_sha_mac_verify_param.crypto_param
1277 >> INTEL_SIP_SMC_FCS_DIGEST_SIZE_OFFSET)
1278 & INTEL_SIP_SMC_FCS_DIGEST_SIZE_MASK)
1279 << FCS_SHA_HMAC_CRYPTO_PARAM_SIZE_OFFSET;
1280 i++;
1281 }
1282 /* Data source address and size */
1283 payload[i] = src_addr;
1284 i++;
1285 payload[i] = data_size;
1286 i++;
1287
1288 if ((crypto_header >> FCS_CS_FIELD_FLAG_OFFSET) &
1289 FCS_CS_FIELD_FLAG_FINALIZE) {
1290 /* Copy mac data to command
1291 * Using dst_addr (physical address) to store mac_offset
1292 * mac_offset = MAC data
1293 */
1294 mac_offset = dst_addr;
Jit Loon Lim581ad472023-05-17 12:26:11 +08001295
1296 if ((i + ((src_size - data_size) / MBOX_WORD_BYTE)) >
1297 FCS_MAC_VERIFY_CMD_MAX_WORD_SIZE) {
1298 return INTEL_SIP_SMC_STATUS_REJECTED;
1299 }
1300
Sieu Mun Tangbd8da632022-09-28 15:58:28 +08001301 memcpy((uint8_t *) &payload[i], (uint8_t *) mac_offset,
1302 src_size - data_size);
1303
Sieu Mun Tang73d03842023-03-21 15:11:08 +08001304 memset((void *) dst_addr, 0, *dst_size);
Sieu Mun Tangbd8da632022-09-28 15:58:28 +08001305
1306 i += (src_size - data_size) / MBOX_WORD_BYTE;
1307 }
1308
1309 status = mailbox_send_cmd_async(send_id, MBOX_FCS_MAC_VERIFY_REQ,
1310 payload, i, CMD_INDIRECT);
1311
1312 if (is_finalised) {
1313 memset((void *)&fcs_sha_mac_verify_param, 0,
1314 sizeof(fcs_crypto_service_data));
1315 }
1316
1317 if (status < 0) {
1318 *mbox_error = -status;
1319 return INTEL_SIP_SMC_STATUS_ERROR;
1320 }
1321
1322 *dst_size = resp_len * MBOX_WORD_BYTE;
1323 flush_dcache_range(dst_addr, *dst_size);
1324
1325 return INTEL_SIP_SMC_STATUS_OK;
1326}
1327
Sieu Mun Tang8aa05ad2022-05-10 17:50:30 +08001328int intel_fcs_ecdsa_hash_sign_init(uint32_t session_id, uint32_t context_id,
1329 uint32_t key_id, uint32_t param_size,
1330 uint64_t param_data, uint32_t *mbox_error)
1331{
1332 return intel_fcs_crypto_service_init(session_id, context_id,
1333 key_id, param_size, param_data,
1334 (void *) &fcs_ecdsa_hash_sign_param,
1335 mbox_error);
1336}
1337
1338int intel_fcs_ecdsa_hash_sign_finalize(uint32_t session_id, uint32_t context_id,
1339 uint32_t src_addr, uint32_t src_size,
1340 uint64_t dst_addr, uint32_t *dst_size,
1341 uint32_t *mbox_error)
1342{
1343 int status;
1344 uint32_t i;
1345 uint32_t payload[FCS_ECDSA_HASH_SIGN_CMD_MAX_WORD_SIZE] = {0U};
Boon Khai Ngd2df2042021-08-30 15:05:49 +08001346 uint32_t resp_len;
Sieu Mun Tang8aa05ad2022-05-10 17:50:30 +08001347 uintptr_t hash_data_addr;
Jit Loon Lim581ad472023-05-17 12:26:11 +08001348 uint32_t dst_size_check = 0;
Sieu Mun Tang8aa05ad2022-05-10 17:50:30 +08001349
1350 if ((dst_size == NULL) || (mbox_error == NULL)) {
1351 return INTEL_SIP_SMC_STATUS_REJECTED;
1352 }
1353
1354 if (fcs_ecdsa_hash_sign_param.session_id != session_id ||
1355 fcs_ecdsa_hash_sign_param.context_id != context_id) {
1356 return INTEL_SIP_SMC_STATUS_REJECTED;
1357 }
1358
1359 if (!is_address_in_ddr_range(src_addr, src_size) ||
1360 !is_address_in_ddr_range(dst_addr, *dst_size)) {
1361 return INTEL_SIP_SMC_STATUS_REJECTED;
1362 }
1363
Jit Loon Lim581ad472023-05-17 12:26:11 +08001364 dst_size_check = *dst_size;
1365 if ((dst_size_check > FCS_MAX_DATA_SIZE ||
1366 dst_size_check < FCS_MIN_DATA_SIZE) ||
1367 (src_size > FCS_MAX_DATA_SIZE ||
1368 src_size < FCS_MIN_DATA_SIZE)) {
1369 return INTEL_SIP_SMC_STATUS_REJECTED;
1370 }
1371
Boon Khai Ngd2df2042021-08-30 15:05:49 +08001372 resp_len = *dst_size / MBOX_WORD_BYTE;
1373
Sieu Mun Tang8aa05ad2022-05-10 17:50:30 +08001374 /* Prepare command payload */
1375 /* Crypto header */
1376 i = 0;
1377 payload[i] = fcs_ecdsa_hash_sign_param.session_id;
1378 i++;
1379 payload[i] = fcs_ecdsa_hash_sign_param.context_id;
1380
1381 i++;
1382 payload[i] = fcs_ecdsa_hash_sign_param.crypto_param_size
1383 & FCS_CS_FIELD_SIZE_MASK;
1384 payload[i] |= (FCS_CS_FIELD_FLAG_INIT | FCS_CS_FIELD_FLAG_UPDATE
1385 | FCS_CS_FIELD_FLAG_FINALIZE)
1386 << FCS_CS_FIELD_FLAG_OFFSET;
1387 i++;
1388 payload[i] = fcs_ecdsa_hash_sign_param.key_id;
1389
1390 /* Crypto parameters */
1391 i++;
1392 payload[i] = fcs_ecdsa_hash_sign_param.crypto_param
1393 & INTEL_SIP_SMC_FCS_ECC_ALGO_MASK;
1394
1395 /* Hash Data */
1396 i++;
1397 hash_data_addr = src_addr;
Jit Loon Lim581ad472023-05-17 12:26:11 +08001398
1399 if ((i + ((src_size) / MBOX_WORD_BYTE)) >
1400 FCS_ECDSA_HASH_SIGN_CMD_MAX_WORD_SIZE) {
1401 return INTEL_SIP_SMC_STATUS_REJECTED;
1402 }
1403
Sieu Mun Tang8aa05ad2022-05-10 17:50:30 +08001404 memcpy((uint8_t *) &payload[i], (uint8_t *) hash_data_addr,
1405 src_size);
1406
1407 i += src_size / MBOX_WORD_BYTE;
1408
1409 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_ECDSA_HASH_SIGN_REQ,
1410 payload, i, CMD_CASUAL, (uint32_t *) dst_addr,
1411 &resp_len);
1412
1413 memset((void *) &fcs_ecdsa_hash_sign_param,
1414 0, sizeof(fcs_crypto_service_data));
1415
1416 if (status < 0) {
1417 *mbox_error = -status;
1418 return INTEL_SIP_SMC_STATUS_ERROR;
1419 }
1420
1421 *dst_size = resp_len * MBOX_WORD_BYTE;
1422 flush_dcache_range(dst_addr, *dst_size);
1423
1424 return INTEL_SIP_SMC_STATUS_OK;
1425}
1426
Sieu Mun Tang59357e82022-05-10 17:53:32 +08001427int intel_fcs_ecdsa_hash_sig_verify_init(uint32_t session_id, uint32_t context_id,
1428 uint32_t key_id, uint32_t param_size,
1429 uint64_t param_data, uint32_t *mbox_error)
1430{
1431 return intel_fcs_crypto_service_init(session_id, context_id,
1432 key_id, param_size, param_data,
1433 (void *) &fcs_ecdsa_hash_sig_verify_param,
1434 mbox_error);
1435}
1436
1437int intel_fcs_ecdsa_hash_sig_verify_finalize(uint32_t session_id, uint32_t context_id,
1438 uint32_t src_addr, uint32_t src_size,
1439 uint64_t dst_addr, uint32_t *dst_size,
1440 uint32_t *mbox_error)
1441{
1442 int status;
1443 uint32_t i = 0;
1444 uint32_t payload[FCS_ECDSA_HASH_SIG_VERIFY_CMD_MAX_WORD_SIZE] = {0U};
Boon Khai Ngd2df2042021-08-30 15:05:49 +08001445 uint32_t resp_len;
Sieu Mun Tang59357e82022-05-10 17:53:32 +08001446 uintptr_t hash_sig_pubkey_addr;
Jit Loon Lim581ad472023-05-17 12:26:11 +08001447 uint32_t dst_size_check = 0;
Sieu Mun Tang59357e82022-05-10 17:53:32 +08001448
1449 if ((dst_size == NULL) || (mbox_error == NULL)) {
1450 return INTEL_SIP_SMC_STATUS_REJECTED;
1451 }
1452
1453 if (fcs_ecdsa_hash_sig_verify_param.session_id != session_id ||
1454 fcs_ecdsa_hash_sig_verify_param.context_id != context_id) {
1455 return INTEL_SIP_SMC_STATUS_REJECTED;
1456 }
1457
1458 if (!is_address_in_ddr_range(src_addr, src_size) ||
1459 !is_address_in_ddr_range(dst_addr, *dst_size)) {
1460 return INTEL_SIP_SMC_STATUS_REJECTED;
1461 }
1462
Jit Loon Lim581ad472023-05-17 12:26:11 +08001463 dst_size_check = *dst_size;
1464 if ((dst_size_check > FCS_MAX_DATA_SIZE ||
1465 dst_size_check < FCS_MIN_DATA_SIZE) ||
1466 (src_size > FCS_MAX_DATA_SIZE ||
1467 src_size < FCS_MIN_DATA_SIZE)) {
1468 return INTEL_SIP_SMC_STATUS_REJECTED;
1469 }
1470
Boon Khai Ngd2df2042021-08-30 15:05:49 +08001471 resp_len = *dst_size / MBOX_WORD_BYTE;
1472
Sieu Mun Tang59357e82022-05-10 17:53:32 +08001473 /* Prepare command payload */
1474 /* Crypto header */
1475 i = 0;
1476 payload[i] = fcs_ecdsa_hash_sig_verify_param.session_id;
1477
1478 i++;
1479 payload[i] = fcs_ecdsa_hash_sig_verify_param.context_id;
1480
1481 i++;
1482 payload[i] = fcs_ecdsa_hash_sig_verify_param.crypto_param_size
1483 & FCS_CS_FIELD_SIZE_MASK;
1484 payload[i] |= (FCS_CS_FIELD_FLAG_INIT | FCS_CS_FIELD_FLAG_UPDATE
1485 | FCS_CS_FIELD_FLAG_FINALIZE)
1486 << FCS_CS_FIELD_FLAG_OFFSET;
1487
1488 i++;
1489 payload[i] = fcs_ecdsa_hash_sig_verify_param.key_id;
1490
1491 /* Crypto parameters */
1492 i++;
1493 payload[i] = fcs_ecdsa_hash_sig_verify_param.crypto_param
1494 & INTEL_SIP_SMC_FCS_ECC_ALGO_MASK;
1495
1496 /* Hash Data Word, Signature Data Word and Public Key Data word */
1497 i++;
1498 hash_sig_pubkey_addr = src_addr;
Jit Loon Lim581ad472023-05-17 12:26:11 +08001499
1500 if ((i + ((src_size) / MBOX_WORD_BYTE)) >
1501 FCS_ECDSA_HASH_SIG_VERIFY_CMD_MAX_WORD_SIZE) {
1502 return INTEL_SIP_SMC_STATUS_REJECTED;
1503 }
1504
Sieu Mun Tang59357e82022-05-10 17:53:32 +08001505 memcpy((uint8_t *) &payload[i],
1506 (uint8_t *) hash_sig_pubkey_addr, src_size);
1507
1508 i += (src_size / MBOX_WORD_BYTE);
1509
1510 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_ECDSA_HASH_SIG_VERIFY,
1511 payload, i, CMD_CASUAL, (uint32_t *) dst_addr,
1512 &resp_len);
1513
1514 memset((void *)&fcs_ecdsa_hash_sig_verify_param,
1515 0, sizeof(fcs_crypto_service_data));
1516
1517 if (status < 0) {
1518 *mbox_error = -status;
1519 return INTEL_SIP_SMC_STATUS_ERROR;
1520 }
1521
1522 *dst_size = resp_len * MBOX_WORD_BYTE;
1523 flush_dcache_range(dst_addr, *dst_size);
1524
1525 return INTEL_SIP_SMC_STATUS_OK;
1526}
1527
Sieu Mun Tang153ecfb2022-05-10 17:39:26 +08001528int intel_fcs_ecdsa_sha2_data_sign_init(uint32_t session_id,
1529 uint32_t context_id, uint32_t key_id,
1530 uint32_t param_size, uint64_t param_data,
1531 uint32_t *mbox_error)
1532{
1533 return intel_fcs_crypto_service_init(session_id, context_id,
1534 key_id, param_size, param_data,
1535 (void *) &fcs_sha2_data_sign_param,
1536 mbox_error);
1537}
1538
Sieu Mun Tange77d37d2022-04-28 16:23:20 +08001539int intel_fcs_ecdsa_sha2_data_sign_update_finalize(uint32_t session_id,
Sieu Mun Tang153ecfb2022-05-10 17:39:26 +08001540 uint32_t context_id, uint32_t src_addr,
1541 uint32_t src_size, uint64_t dst_addr,
Sieu Mun Tange77d37d2022-04-28 16:23:20 +08001542 uint32_t *dst_size, uint8_t is_finalised,
1543 uint32_t *mbox_error)
Sieu Mun Tang153ecfb2022-05-10 17:39:26 +08001544{
1545 int status;
1546 int i;
Sieu Mun Tange77d37d2022-04-28 16:23:20 +08001547 uint32_t flag;
1548 uint32_t crypto_header;
Sieu Mun Tang153ecfb2022-05-10 17:39:26 +08001549 uint32_t payload[FCS_ECDSA_SHA2_DATA_SIGN_CMD_MAX_WORD_SIZE] = {0U};
Boon Khai Ngd2df2042021-08-30 15:05:49 +08001550 uint32_t resp_len;
Sieu Mun Tang153ecfb2022-05-10 17:39:26 +08001551
1552 if ((dst_size == NULL) || (mbox_error == NULL)) {
1553 return INTEL_SIP_SMC_STATUS_REJECTED;
1554 }
1555
1556 if (fcs_sha2_data_sign_param.session_id != session_id ||
1557 fcs_sha2_data_sign_param.context_id != context_id) {
1558 return INTEL_SIP_SMC_STATUS_REJECTED;
1559 }
1560
1561 /* Source data must be 8 bytes aligned */
1562 if (!is_8_bytes_aligned(src_size)) {
1563 return INTEL_SIP_SMC_STATUS_REJECTED;
1564 }
1565
1566 if (!is_address_in_ddr_range(src_addr, src_size) ||
1567 !is_address_in_ddr_range(dst_addr, *dst_size)) {
1568 return INTEL_SIP_SMC_STATUS_REJECTED;
1569 }
1570
Boon Khai Ngd2df2042021-08-30 15:05:49 +08001571 resp_len = *dst_size / MBOX_WORD_BYTE;
1572
Sieu Mun Tange77d37d2022-04-28 16:23:20 +08001573 /* Prepare crypto header */
1574 flag = 0;
1575 if (fcs_sha2_data_sign_param.is_updated) {
1576 fcs_sha2_data_sign_param.crypto_param_size = 0;
1577 } else {
1578 flag |= FCS_CS_FIELD_FLAG_INIT;
1579 }
1580
1581 if (is_finalised != 0U) {
1582 flag |= FCS_CS_FIELD_FLAG_FINALIZE;
1583 } else {
1584 flag |= FCS_CS_FIELD_FLAG_UPDATE;
1585 fcs_sha2_data_sign_param.is_updated = 1;
1586 }
1587 crypto_header = (flag << FCS_CS_FIELD_FLAG_OFFSET) |
1588 fcs_sha2_data_sign_param.crypto_param_size;
1589
Sieu Mun Tang153ecfb2022-05-10 17:39:26 +08001590 /* Prepare command payload */
Sieu Mun Tang153ecfb2022-05-10 17:39:26 +08001591 i = 0;
1592 payload[i] = fcs_sha2_data_sign_param.session_id;
1593 i++;
1594 payload[i] = fcs_sha2_data_sign_param.context_id;
1595 i++;
Sieu Mun Tange77d37d2022-04-28 16:23:20 +08001596 payload[i] = crypto_header;
Sieu Mun Tang153ecfb2022-05-10 17:39:26 +08001597 i++;
Sieu Mun Tange77d37d2022-04-28 16:23:20 +08001598
1599 if ((crypto_header >> FCS_CS_FIELD_FLAG_OFFSET) &
1600 FCS_CS_FIELD_FLAG_INIT) {
1601 payload[i] = fcs_sha2_data_sign_param.key_id;
1602 /* Crypto parameters */
1603 i++;
1604 payload[i] = fcs_sha2_data_sign_param.crypto_param
1605 & INTEL_SIP_SMC_FCS_ECC_ALGO_MASK;
1606 i++;
1607 }
1608
Sieu Mun Tang153ecfb2022-05-10 17:39:26 +08001609 /* Data source address and size */
Sieu Mun Tang153ecfb2022-05-10 17:39:26 +08001610 payload[i] = src_addr;
1611 i++;
1612 payload[i] = src_size;
1613 i++;
1614 status = mailbox_send_cmd(MBOX_JOB_ID,
1615 MBOX_FCS_ECDSA_SHA2_DATA_SIGN_REQ, payload,
1616 i, CMD_CASUAL, (uint32_t *) dst_addr,
1617 &resp_len);
1618
Sieu Mun Tange77d37d2022-04-28 16:23:20 +08001619 if (is_finalised != 0U) {
1620 memset((void *)&fcs_sha2_data_sign_param, 0,
Sieu Mun Tang153ecfb2022-05-10 17:39:26 +08001621 sizeof(fcs_crypto_service_data));
Sieu Mun Tange77d37d2022-04-28 16:23:20 +08001622 }
Sieu Mun Tang153ecfb2022-05-10 17:39:26 +08001623
1624 if (status < 0) {
1625 *mbox_error = -status;
1626 return INTEL_SIP_SMC_STATUS_ERROR;
1627 }
1628
1629 *dst_size = resp_len * MBOX_WORD_BYTE;
1630 flush_dcache_range(dst_addr, *dst_size);
1631
1632 return INTEL_SIP_SMC_STATUS_OK;
1633}
1634
Sieu Mun Tangbd8da632022-09-28 15:58:28 +08001635int intel_fcs_ecdsa_sha2_data_sign_smmu_update_finalize(uint32_t session_id,
1636 uint32_t context_id, uint32_t src_addr,
1637 uint32_t src_size, uint64_t dst_addr,
1638 uint32_t *dst_size, uint8_t is_finalised,
1639 uint32_t *mbox_error, uint32_t *send_id)
1640{
1641 int status;
1642 int i;
1643 uint32_t flag;
1644 uint32_t crypto_header;
1645 uint32_t payload[FCS_ECDSA_SHA2_DATA_SIGN_CMD_MAX_WORD_SIZE] = {0U};
1646 uint32_t resp_len;
1647
1648 /* Source data must be 8 bytes aligned */
1649 if ((dst_size == NULL) || (mbox_error == NULL ||
1650 !is_8_bytes_aligned(src_size))) {
1651 return INTEL_SIP_SMC_STATUS_REJECTED;
1652 }
1653
1654 if (fcs_sha2_data_sign_param.session_id != session_id ||
1655 fcs_sha2_data_sign_param.context_id != context_id) {
1656 return INTEL_SIP_SMC_STATUS_REJECTED;
1657 }
1658
1659 if (!is_address_in_ddr_range(src_addr, src_size) ||
1660 !is_address_in_ddr_range(dst_addr, *dst_size)) {
1661 return INTEL_SIP_SMC_STATUS_REJECTED;
1662 }
1663
1664 resp_len = *dst_size / MBOX_WORD_BYTE;
1665
1666 /* Prepare crypto header */
1667 flag = 0;
1668 if (fcs_sha2_data_sign_param.is_updated) {
1669 fcs_sha2_data_sign_param.crypto_param_size = 0;
1670 } else {
1671 flag |= FCS_CS_FIELD_FLAG_INIT;
1672 }
1673
1674 if (is_finalised != 0U) {
1675 flag |= FCS_CS_FIELD_FLAG_FINALIZE;
1676 } else {
1677 flag |= FCS_CS_FIELD_FLAG_UPDATE;
1678 fcs_sha2_data_sign_param.is_updated = 1;
1679 }
1680 crypto_header = (flag << FCS_CS_FIELD_FLAG_OFFSET) |
1681 fcs_sha2_data_sign_param.crypto_param_size;
1682
1683 /* Prepare command payload */
1684 i = 0;
1685 payload[i] = fcs_sha2_data_sign_param.session_id;
1686 i++;
1687 payload[i] = fcs_sha2_data_sign_param.context_id;
1688 i++;
1689 payload[i] = crypto_header;
1690 i++;
1691
1692 if ((crypto_header >> FCS_CS_FIELD_FLAG_OFFSET) &
1693 FCS_CS_FIELD_FLAG_INIT) {
1694 payload[i] = fcs_sha2_data_sign_param.key_id;
1695 /* Crypto parameters */
1696 i++;
1697 payload[i] = fcs_sha2_data_sign_param.crypto_param
1698 & INTEL_SIP_SMC_FCS_ECC_ALGO_MASK;
1699 i++;
1700 }
1701
1702 /* Data source address and size */
1703 payload[i] = src_addr;
1704 i++;
1705 payload[i] = src_size;
1706 i++;
1707
1708 status = mailbox_send_cmd_async(send_id,
1709 MBOX_FCS_ECDSA_SHA2_DATA_SIGN_REQ,
1710 payload, i, CMD_INDIRECT);
1711
1712 if (is_finalised != 0U) {
1713 memset((void *)&fcs_sha2_data_sign_param, 0,
1714 sizeof(fcs_crypto_service_data));
1715 }
1716
1717 if (status < 0) {
1718 *mbox_error = -status;
1719 return INTEL_SIP_SMC_STATUS_ERROR;
1720 }
1721
1722 *dst_size = resp_len * MBOX_WORD_BYTE;
1723 flush_dcache_range(dst_addr, *dst_size);
1724
1725 return INTEL_SIP_SMC_STATUS_OK;
1726}
1727
Sieu Mun Tangdcaab772022-05-11 10:16:40 +08001728int intel_fcs_ecdsa_sha2_data_sig_verify_init(uint32_t session_id,
1729 uint32_t context_id, uint32_t key_id,
1730 uint32_t param_size, uint64_t param_data,
1731 uint32_t *mbox_error)
1732{
1733 return intel_fcs_crypto_service_init(session_id, context_id,
1734 key_id, param_size, param_data,
1735 (void *) &fcs_sha2_data_sig_verify_param,
1736 mbox_error);
1737}
1738
Sieu Mun Tange77d37d2022-04-28 16:23:20 +08001739int intel_fcs_ecdsa_sha2_data_sig_verify_update_finalize(uint32_t session_id,
Sieu Mun Tangdcaab772022-05-11 10:16:40 +08001740 uint32_t context_id, uint32_t src_addr,
1741 uint32_t src_size, uint64_t dst_addr,
1742 uint32_t *dst_size, uint32_t data_size,
Sieu Mun Tange77d37d2022-04-28 16:23:20 +08001743 uint8_t is_finalised, uint32_t *mbox_error)
Sieu Mun Tangdcaab772022-05-11 10:16:40 +08001744{
1745 int status;
1746 uint32_t i;
Sieu Mun Tange77d37d2022-04-28 16:23:20 +08001747 uint32_t flag;
1748 uint32_t crypto_header;
Sieu Mun Tangdcaab772022-05-11 10:16:40 +08001749 uint32_t payload[FCS_ECDSA_SHA2_DATA_SIG_VERIFY_CMD_MAX_WORD_SIZE] = {0U};
Boon Khai Ngd2df2042021-08-30 15:05:49 +08001750 uint32_t resp_len;
Sieu Mun Tangdcaab772022-05-11 10:16:40 +08001751 uintptr_t sig_pubkey_offset;
Jit Loon Lim581ad472023-05-17 12:26:11 +08001752 uint32_t dst_size_check = 0;
Sieu Mun Tangdcaab772022-05-11 10:16:40 +08001753
1754 if ((dst_size == NULL) || (mbox_error == NULL)) {
1755 return INTEL_SIP_SMC_STATUS_REJECTED;
1756 }
1757
1758 if (fcs_sha2_data_sig_verify_param.session_id != session_id ||
1759 fcs_sha2_data_sig_verify_param.context_id != context_id) {
1760 return INTEL_SIP_SMC_STATUS_REJECTED;
1761 }
1762
Jit Loon Lim581ad472023-05-17 12:26:11 +08001763 if (data_size > src_size) {
1764 return INTEL_SIP_SMC_STATUS_REJECTED;
1765 }
1766
Sieu Mun Tangdcaab772022-05-11 10:16:40 +08001767 if (!is_size_4_bytes_aligned(src_size)) {
1768 return INTEL_SIP_SMC_STATUS_REJECTED;
1769 }
1770
1771 if (!is_8_bytes_aligned(data_size) ||
1772 !is_8_bytes_aligned(src_addr)) {
1773 return INTEL_SIP_SMC_STATUS_REJECTED;
1774 }
1775
1776 if (!is_address_in_ddr_range(src_addr, src_size) ||
1777 !is_address_in_ddr_range(dst_addr, *dst_size)) {
1778 return INTEL_SIP_SMC_STATUS_REJECTED;
1779 }
1780
Jit Loon Lim581ad472023-05-17 12:26:11 +08001781 dst_size_check = *dst_size;
1782 if ((dst_size_check > FCS_MAX_DATA_SIZE ||
1783 dst_size_check < FCS_MIN_DATA_SIZE) ||
1784 (src_size > FCS_MAX_DATA_SIZE ||
1785 src_size < FCS_MIN_DATA_SIZE)) {
1786 return INTEL_SIP_SMC_STATUS_REJECTED;
1787 }
1788
Boon Khai Ngd2df2042021-08-30 15:05:49 +08001789 resp_len = *dst_size / MBOX_WORD_BYTE;
1790
Sieu Mun Tange77d37d2022-04-28 16:23:20 +08001791 /* Prepare crypto header */
1792 flag = 0;
1793 if (fcs_sha2_data_sig_verify_param.is_updated)
1794 fcs_sha2_data_sig_verify_param.crypto_param_size = 0;
1795 else
1796 flag |= FCS_CS_FIELD_FLAG_INIT;
1797
1798 if (is_finalised != 0U)
1799 flag |= FCS_CS_FIELD_FLAG_FINALIZE;
1800 else {
1801 flag |= FCS_CS_FIELD_FLAG_UPDATE;
1802 fcs_sha2_data_sig_verify_param.is_updated = 1;
1803 }
1804 crypto_header = (flag << FCS_CS_FIELD_FLAG_OFFSET) |
1805 fcs_sha2_data_sig_verify_param.crypto_param_size;
1806
Sieu Mun Tangdcaab772022-05-11 10:16:40 +08001807 /* Prepare command payload */
Sieu Mun Tangdcaab772022-05-11 10:16:40 +08001808 i = 0;
1809 payload[i] = fcs_sha2_data_sig_verify_param.session_id;
1810 i++;
1811 payload[i] = fcs_sha2_data_sig_verify_param.context_id;
1812 i++;
Sieu Mun Tange77d37d2022-04-28 16:23:20 +08001813 payload[i] = crypto_header;
Sieu Mun Tangdcaab772022-05-11 10:16:40 +08001814 i++;
Sieu Mun Tange77d37d2022-04-28 16:23:20 +08001815
1816 if ((crypto_header >> FCS_CS_FIELD_FLAG_OFFSET) &
1817 FCS_CS_FIELD_FLAG_INIT) {
1818 payload[i] = fcs_sha2_data_sig_verify_param.key_id;
1819 i++;
1820 /* Crypto parameters */
1821 payload[i] = fcs_sha2_data_sig_verify_param.crypto_param
1822 & INTEL_SIP_SMC_FCS_ECC_ALGO_MASK;
1823 i++;
1824 }
1825
Sieu Mun Tangdcaab772022-05-11 10:16:40 +08001826 /* Data source address and size */
1827 payload[i] = src_addr;
1828 i++;
1829 payload[i] = data_size;
1830 i++;
Sieu Mun Tangdcaab772022-05-11 10:16:40 +08001831
Sieu Mun Tange77d37d2022-04-28 16:23:20 +08001832 if ((crypto_header >> FCS_CS_FIELD_FLAG_OFFSET) &
1833 FCS_CS_FIELD_FLAG_FINALIZE) {
1834 /* Signature + Public Key Data */
1835 sig_pubkey_offset = src_addr + data_size;
Jit Loon Lim581ad472023-05-17 12:26:11 +08001836
1837 if ((i + ((src_size - data_size) / MBOX_WORD_BYTE)) >
1838 FCS_ECDSA_SHA2_DATA_SIG_VERIFY_CMD_MAX_WORD_SIZE) {
1839 return INTEL_SIP_SMC_STATUS_REJECTED;
1840 }
1841
Sieu Mun Tange77d37d2022-04-28 16:23:20 +08001842 memcpy((uint8_t *) &payload[i], (uint8_t *) sig_pubkey_offset,
1843 src_size - data_size);
1844
1845 i += (src_size - data_size) / MBOX_WORD_BYTE;
1846 }
Sieu Mun Tangdcaab772022-05-11 10:16:40 +08001847
1848 status = mailbox_send_cmd(MBOX_JOB_ID,
1849 MBOX_FCS_ECDSA_SHA2_DATA_SIGN_VERIFY, payload, i,
1850 CMD_CASUAL, (uint32_t *) dst_addr, &resp_len);
1851
Sieu Mun Tange77d37d2022-04-28 16:23:20 +08001852 if (is_finalised != 0U) {
1853 memset((void *) &fcs_sha2_data_sig_verify_param, 0,
Sieu Mun Tangdcaab772022-05-11 10:16:40 +08001854 sizeof(fcs_crypto_service_data));
Sieu Mun Tange77d37d2022-04-28 16:23:20 +08001855 }
Sieu Mun Tangdcaab772022-05-11 10:16:40 +08001856
1857 if (status < 0) {
1858 *mbox_error = -status;
1859 return INTEL_SIP_SMC_STATUS_ERROR;
1860 }
1861
1862 *dst_size = resp_len * MBOX_WORD_BYTE;
1863 flush_dcache_range(dst_addr, *dst_size);
1864
1865 return INTEL_SIP_SMC_STATUS_OK;
1866}
1867
Sieu Mun Tangbd8da632022-09-28 15:58:28 +08001868int intel_fcs_ecdsa_sha2_data_sig_verify_smmu_update_finalize(uint32_t session_id,
1869 uint32_t context_id, uint32_t src_addr,
1870 uint32_t src_size, uint64_t dst_addr,
1871 uint32_t *dst_size, uint32_t data_size,
1872 uint8_t is_finalised, uint32_t *mbox_error,
1873 uint32_t *send_id)
1874{
1875 int status;
1876 uint32_t i;
1877 uint32_t flag;
1878 uint32_t crypto_header;
1879 uint32_t payload[FCS_ECDSA_SHA2_DATA_SIG_VERIFY_CMD_MAX_WORD_SIZE] = {0U};
1880 uint32_t resp_len;
1881 uintptr_t sig_pubkey_offset;
Jit Loon Lim581ad472023-05-17 12:26:11 +08001882 uint32_t dst_size_check = 0;
Sieu Mun Tangbd8da632022-09-28 15:58:28 +08001883
1884 /*
1885 * Source data must be 4 bytes aligned
Elyes Haouas2be03c02023-02-13 09:14:48 +01001886 * Source address must be 8 bytes aligned
Sieu Mun Tangbd8da632022-09-28 15:58:28 +08001887 * User data must be 8 bytes aligned
1888 */
1889 if ((dst_size == NULL) || (mbox_error == NULL) ||
1890 !is_size_4_bytes_aligned(src_size) ||
1891 !is_8_bytes_aligned(src_addr) ||
1892 !is_8_bytes_aligned(data_size)) {
1893 return INTEL_SIP_SMC_STATUS_REJECTED;
1894 }
1895
1896 if (fcs_sha2_data_sig_verify_param.session_id != session_id ||
1897 fcs_sha2_data_sig_verify_param.context_id != context_id) {
1898 return INTEL_SIP_SMC_STATUS_REJECTED;
1899 }
1900
Jit Loon Lim581ad472023-05-17 12:26:11 +08001901 if (data_size > src_size) {
1902 return INTEL_SIP_SMC_STATUS_REJECTED;
1903 }
1904
Sieu Mun Tangbd8da632022-09-28 15:58:28 +08001905 if (!is_address_in_ddr_range(src_addr, src_size) ||
1906 !is_address_in_ddr_range(dst_addr, *dst_size)) {
1907 return INTEL_SIP_SMC_STATUS_REJECTED;
1908 }
1909
Jit Loon Lim581ad472023-05-17 12:26:11 +08001910 dst_size_check = *dst_size;
1911 if ((dst_size_check > FCS_MAX_DATA_SIZE ||
1912 dst_size_check < FCS_MIN_DATA_SIZE) ||
1913 (src_size > FCS_MAX_DATA_SIZE ||
1914 src_size < FCS_MIN_DATA_SIZE)) {
1915 return INTEL_SIP_SMC_STATUS_REJECTED;
1916 }
1917
Sieu Mun Tangbd8da632022-09-28 15:58:28 +08001918 resp_len = *dst_size / MBOX_WORD_BYTE;
1919
1920 /* Prepare crypto header */
1921 flag = 0;
1922 if (fcs_sha2_data_sig_verify_param.is_updated)
1923 fcs_sha2_data_sig_verify_param.crypto_param_size = 0;
1924 else
1925 flag |= FCS_CS_FIELD_FLAG_INIT;
1926
1927 if (is_finalised != 0U)
1928 flag |= FCS_CS_FIELD_FLAG_FINALIZE;
1929 else {
1930 flag |= FCS_CS_FIELD_FLAG_UPDATE;
1931 fcs_sha2_data_sig_verify_param.is_updated = 1;
1932 }
1933 crypto_header = (flag << FCS_CS_FIELD_FLAG_OFFSET) |
1934 fcs_sha2_data_sig_verify_param.crypto_param_size;
1935
1936 /* Prepare command payload */
1937 i = 0;
1938 payload[i] = fcs_sha2_data_sig_verify_param.session_id;
1939 i++;
1940 payload[i] = fcs_sha2_data_sig_verify_param.context_id;
1941 i++;
1942 payload[i] = crypto_header;
1943 i++;
1944
1945 if ((crypto_header >> FCS_CS_FIELD_FLAG_OFFSET) &
1946 FCS_CS_FIELD_FLAG_INIT) {
1947 payload[i] = fcs_sha2_data_sig_verify_param.key_id;
1948 i++;
1949 /* Crypto parameters */
1950 payload[i] = fcs_sha2_data_sig_verify_param.crypto_param
1951 & INTEL_SIP_SMC_FCS_ECC_ALGO_MASK;
1952 i++;
1953 }
1954
1955 /* Data source address and size */
1956 payload[i] = src_addr;
1957 i++;
1958 payload[i] = data_size;
1959 i++;
1960
1961 if ((crypto_header >> FCS_CS_FIELD_FLAG_OFFSET) &
1962 FCS_CS_FIELD_FLAG_FINALIZE) {
1963 /* Copy mac data to command
1964 * Using dst_addr (physical address) to store sig_pubkey_offset
1965 * sig_pubkey_offset is Signature + Public Key Data
1966 */
1967 sig_pubkey_offset = dst_addr;
Jit Loon Lim581ad472023-05-17 12:26:11 +08001968
1969 if ((i + ((src_size - data_size) / MBOX_WORD_BYTE)) >
1970 FCS_ECDSA_SHA2_DATA_SIG_VERIFY_CMD_MAX_WORD_SIZE) {
1971 return INTEL_SIP_SMC_STATUS_REJECTED;
1972 }
1973
Sieu Mun Tangbd8da632022-09-28 15:58:28 +08001974 memcpy((uint8_t *) &payload[i], (uint8_t *) sig_pubkey_offset,
1975 src_size - data_size);
1976
Sieu Mun Tang73d03842023-03-21 15:11:08 +08001977 memset((void *) dst_addr, 0, *dst_size);
Sieu Mun Tangbd8da632022-09-28 15:58:28 +08001978
1979 i += (src_size - data_size) / MBOX_WORD_BYTE;
1980 }
1981
1982 status = mailbox_send_cmd_async(send_id,
1983 MBOX_FCS_ECDSA_SHA2_DATA_SIGN_VERIFY,
1984 payload, i, CMD_INDIRECT);
1985
1986 if (is_finalised != 0U) {
1987 memset((void *) &fcs_sha2_data_sig_verify_param, 0,
1988 sizeof(fcs_crypto_service_data));
1989 }
1990
1991 if (status < 0) {
1992 *mbox_error = -status;
1993 return INTEL_SIP_SMC_STATUS_ERROR;
1994 }
1995
1996 *dst_size = resp_len * MBOX_WORD_BYTE;
1997 flush_dcache_range(dst_addr, *dst_size);
1998
1999 return INTEL_SIP_SMC_STATUS_OK;
2000}
2001
Sieu Mun Tange2f3ede2022-05-10 17:36:32 +08002002int intel_fcs_ecdsa_get_pubkey_init(uint32_t session_id, uint32_t context_id,
2003 uint32_t key_id, uint32_t param_size,
2004 uint64_t param_data, uint32_t *mbox_error)
2005{
2006 return intel_fcs_crypto_service_init(session_id, context_id,
2007 key_id, param_size, param_data,
2008 (void *) &fcs_ecdsa_get_pubkey_param,
2009 mbox_error);
2010}
2011
2012int intel_fcs_ecdsa_get_pubkey_finalize(uint32_t session_id, uint32_t context_id,
2013 uint64_t dst_addr, uint32_t *dst_size,
2014 uint32_t *mbox_error)
2015{
2016 int status;
2017 int i;
2018 uint32_t crypto_header;
Boon Khai Ngd2df2042021-08-30 15:05:49 +08002019 uint32_t ret_size;
Sieu Mun Tange2f3ede2022-05-10 17:36:32 +08002020 uint32_t payload[FCS_ECDSA_GET_PUBKEY_MAX_WORD_SIZE] = {0U};
2021
2022 if ((dst_size == NULL) || (mbox_error == NULL)) {
2023 return INTEL_SIP_SMC_STATUS_REJECTED;
2024 }
2025
2026 if (fcs_ecdsa_get_pubkey_param.session_id != session_id ||
2027 fcs_ecdsa_get_pubkey_param.context_id != context_id) {
2028 return INTEL_SIP_SMC_STATUS_REJECTED;
2029 }
2030
Boon Khai Ngd2df2042021-08-30 15:05:49 +08002031 ret_size = *dst_size / MBOX_WORD_BYTE;
2032
Sieu Mun Tange2f3ede2022-05-10 17:36:32 +08002033 crypto_header = ((FCS_CS_FIELD_FLAG_INIT |
2034 FCS_CS_FIELD_FLAG_UPDATE |
2035 FCS_CS_FIELD_FLAG_FINALIZE) <<
2036 FCS_CS_FIELD_FLAG_OFFSET) |
2037 fcs_ecdsa_get_pubkey_param.crypto_param_size;
2038 i = 0;
2039 /* Prepare command payload */
2040 payload[i] = session_id;
2041 i++;
2042 payload[i] = context_id;
2043 i++;
2044 payload[i] = crypto_header;
2045 i++;
2046 payload[i] = fcs_ecdsa_get_pubkey_param.key_id;
2047 i++;
2048 payload[i] = (uint32_t) fcs_ecdsa_get_pubkey_param.crypto_param &
2049 INTEL_SIP_SMC_FCS_ECC_ALGO_MASK;
2050 i++;
2051
2052 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_ECDSA_GET_PUBKEY,
2053 payload, i, CMD_CASUAL,
2054 (uint32_t *) dst_addr, &ret_size);
2055
2056 memset((void *) &fcs_ecdsa_get_pubkey_param, 0,
2057 sizeof(fcs_crypto_service_data));
2058
2059 if (status < 0) {
2060 *mbox_error = -status;
2061 return INTEL_SIP_SMC_STATUS_ERROR;
2062 }
2063
2064 *dst_size = ret_size * MBOX_WORD_BYTE;
2065 flush_dcache_range(dst_addr, *dst_size);
2066
2067 return INTEL_SIP_SMC_STATUS_OK;
2068}
2069
Sieu Mun Tang0675c222022-05-10 17:48:11 +08002070int intel_fcs_ecdh_request_init(uint32_t session_id, uint32_t context_id,
2071 uint32_t key_id, uint32_t param_size,
2072 uint64_t param_data, uint32_t *mbox_error)
2073{
2074 return intel_fcs_crypto_service_init(session_id, context_id,
2075 key_id, param_size, param_data,
2076 (void *) &fcs_ecdh_request_param,
2077 mbox_error);
2078}
2079
2080int intel_fcs_ecdh_request_finalize(uint32_t session_id, uint32_t context_id,
2081 uint32_t src_addr, uint32_t src_size,
2082 uint64_t dst_addr, uint32_t *dst_size,
2083 uint32_t *mbox_error)
2084{
2085 int status;
2086 uint32_t i;
2087 uint32_t payload[FCS_ECDH_REQUEST_CMD_MAX_WORD_SIZE] = {0U};
Boon Khai Ngd2df2042021-08-30 15:05:49 +08002088 uint32_t resp_len;
Sieu Mun Tang0675c222022-05-10 17:48:11 +08002089 uintptr_t pubkey;
Jit Loon Lim581ad472023-05-17 12:26:11 +08002090 uint32_t dst_size_check = 0;
Sieu Mun Tang0675c222022-05-10 17:48:11 +08002091
2092 if ((dst_size == NULL) || (mbox_error == NULL)) {
2093 return INTEL_SIP_SMC_STATUS_REJECTED;
2094 }
2095
Jit Loon Lim581ad472023-05-17 12:26:11 +08002096
Sieu Mun Tang0675c222022-05-10 17:48:11 +08002097 if (fcs_ecdh_request_param.session_id != session_id ||
2098 fcs_ecdh_request_param.context_id != context_id) {
2099 return INTEL_SIP_SMC_STATUS_REJECTED;
2100 }
2101
2102 if (!is_address_in_ddr_range(src_addr, src_size) ||
2103 !is_address_in_ddr_range(dst_addr, *dst_size)) {
2104 return INTEL_SIP_SMC_STATUS_REJECTED;
2105 }
2106
Jit Loon Lim581ad472023-05-17 12:26:11 +08002107 dst_size_check = *dst_size;
2108 if ((dst_size_check > FCS_MAX_DATA_SIZE ||
2109 dst_size_check < FCS_MIN_DATA_SIZE) ||
2110 (src_size > FCS_MAX_DATA_SIZE ||
2111 src_size < FCS_MIN_DATA_SIZE)) {
2112 return INTEL_SIP_SMC_STATUS_REJECTED;
2113 }
2114
Boon Khai Ngd2df2042021-08-30 15:05:49 +08002115 resp_len = *dst_size / MBOX_WORD_BYTE;
2116
Sieu Mun Tang0675c222022-05-10 17:48:11 +08002117 /* Prepare command payload */
2118 i = 0;
2119 /* Crypto header */
2120 payload[i] = fcs_ecdh_request_param.session_id;
2121 i++;
2122 payload[i] = fcs_ecdh_request_param.context_id;
2123 i++;
2124 payload[i] = fcs_ecdh_request_param.crypto_param_size
2125 & FCS_CS_FIELD_SIZE_MASK;
2126 payload[i] |= (FCS_CS_FIELD_FLAG_INIT | FCS_CS_FIELD_FLAG_UPDATE
2127 | FCS_CS_FIELD_FLAG_FINALIZE)
2128 << FCS_CS_FIELD_FLAG_OFFSET;
2129 i++;
2130 payload[i] = fcs_ecdh_request_param.key_id;
2131 i++;
2132 /* Crypto parameters */
2133 payload[i] = fcs_ecdh_request_param.crypto_param
2134 & INTEL_SIP_SMC_FCS_ECC_ALGO_MASK;
2135 i++;
2136 /* Public key data */
2137 pubkey = src_addr;
Jit Loon Lim581ad472023-05-17 12:26:11 +08002138
2139 if ((i + ((src_size) / MBOX_WORD_BYTE)) >
2140 FCS_ECDH_REQUEST_CMD_MAX_WORD_SIZE) {
2141 return INTEL_SIP_SMC_STATUS_REJECTED;
2142 }
2143
Sieu Mun Tang0675c222022-05-10 17:48:11 +08002144 memcpy((uint8_t *) &payload[i], (uint8_t *) pubkey, src_size);
2145 i += src_size / MBOX_WORD_BYTE;
2146
2147 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_ECDH_REQUEST,
2148 payload, i, CMD_CASUAL, (uint32_t *) dst_addr,
2149 &resp_len);
2150
2151 memset((void *)&fcs_ecdh_request_param, 0,
2152 sizeof(fcs_crypto_service_data));
2153
2154 if (status < 0) {
2155 *mbox_error = -status;
2156 return INTEL_SIP_SMC_STATUS_ERROR;
2157 }
2158
2159 *dst_size = resp_len * MBOX_WORD_BYTE;
2160 flush_dcache_range(dst_addr, *dst_size);
2161
2162 return INTEL_SIP_SMC_STATUS_OK;
2163}
2164
Sieu Mun Tangb0c1d112022-05-10 17:30:00 +08002165int intel_fcs_aes_crypt_init(uint32_t session_id, uint32_t context_id,
2166 uint32_t key_id, uint64_t param_addr,
2167 uint32_t param_size, uint32_t *mbox_error)
2168{
Jit Loon Lim6f9a4cc2022-09-13 10:24:04 +08002169 /* ptr to get param_addr value */
2170 uint64_t *param_addr_ptr;
2171
2172 param_addr_ptr = (uint64_t *) param_addr;
2173
2174 /*
2175 * Since crypto param size vary between mode.
2176 * Check ECB here and limit to size 12 bytes
2177 */
2178 if (((*param_addr_ptr & FCS_CRYPTO_BLOCK_MODE_MASK) == FCS_CRYPTO_ECB_MODE) &&
2179 (param_size > FCS_CRYPTO_ECB_BUFFER_SIZE)) {
2180 return INTEL_SIP_SMC_STATUS_REJECTED;
2181 }
2182 /*
2183 * Since crypto param size vary between mode.
2184 * Check CBC/CTR here and limit to size 28 bytes
2185 */
2186 if ((((*param_addr_ptr & FCS_CRYPTO_BLOCK_MODE_MASK) == FCS_CRYPTO_CBC_MODE) ||
2187 ((*param_addr_ptr & FCS_CRYPTO_BLOCK_MODE_MASK) == FCS_CRYPTO_CTR_MODE)) &&
2188 (param_size > FCS_CRYPTO_CBC_CTR_BUFFER_SIZE)) {
2189 return INTEL_SIP_SMC_STATUS_REJECTED;
2190 }
2191
Sieu Mun Tangb0c1d112022-05-10 17:30:00 +08002192 if (mbox_error == NULL) {
2193 return INTEL_SIP_SMC_STATUS_REJECTED;
2194 }
2195
2196 memset((void *)&fcs_aes_init_payload, 0U, sizeof(fcs_aes_init_payload));
2197
2198 fcs_aes_init_payload.session_id = session_id;
2199 fcs_aes_init_payload.context_id = context_id;
2200 fcs_aes_init_payload.param_size = param_size;
2201 fcs_aes_init_payload.key_id = key_id;
2202
2203 memcpy((uint8_t *) fcs_aes_init_payload.crypto_param,
2204 (uint8_t *) param_addr, param_size);
2205
Sieu Mun Tang9bea8152022-04-28 16:15:54 +08002206 fcs_aes_init_payload.is_updated = 0;
2207
Sieu Mun Tangb0c1d112022-05-10 17:30:00 +08002208 *mbox_error = 0;
2209
2210 return INTEL_SIP_SMC_STATUS_OK;
2211}
2212
Sieu Mun Tang9bea8152022-04-28 16:15:54 +08002213int intel_fcs_aes_crypt_update_finalize(uint32_t session_id,
2214 uint32_t context_id, uint64_t src_addr,
2215 uint32_t src_size, uint64_t dst_addr,
2216 uint32_t dst_size, uint8_t is_finalised,
Sieu Mun Tangb0c1d112022-05-10 17:30:00 +08002217 uint32_t *send_id)
2218{
2219 int status;
2220 int i;
Sieu Mun Tang9bea8152022-04-28 16:15:54 +08002221 uint32_t flag;
Sieu Mun Tangb0c1d112022-05-10 17:30:00 +08002222 uint32_t crypto_header;
2223 uint32_t fcs_aes_crypt_payload[FCS_AES_CMD_MAX_WORD_SIZE];
2224
2225 if (fcs_aes_init_payload.session_id != session_id ||
2226 fcs_aes_init_payload.context_id != context_id) {
2227 return INTEL_SIP_SMC_STATUS_REJECTED;
2228 }
2229
2230 if ((!is_8_bytes_aligned(src_addr)) ||
2231 (!is_32_bytes_aligned(src_size)) ||
2232 (!is_address_in_ddr_range(src_addr, src_size))) {
2233 return INTEL_SIP_SMC_STATUS_REJECTED;
2234 }
2235
2236 if ((!is_8_bytes_aligned(dst_addr)) ||
2237 (!is_32_bytes_aligned(dst_size))) {
2238 return INTEL_SIP_SMC_STATUS_REJECTED;
2239 }
2240
2241 if ((dst_size > FCS_AES_MAX_DATA_SIZE ||
2242 dst_size < FCS_AES_MIN_DATA_SIZE) ||
2243 (src_size > FCS_AES_MAX_DATA_SIZE ||
2244 src_size < FCS_AES_MIN_DATA_SIZE)) {
2245 return INTEL_SIP_SMC_STATUS_REJECTED;
2246 }
2247
Sieu Mun Tang9bea8152022-04-28 16:15:54 +08002248 /* Prepare crypto header*/
2249 flag = 0;
2250 if (fcs_aes_init_payload.is_updated) {
2251 fcs_aes_init_payload.param_size = 0;
2252 } else {
2253 flag |= FCS_CS_FIELD_FLAG_INIT;
2254 }
2255
2256 if (is_finalised != 0U) {
2257 flag |= FCS_CS_FIELD_FLAG_FINALIZE;
2258 } else {
2259 flag |= FCS_CS_FIELD_FLAG_UPDATE;
2260 fcs_aes_init_payload.is_updated = 1;
2261 }
2262 crypto_header = (flag << FCS_CS_FIELD_FLAG_OFFSET) |
Sieu Mun Tangb0c1d112022-05-10 17:30:00 +08002263 fcs_aes_init_payload.param_size;
Sieu Mun Tang9bea8152022-04-28 16:15:54 +08002264
Sieu Mun Tangb0c1d112022-05-10 17:30:00 +08002265 i = 0U;
2266 fcs_aes_crypt_payload[i] = session_id;
2267 i++;
2268 fcs_aes_crypt_payload[i] = context_id;
2269 i++;
2270 fcs_aes_crypt_payload[i] = crypto_header;
2271 i++;
Sieu Mun Tangb0c1d112022-05-10 17:30:00 +08002272
Sieu Mun Tang9bea8152022-04-28 16:15:54 +08002273 if ((crypto_header >> FCS_CS_FIELD_FLAG_OFFSET) &
2274 FCS_CS_FIELD_FLAG_INIT) {
2275 fcs_aes_crypt_payload[i] = fcs_aes_init_payload.key_id;
2276 i++;
2277
Jit Loon Lim581ad472023-05-17 12:26:11 +08002278 if ((i + ((fcs_aes_init_payload.param_size) / MBOX_WORD_BYTE)) >
2279 FCS_AES_CMD_MAX_WORD_SIZE) {
2280 return INTEL_SIP_SMC_STATUS_REJECTED;
2281 }
2282
Sieu Mun Tang9bea8152022-04-28 16:15:54 +08002283 memcpy((uint8_t *) &fcs_aes_crypt_payload[i],
2284 (uint8_t *) fcs_aes_init_payload.crypto_param,
2285 fcs_aes_init_payload.param_size);
Sieu Mun Tangb0c1d112022-05-10 17:30:00 +08002286
Sieu Mun Tang9bea8152022-04-28 16:15:54 +08002287 i += fcs_aes_init_payload.param_size / MBOX_WORD_BYTE;
2288 }
Sieu Mun Tangb0c1d112022-05-10 17:30:00 +08002289
2290 fcs_aes_crypt_payload[i] = (uint32_t) src_addr;
2291 i++;
2292 fcs_aes_crypt_payload[i] = src_size;
2293 i++;
2294 fcs_aes_crypt_payload[i] = (uint32_t) dst_addr;
2295 i++;
2296 fcs_aes_crypt_payload[i] = dst_size;
2297 i++;
2298
2299 status = mailbox_send_cmd_async(send_id, MBOX_FCS_AES_CRYPT_REQ,
2300 fcs_aes_crypt_payload, i,
2301 CMD_INDIRECT);
2302
Sieu Mun Tang9bea8152022-04-28 16:15:54 +08002303 if (is_finalised != 0U) {
2304 memset((void *)&fcs_aes_init_payload, 0,
2305 sizeof(fcs_aes_init_payload));
2306 }
Sieu Mun Tangb0c1d112022-05-10 17:30:00 +08002307
2308 if (status < 0U) {
2309 return INTEL_SIP_SMC_STATUS_ERROR;
2310 }
2311
2312 return INTEL_SIP_SMC_STATUS_OK;
2313}