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