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