blob: 2342e45c9ecb338c5180990a7edfebd455882dd9 [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
74 *mbox_error = 0;
75
76 return INTEL_SIP_SMC_STATUS_OK;
Sieu Mun Tangdb79fa52022-03-20 00:49:57 +080077}
78
Sieu Mun Tang9f22cbf2022-03-02 11:04:09 +080079uint32_t intel_fcs_random_number_gen(uint64_t addr, uint64_t *ret_size,
80 uint32_t *mbox_error)
81{
82 int status;
83 unsigned int i;
84 unsigned int resp_len = FCS_RANDOM_WORD_SIZE;
85 uint32_t random_data[FCS_RANDOM_WORD_SIZE] = {0U};
86
87 if (!is_address_in_ddr_range(addr, FCS_RANDOM_BYTE_SIZE)) {
88 return INTEL_SIP_SMC_STATUS_REJECTED;
89 }
90
91 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_RANDOM_GEN, NULL, 0U,
92 CMD_CASUAL, random_data, &resp_len);
93
94 if (status < 0) {
95 *mbox_error = -status;
96 return INTEL_SIP_SMC_STATUS_ERROR;
97 }
98
99 if (resp_len != FCS_RANDOM_WORD_SIZE) {
100 *mbox_error = GENERIC_RESPONSE_ERROR;
101 return INTEL_SIP_SMC_STATUS_ERROR;
102 }
103
104 *ret_size = FCS_RANDOM_BYTE_SIZE;
105
106 for (i = 0U; i < FCS_RANDOM_WORD_SIZE; i++) {
107 mmio_write_32(addr, random_data[i]);
108 addr += MBOX_WORD_BYTE;
109 }
110
111 flush_dcache_range(addr - *ret_size, *ret_size);
112
113 return INTEL_SIP_SMC_STATUS_OK;
114}
115
Sieu Mun Tange7a037f2022-05-10 17:18:19 +0800116int intel_fcs_random_number_gen_ext(uint32_t session_id, uint32_t context_id,
117 uint32_t size, uint32_t *send_id)
118{
119 int status;
120 uint32_t payload_size;
121 uint32_t crypto_header;
122
123 if (size > (FCS_RANDOM_EXT_MAX_WORD_SIZE *
124 MBOX_WORD_BYTE) || size == 0U) {
125 return INTEL_SIP_SMC_STATUS_REJECTED;
126 }
127
128 if (!is_size_4_bytes_aligned(size)) {
129 return INTEL_SIP_SMC_STATUS_REJECTED;
130 }
131
132 crypto_header = (FCS_CS_FIELD_FLAG_INIT | FCS_CS_FIELD_FLAG_FINALIZE) <<
133 FCS_CS_FIELD_FLAG_OFFSET;
134
135 fcs_rng_payload payload = {
136 session_id,
137 context_id,
138 crypto_header,
139 size
140 };
141
142 payload_size = sizeof(payload) / MBOX_WORD_BYTE;
143
144 status = mailbox_send_cmd_async(send_id, MBOX_FCS_RANDOM_GEN,
145 (uint32_t *) &payload, payload_size,
146 CMD_INDIRECT);
147
148 if (status < 0) {
149 return INTEL_SIP_SMC_STATUS_ERROR;
150 }
151
152 return INTEL_SIP_SMC_STATUS_OK;
153}
154
Sieu Mun Tang9f22cbf2022-03-02 11:04:09 +0800155uint32_t intel_fcs_send_cert(uint64_t addr, uint64_t size,
156 uint32_t *send_id)
157{
158 int status;
159
160 if (!is_address_in_ddr_range(addr, size)) {
161 return INTEL_SIP_SMC_STATUS_REJECTED;
162 }
163
Sieu Mun Tangdb79fa52022-03-20 00:49:57 +0800164 if (!is_size_4_bytes_aligned(size)) {
165 return INTEL_SIP_SMC_STATUS_REJECTED;
166 }
167
Sieu Mun Tang9f22cbf2022-03-02 11:04:09 +0800168 status = mailbox_send_cmd_async(send_id, MBOX_CMD_VAB_SRC_CERT,
169 (uint32_t *)addr, size / MBOX_WORD_BYTE,
170 CMD_DIRECT);
171
Boon Khai Ngcac786d2021-05-26 01:50:34 +0800172 flush_dcache_range(addr, size);
173
Sieu Mun Tang9f22cbf2022-03-02 11:04:09 +0800174 if (status < 0) {
175 return INTEL_SIP_SMC_STATUS_ERROR;
176 }
177
178 return INTEL_SIP_SMC_STATUS_OK;
179}
180
181uint32_t intel_fcs_get_provision_data(uint32_t *send_id)
182{
183 int status;
184
185 status = mailbox_send_cmd_async(send_id, MBOX_FCS_GET_PROVISION,
186 NULL, 0U, CMD_DIRECT);
187
188 if (status < 0) {
189 return INTEL_SIP_SMC_STATUS_ERROR;
190 }
191
192 return INTEL_SIP_SMC_STATUS_OK;
193}
194
Sieu Mun Tanga068fdf2022-05-11 10:01:54 +0800195uint32_t intel_fcs_cntr_set_preauth(uint8_t counter_type, int32_t counter_value,
196 uint32_t test_bit, uint32_t *mbox_error)
197{
198 int status;
199 uint32_t first_word;
200 uint32_t payload_size;
201
202 if ((test_bit != MBOX_TEST_BIT) &&
203 (test_bit != 0)) {
204 return INTEL_SIP_SMC_STATUS_REJECTED;
205 }
206
207 if ((counter_type < FCS_BIG_CNTR_SEL) ||
208 (counter_type > FCS_SVN_CNTR_3_SEL)) {
209 return INTEL_SIP_SMC_STATUS_REJECTED;
210 }
211
212 if ((counter_type == FCS_BIG_CNTR_SEL) &&
213 (counter_value > FCS_BIG_CNTR_VAL_MAX)) {
214 return INTEL_SIP_SMC_STATUS_REJECTED;
215 }
216
217 if ((counter_type >= FCS_SVN_CNTR_0_SEL) &&
218 (counter_type <= FCS_SVN_CNTR_3_SEL) &&
219 (counter_value > FCS_SVN_CNTR_VAL_MAX)) {
220 return INTEL_SIP_SMC_STATUS_REJECTED;
221 }
222
223 first_word = test_bit | counter_type;
224 fcs_cntr_set_preauth_payload payload = {
225 first_word,
226 counter_value
227 };
228
229 payload_size = sizeof(payload) / MBOX_WORD_BYTE;
230 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_CNTR_SET_PREAUTH,
231 (uint32_t *) &payload, payload_size,
232 CMD_CASUAL, NULL, NULL);
233
234 if (status < 0) {
235 *mbox_error = -status;
236 return INTEL_SIP_SMC_STATUS_ERROR;
237 }
238
239 return INTEL_SIP_SMC_STATUS_OK;
240}
241
Sieu Mun Tang128d2a72022-05-11 09:49:25 +0800242uint32_t intel_fcs_encryption(uint32_t src_addr, uint32_t src_size,
243 uint32_t dst_addr, uint32_t dst_size, uint32_t *send_id)
Sieu Mun Tang9f22cbf2022-03-02 11:04:09 +0800244{
245 int status;
Sieu Mun Tang128d2a72022-05-11 09:49:25 +0800246 uint32_t load_size;
Sieu Mun Tang9f22cbf2022-03-02 11:04:09 +0800247
Sieu Mun Tang128d2a72022-05-11 09:49:25 +0800248 fcs_encrypt_payload payload = {
249 FCS_ENCRYPTION_DATA_0,
Sieu Mun Tang9f22cbf2022-03-02 11:04:09 +0800250 src_addr,
251 src_size,
252 dst_addr,
253 dst_size };
Sieu Mun Tang128d2a72022-05-11 09:49:25 +0800254 load_size = sizeof(payload) / MBOX_WORD_BYTE;
Sieu Mun Tang9f22cbf2022-03-02 11:04:09 +0800255
Sieu Mun Tangdb79fa52022-03-20 00:49:57 +0800256 if (!is_address_in_ddr_range(src_addr, src_size) ||
257 !is_address_in_ddr_range(dst_addr, dst_size)) {
258 return INTEL_SIP_SMC_STATUS_REJECTED;
259 }
260
Sieu Mun Tang128d2a72022-05-11 09:49:25 +0800261 if (!is_size_4_bytes_aligned(src_size)) {
Sieu Mun Tangdb79fa52022-03-20 00:49:57 +0800262 return INTEL_SIP_SMC_STATUS_REJECTED;
263 }
264
Sieu Mun Tang128d2a72022-05-11 09:49:25 +0800265 status = mailbox_send_cmd_async(send_id, MBOX_FCS_ENCRYPT_REQ,
266 (uint32_t *) &payload, load_size,
267 CMD_INDIRECT);
268 inv_dcache_range(dst_addr, dst_size);
269
270 if (status < 0) {
271 return INTEL_SIP_SMC_STATUS_REJECTED;
272 }
273
274 return INTEL_SIP_SMC_STATUS_OK;
275}
276
277uint32_t intel_fcs_decryption(uint32_t src_addr, uint32_t src_size,
278 uint32_t dst_addr, uint32_t dst_size, uint32_t *send_id)
279{
280 int status;
281 uint32_t load_size;
282 uintptr_t id_offset;
283
284 id_offset = src_addr + FCS_OWNER_ID_OFFSET;
285 fcs_decrypt_payload payload = {
286 FCS_DECRYPTION_DATA_0,
287 {mmio_read_32(id_offset),
288 mmio_read_32(id_offset + MBOX_WORD_BYTE)},
289 src_addr,
290 src_size,
291 dst_addr,
292 dst_size };
293 load_size = sizeof(payload) / MBOX_WORD_BYTE;
294
295 if (!is_address_in_ddr_range(src_addr, src_size) ||
296 !is_address_in_ddr_range(dst_addr, dst_size)) {
297 return INTEL_SIP_SMC_STATUS_REJECTED;
298 }
299
300 if (!is_size_4_bytes_aligned(src_size)) {
301 return INTEL_SIP_SMC_STATUS_REJECTED;
Sieu Mun Tang9f22cbf2022-03-02 11:04:09 +0800302 }
303
Sieu Mun Tang128d2a72022-05-11 09:49:25 +0800304 status = mailbox_send_cmd_async(send_id, MBOX_FCS_DECRYPT_REQ,
305 (uint32_t *) &payload, load_size,
Sieu Mun Tang9f22cbf2022-03-02 11:04:09 +0800306 CMD_INDIRECT);
307 inv_dcache_range(dst_addr, dst_size);
308
309 if (status < 0) {
310 return INTEL_SIP_SMC_STATUS_REJECTED;
311 }
312
313 return INTEL_SIP_SMC_STATUS_OK;
314}
Sieu Mun Tanga34b8812022-03-17 03:11:55 +0800315
316uint32_t intel_fcs_get_rom_patch_sha384(uint64_t addr, uint64_t *ret_size,
317 uint32_t *mbox_error)
318{
319 int status;
320 unsigned int resp_len = FCS_SHA384_WORD_SIZE;
321
322 if (!is_address_in_ddr_range(addr, FCS_SHA384_BYTE_SIZE)) {
323 return INTEL_SIP_SMC_STATUS_REJECTED;
324 }
325
326 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_GET_ROM_PATCH_SHA384, NULL, 0U,
327 CMD_CASUAL, (uint32_t *) addr, &resp_len);
328
329 if (status < 0) {
330 *mbox_error = -status;
331 return INTEL_SIP_SMC_STATUS_ERROR;
332 }
333
334 if (resp_len != FCS_SHA384_WORD_SIZE) {
335 *mbox_error = GENERIC_RESPONSE_ERROR;
336 return INTEL_SIP_SMC_STATUS_ERROR;
337 }
338
339 *ret_size = FCS_SHA384_BYTE_SIZE;
340
341 flush_dcache_range(addr, *ret_size);
342
343 return INTEL_SIP_SMC_STATUS_OK;
344}
Sieu Mun Tang2a820b92022-05-11 09:59:55 +0800345
Sieu Mun Tang22322fb2022-05-09 16:05:58 +0800346int intel_fcs_encryption_ext(uint32_t session_id, uint32_t context_id,
347 uint32_t src_addr, uint32_t src_size,
348 uint32_t dst_addr, uint32_t *dst_size, uint32_t *mbox_error)
349{
350 int status;
351 uint32_t payload_size;
352 uint32_t resp_len = FCS_CRYPTION_RESP_WORD_SIZE;
353 uint32_t resp_data[FCS_CRYPTION_RESP_WORD_SIZE] = {0U};
354
355 if ((dst_size == NULL) || (mbox_error == NULL)) {
356 return INTEL_SIP_SMC_STATUS_REJECTED;
357 }
358
359 if (!is_address_in_ddr_range(src_addr, src_size) ||
360 !is_address_in_ddr_range(dst_addr, *dst_size)) {
361 return INTEL_SIP_SMC_STATUS_REJECTED;
362 }
363
364 if (!is_size_4_bytes_aligned(src_size)) {
365 return INTEL_SIP_SMC_STATUS_REJECTED;
366 }
367
368 fcs_encrypt_ext_payload payload = {
369 session_id,
370 context_id,
371 FCS_CRYPTION_CRYPTO_HEADER,
372 src_addr,
373 src_size,
374 dst_addr,
375 *dst_size
376 };
377
378 payload_size = sizeof(payload) / MBOX_WORD_BYTE;
379
380 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_ENCRYPT_REQ,
381 (uint32_t *) &payload, payload_size,
382 CMD_CASUAL, resp_data, &resp_len);
383
384 if (status < 0) {
385 *mbox_error = -status;
386 return INTEL_SIP_SMC_STATUS_ERROR;
387 }
388
389 if (resp_len != FCS_CRYPTION_RESP_WORD_SIZE) {
390 *mbox_error = MBOX_RET_ERROR;
391 return INTEL_SIP_SMC_STATUS_ERROR;
392 }
393
394 *dst_size = resp_data[FCS_CRYPTION_RESP_SIZE_OFFSET];
395 inv_dcache_range(dst_addr, *dst_size);
396
397 return INTEL_SIP_SMC_STATUS_OK;
398}
399
400int intel_fcs_decryption_ext(uint32_t session_id, uint32_t context_id,
401 uint32_t src_addr, uint32_t src_size,
402 uint32_t dst_addr, uint32_t *dst_size, uint32_t *mbox_error)
403{
404 int status;
405 uintptr_t id_offset;
406 uint32_t payload_size;
407 uint32_t resp_len = FCS_CRYPTION_RESP_WORD_SIZE;
408 uint32_t resp_data[FCS_CRYPTION_RESP_WORD_SIZE] = {0U};
409
410 if ((dst_size == NULL) || (mbox_error == NULL)) {
411 return INTEL_SIP_SMC_STATUS_REJECTED;
412 }
413
414 if (!is_address_in_ddr_range(src_addr, src_size) ||
415 !is_address_in_ddr_range(dst_addr, *dst_size)) {
416 return INTEL_SIP_SMC_STATUS_REJECTED;
417 }
418
419 if (!is_size_4_bytes_aligned(src_size)) {
420 return INTEL_SIP_SMC_STATUS_REJECTED;
421 }
422
423 id_offset = src_addr + FCS_OWNER_ID_OFFSET;
424 fcs_decrypt_ext_payload payload = {
425 session_id,
426 context_id,
427 FCS_CRYPTION_CRYPTO_HEADER,
428 {mmio_read_32(id_offset),
429 mmio_read_32(id_offset + MBOX_WORD_BYTE)},
430 src_addr,
431 src_size,
432 dst_addr,
433 *dst_size
434 };
435
436 payload_size = sizeof(payload) / MBOX_WORD_BYTE;
437
438 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_DECRYPT_REQ,
439 (uint32_t *) &payload, payload_size,
440 CMD_CASUAL, resp_data, &resp_len);
441
442 if (status < 0) {
443 *mbox_error = -status;
444 return INTEL_SIP_SMC_STATUS_ERROR;
445 }
446
447 if (resp_len != FCS_CRYPTION_RESP_WORD_SIZE) {
448 *mbox_error = MBOX_RET_ERROR;
449 return INTEL_SIP_SMC_STATUS_ERROR;
450 }
451
452 *dst_size = resp_data[FCS_CRYPTION_RESP_SIZE_OFFSET];
453 inv_dcache_range(dst_addr, *dst_size);
454
455 return INTEL_SIP_SMC_STATUS_OK;
456}
457
Sieu Mun Tang2a820b92022-05-11 09:59:55 +0800458int intel_fcs_sigma_teardown(uint32_t session_id, uint32_t *mbox_error)
459{
460 int status;
461
462 if ((session_id != PSGSIGMA_SESSION_ID_ONE) &&
463 (session_id != PSGSIGMA_UNKNOWN_SESSION)) {
464 return INTEL_SIP_SMC_STATUS_REJECTED;
465 }
466
467 psgsigma_teardown_msg message = {
468 RESERVED_AS_ZERO,
469 PSGSIGMA_TEARDOWN_MAGIC,
470 session_id
471 };
472
473 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_PSG_SIGMA_TEARDOWN,
474 (uint32_t *) &message, sizeof(message) / MBOX_WORD_BYTE,
475 CMD_CASUAL, NULL, NULL);
476
477 if (status < 0) {
478 *mbox_error = -status;
479 return INTEL_SIP_SMC_STATUS_ERROR;
480 }
481
482 return INTEL_SIP_SMC_STATUS_OK;
483}
484
485int intel_fcs_chip_id(uint32_t *id_low, uint32_t *id_high, uint32_t *mbox_error)
486{
487 int status;
488 uint32_t load_size;
489 uint32_t chip_id[2];
490
491 load_size = sizeof(chip_id) / MBOX_WORD_BYTE;
492
493 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_CMD_GET_CHIPID, NULL,
494 0U, CMD_CASUAL, (uint32_t *) chip_id, &load_size);
495
496 if (status < 0) {
497 *mbox_error = -status;
498 return INTEL_SIP_SMC_STATUS_ERROR;
499 }
500
501 *id_low = chip_id[0];
502 *id_high = chip_id[1];
503
504 return INTEL_SIP_SMC_STATUS_OK;
505}
506
507int intel_fcs_attestation_subkey(uint64_t src_addr, uint32_t src_size,
508 uint64_t dst_addr, uint32_t *dst_size, uint32_t *mbox_error)
509{
510 int status;
511 uint32_t send_size = src_size / MBOX_WORD_BYTE;
512 uint32_t ret_size = *dst_size / MBOX_WORD_BYTE;
513
514
515 if (!is_address_in_ddr_range(src_addr, src_size) ||
516 !is_address_in_ddr_range(dst_addr, *dst_size)) {
517 return INTEL_SIP_SMC_STATUS_REJECTED;
518 }
519
520 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_ATTESTATION_SUBKEY,
521 (uint32_t *) src_addr, send_size, CMD_CASUAL,
522 (uint32_t *) dst_addr, &ret_size);
523
524 if (status < 0) {
525 *mbox_error = -status;
526 return INTEL_SIP_SMC_STATUS_ERROR;
527 }
528
529 *dst_size = ret_size * MBOX_WORD_BYTE;
530 flush_dcache_range(dst_addr, *dst_size);
531
532 return INTEL_SIP_SMC_STATUS_OK;
533}
534
535int intel_fcs_get_measurement(uint64_t src_addr, uint32_t src_size,
536 uint64_t dst_addr, uint32_t *dst_size, uint32_t *mbox_error)
537{
538 int status;
539 uint32_t send_size = src_size / MBOX_WORD_BYTE;
540 uint32_t ret_size = *dst_size / MBOX_WORD_BYTE;
541
542 if (!is_address_in_ddr_range(src_addr, src_size) ||
543 !is_address_in_ddr_range(dst_addr, *dst_size)) {
544 return INTEL_SIP_SMC_STATUS_REJECTED;
545 }
546
547 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_GET_MEASUREMENT,
548 (uint32_t *) src_addr, send_size, CMD_CASUAL,
549 (uint32_t *) dst_addr, &ret_size);
550
551 if (status < 0) {
552 *mbox_error = -status;
553 return INTEL_SIP_SMC_STATUS_ERROR;
554 }
555
556 *dst_size = ret_size * MBOX_WORD_BYTE;
557 flush_dcache_range(dst_addr, *dst_size);
558
559 return INTEL_SIP_SMC_STATUS_OK;
560}
Sieu Mun Tang28af1652022-05-09 10:48:53 +0800561
562int intel_fcs_get_attestation_cert(uint32_t cert_request, uint64_t dst_addr,
563 uint32_t *dst_size, uint32_t *mbox_error)
564{
565 int status;
566 uint32_t ret_size = *dst_size / MBOX_WORD_BYTE;
567
568 if (mbox_error == NULL) {
569 return INTEL_SIP_SMC_STATUS_REJECTED;
570 }
571
Boon Khai Ngd2df2042021-08-30 15:05:49 +0800572 if (cert_request < FCS_ATTEST_FIRMWARE_CERT ||
573 cert_request > FCS_ATTEST_CERT_MAX_REQ_PARAM) {
Sieu Mun Tang28af1652022-05-09 10:48:53 +0800574 return INTEL_SIP_SMC_STATUS_REJECTED;
575 }
576
577 if (!is_address_in_ddr_range(dst_addr, *dst_size)) {
578 return INTEL_SIP_SMC_STATUS_REJECTED;
579 }
580
581 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_GET_ATTESTATION_CERT,
582 (uint32_t *) &cert_request, 1U, CMD_CASUAL,
583 (uint32_t *) dst_addr, &ret_size);
584
585 if (status < 0) {
586 *mbox_error = -status;
587 return INTEL_SIP_SMC_STATUS_ERROR;
588 }
589
590 *dst_size = ret_size * MBOX_WORD_BYTE;
591 flush_dcache_range(dst_addr, *dst_size);
592
593 return INTEL_SIP_SMC_STATUS_OK;
594}
595
596int intel_fcs_create_cert_on_reload(uint32_t cert_request,
597 uint32_t *mbox_error)
598{
599 int status;
600
601 if (mbox_error == NULL) {
602 return INTEL_SIP_SMC_STATUS_REJECTED;
603 }
604
Boon Khai Ngd2df2042021-08-30 15:05:49 +0800605 if (cert_request < FCS_ATTEST_FIRMWARE_CERT ||
606 cert_request > FCS_ATTEST_CERT_MAX_REQ_PARAM) {
Sieu Mun Tang28af1652022-05-09 10:48:53 +0800607 return INTEL_SIP_SMC_STATUS_REJECTED;
608 }
609
610 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_CREATE_CERT_ON_RELOAD,
611 (uint32_t *) &cert_request, 1U, CMD_CASUAL,
612 NULL, NULL);
613
614 if (status < 0) {
615 *mbox_error = -status;
616 return INTEL_SIP_SMC_STATUS_ERROR;
617 }
618
619 return INTEL_SIP_SMC_STATUS_OK;
620}
Sieu Mun Tang16754e12022-05-09 12:08:42 +0800621
622int intel_fcs_open_crypto_service_session(uint32_t *session_id,
623 uint32_t *mbox_error)
624{
625 int status;
626 uint32_t resp_len = 1U;
627
628 if ((session_id == NULL) || (mbox_error == NULL)) {
629 return INTEL_SIP_SMC_STATUS_REJECTED;
630 }
631
632 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_OPEN_CS_SESSION,
633 NULL, 0U, CMD_CASUAL, session_id, &resp_len);
634
635 if (status < 0) {
636 *mbox_error = -status;
637 return INTEL_SIP_SMC_STATUS_ERROR;
638 }
639
640 return INTEL_SIP_SMC_STATUS_OK;
641}
642
643int intel_fcs_close_crypto_service_session(uint32_t session_id,
644 uint32_t *mbox_error)
645{
646 int status;
647
648 if (mbox_error == NULL) {
649 return INTEL_SIP_SMC_STATUS_REJECTED;
650 }
651
652 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_CLOSE_CS_SESSION,
653 &session_id, 1U, CMD_CASUAL, NULL, NULL);
654
655 if (status < 0) {
656 *mbox_error = -status;
657 return INTEL_SIP_SMC_STATUS_ERROR;
658 }
659
660 return INTEL_SIP_SMC_STATUS_OK;
661}
Sieu Mun Tangfb1f6e92022-05-09 14:16:14 +0800662
663int intel_fcs_import_crypto_service_key(uint64_t src_addr, uint32_t src_size,
664 uint32_t *send_id)
665{
666 int status;
667
668 if (src_size > (FCS_CS_KEY_OBJ_MAX_WORD_SIZE *
669 MBOX_WORD_BYTE)) {
670 return INTEL_SIP_SMC_STATUS_REJECTED;
671 }
672
673 if (!is_address_in_ddr_range(src_addr, src_size)) {
674 return INTEL_SIP_SMC_STATUS_REJECTED;
675 }
676
677 status = mailbox_send_cmd_async(send_id, MBOX_FCS_IMPORT_CS_KEY,
678 (uint32_t *)src_addr, src_size / MBOX_WORD_BYTE,
679 CMD_INDIRECT);
680
681 if (status < 0) {
682 return INTEL_SIP_SMC_STATUS_ERROR;
683 }
684
685 return INTEL_SIP_SMC_STATUS_OK;
686}
687
688int intel_fcs_export_crypto_service_key(uint32_t session_id, uint32_t key_id,
689 uint64_t dst_addr, uint32_t *dst_size,
690 uint32_t *mbox_error)
691{
692 int status;
693 uint32_t i;
694 uint32_t payload_size;
695 uint32_t resp_len = FCS_CS_KEY_OBJ_MAX_WORD_SIZE;
696 uint32_t resp_data[FCS_CS_KEY_OBJ_MAX_WORD_SIZE] = {0U};
697 uint32_t op_status = 0U;
698
699 if ((dst_size == NULL) || (mbox_error == NULL)) {
700 return INTEL_SIP_SMC_STATUS_REJECTED;
701 }
702
703 if (!is_address_in_ddr_range(dst_addr, *dst_size)) {
704 return INTEL_SIP_SMC_STATUS_REJECTED;
705 }
706
707 fcs_cs_key_payload payload = {
708 session_id,
709 RESERVED_AS_ZERO,
710 RESERVED_AS_ZERO,
711 key_id
712 };
713
714 payload_size = sizeof(payload) / MBOX_WORD_BYTE;
715
716 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_EXPORT_CS_KEY,
717 (uint32_t *) &payload, payload_size,
718 CMD_CASUAL, resp_data, &resp_len);
719
720 if (resp_len > 0) {
721 op_status = resp_data[0] & FCS_CS_KEY_RESP_STATUS_MASK;
722 }
723
724 if (status < 0) {
725 *mbox_error = (-status) | (op_status << FCS_CS_KEY_RESP_STATUS_OFFSET);
726 return INTEL_SIP_SMC_STATUS_ERROR;
727 }
728
729 if (resp_len > 1) {
730
731 /* Export key object is start at second response data */
732 *dst_size = (resp_len - 1) * MBOX_WORD_BYTE;
733
734 for (i = 1U; i < resp_len; i++) {
735 mmio_write_32(dst_addr, resp_data[i]);
736 dst_addr += MBOX_WORD_BYTE;
737 }
738
739 flush_dcache_range(dst_addr - *dst_size, *dst_size);
740
741 } else {
742
743 /* Unexpected response, missing key object in response */
744 *mbox_error = MBOX_RET_ERROR;
745 return INTEL_SIP_SMC_STATUS_ERROR;
746 }
747
748 return INTEL_SIP_SMC_STATUS_OK;
749}
750
751int intel_fcs_remove_crypto_service_key(uint32_t session_id, uint32_t key_id,
752 uint32_t *mbox_error)
753{
754 int status;
755 uint32_t payload_size;
756 uint32_t resp_len = 1U;
757 uint32_t resp_data = 0U;
758 uint32_t op_status = 0U;
759
760 if (mbox_error == NULL) {
761 return INTEL_SIP_SMC_STATUS_REJECTED;
762 }
763
764 fcs_cs_key_payload payload = {
765 session_id,
766 RESERVED_AS_ZERO,
767 RESERVED_AS_ZERO,
768 key_id
769 };
770
771 payload_size = sizeof(payload) / MBOX_WORD_BYTE;
772
773 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_REMOVE_CS_KEY,
774 (uint32_t *) &payload, payload_size,
775 CMD_CASUAL, &resp_data, &resp_len);
776
777 if (resp_len > 0) {
778 op_status = resp_data & FCS_CS_KEY_RESP_STATUS_MASK;
779 }
780
781 if (status < 0) {
782 *mbox_error = (-status) | (op_status << FCS_CS_KEY_RESP_STATUS_OFFSET);
783 return INTEL_SIP_SMC_STATUS_ERROR;
784 }
785
786 return INTEL_SIP_SMC_STATUS_OK;
787}
788
789int intel_fcs_get_crypto_service_key_info(uint32_t session_id, uint32_t key_id,
790 uint64_t dst_addr, uint32_t *dst_size,
791 uint32_t *mbox_error)
792{
793 int status;
794 uint32_t payload_size;
795 uint32_t resp_len = FCS_CS_KEY_INFO_MAX_WORD_SIZE;
796 uint32_t op_status = 0U;
797
798 if ((dst_size == NULL) || (mbox_error == NULL)) {
799 return INTEL_SIP_SMC_STATUS_REJECTED;
800 }
801
802 if (!is_address_in_ddr_range(dst_addr, *dst_size)) {
803 return INTEL_SIP_SMC_STATUS_REJECTED;
804 }
805
806 fcs_cs_key_payload payload = {
807 session_id,
808 RESERVED_AS_ZERO,
809 RESERVED_AS_ZERO,
810 key_id
811 };
812
813 payload_size = sizeof(payload) / MBOX_WORD_BYTE;
814
815 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_GET_CS_KEY_INFO,
816 (uint32_t *) &payload, payload_size,
817 CMD_CASUAL, (uint32_t *) dst_addr, &resp_len);
818
819 if (resp_len > 0) {
820 op_status = mmio_read_32(dst_addr) &
821 FCS_CS_KEY_RESP_STATUS_MASK;
822 }
823
824 if (status < 0) {
825 *mbox_error = (-status) | (op_status << FCS_CS_KEY_RESP_STATUS_OFFSET);
826 return INTEL_SIP_SMC_STATUS_ERROR;
827 }
828
829 *dst_size = resp_len * MBOX_WORD_BYTE;
830 flush_dcache_range(dst_addr, *dst_size);
831
832 return INTEL_SIP_SMC_STATUS_OK;
833}
Sieu Mun Tangd907cc32022-05-10 17:24:05 +0800834
835int intel_fcs_get_digest_init(uint32_t session_id, uint32_t context_id,
836 uint32_t key_id, uint32_t param_size,
837 uint64_t param_data, uint32_t *mbox_error)
838{
839 return intel_fcs_crypto_service_init(session_id, context_id,
840 key_id, param_size, param_data,
841 (void *) &fcs_sha_get_digest_param,
842 mbox_error);
843}
844
845int intel_fcs_get_digest_finalize(uint32_t session_id, uint32_t context_id,
846 uint32_t src_addr, uint32_t src_size,
847 uint64_t dst_addr, uint32_t *dst_size,
848 uint32_t *mbox_error)
849{
850 int status;
851 uint32_t i;
Boon Khai Ngd2df2042021-08-30 15:05:49 +0800852 uint32_t resp_len;
Sieu Mun Tangd907cc32022-05-10 17:24:05 +0800853 uint32_t payload[FCS_GET_DIGEST_CMD_MAX_WORD_SIZE] = {0U};
854
855 if (dst_size == NULL || mbox_error == NULL) {
856 return INTEL_SIP_SMC_STATUS_REJECTED;
857 }
858
859 if (fcs_sha_get_digest_param.session_id != session_id ||
860 fcs_sha_get_digest_param.context_id != context_id) {
861 return INTEL_SIP_SMC_STATUS_REJECTED;
862 }
863
864 /* Source data must be 8 bytes aligned */
865 if (!is_8_bytes_aligned(src_size)) {
866 return INTEL_SIP_SMC_STATUS_REJECTED;
867 }
868
869 if (!is_address_in_ddr_range(src_addr, src_size) ||
870 !is_address_in_ddr_range(dst_addr, *dst_size)) {
871 return INTEL_SIP_SMC_STATUS_REJECTED;
872 }
873
Boon Khai Ngd2df2042021-08-30 15:05:49 +0800874 resp_len = *dst_size / MBOX_WORD_BYTE;
875
Sieu Mun Tangd907cc32022-05-10 17:24:05 +0800876 /* Prepare command payload */
877 i = 0;
878 /* Crypto header */
879 payload[i] = fcs_sha_get_digest_param.session_id;
880 i++;
881 payload[i] = fcs_sha_get_digest_param.context_id;
882 i++;
883 payload[i] = fcs_sha_get_digest_param.crypto_param_size
884 & FCS_CS_FIELD_SIZE_MASK;
885 payload[i] |= (FCS_CS_FIELD_FLAG_INIT | FCS_CS_FIELD_FLAG_UPDATE
886 | FCS_CS_FIELD_FLAG_FINALIZE)
887 << FCS_CS_FIELD_FLAG_OFFSET;
888 i++;
889 payload[i] = fcs_sha_get_digest_param.key_id;
890 i++;
891 /* Crypto parameters */
892 payload[i] = fcs_sha_get_digest_param.crypto_param
893 & INTEL_SIP_SMC_FCS_SHA_MODE_MASK;
894 payload[i] |= ((fcs_sha_get_digest_param.crypto_param
895 >> INTEL_SIP_SMC_FCS_DIGEST_SIZE_OFFSET)
896 & INTEL_SIP_SMC_FCS_DIGEST_SIZE_MASK)
897 << FCS_SHA_HMAC_CRYPTO_PARAM_SIZE_OFFSET;
898 i++;
899 /* Data source address and size */
900 payload[i] = src_addr;
901 i++;
902 payload[i] = src_size;
903 i++;
904
905 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_GET_DIGEST_REQ,
906 payload, i, CMD_CASUAL,
907 (uint32_t *) dst_addr, &resp_len);
908
909 memset((void *)&fcs_sha_get_digest_param, 0, sizeof(fcs_crypto_service_data));
910
911 if (status < 0) {
912 *mbox_error = -status;
913 return INTEL_SIP_SMC_STATUS_ERROR;
914 }
915
916 *dst_size = resp_len * MBOX_WORD_BYTE;
917 flush_dcache_range(dst_addr, *dst_size);
918
919 return INTEL_SIP_SMC_STATUS_OK;
920}
Sieu Mun Tang583149a2022-05-10 17:27:12 +0800921
922int intel_fcs_mac_verify_init(uint32_t session_id, uint32_t context_id,
923 uint32_t key_id, uint32_t param_size,
924 uint64_t param_data, uint32_t *mbox_error)
925{
926 return intel_fcs_crypto_service_init(session_id, context_id,
927 key_id, param_size, param_data,
928 (void *) &fcs_sha_mac_verify_param,
929 mbox_error);
930}
931
932int intel_fcs_mac_verify_finalize(uint32_t session_id, uint32_t context_id,
933 uint32_t src_addr, uint32_t src_size,
934 uint64_t dst_addr, uint32_t *dst_size,
935 uint32_t data_size, uint32_t *mbox_error)
936{
937 int status;
938 uint32_t i;
Boon Khai Ngd2df2042021-08-30 15:05:49 +0800939 uint32_t resp_len;
Sieu Mun Tang583149a2022-05-10 17:27:12 +0800940 uint32_t payload[FCS_MAC_VERIFY_CMD_MAX_WORD_SIZE] = {0U};
941 uintptr_t mac_offset;
942
943 if (dst_size == NULL || mbox_error == NULL) {
944 return INTEL_SIP_SMC_STATUS_REJECTED;
945 }
946
947 if (fcs_sha_mac_verify_param.session_id != session_id ||
948 fcs_sha_mac_verify_param.context_id != context_id) {
949 return INTEL_SIP_SMC_STATUS_REJECTED;
950 }
951
952 if (data_size >= src_size) {
953 return INTEL_SIP_SMC_STATUS_REJECTED;
954 }
955
956 if (!is_size_4_bytes_aligned(src_size) ||
957 !is_8_bytes_aligned(data_size)) {
958 return INTEL_SIP_SMC_STATUS_REJECTED;
959 }
960
961 if (!is_address_in_ddr_range(src_addr, src_size) ||
962 !is_address_in_ddr_range(dst_addr, *dst_size)) {
963 return INTEL_SIP_SMC_STATUS_REJECTED;
964 }
965
Boon Khai Ngd2df2042021-08-30 15:05:49 +0800966 resp_len = *dst_size / MBOX_WORD_BYTE;
967
Sieu Mun Tang583149a2022-05-10 17:27:12 +0800968 /* Prepare command payload */
969 i = 0;
970 /* Crypto header */
971 payload[i] = fcs_sha_mac_verify_param.session_id;
972 i++;
973 payload[i] = fcs_sha_mac_verify_param.context_id;
974 i++;
975 payload[i] = fcs_sha_mac_verify_param.crypto_param_size
976 & FCS_CS_FIELD_SIZE_MASK;
977 payload[i] |= (FCS_CS_FIELD_FLAG_INIT | FCS_CS_FIELD_FLAG_UPDATE
978 | FCS_CS_FIELD_FLAG_FINALIZE)
979 << FCS_CS_FIELD_FLAG_OFFSET;
980 i++;
981 payload[i] = fcs_sha_mac_verify_param.key_id;
982 i++;
983 /* Crypto parameters */
984 payload[i] = ((fcs_sha_mac_verify_param.crypto_param
985 >> INTEL_SIP_SMC_FCS_DIGEST_SIZE_OFFSET)
986 & INTEL_SIP_SMC_FCS_DIGEST_SIZE_MASK)
987 << FCS_SHA_HMAC_CRYPTO_PARAM_SIZE_OFFSET;
988 i++;
989 /* Data source address and size */
990 payload[i] = src_addr;
991 i++;
992 payload[i] = data_size;
993 i++;
994 /* Copy mac data to command */
995 mac_offset = src_addr + data_size;
996 memcpy((uint8_t *) &payload[i], (uint8_t *) mac_offset,
997 src_size - data_size);
998
999 i += (src_size - data_size) / MBOX_WORD_BYTE;
1000
1001 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_MAC_VERIFY_REQ,
1002 payload, i, CMD_CASUAL,
1003 (uint32_t *) dst_addr, &resp_len);
1004
1005 memset((void *)&fcs_sha_mac_verify_param, 0,
1006 sizeof(fcs_crypto_service_data));
1007
1008 if (status < 0) {
1009 *mbox_error = -status;
1010 return INTEL_SIP_SMC_STATUS_ERROR;
1011 }
1012
1013 *dst_size = resp_len * MBOX_WORD_BYTE;
1014 flush_dcache_range(dst_addr, *dst_size);
1015
1016 return INTEL_SIP_SMC_STATUS_OK;
1017}
Sieu Mun Tangb0c1d112022-05-10 17:30:00 +08001018
Sieu Mun Tang8aa05ad2022-05-10 17:50:30 +08001019int intel_fcs_ecdsa_hash_sign_init(uint32_t session_id, uint32_t context_id,
1020 uint32_t key_id, uint32_t param_size,
1021 uint64_t param_data, uint32_t *mbox_error)
1022{
1023 return intel_fcs_crypto_service_init(session_id, context_id,
1024 key_id, param_size, param_data,
1025 (void *) &fcs_ecdsa_hash_sign_param,
1026 mbox_error);
1027}
1028
1029int intel_fcs_ecdsa_hash_sign_finalize(uint32_t session_id, uint32_t context_id,
1030 uint32_t src_addr, uint32_t src_size,
1031 uint64_t dst_addr, uint32_t *dst_size,
1032 uint32_t *mbox_error)
1033{
1034 int status;
1035 uint32_t i;
1036 uint32_t payload[FCS_ECDSA_HASH_SIGN_CMD_MAX_WORD_SIZE] = {0U};
Boon Khai Ngd2df2042021-08-30 15:05:49 +08001037 uint32_t resp_len;
Sieu Mun Tang8aa05ad2022-05-10 17:50:30 +08001038 uintptr_t hash_data_addr;
1039
1040 if ((dst_size == NULL) || (mbox_error == NULL)) {
1041 return INTEL_SIP_SMC_STATUS_REJECTED;
1042 }
1043
1044 if (fcs_ecdsa_hash_sign_param.session_id != session_id ||
1045 fcs_ecdsa_hash_sign_param.context_id != context_id) {
1046 return INTEL_SIP_SMC_STATUS_REJECTED;
1047 }
1048
1049 if (!is_address_in_ddr_range(src_addr, src_size) ||
1050 !is_address_in_ddr_range(dst_addr, *dst_size)) {
1051 return INTEL_SIP_SMC_STATUS_REJECTED;
1052 }
1053
Boon Khai Ngd2df2042021-08-30 15:05:49 +08001054 resp_len = *dst_size / MBOX_WORD_BYTE;
1055
Sieu Mun Tang8aa05ad2022-05-10 17:50:30 +08001056 /* Prepare command payload */
1057 /* Crypto header */
1058 i = 0;
1059 payload[i] = fcs_ecdsa_hash_sign_param.session_id;
1060 i++;
1061 payload[i] = fcs_ecdsa_hash_sign_param.context_id;
1062
1063 i++;
1064 payload[i] = fcs_ecdsa_hash_sign_param.crypto_param_size
1065 & FCS_CS_FIELD_SIZE_MASK;
1066 payload[i] |= (FCS_CS_FIELD_FLAG_INIT | FCS_CS_FIELD_FLAG_UPDATE
1067 | FCS_CS_FIELD_FLAG_FINALIZE)
1068 << FCS_CS_FIELD_FLAG_OFFSET;
1069 i++;
1070 payload[i] = fcs_ecdsa_hash_sign_param.key_id;
1071
1072 /* Crypto parameters */
1073 i++;
1074 payload[i] = fcs_ecdsa_hash_sign_param.crypto_param
1075 & INTEL_SIP_SMC_FCS_ECC_ALGO_MASK;
1076
1077 /* Hash Data */
1078 i++;
1079 hash_data_addr = src_addr;
1080 memcpy((uint8_t *) &payload[i], (uint8_t *) hash_data_addr,
1081 src_size);
1082
1083 i += src_size / MBOX_WORD_BYTE;
1084
1085 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_ECDSA_HASH_SIGN_REQ,
1086 payload, i, CMD_CASUAL, (uint32_t *) dst_addr,
1087 &resp_len);
1088
1089 memset((void *) &fcs_ecdsa_hash_sign_param,
1090 0, sizeof(fcs_crypto_service_data));
1091
1092 if (status < 0) {
1093 *mbox_error = -status;
1094 return INTEL_SIP_SMC_STATUS_ERROR;
1095 }
1096
1097 *dst_size = resp_len * MBOX_WORD_BYTE;
1098 flush_dcache_range(dst_addr, *dst_size);
1099
1100 return INTEL_SIP_SMC_STATUS_OK;
1101}
1102
Sieu Mun Tang59357e82022-05-10 17:53:32 +08001103int intel_fcs_ecdsa_hash_sig_verify_init(uint32_t session_id, uint32_t context_id,
1104 uint32_t key_id, uint32_t param_size,
1105 uint64_t param_data, uint32_t *mbox_error)
1106{
1107 return intel_fcs_crypto_service_init(session_id, context_id,
1108 key_id, param_size, param_data,
1109 (void *) &fcs_ecdsa_hash_sig_verify_param,
1110 mbox_error);
1111}
1112
1113int intel_fcs_ecdsa_hash_sig_verify_finalize(uint32_t session_id, uint32_t context_id,
1114 uint32_t src_addr, uint32_t src_size,
1115 uint64_t dst_addr, uint32_t *dst_size,
1116 uint32_t *mbox_error)
1117{
1118 int status;
1119 uint32_t i = 0;
1120 uint32_t payload[FCS_ECDSA_HASH_SIG_VERIFY_CMD_MAX_WORD_SIZE] = {0U};
Boon Khai Ngd2df2042021-08-30 15:05:49 +08001121 uint32_t resp_len;
Sieu Mun Tang59357e82022-05-10 17:53:32 +08001122 uintptr_t hash_sig_pubkey_addr;
1123
1124 if ((dst_size == NULL) || (mbox_error == NULL)) {
1125 return INTEL_SIP_SMC_STATUS_REJECTED;
1126 }
1127
1128 if (fcs_ecdsa_hash_sig_verify_param.session_id != session_id ||
1129 fcs_ecdsa_hash_sig_verify_param.context_id != context_id) {
1130 return INTEL_SIP_SMC_STATUS_REJECTED;
1131 }
1132
1133 if (!is_address_in_ddr_range(src_addr, src_size) ||
1134 !is_address_in_ddr_range(dst_addr, *dst_size)) {
1135 return INTEL_SIP_SMC_STATUS_REJECTED;
1136 }
1137
Boon Khai Ngd2df2042021-08-30 15:05:49 +08001138 resp_len = *dst_size / MBOX_WORD_BYTE;
1139
Sieu Mun Tang59357e82022-05-10 17:53:32 +08001140 /* Prepare command payload */
1141 /* Crypto header */
1142 i = 0;
1143 payload[i] = fcs_ecdsa_hash_sig_verify_param.session_id;
1144
1145 i++;
1146 payload[i] = fcs_ecdsa_hash_sig_verify_param.context_id;
1147
1148 i++;
1149 payload[i] = fcs_ecdsa_hash_sig_verify_param.crypto_param_size
1150 & FCS_CS_FIELD_SIZE_MASK;
1151 payload[i] |= (FCS_CS_FIELD_FLAG_INIT | FCS_CS_FIELD_FLAG_UPDATE
1152 | FCS_CS_FIELD_FLAG_FINALIZE)
1153 << FCS_CS_FIELD_FLAG_OFFSET;
1154
1155 i++;
1156 payload[i] = fcs_ecdsa_hash_sig_verify_param.key_id;
1157
1158 /* Crypto parameters */
1159 i++;
1160 payload[i] = fcs_ecdsa_hash_sig_verify_param.crypto_param
1161 & INTEL_SIP_SMC_FCS_ECC_ALGO_MASK;
1162
1163 /* Hash Data Word, Signature Data Word and Public Key Data word */
1164 i++;
1165 hash_sig_pubkey_addr = src_addr;
1166 memcpy((uint8_t *) &payload[i],
1167 (uint8_t *) hash_sig_pubkey_addr, src_size);
1168
1169 i += (src_size / MBOX_WORD_BYTE);
1170
1171 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_ECDSA_HASH_SIG_VERIFY,
1172 payload, i, CMD_CASUAL, (uint32_t *) dst_addr,
1173 &resp_len);
1174
1175 memset((void *)&fcs_ecdsa_hash_sig_verify_param,
1176 0, sizeof(fcs_crypto_service_data));
1177
1178 if (status < 0) {
1179 *mbox_error = -status;
1180 return INTEL_SIP_SMC_STATUS_ERROR;
1181 }
1182
1183 *dst_size = resp_len * MBOX_WORD_BYTE;
1184 flush_dcache_range(dst_addr, *dst_size);
1185
1186 return INTEL_SIP_SMC_STATUS_OK;
1187}
1188
Sieu Mun Tang153ecfb2022-05-10 17:39:26 +08001189int intel_fcs_ecdsa_sha2_data_sign_init(uint32_t session_id,
1190 uint32_t context_id, uint32_t key_id,
1191 uint32_t param_size, uint64_t param_data,
1192 uint32_t *mbox_error)
1193{
1194 return intel_fcs_crypto_service_init(session_id, context_id,
1195 key_id, param_size, param_data,
1196 (void *) &fcs_sha2_data_sign_param,
1197 mbox_error);
1198}
1199
1200int intel_fcs_ecdsa_sha2_data_sign_finalize(uint32_t session_id,
1201 uint32_t context_id, uint32_t src_addr,
1202 uint32_t src_size, uint64_t dst_addr,
1203 uint32_t *dst_size, uint32_t *mbox_error)
1204{
1205 int status;
1206 int i;
1207 uint32_t payload[FCS_ECDSA_SHA2_DATA_SIGN_CMD_MAX_WORD_SIZE] = {0U};
Boon Khai Ngd2df2042021-08-30 15:05:49 +08001208 uint32_t resp_len;
Sieu Mun Tang153ecfb2022-05-10 17:39:26 +08001209
1210 if ((dst_size == NULL) || (mbox_error == NULL)) {
1211 return INTEL_SIP_SMC_STATUS_REJECTED;
1212 }
1213
1214 if (fcs_sha2_data_sign_param.session_id != session_id ||
1215 fcs_sha2_data_sign_param.context_id != context_id) {
1216 return INTEL_SIP_SMC_STATUS_REJECTED;
1217 }
1218
1219 /* Source data must be 8 bytes aligned */
1220 if (!is_8_bytes_aligned(src_size)) {
1221 return INTEL_SIP_SMC_STATUS_REJECTED;
1222 }
1223
1224 if (!is_address_in_ddr_range(src_addr, src_size) ||
1225 !is_address_in_ddr_range(dst_addr, *dst_size)) {
1226 return INTEL_SIP_SMC_STATUS_REJECTED;
1227 }
1228
Boon Khai Ngd2df2042021-08-30 15:05:49 +08001229 resp_len = *dst_size / MBOX_WORD_BYTE;
1230
Sieu Mun Tang153ecfb2022-05-10 17:39:26 +08001231 /* Prepare command payload */
1232 /* Crypto header */
1233 i = 0;
1234 payload[i] = fcs_sha2_data_sign_param.session_id;
1235 i++;
1236 payload[i] = fcs_sha2_data_sign_param.context_id;
1237 i++;
1238 payload[i] = fcs_sha2_data_sign_param.crypto_param_size
1239 & FCS_CS_FIELD_SIZE_MASK;
1240 payload[i] |= (FCS_CS_FIELD_FLAG_INIT | FCS_CS_FIELD_FLAG_UPDATE
1241 | FCS_CS_FIELD_FLAG_FINALIZE)
1242 << FCS_CS_FIELD_FLAG_OFFSET;
1243 i++;
1244 payload[i] = fcs_sha2_data_sign_param.key_id;
1245 /* Crypto parameters */
1246 i++;
1247 payload[i] = fcs_sha2_data_sign_param.crypto_param
1248 & INTEL_SIP_SMC_FCS_ECC_ALGO_MASK;
1249 /* Data source address and size */
1250 i++;
1251 payload[i] = src_addr;
1252 i++;
1253 payload[i] = src_size;
1254 i++;
1255 status = mailbox_send_cmd(MBOX_JOB_ID,
1256 MBOX_FCS_ECDSA_SHA2_DATA_SIGN_REQ, payload,
1257 i, CMD_CASUAL, (uint32_t *) dst_addr,
1258 &resp_len);
1259
1260 memset((void *)&fcs_sha2_data_sign_param, 0,
1261 sizeof(fcs_crypto_service_data));
1262
1263 if (status < 0) {
1264 *mbox_error = -status;
1265 return INTEL_SIP_SMC_STATUS_ERROR;
1266 }
1267
1268 *dst_size = resp_len * MBOX_WORD_BYTE;
1269 flush_dcache_range(dst_addr, *dst_size);
1270
1271 return INTEL_SIP_SMC_STATUS_OK;
1272}
1273
Sieu Mun Tangdcaab772022-05-11 10:16:40 +08001274int intel_fcs_ecdsa_sha2_data_sig_verify_init(uint32_t session_id,
1275 uint32_t context_id, uint32_t key_id,
1276 uint32_t param_size, uint64_t param_data,
1277 uint32_t *mbox_error)
1278{
1279 return intel_fcs_crypto_service_init(session_id, context_id,
1280 key_id, param_size, param_data,
1281 (void *) &fcs_sha2_data_sig_verify_param,
1282 mbox_error);
1283}
1284
1285int intel_fcs_ecdsa_sha2_data_sig_verify_finalize(uint32_t session_id,
1286 uint32_t context_id, uint32_t src_addr,
1287 uint32_t src_size, uint64_t dst_addr,
1288 uint32_t *dst_size, uint32_t data_size,
1289 uint32_t *mbox_error)
1290{
1291 int status;
1292 uint32_t i;
1293 uint32_t payload[FCS_ECDSA_SHA2_DATA_SIG_VERIFY_CMD_MAX_WORD_SIZE] = {0U};
Boon Khai Ngd2df2042021-08-30 15:05:49 +08001294 uint32_t resp_len;
Sieu Mun Tangdcaab772022-05-11 10:16:40 +08001295 uintptr_t sig_pubkey_offset;
1296
1297 if ((dst_size == NULL) || (mbox_error == NULL)) {
1298 return INTEL_SIP_SMC_STATUS_REJECTED;
1299 }
1300
1301 if (fcs_sha2_data_sig_verify_param.session_id != session_id ||
1302 fcs_sha2_data_sig_verify_param.context_id != context_id) {
1303 return INTEL_SIP_SMC_STATUS_REJECTED;
1304 }
1305
1306 if (!is_size_4_bytes_aligned(src_size)) {
1307 return INTEL_SIP_SMC_STATUS_REJECTED;
1308 }
1309
1310 if (!is_8_bytes_aligned(data_size) ||
1311 !is_8_bytes_aligned(src_addr)) {
1312 return INTEL_SIP_SMC_STATUS_REJECTED;
1313 }
1314
1315 if (!is_address_in_ddr_range(src_addr, src_size) ||
1316 !is_address_in_ddr_range(dst_addr, *dst_size)) {
1317 return INTEL_SIP_SMC_STATUS_REJECTED;
1318 }
1319
Boon Khai Ngd2df2042021-08-30 15:05:49 +08001320 resp_len = *dst_size / MBOX_WORD_BYTE;
1321
Sieu Mun Tangdcaab772022-05-11 10:16:40 +08001322 /* Prepare command payload */
1323 /* Crypto header */
1324 i = 0;
1325 payload[i] = fcs_sha2_data_sig_verify_param.session_id;
1326 i++;
1327 payload[i] = fcs_sha2_data_sig_verify_param.context_id;
1328 i++;
1329
1330 payload[i] = fcs_sha2_data_sig_verify_param.crypto_param_size
1331 & FCS_CS_FIELD_SIZE_MASK;
1332 payload[i] |= (FCS_CS_FIELD_FLAG_INIT | FCS_CS_FIELD_FLAG_UPDATE
1333 | FCS_CS_FIELD_FLAG_FINALIZE)
1334 << FCS_CS_FIELD_FLAG_OFFSET;
1335 i++;
1336 payload[i] = fcs_sha2_data_sig_verify_param.key_id;
1337 i++;
1338 /* Crypto parameters */
1339 payload[i] = fcs_sha2_data_sig_verify_param.crypto_param
1340 & INTEL_SIP_SMC_FCS_ECC_ALGO_MASK;
1341 i++;
1342 /* Data source address and size */
1343 payload[i] = src_addr;
1344 i++;
1345 payload[i] = data_size;
1346 i++;
1347 /* Signature + Public Key Data */
1348 sig_pubkey_offset = src_addr + data_size;
1349 memcpy((uint8_t *) &payload[i], (uint8_t *) sig_pubkey_offset,
1350 src_size - data_size);
1351
1352 i += (src_size - data_size) / MBOX_WORD_BYTE;
1353
1354 status = mailbox_send_cmd(MBOX_JOB_ID,
1355 MBOX_FCS_ECDSA_SHA2_DATA_SIGN_VERIFY, payload, i,
1356 CMD_CASUAL, (uint32_t *) dst_addr, &resp_len);
1357
1358 memset((void *) &fcs_sha2_data_sig_verify_param, 0,
1359 sizeof(fcs_crypto_service_data));
1360
1361 if (status < 0) {
1362 *mbox_error = -status;
1363 return INTEL_SIP_SMC_STATUS_ERROR;
1364 }
1365
1366 *dst_size = resp_len * MBOX_WORD_BYTE;
1367 flush_dcache_range(dst_addr, *dst_size);
1368
1369 return INTEL_SIP_SMC_STATUS_OK;
1370}
1371
Sieu Mun Tange2f3ede2022-05-10 17:36:32 +08001372int intel_fcs_ecdsa_get_pubkey_init(uint32_t session_id, uint32_t context_id,
1373 uint32_t key_id, uint32_t param_size,
1374 uint64_t param_data, uint32_t *mbox_error)
1375{
1376 return intel_fcs_crypto_service_init(session_id, context_id,
1377 key_id, param_size, param_data,
1378 (void *) &fcs_ecdsa_get_pubkey_param,
1379 mbox_error);
1380}
1381
1382int intel_fcs_ecdsa_get_pubkey_finalize(uint32_t session_id, uint32_t context_id,
1383 uint64_t dst_addr, uint32_t *dst_size,
1384 uint32_t *mbox_error)
1385{
1386 int status;
1387 int i;
1388 uint32_t crypto_header;
Boon Khai Ngd2df2042021-08-30 15:05:49 +08001389 uint32_t ret_size;
Sieu Mun Tange2f3ede2022-05-10 17:36:32 +08001390 uint32_t payload[FCS_ECDSA_GET_PUBKEY_MAX_WORD_SIZE] = {0U};
1391
1392 if ((dst_size == NULL) || (mbox_error == NULL)) {
1393 return INTEL_SIP_SMC_STATUS_REJECTED;
1394 }
1395
1396 if (fcs_ecdsa_get_pubkey_param.session_id != session_id ||
1397 fcs_ecdsa_get_pubkey_param.context_id != context_id) {
1398 return INTEL_SIP_SMC_STATUS_REJECTED;
1399 }
1400
Boon Khai Ngd2df2042021-08-30 15:05:49 +08001401 ret_size = *dst_size / MBOX_WORD_BYTE;
1402
Sieu Mun Tange2f3ede2022-05-10 17:36:32 +08001403 crypto_header = ((FCS_CS_FIELD_FLAG_INIT |
1404 FCS_CS_FIELD_FLAG_UPDATE |
1405 FCS_CS_FIELD_FLAG_FINALIZE) <<
1406 FCS_CS_FIELD_FLAG_OFFSET) |
1407 fcs_ecdsa_get_pubkey_param.crypto_param_size;
1408 i = 0;
1409 /* Prepare command payload */
1410 payload[i] = session_id;
1411 i++;
1412 payload[i] = context_id;
1413 i++;
1414 payload[i] = crypto_header;
1415 i++;
1416 payload[i] = fcs_ecdsa_get_pubkey_param.key_id;
1417 i++;
1418 payload[i] = (uint32_t) fcs_ecdsa_get_pubkey_param.crypto_param &
1419 INTEL_SIP_SMC_FCS_ECC_ALGO_MASK;
1420 i++;
1421
1422 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_ECDSA_GET_PUBKEY,
1423 payload, i, CMD_CASUAL,
1424 (uint32_t *) dst_addr, &ret_size);
1425
1426 memset((void *) &fcs_ecdsa_get_pubkey_param, 0,
1427 sizeof(fcs_crypto_service_data));
1428
1429 if (status < 0) {
1430 *mbox_error = -status;
1431 return INTEL_SIP_SMC_STATUS_ERROR;
1432 }
1433
1434 *dst_size = ret_size * MBOX_WORD_BYTE;
1435 flush_dcache_range(dst_addr, *dst_size);
1436
1437 return INTEL_SIP_SMC_STATUS_OK;
1438}
1439
Sieu Mun Tang0675c222022-05-10 17:48:11 +08001440int intel_fcs_ecdh_request_init(uint32_t session_id, uint32_t context_id,
1441 uint32_t key_id, uint32_t param_size,
1442 uint64_t param_data, uint32_t *mbox_error)
1443{
1444 return intel_fcs_crypto_service_init(session_id, context_id,
1445 key_id, param_size, param_data,
1446 (void *) &fcs_ecdh_request_param,
1447 mbox_error);
1448}
1449
1450int intel_fcs_ecdh_request_finalize(uint32_t session_id, uint32_t context_id,
1451 uint32_t src_addr, uint32_t src_size,
1452 uint64_t dst_addr, uint32_t *dst_size,
1453 uint32_t *mbox_error)
1454{
1455 int status;
1456 uint32_t i;
1457 uint32_t payload[FCS_ECDH_REQUEST_CMD_MAX_WORD_SIZE] = {0U};
Boon Khai Ngd2df2042021-08-30 15:05:49 +08001458 uint32_t resp_len;
Sieu Mun Tang0675c222022-05-10 17:48:11 +08001459 uintptr_t pubkey;
1460
1461 if ((dst_size == NULL) || (mbox_error == NULL)) {
1462 return INTEL_SIP_SMC_STATUS_REJECTED;
1463 }
1464
1465 if (fcs_ecdh_request_param.session_id != session_id ||
1466 fcs_ecdh_request_param.context_id != context_id) {
1467 return INTEL_SIP_SMC_STATUS_REJECTED;
1468 }
1469
1470 if (!is_address_in_ddr_range(src_addr, src_size) ||
1471 !is_address_in_ddr_range(dst_addr, *dst_size)) {
1472 return INTEL_SIP_SMC_STATUS_REJECTED;
1473 }
1474
Boon Khai Ngd2df2042021-08-30 15:05:49 +08001475 resp_len = *dst_size / MBOX_WORD_BYTE;
1476
Sieu Mun Tang0675c222022-05-10 17:48:11 +08001477 /* Prepare command payload */
1478 i = 0;
1479 /* Crypto header */
1480 payload[i] = fcs_ecdh_request_param.session_id;
1481 i++;
1482 payload[i] = fcs_ecdh_request_param.context_id;
1483 i++;
1484 payload[i] = fcs_ecdh_request_param.crypto_param_size
1485 & FCS_CS_FIELD_SIZE_MASK;
1486 payload[i] |= (FCS_CS_FIELD_FLAG_INIT | FCS_CS_FIELD_FLAG_UPDATE
1487 | FCS_CS_FIELD_FLAG_FINALIZE)
1488 << FCS_CS_FIELD_FLAG_OFFSET;
1489 i++;
1490 payload[i] = fcs_ecdh_request_param.key_id;
1491 i++;
1492 /* Crypto parameters */
1493 payload[i] = fcs_ecdh_request_param.crypto_param
1494 & INTEL_SIP_SMC_FCS_ECC_ALGO_MASK;
1495 i++;
1496 /* Public key data */
1497 pubkey = src_addr;
1498 memcpy((uint8_t *) &payload[i], (uint8_t *) pubkey, src_size);
1499 i += src_size / MBOX_WORD_BYTE;
1500
1501 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_ECDH_REQUEST,
1502 payload, i, CMD_CASUAL, (uint32_t *) dst_addr,
1503 &resp_len);
1504
1505 memset((void *)&fcs_ecdh_request_param, 0,
1506 sizeof(fcs_crypto_service_data));
1507
1508 if (status < 0) {
1509 *mbox_error = -status;
1510 return INTEL_SIP_SMC_STATUS_ERROR;
1511 }
1512
1513 *dst_size = resp_len * MBOX_WORD_BYTE;
1514 flush_dcache_range(dst_addr, *dst_size);
1515
1516 return INTEL_SIP_SMC_STATUS_OK;
1517}
1518
Sieu Mun Tangb0c1d112022-05-10 17:30:00 +08001519int intel_fcs_aes_crypt_init(uint32_t session_id, uint32_t context_id,
1520 uint32_t key_id, uint64_t param_addr,
1521 uint32_t param_size, uint32_t *mbox_error)
1522{
1523 if (mbox_error == NULL) {
1524 return INTEL_SIP_SMC_STATUS_REJECTED;
1525 }
1526
1527 memset((void *)&fcs_aes_init_payload, 0U, sizeof(fcs_aes_init_payload));
1528
1529 fcs_aes_init_payload.session_id = session_id;
1530 fcs_aes_init_payload.context_id = context_id;
1531 fcs_aes_init_payload.param_size = param_size;
1532 fcs_aes_init_payload.key_id = key_id;
1533
1534 memcpy((uint8_t *) fcs_aes_init_payload.crypto_param,
1535 (uint8_t *) param_addr, param_size);
1536
1537 *mbox_error = 0;
1538
1539 return INTEL_SIP_SMC_STATUS_OK;
1540}
1541
1542int intel_fcs_aes_crypt_finalize(uint32_t session_id, uint32_t context_id,
1543 uint64_t src_addr, uint32_t src_size,
1544 uint64_t dst_addr, uint32_t dst_size,
1545 uint32_t *send_id)
1546{
1547 int status;
1548 int i;
1549 uint32_t crypto_header;
1550 uint32_t fcs_aes_crypt_payload[FCS_AES_CMD_MAX_WORD_SIZE];
1551
1552 if (fcs_aes_init_payload.session_id != session_id ||
1553 fcs_aes_init_payload.context_id != context_id) {
1554 return INTEL_SIP_SMC_STATUS_REJECTED;
1555 }
1556
1557 if ((!is_8_bytes_aligned(src_addr)) ||
1558 (!is_32_bytes_aligned(src_size)) ||
1559 (!is_address_in_ddr_range(src_addr, src_size))) {
1560 return INTEL_SIP_SMC_STATUS_REJECTED;
1561 }
1562
1563 if ((!is_8_bytes_aligned(dst_addr)) ||
1564 (!is_32_bytes_aligned(dst_size))) {
1565 return INTEL_SIP_SMC_STATUS_REJECTED;
1566 }
1567
1568 if ((dst_size > FCS_AES_MAX_DATA_SIZE ||
1569 dst_size < FCS_AES_MIN_DATA_SIZE) ||
1570 (src_size > FCS_AES_MAX_DATA_SIZE ||
1571 src_size < FCS_AES_MIN_DATA_SIZE)) {
1572 return INTEL_SIP_SMC_STATUS_REJECTED;
1573 }
1574
1575 crypto_header = ((FCS_CS_FIELD_FLAG_INIT |
1576 FCS_CS_FIELD_FLAG_UPDATE |
1577 FCS_CS_FIELD_FLAG_FINALIZE) <<
1578 FCS_CS_FIELD_FLAG_OFFSET) |
1579 fcs_aes_init_payload.param_size;
1580 i = 0U;
1581 fcs_aes_crypt_payload[i] = session_id;
1582 i++;
1583 fcs_aes_crypt_payload[i] = context_id;
1584 i++;
1585 fcs_aes_crypt_payload[i] = crypto_header;
1586 i++;
1587 fcs_aes_crypt_payload[i] = fcs_aes_init_payload.key_id;
1588
1589 i++;
1590 memcpy((uint8_t *) &fcs_aes_crypt_payload[i],
1591 (uint8_t *) fcs_aes_init_payload.crypto_param,
1592 fcs_aes_init_payload.param_size);
1593
1594 i += fcs_aes_init_payload.param_size / MBOX_WORD_BYTE;
1595
1596 fcs_aes_crypt_payload[i] = (uint32_t) src_addr;
1597 i++;
1598 fcs_aes_crypt_payload[i] = src_size;
1599 i++;
1600 fcs_aes_crypt_payload[i] = (uint32_t) dst_addr;
1601 i++;
1602 fcs_aes_crypt_payload[i] = dst_size;
1603 i++;
1604
1605 status = mailbox_send_cmd_async(send_id, MBOX_FCS_AES_CRYPT_REQ,
1606 fcs_aes_crypt_payload, i,
1607 CMD_INDIRECT);
1608
1609 memset((void *)&fcs_aes_init_payload, 0U, sizeof(fcs_aes_init_payload));
1610
1611 if (status < 0U) {
1612 return INTEL_SIP_SMC_STATUS_ERROR;
1613 }
1614
1615 return INTEL_SIP_SMC_STATUS_OK;
1616}