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_sigma_teardown(uint32_t session_id, uint32_t *mbox_error) 341 { 342 int status; 343 344 if ((session_id != PSGSIGMA_SESSION_ID_ONE) && 345 (session_id != PSGSIGMA_UNKNOWN_SESSION)) { 346 return INTEL_SIP_SMC_STATUS_REJECTED; 347 } 348 349 psgsigma_teardown_msg message = { 350 RESERVED_AS_ZERO, 351 PSGSIGMA_TEARDOWN_MAGIC, 352 session_id 353 }; 354 355 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_PSG_SIGMA_TEARDOWN, 356 (uint32_t *) &message, sizeof(message) / MBOX_WORD_BYTE, 357 CMD_CASUAL, NULL, NULL); 358 359 if (status < 0) { 360 *mbox_error = -status; 361 return INTEL_SIP_SMC_STATUS_ERROR; 362 } 363 364 return INTEL_SIP_SMC_STATUS_OK; 365 } 366 367 int intel_fcs_chip_id(uint32_t *id_low, uint32_t *id_high, uint32_t *mbox_error) 368 { 369 int status; 370 uint32_t load_size; 371 uint32_t chip_id[2]; 372 373 load_size = sizeof(chip_id) / MBOX_WORD_BYTE; 374 375 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_CMD_GET_CHIPID, NULL, 376 0U, CMD_CASUAL, (uint32_t *) chip_id, &load_size); 377 378 if (status < 0) { 379 *mbox_error = -status; 380 return INTEL_SIP_SMC_STATUS_ERROR; 381 } 382 383 *id_low = chip_id[0]; 384 *id_high = chip_id[1]; 385 386 return INTEL_SIP_SMC_STATUS_OK; 387 } 388 389 int intel_fcs_attestation_subkey(uint64_t src_addr, uint32_t src_size, 390 uint64_t dst_addr, uint32_t *dst_size, uint32_t *mbox_error) 391 { 392 int status; 393 uint32_t send_size = src_size / MBOX_WORD_BYTE; 394 uint32_t ret_size = *dst_size / MBOX_WORD_BYTE; 395 396 397 if (!is_address_in_ddr_range(src_addr, src_size) || 398 !is_address_in_ddr_range(dst_addr, *dst_size)) { 399 return INTEL_SIP_SMC_STATUS_REJECTED; 400 } 401 402 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_ATTESTATION_SUBKEY, 403 (uint32_t *) src_addr, send_size, CMD_CASUAL, 404 (uint32_t *) dst_addr, &ret_size); 405 406 if (status < 0) { 407 *mbox_error = -status; 408 return INTEL_SIP_SMC_STATUS_ERROR; 409 } 410 411 *dst_size = ret_size * MBOX_WORD_BYTE; 412 flush_dcache_range(dst_addr, *dst_size); 413 414 return INTEL_SIP_SMC_STATUS_OK; 415 } 416 417 int intel_fcs_get_measurement(uint64_t src_addr, uint32_t src_size, 418 uint64_t dst_addr, uint32_t *dst_size, uint32_t *mbox_error) 419 { 420 int status; 421 uint32_t send_size = src_size / MBOX_WORD_BYTE; 422 uint32_t ret_size = *dst_size / MBOX_WORD_BYTE; 423 424 if (!is_address_in_ddr_range(src_addr, src_size) || 425 !is_address_in_ddr_range(dst_addr, *dst_size)) { 426 return INTEL_SIP_SMC_STATUS_REJECTED; 427 } 428 429 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_GET_MEASUREMENT, 430 (uint32_t *) src_addr, send_size, CMD_CASUAL, 431 (uint32_t *) dst_addr, &ret_size); 432 433 if (status < 0) { 434 *mbox_error = -status; 435 return INTEL_SIP_SMC_STATUS_ERROR; 436 } 437 438 *dst_size = ret_size * MBOX_WORD_BYTE; 439 flush_dcache_range(dst_addr, *dst_size); 440 441 return INTEL_SIP_SMC_STATUS_OK; 442 } 443 444 int intel_fcs_get_attestation_cert(uint32_t cert_request, uint64_t dst_addr, 445 uint32_t *dst_size, uint32_t *mbox_error) 446 { 447 int status; 448 uint32_t ret_size = *dst_size / MBOX_WORD_BYTE; 449 450 if (mbox_error == NULL) { 451 return INTEL_SIP_SMC_STATUS_REJECTED; 452 } 453 454 if (cert_request < FCS_ALIAS_CERT || 455 cert_request > 456 (FCS_ALIAS_CERT | 457 FCS_DEV_ID_SELF_SIGN_CERT | 458 FCS_DEV_ID_ENROLL_CERT | 459 FCS_ENROLL_SELF_SIGN_CERT | 460 FCS_PLAT_KEY_CERT)) { 461 return INTEL_SIP_SMC_STATUS_REJECTED; 462 } 463 464 if (!is_address_in_ddr_range(dst_addr, *dst_size)) { 465 return INTEL_SIP_SMC_STATUS_REJECTED; 466 } 467 468 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_GET_ATTESTATION_CERT, 469 (uint32_t *) &cert_request, 1U, CMD_CASUAL, 470 (uint32_t *) dst_addr, &ret_size); 471 472 if (status < 0) { 473 *mbox_error = -status; 474 return INTEL_SIP_SMC_STATUS_ERROR; 475 } 476 477 *dst_size = ret_size * MBOX_WORD_BYTE; 478 flush_dcache_range(dst_addr, *dst_size); 479 480 return INTEL_SIP_SMC_STATUS_OK; 481 } 482 483 int intel_fcs_create_cert_on_reload(uint32_t cert_request, 484 uint32_t *mbox_error) 485 { 486 int status; 487 488 if (mbox_error == NULL) { 489 return INTEL_SIP_SMC_STATUS_REJECTED; 490 } 491 492 if (cert_request < FCS_ALIAS_CERT || 493 cert_request > 494 (FCS_ALIAS_CERT | 495 FCS_DEV_ID_SELF_SIGN_CERT | 496 FCS_DEV_ID_ENROLL_CERT | 497 FCS_ENROLL_SELF_SIGN_CERT | 498 FCS_PLAT_KEY_CERT)) { 499 return INTEL_SIP_SMC_STATUS_REJECTED; 500 } 501 502 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_CREATE_CERT_ON_RELOAD, 503 (uint32_t *) &cert_request, 1U, CMD_CASUAL, 504 NULL, NULL); 505 506 if (status < 0) { 507 *mbox_error = -status; 508 return INTEL_SIP_SMC_STATUS_ERROR; 509 } 510 511 return INTEL_SIP_SMC_STATUS_OK; 512 } 513 514 int intel_fcs_open_crypto_service_session(uint32_t *session_id, 515 uint32_t *mbox_error) 516 { 517 int status; 518 uint32_t resp_len = 1U; 519 520 if ((session_id == NULL) || (mbox_error == NULL)) { 521 return INTEL_SIP_SMC_STATUS_REJECTED; 522 } 523 524 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_OPEN_CS_SESSION, 525 NULL, 0U, CMD_CASUAL, session_id, &resp_len); 526 527 if (status < 0) { 528 *mbox_error = -status; 529 return INTEL_SIP_SMC_STATUS_ERROR; 530 } 531 532 return INTEL_SIP_SMC_STATUS_OK; 533 } 534 535 int intel_fcs_close_crypto_service_session(uint32_t session_id, 536 uint32_t *mbox_error) 537 { 538 int status; 539 540 if (mbox_error == NULL) { 541 return INTEL_SIP_SMC_STATUS_REJECTED; 542 } 543 544 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_CLOSE_CS_SESSION, 545 &session_id, 1U, CMD_CASUAL, NULL, NULL); 546 547 if (status < 0) { 548 *mbox_error = -status; 549 return INTEL_SIP_SMC_STATUS_ERROR; 550 } 551 552 return INTEL_SIP_SMC_STATUS_OK; 553 } 554 555 int intel_fcs_import_crypto_service_key(uint64_t src_addr, uint32_t src_size, 556 uint32_t *send_id) 557 { 558 int status; 559 560 if (src_size > (FCS_CS_KEY_OBJ_MAX_WORD_SIZE * 561 MBOX_WORD_BYTE)) { 562 return INTEL_SIP_SMC_STATUS_REJECTED; 563 } 564 565 if (!is_address_in_ddr_range(src_addr, src_size)) { 566 return INTEL_SIP_SMC_STATUS_REJECTED; 567 } 568 569 status = mailbox_send_cmd_async(send_id, MBOX_FCS_IMPORT_CS_KEY, 570 (uint32_t *)src_addr, src_size / MBOX_WORD_BYTE, 571 CMD_INDIRECT); 572 573 if (status < 0) { 574 return INTEL_SIP_SMC_STATUS_ERROR; 575 } 576 577 return INTEL_SIP_SMC_STATUS_OK; 578 } 579 580 int intel_fcs_export_crypto_service_key(uint32_t session_id, uint32_t key_id, 581 uint64_t dst_addr, uint32_t *dst_size, 582 uint32_t *mbox_error) 583 { 584 int status; 585 uint32_t i; 586 uint32_t payload_size; 587 uint32_t resp_len = FCS_CS_KEY_OBJ_MAX_WORD_SIZE; 588 uint32_t resp_data[FCS_CS_KEY_OBJ_MAX_WORD_SIZE] = {0U}; 589 uint32_t op_status = 0U; 590 591 if ((dst_size == NULL) || (mbox_error == NULL)) { 592 return INTEL_SIP_SMC_STATUS_REJECTED; 593 } 594 595 if (!is_address_in_ddr_range(dst_addr, *dst_size)) { 596 return INTEL_SIP_SMC_STATUS_REJECTED; 597 } 598 599 fcs_cs_key_payload payload = { 600 session_id, 601 RESERVED_AS_ZERO, 602 RESERVED_AS_ZERO, 603 key_id 604 }; 605 606 payload_size = sizeof(payload) / MBOX_WORD_BYTE; 607 608 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_EXPORT_CS_KEY, 609 (uint32_t *) &payload, payload_size, 610 CMD_CASUAL, resp_data, &resp_len); 611 612 if (resp_len > 0) { 613 op_status = resp_data[0] & FCS_CS_KEY_RESP_STATUS_MASK; 614 } 615 616 if (status < 0) { 617 *mbox_error = (-status) | (op_status << FCS_CS_KEY_RESP_STATUS_OFFSET); 618 return INTEL_SIP_SMC_STATUS_ERROR; 619 } 620 621 if (resp_len > 1) { 622 623 /* Export key object is start at second response data */ 624 *dst_size = (resp_len - 1) * MBOX_WORD_BYTE; 625 626 for (i = 1U; i < resp_len; i++) { 627 mmio_write_32(dst_addr, resp_data[i]); 628 dst_addr += MBOX_WORD_BYTE; 629 } 630 631 flush_dcache_range(dst_addr - *dst_size, *dst_size); 632 633 } else { 634 635 /* Unexpected response, missing key object in response */ 636 *mbox_error = MBOX_RET_ERROR; 637 return INTEL_SIP_SMC_STATUS_ERROR; 638 } 639 640 return INTEL_SIP_SMC_STATUS_OK; 641 } 642 643 int intel_fcs_remove_crypto_service_key(uint32_t session_id, uint32_t key_id, 644 uint32_t *mbox_error) 645 { 646 int status; 647 uint32_t payload_size; 648 uint32_t resp_len = 1U; 649 uint32_t resp_data = 0U; 650 uint32_t op_status = 0U; 651 652 if (mbox_error == NULL) { 653 return INTEL_SIP_SMC_STATUS_REJECTED; 654 } 655 656 fcs_cs_key_payload payload = { 657 session_id, 658 RESERVED_AS_ZERO, 659 RESERVED_AS_ZERO, 660 key_id 661 }; 662 663 payload_size = sizeof(payload) / MBOX_WORD_BYTE; 664 665 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_REMOVE_CS_KEY, 666 (uint32_t *) &payload, payload_size, 667 CMD_CASUAL, &resp_data, &resp_len); 668 669 if (resp_len > 0) { 670 op_status = resp_data & FCS_CS_KEY_RESP_STATUS_MASK; 671 } 672 673 if (status < 0) { 674 *mbox_error = (-status) | (op_status << FCS_CS_KEY_RESP_STATUS_OFFSET); 675 return INTEL_SIP_SMC_STATUS_ERROR; 676 } 677 678 return INTEL_SIP_SMC_STATUS_OK; 679 } 680 681 int intel_fcs_get_crypto_service_key_info(uint32_t session_id, uint32_t key_id, 682 uint64_t dst_addr, uint32_t *dst_size, 683 uint32_t *mbox_error) 684 { 685 int status; 686 uint32_t payload_size; 687 uint32_t resp_len = FCS_CS_KEY_INFO_MAX_WORD_SIZE; 688 uint32_t op_status = 0U; 689 690 if ((dst_size == NULL) || (mbox_error == NULL)) { 691 return INTEL_SIP_SMC_STATUS_REJECTED; 692 } 693 694 if (!is_address_in_ddr_range(dst_addr, *dst_size)) { 695 return INTEL_SIP_SMC_STATUS_REJECTED; 696 } 697 698 fcs_cs_key_payload payload = { 699 session_id, 700 RESERVED_AS_ZERO, 701 RESERVED_AS_ZERO, 702 key_id 703 }; 704 705 payload_size = sizeof(payload) / MBOX_WORD_BYTE; 706 707 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_GET_CS_KEY_INFO, 708 (uint32_t *) &payload, payload_size, 709 CMD_CASUAL, (uint32_t *) dst_addr, &resp_len); 710 711 if (resp_len > 0) { 712 op_status = mmio_read_32(dst_addr) & 713 FCS_CS_KEY_RESP_STATUS_MASK; 714 } 715 716 if (status < 0) { 717 *mbox_error = (-status) | (op_status << FCS_CS_KEY_RESP_STATUS_OFFSET); 718 return INTEL_SIP_SMC_STATUS_ERROR; 719 } 720 721 *dst_size = resp_len * MBOX_WORD_BYTE; 722 flush_dcache_range(dst_addr, *dst_size); 723 724 return INTEL_SIP_SMC_STATUS_OK; 725 } 726 727 int intel_fcs_get_digest_init(uint32_t session_id, uint32_t context_id, 728 uint32_t key_id, uint32_t param_size, 729 uint64_t param_data, uint32_t *mbox_error) 730 { 731 return intel_fcs_crypto_service_init(session_id, context_id, 732 key_id, param_size, param_data, 733 (void *) &fcs_sha_get_digest_param, 734 mbox_error); 735 } 736 737 int intel_fcs_get_digest_finalize(uint32_t session_id, uint32_t context_id, 738 uint32_t src_addr, uint32_t src_size, 739 uint64_t dst_addr, uint32_t *dst_size, 740 uint32_t *mbox_error) 741 { 742 int status; 743 uint32_t i; 744 uint32_t resp_len = *dst_size / MBOX_WORD_BYTE; 745 uint32_t payload[FCS_GET_DIGEST_CMD_MAX_WORD_SIZE] = {0U}; 746 747 if (dst_size == NULL || mbox_error == NULL) { 748 return INTEL_SIP_SMC_STATUS_REJECTED; 749 } 750 751 if (fcs_sha_get_digest_param.session_id != session_id || 752 fcs_sha_get_digest_param.context_id != context_id) { 753 return INTEL_SIP_SMC_STATUS_REJECTED; 754 } 755 756 /* Source data must be 8 bytes aligned */ 757 if (!is_8_bytes_aligned(src_size)) { 758 return INTEL_SIP_SMC_STATUS_REJECTED; 759 } 760 761 if (!is_address_in_ddr_range(src_addr, src_size) || 762 !is_address_in_ddr_range(dst_addr, *dst_size)) { 763 return INTEL_SIP_SMC_STATUS_REJECTED; 764 } 765 766 /* Prepare command payload */ 767 i = 0; 768 /* Crypto header */ 769 payload[i] = fcs_sha_get_digest_param.session_id; 770 i++; 771 payload[i] = fcs_sha_get_digest_param.context_id; 772 i++; 773 payload[i] = fcs_sha_get_digest_param.crypto_param_size 774 & FCS_CS_FIELD_SIZE_MASK; 775 payload[i] |= (FCS_CS_FIELD_FLAG_INIT | FCS_CS_FIELD_FLAG_UPDATE 776 | FCS_CS_FIELD_FLAG_FINALIZE) 777 << FCS_CS_FIELD_FLAG_OFFSET; 778 i++; 779 payload[i] = fcs_sha_get_digest_param.key_id; 780 i++; 781 /* Crypto parameters */ 782 payload[i] = fcs_sha_get_digest_param.crypto_param 783 & INTEL_SIP_SMC_FCS_SHA_MODE_MASK; 784 payload[i] |= ((fcs_sha_get_digest_param.crypto_param 785 >> INTEL_SIP_SMC_FCS_DIGEST_SIZE_OFFSET) 786 & INTEL_SIP_SMC_FCS_DIGEST_SIZE_MASK) 787 << FCS_SHA_HMAC_CRYPTO_PARAM_SIZE_OFFSET; 788 i++; 789 /* Data source address and size */ 790 payload[i] = src_addr; 791 i++; 792 payload[i] = src_size; 793 i++; 794 795 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_GET_DIGEST_REQ, 796 payload, i, CMD_CASUAL, 797 (uint32_t *) dst_addr, &resp_len); 798 799 memset((void *)&fcs_sha_get_digest_param, 0, sizeof(fcs_crypto_service_data)); 800 801 if (status < 0) { 802 *mbox_error = -status; 803 return INTEL_SIP_SMC_STATUS_ERROR; 804 } 805 806 *dst_size = resp_len * MBOX_WORD_BYTE; 807 flush_dcache_range(dst_addr, *dst_size); 808 809 return INTEL_SIP_SMC_STATUS_OK; 810 } 811 812 int intel_fcs_mac_verify_init(uint32_t session_id, uint32_t context_id, 813 uint32_t key_id, uint32_t param_size, 814 uint64_t param_data, uint32_t *mbox_error) 815 { 816 return intel_fcs_crypto_service_init(session_id, context_id, 817 key_id, param_size, param_data, 818 (void *) &fcs_sha_mac_verify_param, 819 mbox_error); 820 } 821 822 int intel_fcs_mac_verify_finalize(uint32_t session_id, uint32_t context_id, 823 uint32_t src_addr, uint32_t src_size, 824 uint64_t dst_addr, uint32_t *dst_size, 825 uint32_t data_size, uint32_t *mbox_error) 826 { 827 int status; 828 uint32_t i; 829 uint32_t resp_len = *dst_size / MBOX_WORD_BYTE; 830 uint32_t payload[FCS_MAC_VERIFY_CMD_MAX_WORD_SIZE] = {0U}; 831 uintptr_t mac_offset; 832 833 if (dst_size == NULL || mbox_error == NULL) { 834 return INTEL_SIP_SMC_STATUS_REJECTED; 835 } 836 837 if (fcs_sha_mac_verify_param.session_id != session_id || 838 fcs_sha_mac_verify_param.context_id != context_id) { 839 return INTEL_SIP_SMC_STATUS_REJECTED; 840 } 841 842 if (data_size >= src_size) { 843 return INTEL_SIP_SMC_STATUS_REJECTED; 844 } 845 846 if (!is_size_4_bytes_aligned(src_size) || 847 !is_8_bytes_aligned(data_size)) { 848 return INTEL_SIP_SMC_STATUS_REJECTED; 849 } 850 851 if (!is_address_in_ddr_range(src_addr, src_size) || 852 !is_address_in_ddr_range(dst_addr, *dst_size)) { 853 return INTEL_SIP_SMC_STATUS_REJECTED; 854 } 855 856 /* Prepare command payload */ 857 i = 0; 858 /* Crypto header */ 859 payload[i] = fcs_sha_mac_verify_param.session_id; 860 i++; 861 payload[i] = fcs_sha_mac_verify_param.context_id; 862 i++; 863 payload[i] = fcs_sha_mac_verify_param.crypto_param_size 864 & FCS_CS_FIELD_SIZE_MASK; 865 payload[i] |= (FCS_CS_FIELD_FLAG_INIT | FCS_CS_FIELD_FLAG_UPDATE 866 | FCS_CS_FIELD_FLAG_FINALIZE) 867 << FCS_CS_FIELD_FLAG_OFFSET; 868 i++; 869 payload[i] = fcs_sha_mac_verify_param.key_id; 870 i++; 871 /* Crypto parameters */ 872 payload[i] = ((fcs_sha_mac_verify_param.crypto_param 873 >> INTEL_SIP_SMC_FCS_DIGEST_SIZE_OFFSET) 874 & INTEL_SIP_SMC_FCS_DIGEST_SIZE_MASK) 875 << FCS_SHA_HMAC_CRYPTO_PARAM_SIZE_OFFSET; 876 i++; 877 /* Data source address and size */ 878 payload[i] = src_addr; 879 i++; 880 payload[i] = data_size; 881 i++; 882 /* Copy mac data to command */ 883 mac_offset = src_addr + data_size; 884 memcpy((uint8_t *) &payload[i], (uint8_t *) mac_offset, 885 src_size - data_size); 886 887 i += (src_size - data_size) / MBOX_WORD_BYTE; 888 889 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_MAC_VERIFY_REQ, 890 payload, i, CMD_CASUAL, 891 (uint32_t *) dst_addr, &resp_len); 892 893 memset((void *)&fcs_sha_mac_verify_param, 0, 894 sizeof(fcs_crypto_service_data)); 895 896 if (status < 0) { 897 *mbox_error = -status; 898 return INTEL_SIP_SMC_STATUS_ERROR; 899 } 900 901 *dst_size = resp_len * MBOX_WORD_BYTE; 902 flush_dcache_range(dst_addr, *dst_size); 903 904 return INTEL_SIP_SMC_STATUS_OK; 905 } 906 907 int intel_fcs_aes_crypt_init(uint32_t session_id, uint32_t context_id, 908 uint32_t key_id, uint64_t param_addr, 909 uint32_t param_size, uint32_t *mbox_error) 910 { 911 if (mbox_error == NULL) { 912 return INTEL_SIP_SMC_STATUS_REJECTED; 913 } 914 915 memset((void *)&fcs_aes_init_payload, 0U, sizeof(fcs_aes_init_payload)); 916 917 fcs_aes_init_payload.session_id = session_id; 918 fcs_aes_init_payload.context_id = context_id; 919 fcs_aes_init_payload.param_size = param_size; 920 fcs_aes_init_payload.key_id = key_id; 921 922 memcpy((uint8_t *) fcs_aes_init_payload.crypto_param, 923 (uint8_t *) param_addr, param_size); 924 925 *mbox_error = 0; 926 927 return INTEL_SIP_SMC_STATUS_OK; 928 } 929 930 int intel_fcs_aes_crypt_finalize(uint32_t session_id, uint32_t context_id, 931 uint64_t src_addr, uint32_t src_size, 932 uint64_t dst_addr, uint32_t dst_size, 933 uint32_t *send_id) 934 { 935 int status; 936 int i; 937 uint32_t crypto_header; 938 uint32_t fcs_aes_crypt_payload[FCS_AES_CMD_MAX_WORD_SIZE]; 939 940 if (fcs_aes_init_payload.session_id != session_id || 941 fcs_aes_init_payload.context_id != context_id) { 942 return INTEL_SIP_SMC_STATUS_REJECTED; 943 } 944 945 if ((!is_8_bytes_aligned(src_addr)) || 946 (!is_32_bytes_aligned(src_size)) || 947 (!is_address_in_ddr_range(src_addr, src_size))) { 948 return INTEL_SIP_SMC_STATUS_REJECTED; 949 } 950 951 if ((!is_8_bytes_aligned(dst_addr)) || 952 (!is_32_bytes_aligned(dst_size))) { 953 return INTEL_SIP_SMC_STATUS_REJECTED; 954 } 955 956 if ((dst_size > FCS_AES_MAX_DATA_SIZE || 957 dst_size < FCS_AES_MIN_DATA_SIZE) || 958 (src_size > FCS_AES_MAX_DATA_SIZE || 959 src_size < FCS_AES_MIN_DATA_SIZE)) { 960 return INTEL_SIP_SMC_STATUS_REJECTED; 961 } 962 963 crypto_header = ((FCS_CS_FIELD_FLAG_INIT | 964 FCS_CS_FIELD_FLAG_UPDATE | 965 FCS_CS_FIELD_FLAG_FINALIZE) << 966 FCS_CS_FIELD_FLAG_OFFSET) | 967 fcs_aes_init_payload.param_size; 968 i = 0U; 969 fcs_aes_crypt_payload[i] = session_id; 970 i++; 971 fcs_aes_crypt_payload[i] = context_id; 972 i++; 973 fcs_aes_crypt_payload[i] = crypto_header; 974 i++; 975 fcs_aes_crypt_payload[i] = fcs_aes_init_payload.key_id; 976 977 i++; 978 memcpy((uint8_t *) &fcs_aes_crypt_payload[i], 979 (uint8_t *) fcs_aes_init_payload.crypto_param, 980 fcs_aes_init_payload.param_size); 981 982 i += fcs_aes_init_payload.param_size / MBOX_WORD_BYTE; 983 984 fcs_aes_crypt_payload[i] = (uint32_t) src_addr; 985 i++; 986 fcs_aes_crypt_payload[i] = src_size; 987 i++; 988 fcs_aes_crypt_payload[i] = (uint32_t) dst_addr; 989 i++; 990 fcs_aes_crypt_payload[i] = dst_size; 991 i++; 992 993 status = mailbox_send_cmd_async(send_id, MBOX_FCS_AES_CRYPT_REQ, 994 fcs_aes_crypt_payload, i, 995 CMD_INDIRECT); 996 997 memset((void *)&fcs_aes_init_payload, 0U, sizeof(fcs_aes_init_payload)); 998 999 if (status < 0U) { 1000 return INTEL_SIP_SMC_STATUS_ERROR; 1001 } 1002 1003 return INTEL_SIP_SMC_STATUS_OK; 1004 } 1005