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 uint32_t intel_fcs_get_rom_patch_sha384(uint64_t addr, uint64_t *ret_size, 319 uint32_t *mbox_error) 320 { 321 int status; 322 unsigned int resp_len = FCS_SHA384_WORD_SIZE; 323 324 if (!is_address_in_ddr_range(addr, FCS_SHA384_BYTE_SIZE)) { 325 return INTEL_SIP_SMC_STATUS_REJECTED; 326 } 327 328 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_GET_ROM_PATCH_SHA384, NULL, 0U, 329 CMD_CASUAL, (uint32_t *) addr, &resp_len); 330 331 if (status < 0) { 332 *mbox_error = -status; 333 return INTEL_SIP_SMC_STATUS_ERROR; 334 } 335 336 if (resp_len != FCS_SHA384_WORD_SIZE) { 337 *mbox_error = GENERIC_RESPONSE_ERROR; 338 return INTEL_SIP_SMC_STATUS_ERROR; 339 } 340 341 *ret_size = FCS_SHA384_BYTE_SIZE; 342 343 flush_dcache_range(addr, *ret_size); 344 345 return INTEL_SIP_SMC_STATUS_OK; 346 } 347 348 int intel_fcs_encryption_ext(uint32_t session_id, uint32_t context_id, 349 uint32_t src_addr, uint32_t src_size, 350 uint32_t dst_addr, uint32_t *dst_size, uint32_t *mbox_error) 351 { 352 int status; 353 uint32_t payload_size; 354 uint32_t resp_len = FCS_CRYPTION_RESP_WORD_SIZE; 355 uint32_t resp_data[FCS_CRYPTION_RESP_WORD_SIZE] = {0U}; 356 357 if ((dst_size == NULL) || (mbox_error == NULL)) { 358 return INTEL_SIP_SMC_STATUS_REJECTED; 359 } 360 361 if (!is_address_in_ddr_range(src_addr, src_size) || 362 !is_address_in_ddr_range(dst_addr, *dst_size)) { 363 return INTEL_SIP_SMC_STATUS_REJECTED; 364 } 365 366 if (!is_size_4_bytes_aligned(src_size)) { 367 return INTEL_SIP_SMC_STATUS_REJECTED; 368 } 369 370 fcs_encrypt_ext_payload payload = { 371 session_id, 372 context_id, 373 FCS_CRYPTION_CRYPTO_HEADER, 374 src_addr, 375 src_size, 376 dst_addr, 377 *dst_size 378 }; 379 380 payload_size = sizeof(payload) / MBOX_WORD_BYTE; 381 382 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_ENCRYPT_REQ, 383 (uint32_t *) &payload, payload_size, 384 CMD_CASUAL, resp_data, &resp_len); 385 386 if (status < 0) { 387 *mbox_error = -status; 388 return INTEL_SIP_SMC_STATUS_ERROR; 389 } 390 391 if (resp_len != FCS_CRYPTION_RESP_WORD_SIZE) { 392 *mbox_error = MBOX_RET_ERROR; 393 return INTEL_SIP_SMC_STATUS_ERROR; 394 } 395 396 *dst_size = resp_data[FCS_CRYPTION_RESP_SIZE_OFFSET]; 397 inv_dcache_range(dst_addr, *dst_size); 398 399 return INTEL_SIP_SMC_STATUS_OK; 400 } 401 402 int intel_fcs_decryption_ext(uint32_t session_id, uint32_t context_id, 403 uint32_t src_addr, uint32_t src_size, 404 uint32_t dst_addr, uint32_t *dst_size, uint32_t *mbox_error) 405 { 406 int status; 407 uintptr_t id_offset; 408 uint32_t payload_size; 409 uint32_t resp_len = FCS_CRYPTION_RESP_WORD_SIZE; 410 uint32_t resp_data[FCS_CRYPTION_RESP_WORD_SIZE] = {0U}; 411 412 if ((dst_size == NULL) || (mbox_error == NULL)) { 413 return INTEL_SIP_SMC_STATUS_REJECTED; 414 } 415 416 if (!is_address_in_ddr_range(src_addr, src_size) || 417 !is_address_in_ddr_range(dst_addr, *dst_size)) { 418 return INTEL_SIP_SMC_STATUS_REJECTED; 419 } 420 421 if (!is_size_4_bytes_aligned(src_size)) { 422 return INTEL_SIP_SMC_STATUS_REJECTED; 423 } 424 425 id_offset = src_addr + FCS_OWNER_ID_OFFSET; 426 fcs_decrypt_ext_payload payload = { 427 session_id, 428 context_id, 429 FCS_CRYPTION_CRYPTO_HEADER, 430 {mmio_read_32(id_offset), 431 mmio_read_32(id_offset + MBOX_WORD_BYTE)}, 432 src_addr, 433 src_size, 434 dst_addr, 435 *dst_size 436 }; 437 438 payload_size = sizeof(payload) / MBOX_WORD_BYTE; 439 440 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_DECRYPT_REQ, 441 (uint32_t *) &payload, payload_size, 442 CMD_CASUAL, resp_data, &resp_len); 443 444 if (status < 0) { 445 *mbox_error = -status; 446 return INTEL_SIP_SMC_STATUS_ERROR; 447 } 448 449 if (resp_len != FCS_CRYPTION_RESP_WORD_SIZE) { 450 *mbox_error = MBOX_RET_ERROR; 451 return INTEL_SIP_SMC_STATUS_ERROR; 452 } 453 454 *dst_size = resp_data[FCS_CRYPTION_RESP_SIZE_OFFSET]; 455 inv_dcache_range(dst_addr, *dst_size); 456 457 return INTEL_SIP_SMC_STATUS_OK; 458 } 459 460 int intel_fcs_sigma_teardown(uint32_t session_id, uint32_t *mbox_error) 461 { 462 int status; 463 464 if ((session_id != PSGSIGMA_SESSION_ID_ONE) && 465 (session_id != PSGSIGMA_UNKNOWN_SESSION)) { 466 return INTEL_SIP_SMC_STATUS_REJECTED; 467 } 468 469 psgsigma_teardown_msg message = { 470 RESERVED_AS_ZERO, 471 PSGSIGMA_TEARDOWN_MAGIC, 472 session_id 473 }; 474 475 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_PSG_SIGMA_TEARDOWN, 476 (uint32_t *) &message, sizeof(message) / MBOX_WORD_BYTE, 477 CMD_CASUAL, NULL, NULL); 478 479 if (status < 0) { 480 *mbox_error = -status; 481 return INTEL_SIP_SMC_STATUS_ERROR; 482 } 483 484 return INTEL_SIP_SMC_STATUS_OK; 485 } 486 487 int intel_fcs_chip_id(uint32_t *id_low, uint32_t *id_high, uint32_t *mbox_error) 488 { 489 int status; 490 uint32_t load_size; 491 uint32_t chip_id[2]; 492 493 load_size = sizeof(chip_id) / MBOX_WORD_BYTE; 494 495 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_CMD_GET_CHIPID, NULL, 496 0U, CMD_CASUAL, (uint32_t *) chip_id, &load_size); 497 498 if (status < 0) { 499 *mbox_error = -status; 500 return INTEL_SIP_SMC_STATUS_ERROR; 501 } 502 503 *id_low = chip_id[0]; 504 *id_high = chip_id[1]; 505 506 return INTEL_SIP_SMC_STATUS_OK; 507 } 508 509 int intel_fcs_attestation_subkey(uint64_t src_addr, uint32_t src_size, 510 uint64_t dst_addr, uint32_t *dst_size, uint32_t *mbox_error) 511 { 512 int status; 513 uint32_t send_size = src_size / MBOX_WORD_BYTE; 514 uint32_t ret_size = *dst_size / MBOX_WORD_BYTE; 515 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_ATTESTATION_SUBKEY, 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 int intel_fcs_get_measurement(uint64_t src_addr, uint32_t src_size, 538 uint64_t dst_addr, uint32_t *dst_size, uint32_t *mbox_error) 539 { 540 int status; 541 uint32_t send_size = src_size / MBOX_WORD_BYTE; 542 uint32_t ret_size = *dst_size / MBOX_WORD_BYTE; 543 544 if (!is_address_in_ddr_range(src_addr, src_size) || 545 !is_address_in_ddr_range(dst_addr, *dst_size)) { 546 return INTEL_SIP_SMC_STATUS_REJECTED; 547 } 548 549 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_GET_MEASUREMENT, 550 (uint32_t *) src_addr, send_size, CMD_CASUAL, 551 (uint32_t *) dst_addr, &ret_size); 552 553 if (status < 0) { 554 *mbox_error = -status; 555 return INTEL_SIP_SMC_STATUS_ERROR; 556 } 557 558 *dst_size = ret_size * MBOX_WORD_BYTE; 559 flush_dcache_range(dst_addr, *dst_size); 560 561 return INTEL_SIP_SMC_STATUS_OK; 562 } 563 564 int intel_fcs_get_attestation_cert(uint32_t cert_request, uint64_t dst_addr, 565 uint32_t *dst_size, uint32_t *mbox_error) 566 { 567 int status; 568 uint32_t ret_size = *dst_size / MBOX_WORD_BYTE; 569 570 if (mbox_error == NULL) { 571 return INTEL_SIP_SMC_STATUS_REJECTED; 572 } 573 574 if (cert_request < FCS_ATTEST_FIRMWARE_CERT || 575 cert_request > FCS_ATTEST_CERT_MAX_REQ_PARAM) { 576 return INTEL_SIP_SMC_STATUS_REJECTED; 577 } 578 579 if (!is_address_in_ddr_range(dst_addr, *dst_size)) { 580 return INTEL_SIP_SMC_STATUS_REJECTED; 581 } 582 583 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_GET_ATTESTATION_CERT, 584 (uint32_t *) &cert_request, 1U, CMD_CASUAL, 585 (uint32_t *) dst_addr, &ret_size); 586 587 if (status < 0) { 588 *mbox_error = -status; 589 return INTEL_SIP_SMC_STATUS_ERROR; 590 } 591 592 *dst_size = ret_size * MBOX_WORD_BYTE; 593 flush_dcache_range(dst_addr, *dst_size); 594 595 return INTEL_SIP_SMC_STATUS_OK; 596 } 597 598 int intel_fcs_create_cert_on_reload(uint32_t cert_request, 599 uint32_t *mbox_error) 600 { 601 int status; 602 603 if (mbox_error == NULL) { 604 return INTEL_SIP_SMC_STATUS_REJECTED; 605 } 606 607 if (cert_request < FCS_ATTEST_FIRMWARE_CERT || 608 cert_request > FCS_ATTEST_CERT_MAX_REQ_PARAM) { 609 return INTEL_SIP_SMC_STATUS_REJECTED; 610 } 611 612 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_CREATE_CERT_ON_RELOAD, 613 (uint32_t *) &cert_request, 1U, CMD_CASUAL, 614 NULL, NULL); 615 616 if (status < 0) { 617 *mbox_error = -status; 618 return INTEL_SIP_SMC_STATUS_ERROR; 619 } 620 621 return INTEL_SIP_SMC_STATUS_OK; 622 } 623 624 int intel_fcs_open_crypto_service_session(uint32_t *session_id, 625 uint32_t *mbox_error) 626 { 627 int status; 628 uint32_t resp_len = 1U; 629 630 if ((session_id == NULL) || (mbox_error == NULL)) { 631 return INTEL_SIP_SMC_STATUS_REJECTED; 632 } 633 634 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_OPEN_CS_SESSION, 635 NULL, 0U, CMD_CASUAL, session_id, &resp_len); 636 637 if (status < 0) { 638 *mbox_error = -status; 639 return INTEL_SIP_SMC_STATUS_ERROR; 640 } 641 642 return INTEL_SIP_SMC_STATUS_OK; 643 } 644 645 int intel_fcs_close_crypto_service_session(uint32_t session_id, 646 uint32_t *mbox_error) 647 { 648 int status; 649 650 if (mbox_error == NULL) { 651 return INTEL_SIP_SMC_STATUS_REJECTED; 652 } 653 654 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_CLOSE_CS_SESSION, 655 &session_id, 1U, CMD_CASUAL, NULL, NULL); 656 657 if (status < 0) { 658 *mbox_error = -status; 659 return INTEL_SIP_SMC_STATUS_ERROR; 660 } 661 662 return INTEL_SIP_SMC_STATUS_OK; 663 } 664 665 int intel_fcs_import_crypto_service_key(uint64_t src_addr, uint32_t src_size, 666 uint32_t *send_id) 667 { 668 int status; 669 670 if (src_size > (FCS_CS_KEY_OBJ_MAX_WORD_SIZE * 671 MBOX_WORD_BYTE)) { 672 return INTEL_SIP_SMC_STATUS_REJECTED; 673 } 674 675 if (!is_address_in_ddr_range(src_addr, src_size)) { 676 return INTEL_SIP_SMC_STATUS_REJECTED; 677 } 678 679 status = mailbox_send_cmd_async(send_id, MBOX_FCS_IMPORT_CS_KEY, 680 (uint32_t *)src_addr, src_size / MBOX_WORD_BYTE, 681 CMD_INDIRECT); 682 683 if (status < 0) { 684 return INTEL_SIP_SMC_STATUS_ERROR; 685 } 686 687 return INTEL_SIP_SMC_STATUS_OK; 688 } 689 690 int intel_fcs_export_crypto_service_key(uint32_t session_id, uint32_t key_id, 691 uint64_t dst_addr, uint32_t *dst_size, 692 uint32_t *mbox_error) 693 { 694 int status; 695 uint32_t i; 696 uint32_t payload_size; 697 uint32_t resp_len = FCS_CS_KEY_OBJ_MAX_WORD_SIZE; 698 uint32_t resp_data[FCS_CS_KEY_OBJ_MAX_WORD_SIZE] = {0U}; 699 uint32_t op_status = 0U; 700 701 if ((dst_size == NULL) || (mbox_error == NULL)) { 702 return INTEL_SIP_SMC_STATUS_REJECTED; 703 } 704 705 if (!is_address_in_ddr_range(dst_addr, *dst_size)) { 706 return INTEL_SIP_SMC_STATUS_REJECTED; 707 } 708 709 fcs_cs_key_payload payload = { 710 session_id, 711 RESERVED_AS_ZERO, 712 RESERVED_AS_ZERO, 713 key_id 714 }; 715 716 payload_size = sizeof(payload) / MBOX_WORD_BYTE; 717 718 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_EXPORT_CS_KEY, 719 (uint32_t *) &payload, payload_size, 720 CMD_CASUAL, resp_data, &resp_len); 721 722 if (resp_len > 0) { 723 op_status = resp_data[0] & FCS_CS_KEY_RESP_STATUS_MASK; 724 } 725 726 if (status < 0) { 727 *mbox_error = (-status) | (op_status << FCS_CS_KEY_RESP_STATUS_OFFSET); 728 return INTEL_SIP_SMC_STATUS_ERROR; 729 } 730 731 if (resp_len > 1) { 732 733 /* Export key object is start at second response data */ 734 *dst_size = (resp_len - 1) * MBOX_WORD_BYTE; 735 736 for (i = 1U; i < resp_len; i++) { 737 mmio_write_32(dst_addr, resp_data[i]); 738 dst_addr += MBOX_WORD_BYTE; 739 } 740 741 flush_dcache_range(dst_addr - *dst_size, *dst_size); 742 743 } else { 744 745 /* Unexpected response, missing key object in response */ 746 *mbox_error = MBOX_RET_ERROR; 747 return INTEL_SIP_SMC_STATUS_ERROR; 748 } 749 750 return INTEL_SIP_SMC_STATUS_OK; 751 } 752 753 int intel_fcs_remove_crypto_service_key(uint32_t session_id, uint32_t key_id, 754 uint32_t *mbox_error) 755 { 756 int status; 757 uint32_t payload_size; 758 uint32_t resp_len = 1U; 759 uint32_t resp_data = 0U; 760 uint32_t op_status = 0U; 761 762 if (mbox_error == NULL) { 763 return INTEL_SIP_SMC_STATUS_REJECTED; 764 } 765 766 fcs_cs_key_payload payload = { 767 session_id, 768 RESERVED_AS_ZERO, 769 RESERVED_AS_ZERO, 770 key_id 771 }; 772 773 payload_size = sizeof(payload) / MBOX_WORD_BYTE; 774 775 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_REMOVE_CS_KEY, 776 (uint32_t *) &payload, payload_size, 777 CMD_CASUAL, &resp_data, &resp_len); 778 779 if (resp_len > 0) { 780 op_status = resp_data & FCS_CS_KEY_RESP_STATUS_MASK; 781 } 782 783 if (status < 0) { 784 *mbox_error = (-status) | (op_status << FCS_CS_KEY_RESP_STATUS_OFFSET); 785 return INTEL_SIP_SMC_STATUS_ERROR; 786 } 787 788 return INTEL_SIP_SMC_STATUS_OK; 789 } 790 791 int intel_fcs_get_crypto_service_key_info(uint32_t session_id, uint32_t key_id, 792 uint64_t dst_addr, uint32_t *dst_size, 793 uint32_t *mbox_error) 794 { 795 int status; 796 uint32_t payload_size; 797 uint32_t resp_len = FCS_CS_KEY_INFO_MAX_WORD_SIZE; 798 uint32_t op_status = 0U; 799 800 if ((dst_size == NULL) || (mbox_error == NULL)) { 801 return INTEL_SIP_SMC_STATUS_REJECTED; 802 } 803 804 if (!is_address_in_ddr_range(dst_addr, *dst_size)) { 805 return INTEL_SIP_SMC_STATUS_REJECTED; 806 } 807 808 fcs_cs_key_payload payload = { 809 session_id, 810 RESERVED_AS_ZERO, 811 RESERVED_AS_ZERO, 812 key_id 813 }; 814 815 payload_size = sizeof(payload) / MBOX_WORD_BYTE; 816 817 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_GET_CS_KEY_INFO, 818 (uint32_t *) &payload, payload_size, 819 CMD_CASUAL, (uint32_t *) dst_addr, &resp_len); 820 821 if (resp_len > 0) { 822 op_status = mmio_read_32(dst_addr) & 823 FCS_CS_KEY_RESP_STATUS_MASK; 824 } 825 826 if (status < 0) { 827 *mbox_error = (-status) | (op_status << FCS_CS_KEY_RESP_STATUS_OFFSET); 828 return INTEL_SIP_SMC_STATUS_ERROR; 829 } 830 831 *dst_size = resp_len * MBOX_WORD_BYTE; 832 flush_dcache_range(dst_addr, *dst_size); 833 834 return INTEL_SIP_SMC_STATUS_OK; 835 } 836 837 int intel_fcs_get_digest_init(uint32_t session_id, uint32_t context_id, 838 uint32_t key_id, uint32_t param_size, 839 uint64_t param_data, uint32_t *mbox_error) 840 { 841 return intel_fcs_crypto_service_init(session_id, context_id, 842 key_id, param_size, param_data, 843 (void *) &fcs_sha_get_digest_param, 844 mbox_error); 845 } 846 847 int intel_fcs_get_digest_finalize(uint32_t session_id, uint32_t context_id, 848 uint32_t src_addr, uint32_t src_size, 849 uint64_t dst_addr, uint32_t *dst_size, 850 uint32_t *mbox_error) 851 { 852 int status; 853 uint32_t i; 854 uint32_t resp_len; 855 uint32_t payload[FCS_GET_DIGEST_CMD_MAX_WORD_SIZE] = {0U}; 856 857 if (dst_size == NULL || mbox_error == NULL) { 858 return INTEL_SIP_SMC_STATUS_REJECTED; 859 } 860 861 if (fcs_sha_get_digest_param.session_id != session_id || 862 fcs_sha_get_digest_param.context_id != context_id) { 863 return INTEL_SIP_SMC_STATUS_REJECTED; 864 } 865 866 /* Source data must be 8 bytes aligned */ 867 if (!is_8_bytes_aligned(src_size)) { 868 return INTEL_SIP_SMC_STATUS_REJECTED; 869 } 870 871 if (!is_address_in_ddr_range(src_addr, src_size) || 872 !is_address_in_ddr_range(dst_addr, *dst_size)) { 873 return INTEL_SIP_SMC_STATUS_REJECTED; 874 } 875 876 resp_len = *dst_size / MBOX_WORD_BYTE; 877 878 /* Prepare command payload */ 879 i = 0; 880 /* Crypto header */ 881 payload[i] = fcs_sha_get_digest_param.session_id; 882 i++; 883 payload[i] = fcs_sha_get_digest_param.context_id; 884 i++; 885 payload[i] = fcs_sha_get_digest_param.crypto_param_size 886 & FCS_CS_FIELD_SIZE_MASK; 887 payload[i] |= (FCS_CS_FIELD_FLAG_INIT | FCS_CS_FIELD_FLAG_UPDATE 888 | FCS_CS_FIELD_FLAG_FINALIZE) 889 << FCS_CS_FIELD_FLAG_OFFSET; 890 i++; 891 payload[i] = fcs_sha_get_digest_param.key_id; 892 i++; 893 /* Crypto parameters */ 894 payload[i] = fcs_sha_get_digest_param.crypto_param 895 & INTEL_SIP_SMC_FCS_SHA_MODE_MASK; 896 payload[i] |= ((fcs_sha_get_digest_param.crypto_param 897 >> INTEL_SIP_SMC_FCS_DIGEST_SIZE_OFFSET) 898 & INTEL_SIP_SMC_FCS_DIGEST_SIZE_MASK) 899 << FCS_SHA_HMAC_CRYPTO_PARAM_SIZE_OFFSET; 900 i++; 901 /* Data source address and size */ 902 payload[i] = src_addr; 903 i++; 904 payload[i] = src_size; 905 i++; 906 907 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_GET_DIGEST_REQ, 908 payload, i, CMD_CASUAL, 909 (uint32_t *) dst_addr, &resp_len); 910 911 memset((void *)&fcs_sha_get_digest_param, 0, sizeof(fcs_crypto_service_data)); 912 913 if (status < 0) { 914 *mbox_error = -status; 915 return INTEL_SIP_SMC_STATUS_ERROR; 916 } 917 918 *dst_size = resp_len * MBOX_WORD_BYTE; 919 flush_dcache_range(dst_addr, *dst_size); 920 921 return INTEL_SIP_SMC_STATUS_OK; 922 } 923 924 int intel_fcs_mac_verify_init(uint32_t session_id, uint32_t context_id, 925 uint32_t key_id, uint32_t param_size, 926 uint64_t param_data, uint32_t *mbox_error) 927 { 928 return intel_fcs_crypto_service_init(session_id, context_id, 929 key_id, param_size, param_data, 930 (void *) &fcs_sha_mac_verify_param, 931 mbox_error); 932 } 933 934 int intel_fcs_mac_verify_finalize(uint32_t session_id, uint32_t context_id, 935 uint32_t src_addr, uint32_t src_size, 936 uint64_t dst_addr, uint32_t *dst_size, 937 uint32_t data_size, uint32_t *mbox_error) 938 { 939 int status; 940 uint32_t i; 941 uint32_t resp_len; 942 uint32_t payload[FCS_MAC_VERIFY_CMD_MAX_WORD_SIZE] = {0U}; 943 uintptr_t mac_offset; 944 945 if (dst_size == NULL || mbox_error == NULL) { 946 return INTEL_SIP_SMC_STATUS_REJECTED; 947 } 948 949 if (fcs_sha_mac_verify_param.session_id != session_id || 950 fcs_sha_mac_verify_param.context_id != context_id) { 951 return INTEL_SIP_SMC_STATUS_REJECTED; 952 } 953 954 if (data_size >= src_size) { 955 return INTEL_SIP_SMC_STATUS_REJECTED; 956 } 957 958 if (!is_size_4_bytes_aligned(src_size) || 959 !is_8_bytes_aligned(data_size)) { 960 return INTEL_SIP_SMC_STATUS_REJECTED; 961 } 962 963 if (!is_address_in_ddr_range(src_addr, src_size) || 964 !is_address_in_ddr_range(dst_addr, *dst_size)) { 965 return INTEL_SIP_SMC_STATUS_REJECTED; 966 } 967 968 resp_len = *dst_size / MBOX_WORD_BYTE; 969 970 /* Prepare command payload */ 971 i = 0; 972 /* Crypto header */ 973 payload[i] = fcs_sha_mac_verify_param.session_id; 974 i++; 975 payload[i] = fcs_sha_mac_verify_param.context_id; 976 i++; 977 payload[i] = fcs_sha_mac_verify_param.crypto_param_size 978 & FCS_CS_FIELD_SIZE_MASK; 979 payload[i] |= (FCS_CS_FIELD_FLAG_INIT | FCS_CS_FIELD_FLAG_UPDATE 980 | FCS_CS_FIELD_FLAG_FINALIZE) 981 << FCS_CS_FIELD_FLAG_OFFSET; 982 i++; 983 payload[i] = fcs_sha_mac_verify_param.key_id; 984 i++; 985 /* Crypto parameters */ 986 payload[i] = ((fcs_sha_mac_verify_param.crypto_param 987 >> INTEL_SIP_SMC_FCS_DIGEST_SIZE_OFFSET) 988 & INTEL_SIP_SMC_FCS_DIGEST_SIZE_MASK) 989 << FCS_SHA_HMAC_CRYPTO_PARAM_SIZE_OFFSET; 990 i++; 991 /* Data source address and size */ 992 payload[i] = src_addr; 993 i++; 994 payload[i] = data_size; 995 i++; 996 /* Copy mac data to command */ 997 mac_offset = src_addr + data_size; 998 memcpy((uint8_t *) &payload[i], (uint8_t *) mac_offset, 999 src_size - data_size); 1000 1001 i += (src_size - data_size) / MBOX_WORD_BYTE; 1002 1003 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_MAC_VERIFY_REQ, 1004 payload, i, CMD_CASUAL, 1005 (uint32_t *) dst_addr, &resp_len); 1006 1007 memset((void *)&fcs_sha_mac_verify_param, 0, 1008 sizeof(fcs_crypto_service_data)); 1009 1010 if (status < 0) { 1011 *mbox_error = -status; 1012 return INTEL_SIP_SMC_STATUS_ERROR; 1013 } 1014 1015 *dst_size = resp_len * MBOX_WORD_BYTE; 1016 flush_dcache_range(dst_addr, *dst_size); 1017 1018 return INTEL_SIP_SMC_STATUS_OK; 1019 } 1020 1021 int intel_fcs_ecdsa_hash_sign_init(uint32_t session_id, uint32_t context_id, 1022 uint32_t key_id, uint32_t param_size, 1023 uint64_t param_data, uint32_t *mbox_error) 1024 { 1025 return intel_fcs_crypto_service_init(session_id, context_id, 1026 key_id, param_size, param_data, 1027 (void *) &fcs_ecdsa_hash_sign_param, 1028 mbox_error); 1029 } 1030 1031 int intel_fcs_ecdsa_hash_sign_finalize(uint32_t session_id, uint32_t context_id, 1032 uint32_t src_addr, uint32_t src_size, 1033 uint64_t dst_addr, uint32_t *dst_size, 1034 uint32_t *mbox_error) 1035 { 1036 int status; 1037 uint32_t i; 1038 uint32_t payload[FCS_ECDSA_HASH_SIGN_CMD_MAX_WORD_SIZE] = {0U}; 1039 uint32_t resp_len; 1040 uintptr_t hash_data_addr; 1041 1042 if ((dst_size == NULL) || (mbox_error == NULL)) { 1043 return INTEL_SIP_SMC_STATUS_REJECTED; 1044 } 1045 1046 if (fcs_ecdsa_hash_sign_param.session_id != session_id || 1047 fcs_ecdsa_hash_sign_param.context_id != context_id) { 1048 return INTEL_SIP_SMC_STATUS_REJECTED; 1049 } 1050 1051 if (!is_address_in_ddr_range(src_addr, src_size) || 1052 !is_address_in_ddr_range(dst_addr, *dst_size)) { 1053 return INTEL_SIP_SMC_STATUS_REJECTED; 1054 } 1055 1056 resp_len = *dst_size / MBOX_WORD_BYTE; 1057 1058 /* Prepare command payload */ 1059 /* Crypto header */ 1060 i = 0; 1061 payload[i] = fcs_ecdsa_hash_sign_param.session_id; 1062 i++; 1063 payload[i] = fcs_ecdsa_hash_sign_param.context_id; 1064 1065 i++; 1066 payload[i] = fcs_ecdsa_hash_sign_param.crypto_param_size 1067 & FCS_CS_FIELD_SIZE_MASK; 1068 payload[i] |= (FCS_CS_FIELD_FLAG_INIT | FCS_CS_FIELD_FLAG_UPDATE 1069 | FCS_CS_FIELD_FLAG_FINALIZE) 1070 << FCS_CS_FIELD_FLAG_OFFSET; 1071 i++; 1072 payload[i] = fcs_ecdsa_hash_sign_param.key_id; 1073 1074 /* Crypto parameters */ 1075 i++; 1076 payload[i] = fcs_ecdsa_hash_sign_param.crypto_param 1077 & INTEL_SIP_SMC_FCS_ECC_ALGO_MASK; 1078 1079 /* Hash Data */ 1080 i++; 1081 hash_data_addr = src_addr; 1082 memcpy((uint8_t *) &payload[i], (uint8_t *) hash_data_addr, 1083 src_size); 1084 1085 i += src_size / MBOX_WORD_BYTE; 1086 1087 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_ECDSA_HASH_SIGN_REQ, 1088 payload, i, CMD_CASUAL, (uint32_t *) dst_addr, 1089 &resp_len); 1090 1091 memset((void *) &fcs_ecdsa_hash_sign_param, 1092 0, sizeof(fcs_crypto_service_data)); 1093 1094 if (status < 0) { 1095 *mbox_error = -status; 1096 return INTEL_SIP_SMC_STATUS_ERROR; 1097 } 1098 1099 *dst_size = resp_len * MBOX_WORD_BYTE; 1100 flush_dcache_range(dst_addr, *dst_size); 1101 1102 return INTEL_SIP_SMC_STATUS_OK; 1103 } 1104 1105 int intel_fcs_ecdsa_hash_sig_verify_init(uint32_t session_id, uint32_t context_id, 1106 uint32_t key_id, uint32_t param_size, 1107 uint64_t param_data, uint32_t *mbox_error) 1108 { 1109 return intel_fcs_crypto_service_init(session_id, context_id, 1110 key_id, param_size, param_data, 1111 (void *) &fcs_ecdsa_hash_sig_verify_param, 1112 mbox_error); 1113 } 1114 1115 int intel_fcs_ecdsa_hash_sig_verify_finalize(uint32_t session_id, uint32_t context_id, 1116 uint32_t src_addr, uint32_t src_size, 1117 uint64_t dst_addr, uint32_t *dst_size, 1118 uint32_t *mbox_error) 1119 { 1120 int status; 1121 uint32_t i = 0; 1122 uint32_t payload[FCS_ECDSA_HASH_SIG_VERIFY_CMD_MAX_WORD_SIZE] = {0U}; 1123 uint32_t resp_len; 1124 uintptr_t hash_sig_pubkey_addr; 1125 1126 if ((dst_size == NULL) || (mbox_error == NULL)) { 1127 return INTEL_SIP_SMC_STATUS_REJECTED; 1128 } 1129 1130 if (fcs_ecdsa_hash_sig_verify_param.session_id != session_id || 1131 fcs_ecdsa_hash_sig_verify_param.context_id != context_id) { 1132 return INTEL_SIP_SMC_STATUS_REJECTED; 1133 } 1134 1135 if (!is_address_in_ddr_range(src_addr, src_size) || 1136 !is_address_in_ddr_range(dst_addr, *dst_size)) { 1137 return INTEL_SIP_SMC_STATUS_REJECTED; 1138 } 1139 1140 resp_len = *dst_size / MBOX_WORD_BYTE; 1141 1142 /* Prepare command payload */ 1143 /* Crypto header */ 1144 i = 0; 1145 payload[i] = fcs_ecdsa_hash_sig_verify_param.session_id; 1146 1147 i++; 1148 payload[i] = fcs_ecdsa_hash_sig_verify_param.context_id; 1149 1150 i++; 1151 payload[i] = fcs_ecdsa_hash_sig_verify_param.crypto_param_size 1152 & FCS_CS_FIELD_SIZE_MASK; 1153 payload[i] |= (FCS_CS_FIELD_FLAG_INIT | FCS_CS_FIELD_FLAG_UPDATE 1154 | FCS_CS_FIELD_FLAG_FINALIZE) 1155 << FCS_CS_FIELD_FLAG_OFFSET; 1156 1157 i++; 1158 payload[i] = fcs_ecdsa_hash_sig_verify_param.key_id; 1159 1160 /* Crypto parameters */ 1161 i++; 1162 payload[i] = fcs_ecdsa_hash_sig_verify_param.crypto_param 1163 & INTEL_SIP_SMC_FCS_ECC_ALGO_MASK; 1164 1165 /* Hash Data Word, Signature Data Word and Public Key Data word */ 1166 i++; 1167 hash_sig_pubkey_addr = src_addr; 1168 memcpy((uint8_t *) &payload[i], 1169 (uint8_t *) hash_sig_pubkey_addr, src_size); 1170 1171 i += (src_size / MBOX_WORD_BYTE); 1172 1173 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_ECDSA_HASH_SIG_VERIFY, 1174 payload, i, CMD_CASUAL, (uint32_t *) dst_addr, 1175 &resp_len); 1176 1177 memset((void *)&fcs_ecdsa_hash_sig_verify_param, 1178 0, sizeof(fcs_crypto_service_data)); 1179 1180 if (status < 0) { 1181 *mbox_error = -status; 1182 return INTEL_SIP_SMC_STATUS_ERROR; 1183 } 1184 1185 *dst_size = resp_len * MBOX_WORD_BYTE; 1186 flush_dcache_range(dst_addr, *dst_size); 1187 1188 return INTEL_SIP_SMC_STATUS_OK; 1189 } 1190 1191 int intel_fcs_ecdsa_sha2_data_sign_init(uint32_t session_id, 1192 uint32_t context_id, uint32_t key_id, 1193 uint32_t param_size, uint64_t param_data, 1194 uint32_t *mbox_error) 1195 { 1196 return intel_fcs_crypto_service_init(session_id, context_id, 1197 key_id, param_size, param_data, 1198 (void *) &fcs_sha2_data_sign_param, 1199 mbox_error); 1200 } 1201 1202 int intel_fcs_ecdsa_sha2_data_sign_update_finalize(uint32_t session_id, 1203 uint32_t context_id, uint32_t src_addr, 1204 uint32_t src_size, uint64_t dst_addr, 1205 uint32_t *dst_size, uint8_t is_finalised, 1206 uint32_t *mbox_error) 1207 { 1208 int status; 1209 int i; 1210 uint32_t flag; 1211 uint32_t crypto_header; 1212 uint32_t payload[FCS_ECDSA_SHA2_DATA_SIGN_CMD_MAX_WORD_SIZE] = {0U}; 1213 uint32_t resp_len; 1214 1215 if ((dst_size == NULL) || (mbox_error == NULL)) { 1216 return INTEL_SIP_SMC_STATUS_REJECTED; 1217 } 1218 1219 if (fcs_sha2_data_sign_param.session_id != session_id || 1220 fcs_sha2_data_sign_param.context_id != context_id) { 1221 return INTEL_SIP_SMC_STATUS_REJECTED; 1222 } 1223 1224 /* Source data must be 8 bytes aligned */ 1225 if (!is_8_bytes_aligned(src_size)) { 1226 return INTEL_SIP_SMC_STATUS_REJECTED; 1227 } 1228 1229 if (!is_address_in_ddr_range(src_addr, src_size) || 1230 !is_address_in_ddr_range(dst_addr, *dst_size)) { 1231 return INTEL_SIP_SMC_STATUS_REJECTED; 1232 } 1233 1234 resp_len = *dst_size / MBOX_WORD_BYTE; 1235 1236 /* Prepare crypto header */ 1237 flag = 0; 1238 if (fcs_sha2_data_sign_param.is_updated) { 1239 fcs_sha2_data_sign_param.crypto_param_size = 0; 1240 } else { 1241 flag |= FCS_CS_FIELD_FLAG_INIT; 1242 } 1243 1244 if (is_finalised != 0U) { 1245 flag |= FCS_CS_FIELD_FLAG_FINALIZE; 1246 } else { 1247 flag |= FCS_CS_FIELD_FLAG_UPDATE; 1248 fcs_sha2_data_sign_param.is_updated = 1; 1249 } 1250 crypto_header = (flag << FCS_CS_FIELD_FLAG_OFFSET) | 1251 fcs_sha2_data_sign_param.crypto_param_size; 1252 1253 /* Prepare command payload */ 1254 i = 0; 1255 payload[i] = fcs_sha2_data_sign_param.session_id; 1256 i++; 1257 payload[i] = fcs_sha2_data_sign_param.context_id; 1258 i++; 1259 payload[i] = crypto_header; 1260 i++; 1261 1262 if ((crypto_header >> FCS_CS_FIELD_FLAG_OFFSET) & 1263 FCS_CS_FIELD_FLAG_INIT) { 1264 payload[i] = fcs_sha2_data_sign_param.key_id; 1265 /* Crypto parameters */ 1266 i++; 1267 payload[i] = fcs_sha2_data_sign_param.crypto_param 1268 & INTEL_SIP_SMC_FCS_ECC_ALGO_MASK; 1269 i++; 1270 } 1271 1272 /* Data source address and size */ 1273 payload[i] = src_addr; 1274 i++; 1275 payload[i] = src_size; 1276 i++; 1277 status = mailbox_send_cmd(MBOX_JOB_ID, 1278 MBOX_FCS_ECDSA_SHA2_DATA_SIGN_REQ, payload, 1279 i, CMD_CASUAL, (uint32_t *) dst_addr, 1280 &resp_len); 1281 1282 if (is_finalised != 0U) { 1283 memset((void *)&fcs_sha2_data_sign_param, 0, 1284 sizeof(fcs_crypto_service_data)); 1285 } 1286 1287 if (status < 0) { 1288 *mbox_error = -status; 1289 return INTEL_SIP_SMC_STATUS_ERROR; 1290 } 1291 1292 *dst_size = resp_len * MBOX_WORD_BYTE; 1293 flush_dcache_range(dst_addr, *dst_size); 1294 1295 return INTEL_SIP_SMC_STATUS_OK; 1296 } 1297 1298 int intel_fcs_ecdsa_sha2_data_sig_verify_init(uint32_t session_id, 1299 uint32_t context_id, uint32_t key_id, 1300 uint32_t param_size, uint64_t param_data, 1301 uint32_t *mbox_error) 1302 { 1303 return intel_fcs_crypto_service_init(session_id, context_id, 1304 key_id, param_size, param_data, 1305 (void *) &fcs_sha2_data_sig_verify_param, 1306 mbox_error); 1307 } 1308 1309 int intel_fcs_ecdsa_sha2_data_sig_verify_update_finalize(uint32_t session_id, 1310 uint32_t context_id, uint32_t src_addr, 1311 uint32_t src_size, uint64_t dst_addr, 1312 uint32_t *dst_size, uint32_t data_size, 1313 uint8_t is_finalised, uint32_t *mbox_error) 1314 { 1315 int status; 1316 uint32_t i; 1317 uint32_t flag; 1318 uint32_t crypto_header; 1319 uint32_t payload[FCS_ECDSA_SHA2_DATA_SIG_VERIFY_CMD_MAX_WORD_SIZE] = {0U}; 1320 uint32_t resp_len; 1321 uintptr_t sig_pubkey_offset; 1322 1323 if ((dst_size == NULL) || (mbox_error == NULL)) { 1324 return INTEL_SIP_SMC_STATUS_REJECTED; 1325 } 1326 1327 if (fcs_sha2_data_sig_verify_param.session_id != session_id || 1328 fcs_sha2_data_sig_verify_param.context_id != context_id) { 1329 return INTEL_SIP_SMC_STATUS_REJECTED; 1330 } 1331 1332 if (!is_size_4_bytes_aligned(src_size)) { 1333 return INTEL_SIP_SMC_STATUS_REJECTED; 1334 } 1335 1336 if (!is_8_bytes_aligned(data_size) || 1337 !is_8_bytes_aligned(src_addr)) { 1338 return INTEL_SIP_SMC_STATUS_REJECTED; 1339 } 1340 1341 if (!is_address_in_ddr_range(src_addr, src_size) || 1342 !is_address_in_ddr_range(dst_addr, *dst_size)) { 1343 return INTEL_SIP_SMC_STATUS_REJECTED; 1344 } 1345 1346 resp_len = *dst_size / MBOX_WORD_BYTE; 1347 1348 /* Prepare crypto header */ 1349 flag = 0; 1350 if (fcs_sha2_data_sig_verify_param.is_updated) 1351 fcs_sha2_data_sig_verify_param.crypto_param_size = 0; 1352 else 1353 flag |= FCS_CS_FIELD_FLAG_INIT; 1354 1355 if (is_finalised != 0U) 1356 flag |= FCS_CS_FIELD_FLAG_FINALIZE; 1357 else { 1358 flag |= FCS_CS_FIELD_FLAG_UPDATE; 1359 fcs_sha2_data_sig_verify_param.is_updated = 1; 1360 } 1361 crypto_header = (flag << FCS_CS_FIELD_FLAG_OFFSET) | 1362 fcs_sha2_data_sig_verify_param.crypto_param_size; 1363 1364 /* Prepare command payload */ 1365 i = 0; 1366 payload[i] = fcs_sha2_data_sig_verify_param.session_id; 1367 i++; 1368 payload[i] = fcs_sha2_data_sig_verify_param.context_id; 1369 i++; 1370 payload[i] = crypto_header; 1371 i++; 1372 1373 if ((crypto_header >> FCS_CS_FIELD_FLAG_OFFSET) & 1374 FCS_CS_FIELD_FLAG_INIT) { 1375 payload[i] = fcs_sha2_data_sig_verify_param.key_id; 1376 i++; 1377 /* Crypto parameters */ 1378 payload[i] = fcs_sha2_data_sig_verify_param.crypto_param 1379 & INTEL_SIP_SMC_FCS_ECC_ALGO_MASK; 1380 i++; 1381 } 1382 1383 /* Data source address and size */ 1384 payload[i] = src_addr; 1385 i++; 1386 payload[i] = data_size; 1387 i++; 1388 1389 if ((crypto_header >> FCS_CS_FIELD_FLAG_OFFSET) & 1390 FCS_CS_FIELD_FLAG_FINALIZE) { 1391 /* Signature + Public Key Data */ 1392 sig_pubkey_offset = src_addr + data_size; 1393 memcpy((uint8_t *) &payload[i], (uint8_t *) sig_pubkey_offset, 1394 src_size - data_size); 1395 1396 i += (src_size - data_size) / MBOX_WORD_BYTE; 1397 } 1398 1399 status = mailbox_send_cmd(MBOX_JOB_ID, 1400 MBOX_FCS_ECDSA_SHA2_DATA_SIGN_VERIFY, payload, i, 1401 CMD_CASUAL, (uint32_t *) dst_addr, &resp_len); 1402 1403 if (is_finalised != 0U) { 1404 memset((void *) &fcs_sha2_data_sig_verify_param, 0, 1405 sizeof(fcs_crypto_service_data)); 1406 } 1407 1408 if (status < 0) { 1409 *mbox_error = -status; 1410 return INTEL_SIP_SMC_STATUS_ERROR; 1411 } 1412 1413 *dst_size = resp_len * MBOX_WORD_BYTE; 1414 flush_dcache_range(dst_addr, *dst_size); 1415 1416 return INTEL_SIP_SMC_STATUS_OK; 1417 } 1418 1419 int intel_fcs_ecdsa_get_pubkey_init(uint32_t session_id, uint32_t context_id, 1420 uint32_t key_id, uint32_t param_size, 1421 uint64_t param_data, uint32_t *mbox_error) 1422 { 1423 return intel_fcs_crypto_service_init(session_id, context_id, 1424 key_id, param_size, param_data, 1425 (void *) &fcs_ecdsa_get_pubkey_param, 1426 mbox_error); 1427 } 1428 1429 int intel_fcs_ecdsa_get_pubkey_finalize(uint32_t session_id, uint32_t context_id, 1430 uint64_t dst_addr, uint32_t *dst_size, 1431 uint32_t *mbox_error) 1432 { 1433 int status; 1434 int i; 1435 uint32_t crypto_header; 1436 uint32_t ret_size; 1437 uint32_t payload[FCS_ECDSA_GET_PUBKEY_MAX_WORD_SIZE] = {0U}; 1438 1439 if ((dst_size == NULL) || (mbox_error == NULL)) { 1440 return INTEL_SIP_SMC_STATUS_REJECTED; 1441 } 1442 1443 if (fcs_ecdsa_get_pubkey_param.session_id != session_id || 1444 fcs_ecdsa_get_pubkey_param.context_id != context_id) { 1445 return INTEL_SIP_SMC_STATUS_REJECTED; 1446 } 1447 1448 ret_size = *dst_size / MBOX_WORD_BYTE; 1449 1450 crypto_header = ((FCS_CS_FIELD_FLAG_INIT | 1451 FCS_CS_FIELD_FLAG_UPDATE | 1452 FCS_CS_FIELD_FLAG_FINALIZE) << 1453 FCS_CS_FIELD_FLAG_OFFSET) | 1454 fcs_ecdsa_get_pubkey_param.crypto_param_size; 1455 i = 0; 1456 /* Prepare command payload */ 1457 payload[i] = session_id; 1458 i++; 1459 payload[i] = context_id; 1460 i++; 1461 payload[i] = crypto_header; 1462 i++; 1463 payload[i] = fcs_ecdsa_get_pubkey_param.key_id; 1464 i++; 1465 payload[i] = (uint32_t) fcs_ecdsa_get_pubkey_param.crypto_param & 1466 INTEL_SIP_SMC_FCS_ECC_ALGO_MASK; 1467 i++; 1468 1469 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_ECDSA_GET_PUBKEY, 1470 payload, i, CMD_CASUAL, 1471 (uint32_t *) dst_addr, &ret_size); 1472 1473 memset((void *) &fcs_ecdsa_get_pubkey_param, 0, 1474 sizeof(fcs_crypto_service_data)); 1475 1476 if (status < 0) { 1477 *mbox_error = -status; 1478 return INTEL_SIP_SMC_STATUS_ERROR; 1479 } 1480 1481 *dst_size = ret_size * MBOX_WORD_BYTE; 1482 flush_dcache_range(dst_addr, *dst_size); 1483 1484 return INTEL_SIP_SMC_STATUS_OK; 1485 } 1486 1487 int intel_fcs_ecdh_request_init(uint32_t session_id, uint32_t context_id, 1488 uint32_t key_id, uint32_t param_size, 1489 uint64_t param_data, uint32_t *mbox_error) 1490 { 1491 return intel_fcs_crypto_service_init(session_id, context_id, 1492 key_id, param_size, param_data, 1493 (void *) &fcs_ecdh_request_param, 1494 mbox_error); 1495 } 1496 1497 int intel_fcs_ecdh_request_finalize(uint32_t session_id, uint32_t context_id, 1498 uint32_t src_addr, uint32_t src_size, 1499 uint64_t dst_addr, uint32_t *dst_size, 1500 uint32_t *mbox_error) 1501 { 1502 int status; 1503 uint32_t i; 1504 uint32_t payload[FCS_ECDH_REQUEST_CMD_MAX_WORD_SIZE] = {0U}; 1505 uint32_t resp_len; 1506 uintptr_t pubkey; 1507 1508 if ((dst_size == NULL) || (mbox_error == NULL)) { 1509 return INTEL_SIP_SMC_STATUS_REJECTED; 1510 } 1511 1512 if (fcs_ecdh_request_param.session_id != session_id || 1513 fcs_ecdh_request_param.context_id != context_id) { 1514 return INTEL_SIP_SMC_STATUS_REJECTED; 1515 } 1516 1517 if (!is_address_in_ddr_range(src_addr, src_size) || 1518 !is_address_in_ddr_range(dst_addr, *dst_size)) { 1519 return INTEL_SIP_SMC_STATUS_REJECTED; 1520 } 1521 1522 resp_len = *dst_size / MBOX_WORD_BYTE; 1523 1524 /* Prepare command payload */ 1525 i = 0; 1526 /* Crypto header */ 1527 payload[i] = fcs_ecdh_request_param.session_id; 1528 i++; 1529 payload[i] = fcs_ecdh_request_param.context_id; 1530 i++; 1531 payload[i] = fcs_ecdh_request_param.crypto_param_size 1532 & FCS_CS_FIELD_SIZE_MASK; 1533 payload[i] |= (FCS_CS_FIELD_FLAG_INIT | FCS_CS_FIELD_FLAG_UPDATE 1534 | FCS_CS_FIELD_FLAG_FINALIZE) 1535 << FCS_CS_FIELD_FLAG_OFFSET; 1536 i++; 1537 payload[i] = fcs_ecdh_request_param.key_id; 1538 i++; 1539 /* Crypto parameters */ 1540 payload[i] = fcs_ecdh_request_param.crypto_param 1541 & INTEL_SIP_SMC_FCS_ECC_ALGO_MASK; 1542 i++; 1543 /* Public key data */ 1544 pubkey = src_addr; 1545 memcpy((uint8_t *) &payload[i], (uint8_t *) pubkey, src_size); 1546 i += src_size / MBOX_WORD_BYTE; 1547 1548 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_ECDH_REQUEST, 1549 payload, i, CMD_CASUAL, (uint32_t *) dst_addr, 1550 &resp_len); 1551 1552 memset((void *)&fcs_ecdh_request_param, 0, 1553 sizeof(fcs_crypto_service_data)); 1554 1555 if (status < 0) { 1556 *mbox_error = -status; 1557 return INTEL_SIP_SMC_STATUS_ERROR; 1558 } 1559 1560 *dst_size = resp_len * MBOX_WORD_BYTE; 1561 flush_dcache_range(dst_addr, *dst_size); 1562 1563 return INTEL_SIP_SMC_STATUS_OK; 1564 } 1565 1566 int intel_fcs_aes_crypt_init(uint32_t session_id, uint32_t context_id, 1567 uint32_t key_id, uint64_t param_addr, 1568 uint32_t param_size, uint32_t *mbox_error) 1569 { 1570 if (mbox_error == NULL) { 1571 return INTEL_SIP_SMC_STATUS_REJECTED; 1572 } 1573 1574 memset((void *)&fcs_aes_init_payload, 0U, sizeof(fcs_aes_init_payload)); 1575 1576 fcs_aes_init_payload.session_id = session_id; 1577 fcs_aes_init_payload.context_id = context_id; 1578 fcs_aes_init_payload.param_size = param_size; 1579 fcs_aes_init_payload.key_id = key_id; 1580 1581 memcpy((uint8_t *) fcs_aes_init_payload.crypto_param, 1582 (uint8_t *) param_addr, param_size); 1583 1584 fcs_aes_init_payload.is_updated = 0; 1585 1586 *mbox_error = 0; 1587 1588 return INTEL_SIP_SMC_STATUS_OK; 1589 } 1590 1591 int intel_fcs_aes_crypt_update_finalize(uint32_t session_id, 1592 uint32_t context_id, uint64_t src_addr, 1593 uint32_t src_size, uint64_t dst_addr, 1594 uint32_t dst_size, uint8_t is_finalised, 1595 uint32_t *send_id) 1596 { 1597 int status; 1598 int i; 1599 uint32_t flag; 1600 uint32_t crypto_header; 1601 uint32_t fcs_aes_crypt_payload[FCS_AES_CMD_MAX_WORD_SIZE]; 1602 1603 if (fcs_aes_init_payload.session_id != session_id || 1604 fcs_aes_init_payload.context_id != context_id) { 1605 return INTEL_SIP_SMC_STATUS_REJECTED; 1606 } 1607 1608 if ((!is_8_bytes_aligned(src_addr)) || 1609 (!is_32_bytes_aligned(src_size)) || 1610 (!is_address_in_ddr_range(src_addr, src_size))) { 1611 return INTEL_SIP_SMC_STATUS_REJECTED; 1612 } 1613 1614 if ((!is_8_bytes_aligned(dst_addr)) || 1615 (!is_32_bytes_aligned(dst_size))) { 1616 return INTEL_SIP_SMC_STATUS_REJECTED; 1617 } 1618 1619 if ((dst_size > FCS_AES_MAX_DATA_SIZE || 1620 dst_size < FCS_AES_MIN_DATA_SIZE) || 1621 (src_size > FCS_AES_MAX_DATA_SIZE || 1622 src_size < FCS_AES_MIN_DATA_SIZE)) { 1623 return INTEL_SIP_SMC_STATUS_REJECTED; 1624 } 1625 1626 /* Prepare crypto header*/ 1627 flag = 0; 1628 if (fcs_aes_init_payload.is_updated) { 1629 fcs_aes_init_payload.param_size = 0; 1630 } else { 1631 flag |= FCS_CS_FIELD_FLAG_INIT; 1632 } 1633 1634 if (is_finalised != 0U) { 1635 flag |= FCS_CS_FIELD_FLAG_FINALIZE; 1636 } else { 1637 flag |= FCS_CS_FIELD_FLAG_UPDATE; 1638 fcs_aes_init_payload.is_updated = 1; 1639 } 1640 crypto_header = (flag << FCS_CS_FIELD_FLAG_OFFSET) | 1641 fcs_aes_init_payload.param_size; 1642 1643 i = 0U; 1644 fcs_aes_crypt_payload[i] = session_id; 1645 i++; 1646 fcs_aes_crypt_payload[i] = context_id; 1647 i++; 1648 fcs_aes_crypt_payload[i] = crypto_header; 1649 i++; 1650 1651 if ((crypto_header >> FCS_CS_FIELD_FLAG_OFFSET) & 1652 FCS_CS_FIELD_FLAG_INIT) { 1653 fcs_aes_crypt_payload[i] = fcs_aes_init_payload.key_id; 1654 i++; 1655 1656 memcpy((uint8_t *) &fcs_aes_crypt_payload[i], 1657 (uint8_t *) fcs_aes_init_payload.crypto_param, 1658 fcs_aes_init_payload.param_size); 1659 1660 i += fcs_aes_init_payload.param_size / MBOX_WORD_BYTE; 1661 } 1662 1663 fcs_aes_crypt_payload[i] = (uint32_t) src_addr; 1664 i++; 1665 fcs_aes_crypt_payload[i] = src_size; 1666 i++; 1667 fcs_aes_crypt_payload[i] = (uint32_t) dst_addr; 1668 i++; 1669 fcs_aes_crypt_payload[i] = dst_size; 1670 i++; 1671 1672 status = mailbox_send_cmd_async(send_id, MBOX_FCS_AES_CRYPT_REQ, 1673 fcs_aes_crypt_payload, i, 1674 CMD_INDIRECT); 1675 1676 if (is_finalised != 0U) { 1677 memset((void *)&fcs_aes_init_payload, 0, 1678 sizeof(fcs_aes_init_payload)); 1679 } 1680 1681 if (status < 0U) { 1682 return INTEL_SIP_SMC_STATUS_ERROR; 1683 } 1684 1685 return INTEL_SIP_SMC_STATUS_OK; 1686 } 1687