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