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_data fcs_sha_get_digest_param; 16 17 bool is_size_4_bytes_aligned(uint32_t size) 18 { 19 if ((size % MBOX_WORD_BYTE) != 0U) { 20 return false; 21 } else { 22 return true; 23 } 24 } 25 26 static bool is_8_bytes_aligned(uint32_t data) 27 { 28 if ((data % (MBOX_WORD_BYTE * 2U)) != 0U) { 29 return false; 30 } else { 31 return true; 32 } 33 } 34 35 static int intel_fcs_crypto_service_init(uint32_t session_id, 36 uint32_t context_id, uint32_t key_id, 37 uint32_t param_size, uint64_t param_data, 38 fcs_crypto_service_data *data_addr, 39 uint32_t *mbox_error) 40 { 41 if (mbox_error == NULL) { 42 return INTEL_SIP_SMC_STATUS_REJECTED; 43 } 44 45 if (param_size != 4) { 46 return INTEL_SIP_SMC_STATUS_REJECTED; 47 } 48 49 memset(data_addr, 0, sizeof(fcs_crypto_service_data)); 50 51 data_addr->session_id = session_id; 52 data_addr->context_id = context_id; 53 data_addr->key_id = key_id; 54 data_addr->crypto_param_size = param_size; 55 data_addr->crypto_param = param_data; 56 57 *mbox_error = 0; 58 59 return INTEL_SIP_SMC_STATUS_OK; 60 } 61 62 uint32_t intel_fcs_random_number_gen(uint64_t addr, uint64_t *ret_size, 63 uint32_t *mbox_error) 64 { 65 int status; 66 unsigned int i; 67 unsigned int resp_len = FCS_RANDOM_WORD_SIZE; 68 uint32_t random_data[FCS_RANDOM_WORD_SIZE] = {0U}; 69 70 if (!is_address_in_ddr_range(addr, FCS_RANDOM_BYTE_SIZE)) { 71 return INTEL_SIP_SMC_STATUS_REJECTED; 72 } 73 74 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_RANDOM_GEN, NULL, 0U, 75 CMD_CASUAL, random_data, &resp_len); 76 77 if (status < 0) { 78 *mbox_error = -status; 79 return INTEL_SIP_SMC_STATUS_ERROR; 80 } 81 82 if (resp_len != FCS_RANDOM_WORD_SIZE) { 83 *mbox_error = GENERIC_RESPONSE_ERROR; 84 return INTEL_SIP_SMC_STATUS_ERROR; 85 } 86 87 *ret_size = FCS_RANDOM_BYTE_SIZE; 88 89 for (i = 0U; i < FCS_RANDOM_WORD_SIZE; i++) { 90 mmio_write_32(addr, random_data[i]); 91 addr += MBOX_WORD_BYTE; 92 } 93 94 flush_dcache_range(addr - *ret_size, *ret_size); 95 96 return INTEL_SIP_SMC_STATUS_OK; 97 } 98 99 int intel_fcs_random_number_gen_ext(uint32_t session_id, uint32_t context_id, 100 uint32_t size, uint32_t *send_id) 101 { 102 int status; 103 uint32_t payload_size; 104 uint32_t crypto_header; 105 106 if (size > (FCS_RANDOM_EXT_MAX_WORD_SIZE * 107 MBOX_WORD_BYTE) || size == 0U) { 108 return INTEL_SIP_SMC_STATUS_REJECTED; 109 } 110 111 if (!is_size_4_bytes_aligned(size)) { 112 return INTEL_SIP_SMC_STATUS_REJECTED; 113 } 114 115 crypto_header = (FCS_CS_FIELD_FLAG_INIT | FCS_CS_FIELD_FLAG_FINALIZE) << 116 FCS_CS_FIELD_FLAG_OFFSET; 117 118 fcs_rng_payload payload = { 119 session_id, 120 context_id, 121 crypto_header, 122 size 123 }; 124 125 payload_size = sizeof(payload) / MBOX_WORD_BYTE; 126 127 status = mailbox_send_cmd_async(send_id, MBOX_FCS_RANDOM_GEN, 128 (uint32_t *) &payload, payload_size, 129 CMD_INDIRECT); 130 131 if (status < 0) { 132 return INTEL_SIP_SMC_STATUS_ERROR; 133 } 134 135 return INTEL_SIP_SMC_STATUS_OK; 136 } 137 138 uint32_t intel_fcs_send_cert(uint64_t addr, uint64_t size, 139 uint32_t *send_id) 140 { 141 int status; 142 143 if (!is_address_in_ddr_range(addr, size)) { 144 return INTEL_SIP_SMC_STATUS_REJECTED; 145 } 146 147 if (!is_size_4_bytes_aligned(size)) { 148 return INTEL_SIP_SMC_STATUS_REJECTED; 149 } 150 151 status = mailbox_send_cmd_async(send_id, MBOX_CMD_VAB_SRC_CERT, 152 (uint32_t *)addr, size / MBOX_WORD_BYTE, 153 CMD_DIRECT); 154 155 flush_dcache_range(addr, size); 156 157 if (status < 0) { 158 return INTEL_SIP_SMC_STATUS_ERROR; 159 } 160 161 return INTEL_SIP_SMC_STATUS_OK; 162 } 163 164 uint32_t intel_fcs_get_provision_data(uint32_t *send_id) 165 { 166 int status; 167 168 status = mailbox_send_cmd_async(send_id, MBOX_FCS_GET_PROVISION, 169 NULL, 0U, CMD_DIRECT); 170 171 if (status < 0) { 172 return INTEL_SIP_SMC_STATUS_ERROR; 173 } 174 175 return INTEL_SIP_SMC_STATUS_OK; 176 } 177 178 uint32_t intel_fcs_cntr_set_preauth(uint8_t counter_type, int32_t counter_value, 179 uint32_t test_bit, uint32_t *mbox_error) 180 { 181 int status; 182 uint32_t first_word; 183 uint32_t payload_size; 184 185 if ((test_bit != MBOX_TEST_BIT) && 186 (test_bit != 0)) { 187 return INTEL_SIP_SMC_STATUS_REJECTED; 188 } 189 190 if ((counter_type < FCS_BIG_CNTR_SEL) || 191 (counter_type > FCS_SVN_CNTR_3_SEL)) { 192 return INTEL_SIP_SMC_STATUS_REJECTED; 193 } 194 195 if ((counter_type == FCS_BIG_CNTR_SEL) && 196 (counter_value > FCS_BIG_CNTR_VAL_MAX)) { 197 return INTEL_SIP_SMC_STATUS_REJECTED; 198 } 199 200 if ((counter_type >= FCS_SVN_CNTR_0_SEL) && 201 (counter_type <= FCS_SVN_CNTR_3_SEL) && 202 (counter_value > FCS_SVN_CNTR_VAL_MAX)) { 203 return INTEL_SIP_SMC_STATUS_REJECTED; 204 } 205 206 first_word = test_bit | counter_type; 207 fcs_cntr_set_preauth_payload payload = { 208 first_word, 209 counter_value 210 }; 211 212 payload_size = sizeof(payload) / MBOX_WORD_BYTE; 213 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_CNTR_SET_PREAUTH, 214 (uint32_t *) &payload, payload_size, 215 CMD_CASUAL, NULL, NULL); 216 217 if (status < 0) { 218 *mbox_error = -status; 219 return INTEL_SIP_SMC_STATUS_ERROR; 220 } 221 222 return INTEL_SIP_SMC_STATUS_OK; 223 } 224 225 uint32_t intel_fcs_encryption(uint32_t src_addr, uint32_t src_size, 226 uint32_t dst_addr, uint32_t dst_size, uint32_t *send_id) 227 { 228 int status; 229 uint32_t load_size; 230 231 fcs_encrypt_payload payload = { 232 FCS_ENCRYPTION_DATA_0, 233 src_addr, 234 src_size, 235 dst_addr, 236 dst_size }; 237 load_size = sizeof(payload) / MBOX_WORD_BYTE; 238 239 if (!is_address_in_ddr_range(src_addr, src_size) || 240 !is_address_in_ddr_range(dst_addr, dst_size)) { 241 return INTEL_SIP_SMC_STATUS_REJECTED; 242 } 243 244 if (!is_size_4_bytes_aligned(src_size)) { 245 return INTEL_SIP_SMC_STATUS_REJECTED; 246 } 247 248 status = mailbox_send_cmd_async(send_id, MBOX_FCS_ENCRYPT_REQ, 249 (uint32_t *) &payload, load_size, 250 CMD_INDIRECT); 251 inv_dcache_range(dst_addr, dst_size); 252 253 if (status < 0) { 254 return INTEL_SIP_SMC_STATUS_REJECTED; 255 } 256 257 return INTEL_SIP_SMC_STATUS_OK; 258 } 259 260 uint32_t intel_fcs_decryption(uint32_t src_addr, uint32_t src_size, 261 uint32_t dst_addr, uint32_t dst_size, uint32_t *send_id) 262 { 263 int status; 264 uint32_t load_size; 265 uintptr_t id_offset; 266 267 id_offset = src_addr + FCS_OWNER_ID_OFFSET; 268 fcs_decrypt_payload payload = { 269 FCS_DECRYPTION_DATA_0, 270 {mmio_read_32(id_offset), 271 mmio_read_32(id_offset + MBOX_WORD_BYTE)}, 272 src_addr, 273 src_size, 274 dst_addr, 275 dst_size }; 276 load_size = sizeof(payload) / MBOX_WORD_BYTE; 277 278 if (!is_address_in_ddr_range(src_addr, src_size) || 279 !is_address_in_ddr_range(dst_addr, dst_size)) { 280 return INTEL_SIP_SMC_STATUS_REJECTED; 281 } 282 283 if (!is_size_4_bytes_aligned(src_size)) { 284 return INTEL_SIP_SMC_STATUS_REJECTED; 285 } 286 287 status = mailbox_send_cmd_async(send_id, MBOX_FCS_DECRYPT_REQ, 288 (uint32_t *) &payload, load_size, 289 CMD_INDIRECT); 290 inv_dcache_range(dst_addr, dst_size); 291 292 if (status < 0) { 293 return INTEL_SIP_SMC_STATUS_REJECTED; 294 } 295 296 return INTEL_SIP_SMC_STATUS_OK; 297 } 298 299 uint32_t intel_fcs_get_rom_patch_sha384(uint64_t addr, uint64_t *ret_size, 300 uint32_t *mbox_error) 301 { 302 int status; 303 unsigned int resp_len = FCS_SHA384_WORD_SIZE; 304 305 if (!is_address_in_ddr_range(addr, FCS_SHA384_BYTE_SIZE)) { 306 return INTEL_SIP_SMC_STATUS_REJECTED; 307 } 308 309 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_GET_ROM_PATCH_SHA384, NULL, 0U, 310 CMD_CASUAL, (uint32_t *) addr, &resp_len); 311 312 if (status < 0) { 313 *mbox_error = -status; 314 return INTEL_SIP_SMC_STATUS_ERROR; 315 } 316 317 if (resp_len != FCS_SHA384_WORD_SIZE) { 318 *mbox_error = GENERIC_RESPONSE_ERROR; 319 return INTEL_SIP_SMC_STATUS_ERROR; 320 } 321 322 *ret_size = FCS_SHA384_BYTE_SIZE; 323 324 flush_dcache_range(addr, *ret_size); 325 326 return INTEL_SIP_SMC_STATUS_OK; 327 } 328 329 int intel_fcs_sigma_teardown(uint32_t session_id, uint32_t *mbox_error) 330 { 331 int status; 332 333 if ((session_id != PSGSIGMA_SESSION_ID_ONE) && 334 (session_id != PSGSIGMA_UNKNOWN_SESSION)) { 335 return INTEL_SIP_SMC_STATUS_REJECTED; 336 } 337 338 psgsigma_teardown_msg message = { 339 RESERVED_AS_ZERO, 340 PSGSIGMA_TEARDOWN_MAGIC, 341 session_id 342 }; 343 344 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_PSG_SIGMA_TEARDOWN, 345 (uint32_t *) &message, sizeof(message) / MBOX_WORD_BYTE, 346 CMD_CASUAL, NULL, NULL); 347 348 if (status < 0) { 349 *mbox_error = -status; 350 return INTEL_SIP_SMC_STATUS_ERROR; 351 } 352 353 return INTEL_SIP_SMC_STATUS_OK; 354 } 355 356 int intel_fcs_chip_id(uint32_t *id_low, uint32_t *id_high, uint32_t *mbox_error) 357 { 358 int status; 359 uint32_t load_size; 360 uint32_t chip_id[2]; 361 362 load_size = sizeof(chip_id) / MBOX_WORD_BYTE; 363 364 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_CMD_GET_CHIPID, NULL, 365 0U, CMD_CASUAL, (uint32_t *) chip_id, &load_size); 366 367 if (status < 0) { 368 *mbox_error = -status; 369 return INTEL_SIP_SMC_STATUS_ERROR; 370 } 371 372 *id_low = chip_id[0]; 373 *id_high = chip_id[1]; 374 375 return INTEL_SIP_SMC_STATUS_OK; 376 } 377 378 int intel_fcs_attestation_subkey(uint64_t src_addr, uint32_t src_size, 379 uint64_t dst_addr, uint32_t *dst_size, uint32_t *mbox_error) 380 { 381 int status; 382 uint32_t send_size = src_size / MBOX_WORD_BYTE; 383 uint32_t ret_size = *dst_size / MBOX_WORD_BYTE; 384 385 386 if (!is_address_in_ddr_range(src_addr, src_size) || 387 !is_address_in_ddr_range(dst_addr, *dst_size)) { 388 return INTEL_SIP_SMC_STATUS_REJECTED; 389 } 390 391 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_ATTESTATION_SUBKEY, 392 (uint32_t *) src_addr, send_size, CMD_CASUAL, 393 (uint32_t *) dst_addr, &ret_size); 394 395 if (status < 0) { 396 *mbox_error = -status; 397 return INTEL_SIP_SMC_STATUS_ERROR; 398 } 399 400 *dst_size = ret_size * MBOX_WORD_BYTE; 401 flush_dcache_range(dst_addr, *dst_size); 402 403 return INTEL_SIP_SMC_STATUS_OK; 404 } 405 406 int intel_fcs_get_measurement(uint64_t src_addr, uint32_t src_size, 407 uint64_t dst_addr, uint32_t *dst_size, uint32_t *mbox_error) 408 { 409 int status; 410 uint32_t send_size = src_size / MBOX_WORD_BYTE; 411 uint32_t ret_size = *dst_size / MBOX_WORD_BYTE; 412 413 if (!is_address_in_ddr_range(src_addr, src_size) || 414 !is_address_in_ddr_range(dst_addr, *dst_size)) { 415 return INTEL_SIP_SMC_STATUS_REJECTED; 416 } 417 418 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_GET_MEASUREMENT, 419 (uint32_t *) src_addr, send_size, CMD_CASUAL, 420 (uint32_t *) dst_addr, &ret_size); 421 422 if (status < 0) { 423 *mbox_error = -status; 424 return INTEL_SIP_SMC_STATUS_ERROR; 425 } 426 427 *dst_size = ret_size * MBOX_WORD_BYTE; 428 flush_dcache_range(dst_addr, *dst_size); 429 430 return INTEL_SIP_SMC_STATUS_OK; 431 } 432 433 int intel_fcs_get_attestation_cert(uint32_t cert_request, uint64_t dst_addr, 434 uint32_t *dst_size, uint32_t *mbox_error) 435 { 436 int status; 437 uint32_t ret_size = *dst_size / MBOX_WORD_BYTE; 438 439 if (mbox_error == NULL) { 440 return INTEL_SIP_SMC_STATUS_REJECTED; 441 } 442 443 if (cert_request < FCS_ALIAS_CERT || 444 cert_request > 445 (FCS_ALIAS_CERT | 446 FCS_DEV_ID_SELF_SIGN_CERT | 447 FCS_DEV_ID_ENROLL_CERT | 448 FCS_ENROLL_SELF_SIGN_CERT | 449 FCS_PLAT_KEY_CERT)) { 450 return INTEL_SIP_SMC_STATUS_REJECTED; 451 } 452 453 if (!is_address_in_ddr_range(dst_addr, *dst_size)) { 454 return INTEL_SIP_SMC_STATUS_REJECTED; 455 } 456 457 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_GET_ATTESTATION_CERT, 458 (uint32_t *) &cert_request, 1U, CMD_CASUAL, 459 (uint32_t *) dst_addr, &ret_size); 460 461 if (status < 0) { 462 *mbox_error = -status; 463 return INTEL_SIP_SMC_STATUS_ERROR; 464 } 465 466 *dst_size = ret_size * MBOX_WORD_BYTE; 467 flush_dcache_range(dst_addr, *dst_size); 468 469 return INTEL_SIP_SMC_STATUS_OK; 470 } 471 472 int intel_fcs_create_cert_on_reload(uint32_t cert_request, 473 uint32_t *mbox_error) 474 { 475 int status; 476 477 if (mbox_error == NULL) { 478 return INTEL_SIP_SMC_STATUS_REJECTED; 479 } 480 481 if (cert_request < FCS_ALIAS_CERT || 482 cert_request > 483 (FCS_ALIAS_CERT | 484 FCS_DEV_ID_SELF_SIGN_CERT | 485 FCS_DEV_ID_ENROLL_CERT | 486 FCS_ENROLL_SELF_SIGN_CERT | 487 FCS_PLAT_KEY_CERT)) { 488 return INTEL_SIP_SMC_STATUS_REJECTED; 489 } 490 491 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_CREATE_CERT_ON_RELOAD, 492 (uint32_t *) &cert_request, 1U, CMD_CASUAL, 493 NULL, NULL); 494 495 if (status < 0) { 496 *mbox_error = -status; 497 return INTEL_SIP_SMC_STATUS_ERROR; 498 } 499 500 return INTEL_SIP_SMC_STATUS_OK; 501 } 502 503 int intel_fcs_open_crypto_service_session(uint32_t *session_id, 504 uint32_t *mbox_error) 505 { 506 int status; 507 uint32_t resp_len = 1U; 508 509 if ((session_id == NULL) || (mbox_error == NULL)) { 510 return INTEL_SIP_SMC_STATUS_REJECTED; 511 } 512 513 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_OPEN_CS_SESSION, 514 NULL, 0U, CMD_CASUAL, session_id, &resp_len); 515 516 if (status < 0) { 517 *mbox_error = -status; 518 return INTEL_SIP_SMC_STATUS_ERROR; 519 } 520 521 return INTEL_SIP_SMC_STATUS_OK; 522 } 523 524 int intel_fcs_close_crypto_service_session(uint32_t session_id, 525 uint32_t *mbox_error) 526 { 527 int status; 528 529 if (mbox_error == NULL) { 530 return INTEL_SIP_SMC_STATUS_REJECTED; 531 } 532 533 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_CLOSE_CS_SESSION, 534 &session_id, 1U, CMD_CASUAL, NULL, NULL); 535 536 if (status < 0) { 537 *mbox_error = -status; 538 return INTEL_SIP_SMC_STATUS_ERROR; 539 } 540 541 return INTEL_SIP_SMC_STATUS_OK; 542 } 543 544 int intel_fcs_import_crypto_service_key(uint64_t src_addr, uint32_t src_size, 545 uint32_t *send_id) 546 { 547 int status; 548 549 if (src_size > (FCS_CS_KEY_OBJ_MAX_WORD_SIZE * 550 MBOX_WORD_BYTE)) { 551 return INTEL_SIP_SMC_STATUS_REJECTED; 552 } 553 554 if (!is_address_in_ddr_range(src_addr, src_size)) { 555 return INTEL_SIP_SMC_STATUS_REJECTED; 556 } 557 558 status = mailbox_send_cmd_async(send_id, MBOX_FCS_IMPORT_CS_KEY, 559 (uint32_t *)src_addr, src_size / MBOX_WORD_BYTE, 560 CMD_INDIRECT); 561 562 if (status < 0) { 563 return INTEL_SIP_SMC_STATUS_ERROR; 564 } 565 566 return INTEL_SIP_SMC_STATUS_OK; 567 } 568 569 int intel_fcs_export_crypto_service_key(uint32_t session_id, uint32_t key_id, 570 uint64_t dst_addr, uint32_t *dst_size, 571 uint32_t *mbox_error) 572 { 573 int status; 574 uint32_t i; 575 uint32_t payload_size; 576 uint32_t resp_len = FCS_CS_KEY_OBJ_MAX_WORD_SIZE; 577 uint32_t resp_data[FCS_CS_KEY_OBJ_MAX_WORD_SIZE] = {0U}; 578 uint32_t op_status = 0U; 579 580 if ((dst_size == NULL) || (mbox_error == NULL)) { 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 fcs_cs_key_payload payload = { 589 session_id, 590 RESERVED_AS_ZERO, 591 RESERVED_AS_ZERO, 592 key_id 593 }; 594 595 payload_size = sizeof(payload) / MBOX_WORD_BYTE; 596 597 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_EXPORT_CS_KEY, 598 (uint32_t *) &payload, payload_size, 599 CMD_CASUAL, resp_data, &resp_len); 600 601 if (resp_len > 0) { 602 op_status = resp_data[0] & FCS_CS_KEY_RESP_STATUS_MASK; 603 } 604 605 if (status < 0) { 606 *mbox_error = (-status) | (op_status << FCS_CS_KEY_RESP_STATUS_OFFSET); 607 return INTEL_SIP_SMC_STATUS_ERROR; 608 } 609 610 if (resp_len > 1) { 611 612 /* Export key object is start at second response data */ 613 *dst_size = (resp_len - 1) * MBOX_WORD_BYTE; 614 615 for (i = 1U; i < resp_len; i++) { 616 mmio_write_32(dst_addr, resp_data[i]); 617 dst_addr += MBOX_WORD_BYTE; 618 } 619 620 flush_dcache_range(dst_addr - *dst_size, *dst_size); 621 622 } else { 623 624 /* Unexpected response, missing key object in response */ 625 *mbox_error = MBOX_RET_ERROR; 626 return INTEL_SIP_SMC_STATUS_ERROR; 627 } 628 629 return INTEL_SIP_SMC_STATUS_OK; 630 } 631 632 int intel_fcs_remove_crypto_service_key(uint32_t session_id, uint32_t key_id, 633 uint32_t *mbox_error) 634 { 635 int status; 636 uint32_t payload_size; 637 uint32_t resp_len = 1U; 638 uint32_t resp_data = 0U; 639 uint32_t op_status = 0U; 640 641 if (mbox_error == NULL) { 642 return INTEL_SIP_SMC_STATUS_REJECTED; 643 } 644 645 fcs_cs_key_payload payload = { 646 session_id, 647 RESERVED_AS_ZERO, 648 RESERVED_AS_ZERO, 649 key_id 650 }; 651 652 payload_size = sizeof(payload) / MBOX_WORD_BYTE; 653 654 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_REMOVE_CS_KEY, 655 (uint32_t *) &payload, payload_size, 656 CMD_CASUAL, &resp_data, &resp_len); 657 658 if (resp_len > 0) { 659 op_status = resp_data & FCS_CS_KEY_RESP_STATUS_MASK; 660 } 661 662 if (status < 0) { 663 *mbox_error = (-status) | (op_status << FCS_CS_KEY_RESP_STATUS_OFFSET); 664 return INTEL_SIP_SMC_STATUS_ERROR; 665 } 666 667 return INTEL_SIP_SMC_STATUS_OK; 668 } 669 670 int intel_fcs_get_crypto_service_key_info(uint32_t session_id, uint32_t key_id, 671 uint64_t dst_addr, uint32_t *dst_size, 672 uint32_t *mbox_error) 673 { 674 int status; 675 uint32_t payload_size; 676 uint32_t resp_len = FCS_CS_KEY_INFO_MAX_WORD_SIZE; 677 uint32_t op_status = 0U; 678 679 if ((dst_size == NULL) || (mbox_error == NULL)) { 680 return INTEL_SIP_SMC_STATUS_REJECTED; 681 } 682 683 if (!is_address_in_ddr_range(dst_addr, *dst_size)) { 684 return INTEL_SIP_SMC_STATUS_REJECTED; 685 } 686 687 fcs_cs_key_payload payload = { 688 session_id, 689 RESERVED_AS_ZERO, 690 RESERVED_AS_ZERO, 691 key_id 692 }; 693 694 payload_size = sizeof(payload) / MBOX_WORD_BYTE; 695 696 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_GET_CS_KEY_INFO, 697 (uint32_t *) &payload, payload_size, 698 CMD_CASUAL, (uint32_t *) dst_addr, &resp_len); 699 700 if (resp_len > 0) { 701 op_status = mmio_read_32(dst_addr) & 702 FCS_CS_KEY_RESP_STATUS_MASK; 703 } 704 705 if (status < 0) { 706 *mbox_error = (-status) | (op_status << FCS_CS_KEY_RESP_STATUS_OFFSET); 707 return INTEL_SIP_SMC_STATUS_ERROR; 708 } 709 710 *dst_size = resp_len * MBOX_WORD_BYTE; 711 flush_dcache_range(dst_addr, *dst_size); 712 713 return INTEL_SIP_SMC_STATUS_OK; 714 } 715 716 int intel_fcs_get_digest_init(uint32_t session_id, uint32_t context_id, 717 uint32_t key_id, uint32_t param_size, 718 uint64_t param_data, uint32_t *mbox_error) 719 { 720 return intel_fcs_crypto_service_init(session_id, context_id, 721 key_id, param_size, param_data, 722 (void *) &fcs_sha_get_digest_param, 723 mbox_error); 724 } 725 726 int intel_fcs_get_digest_finalize(uint32_t session_id, uint32_t context_id, 727 uint32_t src_addr, uint32_t src_size, 728 uint64_t dst_addr, uint32_t *dst_size, 729 uint32_t *mbox_error) 730 { 731 int status; 732 uint32_t i; 733 uint32_t resp_len = *dst_size / MBOX_WORD_BYTE; 734 uint32_t payload[FCS_GET_DIGEST_CMD_MAX_WORD_SIZE] = {0U}; 735 736 if (dst_size == NULL || mbox_error == NULL) { 737 return INTEL_SIP_SMC_STATUS_REJECTED; 738 } 739 740 if (fcs_sha_get_digest_param.session_id != session_id || 741 fcs_sha_get_digest_param.context_id != context_id) { 742 return INTEL_SIP_SMC_STATUS_REJECTED; 743 } 744 745 /* Source data must be 8 bytes aligned */ 746 if (!is_8_bytes_aligned(src_size)) { 747 return INTEL_SIP_SMC_STATUS_REJECTED; 748 } 749 750 if (!is_address_in_ddr_range(src_addr, src_size) || 751 !is_address_in_ddr_range(dst_addr, *dst_size)) { 752 return INTEL_SIP_SMC_STATUS_REJECTED; 753 } 754 755 /* Prepare command payload */ 756 i = 0; 757 /* Crypto header */ 758 payload[i] = fcs_sha_get_digest_param.session_id; 759 i++; 760 payload[i] = fcs_sha_get_digest_param.context_id; 761 i++; 762 payload[i] = fcs_sha_get_digest_param.crypto_param_size 763 & FCS_CS_FIELD_SIZE_MASK; 764 payload[i] |= (FCS_CS_FIELD_FLAG_INIT | FCS_CS_FIELD_FLAG_UPDATE 765 | FCS_CS_FIELD_FLAG_FINALIZE) 766 << FCS_CS_FIELD_FLAG_OFFSET; 767 i++; 768 payload[i] = fcs_sha_get_digest_param.key_id; 769 i++; 770 /* Crypto parameters */ 771 payload[i] = fcs_sha_get_digest_param.crypto_param 772 & INTEL_SIP_SMC_FCS_SHA_MODE_MASK; 773 payload[i] |= ((fcs_sha_get_digest_param.crypto_param 774 >> INTEL_SIP_SMC_FCS_DIGEST_SIZE_OFFSET) 775 & INTEL_SIP_SMC_FCS_DIGEST_SIZE_MASK) 776 << FCS_SHA_HMAC_CRYPTO_PARAM_SIZE_OFFSET; 777 i++; 778 /* Data source address and size */ 779 payload[i] = src_addr; 780 i++; 781 payload[i] = src_size; 782 i++; 783 784 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_GET_DIGEST_REQ, 785 payload, i, CMD_CASUAL, 786 (uint32_t *) dst_addr, &resp_len); 787 788 memset((void *)&fcs_sha_get_digest_param, 0, sizeof(fcs_crypto_service_data)); 789 790 if (status < 0) { 791 *mbox_error = -status; 792 return INTEL_SIP_SMC_STATUS_ERROR; 793 } 794 795 *dst_size = resp_len * MBOX_WORD_BYTE; 796 flush_dcache_range(dst_addr, *dst_size); 797 798 return INTEL_SIP_SMC_STATUS_OK; 799 } 800