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 if (!is_address_in_ddr_range(src_addr, src_size) || 251 !is_address_in_ddr_range(dst_addr, dst_size)) { 252 return INTEL_SIP_SMC_STATUS_REJECTED; 253 } 254 255 if (!is_size_4_bytes_aligned(src_size)) { 256 return INTEL_SIP_SMC_STATUS_REJECTED; 257 } 258 259 fcs_encrypt_payload payload = { 260 FCS_ENCRYPTION_DATA_0, 261 src_addr, 262 src_size, 263 dst_addr, 264 dst_size }; 265 load_size = sizeof(payload) / MBOX_WORD_BYTE; 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 if (!is_address_in_ddr_range(src_addr, src_size) || 287 !is_address_in_ddr_range(dst_addr, dst_size)) { 288 return INTEL_SIP_SMC_STATUS_REJECTED; 289 } 290 291 if (!is_size_4_bytes_aligned(src_size)) { 292 return INTEL_SIP_SMC_STATUS_REJECTED; 293 } 294 295 inv_dcache_range(src_addr, src_size); /* flush cache before mmio read to avoid reading old values */ 296 id_offset = src_addr + FCS_OWNER_ID_OFFSET; 297 fcs_decrypt_payload payload = { 298 FCS_DECRYPTION_DATA_0, 299 {mmio_read_32(id_offset), 300 mmio_read_32(id_offset + MBOX_WORD_BYTE)}, 301 src_addr, 302 src_size, 303 dst_addr, 304 dst_size }; 305 load_size = sizeof(payload) / MBOX_WORD_BYTE; 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 uint32_t dst_size_check = 0; 1077 1078 if (dst_size == NULL || mbox_error == NULL) { 1079 return INTEL_SIP_SMC_STATUS_REJECTED; 1080 } 1081 1082 if (fcs_sha_mac_verify_param.session_id != session_id || 1083 fcs_sha_mac_verify_param.context_id != context_id) { 1084 return INTEL_SIP_SMC_STATUS_REJECTED; 1085 } 1086 1087 if (data_size > src_size) { 1088 return INTEL_SIP_SMC_STATUS_REJECTED; 1089 } 1090 1091 if (!is_size_4_bytes_aligned(src_size) || 1092 !is_8_bytes_aligned(data_size)) { 1093 return INTEL_SIP_SMC_STATUS_REJECTED; 1094 } 1095 1096 if (!is_address_in_ddr_range(src_addr, src_size) || 1097 !is_address_in_ddr_range(dst_addr, *dst_size)) { 1098 return INTEL_SIP_SMC_STATUS_REJECTED; 1099 } 1100 1101 dst_size_check = *dst_size; 1102 if ((dst_size_check > FCS_MAX_DATA_SIZE || 1103 dst_size_check < FCS_MIN_DATA_SIZE) || 1104 (src_size > FCS_MAX_DATA_SIZE || 1105 src_size < FCS_MIN_DATA_SIZE)) { 1106 return INTEL_SIP_SMC_STATUS_REJECTED; 1107 } 1108 1109 resp_len = *dst_size / MBOX_WORD_BYTE; 1110 1111 /* Prepare crypto header */ 1112 flag = 0; 1113 1114 if (fcs_sha_mac_verify_param.is_updated) { 1115 fcs_sha_mac_verify_param.crypto_param_size = 0; 1116 } else { 1117 flag |= FCS_CS_FIELD_FLAG_INIT; 1118 } 1119 1120 if (is_finalised) { 1121 flag |= FCS_CS_FIELD_FLAG_FINALIZE; 1122 } else { 1123 flag |= FCS_CS_FIELD_FLAG_UPDATE; 1124 fcs_sha_mac_verify_param.is_updated = 1; 1125 } 1126 1127 crypto_header = ((flag << FCS_CS_FIELD_FLAG_OFFSET) | 1128 (fcs_sha_mac_verify_param.crypto_param_size & 1129 FCS_CS_FIELD_SIZE_MASK)); 1130 1131 /* Prepare command payload */ 1132 i = 0; 1133 payload[i] = fcs_sha_mac_verify_param.session_id; 1134 i++; 1135 payload[i] = fcs_sha_mac_verify_param.context_id; 1136 i++; 1137 payload[i] = crypto_header; 1138 i++; 1139 1140 if ((crypto_header >> FCS_CS_FIELD_FLAG_OFFSET) & 1141 FCS_CS_FIELD_FLAG_INIT) { 1142 payload[i] = fcs_sha_mac_verify_param.key_id; 1143 i++; 1144 /* Crypto parameters */ 1145 payload[i] = ((fcs_sha_mac_verify_param.crypto_param 1146 >> INTEL_SIP_SMC_FCS_DIGEST_SIZE_OFFSET) 1147 & INTEL_SIP_SMC_FCS_DIGEST_SIZE_MASK) 1148 << FCS_SHA_HMAC_CRYPTO_PARAM_SIZE_OFFSET; 1149 i++; 1150 } 1151 /* Data source address and size */ 1152 payload[i] = src_addr; 1153 i++; 1154 payload[i] = data_size; 1155 i++; 1156 1157 if ((crypto_header >> FCS_CS_FIELD_FLAG_OFFSET) & 1158 FCS_CS_FIELD_FLAG_FINALIZE) { 1159 /* Copy mac data to command */ 1160 mac_offset = src_addr + data_size; 1161 1162 if ((i + ((src_size - data_size) / MBOX_WORD_BYTE)) > 1163 FCS_MAC_VERIFY_CMD_MAX_WORD_SIZE) { 1164 return INTEL_SIP_SMC_STATUS_REJECTED; 1165 } 1166 1167 memcpy((uint8_t *) &payload[i], (uint8_t *) mac_offset, 1168 src_size - data_size); 1169 1170 i += (src_size - data_size) / MBOX_WORD_BYTE; 1171 } 1172 1173 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_MAC_VERIFY_REQ, 1174 payload, i, CMD_CASUAL, 1175 (uint32_t *) dst_addr, &resp_len); 1176 1177 if (is_finalised) { 1178 memset((void *)&fcs_sha_mac_verify_param, 0, 1179 sizeof(fcs_crypto_service_data)); 1180 } 1181 1182 if (status < 0) { 1183 *mbox_error = -status; 1184 return INTEL_SIP_SMC_STATUS_ERROR; 1185 } 1186 1187 *dst_size = resp_len * MBOX_WORD_BYTE; 1188 flush_dcache_range(dst_addr, *dst_size); 1189 1190 return INTEL_SIP_SMC_STATUS_OK; 1191 } 1192 1193 int intel_fcs_mac_verify_smmu_update_finalize(uint32_t session_id, 1194 uint32_t context_id, uint32_t src_addr, 1195 uint32_t src_size, uint64_t dst_addr, 1196 uint32_t *dst_size, uint32_t data_size, 1197 uint8_t is_finalised, uint32_t *mbox_error, 1198 uint32_t *send_id) 1199 { 1200 int status; 1201 uint32_t i; 1202 uint32_t flag; 1203 uint32_t crypto_header; 1204 uint32_t resp_len; 1205 uint32_t payload[FCS_MAC_VERIFY_CMD_MAX_WORD_SIZE] = {0U}; 1206 uintptr_t mac_offset; 1207 uint32_t dst_size_check = 0; 1208 /* 1209 * Source data must be 4 bytes aligned 1210 * User data must be 8 bytes aligned 1211 */ 1212 if (dst_size == NULL || mbox_error == NULL || 1213 !is_size_4_bytes_aligned(src_size) || 1214 !is_8_bytes_aligned(data_size)) { 1215 return INTEL_SIP_SMC_STATUS_REJECTED; 1216 } 1217 1218 if (data_size > src_size) { 1219 return INTEL_SIP_SMC_STATUS_REJECTED; 1220 } 1221 1222 if (fcs_sha_mac_verify_param.session_id != session_id || 1223 fcs_sha_mac_verify_param.context_id != context_id) { 1224 return INTEL_SIP_SMC_STATUS_REJECTED; 1225 } 1226 1227 if (!is_address_in_ddr_range(src_addr, src_size) || 1228 !is_address_in_ddr_range(dst_addr, *dst_size)) { 1229 return INTEL_SIP_SMC_STATUS_REJECTED; 1230 } 1231 1232 dst_size_check = *dst_size; 1233 if ((dst_size_check > FCS_MAX_DATA_SIZE || 1234 dst_size_check < FCS_MIN_DATA_SIZE) || 1235 (src_size > FCS_MAX_DATA_SIZE || 1236 src_size < FCS_MIN_DATA_SIZE)) { 1237 return INTEL_SIP_SMC_STATUS_REJECTED; 1238 } 1239 1240 resp_len = *dst_size / MBOX_WORD_BYTE; 1241 1242 /* Prepare crypto header */ 1243 flag = 0; 1244 1245 if (fcs_sha_mac_verify_param.is_updated) { 1246 fcs_sha_mac_verify_param.crypto_param_size = 0; 1247 } else { 1248 flag |= FCS_CS_FIELD_FLAG_INIT; 1249 } 1250 1251 if (is_finalised) { 1252 flag |= FCS_CS_FIELD_FLAG_FINALIZE; 1253 } else { 1254 flag |= FCS_CS_FIELD_FLAG_UPDATE; 1255 fcs_sha_mac_verify_param.is_updated = 1; 1256 } 1257 1258 crypto_header = ((flag << FCS_CS_FIELD_FLAG_OFFSET) | 1259 (fcs_sha_mac_verify_param.crypto_param_size & 1260 FCS_CS_FIELD_SIZE_MASK)); 1261 1262 /* Prepare command payload */ 1263 i = 0; 1264 payload[i] = fcs_sha_mac_verify_param.session_id; 1265 i++; 1266 payload[i] = fcs_sha_mac_verify_param.context_id; 1267 i++; 1268 payload[i] = crypto_header; 1269 i++; 1270 1271 if ((crypto_header >> FCS_CS_FIELD_FLAG_OFFSET) & 1272 FCS_CS_FIELD_FLAG_INIT) { 1273 payload[i] = fcs_sha_mac_verify_param.key_id; 1274 i++; 1275 /* Crypto parameters */ 1276 payload[i] = ((fcs_sha_mac_verify_param.crypto_param 1277 >> INTEL_SIP_SMC_FCS_DIGEST_SIZE_OFFSET) 1278 & INTEL_SIP_SMC_FCS_DIGEST_SIZE_MASK) 1279 << FCS_SHA_HMAC_CRYPTO_PARAM_SIZE_OFFSET; 1280 i++; 1281 } 1282 /* Data source address and size */ 1283 payload[i] = src_addr; 1284 i++; 1285 payload[i] = data_size; 1286 i++; 1287 1288 if ((crypto_header >> FCS_CS_FIELD_FLAG_OFFSET) & 1289 FCS_CS_FIELD_FLAG_FINALIZE) { 1290 /* Copy mac data to command 1291 * Using dst_addr (physical address) to store mac_offset 1292 * mac_offset = MAC data 1293 */ 1294 mac_offset = dst_addr; 1295 1296 if ((i + ((src_size - data_size) / MBOX_WORD_BYTE)) > 1297 FCS_MAC_VERIFY_CMD_MAX_WORD_SIZE) { 1298 return INTEL_SIP_SMC_STATUS_REJECTED; 1299 } 1300 1301 memcpy((uint8_t *) &payload[i], (uint8_t *) mac_offset, 1302 src_size - data_size); 1303 1304 memset((void *) dst_addr, 0, *dst_size); 1305 1306 i += (src_size - data_size) / MBOX_WORD_BYTE; 1307 } 1308 1309 status = mailbox_send_cmd_async(send_id, MBOX_FCS_MAC_VERIFY_REQ, 1310 payload, i, CMD_INDIRECT); 1311 1312 if (is_finalised) { 1313 memset((void *)&fcs_sha_mac_verify_param, 0, 1314 sizeof(fcs_crypto_service_data)); 1315 } 1316 1317 if (status < 0) { 1318 *mbox_error = -status; 1319 return INTEL_SIP_SMC_STATUS_ERROR; 1320 } 1321 1322 *dst_size = resp_len * MBOX_WORD_BYTE; 1323 flush_dcache_range(dst_addr, *dst_size); 1324 1325 return INTEL_SIP_SMC_STATUS_OK; 1326 } 1327 1328 int intel_fcs_ecdsa_hash_sign_init(uint32_t session_id, uint32_t context_id, 1329 uint32_t key_id, uint32_t param_size, 1330 uint64_t param_data, uint32_t *mbox_error) 1331 { 1332 return intel_fcs_crypto_service_init(session_id, context_id, 1333 key_id, param_size, param_data, 1334 (void *) &fcs_ecdsa_hash_sign_param, 1335 mbox_error); 1336 } 1337 1338 int intel_fcs_ecdsa_hash_sign_finalize(uint32_t session_id, uint32_t context_id, 1339 uint32_t src_addr, uint32_t src_size, 1340 uint64_t dst_addr, uint32_t *dst_size, 1341 uint32_t *mbox_error) 1342 { 1343 int status; 1344 uint32_t i; 1345 uint32_t payload[FCS_ECDSA_HASH_SIGN_CMD_MAX_WORD_SIZE] = {0U}; 1346 uint32_t resp_len; 1347 uintptr_t hash_data_addr; 1348 uint32_t dst_size_check = 0; 1349 1350 if ((dst_size == NULL) || (mbox_error == NULL)) { 1351 return INTEL_SIP_SMC_STATUS_REJECTED; 1352 } 1353 1354 if (fcs_ecdsa_hash_sign_param.session_id != session_id || 1355 fcs_ecdsa_hash_sign_param.context_id != context_id) { 1356 return INTEL_SIP_SMC_STATUS_REJECTED; 1357 } 1358 1359 if (!is_address_in_ddr_range(src_addr, src_size) || 1360 !is_address_in_ddr_range(dst_addr, *dst_size)) { 1361 return INTEL_SIP_SMC_STATUS_REJECTED; 1362 } 1363 1364 dst_size_check = *dst_size; 1365 if ((dst_size_check > FCS_MAX_DATA_SIZE || 1366 dst_size_check < FCS_MIN_DATA_SIZE) || 1367 (src_size > FCS_MAX_DATA_SIZE || 1368 src_size < FCS_MIN_DATA_SIZE)) { 1369 return INTEL_SIP_SMC_STATUS_REJECTED; 1370 } 1371 1372 resp_len = *dst_size / MBOX_WORD_BYTE; 1373 1374 /* Prepare command payload */ 1375 /* Crypto header */ 1376 i = 0; 1377 payload[i] = fcs_ecdsa_hash_sign_param.session_id; 1378 i++; 1379 payload[i] = fcs_ecdsa_hash_sign_param.context_id; 1380 1381 i++; 1382 payload[i] = fcs_ecdsa_hash_sign_param.crypto_param_size 1383 & FCS_CS_FIELD_SIZE_MASK; 1384 payload[i] |= (FCS_CS_FIELD_FLAG_INIT | FCS_CS_FIELD_FLAG_UPDATE 1385 | FCS_CS_FIELD_FLAG_FINALIZE) 1386 << FCS_CS_FIELD_FLAG_OFFSET; 1387 i++; 1388 payload[i] = fcs_ecdsa_hash_sign_param.key_id; 1389 1390 /* Crypto parameters */ 1391 i++; 1392 payload[i] = fcs_ecdsa_hash_sign_param.crypto_param 1393 & INTEL_SIP_SMC_FCS_ECC_ALGO_MASK; 1394 1395 /* Hash Data */ 1396 i++; 1397 hash_data_addr = src_addr; 1398 1399 if ((i + ((src_size) / MBOX_WORD_BYTE)) > 1400 FCS_ECDSA_HASH_SIGN_CMD_MAX_WORD_SIZE) { 1401 return INTEL_SIP_SMC_STATUS_REJECTED; 1402 } 1403 1404 memcpy((uint8_t *) &payload[i], (uint8_t *) hash_data_addr, 1405 src_size); 1406 1407 i += src_size / MBOX_WORD_BYTE; 1408 1409 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_ECDSA_HASH_SIGN_REQ, 1410 payload, i, CMD_CASUAL, (uint32_t *) dst_addr, 1411 &resp_len); 1412 1413 memset((void *) &fcs_ecdsa_hash_sign_param, 1414 0, sizeof(fcs_crypto_service_data)); 1415 1416 if (status < 0) { 1417 *mbox_error = -status; 1418 return INTEL_SIP_SMC_STATUS_ERROR; 1419 } 1420 1421 *dst_size = resp_len * MBOX_WORD_BYTE; 1422 flush_dcache_range(dst_addr, *dst_size); 1423 1424 return INTEL_SIP_SMC_STATUS_OK; 1425 } 1426 1427 int intel_fcs_ecdsa_hash_sig_verify_init(uint32_t session_id, uint32_t context_id, 1428 uint32_t key_id, uint32_t param_size, 1429 uint64_t param_data, uint32_t *mbox_error) 1430 { 1431 return intel_fcs_crypto_service_init(session_id, context_id, 1432 key_id, param_size, param_data, 1433 (void *) &fcs_ecdsa_hash_sig_verify_param, 1434 mbox_error); 1435 } 1436 1437 int intel_fcs_ecdsa_hash_sig_verify_finalize(uint32_t session_id, uint32_t context_id, 1438 uint32_t src_addr, uint32_t src_size, 1439 uint64_t dst_addr, uint32_t *dst_size, 1440 uint32_t *mbox_error) 1441 { 1442 int status; 1443 uint32_t i = 0; 1444 uint32_t payload[FCS_ECDSA_HASH_SIG_VERIFY_CMD_MAX_WORD_SIZE] = {0U}; 1445 uint32_t resp_len; 1446 uintptr_t hash_sig_pubkey_addr; 1447 uint32_t dst_size_check = 0; 1448 1449 if ((dst_size == NULL) || (mbox_error == NULL)) { 1450 return INTEL_SIP_SMC_STATUS_REJECTED; 1451 } 1452 1453 if (fcs_ecdsa_hash_sig_verify_param.session_id != session_id || 1454 fcs_ecdsa_hash_sig_verify_param.context_id != context_id) { 1455 return INTEL_SIP_SMC_STATUS_REJECTED; 1456 } 1457 1458 if (!is_address_in_ddr_range(src_addr, src_size) || 1459 !is_address_in_ddr_range(dst_addr, *dst_size)) { 1460 return INTEL_SIP_SMC_STATUS_REJECTED; 1461 } 1462 1463 dst_size_check = *dst_size; 1464 if ((dst_size_check > FCS_MAX_DATA_SIZE || 1465 dst_size_check < FCS_MIN_DATA_SIZE) || 1466 (src_size > FCS_MAX_DATA_SIZE || 1467 src_size < FCS_MIN_DATA_SIZE)) { 1468 return INTEL_SIP_SMC_STATUS_REJECTED; 1469 } 1470 1471 resp_len = *dst_size / MBOX_WORD_BYTE; 1472 1473 /* Prepare command payload */ 1474 /* Crypto header */ 1475 i = 0; 1476 payload[i] = fcs_ecdsa_hash_sig_verify_param.session_id; 1477 1478 i++; 1479 payload[i] = fcs_ecdsa_hash_sig_verify_param.context_id; 1480 1481 i++; 1482 payload[i] = fcs_ecdsa_hash_sig_verify_param.crypto_param_size 1483 & FCS_CS_FIELD_SIZE_MASK; 1484 payload[i] |= (FCS_CS_FIELD_FLAG_INIT | FCS_CS_FIELD_FLAG_UPDATE 1485 | FCS_CS_FIELD_FLAG_FINALIZE) 1486 << FCS_CS_FIELD_FLAG_OFFSET; 1487 1488 i++; 1489 payload[i] = fcs_ecdsa_hash_sig_verify_param.key_id; 1490 1491 /* Crypto parameters */ 1492 i++; 1493 payload[i] = fcs_ecdsa_hash_sig_verify_param.crypto_param 1494 & INTEL_SIP_SMC_FCS_ECC_ALGO_MASK; 1495 1496 /* Hash Data Word, Signature Data Word and Public Key Data word */ 1497 i++; 1498 hash_sig_pubkey_addr = src_addr; 1499 1500 if ((i + ((src_size) / MBOX_WORD_BYTE)) > 1501 FCS_ECDSA_HASH_SIG_VERIFY_CMD_MAX_WORD_SIZE) { 1502 return INTEL_SIP_SMC_STATUS_REJECTED; 1503 } 1504 1505 memcpy((uint8_t *) &payload[i], 1506 (uint8_t *) hash_sig_pubkey_addr, src_size); 1507 1508 i += (src_size / MBOX_WORD_BYTE); 1509 1510 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_ECDSA_HASH_SIG_VERIFY, 1511 payload, i, CMD_CASUAL, (uint32_t *) dst_addr, 1512 &resp_len); 1513 1514 memset((void *)&fcs_ecdsa_hash_sig_verify_param, 1515 0, sizeof(fcs_crypto_service_data)); 1516 1517 if (status < 0) { 1518 *mbox_error = -status; 1519 return INTEL_SIP_SMC_STATUS_ERROR; 1520 } 1521 1522 *dst_size = resp_len * MBOX_WORD_BYTE; 1523 flush_dcache_range(dst_addr, *dst_size); 1524 1525 return INTEL_SIP_SMC_STATUS_OK; 1526 } 1527 1528 int intel_fcs_ecdsa_sha2_data_sign_init(uint32_t session_id, 1529 uint32_t context_id, uint32_t key_id, 1530 uint32_t param_size, uint64_t param_data, 1531 uint32_t *mbox_error) 1532 { 1533 return intel_fcs_crypto_service_init(session_id, context_id, 1534 key_id, param_size, param_data, 1535 (void *) &fcs_sha2_data_sign_param, 1536 mbox_error); 1537 } 1538 1539 int intel_fcs_ecdsa_sha2_data_sign_update_finalize(uint32_t session_id, 1540 uint32_t context_id, uint32_t src_addr, 1541 uint32_t src_size, uint64_t dst_addr, 1542 uint32_t *dst_size, uint8_t is_finalised, 1543 uint32_t *mbox_error) 1544 { 1545 int status; 1546 int i; 1547 uint32_t flag; 1548 uint32_t crypto_header; 1549 uint32_t payload[FCS_ECDSA_SHA2_DATA_SIGN_CMD_MAX_WORD_SIZE] = {0U}; 1550 uint32_t resp_len; 1551 1552 if ((dst_size == NULL) || (mbox_error == NULL)) { 1553 return INTEL_SIP_SMC_STATUS_REJECTED; 1554 } 1555 1556 if (fcs_sha2_data_sign_param.session_id != session_id || 1557 fcs_sha2_data_sign_param.context_id != context_id) { 1558 return INTEL_SIP_SMC_STATUS_REJECTED; 1559 } 1560 1561 /* Source data must be 8 bytes aligned */ 1562 if (!is_8_bytes_aligned(src_size)) { 1563 return INTEL_SIP_SMC_STATUS_REJECTED; 1564 } 1565 1566 if (!is_address_in_ddr_range(src_addr, src_size) || 1567 !is_address_in_ddr_range(dst_addr, *dst_size)) { 1568 return INTEL_SIP_SMC_STATUS_REJECTED; 1569 } 1570 1571 resp_len = *dst_size / MBOX_WORD_BYTE; 1572 1573 /* Prepare crypto header */ 1574 flag = 0; 1575 if (fcs_sha2_data_sign_param.is_updated) { 1576 fcs_sha2_data_sign_param.crypto_param_size = 0; 1577 } else { 1578 flag |= FCS_CS_FIELD_FLAG_INIT; 1579 } 1580 1581 if (is_finalised != 0U) { 1582 flag |= FCS_CS_FIELD_FLAG_FINALIZE; 1583 } else { 1584 flag |= FCS_CS_FIELD_FLAG_UPDATE; 1585 fcs_sha2_data_sign_param.is_updated = 1; 1586 } 1587 crypto_header = (flag << FCS_CS_FIELD_FLAG_OFFSET) | 1588 fcs_sha2_data_sign_param.crypto_param_size; 1589 1590 /* Prepare command payload */ 1591 i = 0; 1592 payload[i] = fcs_sha2_data_sign_param.session_id; 1593 i++; 1594 payload[i] = fcs_sha2_data_sign_param.context_id; 1595 i++; 1596 payload[i] = crypto_header; 1597 i++; 1598 1599 if ((crypto_header >> FCS_CS_FIELD_FLAG_OFFSET) & 1600 FCS_CS_FIELD_FLAG_INIT) { 1601 payload[i] = fcs_sha2_data_sign_param.key_id; 1602 /* Crypto parameters */ 1603 i++; 1604 payload[i] = fcs_sha2_data_sign_param.crypto_param 1605 & INTEL_SIP_SMC_FCS_ECC_ALGO_MASK; 1606 i++; 1607 } 1608 1609 /* Data source address and size */ 1610 payload[i] = src_addr; 1611 i++; 1612 payload[i] = src_size; 1613 i++; 1614 status = mailbox_send_cmd(MBOX_JOB_ID, 1615 MBOX_FCS_ECDSA_SHA2_DATA_SIGN_REQ, payload, 1616 i, CMD_CASUAL, (uint32_t *) dst_addr, 1617 &resp_len); 1618 1619 if (is_finalised != 0U) { 1620 memset((void *)&fcs_sha2_data_sign_param, 0, 1621 sizeof(fcs_crypto_service_data)); 1622 } 1623 1624 if (status < 0) { 1625 *mbox_error = -status; 1626 return INTEL_SIP_SMC_STATUS_ERROR; 1627 } 1628 1629 *dst_size = resp_len * MBOX_WORD_BYTE; 1630 flush_dcache_range(dst_addr, *dst_size); 1631 1632 return INTEL_SIP_SMC_STATUS_OK; 1633 } 1634 1635 int intel_fcs_ecdsa_sha2_data_sign_smmu_update_finalize(uint32_t session_id, 1636 uint32_t context_id, uint32_t src_addr, 1637 uint32_t src_size, uint64_t dst_addr, 1638 uint32_t *dst_size, uint8_t is_finalised, 1639 uint32_t *mbox_error, uint32_t *send_id) 1640 { 1641 int status; 1642 int i; 1643 uint32_t flag; 1644 uint32_t crypto_header; 1645 uint32_t payload[FCS_ECDSA_SHA2_DATA_SIGN_CMD_MAX_WORD_SIZE] = {0U}; 1646 uint32_t resp_len; 1647 1648 /* Source data must be 8 bytes aligned */ 1649 if ((dst_size == NULL) || (mbox_error == NULL || 1650 !is_8_bytes_aligned(src_size))) { 1651 return INTEL_SIP_SMC_STATUS_REJECTED; 1652 } 1653 1654 if (fcs_sha2_data_sign_param.session_id != session_id || 1655 fcs_sha2_data_sign_param.context_id != context_id) { 1656 return INTEL_SIP_SMC_STATUS_REJECTED; 1657 } 1658 1659 if (!is_address_in_ddr_range(src_addr, src_size) || 1660 !is_address_in_ddr_range(dst_addr, *dst_size)) { 1661 return INTEL_SIP_SMC_STATUS_REJECTED; 1662 } 1663 1664 resp_len = *dst_size / MBOX_WORD_BYTE; 1665 1666 /* Prepare crypto header */ 1667 flag = 0; 1668 if (fcs_sha2_data_sign_param.is_updated) { 1669 fcs_sha2_data_sign_param.crypto_param_size = 0; 1670 } else { 1671 flag |= FCS_CS_FIELD_FLAG_INIT; 1672 } 1673 1674 if (is_finalised != 0U) { 1675 flag |= FCS_CS_FIELD_FLAG_FINALIZE; 1676 } else { 1677 flag |= FCS_CS_FIELD_FLAG_UPDATE; 1678 fcs_sha2_data_sign_param.is_updated = 1; 1679 } 1680 crypto_header = (flag << FCS_CS_FIELD_FLAG_OFFSET) | 1681 fcs_sha2_data_sign_param.crypto_param_size; 1682 1683 /* Prepare command payload */ 1684 i = 0; 1685 payload[i] = fcs_sha2_data_sign_param.session_id; 1686 i++; 1687 payload[i] = fcs_sha2_data_sign_param.context_id; 1688 i++; 1689 payload[i] = crypto_header; 1690 i++; 1691 1692 if ((crypto_header >> FCS_CS_FIELD_FLAG_OFFSET) & 1693 FCS_CS_FIELD_FLAG_INIT) { 1694 payload[i] = fcs_sha2_data_sign_param.key_id; 1695 /* Crypto parameters */ 1696 i++; 1697 payload[i] = fcs_sha2_data_sign_param.crypto_param 1698 & INTEL_SIP_SMC_FCS_ECC_ALGO_MASK; 1699 i++; 1700 } 1701 1702 /* Data source address and size */ 1703 payload[i] = src_addr; 1704 i++; 1705 payload[i] = src_size; 1706 i++; 1707 1708 status = mailbox_send_cmd_async(send_id, 1709 MBOX_FCS_ECDSA_SHA2_DATA_SIGN_REQ, 1710 payload, i, CMD_INDIRECT); 1711 1712 if (is_finalised != 0U) { 1713 memset((void *)&fcs_sha2_data_sign_param, 0, 1714 sizeof(fcs_crypto_service_data)); 1715 } 1716 1717 if (status < 0) { 1718 *mbox_error = -status; 1719 return INTEL_SIP_SMC_STATUS_ERROR; 1720 } 1721 1722 *dst_size = resp_len * MBOX_WORD_BYTE; 1723 flush_dcache_range(dst_addr, *dst_size); 1724 1725 return INTEL_SIP_SMC_STATUS_OK; 1726 } 1727 1728 int intel_fcs_ecdsa_sha2_data_sig_verify_init(uint32_t session_id, 1729 uint32_t context_id, uint32_t key_id, 1730 uint32_t param_size, uint64_t param_data, 1731 uint32_t *mbox_error) 1732 { 1733 return intel_fcs_crypto_service_init(session_id, context_id, 1734 key_id, param_size, param_data, 1735 (void *) &fcs_sha2_data_sig_verify_param, 1736 mbox_error); 1737 } 1738 1739 int intel_fcs_ecdsa_sha2_data_sig_verify_update_finalize(uint32_t session_id, 1740 uint32_t context_id, uint32_t src_addr, 1741 uint32_t src_size, uint64_t dst_addr, 1742 uint32_t *dst_size, uint32_t data_size, 1743 uint8_t is_finalised, uint32_t *mbox_error) 1744 { 1745 int status; 1746 uint32_t i; 1747 uint32_t flag; 1748 uint32_t crypto_header; 1749 uint32_t payload[FCS_ECDSA_SHA2_DATA_SIG_VERIFY_CMD_MAX_WORD_SIZE] = {0U}; 1750 uint32_t resp_len; 1751 uintptr_t sig_pubkey_offset; 1752 uint32_t dst_size_check = 0; 1753 1754 if ((dst_size == NULL) || (mbox_error == NULL)) { 1755 return INTEL_SIP_SMC_STATUS_REJECTED; 1756 } 1757 1758 if (fcs_sha2_data_sig_verify_param.session_id != session_id || 1759 fcs_sha2_data_sig_verify_param.context_id != context_id) { 1760 return INTEL_SIP_SMC_STATUS_REJECTED; 1761 } 1762 1763 if (data_size > src_size) { 1764 return INTEL_SIP_SMC_STATUS_REJECTED; 1765 } 1766 1767 if (!is_size_4_bytes_aligned(src_size)) { 1768 return INTEL_SIP_SMC_STATUS_REJECTED; 1769 } 1770 1771 if (!is_8_bytes_aligned(data_size) || 1772 !is_8_bytes_aligned(src_addr)) { 1773 return INTEL_SIP_SMC_STATUS_REJECTED; 1774 } 1775 1776 if (!is_address_in_ddr_range(src_addr, src_size) || 1777 !is_address_in_ddr_range(dst_addr, *dst_size)) { 1778 return INTEL_SIP_SMC_STATUS_REJECTED; 1779 } 1780 1781 dst_size_check = *dst_size; 1782 if ((dst_size_check > FCS_MAX_DATA_SIZE || 1783 dst_size_check < FCS_MIN_DATA_SIZE) || 1784 (src_size > FCS_MAX_DATA_SIZE || 1785 src_size < FCS_MIN_DATA_SIZE)) { 1786 return INTEL_SIP_SMC_STATUS_REJECTED; 1787 } 1788 1789 resp_len = *dst_size / MBOX_WORD_BYTE; 1790 1791 /* Prepare crypto header */ 1792 flag = 0; 1793 if (fcs_sha2_data_sig_verify_param.is_updated) 1794 fcs_sha2_data_sig_verify_param.crypto_param_size = 0; 1795 else 1796 flag |= FCS_CS_FIELD_FLAG_INIT; 1797 1798 if (is_finalised != 0U) 1799 flag |= FCS_CS_FIELD_FLAG_FINALIZE; 1800 else { 1801 flag |= FCS_CS_FIELD_FLAG_UPDATE; 1802 fcs_sha2_data_sig_verify_param.is_updated = 1; 1803 } 1804 crypto_header = (flag << FCS_CS_FIELD_FLAG_OFFSET) | 1805 fcs_sha2_data_sig_verify_param.crypto_param_size; 1806 1807 /* Prepare command payload */ 1808 i = 0; 1809 payload[i] = fcs_sha2_data_sig_verify_param.session_id; 1810 i++; 1811 payload[i] = fcs_sha2_data_sig_verify_param.context_id; 1812 i++; 1813 payload[i] = crypto_header; 1814 i++; 1815 1816 if ((crypto_header >> FCS_CS_FIELD_FLAG_OFFSET) & 1817 FCS_CS_FIELD_FLAG_INIT) { 1818 payload[i] = fcs_sha2_data_sig_verify_param.key_id; 1819 i++; 1820 /* Crypto parameters */ 1821 payload[i] = fcs_sha2_data_sig_verify_param.crypto_param 1822 & INTEL_SIP_SMC_FCS_ECC_ALGO_MASK; 1823 i++; 1824 } 1825 1826 /* Data source address and size */ 1827 payload[i] = src_addr; 1828 i++; 1829 payload[i] = data_size; 1830 i++; 1831 1832 if ((crypto_header >> FCS_CS_FIELD_FLAG_OFFSET) & 1833 FCS_CS_FIELD_FLAG_FINALIZE) { 1834 /* Signature + Public Key Data */ 1835 sig_pubkey_offset = src_addr + data_size; 1836 1837 if ((i + ((src_size - data_size) / MBOX_WORD_BYTE)) > 1838 FCS_ECDSA_SHA2_DATA_SIG_VERIFY_CMD_MAX_WORD_SIZE) { 1839 return INTEL_SIP_SMC_STATUS_REJECTED; 1840 } 1841 1842 memcpy((uint8_t *) &payload[i], (uint8_t *) sig_pubkey_offset, 1843 src_size - data_size); 1844 1845 i += (src_size - data_size) / MBOX_WORD_BYTE; 1846 } 1847 1848 status = mailbox_send_cmd(MBOX_JOB_ID, 1849 MBOX_FCS_ECDSA_SHA2_DATA_SIGN_VERIFY, payload, i, 1850 CMD_CASUAL, (uint32_t *) dst_addr, &resp_len); 1851 1852 if (is_finalised != 0U) { 1853 memset((void *) &fcs_sha2_data_sig_verify_param, 0, 1854 sizeof(fcs_crypto_service_data)); 1855 } 1856 1857 if (status < 0) { 1858 *mbox_error = -status; 1859 return INTEL_SIP_SMC_STATUS_ERROR; 1860 } 1861 1862 *dst_size = resp_len * MBOX_WORD_BYTE; 1863 flush_dcache_range(dst_addr, *dst_size); 1864 1865 return INTEL_SIP_SMC_STATUS_OK; 1866 } 1867 1868 int intel_fcs_ecdsa_sha2_data_sig_verify_smmu_update_finalize(uint32_t session_id, 1869 uint32_t context_id, uint32_t src_addr, 1870 uint32_t src_size, uint64_t dst_addr, 1871 uint32_t *dst_size, uint32_t data_size, 1872 uint8_t is_finalised, uint32_t *mbox_error, 1873 uint32_t *send_id) 1874 { 1875 int status; 1876 uint32_t i; 1877 uint32_t flag; 1878 uint32_t crypto_header; 1879 uint32_t payload[FCS_ECDSA_SHA2_DATA_SIG_VERIFY_CMD_MAX_WORD_SIZE] = {0U}; 1880 uint32_t resp_len; 1881 uintptr_t sig_pubkey_offset; 1882 uint32_t dst_size_check = 0; 1883 1884 /* 1885 * Source data must be 4 bytes aligned 1886 * Source address must be 8 bytes aligned 1887 * User data must be 8 bytes aligned 1888 */ 1889 if ((dst_size == NULL) || (mbox_error == NULL) || 1890 !is_size_4_bytes_aligned(src_size) || 1891 !is_8_bytes_aligned(src_addr) || 1892 !is_8_bytes_aligned(data_size)) { 1893 return INTEL_SIP_SMC_STATUS_REJECTED; 1894 } 1895 1896 if (fcs_sha2_data_sig_verify_param.session_id != session_id || 1897 fcs_sha2_data_sig_verify_param.context_id != context_id) { 1898 return INTEL_SIP_SMC_STATUS_REJECTED; 1899 } 1900 1901 if (data_size > src_size) { 1902 return INTEL_SIP_SMC_STATUS_REJECTED; 1903 } 1904 1905 if (!is_address_in_ddr_range(src_addr, src_size) || 1906 !is_address_in_ddr_range(dst_addr, *dst_size)) { 1907 return INTEL_SIP_SMC_STATUS_REJECTED; 1908 } 1909 1910 dst_size_check = *dst_size; 1911 if ((dst_size_check > FCS_MAX_DATA_SIZE || 1912 dst_size_check < FCS_MIN_DATA_SIZE) || 1913 (src_size > FCS_MAX_DATA_SIZE || 1914 src_size < FCS_MIN_DATA_SIZE)) { 1915 return INTEL_SIP_SMC_STATUS_REJECTED; 1916 } 1917 1918 resp_len = *dst_size / MBOX_WORD_BYTE; 1919 1920 /* Prepare crypto header */ 1921 flag = 0; 1922 if (fcs_sha2_data_sig_verify_param.is_updated) 1923 fcs_sha2_data_sig_verify_param.crypto_param_size = 0; 1924 else 1925 flag |= FCS_CS_FIELD_FLAG_INIT; 1926 1927 if (is_finalised != 0U) 1928 flag |= FCS_CS_FIELD_FLAG_FINALIZE; 1929 else { 1930 flag |= FCS_CS_FIELD_FLAG_UPDATE; 1931 fcs_sha2_data_sig_verify_param.is_updated = 1; 1932 } 1933 crypto_header = (flag << FCS_CS_FIELD_FLAG_OFFSET) | 1934 fcs_sha2_data_sig_verify_param.crypto_param_size; 1935 1936 /* Prepare command payload */ 1937 i = 0; 1938 payload[i] = fcs_sha2_data_sig_verify_param.session_id; 1939 i++; 1940 payload[i] = fcs_sha2_data_sig_verify_param.context_id; 1941 i++; 1942 payload[i] = crypto_header; 1943 i++; 1944 1945 if ((crypto_header >> FCS_CS_FIELD_FLAG_OFFSET) & 1946 FCS_CS_FIELD_FLAG_INIT) { 1947 payload[i] = fcs_sha2_data_sig_verify_param.key_id; 1948 i++; 1949 /* Crypto parameters */ 1950 payload[i] = fcs_sha2_data_sig_verify_param.crypto_param 1951 & INTEL_SIP_SMC_FCS_ECC_ALGO_MASK; 1952 i++; 1953 } 1954 1955 /* Data source address and size */ 1956 payload[i] = src_addr; 1957 i++; 1958 payload[i] = data_size; 1959 i++; 1960 1961 if ((crypto_header >> FCS_CS_FIELD_FLAG_OFFSET) & 1962 FCS_CS_FIELD_FLAG_FINALIZE) { 1963 /* Copy mac data to command 1964 * Using dst_addr (physical address) to store sig_pubkey_offset 1965 * sig_pubkey_offset is Signature + Public Key Data 1966 */ 1967 sig_pubkey_offset = dst_addr; 1968 1969 if ((i + ((src_size - data_size) / MBOX_WORD_BYTE)) > 1970 FCS_ECDSA_SHA2_DATA_SIG_VERIFY_CMD_MAX_WORD_SIZE) { 1971 return INTEL_SIP_SMC_STATUS_REJECTED; 1972 } 1973 1974 memcpy((uint8_t *) &payload[i], (uint8_t *) sig_pubkey_offset, 1975 src_size - data_size); 1976 1977 memset((void *) dst_addr, 0, *dst_size); 1978 1979 i += (src_size - data_size) / MBOX_WORD_BYTE; 1980 } 1981 1982 status = mailbox_send_cmd_async(send_id, 1983 MBOX_FCS_ECDSA_SHA2_DATA_SIGN_VERIFY, 1984 payload, i, CMD_INDIRECT); 1985 1986 if (is_finalised != 0U) { 1987 memset((void *) &fcs_sha2_data_sig_verify_param, 0, 1988 sizeof(fcs_crypto_service_data)); 1989 } 1990 1991 if (status < 0) { 1992 *mbox_error = -status; 1993 return INTEL_SIP_SMC_STATUS_ERROR; 1994 } 1995 1996 *dst_size = resp_len * MBOX_WORD_BYTE; 1997 flush_dcache_range(dst_addr, *dst_size); 1998 1999 return INTEL_SIP_SMC_STATUS_OK; 2000 } 2001 2002 int intel_fcs_ecdsa_get_pubkey_init(uint32_t session_id, uint32_t context_id, 2003 uint32_t key_id, uint32_t param_size, 2004 uint64_t param_data, uint32_t *mbox_error) 2005 { 2006 return intel_fcs_crypto_service_init(session_id, context_id, 2007 key_id, param_size, param_data, 2008 (void *) &fcs_ecdsa_get_pubkey_param, 2009 mbox_error); 2010 } 2011 2012 int intel_fcs_ecdsa_get_pubkey_finalize(uint32_t session_id, uint32_t context_id, 2013 uint64_t dst_addr, uint32_t *dst_size, 2014 uint32_t *mbox_error) 2015 { 2016 int status; 2017 int i; 2018 uint32_t crypto_header; 2019 uint32_t ret_size; 2020 uint32_t payload[FCS_ECDSA_GET_PUBKEY_MAX_WORD_SIZE] = {0U}; 2021 2022 if ((dst_size == NULL) || (mbox_error == NULL)) { 2023 return INTEL_SIP_SMC_STATUS_REJECTED; 2024 } 2025 2026 if (!is_address_in_ddr_range(dst_addr, *dst_size)) { 2027 return INTEL_SIP_SMC_STATUS_REJECTED; 2028 } 2029 2030 if (fcs_ecdsa_get_pubkey_param.session_id != session_id || 2031 fcs_ecdsa_get_pubkey_param.context_id != context_id) { 2032 return INTEL_SIP_SMC_STATUS_REJECTED; 2033 } 2034 2035 ret_size = *dst_size / MBOX_WORD_BYTE; 2036 2037 crypto_header = ((FCS_CS_FIELD_FLAG_INIT | 2038 FCS_CS_FIELD_FLAG_UPDATE | 2039 FCS_CS_FIELD_FLAG_FINALIZE) << 2040 FCS_CS_FIELD_FLAG_OFFSET) | 2041 fcs_ecdsa_get_pubkey_param.crypto_param_size; 2042 i = 0; 2043 /* Prepare command payload */ 2044 payload[i] = session_id; 2045 i++; 2046 payload[i] = context_id; 2047 i++; 2048 payload[i] = crypto_header; 2049 i++; 2050 payload[i] = fcs_ecdsa_get_pubkey_param.key_id; 2051 i++; 2052 payload[i] = (uint32_t) fcs_ecdsa_get_pubkey_param.crypto_param & 2053 INTEL_SIP_SMC_FCS_ECC_ALGO_MASK; 2054 i++; 2055 2056 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_ECDSA_GET_PUBKEY, 2057 payload, i, CMD_CASUAL, 2058 (uint32_t *) dst_addr, &ret_size); 2059 2060 memset((void *) &fcs_ecdsa_get_pubkey_param, 0, 2061 sizeof(fcs_crypto_service_data)); 2062 2063 if (status < 0) { 2064 *mbox_error = -status; 2065 return INTEL_SIP_SMC_STATUS_ERROR; 2066 } 2067 2068 *dst_size = ret_size * MBOX_WORD_BYTE; 2069 flush_dcache_range(dst_addr, *dst_size); 2070 2071 return INTEL_SIP_SMC_STATUS_OK; 2072 } 2073 2074 int intel_fcs_ecdh_request_init(uint32_t session_id, uint32_t context_id, 2075 uint32_t key_id, uint32_t param_size, 2076 uint64_t param_data, uint32_t *mbox_error) 2077 { 2078 return intel_fcs_crypto_service_init(session_id, context_id, 2079 key_id, param_size, param_data, 2080 (void *) &fcs_ecdh_request_param, 2081 mbox_error); 2082 } 2083 2084 int intel_fcs_ecdh_request_finalize(uint32_t session_id, uint32_t context_id, 2085 uint32_t src_addr, uint32_t src_size, 2086 uint64_t dst_addr, uint32_t *dst_size, 2087 uint32_t *mbox_error) 2088 { 2089 int status; 2090 uint32_t i; 2091 uint32_t payload[FCS_ECDH_REQUEST_CMD_MAX_WORD_SIZE] = {0U}; 2092 uint32_t resp_len; 2093 uintptr_t pubkey; 2094 uint32_t dst_size_check = 0; 2095 2096 if ((dst_size == NULL) || (mbox_error == NULL)) { 2097 return INTEL_SIP_SMC_STATUS_REJECTED; 2098 } 2099 2100 2101 if (fcs_ecdh_request_param.session_id != session_id || 2102 fcs_ecdh_request_param.context_id != context_id) { 2103 return INTEL_SIP_SMC_STATUS_REJECTED; 2104 } 2105 2106 if (!is_address_in_ddr_range(src_addr, src_size) || 2107 !is_address_in_ddr_range(dst_addr, *dst_size)) { 2108 return INTEL_SIP_SMC_STATUS_REJECTED; 2109 } 2110 2111 dst_size_check = *dst_size; 2112 if ((dst_size_check > FCS_MAX_DATA_SIZE || 2113 dst_size_check < FCS_MIN_DATA_SIZE) || 2114 (src_size > FCS_MAX_DATA_SIZE || 2115 src_size < FCS_MIN_DATA_SIZE)) { 2116 return INTEL_SIP_SMC_STATUS_REJECTED; 2117 } 2118 2119 resp_len = *dst_size / MBOX_WORD_BYTE; 2120 2121 /* Prepare command payload */ 2122 i = 0; 2123 /* Crypto header */ 2124 payload[i] = fcs_ecdh_request_param.session_id; 2125 i++; 2126 payload[i] = fcs_ecdh_request_param.context_id; 2127 i++; 2128 payload[i] = fcs_ecdh_request_param.crypto_param_size 2129 & FCS_CS_FIELD_SIZE_MASK; 2130 payload[i] |= (FCS_CS_FIELD_FLAG_INIT | FCS_CS_FIELD_FLAG_UPDATE 2131 | FCS_CS_FIELD_FLAG_FINALIZE) 2132 << FCS_CS_FIELD_FLAG_OFFSET; 2133 i++; 2134 payload[i] = fcs_ecdh_request_param.key_id; 2135 i++; 2136 /* Crypto parameters */ 2137 payload[i] = fcs_ecdh_request_param.crypto_param 2138 & INTEL_SIP_SMC_FCS_ECC_ALGO_MASK; 2139 i++; 2140 /* Public key data */ 2141 pubkey = src_addr; 2142 2143 if ((i + ((src_size) / MBOX_WORD_BYTE)) > 2144 FCS_ECDH_REQUEST_CMD_MAX_WORD_SIZE) { 2145 return INTEL_SIP_SMC_STATUS_REJECTED; 2146 } 2147 2148 memcpy((uint8_t *) &payload[i], (uint8_t *) pubkey, src_size); 2149 i += src_size / MBOX_WORD_BYTE; 2150 2151 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_ECDH_REQUEST, 2152 payload, i, CMD_CASUAL, (uint32_t *) dst_addr, 2153 &resp_len); 2154 2155 memset((void *)&fcs_ecdh_request_param, 0, 2156 sizeof(fcs_crypto_service_data)); 2157 2158 if (status < 0) { 2159 *mbox_error = -status; 2160 return INTEL_SIP_SMC_STATUS_ERROR; 2161 } 2162 2163 *dst_size = resp_len * MBOX_WORD_BYTE; 2164 flush_dcache_range(dst_addr, *dst_size); 2165 2166 return INTEL_SIP_SMC_STATUS_OK; 2167 } 2168 2169 int intel_fcs_aes_crypt_init(uint32_t session_id, uint32_t context_id, 2170 uint32_t key_id, uint64_t param_addr, 2171 uint32_t param_size, uint32_t *mbox_error) 2172 { 2173 /* ptr to get param_addr value */ 2174 uint64_t *param_addr_ptr; 2175 2176 param_addr_ptr = (uint64_t *) param_addr; 2177 2178 /* Check if mbox_error is not NULL or 0xF or 0x3FF */ 2179 if (mbox_error == NULL || *mbox_error > 0xF || 2180 (*mbox_error != 0 && *mbox_error != 0x3FF)) { 2181 return INTEL_SIP_SMC_STATUS_REJECTED; 2182 } 2183 2184 /* Check if param_addr is not 0 or larger that 0xFFFFFFFFFF */ 2185 if (param_addr == 0 || param_addr > 0xFFFFFFFFFF) { 2186 return INTEL_SIP_SMC_STATUS_REJECTED; 2187 } 2188 2189 /* 2190 * Check if not ECB, CBC and CTR mode, addr ptr is NULL. 2191 * Return "Reject" status 2192 */ 2193 if ((param_addr_ptr == NULL) || 2194 (((*param_addr_ptr & FCS_CRYPTO_BLOCK_MODE_MASK) != FCS_CRYPTO_ECB_MODE) && 2195 ((*param_addr_ptr & FCS_CRYPTO_BLOCK_MODE_MASK) != FCS_CRYPTO_CBC_MODE) && 2196 ((*param_addr_ptr & FCS_CRYPTO_BLOCK_MODE_MASK) != FCS_CRYPTO_CTR_MODE))) { 2197 return INTEL_SIP_SMC_STATUS_REJECTED; 2198 } 2199 2200 /* 2201 * Since crypto param size vary between mode. 2202 * Check CBC/CTR here and limit to size 28 bytes 2203 */ 2204 if ((((*param_addr_ptr & FCS_CRYPTO_BLOCK_MODE_MASK) == FCS_CRYPTO_CBC_MODE) || 2205 ((*param_addr_ptr & FCS_CRYPTO_BLOCK_MODE_MASK) == FCS_CRYPTO_CTR_MODE)) && 2206 (param_size > FCS_CRYPTO_CBC_CTR_BUFFER_SIZE)) { 2207 return INTEL_SIP_SMC_STATUS_REJECTED; 2208 } 2209 2210 /* 2211 * Since crypto param size vary between mode. 2212 * Check ECB here and limit to size 12 bytes 2213 */ 2214 if (((*param_addr_ptr & FCS_CRYPTO_BLOCK_MODE_MASK) == FCS_CRYPTO_ECB_MODE) && 2215 (param_size > FCS_CRYPTO_ECB_BUFFER_SIZE)) { 2216 return INTEL_SIP_SMC_STATUS_REJECTED; 2217 } 2218 2219 memset((void *)&fcs_aes_init_payload, 0U, sizeof(fcs_aes_init_payload)); 2220 2221 fcs_aes_init_payload.session_id = session_id; 2222 fcs_aes_init_payload.context_id = context_id; 2223 fcs_aes_init_payload.param_size = param_size; 2224 fcs_aes_init_payload.key_id = key_id; 2225 2226 memcpy((uint8_t *) fcs_aes_init_payload.crypto_param, 2227 (uint8_t *) param_addr, param_size); 2228 2229 fcs_aes_init_payload.is_updated = 0; 2230 2231 *mbox_error = 0; 2232 2233 return INTEL_SIP_SMC_STATUS_OK; 2234 } 2235 2236 int intel_fcs_aes_crypt_update_finalize(uint32_t session_id, 2237 uint32_t context_id, uint64_t src_addr, 2238 uint32_t src_size, uint64_t dst_addr, 2239 uint32_t dst_size, uint8_t is_finalised, 2240 uint32_t *send_id) 2241 { 2242 int status; 2243 int i; 2244 uint32_t flag; 2245 uint32_t crypto_header; 2246 uint32_t fcs_aes_crypt_payload[FCS_AES_CMD_MAX_WORD_SIZE]; 2247 2248 if (fcs_aes_init_payload.session_id != session_id || 2249 fcs_aes_init_payload.context_id != context_id) { 2250 return INTEL_SIP_SMC_STATUS_REJECTED; 2251 } 2252 2253 if ((!is_8_bytes_aligned(src_addr)) || 2254 (!is_32_bytes_aligned(src_size)) || 2255 (!is_address_in_ddr_range(src_addr, src_size))) { 2256 return INTEL_SIP_SMC_STATUS_REJECTED; 2257 } 2258 2259 if ((!is_8_bytes_aligned(dst_addr)) || 2260 (!is_32_bytes_aligned(dst_size)) || 2261 (!is_address_in_ddr_range(dst_addr, dst_size))) { 2262 return INTEL_SIP_SMC_STATUS_REJECTED; 2263 } 2264 2265 if ((dst_size > FCS_AES_MAX_DATA_SIZE || 2266 dst_size < FCS_AES_MIN_DATA_SIZE) || 2267 (src_size > FCS_AES_MAX_DATA_SIZE || 2268 src_size < FCS_AES_MIN_DATA_SIZE)) { 2269 return INTEL_SIP_SMC_STATUS_REJECTED; 2270 } 2271 2272 /* Prepare crypto header*/ 2273 flag = 0; 2274 if (fcs_aes_init_payload.is_updated) { 2275 fcs_aes_init_payload.param_size = 0; 2276 } else { 2277 flag |= FCS_CS_FIELD_FLAG_INIT; 2278 } 2279 2280 if (is_finalised != 0U) { 2281 flag |= FCS_CS_FIELD_FLAG_FINALIZE; 2282 } else { 2283 flag |= FCS_CS_FIELD_FLAG_UPDATE; 2284 fcs_aes_init_payload.is_updated = 1; 2285 } 2286 crypto_header = (flag << FCS_CS_FIELD_FLAG_OFFSET) | 2287 fcs_aes_init_payload.param_size; 2288 2289 i = 0U; 2290 fcs_aes_crypt_payload[i] = session_id; 2291 i++; 2292 fcs_aes_crypt_payload[i] = context_id; 2293 i++; 2294 fcs_aes_crypt_payload[i] = crypto_header; 2295 i++; 2296 2297 if ((crypto_header >> FCS_CS_FIELD_FLAG_OFFSET) & 2298 FCS_CS_FIELD_FLAG_INIT) { 2299 fcs_aes_crypt_payload[i] = fcs_aes_init_payload.key_id; 2300 i++; 2301 2302 if ((i + ((fcs_aes_init_payload.param_size) / MBOX_WORD_BYTE)) > 2303 FCS_AES_CMD_MAX_WORD_SIZE) { 2304 return INTEL_SIP_SMC_STATUS_REJECTED; 2305 } 2306 2307 memcpy((uint8_t *) &fcs_aes_crypt_payload[i], 2308 (uint8_t *) fcs_aes_init_payload.crypto_param, 2309 fcs_aes_init_payload.param_size); 2310 2311 i += fcs_aes_init_payload.param_size / MBOX_WORD_BYTE; 2312 } 2313 2314 fcs_aes_crypt_payload[i] = (uint32_t) src_addr; 2315 i++; 2316 fcs_aes_crypt_payload[i] = src_size; 2317 i++; 2318 fcs_aes_crypt_payload[i] = (uint32_t) dst_addr; 2319 i++; 2320 fcs_aes_crypt_payload[i] = dst_size; 2321 i++; 2322 2323 status = mailbox_send_cmd_async(send_id, MBOX_FCS_AES_CRYPT_REQ, 2324 fcs_aes_crypt_payload, i, 2325 CMD_INDIRECT); 2326 2327 if (is_finalised != 0U) { 2328 memset((void *)&fcs_aes_init_payload, 0, 2329 sizeof(fcs_aes_init_payload)); 2330 } 2331 2332 if (status < 0U) { 2333 return INTEL_SIP_SMC_STATUS_ERROR; 2334 } 2335 2336 return INTEL_SIP_SMC_STATUS_OK; 2337 } 2338