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