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_ecdsa_hash_sign_param; 19 static fcs_crypto_service_data fcs_ecdsa_hash_sig_verify_param; 20 static fcs_crypto_service_data fcs_sha2_data_sign_param; 21 static fcs_crypto_service_data fcs_sha2_data_sig_verify_param; 22 static fcs_crypto_service_data fcs_ecdsa_get_pubkey_param; 23 static fcs_crypto_service_data fcs_ecdh_request_param; 24 25 bool is_size_4_bytes_aligned(uint32_t size) 26 { 27 if ((size % MBOX_WORD_BYTE) != 0U) { 28 return false; 29 } else { 30 return true; 31 } 32 } 33 34 static bool is_8_bytes_aligned(uint32_t data) 35 { 36 if ((data % (MBOX_WORD_BYTE * 2U)) != 0U) { 37 return false; 38 } else { 39 return true; 40 } 41 } 42 43 static bool is_32_bytes_aligned(uint32_t data) 44 { 45 if ((data % (8U * MBOX_WORD_BYTE)) != 0U) { 46 return false; 47 } else { 48 return true; 49 } 50 } 51 52 static int intel_fcs_crypto_service_init(uint32_t session_id, 53 uint32_t context_id, uint32_t key_id, 54 uint32_t param_size, uint64_t param_data, 55 fcs_crypto_service_data *data_addr, 56 uint32_t *mbox_error) 57 { 58 if (mbox_error == NULL) { 59 return INTEL_SIP_SMC_STATUS_REJECTED; 60 } 61 62 if (param_size != 4) { 63 return INTEL_SIP_SMC_STATUS_REJECTED; 64 } 65 66 memset(data_addr, 0, sizeof(fcs_crypto_service_data)); 67 68 data_addr->session_id = session_id; 69 data_addr->context_id = context_id; 70 data_addr->key_id = key_id; 71 data_addr->crypto_param_size = param_size; 72 data_addr->crypto_param = param_data; 73 74 data_addr->is_updated = 0; 75 76 *mbox_error = 0; 77 78 return INTEL_SIP_SMC_STATUS_OK; 79 } 80 81 uint32_t intel_fcs_random_number_gen(uint64_t addr, uint64_t *ret_size, 82 uint32_t *mbox_error) 83 { 84 int status; 85 unsigned int i; 86 unsigned int resp_len = FCS_RANDOM_WORD_SIZE; 87 uint32_t random_data[FCS_RANDOM_WORD_SIZE] = {0U}; 88 89 if (!is_address_in_ddr_range(addr, FCS_RANDOM_BYTE_SIZE)) { 90 return INTEL_SIP_SMC_STATUS_REJECTED; 91 } 92 93 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_RANDOM_GEN, NULL, 0U, 94 CMD_CASUAL, random_data, &resp_len); 95 96 if (status < 0) { 97 *mbox_error = -status; 98 return INTEL_SIP_SMC_STATUS_ERROR; 99 } 100 101 if (resp_len != FCS_RANDOM_WORD_SIZE) { 102 *mbox_error = GENERIC_RESPONSE_ERROR; 103 return INTEL_SIP_SMC_STATUS_ERROR; 104 } 105 106 *ret_size = FCS_RANDOM_BYTE_SIZE; 107 108 for (i = 0U; i < FCS_RANDOM_WORD_SIZE; i++) { 109 mmio_write_32(addr, random_data[i]); 110 addr += MBOX_WORD_BYTE; 111 } 112 113 flush_dcache_range(addr - *ret_size, *ret_size); 114 115 return INTEL_SIP_SMC_STATUS_OK; 116 } 117 118 int intel_fcs_random_number_gen_ext(uint32_t session_id, uint32_t context_id, 119 uint32_t size, uint32_t *send_id) 120 { 121 int status; 122 uint32_t payload_size; 123 uint32_t crypto_header; 124 125 if (size > (FCS_RANDOM_EXT_MAX_WORD_SIZE * 126 MBOX_WORD_BYTE) || size == 0U) { 127 return INTEL_SIP_SMC_STATUS_REJECTED; 128 } 129 130 if (!is_size_4_bytes_aligned(size)) { 131 return INTEL_SIP_SMC_STATUS_REJECTED; 132 } 133 134 crypto_header = (FCS_CS_FIELD_FLAG_INIT | FCS_CS_FIELD_FLAG_FINALIZE) << 135 FCS_CS_FIELD_FLAG_OFFSET; 136 137 fcs_rng_payload payload = { 138 session_id, 139 context_id, 140 crypto_header, 141 size 142 }; 143 144 payload_size = sizeof(payload) / MBOX_WORD_BYTE; 145 146 status = mailbox_send_cmd_async(send_id, MBOX_FCS_RANDOM_GEN, 147 (uint32_t *) &payload, payload_size, 148 CMD_INDIRECT); 149 150 if (status < 0) { 151 return INTEL_SIP_SMC_STATUS_ERROR; 152 } 153 154 return INTEL_SIP_SMC_STATUS_OK; 155 } 156 157 uint32_t intel_fcs_send_cert(uint64_t addr, uint64_t size, 158 uint32_t *send_id) 159 { 160 int status; 161 162 if (!is_address_in_ddr_range(addr, size)) { 163 return INTEL_SIP_SMC_STATUS_REJECTED; 164 } 165 166 if (!is_size_4_bytes_aligned(size)) { 167 return INTEL_SIP_SMC_STATUS_REJECTED; 168 } 169 170 status = mailbox_send_cmd_async(send_id, MBOX_CMD_VAB_SRC_CERT, 171 (uint32_t *)addr, size / MBOX_WORD_BYTE, 172 CMD_DIRECT); 173 174 flush_dcache_range(addr, size); 175 176 if (status < 0) { 177 return INTEL_SIP_SMC_STATUS_ERROR; 178 } 179 180 return INTEL_SIP_SMC_STATUS_OK; 181 } 182 183 uint32_t intel_fcs_get_provision_data(uint32_t *send_id) 184 { 185 int status; 186 187 status = mailbox_send_cmd_async(send_id, MBOX_FCS_GET_PROVISION, 188 NULL, 0U, CMD_DIRECT); 189 190 if (status < 0) { 191 return INTEL_SIP_SMC_STATUS_ERROR; 192 } 193 194 return INTEL_SIP_SMC_STATUS_OK; 195 } 196 197 uint32_t intel_fcs_cntr_set_preauth(uint8_t counter_type, int32_t counter_value, 198 uint32_t test_bit, uint32_t *mbox_error) 199 { 200 int status; 201 uint32_t first_word; 202 uint32_t payload_size; 203 204 if ((test_bit != MBOX_TEST_BIT) && 205 (test_bit != 0)) { 206 return INTEL_SIP_SMC_STATUS_REJECTED; 207 } 208 209 if ((counter_type < FCS_BIG_CNTR_SEL) || 210 (counter_type > FCS_SVN_CNTR_3_SEL)) { 211 return INTEL_SIP_SMC_STATUS_REJECTED; 212 } 213 214 if ((counter_type == FCS_BIG_CNTR_SEL) && 215 (counter_value > FCS_BIG_CNTR_VAL_MAX)) { 216 return INTEL_SIP_SMC_STATUS_REJECTED; 217 } 218 219 if ((counter_type >= FCS_SVN_CNTR_0_SEL) && 220 (counter_type <= FCS_SVN_CNTR_3_SEL) && 221 (counter_value > FCS_SVN_CNTR_VAL_MAX)) { 222 return INTEL_SIP_SMC_STATUS_REJECTED; 223 } 224 225 first_word = test_bit | counter_type; 226 fcs_cntr_set_preauth_payload payload = { 227 first_word, 228 counter_value 229 }; 230 231 payload_size = sizeof(payload) / MBOX_WORD_BYTE; 232 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_CNTR_SET_PREAUTH, 233 (uint32_t *) &payload, payload_size, 234 CMD_CASUAL, NULL, NULL); 235 236 if (status < 0) { 237 *mbox_error = -status; 238 return INTEL_SIP_SMC_STATUS_ERROR; 239 } 240 241 return INTEL_SIP_SMC_STATUS_OK; 242 } 243 244 uint32_t intel_fcs_encryption(uint32_t src_addr, uint32_t src_size, 245 uint32_t dst_addr, uint32_t dst_size, uint32_t *send_id) 246 { 247 int status; 248 uint32_t load_size; 249 250 fcs_encrypt_payload payload = { 251 FCS_ENCRYPTION_DATA_0, 252 src_addr, 253 src_size, 254 dst_addr, 255 dst_size }; 256 load_size = sizeof(payload) / MBOX_WORD_BYTE; 257 258 if (!is_address_in_ddr_range(src_addr, src_size) || 259 !is_address_in_ddr_range(dst_addr, dst_size)) { 260 return INTEL_SIP_SMC_STATUS_REJECTED; 261 } 262 263 if (!is_size_4_bytes_aligned(src_size)) { 264 return INTEL_SIP_SMC_STATUS_REJECTED; 265 } 266 267 status = mailbox_send_cmd_async(send_id, MBOX_FCS_ENCRYPT_REQ, 268 (uint32_t *) &payload, load_size, 269 CMD_INDIRECT); 270 inv_dcache_range(dst_addr, dst_size); 271 272 if (status < 0) { 273 return INTEL_SIP_SMC_STATUS_REJECTED; 274 } 275 276 return INTEL_SIP_SMC_STATUS_OK; 277 } 278 279 uint32_t intel_fcs_decryption(uint32_t src_addr, uint32_t src_size, 280 uint32_t dst_addr, uint32_t dst_size, uint32_t *send_id) 281 { 282 int status; 283 uint32_t load_size; 284 uintptr_t id_offset; 285 286 id_offset = src_addr + FCS_OWNER_ID_OFFSET; 287 fcs_decrypt_payload payload = { 288 FCS_DECRYPTION_DATA_0, 289 {mmio_read_32(id_offset), 290 mmio_read_32(id_offset + MBOX_WORD_BYTE)}, 291 src_addr, 292 src_size, 293 dst_addr, 294 dst_size }; 295 load_size = sizeof(payload) / MBOX_WORD_BYTE; 296 297 if (!is_address_in_ddr_range(src_addr, src_size) || 298 !is_address_in_ddr_range(dst_addr, dst_size)) { 299 return INTEL_SIP_SMC_STATUS_REJECTED; 300 } 301 302 if (!is_size_4_bytes_aligned(src_size)) { 303 return INTEL_SIP_SMC_STATUS_REJECTED; 304 } 305 306 status = mailbox_send_cmd_async(send_id, MBOX_FCS_DECRYPT_REQ, 307 (uint32_t *) &payload, load_size, 308 CMD_INDIRECT); 309 inv_dcache_range(dst_addr, dst_size); 310 311 if (status < 0) { 312 return INTEL_SIP_SMC_STATUS_REJECTED; 313 } 314 315 return INTEL_SIP_SMC_STATUS_OK; 316 } 317 318 int intel_fcs_encryption_ext(uint32_t session_id, uint32_t context_id, 319 uint32_t src_addr, uint32_t src_size, 320 uint32_t dst_addr, uint32_t *dst_size, uint32_t *mbox_error) 321 { 322 int status; 323 uint32_t payload_size; 324 uint32_t resp_len = FCS_CRYPTION_RESP_WORD_SIZE; 325 uint32_t resp_data[FCS_CRYPTION_RESP_WORD_SIZE] = {0U}; 326 327 if ((dst_size == NULL) || (mbox_error == NULL)) { 328 return INTEL_SIP_SMC_STATUS_REJECTED; 329 } 330 331 if (!is_address_in_ddr_range(src_addr, src_size) || 332 !is_address_in_ddr_range(dst_addr, *dst_size)) { 333 return INTEL_SIP_SMC_STATUS_REJECTED; 334 } 335 336 if (!is_size_4_bytes_aligned(src_size)) { 337 return INTEL_SIP_SMC_STATUS_REJECTED; 338 } 339 340 fcs_encrypt_ext_payload payload = { 341 session_id, 342 context_id, 343 FCS_CRYPTION_CRYPTO_HEADER, 344 src_addr, 345 src_size, 346 dst_addr, 347 *dst_size 348 }; 349 350 payload_size = sizeof(payload) / MBOX_WORD_BYTE; 351 352 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_ENCRYPT_REQ, 353 (uint32_t *) &payload, payload_size, 354 CMD_CASUAL, resp_data, &resp_len); 355 356 if (status < 0) { 357 *mbox_error = -status; 358 return INTEL_SIP_SMC_STATUS_ERROR; 359 } 360 361 if (resp_len != FCS_CRYPTION_RESP_WORD_SIZE) { 362 *mbox_error = MBOX_RET_ERROR; 363 return INTEL_SIP_SMC_STATUS_ERROR; 364 } 365 366 *dst_size = resp_data[FCS_CRYPTION_RESP_SIZE_OFFSET]; 367 inv_dcache_range(dst_addr, *dst_size); 368 369 return INTEL_SIP_SMC_STATUS_OK; 370 } 371 372 int intel_fcs_decryption_ext(uint32_t session_id, uint32_t context_id, 373 uint32_t src_addr, uint32_t src_size, 374 uint32_t dst_addr, uint32_t *dst_size, uint32_t *mbox_error) 375 { 376 int status; 377 uintptr_t id_offset; 378 uint32_t payload_size; 379 uint32_t resp_len = FCS_CRYPTION_RESP_WORD_SIZE; 380 uint32_t resp_data[FCS_CRYPTION_RESP_WORD_SIZE] = {0U}; 381 382 if ((dst_size == NULL) || (mbox_error == NULL)) { 383 return INTEL_SIP_SMC_STATUS_REJECTED; 384 } 385 386 if (!is_address_in_ddr_range(src_addr, src_size) || 387 !is_address_in_ddr_range(dst_addr, *dst_size)) { 388 return INTEL_SIP_SMC_STATUS_REJECTED; 389 } 390 391 if (!is_size_4_bytes_aligned(src_size)) { 392 return INTEL_SIP_SMC_STATUS_REJECTED; 393 } 394 395 id_offset = src_addr + FCS_OWNER_ID_OFFSET; 396 fcs_decrypt_ext_payload payload = { 397 session_id, 398 context_id, 399 FCS_CRYPTION_CRYPTO_HEADER, 400 {mmio_read_32(id_offset), 401 mmio_read_32(id_offset + MBOX_WORD_BYTE)}, 402 src_addr, 403 src_size, 404 dst_addr, 405 *dst_size 406 }; 407 408 payload_size = sizeof(payload) / MBOX_WORD_BYTE; 409 410 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_DECRYPT_REQ, 411 (uint32_t *) &payload, payload_size, 412 CMD_CASUAL, resp_data, &resp_len); 413 414 if (status < 0) { 415 *mbox_error = -status; 416 return INTEL_SIP_SMC_STATUS_ERROR; 417 } 418 419 if (resp_len != FCS_CRYPTION_RESP_WORD_SIZE) { 420 *mbox_error = MBOX_RET_ERROR; 421 return INTEL_SIP_SMC_STATUS_ERROR; 422 } 423 424 *dst_size = resp_data[FCS_CRYPTION_RESP_SIZE_OFFSET]; 425 inv_dcache_range(dst_addr, *dst_size); 426 427 return INTEL_SIP_SMC_STATUS_OK; 428 } 429 430 int intel_fcs_sigma_teardown(uint32_t session_id, uint32_t *mbox_error) 431 { 432 int status; 433 434 if ((session_id != PSGSIGMA_SESSION_ID_ONE) && 435 (session_id != PSGSIGMA_UNKNOWN_SESSION)) { 436 return INTEL_SIP_SMC_STATUS_REJECTED; 437 } 438 439 psgsigma_teardown_msg message = { 440 RESERVED_AS_ZERO, 441 PSGSIGMA_TEARDOWN_MAGIC, 442 session_id 443 }; 444 445 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_PSG_SIGMA_TEARDOWN, 446 (uint32_t *) &message, sizeof(message) / MBOX_WORD_BYTE, 447 CMD_CASUAL, NULL, NULL); 448 449 if (status < 0) { 450 *mbox_error = -status; 451 return INTEL_SIP_SMC_STATUS_ERROR; 452 } 453 454 return INTEL_SIP_SMC_STATUS_OK; 455 } 456 457 int intel_fcs_chip_id(uint32_t *id_low, uint32_t *id_high, uint32_t *mbox_error) 458 { 459 int status; 460 uint32_t load_size; 461 uint32_t chip_id[2]; 462 463 load_size = sizeof(chip_id) / MBOX_WORD_BYTE; 464 465 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_CMD_GET_CHIPID, NULL, 466 0U, CMD_CASUAL, (uint32_t *) chip_id, &load_size); 467 468 if (status < 0) { 469 *mbox_error = -status; 470 return INTEL_SIP_SMC_STATUS_ERROR; 471 } 472 473 *id_low = chip_id[0]; 474 *id_high = chip_id[1]; 475 476 return INTEL_SIP_SMC_STATUS_OK; 477 } 478 479 int intel_fcs_attestation_subkey(uint64_t src_addr, uint32_t src_size, 480 uint64_t dst_addr, uint32_t *dst_size, uint32_t *mbox_error) 481 { 482 int status; 483 uint32_t send_size = src_size / MBOX_WORD_BYTE; 484 uint32_t ret_size = *dst_size / MBOX_WORD_BYTE; 485 486 487 if (!is_address_in_ddr_range(src_addr, src_size) || 488 !is_address_in_ddr_range(dst_addr, *dst_size)) { 489 return INTEL_SIP_SMC_STATUS_REJECTED; 490 } 491 492 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_ATTESTATION_SUBKEY, 493 (uint32_t *) src_addr, send_size, CMD_CASUAL, 494 (uint32_t *) dst_addr, &ret_size); 495 496 if (status < 0) { 497 *mbox_error = -status; 498 return INTEL_SIP_SMC_STATUS_ERROR; 499 } 500 501 *dst_size = ret_size * MBOX_WORD_BYTE; 502 flush_dcache_range(dst_addr, *dst_size); 503 504 return INTEL_SIP_SMC_STATUS_OK; 505 } 506 507 int intel_fcs_get_measurement(uint64_t src_addr, uint32_t src_size, 508 uint64_t dst_addr, uint32_t *dst_size, uint32_t *mbox_error) 509 { 510 int status; 511 uint32_t send_size = src_size / MBOX_WORD_BYTE; 512 uint32_t ret_size = *dst_size / MBOX_WORD_BYTE; 513 514 if (!is_address_in_ddr_range(src_addr, src_size) || 515 !is_address_in_ddr_range(dst_addr, *dst_size)) { 516 return INTEL_SIP_SMC_STATUS_REJECTED; 517 } 518 519 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_GET_MEASUREMENT, 520 (uint32_t *) src_addr, send_size, CMD_CASUAL, 521 (uint32_t *) dst_addr, &ret_size); 522 523 if (status < 0) { 524 *mbox_error = -status; 525 return INTEL_SIP_SMC_STATUS_ERROR; 526 } 527 528 *dst_size = ret_size * MBOX_WORD_BYTE; 529 flush_dcache_range(dst_addr, *dst_size); 530 531 return INTEL_SIP_SMC_STATUS_OK; 532 } 533 534 uint32_t intel_fcs_get_rom_patch_sha384(uint64_t addr, uint64_t *ret_size, 535 uint32_t *mbox_error) 536 { 537 int status; 538 unsigned int resp_len = FCS_SHA384_WORD_SIZE; 539 540 if (!is_address_in_ddr_range(addr, FCS_SHA384_BYTE_SIZE)) { 541 return INTEL_SIP_SMC_STATUS_REJECTED; 542 } 543 544 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_GET_ROM_PATCH_SHA384, NULL, 0U, 545 CMD_CASUAL, (uint32_t *) addr, &resp_len); 546 547 if (status < 0) { 548 *mbox_error = -status; 549 return INTEL_SIP_SMC_STATUS_ERROR; 550 } 551 552 if (resp_len != FCS_SHA384_WORD_SIZE) { 553 *mbox_error = GENERIC_RESPONSE_ERROR; 554 return INTEL_SIP_SMC_STATUS_ERROR; 555 } 556 557 *ret_size = FCS_SHA384_BYTE_SIZE; 558 559 flush_dcache_range(addr, *ret_size); 560 561 return INTEL_SIP_SMC_STATUS_OK; 562 } 563 564 int intel_fcs_get_attestation_cert(uint32_t cert_request, uint64_t dst_addr, 565 uint32_t *dst_size, uint32_t *mbox_error) 566 { 567 int status; 568 uint32_t ret_size = *dst_size / MBOX_WORD_BYTE; 569 570 if (mbox_error == NULL) { 571 return INTEL_SIP_SMC_STATUS_REJECTED; 572 } 573 574 if (cert_request < FCS_ATTEST_FIRMWARE_CERT || 575 cert_request > FCS_ATTEST_CERT_MAX_REQ_PARAM) { 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_ATTEST_FIRMWARE_CERT || 608 cert_request > FCS_ATTEST_CERT_MAX_REQ_PARAM) { 609 return INTEL_SIP_SMC_STATUS_REJECTED; 610 } 611 612 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_CREATE_CERT_ON_RELOAD, 613 (uint32_t *) &cert_request, 1U, CMD_CASUAL, 614 NULL, NULL); 615 616 if (status < 0) { 617 *mbox_error = -status; 618 return INTEL_SIP_SMC_STATUS_ERROR; 619 } 620 621 return INTEL_SIP_SMC_STATUS_OK; 622 } 623 624 int intel_fcs_open_crypto_service_session(uint32_t *session_id, 625 uint32_t *mbox_error) 626 { 627 int status; 628 uint32_t resp_len = 1U; 629 630 if ((session_id == NULL) || (mbox_error == NULL)) { 631 return INTEL_SIP_SMC_STATUS_REJECTED; 632 } 633 634 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_OPEN_CS_SESSION, 635 NULL, 0U, CMD_CASUAL, session_id, &resp_len); 636 637 if (status < 0) { 638 *mbox_error = -status; 639 return INTEL_SIP_SMC_STATUS_ERROR; 640 } 641 642 return INTEL_SIP_SMC_STATUS_OK; 643 } 644 645 int intel_fcs_close_crypto_service_session(uint32_t session_id, 646 uint32_t *mbox_error) 647 { 648 int status; 649 650 if (mbox_error == NULL) { 651 return INTEL_SIP_SMC_STATUS_REJECTED; 652 } 653 654 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_CLOSE_CS_SESSION, 655 &session_id, 1U, CMD_CASUAL, NULL, NULL); 656 657 if (status < 0) { 658 *mbox_error = -status; 659 return INTEL_SIP_SMC_STATUS_ERROR; 660 } 661 662 return INTEL_SIP_SMC_STATUS_OK; 663 } 664 665 int intel_fcs_import_crypto_service_key(uint64_t src_addr, uint32_t src_size, 666 uint32_t *send_id) 667 { 668 int status; 669 670 if (src_size > (FCS_CS_KEY_OBJ_MAX_WORD_SIZE * 671 MBOX_WORD_BYTE)) { 672 return INTEL_SIP_SMC_STATUS_REJECTED; 673 } 674 675 if (!is_address_in_ddr_range(src_addr, src_size)) { 676 return INTEL_SIP_SMC_STATUS_REJECTED; 677 } 678 679 status = mailbox_send_cmd_async(send_id, MBOX_FCS_IMPORT_CS_KEY, 680 (uint32_t *)src_addr, src_size / MBOX_WORD_BYTE, 681 CMD_INDIRECT); 682 683 if (status < 0) { 684 return INTEL_SIP_SMC_STATUS_ERROR; 685 } 686 687 return INTEL_SIP_SMC_STATUS_OK; 688 } 689 690 int intel_fcs_export_crypto_service_key(uint32_t session_id, uint32_t key_id, 691 uint64_t dst_addr, uint32_t *dst_size, 692 uint32_t *mbox_error) 693 { 694 int status; 695 uint32_t i; 696 uint32_t payload_size; 697 uint32_t resp_len = FCS_CS_KEY_OBJ_MAX_WORD_SIZE; 698 uint32_t resp_data[FCS_CS_KEY_OBJ_MAX_WORD_SIZE] = {0U}; 699 uint32_t op_status = 0U; 700 701 if ((dst_size == NULL) || (mbox_error == NULL)) { 702 return INTEL_SIP_SMC_STATUS_REJECTED; 703 } 704 705 if (!is_address_in_ddr_range(dst_addr, *dst_size)) { 706 return INTEL_SIP_SMC_STATUS_REJECTED; 707 } 708 709 fcs_cs_key_payload payload = { 710 session_id, 711 RESERVED_AS_ZERO, 712 RESERVED_AS_ZERO, 713 key_id 714 }; 715 716 payload_size = sizeof(payload) / MBOX_WORD_BYTE; 717 718 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_EXPORT_CS_KEY, 719 (uint32_t *) &payload, payload_size, 720 CMD_CASUAL, resp_data, &resp_len); 721 722 if (resp_len > 0) { 723 op_status = resp_data[0] & FCS_CS_KEY_RESP_STATUS_MASK; 724 } 725 726 if (status < 0) { 727 *mbox_error = (-status) | (op_status << FCS_CS_KEY_RESP_STATUS_OFFSET); 728 return INTEL_SIP_SMC_STATUS_ERROR; 729 } 730 731 if (resp_len > 1) { 732 733 /* Export key object is start at second response data */ 734 *dst_size = (resp_len - 1) * MBOX_WORD_BYTE; 735 736 for (i = 1U; i < resp_len; i++) { 737 mmio_write_32(dst_addr, resp_data[i]); 738 dst_addr += MBOX_WORD_BYTE; 739 } 740 741 flush_dcache_range(dst_addr - *dst_size, *dst_size); 742 743 } else { 744 745 /* Unexpected response, missing key object in response */ 746 *mbox_error = MBOX_RET_ERROR; 747 return INTEL_SIP_SMC_STATUS_ERROR; 748 } 749 750 return INTEL_SIP_SMC_STATUS_OK; 751 } 752 753 int intel_fcs_remove_crypto_service_key(uint32_t session_id, uint32_t key_id, 754 uint32_t *mbox_error) 755 { 756 int status; 757 uint32_t payload_size; 758 uint32_t resp_len = 1U; 759 uint32_t resp_data = 0U; 760 uint32_t op_status = 0U; 761 762 if (mbox_error == NULL) { 763 return INTEL_SIP_SMC_STATUS_REJECTED; 764 } 765 766 fcs_cs_key_payload payload = { 767 session_id, 768 RESERVED_AS_ZERO, 769 RESERVED_AS_ZERO, 770 key_id 771 }; 772 773 payload_size = sizeof(payload) / MBOX_WORD_BYTE; 774 775 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_REMOVE_CS_KEY, 776 (uint32_t *) &payload, payload_size, 777 CMD_CASUAL, &resp_data, &resp_len); 778 779 if (resp_len > 0) { 780 op_status = resp_data & FCS_CS_KEY_RESP_STATUS_MASK; 781 } 782 783 if (status < 0) { 784 *mbox_error = (-status) | (op_status << FCS_CS_KEY_RESP_STATUS_OFFSET); 785 return INTEL_SIP_SMC_STATUS_ERROR; 786 } 787 788 return INTEL_SIP_SMC_STATUS_OK; 789 } 790 791 int intel_fcs_get_crypto_service_key_info(uint32_t session_id, uint32_t key_id, 792 uint64_t dst_addr, uint32_t *dst_size, 793 uint32_t *mbox_error) 794 { 795 int status; 796 uint32_t payload_size; 797 uint32_t resp_len = FCS_CS_KEY_INFO_MAX_WORD_SIZE; 798 uint32_t op_status = 0U; 799 800 if ((dst_size == NULL) || (mbox_error == NULL)) { 801 return INTEL_SIP_SMC_STATUS_REJECTED; 802 } 803 804 if (!is_address_in_ddr_range(dst_addr, *dst_size)) { 805 return INTEL_SIP_SMC_STATUS_REJECTED; 806 } 807 808 fcs_cs_key_payload payload = { 809 session_id, 810 RESERVED_AS_ZERO, 811 RESERVED_AS_ZERO, 812 key_id 813 }; 814 815 payload_size = sizeof(payload) / MBOX_WORD_BYTE; 816 817 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_GET_CS_KEY_INFO, 818 (uint32_t *) &payload, payload_size, 819 CMD_CASUAL, (uint32_t *) dst_addr, &resp_len); 820 821 if (resp_len > 0) { 822 op_status = mmio_read_32(dst_addr) & 823 FCS_CS_KEY_RESP_STATUS_MASK; 824 } 825 826 if (status < 0) { 827 *mbox_error = (-status) | (op_status << FCS_CS_KEY_RESP_STATUS_OFFSET); 828 return INTEL_SIP_SMC_STATUS_ERROR; 829 } 830 831 *dst_size = resp_len * MBOX_WORD_BYTE; 832 flush_dcache_range(dst_addr, *dst_size); 833 834 return INTEL_SIP_SMC_STATUS_OK; 835 } 836 837 int intel_fcs_get_digest_init(uint32_t session_id, uint32_t context_id, 838 uint32_t key_id, uint32_t param_size, 839 uint64_t param_data, uint32_t *mbox_error) 840 { 841 return intel_fcs_crypto_service_init(session_id, context_id, 842 key_id, param_size, param_data, 843 (void *) &fcs_sha_get_digest_param, 844 mbox_error); 845 } 846 847 int intel_fcs_get_digest_update_finalize(uint32_t session_id, 848 uint32_t context_id, uint32_t src_addr, 849 uint32_t src_size, uint64_t dst_addr, 850 uint32_t *dst_size, uint8_t is_finalised, 851 uint32_t *mbox_error) 852 { 853 int status; 854 uint32_t i; 855 uint32_t flag; 856 uint32_t crypto_header; 857 uint32_t resp_len; 858 uint32_t payload[FCS_GET_DIGEST_CMD_MAX_WORD_SIZE] = {0U}; 859 860 if (dst_size == NULL || mbox_error == NULL) { 861 return INTEL_SIP_SMC_STATUS_REJECTED; 862 } 863 864 if (fcs_sha_get_digest_param.session_id != session_id || 865 fcs_sha_get_digest_param.context_id != context_id) { 866 return INTEL_SIP_SMC_STATUS_REJECTED; 867 } 868 869 /* Source data must be 8 bytes aligned */ 870 if (!is_8_bytes_aligned(src_size)) { 871 return INTEL_SIP_SMC_STATUS_REJECTED; 872 } 873 874 if (!is_address_in_ddr_range(src_addr, src_size) || 875 !is_address_in_ddr_range(dst_addr, *dst_size)) { 876 return INTEL_SIP_SMC_STATUS_REJECTED; 877 } 878 879 resp_len = *dst_size / MBOX_WORD_BYTE; 880 881 /* Prepare crypto header */ 882 flag = 0; 883 884 if (fcs_sha_get_digest_param.is_updated) { 885 fcs_sha_get_digest_param.crypto_param_size = 0; 886 } else { 887 flag |= FCS_CS_FIELD_FLAG_INIT; 888 } 889 890 if (is_finalised != 0U) { 891 flag |= FCS_CS_FIELD_FLAG_FINALIZE; 892 } else { 893 flag |= FCS_CS_FIELD_FLAG_UPDATE; 894 fcs_sha_get_digest_param.is_updated = 1; 895 } 896 897 crypto_header = ((flag << FCS_CS_FIELD_FLAG_OFFSET) | 898 (fcs_sha_get_digest_param.crypto_param_size & 899 FCS_CS_FIELD_SIZE_MASK)); 900 901 /* Prepare command payload */ 902 i = 0; 903 payload[i] = fcs_sha_get_digest_param.session_id; 904 i++; 905 payload[i] = fcs_sha_get_digest_param.context_id; 906 i++; 907 payload[i] = crypto_header; 908 i++; 909 910 if ((crypto_header >> FCS_CS_FIELD_FLAG_OFFSET) & 911 FCS_CS_FIELD_FLAG_INIT) { 912 payload[i] = fcs_sha_get_digest_param.key_id; 913 i++; 914 /* Crypto parameters */ 915 payload[i] = fcs_sha_get_digest_param.crypto_param 916 & INTEL_SIP_SMC_FCS_SHA_MODE_MASK; 917 payload[i] |= ((fcs_sha_get_digest_param.crypto_param 918 >> INTEL_SIP_SMC_FCS_DIGEST_SIZE_OFFSET) 919 & INTEL_SIP_SMC_FCS_DIGEST_SIZE_MASK) 920 << FCS_SHA_HMAC_CRYPTO_PARAM_SIZE_OFFSET; 921 i++; 922 } 923 /* Data source address and size */ 924 payload[i] = src_addr; 925 i++; 926 payload[i] = src_size; 927 i++; 928 929 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_GET_DIGEST_REQ, 930 payload, i, CMD_CASUAL, 931 (uint32_t *) dst_addr, &resp_len); 932 933 if (is_finalised != 0U) { 934 memset((void *)&fcs_sha_get_digest_param, 0, 935 sizeof(fcs_crypto_service_data)); 936 } 937 938 if (status < 0) { 939 *mbox_error = -status; 940 return INTEL_SIP_SMC_STATUS_ERROR; 941 } 942 943 *dst_size = resp_len * MBOX_WORD_BYTE; 944 flush_dcache_range(dst_addr, *dst_size); 945 946 return INTEL_SIP_SMC_STATUS_OK; 947 } 948 949 int intel_fcs_get_digest_smmu_update_finalize(uint32_t session_id, 950 uint32_t context_id, uint32_t src_addr, 951 uint32_t src_size, uint64_t dst_addr, 952 uint32_t *dst_size, uint8_t is_finalised, 953 uint32_t *mbox_error, uint32_t *send_id) 954 { 955 int status; 956 uint32_t i; 957 uint32_t flag; 958 uint32_t crypto_header; 959 uint32_t resp_len; 960 uint32_t payload[FCS_GET_DIGEST_CMD_MAX_WORD_SIZE] = {0U}; 961 962 /* Source data must be 8 bytes aligned */ 963 if (dst_size == NULL || mbox_error == NULL || 964 !is_8_bytes_aligned(src_size)) { 965 return INTEL_SIP_SMC_STATUS_REJECTED; 966 } 967 968 if (fcs_sha_get_digest_param.session_id != session_id || 969 fcs_sha_get_digest_param.context_id != context_id) { 970 return INTEL_SIP_SMC_STATUS_REJECTED; 971 } 972 973 if (!is_address_in_ddr_range(src_addr, src_size) || 974 !is_address_in_ddr_range(dst_addr, *dst_size)) { 975 return INTEL_SIP_SMC_STATUS_REJECTED; 976 } 977 978 resp_len = *dst_size / MBOX_WORD_BYTE; 979 980 /* Prepare crypto header */ 981 flag = 0; 982 983 if (fcs_sha_get_digest_param.is_updated) { 984 fcs_sha_get_digest_param.crypto_param_size = 0; 985 } else { 986 flag |= FCS_CS_FIELD_FLAG_INIT; 987 } 988 989 if (is_finalised != 0U) { 990 flag |= FCS_CS_FIELD_FLAG_FINALIZE; 991 } else { 992 flag |= FCS_CS_FIELD_FLAG_UPDATE; 993 fcs_sha_get_digest_param.is_updated = 1; 994 } 995 996 crypto_header = ((flag << FCS_CS_FIELD_FLAG_OFFSET) | 997 (fcs_sha_get_digest_param.crypto_param_size & 998 FCS_CS_FIELD_SIZE_MASK)); 999 1000 /* Prepare command payload */ 1001 i = 0; 1002 payload[i] = fcs_sha_get_digest_param.session_id; 1003 i++; 1004 payload[i] = fcs_sha_get_digest_param.context_id; 1005 i++; 1006 payload[i] = crypto_header; 1007 i++; 1008 1009 if ((crypto_header >> FCS_CS_FIELD_FLAG_OFFSET) & 1010 FCS_CS_FIELD_FLAG_INIT) { 1011 payload[i] = fcs_sha_get_digest_param.key_id; 1012 i++; 1013 /* Crypto parameters */ 1014 payload[i] = fcs_sha_get_digest_param.crypto_param 1015 & INTEL_SIP_SMC_FCS_SHA_MODE_MASK; 1016 payload[i] |= ((fcs_sha_get_digest_param.crypto_param 1017 >> INTEL_SIP_SMC_FCS_DIGEST_SIZE_OFFSET) 1018 & INTEL_SIP_SMC_FCS_DIGEST_SIZE_MASK) 1019 << FCS_SHA_HMAC_CRYPTO_PARAM_SIZE_OFFSET; 1020 i++; 1021 } 1022 /* Data source address and size */ 1023 payload[i] = src_addr; 1024 i++; 1025 payload[i] = src_size; 1026 i++; 1027 1028 status = mailbox_send_cmd_async(send_id, MBOX_FCS_GET_DIGEST_REQ, 1029 payload, i, CMD_INDIRECT); 1030 1031 if (is_finalised != 0U) { 1032 memset((void *)&fcs_sha_get_digest_param, 0, 1033 sizeof(fcs_crypto_service_data)); 1034 } 1035 1036 if (status < 0) { 1037 *mbox_error = -status; 1038 return INTEL_SIP_SMC_STATUS_ERROR; 1039 } 1040 1041 *dst_size = resp_len * MBOX_WORD_BYTE; 1042 flush_dcache_range(dst_addr, *dst_size); 1043 1044 return INTEL_SIP_SMC_STATUS_OK; 1045 } 1046 1047 int intel_fcs_mac_verify_init(uint32_t session_id, uint32_t context_id, 1048 uint32_t key_id, uint32_t param_size, 1049 uint64_t param_data, uint32_t *mbox_error) 1050 { 1051 return intel_fcs_crypto_service_init(session_id, context_id, 1052 key_id, param_size, param_data, 1053 (void *) &fcs_sha_mac_verify_param, 1054 mbox_error); 1055 } 1056 1057 int intel_fcs_mac_verify_update_finalize(uint32_t session_id, 1058 uint32_t context_id, uint32_t src_addr, 1059 uint32_t src_size, uint64_t dst_addr, 1060 uint32_t *dst_size, uint32_t data_size, 1061 uint8_t is_finalised, uint32_t *mbox_error) 1062 { 1063 int status; 1064 uint32_t i; 1065 uint32_t flag; 1066 uint32_t crypto_header; 1067 uint32_t resp_len; 1068 uint32_t payload[FCS_MAC_VERIFY_CMD_MAX_WORD_SIZE] = {0U}; 1069 uintptr_t mac_offset; 1070 1071 if (dst_size == NULL || mbox_error == NULL) { 1072 return INTEL_SIP_SMC_STATUS_REJECTED; 1073 } 1074 1075 if (fcs_sha_mac_verify_param.session_id != session_id || 1076 fcs_sha_mac_verify_param.context_id != context_id) { 1077 return INTEL_SIP_SMC_STATUS_REJECTED; 1078 } 1079 1080 if (data_size > src_size) { 1081 return INTEL_SIP_SMC_STATUS_REJECTED; 1082 } 1083 1084 if (!is_size_4_bytes_aligned(src_size) || 1085 !is_8_bytes_aligned(data_size)) { 1086 return INTEL_SIP_SMC_STATUS_REJECTED; 1087 } 1088 1089 if (!is_address_in_ddr_range(src_addr, src_size) || 1090 !is_address_in_ddr_range(dst_addr, *dst_size)) { 1091 return INTEL_SIP_SMC_STATUS_REJECTED; 1092 } 1093 1094 resp_len = *dst_size / MBOX_WORD_BYTE; 1095 1096 /* Prepare crypto header */ 1097 flag = 0; 1098 1099 if (fcs_sha_mac_verify_param.is_updated) { 1100 fcs_sha_mac_verify_param.crypto_param_size = 0; 1101 } else { 1102 flag |= FCS_CS_FIELD_FLAG_INIT; 1103 } 1104 1105 if (is_finalised) { 1106 flag |= FCS_CS_FIELD_FLAG_FINALIZE; 1107 } else { 1108 flag |= FCS_CS_FIELD_FLAG_UPDATE; 1109 fcs_sha_mac_verify_param.is_updated = 1; 1110 } 1111 1112 crypto_header = ((flag << FCS_CS_FIELD_FLAG_OFFSET) | 1113 (fcs_sha_mac_verify_param.crypto_param_size & 1114 FCS_CS_FIELD_SIZE_MASK)); 1115 1116 /* Prepare command payload */ 1117 i = 0; 1118 payload[i] = fcs_sha_mac_verify_param.session_id; 1119 i++; 1120 payload[i] = fcs_sha_mac_verify_param.context_id; 1121 i++; 1122 payload[i] = crypto_header; 1123 i++; 1124 1125 if ((crypto_header >> FCS_CS_FIELD_FLAG_OFFSET) & 1126 FCS_CS_FIELD_FLAG_INIT) { 1127 payload[i] = fcs_sha_mac_verify_param.key_id; 1128 i++; 1129 /* Crypto parameters */ 1130 payload[i] = ((fcs_sha_mac_verify_param.crypto_param 1131 >> INTEL_SIP_SMC_FCS_DIGEST_SIZE_OFFSET) 1132 & INTEL_SIP_SMC_FCS_DIGEST_SIZE_MASK) 1133 << FCS_SHA_HMAC_CRYPTO_PARAM_SIZE_OFFSET; 1134 i++; 1135 } 1136 /* Data source address and size */ 1137 payload[i] = src_addr; 1138 i++; 1139 payload[i] = data_size; 1140 i++; 1141 1142 if ((crypto_header >> FCS_CS_FIELD_FLAG_OFFSET) & 1143 FCS_CS_FIELD_FLAG_FINALIZE) { 1144 /* Copy mac data to command */ 1145 mac_offset = src_addr + data_size; 1146 memcpy((uint8_t *) &payload[i], (uint8_t *) mac_offset, 1147 src_size - data_size); 1148 1149 i += (src_size - data_size) / MBOX_WORD_BYTE; 1150 } 1151 1152 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_MAC_VERIFY_REQ, 1153 payload, i, CMD_CASUAL, 1154 (uint32_t *) dst_addr, &resp_len); 1155 1156 if (is_finalised) { 1157 memset((void *)&fcs_sha_mac_verify_param, 0, 1158 sizeof(fcs_crypto_service_data)); 1159 } 1160 1161 if (status < 0) { 1162 *mbox_error = -status; 1163 return INTEL_SIP_SMC_STATUS_ERROR; 1164 } 1165 1166 *dst_size = resp_len * MBOX_WORD_BYTE; 1167 flush_dcache_range(dst_addr, *dst_size); 1168 1169 return INTEL_SIP_SMC_STATUS_OK; 1170 } 1171 1172 int intel_fcs_mac_verify_smmu_update_finalize(uint32_t session_id, 1173 uint32_t context_id, uint32_t src_addr, 1174 uint32_t src_size, uint64_t dst_addr, 1175 uint32_t *dst_size, uint32_t data_size, 1176 uint8_t is_finalised, uint32_t *mbox_error, 1177 uint32_t *send_id) 1178 { 1179 int status; 1180 uint32_t i; 1181 uint32_t flag; 1182 uint32_t crypto_header; 1183 uint32_t resp_len; 1184 uint32_t payload[FCS_MAC_VERIFY_CMD_MAX_WORD_SIZE] = {0U}; 1185 uintptr_t mac_offset; 1186 1187 /* 1188 * Source data must be 4 bytes aligned 1189 * User data must be 8 bytes aligned 1190 */ 1191 if (dst_size == NULL || mbox_error == NULL || 1192 !is_size_4_bytes_aligned(src_size) || 1193 !is_8_bytes_aligned(data_size)) { 1194 return INTEL_SIP_SMC_STATUS_REJECTED; 1195 } 1196 1197 if (data_size > src_size) { 1198 return INTEL_SIP_SMC_STATUS_REJECTED; 1199 } 1200 1201 if (fcs_sha_mac_verify_param.session_id != session_id || 1202 fcs_sha_mac_verify_param.context_id != context_id) { 1203 return INTEL_SIP_SMC_STATUS_REJECTED; 1204 } 1205 1206 if (!is_address_in_ddr_range(src_addr, src_size) || 1207 !is_address_in_ddr_range(dst_addr, *dst_size)) { 1208 return INTEL_SIP_SMC_STATUS_REJECTED; 1209 } 1210 1211 resp_len = *dst_size / MBOX_WORD_BYTE; 1212 1213 /* Prepare crypto header */ 1214 flag = 0; 1215 1216 if (fcs_sha_mac_verify_param.is_updated) { 1217 fcs_sha_mac_verify_param.crypto_param_size = 0; 1218 } else { 1219 flag |= FCS_CS_FIELD_FLAG_INIT; 1220 } 1221 1222 if (is_finalised) { 1223 flag |= FCS_CS_FIELD_FLAG_FINALIZE; 1224 } else { 1225 flag |= FCS_CS_FIELD_FLAG_UPDATE; 1226 fcs_sha_mac_verify_param.is_updated = 1; 1227 } 1228 1229 crypto_header = ((flag << FCS_CS_FIELD_FLAG_OFFSET) | 1230 (fcs_sha_mac_verify_param.crypto_param_size & 1231 FCS_CS_FIELD_SIZE_MASK)); 1232 1233 /* Prepare command payload */ 1234 i = 0; 1235 payload[i] = fcs_sha_mac_verify_param.session_id; 1236 i++; 1237 payload[i] = fcs_sha_mac_verify_param.context_id; 1238 i++; 1239 payload[i] = crypto_header; 1240 i++; 1241 1242 if ((crypto_header >> FCS_CS_FIELD_FLAG_OFFSET) & 1243 FCS_CS_FIELD_FLAG_INIT) { 1244 payload[i] = fcs_sha_mac_verify_param.key_id; 1245 i++; 1246 /* Crypto parameters */ 1247 payload[i] = ((fcs_sha_mac_verify_param.crypto_param 1248 >> INTEL_SIP_SMC_FCS_DIGEST_SIZE_OFFSET) 1249 & INTEL_SIP_SMC_FCS_DIGEST_SIZE_MASK) 1250 << FCS_SHA_HMAC_CRYPTO_PARAM_SIZE_OFFSET; 1251 i++; 1252 } 1253 /* Data source address and size */ 1254 payload[i] = src_addr; 1255 i++; 1256 payload[i] = data_size; 1257 i++; 1258 1259 if ((crypto_header >> FCS_CS_FIELD_FLAG_OFFSET) & 1260 FCS_CS_FIELD_FLAG_FINALIZE) { 1261 /* Copy mac data to command 1262 * Using dst_addr (physical address) to store mac_offset 1263 * mac_offset = MAC data 1264 */ 1265 mac_offset = dst_addr; 1266 memcpy((uint8_t *) &payload[i], (uint8_t *) mac_offset, 1267 src_size - data_size); 1268 1269 memset((void *)&dst_addr, 0, sizeof(dst_size)); 1270 1271 i += (src_size - data_size) / MBOX_WORD_BYTE; 1272 } 1273 1274 status = mailbox_send_cmd_async(send_id, MBOX_FCS_MAC_VERIFY_REQ, 1275 payload, i, CMD_INDIRECT); 1276 1277 if (is_finalised) { 1278 memset((void *)&fcs_sha_mac_verify_param, 0, 1279 sizeof(fcs_crypto_service_data)); 1280 } 1281 1282 if (status < 0) { 1283 *mbox_error = -status; 1284 return INTEL_SIP_SMC_STATUS_ERROR; 1285 } 1286 1287 *dst_size = resp_len * MBOX_WORD_BYTE; 1288 flush_dcache_range(dst_addr, *dst_size); 1289 1290 return INTEL_SIP_SMC_STATUS_OK; 1291 } 1292 1293 int intel_fcs_ecdsa_hash_sign_init(uint32_t session_id, uint32_t context_id, 1294 uint32_t key_id, uint32_t param_size, 1295 uint64_t param_data, uint32_t *mbox_error) 1296 { 1297 return intel_fcs_crypto_service_init(session_id, context_id, 1298 key_id, param_size, param_data, 1299 (void *) &fcs_ecdsa_hash_sign_param, 1300 mbox_error); 1301 } 1302 1303 int intel_fcs_ecdsa_hash_sign_finalize(uint32_t session_id, uint32_t context_id, 1304 uint32_t src_addr, uint32_t src_size, 1305 uint64_t dst_addr, uint32_t *dst_size, 1306 uint32_t *mbox_error) 1307 { 1308 int status; 1309 uint32_t i; 1310 uint32_t payload[FCS_ECDSA_HASH_SIGN_CMD_MAX_WORD_SIZE] = {0U}; 1311 uint32_t resp_len; 1312 uintptr_t hash_data_addr; 1313 1314 if ((dst_size == NULL) || (mbox_error == NULL)) { 1315 return INTEL_SIP_SMC_STATUS_REJECTED; 1316 } 1317 1318 if (fcs_ecdsa_hash_sign_param.session_id != session_id || 1319 fcs_ecdsa_hash_sign_param.context_id != context_id) { 1320 return INTEL_SIP_SMC_STATUS_REJECTED; 1321 } 1322 1323 if (!is_address_in_ddr_range(src_addr, src_size) || 1324 !is_address_in_ddr_range(dst_addr, *dst_size)) { 1325 return INTEL_SIP_SMC_STATUS_REJECTED; 1326 } 1327 1328 resp_len = *dst_size / MBOX_WORD_BYTE; 1329 1330 /* Prepare command payload */ 1331 /* Crypto header */ 1332 i = 0; 1333 payload[i] = fcs_ecdsa_hash_sign_param.session_id; 1334 i++; 1335 payload[i] = fcs_ecdsa_hash_sign_param.context_id; 1336 1337 i++; 1338 payload[i] = fcs_ecdsa_hash_sign_param.crypto_param_size 1339 & FCS_CS_FIELD_SIZE_MASK; 1340 payload[i] |= (FCS_CS_FIELD_FLAG_INIT | FCS_CS_FIELD_FLAG_UPDATE 1341 | FCS_CS_FIELD_FLAG_FINALIZE) 1342 << FCS_CS_FIELD_FLAG_OFFSET; 1343 i++; 1344 payload[i] = fcs_ecdsa_hash_sign_param.key_id; 1345 1346 /* Crypto parameters */ 1347 i++; 1348 payload[i] = fcs_ecdsa_hash_sign_param.crypto_param 1349 & INTEL_SIP_SMC_FCS_ECC_ALGO_MASK; 1350 1351 /* Hash Data */ 1352 i++; 1353 hash_data_addr = src_addr; 1354 memcpy((uint8_t *) &payload[i], (uint8_t *) hash_data_addr, 1355 src_size); 1356 1357 i += src_size / MBOX_WORD_BYTE; 1358 1359 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_ECDSA_HASH_SIGN_REQ, 1360 payload, i, CMD_CASUAL, (uint32_t *) dst_addr, 1361 &resp_len); 1362 1363 memset((void *) &fcs_ecdsa_hash_sign_param, 1364 0, sizeof(fcs_crypto_service_data)); 1365 1366 if (status < 0) { 1367 *mbox_error = -status; 1368 return INTEL_SIP_SMC_STATUS_ERROR; 1369 } 1370 1371 *dst_size = resp_len * MBOX_WORD_BYTE; 1372 flush_dcache_range(dst_addr, *dst_size); 1373 1374 return INTEL_SIP_SMC_STATUS_OK; 1375 } 1376 1377 int intel_fcs_ecdsa_hash_sig_verify_init(uint32_t session_id, uint32_t context_id, 1378 uint32_t key_id, uint32_t param_size, 1379 uint64_t param_data, uint32_t *mbox_error) 1380 { 1381 return intel_fcs_crypto_service_init(session_id, context_id, 1382 key_id, param_size, param_data, 1383 (void *) &fcs_ecdsa_hash_sig_verify_param, 1384 mbox_error); 1385 } 1386 1387 int intel_fcs_ecdsa_hash_sig_verify_finalize(uint32_t session_id, uint32_t context_id, 1388 uint32_t src_addr, uint32_t src_size, 1389 uint64_t dst_addr, uint32_t *dst_size, 1390 uint32_t *mbox_error) 1391 { 1392 int status; 1393 uint32_t i = 0; 1394 uint32_t payload[FCS_ECDSA_HASH_SIG_VERIFY_CMD_MAX_WORD_SIZE] = {0U}; 1395 uint32_t resp_len; 1396 uintptr_t hash_sig_pubkey_addr; 1397 1398 if ((dst_size == NULL) || (mbox_error == NULL)) { 1399 return INTEL_SIP_SMC_STATUS_REJECTED; 1400 } 1401 1402 if (fcs_ecdsa_hash_sig_verify_param.session_id != session_id || 1403 fcs_ecdsa_hash_sig_verify_param.context_id != context_id) { 1404 return INTEL_SIP_SMC_STATUS_REJECTED; 1405 } 1406 1407 if (!is_address_in_ddr_range(src_addr, src_size) || 1408 !is_address_in_ddr_range(dst_addr, *dst_size)) { 1409 return INTEL_SIP_SMC_STATUS_REJECTED; 1410 } 1411 1412 resp_len = *dst_size / MBOX_WORD_BYTE; 1413 1414 /* Prepare command payload */ 1415 /* Crypto header */ 1416 i = 0; 1417 payload[i] = fcs_ecdsa_hash_sig_verify_param.session_id; 1418 1419 i++; 1420 payload[i] = fcs_ecdsa_hash_sig_verify_param.context_id; 1421 1422 i++; 1423 payload[i] = fcs_ecdsa_hash_sig_verify_param.crypto_param_size 1424 & FCS_CS_FIELD_SIZE_MASK; 1425 payload[i] |= (FCS_CS_FIELD_FLAG_INIT | FCS_CS_FIELD_FLAG_UPDATE 1426 | FCS_CS_FIELD_FLAG_FINALIZE) 1427 << FCS_CS_FIELD_FLAG_OFFSET; 1428 1429 i++; 1430 payload[i] = fcs_ecdsa_hash_sig_verify_param.key_id; 1431 1432 /* Crypto parameters */ 1433 i++; 1434 payload[i] = fcs_ecdsa_hash_sig_verify_param.crypto_param 1435 & INTEL_SIP_SMC_FCS_ECC_ALGO_MASK; 1436 1437 /* Hash Data Word, Signature Data Word and Public Key Data word */ 1438 i++; 1439 hash_sig_pubkey_addr = src_addr; 1440 memcpy((uint8_t *) &payload[i], 1441 (uint8_t *) hash_sig_pubkey_addr, src_size); 1442 1443 i += (src_size / MBOX_WORD_BYTE); 1444 1445 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_ECDSA_HASH_SIG_VERIFY, 1446 payload, i, CMD_CASUAL, (uint32_t *) dst_addr, 1447 &resp_len); 1448 1449 memset((void *)&fcs_ecdsa_hash_sig_verify_param, 1450 0, sizeof(fcs_crypto_service_data)); 1451 1452 if (status < 0) { 1453 *mbox_error = -status; 1454 return INTEL_SIP_SMC_STATUS_ERROR; 1455 } 1456 1457 *dst_size = resp_len * MBOX_WORD_BYTE; 1458 flush_dcache_range(dst_addr, *dst_size); 1459 1460 return INTEL_SIP_SMC_STATUS_OK; 1461 } 1462 1463 int intel_fcs_ecdsa_sha2_data_sign_init(uint32_t session_id, 1464 uint32_t context_id, uint32_t key_id, 1465 uint32_t param_size, uint64_t param_data, 1466 uint32_t *mbox_error) 1467 { 1468 return intel_fcs_crypto_service_init(session_id, context_id, 1469 key_id, param_size, param_data, 1470 (void *) &fcs_sha2_data_sign_param, 1471 mbox_error); 1472 } 1473 1474 int intel_fcs_ecdsa_sha2_data_sign_update_finalize(uint32_t session_id, 1475 uint32_t context_id, uint32_t src_addr, 1476 uint32_t src_size, uint64_t dst_addr, 1477 uint32_t *dst_size, uint8_t is_finalised, 1478 uint32_t *mbox_error) 1479 { 1480 int status; 1481 int i; 1482 uint32_t flag; 1483 uint32_t crypto_header; 1484 uint32_t payload[FCS_ECDSA_SHA2_DATA_SIGN_CMD_MAX_WORD_SIZE] = {0U}; 1485 uint32_t resp_len; 1486 1487 if ((dst_size == NULL) || (mbox_error == NULL)) { 1488 return INTEL_SIP_SMC_STATUS_REJECTED; 1489 } 1490 1491 if (fcs_sha2_data_sign_param.session_id != session_id || 1492 fcs_sha2_data_sign_param.context_id != context_id) { 1493 return INTEL_SIP_SMC_STATUS_REJECTED; 1494 } 1495 1496 /* Source data must be 8 bytes aligned */ 1497 if (!is_8_bytes_aligned(src_size)) { 1498 return INTEL_SIP_SMC_STATUS_REJECTED; 1499 } 1500 1501 if (!is_address_in_ddr_range(src_addr, src_size) || 1502 !is_address_in_ddr_range(dst_addr, *dst_size)) { 1503 return INTEL_SIP_SMC_STATUS_REJECTED; 1504 } 1505 1506 resp_len = *dst_size / MBOX_WORD_BYTE; 1507 1508 /* Prepare crypto header */ 1509 flag = 0; 1510 if (fcs_sha2_data_sign_param.is_updated) { 1511 fcs_sha2_data_sign_param.crypto_param_size = 0; 1512 } else { 1513 flag |= FCS_CS_FIELD_FLAG_INIT; 1514 } 1515 1516 if (is_finalised != 0U) { 1517 flag |= FCS_CS_FIELD_FLAG_FINALIZE; 1518 } else { 1519 flag |= FCS_CS_FIELD_FLAG_UPDATE; 1520 fcs_sha2_data_sign_param.is_updated = 1; 1521 } 1522 crypto_header = (flag << FCS_CS_FIELD_FLAG_OFFSET) | 1523 fcs_sha2_data_sign_param.crypto_param_size; 1524 1525 /* Prepare command payload */ 1526 i = 0; 1527 payload[i] = fcs_sha2_data_sign_param.session_id; 1528 i++; 1529 payload[i] = fcs_sha2_data_sign_param.context_id; 1530 i++; 1531 payload[i] = crypto_header; 1532 i++; 1533 1534 if ((crypto_header >> FCS_CS_FIELD_FLAG_OFFSET) & 1535 FCS_CS_FIELD_FLAG_INIT) { 1536 payload[i] = fcs_sha2_data_sign_param.key_id; 1537 /* Crypto parameters */ 1538 i++; 1539 payload[i] = fcs_sha2_data_sign_param.crypto_param 1540 & INTEL_SIP_SMC_FCS_ECC_ALGO_MASK; 1541 i++; 1542 } 1543 1544 /* Data source address and size */ 1545 payload[i] = src_addr; 1546 i++; 1547 payload[i] = src_size; 1548 i++; 1549 status = mailbox_send_cmd(MBOX_JOB_ID, 1550 MBOX_FCS_ECDSA_SHA2_DATA_SIGN_REQ, payload, 1551 i, CMD_CASUAL, (uint32_t *) dst_addr, 1552 &resp_len); 1553 1554 if (is_finalised != 0U) { 1555 memset((void *)&fcs_sha2_data_sign_param, 0, 1556 sizeof(fcs_crypto_service_data)); 1557 } 1558 1559 if (status < 0) { 1560 *mbox_error = -status; 1561 return INTEL_SIP_SMC_STATUS_ERROR; 1562 } 1563 1564 *dst_size = resp_len * MBOX_WORD_BYTE; 1565 flush_dcache_range(dst_addr, *dst_size); 1566 1567 return INTEL_SIP_SMC_STATUS_OK; 1568 } 1569 1570 int intel_fcs_ecdsa_sha2_data_sign_smmu_update_finalize(uint32_t session_id, 1571 uint32_t context_id, uint32_t src_addr, 1572 uint32_t src_size, uint64_t dst_addr, 1573 uint32_t *dst_size, uint8_t is_finalised, 1574 uint32_t *mbox_error, uint32_t *send_id) 1575 { 1576 int status; 1577 int i; 1578 uint32_t flag; 1579 uint32_t crypto_header; 1580 uint32_t payload[FCS_ECDSA_SHA2_DATA_SIGN_CMD_MAX_WORD_SIZE] = {0U}; 1581 uint32_t resp_len; 1582 1583 /* Source data must be 8 bytes aligned */ 1584 if ((dst_size == NULL) || (mbox_error == NULL || 1585 !is_8_bytes_aligned(src_size))) { 1586 return INTEL_SIP_SMC_STATUS_REJECTED; 1587 } 1588 1589 if (fcs_sha2_data_sign_param.session_id != session_id || 1590 fcs_sha2_data_sign_param.context_id != context_id) { 1591 return INTEL_SIP_SMC_STATUS_REJECTED; 1592 } 1593 1594 if (!is_address_in_ddr_range(src_addr, src_size) || 1595 !is_address_in_ddr_range(dst_addr, *dst_size)) { 1596 return INTEL_SIP_SMC_STATUS_REJECTED; 1597 } 1598 1599 resp_len = *dst_size / MBOX_WORD_BYTE; 1600 1601 /* Prepare crypto header */ 1602 flag = 0; 1603 if (fcs_sha2_data_sign_param.is_updated) { 1604 fcs_sha2_data_sign_param.crypto_param_size = 0; 1605 } else { 1606 flag |= FCS_CS_FIELD_FLAG_INIT; 1607 } 1608 1609 if (is_finalised != 0U) { 1610 flag |= FCS_CS_FIELD_FLAG_FINALIZE; 1611 } else { 1612 flag |= FCS_CS_FIELD_FLAG_UPDATE; 1613 fcs_sha2_data_sign_param.is_updated = 1; 1614 } 1615 crypto_header = (flag << FCS_CS_FIELD_FLAG_OFFSET) | 1616 fcs_sha2_data_sign_param.crypto_param_size; 1617 1618 /* Prepare command payload */ 1619 i = 0; 1620 payload[i] = fcs_sha2_data_sign_param.session_id; 1621 i++; 1622 payload[i] = fcs_sha2_data_sign_param.context_id; 1623 i++; 1624 payload[i] = crypto_header; 1625 i++; 1626 1627 if ((crypto_header >> FCS_CS_FIELD_FLAG_OFFSET) & 1628 FCS_CS_FIELD_FLAG_INIT) { 1629 payload[i] = fcs_sha2_data_sign_param.key_id; 1630 /* Crypto parameters */ 1631 i++; 1632 payload[i] = fcs_sha2_data_sign_param.crypto_param 1633 & INTEL_SIP_SMC_FCS_ECC_ALGO_MASK; 1634 i++; 1635 } 1636 1637 /* Data source address and size */ 1638 payload[i] = src_addr; 1639 i++; 1640 payload[i] = src_size; 1641 i++; 1642 1643 status = mailbox_send_cmd_async(send_id, 1644 MBOX_FCS_ECDSA_SHA2_DATA_SIGN_REQ, 1645 payload, i, CMD_INDIRECT); 1646 1647 if (is_finalised != 0U) { 1648 memset((void *)&fcs_sha2_data_sign_param, 0, 1649 sizeof(fcs_crypto_service_data)); 1650 } 1651 1652 if (status < 0) { 1653 *mbox_error = -status; 1654 return INTEL_SIP_SMC_STATUS_ERROR; 1655 } 1656 1657 *dst_size = resp_len * MBOX_WORD_BYTE; 1658 flush_dcache_range(dst_addr, *dst_size); 1659 1660 return INTEL_SIP_SMC_STATUS_OK; 1661 } 1662 1663 int intel_fcs_ecdsa_sha2_data_sig_verify_init(uint32_t session_id, 1664 uint32_t context_id, uint32_t key_id, 1665 uint32_t param_size, uint64_t param_data, 1666 uint32_t *mbox_error) 1667 { 1668 return intel_fcs_crypto_service_init(session_id, context_id, 1669 key_id, param_size, param_data, 1670 (void *) &fcs_sha2_data_sig_verify_param, 1671 mbox_error); 1672 } 1673 1674 int intel_fcs_ecdsa_sha2_data_sig_verify_update_finalize(uint32_t session_id, 1675 uint32_t context_id, uint32_t src_addr, 1676 uint32_t src_size, uint64_t dst_addr, 1677 uint32_t *dst_size, uint32_t data_size, 1678 uint8_t is_finalised, uint32_t *mbox_error) 1679 { 1680 int status; 1681 uint32_t i; 1682 uint32_t flag; 1683 uint32_t crypto_header; 1684 uint32_t payload[FCS_ECDSA_SHA2_DATA_SIG_VERIFY_CMD_MAX_WORD_SIZE] = {0U}; 1685 uint32_t resp_len; 1686 uintptr_t sig_pubkey_offset; 1687 1688 if ((dst_size == NULL) || (mbox_error == NULL)) { 1689 return INTEL_SIP_SMC_STATUS_REJECTED; 1690 } 1691 1692 if (fcs_sha2_data_sig_verify_param.session_id != session_id || 1693 fcs_sha2_data_sig_verify_param.context_id != context_id) { 1694 return INTEL_SIP_SMC_STATUS_REJECTED; 1695 } 1696 1697 if (!is_size_4_bytes_aligned(src_size)) { 1698 return INTEL_SIP_SMC_STATUS_REJECTED; 1699 } 1700 1701 if (!is_8_bytes_aligned(data_size) || 1702 !is_8_bytes_aligned(src_addr)) { 1703 return INTEL_SIP_SMC_STATUS_REJECTED; 1704 } 1705 1706 if (!is_address_in_ddr_range(src_addr, src_size) || 1707 !is_address_in_ddr_range(dst_addr, *dst_size)) { 1708 return INTEL_SIP_SMC_STATUS_REJECTED; 1709 } 1710 1711 resp_len = *dst_size / MBOX_WORD_BYTE; 1712 1713 /* Prepare crypto header */ 1714 flag = 0; 1715 if (fcs_sha2_data_sig_verify_param.is_updated) 1716 fcs_sha2_data_sig_verify_param.crypto_param_size = 0; 1717 else 1718 flag |= FCS_CS_FIELD_FLAG_INIT; 1719 1720 if (is_finalised != 0U) 1721 flag |= FCS_CS_FIELD_FLAG_FINALIZE; 1722 else { 1723 flag |= FCS_CS_FIELD_FLAG_UPDATE; 1724 fcs_sha2_data_sig_verify_param.is_updated = 1; 1725 } 1726 crypto_header = (flag << FCS_CS_FIELD_FLAG_OFFSET) | 1727 fcs_sha2_data_sig_verify_param.crypto_param_size; 1728 1729 /* Prepare command payload */ 1730 i = 0; 1731 payload[i] = fcs_sha2_data_sig_verify_param.session_id; 1732 i++; 1733 payload[i] = fcs_sha2_data_sig_verify_param.context_id; 1734 i++; 1735 payload[i] = crypto_header; 1736 i++; 1737 1738 if ((crypto_header >> FCS_CS_FIELD_FLAG_OFFSET) & 1739 FCS_CS_FIELD_FLAG_INIT) { 1740 payload[i] = fcs_sha2_data_sig_verify_param.key_id; 1741 i++; 1742 /* Crypto parameters */ 1743 payload[i] = fcs_sha2_data_sig_verify_param.crypto_param 1744 & INTEL_SIP_SMC_FCS_ECC_ALGO_MASK; 1745 i++; 1746 } 1747 1748 /* Data source address and size */ 1749 payload[i] = src_addr; 1750 i++; 1751 payload[i] = data_size; 1752 i++; 1753 1754 if ((crypto_header >> FCS_CS_FIELD_FLAG_OFFSET) & 1755 FCS_CS_FIELD_FLAG_FINALIZE) { 1756 /* Signature + Public Key Data */ 1757 sig_pubkey_offset = src_addr + data_size; 1758 memcpy((uint8_t *) &payload[i], (uint8_t *) sig_pubkey_offset, 1759 src_size - data_size); 1760 1761 i += (src_size - data_size) / MBOX_WORD_BYTE; 1762 } 1763 1764 status = mailbox_send_cmd(MBOX_JOB_ID, 1765 MBOX_FCS_ECDSA_SHA2_DATA_SIGN_VERIFY, payload, i, 1766 CMD_CASUAL, (uint32_t *) dst_addr, &resp_len); 1767 1768 if (is_finalised != 0U) { 1769 memset((void *) &fcs_sha2_data_sig_verify_param, 0, 1770 sizeof(fcs_crypto_service_data)); 1771 } 1772 1773 if (status < 0) { 1774 *mbox_error = -status; 1775 return INTEL_SIP_SMC_STATUS_ERROR; 1776 } 1777 1778 *dst_size = resp_len * MBOX_WORD_BYTE; 1779 flush_dcache_range(dst_addr, *dst_size); 1780 1781 return INTEL_SIP_SMC_STATUS_OK; 1782 } 1783 1784 int intel_fcs_ecdsa_sha2_data_sig_verify_smmu_update_finalize(uint32_t session_id, 1785 uint32_t context_id, uint32_t src_addr, 1786 uint32_t src_size, uint64_t dst_addr, 1787 uint32_t *dst_size, uint32_t data_size, 1788 uint8_t is_finalised, uint32_t *mbox_error, 1789 uint32_t *send_id) 1790 { 1791 int status; 1792 uint32_t i; 1793 uint32_t flag; 1794 uint32_t crypto_header; 1795 uint32_t payload[FCS_ECDSA_SHA2_DATA_SIG_VERIFY_CMD_MAX_WORD_SIZE] = {0U}; 1796 uint32_t resp_len; 1797 uintptr_t sig_pubkey_offset; 1798 1799 /* 1800 * Source data must be 4 bytes aligned 1801 * Source addrress must be 8 bytes aligned 1802 * User data must be 8 bytes aligned 1803 */ 1804 if ((dst_size == NULL) || (mbox_error == NULL) || 1805 !is_size_4_bytes_aligned(src_size) || 1806 !is_8_bytes_aligned(src_addr) || 1807 !is_8_bytes_aligned(data_size)) { 1808 return INTEL_SIP_SMC_STATUS_REJECTED; 1809 } 1810 1811 if (fcs_sha2_data_sig_verify_param.session_id != session_id || 1812 fcs_sha2_data_sig_verify_param.context_id != context_id) { 1813 return INTEL_SIP_SMC_STATUS_REJECTED; 1814 } 1815 1816 if (!is_address_in_ddr_range(src_addr, src_size) || 1817 !is_address_in_ddr_range(dst_addr, *dst_size)) { 1818 return INTEL_SIP_SMC_STATUS_REJECTED; 1819 } 1820 1821 resp_len = *dst_size / MBOX_WORD_BYTE; 1822 1823 /* Prepare crypto header */ 1824 flag = 0; 1825 if (fcs_sha2_data_sig_verify_param.is_updated) 1826 fcs_sha2_data_sig_verify_param.crypto_param_size = 0; 1827 else 1828 flag |= FCS_CS_FIELD_FLAG_INIT; 1829 1830 if (is_finalised != 0U) 1831 flag |= FCS_CS_FIELD_FLAG_FINALIZE; 1832 else { 1833 flag |= FCS_CS_FIELD_FLAG_UPDATE; 1834 fcs_sha2_data_sig_verify_param.is_updated = 1; 1835 } 1836 crypto_header = (flag << FCS_CS_FIELD_FLAG_OFFSET) | 1837 fcs_sha2_data_sig_verify_param.crypto_param_size; 1838 1839 /* Prepare command payload */ 1840 i = 0; 1841 payload[i] = fcs_sha2_data_sig_verify_param.session_id; 1842 i++; 1843 payload[i] = fcs_sha2_data_sig_verify_param.context_id; 1844 i++; 1845 payload[i] = crypto_header; 1846 i++; 1847 1848 if ((crypto_header >> FCS_CS_FIELD_FLAG_OFFSET) & 1849 FCS_CS_FIELD_FLAG_INIT) { 1850 payload[i] = fcs_sha2_data_sig_verify_param.key_id; 1851 i++; 1852 /* Crypto parameters */ 1853 payload[i] = fcs_sha2_data_sig_verify_param.crypto_param 1854 & INTEL_SIP_SMC_FCS_ECC_ALGO_MASK; 1855 i++; 1856 } 1857 1858 /* Data source address and size */ 1859 payload[i] = src_addr; 1860 i++; 1861 payload[i] = data_size; 1862 i++; 1863 1864 if ((crypto_header >> FCS_CS_FIELD_FLAG_OFFSET) & 1865 FCS_CS_FIELD_FLAG_FINALIZE) { 1866 /* Copy mac data to command 1867 * Using dst_addr (physical address) to store sig_pubkey_offset 1868 * sig_pubkey_offset is Signature + Public Key Data 1869 */ 1870 sig_pubkey_offset = dst_addr; 1871 memcpy((uint8_t *) &payload[i], (uint8_t *) sig_pubkey_offset, 1872 src_size - data_size); 1873 1874 memset((void *)&dst_addr, 0, sizeof(dst_size)); 1875 1876 i += (src_size - data_size) / MBOX_WORD_BYTE; 1877 } 1878 1879 status = mailbox_send_cmd_async(send_id, 1880 MBOX_FCS_ECDSA_SHA2_DATA_SIGN_VERIFY, 1881 payload, i, CMD_INDIRECT); 1882 1883 if (is_finalised != 0U) { 1884 memset((void *) &fcs_sha2_data_sig_verify_param, 0, 1885 sizeof(fcs_crypto_service_data)); 1886 } 1887 1888 if (status < 0) { 1889 *mbox_error = -status; 1890 return INTEL_SIP_SMC_STATUS_ERROR; 1891 } 1892 1893 *dst_size = resp_len * MBOX_WORD_BYTE; 1894 flush_dcache_range(dst_addr, *dst_size); 1895 1896 return INTEL_SIP_SMC_STATUS_OK; 1897 } 1898 1899 int intel_fcs_ecdsa_get_pubkey_init(uint32_t session_id, uint32_t context_id, 1900 uint32_t key_id, uint32_t param_size, 1901 uint64_t param_data, uint32_t *mbox_error) 1902 { 1903 return intel_fcs_crypto_service_init(session_id, context_id, 1904 key_id, param_size, param_data, 1905 (void *) &fcs_ecdsa_get_pubkey_param, 1906 mbox_error); 1907 } 1908 1909 int intel_fcs_ecdsa_get_pubkey_finalize(uint32_t session_id, uint32_t context_id, 1910 uint64_t dst_addr, uint32_t *dst_size, 1911 uint32_t *mbox_error) 1912 { 1913 int status; 1914 int i; 1915 uint32_t crypto_header; 1916 uint32_t ret_size; 1917 uint32_t payload[FCS_ECDSA_GET_PUBKEY_MAX_WORD_SIZE] = {0U}; 1918 1919 if ((dst_size == NULL) || (mbox_error == NULL)) { 1920 return INTEL_SIP_SMC_STATUS_REJECTED; 1921 } 1922 1923 if (fcs_ecdsa_get_pubkey_param.session_id != session_id || 1924 fcs_ecdsa_get_pubkey_param.context_id != context_id) { 1925 return INTEL_SIP_SMC_STATUS_REJECTED; 1926 } 1927 1928 ret_size = *dst_size / MBOX_WORD_BYTE; 1929 1930 crypto_header = ((FCS_CS_FIELD_FLAG_INIT | 1931 FCS_CS_FIELD_FLAG_UPDATE | 1932 FCS_CS_FIELD_FLAG_FINALIZE) << 1933 FCS_CS_FIELD_FLAG_OFFSET) | 1934 fcs_ecdsa_get_pubkey_param.crypto_param_size; 1935 i = 0; 1936 /* Prepare command payload */ 1937 payload[i] = session_id; 1938 i++; 1939 payload[i] = context_id; 1940 i++; 1941 payload[i] = crypto_header; 1942 i++; 1943 payload[i] = fcs_ecdsa_get_pubkey_param.key_id; 1944 i++; 1945 payload[i] = (uint32_t) fcs_ecdsa_get_pubkey_param.crypto_param & 1946 INTEL_SIP_SMC_FCS_ECC_ALGO_MASK; 1947 i++; 1948 1949 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_ECDSA_GET_PUBKEY, 1950 payload, i, CMD_CASUAL, 1951 (uint32_t *) dst_addr, &ret_size); 1952 1953 memset((void *) &fcs_ecdsa_get_pubkey_param, 0, 1954 sizeof(fcs_crypto_service_data)); 1955 1956 if (status < 0) { 1957 *mbox_error = -status; 1958 return INTEL_SIP_SMC_STATUS_ERROR; 1959 } 1960 1961 *dst_size = ret_size * MBOX_WORD_BYTE; 1962 flush_dcache_range(dst_addr, *dst_size); 1963 1964 return INTEL_SIP_SMC_STATUS_OK; 1965 } 1966 1967 int intel_fcs_ecdh_request_init(uint32_t session_id, uint32_t context_id, 1968 uint32_t key_id, uint32_t param_size, 1969 uint64_t param_data, uint32_t *mbox_error) 1970 { 1971 return intel_fcs_crypto_service_init(session_id, context_id, 1972 key_id, param_size, param_data, 1973 (void *) &fcs_ecdh_request_param, 1974 mbox_error); 1975 } 1976 1977 int intel_fcs_ecdh_request_finalize(uint32_t session_id, uint32_t context_id, 1978 uint32_t src_addr, uint32_t src_size, 1979 uint64_t dst_addr, uint32_t *dst_size, 1980 uint32_t *mbox_error) 1981 { 1982 int status; 1983 uint32_t i; 1984 uint32_t payload[FCS_ECDH_REQUEST_CMD_MAX_WORD_SIZE] = {0U}; 1985 uint32_t resp_len; 1986 uintptr_t pubkey; 1987 1988 if ((dst_size == NULL) || (mbox_error == NULL)) { 1989 return INTEL_SIP_SMC_STATUS_REJECTED; 1990 } 1991 1992 if (fcs_ecdh_request_param.session_id != session_id || 1993 fcs_ecdh_request_param.context_id != context_id) { 1994 return INTEL_SIP_SMC_STATUS_REJECTED; 1995 } 1996 1997 if (!is_address_in_ddr_range(src_addr, src_size) || 1998 !is_address_in_ddr_range(dst_addr, *dst_size)) { 1999 return INTEL_SIP_SMC_STATUS_REJECTED; 2000 } 2001 2002 resp_len = *dst_size / MBOX_WORD_BYTE; 2003 2004 /* Prepare command payload */ 2005 i = 0; 2006 /* Crypto header */ 2007 payload[i] = fcs_ecdh_request_param.session_id; 2008 i++; 2009 payload[i] = fcs_ecdh_request_param.context_id; 2010 i++; 2011 payload[i] = fcs_ecdh_request_param.crypto_param_size 2012 & FCS_CS_FIELD_SIZE_MASK; 2013 payload[i] |= (FCS_CS_FIELD_FLAG_INIT | FCS_CS_FIELD_FLAG_UPDATE 2014 | FCS_CS_FIELD_FLAG_FINALIZE) 2015 << FCS_CS_FIELD_FLAG_OFFSET; 2016 i++; 2017 payload[i] = fcs_ecdh_request_param.key_id; 2018 i++; 2019 /* Crypto parameters */ 2020 payload[i] = fcs_ecdh_request_param.crypto_param 2021 & INTEL_SIP_SMC_FCS_ECC_ALGO_MASK; 2022 i++; 2023 /* Public key data */ 2024 pubkey = src_addr; 2025 memcpy((uint8_t *) &payload[i], (uint8_t *) pubkey, src_size); 2026 i += src_size / MBOX_WORD_BYTE; 2027 2028 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_ECDH_REQUEST, 2029 payload, i, CMD_CASUAL, (uint32_t *) dst_addr, 2030 &resp_len); 2031 2032 memset((void *)&fcs_ecdh_request_param, 0, 2033 sizeof(fcs_crypto_service_data)); 2034 2035 if (status < 0) { 2036 *mbox_error = -status; 2037 return INTEL_SIP_SMC_STATUS_ERROR; 2038 } 2039 2040 *dst_size = resp_len * MBOX_WORD_BYTE; 2041 flush_dcache_range(dst_addr, *dst_size); 2042 2043 return INTEL_SIP_SMC_STATUS_OK; 2044 } 2045 2046 int intel_fcs_aes_crypt_init(uint32_t session_id, uint32_t context_id, 2047 uint32_t key_id, uint64_t param_addr, 2048 uint32_t param_size, uint32_t *mbox_error) 2049 { 2050 if (mbox_error == NULL) { 2051 return INTEL_SIP_SMC_STATUS_REJECTED; 2052 } 2053 2054 memset((void *)&fcs_aes_init_payload, 0U, sizeof(fcs_aes_init_payload)); 2055 2056 fcs_aes_init_payload.session_id = session_id; 2057 fcs_aes_init_payload.context_id = context_id; 2058 fcs_aes_init_payload.param_size = param_size; 2059 fcs_aes_init_payload.key_id = key_id; 2060 2061 memcpy((uint8_t *) fcs_aes_init_payload.crypto_param, 2062 (uint8_t *) param_addr, param_size); 2063 2064 fcs_aes_init_payload.is_updated = 0; 2065 2066 *mbox_error = 0; 2067 2068 return INTEL_SIP_SMC_STATUS_OK; 2069 } 2070 2071 int intel_fcs_aes_crypt_update_finalize(uint32_t session_id, 2072 uint32_t context_id, uint64_t src_addr, 2073 uint32_t src_size, uint64_t dst_addr, 2074 uint32_t dst_size, uint8_t is_finalised, 2075 uint32_t *send_id) 2076 { 2077 int status; 2078 int i; 2079 uint32_t flag; 2080 uint32_t crypto_header; 2081 uint32_t fcs_aes_crypt_payload[FCS_AES_CMD_MAX_WORD_SIZE]; 2082 2083 if (fcs_aes_init_payload.session_id != session_id || 2084 fcs_aes_init_payload.context_id != context_id) { 2085 return INTEL_SIP_SMC_STATUS_REJECTED; 2086 } 2087 2088 if ((!is_8_bytes_aligned(src_addr)) || 2089 (!is_32_bytes_aligned(src_size)) || 2090 (!is_address_in_ddr_range(src_addr, src_size))) { 2091 return INTEL_SIP_SMC_STATUS_REJECTED; 2092 } 2093 2094 if ((!is_8_bytes_aligned(dst_addr)) || 2095 (!is_32_bytes_aligned(dst_size))) { 2096 return INTEL_SIP_SMC_STATUS_REJECTED; 2097 } 2098 2099 if ((dst_size > FCS_AES_MAX_DATA_SIZE || 2100 dst_size < FCS_AES_MIN_DATA_SIZE) || 2101 (src_size > FCS_AES_MAX_DATA_SIZE || 2102 src_size < FCS_AES_MIN_DATA_SIZE)) { 2103 return INTEL_SIP_SMC_STATUS_REJECTED; 2104 } 2105 2106 /* Prepare crypto header*/ 2107 flag = 0; 2108 if (fcs_aes_init_payload.is_updated) { 2109 fcs_aes_init_payload.param_size = 0; 2110 } else { 2111 flag |= FCS_CS_FIELD_FLAG_INIT; 2112 } 2113 2114 if (is_finalised != 0U) { 2115 flag |= FCS_CS_FIELD_FLAG_FINALIZE; 2116 } else { 2117 flag |= FCS_CS_FIELD_FLAG_UPDATE; 2118 fcs_aes_init_payload.is_updated = 1; 2119 } 2120 crypto_header = (flag << FCS_CS_FIELD_FLAG_OFFSET) | 2121 fcs_aes_init_payload.param_size; 2122 2123 i = 0U; 2124 fcs_aes_crypt_payload[i] = session_id; 2125 i++; 2126 fcs_aes_crypt_payload[i] = context_id; 2127 i++; 2128 fcs_aes_crypt_payload[i] = crypto_header; 2129 i++; 2130 2131 if ((crypto_header >> FCS_CS_FIELD_FLAG_OFFSET) & 2132 FCS_CS_FIELD_FLAG_INIT) { 2133 fcs_aes_crypt_payload[i] = fcs_aes_init_payload.key_id; 2134 i++; 2135 2136 memcpy((uint8_t *) &fcs_aes_crypt_payload[i], 2137 (uint8_t *) fcs_aes_init_payload.crypto_param, 2138 fcs_aes_init_payload.param_size); 2139 2140 i += fcs_aes_init_payload.param_size / MBOX_WORD_BYTE; 2141 } 2142 2143 fcs_aes_crypt_payload[i] = (uint32_t) src_addr; 2144 i++; 2145 fcs_aes_crypt_payload[i] = src_size; 2146 i++; 2147 fcs_aes_crypt_payload[i] = (uint32_t) dst_addr; 2148 i++; 2149 fcs_aes_crypt_payload[i] = dst_size; 2150 i++; 2151 2152 status = mailbox_send_cmd_async(send_id, MBOX_FCS_AES_CRYPT_REQ, 2153 fcs_aes_crypt_payload, i, 2154 CMD_INDIRECT); 2155 2156 if (is_finalised != 0U) { 2157 memset((void *)&fcs_aes_init_payload, 0, 2158 sizeof(fcs_aes_init_payload)); 2159 } 2160 2161 if (status < 0U) { 2162 return INTEL_SIP_SMC_STATUS_ERROR; 2163 } 2164 2165 return INTEL_SIP_SMC_STATUS_OK; 2166 } 2167