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_ALIAS_CERT || 573 cert_request > 574 (FCS_ALIAS_CERT | 575 FCS_DEV_ID_SELF_SIGN_CERT | 576 FCS_DEV_ID_ENROLL_CERT | 577 FCS_ENROLL_SELF_SIGN_CERT | 578 FCS_PLAT_KEY_CERT)) { 579 return INTEL_SIP_SMC_STATUS_REJECTED; 580 } 581 582 if (!is_address_in_ddr_range(dst_addr, *dst_size)) { 583 return INTEL_SIP_SMC_STATUS_REJECTED; 584 } 585 586 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_GET_ATTESTATION_CERT, 587 (uint32_t *) &cert_request, 1U, CMD_CASUAL, 588 (uint32_t *) dst_addr, &ret_size); 589 590 if (status < 0) { 591 *mbox_error = -status; 592 return INTEL_SIP_SMC_STATUS_ERROR; 593 } 594 595 *dst_size = ret_size * MBOX_WORD_BYTE; 596 flush_dcache_range(dst_addr, *dst_size); 597 598 return INTEL_SIP_SMC_STATUS_OK; 599 } 600 601 int intel_fcs_create_cert_on_reload(uint32_t cert_request, 602 uint32_t *mbox_error) 603 { 604 int status; 605 606 if (mbox_error == NULL) { 607 return INTEL_SIP_SMC_STATUS_REJECTED; 608 } 609 610 if (cert_request < FCS_ALIAS_CERT || 611 cert_request > 612 (FCS_ALIAS_CERT | 613 FCS_DEV_ID_SELF_SIGN_CERT | 614 FCS_DEV_ID_ENROLL_CERT | 615 FCS_ENROLL_SELF_SIGN_CERT | 616 FCS_PLAT_KEY_CERT)) { 617 return INTEL_SIP_SMC_STATUS_REJECTED; 618 } 619 620 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_CREATE_CERT_ON_RELOAD, 621 (uint32_t *) &cert_request, 1U, CMD_CASUAL, 622 NULL, NULL); 623 624 if (status < 0) { 625 *mbox_error = -status; 626 return INTEL_SIP_SMC_STATUS_ERROR; 627 } 628 629 return INTEL_SIP_SMC_STATUS_OK; 630 } 631 632 int intel_fcs_open_crypto_service_session(uint32_t *session_id, 633 uint32_t *mbox_error) 634 { 635 int status; 636 uint32_t resp_len = 1U; 637 638 if ((session_id == NULL) || (mbox_error == NULL)) { 639 return INTEL_SIP_SMC_STATUS_REJECTED; 640 } 641 642 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_OPEN_CS_SESSION, 643 NULL, 0U, CMD_CASUAL, session_id, &resp_len); 644 645 if (status < 0) { 646 *mbox_error = -status; 647 return INTEL_SIP_SMC_STATUS_ERROR; 648 } 649 650 return INTEL_SIP_SMC_STATUS_OK; 651 } 652 653 int intel_fcs_close_crypto_service_session(uint32_t session_id, 654 uint32_t *mbox_error) 655 { 656 int status; 657 658 if (mbox_error == NULL) { 659 return INTEL_SIP_SMC_STATUS_REJECTED; 660 } 661 662 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_CLOSE_CS_SESSION, 663 &session_id, 1U, CMD_CASUAL, NULL, NULL); 664 665 if (status < 0) { 666 *mbox_error = -status; 667 return INTEL_SIP_SMC_STATUS_ERROR; 668 } 669 670 return INTEL_SIP_SMC_STATUS_OK; 671 } 672 673 int intel_fcs_import_crypto_service_key(uint64_t src_addr, uint32_t src_size, 674 uint32_t *send_id) 675 { 676 int status; 677 678 if (src_size > (FCS_CS_KEY_OBJ_MAX_WORD_SIZE * 679 MBOX_WORD_BYTE)) { 680 return INTEL_SIP_SMC_STATUS_REJECTED; 681 } 682 683 if (!is_address_in_ddr_range(src_addr, src_size)) { 684 return INTEL_SIP_SMC_STATUS_REJECTED; 685 } 686 687 status = mailbox_send_cmd_async(send_id, MBOX_FCS_IMPORT_CS_KEY, 688 (uint32_t *)src_addr, src_size / MBOX_WORD_BYTE, 689 CMD_INDIRECT); 690 691 if (status < 0) { 692 return INTEL_SIP_SMC_STATUS_ERROR; 693 } 694 695 return INTEL_SIP_SMC_STATUS_OK; 696 } 697 698 int intel_fcs_export_crypto_service_key(uint32_t session_id, uint32_t key_id, 699 uint64_t dst_addr, uint32_t *dst_size, 700 uint32_t *mbox_error) 701 { 702 int status; 703 uint32_t i; 704 uint32_t payload_size; 705 uint32_t resp_len = FCS_CS_KEY_OBJ_MAX_WORD_SIZE; 706 uint32_t resp_data[FCS_CS_KEY_OBJ_MAX_WORD_SIZE] = {0U}; 707 uint32_t op_status = 0U; 708 709 if ((dst_size == NULL) || (mbox_error == NULL)) { 710 return INTEL_SIP_SMC_STATUS_REJECTED; 711 } 712 713 if (!is_address_in_ddr_range(dst_addr, *dst_size)) { 714 return INTEL_SIP_SMC_STATUS_REJECTED; 715 } 716 717 fcs_cs_key_payload payload = { 718 session_id, 719 RESERVED_AS_ZERO, 720 RESERVED_AS_ZERO, 721 key_id 722 }; 723 724 payload_size = sizeof(payload) / MBOX_WORD_BYTE; 725 726 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_EXPORT_CS_KEY, 727 (uint32_t *) &payload, payload_size, 728 CMD_CASUAL, resp_data, &resp_len); 729 730 if (resp_len > 0) { 731 op_status = resp_data[0] & FCS_CS_KEY_RESP_STATUS_MASK; 732 } 733 734 if (status < 0) { 735 *mbox_error = (-status) | (op_status << FCS_CS_KEY_RESP_STATUS_OFFSET); 736 return INTEL_SIP_SMC_STATUS_ERROR; 737 } 738 739 if (resp_len > 1) { 740 741 /* Export key object is start at second response data */ 742 *dst_size = (resp_len - 1) * MBOX_WORD_BYTE; 743 744 for (i = 1U; i < resp_len; i++) { 745 mmio_write_32(dst_addr, resp_data[i]); 746 dst_addr += MBOX_WORD_BYTE; 747 } 748 749 flush_dcache_range(dst_addr - *dst_size, *dst_size); 750 751 } else { 752 753 /* Unexpected response, missing key object in response */ 754 *mbox_error = MBOX_RET_ERROR; 755 return INTEL_SIP_SMC_STATUS_ERROR; 756 } 757 758 return INTEL_SIP_SMC_STATUS_OK; 759 } 760 761 int intel_fcs_remove_crypto_service_key(uint32_t session_id, uint32_t key_id, 762 uint32_t *mbox_error) 763 { 764 int status; 765 uint32_t payload_size; 766 uint32_t resp_len = 1U; 767 uint32_t resp_data = 0U; 768 uint32_t op_status = 0U; 769 770 if (mbox_error == NULL) { 771 return INTEL_SIP_SMC_STATUS_REJECTED; 772 } 773 774 fcs_cs_key_payload payload = { 775 session_id, 776 RESERVED_AS_ZERO, 777 RESERVED_AS_ZERO, 778 key_id 779 }; 780 781 payload_size = sizeof(payload) / MBOX_WORD_BYTE; 782 783 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_REMOVE_CS_KEY, 784 (uint32_t *) &payload, payload_size, 785 CMD_CASUAL, &resp_data, &resp_len); 786 787 if (resp_len > 0) { 788 op_status = resp_data & FCS_CS_KEY_RESP_STATUS_MASK; 789 } 790 791 if (status < 0) { 792 *mbox_error = (-status) | (op_status << FCS_CS_KEY_RESP_STATUS_OFFSET); 793 return INTEL_SIP_SMC_STATUS_ERROR; 794 } 795 796 return INTEL_SIP_SMC_STATUS_OK; 797 } 798 799 int intel_fcs_get_crypto_service_key_info(uint32_t session_id, uint32_t key_id, 800 uint64_t dst_addr, uint32_t *dst_size, 801 uint32_t *mbox_error) 802 { 803 int status; 804 uint32_t payload_size; 805 uint32_t resp_len = FCS_CS_KEY_INFO_MAX_WORD_SIZE; 806 uint32_t op_status = 0U; 807 808 if ((dst_size == NULL) || (mbox_error == NULL)) { 809 return INTEL_SIP_SMC_STATUS_REJECTED; 810 } 811 812 if (!is_address_in_ddr_range(dst_addr, *dst_size)) { 813 return INTEL_SIP_SMC_STATUS_REJECTED; 814 } 815 816 fcs_cs_key_payload payload = { 817 session_id, 818 RESERVED_AS_ZERO, 819 RESERVED_AS_ZERO, 820 key_id 821 }; 822 823 payload_size = sizeof(payload) / MBOX_WORD_BYTE; 824 825 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_GET_CS_KEY_INFO, 826 (uint32_t *) &payload, payload_size, 827 CMD_CASUAL, (uint32_t *) dst_addr, &resp_len); 828 829 if (resp_len > 0) { 830 op_status = mmio_read_32(dst_addr) & 831 FCS_CS_KEY_RESP_STATUS_MASK; 832 } 833 834 if (status < 0) { 835 *mbox_error = (-status) | (op_status << FCS_CS_KEY_RESP_STATUS_OFFSET); 836 return INTEL_SIP_SMC_STATUS_ERROR; 837 } 838 839 *dst_size = resp_len * MBOX_WORD_BYTE; 840 flush_dcache_range(dst_addr, *dst_size); 841 842 return INTEL_SIP_SMC_STATUS_OK; 843 } 844 845 int intel_fcs_get_digest_init(uint32_t session_id, uint32_t context_id, 846 uint32_t key_id, uint32_t param_size, 847 uint64_t param_data, uint32_t *mbox_error) 848 { 849 return intel_fcs_crypto_service_init(session_id, context_id, 850 key_id, param_size, param_data, 851 (void *) &fcs_sha_get_digest_param, 852 mbox_error); 853 } 854 855 int intel_fcs_get_digest_finalize(uint32_t session_id, uint32_t context_id, 856 uint32_t src_addr, uint32_t src_size, 857 uint64_t dst_addr, uint32_t *dst_size, 858 uint32_t *mbox_error) 859 { 860 int status; 861 uint32_t i; 862 uint32_t resp_len = *dst_size / MBOX_WORD_BYTE; 863 uint32_t payload[FCS_GET_DIGEST_CMD_MAX_WORD_SIZE] = {0U}; 864 865 if (dst_size == NULL || mbox_error == NULL) { 866 return INTEL_SIP_SMC_STATUS_REJECTED; 867 } 868 869 if (fcs_sha_get_digest_param.session_id != session_id || 870 fcs_sha_get_digest_param.context_id != context_id) { 871 return INTEL_SIP_SMC_STATUS_REJECTED; 872 } 873 874 /* Source data must be 8 bytes aligned */ 875 if (!is_8_bytes_aligned(src_size)) { 876 return INTEL_SIP_SMC_STATUS_REJECTED; 877 } 878 879 if (!is_address_in_ddr_range(src_addr, src_size) || 880 !is_address_in_ddr_range(dst_addr, *dst_size)) { 881 return INTEL_SIP_SMC_STATUS_REJECTED; 882 } 883 884 /* Prepare command payload */ 885 i = 0; 886 /* Crypto header */ 887 payload[i] = fcs_sha_get_digest_param.session_id; 888 i++; 889 payload[i] = fcs_sha_get_digest_param.context_id; 890 i++; 891 payload[i] = fcs_sha_get_digest_param.crypto_param_size 892 & FCS_CS_FIELD_SIZE_MASK; 893 payload[i] |= (FCS_CS_FIELD_FLAG_INIT | FCS_CS_FIELD_FLAG_UPDATE 894 | FCS_CS_FIELD_FLAG_FINALIZE) 895 << FCS_CS_FIELD_FLAG_OFFSET; 896 i++; 897 payload[i] = fcs_sha_get_digest_param.key_id; 898 i++; 899 /* Crypto parameters */ 900 payload[i] = fcs_sha_get_digest_param.crypto_param 901 & INTEL_SIP_SMC_FCS_SHA_MODE_MASK; 902 payload[i] |= ((fcs_sha_get_digest_param.crypto_param 903 >> INTEL_SIP_SMC_FCS_DIGEST_SIZE_OFFSET) 904 & INTEL_SIP_SMC_FCS_DIGEST_SIZE_MASK) 905 << FCS_SHA_HMAC_CRYPTO_PARAM_SIZE_OFFSET; 906 i++; 907 /* Data source address and size */ 908 payload[i] = src_addr; 909 i++; 910 payload[i] = src_size; 911 i++; 912 913 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_GET_DIGEST_REQ, 914 payload, i, CMD_CASUAL, 915 (uint32_t *) dst_addr, &resp_len); 916 917 memset((void *)&fcs_sha_get_digest_param, 0, sizeof(fcs_crypto_service_data)); 918 919 if (status < 0) { 920 *mbox_error = -status; 921 return INTEL_SIP_SMC_STATUS_ERROR; 922 } 923 924 *dst_size = resp_len * MBOX_WORD_BYTE; 925 flush_dcache_range(dst_addr, *dst_size); 926 927 return INTEL_SIP_SMC_STATUS_OK; 928 } 929 930 int intel_fcs_mac_verify_init(uint32_t session_id, uint32_t context_id, 931 uint32_t key_id, uint32_t param_size, 932 uint64_t param_data, uint32_t *mbox_error) 933 { 934 return intel_fcs_crypto_service_init(session_id, context_id, 935 key_id, param_size, param_data, 936 (void *) &fcs_sha_mac_verify_param, 937 mbox_error); 938 } 939 940 int intel_fcs_mac_verify_finalize(uint32_t session_id, uint32_t context_id, 941 uint32_t src_addr, uint32_t src_size, 942 uint64_t dst_addr, uint32_t *dst_size, 943 uint32_t data_size, uint32_t *mbox_error) 944 { 945 int status; 946 uint32_t i; 947 uint32_t resp_len = *dst_size / MBOX_WORD_BYTE; 948 uint32_t payload[FCS_MAC_VERIFY_CMD_MAX_WORD_SIZE] = {0U}; 949 uintptr_t mac_offset; 950 951 if (dst_size == NULL || mbox_error == NULL) { 952 return INTEL_SIP_SMC_STATUS_REJECTED; 953 } 954 955 if (fcs_sha_mac_verify_param.session_id != session_id || 956 fcs_sha_mac_verify_param.context_id != context_id) { 957 return INTEL_SIP_SMC_STATUS_REJECTED; 958 } 959 960 if (data_size >= src_size) { 961 return INTEL_SIP_SMC_STATUS_REJECTED; 962 } 963 964 if (!is_size_4_bytes_aligned(src_size) || 965 !is_8_bytes_aligned(data_size)) { 966 return INTEL_SIP_SMC_STATUS_REJECTED; 967 } 968 969 if (!is_address_in_ddr_range(src_addr, src_size) || 970 !is_address_in_ddr_range(dst_addr, *dst_size)) { 971 return INTEL_SIP_SMC_STATUS_REJECTED; 972 } 973 974 /* Prepare command payload */ 975 i = 0; 976 /* Crypto header */ 977 payload[i] = fcs_sha_mac_verify_param.session_id; 978 i++; 979 payload[i] = fcs_sha_mac_verify_param.context_id; 980 i++; 981 payload[i] = fcs_sha_mac_verify_param.crypto_param_size 982 & FCS_CS_FIELD_SIZE_MASK; 983 payload[i] |= (FCS_CS_FIELD_FLAG_INIT | FCS_CS_FIELD_FLAG_UPDATE 984 | FCS_CS_FIELD_FLAG_FINALIZE) 985 << FCS_CS_FIELD_FLAG_OFFSET; 986 i++; 987 payload[i] = fcs_sha_mac_verify_param.key_id; 988 i++; 989 /* Crypto parameters */ 990 payload[i] = ((fcs_sha_mac_verify_param.crypto_param 991 >> INTEL_SIP_SMC_FCS_DIGEST_SIZE_OFFSET) 992 & INTEL_SIP_SMC_FCS_DIGEST_SIZE_MASK) 993 << FCS_SHA_HMAC_CRYPTO_PARAM_SIZE_OFFSET; 994 i++; 995 /* Data source address and size */ 996 payload[i] = src_addr; 997 i++; 998 payload[i] = data_size; 999 i++; 1000 /* Copy mac data to command */ 1001 mac_offset = src_addr + data_size; 1002 memcpy((uint8_t *) &payload[i], (uint8_t *) mac_offset, 1003 src_size - data_size); 1004 1005 i += (src_size - data_size) / MBOX_WORD_BYTE; 1006 1007 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_MAC_VERIFY_REQ, 1008 payload, i, CMD_CASUAL, 1009 (uint32_t *) dst_addr, &resp_len); 1010 1011 memset((void *)&fcs_sha_mac_verify_param, 0, 1012 sizeof(fcs_crypto_service_data)); 1013 1014 if (status < 0) { 1015 *mbox_error = -status; 1016 return INTEL_SIP_SMC_STATUS_ERROR; 1017 } 1018 1019 *dst_size = resp_len * MBOX_WORD_BYTE; 1020 flush_dcache_range(dst_addr, *dst_size); 1021 1022 return INTEL_SIP_SMC_STATUS_OK; 1023 } 1024 1025 int intel_fcs_ecdsa_hash_sign_init(uint32_t session_id, uint32_t context_id, 1026 uint32_t key_id, uint32_t param_size, 1027 uint64_t param_data, uint32_t *mbox_error) 1028 { 1029 return intel_fcs_crypto_service_init(session_id, context_id, 1030 key_id, param_size, param_data, 1031 (void *) &fcs_ecdsa_hash_sign_param, 1032 mbox_error); 1033 } 1034 1035 int intel_fcs_ecdsa_hash_sign_finalize(uint32_t session_id, uint32_t context_id, 1036 uint32_t src_addr, uint32_t src_size, 1037 uint64_t dst_addr, uint32_t *dst_size, 1038 uint32_t *mbox_error) 1039 { 1040 int status; 1041 uint32_t i; 1042 uint32_t payload[FCS_ECDSA_HASH_SIGN_CMD_MAX_WORD_SIZE] = {0U}; 1043 uint32_t resp_len = *dst_size / MBOX_WORD_BYTE; 1044 uintptr_t hash_data_addr; 1045 1046 if ((dst_size == NULL) || (mbox_error == NULL)) { 1047 return INTEL_SIP_SMC_STATUS_REJECTED; 1048 } 1049 1050 if (fcs_ecdsa_hash_sign_param.session_id != session_id || 1051 fcs_ecdsa_hash_sign_param.context_id != context_id) { 1052 return INTEL_SIP_SMC_STATUS_REJECTED; 1053 } 1054 1055 if (!is_address_in_ddr_range(src_addr, src_size) || 1056 !is_address_in_ddr_range(dst_addr, *dst_size)) { 1057 return INTEL_SIP_SMC_STATUS_REJECTED; 1058 } 1059 1060 /* Prepare command payload */ 1061 /* Crypto header */ 1062 i = 0; 1063 payload[i] = fcs_ecdsa_hash_sign_param.session_id; 1064 i++; 1065 payload[i] = fcs_ecdsa_hash_sign_param.context_id; 1066 1067 i++; 1068 payload[i] = fcs_ecdsa_hash_sign_param.crypto_param_size 1069 & FCS_CS_FIELD_SIZE_MASK; 1070 payload[i] |= (FCS_CS_FIELD_FLAG_INIT | FCS_CS_FIELD_FLAG_UPDATE 1071 | FCS_CS_FIELD_FLAG_FINALIZE) 1072 << FCS_CS_FIELD_FLAG_OFFSET; 1073 i++; 1074 payload[i] = fcs_ecdsa_hash_sign_param.key_id; 1075 1076 /* Crypto parameters */ 1077 i++; 1078 payload[i] = fcs_ecdsa_hash_sign_param.crypto_param 1079 & INTEL_SIP_SMC_FCS_ECC_ALGO_MASK; 1080 1081 /* Hash Data */ 1082 i++; 1083 hash_data_addr = src_addr; 1084 memcpy((uint8_t *) &payload[i], (uint8_t *) hash_data_addr, 1085 src_size); 1086 1087 i += src_size / MBOX_WORD_BYTE; 1088 1089 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_ECDSA_HASH_SIGN_REQ, 1090 payload, i, CMD_CASUAL, (uint32_t *) dst_addr, 1091 &resp_len); 1092 1093 memset((void *) &fcs_ecdsa_hash_sign_param, 1094 0, sizeof(fcs_crypto_service_data)); 1095 1096 if (status < 0) { 1097 *mbox_error = -status; 1098 return INTEL_SIP_SMC_STATUS_ERROR; 1099 } 1100 1101 *dst_size = resp_len * MBOX_WORD_BYTE; 1102 flush_dcache_range(dst_addr, *dst_size); 1103 1104 return INTEL_SIP_SMC_STATUS_OK; 1105 } 1106 1107 int intel_fcs_ecdsa_hash_sig_verify_init(uint32_t session_id, uint32_t context_id, 1108 uint32_t key_id, uint32_t param_size, 1109 uint64_t param_data, 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_ecdsa_hash_sig_verify_param, 1114 mbox_error); 1115 } 1116 1117 int intel_fcs_ecdsa_hash_sig_verify_finalize(uint32_t session_id, uint32_t context_id, 1118 uint32_t src_addr, uint32_t src_size, 1119 uint64_t dst_addr, uint32_t *dst_size, 1120 uint32_t *mbox_error) 1121 { 1122 int status; 1123 uint32_t i = 0; 1124 uint32_t payload[FCS_ECDSA_HASH_SIG_VERIFY_CMD_MAX_WORD_SIZE] = {0U}; 1125 uint32_t resp_len = *dst_size / MBOX_WORD_BYTE; 1126 uintptr_t hash_sig_pubkey_addr; 1127 1128 if ((dst_size == NULL) || (mbox_error == NULL)) { 1129 return INTEL_SIP_SMC_STATUS_REJECTED; 1130 } 1131 1132 if (fcs_ecdsa_hash_sig_verify_param.session_id != session_id || 1133 fcs_ecdsa_hash_sig_verify_param.context_id != context_id) { 1134 return INTEL_SIP_SMC_STATUS_REJECTED; 1135 } 1136 1137 if (!is_address_in_ddr_range(src_addr, src_size) || 1138 !is_address_in_ddr_range(dst_addr, *dst_size)) { 1139 return INTEL_SIP_SMC_STATUS_REJECTED; 1140 } 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_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, uint32_t *mbox_error) 1206 { 1207 int status; 1208 int i; 1209 uint32_t payload[FCS_ECDSA_SHA2_DATA_SIGN_CMD_MAX_WORD_SIZE] = {0U}; 1210 uint32_t resp_len = *dst_size / MBOX_WORD_BYTE; 1211 1212 if ((dst_size == NULL) || (mbox_error == NULL)) { 1213 return INTEL_SIP_SMC_STATUS_REJECTED; 1214 } 1215 1216 if (fcs_sha2_data_sign_param.session_id != session_id || 1217 fcs_sha2_data_sign_param.context_id != context_id) { 1218 return INTEL_SIP_SMC_STATUS_REJECTED; 1219 } 1220 1221 /* Source data must be 8 bytes aligned */ 1222 if (!is_8_bytes_aligned(src_size)) { 1223 return INTEL_SIP_SMC_STATUS_REJECTED; 1224 } 1225 1226 if (!is_address_in_ddr_range(src_addr, src_size) || 1227 !is_address_in_ddr_range(dst_addr, *dst_size)) { 1228 return INTEL_SIP_SMC_STATUS_REJECTED; 1229 } 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 = *dst_size / MBOX_WORD_BYTE; 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 /* Prepare command payload */ 1321 /* Crypto header */ 1322 i = 0; 1323 payload[i] = fcs_sha2_data_sig_verify_param.session_id; 1324 i++; 1325 payload[i] = fcs_sha2_data_sig_verify_param.context_id; 1326 i++; 1327 1328 payload[i] = fcs_sha2_data_sig_verify_param.crypto_param_size 1329 & FCS_CS_FIELD_SIZE_MASK; 1330 payload[i] |= (FCS_CS_FIELD_FLAG_INIT | FCS_CS_FIELD_FLAG_UPDATE 1331 | FCS_CS_FIELD_FLAG_FINALIZE) 1332 << FCS_CS_FIELD_FLAG_OFFSET; 1333 i++; 1334 payload[i] = fcs_sha2_data_sig_verify_param.key_id; 1335 i++; 1336 /* Crypto parameters */ 1337 payload[i] = fcs_sha2_data_sig_verify_param.crypto_param 1338 & INTEL_SIP_SMC_FCS_ECC_ALGO_MASK; 1339 i++; 1340 /* Data source address and size */ 1341 payload[i] = src_addr; 1342 i++; 1343 payload[i] = data_size; 1344 i++; 1345 /* Signature + Public Key Data */ 1346 sig_pubkey_offset = src_addr + data_size; 1347 memcpy((uint8_t *) &payload[i], (uint8_t *) sig_pubkey_offset, 1348 src_size - data_size); 1349 1350 i += (src_size - data_size) / MBOX_WORD_BYTE; 1351 1352 status = mailbox_send_cmd(MBOX_JOB_ID, 1353 MBOX_FCS_ECDSA_SHA2_DATA_SIGN_VERIFY, payload, i, 1354 CMD_CASUAL, (uint32_t *) dst_addr, &resp_len); 1355 1356 memset((void *) &fcs_sha2_data_sig_verify_param, 0, 1357 sizeof(fcs_crypto_service_data)); 1358 1359 if (status < 0) { 1360 *mbox_error = -status; 1361 return INTEL_SIP_SMC_STATUS_ERROR; 1362 } 1363 1364 *dst_size = resp_len * MBOX_WORD_BYTE; 1365 flush_dcache_range(dst_addr, *dst_size); 1366 1367 return INTEL_SIP_SMC_STATUS_OK; 1368 } 1369 1370 int intel_fcs_ecdsa_get_pubkey_init(uint32_t session_id, uint32_t context_id, 1371 uint32_t key_id, uint32_t param_size, 1372 uint64_t param_data, uint32_t *mbox_error) 1373 { 1374 return intel_fcs_crypto_service_init(session_id, context_id, 1375 key_id, param_size, param_data, 1376 (void *) &fcs_ecdsa_get_pubkey_param, 1377 mbox_error); 1378 } 1379 1380 int intel_fcs_ecdsa_get_pubkey_finalize(uint32_t session_id, uint32_t context_id, 1381 uint64_t dst_addr, uint32_t *dst_size, 1382 uint32_t *mbox_error) 1383 { 1384 int status; 1385 int i; 1386 uint32_t crypto_header; 1387 uint32_t ret_size = *dst_size / MBOX_WORD_BYTE; 1388 uint32_t payload[FCS_ECDSA_GET_PUBKEY_MAX_WORD_SIZE] = {0U}; 1389 1390 if ((dst_size == NULL) || (mbox_error == NULL)) { 1391 return INTEL_SIP_SMC_STATUS_REJECTED; 1392 } 1393 1394 if (fcs_ecdsa_get_pubkey_param.session_id != session_id || 1395 fcs_ecdsa_get_pubkey_param.context_id != context_id) { 1396 return INTEL_SIP_SMC_STATUS_REJECTED; 1397 } 1398 1399 crypto_header = ((FCS_CS_FIELD_FLAG_INIT | 1400 FCS_CS_FIELD_FLAG_UPDATE | 1401 FCS_CS_FIELD_FLAG_FINALIZE) << 1402 FCS_CS_FIELD_FLAG_OFFSET) | 1403 fcs_ecdsa_get_pubkey_param.crypto_param_size; 1404 i = 0; 1405 /* Prepare command payload */ 1406 payload[i] = session_id; 1407 i++; 1408 payload[i] = context_id; 1409 i++; 1410 payload[i] = crypto_header; 1411 i++; 1412 payload[i] = fcs_ecdsa_get_pubkey_param.key_id; 1413 i++; 1414 payload[i] = (uint32_t) fcs_ecdsa_get_pubkey_param.crypto_param & 1415 INTEL_SIP_SMC_FCS_ECC_ALGO_MASK; 1416 i++; 1417 1418 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_ECDSA_GET_PUBKEY, 1419 payload, i, CMD_CASUAL, 1420 (uint32_t *) dst_addr, &ret_size); 1421 1422 memset((void *) &fcs_ecdsa_get_pubkey_param, 0, 1423 sizeof(fcs_crypto_service_data)); 1424 1425 if (status < 0) { 1426 *mbox_error = -status; 1427 return INTEL_SIP_SMC_STATUS_ERROR; 1428 } 1429 1430 *dst_size = ret_size * MBOX_WORD_BYTE; 1431 flush_dcache_range(dst_addr, *dst_size); 1432 1433 return INTEL_SIP_SMC_STATUS_OK; 1434 } 1435 1436 int intel_fcs_ecdh_request_init(uint32_t session_id, uint32_t context_id, 1437 uint32_t key_id, uint32_t param_size, 1438 uint64_t param_data, uint32_t *mbox_error) 1439 { 1440 return intel_fcs_crypto_service_init(session_id, context_id, 1441 key_id, param_size, param_data, 1442 (void *) &fcs_ecdh_request_param, 1443 mbox_error); 1444 } 1445 1446 int intel_fcs_ecdh_request_finalize(uint32_t session_id, uint32_t context_id, 1447 uint32_t src_addr, uint32_t src_size, 1448 uint64_t dst_addr, uint32_t *dst_size, 1449 uint32_t *mbox_error) 1450 { 1451 int status; 1452 uint32_t i; 1453 uint32_t payload[FCS_ECDH_REQUEST_CMD_MAX_WORD_SIZE] = {0U}; 1454 uint32_t resp_len = *dst_size / MBOX_WORD_BYTE; 1455 uintptr_t pubkey; 1456 1457 if ((dst_size == NULL) || (mbox_error == NULL)) { 1458 return INTEL_SIP_SMC_STATUS_REJECTED; 1459 } 1460 1461 if (fcs_ecdh_request_param.session_id != session_id || 1462 fcs_ecdh_request_param.context_id != context_id) { 1463 return INTEL_SIP_SMC_STATUS_REJECTED; 1464 } 1465 1466 if (!is_address_in_ddr_range(src_addr, src_size) || 1467 !is_address_in_ddr_range(dst_addr, *dst_size)) { 1468 return INTEL_SIP_SMC_STATUS_REJECTED; 1469 } 1470 1471 /* Prepare command payload */ 1472 i = 0; 1473 /* Crypto header */ 1474 payload[i] = fcs_ecdh_request_param.session_id; 1475 i++; 1476 payload[i] = fcs_ecdh_request_param.context_id; 1477 i++; 1478 payload[i] = fcs_ecdh_request_param.crypto_param_size 1479 & FCS_CS_FIELD_SIZE_MASK; 1480 payload[i] |= (FCS_CS_FIELD_FLAG_INIT | FCS_CS_FIELD_FLAG_UPDATE 1481 | FCS_CS_FIELD_FLAG_FINALIZE) 1482 << FCS_CS_FIELD_FLAG_OFFSET; 1483 i++; 1484 payload[i] = fcs_ecdh_request_param.key_id; 1485 i++; 1486 /* Crypto parameters */ 1487 payload[i] = fcs_ecdh_request_param.crypto_param 1488 & INTEL_SIP_SMC_FCS_ECC_ALGO_MASK; 1489 i++; 1490 /* Public key data */ 1491 pubkey = src_addr; 1492 memcpy((uint8_t *) &payload[i], (uint8_t *) pubkey, src_size); 1493 i += src_size / MBOX_WORD_BYTE; 1494 1495 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_ECDH_REQUEST, 1496 payload, i, CMD_CASUAL, (uint32_t *) dst_addr, 1497 &resp_len); 1498 1499 memset((void *)&fcs_ecdh_request_param, 0, 1500 sizeof(fcs_crypto_service_data)); 1501 1502 if (status < 0) { 1503 *mbox_error = -status; 1504 return INTEL_SIP_SMC_STATUS_ERROR; 1505 } 1506 1507 *dst_size = resp_len * MBOX_WORD_BYTE; 1508 flush_dcache_range(dst_addr, *dst_size); 1509 1510 return INTEL_SIP_SMC_STATUS_OK; 1511 } 1512 1513 int intel_fcs_aes_crypt_init(uint32_t session_id, uint32_t context_id, 1514 uint32_t key_id, uint64_t param_addr, 1515 uint32_t param_size, uint32_t *mbox_error) 1516 { 1517 if (mbox_error == NULL) { 1518 return INTEL_SIP_SMC_STATUS_REJECTED; 1519 } 1520 1521 memset((void *)&fcs_aes_init_payload, 0U, sizeof(fcs_aes_init_payload)); 1522 1523 fcs_aes_init_payload.session_id = session_id; 1524 fcs_aes_init_payload.context_id = context_id; 1525 fcs_aes_init_payload.param_size = param_size; 1526 fcs_aes_init_payload.key_id = key_id; 1527 1528 memcpy((uint8_t *) fcs_aes_init_payload.crypto_param, 1529 (uint8_t *) param_addr, param_size); 1530 1531 *mbox_error = 0; 1532 1533 return INTEL_SIP_SMC_STATUS_OK; 1534 } 1535 1536 int intel_fcs_aes_crypt_finalize(uint32_t session_id, uint32_t context_id, 1537 uint64_t src_addr, uint32_t src_size, 1538 uint64_t dst_addr, uint32_t dst_size, 1539 uint32_t *send_id) 1540 { 1541 int status; 1542 int i; 1543 uint32_t crypto_header; 1544 uint32_t fcs_aes_crypt_payload[FCS_AES_CMD_MAX_WORD_SIZE]; 1545 1546 if (fcs_aes_init_payload.session_id != session_id || 1547 fcs_aes_init_payload.context_id != context_id) { 1548 return INTEL_SIP_SMC_STATUS_REJECTED; 1549 } 1550 1551 if ((!is_8_bytes_aligned(src_addr)) || 1552 (!is_32_bytes_aligned(src_size)) || 1553 (!is_address_in_ddr_range(src_addr, src_size))) { 1554 return INTEL_SIP_SMC_STATUS_REJECTED; 1555 } 1556 1557 if ((!is_8_bytes_aligned(dst_addr)) || 1558 (!is_32_bytes_aligned(dst_size))) { 1559 return INTEL_SIP_SMC_STATUS_REJECTED; 1560 } 1561 1562 if ((dst_size > FCS_AES_MAX_DATA_SIZE || 1563 dst_size < FCS_AES_MIN_DATA_SIZE) || 1564 (src_size > FCS_AES_MAX_DATA_SIZE || 1565 src_size < FCS_AES_MIN_DATA_SIZE)) { 1566 return INTEL_SIP_SMC_STATUS_REJECTED; 1567 } 1568 1569 crypto_header = ((FCS_CS_FIELD_FLAG_INIT | 1570 FCS_CS_FIELD_FLAG_UPDATE | 1571 FCS_CS_FIELD_FLAG_FINALIZE) << 1572 FCS_CS_FIELD_FLAG_OFFSET) | 1573 fcs_aes_init_payload.param_size; 1574 i = 0U; 1575 fcs_aes_crypt_payload[i] = session_id; 1576 i++; 1577 fcs_aes_crypt_payload[i] = context_id; 1578 i++; 1579 fcs_aes_crypt_payload[i] = crypto_header; 1580 i++; 1581 fcs_aes_crypt_payload[i] = fcs_aes_init_payload.key_id; 1582 1583 i++; 1584 memcpy((uint8_t *) &fcs_aes_crypt_payload[i], 1585 (uint8_t *) fcs_aes_init_payload.crypto_param, 1586 fcs_aes_init_payload.param_size); 1587 1588 i += fcs_aes_init_payload.param_size / MBOX_WORD_BYTE; 1589 1590 fcs_aes_crypt_payload[i] = (uint32_t) src_addr; 1591 i++; 1592 fcs_aes_crypt_payload[i] = src_size; 1593 i++; 1594 fcs_aes_crypt_payload[i] = (uint32_t) dst_addr; 1595 i++; 1596 fcs_aes_crypt_payload[i] = dst_size; 1597 i++; 1598 1599 status = mailbox_send_cmd_async(send_id, MBOX_FCS_AES_CRYPT_REQ, 1600 fcs_aes_crypt_payload, i, 1601 CMD_INDIRECT); 1602 1603 memset((void *)&fcs_aes_init_payload, 0U, sizeof(fcs_aes_init_payload)); 1604 1605 if (status < 0U) { 1606 return INTEL_SIP_SMC_STATUS_ERROR; 1607 } 1608 1609 return INTEL_SIP_SMC_STATUS_OK; 1610 } 1611