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