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 == MBOX_RET_SDOS_DECRYPTION_ERROR_102 || 415 status == MBOX_RET_SDOS_DECRYPTION_ERROR_103) { 416 *mbox_error = -status; 417 } else if (status < 0) { 418 *mbox_error = -status; 419 return INTEL_SIP_SMC_STATUS_ERROR; 420 } 421 422 if (resp_len != FCS_CRYPTION_RESP_WORD_SIZE) { 423 *mbox_error = MBOX_RET_ERROR; 424 return INTEL_SIP_SMC_STATUS_ERROR; 425 } 426 427 *dst_size = resp_data[FCS_CRYPTION_RESP_SIZE_OFFSET]; 428 inv_dcache_range(dst_addr, *dst_size); 429 430 return INTEL_SIP_SMC_STATUS_OK; 431 } 432 433 int intel_fcs_sigma_teardown(uint32_t session_id, uint32_t *mbox_error) 434 { 435 int status; 436 437 if ((session_id != PSGSIGMA_SESSION_ID_ONE) && 438 (session_id != PSGSIGMA_UNKNOWN_SESSION)) { 439 return INTEL_SIP_SMC_STATUS_REJECTED; 440 } 441 442 psgsigma_teardown_msg message = { 443 RESERVED_AS_ZERO, 444 PSGSIGMA_TEARDOWN_MAGIC, 445 session_id 446 }; 447 448 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_PSG_SIGMA_TEARDOWN, 449 (uint32_t *) &message, sizeof(message) / MBOX_WORD_BYTE, 450 CMD_CASUAL, NULL, NULL); 451 452 if (status < 0) { 453 *mbox_error = -status; 454 return INTEL_SIP_SMC_STATUS_ERROR; 455 } 456 457 return INTEL_SIP_SMC_STATUS_OK; 458 } 459 460 int intel_fcs_chip_id(uint32_t *id_low, uint32_t *id_high, uint32_t *mbox_error) 461 { 462 int status; 463 uint32_t load_size; 464 uint32_t chip_id[2]; 465 466 load_size = sizeof(chip_id) / MBOX_WORD_BYTE; 467 468 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_CMD_GET_CHIPID, NULL, 469 0U, CMD_CASUAL, (uint32_t *) chip_id, &load_size); 470 471 if (status < 0) { 472 *mbox_error = -status; 473 return INTEL_SIP_SMC_STATUS_ERROR; 474 } 475 476 *id_low = chip_id[0]; 477 *id_high = chip_id[1]; 478 479 return INTEL_SIP_SMC_STATUS_OK; 480 } 481 482 int intel_fcs_attestation_subkey(uint64_t src_addr, uint32_t src_size, 483 uint64_t dst_addr, uint32_t *dst_size, uint32_t *mbox_error) 484 { 485 int status; 486 uint32_t send_size = src_size / MBOX_WORD_BYTE; 487 uint32_t ret_size = *dst_size / MBOX_WORD_BYTE; 488 489 490 if (!is_address_in_ddr_range(src_addr, src_size) || 491 !is_address_in_ddr_range(dst_addr, *dst_size)) { 492 return INTEL_SIP_SMC_STATUS_REJECTED; 493 } 494 495 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_ATTESTATION_SUBKEY, 496 (uint32_t *) src_addr, send_size, CMD_CASUAL, 497 (uint32_t *) dst_addr, &ret_size); 498 499 if (status < 0) { 500 *mbox_error = -status; 501 return INTEL_SIP_SMC_STATUS_ERROR; 502 } 503 504 *dst_size = ret_size * MBOX_WORD_BYTE; 505 flush_dcache_range(dst_addr, *dst_size); 506 507 return INTEL_SIP_SMC_STATUS_OK; 508 } 509 510 int intel_fcs_get_measurement(uint64_t src_addr, uint32_t src_size, 511 uint64_t dst_addr, uint32_t *dst_size, uint32_t *mbox_error) 512 { 513 int status; 514 uint32_t send_size = src_size / MBOX_WORD_BYTE; 515 uint32_t ret_size = *dst_size / MBOX_WORD_BYTE; 516 517 if (!is_address_in_ddr_range(src_addr, src_size) || 518 !is_address_in_ddr_range(dst_addr, *dst_size)) { 519 return INTEL_SIP_SMC_STATUS_REJECTED; 520 } 521 522 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_GET_MEASUREMENT, 523 (uint32_t *) src_addr, send_size, CMD_CASUAL, 524 (uint32_t *) dst_addr, &ret_size); 525 526 if (status < 0) { 527 *mbox_error = -status; 528 return INTEL_SIP_SMC_STATUS_ERROR; 529 } 530 531 *dst_size = ret_size * MBOX_WORD_BYTE; 532 flush_dcache_range(dst_addr, *dst_size); 533 534 return INTEL_SIP_SMC_STATUS_OK; 535 } 536 537 uint32_t intel_fcs_get_rom_patch_sha384(uint64_t addr, uint64_t *ret_size, 538 uint32_t *mbox_error) 539 { 540 int status; 541 unsigned int resp_len = FCS_SHA384_WORD_SIZE; 542 543 if (!is_address_in_ddr_range(addr, FCS_SHA384_BYTE_SIZE)) { 544 return INTEL_SIP_SMC_STATUS_REJECTED; 545 } 546 547 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_GET_ROM_PATCH_SHA384, NULL, 0U, 548 CMD_CASUAL, (uint32_t *) addr, &resp_len); 549 550 if (status < 0) { 551 *mbox_error = -status; 552 return INTEL_SIP_SMC_STATUS_ERROR; 553 } 554 555 if (resp_len != FCS_SHA384_WORD_SIZE) { 556 *mbox_error = GENERIC_RESPONSE_ERROR; 557 return INTEL_SIP_SMC_STATUS_ERROR; 558 } 559 560 *ret_size = FCS_SHA384_BYTE_SIZE; 561 562 flush_dcache_range(addr, *ret_size); 563 564 return INTEL_SIP_SMC_STATUS_OK; 565 } 566 567 int intel_fcs_get_attestation_cert(uint32_t cert_request, uint64_t dst_addr, 568 uint32_t *dst_size, uint32_t *mbox_error) 569 { 570 int status; 571 uint32_t ret_size = *dst_size / MBOX_WORD_BYTE; 572 573 if (mbox_error == NULL) { 574 return INTEL_SIP_SMC_STATUS_REJECTED; 575 } 576 577 if (cert_request < FCS_ATTEST_FIRMWARE_CERT || 578 cert_request > FCS_ATTEST_CERT_MAX_REQ_PARAM) { 579 return INTEL_SIP_SMC_STATUS_REJECTED; 580 } 581 582 if (!is_address_in_ddr_range(dst_addr, *dst_size)) { 583 return INTEL_SIP_SMC_STATUS_REJECTED; 584 } 585 586 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_GET_ATTESTATION_CERT, 587 (uint32_t *) &cert_request, 1U, CMD_CASUAL, 588 (uint32_t *) dst_addr, &ret_size); 589 590 if (status < 0) { 591 *mbox_error = -status; 592 return INTEL_SIP_SMC_STATUS_ERROR; 593 } 594 595 *dst_size = ret_size * MBOX_WORD_BYTE; 596 flush_dcache_range(dst_addr, *dst_size); 597 598 return INTEL_SIP_SMC_STATUS_OK; 599 } 600 601 int intel_fcs_create_cert_on_reload(uint32_t cert_request, 602 uint32_t *mbox_error) 603 { 604 int status; 605 606 if (mbox_error == NULL) { 607 return INTEL_SIP_SMC_STATUS_REJECTED; 608 } 609 610 if (cert_request < FCS_ATTEST_FIRMWARE_CERT || 611 cert_request > FCS_ATTEST_CERT_MAX_REQ_PARAM) { 612 return INTEL_SIP_SMC_STATUS_REJECTED; 613 } 614 615 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_CREATE_CERT_ON_RELOAD, 616 (uint32_t *) &cert_request, 1U, CMD_CASUAL, 617 NULL, NULL); 618 619 if (status < 0) { 620 *mbox_error = -status; 621 return INTEL_SIP_SMC_STATUS_ERROR; 622 } 623 624 return INTEL_SIP_SMC_STATUS_OK; 625 } 626 627 int intel_fcs_open_crypto_service_session(uint32_t *session_id, 628 uint32_t *mbox_error) 629 { 630 int status; 631 uint32_t resp_len = 1U; 632 633 if ((session_id == NULL) || (mbox_error == NULL)) { 634 return INTEL_SIP_SMC_STATUS_REJECTED; 635 } 636 637 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_OPEN_CS_SESSION, 638 NULL, 0U, CMD_CASUAL, session_id, &resp_len); 639 640 if (status < 0) { 641 *mbox_error = -status; 642 return INTEL_SIP_SMC_STATUS_ERROR; 643 } 644 645 return INTEL_SIP_SMC_STATUS_OK; 646 } 647 648 int intel_fcs_close_crypto_service_session(uint32_t session_id, 649 uint32_t *mbox_error) 650 { 651 int status; 652 653 if (mbox_error == NULL) { 654 return INTEL_SIP_SMC_STATUS_REJECTED; 655 } 656 657 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_CLOSE_CS_SESSION, 658 &session_id, 1U, CMD_CASUAL, NULL, NULL); 659 660 if (status < 0) { 661 *mbox_error = -status; 662 return INTEL_SIP_SMC_STATUS_ERROR; 663 } 664 665 return INTEL_SIP_SMC_STATUS_OK; 666 } 667 668 int intel_fcs_import_crypto_service_key(uint64_t src_addr, uint32_t src_size, 669 uint32_t *send_id) 670 { 671 int status; 672 673 if (src_size > (FCS_CS_KEY_OBJ_MAX_WORD_SIZE * 674 MBOX_WORD_BYTE)) { 675 return INTEL_SIP_SMC_STATUS_REJECTED; 676 } 677 678 if (!is_address_in_ddr_range(src_addr, src_size)) { 679 return INTEL_SIP_SMC_STATUS_REJECTED; 680 } 681 682 status = mailbox_send_cmd_async(send_id, MBOX_FCS_IMPORT_CS_KEY, 683 (uint32_t *)src_addr, src_size / MBOX_WORD_BYTE, 684 CMD_INDIRECT); 685 686 if (status < 0) { 687 return INTEL_SIP_SMC_STATUS_ERROR; 688 } 689 690 return INTEL_SIP_SMC_STATUS_OK; 691 } 692 693 int intel_fcs_export_crypto_service_key(uint32_t session_id, uint32_t key_id, 694 uint64_t dst_addr, uint32_t *dst_size, 695 uint32_t *mbox_error) 696 { 697 int status; 698 uint32_t i; 699 uint32_t payload_size; 700 uint32_t resp_len = FCS_CS_KEY_OBJ_MAX_WORD_SIZE; 701 uint32_t resp_data[FCS_CS_KEY_OBJ_MAX_WORD_SIZE] = {0U}; 702 uint32_t op_status = 0U; 703 704 if ((dst_size == NULL) || (mbox_error == NULL)) { 705 return INTEL_SIP_SMC_STATUS_REJECTED; 706 } 707 708 if (!is_address_in_ddr_range(dst_addr, *dst_size)) { 709 return INTEL_SIP_SMC_STATUS_REJECTED; 710 } 711 712 fcs_cs_key_payload payload = { 713 session_id, 714 RESERVED_AS_ZERO, 715 RESERVED_AS_ZERO, 716 key_id 717 }; 718 719 payload_size = sizeof(payload) / MBOX_WORD_BYTE; 720 721 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_EXPORT_CS_KEY, 722 (uint32_t *) &payload, payload_size, 723 CMD_CASUAL, resp_data, &resp_len); 724 725 if (resp_len > 0) { 726 op_status = resp_data[0] & FCS_CS_KEY_RESP_STATUS_MASK; 727 } 728 729 if (status < 0) { 730 *mbox_error = (-status) | (op_status << FCS_CS_KEY_RESP_STATUS_OFFSET); 731 return INTEL_SIP_SMC_STATUS_ERROR; 732 } 733 734 if (resp_len > 1) { 735 736 /* Export key object is start at second response data */ 737 *dst_size = (resp_len - 1) * MBOX_WORD_BYTE; 738 739 for (i = 1U; i < resp_len; i++) { 740 mmio_write_32(dst_addr, resp_data[i]); 741 dst_addr += MBOX_WORD_BYTE; 742 } 743 744 flush_dcache_range(dst_addr - *dst_size, *dst_size); 745 746 } else { 747 748 /* Unexpected response, missing key object in response */ 749 *mbox_error = MBOX_RET_ERROR; 750 return INTEL_SIP_SMC_STATUS_ERROR; 751 } 752 753 return INTEL_SIP_SMC_STATUS_OK; 754 } 755 756 int intel_fcs_remove_crypto_service_key(uint32_t session_id, uint32_t key_id, 757 uint32_t *mbox_error) 758 { 759 int status; 760 uint32_t payload_size; 761 uint32_t resp_len = 1U; 762 uint32_t resp_data = 0U; 763 uint32_t op_status = 0U; 764 765 if (mbox_error == NULL) { 766 return INTEL_SIP_SMC_STATUS_REJECTED; 767 } 768 769 fcs_cs_key_payload payload = { 770 session_id, 771 RESERVED_AS_ZERO, 772 RESERVED_AS_ZERO, 773 key_id 774 }; 775 776 payload_size = sizeof(payload) / MBOX_WORD_BYTE; 777 778 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_REMOVE_CS_KEY, 779 (uint32_t *) &payload, payload_size, 780 CMD_CASUAL, &resp_data, &resp_len); 781 782 if (resp_len > 0) { 783 op_status = resp_data & FCS_CS_KEY_RESP_STATUS_MASK; 784 } 785 786 if (status < 0) { 787 *mbox_error = (-status) | (op_status << FCS_CS_KEY_RESP_STATUS_OFFSET); 788 return INTEL_SIP_SMC_STATUS_ERROR; 789 } 790 791 return INTEL_SIP_SMC_STATUS_OK; 792 } 793 794 int intel_fcs_get_crypto_service_key_info(uint32_t session_id, uint32_t key_id, 795 uint64_t dst_addr, uint32_t *dst_size, 796 uint32_t *mbox_error) 797 { 798 int status; 799 uint32_t payload_size; 800 uint32_t resp_len = FCS_CS_KEY_INFO_MAX_WORD_SIZE; 801 uint32_t op_status = 0U; 802 803 if ((dst_size == NULL) || (mbox_error == NULL)) { 804 return INTEL_SIP_SMC_STATUS_REJECTED; 805 } 806 807 if (!is_address_in_ddr_range(dst_addr, *dst_size)) { 808 return INTEL_SIP_SMC_STATUS_REJECTED; 809 } 810 811 fcs_cs_key_payload payload = { 812 session_id, 813 RESERVED_AS_ZERO, 814 RESERVED_AS_ZERO, 815 key_id 816 }; 817 818 payload_size = sizeof(payload) / MBOX_WORD_BYTE; 819 820 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_GET_CS_KEY_INFO, 821 (uint32_t *) &payload, payload_size, 822 CMD_CASUAL, (uint32_t *) dst_addr, &resp_len); 823 824 if (resp_len > 0) { 825 op_status = mmio_read_32(dst_addr) & 826 FCS_CS_KEY_RESP_STATUS_MASK; 827 } 828 829 if (status < 0) { 830 *mbox_error = (-status) | (op_status << FCS_CS_KEY_RESP_STATUS_OFFSET); 831 return INTEL_SIP_SMC_STATUS_ERROR; 832 } 833 834 *dst_size = resp_len * MBOX_WORD_BYTE; 835 flush_dcache_range(dst_addr, *dst_size); 836 837 return INTEL_SIP_SMC_STATUS_OK; 838 } 839 840 int intel_fcs_get_digest_init(uint32_t session_id, uint32_t context_id, 841 uint32_t key_id, uint32_t param_size, 842 uint64_t param_data, uint32_t *mbox_error) 843 { 844 return intel_fcs_crypto_service_init(session_id, context_id, 845 key_id, param_size, param_data, 846 (void *) &fcs_sha_get_digest_param, 847 mbox_error); 848 } 849 850 int intel_fcs_get_digest_update_finalize(uint32_t session_id, 851 uint32_t context_id, uint32_t src_addr, 852 uint32_t src_size, uint64_t dst_addr, 853 uint32_t *dst_size, uint8_t is_finalised, 854 uint32_t *mbox_error) 855 { 856 int status; 857 uint32_t i; 858 uint32_t flag; 859 uint32_t crypto_header; 860 uint32_t resp_len; 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 resp_len = *dst_size / MBOX_WORD_BYTE; 883 884 /* Prepare crypto header */ 885 flag = 0; 886 887 if (fcs_sha_get_digest_param.is_updated) { 888 fcs_sha_get_digest_param.crypto_param_size = 0; 889 } else { 890 flag |= FCS_CS_FIELD_FLAG_INIT; 891 } 892 893 if (is_finalised != 0U) { 894 flag |= FCS_CS_FIELD_FLAG_FINALIZE; 895 } else { 896 flag |= FCS_CS_FIELD_FLAG_UPDATE; 897 fcs_sha_get_digest_param.is_updated = 1; 898 } 899 900 crypto_header = ((flag << FCS_CS_FIELD_FLAG_OFFSET) | 901 (fcs_sha_get_digest_param.crypto_param_size & 902 FCS_CS_FIELD_SIZE_MASK)); 903 904 /* Prepare command payload */ 905 i = 0; 906 payload[i] = fcs_sha_get_digest_param.session_id; 907 i++; 908 payload[i] = fcs_sha_get_digest_param.context_id; 909 i++; 910 payload[i] = crypto_header; 911 i++; 912 913 if ((crypto_header >> FCS_CS_FIELD_FLAG_OFFSET) & 914 FCS_CS_FIELD_FLAG_INIT) { 915 payload[i] = fcs_sha_get_digest_param.key_id; 916 i++; 917 /* Crypto parameters */ 918 payload[i] = fcs_sha_get_digest_param.crypto_param 919 & INTEL_SIP_SMC_FCS_SHA_MODE_MASK; 920 payload[i] |= ((fcs_sha_get_digest_param.crypto_param 921 >> INTEL_SIP_SMC_FCS_DIGEST_SIZE_OFFSET) 922 & INTEL_SIP_SMC_FCS_DIGEST_SIZE_MASK) 923 << FCS_SHA_HMAC_CRYPTO_PARAM_SIZE_OFFSET; 924 i++; 925 } 926 /* Data source address and size */ 927 payload[i] = src_addr; 928 i++; 929 payload[i] = src_size; 930 i++; 931 932 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_GET_DIGEST_REQ, 933 payload, i, CMD_CASUAL, 934 (uint32_t *) dst_addr, &resp_len); 935 936 if (is_finalised != 0U) { 937 memset((void *)&fcs_sha_get_digest_param, 0, 938 sizeof(fcs_crypto_service_data)); 939 } 940 941 if (status < 0) { 942 *mbox_error = -status; 943 return INTEL_SIP_SMC_STATUS_ERROR; 944 } 945 946 *dst_size = resp_len * MBOX_WORD_BYTE; 947 flush_dcache_range(dst_addr, *dst_size); 948 949 return INTEL_SIP_SMC_STATUS_OK; 950 } 951 952 int intel_fcs_get_digest_smmu_update_finalize(uint32_t session_id, 953 uint32_t context_id, uint32_t src_addr, 954 uint32_t src_size, uint64_t dst_addr, 955 uint32_t *dst_size, uint8_t is_finalised, 956 uint32_t *mbox_error, uint32_t *send_id) 957 { 958 int status; 959 uint32_t i; 960 uint32_t flag; 961 uint32_t crypto_header; 962 uint32_t resp_len; 963 uint32_t payload[FCS_GET_DIGEST_CMD_MAX_WORD_SIZE] = {0U}; 964 965 /* Source data must be 8 bytes aligned */ 966 if (dst_size == NULL || mbox_error == NULL || 967 !is_8_bytes_aligned(src_size)) { 968 return INTEL_SIP_SMC_STATUS_REJECTED; 969 } 970 971 if (fcs_sha_get_digest_param.session_id != session_id || 972 fcs_sha_get_digest_param.context_id != context_id) { 973 return INTEL_SIP_SMC_STATUS_REJECTED; 974 } 975 976 if (!is_address_in_ddr_range(src_addr, src_size) || 977 !is_address_in_ddr_range(dst_addr, *dst_size)) { 978 return INTEL_SIP_SMC_STATUS_REJECTED; 979 } 980 981 resp_len = *dst_size / MBOX_WORD_BYTE; 982 983 /* Prepare crypto header */ 984 flag = 0; 985 986 if (fcs_sha_get_digest_param.is_updated) { 987 fcs_sha_get_digest_param.crypto_param_size = 0; 988 } else { 989 flag |= FCS_CS_FIELD_FLAG_INIT; 990 } 991 992 if (is_finalised != 0U) { 993 flag |= FCS_CS_FIELD_FLAG_FINALIZE; 994 } else { 995 flag |= FCS_CS_FIELD_FLAG_UPDATE; 996 fcs_sha_get_digest_param.is_updated = 1; 997 } 998 999 crypto_header = ((flag << FCS_CS_FIELD_FLAG_OFFSET) | 1000 (fcs_sha_get_digest_param.crypto_param_size & 1001 FCS_CS_FIELD_SIZE_MASK)); 1002 1003 /* Prepare command payload */ 1004 i = 0; 1005 payload[i] = fcs_sha_get_digest_param.session_id; 1006 i++; 1007 payload[i] = fcs_sha_get_digest_param.context_id; 1008 i++; 1009 payload[i] = crypto_header; 1010 i++; 1011 1012 if ((crypto_header >> FCS_CS_FIELD_FLAG_OFFSET) & 1013 FCS_CS_FIELD_FLAG_INIT) { 1014 payload[i] = fcs_sha_get_digest_param.key_id; 1015 i++; 1016 /* Crypto parameters */ 1017 payload[i] = fcs_sha_get_digest_param.crypto_param 1018 & INTEL_SIP_SMC_FCS_SHA_MODE_MASK; 1019 payload[i] |= ((fcs_sha_get_digest_param.crypto_param 1020 >> INTEL_SIP_SMC_FCS_DIGEST_SIZE_OFFSET) 1021 & INTEL_SIP_SMC_FCS_DIGEST_SIZE_MASK) 1022 << FCS_SHA_HMAC_CRYPTO_PARAM_SIZE_OFFSET; 1023 i++; 1024 } 1025 /* Data source address and size */ 1026 payload[i] = src_addr; 1027 i++; 1028 payload[i] = src_size; 1029 i++; 1030 1031 status = mailbox_send_cmd_async(send_id, MBOX_FCS_GET_DIGEST_REQ, 1032 payload, i, CMD_INDIRECT); 1033 1034 if (is_finalised != 0U) { 1035 memset((void *)&fcs_sha_get_digest_param, 0, 1036 sizeof(fcs_crypto_service_data)); 1037 } 1038 1039 if (status < 0) { 1040 *mbox_error = -status; 1041 return INTEL_SIP_SMC_STATUS_ERROR; 1042 } 1043 1044 *dst_size = resp_len * MBOX_WORD_BYTE; 1045 flush_dcache_range(dst_addr, *dst_size); 1046 1047 return INTEL_SIP_SMC_STATUS_OK; 1048 } 1049 1050 int intel_fcs_mac_verify_init(uint32_t session_id, uint32_t context_id, 1051 uint32_t key_id, uint32_t param_size, 1052 uint64_t param_data, uint32_t *mbox_error) 1053 { 1054 return intel_fcs_crypto_service_init(session_id, context_id, 1055 key_id, param_size, param_data, 1056 (void *) &fcs_sha_mac_verify_param, 1057 mbox_error); 1058 } 1059 1060 int intel_fcs_mac_verify_update_finalize(uint32_t session_id, 1061 uint32_t context_id, uint32_t src_addr, 1062 uint32_t src_size, uint64_t dst_addr, 1063 uint32_t *dst_size, uint32_t data_size, 1064 uint8_t is_finalised, uint32_t *mbox_error) 1065 { 1066 int status; 1067 uint32_t i; 1068 uint32_t flag; 1069 uint32_t crypto_header; 1070 uint32_t resp_len; 1071 uint32_t payload[FCS_MAC_VERIFY_CMD_MAX_WORD_SIZE] = {0U}; 1072 uintptr_t mac_offset; 1073 1074 if (dst_size == NULL || mbox_error == NULL) { 1075 return INTEL_SIP_SMC_STATUS_REJECTED; 1076 } 1077 1078 if (fcs_sha_mac_verify_param.session_id != session_id || 1079 fcs_sha_mac_verify_param.context_id != context_id) { 1080 return INTEL_SIP_SMC_STATUS_REJECTED; 1081 } 1082 1083 if (data_size > src_size) { 1084 return INTEL_SIP_SMC_STATUS_REJECTED; 1085 } 1086 1087 if (!is_size_4_bytes_aligned(src_size) || 1088 !is_8_bytes_aligned(data_size)) { 1089 return INTEL_SIP_SMC_STATUS_REJECTED; 1090 } 1091 1092 if (!is_address_in_ddr_range(src_addr, src_size) || 1093 !is_address_in_ddr_range(dst_addr, *dst_size)) { 1094 return INTEL_SIP_SMC_STATUS_REJECTED; 1095 } 1096 1097 resp_len = *dst_size / MBOX_WORD_BYTE; 1098 1099 /* Prepare crypto header */ 1100 flag = 0; 1101 1102 if (fcs_sha_mac_verify_param.is_updated) { 1103 fcs_sha_mac_verify_param.crypto_param_size = 0; 1104 } else { 1105 flag |= FCS_CS_FIELD_FLAG_INIT; 1106 } 1107 1108 if (is_finalised) { 1109 flag |= FCS_CS_FIELD_FLAG_FINALIZE; 1110 } else { 1111 flag |= FCS_CS_FIELD_FLAG_UPDATE; 1112 fcs_sha_mac_verify_param.is_updated = 1; 1113 } 1114 1115 crypto_header = ((flag << FCS_CS_FIELD_FLAG_OFFSET) | 1116 (fcs_sha_mac_verify_param.crypto_param_size & 1117 FCS_CS_FIELD_SIZE_MASK)); 1118 1119 /* Prepare command payload */ 1120 i = 0; 1121 payload[i] = fcs_sha_mac_verify_param.session_id; 1122 i++; 1123 payload[i] = fcs_sha_mac_verify_param.context_id; 1124 i++; 1125 payload[i] = crypto_header; 1126 i++; 1127 1128 if ((crypto_header >> FCS_CS_FIELD_FLAG_OFFSET) & 1129 FCS_CS_FIELD_FLAG_INIT) { 1130 payload[i] = fcs_sha_mac_verify_param.key_id; 1131 i++; 1132 /* Crypto parameters */ 1133 payload[i] = ((fcs_sha_mac_verify_param.crypto_param 1134 >> INTEL_SIP_SMC_FCS_DIGEST_SIZE_OFFSET) 1135 & INTEL_SIP_SMC_FCS_DIGEST_SIZE_MASK) 1136 << FCS_SHA_HMAC_CRYPTO_PARAM_SIZE_OFFSET; 1137 i++; 1138 } 1139 /* Data source address and size */ 1140 payload[i] = src_addr; 1141 i++; 1142 payload[i] = data_size; 1143 i++; 1144 1145 if ((crypto_header >> FCS_CS_FIELD_FLAG_OFFSET) & 1146 FCS_CS_FIELD_FLAG_FINALIZE) { 1147 /* Copy mac data to command */ 1148 mac_offset = src_addr + data_size; 1149 memcpy((uint8_t *) &payload[i], (uint8_t *) mac_offset, 1150 src_size - data_size); 1151 1152 i += (src_size - data_size) / MBOX_WORD_BYTE; 1153 } 1154 1155 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_MAC_VERIFY_REQ, 1156 payload, i, CMD_CASUAL, 1157 (uint32_t *) dst_addr, &resp_len); 1158 1159 if (is_finalised) { 1160 memset((void *)&fcs_sha_mac_verify_param, 0, 1161 sizeof(fcs_crypto_service_data)); 1162 } 1163 1164 if (status < 0) { 1165 *mbox_error = -status; 1166 return INTEL_SIP_SMC_STATUS_ERROR; 1167 } 1168 1169 *dst_size = resp_len * MBOX_WORD_BYTE; 1170 flush_dcache_range(dst_addr, *dst_size); 1171 1172 return INTEL_SIP_SMC_STATUS_OK; 1173 } 1174 1175 int intel_fcs_mac_verify_smmu_update_finalize(uint32_t session_id, 1176 uint32_t context_id, uint32_t src_addr, 1177 uint32_t src_size, uint64_t dst_addr, 1178 uint32_t *dst_size, uint32_t data_size, 1179 uint8_t is_finalised, uint32_t *mbox_error, 1180 uint32_t *send_id) 1181 { 1182 int status; 1183 uint32_t i; 1184 uint32_t flag; 1185 uint32_t crypto_header; 1186 uint32_t resp_len; 1187 uint32_t payload[FCS_MAC_VERIFY_CMD_MAX_WORD_SIZE] = {0U}; 1188 uintptr_t mac_offset; 1189 1190 /* 1191 * Source data must be 4 bytes aligned 1192 * User data must be 8 bytes aligned 1193 */ 1194 if (dst_size == NULL || mbox_error == NULL || 1195 !is_size_4_bytes_aligned(src_size) || 1196 !is_8_bytes_aligned(data_size)) { 1197 return INTEL_SIP_SMC_STATUS_REJECTED; 1198 } 1199 1200 if (data_size > src_size) { 1201 return INTEL_SIP_SMC_STATUS_REJECTED; 1202 } 1203 1204 if (fcs_sha_mac_verify_param.session_id != session_id || 1205 fcs_sha_mac_verify_param.context_id != context_id) { 1206 return INTEL_SIP_SMC_STATUS_REJECTED; 1207 } 1208 1209 if (!is_address_in_ddr_range(src_addr, src_size) || 1210 !is_address_in_ddr_range(dst_addr, *dst_size)) { 1211 return INTEL_SIP_SMC_STATUS_REJECTED; 1212 } 1213 1214 resp_len = *dst_size / MBOX_WORD_BYTE; 1215 1216 /* Prepare crypto header */ 1217 flag = 0; 1218 1219 if (fcs_sha_mac_verify_param.is_updated) { 1220 fcs_sha_mac_verify_param.crypto_param_size = 0; 1221 } else { 1222 flag |= FCS_CS_FIELD_FLAG_INIT; 1223 } 1224 1225 if (is_finalised) { 1226 flag |= FCS_CS_FIELD_FLAG_FINALIZE; 1227 } else { 1228 flag |= FCS_CS_FIELD_FLAG_UPDATE; 1229 fcs_sha_mac_verify_param.is_updated = 1; 1230 } 1231 1232 crypto_header = ((flag << FCS_CS_FIELD_FLAG_OFFSET) | 1233 (fcs_sha_mac_verify_param.crypto_param_size & 1234 FCS_CS_FIELD_SIZE_MASK)); 1235 1236 /* Prepare command payload */ 1237 i = 0; 1238 payload[i] = fcs_sha_mac_verify_param.session_id; 1239 i++; 1240 payload[i] = fcs_sha_mac_verify_param.context_id; 1241 i++; 1242 payload[i] = crypto_header; 1243 i++; 1244 1245 if ((crypto_header >> FCS_CS_FIELD_FLAG_OFFSET) & 1246 FCS_CS_FIELD_FLAG_INIT) { 1247 payload[i] = fcs_sha_mac_verify_param.key_id; 1248 i++; 1249 /* Crypto parameters */ 1250 payload[i] = ((fcs_sha_mac_verify_param.crypto_param 1251 >> INTEL_SIP_SMC_FCS_DIGEST_SIZE_OFFSET) 1252 & INTEL_SIP_SMC_FCS_DIGEST_SIZE_MASK) 1253 << FCS_SHA_HMAC_CRYPTO_PARAM_SIZE_OFFSET; 1254 i++; 1255 } 1256 /* Data source address and size */ 1257 payload[i] = src_addr; 1258 i++; 1259 payload[i] = data_size; 1260 i++; 1261 1262 if ((crypto_header >> FCS_CS_FIELD_FLAG_OFFSET) & 1263 FCS_CS_FIELD_FLAG_FINALIZE) { 1264 /* Copy mac data to command 1265 * Using dst_addr (physical address) to store mac_offset 1266 * mac_offset = MAC data 1267 */ 1268 mac_offset = dst_addr; 1269 memcpy((uint8_t *) &payload[i], (uint8_t *) mac_offset, 1270 src_size - data_size); 1271 1272 memset((void *)&dst_addr, 0, sizeof(dst_size)); 1273 1274 i += (src_size - data_size) / MBOX_WORD_BYTE; 1275 } 1276 1277 status = mailbox_send_cmd_async(send_id, MBOX_FCS_MAC_VERIFY_REQ, 1278 payload, i, CMD_INDIRECT); 1279 1280 if (is_finalised) { 1281 memset((void *)&fcs_sha_mac_verify_param, 0, 1282 sizeof(fcs_crypto_service_data)); 1283 } 1284 1285 if (status < 0) { 1286 *mbox_error = -status; 1287 return INTEL_SIP_SMC_STATUS_ERROR; 1288 } 1289 1290 *dst_size = resp_len * MBOX_WORD_BYTE; 1291 flush_dcache_range(dst_addr, *dst_size); 1292 1293 return INTEL_SIP_SMC_STATUS_OK; 1294 } 1295 1296 int intel_fcs_ecdsa_hash_sign_init(uint32_t session_id, uint32_t context_id, 1297 uint32_t key_id, uint32_t param_size, 1298 uint64_t param_data, uint32_t *mbox_error) 1299 { 1300 return intel_fcs_crypto_service_init(session_id, context_id, 1301 key_id, param_size, param_data, 1302 (void *) &fcs_ecdsa_hash_sign_param, 1303 mbox_error); 1304 } 1305 1306 int intel_fcs_ecdsa_hash_sign_finalize(uint32_t session_id, uint32_t context_id, 1307 uint32_t src_addr, uint32_t src_size, 1308 uint64_t dst_addr, uint32_t *dst_size, 1309 uint32_t *mbox_error) 1310 { 1311 int status; 1312 uint32_t i; 1313 uint32_t payload[FCS_ECDSA_HASH_SIGN_CMD_MAX_WORD_SIZE] = {0U}; 1314 uint32_t resp_len; 1315 uintptr_t hash_data_addr; 1316 1317 if ((dst_size == NULL) || (mbox_error == NULL)) { 1318 return INTEL_SIP_SMC_STATUS_REJECTED; 1319 } 1320 1321 if (fcs_ecdsa_hash_sign_param.session_id != session_id || 1322 fcs_ecdsa_hash_sign_param.context_id != context_id) { 1323 return INTEL_SIP_SMC_STATUS_REJECTED; 1324 } 1325 1326 if (!is_address_in_ddr_range(src_addr, src_size) || 1327 !is_address_in_ddr_range(dst_addr, *dst_size)) { 1328 return INTEL_SIP_SMC_STATUS_REJECTED; 1329 } 1330 1331 resp_len = *dst_size / MBOX_WORD_BYTE; 1332 1333 /* Prepare command payload */ 1334 /* Crypto header */ 1335 i = 0; 1336 payload[i] = fcs_ecdsa_hash_sign_param.session_id; 1337 i++; 1338 payload[i] = fcs_ecdsa_hash_sign_param.context_id; 1339 1340 i++; 1341 payload[i] = fcs_ecdsa_hash_sign_param.crypto_param_size 1342 & FCS_CS_FIELD_SIZE_MASK; 1343 payload[i] |= (FCS_CS_FIELD_FLAG_INIT | FCS_CS_FIELD_FLAG_UPDATE 1344 | FCS_CS_FIELD_FLAG_FINALIZE) 1345 << FCS_CS_FIELD_FLAG_OFFSET; 1346 i++; 1347 payload[i] = fcs_ecdsa_hash_sign_param.key_id; 1348 1349 /* Crypto parameters */ 1350 i++; 1351 payload[i] = fcs_ecdsa_hash_sign_param.crypto_param 1352 & INTEL_SIP_SMC_FCS_ECC_ALGO_MASK; 1353 1354 /* Hash Data */ 1355 i++; 1356 hash_data_addr = src_addr; 1357 memcpy((uint8_t *) &payload[i], (uint8_t *) hash_data_addr, 1358 src_size); 1359 1360 i += src_size / MBOX_WORD_BYTE; 1361 1362 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_ECDSA_HASH_SIGN_REQ, 1363 payload, i, CMD_CASUAL, (uint32_t *) dst_addr, 1364 &resp_len); 1365 1366 memset((void *) &fcs_ecdsa_hash_sign_param, 1367 0, sizeof(fcs_crypto_service_data)); 1368 1369 if (status < 0) { 1370 *mbox_error = -status; 1371 return INTEL_SIP_SMC_STATUS_ERROR; 1372 } 1373 1374 *dst_size = resp_len * MBOX_WORD_BYTE; 1375 flush_dcache_range(dst_addr, *dst_size); 1376 1377 return INTEL_SIP_SMC_STATUS_OK; 1378 } 1379 1380 int intel_fcs_ecdsa_hash_sig_verify_init(uint32_t session_id, uint32_t context_id, 1381 uint32_t key_id, uint32_t param_size, 1382 uint64_t param_data, uint32_t *mbox_error) 1383 { 1384 return intel_fcs_crypto_service_init(session_id, context_id, 1385 key_id, param_size, param_data, 1386 (void *) &fcs_ecdsa_hash_sig_verify_param, 1387 mbox_error); 1388 } 1389 1390 int intel_fcs_ecdsa_hash_sig_verify_finalize(uint32_t session_id, uint32_t context_id, 1391 uint32_t src_addr, uint32_t src_size, 1392 uint64_t dst_addr, uint32_t *dst_size, 1393 uint32_t *mbox_error) 1394 { 1395 int status; 1396 uint32_t i = 0; 1397 uint32_t payload[FCS_ECDSA_HASH_SIG_VERIFY_CMD_MAX_WORD_SIZE] = {0U}; 1398 uint32_t resp_len; 1399 uintptr_t hash_sig_pubkey_addr; 1400 1401 if ((dst_size == NULL) || (mbox_error == NULL)) { 1402 return INTEL_SIP_SMC_STATUS_REJECTED; 1403 } 1404 1405 if (fcs_ecdsa_hash_sig_verify_param.session_id != session_id || 1406 fcs_ecdsa_hash_sig_verify_param.context_id != context_id) { 1407 return INTEL_SIP_SMC_STATUS_REJECTED; 1408 } 1409 1410 if (!is_address_in_ddr_range(src_addr, src_size) || 1411 !is_address_in_ddr_range(dst_addr, *dst_size)) { 1412 return INTEL_SIP_SMC_STATUS_REJECTED; 1413 } 1414 1415 resp_len = *dst_size / MBOX_WORD_BYTE; 1416 1417 /* Prepare command payload */ 1418 /* Crypto header */ 1419 i = 0; 1420 payload[i] = fcs_ecdsa_hash_sig_verify_param.session_id; 1421 1422 i++; 1423 payload[i] = fcs_ecdsa_hash_sig_verify_param.context_id; 1424 1425 i++; 1426 payload[i] = fcs_ecdsa_hash_sig_verify_param.crypto_param_size 1427 & FCS_CS_FIELD_SIZE_MASK; 1428 payload[i] |= (FCS_CS_FIELD_FLAG_INIT | FCS_CS_FIELD_FLAG_UPDATE 1429 | FCS_CS_FIELD_FLAG_FINALIZE) 1430 << FCS_CS_FIELD_FLAG_OFFSET; 1431 1432 i++; 1433 payload[i] = fcs_ecdsa_hash_sig_verify_param.key_id; 1434 1435 /* Crypto parameters */ 1436 i++; 1437 payload[i] = fcs_ecdsa_hash_sig_verify_param.crypto_param 1438 & INTEL_SIP_SMC_FCS_ECC_ALGO_MASK; 1439 1440 /* Hash Data Word, Signature Data Word and Public Key Data word */ 1441 i++; 1442 hash_sig_pubkey_addr = src_addr; 1443 memcpy((uint8_t *) &payload[i], 1444 (uint8_t *) hash_sig_pubkey_addr, src_size); 1445 1446 i += (src_size / MBOX_WORD_BYTE); 1447 1448 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_ECDSA_HASH_SIG_VERIFY, 1449 payload, i, CMD_CASUAL, (uint32_t *) dst_addr, 1450 &resp_len); 1451 1452 memset((void *)&fcs_ecdsa_hash_sig_verify_param, 1453 0, sizeof(fcs_crypto_service_data)); 1454 1455 if (status < 0) { 1456 *mbox_error = -status; 1457 return INTEL_SIP_SMC_STATUS_ERROR; 1458 } 1459 1460 *dst_size = resp_len * MBOX_WORD_BYTE; 1461 flush_dcache_range(dst_addr, *dst_size); 1462 1463 return INTEL_SIP_SMC_STATUS_OK; 1464 } 1465 1466 int intel_fcs_ecdsa_sha2_data_sign_init(uint32_t session_id, 1467 uint32_t context_id, uint32_t key_id, 1468 uint32_t param_size, uint64_t param_data, 1469 uint32_t *mbox_error) 1470 { 1471 return intel_fcs_crypto_service_init(session_id, context_id, 1472 key_id, param_size, param_data, 1473 (void *) &fcs_sha2_data_sign_param, 1474 mbox_error); 1475 } 1476 1477 int intel_fcs_ecdsa_sha2_data_sign_update_finalize(uint32_t session_id, 1478 uint32_t context_id, uint32_t src_addr, 1479 uint32_t src_size, uint64_t dst_addr, 1480 uint32_t *dst_size, uint8_t is_finalised, 1481 uint32_t *mbox_error) 1482 { 1483 int status; 1484 int i; 1485 uint32_t flag; 1486 uint32_t crypto_header; 1487 uint32_t payload[FCS_ECDSA_SHA2_DATA_SIGN_CMD_MAX_WORD_SIZE] = {0U}; 1488 uint32_t resp_len; 1489 1490 if ((dst_size == NULL) || (mbox_error == NULL)) { 1491 return INTEL_SIP_SMC_STATUS_REJECTED; 1492 } 1493 1494 if (fcs_sha2_data_sign_param.session_id != session_id || 1495 fcs_sha2_data_sign_param.context_id != context_id) { 1496 return INTEL_SIP_SMC_STATUS_REJECTED; 1497 } 1498 1499 /* Source data must be 8 bytes aligned */ 1500 if (!is_8_bytes_aligned(src_size)) { 1501 return INTEL_SIP_SMC_STATUS_REJECTED; 1502 } 1503 1504 if (!is_address_in_ddr_range(src_addr, src_size) || 1505 !is_address_in_ddr_range(dst_addr, *dst_size)) { 1506 return INTEL_SIP_SMC_STATUS_REJECTED; 1507 } 1508 1509 resp_len = *dst_size / MBOX_WORD_BYTE; 1510 1511 /* Prepare crypto header */ 1512 flag = 0; 1513 if (fcs_sha2_data_sign_param.is_updated) { 1514 fcs_sha2_data_sign_param.crypto_param_size = 0; 1515 } else { 1516 flag |= FCS_CS_FIELD_FLAG_INIT; 1517 } 1518 1519 if (is_finalised != 0U) { 1520 flag |= FCS_CS_FIELD_FLAG_FINALIZE; 1521 } else { 1522 flag |= FCS_CS_FIELD_FLAG_UPDATE; 1523 fcs_sha2_data_sign_param.is_updated = 1; 1524 } 1525 crypto_header = (flag << FCS_CS_FIELD_FLAG_OFFSET) | 1526 fcs_sha2_data_sign_param.crypto_param_size; 1527 1528 /* Prepare command payload */ 1529 i = 0; 1530 payload[i] = fcs_sha2_data_sign_param.session_id; 1531 i++; 1532 payload[i] = fcs_sha2_data_sign_param.context_id; 1533 i++; 1534 payload[i] = crypto_header; 1535 i++; 1536 1537 if ((crypto_header >> FCS_CS_FIELD_FLAG_OFFSET) & 1538 FCS_CS_FIELD_FLAG_INIT) { 1539 payload[i] = fcs_sha2_data_sign_param.key_id; 1540 /* Crypto parameters */ 1541 i++; 1542 payload[i] = fcs_sha2_data_sign_param.crypto_param 1543 & INTEL_SIP_SMC_FCS_ECC_ALGO_MASK; 1544 i++; 1545 } 1546 1547 /* Data source address and size */ 1548 payload[i] = src_addr; 1549 i++; 1550 payload[i] = src_size; 1551 i++; 1552 status = mailbox_send_cmd(MBOX_JOB_ID, 1553 MBOX_FCS_ECDSA_SHA2_DATA_SIGN_REQ, payload, 1554 i, CMD_CASUAL, (uint32_t *) dst_addr, 1555 &resp_len); 1556 1557 if (is_finalised != 0U) { 1558 memset((void *)&fcs_sha2_data_sign_param, 0, 1559 sizeof(fcs_crypto_service_data)); 1560 } 1561 1562 if (status < 0) { 1563 *mbox_error = -status; 1564 return INTEL_SIP_SMC_STATUS_ERROR; 1565 } 1566 1567 *dst_size = resp_len * MBOX_WORD_BYTE; 1568 flush_dcache_range(dst_addr, *dst_size); 1569 1570 return INTEL_SIP_SMC_STATUS_OK; 1571 } 1572 1573 int intel_fcs_ecdsa_sha2_data_sign_smmu_update_finalize(uint32_t session_id, 1574 uint32_t context_id, uint32_t src_addr, 1575 uint32_t src_size, uint64_t dst_addr, 1576 uint32_t *dst_size, uint8_t is_finalised, 1577 uint32_t *mbox_error, uint32_t *send_id) 1578 { 1579 int status; 1580 int i; 1581 uint32_t flag; 1582 uint32_t crypto_header; 1583 uint32_t payload[FCS_ECDSA_SHA2_DATA_SIGN_CMD_MAX_WORD_SIZE] = {0U}; 1584 uint32_t resp_len; 1585 1586 /* Source data must be 8 bytes aligned */ 1587 if ((dst_size == NULL) || (mbox_error == NULL || 1588 !is_8_bytes_aligned(src_size))) { 1589 return INTEL_SIP_SMC_STATUS_REJECTED; 1590 } 1591 1592 if (fcs_sha2_data_sign_param.session_id != session_id || 1593 fcs_sha2_data_sign_param.context_id != context_id) { 1594 return INTEL_SIP_SMC_STATUS_REJECTED; 1595 } 1596 1597 if (!is_address_in_ddr_range(src_addr, src_size) || 1598 !is_address_in_ddr_range(dst_addr, *dst_size)) { 1599 return INTEL_SIP_SMC_STATUS_REJECTED; 1600 } 1601 1602 resp_len = *dst_size / MBOX_WORD_BYTE; 1603 1604 /* Prepare crypto header */ 1605 flag = 0; 1606 if (fcs_sha2_data_sign_param.is_updated) { 1607 fcs_sha2_data_sign_param.crypto_param_size = 0; 1608 } else { 1609 flag |= FCS_CS_FIELD_FLAG_INIT; 1610 } 1611 1612 if (is_finalised != 0U) { 1613 flag |= FCS_CS_FIELD_FLAG_FINALIZE; 1614 } else { 1615 flag |= FCS_CS_FIELD_FLAG_UPDATE; 1616 fcs_sha2_data_sign_param.is_updated = 1; 1617 } 1618 crypto_header = (flag << FCS_CS_FIELD_FLAG_OFFSET) | 1619 fcs_sha2_data_sign_param.crypto_param_size; 1620 1621 /* Prepare command payload */ 1622 i = 0; 1623 payload[i] = fcs_sha2_data_sign_param.session_id; 1624 i++; 1625 payload[i] = fcs_sha2_data_sign_param.context_id; 1626 i++; 1627 payload[i] = crypto_header; 1628 i++; 1629 1630 if ((crypto_header >> FCS_CS_FIELD_FLAG_OFFSET) & 1631 FCS_CS_FIELD_FLAG_INIT) { 1632 payload[i] = fcs_sha2_data_sign_param.key_id; 1633 /* Crypto parameters */ 1634 i++; 1635 payload[i] = fcs_sha2_data_sign_param.crypto_param 1636 & INTEL_SIP_SMC_FCS_ECC_ALGO_MASK; 1637 i++; 1638 } 1639 1640 /* Data source address and size */ 1641 payload[i] = src_addr; 1642 i++; 1643 payload[i] = src_size; 1644 i++; 1645 1646 status = mailbox_send_cmd_async(send_id, 1647 MBOX_FCS_ECDSA_SHA2_DATA_SIGN_REQ, 1648 payload, i, CMD_INDIRECT); 1649 1650 if (is_finalised != 0U) { 1651 memset((void *)&fcs_sha2_data_sign_param, 0, 1652 sizeof(fcs_crypto_service_data)); 1653 } 1654 1655 if (status < 0) { 1656 *mbox_error = -status; 1657 return INTEL_SIP_SMC_STATUS_ERROR; 1658 } 1659 1660 *dst_size = resp_len * MBOX_WORD_BYTE; 1661 flush_dcache_range(dst_addr, *dst_size); 1662 1663 return INTEL_SIP_SMC_STATUS_OK; 1664 } 1665 1666 int intel_fcs_ecdsa_sha2_data_sig_verify_init(uint32_t session_id, 1667 uint32_t context_id, uint32_t key_id, 1668 uint32_t param_size, uint64_t param_data, 1669 uint32_t *mbox_error) 1670 { 1671 return intel_fcs_crypto_service_init(session_id, context_id, 1672 key_id, param_size, param_data, 1673 (void *) &fcs_sha2_data_sig_verify_param, 1674 mbox_error); 1675 } 1676 1677 int intel_fcs_ecdsa_sha2_data_sig_verify_update_finalize(uint32_t session_id, 1678 uint32_t context_id, uint32_t src_addr, 1679 uint32_t src_size, uint64_t dst_addr, 1680 uint32_t *dst_size, uint32_t data_size, 1681 uint8_t is_finalised, uint32_t *mbox_error) 1682 { 1683 int status; 1684 uint32_t i; 1685 uint32_t flag; 1686 uint32_t crypto_header; 1687 uint32_t payload[FCS_ECDSA_SHA2_DATA_SIG_VERIFY_CMD_MAX_WORD_SIZE] = {0U}; 1688 uint32_t resp_len; 1689 uintptr_t sig_pubkey_offset; 1690 1691 if ((dst_size == NULL) || (mbox_error == NULL)) { 1692 return INTEL_SIP_SMC_STATUS_REJECTED; 1693 } 1694 1695 if (fcs_sha2_data_sig_verify_param.session_id != session_id || 1696 fcs_sha2_data_sig_verify_param.context_id != context_id) { 1697 return INTEL_SIP_SMC_STATUS_REJECTED; 1698 } 1699 1700 if (!is_size_4_bytes_aligned(src_size)) { 1701 return INTEL_SIP_SMC_STATUS_REJECTED; 1702 } 1703 1704 if (!is_8_bytes_aligned(data_size) || 1705 !is_8_bytes_aligned(src_addr)) { 1706 return INTEL_SIP_SMC_STATUS_REJECTED; 1707 } 1708 1709 if (!is_address_in_ddr_range(src_addr, src_size) || 1710 !is_address_in_ddr_range(dst_addr, *dst_size)) { 1711 return INTEL_SIP_SMC_STATUS_REJECTED; 1712 } 1713 1714 resp_len = *dst_size / MBOX_WORD_BYTE; 1715 1716 /* Prepare crypto header */ 1717 flag = 0; 1718 if (fcs_sha2_data_sig_verify_param.is_updated) 1719 fcs_sha2_data_sig_verify_param.crypto_param_size = 0; 1720 else 1721 flag |= FCS_CS_FIELD_FLAG_INIT; 1722 1723 if (is_finalised != 0U) 1724 flag |= FCS_CS_FIELD_FLAG_FINALIZE; 1725 else { 1726 flag |= FCS_CS_FIELD_FLAG_UPDATE; 1727 fcs_sha2_data_sig_verify_param.is_updated = 1; 1728 } 1729 crypto_header = (flag << FCS_CS_FIELD_FLAG_OFFSET) | 1730 fcs_sha2_data_sig_verify_param.crypto_param_size; 1731 1732 /* Prepare command payload */ 1733 i = 0; 1734 payload[i] = fcs_sha2_data_sig_verify_param.session_id; 1735 i++; 1736 payload[i] = fcs_sha2_data_sig_verify_param.context_id; 1737 i++; 1738 payload[i] = crypto_header; 1739 i++; 1740 1741 if ((crypto_header >> FCS_CS_FIELD_FLAG_OFFSET) & 1742 FCS_CS_FIELD_FLAG_INIT) { 1743 payload[i] = fcs_sha2_data_sig_verify_param.key_id; 1744 i++; 1745 /* Crypto parameters */ 1746 payload[i] = fcs_sha2_data_sig_verify_param.crypto_param 1747 & INTEL_SIP_SMC_FCS_ECC_ALGO_MASK; 1748 i++; 1749 } 1750 1751 /* Data source address and size */ 1752 payload[i] = src_addr; 1753 i++; 1754 payload[i] = data_size; 1755 i++; 1756 1757 if ((crypto_header >> FCS_CS_FIELD_FLAG_OFFSET) & 1758 FCS_CS_FIELD_FLAG_FINALIZE) { 1759 /* Signature + Public Key Data */ 1760 sig_pubkey_offset = src_addr + data_size; 1761 memcpy((uint8_t *) &payload[i], (uint8_t *) sig_pubkey_offset, 1762 src_size - data_size); 1763 1764 i += (src_size - data_size) / MBOX_WORD_BYTE; 1765 } 1766 1767 status = mailbox_send_cmd(MBOX_JOB_ID, 1768 MBOX_FCS_ECDSA_SHA2_DATA_SIGN_VERIFY, payload, i, 1769 CMD_CASUAL, (uint32_t *) dst_addr, &resp_len); 1770 1771 if (is_finalised != 0U) { 1772 memset((void *) &fcs_sha2_data_sig_verify_param, 0, 1773 sizeof(fcs_crypto_service_data)); 1774 } 1775 1776 if (status < 0) { 1777 *mbox_error = -status; 1778 return INTEL_SIP_SMC_STATUS_ERROR; 1779 } 1780 1781 *dst_size = resp_len * MBOX_WORD_BYTE; 1782 flush_dcache_range(dst_addr, *dst_size); 1783 1784 return INTEL_SIP_SMC_STATUS_OK; 1785 } 1786 1787 int intel_fcs_ecdsa_sha2_data_sig_verify_smmu_update_finalize(uint32_t session_id, 1788 uint32_t context_id, uint32_t src_addr, 1789 uint32_t src_size, uint64_t dst_addr, 1790 uint32_t *dst_size, uint32_t data_size, 1791 uint8_t is_finalised, uint32_t *mbox_error, 1792 uint32_t *send_id) 1793 { 1794 int status; 1795 uint32_t i; 1796 uint32_t flag; 1797 uint32_t crypto_header; 1798 uint32_t payload[FCS_ECDSA_SHA2_DATA_SIG_VERIFY_CMD_MAX_WORD_SIZE] = {0U}; 1799 uint32_t resp_len; 1800 uintptr_t sig_pubkey_offset; 1801 1802 /* 1803 * Source data must be 4 bytes aligned 1804 * Source addrress must be 8 bytes aligned 1805 * User data must be 8 bytes aligned 1806 */ 1807 if ((dst_size == NULL) || (mbox_error == NULL) || 1808 !is_size_4_bytes_aligned(src_size) || 1809 !is_8_bytes_aligned(src_addr) || 1810 !is_8_bytes_aligned(data_size)) { 1811 return INTEL_SIP_SMC_STATUS_REJECTED; 1812 } 1813 1814 if (fcs_sha2_data_sig_verify_param.session_id != session_id || 1815 fcs_sha2_data_sig_verify_param.context_id != context_id) { 1816 return INTEL_SIP_SMC_STATUS_REJECTED; 1817 } 1818 1819 if (!is_address_in_ddr_range(src_addr, src_size) || 1820 !is_address_in_ddr_range(dst_addr, *dst_size)) { 1821 return INTEL_SIP_SMC_STATUS_REJECTED; 1822 } 1823 1824 resp_len = *dst_size / MBOX_WORD_BYTE; 1825 1826 /* Prepare crypto header */ 1827 flag = 0; 1828 if (fcs_sha2_data_sig_verify_param.is_updated) 1829 fcs_sha2_data_sig_verify_param.crypto_param_size = 0; 1830 else 1831 flag |= FCS_CS_FIELD_FLAG_INIT; 1832 1833 if (is_finalised != 0U) 1834 flag |= FCS_CS_FIELD_FLAG_FINALIZE; 1835 else { 1836 flag |= FCS_CS_FIELD_FLAG_UPDATE; 1837 fcs_sha2_data_sig_verify_param.is_updated = 1; 1838 } 1839 crypto_header = (flag << FCS_CS_FIELD_FLAG_OFFSET) | 1840 fcs_sha2_data_sig_verify_param.crypto_param_size; 1841 1842 /* Prepare command payload */ 1843 i = 0; 1844 payload[i] = fcs_sha2_data_sig_verify_param.session_id; 1845 i++; 1846 payload[i] = fcs_sha2_data_sig_verify_param.context_id; 1847 i++; 1848 payload[i] = crypto_header; 1849 i++; 1850 1851 if ((crypto_header >> FCS_CS_FIELD_FLAG_OFFSET) & 1852 FCS_CS_FIELD_FLAG_INIT) { 1853 payload[i] = fcs_sha2_data_sig_verify_param.key_id; 1854 i++; 1855 /* Crypto parameters */ 1856 payload[i] = fcs_sha2_data_sig_verify_param.crypto_param 1857 & INTEL_SIP_SMC_FCS_ECC_ALGO_MASK; 1858 i++; 1859 } 1860 1861 /* Data source address and size */ 1862 payload[i] = src_addr; 1863 i++; 1864 payload[i] = data_size; 1865 i++; 1866 1867 if ((crypto_header >> FCS_CS_FIELD_FLAG_OFFSET) & 1868 FCS_CS_FIELD_FLAG_FINALIZE) { 1869 /* Copy mac data to command 1870 * Using dst_addr (physical address) to store sig_pubkey_offset 1871 * sig_pubkey_offset is Signature + Public Key Data 1872 */ 1873 sig_pubkey_offset = dst_addr; 1874 memcpy((uint8_t *) &payload[i], (uint8_t *) sig_pubkey_offset, 1875 src_size - data_size); 1876 1877 memset((void *)&dst_addr, 0, sizeof(dst_size)); 1878 1879 i += (src_size - data_size) / MBOX_WORD_BYTE; 1880 } 1881 1882 status = mailbox_send_cmd_async(send_id, 1883 MBOX_FCS_ECDSA_SHA2_DATA_SIGN_VERIFY, 1884 payload, i, CMD_INDIRECT); 1885 1886 if (is_finalised != 0U) { 1887 memset((void *) &fcs_sha2_data_sig_verify_param, 0, 1888 sizeof(fcs_crypto_service_data)); 1889 } 1890 1891 if (status < 0) { 1892 *mbox_error = -status; 1893 return INTEL_SIP_SMC_STATUS_ERROR; 1894 } 1895 1896 *dst_size = resp_len * MBOX_WORD_BYTE; 1897 flush_dcache_range(dst_addr, *dst_size); 1898 1899 return INTEL_SIP_SMC_STATUS_OK; 1900 } 1901 1902 int intel_fcs_ecdsa_get_pubkey_init(uint32_t session_id, uint32_t context_id, 1903 uint32_t key_id, uint32_t param_size, 1904 uint64_t param_data, uint32_t *mbox_error) 1905 { 1906 return intel_fcs_crypto_service_init(session_id, context_id, 1907 key_id, param_size, param_data, 1908 (void *) &fcs_ecdsa_get_pubkey_param, 1909 mbox_error); 1910 } 1911 1912 int intel_fcs_ecdsa_get_pubkey_finalize(uint32_t session_id, uint32_t context_id, 1913 uint64_t dst_addr, uint32_t *dst_size, 1914 uint32_t *mbox_error) 1915 { 1916 int status; 1917 int i; 1918 uint32_t crypto_header; 1919 uint32_t ret_size; 1920 uint32_t payload[FCS_ECDSA_GET_PUBKEY_MAX_WORD_SIZE] = {0U}; 1921 1922 if ((dst_size == NULL) || (mbox_error == NULL)) { 1923 return INTEL_SIP_SMC_STATUS_REJECTED; 1924 } 1925 1926 if (fcs_ecdsa_get_pubkey_param.session_id != session_id || 1927 fcs_ecdsa_get_pubkey_param.context_id != context_id) { 1928 return INTEL_SIP_SMC_STATUS_REJECTED; 1929 } 1930 1931 ret_size = *dst_size / MBOX_WORD_BYTE; 1932 1933 crypto_header = ((FCS_CS_FIELD_FLAG_INIT | 1934 FCS_CS_FIELD_FLAG_UPDATE | 1935 FCS_CS_FIELD_FLAG_FINALIZE) << 1936 FCS_CS_FIELD_FLAG_OFFSET) | 1937 fcs_ecdsa_get_pubkey_param.crypto_param_size; 1938 i = 0; 1939 /* Prepare command payload */ 1940 payload[i] = session_id; 1941 i++; 1942 payload[i] = context_id; 1943 i++; 1944 payload[i] = crypto_header; 1945 i++; 1946 payload[i] = fcs_ecdsa_get_pubkey_param.key_id; 1947 i++; 1948 payload[i] = (uint32_t) fcs_ecdsa_get_pubkey_param.crypto_param & 1949 INTEL_SIP_SMC_FCS_ECC_ALGO_MASK; 1950 i++; 1951 1952 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_ECDSA_GET_PUBKEY, 1953 payload, i, CMD_CASUAL, 1954 (uint32_t *) dst_addr, &ret_size); 1955 1956 memset((void *) &fcs_ecdsa_get_pubkey_param, 0, 1957 sizeof(fcs_crypto_service_data)); 1958 1959 if (status < 0) { 1960 *mbox_error = -status; 1961 return INTEL_SIP_SMC_STATUS_ERROR; 1962 } 1963 1964 *dst_size = ret_size * MBOX_WORD_BYTE; 1965 flush_dcache_range(dst_addr, *dst_size); 1966 1967 return INTEL_SIP_SMC_STATUS_OK; 1968 } 1969 1970 int intel_fcs_ecdh_request_init(uint32_t session_id, uint32_t context_id, 1971 uint32_t key_id, uint32_t param_size, 1972 uint64_t param_data, uint32_t *mbox_error) 1973 { 1974 return intel_fcs_crypto_service_init(session_id, context_id, 1975 key_id, param_size, param_data, 1976 (void *) &fcs_ecdh_request_param, 1977 mbox_error); 1978 } 1979 1980 int intel_fcs_ecdh_request_finalize(uint32_t session_id, uint32_t context_id, 1981 uint32_t src_addr, uint32_t src_size, 1982 uint64_t dst_addr, uint32_t *dst_size, 1983 uint32_t *mbox_error) 1984 { 1985 int status; 1986 uint32_t i; 1987 uint32_t payload[FCS_ECDH_REQUEST_CMD_MAX_WORD_SIZE] = {0U}; 1988 uint32_t resp_len; 1989 uintptr_t pubkey; 1990 1991 if ((dst_size == NULL) || (mbox_error == NULL)) { 1992 return INTEL_SIP_SMC_STATUS_REJECTED; 1993 } 1994 1995 if (fcs_ecdh_request_param.session_id != session_id || 1996 fcs_ecdh_request_param.context_id != context_id) { 1997 return INTEL_SIP_SMC_STATUS_REJECTED; 1998 } 1999 2000 if (!is_address_in_ddr_range(src_addr, src_size) || 2001 !is_address_in_ddr_range(dst_addr, *dst_size)) { 2002 return INTEL_SIP_SMC_STATUS_REJECTED; 2003 } 2004 2005 resp_len = *dst_size / MBOX_WORD_BYTE; 2006 2007 /* Prepare command payload */ 2008 i = 0; 2009 /* Crypto header */ 2010 payload[i] = fcs_ecdh_request_param.session_id; 2011 i++; 2012 payload[i] = fcs_ecdh_request_param.context_id; 2013 i++; 2014 payload[i] = fcs_ecdh_request_param.crypto_param_size 2015 & FCS_CS_FIELD_SIZE_MASK; 2016 payload[i] |= (FCS_CS_FIELD_FLAG_INIT | FCS_CS_FIELD_FLAG_UPDATE 2017 | FCS_CS_FIELD_FLAG_FINALIZE) 2018 << FCS_CS_FIELD_FLAG_OFFSET; 2019 i++; 2020 payload[i] = fcs_ecdh_request_param.key_id; 2021 i++; 2022 /* Crypto parameters */ 2023 payload[i] = fcs_ecdh_request_param.crypto_param 2024 & INTEL_SIP_SMC_FCS_ECC_ALGO_MASK; 2025 i++; 2026 /* Public key data */ 2027 pubkey = src_addr; 2028 memcpy((uint8_t *) &payload[i], (uint8_t *) pubkey, src_size); 2029 i += src_size / MBOX_WORD_BYTE; 2030 2031 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_ECDH_REQUEST, 2032 payload, i, CMD_CASUAL, (uint32_t *) dst_addr, 2033 &resp_len); 2034 2035 memset((void *)&fcs_ecdh_request_param, 0, 2036 sizeof(fcs_crypto_service_data)); 2037 2038 if (status < 0) { 2039 *mbox_error = -status; 2040 return INTEL_SIP_SMC_STATUS_ERROR; 2041 } 2042 2043 *dst_size = resp_len * MBOX_WORD_BYTE; 2044 flush_dcache_range(dst_addr, *dst_size); 2045 2046 return INTEL_SIP_SMC_STATUS_OK; 2047 } 2048 2049 int intel_fcs_aes_crypt_init(uint32_t session_id, uint32_t context_id, 2050 uint32_t key_id, uint64_t param_addr, 2051 uint32_t param_size, uint32_t *mbox_error) 2052 { 2053 /* ptr to get param_addr value */ 2054 uint64_t *param_addr_ptr; 2055 2056 param_addr_ptr = (uint64_t *) param_addr; 2057 2058 /* 2059 * Since crypto param size vary between mode. 2060 * Check ECB here and limit to size 12 bytes 2061 */ 2062 if (((*param_addr_ptr & FCS_CRYPTO_BLOCK_MODE_MASK) == FCS_CRYPTO_ECB_MODE) && 2063 (param_size > FCS_CRYPTO_ECB_BUFFER_SIZE)) { 2064 return INTEL_SIP_SMC_STATUS_REJECTED; 2065 } 2066 /* 2067 * Since crypto param size vary between mode. 2068 * Check CBC/CTR here and limit to size 28 bytes 2069 */ 2070 if ((((*param_addr_ptr & FCS_CRYPTO_BLOCK_MODE_MASK) == FCS_CRYPTO_CBC_MODE) || 2071 ((*param_addr_ptr & FCS_CRYPTO_BLOCK_MODE_MASK) == FCS_CRYPTO_CTR_MODE)) && 2072 (param_size > FCS_CRYPTO_CBC_CTR_BUFFER_SIZE)) { 2073 return INTEL_SIP_SMC_STATUS_REJECTED; 2074 } 2075 2076 if (mbox_error == NULL) { 2077 return INTEL_SIP_SMC_STATUS_REJECTED; 2078 } 2079 2080 memset((void *)&fcs_aes_init_payload, 0U, sizeof(fcs_aes_init_payload)); 2081 2082 fcs_aes_init_payload.session_id = session_id; 2083 fcs_aes_init_payload.context_id = context_id; 2084 fcs_aes_init_payload.param_size = param_size; 2085 fcs_aes_init_payload.key_id = key_id; 2086 2087 memcpy((uint8_t *) fcs_aes_init_payload.crypto_param, 2088 (uint8_t *) param_addr, param_size); 2089 2090 fcs_aes_init_payload.is_updated = 0; 2091 2092 *mbox_error = 0; 2093 2094 return INTEL_SIP_SMC_STATUS_OK; 2095 } 2096 2097 int intel_fcs_aes_crypt_update_finalize(uint32_t session_id, 2098 uint32_t context_id, uint64_t src_addr, 2099 uint32_t src_size, uint64_t dst_addr, 2100 uint32_t dst_size, uint8_t is_finalised, 2101 uint32_t *send_id) 2102 { 2103 int status; 2104 int i; 2105 uint32_t flag; 2106 uint32_t crypto_header; 2107 uint32_t fcs_aes_crypt_payload[FCS_AES_CMD_MAX_WORD_SIZE]; 2108 2109 if (fcs_aes_init_payload.session_id != session_id || 2110 fcs_aes_init_payload.context_id != context_id) { 2111 return INTEL_SIP_SMC_STATUS_REJECTED; 2112 } 2113 2114 if ((!is_8_bytes_aligned(src_addr)) || 2115 (!is_32_bytes_aligned(src_size)) || 2116 (!is_address_in_ddr_range(src_addr, src_size))) { 2117 return INTEL_SIP_SMC_STATUS_REJECTED; 2118 } 2119 2120 if ((!is_8_bytes_aligned(dst_addr)) || 2121 (!is_32_bytes_aligned(dst_size))) { 2122 return INTEL_SIP_SMC_STATUS_REJECTED; 2123 } 2124 2125 if ((dst_size > FCS_AES_MAX_DATA_SIZE || 2126 dst_size < FCS_AES_MIN_DATA_SIZE) || 2127 (src_size > FCS_AES_MAX_DATA_SIZE || 2128 src_size < FCS_AES_MIN_DATA_SIZE)) { 2129 return INTEL_SIP_SMC_STATUS_REJECTED; 2130 } 2131 2132 /* Prepare crypto header*/ 2133 flag = 0; 2134 if (fcs_aes_init_payload.is_updated) { 2135 fcs_aes_init_payload.param_size = 0; 2136 } else { 2137 flag |= FCS_CS_FIELD_FLAG_INIT; 2138 } 2139 2140 if (is_finalised != 0U) { 2141 flag |= FCS_CS_FIELD_FLAG_FINALIZE; 2142 } else { 2143 flag |= FCS_CS_FIELD_FLAG_UPDATE; 2144 fcs_aes_init_payload.is_updated = 1; 2145 } 2146 crypto_header = (flag << FCS_CS_FIELD_FLAG_OFFSET) | 2147 fcs_aes_init_payload.param_size; 2148 2149 i = 0U; 2150 fcs_aes_crypt_payload[i] = session_id; 2151 i++; 2152 fcs_aes_crypt_payload[i] = context_id; 2153 i++; 2154 fcs_aes_crypt_payload[i] = crypto_header; 2155 i++; 2156 2157 if ((crypto_header >> FCS_CS_FIELD_FLAG_OFFSET) & 2158 FCS_CS_FIELD_FLAG_INIT) { 2159 fcs_aes_crypt_payload[i] = fcs_aes_init_payload.key_id; 2160 i++; 2161 2162 memcpy((uint8_t *) &fcs_aes_crypt_payload[i], 2163 (uint8_t *) fcs_aes_init_payload.crypto_param, 2164 fcs_aes_init_payload.param_size); 2165 2166 i += fcs_aes_init_payload.param_size / MBOX_WORD_BYTE; 2167 } 2168 2169 fcs_aes_crypt_payload[i] = (uint32_t) src_addr; 2170 i++; 2171 fcs_aes_crypt_payload[i] = src_size; 2172 i++; 2173 fcs_aes_crypt_payload[i] = (uint32_t) dst_addr; 2174 i++; 2175 fcs_aes_crypt_payload[i] = dst_size; 2176 i++; 2177 2178 status = mailbox_send_cmd_async(send_id, MBOX_FCS_AES_CRYPT_REQ, 2179 fcs_aes_crypt_payload, i, 2180 CMD_INDIRECT); 2181 2182 if (is_finalised != 0U) { 2183 memset((void *)&fcs_aes_init_payload, 0, 2184 sizeof(fcs_aes_init_payload)); 2185 } 2186 2187 if (status < 0U) { 2188 return INTEL_SIP_SMC_STATUS_ERROR; 2189 } 2190 2191 return INTEL_SIP_SMC_STATUS_OK; 2192 } 2193