blob: e3ed4e065b544f9302e5f1a26f1d4d83c4f85cb0 [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 Tang153ecfb2022-05-10 17:39:26 +080018static fcs_crypto_service_data fcs_sha2_data_sign_param;
Sieu Mun Tangdcaab772022-05-11 10:16:40 +080019static fcs_crypto_service_data fcs_sha2_data_sig_verify_param;
20static fcs_crypto_service_data fcs_ecdsa_get_pubkey_param;
Sieu Mun Tang0675c222022-05-10 17:48:11 +080021static fcs_crypto_service_data fcs_ecdh_request_param;
Sieu Mun Tangd907cc32022-05-10 17:24:05 +080022
Sieu Mun Tang128d2a72022-05-11 09:49:25 +080023bool is_size_4_bytes_aligned(uint32_t size)
Sieu Mun Tangdb79fa52022-03-20 00:49:57 +080024{
25 if ((size % MBOX_WORD_BYTE) != 0U) {
26 return false;
27 } else {
28 return true;
29 }
Sieu Mun Tangd907cc32022-05-10 17:24:05 +080030}
31
32static bool is_8_bytes_aligned(uint32_t data)
33{
34 if ((data % (MBOX_WORD_BYTE * 2U)) != 0U) {
35 return false;
36 } else {
37 return true;
38 }
39}
40
Sieu Mun Tangb0c1d112022-05-10 17:30:00 +080041static bool is_32_bytes_aligned(uint32_t data)
42{
43 if ((data % (8U * MBOX_WORD_BYTE)) != 0U) {
44 return false;
45 } else {
46 return true;
47 }
48}
49
Sieu Mun Tangd907cc32022-05-10 17:24:05 +080050static int intel_fcs_crypto_service_init(uint32_t session_id,
51 uint32_t context_id, uint32_t key_id,
52 uint32_t param_size, uint64_t param_data,
53 fcs_crypto_service_data *data_addr,
54 uint32_t *mbox_error)
55{
56 if (mbox_error == NULL) {
57 return INTEL_SIP_SMC_STATUS_REJECTED;
58 }
59
60 if (param_size != 4) {
61 return INTEL_SIP_SMC_STATUS_REJECTED;
62 }
63
64 memset(data_addr, 0, sizeof(fcs_crypto_service_data));
65
66 data_addr->session_id = session_id;
67 data_addr->context_id = context_id;
68 data_addr->key_id = key_id;
69 data_addr->crypto_param_size = param_size;
70 data_addr->crypto_param = param_data;
71
72 *mbox_error = 0;
73
74 return INTEL_SIP_SMC_STATUS_OK;
Sieu Mun Tangdb79fa52022-03-20 00:49:57 +080075}
76
Sieu Mun Tang9f22cbf2022-03-02 11:04:09 +080077uint32_t intel_fcs_random_number_gen(uint64_t addr, uint64_t *ret_size,
78 uint32_t *mbox_error)
79{
80 int status;
81 unsigned int i;
82 unsigned int resp_len = FCS_RANDOM_WORD_SIZE;
83 uint32_t random_data[FCS_RANDOM_WORD_SIZE] = {0U};
84
85 if (!is_address_in_ddr_range(addr, FCS_RANDOM_BYTE_SIZE)) {
86 return INTEL_SIP_SMC_STATUS_REJECTED;
87 }
88
89 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_RANDOM_GEN, NULL, 0U,
90 CMD_CASUAL, random_data, &resp_len);
91
92 if (status < 0) {
93 *mbox_error = -status;
94 return INTEL_SIP_SMC_STATUS_ERROR;
95 }
96
97 if (resp_len != FCS_RANDOM_WORD_SIZE) {
98 *mbox_error = GENERIC_RESPONSE_ERROR;
99 return INTEL_SIP_SMC_STATUS_ERROR;
100 }
101
102 *ret_size = FCS_RANDOM_BYTE_SIZE;
103
104 for (i = 0U; i < FCS_RANDOM_WORD_SIZE; i++) {
105 mmio_write_32(addr, random_data[i]);
106 addr += MBOX_WORD_BYTE;
107 }
108
109 flush_dcache_range(addr - *ret_size, *ret_size);
110
111 return INTEL_SIP_SMC_STATUS_OK;
112}
113
Sieu Mun Tange7a037f2022-05-10 17:18:19 +0800114int intel_fcs_random_number_gen_ext(uint32_t session_id, uint32_t context_id,
115 uint32_t size, uint32_t *send_id)
116{
117 int status;
118 uint32_t payload_size;
119 uint32_t crypto_header;
120
121 if (size > (FCS_RANDOM_EXT_MAX_WORD_SIZE *
122 MBOX_WORD_BYTE) || size == 0U) {
123 return INTEL_SIP_SMC_STATUS_REJECTED;
124 }
125
126 if (!is_size_4_bytes_aligned(size)) {
127 return INTEL_SIP_SMC_STATUS_REJECTED;
128 }
129
130 crypto_header = (FCS_CS_FIELD_FLAG_INIT | FCS_CS_FIELD_FLAG_FINALIZE) <<
131 FCS_CS_FIELD_FLAG_OFFSET;
132
133 fcs_rng_payload payload = {
134 session_id,
135 context_id,
136 crypto_header,
137 size
138 };
139
140 payload_size = sizeof(payload) / MBOX_WORD_BYTE;
141
142 status = mailbox_send_cmd_async(send_id, MBOX_FCS_RANDOM_GEN,
143 (uint32_t *) &payload, payload_size,
144 CMD_INDIRECT);
145
146 if (status < 0) {
147 return INTEL_SIP_SMC_STATUS_ERROR;
148 }
149
150 return INTEL_SIP_SMC_STATUS_OK;
151}
152
Sieu Mun Tang9f22cbf2022-03-02 11:04:09 +0800153uint32_t intel_fcs_send_cert(uint64_t addr, uint64_t size,
154 uint32_t *send_id)
155{
156 int status;
157
158 if (!is_address_in_ddr_range(addr, size)) {
159 return INTEL_SIP_SMC_STATUS_REJECTED;
160 }
161
Sieu Mun Tangdb79fa52022-03-20 00:49:57 +0800162 if (!is_size_4_bytes_aligned(size)) {
163 return INTEL_SIP_SMC_STATUS_REJECTED;
164 }
165
Sieu Mun Tang9f22cbf2022-03-02 11:04:09 +0800166 status = mailbox_send_cmd_async(send_id, MBOX_CMD_VAB_SRC_CERT,
167 (uint32_t *)addr, size / MBOX_WORD_BYTE,
168 CMD_DIRECT);
169
Boon Khai Ngcac786d2021-05-26 01:50:34 +0800170 flush_dcache_range(addr, size);
171
Sieu Mun Tang9f22cbf2022-03-02 11:04:09 +0800172 if (status < 0) {
173 return INTEL_SIP_SMC_STATUS_ERROR;
174 }
175
176 return INTEL_SIP_SMC_STATUS_OK;
177}
178
179uint32_t intel_fcs_get_provision_data(uint32_t *send_id)
180{
181 int status;
182
183 status = mailbox_send_cmd_async(send_id, MBOX_FCS_GET_PROVISION,
184 NULL, 0U, CMD_DIRECT);
185
186 if (status < 0) {
187 return INTEL_SIP_SMC_STATUS_ERROR;
188 }
189
190 return INTEL_SIP_SMC_STATUS_OK;
191}
192
Sieu Mun Tanga068fdf2022-05-11 10:01:54 +0800193uint32_t intel_fcs_cntr_set_preauth(uint8_t counter_type, int32_t counter_value,
194 uint32_t test_bit, uint32_t *mbox_error)
195{
196 int status;
197 uint32_t first_word;
198 uint32_t payload_size;
199
200 if ((test_bit != MBOX_TEST_BIT) &&
201 (test_bit != 0)) {
202 return INTEL_SIP_SMC_STATUS_REJECTED;
203 }
204
205 if ((counter_type < FCS_BIG_CNTR_SEL) ||
206 (counter_type > FCS_SVN_CNTR_3_SEL)) {
207 return INTEL_SIP_SMC_STATUS_REJECTED;
208 }
209
210 if ((counter_type == FCS_BIG_CNTR_SEL) &&
211 (counter_value > FCS_BIG_CNTR_VAL_MAX)) {
212 return INTEL_SIP_SMC_STATUS_REJECTED;
213 }
214
215 if ((counter_type >= FCS_SVN_CNTR_0_SEL) &&
216 (counter_type <= FCS_SVN_CNTR_3_SEL) &&
217 (counter_value > FCS_SVN_CNTR_VAL_MAX)) {
218 return INTEL_SIP_SMC_STATUS_REJECTED;
219 }
220
221 first_word = test_bit | counter_type;
222 fcs_cntr_set_preauth_payload payload = {
223 first_word,
224 counter_value
225 };
226
227 payload_size = sizeof(payload) / MBOX_WORD_BYTE;
228 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_CNTR_SET_PREAUTH,
229 (uint32_t *) &payload, payload_size,
230 CMD_CASUAL, NULL, NULL);
231
232 if (status < 0) {
233 *mbox_error = -status;
234 return INTEL_SIP_SMC_STATUS_ERROR;
235 }
236
237 return INTEL_SIP_SMC_STATUS_OK;
238}
239
Sieu Mun Tang128d2a72022-05-11 09:49:25 +0800240uint32_t intel_fcs_encryption(uint32_t src_addr, uint32_t src_size,
241 uint32_t dst_addr, uint32_t dst_size, uint32_t *send_id)
Sieu Mun Tang9f22cbf2022-03-02 11:04:09 +0800242{
243 int status;
Sieu Mun Tang128d2a72022-05-11 09:49:25 +0800244 uint32_t load_size;
Sieu Mun Tang9f22cbf2022-03-02 11:04:09 +0800245
Sieu Mun Tang128d2a72022-05-11 09:49:25 +0800246 fcs_encrypt_payload payload = {
247 FCS_ENCRYPTION_DATA_0,
Sieu Mun Tang9f22cbf2022-03-02 11:04:09 +0800248 src_addr,
249 src_size,
250 dst_addr,
251 dst_size };
Sieu Mun Tang128d2a72022-05-11 09:49:25 +0800252 load_size = sizeof(payload) / MBOX_WORD_BYTE;
Sieu Mun Tang9f22cbf2022-03-02 11:04:09 +0800253
Sieu Mun Tangdb79fa52022-03-20 00:49:57 +0800254 if (!is_address_in_ddr_range(src_addr, src_size) ||
255 !is_address_in_ddr_range(dst_addr, dst_size)) {
256 return INTEL_SIP_SMC_STATUS_REJECTED;
257 }
258
Sieu Mun Tang128d2a72022-05-11 09:49:25 +0800259 if (!is_size_4_bytes_aligned(src_size)) {
Sieu Mun Tangdb79fa52022-03-20 00:49:57 +0800260 return INTEL_SIP_SMC_STATUS_REJECTED;
261 }
262
Sieu Mun Tang128d2a72022-05-11 09:49:25 +0800263 status = mailbox_send_cmd_async(send_id, MBOX_FCS_ENCRYPT_REQ,
264 (uint32_t *) &payload, load_size,
265 CMD_INDIRECT);
266 inv_dcache_range(dst_addr, dst_size);
267
268 if (status < 0) {
269 return INTEL_SIP_SMC_STATUS_REJECTED;
270 }
271
272 return INTEL_SIP_SMC_STATUS_OK;
273}
274
275uint32_t intel_fcs_decryption(uint32_t src_addr, uint32_t src_size,
276 uint32_t dst_addr, uint32_t dst_size, uint32_t *send_id)
277{
278 int status;
279 uint32_t load_size;
280 uintptr_t id_offset;
281
282 id_offset = src_addr + FCS_OWNER_ID_OFFSET;
283 fcs_decrypt_payload payload = {
284 FCS_DECRYPTION_DATA_0,
285 {mmio_read_32(id_offset),
286 mmio_read_32(id_offset + MBOX_WORD_BYTE)},
287 src_addr,
288 src_size,
289 dst_addr,
290 dst_size };
291 load_size = sizeof(payload) / MBOX_WORD_BYTE;
292
293 if (!is_address_in_ddr_range(src_addr, src_size) ||
294 !is_address_in_ddr_range(dst_addr, dst_size)) {
295 return INTEL_SIP_SMC_STATUS_REJECTED;
296 }
297
298 if (!is_size_4_bytes_aligned(src_size)) {
299 return INTEL_SIP_SMC_STATUS_REJECTED;
Sieu Mun Tang9f22cbf2022-03-02 11:04:09 +0800300 }
301
Sieu Mun Tang128d2a72022-05-11 09:49:25 +0800302 status = mailbox_send_cmd_async(send_id, MBOX_FCS_DECRYPT_REQ,
303 (uint32_t *) &payload, load_size,
Sieu Mun Tang9f22cbf2022-03-02 11:04:09 +0800304 CMD_INDIRECT);
305 inv_dcache_range(dst_addr, dst_size);
306
307 if (status < 0) {
308 return INTEL_SIP_SMC_STATUS_REJECTED;
309 }
310
311 return INTEL_SIP_SMC_STATUS_OK;
312}
Sieu Mun Tanga34b8812022-03-17 03:11:55 +0800313
314uint32_t intel_fcs_get_rom_patch_sha384(uint64_t addr, uint64_t *ret_size,
315 uint32_t *mbox_error)
316{
317 int status;
318 unsigned int resp_len = FCS_SHA384_WORD_SIZE;
319
320 if (!is_address_in_ddr_range(addr, FCS_SHA384_BYTE_SIZE)) {
321 return INTEL_SIP_SMC_STATUS_REJECTED;
322 }
323
324 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_GET_ROM_PATCH_SHA384, NULL, 0U,
325 CMD_CASUAL, (uint32_t *) addr, &resp_len);
326
327 if (status < 0) {
328 *mbox_error = -status;
329 return INTEL_SIP_SMC_STATUS_ERROR;
330 }
331
332 if (resp_len != FCS_SHA384_WORD_SIZE) {
333 *mbox_error = GENERIC_RESPONSE_ERROR;
334 return INTEL_SIP_SMC_STATUS_ERROR;
335 }
336
337 *ret_size = FCS_SHA384_BYTE_SIZE;
338
339 flush_dcache_range(addr, *ret_size);
340
341 return INTEL_SIP_SMC_STATUS_OK;
342}
Sieu Mun Tang2a820b92022-05-11 09:59:55 +0800343
Sieu Mun Tang22322fb2022-05-09 16:05:58 +0800344int intel_fcs_encryption_ext(uint32_t session_id, uint32_t context_id,
345 uint32_t src_addr, uint32_t src_size,
346 uint32_t dst_addr, uint32_t *dst_size, uint32_t *mbox_error)
347{
348 int status;
349 uint32_t payload_size;
350 uint32_t resp_len = FCS_CRYPTION_RESP_WORD_SIZE;
351 uint32_t resp_data[FCS_CRYPTION_RESP_WORD_SIZE] = {0U};
352
353 if ((dst_size == NULL) || (mbox_error == NULL)) {
354 return INTEL_SIP_SMC_STATUS_REJECTED;
355 }
356
357 if (!is_address_in_ddr_range(src_addr, src_size) ||
358 !is_address_in_ddr_range(dst_addr, *dst_size)) {
359 return INTEL_SIP_SMC_STATUS_REJECTED;
360 }
361
362 if (!is_size_4_bytes_aligned(src_size)) {
363 return INTEL_SIP_SMC_STATUS_REJECTED;
364 }
365
366 fcs_encrypt_ext_payload payload = {
367 session_id,
368 context_id,
369 FCS_CRYPTION_CRYPTO_HEADER,
370 src_addr,
371 src_size,
372 dst_addr,
373 *dst_size
374 };
375
376 payload_size = sizeof(payload) / MBOX_WORD_BYTE;
377
378 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_ENCRYPT_REQ,
379 (uint32_t *) &payload, payload_size,
380 CMD_CASUAL, resp_data, &resp_len);
381
382 if (status < 0) {
383 *mbox_error = -status;
384 return INTEL_SIP_SMC_STATUS_ERROR;
385 }
386
387 if (resp_len != FCS_CRYPTION_RESP_WORD_SIZE) {
388 *mbox_error = MBOX_RET_ERROR;
389 return INTEL_SIP_SMC_STATUS_ERROR;
390 }
391
392 *dst_size = resp_data[FCS_CRYPTION_RESP_SIZE_OFFSET];
393 inv_dcache_range(dst_addr, *dst_size);
394
395 return INTEL_SIP_SMC_STATUS_OK;
396}
397
398int intel_fcs_decryption_ext(uint32_t session_id, uint32_t context_id,
399 uint32_t src_addr, uint32_t src_size,
400 uint32_t dst_addr, uint32_t *dst_size, uint32_t *mbox_error)
401{
402 int status;
403 uintptr_t id_offset;
404 uint32_t payload_size;
405 uint32_t resp_len = FCS_CRYPTION_RESP_WORD_SIZE;
406 uint32_t resp_data[FCS_CRYPTION_RESP_WORD_SIZE] = {0U};
407
408 if ((dst_size == NULL) || (mbox_error == NULL)) {
409 return INTEL_SIP_SMC_STATUS_REJECTED;
410 }
411
412 if (!is_address_in_ddr_range(src_addr, src_size) ||
413 !is_address_in_ddr_range(dst_addr, *dst_size)) {
414 return INTEL_SIP_SMC_STATUS_REJECTED;
415 }
416
417 if (!is_size_4_bytes_aligned(src_size)) {
418 return INTEL_SIP_SMC_STATUS_REJECTED;
419 }
420
421 id_offset = src_addr + FCS_OWNER_ID_OFFSET;
422 fcs_decrypt_ext_payload payload = {
423 session_id,
424 context_id,
425 FCS_CRYPTION_CRYPTO_HEADER,
426 {mmio_read_32(id_offset),
427 mmio_read_32(id_offset + MBOX_WORD_BYTE)},
428 src_addr,
429 src_size,
430 dst_addr,
431 *dst_size
432 };
433
434 payload_size = sizeof(payload) / MBOX_WORD_BYTE;
435
436 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_DECRYPT_REQ,
437 (uint32_t *) &payload, payload_size,
438 CMD_CASUAL, resp_data, &resp_len);
439
440 if (status < 0) {
441 *mbox_error = -status;
442 return INTEL_SIP_SMC_STATUS_ERROR;
443 }
444
445 if (resp_len != FCS_CRYPTION_RESP_WORD_SIZE) {
446 *mbox_error = MBOX_RET_ERROR;
447 return INTEL_SIP_SMC_STATUS_ERROR;
448 }
449
450 *dst_size = resp_data[FCS_CRYPTION_RESP_SIZE_OFFSET];
451 inv_dcache_range(dst_addr, *dst_size);
452
453 return INTEL_SIP_SMC_STATUS_OK;
454}
455
Sieu Mun Tang2a820b92022-05-11 09:59:55 +0800456int intel_fcs_sigma_teardown(uint32_t session_id, uint32_t *mbox_error)
457{
458 int status;
459
460 if ((session_id != PSGSIGMA_SESSION_ID_ONE) &&
461 (session_id != PSGSIGMA_UNKNOWN_SESSION)) {
462 return INTEL_SIP_SMC_STATUS_REJECTED;
463 }
464
465 psgsigma_teardown_msg message = {
466 RESERVED_AS_ZERO,
467 PSGSIGMA_TEARDOWN_MAGIC,
468 session_id
469 };
470
471 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_PSG_SIGMA_TEARDOWN,
472 (uint32_t *) &message, sizeof(message) / MBOX_WORD_BYTE,
473 CMD_CASUAL, NULL, NULL);
474
475 if (status < 0) {
476 *mbox_error = -status;
477 return INTEL_SIP_SMC_STATUS_ERROR;
478 }
479
480 return INTEL_SIP_SMC_STATUS_OK;
481}
482
483int intel_fcs_chip_id(uint32_t *id_low, uint32_t *id_high, uint32_t *mbox_error)
484{
485 int status;
486 uint32_t load_size;
487 uint32_t chip_id[2];
488
489 load_size = sizeof(chip_id) / MBOX_WORD_BYTE;
490
491 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_CMD_GET_CHIPID, NULL,
492 0U, CMD_CASUAL, (uint32_t *) chip_id, &load_size);
493
494 if (status < 0) {
495 *mbox_error = -status;
496 return INTEL_SIP_SMC_STATUS_ERROR;
497 }
498
499 *id_low = chip_id[0];
500 *id_high = chip_id[1];
501
502 return INTEL_SIP_SMC_STATUS_OK;
503}
504
505int intel_fcs_attestation_subkey(uint64_t src_addr, uint32_t src_size,
506 uint64_t dst_addr, uint32_t *dst_size, uint32_t *mbox_error)
507{
508 int status;
509 uint32_t send_size = src_size / MBOX_WORD_BYTE;
510 uint32_t ret_size = *dst_size / MBOX_WORD_BYTE;
511
512
513 if (!is_address_in_ddr_range(src_addr, src_size) ||
514 !is_address_in_ddr_range(dst_addr, *dst_size)) {
515 return INTEL_SIP_SMC_STATUS_REJECTED;
516 }
517
518 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_ATTESTATION_SUBKEY,
519 (uint32_t *) src_addr, send_size, CMD_CASUAL,
520 (uint32_t *) dst_addr, &ret_size);
521
522 if (status < 0) {
523 *mbox_error = -status;
524 return INTEL_SIP_SMC_STATUS_ERROR;
525 }
526
527 *dst_size = ret_size * MBOX_WORD_BYTE;
528 flush_dcache_range(dst_addr, *dst_size);
529
530 return INTEL_SIP_SMC_STATUS_OK;
531}
532
533int intel_fcs_get_measurement(uint64_t src_addr, uint32_t src_size,
534 uint64_t dst_addr, uint32_t *dst_size, uint32_t *mbox_error)
535{
536 int status;
537 uint32_t send_size = src_size / MBOX_WORD_BYTE;
538 uint32_t ret_size = *dst_size / MBOX_WORD_BYTE;
539
540 if (!is_address_in_ddr_range(src_addr, src_size) ||
541 !is_address_in_ddr_range(dst_addr, *dst_size)) {
542 return INTEL_SIP_SMC_STATUS_REJECTED;
543 }
544
545 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_GET_MEASUREMENT,
546 (uint32_t *) src_addr, send_size, CMD_CASUAL,
547 (uint32_t *) dst_addr, &ret_size);
548
549 if (status < 0) {
550 *mbox_error = -status;
551 return INTEL_SIP_SMC_STATUS_ERROR;
552 }
553
554 *dst_size = ret_size * MBOX_WORD_BYTE;
555 flush_dcache_range(dst_addr, *dst_size);
556
557 return INTEL_SIP_SMC_STATUS_OK;
558}
Sieu Mun Tang28af1652022-05-09 10:48:53 +0800559
560int intel_fcs_get_attestation_cert(uint32_t cert_request, uint64_t dst_addr,
561 uint32_t *dst_size, uint32_t *mbox_error)
562{
563 int status;
564 uint32_t ret_size = *dst_size / MBOX_WORD_BYTE;
565
566 if (mbox_error == NULL) {
567 return INTEL_SIP_SMC_STATUS_REJECTED;
568 }
569
570 if (cert_request < FCS_ALIAS_CERT ||
571 cert_request >
572 (FCS_ALIAS_CERT |
573 FCS_DEV_ID_SELF_SIGN_CERT |
574 FCS_DEV_ID_ENROLL_CERT |
575 FCS_ENROLL_SELF_SIGN_CERT |
576 FCS_PLAT_KEY_CERT)) {
577 return INTEL_SIP_SMC_STATUS_REJECTED;
578 }
579
580 if (!is_address_in_ddr_range(dst_addr, *dst_size)) {
581 return INTEL_SIP_SMC_STATUS_REJECTED;
582 }
583
584 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_GET_ATTESTATION_CERT,
585 (uint32_t *) &cert_request, 1U, CMD_CASUAL,
586 (uint32_t *) dst_addr, &ret_size);
587
588 if (status < 0) {
589 *mbox_error = -status;
590 return INTEL_SIP_SMC_STATUS_ERROR;
591 }
592
593 *dst_size = ret_size * MBOX_WORD_BYTE;
594 flush_dcache_range(dst_addr, *dst_size);
595
596 return INTEL_SIP_SMC_STATUS_OK;
597}
598
599int intel_fcs_create_cert_on_reload(uint32_t cert_request,
600 uint32_t *mbox_error)
601{
602 int status;
603
604 if (mbox_error == NULL) {
605 return INTEL_SIP_SMC_STATUS_REJECTED;
606 }
607
608 if (cert_request < FCS_ALIAS_CERT ||
609 cert_request >
610 (FCS_ALIAS_CERT |
611 FCS_DEV_ID_SELF_SIGN_CERT |
612 FCS_DEV_ID_ENROLL_CERT |
613 FCS_ENROLL_SELF_SIGN_CERT |
614 FCS_PLAT_KEY_CERT)) {
615 return INTEL_SIP_SMC_STATUS_REJECTED;
616 }
617
618 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_CREATE_CERT_ON_RELOAD,
619 (uint32_t *) &cert_request, 1U, CMD_CASUAL,
620 NULL, NULL);
621
622 if (status < 0) {
623 *mbox_error = -status;
624 return INTEL_SIP_SMC_STATUS_ERROR;
625 }
626
627 return INTEL_SIP_SMC_STATUS_OK;
628}
Sieu Mun Tang16754e12022-05-09 12:08:42 +0800629
630int intel_fcs_open_crypto_service_session(uint32_t *session_id,
631 uint32_t *mbox_error)
632{
633 int status;
634 uint32_t resp_len = 1U;
635
636 if ((session_id == NULL) || (mbox_error == NULL)) {
637 return INTEL_SIP_SMC_STATUS_REJECTED;
638 }
639
640 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_OPEN_CS_SESSION,
641 NULL, 0U, CMD_CASUAL, session_id, &resp_len);
642
643 if (status < 0) {
644 *mbox_error = -status;
645 return INTEL_SIP_SMC_STATUS_ERROR;
646 }
647
648 return INTEL_SIP_SMC_STATUS_OK;
649}
650
651int intel_fcs_close_crypto_service_session(uint32_t session_id,
652 uint32_t *mbox_error)
653{
654 int status;
655
656 if (mbox_error == NULL) {
657 return INTEL_SIP_SMC_STATUS_REJECTED;
658 }
659
660 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_CLOSE_CS_SESSION,
661 &session_id, 1U, CMD_CASUAL, NULL, NULL);
662
663 if (status < 0) {
664 *mbox_error = -status;
665 return INTEL_SIP_SMC_STATUS_ERROR;
666 }
667
668 return INTEL_SIP_SMC_STATUS_OK;
669}
Sieu Mun Tangfb1f6e92022-05-09 14:16:14 +0800670
671int intel_fcs_import_crypto_service_key(uint64_t src_addr, uint32_t src_size,
672 uint32_t *send_id)
673{
674 int status;
675
676 if (src_size > (FCS_CS_KEY_OBJ_MAX_WORD_SIZE *
677 MBOX_WORD_BYTE)) {
678 return INTEL_SIP_SMC_STATUS_REJECTED;
679 }
680
681 if (!is_address_in_ddr_range(src_addr, src_size)) {
682 return INTEL_SIP_SMC_STATUS_REJECTED;
683 }
684
685 status = mailbox_send_cmd_async(send_id, MBOX_FCS_IMPORT_CS_KEY,
686 (uint32_t *)src_addr, src_size / MBOX_WORD_BYTE,
687 CMD_INDIRECT);
688
689 if (status < 0) {
690 return INTEL_SIP_SMC_STATUS_ERROR;
691 }
692
693 return INTEL_SIP_SMC_STATUS_OK;
694}
695
696int intel_fcs_export_crypto_service_key(uint32_t session_id, uint32_t key_id,
697 uint64_t dst_addr, uint32_t *dst_size,
698 uint32_t *mbox_error)
699{
700 int status;
701 uint32_t i;
702 uint32_t payload_size;
703 uint32_t resp_len = FCS_CS_KEY_OBJ_MAX_WORD_SIZE;
704 uint32_t resp_data[FCS_CS_KEY_OBJ_MAX_WORD_SIZE] = {0U};
705 uint32_t op_status = 0U;
706
707 if ((dst_size == NULL) || (mbox_error == NULL)) {
708 return INTEL_SIP_SMC_STATUS_REJECTED;
709 }
710
711 if (!is_address_in_ddr_range(dst_addr, *dst_size)) {
712 return INTEL_SIP_SMC_STATUS_REJECTED;
713 }
714
715 fcs_cs_key_payload payload = {
716 session_id,
717 RESERVED_AS_ZERO,
718 RESERVED_AS_ZERO,
719 key_id
720 };
721
722 payload_size = sizeof(payload) / MBOX_WORD_BYTE;
723
724 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_EXPORT_CS_KEY,
725 (uint32_t *) &payload, payload_size,
726 CMD_CASUAL, resp_data, &resp_len);
727
728 if (resp_len > 0) {
729 op_status = resp_data[0] & FCS_CS_KEY_RESP_STATUS_MASK;
730 }
731
732 if (status < 0) {
733 *mbox_error = (-status) | (op_status << FCS_CS_KEY_RESP_STATUS_OFFSET);
734 return INTEL_SIP_SMC_STATUS_ERROR;
735 }
736
737 if (resp_len > 1) {
738
739 /* Export key object is start at second response data */
740 *dst_size = (resp_len - 1) * MBOX_WORD_BYTE;
741
742 for (i = 1U; i < resp_len; i++) {
743 mmio_write_32(dst_addr, resp_data[i]);
744 dst_addr += MBOX_WORD_BYTE;
745 }
746
747 flush_dcache_range(dst_addr - *dst_size, *dst_size);
748
749 } else {
750
751 /* Unexpected response, missing key object in response */
752 *mbox_error = MBOX_RET_ERROR;
753 return INTEL_SIP_SMC_STATUS_ERROR;
754 }
755
756 return INTEL_SIP_SMC_STATUS_OK;
757}
758
759int intel_fcs_remove_crypto_service_key(uint32_t session_id, uint32_t key_id,
760 uint32_t *mbox_error)
761{
762 int status;
763 uint32_t payload_size;
764 uint32_t resp_len = 1U;
765 uint32_t resp_data = 0U;
766 uint32_t op_status = 0U;
767
768 if (mbox_error == NULL) {
769 return INTEL_SIP_SMC_STATUS_REJECTED;
770 }
771
772 fcs_cs_key_payload payload = {
773 session_id,
774 RESERVED_AS_ZERO,
775 RESERVED_AS_ZERO,
776 key_id
777 };
778
779 payload_size = sizeof(payload) / MBOX_WORD_BYTE;
780
781 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_REMOVE_CS_KEY,
782 (uint32_t *) &payload, payload_size,
783 CMD_CASUAL, &resp_data, &resp_len);
784
785 if (resp_len > 0) {
786 op_status = resp_data & FCS_CS_KEY_RESP_STATUS_MASK;
787 }
788
789 if (status < 0) {
790 *mbox_error = (-status) | (op_status << FCS_CS_KEY_RESP_STATUS_OFFSET);
791 return INTEL_SIP_SMC_STATUS_ERROR;
792 }
793
794 return INTEL_SIP_SMC_STATUS_OK;
795}
796
797int intel_fcs_get_crypto_service_key_info(uint32_t session_id, uint32_t key_id,
798 uint64_t dst_addr, uint32_t *dst_size,
799 uint32_t *mbox_error)
800{
801 int status;
802 uint32_t payload_size;
803 uint32_t resp_len = FCS_CS_KEY_INFO_MAX_WORD_SIZE;
804 uint32_t op_status = 0U;
805
806 if ((dst_size == NULL) || (mbox_error == NULL)) {
807 return INTEL_SIP_SMC_STATUS_REJECTED;
808 }
809
810 if (!is_address_in_ddr_range(dst_addr, *dst_size)) {
811 return INTEL_SIP_SMC_STATUS_REJECTED;
812 }
813
814 fcs_cs_key_payload payload = {
815 session_id,
816 RESERVED_AS_ZERO,
817 RESERVED_AS_ZERO,
818 key_id
819 };
820
821 payload_size = sizeof(payload) / MBOX_WORD_BYTE;
822
823 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_GET_CS_KEY_INFO,
824 (uint32_t *) &payload, payload_size,
825 CMD_CASUAL, (uint32_t *) dst_addr, &resp_len);
826
827 if (resp_len > 0) {
828 op_status = mmio_read_32(dst_addr) &
829 FCS_CS_KEY_RESP_STATUS_MASK;
830 }
831
832 if (status < 0) {
833 *mbox_error = (-status) | (op_status << FCS_CS_KEY_RESP_STATUS_OFFSET);
834 return INTEL_SIP_SMC_STATUS_ERROR;
835 }
836
837 *dst_size = resp_len * MBOX_WORD_BYTE;
838 flush_dcache_range(dst_addr, *dst_size);
839
840 return INTEL_SIP_SMC_STATUS_OK;
841}
Sieu Mun Tangd907cc32022-05-10 17:24:05 +0800842
843int intel_fcs_get_digest_init(uint32_t session_id, uint32_t context_id,
844 uint32_t key_id, uint32_t param_size,
845 uint64_t param_data, uint32_t *mbox_error)
846{
847 return intel_fcs_crypto_service_init(session_id, context_id,
848 key_id, param_size, param_data,
849 (void *) &fcs_sha_get_digest_param,
850 mbox_error);
851}
852
853int intel_fcs_get_digest_finalize(uint32_t session_id, uint32_t context_id,
854 uint32_t src_addr, uint32_t src_size,
855 uint64_t dst_addr, uint32_t *dst_size,
856 uint32_t *mbox_error)
857{
858 int status;
859 uint32_t i;
860 uint32_t resp_len = *dst_size / MBOX_WORD_BYTE;
861 uint32_t payload[FCS_GET_DIGEST_CMD_MAX_WORD_SIZE] = {0U};
862
863 if (dst_size == NULL || mbox_error == NULL) {
864 return INTEL_SIP_SMC_STATUS_REJECTED;
865 }
866
867 if (fcs_sha_get_digest_param.session_id != session_id ||
868 fcs_sha_get_digest_param.context_id != context_id) {
869 return INTEL_SIP_SMC_STATUS_REJECTED;
870 }
871
872 /* Source data must be 8 bytes aligned */
873 if (!is_8_bytes_aligned(src_size)) {
874 return INTEL_SIP_SMC_STATUS_REJECTED;
875 }
876
877 if (!is_address_in_ddr_range(src_addr, src_size) ||
878 !is_address_in_ddr_range(dst_addr, *dst_size)) {
879 return INTEL_SIP_SMC_STATUS_REJECTED;
880 }
881
882 /* Prepare command payload */
883 i = 0;
884 /* Crypto header */
885 payload[i] = fcs_sha_get_digest_param.session_id;
886 i++;
887 payload[i] = fcs_sha_get_digest_param.context_id;
888 i++;
889 payload[i] = fcs_sha_get_digest_param.crypto_param_size
890 & FCS_CS_FIELD_SIZE_MASK;
891 payload[i] |= (FCS_CS_FIELD_FLAG_INIT | FCS_CS_FIELD_FLAG_UPDATE
892 | FCS_CS_FIELD_FLAG_FINALIZE)
893 << FCS_CS_FIELD_FLAG_OFFSET;
894 i++;
895 payload[i] = fcs_sha_get_digest_param.key_id;
896 i++;
897 /* Crypto parameters */
898 payload[i] = fcs_sha_get_digest_param.crypto_param
899 & INTEL_SIP_SMC_FCS_SHA_MODE_MASK;
900 payload[i] |= ((fcs_sha_get_digest_param.crypto_param
901 >> INTEL_SIP_SMC_FCS_DIGEST_SIZE_OFFSET)
902 & INTEL_SIP_SMC_FCS_DIGEST_SIZE_MASK)
903 << FCS_SHA_HMAC_CRYPTO_PARAM_SIZE_OFFSET;
904 i++;
905 /* Data source address and size */
906 payload[i] = src_addr;
907 i++;
908 payload[i] = src_size;
909 i++;
910
911 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_GET_DIGEST_REQ,
912 payload, i, CMD_CASUAL,
913 (uint32_t *) dst_addr, &resp_len);
914
915 memset((void *)&fcs_sha_get_digest_param, 0, sizeof(fcs_crypto_service_data));
916
917 if (status < 0) {
918 *mbox_error = -status;
919 return INTEL_SIP_SMC_STATUS_ERROR;
920 }
921
922 *dst_size = resp_len * MBOX_WORD_BYTE;
923 flush_dcache_range(dst_addr, *dst_size);
924
925 return INTEL_SIP_SMC_STATUS_OK;
926}
Sieu Mun Tang583149a2022-05-10 17:27:12 +0800927
928int intel_fcs_mac_verify_init(uint32_t session_id, uint32_t context_id,
929 uint32_t key_id, uint32_t param_size,
930 uint64_t param_data, uint32_t *mbox_error)
931{
932 return intel_fcs_crypto_service_init(session_id, context_id,
933 key_id, param_size, param_data,
934 (void *) &fcs_sha_mac_verify_param,
935 mbox_error);
936}
937
938int intel_fcs_mac_verify_finalize(uint32_t session_id, uint32_t context_id,
939 uint32_t src_addr, uint32_t src_size,
940 uint64_t dst_addr, uint32_t *dst_size,
941 uint32_t data_size, uint32_t *mbox_error)
942{
943 int status;
944 uint32_t i;
945 uint32_t resp_len = *dst_size / MBOX_WORD_BYTE;
946 uint32_t payload[FCS_MAC_VERIFY_CMD_MAX_WORD_SIZE] = {0U};
947 uintptr_t mac_offset;
948
949 if (dst_size == NULL || mbox_error == NULL) {
950 return INTEL_SIP_SMC_STATUS_REJECTED;
951 }
952
953 if (fcs_sha_mac_verify_param.session_id != session_id ||
954 fcs_sha_mac_verify_param.context_id != context_id) {
955 return INTEL_SIP_SMC_STATUS_REJECTED;
956 }
957
958 if (data_size >= src_size) {
959 return INTEL_SIP_SMC_STATUS_REJECTED;
960 }
961
962 if (!is_size_4_bytes_aligned(src_size) ||
963 !is_8_bytes_aligned(data_size)) {
964 return INTEL_SIP_SMC_STATUS_REJECTED;
965 }
966
967 if (!is_address_in_ddr_range(src_addr, src_size) ||
968 !is_address_in_ddr_range(dst_addr, *dst_size)) {
969 return INTEL_SIP_SMC_STATUS_REJECTED;
970 }
971
972 /* Prepare command payload */
973 i = 0;
974 /* Crypto header */
975 payload[i] = fcs_sha_mac_verify_param.session_id;
976 i++;
977 payload[i] = fcs_sha_mac_verify_param.context_id;
978 i++;
979 payload[i] = fcs_sha_mac_verify_param.crypto_param_size
980 & FCS_CS_FIELD_SIZE_MASK;
981 payload[i] |= (FCS_CS_FIELD_FLAG_INIT | FCS_CS_FIELD_FLAG_UPDATE
982 | FCS_CS_FIELD_FLAG_FINALIZE)
983 << FCS_CS_FIELD_FLAG_OFFSET;
984 i++;
985 payload[i] = fcs_sha_mac_verify_param.key_id;
986 i++;
987 /* Crypto parameters */
988 payload[i] = ((fcs_sha_mac_verify_param.crypto_param
989 >> INTEL_SIP_SMC_FCS_DIGEST_SIZE_OFFSET)
990 & INTEL_SIP_SMC_FCS_DIGEST_SIZE_MASK)
991 << FCS_SHA_HMAC_CRYPTO_PARAM_SIZE_OFFSET;
992 i++;
993 /* Data source address and size */
994 payload[i] = src_addr;
995 i++;
996 payload[i] = data_size;
997 i++;
998 /* Copy mac data to command */
999 mac_offset = src_addr + data_size;
1000 memcpy((uint8_t *) &payload[i], (uint8_t *) mac_offset,
1001 src_size - data_size);
1002
1003 i += (src_size - data_size) / MBOX_WORD_BYTE;
1004
1005 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_MAC_VERIFY_REQ,
1006 payload, i, CMD_CASUAL,
1007 (uint32_t *) dst_addr, &resp_len);
1008
1009 memset((void *)&fcs_sha_mac_verify_param, 0,
1010 sizeof(fcs_crypto_service_data));
1011
1012 if (status < 0) {
1013 *mbox_error = -status;
1014 return INTEL_SIP_SMC_STATUS_ERROR;
1015 }
1016
1017 *dst_size = resp_len * MBOX_WORD_BYTE;
1018 flush_dcache_range(dst_addr, *dst_size);
1019
1020 return INTEL_SIP_SMC_STATUS_OK;
1021}
Sieu Mun Tangb0c1d112022-05-10 17:30:00 +08001022
Sieu Mun Tang153ecfb2022-05-10 17:39:26 +08001023int intel_fcs_ecdsa_sha2_data_sign_init(uint32_t session_id,
1024 uint32_t context_id, uint32_t key_id,
1025 uint32_t param_size, uint64_t param_data,
1026 uint32_t *mbox_error)
1027{
1028 return intel_fcs_crypto_service_init(session_id, context_id,
1029 key_id, param_size, param_data,
1030 (void *) &fcs_sha2_data_sign_param,
1031 mbox_error);
1032}
1033
1034int intel_fcs_ecdsa_sha2_data_sign_finalize(uint32_t session_id,
1035 uint32_t context_id, uint32_t src_addr,
1036 uint32_t src_size, uint64_t dst_addr,
1037 uint32_t *dst_size, uint32_t *mbox_error)
1038{
1039 int status;
1040 int i;
1041 uint32_t payload[FCS_ECDSA_SHA2_DATA_SIGN_CMD_MAX_WORD_SIZE] = {0U};
1042 uint32_t resp_len = *dst_size / MBOX_WORD_BYTE;
1043
1044 if ((dst_size == NULL) || (mbox_error == NULL)) {
1045 return INTEL_SIP_SMC_STATUS_REJECTED;
1046 }
1047
1048 if (fcs_sha2_data_sign_param.session_id != session_id ||
1049 fcs_sha2_data_sign_param.context_id != context_id) {
1050 return INTEL_SIP_SMC_STATUS_REJECTED;
1051 }
1052
1053 /* Source data must be 8 bytes aligned */
1054 if (!is_8_bytes_aligned(src_size)) {
1055 return INTEL_SIP_SMC_STATUS_REJECTED;
1056 }
1057
1058 if (!is_address_in_ddr_range(src_addr, src_size) ||
1059 !is_address_in_ddr_range(dst_addr, *dst_size)) {
1060 return INTEL_SIP_SMC_STATUS_REJECTED;
1061 }
1062
1063 /* Prepare command payload */
1064 /* Crypto header */
1065 i = 0;
1066 payload[i] = fcs_sha2_data_sign_param.session_id;
1067 i++;
1068 payload[i] = fcs_sha2_data_sign_param.context_id;
1069 i++;
1070 payload[i] = fcs_sha2_data_sign_param.crypto_param_size
1071 & FCS_CS_FIELD_SIZE_MASK;
1072 payload[i] |= (FCS_CS_FIELD_FLAG_INIT | FCS_CS_FIELD_FLAG_UPDATE
1073 | FCS_CS_FIELD_FLAG_FINALIZE)
1074 << FCS_CS_FIELD_FLAG_OFFSET;
1075 i++;
1076 payload[i] = fcs_sha2_data_sign_param.key_id;
1077 /* Crypto parameters */
1078 i++;
1079 payload[i] = fcs_sha2_data_sign_param.crypto_param
1080 & INTEL_SIP_SMC_FCS_ECC_ALGO_MASK;
1081 /* Data source address and size */
1082 i++;
1083 payload[i] = src_addr;
1084 i++;
1085 payload[i] = src_size;
1086 i++;
1087 status = mailbox_send_cmd(MBOX_JOB_ID,
1088 MBOX_FCS_ECDSA_SHA2_DATA_SIGN_REQ, payload,
1089 i, CMD_CASUAL, (uint32_t *) dst_addr,
1090 &resp_len);
1091
1092 memset((void *)&fcs_sha2_data_sign_param, 0,
1093 sizeof(fcs_crypto_service_data));
1094
1095 if (status < 0) {
1096 *mbox_error = -status;
1097 return INTEL_SIP_SMC_STATUS_ERROR;
1098 }
1099
1100 *dst_size = resp_len * MBOX_WORD_BYTE;
1101 flush_dcache_range(dst_addr, *dst_size);
1102
1103 return INTEL_SIP_SMC_STATUS_OK;
1104}
1105
Sieu Mun Tangdcaab772022-05-11 10:16:40 +08001106int intel_fcs_ecdsa_sha2_data_sig_verify_init(uint32_t session_id,
1107 uint32_t context_id, uint32_t key_id,
1108 uint32_t param_size, uint64_t param_data,
1109 uint32_t *mbox_error)
1110{
1111 return intel_fcs_crypto_service_init(session_id, context_id,
1112 key_id, param_size, param_data,
1113 (void *) &fcs_sha2_data_sig_verify_param,
1114 mbox_error);
1115}
1116
1117int intel_fcs_ecdsa_sha2_data_sig_verify_finalize(uint32_t session_id,
1118 uint32_t context_id, uint32_t src_addr,
1119 uint32_t src_size, uint64_t dst_addr,
1120 uint32_t *dst_size, uint32_t data_size,
1121 uint32_t *mbox_error)
1122{
1123 int status;
1124 uint32_t i;
1125 uint32_t payload[FCS_ECDSA_SHA2_DATA_SIG_VERIFY_CMD_MAX_WORD_SIZE] = {0U};
1126 uint32_t resp_len = *dst_size / MBOX_WORD_BYTE;
1127 uintptr_t sig_pubkey_offset;
1128
1129 if ((dst_size == NULL) || (mbox_error == NULL)) {
1130 return INTEL_SIP_SMC_STATUS_REJECTED;
1131 }
1132
1133 if (fcs_sha2_data_sig_verify_param.session_id != session_id ||
1134 fcs_sha2_data_sig_verify_param.context_id != context_id) {
1135 return INTEL_SIP_SMC_STATUS_REJECTED;
1136 }
1137
1138 if (!is_size_4_bytes_aligned(src_size)) {
1139 return INTEL_SIP_SMC_STATUS_REJECTED;
1140 }
1141
1142 if (!is_8_bytes_aligned(data_size) ||
1143 !is_8_bytes_aligned(src_addr)) {
1144 return INTEL_SIP_SMC_STATUS_REJECTED;
1145 }
1146
1147 if (!is_address_in_ddr_range(src_addr, src_size) ||
1148 !is_address_in_ddr_range(dst_addr, *dst_size)) {
1149 return INTEL_SIP_SMC_STATUS_REJECTED;
1150 }
1151
1152 /* Prepare command payload */
1153 /* Crypto header */
1154 i = 0;
1155 payload[i] = fcs_sha2_data_sig_verify_param.session_id;
1156 i++;
1157 payload[i] = fcs_sha2_data_sig_verify_param.context_id;
1158 i++;
1159
1160 payload[i] = fcs_sha2_data_sig_verify_param.crypto_param_size
1161 & FCS_CS_FIELD_SIZE_MASK;
1162 payload[i] |= (FCS_CS_FIELD_FLAG_INIT | FCS_CS_FIELD_FLAG_UPDATE
1163 | FCS_CS_FIELD_FLAG_FINALIZE)
1164 << FCS_CS_FIELD_FLAG_OFFSET;
1165 i++;
1166 payload[i] = fcs_sha2_data_sig_verify_param.key_id;
1167 i++;
1168 /* Crypto parameters */
1169 payload[i] = fcs_sha2_data_sig_verify_param.crypto_param
1170 & INTEL_SIP_SMC_FCS_ECC_ALGO_MASK;
1171 i++;
1172 /* Data source address and size */
1173 payload[i] = src_addr;
1174 i++;
1175 payload[i] = data_size;
1176 i++;
1177 /* Signature + Public Key Data */
1178 sig_pubkey_offset = src_addr + data_size;
1179 memcpy((uint8_t *) &payload[i], (uint8_t *) sig_pubkey_offset,
1180 src_size - data_size);
1181
1182 i += (src_size - data_size) / MBOX_WORD_BYTE;
1183
1184 status = mailbox_send_cmd(MBOX_JOB_ID,
1185 MBOX_FCS_ECDSA_SHA2_DATA_SIGN_VERIFY, payload, i,
1186 CMD_CASUAL, (uint32_t *) dst_addr, &resp_len);
1187
1188 memset((void *) &fcs_sha2_data_sig_verify_param, 0,
1189 sizeof(fcs_crypto_service_data));
1190
1191 if (status < 0) {
1192 *mbox_error = -status;
1193 return INTEL_SIP_SMC_STATUS_ERROR;
1194 }
1195
1196 *dst_size = resp_len * MBOX_WORD_BYTE;
1197 flush_dcache_range(dst_addr, *dst_size);
1198
1199 return INTEL_SIP_SMC_STATUS_OK;
1200}
1201
Sieu Mun Tange2f3ede2022-05-10 17:36:32 +08001202int intel_fcs_ecdsa_get_pubkey_init(uint32_t session_id, uint32_t context_id,
1203 uint32_t key_id, uint32_t param_size,
1204 uint64_t param_data, uint32_t *mbox_error)
1205{
1206 return intel_fcs_crypto_service_init(session_id, context_id,
1207 key_id, param_size, param_data,
1208 (void *) &fcs_ecdsa_get_pubkey_param,
1209 mbox_error);
1210}
1211
1212int intel_fcs_ecdsa_get_pubkey_finalize(uint32_t session_id, uint32_t context_id,
1213 uint64_t dst_addr, uint32_t *dst_size,
1214 uint32_t *mbox_error)
1215{
1216 int status;
1217 int i;
1218 uint32_t crypto_header;
1219 uint32_t ret_size = *dst_size / MBOX_WORD_BYTE;
1220 uint32_t payload[FCS_ECDSA_GET_PUBKEY_MAX_WORD_SIZE] = {0U};
1221
1222 if ((dst_size == NULL) || (mbox_error == NULL)) {
1223 return INTEL_SIP_SMC_STATUS_REJECTED;
1224 }
1225
1226 if (fcs_ecdsa_get_pubkey_param.session_id != session_id ||
1227 fcs_ecdsa_get_pubkey_param.context_id != context_id) {
1228 return INTEL_SIP_SMC_STATUS_REJECTED;
1229 }
1230
1231 crypto_header = ((FCS_CS_FIELD_FLAG_INIT |
1232 FCS_CS_FIELD_FLAG_UPDATE |
1233 FCS_CS_FIELD_FLAG_FINALIZE) <<
1234 FCS_CS_FIELD_FLAG_OFFSET) |
1235 fcs_ecdsa_get_pubkey_param.crypto_param_size;
1236 i = 0;
1237 /* Prepare command payload */
1238 payload[i] = session_id;
1239 i++;
1240 payload[i] = context_id;
1241 i++;
1242 payload[i] = crypto_header;
1243 i++;
1244 payload[i] = fcs_ecdsa_get_pubkey_param.key_id;
1245 i++;
1246 payload[i] = (uint32_t) fcs_ecdsa_get_pubkey_param.crypto_param &
1247 INTEL_SIP_SMC_FCS_ECC_ALGO_MASK;
1248 i++;
1249
1250 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_ECDSA_GET_PUBKEY,
1251 payload, i, CMD_CASUAL,
1252 (uint32_t *) dst_addr, &ret_size);
1253
1254 memset((void *) &fcs_ecdsa_get_pubkey_param, 0,
1255 sizeof(fcs_crypto_service_data));
1256
1257 if (status < 0) {
1258 *mbox_error = -status;
1259 return INTEL_SIP_SMC_STATUS_ERROR;
1260 }
1261
1262 *dst_size = ret_size * MBOX_WORD_BYTE;
1263 flush_dcache_range(dst_addr, *dst_size);
1264
1265 return INTEL_SIP_SMC_STATUS_OK;
1266}
1267
Sieu Mun Tang0675c222022-05-10 17:48:11 +08001268int intel_fcs_ecdh_request_init(uint32_t session_id, uint32_t context_id,
1269 uint32_t key_id, uint32_t param_size,
1270 uint64_t param_data, uint32_t *mbox_error)
1271{
1272 return intel_fcs_crypto_service_init(session_id, context_id,
1273 key_id, param_size, param_data,
1274 (void *) &fcs_ecdh_request_param,
1275 mbox_error);
1276}
1277
1278int intel_fcs_ecdh_request_finalize(uint32_t session_id, uint32_t context_id,
1279 uint32_t src_addr, uint32_t src_size,
1280 uint64_t dst_addr, uint32_t *dst_size,
1281 uint32_t *mbox_error)
1282{
1283 int status;
1284 uint32_t i;
1285 uint32_t payload[FCS_ECDH_REQUEST_CMD_MAX_WORD_SIZE] = {0U};
1286 uint32_t resp_len = *dst_size / MBOX_WORD_BYTE;
1287 uintptr_t pubkey;
1288
1289 if ((dst_size == NULL) || (mbox_error == NULL)) {
1290 return INTEL_SIP_SMC_STATUS_REJECTED;
1291 }
1292
1293 if (fcs_ecdh_request_param.session_id != session_id ||
1294 fcs_ecdh_request_param.context_id != context_id) {
1295 return INTEL_SIP_SMC_STATUS_REJECTED;
1296 }
1297
1298 if (!is_address_in_ddr_range(src_addr, src_size) ||
1299 !is_address_in_ddr_range(dst_addr, *dst_size)) {
1300 return INTEL_SIP_SMC_STATUS_REJECTED;
1301 }
1302
1303 /* Prepare command payload */
1304 i = 0;
1305 /* Crypto header */
1306 payload[i] = fcs_ecdh_request_param.session_id;
1307 i++;
1308 payload[i] = fcs_ecdh_request_param.context_id;
1309 i++;
1310 payload[i] = fcs_ecdh_request_param.crypto_param_size
1311 & FCS_CS_FIELD_SIZE_MASK;
1312 payload[i] |= (FCS_CS_FIELD_FLAG_INIT | FCS_CS_FIELD_FLAG_UPDATE
1313 | FCS_CS_FIELD_FLAG_FINALIZE)
1314 << FCS_CS_FIELD_FLAG_OFFSET;
1315 i++;
1316 payload[i] = fcs_ecdh_request_param.key_id;
1317 i++;
1318 /* Crypto parameters */
1319 payload[i] = fcs_ecdh_request_param.crypto_param
1320 & INTEL_SIP_SMC_FCS_ECC_ALGO_MASK;
1321 i++;
1322 /* Public key data */
1323 pubkey = src_addr;
1324 memcpy((uint8_t *) &payload[i], (uint8_t *) pubkey, src_size);
1325 i += src_size / MBOX_WORD_BYTE;
1326
1327 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_ECDH_REQUEST,
1328 payload, i, CMD_CASUAL, (uint32_t *) dst_addr,
1329 &resp_len);
1330
1331 memset((void *)&fcs_ecdh_request_param, 0,
1332 sizeof(fcs_crypto_service_data));
1333
1334 if (status < 0) {
1335 *mbox_error = -status;
1336 return INTEL_SIP_SMC_STATUS_ERROR;
1337 }
1338
1339 *dst_size = resp_len * MBOX_WORD_BYTE;
1340 flush_dcache_range(dst_addr, *dst_size);
1341
1342 return INTEL_SIP_SMC_STATUS_OK;
1343}
1344
Sieu Mun Tangb0c1d112022-05-10 17:30:00 +08001345int intel_fcs_aes_crypt_init(uint32_t session_id, uint32_t context_id,
1346 uint32_t key_id, uint64_t param_addr,
1347 uint32_t param_size, uint32_t *mbox_error)
1348{
1349 if (mbox_error == NULL) {
1350 return INTEL_SIP_SMC_STATUS_REJECTED;
1351 }
1352
1353 memset((void *)&fcs_aes_init_payload, 0U, sizeof(fcs_aes_init_payload));
1354
1355 fcs_aes_init_payload.session_id = session_id;
1356 fcs_aes_init_payload.context_id = context_id;
1357 fcs_aes_init_payload.param_size = param_size;
1358 fcs_aes_init_payload.key_id = key_id;
1359
1360 memcpy((uint8_t *) fcs_aes_init_payload.crypto_param,
1361 (uint8_t *) param_addr, param_size);
1362
1363 *mbox_error = 0;
1364
1365 return INTEL_SIP_SMC_STATUS_OK;
1366}
1367
1368int intel_fcs_aes_crypt_finalize(uint32_t session_id, uint32_t context_id,
1369 uint64_t src_addr, uint32_t src_size,
1370 uint64_t dst_addr, uint32_t dst_size,
1371 uint32_t *send_id)
1372{
1373 int status;
1374 int i;
1375 uint32_t crypto_header;
1376 uint32_t fcs_aes_crypt_payload[FCS_AES_CMD_MAX_WORD_SIZE];
1377
1378 if (fcs_aes_init_payload.session_id != session_id ||
1379 fcs_aes_init_payload.context_id != context_id) {
1380 return INTEL_SIP_SMC_STATUS_REJECTED;
1381 }
1382
1383 if ((!is_8_bytes_aligned(src_addr)) ||
1384 (!is_32_bytes_aligned(src_size)) ||
1385 (!is_address_in_ddr_range(src_addr, src_size))) {
1386 return INTEL_SIP_SMC_STATUS_REJECTED;
1387 }
1388
1389 if ((!is_8_bytes_aligned(dst_addr)) ||
1390 (!is_32_bytes_aligned(dst_size))) {
1391 return INTEL_SIP_SMC_STATUS_REJECTED;
1392 }
1393
1394 if ((dst_size > FCS_AES_MAX_DATA_SIZE ||
1395 dst_size < FCS_AES_MIN_DATA_SIZE) ||
1396 (src_size > FCS_AES_MAX_DATA_SIZE ||
1397 src_size < FCS_AES_MIN_DATA_SIZE)) {
1398 return INTEL_SIP_SMC_STATUS_REJECTED;
1399 }
1400
1401 crypto_header = ((FCS_CS_FIELD_FLAG_INIT |
1402 FCS_CS_FIELD_FLAG_UPDATE |
1403 FCS_CS_FIELD_FLAG_FINALIZE) <<
1404 FCS_CS_FIELD_FLAG_OFFSET) |
1405 fcs_aes_init_payload.param_size;
1406 i = 0U;
1407 fcs_aes_crypt_payload[i] = session_id;
1408 i++;
1409 fcs_aes_crypt_payload[i] = context_id;
1410 i++;
1411 fcs_aes_crypt_payload[i] = crypto_header;
1412 i++;
1413 fcs_aes_crypt_payload[i] = fcs_aes_init_payload.key_id;
1414
1415 i++;
1416 memcpy((uint8_t *) &fcs_aes_crypt_payload[i],
1417 (uint8_t *) fcs_aes_init_payload.crypto_param,
1418 fcs_aes_init_payload.param_size);
1419
1420 i += fcs_aes_init_payload.param_size / MBOX_WORD_BYTE;
1421
1422 fcs_aes_crypt_payload[i] = (uint32_t) src_addr;
1423 i++;
1424 fcs_aes_crypt_payload[i] = src_size;
1425 i++;
1426 fcs_aes_crypt_payload[i] = (uint32_t) dst_addr;
1427 i++;
1428 fcs_aes_crypt_payload[i] = dst_size;
1429 i++;
1430
1431 status = mailbox_send_cmd_async(send_id, MBOX_FCS_AES_CRYPT_REQ,
1432 fcs_aes_crypt_payload, i,
1433 CMD_INDIRECT);
1434
1435 memset((void *)&fcs_aes_init_payload, 0U, sizeof(fcs_aes_init_payload));
1436
1437 if (status < 0U) {
1438 return INTEL_SIP_SMC_STATUS_ERROR;
1439 }
1440
1441 return INTEL_SIP_SMC_STATUS_OK;
1442}