blob: ff31c9714d19bee0bc0ddbdc7a2110b46ad0846d [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 Tangd907cc32022-05-10 17:24:05 +080018
Sieu Mun Tang128d2a72022-05-11 09:49:25 +080019bool is_size_4_bytes_aligned(uint32_t size)
Sieu Mun Tangdb79fa52022-03-20 00:49:57 +080020{
21 if ((size % MBOX_WORD_BYTE) != 0U) {
22 return false;
23 } else {
24 return true;
25 }
Sieu Mun Tangd907cc32022-05-10 17:24:05 +080026}
27
28static bool is_8_bytes_aligned(uint32_t data)
29{
30 if ((data % (MBOX_WORD_BYTE * 2U)) != 0U) {
31 return false;
32 } else {
33 return true;
34 }
35}
36
Sieu Mun Tangb0c1d112022-05-10 17:30:00 +080037static bool is_32_bytes_aligned(uint32_t data)
38{
39 if ((data % (8U * MBOX_WORD_BYTE)) != 0U) {
40 return false;
41 } else {
42 return true;
43 }
44}
45
Sieu Mun Tangd907cc32022-05-10 17:24:05 +080046static int intel_fcs_crypto_service_init(uint32_t session_id,
47 uint32_t context_id, uint32_t key_id,
48 uint32_t param_size, uint64_t param_data,
49 fcs_crypto_service_data *data_addr,
50 uint32_t *mbox_error)
51{
52 if (mbox_error == NULL) {
53 return INTEL_SIP_SMC_STATUS_REJECTED;
54 }
55
56 if (param_size != 4) {
57 return INTEL_SIP_SMC_STATUS_REJECTED;
58 }
59
60 memset(data_addr, 0, sizeof(fcs_crypto_service_data));
61
62 data_addr->session_id = session_id;
63 data_addr->context_id = context_id;
64 data_addr->key_id = key_id;
65 data_addr->crypto_param_size = param_size;
66 data_addr->crypto_param = param_data;
67
68 *mbox_error = 0;
69
70 return INTEL_SIP_SMC_STATUS_OK;
Sieu Mun Tangdb79fa52022-03-20 00:49:57 +080071}
72
Sieu Mun Tang9f22cbf2022-03-02 11:04:09 +080073uint32_t intel_fcs_random_number_gen(uint64_t addr, uint64_t *ret_size,
74 uint32_t *mbox_error)
75{
76 int status;
77 unsigned int i;
78 unsigned int resp_len = FCS_RANDOM_WORD_SIZE;
79 uint32_t random_data[FCS_RANDOM_WORD_SIZE] = {0U};
80
81 if (!is_address_in_ddr_range(addr, FCS_RANDOM_BYTE_SIZE)) {
82 return INTEL_SIP_SMC_STATUS_REJECTED;
83 }
84
85 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_RANDOM_GEN, NULL, 0U,
86 CMD_CASUAL, random_data, &resp_len);
87
88 if (status < 0) {
89 *mbox_error = -status;
90 return INTEL_SIP_SMC_STATUS_ERROR;
91 }
92
93 if (resp_len != FCS_RANDOM_WORD_SIZE) {
94 *mbox_error = GENERIC_RESPONSE_ERROR;
95 return INTEL_SIP_SMC_STATUS_ERROR;
96 }
97
98 *ret_size = FCS_RANDOM_BYTE_SIZE;
99
100 for (i = 0U; i < FCS_RANDOM_WORD_SIZE; i++) {
101 mmio_write_32(addr, random_data[i]);
102 addr += MBOX_WORD_BYTE;
103 }
104
105 flush_dcache_range(addr - *ret_size, *ret_size);
106
107 return INTEL_SIP_SMC_STATUS_OK;
108}
109
Sieu Mun Tange7a037f2022-05-10 17:18:19 +0800110int intel_fcs_random_number_gen_ext(uint32_t session_id, uint32_t context_id,
111 uint32_t size, uint32_t *send_id)
112{
113 int status;
114 uint32_t payload_size;
115 uint32_t crypto_header;
116
117 if (size > (FCS_RANDOM_EXT_MAX_WORD_SIZE *
118 MBOX_WORD_BYTE) || size == 0U) {
119 return INTEL_SIP_SMC_STATUS_REJECTED;
120 }
121
122 if (!is_size_4_bytes_aligned(size)) {
123 return INTEL_SIP_SMC_STATUS_REJECTED;
124 }
125
126 crypto_header = (FCS_CS_FIELD_FLAG_INIT | FCS_CS_FIELD_FLAG_FINALIZE) <<
127 FCS_CS_FIELD_FLAG_OFFSET;
128
129 fcs_rng_payload payload = {
130 session_id,
131 context_id,
132 crypto_header,
133 size
134 };
135
136 payload_size = sizeof(payload) / MBOX_WORD_BYTE;
137
138 status = mailbox_send_cmd_async(send_id, MBOX_FCS_RANDOM_GEN,
139 (uint32_t *) &payload, payload_size,
140 CMD_INDIRECT);
141
142 if (status < 0) {
143 return INTEL_SIP_SMC_STATUS_ERROR;
144 }
145
146 return INTEL_SIP_SMC_STATUS_OK;
147}
148
Sieu Mun Tang9f22cbf2022-03-02 11:04:09 +0800149uint32_t intel_fcs_send_cert(uint64_t addr, uint64_t size,
150 uint32_t *send_id)
151{
152 int status;
153
154 if (!is_address_in_ddr_range(addr, size)) {
155 return INTEL_SIP_SMC_STATUS_REJECTED;
156 }
157
Sieu Mun Tangdb79fa52022-03-20 00:49:57 +0800158 if (!is_size_4_bytes_aligned(size)) {
159 return INTEL_SIP_SMC_STATUS_REJECTED;
160 }
161
Sieu Mun Tang9f22cbf2022-03-02 11:04:09 +0800162 status = mailbox_send_cmd_async(send_id, MBOX_CMD_VAB_SRC_CERT,
163 (uint32_t *)addr, size / MBOX_WORD_BYTE,
164 CMD_DIRECT);
165
Boon Khai Ngcac786d2021-05-26 01:50:34 +0800166 flush_dcache_range(addr, size);
167
Sieu Mun Tang9f22cbf2022-03-02 11:04:09 +0800168 if (status < 0) {
169 return INTEL_SIP_SMC_STATUS_ERROR;
170 }
171
172 return INTEL_SIP_SMC_STATUS_OK;
173}
174
175uint32_t intel_fcs_get_provision_data(uint32_t *send_id)
176{
177 int status;
178
179 status = mailbox_send_cmd_async(send_id, MBOX_FCS_GET_PROVISION,
180 NULL, 0U, CMD_DIRECT);
181
182 if (status < 0) {
183 return INTEL_SIP_SMC_STATUS_ERROR;
184 }
185
186 return INTEL_SIP_SMC_STATUS_OK;
187}
188
Sieu Mun Tanga068fdf2022-05-11 10:01:54 +0800189uint32_t intel_fcs_cntr_set_preauth(uint8_t counter_type, int32_t counter_value,
190 uint32_t test_bit, uint32_t *mbox_error)
191{
192 int status;
193 uint32_t first_word;
194 uint32_t payload_size;
195
196 if ((test_bit != MBOX_TEST_BIT) &&
197 (test_bit != 0)) {
198 return INTEL_SIP_SMC_STATUS_REJECTED;
199 }
200
201 if ((counter_type < FCS_BIG_CNTR_SEL) ||
202 (counter_type > FCS_SVN_CNTR_3_SEL)) {
203 return INTEL_SIP_SMC_STATUS_REJECTED;
204 }
205
206 if ((counter_type == FCS_BIG_CNTR_SEL) &&
207 (counter_value > FCS_BIG_CNTR_VAL_MAX)) {
208 return INTEL_SIP_SMC_STATUS_REJECTED;
209 }
210
211 if ((counter_type >= FCS_SVN_CNTR_0_SEL) &&
212 (counter_type <= FCS_SVN_CNTR_3_SEL) &&
213 (counter_value > FCS_SVN_CNTR_VAL_MAX)) {
214 return INTEL_SIP_SMC_STATUS_REJECTED;
215 }
216
217 first_word = test_bit | counter_type;
218 fcs_cntr_set_preauth_payload payload = {
219 first_word,
220 counter_value
221 };
222
223 payload_size = sizeof(payload) / MBOX_WORD_BYTE;
224 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_CNTR_SET_PREAUTH,
225 (uint32_t *) &payload, payload_size,
226 CMD_CASUAL, NULL, NULL);
227
228 if (status < 0) {
229 *mbox_error = -status;
230 return INTEL_SIP_SMC_STATUS_ERROR;
231 }
232
233 return INTEL_SIP_SMC_STATUS_OK;
234}
235
Sieu Mun Tang128d2a72022-05-11 09:49:25 +0800236uint32_t intel_fcs_encryption(uint32_t src_addr, uint32_t src_size,
237 uint32_t dst_addr, uint32_t dst_size, uint32_t *send_id)
Sieu Mun Tang9f22cbf2022-03-02 11:04:09 +0800238{
239 int status;
Sieu Mun Tang128d2a72022-05-11 09:49:25 +0800240 uint32_t load_size;
Sieu Mun Tang9f22cbf2022-03-02 11:04:09 +0800241
Sieu Mun Tang128d2a72022-05-11 09:49:25 +0800242 fcs_encrypt_payload payload = {
243 FCS_ENCRYPTION_DATA_0,
Sieu Mun Tang9f22cbf2022-03-02 11:04:09 +0800244 src_addr,
245 src_size,
246 dst_addr,
247 dst_size };
Sieu Mun Tang128d2a72022-05-11 09:49:25 +0800248 load_size = sizeof(payload) / MBOX_WORD_BYTE;
Sieu Mun Tang9f22cbf2022-03-02 11:04:09 +0800249
Sieu Mun Tangdb79fa52022-03-20 00:49:57 +0800250 if (!is_address_in_ddr_range(src_addr, src_size) ||
251 !is_address_in_ddr_range(dst_addr, dst_size)) {
252 return INTEL_SIP_SMC_STATUS_REJECTED;
253 }
254
Sieu Mun Tang128d2a72022-05-11 09:49:25 +0800255 if (!is_size_4_bytes_aligned(src_size)) {
Sieu Mun Tangdb79fa52022-03-20 00:49:57 +0800256 return INTEL_SIP_SMC_STATUS_REJECTED;
257 }
258
Sieu Mun Tang128d2a72022-05-11 09:49:25 +0800259 status = mailbox_send_cmd_async(send_id, MBOX_FCS_ENCRYPT_REQ,
260 (uint32_t *) &payload, load_size,
261 CMD_INDIRECT);
262 inv_dcache_range(dst_addr, dst_size);
263
264 if (status < 0) {
265 return INTEL_SIP_SMC_STATUS_REJECTED;
266 }
267
268 return INTEL_SIP_SMC_STATUS_OK;
269}
270
271uint32_t intel_fcs_decryption(uint32_t src_addr, uint32_t src_size,
272 uint32_t dst_addr, uint32_t dst_size, uint32_t *send_id)
273{
274 int status;
275 uint32_t load_size;
276 uintptr_t id_offset;
277
278 id_offset = src_addr + FCS_OWNER_ID_OFFSET;
279 fcs_decrypt_payload payload = {
280 FCS_DECRYPTION_DATA_0,
281 {mmio_read_32(id_offset),
282 mmio_read_32(id_offset + MBOX_WORD_BYTE)},
283 src_addr,
284 src_size,
285 dst_addr,
286 dst_size };
287 load_size = sizeof(payload) / MBOX_WORD_BYTE;
288
289 if (!is_address_in_ddr_range(src_addr, src_size) ||
290 !is_address_in_ddr_range(dst_addr, dst_size)) {
291 return INTEL_SIP_SMC_STATUS_REJECTED;
292 }
293
294 if (!is_size_4_bytes_aligned(src_size)) {
295 return INTEL_SIP_SMC_STATUS_REJECTED;
Sieu Mun Tang9f22cbf2022-03-02 11:04:09 +0800296 }
297
Sieu Mun Tang128d2a72022-05-11 09:49:25 +0800298 status = mailbox_send_cmd_async(send_id, MBOX_FCS_DECRYPT_REQ,
299 (uint32_t *) &payload, load_size,
Sieu Mun Tang9f22cbf2022-03-02 11:04:09 +0800300 CMD_INDIRECT);
301 inv_dcache_range(dst_addr, dst_size);
302
303 if (status < 0) {
304 return INTEL_SIP_SMC_STATUS_REJECTED;
305 }
306
307 return INTEL_SIP_SMC_STATUS_OK;
308}
Sieu Mun Tanga34b8812022-03-17 03:11:55 +0800309
310uint32_t intel_fcs_get_rom_patch_sha384(uint64_t addr, uint64_t *ret_size,
311 uint32_t *mbox_error)
312{
313 int status;
314 unsigned int resp_len = FCS_SHA384_WORD_SIZE;
315
316 if (!is_address_in_ddr_range(addr, FCS_SHA384_BYTE_SIZE)) {
317 return INTEL_SIP_SMC_STATUS_REJECTED;
318 }
319
320 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_GET_ROM_PATCH_SHA384, NULL, 0U,
321 CMD_CASUAL, (uint32_t *) addr, &resp_len);
322
323 if (status < 0) {
324 *mbox_error = -status;
325 return INTEL_SIP_SMC_STATUS_ERROR;
326 }
327
328 if (resp_len != FCS_SHA384_WORD_SIZE) {
329 *mbox_error = GENERIC_RESPONSE_ERROR;
330 return INTEL_SIP_SMC_STATUS_ERROR;
331 }
332
333 *ret_size = FCS_SHA384_BYTE_SIZE;
334
335 flush_dcache_range(addr, *ret_size);
336
337 return INTEL_SIP_SMC_STATUS_OK;
338}
Sieu Mun Tang2a820b92022-05-11 09:59:55 +0800339
340int intel_fcs_sigma_teardown(uint32_t session_id, uint32_t *mbox_error)
341{
342 int status;
343
344 if ((session_id != PSGSIGMA_SESSION_ID_ONE) &&
345 (session_id != PSGSIGMA_UNKNOWN_SESSION)) {
346 return INTEL_SIP_SMC_STATUS_REJECTED;
347 }
348
349 psgsigma_teardown_msg message = {
350 RESERVED_AS_ZERO,
351 PSGSIGMA_TEARDOWN_MAGIC,
352 session_id
353 };
354
355 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_PSG_SIGMA_TEARDOWN,
356 (uint32_t *) &message, sizeof(message) / MBOX_WORD_BYTE,
357 CMD_CASUAL, NULL, NULL);
358
359 if (status < 0) {
360 *mbox_error = -status;
361 return INTEL_SIP_SMC_STATUS_ERROR;
362 }
363
364 return INTEL_SIP_SMC_STATUS_OK;
365}
366
367int intel_fcs_chip_id(uint32_t *id_low, uint32_t *id_high, uint32_t *mbox_error)
368{
369 int status;
370 uint32_t load_size;
371 uint32_t chip_id[2];
372
373 load_size = sizeof(chip_id) / MBOX_WORD_BYTE;
374
375 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_CMD_GET_CHIPID, NULL,
376 0U, CMD_CASUAL, (uint32_t *) chip_id, &load_size);
377
378 if (status < 0) {
379 *mbox_error = -status;
380 return INTEL_SIP_SMC_STATUS_ERROR;
381 }
382
383 *id_low = chip_id[0];
384 *id_high = chip_id[1];
385
386 return INTEL_SIP_SMC_STATUS_OK;
387}
388
389int intel_fcs_attestation_subkey(uint64_t src_addr, uint32_t src_size,
390 uint64_t dst_addr, uint32_t *dst_size, uint32_t *mbox_error)
391{
392 int status;
393 uint32_t send_size = src_size / MBOX_WORD_BYTE;
394 uint32_t ret_size = *dst_size / MBOX_WORD_BYTE;
395
396
397 if (!is_address_in_ddr_range(src_addr, src_size) ||
398 !is_address_in_ddr_range(dst_addr, *dst_size)) {
399 return INTEL_SIP_SMC_STATUS_REJECTED;
400 }
401
402 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_ATTESTATION_SUBKEY,
403 (uint32_t *) src_addr, send_size, CMD_CASUAL,
404 (uint32_t *) dst_addr, &ret_size);
405
406 if (status < 0) {
407 *mbox_error = -status;
408 return INTEL_SIP_SMC_STATUS_ERROR;
409 }
410
411 *dst_size = ret_size * MBOX_WORD_BYTE;
412 flush_dcache_range(dst_addr, *dst_size);
413
414 return INTEL_SIP_SMC_STATUS_OK;
415}
416
417int intel_fcs_get_measurement(uint64_t src_addr, uint32_t src_size,
418 uint64_t dst_addr, uint32_t *dst_size, uint32_t *mbox_error)
419{
420 int status;
421 uint32_t send_size = src_size / MBOX_WORD_BYTE;
422 uint32_t ret_size = *dst_size / MBOX_WORD_BYTE;
423
424 if (!is_address_in_ddr_range(src_addr, src_size) ||
425 !is_address_in_ddr_range(dst_addr, *dst_size)) {
426 return INTEL_SIP_SMC_STATUS_REJECTED;
427 }
428
429 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_GET_MEASUREMENT,
430 (uint32_t *) src_addr, send_size, CMD_CASUAL,
431 (uint32_t *) dst_addr, &ret_size);
432
433 if (status < 0) {
434 *mbox_error = -status;
435 return INTEL_SIP_SMC_STATUS_ERROR;
436 }
437
438 *dst_size = ret_size * MBOX_WORD_BYTE;
439 flush_dcache_range(dst_addr, *dst_size);
440
441 return INTEL_SIP_SMC_STATUS_OK;
442}
Sieu Mun Tang28af1652022-05-09 10:48:53 +0800443
444int intel_fcs_get_attestation_cert(uint32_t cert_request, uint64_t dst_addr,
445 uint32_t *dst_size, uint32_t *mbox_error)
446{
447 int status;
448 uint32_t ret_size = *dst_size / MBOX_WORD_BYTE;
449
450 if (mbox_error == NULL) {
451 return INTEL_SIP_SMC_STATUS_REJECTED;
452 }
453
454 if (cert_request < FCS_ALIAS_CERT ||
455 cert_request >
456 (FCS_ALIAS_CERT |
457 FCS_DEV_ID_SELF_SIGN_CERT |
458 FCS_DEV_ID_ENROLL_CERT |
459 FCS_ENROLL_SELF_SIGN_CERT |
460 FCS_PLAT_KEY_CERT)) {
461 return INTEL_SIP_SMC_STATUS_REJECTED;
462 }
463
464 if (!is_address_in_ddr_range(dst_addr, *dst_size)) {
465 return INTEL_SIP_SMC_STATUS_REJECTED;
466 }
467
468 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_GET_ATTESTATION_CERT,
469 (uint32_t *) &cert_request, 1U, CMD_CASUAL,
470 (uint32_t *) dst_addr, &ret_size);
471
472 if (status < 0) {
473 *mbox_error = -status;
474 return INTEL_SIP_SMC_STATUS_ERROR;
475 }
476
477 *dst_size = ret_size * MBOX_WORD_BYTE;
478 flush_dcache_range(dst_addr, *dst_size);
479
480 return INTEL_SIP_SMC_STATUS_OK;
481}
482
483int intel_fcs_create_cert_on_reload(uint32_t cert_request,
484 uint32_t *mbox_error)
485{
486 int status;
487
488 if (mbox_error == NULL) {
489 return INTEL_SIP_SMC_STATUS_REJECTED;
490 }
491
492 if (cert_request < FCS_ALIAS_CERT ||
493 cert_request >
494 (FCS_ALIAS_CERT |
495 FCS_DEV_ID_SELF_SIGN_CERT |
496 FCS_DEV_ID_ENROLL_CERT |
497 FCS_ENROLL_SELF_SIGN_CERT |
498 FCS_PLAT_KEY_CERT)) {
499 return INTEL_SIP_SMC_STATUS_REJECTED;
500 }
501
502 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_CREATE_CERT_ON_RELOAD,
503 (uint32_t *) &cert_request, 1U, CMD_CASUAL,
504 NULL, NULL);
505
506 if (status < 0) {
507 *mbox_error = -status;
508 return INTEL_SIP_SMC_STATUS_ERROR;
509 }
510
511 return INTEL_SIP_SMC_STATUS_OK;
512}
Sieu Mun Tang16754e12022-05-09 12:08:42 +0800513
514int intel_fcs_open_crypto_service_session(uint32_t *session_id,
515 uint32_t *mbox_error)
516{
517 int status;
518 uint32_t resp_len = 1U;
519
520 if ((session_id == NULL) || (mbox_error == NULL)) {
521 return INTEL_SIP_SMC_STATUS_REJECTED;
522 }
523
524 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_OPEN_CS_SESSION,
525 NULL, 0U, CMD_CASUAL, session_id, &resp_len);
526
527 if (status < 0) {
528 *mbox_error = -status;
529 return INTEL_SIP_SMC_STATUS_ERROR;
530 }
531
532 return INTEL_SIP_SMC_STATUS_OK;
533}
534
535int intel_fcs_close_crypto_service_session(uint32_t session_id,
536 uint32_t *mbox_error)
537{
538 int status;
539
540 if (mbox_error == NULL) {
541 return INTEL_SIP_SMC_STATUS_REJECTED;
542 }
543
544 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_CLOSE_CS_SESSION,
545 &session_id, 1U, CMD_CASUAL, NULL, NULL);
546
547 if (status < 0) {
548 *mbox_error = -status;
549 return INTEL_SIP_SMC_STATUS_ERROR;
550 }
551
552 return INTEL_SIP_SMC_STATUS_OK;
553}
Sieu Mun Tangfb1f6e92022-05-09 14:16:14 +0800554
555int intel_fcs_import_crypto_service_key(uint64_t src_addr, uint32_t src_size,
556 uint32_t *send_id)
557{
558 int status;
559
560 if (src_size > (FCS_CS_KEY_OBJ_MAX_WORD_SIZE *
561 MBOX_WORD_BYTE)) {
562 return INTEL_SIP_SMC_STATUS_REJECTED;
563 }
564
565 if (!is_address_in_ddr_range(src_addr, src_size)) {
566 return INTEL_SIP_SMC_STATUS_REJECTED;
567 }
568
569 status = mailbox_send_cmd_async(send_id, MBOX_FCS_IMPORT_CS_KEY,
570 (uint32_t *)src_addr, src_size / MBOX_WORD_BYTE,
571 CMD_INDIRECT);
572
573 if (status < 0) {
574 return INTEL_SIP_SMC_STATUS_ERROR;
575 }
576
577 return INTEL_SIP_SMC_STATUS_OK;
578}
579
580int intel_fcs_export_crypto_service_key(uint32_t session_id, uint32_t key_id,
581 uint64_t dst_addr, uint32_t *dst_size,
582 uint32_t *mbox_error)
583{
584 int status;
585 uint32_t i;
586 uint32_t payload_size;
587 uint32_t resp_len = FCS_CS_KEY_OBJ_MAX_WORD_SIZE;
588 uint32_t resp_data[FCS_CS_KEY_OBJ_MAX_WORD_SIZE] = {0U};
589 uint32_t op_status = 0U;
590
591 if ((dst_size == NULL) || (mbox_error == NULL)) {
592 return INTEL_SIP_SMC_STATUS_REJECTED;
593 }
594
595 if (!is_address_in_ddr_range(dst_addr, *dst_size)) {
596 return INTEL_SIP_SMC_STATUS_REJECTED;
597 }
598
599 fcs_cs_key_payload payload = {
600 session_id,
601 RESERVED_AS_ZERO,
602 RESERVED_AS_ZERO,
603 key_id
604 };
605
606 payload_size = sizeof(payload) / MBOX_WORD_BYTE;
607
608 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_EXPORT_CS_KEY,
609 (uint32_t *) &payload, payload_size,
610 CMD_CASUAL, resp_data, &resp_len);
611
612 if (resp_len > 0) {
613 op_status = resp_data[0] & FCS_CS_KEY_RESP_STATUS_MASK;
614 }
615
616 if (status < 0) {
617 *mbox_error = (-status) | (op_status << FCS_CS_KEY_RESP_STATUS_OFFSET);
618 return INTEL_SIP_SMC_STATUS_ERROR;
619 }
620
621 if (resp_len > 1) {
622
623 /* Export key object is start at second response data */
624 *dst_size = (resp_len - 1) * MBOX_WORD_BYTE;
625
626 for (i = 1U; i < resp_len; i++) {
627 mmio_write_32(dst_addr, resp_data[i]);
628 dst_addr += MBOX_WORD_BYTE;
629 }
630
631 flush_dcache_range(dst_addr - *dst_size, *dst_size);
632
633 } else {
634
635 /* Unexpected response, missing key object in response */
636 *mbox_error = MBOX_RET_ERROR;
637 return INTEL_SIP_SMC_STATUS_ERROR;
638 }
639
640 return INTEL_SIP_SMC_STATUS_OK;
641}
642
643int intel_fcs_remove_crypto_service_key(uint32_t session_id, uint32_t key_id,
644 uint32_t *mbox_error)
645{
646 int status;
647 uint32_t payload_size;
648 uint32_t resp_len = 1U;
649 uint32_t resp_data = 0U;
650 uint32_t op_status = 0U;
651
652 if (mbox_error == NULL) {
653 return INTEL_SIP_SMC_STATUS_REJECTED;
654 }
655
656 fcs_cs_key_payload payload = {
657 session_id,
658 RESERVED_AS_ZERO,
659 RESERVED_AS_ZERO,
660 key_id
661 };
662
663 payload_size = sizeof(payload) / MBOX_WORD_BYTE;
664
665 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_REMOVE_CS_KEY,
666 (uint32_t *) &payload, payload_size,
667 CMD_CASUAL, &resp_data, &resp_len);
668
669 if (resp_len > 0) {
670 op_status = resp_data & FCS_CS_KEY_RESP_STATUS_MASK;
671 }
672
673 if (status < 0) {
674 *mbox_error = (-status) | (op_status << FCS_CS_KEY_RESP_STATUS_OFFSET);
675 return INTEL_SIP_SMC_STATUS_ERROR;
676 }
677
678 return INTEL_SIP_SMC_STATUS_OK;
679}
680
681int intel_fcs_get_crypto_service_key_info(uint32_t session_id, uint32_t key_id,
682 uint64_t dst_addr, uint32_t *dst_size,
683 uint32_t *mbox_error)
684{
685 int status;
686 uint32_t payload_size;
687 uint32_t resp_len = FCS_CS_KEY_INFO_MAX_WORD_SIZE;
688 uint32_t op_status = 0U;
689
690 if ((dst_size == NULL) || (mbox_error == NULL)) {
691 return INTEL_SIP_SMC_STATUS_REJECTED;
692 }
693
694 if (!is_address_in_ddr_range(dst_addr, *dst_size)) {
695 return INTEL_SIP_SMC_STATUS_REJECTED;
696 }
697
698 fcs_cs_key_payload payload = {
699 session_id,
700 RESERVED_AS_ZERO,
701 RESERVED_AS_ZERO,
702 key_id
703 };
704
705 payload_size = sizeof(payload) / MBOX_WORD_BYTE;
706
707 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_GET_CS_KEY_INFO,
708 (uint32_t *) &payload, payload_size,
709 CMD_CASUAL, (uint32_t *) dst_addr, &resp_len);
710
711 if (resp_len > 0) {
712 op_status = mmio_read_32(dst_addr) &
713 FCS_CS_KEY_RESP_STATUS_MASK;
714 }
715
716 if (status < 0) {
717 *mbox_error = (-status) | (op_status << FCS_CS_KEY_RESP_STATUS_OFFSET);
718 return INTEL_SIP_SMC_STATUS_ERROR;
719 }
720
721 *dst_size = resp_len * MBOX_WORD_BYTE;
722 flush_dcache_range(dst_addr, *dst_size);
723
724 return INTEL_SIP_SMC_STATUS_OK;
725}
Sieu Mun Tangd907cc32022-05-10 17:24:05 +0800726
727int intel_fcs_get_digest_init(uint32_t session_id, uint32_t context_id,
728 uint32_t key_id, uint32_t param_size,
729 uint64_t param_data, uint32_t *mbox_error)
730{
731 return intel_fcs_crypto_service_init(session_id, context_id,
732 key_id, param_size, param_data,
733 (void *) &fcs_sha_get_digest_param,
734 mbox_error);
735}
736
737int intel_fcs_get_digest_finalize(uint32_t session_id, uint32_t context_id,
738 uint32_t src_addr, uint32_t src_size,
739 uint64_t dst_addr, uint32_t *dst_size,
740 uint32_t *mbox_error)
741{
742 int status;
743 uint32_t i;
744 uint32_t resp_len = *dst_size / MBOX_WORD_BYTE;
745 uint32_t payload[FCS_GET_DIGEST_CMD_MAX_WORD_SIZE] = {0U};
746
747 if (dst_size == NULL || mbox_error == NULL) {
748 return INTEL_SIP_SMC_STATUS_REJECTED;
749 }
750
751 if (fcs_sha_get_digest_param.session_id != session_id ||
752 fcs_sha_get_digest_param.context_id != context_id) {
753 return INTEL_SIP_SMC_STATUS_REJECTED;
754 }
755
756 /* Source data must be 8 bytes aligned */
757 if (!is_8_bytes_aligned(src_size)) {
758 return INTEL_SIP_SMC_STATUS_REJECTED;
759 }
760
761 if (!is_address_in_ddr_range(src_addr, src_size) ||
762 !is_address_in_ddr_range(dst_addr, *dst_size)) {
763 return INTEL_SIP_SMC_STATUS_REJECTED;
764 }
765
766 /* Prepare command payload */
767 i = 0;
768 /* Crypto header */
769 payload[i] = fcs_sha_get_digest_param.session_id;
770 i++;
771 payload[i] = fcs_sha_get_digest_param.context_id;
772 i++;
773 payload[i] = fcs_sha_get_digest_param.crypto_param_size
774 & FCS_CS_FIELD_SIZE_MASK;
775 payload[i] |= (FCS_CS_FIELD_FLAG_INIT | FCS_CS_FIELD_FLAG_UPDATE
776 | FCS_CS_FIELD_FLAG_FINALIZE)
777 << FCS_CS_FIELD_FLAG_OFFSET;
778 i++;
779 payload[i] = fcs_sha_get_digest_param.key_id;
780 i++;
781 /* Crypto parameters */
782 payload[i] = fcs_sha_get_digest_param.crypto_param
783 & INTEL_SIP_SMC_FCS_SHA_MODE_MASK;
784 payload[i] |= ((fcs_sha_get_digest_param.crypto_param
785 >> INTEL_SIP_SMC_FCS_DIGEST_SIZE_OFFSET)
786 & INTEL_SIP_SMC_FCS_DIGEST_SIZE_MASK)
787 << FCS_SHA_HMAC_CRYPTO_PARAM_SIZE_OFFSET;
788 i++;
789 /* Data source address and size */
790 payload[i] = src_addr;
791 i++;
792 payload[i] = src_size;
793 i++;
794
795 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_GET_DIGEST_REQ,
796 payload, i, CMD_CASUAL,
797 (uint32_t *) dst_addr, &resp_len);
798
799 memset((void *)&fcs_sha_get_digest_param, 0, sizeof(fcs_crypto_service_data));
800
801 if (status < 0) {
802 *mbox_error = -status;
803 return INTEL_SIP_SMC_STATUS_ERROR;
804 }
805
806 *dst_size = resp_len * MBOX_WORD_BYTE;
807 flush_dcache_range(dst_addr, *dst_size);
808
809 return INTEL_SIP_SMC_STATUS_OK;
810}
Sieu Mun Tang583149a2022-05-10 17:27:12 +0800811
812int intel_fcs_mac_verify_init(uint32_t session_id, uint32_t context_id,
813 uint32_t key_id, uint32_t param_size,
814 uint64_t param_data, uint32_t *mbox_error)
815{
816 return intel_fcs_crypto_service_init(session_id, context_id,
817 key_id, param_size, param_data,
818 (void *) &fcs_sha_mac_verify_param,
819 mbox_error);
820}
821
822int intel_fcs_mac_verify_finalize(uint32_t session_id, uint32_t context_id,
823 uint32_t src_addr, uint32_t src_size,
824 uint64_t dst_addr, uint32_t *dst_size,
825 uint32_t data_size, uint32_t *mbox_error)
826{
827 int status;
828 uint32_t i;
829 uint32_t resp_len = *dst_size / MBOX_WORD_BYTE;
830 uint32_t payload[FCS_MAC_VERIFY_CMD_MAX_WORD_SIZE] = {0U};
831 uintptr_t mac_offset;
832
833 if (dst_size == NULL || mbox_error == NULL) {
834 return INTEL_SIP_SMC_STATUS_REJECTED;
835 }
836
837 if (fcs_sha_mac_verify_param.session_id != session_id ||
838 fcs_sha_mac_verify_param.context_id != context_id) {
839 return INTEL_SIP_SMC_STATUS_REJECTED;
840 }
841
842 if (data_size >= src_size) {
843 return INTEL_SIP_SMC_STATUS_REJECTED;
844 }
845
846 if (!is_size_4_bytes_aligned(src_size) ||
847 !is_8_bytes_aligned(data_size)) {
848 return INTEL_SIP_SMC_STATUS_REJECTED;
849 }
850
851 if (!is_address_in_ddr_range(src_addr, src_size) ||
852 !is_address_in_ddr_range(dst_addr, *dst_size)) {
853 return INTEL_SIP_SMC_STATUS_REJECTED;
854 }
855
856 /* Prepare command payload */
857 i = 0;
858 /* Crypto header */
859 payload[i] = fcs_sha_mac_verify_param.session_id;
860 i++;
861 payload[i] = fcs_sha_mac_verify_param.context_id;
862 i++;
863 payload[i] = fcs_sha_mac_verify_param.crypto_param_size
864 & FCS_CS_FIELD_SIZE_MASK;
865 payload[i] |= (FCS_CS_FIELD_FLAG_INIT | FCS_CS_FIELD_FLAG_UPDATE
866 | FCS_CS_FIELD_FLAG_FINALIZE)
867 << FCS_CS_FIELD_FLAG_OFFSET;
868 i++;
869 payload[i] = fcs_sha_mac_verify_param.key_id;
870 i++;
871 /* Crypto parameters */
872 payload[i] = ((fcs_sha_mac_verify_param.crypto_param
873 >> INTEL_SIP_SMC_FCS_DIGEST_SIZE_OFFSET)
874 & INTEL_SIP_SMC_FCS_DIGEST_SIZE_MASK)
875 << FCS_SHA_HMAC_CRYPTO_PARAM_SIZE_OFFSET;
876 i++;
877 /* Data source address and size */
878 payload[i] = src_addr;
879 i++;
880 payload[i] = data_size;
881 i++;
882 /* Copy mac data to command */
883 mac_offset = src_addr + data_size;
884 memcpy((uint8_t *) &payload[i], (uint8_t *) mac_offset,
885 src_size - data_size);
886
887 i += (src_size - data_size) / MBOX_WORD_BYTE;
888
889 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_MAC_VERIFY_REQ,
890 payload, i, CMD_CASUAL,
891 (uint32_t *) dst_addr, &resp_len);
892
893 memset((void *)&fcs_sha_mac_verify_param, 0,
894 sizeof(fcs_crypto_service_data));
895
896 if (status < 0) {
897 *mbox_error = -status;
898 return INTEL_SIP_SMC_STATUS_ERROR;
899 }
900
901 *dst_size = resp_len * MBOX_WORD_BYTE;
902 flush_dcache_range(dst_addr, *dst_size);
903
904 return INTEL_SIP_SMC_STATUS_OK;
905}
Sieu Mun Tangb0c1d112022-05-10 17:30:00 +0800906
907int intel_fcs_aes_crypt_init(uint32_t session_id, uint32_t context_id,
908 uint32_t key_id, uint64_t param_addr,
909 uint32_t param_size, uint32_t *mbox_error)
910{
911 if (mbox_error == NULL) {
912 return INTEL_SIP_SMC_STATUS_REJECTED;
913 }
914
915 memset((void *)&fcs_aes_init_payload, 0U, sizeof(fcs_aes_init_payload));
916
917 fcs_aes_init_payload.session_id = session_id;
918 fcs_aes_init_payload.context_id = context_id;
919 fcs_aes_init_payload.param_size = param_size;
920 fcs_aes_init_payload.key_id = key_id;
921
922 memcpy((uint8_t *) fcs_aes_init_payload.crypto_param,
923 (uint8_t *) param_addr, param_size);
924
925 *mbox_error = 0;
926
927 return INTEL_SIP_SMC_STATUS_OK;
928}
929
930int intel_fcs_aes_crypt_finalize(uint32_t session_id, uint32_t context_id,
931 uint64_t src_addr, uint32_t src_size,
932 uint64_t dst_addr, uint32_t dst_size,
933 uint32_t *send_id)
934{
935 int status;
936 int i;
937 uint32_t crypto_header;
938 uint32_t fcs_aes_crypt_payload[FCS_AES_CMD_MAX_WORD_SIZE];
939
940 if (fcs_aes_init_payload.session_id != session_id ||
941 fcs_aes_init_payload.context_id != context_id) {
942 return INTEL_SIP_SMC_STATUS_REJECTED;
943 }
944
945 if ((!is_8_bytes_aligned(src_addr)) ||
946 (!is_32_bytes_aligned(src_size)) ||
947 (!is_address_in_ddr_range(src_addr, src_size))) {
948 return INTEL_SIP_SMC_STATUS_REJECTED;
949 }
950
951 if ((!is_8_bytes_aligned(dst_addr)) ||
952 (!is_32_bytes_aligned(dst_size))) {
953 return INTEL_SIP_SMC_STATUS_REJECTED;
954 }
955
956 if ((dst_size > FCS_AES_MAX_DATA_SIZE ||
957 dst_size < FCS_AES_MIN_DATA_SIZE) ||
958 (src_size > FCS_AES_MAX_DATA_SIZE ||
959 src_size < FCS_AES_MIN_DATA_SIZE)) {
960 return INTEL_SIP_SMC_STATUS_REJECTED;
961 }
962
963 crypto_header = ((FCS_CS_FIELD_FLAG_INIT |
964 FCS_CS_FIELD_FLAG_UPDATE |
965 FCS_CS_FIELD_FLAG_FINALIZE) <<
966 FCS_CS_FIELD_FLAG_OFFSET) |
967 fcs_aes_init_payload.param_size;
968 i = 0U;
969 fcs_aes_crypt_payload[i] = session_id;
970 i++;
971 fcs_aes_crypt_payload[i] = context_id;
972 i++;
973 fcs_aes_crypt_payload[i] = crypto_header;
974 i++;
975 fcs_aes_crypt_payload[i] = fcs_aes_init_payload.key_id;
976
977 i++;
978 memcpy((uint8_t *) &fcs_aes_crypt_payload[i],
979 (uint8_t *) fcs_aes_init_payload.crypto_param,
980 fcs_aes_init_payload.param_size);
981
982 i += fcs_aes_init_payload.param_size / MBOX_WORD_BYTE;
983
984 fcs_aes_crypt_payload[i] = (uint32_t) src_addr;
985 i++;
986 fcs_aes_crypt_payload[i] = src_size;
987 i++;
988 fcs_aes_crypt_payload[i] = (uint32_t) dst_addr;
989 i++;
990 fcs_aes_crypt_payload[i] = dst_size;
991 i++;
992
993 status = mailbox_send_cmd_async(send_id, MBOX_FCS_AES_CRYPT_REQ,
994 fcs_aes_crypt_payload, i,
995 CMD_INDIRECT);
996
997 memset((void *)&fcs_aes_init_payload, 0U, sizeof(fcs_aes_init_payload));
998
999 if (status < 0U) {
1000 return INTEL_SIP_SMC_STATUS_ERROR;
1001 }
1002
1003 return INTEL_SIP_SMC_STATUS_OK;
1004}