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