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