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