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