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 inv_dcache_range(src_addr, src_size); /* flush cache before mmio read to avoid reading old values */ 287 id_offset = src_addr + FCS_OWNER_ID_OFFSET; 288 fcs_decrypt_payload payload = { 289 FCS_DECRYPTION_DATA_0, 290 {mmio_read_32(id_offset), 291 mmio_read_32(id_offset + MBOX_WORD_BYTE)}, 292 src_addr, 293 src_size, 294 dst_addr, 295 dst_size }; 296 load_size = sizeof(payload) / MBOX_WORD_BYTE; 297 298 if (!is_address_in_ddr_range(src_addr, src_size) || 299 !is_address_in_ddr_range(dst_addr, dst_size)) { 300 return INTEL_SIP_SMC_STATUS_REJECTED; 301 } 302 303 if (!is_size_4_bytes_aligned(src_size)) { 304 return INTEL_SIP_SMC_STATUS_REJECTED; 305 } 306 307 status = mailbox_send_cmd_async(send_id, MBOX_FCS_DECRYPT_REQ, 308 (uint32_t *) &payload, load_size, 309 CMD_INDIRECT); 310 inv_dcache_range(dst_addr, dst_size); 311 312 if (status < 0) { 313 return INTEL_SIP_SMC_STATUS_REJECTED; 314 } 315 316 return INTEL_SIP_SMC_STATUS_OK; 317 } 318 319 int intel_fcs_encryption_ext(uint32_t session_id, uint32_t context_id, 320 uint32_t src_addr, uint32_t src_size, 321 uint32_t dst_addr, uint32_t *dst_size, uint32_t *mbox_error) 322 { 323 int status; 324 uint32_t payload_size; 325 uint32_t resp_len = FCS_CRYPTION_RESP_WORD_SIZE; 326 uint32_t resp_data[FCS_CRYPTION_RESP_WORD_SIZE] = {0U}; 327 328 if ((dst_size == NULL) || (mbox_error == NULL)) { 329 return INTEL_SIP_SMC_STATUS_REJECTED; 330 } 331 332 if (!is_address_in_ddr_range(src_addr, src_size) || 333 !is_address_in_ddr_range(dst_addr, *dst_size)) { 334 return INTEL_SIP_SMC_STATUS_REJECTED; 335 } 336 337 if (!is_size_4_bytes_aligned(src_size)) { 338 return INTEL_SIP_SMC_STATUS_REJECTED; 339 } 340 341 fcs_encrypt_ext_payload payload = { 342 session_id, 343 context_id, 344 FCS_CRYPTION_CRYPTO_HEADER, 345 src_addr, 346 src_size, 347 dst_addr, 348 *dst_size 349 }; 350 351 payload_size = sizeof(payload) / MBOX_WORD_BYTE; 352 353 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_ENCRYPT_REQ, 354 (uint32_t *) &payload, payload_size, 355 CMD_CASUAL, resp_data, &resp_len); 356 357 if (status < 0) { 358 *mbox_error = -status; 359 return INTEL_SIP_SMC_STATUS_ERROR; 360 } 361 362 if (resp_len != FCS_CRYPTION_RESP_WORD_SIZE) { 363 *mbox_error = MBOX_RET_ERROR; 364 return INTEL_SIP_SMC_STATUS_ERROR; 365 } 366 367 *dst_size = resp_data[FCS_CRYPTION_RESP_SIZE_OFFSET]; 368 inv_dcache_range(dst_addr, *dst_size); 369 370 return INTEL_SIP_SMC_STATUS_OK; 371 } 372 373 int intel_fcs_decryption_ext(uint32_t session_id, uint32_t context_id, 374 uint32_t src_addr, uint32_t src_size, 375 uint32_t dst_addr, uint32_t *dst_size, uint32_t *mbox_error) 376 { 377 int status; 378 uintptr_t id_offset; 379 uint32_t payload_size; 380 uint32_t resp_len = FCS_CRYPTION_RESP_WORD_SIZE; 381 uint32_t resp_data[FCS_CRYPTION_RESP_WORD_SIZE] = {0U}; 382 383 if ((dst_size == NULL) || (mbox_error == NULL)) { 384 return INTEL_SIP_SMC_STATUS_REJECTED; 385 } 386 387 if (!is_address_in_ddr_range(src_addr, src_size) || 388 !is_address_in_ddr_range(dst_addr, *dst_size)) { 389 return INTEL_SIP_SMC_STATUS_REJECTED; 390 } 391 392 if (!is_size_4_bytes_aligned(src_size)) { 393 return INTEL_SIP_SMC_STATUS_REJECTED; 394 } 395 396 inv_dcache_range(src_addr, src_size); /* flush cache before mmio read to avoid reading old values */ 397 id_offset = src_addr + FCS_OWNER_ID_OFFSET; 398 fcs_decrypt_ext_payload payload = { 399 session_id, 400 context_id, 401 FCS_CRYPTION_CRYPTO_HEADER, 402 {mmio_read_32(id_offset), 403 mmio_read_32(id_offset + MBOX_WORD_BYTE)}, 404 src_addr, 405 src_size, 406 dst_addr, 407 *dst_size 408 }; 409 410 payload_size = sizeof(payload) / MBOX_WORD_BYTE; 411 412 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_DECRYPT_REQ, 413 (uint32_t *) &payload, payload_size, 414 CMD_CASUAL, resp_data, &resp_len); 415 416 if (status == MBOX_RET_SDOS_DECRYPTION_ERROR_102 || 417 status == MBOX_RET_SDOS_DECRYPTION_ERROR_103) { 418 *mbox_error = -status; 419 } else if (status < 0) { 420 *mbox_error = -status; 421 return INTEL_SIP_SMC_STATUS_ERROR; 422 } 423 424 if (resp_len != FCS_CRYPTION_RESP_WORD_SIZE) { 425 *mbox_error = MBOX_RET_ERROR; 426 return INTEL_SIP_SMC_STATUS_ERROR; 427 } 428 429 *dst_size = resp_data[FCS_CRYPTION_RESP_SIZE_OFFSET]; 430 inv_dcache_range(dst_addr, *dst_size); 431 432 return INTEL_SIP_SMC_STATUS_OK; 433 } 434 435 int intel_fcs_sigma_teardown(uint32_t session_id, uint32_t *mbox_error) 436 { 437 int status; 438 439 if ((session_id != PSGSIGMA_SESSION_ID_ONE) && 440 (session_id != PSGSIGMA_UNKNOWN_SESSION)) { 441 return INTEL_SIP_SMC_STATUS_REJECTED; 442 } 443 444 psgsigma_teardown_msg message = { 445 RESERVED_AS_ZERO, 446 PSGSIGMA_TEARDOWN_MAGIC, 447 session_id 448 }; 449 450 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_PSG_SIGMA_TEARDOWN, 451 (uint32_t *) &message, sizeof(message) / MBOX_WORD_BYTE, 452 CMD_CASUAL, NULL, NULL); 453 454 if (status < 0) { 455 *mbox_error = -status; 456 return INTEL_SIP_SMC_STATUS_ERROR; 457 } 458 459 return INTEL_SIP_SMC_STATUS_OK; 460 } 461 462 int intel_fcs_chip_id(uint32_t *id_low, uint32_t *id_high, uint32_t *mbox_error) 463 { 464 int status; 465 uint32_t load_size; 466 uint32_t chip_id[2]; 467 468 load_size = sizeof(chip_id) / MBOX_WORD_BYTE; 469 470 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_CMD_GET_CHIPID, NULL, 471 0U, CMD_CASUAL, (uint32_t *) chip_id, &load_size); 472 473 if (status < 0) { 474 *mbox_error = -status; 475 return INTEL_SIP_SMC_STATUS_ERROR; 476 } 477 478 *id_low = chip_id[0]; 479 *id_high = chip_id[1]; 480 481 return INTEL_SIP_SMC_STATUS_OK; 482 } 483 484 int intel_fcs_attestation_subkey(uint64_t src_addr, uint32_t src_size, 485 uint64_t dst_addr, uint32_t *dst_size, uint32_t *mbox_error) 486 { 487 int status; 488 uint32_t send_size = src_size / MBOX_WORD_BYTE; 489 uint32_t ret_size = *dst_size / MBOX_WORD_BYTE; 490 491 492 if (!is_address_in_ddr_range(src_addr, src_size) || 493 !is_address_in_ddr_range(dst_addr, *dst_size)) { 494 return INTEL_SIP_SMC_STATUS_REJECTED; 495 } 496 497 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_ATTESTATION_SUBKEY, 498 (uint32_t *) src_addr, send_size, CMD_CASUAL, 499 (uint32_t *) dst_addr, &ret_size); 500 501 if (status < 0) { 502 *mbox_error = -status; 503 return INTEL_SIP_SMC_STATUS_ERROR; 504 } 505 506 *dst_size = ret_size * MBOX_WORD_BYTE; 507 flush_dcache_range(dst_addr, *dst_size); 508 509 return INTEL_SIP_SMC_STATUS_OK; 510 } 511 512 int intel_fcs_get_measurement(uint64_t src_addr, uint32_t src_size, 513 uint64_t dst_addr, uint32_t *dst_size, uint32_t *mbox_error) 514 { 515 int status; 516 uint32_t send_size = src_size / MBOX_WORD_BYTE; 517 uint32_t ret_size = *dst_size / MBOX_WORD_BYTE; 518 519 if (!is_address_in_ddr_range(src_addr, src_size) || 520 !is_address_in_ddr_range(dst_addr, *dst_size)) { 521 return INTEL_SIP_SMC_STATUS_REJECTED; 522 } 523 524 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_GET_MEASUREMENT, 525 (uint32_t *) src_addr, send_size, CMD_CASUAL, 526 (uint32_t *) dst_addr, &ret_size); 527 528 if (status < 0) { 529 *mbox_error = -status; 530 return INTEL_SIP_SMC_STATUS_ERROR; 531 } 532 533 *dst_size = ret_size * MBOX_WORD_BYTE; 534 flush_dcache_range(dst_addr, *dst_size); 535 536 return INTEL_SIP_SMC_STATUS_OK; 537 } 538 539 uint32_t intel_fcs_get_rom_patch_sha384(uint64_t addr, uint64_t *ret_size, 540 uint32_t *mbox_error) 541 { 542 int status; 543 unsigned int resp_len = FCS_SHA384_WORD_SIZE; 544 545 if (!is_address_in_ddr_range(addr, FCS_SHA384_BYTE_SIZE)) { 546 return INTEL_SIP_SMC_STATUS_REJECTED; 547 } 548 549 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_GET_ROM_PATCH_SHA384, NULL, 0U, 550 CMD_CASUAL, (uint32_t *) addr, &resp_len); 551 552 if (status < 0) { 553 *mbox_error = -status; 554 return INTEL_SIP_SMC_STATUS_ERROR; 555 } 556 557 if (resp_len != FCS_SHA384_WORD_SIZE) { 558 *mbox_error = GENERIC_RESPONSE_ERROR; 559 return INTEL_SIP_SMC_STATUS_ERROR; 560 } 561 562 *ret_size = FCS_SHA384_BYTE_SIZE; 563 564 flush_dcache_range(addr, *ret_size); 565 566 return INTEL_SIP_SMC_STATUS_OK; 567 } 568 569 int intel_fcs_get_attestation_cert(uint32_t cert_request, uint64_t dst_addr, 570 uint32_t *dst_size, uint32_t *mbox_error) 571 { 572 int status; 573 uint32_t ret_size = *dst_size / MBOX_WORD_BYTE; 574 575 if (mbox_error == NULL) { 576 return INTEL_SIP_SMC_STATUS_REJECTED; 577 } 578 579 if (cert_request < FCS_ATTEST_FIRMWARE_CERT || 580 cert_request > FCS_ATTEST_CERT_MAX_REQ_PARAM) { 581 return INTEL_SIP_SMC_STATUS_REJECTED; 582 } 583 584 if (!is_address_in_ddr_range(dst_addr, *dst_size)) { 585 return INTEL_SIP_SMC_STATUS_REJECTED; 586 } 587 588 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_GET_ATTESTATION_CERT, 589 (uint32_t *) &cert_request, 1U, CMD_CASUAL, 590 (uint32_t *) dst_addr, &ret_size); 591 592 if (status < 0) { 593 *mbox_error = -status; 594 return INTEL_SIP_SMC_STATUS_ERROR; 595 } 596 597 *dst_size = ret_size * MBOX_WORD_BYTE; 598 flush_dcache_range(dst_addr, *dst_size); 599 600 return INTEL_SIP_SMC_STATUS_OK; 601 } 602 603 int intel_fcs_create_cert_on_reload(uint32_t cert_request, 604 uint32_t *mbox_error) 605 { 606 int status; 607 608 if (mbox_error == NULL) { 609 return INTEL_SIP_SMC_STATUS_REJECTED; 610 } 611 612 if (cert_request < FCS_ATTEST_FIRMWARE_CERT || 613 cert_request > FCS_ATTEST_CERT_MAX_REQ_PARAM) { 614 return INTEL_SIP_SMC_STATUS_REJECTED; 615 } 616 617 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_CREATE_CERT_ON_RELOAD, 618 (uint32_t *) &cert_request, 1U, CMD_CASUAL, 619 NULL, NULL); 620 621 if (status < 0) { 622 *mbox_error = -status; 623 return INTEL_SIP_SMC_STATUS_ERROR; 624 } 625 626 return INTEL_SIP_SMC_STATUS_OK; 627 } 628 629 int intel_fcs_open_crypto_service_session(uint32_t *session_id, 630 uint32_t *mbox_error) 631 { 632 int status; 633 uint32_t resp_len = 1U; 634 635 if ((session_id == NULL) || (mbox_error == NULL)) { 636 return INTEL_SIP_SMC_STATUS_REJECTED; 637 } 638 639 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_OPEN_CS_SESSION, 640 NULL, 0U, CMD_CASUAL, session_id, &resp_len); 641 642 if (status < 0) { 643 *mbox_error = -status; 644 return INTEL_SIP_SMC_STATUS_ERROR; 645 } 646 647 return INTEL_SIP_SMC_STATUS_OK; 648 } 649 650 int intel_fcs_close_crypto_service_session(uint32_t session_id, 651 uint32_t *mbox_error) 652 { 653 int status; 654 655 if (mbox_error == NULL) { 656 return INTEL_SIP_SMC_STATUS_REJECTED; 657 } 658 659 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_CLOSE_CS_SESSION, 660 &session_id, 1U, CMD_CASUAL, NULL, NULL); 661 662 if (status < 0) { 663 *mbox_error = -status; 664 return INTEL_SIP_SMC_STATUS_ERROR; 665 } 666 667 return INTEL_SIP_SMC_STATUS_OK; 668 } 669 670 int intel_fcs_import_crypto_service_key(uint64_t src_addr, uint32_t src_size, 671 uint32_t *send_id) 672 { 673 int status; 674 675 if (src_size > (FCS_CS_KEY_OBJ_MAX_WORD_SIZE * 676 MBOX_WORD_BYTE)) { 677 return INTEL_SIP_SMC_STATUS_REJECTED; 678 } 679 680 if (!is_address_in_ddr_range(src_addr, src_size)) { 681 return INTEL_SIP_SMC_STATUS_REJECTED; 682 } 683 684 status = mailbox_send_cmd_async(send_id, MBOX_FCS_IMPORT_CS_KEY, 685 (uint32_t *)src_addr, src_size / MBOX_WORD_BYTE, 686 CMD_INDIRECT); 687 688 if (status < 0) { 689 return INTEL_SIP_SMC_STATUS_ERROR; 690 } 691 692 return INTEL_SIP_SMC_STATUS_OK; 693 } 694 695 int intel_fcs_export_crypto_service_key(uint32_t session_id, uint32_t key_id, 696 uint64_t dst_addr, uint32_t *dst_size, 697 uint32_t *mbox_error) 698 { 699 int status; 700 uint32_t i; 701 uint32_t payload_size; 702 uint32_t resp_len = FCS_CS_KEY_OBJ_MAX_WORD_SIZE; 703 uint32_t resp_data[FCS_CS_KEY_OBJ_MAX_WORD_SIZE] = {0U}; 704 uint32_t op_status = 0U; 705 706 if ((dst_size == NULL) || (mbox_error == NULL)) { 707 return INTEL_SIP_SMC_STATUS_REJECTED; 708 } 709 710 if (!is_address_in_ddr_range(dst_addr, *dst_size)) { 711 return INTEL_SIP_SMC_STATUS_REJECTED; 712 } 713 714 fcs_cs_key_payload payload = { 715 session_id, 716 RESERVED_AS_ZERO, 717 RESERVED_AS_ZERO, 718 key_id 719 }; 720 721 payload_size = sizeof(payload) / MBOX_WORD_BYTE; 722 723 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_EXPORT_CS_KEY, 724 (uint32_t *) &payload, payload_size, 725 CMD_CASUAL, resp_data, &resp_len); 726 727 if (resp_len > 0) { 728 op_status = resp_data[0] & FCS_CS_KEY_RESP_STATUS_MASK; 729 } 730 731 if (status < 0) { 732 *mbox_error = (-status) | (op_status << FCS_CS_KEY_RESP_STATUS_OFFSET); 733 return INTEL_SIP_SMC_STATUS_ERROR; 734 } 735 736 if (resp_len > 1) { 737 738 /* Export key object is start at second response data */ 739 *dst_size = (resp_len - 1) * MBOX_WORD_BYTE; 740 741 for (i = 1U; i < resp_len; i++) { 742 mmio_write_32(dst_addr, resp_data[i]); 743 dst_addr += MBOX_WORD_BYTE; 744 } 745 746 flush_dcache_range(dst_addr - *dst_size, *dst_size); 747 748 } else { 749 750 /* Unexpected response, missing key object in response */ 751 *mbox_error = MBOX_RET_ERROR; 752 return INTEL_SIP_SMC_STATUS_ERROR; 753 } 754 755 return INTEL_SIP_SMC_STATUS_OK; 756 } 757 758 int intel_fcs_remove_crypto_service_key(uint32_t session_id, uint32_t key_id, 759 uint32_t *mbox_error) 760 { 761 int status; 762 uint32_t payload_size; 763 uint32_t resp_len = 1U; 764 uint32_t resp_data = 0U; 765 uint32_t op_status = 0U; 766 767 if (mbox_error == NULL) { 768 return INTEL_SIP_SMC_STATUS_REJECTED; 769 } 770 771 fcs_cs_key_payload payload = { 772 session_id, 773 RESERVED_AS_ZERO, 774 RESERVED_AS_ZERO, 775 key_id 776 }; 777 778 payload_size = sizeof(payload) / MBOX_WORD_BYTE; 779 780 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_REMOVE_CS_KEY, 781 (uint32_t *) &payload, payload_size, 782 CMD_CASUAL, &resp_data, &resp_len); 783 784 if (resp_len > 0) { 785 op_status = resp_data & FCS_CS_KEY_RESP_STATUS_MASK; 786 } 787 788 if (status < 0) { 789 *mbox_error = (-status) | (op_status << FCS_CS_KEY_RESP_STATUS_OFFSET); 790 return INTEL_SIP_SMC_STATUS_ERROR; 791 } 792 793 return INTEL_SIP_SMC_STATUS_OK; 794 } 795 796 int intel_fcs_get_crypto_service_key_info(uint32_t session_id, uint32_t key_id, 797 uint64_t dst_addr, uint32_t *dst_size, 798 uint32_t *mbox_error) 799 { 800 int status; 801 uint32_t payload_size; 802 uint32_t resp_len = FCS_CS_KEY_INFO_MAX_WORD_SIZE; 803 uint32_t op_status = 0U; 804 805 if ((dst_size == NULL) || (mbox_error == NULL)) { 806 return INTEL_SIP_SMC_STATUS_REJECTED; 807 } 808 809 if (!is_address_in_ddr_range(dst_addr, *dst_size)) { 810 return INTEL_SIP_SMC_STATUS_REJECTED; 811 } 812 813 fcs_cs_key_payload payload = { 814 session_id, 815 RESERVED_AS_ZERO, 816 RESERVED_AS_ZERO, 817 key_id 818 }; 819 820 payload_size = sizeof(payload) / MBOX_WORD_BYTE; 821 822 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_GET_CS_KEY_INFO, 823 (uint32_t *) &payload, payload_size, 824 CMD_CASUAL, (uint32_t *) dst_addr, &resp_len); 825 826 if (resp_len > 0) { 827 inv_dcache_range(dst_addr, (resp_len * MBOX_WORD_BYTE)); /* flush cache before mmio read to avoid reading old values */ 828 op_status = mmio_read_32(dst_addr) & 829 FCS_CS_KEY_RESP_STATUS_MASK; 830 } 831 832 if (status < 0) { 833 *mbox_error = (-status) | (op_status << FCS_CS_KEY_RESP_STATUS_OFFSET); 834 return INTEL_SIP_SMC_STATUS_ERROR; 835 } 836 837 *dst_size = resp_len * MBOX_WORD_BYTE; 838 flush_dcache_range(dst_addr, *dst_size); 839 840 return INTEL_SIP_SMC_STATUS_OK; 841 } 842 843 int intel_fcs_get_digest_init(uint32_t session_id, uint32_t context_id, 844 uint32_t key_id, uint32_t param_size, 845 uint64_t param_data, uint32_t *mbox_error) 846 { 847 return intel_fcs_crypto_service_init(session_id, context_id, 848 key_id, param_size, param_data, 849 (void *) &fcs_sha_get_digest_param, 850 mbox_error); 851 } 852 853 int intel_fcs_get_digest_update_finalize(uint32_t session_id, 854 uint32_t context_id, uint32_t src_addr, 855 uint32_t src_size, uint64_t dst_addr, 856 uint32_t *dst_size, uint8_t is_finalised, 857 uint32_t *mbox_error) 858 { 859 int status; 860 uint32_t i; 861 uint32_t flag; 862 uint32_t crypto_header; 863 uint32_t resp_len; 864 uint32_t payload[FCS_GET_DIGEST_CMD_MAX_WORD_SIZE] = {0U}; 865 866 if (dst_size == NULL || mbox_error == NULL) { 867 return INTEL_SIP_SMC_STATUS_REJECTED; 868 } 869 870 if (fcs_sha_get_digest_param.session_id != session_id || 871 fcs_sha_get_digest_param.context_id != context_id) { 872 return INTEL_SIP_SMC_STATUS_REJECTED; 873 } 874 875 /* Source data must be 8 bytes aligned */ 876 if (!is_8_bytes_aligned(src_size)) { 877 return INTEL_SIP_SMC_STATUS_REJECTED; 878 } 879 880 if (!is_address_in_ddr_range(src_addr, src_size) || 881 !is_address_in_ddr_range(dst_addr, *dst_size)) { 882 return INTEL_SIP_SMC_STATUS_REJECTED; 883 } 884 885 resp_len = *dst_size / MBOX_WORD_BYTE; 886 887 /* Prepare crypto header */ 888 flag = 0; 889 890 if (fcs_sha_get_digest_param.is_updated) { 891 fcs_sha_get_digest_param.crypto_param_size = 0; 892 } else { 893 flag |= FCS_CS_FIELD_FLAG_INIT; 894 } 895 896 if (is_finalised != 0U) { 897 flag |= FCS_CS_FIELD_FLAG_FINALIZE; 898 } else { 899 flag |= FCS_CS_FIELD_FLAG_UPDATE; 900 fcs_sha_get_digest_param.is_updated = 1; 901 } 902 903 crypto_header = ((flag << FCS_CS_FIELD_FLAG_OFFSET) | 904 (fcs_sha_get_digest_param.crypto_param_size & 905 FCS_CS_FIELD_SIZE_MASK)); 906 907 /* Prepare command payload */ 908 i = 0; 909 payload[i] = fcs_sha_get_digest_param.session_id; 910 i++; 911 payload[i] = fcs_sha_get_digest_param.context_id; 912 i++; 913 payload[i] = crypto_header; 914 i++; 915 916 if ((crypto_header >> FCS_CS_FIELD_FLAG_OFFSET) & 917 FCS_CS_FIELD_FLAG_INIT) { 918 payload[i] = fcs_sha_get_digest_param.key_id; 919 i++; 920 /* Crypto parameters */ 921 payload[i] = fcs_sha_get_digest_param.crypto_param 922 & INTEL_SIP_SMC_FCS_SHA_MODE_MASK; 923 payload[i] |= ((fcs_sha_get_digest_param.crypto_param 924 >> INTEL_SIP_SMC_FCS_DIGEST_SIZE_OFFSET) 925 & INTEL_SIP_SMC_FCS_DIGEST_SIZE_MASK) 926 << FCS_SHA_HMAC_CRYPTO_PARAM_SIZE_OFFSET; 927 i++; 928 } 929 /* Data source address and size */ 930 payload[i] = src_addr; 931 i++; 932 payload[i] = src_size; 933 i++; 934 935 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_GET_DIGEST_REQ, 936 payload, i, CMD_CASUAL, 937 (uint32_t *) dst_addr, &resp_len); 938 939 if (is_finalised != 0U) { 940 memset((void *)&fcs_sha_get_digest_param, 0, 941 sizeof(fcs_crypto_service_data)); 942 } 943 944 if (status < 0) { 945 *mbox_error = -status; 946 return INTEL_SIP_SMC_STATUS_ERROR; 947 } 948 949 *dst_size = resp_len * MBOX_WORD_BYTE; 950 flush_dcache_range(dst_addr, *dst_size); 951 952 return INTEL_SIP_SMC_STATUS_OK; 953 } 954 955 int intel_fcs_get_digest_smmu_update_finalize(uint32_t session_id, 956 uint32_t context_id, uint32_t src_addr, 957 uint32_t src_size, uint64_t dst_addr, 958 uint32_t *dst_size, uint8_t is_finalised, 959 uint32_t *mbox_error, uint32_t *send_id) 960 { 961 int status; 962 uint32_t i; 963 uint32_t flag; 964 uint32_t crypto_header; 965 uint32_t resp_len; 966 uint32_t payload[FCS_GET_DIGEST_CMD_MAX_WORD_SIZE] = {0U}; 967 968 /* Source data must be 8 bytes aligned */ 969 if (dst_size == NULL || mbox_error == NULL || 970 !is_8_bytes_aligned(src_size)) { 971 return INTEL_SIP_SMC_STATUS_REJECTED; 972 } 973 974 if (fcs_sha_get_digest_param.session_id != session_id || 975 fcs_sha_get_digest_param.context_id != context_id) { 976 return INTEL_SIP_SMC_STATUS_REJECTED; 977 } 978 979 if (!is_address_in_ddr_range(src_addr, src_size) || 980 !is_address_in_ddr_range(dst_addr, *dst_size)) { 981 return INTEL_SIP_SMC_STATUS_REJECTED; 982 } 983 984 resp_len = *dst_size / MBOX_WORD_BYTE; 985 986 /* Prepare crypto header */ 987 flag = 0; 988 989 if (fcs_sha_get_digest_param.is_updated) { 990 fcs_sha_get_digest_param.crypto_param_size = 0; 991 } else { 992 flag |= FCS_CS_FIELD_FLAG_INIT; 993 } 994 995 if (is_finalised != 0U) { 996 flag |= FCS_CS_FIELD_FLAG_FINALIZE; 997 } else { 998 flag |= FCS_CS_FIELD_FLAG_UPDATE; 999 fcs_sha_get_digest_param.is_updated = 1; 1000 } 1001 1002 crypto_header = ((flag << FCS_CS_FIELD_FLAG_OFFSET) | 1003 (fcs_sha_get_digest_param.crypto_param_size & 1004 FCS_CS_FIELD_SIZE_MASK)); 1005 1006 /* Prepare command payload */ 1007 i = 0; 1008 payload[i] = fcs_sha_get_digest_param.session_id; 1009 i++; 1010 payload[i] = fcs_sha_get_digest_param.context_id; 1011 i++; 1012 payload[i] = crypto_header; 1013 i++; 1014 1015 if ((crypto_header >> FCS_CS_FIELD_FLAG_OFFSET) & 1016 FCS_CS_FIELD_FLAG_INIT) { 1017 payload[i] = fcs_sha_get_digest_param.key_id; 1018 i++; 1019 /* Crypto parameters */ 1020 payload[i] = fcs_sha_get_digest_param.crypto_param 1021 & INTEL_SIP_SMC_FCS_SHA_MODE_MASK; 1022 payload[i] |= ((fcs_sha_get_digest_param.crypto_param 1023 >> INTEL_SIP_SMC_FCS_DIGEST_SIZE_OFFSET) 1024 & INTEL_SIP_SMC_FCS_DIGEST_SIZE_MASK) 1025 << FCS_SHA_HMAC_CRYPTO_PARAM_SIZE_OFFSET; 1026 i++; 1027 } 1028 /* Data source address and size */ 1029 payload[i] = src_addr; 1030 i++; 1031 payload[i] = src_size; 1032 i++; 1033 1034 status = mailbox_send_cmd_async(send_id, MBOX_FCS_GET_DIGEST_REQ, 1035 payload, i, CMD_INDIRECT); 1036 1037 if (is_finalised != 0U) { 1038 memset((void *)&fcs_sha_get_digest_param, 0, 1039 sizeof(fcs_crypto_service_data)); 1040 } 1041 1042 if (status < 0) { 1043 *mbox_error = -status; 1044 return INTEL_SIP_SMC_STATUS_ERROR; 1045 } 1046 1047 *dst_size = resp_len * MBOX_WORD_BYTE; 1048 flush_dcache_range(dst_addr, *dst_size); 1049 1050 return INTEL_SIP_SMC_STATUS_OK; 1051 } 1052 1053 int intel_fcs_mac_verify_init(uint32_t session_id, uint32_t context_id, 1054 uint32_t key_id, uint32_t param_size, 1055 uint64_t param_data, uint32_t *mbox_error) 1056 { 1057 return intel_fcs_crypto_service_init(session_id, context_id, 1058 key_id, param_size, param_data, 1059 (void *) &fcs_sha_mac_verify_param, 1060 mbox_error); 1061 } 1062 1063 int intel_fcs_mac_verify_update_finalize(uint32_t session_id, 1064 uint32_t context_id, uint32_t src_addr, 1065 uint32_t src_size, uint64_t dst_addr, 1066 uint32_t *dst_size, uint32_t data_size, 1067 uint8_t is_finalised, uint32_t *mbox_error) 1068 { 1069 int status; 1070 uint32_t i; 1071 uint32_t flag; 1072 uint32_t crypto_header; 1073 uint32_t resp_len; 1074 uint32_t payload[FCS_MAC_VERIFY_CMD_MAX_WORD_SIZE] = {0U}; 1075 uintptr_t mac_offset; 1076 1077 if (dst_size == NULL || mbox_error == NULL) { 1078 return INTEL_SIP_SMC_STATUS_REJECTED; 1079 } 1080 1081 if (fcs_sha_mac_verify_param.session_id != session_id || 1082 fcs_sha_mac_verify_param.context_id != context_id) { 1083 return INTEL_SIP_SMC_STATUS_REJECTED; 1084 } 1085 1086 if (data_size > src_size) { 1087 return INTEL_SIP_SMC_STATUS_REJECTED; 1088 } 1089 1090 if (!is_size_4_bytes_aligned(src_size) || 1091 !is_8_bytes_aligned(data_size)) { 1092 return INTEL_SIP_SMC_STATUS_REJECTED; 1093 } 1094 1095 if (!is_address_in_ddr_range(src_addr, src_size) || 1096 !is_address_in_ddr_range(dst_addr, *dst_size)) { 1097 return INTEL_SIP_SMC_STATUS_REJECTED; 1098 } 1099 1100 resp_len = *dst_size / MBOX_WORD_BYTE; 1101 1102 /* Prepare crypto header */ 1103 flag = 0; 1104 1105 if (fcs_sha_mac_verify_param.is_updated) { 1106 fcs_sha_mac_verify_param.crypto_param_size = 0; 1107 } else { 1108 flag |= FCS_CS_FIELD_FLAG_INIT; 1109 } 1110 1111 if (is_finalised) { 1112 flag |= FCS_CS_FIELD_FLAG_FINALIZE; 1113 } else { 1114 flag |= FCS_CS_FIELD_FLAG_UPDATE; 1115 fcs_sha_mac_verify_param.is_updated = 1; 1116 } 1117 1118 crypto_header = ((flag << FCS_CS_FIELD_FLAG_OFFSET) | 1119 (fcs_sha_mac_verify_param.crypto_param_size & 1120 FCS_CS_FIELD_SIZE_MASK)); 1121 1122 /* Prepare command payload */ 1123 i = 0; 1124 payload[i] = fcs_sha_mac_verify_param.session_id; 1125 i++; 1126 payload[i] = fcs_sha_mac_verify_param.context_id; 1127 i++; 1128 payload[i] = crypto_header; 1129 i++; 1130 1131 if ((crypto_header >> FCS_CS_FIELD_FLAG_OFFSET) & 1132 FCS_CS_FIELD_FLAG_INIT) { 1133 payload[i] = fcs_sha_mac_verify_param.key_id; 1134 i++; 1135 /* Crypto parameters */ 1136 payload[i] = ((fcs_sha_mac_verify_param.crypto_param 1137 >> INTEL_SIP_SMC_FCS_DIGEST_SIZE_OFFSET) 1138 & INTEL_SIP_SMC_FCS_DIGEST_SIZE_MASK) 1139 << FCS_SHA_HMAC_CRYPTO_PARAM_SIZE_OFFSET; 1140 i++; 1141 } 1142 /* Data source address and size */ 1143 payload[i] = src_addr; 1144 i++; 1145 payload[i] = data_size; 1146 i++; 1147 1148 if ((crypto_header >> FCS_CS_FIELD_FLAG_OFFSET) & 1149 FCS_CS_FIELD_FLAG_FINALIZE) { 1150 /* Copy mac data to command */ 1151 mac_offset = src_addr + data_size; 1152 memcpy((uint8_t *) &payload[i], (uint8_t *) mac_offset, 1153 src_size - data_size); 1154 1155 i += (src_size - data_size) / MBOX_WORD_BYTE; 1156 } 1157 1158 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_MAC_VERIFY_REQ, 1159 payload, i, CMD_CASUAL, 1160 (uint32_t *) dst_addr, &resp_len); 1161 1162 if (is_finalised) { 1163 memset((void *)&fcs_sha_mac_verify_param, 0, 1164 sizeof(fcs_crypto_service_data)); 1165 } 1166 1167 if (status < 0) { 1168 *mbox_error = -status; 1169 return INTEL_SIP_SMC_STATUS_ERROR; 1170 } 1171 1172 *dst_size = resp_len * MBOX_WORD_BYTE; 1173 flush_dcache_range(dst_addr, *dst_size); 1174 1175 return INTEL_SIP_SMC_STATUS_OK; 1176 } 1177 1178 int intel_fcs_mac_verify_smmu_update_finalize(uint32_t session_id, 1179 uint32_t context_id, uint32_t src_addr, 1180 uint32_t src_size, uint64_t dst_addr, 1181 uint32_t *dst_size, uint32_t data_size, 1182 uint8_t is_finalised, uint32_t *mbox_error, 1183 uint32_t *send_id) 1184 { 1185 int status; 1186 uint32_t i; 1187 uint32_t flag; 1188 uint32_t crypto_header; 1189 uint32_t resp_len; 1190 uint32_t payload[FCS_MAC_VERIFY_CMD_MAX_WORD_SIZE] = {0U}; 1191 uintptr_t mac_offset; 1192 1193 /* 1194 * Source data must be 4 bytes aligned 1195 * User data must be 8 bytes aligned 1196 */ 1197 if (dst_size == NULL || mbox_error == NULL || 1198 !is_size_4_bytes_aligned(src_size) || 1199 !is_8_bytes_aligned(data_size)) { 1200 return INTEL_SIP_SMC_STATUS_REJECTED; 1201 } 1202 1203 if (data_size > src_size) { 1204 return INTEL_SIP_SMC_STATUS_REJECTED; 1205 } 1206 1207 if (fcs_sha_mac_verify_param.session_id != session_id || 1208 fcs_sha_mac_verify_param.context_id != context_id) { 1209 return INTEL_SIP_SMC_STATUS_REJECTED; 1210 } 1211 1212 if (!is_address_in_ddr_range(src_addr, src_size) || 1213 !is_address_in_ddr_range(dst_addr, *dst_size)) { 1214 return INTEL_SIP_SMC_STATUS_REJECTED; 1215 } 1216 1217 resp_len = *dst_size / MBOX_WORD_BYTE; 1218 1219 /* Prepare crypto header */ 1220 flag = 0; 1221 1222 if (fcs_sha_mac_verify_param.is_updated) { 1223 fcs_sha_mac_verify_param.crypto_param_size = 0; 1224 } else { 1225 flag |= FCS_CS_FIELD_FLAG_INIT; 1226 } 1227 1228 if (is_finalised) { 1229 flag |= FCS_CS_FIELD_FLAG_FINALIZE; 1230 } else { 1231 flag |= FCS_CS_FIELD_FLAG_UPDATE; 1232 fcs_sha_mac_verify_param.is_updated = 1; 1233 } 1234 1235 crypto_header = ((flag << FCS_CS_FIELD_FLAG_OFFSET) | 1236 (fcs_sha_mac_verify_param.crypto_param_size & 1237 FCS_CS_FIELD_SIZE_MASK)); 1238 1239 /* Prepare command payload */ 1240 i = 0; 1241 payload[i] = fcs_sha_mac_verify_param.session_id; 1242 i++; 1243 payload[i] = fcs_sha_mac_verify_param.context_id; 1244 i++; 1245 payload[i] = crypto_header; 1246 i++; 1247 1248 if ((crypto_header >> FCS_CS_FIELD_FLAG_OFFSET) & 1249 FCS_CS_FIELD_FLAG_INIT) { 1250 payload[i] = fcs_sha_mac_verify_param.key_id; 1251 i++; 1252 /* Crypto parameters */ 1253 payload[i] = ((fcs_sha_mac_verify_param.crypto_param 1254 >> INTEL_SIP_SMC_FCS_DIGEST_SIZE_OFFSET) 1255 & INTEL_SIP_SMC_FCS_DIGEST_SIZE_MASK) 1256 << FCS_SHA_HMAC_CRYPTO_PARAM_SIZE_OFFSET; 1257 i++; 1258 } 1259 /* Data source address and size */ 1260 payload[i] = src_addr; 1261 i++; 1262 payload[i] = data_size; 1263 i++; 1264 1265 if ((crypto_header >> FCS_CS_FIELD_FLAG_OFFSET) & 1266 FCS_CS_FIELD_FLAG_FINALIZE) { 1267 /* Copy mac data to command 1268 * Using dst_addr (physical address) to store mac_offset 1269 * mac_offset = MAC data 1270 */ 1271 mac_offset = dst_addr; 1272 memcpy((uint8_t *) &payload[i], (uint8_t *) mac_offset, 1273 src_size - data_size); 1274 1275 memset((void *) dst_addr, 0, *dst_size); 1276 1277 i += (src_size - data_size) / MBOX_WORD_BYTE; 1278 } 1279 1280 status = mailbox_send_cmd_async(send_id, MBOX_FCS_MAC_VERIFY_REQ, 1281 payload, i, CMD_INDIRECT); 1282 1283 if (is_finalised) { 1284 memset((void *)&fcs_sha_mac_verify_param, 0, 1285 sizeof(fcs_crypto_service_data)); 1286 } 1287 1288 if (status < 0) { 1289 *mbox_error = -status; 1290 return INTEL_SIP_SMC_STATUS_ERROR; 1291 } 1292 1293 *dst_size = resp_len * MBOX_WORD_BYTE; 1294 flush_dcache_range(dst_addr, *dst_size); 1295 1296 return INTEL_SIP_SMC_STATUS_OK; 1297 } 1298 1299 int intel_fcs_ecdsa_hash_sign_init(uint32_t session_id, uint32_t context_id, 1300 uint32_t key_id, uint32_t param_size, 1301 uint64_t param_data, uint32_t *mbox_error) 1302 { 1303 return intel_fcs_crypto_service_init(session_id, context_id, 1304 key_id, param_size, param_data, 1305 (void *) &fcs_ecdsa_hash_sign_param, 1306 mbox_error); 1307 } 1308 1309 int intel_fcs_ecdsa_hash_sign_finalize(uint32_t session_id, uint32_t context_id, 1310 uint32_t src_addr, uint32_t src_size, 1311 uint64_t dst_addr, uint32_t *dst_size, 1312 uint32_t *mbox_error) 1313 { 1314 int status; 1315 uint32_t i; 1316 uint32_t payload[FCS_ECDSA_HASH_SIGN_CMD_MAX_WORD_SIZE] = {0U}; 1317 uint32_t resp_len; 1318 uintptr_t hash_data_addr; 1319 1320 if ((dst_size == NULL) || (mbox_error == NULL)) { 1321 return INTEL_SIP_SMC_STATUS_REJECTED; 1322 } 1323 1324 if (fcs_ecdsa_hash_sign_param.session_id != session_id || 1325 fcs_ecdsa_hash_sign_param.context_id != context_id) { 1326 return INTEL_SIP_SMC_STATUS_REJECTED; 1327 } 1328 1329 if (!is_address_in_ddr_range(src_addr, src_size) || 1330 !is_address_in_ddr_range(dst_addr, *dst_size)) { 1331 return INTEL_SIP_SMC_STATUS_REJECTED; 1332 } 1333 1334 resp_len = *dst_size / MBOX_WORD_BYTE; 1335 1336 /* Prepare command payload */ 1337 /* Crypto header */ 1338 i = 0; 1339 payload[i] = fcs_ecdsa_hash_sign_param.session_id; 1340 i++; 1341 payload[i] = fcs_ecdsa_hash_sign_param.context_id; 1342 1343 i++; 1344 payload[i] = fcs_ecdsa_hash_sign_param.crypto_param_size 1345 & FCS_CS_FIELD_SIZE_MASK; 1346 payload[i] |= (FCS_CS_FIELD_FLAG_INIT | FCS_CS_FIELD_FLAG_UPDATE 1347 | FCS_CS_FIELD_FLAG_FINALIZE) 1348 << FCS_CS_FIELD_FLAG_OFFSET; 1349 i++; 1350 payload[i] = fcs_ecdsa_hash_sign_param.key_id; 1351 1352 /* Crypto parameters */ 1353 i++; 1354 payload[i] = fcs_ecdsa_hash_sign_param.crypto_param 1355 & INTEL_SIP_SMC_FCS_ECC_ALGO_MASK; 1356 1357 /* Hash Data */ 1358 i++; 1359 hash_data_addr = src_addr; 1360 memcpy((uint8_t *) &payload[i], (uint8_t *) hash_data_addr, 1361 src_size); 1362 1363 i += src_size / MBOX_WORD_BYTE; 1364 1365 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_ECDSA_HASH_SIGN_REQ, 1366 payload, i, CMD_CASUAL, (uint32_t *) dst_addr, 1367 &resp_len); 1368 1369 memset((void *) &fcs_ecdsa_hash_sign_param, 1370 0, sizeof(fcs_crypto_service_data)); 1371 1372 if (status < 0) { 1373 *mbox_error = -status; 1374 return INTEL_SIP_SMC_STATUS_ERROR; 1375 } 1376 1377 *dst_size = resp_len * MBOX_WORD_BYTE; 1378 flush_dcache_range(dst_addr, *dst_size); 1379 1380 return INTEL_SIP_SMC_STATUS_OK; 1381 } 1382 1383 int intel_fcs_ecdsa_hash_sig_verify_init(uint32_t session_id, uint32_t context_id, 1384 uint32_t key_id, uint32_t param_size, 1385 uint64_t param_data, uint32_t *mbox_error) 1386 { 1387 return intel_fcs_crypto_service_init(session_id, context_id, 1388 key_id, param_size, param_data, 1389 (void *) &fcs_ecdsa_hash_sig_verify_param, 1390 mbox_error); 1391 } 1392 1393 int intel_fcs_ecdsa_hash_sig_verify_finalize(uint32_t session_id, uint32_t context_id, 1394 uint32_t src_addr, uint32_t src_size, 1395 uint64_t dst_addr, uint32_t *dst_size, 1396 uint32_t *mbox_error) 1397 { 1398 int status; 1399 uint32_t i = 0; 1400 uint32_t payload[FCS_ECDSA_HASH_SIG_VERIFY_CMD_MAX_WORD_SIZE] = {0U}; 1401 uint32_t resp_len; 1402 uintptr_t hash_sig_pubkey_addr; 1403 1404 if ((dst_size == NULL) || (mbox_error == NULL)) { 1405 return INTEL_SIP_SMC_STATUS_REJECTED; 1406 } 1407 1408 if (fcs_ecdsa_hash_sig_verify_param.session_id != session_id || 1409 fcs_ecdsa_hash_sig_verify_param.context_id != context_id) { 1410 return INTEL_SIP_SMC_STATUS_REJECTED; 1411 } 1412 1413 if (!is_address_in_ddr_range(src_addr, src_size) || 1414 !is_address_in_ddr_range(dst_addr, *dst_size)) { 1415 return INTEL_SIP_SMC_STATUS_REJECTED; 1416 } 1417 1418 resp_len = *dst_size / MBOX_WORD_BYTE; 1419 1420 /* Prepare command payload */ 1421 /* Crypto header */ 1422 i = 0; 1423 payload[i] = fcs_ecdsa_hash_sig_verify_param.session_id; 1424 1425 i++; 1426 payload[i] = fcs_ecdsa_hash_sig_verify_param.context_id; 1427 1428 i++; 1429 payload[i] = fcs_ecdsa_hash_sig_verify_param.crypto_param_size 1430 & FCS_CS_FIELD_SIZE_MASK; 1431 payload[i] |= (FCS_CS_FIELD_FLAG_INIT | FCS_CS_FIELD_FLAG_UPDATE 1432 | FCS_CS_FIELD_FLAG_FINALIZE) 1433 << FCS_CS_FIELD_FLAG_OFFSET; 1434 1435 i++; 1436 payload[i] = fcs_ecdsa_hash_sig_verify_param.key_id; 1437 1438 /* Crypto parameters */ 1439 i++; 1440 payload[i] = fcs_ecdsa_hash_sig_verify_param.crypto_param 1441 & INTEL_SIP_SMC_FCS_ECC_ALGO_MASK; 1442 1443 /* Hash Data Word, Signature Data Word and Public Key Data word */ 1444 i++; 1445 hash_sig_pubkey_addr = src_addr; 1446 memcpy((uint8_t *) &payload[i], 1447 (uint8_t *) hash_sig_pubkey_addr, src_size); 1448 1449 i += (src_size / MBOX_WORD_BYTE); 1450 1451 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_ECDSA_HASH_SIG_VERIFY, 1452 payload, i, CMD_CASUAL, (uint32_t *) dst_addr, 1453 &resp_len); 1454 1455 memset((void *)&fcs_ecdsa_hash_sig_verify_param, 1456 0, sizeof(fcs_crypto_service_data)); 1457 1458 if (status < 0) { 1459 *mbox_error = -status; 1460 return INTEL_SIP_SMC_STATUS_ERROR; 1461 } 1462 1463 *dst_size = resp_len * MBOX_WORD_BYTE; 1464 flush_dcache_range(dst_addr, *dst_size); 1465 1466 return INTEL_SIP_SMC_STATUS_OK; 1467 } 1468 1469 int intel_fcs_ecdsa_sha2_data_sign_init(uint32_t session_id, 1470 uint32_t context_id, uint32_t key_id, 1471 uint32_t param_size, uint64_t param_data, 1472 uint32_t *mbox_error) 1473 { 1474 return intel_fcs_crypto_service_init(session_id, context_id, 1475 key_id, param_size, param_data, 1476 (void *) &fcs_sha2_data_sign_param, 1477 mbox_error); 1478 } 1479 1480 int intel_fcs_ecdsa_sha2_data_sign_update_finalize(uint32_t session_id, 1481 uint32_t context_id, uint32_t src_addr, 1482 uint32_t src_size, uint64_t dst_addr, 1483 uint32_t *dst_size, uint8_t is_finalised, 1484 uint32_t *mbox_error) 1485 { 1486 int status; 1487 int i; 1488 uint32_t flag; 1489 uint32_t crypto_header; 1490 uint32_t payload[FCS_ECDSA_SHA2_DATA_SIGN_CMD_MAX_WORD_SIZE] = {0U}; 1491 uint32_t resp_len; 1492 1493 if ((dst_size == NULL) || (mbox_error == NULL)) { 1494 return INTEL_SIP_SMC_STATUS_REJECTED; 1495 } 1496 1497 if (fcs_sha2_data_sign_param.session_id != session_id || 1498 fcs_sha2_data_sign_param.context_id != context_id) { 1499 return INTEL_SIP_SMC_STATUS_REJECTED; 1500 } 1501 1502 /* Source data must be 8 bytes aligned */ 1503 if (!is_8_bytes_aligned(src_size)) { 1504 return INTEL_SIP_SMC_STATUS_REJECTED; 1505 } 1506 1507 if (!is_address_in_ddr_range(src_addr, src_size) || 1508 !is_address_in_ddr_range(dst_addr, *dst_size)) { 1509 return INTEL_SIP_SMC_STATUS_REJECTED; 1510 } 1511 1512 resp_len = *dst_size / MBOX_WORD_BYTE; 1513 1514 /* Prepare crypto header */ 1515 flag = 0; 1516 if (fcs_sha2_data_sign_param.is_updated) { 1517 fcs_sha2_data_sign_param.crypto_param_size = 0; 1518 } else { 1519 flag |= FCS_CS_FIELD_FLAG_INIT; 1520 } 1521 1522 if (is_finalised != 0U) { 1523 flag |= FCS_CS_FIELD_FLAG_FINALIZE; 1524 } else { 1525 flag |= FCS_CS_FIELD_FLAG_UPDATE; 1526 fcs_sha2_data_sign_param.is_updated = 1; 1527 } 1528 crypto_header = (flag << FCS_CS_FIELD_FLAG_OFFSET) | 1529 fcs_sha2_data_sign_param.crypto_param_size; 1530 1531 /* Prepare command payload */ 1532 i = 0; 1533 payload[i] = fcs_sha2_data_sign_param.session_id; 1534 i++; 1535 payload[i] = fcs_sha2_data_sign_param.context_id; 1536 i++; 1537 payload[i] = crypto_header; 1538 i++; 1539 1540 if ((crypto_header >> FCS_CS_FIELD_FLAG_OFFSET) & 1541 FCS_CS_FIELD_FLAG_INIT) { 1542 payload[i] = fcs_sha2_data_sign_param.key_id; 1543 /* Crypto parameters */ 1544 i++; 1545 payload[i] = fcs_sha2_data_sign_param.crypto_param 1546 & INTEL_SIP_SMC_FCS_ECC_ALGO_MASK; 1547 i++; 1548 } 1549 1550 /* Data source address and size */ 1551 payload[i] = src_addr; 1552 i++; 1553 payload[i] = src_size; 1554 i++; 1555 status = mailbox_send_cmd(MBOX_JOB_ID, 1556 MBOX_FCS_ECDSA_SHA2_DATA_SIGN_REQ, payload, 1557 i, CMD_CASUAL, (uint32_t *) dst_addr, 1558 &resp_len); 1559 1560 if (is_finalised != 0U) { 1561 memset((void *)&fcs_sha2_data_sign_param, 0, 1562 sizeof(fcs_crypto_service_data)); 1563 } 1564 1565 if (status < 0) { 1566 *mbox_error = -status; 1567 return INTEL_SIP_SMC_STATUS_ERROR; 1568 } 1569 1570 *dst_size = resp_len * MBOX_WORD_BYTE; 1571 flush_dcache_range(dst_addr, *dst_size); 1572 1573 return INTEL_SIP_SMC_STATUS_OK; 1574 } 1575 1576 int intel_fcs_ecdsa_sha2_data_sign_smmu_update_finalize(uint32_t session_id, 1577 uint32_t context_id, uint32_t src_addr, 1578 uint32_t src_size, uint64_t dst_addr, 1579 uint32_t *dst_size, uint8_t is_finalised, 1580 uint32_t *mbox_error, uint32_t *send_id) 1581 { 1582 int status; 1583 int i; 1584 uint32_t flag; 1585 uint32_t crypto_header; 1586 uint32_t payload[FCS_ECDSA_SHA2_DATA_SIGN_CMD_MAX_WORD_SIZE] = {0U}; 1587 uint32_t resp_len; 1588 1589 /* Source data must be 8 bytes aligned */ 1590 if ((dst_size == NULL) || (mbox_error == NULL || 1591 !is_8_bytes_aligned(src_size))) { 1592 return INTEL_SIP_SMC_STATUS_REJECTED; 1593 } 1594 1595 if (fcs_sha2_data_sign_param.session_id != session_id || 1596 fcs_sha2_data_sign_param.context_id != context_id) { 1597 return INTEL_SIP_SMC_STATUS_REJECTED; 1598 } 1599 1600 if (!is_address_in_ddr_range(src_addr, src_size) || 1601 !is_address_in_ddr_range(dst_addr, *dst_size)) { 1602 return INTEL_SIP_SMC_STATUS_REJECTED; 1603 } 1604 1605 resp_len = *dst_size / MBOX_WORD_BYTE; 1606 1607 /* Prepare crypto header */ 1608 flag = 0; 1609 if (fcs_sha2_data_sign_param.is_updated) { 1610 fcs_sha2_data_sign_param.crypto_param_size = 0; 1611 } else { 1612 flag |= FCS_CS_FIELD_FLAG_INIT; 1613 } 1614 1615 if (is_finalised != 0U) { 1616 flag |= FCS_CS_FIELD_FLAG_FINALIZE; 1617 } else { 1618 flag |= FCS_CS_FIELD_FLAG_UPDATE; 1619 fcs_sha2_data_sign_param.is_updated = 1; 1620 } 1621 crypto_header = (flag << FCS_CS_FIELD_FLAG_OFFSET) | 1622 fcs_sha2_data_sign_param.crypto_param_size; 1623 1624 /* Prepare command payload */ 1625 i = 0; 1626 payload[i] = fcs_sha2_data_sign_param.session_id; 1627 i++; 1628 payload[i] = fcs_sha2_data_sign_param.context_id; 1629 i++; 1630 payload[i] = crypto_header; 1631 i++; 1632 1633 if ((crypto_header >> FCS_CS_FIELD_FLAG_OFFSET) & 1634 FCS_CS_FIELD_FLAG_INIT) { 1635 payload[i] = fcs_sha2_data_sign_param.key_id; 1636 /* Crypto parameters */ 1637 i++; 1638 payload[i] = fcs_sha2_data_sign_param.crypto_param 1639 & INTEL_SIP_SMC_FCS_ECC_ALGO_MASK; 1640 i++; 1641 } 1642 1643 /* Data source address and size */ 1644 payload[i] = src_addr; 1645 i++; 1646 payload[i] = src_size; 1647 i++; 1648 1649 status = mailbox_send_cmd_async(send_id, 1650 MBOX_FCS_ECDSA_SHA2_DATA_SIGN_REQ, 1651 payload, i, CMD_INDIRECT); 1652 1653 if (is_finalised != 0U) { 1654 memset((void *)&fcs_sha2_data_sign_param, 0, 1655 sizeof(fcs_crypto_service_data)); 1656 } 1657 1658 if (status < 0) { 1659 *mbox_error = -status; 1660 return INTEL_SIP_SMC_STATUS_ERROR; 1661 } 1662 1663 *dst_size = resp_len * MBOX_WORD_BYTE; 1664 flush_dcache_range(dst_addr, *dst_size); 1665 1666 return INTEL_SIP_SMC_STATUS_OK; 1667 } 1668 1669 int intel_fcs_ecdsa_sha2_data_sig_verify_init(uint32_t session_id, 1670 uint32_t context_id, uint32_t key_id, 1671 uint32_t param_size, uint64_t param_data, 1672 uint32_t *mbox_error) 1673 { 1674 return intel_fcs_crypto_service_init(session_id, context_id, 1675 key_id, param_size, param_data, 1676 (void *) &fcs_sha2_data_sig_verify_param, 1677 mbox_error); 1678 } 1679 1680 int intel_fcs_ecdsa_sha2_data_sig_verify_update_finalize(uint32_t session_id, 1681 uint32_t context_id, uint32_t src_addr, 1682 uint32_t src_size, uint64_t dst_addr, 1683 uint32_t *dst_size, uint32_t data_size, 1684 uint8_t is_finalised, uint32_t *mbox_error) 1685 { 1686 int status; 1687 uint32_t i; 1688 uint32_t flag; 1689 uint32_t crypto_header; 1690 uint32_t payload[FCS_ECDSA_SHA2_DATA_SIG_VERIFY_CMD_MAX_WORD_SIZE] = {0U}; 1691 uint32_t resp_len; 1692 uintptr_t sig_pubkey_offset; 1693 1694 if ((dst_size == NULL) || (mbox_error == NULL)) { 1695 return INTEL_SIP_SMC_STATUS_REJECTED; 1696 } 1697 1698 if (fcs_sha2_data_sig_verify_param.session_id != session_id || 1699 fcs_sha2_data_sig_verify_param.context_id != context_id) { 1700 return INTEL_SIP_SMC_STATUS_REJECTED; 1701 } 1702 1703 if (!is_size_4_bytes_aligned(src_size)) { 1704 return INTEL_SIP_SMC_STATUS_REJECTED; 1705 } 1706 1707 if (!is_8_bytes_aligned(data_size) || 1708 !is_8_bytes_aligned(src_addr)) { 1709 return INTEL_SIP_SMC_STATUS_REJECTED; 1710 } 1711 1712 if (!is_address_in_ddr_range(src_addr, src_size) || 1713 !is_address_in_ddr_range(dst_addr, *dst_size)) { 1714 return INTEL_SIP_SMC_STATUS_REJECTED; 1715 } 1716 1717 resp_len = *dst_size / MBOX_WORD_BYTE; 1718 1719 /* Prepare crypto header */ 1720 flag = 0; 1721 if (fcs_sha2_data_sig_verify_param.is_updated) 1722 fcs_sha2_data_sig_verify_param.crypto_param_size = 0; 1723 else 1724 flag |= FCS_CS_FIELD_FLAG_INIT; 1725 1726 if (is_finalised != 0U) 1727 flag |= FCS_CS_FIELD_FLAG_FINALIZE; 1728 else { 1729 flag |= FCS_CS_FIELD_FLAG_UPDATE; 1730 fcs_sha2_data_sig_verify_param.is_updated = 1; 1731 } 1732 crypto_header = (flag << FCS_CS_FIELD_FLAG_OFFSET) | 1733 fcs_sha2_data_sig_verify_param.crypto_param_size; 1734 1735 /* Prepare command payload */ 1736 i = 0; 1737 payload[i] = fcs_sha2_data_sig_verify_param.session_id; 1738 i++; 1739 payload[i] = fcs_sha2_data_sig_verify_param.context_id; 1740 i++; 1741 payload[i] = crypto_header; 1742 i++; 1743 1744 if ((crypto_header >> FCS_CS_FIELD_FLAG_OFFSET) & 1745 FCS_CS_FIELD_FLAG_INIT) { 1746 payload[i] = fcs_sha2_data_sig_verify_param.key_id; 1747 i++; 1748 /* Crypto parameters */ 1749 payload[i] = fcs_sha2_data_sig_verify_param.crypto_param 1750 & INTEL_SIP_SMC_FCS_ECC_ALGO_MASK; 1751 i++; 1752 } 1753 1754 /* Data source address and size */ 1755 payload[i] = src_addr; 1756 i++; 1757 payload[i] = data_size; 1758 i++; 1759 1760 if ((crypto_header >> FCS_CS_FIELD_FLAG_OFFSET) & 1761 FCS_CS_FIELD_FLAG_FINALIZE) { 1762 /* Signature + Public Key Data */ 1763 sig_pubkey_offset = src_addr + data_size; 1764 memcpy((uint8_t *) &payload[i], (uint8_t *) sig_pubkey_offset, 1765 src_size - data_size); 1766 1767 i += (src_size - data_size) / MBOX_WORD_BYTE; 1768 } 1769 1770 status = mailbox_send_cmd(MBOX_JOB_ID, 1771 MBOX_FCS_ECDSA_SHA2_DATA_SIGN_VERIFY, payload, i, 1772 CMD_CASUAL, (uint32_t *) dst_addr, &resp_len); 1773 1774 if (is_finalised != 0U) { 1775 memset((void *) &fcs_sha2_data_sig_verify_param, 0, 1776 sizeof(fcs_crypto_service_data)); 1777 } 1778 1779 if (status < 0) { 1780 *mbox_error = -status; 1781 return INTEL_SIP_SMC_STATUS_ERROR; 1782 } 1783 1784 *dst_size = resp_len * MBOX_WORD_BYTE; 1785 flush_dcache_range(dst_addr, *dst_size); 1786 1787 return INTEL_SIP_SMC_STATUS_OK; 1788 } 1789 1790 int intel_fcs_ecdsa_sha2_data_sig_verify_smmu_update_finalize(uint32_t session_id, 1791 uint32_t context_id, uint32_t src_addr, 1792 uint32_t src_size, uint64_t dst_addr, 1793 uint32_t *dst_size, uint32_t data_size, 1794 uint8_t is_finalised, uint32_t *mbox_error, 1795 uint32_t *send_id) 1796 { 1797 int status; 1798 uint32_t i; 1799 uint32_t flag; 1800 uint32_t crypto_header; 1801 uint32_t payload[FCS_ECDSA_SHA2_DATA_SIG_VERIFY_CMD_MAX_WORD_SIZE] = {0U}; 1802 uint32_t resp_len; 1803 uintptr_t sig_pubkey_offset; 1804 1805 /* 1806 * Source data must be 4 bytes aligned 1807 * Source addrress must be 8 bytes aligned 1808 * User data must be 8 bytes aligned 1809 */ 1810 if ((dst_size == NULL) || (mbox_error == NULL) || 1811 !is_size_4_bytes_aligned(src_size) || 1812 !is_8_bytes_aligned(src_addr) || 1813 !is_8_bytes_aligned(data_size)) { 1814 return INTEL_SIP_SMC_STATUS_REJECTED; 1815 } 1816 1817 if (fcs_sha2_data_sig_verify_param.session_id != session_id || 1818 fcs_sha2_data_sig_verify_param.context_id != context_id) { 1819 return INTEL_SIP_SMC_STATUS_REJECTED; 1820 } 1821 1822 if (!is_address_in_ddr_range(src_addr, src_size) || 1823 !is_address_in_ddr_range(dst_addr, *dst_size)) { 1824 return INTEL_SIP_SMC_STATUS_REJECTED; 1825 } 1826 1827 resp_len = *dst_size / MBOX_WORD_BYTE; 1828 1829 /* Prepare crypto header */ 1830 flag = 0; 1831 if (fcs_sha2_data_sig_verify_param.is_updated) 1832 fcs_sha2_data_sig_verify_param.crypto_param_size = 0; 1833 else 1834 flag |= FCS_CS_FIELD_FLAG_INIT; 1835 1836 if (is_finalised != 0U) 1837 flag |= FCS_CS_FIELD_FLAG_FINALIZE; 1838 else { 1839 flag |= FCS_CS_FIELD_FLAG_UPDATE; 1840 fcs_sha2_data_sig_verify_param.is_updated = 1; 1841 } 1842 crypto_header = (flag << FCS_CS_FIELD_FLAG_OFFSET) | 1843 fcs_sha2_data_sig_verify_param.crypto_param_size; 1844 1845 /* Prepare command payload */ 1846 i = 0; 1847 payload[i] = fcs_sha2_data_sig_verify_param.session_id; 1848 i++; 1849 payload[i] = fcs_sha2_data_sig_verify_param.context_id; 1850 i++; 1851 payload[i] = crypto_header; 1852 i++; 1853 1854 if ((crypto_header >> FCS_CS_FIELD_FLAG_OFFSET) & 1855 FCS_CS_FIELD_FLAG_INIT) { 1856 payload[i] = fcs_sha2_data_sig_verify_param.key_id; 1857 i++; 1858 /* Crypto parameters */ 1859 payload[i] = fcs_sha2_data_sig_verify_param.crypto_param 1860 & INTEL_SIP_SMC_FCS_ECC_ALGO_MASK; 1861 i++; 1862 } 1863 1864 /* Data source address and size */ 1865 payload[i] = src_addr; 1866 i++; 1867 payload[i] = data_size; 1868 i++; 1869 1870 if ((crypto_header >> FCS_CS_FIELD_FLAG_OFFSET) & 1871 FCS_CS_FIELD_FLAG_FINALIZE) { 1872 /* Copy mac data to command 1873 * Using dst_addr (physical address) to store sig_pubkey_offset 1874 * sig_pubkey_offset is Signature + Public Key Data 1875 */ 1876 sig_pubkey_offset = dst_addr; 1877 memcpy((uint8_t *) &payload[i], (uint8_t *) sig_pubkey_offset, 1878 src_size - data_size); 1879 1880 memset((void *) dst_addr, 0, *dst_size); 1881 1882 i += (src_size - data_size) / MBOX_WORD_BYTE; 1883 } 1884 1885 status = mailbox_send_cmd_async(send_id, 1886 MBOX_FCS_ECDSA_SHA2_DATA_SIGN_VERIFY, 1887 payload, i, CMD_INDIRECT); 1888 1889 if (is_finalised != 0U) { 1890 memset((void *) &fcs_sha2_data_sig_verify_param, 0, 1891 sizeof(fcs_crypto_service_data)); 1892 } 1893 1894 if (status < 0) { 1895 *mbox_error = -status; 1896 return INTEL_SIP_SMC_STATUS_ERROR; 1897 } 1898 1899 *dst_size = resp_len * MBOX_WORD_BYTE; 1900 flush_dcache_range(dst_addr, *dst_size); 1901 1902 return INTEL_SIP_SMC_STATUS_OK; 1903 } 1904 1905 int intel_fcs_ecdsa_get_pubkey_init(uint32_t session_id, uint32_t context_id, 1906 uint32_t key_id, uint32_t param_size, 1907 uint64_t param_data, uint32_t *mbox_error) 1908 { 1909 return intel_fcs_crypto_service_init(session_id, context_id, 1910 key_id, param_size, param_data, 1911 (void *) &fcs_ecdsa_get_pubkey_param, 1912 mbox_error); 1913 } 1914 1915 int intel_fcs_ecdsa_get_pubkey_finalize(uint32_t session_id, uint32_t context_id, 1916 uint64_t dst_addr, uint32_t *dst_size, 1917 uint32_t *mbox_error) 1918 { 1919 int status; 1920 int i; 1921 uint32_t crypto_header; 1922 uint32_t ret_size; 1923 uint32_t payload[FCS_ECDSA_GET_PUBKEY_MAX_WORD_SIZE] = {0U}; 1924 1925 if ((dst_size == NULL) || (mbox_error == NULL)) { 1926 return INTEL_SIP_SMC_STATUS_REJECTED; 1927 } 1928 1929 if (fcs_ecdsa_get_pubkey_param.session_id != session_id || 1930 fcs_ecdsa_get_pubkey_param.context_id != context_id) { 1931 return INTEL_SIP_SMC_STATUS_REJECTED; 1932 } 1933 1934 ret_size = *dst_size / MBOX_WORD_BYTE; 1935 1936 crypto_header = ((FCS_CS_FIELD_FLAG_INIT | 1937 FCS_CS_FIELD_FLAG_UPDATE | 1938 FCS_CS_FIELD_FLAG_FINALIZE) << 1939 FCS_CS_FIELD_FLAG_OFFSET) | 1940 fcs_ecdsa_get_pubkey_param.crypto_param_size; 1941 i = 0; 1942 /* Prepare command payload */ 1943 payload[i] = session_id; 1944 i++; 1945 payload[i] = context_id; 1946 i++; 1947 payload[i] = crypto_header; 1948 i++; 1949 payload[i] = fcs_ecdsa_get_pubkey_param.key_id; 1950 i++; 1951 payload[i] = (uint32_t) fcs_ecdsa_get_pubkey_param.crypto_param & 1952 INTEL_SIP_SMC_FCS_ECC_ALGO_MASK; 1953 i++; 1954 1955 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_ECDSA_GET_PUBKEY, 1956 payload, i, CMD_CASUAL, 1957 (uint32_t *) dst_addr, &ret_size); 1958 1959 memset((void *) &fcs_ecdsa_get_pubkey_param, 0, 1960 sizeof(fcs_crypto_service_data)); 1961 1962 if (status < 0) { 1963 *mbox_error = -status; 1964 return INTEL_SIP_SMC_STATUS_ERROR; 1965 } 1966 1967 *dst_size = ret_size * MBOX_WORD_BYTE; 1968 flush_dcache_range(dst_addr, *dst_size); 1969 1970 return INTEL_SIP_SMC_STATUS_OK; 1971 } 1972 1973 int intel_fcs_ecdh_request_init(uint32_t session_id, uint32_t context_id, 1974 uint32_t key_id, uint32_t param_size, 1975 uint64_t param_data, uint32_t *mbox_error) 1976 { 1977 return intel_fcs_crypto_service_init(session_id, context_id, 1978 key_id, param_size, param_data, 1979 (void *) &fcs_ecdh_request_param, 1980 mbox_error); 1981 } 1982 1983 int intel_fcs_ecdh_request_finalize(uint32_t session_id, uint32_t context_id, 1984 uint32_t src_addr, uint32_t src_size, 1985 uint64_t dst_addr, uint32_t *dst_size, 1986 uint32_t *mbox_error) 1987 { 1988 int status; 1989 uint32_t i; 1990 uint32_t payload[FCS_ECDH_REQUEST_CMD_MAX_WORD_SIZE] = {0U}; 1991 uint32_t resp_len; 1992 uintptr_t pubkey; 1993 1994 if ((dst_size == NULL) || (mbox_error == NULL)) { 1995 return INTEL_SIP_SMC_STATUS_REJECTED; 1996 } 1997 1998 if (fcs_ecdh_request_param.session_id != session_id || 1999 fcs_ecdh_request_param.context_id != context_id) { 2000 return INTEL_SIP_SMC_STATUS_REJECTED; 2001 } 2002 2003 if (!is_address_in_ddr_range(src_addr, src_size) || 2004 !is_address_in_ddr_range(dst_addr, *dst_size)) { 2005 return INTEL_SIP_SMC_STATUS_REJECTED; 2006 } 2007 2008 resp_len = *dst_size / MBOX_WORD_BYTE; 2009 2010 /* Prepare command payload */ 2011 i = 0; 2012 /* Crypto header */ 2013 payload[i] = fcs_ecdh_request_param.session_id; 2014 i++; 2015 payload[i] = fcs_ecdh_request_param.context_id; 2016 i++; 2017 payload[i] = fcs_ecdh_request_param.crypto_param_size 2018 & FCS_CS_FIELD_SIZE_MASK; 2019 payload[i] |= (FCS_CS_FIELD_FLAG_INIT | FCS_CS_FIELD_FLAG_UPDATE 2020 | FCS_CS_FIELD_FLAG_FINALIZE) 2021 << FCS_CS_FIELD_FLAG_OFFSET; 2022 i++; 2023 payload[i] = fcs_ecdh_request_param.key_id; 2024 i++; 2025 /* Crypto parameters */ 2026 payload[i] = fcs_ecdh_request_param.crypto_param 2027 & INTEL_SIP_SMC_FCS_ECC_ALGO_MASK; 2028 i++; 2029 /* Public key data */ 2030 pubkey = src_addr; 2031 memcpy((uint8_t *) &payload[i], (uint8_t *) pubkey, src_size); 2032 i += src_size / MBOX_WORD_BYTE; 2033 2034 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_ECDH_REQUEST, 2035 payload, i, CMD_CASUAL, (uint32_t *) dst_addr, 2036 &resp_len); 2037 2038 memset((void *)&fcs_ecdh_request_param, 0, 2039 sizeof(fcs_crypto_service_data)); 2040 2041 if (status < 0) { 2042 *mbox_error = -status; 2043 return INTEL_SIP_SMC_STATUS_ERROR; 2044 } 2045 2046 *dst_size = resp_len * MBOX_WORD_BYTE; 2047 flush_dcache_range(dst_addr, *dst_size); 2048 2049 return INTEL_SIP_SMC_STATUS_OK; 2050 } 2051 2052 int intel_fcs_aes_crypt_init(uint32_t session_id, uint32_t context_id, 2053 uint32_t key_id, uint64_t param_addr, 2054 uint32_t param_size, uint32_t *mbox_error) 2055 { 2056 /* ptr to get param_addr value */ 2057 uint64_t *param_addr_ptr; 2058 2059 param_addr_ptr = (uint64_t *) param_addr; 2060 2061 /* 2062 * Since crypto param size vary between mode. 2063 * Check ECB here and limit to size 12 bytes 2064 */ 2065 if (((*param_addr_ptr & FCS_CRYPTO_BLOCK_MODE_MASK) == FCS_CRYPTO_ECB_MODE) && 2066 (param_size > FCS_CRYPTO_ECB_BUFFER_SIZE)) { 2067 return INTEL_SIP_SMC_STATUS_REJECTED; 2068 } 2069 /* 2070 * Since crypto param size vary between mode. 2071 * Check CBC/CTR here and limit to size 28 bytes 2072 */ 2073 if ((((*param_addr_ptr & FCS_CRYPTO_BLOCK_MODE_MASK) == FCS_CRYPTO_CBC_MODE) || 2074 ((*param_addr_ptr & FCS_CRYPTO_BLOCK_MODE_MASK) == FCS_CRYPTO_CTR_MODE)) && 2075 (param_size > FCS_CRYPTO_CBC_CTR_BUFFER_SIZE)) { 2076 return INTEL_SIP_SMC_STATUS_REJECTED; 2077 } 2078 2079 if (mbox_error == NULL) { 2080 return INTEL_SIP_SMC_STATUS_REJECTED; 2081 } 2082 2083 memset((void *)&fcs_aes_init_payload, 0U, sizeof(fcs_aes_init_payload)); 2084 2085 fcs_aes_init_payload.session_id = session_id; 2086 fcs_aes_init_payload.context_id = context_id; 2087 fcs_aes_init_payload.param_size = param_size; 2088 fcs_aes_init_payload.key_id = key_id; 2089 2090 memcpy((uint8_t *) fcs_aes_init_payload.crypto_param, 2091 (uint8_t *) param_addr, param_size); 2092 2093 fcs_aes_init_payload.is_updated = 0; 2094 2095 *mbox_error = 0; 2096 2097 return INTEL_SIP_SMC_STATUS_OK; 2098 } 2099 2100 int intel_fcs_aes_crypt_update_finalize(uint32_t session_id, 2101 uint32_t context_id, uint64_t src_addr, 2102 uint32_t src_size, uint64_t dst_addr, 2103 uint32_t dst_size, uint8_t is_finalised, 2104 uint32_t *send_id) 2105 { 2106 int status; 2107 int i; 2108 uint32_t flag; 2109 uint32_t crypto_header; 2110 uint32_t fcs_aes_crypt_payload[FCS_AES_CMD_MAX_WORD_SIZE]; 2111 2112 if (fcs_aes_init_payload.session_id != session_id || 2113 fcs_aes_init_payload.context_id != context_id) { 2114 return INTEL_SIP_SMC_STATUS_REJECTED; 2115 } 2116 2117 if ((!is_8_bytes_aligned(src_addr)) || 2118 (!is_32_bytes_aligned(src_size)) || 2119 (!is_address_in_ddr_range(src_addr, src_size))) { 2120 return INTEL_SIP_SMC_STATUS_REJECTED; 2121 } 2122 2123 if ((!is_8_bytes_aligned(dst_addr)) || 2124 (!is_32_bytes_aligned(dst_size))) { 2125 return INTEL_SIP_SMC_STATUS_REJECTED; 2126 } 2127 2128 if ((dst_size > FCS_AES_MAX_DATA_SIZE || 2129 dst_size < FCS_AES_MIN_DATA_SIZE) || 2130 (src_size > FCS_AES_MAX_DATA_SIZE || 2131 src_size < FCS_AES_MIN_DATA_SIZE)) { 2132 return INTEL_SIP_SMC_STATUS_REJECTED; 2133 } 2134 2135 /* Prepare crypto header*/ 2136 flag = 0; 2137 if (fcs_aes_init_payload.is_updated) { 2138 fcs_aes_init_payload.param_size = 0; 2139 } else { 2140 flag |= FCS_CS_FIELD_FLAG_INIT; 2141 } 2142 2143 if (is_finalised != 0U) { 2144 flag |= FCS_CS_FIELD_FLAG_FINALIZE; 2145 } else { 2146 flag |= FCS_CS_FIELD_FLAG_UPDATE; 2147 fcs_aes_init_payload.is_updated = 1; 2148 } 2149 crypto_header = (flag << FCS_CS_FIELD_FLAG_OFFSET) | 2150 fcs_aes_init_payload.param_size; 2151 2152 i = 0U; 2153 fcs_aes_crypt_payload[i] = session_id; 2154 i++; 2155 fcs_aes_crypt_payload[i] = context_id; 2156 i++; 2157 fcs_aes_crypt_payload[i] = crypto_header; 2158 i++; 2159 2160 if ((crypto_header >> FCS_CS_FIELD_FLAG_OFFSET) & 2161 FCS_CS_FIELD_FLAG_INIT) { 2162 fcs_aes_crypt_payload[i] = fcs_aes_init_payload.key_id; 2163 i++; 2164 2165 memcpy((uint8_t *) &fcs_aes_crypt_payload[i], 2166 (uint8_t *) fcs_aes_init_payload.crypto_param, 2167 fcs_aes_init_payload.param_size); 2168 2169 i += fcs_aes_init_payload.param_size / MBOX_WORD_BYTE; 2170 } 2171 2172 fcs_aes_crypt_payload[i] = (uint32_t) src_addr; 2173 i++; 2174 fcs_aes_crypt_payload[i] = src_size; 2175 i++; 2176 fcs_aes_crypt_payload[i] = (uint32_t) dst_addr; 2177 i++; 2178 fcs_aes_crypt_payload[i] = dst_size; 2179 i++; 2180 2181 status = mailbox_send_cmd_async(send_id, MBOX_FCS_AES_CRYPT_REQ, 2182 fcs_aes_crypt_payload, i, 2183 CMD_INDIRECT); 2184 2185 if (is_finalised != 0U) { 2186 memset((void *)&fcs_aes_init_payload, 0, 2187 sizeof(fcs_aes_init_payload)); 2188 } 2189 2190 if (status < 0U) { 2191 return INTEL_SIP_SMC_STATUS_ERROR; 2192 } 2193 2194 return INTEL_SIP_SMC_STATUS_OK; 2195 } 2196