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