blob: 35dd2c58cb5a332a2525b21323be9aaf3f8135e5 [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
572 if (cert_request < FCS_ALIAS_CERT ||
573 cert_request >
574 (FCS_ALIAS_CERT |
575 FCS_DEV_ID_SELF_SIGN_CERT |
576 FCS_DEV_ID_ENROLL_CERT |
577 FCS_ENROLL_SELF_SIGN_CERT |
578 FCS_PLAT_KEY_CERT)) {
579 return INTEL_SIP_SMC_STATUS_REJECTED;
580 }
581
582 if (!is_address_in_ddr_range(dst_addr, *dst_size)) {
583 return INTEL_SIP_SMC_STATUS_REJECTED;
584 }
585
586 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_GET_ATTESTATION_CERT,
587 (uint32_t *) &cert_request, 1U, CMD_CASUAL,
588 (uint32_t *) dst_addr, &ret_size);
589
590 if (status < 0) {
591 *mbox_error = -status;
592 return INTEL_SIP_SMC_STATUS_ERROR;
593 }
594
595 *dst_size = ret_size * MBOX_WORD_BYTE;
596 flush_dcache_range(dst_addr, *dst_size);
597
598 return INTEL_SIP_SMC_STATUS_OK;
599}
600
601int intel_fcs_create_cert_on_reload(uint32_t cert_request,
602 uint32_t *mbox_error)
603{
604 int status;
605
606 if (mbox_error == NULL) {
607 return INTEL_SIP_SMC_STATUS_REJECTED;
608 }
609
610 if (cert_request < FCS_ALIAS_CERT ||
611 cert_request >
612 (FCS_ALIAS_CERT |
613 FCS_DEV_ID_SELF_SIGN_CERT |
614 FCS_DEV_ID_ENROLL_CERT |
615 FCS_ENROLL_SELF_SIGN_CERT |
616 FCS_PLAT_KEY_CERT)) {
617 return INTEL_SIP_SMC_STATUS_REJECTED;
618 }
619
620 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_CREATE_CERT_ON_RELOAD,
621 (uint32_t *) &cert_request, 1U, CMD_CASUAL,
622 NULL, NULL);
623
624 if (status < 0) {
625 *mbox_error = -status;
626 return INTEL_SIP_SMC_STATUS_ERROR;
627 }
628
629 return INTEL_SIP_SMC_STATUS_OK;
630}
Sieu Mun Tang16754e12022-05-09 12:08:42 +0800631
632int intel_fcs_open_crypto_service_session(uint32_t *session_id,
633 uint32_t *mbox_error)
634{
635 int status;
636 uint32_t resp_len = 1U;
637
638 if ((session_id == NULL) || (mbox_error == NULL)) {
639 return INTEL_SIP_SMC_STATUS_REJECTED;
640 }
641
642 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_OPEN_CS_SESSION,
643 NULL, 0U, CMD_CASUAL, session_id, &resp_len);
644
645 if (status < 0) {
646 *mbox_error = -status;
647 return INTEL_SIP_SMC_STATUS_ERROR;
648 }
649
650 return INTEL_SIP_SMC_STATUS_OK;
651}
652
653int intel_fcs_close_crypto_service_session(uint32_t session_id,
654 uint32_t *mbox_error)
655{
656 int status;
657
658 if (mbox_error == NULL) {
659 return INTEL_SIP_SMC_STATUS_REJECTED;
660 }
661
662 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_CLOSE_CS_SESSION,
663 &session_id, 1U, CMD_CASUAL, NULL, NULL);
664
665 if (status < 0) {
666 *mbox_error = -status;
667 return INTEL_SIP_SMC_STATUS_ERROR;
668 }
669
670 return INTEL_SIP_SMC_STATUS_OK;
671}
Sieu Mun Tangfb1f6e92022-05-09 14:16:14 +0800672
673int intel_fcs_import_crypto_service_key(uint64_t src_addr, uint32_t src_size,
674 uint32_t *send_id)
675{
676 int status;
677
678 if (src_size > (FCS_CS_KEY_OBJ_MAX_WORD_SIZE *
679 MBOX_WORD_BYTE)) {
680 return INTEL_SIP_SMC_STATUS_REJECTED;
681 }
682
683 if (!is_address_in_ddr_range(src_addr, src_size)) {
684 return INTEL_SIP_SMC_STATUS_REJECTED;
685 }
686
687 status = mailbox_send_cmd_async(send_id, MBOX_FCS_IMPORT_CS_KEY,
688 (uint32_t *)src_addr, src_size / MBOX_WORD_BYTE,
689 CMD_INDIRECT);
690
691 if (status < 0) {
692 return INTEL_SIP_SMC_STATUS_ERROR;
693 }
694
695 return INTEL_SIP_SMC_STATUS_OK;
696}
697
698int intel_fcs_export_crypto_service_key(uint32_t session_id, uint32_t key_id,
699 uint64_t dst_addr, uint32_t *dst_size,
700 uint32_t *mbox_error)
701{
702 int status;
703 uint32_t i;
704 uint32_t payload_size;
705 uint32_t resp_len = FCS_CS_KEY_OBJ_MAX_WORD_SIZE;
706 uint32_t resp_data[FCS_CS_KEY_OBJ_MAX_WORD_SIZE] = {0U};
707 uint32_t op_status = 0U;
708
709 if ((dst_size == NULL) || (mbox_error == NULL)) {
710 return INTEL_SIP_SMC_STATUS_REJECTED;
711 }
712
713 if (!is_address_in_ddr_range(dst_addr, *dst_size)) {
714 return INTEL_SIP_SMC_STATUS_REJECTED;
715 }
716
717 fcs_cs_key_payload payload = {
718 session_id,
719 RESERVED_AS_ZERO,
720 RESERVED_AS_ZERO,
721 key_id
722 };
723
724 payload_size = sizeof(payload) / MBOX_WORD_BYTE;
725
726 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_EXPORT_CS_KEY,
727 (uint32_t *) &payload, payload_size,
728 CMD_CASUAL, resp_data, &resp_len);
729
730 if (resp_len > 0) {
731 op_status = resp_data[0] & FCS_CS_KEY_RESP_STATUS_MASK;
732 }
733
734 if (status < 0) {
735 *mbox_error = (-status) | (op_status << FCS_CS_KEY_RESP_STATUS_OFFSET);
736 return INTEL_SIP_SMC_STATUS_ERROR;
737 }
738
739 if (resp_len > 1) {
740
741 /* Export key object is start at second response data */
742 *dst_size = (resp_len - 1) * MBOX_WORD_BYTE;
743
744 for (i = 1U; i < resp_len; i++) {
745 mmio_write_32(dst_addr, resp_data[i]);
746 dst_addr += MBOX_WORD_BYTE;
747 }
748
749 flush_dcache_range(dst_addr - *dst_size, *dst_size);
750
751 } else {
752
753 /* Unexpected response, missing key object in response */
754 *mbox_error = MBOX_RET_ERROR;
755 return INTEL_SIP_SMC_STATUS_ERROR;
756 }
757
758 return INTEL_SIP_SMC_STATUS_OK;
759}
760
761int intel_fcs_remove_crypto_service_key(uint32_t session_id, uint32_t key_id,
762 uint32_t *mbox_error)
763{
764 int status;
765 uint32_t payload_size;
766 uint32_t resp_len = 1U;
767 uint32_t resp_data = 0U;
768 uint32_t op_status = 0U;
769
770 if (mbox_error == NULL) {
771 return INTEL_SIP_SMC_STATUS_REJECTED;
772 }
773
774 fcs_cs_key_payload payload = {
775 session_id,
776 RESERVED_AS_ZERO,
777 RESERVED_AS_ZERO,
778 key_id
779 };
780
781 payload_size = sizeof(payload) / MBOX_WORD_BYTE;
782
783 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_REMOVE_CS_KEY,
784 (uint32_t *) &payload, payload_size,
785 CMD_CASUAL, &resp_data, &resp_len);
786
787 if (resp_len > 0) {
788 op_status = resp_data & FCS_CS_KEY_RESP_STATUS_MASK;
789 }
790
791 if (status < 0) {
792 *mbox_error = (-status) | (op_status << FCS_CS_KEY_RESP_STATUS_OFFSET);
793 return INTEL_SIP_SMC_STATUS_ERROR;
794 }
795
796 return INTEL_SIP_SMC_STATUS_OK;
797}
798
799int intel_fcs_get_crypto_service_key_info(uint32_t session_id, uint32_t key_id,
800 uint64_t dst_addr, uint32_t *dst_size,
801 uint32_t *mbox_error)
802{
803 int status;
804 uint32_t payload_size;
805 uint32_t resp_len = FCS_CS_KEY_INFO_MAX_WORD_SIZE;
806 uint32_t op_status = 0U;
807
808 if ((dst_size == NULL) || (mbox_error == NULL)) {
809 return INTEL_SIP_SMC_STATUS_REJECTED;
810 }
811
812 if (!is_address_in_ddr_range(dst_addr, *dst_size)) {
813 return INTEL_SIP_SMC_STATUS_REJECTED;
814 }
815
816 fcs_cs_key_payload payload = {
817 session_id,
818 RESERVED_AS_ZERO,
819 RESERVED_AS_ZERO,
820 key_id
821 };
822
823 payload_size = sizeof(payload) / MBOX_WORD_BYTE;
824
825 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_GET_CS_KEY_INFO,
826 (uint32_t *) &payload, payload_size,
827 CMD_CASUAL, (uint32_t *) dst_addr, &resp_len);
828
829 if (resp_len > 0) {
830 op_status = mmio_read_32(dst_addr) &
831 FCS_CS_KEY_RESP_STATUS_MASK;
832 }
833
834 if (status < 0) {
835 *mbox_error = (-status) | (op_status << FCS_CS_KEY_RESP_STATUS_OFFSET);
836 return INTEL_SIP_SMC_STATUS_ERROR;
837 }
838
839 *dst_size = resp_len * MBOX_WORD_BYTE;
840 flush_dcache_range(dst_addr, *dst_size);
841
842 return INTEL_SIP_SMC_STATUS_OK;
843}
Sieu Mun Tangd907cc32022-05-10 17:24:05 +0800844
845int intel_fcs_get_digest_init(uint32_t session_id, uint32_t context_id,
846 uint32_t key_id, uint32_t param_size,
847 uint64_t param_data, uint32_t *mbox_error)
848{
849 return intel_fcs_crypto_service_init(session_id, context_id,
850 key_id, param_size, param_data,
851 (void *) &fcs_sha_get_digest_param,
852 mbox_error);
853}
854
855int intel_fcs_get_digest_finalize(uint32_t session_id, uint32_t context_id,
856 uint32_t src_addr, uint32_t src_size,
857 uint64_t dst_addr, uint32_t *dst_size,
858 uint32_t *mbox_error)
859{
860 int status;
861 uint32_t i;
862 uint32_t resp_len = *dst_size / MBOX_WORD_BYTE;
863 uint32_t payload[FCS_GET_DIGEST_CMD_MAX_WORD_SIZE] = {0U};
864
865 if (dst_size == NULL || mbox_error == NULL) {
866 return INTEL_SIP_SMC_STATUS_REJECTED;
867 }
868
869 if (fcs_sha_get_digest_param.session_id != session_id ||
870 fcs_sha_get_digest_param.context_id != context_id) {
871 return INTEL_SIP_SMC_STATUS_REJECTED;
872 }
873
874 /* Source data must be 8 bytes aligned */
875 if (!is_8_bytes_aligned(src_size)) {
876 return INTEL_SIP_SMC_STATUS_REJECTED;
877 }
878
879 if (!is_address_in_ddr_range(src_addr, src_size) ||
880 !is_address_in_ddr_range(dst_addr, *dst_size)) {
881 return INTEL_SIP_SMC_STATUS_REJECTED;
882 }
883
884 /* Prepare command payload */
885 i = 0;
886 /* Crypto header */
887 payload[i] = fcs_sha_get_digest_param.session_id;
888 i++;
889 payload[i] = fcs_sha_get_digest_param.context_id;
890 i++;
891 payload[i] = fcs_sha_get_digest_param.crypto_param_size
892 & FCS_CS_FIELD_SIZE_MASK;
893 payload[i] |= (FCS_CS_FIELD_FLAG_INIT | FCS_CS_FIELD_FLAG_UPDATE
894 | FCS_CS_FIELD_FLAG_FINALIZE)
895 << FCS_CS_FIELD_FLAG_OFFSET;
896 i++;
897 payload[i] = fcs_sha_get_digest_param.key_id;
898 i++;
899 /* Crypto parameters */
900 payload[i] = fcs_sha_get_digest_param.crypto_param
901 & INTEL_SIP_SMC_FCS_SHA_MODE_MASK;
902 payload[i] |= ((fcs_sha_get_digest_param.crypto_param
903 >> INTEL_SIP_SMC_FCS_DIGEST_SIZE_OFFSET)
904 & INTEL_SIP_SMC_FCS_DIGEST_SIZE_MASK)
905 << FCS_SHA_HMAC_CRYPTO_PARAM_SIZE_OFFSET;
906 i++;
907 /* Data source address and size */
908 payload[i] = src_addr;
909 i++;
910 payload[i] = src_size;
911 i++;
912
913 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_GET_DIGEST_REQ,
914 payload, i, CMD_CASUAL,
915 (uint32_t *) dst_addr, &resp_len);
916
917 memset((void *)&fcs_sha_get_digest_param, 0, sizeof(fcs_crypto_service_data));
918
919 if (status < 0) {
920 *mbox_error = -status;
921 return INTEL_SIP_SMC_STATUS_ERROR;
922 }
923
924 *dst_size = resp_len * MBOX_WORD_BYTE;
925 flush_dcache_range(dst_addr, *dst_size);
926
927 return INTEL_SIP_SMC_STATUS_OK;
928}
Sieu Mun Tang583149a2022-05-10 17:27:12 +0800929
930int intel_fcs_mac_verify_init(uint32_t session_id, uint32_t context_id,
931 uint32_t key_id, uint32_t param_size,
932 uint64_t param_data, uint32_t *mbox_error)
933{
934 return intel_fcs_crypto_service_init(session_id, context_id,
935 key_id, param_size, param_data,
936 (void *) &fcs_sha_mac_verify_param,
937 mbox_error);
938}
939
940int intel_fcs_mac_verify_finalize(uint32_t session_id, uint32_t context_id,
941 uint32_t src_addr, uint32_t src_size,
942 uint64_t dst_addr, uint32_t *dst_size,
943 uint32_t data_size, uint32_t *mbox_error)
944{
945 int status;
946 uint32_t i;
947 uint32_t resp_len = *dst_size / MBOX_WORD_BYTE;
948 uint32_t payload[FCS_MAC_VERIFY_CMD_MAX_WORD_SIZE] = {0U};
949 uintptr_t mac_offset;
950
951 if (dst_size == NULL || mbox_error == NULL) {
952 return INTEL_SIP_SMC_STATUS_REJECTED;
953 }
954
955 if (fcs_sha_mac_verify_param.session_id != session_id ||
956 fcs_sha_mac_verify_param.context_id != context_id) {
957 return INTEL_SIP_SMC_STATUS_REJECTED;
958 }
959
960 if (data_size >= src_size) {
961 return INTEL_SIP_SMC_STATUS_REJECTED;
962 }
963
964 if (!is_size_4_bytes_aligned(src_size) ||
965 !is_8_bytes_aligned(data_size)) {
966 return INTEL_SIP_SMC_STATUS_REJECTED;
967 }
968
969 if (!is_address_in_ddr_range(src_addr, src_size) ||
970 !is_address_in_ddr_range(dst_addr, *dst_size)) {
971 return INTEL_SIP_SMC_STATUS_REJECTED;
972 }
973
974 /* Prepare command payload */
975 i = 0;
976 /* Crypto header */
977 payload[i] = fcs_sha_mac_verify_param.session_id;
978 i++;
979 payload[i] = fcs_sha_mac_verify_param.context_id;
980 i++;
981 payload[i] = fcs_sha_mac_verify_param.crypto_param_size
982 & FCS_CS_FIELD_SIZE_MASK;
983 payload[i] |= (FCS_CS_FIELD_FLAG_INIT | FCS_CS_FIELD_FLAG_UPDATE
984 | FCS_CS_FIELD_FLAG_FINALIZE)
985 << FCS_CS_FIELD_FLAG_OFFSET;
986 i++;
987 payload[i] = fcs_sha_mac_verify_param.key_id;
988 i++;
989 /* Crypto parameters */
990 payload[i] = ((fcs_sha_mac_verify_param.crypto_param
991 >> INTEL_SIP_SMC_FCS_DIGEST_SIZE_OFFSET)
992 & INTEL_SIP_SMC_FCS_DIGEST_SIZE_MASK)
993 << FCS_SHA_HMAC_CRYPTO_PARAM_SIZE_OFFSET;
994 i++;
995 /* Data source address and size */
996 payload[i] = src_addr;
997 i++;
998 payload[i] = data_size;
999 i++;
1000 /* Copy mac data to command */
1001 mac_offset = src_addr + data_size;
1002 memcpy((uint8_t *) &payload[i], (uint8_t *) mac_offset,
1003 src_size - data_size);
1004
1005 i += (src_size - data_size) / MBOX_WORD_BYTE;
1006
1007 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_MAC_VERIFY_REQ,
1008 payload, i, CMD_CASUAL,
1009 (uint32_t *) dst_addr, &resp_len);
1010
1011 memset((void *)&fcs_sha_mac_verify_param, 0,
1012 sizeof(fcs_crypto_service_data));
1013
1014 if (status < 0) {
1015 *mbox_error = -status;
1016 return INTEL_SIP_SMC_STATUS_ERROR;
1017 }
1018
1019 *dst_size = resp_len * MBOX_WORD_BYTE;
1020 flush_dcache_range(dst_addr, *dst_size);
1021
1022 return INTEL_SIP_SMC_STATUS_OK;
1023}
Sieu Mun Tangb0c1d112022-05-10 17:30:00 +08001024
Sieu Mun Tang8aa05ad2022-05-10 17:50:30 +08001025int intel_fcs_ecdsa_hash_sign_init(uint32_t session_id, uint32_t context_id,
1026 uint32_t key_id, uint32_t param_size,
1027 uint64_t param_data, uint32_t *mbox_error)
1028{
1029 return intel_fcs_crypto_service_init(session_id, context_id,
1030 key_id, param_size, param_data,
1031 (void *) &fcs_ecdsa_hash_sign_param,
1032 mbox_error);
1033}
1034
1035int intel_fcs_ecdsa_hash_sign_finalize(uint32_t session_id, uint32_t context_id,
1036 uint32_t src_addr, uint32_t src_size,
1037 uint64_t dst_addr, uint32_t *dst_size,
1038 uint32_t *mbox_error)
1039{
1040 int status;
1041 uint32_t i;
1042 uint32_t payload[FCS_ECDSA_HASH_SIGN_CMD_MAX_WORD_SIZE] = {0U};
1043 uint32_t resp_len = *dst_size / MBOX_WORD_BYTE;
1044 uintptr_t hash_data_addr;
1045
1046 if ((dst_size == NULL) || (mbox_error == NULL)) {
1047 return INTEL_SIP_SMC_STATUS_REJECTED;
1048 }
1049
1050 if (fcs_ecdsa_hash_sign_param.session_id != session_id ||
1051 fcs_ecdsa_hash_sign_param.context_id != context_id) {
1052 return INTEL_SIP_SMC_STATUS_REJECTED;
1053 }
1054
1055 if (!is_address_in_ddr_range(src_addr, src_size) ||
1056 !is_address_in_ddr_range(dst_addr, *dst_size)) {
1057 return INTEL_SIP_SMC_STATUS_REJECTED;
1058 }
1059
1060 /* Prepare command payload */
1061 /* Crypto header */
1062 i = 0;
1063 payload[i] = fcs_ecdsa_hash_sign_param.session_id;
1064 i++;
1065 payload[i] = fcs_ecdsa_hash_sign_param.context_id;
1066
1067 i++;
1068 payload[i] = fcs_ecdsa_hash_sign_param.crypto_param_size
1069 & FCS_CS_FIELD_SIZE_MASK;
1070 payload[i] |= (FCS_CS_FIELD_FLAG_INIT | FCS_CS_FIELD_FLAG_UPDATE
1071 | FCS_CS_FIELD_FLAG_FINALIZE)
1072 << FCS_CS_FIELD_FLAG_OFFSET;
1073 i++;
1074 payload[i] = fcs_ecdsa_hash_sign_param.key_id;
1075
1076 /* Crypto parameters */
1077 i++;
1078 payload[i] = fcs_ecdsa_hash_sign_param.crypto_param
1079 & INTEL_SIP_SMC_FCS_ECC_ALGO_MASK;
1080
1081 /* Hash Data */
1082 i++;
1083 hash_data_addr = src_addr;
1084 memcpy((uint8_t *) &payload[i], (uint8_t *) hash_data_addr,
1085 src_size);
1086
1087 i += src_size / MBOX_WORD_BYTE;
1088
1089 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_ECDSA_HASH_SIGN_REQ,
1090 payload, i, CMD_CASUAL, (uint32_t *) dst_addr,
1091 &resp_len);
1092
1093 memset((void *) &fcs_ecdsa_hash_sign_param,
1094 0, sizeof(fcs_crypto_service_data));
1095
1096 if (status < 0) {
1097 *mbox_error = -status;
1098 return INTEL_SIP_SMC_STATUS_ERROR;
1099 }
1100
1101 *dst_size = resp_len * MBOX_WORD_BYTE;
1102 flush_dcache_range(dst_addr, *dst_size);
1103
1104 return INTEL_SIP_SMC_STATUS_OK;
1105}
1106
Sieu Mun Tang59357e82022-05-10 17:53:32 +08001107int intel_fcs_ecdsa_hash_sig_verify_init(uint32_t session_id, uint32_t context_id,
1108 uint32_t key_id, uint32_t param_size,
1109 uint64_t param_data, 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_ecdsa_hash_sig_verify_param,
1114 mbox_error);
1115}
1116
1117int intel_fcs_ecdsa_hash_sig_verify_finalize(uint32_t session_id, uint32_t context_id,
1118 uint32_t src_addr, uint32_t src_size,
1119 uint64_t dst_addr, uint32_t *dst_size,
1120 uint32_t *mbox_error)
1121{
1122 int status;
1123 uint32_t i = 0;
1124 uint32_t payload[FCS_ECDSA_HASH_SIG_VERIFY_CMD_MAX_WORD_SIZE] = {0U};
1125 uint32_t resp_len = *dst_size / MBOX_WORD_BYTE;
1126 uintptr_t hash_sig_pubkey_addr;
1127
1128 if ((dst_size == NULL) || (mbox_error == NULL)) {
1129 return INTEL_SIP_SMC_STATUS_REJECTED;
1130 }
1131
1132 if (fcs_ecdsa_hash_sig_verify_param.session_id != session_id ||
1133 fcs_ecdsa_hash_sig_verify_param.context_id != context_id) {
1134 return INTEL_SIP_SMC_STATUS_REJECTED;
1135 }
1136
1137 if (!is_address_in_ddr_range(src_addr, src_size) ||
1138 !is_address_in_ddr_range(dst_addr, *dst_size)) {
1139 return INTEL_SIP_SMC_STATUS_REJECTED;
1140 }
1141
1142 /* Prepare command payload */
1143 /* Crypto header */
1144 i = 0;
1145 payload[i] = fcs_ecdsa_hash_sig_verify_param.session_id;
1146
1147 i++;
1148 payload[i] = fcs_ecdsa_hash_sig_verify_param.context_id;
1149
1150 i++;
1151 payload[i] = fcs_ecdsa_hash_sig_verify_param.crypto_param_size
1152 & FCS_CS_FIELD_SIZE_MASK;
1153 payload[i] |= (FCS_CS_FIELD_FLAG_INIT | FCS_CS_FIELD_FLAG_UPDATE
1154 | FCS_CS_FIELD_FLAG_FINALIZE)
1155 << FCS_CS_FIELD_FLAG_OFFSET;
1156
1157 i++;
1158 payload[i] = fcs_ecdsa_hash_sig_verify_param.key_id;
1159
1160 /* Crypto parameters */
1161 i++;
1162 payload[i] = fcs_ecdsa_hash_sig_verify_param.crypto_param
1163 & INTEL_SIP_SMC_FCS_ECC_ALGO_MASK;
1164
1165 /* Hash Data Word, Signature Data Word and Public Key Data word */
1166 i++;
1167 hash_sig_pubkey_addr = src_addr;
1168 memcpy((uint8_t *) &payload[i],
1169 (uint8_t *) hash_sig_pubkey_addr, src_size);
1170
1171 i += (src_size / MBOX_WORD_BYTE);
1172
1173 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_ECDSA_HASH_SIG_VERIFY,
1174 payload, i, CMD_CASUAL, (uint32_t *) dst_addr,
1175 &resp_len);
1176
1177 memset((void *)&fcs_ecdsa_hash_sig_verify_param,
1178 0, sizeof(fcs_crypto_service_data));
1179
1180 if (status < 0) {
1181 *mbox_error = -status;
1182 return INTEL_SIP_SMC_STATUS_ERROR;
1183 }
1184
1185 *dst_size = resp_len * MBOX_WORD_BYTE;
1186 flush_dcache_range(dst_addr, *dst_size);
1187
1188 return INTEL_SIP_SMC_STATUS_OK;
1189}
1190
Sieu Mun Tang153ecfb2022-05-10 17:39:26 +08001191int intel_fcs_ecdsa_sha2_data_sign_init(uint32_t session_id,
1192 uint32_t context_id, uint32_t key_id,
1193 uint32_t param_size, uint64_t param_data,
1194 uint32_t *mbox_error)
1195{
1196 return intel_fcs_crypto_service_init(session_id, context_id,
1197 key_id, param_size, param_data,
1198 (void *) &fcs_sha2_data_sign_param,
1199 mbox_error);
1200}
1201
1202int intel_fcs_ecdsa_sha2_data_sign_finalize(uint32_t session_id,
1203 uint32_t context_id, uint32_t src_addr,
1204 uint32_t src_size, uint64_t dst_addr,
1205 uint32_t *dst_size, uint32_t *mbox_error)
1206{
1207 int status;
1208 int i;
1209 uint32_t payload[FCS_ECDSA_SHA2_DATA_SIGN_CMD_MAX_WORD_SIZE] = {0U};
1210 uint32_t resp_len = *dst_size / MBOX_WORD_BYTE;
1211
1212 if ((dst_size == NULL) || (mbox_error == NULL)) {
1213 return INTEL_SIP_SMC_STATUS_REJECTED;
1214 }
1215
1216 if (fcs_sha2_data_sign_param.session_id != session_id ||
1217 fcs_sha2_data_sign_param.context_id != context_id) {
1218 return INTEL_SIP_SMC_STATUS_REJECTED;
1219 }
1220
1221 /* Source data must be 8 bytes aligned */
1222 if (!is_8_bytes_aligned(src_size)) {
1223 return INTEL_SIP_SMC_STATUS_REJECTED;
1224 }
1225
1226 if (!is_address_in_ddr_range(src_addr, src_size) ||
1227 !is_address_in_ddr_range(dst_addr, *dst_size)) {
1228 return INTEL_SIP_SMC_STATUS_REJECTED;
1229 }
1230
1231 /* 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};
1294 uint32_t resp_len = *dst_size / MBOX_WORD_BYTE;
1295 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
1320 /* Prepare command payload */
1321 /* Crypto header */
1322 i = 0;
1323 payload[i] = fcs_sha2_data_sig_verify_param.session_id;
1324 i++;
1325 payload[i] = fcs_sha2_data_sig_verify_param.context_id;
1326 i++;
1327
1328 payload[i] = fcs_sha2_data_sig_verify_param.crypto_param_size
1329 & FCS_CS_FIELD_SIZE_MASK;
1330 payload[i] |= (FCS_CS_FIELD_FLAG_INIT | FCS_CS_FIELD_FLAG_UPDATE
1331 | FCS_CS_FIELD_FLAG_FINALIZE)
1332 << FCS_CS_FIELD_FLAG_OFFSET;
1333 i++;
1334 payload[i] = fcs_sha2_data_sig_verify_param.key_id;
1335 i++;
1336 /* Crypto parameters */
1337 payload[i] = fcs_sha2_data_sig_verify_param.crypto_param
1338 & INTEL_SIP_SMC_FCS_ECC_ALGO_MASK;
1339 i++;
1340 /* Data source address and size */
1341 payload[i] = src_addr;
1342 i++;
1343 payload[i] = data_size;
1344 i++;
1345 /* Signature + Public Key Data */
1346 sig_pubkey_offset = src_addr + data_size;
1347 memcpy((uint8_t *) &payload[i], (uint8_t *) sig_pubkey_offset,
1348 src_size - data_size);
1349
1350 i += (src_size - data_size) / MBOX_WORD_BYTE;
1351
1352 status = mailbox_send_cmd(MBOX_JOB_ID,
1353 MBOX_FCS_ECDSA_SHA2_DATA_SIGN_VERIFY, payload, i,
1354 CMD_CASUAL, (uint32_t *) dst_addr, &resp_len);
1355
1356 memset((void *) &fcs_sha2_data_sig_verify_param, 0,
1357 sizeof(fcs_crypto_service_data));
1358
1359 if (status < 0) {
1360 *mbox_error = -status;
1361 return INTEL_SIP_SMC_STATUS_ERROR;
1362 }
1363
1364 *dst_size = resp_len * MBOX_WORD_BYTE;
1365 flush_dcache_range(dst_addr, *dst_size);
1366
1367 return INTEL_SIP_SMC_STATUS_OK;
1368}
1369
Sieu Mun Tange2f3ede2022-05-10 17:36:32 +08001370int intel_fcs_ecdsa_get_pubkey_init(uint32_t session_id, uint32_t context_id,
1371 uint32_t key_id, uint32_t param_size,
1372 uint64_t param_data, uint32_t *mbox_error)
1373{
1374 return intel_fcs_crypto_service_init(session_id, context_id,
1375 key_id, param_size, param_data,
1376 (void *) &fcs_ecdsa_get_pubkey_param,
1377 mbox_error);
1378}
1379
1380int intel_fcs_ecdsa_get_pubkey_finalize(uint32_t session_id, uint32_t context_id,
1381 uint64_t dst_addr, uint32_t *dst_size,
1382 uint32_t *mbox_error)
1383{
1384 int status;
1385 int i;
1386 uint32_t crypto_header;
1387 uint32_t ret_size = *dst_size / MBOX_WORD_BYTE;
1388 uint32_t payload[FCS_ECDSA_GET_PUBKEY_MAX_WORD_SIZE] = {0U};
1389
1390 if ((dst_size == NULL) || (mbox_error == NULL)) {
1391 return INTEL_SIP_SMC_STATUS_REJECTED;
1392 }
1393
1394 if (fcs_ecdsa_get_pubkey_param.session_id != session_id ||
1395 fcs_ecdsa_get_pubkey_param.context_id != context_id) {
1396 return INTEL_SIP_SMC_STATUS_REJECTED;
1397 }
1398
1399 crypto_header = ((FCS_CS_FIELD_FLAG_INIT |
1400 FCS_CS_FIELD_FLAG_UPDATE |
1401 FCS_CS_FIELD_FLAG_FINALIZE) <<
1402 FCS_CS_FIELD_FLAG_OFFSET) |
1403 fcs_ecdsa_get_pubkey_param.crypto_param_size;
1404 i = 0;
1405 /* Prepare command payload */
1406 payload[i] = session_id;
1407 i++;
1408 payload[i] = context_id;
1409 i++;
1410 payload[i] = crypto_header;
1411 i++;
1412 payload[i] = fcs_ecdsa_get_pubkey_param.key_id;
1413 i++;
1414 payload[i] = (uint32_t) fcs_ecdsa_get_pubkey_param.crypto_param &
1415 INTEL_SIP_SMC_FCS_ECC_ALGO_MASK;
1416 i++;
1417
1418 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_ECDSA_GET_PUBKEY,
1419 payload, i, CMD_CASUAL,
1420 (uint32_t *) dst_addr, &ret_size);
1421
1422 memset((void *) &fcs_ecdsa_get_pubkey_param, 0,
1423 sizeof(fcs_crypto_service_data));
1424
1425 if (status < 0) {
1426 *mbox_error = -status;
1427 return INTEL_SIP_SMC_STATUS_ERROR;
1428 }
1429
1430 *dst_size = ret_size * MBOX_WORD_BYTE;
1431 flush_dcache_range(dst_addr, *dst_size);
1432
1433 return INTEL_SIP_SMC_STATUS_OK;
1434}
1435
Sieu Mun Tang0675c222022-05-10 17:48:11 +08001436int intel_fcs_ecdh_request_init(uint32_t session_id, uint32_t context_id,
1437 uint32_t key_id, uint32_t param_size,
1438 uint64_t param_data, uint32_t *mbox_error)
1439{
1440 return intel_fcs_crypto_service_init(session_id, context_id,
1441 key_id, param_size, param_data,
1442 (void *) &fcs_ecdh_request_param,
1443 mbox_error);
1444}
1445
1446int intel_fcs_ecdh_request_finalize(uint32_t session_id, uint32_t context_id,
1447 uint32_t src_addr, uint32_t src_size,
1448 uint64_t dst_addr, uint32_t *dst_size,
1449 uint32_t *mbox_error)
1450{
1451 int status;
1452 uint32_t i;
1453 uint32_t payload[FCS_ECDH_REQUEST_CMD_MAX_WORD_SIZE] = {0U};
1454 uint32_t resp_len = *dst_size / MBOX_WORD_BYTE;
1455 uintptr_t pubkey;
1456
1457 if ((dst_size == NULL) || (mbox_error == NULL)) {
1458 return INTEL_SIP_SMC_STATUS_REJECTED;
1459 }
1460
1461 if (fcs_ecdh_request_param.session_id != session_id ||
1462 fcs_ecdh_request_param.context_id != context_id) {
1463 return INTEL_SIP_SMC_STATUS_REJECTED;
1464 }
1465
1466 if (!is_address_in_ddr_range(src_addr, src_size) ||
1467 !is_address_in_ddr_range(dst_addr, *dst_size)) {
1468 return INTEL_SIP_SMC_STATUS_REJECTED;
1469 }
1470
1471 /* Prepare command payload */
1472 i = 0;
1473 /* Crypto header */
1474 payload[i] = fcs_ecdh_request_param.session_id;
1475 i++;
1476 payload[i] = fcs_ecdh_request_param.context_id;
1477 i++;
1478 payload[i] = fcs_ecdh_request_param.crypto_param_size
1479 & FCS_CS_FIELD_SIZE_MASK;
1480 payload[i] |= (FCS_CS_FIELD_FLAG_INIT | FCS_CS_FIELD_FLAG_UPDATE
1481 | FCS_CS_FIELD_FLAG_FINALIZE)
1482 << FCS_CS_FIELD_FLAG_OFFSET;
1483 i++;
1484 payload[i] = fcs_ecdh_request_param.key_id;
1485 i++;
1486 /* Crypto parameters */
1487 payload[i] = fcs_ecdh_request_param.crypto_param
1488 & INTEL_SIP_SMC_FCS_ECC_ALGO_MASK;
1489 i++;
1490 /* Public key data */
1491 pubkey = src_addr;
1492 memcpy((uint8_t *) &payload[i], (uint8_t *) pubkey, src_size);
1493 i += src_size / MBOX_WORD_BYTE;
1494
1495 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_ECDH_REQUEST,
1496 payload, i, CMD_CASUAL, (uint32_t *) dst_addr,
1497 &resp_len);
1498
1499 memset((void *)&fcs_ecdh_request_param, 0,
1500 sizeof(fcs_crypto_service_data));
1501
1502 if (status < 0) {
1503 *mbox_error = -status;
1504 return INTEL_SIP_SMC_STATUS_ERROR;
1505 }
1506
1507 *dst_size = resp_len * MBOX_WORD_BYTE;
1508 flush_dcache_range(dst_addr, *dst_size);
1509
1510 return INTEL_SIP_SMC_STATUS_OK;
1511}
1512
Sieu Mun Tangb0c1d112022-05-10 17:30:00 +08001513int intel_fcs_aes_crypt_init(uint32_t session_id, uint32_t context_id,
1514 uint32_t key_id, uint64_t param_addr,
1515 uint32_t param_size, uint32_t *mbox_error)
1516{
1517 if (mbox_error == NULL) {
1518 return INTEL_SIP_SMC_STATUS_REJECTED;
1519 }
1520
1521 memset((void *)&fcs_aes_init_payload, 0U, sizeof(fcs_aes_init_payload));
1522
1523 fcs_aes_init_payload.session_id = session_id;
1524 fcs_aes_init_payload.context_id = context_id;
1525 fcs_aes_init_payload.param_size = param_size;
1526 fcs_aes_init_payload.key_id = key_id;
1527
1528 memcpy((uint8_t *) fcs_aes_init_payload.crypto_param,
1529 (uint8_t *) param_addr, param_size);
1530
1531 *mbox_error = 0;
1532
1533 return INTEL_SIP_SMC_STATUS_OK;
1534}
1535
1536int intel_fcs_aes_crypt_finalize(uint32_t session_id, uint32_t context_id,
1537 uint64_t src_addr, uint32_t src_size,
1538 uint64_t dst_addr, uint32_t dst_size,
1539 uint32_t *send_id)
1540{
1541 int status;
1542 int i;
1543 uint32_t crypto_header;
1544 uint32_t fcs_aes_crypt_payload[FCS_AES_CMD_MAX_WORD_SIZE];
1545
1546 if (fcs_aes_init_payload.session_id != session_id ||
1547 fcs_aes_init_payload.context_id != context_id) {
1548 return INTEL_SIP_SMC_STATUS_REJECTED;
1549 }
1550
1551 if ((!is_8_bytes_aligned(src_addr)) ||
1552 (!is_32_bytes_aligned(src_size)) ||
1553 (!is_address_in_ddr_range(src_addr, src_size))) {
1554 return INTEL_SIP_SMC_STATUS_REJECTED;
1555 }
1556
1557 if ((!is_8_bytes_aligned(dst_addr)) ||
1558 (!is_32_bytes_aligned(dst_size))) {
1559 return INTEL_SIP_SMC_STATUS_REJECTED;
1560 }
1561
1562 if ((dst_size > FCS_AES_MAX_DATA_SIZE ||
1563 dst_size < FCS_AES_MIN_DATA_SIZE) ||
1564 (src_size > FCS_AES_MAX_DATA_SIZE ||
1565 src_size < FCS_AES_MIN_DATA_SIZE)) {
1566 return INTEL_SIP_SMC_STATUS_REJECTED;
1567 }
1568
1569 crypto_header = ((FCS_CS_FIELD_FLAG_INIT |
1570 FCS_CS_FIELD_FLAG_UPDATE |
1571 FCS_CS_FIELD_FLAG_FINALIZE) <<
1572 FCS_CS_FIELD_FLAG_OFFSET) |
1573 fcs_aes_init_payload.param_size;
1574 i = 0U;
1575 fcs_aes_crypt_payload[i] = session_id;
1576 i++;
1577 fcs_aes_crypt_payload[i] = context_id;
1578 i++;
1579 fcs_aes_crypt_payload[i] = crypto_header;
1580 i++;
1581 fcs_aes_crypt_payload[i] = fcs_aes_init_payload.key_id;
1582
1583 i++;
1584 memcpy((uint8_t *) &fcs_aes_crypt_payload[i],
1585 (uint8_t *) fcs_aes_init_payload.crypto_param,
1586 fcs_aes_init_payload.param_size);
1587
1588 i += fcs_aes_init_payload.param_size / MBOX_WORD_BYTE;
1589
1590 fcs_aes_crypt_payload[i] = (uint32_t) src_addr;
1591 i++;
1592 fcs_aes_crypt_payload[i] = src_size;
1593 i++;
1594 fcs_aes_crypt_payload[i] = (uint32_t) dst_addr;
1595 i++;
1596 fcs_aes_crypt_payload[i] = dst_size;
1597 i++;
1598
1599 status = mailbox_send_cmd_async(send_id, MBOX_FCS_AES_CRYPT_REQ,
1600 fcs_aes_crypt_payload, i,
1601 CMD_INDIRECT);
1602
1603 memset((void *)&fcs_aes_init_payload, 0U, sizeof(fcs_aes_init_payload));
1604
1605 if (status < 0U) {
1606 return INTEL_SIP_SMC_STATUS_ERROR;
1607 }
1608
1609 return INTEL_SIP_SMC_STATUS_OK;
1610}