1 /* 2 * Copyright (c) 2020-2023, Intel Corporation. All rights reserved. 3 * Copyright (c) 2024-2025, Altera Corporation. All rights reserved. 4 * 5 * SPDX-License-Identifier: BSD-3-Clause 6 */ 7 8 #include <arch_helpers.h> 9 #include <common/debug.h> 10 #include <lib/mmio.h> 11 12 #include "../lib/utils/alignment_utils.h" 13 #include "socfpga_plat_def.h" 14 #include "socfpga_fcs.h" 15 #include "socfpga_mailbox.h" 16 #include "socfpga_sip_svc.h" 17 18 /* FCS static variables */ 19 static fcs_crypto_service_aes_data fcs_aes_init_payload; 20 static fcs_crypto_service_data fcs_sha_get_digest_param; 21 static fcs_crypto_service_data fcs_sha_mac_verify_param; 22 static fcs_crypto_service_data fcs_ecdsa_hash_sign_param; 23 static fcs_crypto_service_data fcs_ecdsa_hash_sig_verify_param; 24 static fcs_crypto_service_data fcs_sha2_data_sign_param; 25 static fcs_crypto_service_data fcs_sha2_data_sig_verify_param; 26 static fcs_crypto_service_data fcs_ecdsa_get_pubkey_param; 27 static fcs_crypto_service_data fcs_ecdh_request_param; 28 29 uint8_t fcs_send_cert_cb(void *resp_desc, void *cmd_desc, uint64_t *ret_args) 30 { 31 uint8_t ret_args_len = 0U; 32 sdm_response_t *resp = (sdm_response_t *)resp_desc; 33 sdm_command_t *cmd = (sdm_command_t *)cmd_desc; 34 35 (void)cmd; 36 INFO("MBOX: %s: mailbox_err 0x%x, status_word %d\n", 37 __func__, resp->err_code, resp->resp_data[0]); 38 39 ret_args[ret_args_len++] = INTEL_SIP_SMC_STATUS_OK; 40 ret_args[ret_args_len++] = resp->err_code; 41 ret_args[ret_args_len++] = resp->resp_data[0]; 42 43 return ret_args_len; 44 } 45 46 uint8_t fcs_cntr_set_preauth_cb(void *resp_desc, void *cmd_desc, uint64_t *ret_args) 47 { 48 uint8_t ret_args_len = 0U; 49 sdm_response_t *resp = (sdm_response_t *)resp_desc; 50 sdm_command_t *cmd = (sdm_command_t *)cmd_desc; 51 52 (void)cmd; 53 INFO("MBOX: %s: mailbox_err 0x%x\n", __func__, resp->err_code); 54 55 ret_args[ret_args_len++] = INTEL_SIP_SMC_STATUS_OK; 56 ret_args[ret_args_len++] = resp->err_code; 57 58 return ret_args_len; 59 } 60 61 uint8_t fcs_get_attest_cert_cb(void *resp_desc, void *cmd_desc, uint64_t *ret_args) 62 { 63 uint8_t ret_args_len = 0U; 64 sdm_response_t *resp = (sdm_response_t *)resp_desc; 65 sdm_command_t *cmd = (sdm_command_t *)cmd_desc; 66 67 INFO("MBOX: %s: mailbox_err 0x%x, nbytes_ret %d\n", 68 __func__, resp->err_code, resp->rcvd_resp_len * MBOX_WORD_BYTE); 69 70 ret_args[ret_args_len++] = INTEL_SIP_SMC_STATUS_OK; 71 ret_args[ret_args_len++] = resp->err_code; 72 ret_args[ret_args_len++] = resp->rcvd_resp_len * MBOX_WORD_BYTE; 73 74 /* Flush the response data buffer. */ 75 flush_dcache_range((uintptr_t)cmd->cb_args, resp->rcvd_resp_len * MBOX_WORD_BYTE); 76 77 return ret_args_len; 78 } 79 80 uint8_t fcs_hkdf_request_cb(void *resp_desc, void *cmd_desc, uint64_t *ret_args) 81 { 82 uint8_t ret_args_len = 0U; 83 sdm_response_t *resp = (sdm_response_t *)resp_desc; 84 sdm_command_t *cmd = (sdm_command_t *)cmd_desc; 85 86 (void)cmd; 87 88 INFO("MBOX: %s: mbox_err 0x%x, hkdf_status 0x%x\n", __func__, 89 resp->err_code, resp->resp_data[0]); 90 91 ret_args[ret_args_len++] = INTEL_SIP_SMC_STATUS_OK; 92 ret_args[ret_args_len++] = resp->err_code; 93 ret_args[ret_args_len++] = resp->resp_data[0]; 94 95 return ret_args_len; 96 } 97 98 uint8_t fcs_create_cert_reload_cb(void *resp_desc, void *cmd_desc, uint64_t *ret_args) 99 { 100 uint8_t ret_args_len = 0U; 101 sdm_response_t *resp = (sdm_response_t *)resp_desc; 102 sdm_command_t *cmd = (sdm_command_t *)cmd_desc; 103 104 (void)cmd; 105 INFO("MBOX: %s: mailbox_err 0x%x\n", __func__, resp->err_code); 106 107 ret_args[ret_args_len++] = INTEL_SIP_SMC_STATUS_OK; 108 ret_args[ret_args_len++] = resp->err_code; 109 110 return ret_args_len; 111 } 112 113 uint8_t fcs_cs_get_digest_cb(void *resp_desc, void *cmd_desc, uint64_t *ret_args) 114 { 115 uint8_t ret_args_len = 0U; 116 sdm_response_t *resp = (sdm_response_t *)resp_desc; 117 sdm_command_t *cmd = (sdm_command_t *)cmd_desc; 118 119 INFO("MBOX: %s: mbox_err 0x%x, nbytes_ret %d\n", __func__, 120 resp->err_code, resp->rcvd_resp_len * MBOX_WORD_BYTE); 121 122 ret_args[ret_args_len++] = INTEL_SIP_SMC_STATUS_OK; 123 ret_args[ret_args_len++] = resp->err_code; 124 ret_args[ret_args_len++] = resp->rcvd_resp_len * MBOX_WORD_BYTE; 125 126 /* Flush the response data buffer. */ 127 flush_dcache_range((uintptr_t)cmd->cb_args, resp->rcvd_resp_len * MBOX_WORD_BYTE); 128 129 return ret_args_len; 130 } 131 132 uint8_t fcs_cs_mac_verify_cb(void *resp_desc, void *cmd_desc, uint64_t *ret_args) 133 { 134 uint8_t ret_args_len = 0U; 135 sdm_response_t *resp = (sdm_response_t *)resp_desc; 136 sdm_command_t *cmd = (sdm_command_t *)cmd_desc; 137 138 INFO("MBOX: %s: mbox_err 0x%x, nbytes_ret %d, verify_result 0x%x\n", 139 __func__, resp->err_code, 140 resp->rcvd_resp_len * MBOX_WORD_BYTE, 141 cmd->cb_args[3]); 142 143 ret_args[ret_args_len++] = INTEL_SIP_SMC_STATUS_OK; 144 ret_args[ret_args_len++] = resp->err_code; 145 ret_args[ret_args_len++] = resp->rcvd_resp_len * MBOX_WORD_BYTE; 146 ret_args[ret_args_len++] = cmd->cb_args[3]; 147 148 /* Flush the response data buffer. */ 149 flush_dcache_range((uintptr_t)cmd->cb_args, resp->rcvd_resp_len * MBOX_WORD_BYTE); 150 151 return ret_args_len; 152 } 153 154 uint8_t fcs_cs_hash_sign_req_cb(void *resp_desc, void *cmd_desc, uint64_t *ret_args) 155 { 156 uint8_t ret_args_len = 0U; 157 sdm_response_t *resp = (sdm_response_t *)resp_desc; 158 sdm_command_t *cmd = (sdm_command_t *)cmd_desc; 159 160 INFO("MBOX: %s: [0] 0%x, [1] 0x%x, [2] 0x%x, len_words %d\n", 161 __func__, resp->resp_data[0], resp->resp_data[1], 162 resp->resp_data[2], resp->rcvd_resp_len); 163 164 ret_args[ret_args_len++] = INTEL_SIP_SMC_STATUS_OK; 165 ret_args[ret_args_len++] = resp->err_code; 166 ret_args[ret_args_len++] = resp->rcvd_resp_len * MBOX_WORD_BYTE; 167 168 /* Flush the response data buffer. */ 169 flush_dcache_range((uintptr_t)cmd->cb_args, resp->rcvd_resp_len * MBOX_WORD_BYTE); 170 171 return ret_args_len; 172 } 173 174 uint8_t fcs_cs_hash_sig_verify_req_cb(void *resp_desc, void *cmd_desc, uint64_t *ret_args) 175 { 176 uint8_t ret_args_len = 0U; 177 sdm_response_t *resp = (sdm_response_t *)resp_desc; 178 sdm_command_t *cmd = (sdm_command_t *)cmd_desc; 179 180 INFO("MBOX: %s: [0] 0%x, [1] 0x%x, [2] 0x%x, [3] 0x%x\n", 181 __func__, resp->resp_data[0], resp->resp_data[1], 182 resp->resp_data[2], resp->resp_data[3]); 183 184 ret_args[ret_args_len++] = INTEL_SIP_SMC_STATUS_OK; 185 ret_args[ret_args_len++] = resp->err_code; 186 ret_args[ret_args_len++] = resp->rcvd_resp_len * MBOX_WORD_BYTE; 187 188 /* Flush the response data buffer. */ 189 flush_dcache_range((uintptr_t)cmd->cb_args, resp->rcvd_resp_len * MBOX_WORD_BYTE); 190 191 return ret_args_len; 192 } 193 194 uint8_t fcs_cs_aes_cb(void *resp_desc, void *cmd_desc, uint64_t *ret_args) 195 { 196 uint8_t ret_args_len = 0U; 197 uint32_t nbytes_ret = 0U; 198 sdm_response_t *resp = (sdm_response_t *)resp_desc; 199 sdm_command_t *cmd = (sdm_command_t *)cmd_desc; 200 201 (void)cmd; 202 203 /* Data size written to the destination is always at last index of the response data. */ 204 nbytes_ret = resp->resp_data[resp->rcvd_resp_len - 1]; 205 206 INFO("MBOX: %s: mbox_err 0x%x, nbytes_ret %d\n", __func__, 207 resp->err_code, nbytes_ret); 208 209 ret_args[ret_args_len++] = INTEL_SIP_SMC_STATUS_OK; 210 ret_args[ret_args_len++] = resp->err_code; 211 ret_args[ret_args_len++] = nbytes_ret; 212 213 return ret_args_len; 214 } 215 216 uint8_t fcs_cs_data_sign_req_cb(void *resp_desc, void *cmd_desc, uint64_t *ret_args) 217 { 218 uint8_t ret_args_len = 0U; 219 sdm_response_t *resp = (sdm_response_t *)resp_desc; 220 sdm_command_t *cmd = (sdm_command_t *)cmd_desc; 221 222 INFO("MBOX: %s: mbox_err 0x%x, nbytes_ret %d\n", __func__, 223 resp->err_code, resp->rcvd_resp_len * MBOX_WORD_BYTE); 224 225 ret_args[ret_args_len++] = INTEL_SIP_SMC_STATUS_OK; 226 ret_args[ret_args_len++] = resp->err_code; 227 ret_args[ret_args_len++] = resp->rcvd_resp_len * MBOX_WORD_BYTE; 228 229 /* Flush the response data buffer. */ 230 flush_dcache_range((uintptr_t)cmd->cb_args, resp->rcvd_resp_len * MBOX_WORD_BYTE); 231 return ret_args_len; 232 } 233 234 uint8_t fcs_sdos_crypto_request_cb(void *resp_desc, void *cmd_desc, uint64_t *ret_args) 235 { 236 uint8_t ret_args_len = 0U; 237 sdm_response_t *resp = (sdm_response_t *)resp_desc; 238 sdm_command_t *cmd = (sdm_command_t *)cmd_desc; 239 240 (void)cmd; 241 INFO("MBOX: %s: mailbox_err 0x%x, nbytes_ret %d\n", 242 __func__, resp->err_code, resp->resp_data[3]); 243 244 ret_args[ret_args_len++] = INTEL_SIP_SMC_STATUS_OK; 245 ret_args[ret_args_len++] = resp->err_code; 246 /* Encrypted/Decrypted data size written to the destination buffer */ 247 ret_args[ret_args_len++] = resp->resp_data[3]; 248 249 return ret_args_len; 250 } 251 252 uint8_t fcs_cs_get_public_key_cb(void *resp_desc, void *cmd_desc, uint64_t *ret_args) 253 { 254 uint8_t ret_args_len = 0U; 255 sdm_response_t *resp = (sdm_response_t *)resp_desc; 256 sdm_command_t *cmd = (sdm_command_t *)cmd_desc; 257 258 INFO("MBOX: %s: mbox_err 0x%x, nbytes_ret %u\n", 259 __func__, resp->err_code, 260 resp->rcvd_resp_len * MBOX_WORD_BYTE); 261 262 ret_args[ret_args_len++] = INTEL_SIP_SMC_STATUS_OK; 263 ret_args[ret_args_len++] = resp->err_code; 264 ret_args[ret_args_len++] = resp->rcvd_resp_len * MBOX_WORD_BYTE; 265 266 /* Flush the response data buffer. */ 267 flush_dcache_range((uintptr_t)cmd->cb_args, resp->rcvd_resp_len * MBOX_WORD_BYTE); 268 269 return ret_args_len; 270 } 271 272 uint8_t fcs_cs_data_sig_verify_req_cb(void *resp_desc, void *cmd_desc, uint64_t *ret_args) 273 { 274 uint8_t ret_args_len = 0U; 275 sdm_response_t *resp = (sdm_response_t *)resp_desc; 276 sdm_command_t *cmd = (sdm_command_t *)cmd_desc; 277 278 INFO("MBOX: %s: mbox_err 0x%x, nbytes_ret 0x%x\n", 279 __func__, resp->err_code, resp->rcvd_resp_len); 280 281 ret_args[ret_args_len++] = INTEL_SIP_SMC_STATUS_OK; 282 ret_args[ret_args_len++] = resp->err_code; 283 ret_args[ret_args_len++] = resp->rcvd_resp_len * MBOX_WORD_BYTE; 284 285 /* Flush the response data buffer. */ 286 flush_dcache_range((uintptr_t)cmd->cb_args, resp->rcvd_resp_len * MBOX_WORD_BYTE); 287 288 return ret_args_len; 289 } 290 291 uint8_t fcs_cs_ecdh_request_cb(void *resp_desc, void *cmd_desc, uint64_t *ret_args) 292 { 293 uint8_t ret_args_len = 0U; 294 sdm_response_t *resp = (sdm_response_t *)resp_desc; 295 sdm_command_t *cmd = (sdm_command_t *)cmd_desc; 296 297 INFO("MBOX: %s: [0] 0%x, [1] 0x%x, [2] 0x%x, len_words %d\n", 298 __func__, resp->resp_data[0], resp->resp_data[1], 299 resp->resp_data[2], resp->rcvd_resp_len); 300 301 ret_args[ret_args_len++] = INTEL_SIP_SMC_STATUS_OK; 302 ret_args[ret_args_len++] = resp->err_code; 303 ret_args[ret_args_len++] = resp->rcvd_resp_len * MBOX_WORD_BYTE; 304 305 /* Flush the response data buffer. */ 306 flush_dcache_range((uintptr_t)cmd->cb_args, resp->rcvd_resp_len * MBOX_WORD_BYTE); 307 308 return ret_args_len; 309 } 310 311 static int intel_fcs_crypto_service_init(uint32_t session_id, 312 uint32_t context_id, uint32_t key_id, 313 uint32_t param_size, uint64_t param_data, 314 fcs_crypto_service_data *data_addr, 315 uint32_t *mbox_error) 316 { 317 if (mbox_error == NULL) { 318 return INTEL_SIP_SMC_STATUS_REJECTED; 319 } 320 321 if (param_size != 4) { 322 return INTEL_SIP_SMC_STATUS_REJECTED; 323 } 324 325 memset(data_addr, 0, sizeof(fcs_crypto_service_data)); 326 327 data_addr->session_id = session_id; 328 data_addr->context_id = context_id; 329 data_addr->key_id = key_id; 330 data_addr->crypto_param_size = param_size; 331 data_addr->crypto_param = param_data; 332 333 data_addr->is_updated = 0; 334 335 *mbox_error = 0; 336 337 return INTEL_SIP_SMC_STATUS_OK; 338 } 339 340 uint32_t intel_fcs_random_number_gen(uint64_t addr, uint64_t *ret_size, 341 uint32_t *mbox_error) 342 { 343 int status; 344 unsigned int i; 345 unsigned int resp_len = FCS_RANDOM_WORD_SIZE; 346 uint32_t random_data[FCS_RANDOM_WORD_SIZE] = {0U}; 347 348 if (!is_address_in_ddr_range(addr, FCS_RANDOM_BYTE_SIZE)) { 349 return INTEL_SIP_SMC_STATUS_REJECTED; 350 } 351 352 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_RANDOM_GEN, NULL, 0U, 353 CMD_CASUAL, random_data, &resp_len); 354 355 if (status < 0) { 356 *mbox_error = -status; 357 return INTEL_SIP_SMC_STATUS_ERROR; 358 } 359 360 if (resp_len != FCS_RANDOM_WORD_SIZE) { 361 *mbox_error = GENERIC_RESPONSE_ERROR; 362 return INTEL_SIP_SMC_STATUS_ERROR; 363 } 364 365 *ret_size = FCS_RANDOM_BYTE_SIZE; 366 367 for (i = 0U; i < FCS_RANDOM_WORD_SIZE; i++) { 368 mmio_write_32(addr, random_data[i]); 369 addr += MBOX_WORD_BYTE; 370 } 371 372 flush_dcache_range(addr - *ret_size, *ret_size); 373 374 return INTEL_SIP_SMC_STATUS_OK; 375 } 376 377 int intel_fcs_random_number_gen_ext(uint32_t session_id, uint32_t context_id, 378 uint32_t size, uint32_t *send_id) 379 { 380 int status; 381 uint32_t payload_size; 382 uint32_t crypto_header; 383 384 if (size > (FCS_RANDOM_EXT_MAX_WORD_SIZE * 385 MBOX_WORD_BYTE) || size == 0U) { 386 return INTEL_SIP_SMC_STATUS_REJECTED; 387 } 388 389 if (!is_size_4_bytes_aligned(size)) { 390 return INTEL_SIP_SMC_STATUS_REJECTED; 391 } 392 393 crypto_header = (FCS_CS_FIELD_FLAG_INIT | FCS_CS_FIELD_FLAG_FINALIZE) << 394 FCS_CS_FIELD_FLAG_OFFSET; 395 396 fcs_rng_payload payload = { 397 session_id, 398 context_id, 399 crypto_header, 400 size 401 }; 402 403 payload_size = sizeof(payload) / MBOX_WORD_BYTE; 404 405 status = mailbox_send_cmd_async(send_id, MBOX_FCS_RANDOM_GEN, 406 (uint32_t *) &payload, payload_size, 407 CMD_INDIRECT); 408 409 if (status < 0) { 410 return INTEL_SIP_SMC_STATUS_ERROR; 411 } 412 413 return INTEL_SIP_SMC_STATUS_OK; 414 } 415 416 uint32_t intel_fcs_send_cert(uint32_t smc_fid, uint32_t trans_id, 417 uint64_t addr, uint64_t size, 418 uint32_t *send_id) 419 { 420 int status; 421 422 if (!is_address_in_ddr_range(addr, size)) { 423 return INTEL_SIP_SMC_STATUS_REJECTED; 424 } 425 426 if (!is_size_4_bytes_aligned(size)) { 427 return INTEL_SIP_SMC_STATUS_REJECTED; 428 } 429 430 status = (smc_fid == ALTERA_SIP_SMC_ASYNC_FCS_SEND_CERTIFICATE) ? 431 mailbox_send_cmd_async_v3(GET_CLIENT_ID(trans_id), 432 GET_JOB_ID(trans_id), 433 MBOX_CMD_VAB_SRC_CERT, 434 (uint32_t *) addr, 435 size / MBOX_WORD_BYTE, 436 MBOX_CMD_FLAG_CASUAL, 437 fcs_send_cert_cb, 438 NULL, 439 0U) : 440 mailbox_send_cmd_async(send_id, MBOX_CMD_VAB_SRC_CERT, 441 (uint32_t *)addr, size / MBOX_WORD_BYTE, 442 CMD_DIRECT); 443 444 flush_dcache_range(addr, size); 445 446 if (status < 0) { 447 return INTEL_SIP_SMC_STATUS_ERROR; 448 } 449 450 return INTEL_SIP_SMC_STATUS_OK; 451 } 452 453 uint32_t intel_fcs_get_provision_data(uint32_t *send_id) 454 { 455 int status; 456 457 status = mailbox_send_cmd_async(send_id, MBOX_FCS_GET_PROVISION, 458 NULL, 0U, CMD_DIRECT); 459 460 if (status < 0) { 461 return INTEL_SIP_SMC_STATUS_ERROR; 462 } 463 464 return INTEL_SIP_SMC_STATUS_OK; 465 } 466 467 uint32_t intel_fcs_cntr_set_preauth(uint32_t smc_fid, uint32_t trans_id, 468 uint8_t counter_type, int32_t counter_value, 469 uint32_t test_bit, uint32_t *mbox_error) 470 { 471 int status; 472 uint32_t first_word; 473 uint32_t payload_size; 474 475 if ((test_bit != MBOX_TEST_BIT) && 476 (test_bit != 0)) { 477 return INTEL_SIP_SMC_STATUS_REJECTED; 478 } 479 480 if ((counter_type < FCS_BIG_CNTR_SEL) || 481 (counter_type > FCS_SVN_CNTR_3_SEL)) { 482 return INTEL_SIP_SMC_STATUS_REJECTED; 483 } 484 485 if ((counter_type == FCS_BIG_CNTR_SEL) && 486 (counter_value > FCS_BIG_CNTR_VAL_MAX)) { 487 return INTEL_SIP_SMC_STATUS_REJECTED; 488 } 489 490 if ((counter_type >= FCS_SVN_CNTR_0_SEL) && 491 (counter_type <= FCS_SVN_CNTR_3_SEL) && 492 (counter_value > FCS_SVN_CNTR_VAL_MAX)) { 493 return INTEL_SIP_SMC_STATUS_REJECTED; 494 } 495 496 first_word = test_bit | counter_type; 497 fcs_cntr_set_preauth_payload payload = { 498 first_word, 499 counter_value 500 }; 501 502 payload_size = sizeof(payload) / MBOX_WORD_BYTE; 503 504 status = (smc_fid == ALTERA_SIP_SMC_ASYNC_FCS_CNTR_SET_PREAUTH) ? 505 mailbox_send_cmd_async_v3(GET_CLIENT_ID(trans_id), 506 GET_JOB_ID(trans_id), 507 MBOX_FCS_CNTR_SET_PREAUTH, 508 (uint32_t *) &payload, 509 payload_size, 510 MBOX_CMD_FLAG_CASUAL, 511 fcs_cntr_set_preauth_cb, 512 NULL, 513 0U) : 514 mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_CNTR_SET_PREAUTH, 515 (uint32_t *) &payload, payload_size, 516 CMD_CASUAL, NULL, NULL); 517 518 if (status < 0) { 519 *mbox_error = -status; 520 return INTEL_SIP_SMC_STATUS_ERROR; 521 } 522 523 return INTEL_SIP_SMC_STATUS_OK; 524 } 525 526 uint32_t intel_fcs_encryption(uint32_t src_addr, uint32_t src_size, 527 uint32_t dst_addr, uint32_t dst_size, uint32_t *send_id) 528 { 529 int status; 530 uint32_t load_size; 531 532 if (!is_address_in_ddr_range(src_addr, src_size) || 533 !is_address_in_ddr_range(dst_addr, dst_size)) { 534 return INTEL_SIP_SMC_STATUS_REJECTED; 535 } 536 537 if (!is_size_4_bytes_aligned(src_size)) { 538 return INTEL_SIP_SMC_STATUS_REJECTED; 539 } 540 541 fcs_encrypt_payload payload = { 542 FCS_ENCRYPTION_DATA_0, 543 src_addr, 544 src_size, 545 dst_addr, 546 dst_size }; 547 load_size = sizeof(payload) / MBOX_WORD_BYTE; 548 549 status = mailbox_send_cmd_async(send_id, MBOX_FCS_ENCRYPT_REQ, 550 (uint32_t *) &payload, load_size, 551 CMD_INDIRECT); 552 inv_dcache_range(dst_addr, dst_size); 553 554 if (status < 0) { 555 return INTEL_SIP_SMC_STATUS_REJECTED; 556 } 557 558 return INTEL_SIP_SMC_STATUS_OK; 559 } 560 561 uint32_t intel_fcs_decryption(uint32_t src_addr, uint32_t src_size, 562 uint32_t dst_addr, uint32_t dst_size, uint32_t *send_id) 563 { 564 int status; 565 uint32_t load_size; 566 uintptr_t id_offset; 567 568 if (!is_address_in_ddr_range(src_addr, src_size) || 569 !is_address_in_ddr_range(dst_addr, dst_size)) { 570 return INTEL_SIP_SMC_STATUS_REJECTED; 571 } 572 573 if (!is_size_4_bytes_aligned(src_size)) { 574 return INTEL_SIP_SMC_STATUS_REJECTED; 575 } 576 577 inv_dcache_range(src_addr, src_size); /* flush cache before mmio read to avoid reading old values */ 578 id_offset = src_addr + FCS_OWNER_ID_OFFSET; 579 fcs_decrypt_payload payload = { 580 FCS_DECRYPTION_DATA_0, 581 {mmio_read_32(id_offset), 582 mmio_read_32(id_offset + MBOX_WORD_BYTE)}, 583 src_addr, 584 src_size, 585 dst_addr, 586 dst_size }; 587 load_size = sizeof(payload) / MBOX_WORD_BYTE; 588 589 status = mailbox_send_cmd_async(send_id, MBOX_FCS_DECRYPT_REQ, 590 (uint32_t *) &payload, load_size, 591 CMD_INDIRECT); 592 inv_dcache_range(dst_addr, dst_size); 593 594 if (status < 0) { 595 return INTEL_SIP_SMC_STATUS_REJECTED; 596 } 597 598 return INTEL_SIP_SMC_STATUS_OK; 599 } 600 601 int intel_fcs_encryption_ext(uint32_t smc_fid, uint32_t trans_id, 602 uint32_t session_id, uint32_t context_id, 603 uint32_t src_addr, uint32_t src_size, 604 uint32_t dst_addr, uint32_t *dst_size, uint32_t *mbox_error, 605 uint32_t smmu_src_addr, uint32_t smmu_dst_addr) 606 { 607 int status; 608 uint32_t payload_size; 609 uint32_t resp_len = FCS_CRYPTION_RESP_WORD_SIZE; 610 uint32_t resp_data[FCS_CRYPTION_RESP_WORD_SIZE] = {0U}; 611 uint32_t src_addr_sdm = src_addr; 612 uint32_t dst_addr_sdm = dst_addr; 613 614 if ((dst_size == NULL) || (mbox_error == NULL)) { 615 return INTEL_SIP_SMC_STATUS_REJECTED; 616 } 617 618 if (!is_address_in_ddr_range(src_addr, src_size) || 619 !is_address_in_ddr_range(dst_addr, *dst_size)) { 620 return INTEL_SIP_SMC_STATUS_REJECTED; 621 } 622 623 if (!is_size_4_bytes_aligned(src_size)) { 624 return INTEL_SIP_SMC_STATUS_REJECTED; 625 } 626 627 /* On the Agilex5 platform, we will use the SMMU payload address */ 628 #if PLATFORM_MODEL == PLAT_SOCFPGA_AGILEX5 629 src_addr_sdm = smmu_src_addr; 630 dst_addr_sdm = smmu_dst_addr; 631 #endif 632 633 fcs_encrypt_ext_payload payload = { 634 session_id, 635 context_id, 636 FCS_CRYPTION_CRYPTO_HEADER, 637 src_addr_sdm, 638 src_size, 639 dst_addr_sdm, 640 *dst_size 641 }; 642 643 payload_size = sizeof(payload) / MBOX_WORD_BYTE; 644 645 status = (smc_fid == ALTERA_SIP_SMC_ASYNC_FCS_CRYPTION_EXT) ? 646 mailbox_send_cmd_async_v3(GET_CLIENT_ID(trans_id), 647 GET_JOB_ID(trans_id), 648 MBOX_FCS_ENCRYPT_REQ, 649 (uint32_t *) &payload, 650 payload_size, 651 MBOX_CMD_FLAG_INDIRECT, 652 fcs_sdos_crypto_request_cb, 653 NULL, 654 0U) : 655 mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_ENCRYPT_REQ, 656 (uint32_t *) &payload, payload_size, 657 CMD_CASUAL, resp_data, &resp_len); 658 659 if (status < 0) { 660 *mbox_error = -status; 661 return INTEL_SIP_SMC_STATUS_ERROR; 662 } 663 664 if (resp_len != FCS_CRYPTION_RESP_WORD_SIZE) { 665 *mbox_error = MBOX_RET_ERROR; 666 return INTEL_SIP_SMC_STATUS_ERROR; 667 } 668 669 *dst_size = resp_data[FCS_CRYPTION_RESP_SIZE_OFFSET]; 670 inv_dcache_range(dst_addr, *dst_size); 671 672 return INTEL_SIP_SMC_STATUS_OK; 673 } 674 675 int intel_fcs_decryption_ext(uint32_t smc_fid, uint32_t trans_id, 676 uint32_t session_id, uint32_t context_id, 677 uint32_t src_addr, uint32_t src_size, 678 uint32_t dst_addr, uint32_t *dst_size, 679 uint32_t *mbox_error, uint64_t owner_id, 680 uint32_t smmu_src_addr, uint32_t smmu_dst_addr) 681 { 682 int status; 683 uintptr_t id_offset; 684 uint32_t payload_size; 685 uint32_t resp_len = FCS_CRYPTION_RESP_WORD_SIZE; 686 uint32_t resp_data[FCS_CRYPTION_RESP_WORD_SIZE] = {0U}; 687 uint32_t src_addr_sdm = src_addr; 688 uint32_t dst_addr_sdm = dst_addr; 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(src_addr, src_size) || 695 !is_address_in_ddr_range(dst_addr, *dst_size)) { 696 return INTEL_SIP_SMC_STATUS_REJECTED; 697 } 698 699 if (!is_size_4_bytes_aligned(src_size)) { 700 return INTEL_SIP_SMC_STATUS_REJECTED; 701 } 702 703 /* On the Agilex5 platform, we will use the SMMU payload address */ 704 #if PLATFORM_MODEL == PLAT_SOCFPGA_AGILEX5 705 src_addr_sdm = smmu_src_addr; 706 dst_addr_sdm = smmu_dst_addr; 707 #endif 708 709 inv_dcache_range(src_addr, src_size); /* flush cache before mmio read to avoid reading old values */ 710 id_offset = src_addr + FCS_OWNER_ID_OFFSET; 711 fcs_decrypt_ext_payload payload = { 712 session_id, 713 context_id, 714 FCS_CRYPTION_CRYPTO_HEADER, 715 {mmio_read_32(id_offset), 716 mmio_read_32(id_offset + MBOX_WORD_BYTE)}, 717 src_addr_sdm, 718 src_size, 719 dst_addr_sdm, 720 *dst_size 721 }; 722 723 payload_size = sizeof(payload) / MBOX_WORD_BYTE; 724 725 status = (smc_fid == ALTERA_SIP_SMC_ASYNC_FCS_CRYPTION_EXT) ? 726 mailbox_send_cmd_async_v3(GET_CLIENT_ID(trans_id), 727 GET_JOB_ID(trans_id), 728 MBOX_FCS_DECRYPT_REQ, 729 (uint32_t *) &payload, 730 payload_size, 731 MBOX_CMD_FLAG_INDIRECT, 732 fcs_sdos_crypto_request_cb, 733 NULL, 734 0U) : 735 mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_DECRYPT_REQ, 736 (uint32_t *) &payload, payload_size, 737 CMD_CASUAL, resp_data, &resp_len); 738 739 if (status == MBOX_RET_SDOS_DECRYPTION_ERROR_102 || 740 status == MBOX_RET_SDOS_DECRYPTION_ERROR_103) { 741 *mbox_error = -status; 742 } else if (status < 0) { 743 *mbox_error = -status; 744 return INTEL_SIP_SMC_STATUS_ERROR; 745 } 746 747 if (resp_len != FCS_CRYPTION_RESP_WORD_SIZE) { 748 *mbox_error = MBOX_RET_ERROR; 749 return INTEL_SIP_SMC_STATUS_ERROR; 750 } 751 752 *dst_size = resp_data[FCS_CRYPTION_RESP_SIZE_OFFSET]; 753 inv_dcache_range(dst_addr, *dst_size); 754 755 return INTEL_SIP_SMC_STATUS_OK; 756 } 757 758 int intel_fcs_sigma_teardown(uint32_t session_id, uint32_t *mbox_error) 759 { 760 int status; 761 762 if ((session_id != PSGSIGMA_SESSION_ID_ONE) && 763 (session_id != PSGSIGMA_UNKNOWN_SESSION)) { 764 return INTEL_SIP_SMC_STATUS_REJECTED; 765 } 766 767 psgsigma_teardown_msg message = { 768 RESERVED_AS_ZERO, 769 PSGSIGMA_TEARDOWN_MAGIC, 770 session_id 771 }; 772 773 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_PSG_SIGMA_TEARDOWN, 774 (uint32_t *) &message, sizeof(message) / MBOX_WORD_BYTE, 775 CMD_CASUAL, NULL, NULL); 776 777 if (status < 0) { 778 *mbox_error = -status; 779 return INTEL_SIP_SMC_STATUS_ERROR; 780 } 781 782 return INTEL_SIP_SMC_STATUS_OK; 783 } 784 785 int intel_fcs_chip_id(uint32_t *id_low, uint32_t *id_high, uint32_t *mbox_error) 786 { 787 int status; 788 uint32_t load_size; 789 uint32_t chip_id[2]; 790 791 load_size = sizeof(chip_id) / MBOX_WORD_BYTE; 792 793 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_CMD_GET_CHIPID, NULL, 794 0U, CMD_CASUAL, (uint32_t *) chip_id, &load_size); 795 796 if (status < 0) { 797 *mbox_error = -status; 798 return INTEL_SIP_SMC_STATUS_ERROR; 799 } 800 801 *id_low = chip_id[0]; 802 *id_high = chip_id[1]; 803 804 return INTEL_SIP_SMC_STATUS_OK; 805 } 806 807 int intel_fcs_attestation_subkey(uint64_t src_addr, uint32_t src_size, 808 uint64_t dst_addr, uint32_t *dst_size, uint32_t *mbox_error) 809 { 810 int status; 811 uint32_t send_size = src_size / MBOX_WORD_BYTE; 812 uint32_t ret_size = *dst_size / MBOX_WORD_BYTE; 813 814 815 if (!is_address_in_ddr_range(src_addr, src_size) || 816 !is_address_in_ddr_range(dst_addr, *dst_size)) { 817 return INTEL_SIP_SMC_STATUS_REJECTED; 818 } 819 820 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_ATTESTATION_SUBKEY, 821 (uint32_t *) src_addr, send_size, CMD_CASUAL, 822 (uint32_t *) dst_addr, &ret_size); 823 824 if (status < 0) { 825 *mbox_error = -status; 826 return INTEL_SIP_SMC_STATUS_ERROR; 827 } 828 829 *dst_size = ret_size * MBOX_WORD_BYTE; 830 flush_dcache_range(dst_addr, *dst_size); 831 832 return INTEL_SIP_SMC_STATUS_OK; 833 } 834 835 int intel_fcs_get_measurement(uint64_t src_addr, uint32_t src_size, 836 uint64_t dst_addr, uint32_t *dst_size, uint32_t *mbox_error) 837 { 838 int status; 839 uint32_t send_size = src_size / MBOX_WORD_BYTE; 840 uint32_t ret_size = *dst_size / MBOX_WORD_BYTE; 841 842 if (!is_address_in_ddr_range(src_addr, src_size) || 843 !is_address_in_ddr_range(dst_addr, *dst_size)) { 844 return INTEL_SIP_SMC_STATUS_REJECTED; 845 } 846 847 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_GET_MEASUREMENT, 848 (uint32_t *) src_addr, send_size, CMD_CASUAL, 849 (uint32_t *) dst_addr, &ret_size); 850 851 if (status < 0) { 852 *mbox_error = -status; 853 return INTEL_SIP_SMC_STATUS_ERROR; 854 } 855 856 *dst_size = ret_size * MBOX_WORD_BYTE; 857 flush_dcache_range(dst_addr, *dst_size); 858 859 return INTEL_SIP_SMC_STATUS_OK; 860 } 861 862 uint32_t intel_fcs_get_rom_patch_sha384(uint64_t addr, uint64_t *ret_size, 863 uint32_t *mbox_error) 864 { 865 int status; 866 unsigned int resp_len = FCS_SHA384_WORD_SIZE; 867 868 if (!is_address_in_ddr_range(addr, FCS_SHA384_BYTE_SIZE)) { 869 return INTEL_SIP_SMC_STATUS_REJECTED; 870 } 871 872 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_GET_ROM_PATCH_SHA384, NULL, 0U, 873 CMD_CASUAL, (uint32_t *) addr, &resp_len); 874 875 if (status < 0) { 876 *mbox_error = -status; 877 return INTEL_SIP_SMC_STATUS_ERROR; 878 } 879 880 if (resp_len != FCS_SHA384_WORD_SIZE) { 881 *mbox_error = GENERIC_RESPONSE_ERROR; 882 return INTEL_SIP_SMC_STATUS_ERROR; 883 } 884 885 *ret_size = FCS_SHA384_BYTE_SIZE; 886 887 flush_dcache_range(addr, *ret_size); 888 889 return INTEL_SIP_SMC_STATUS_OK; 890 } 891 892 int intel_fcs_get_attestation_cert(uint32_t smc_fid, uint32_t trans_id, 893 uint32_t cert_request, uint64_t dst_addr, 894 uint32_t *dst_size, uint32_t *mbox_error) 895 { 896 int status; 897 uint32_t ret_size = *dst_size / MBOX_WORD_BYTE; 898 899 if (mbox_error == NULL) { 900 return INTEL_SIP_SMC_STATUS_REJECTED; 901 } 902 903 if (cert_request < FCS_ATTEST_FIRMWARE_CERT || 904 cert_request > FCS_ATTEST_CERT_MAX_REQ_PARAM) { 905 return INTEL_SIP_SMC_STATUS_REJECTED; 906 } 907 908 if (!is_address_in_ddr_range(dst_addr, *dst_size)) { 909 return INTEL_SIP_SMC_STATUS_REJECTED; 910 } 911 912 status = (smc_fid == ALTERA_SIP_SMC_ASYNC_FCS_GET_ATTESTATION_CERT) ? 913 mailbox_send_cmd_async_v3(GET_CLIENT_ID(trans_id), 914 GET_JOB_ID(trans_id), 915 MBOX_GET_ATTESTATION_CERT, 916 (uint32_t *) &cert_request, 917 1U, 918 MBOX_CMD_FLAG_CASUAL, 919 fcs_get_attest_cert_cb, 920 (uint32_t *)dst_addr, 921 2U) : 922 mailbox_send_cmd(MBOX_JOB_ID, MBOX_GET_ATTESTATION_CERT, 923 (uint32_t *) &cert_request, 1U, CMD_CASUAL, 924 (uint32_t *) dst_addr, &ret_size); 925 926 if (status < 0) { 927 *mbox_error = -status; 928 return INTEL_SIP_SMC_STATUS_ERROR; 929 } 930 931 *dst_size = ret_size * MBOX_WORD_BYTE; 932 flush_dcache_range(dst_addr, *dst_size); 933 934 return INTEL_SIP_SMC_STATUS_OK; 935 } 936 937 int intel_fcs_create_cert_on_reload(uint32_t smc_fid, uint32_t trans_id, 938 uint32_t cert_request, uint32_t *mbox_error) 939 { 940 int status; 941 942 if (mbox_error == NULL) { 943 return INTEL_SIP_SMC_STATUS_REJECTED; 944 } 945 946 if (cert_request < FCS_ATTEST_FIRMWARE_CERT || 947 cert_request > FCS_ATTEST_CERT_MAX_REQ_PARAM) { 948 return INTEL_SIP_SMC_STATUS_REJECTED; 949 } 950 951 status = (smc_fid == ALTERA_SIP_SMC_ASYNC_FCS_CREATE_CERT_ON_RELOAD) ? 952 mailbox_send_cmd_async_v3(GET_CLIENT_ID(trans_id), 953 GET_JOB_ID(trans_id), 954 MBOX_CREATE_CERT_ON_RELOAD, 955 (uint32_t *) &cert_request, 956 1U, 957 MBOX_CMD_FLAG_CASUAL, 958 fcs_create_cert_reload_cb, 959 NULL, 960 0U) : 961 mailbox_send_cmd(MBOX_JOB_ID, MBOX_CREATE_CERT_ON_RELOAD, 962 (uint32_t *) &cert_request, 1U, CMD_CASUAL, 963 NULL, NULL); 964 965 if (status < 0) { 966 *mbox_error = -status; 967 return INTEL_SIP_SMC_STATUS_ERROR; 968 } 969 970 return INTEL_SIP_SMC_STATUS_OK; 971 } 972 973 int intel_fcs_open_crypto_service_session(uint32_t *session_id, 974 uint32_t *mbox_error) 975 { 976 int status; 977 uint32_t resp_len = 1U; 978 979 if ((session_id == NULL) || (mbox_error == NULL)) { 980 return INTEL_SIP_SMC_STATUS_REJECTED; 981 } 982 983 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_OPEN_CS_SESSION, 984 NULL, 0U, CMD_CASUAL, session_id, &resp_len); 985 986 if (status < 0) { 987 *mbox_error = -status; 988 return INTEL_SIP_SMC_STATUS_ERROR; 989 } 990 991 return INTEL_SIP_SMC_STATUS_OK; 992 } 993 994 int intel_fcs_close_crypto_service_session(uint32_t session_id, 995 uint32_t *mbox_error) 996 { 997 int status; 998 999 if (mbox_error == NULL) { 1000 return INTEL_SIP_SMC_STATUS_REJECTED; 1001 } 1002 1003 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_CLOSE_CS_SESSION, 1004 &session_id, 1U, CMD_CASUAL, NULL, NULL); 1005 1006 if (status < 0) { 1007 *mbox_error = -status; 1008 return INTEL_SIP_SMC_STATUS_ERROR; 1009 } 1010 1011 return INTEL_SIP_SMC_STATUS_OK; 1012 } 1013 1014 int intel_fcs_import_crypto_service_key(uint64_t src_addr, uint32_t src_size, 1015 uint32_t *send_id) 1016 { 1017 int status; 1018 1019 if (src_size > (FCS_CS_KEY_OBJ_MAX_WORD_SIZE * 1020 MBOX_WORD_BYTE)) { 1021 return INTEL_SIP_SMC_STATUS_REJECTED; 1022 } 1023 1024 if (!is_address_in_ddr_range(src_addr, src_size)) { 1025 return INTEL_SIP_SMC_STATUS_REJECTED; 1026 } 1027 1028 status = mailbox_send_cmd_async(send_id, MBOX_FCS_IMPORT_CS_KEY, 1029 (uint32_t *)src_addr, src_size / MBOX_WORD_BYTE, 1030 CMD_INDIRECT); 1031 1032 if (status < 0) { 1033 return INTEL_SIP_SMC_STATUS_ERROR; 1034 } 1035 1036 return INTEL_SIP_SMC_STATUS_OK; 1037 } 1038 1039 int intel_fcs_export_crypto_service_key(uint32_t session_id, uint32_t key_id, 1040 uint64_t dst_addr, uint32_t *dst_size, 1041 uint32_t *mbox_error) 1042 { 1043 int status; 1044 uint32_t i; 1045 uint32_t payload_size; 1046 uint32_t resp_len = FCS_CS_KEY_OBJ_MAX_WORD_SIZE; 1047 uint32_t resp_data[FCS_CS_KEY_OBJ_MAX_WORD_SIZE] = {0U}; 1048 uint32_t op_status = 0U; 1049 1050 if ((dst_size == NULL) || (mbox_error == NULL)) { 1051 return INTEL_SIP_SMC_STATUS_REJECTED; 1052 } 1053 1054 if (!is_address_in_ddr_range(dst_addr, *dst_size)) { 1055 return INTEL_SIP_SMC_STATUS_REJECTED; 1056 } 1057 1058 fcs_cs_key_payload payload = { 1059 session_id, 1060 RESERVED_AS_ZERO, 1061 RESERVED_AS_ZERO, 1062 key_id 1063 }; 1064 1065 payload_size = sizeof(payload) / MBOX_WORD_BYTE; 1066 1067 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_EXPORT_CS_KEY, 1068 (uint32_t *) &payload, payload_size, 1069 CMD_CASUAL, resp_data, &resp_len); 1070 1071 if (resp_len > 0) { 1072 op_status = resp_data[0] & FCS_CS_KEY_RESP_STATUS_MASK; 1073 } 1074 1075 if (status < 0) { 1076 *mbox_error = (-status) | (op_status << FCS_CS_KEY_RESP_STATUS_OFFSET); 1077 return INTEL_SIP_SMC_STATUS_ERROR; 1078 } 1079 1080 if (resp_len > 1) { 1081 1082 /* Export key object is start at second response data */ 1083 *dst_size = (resp_len - 1) * MBOX_WORD_BYTE; 1084 1085 for (i = 1U; i < resp_len; i++) { 1086 mmio_write_32(dst_addr, resp_data[i]); 1087 dst_addr += MBOX_WORD_BYTE; 1088 } 1089 1090 flush_dcache_range(dst_addr - *dst_size, *dst_size); 1091 1092 } else { 1093 1094 /* Unexpected response, missing key object in response */ 1095 *mbox_error = MBOX_RET_ERROR; 1096 return INTEL_SIP_SMC_STATUS_ERROR; 1097 } 1098 1099 return INTEL_SIP_SMC_STATUS_OK; 1100 } 1101 1102 int intel_fcs_remove_crypto_service_key(uint32_t session_id, uint32_t key_id, 1103 uint32_t *mbox_error) 1104 { 1105 int status; 1106 uint32_t payload_size; 1107 uint32_t resp_len = 1U; 1108 uint32_t resp_data = 0U; 1109 uint32_t op_status = 0U; 1110 1111 if (mbox_error == NULL) { 1112 return INTEL_SIP_SMC_STATUS_REJECTED; 1113 } 1114 1115 fcs_cs_key_payload payload = { 1116 session_id, 1117 RESERVED_AS_ZERO, 1118 RESERVED_AS_ZERO, 1119 key_id 1120 }; 1121 1122 payload_size = sizeof(payload) / MBOX_WORD_BYTE; 1123 1124 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_REMOVE_CS_KEY, 1125 (uint32_t *) &payload, payload_size, 1126 CMD_CASUAL, &resp_data, &resp_len); 1127 1128 if (resp_len > 0) { 1129 op_status = resp_data & FCS_CS_KEY_RESP_STATUS_MASK; 1130 } 1131 1132 if (status < 0) { 1133 *mbox_error = (-status) | (op_status << FCS_CS_KEY_RESP_STATUS_OFFSET); 1134 return INTEL_SIP_SMC_STATUS_ERROR; 1135 } 1136 1137 return INTEL_SIP_SMC_STATUS_OK; 1138 } 1139 1140 int intel_fcs_get_crypto_service_key_info(uint32_t session_id, uint32_t key_id, 1141 uint64_t dst_addr, uint32_t *dst_size, 1142 uint32_t *mbox_error) 1143 { 1144 int status; 1145 uint32_t payload_size; 1146 uint32_t resp_len = FCS_CS_KEY_INFO_MAX_WORD_SIZE; 1147 uint32_t op_status = 0U; 1148 1149 if ((dst_size == NULL) || (mbox_error == NULL)) { 1150 return INTEL_SIP_SMC_STATUS_REJECTED; 1151 } 1152 1153 if (!is_address_in_ddr_range(dst_addr, *dst_size)) { 1154 return INTEL_SIP_SMC_STATUS_REJECTED; 1155 } 1156 1157 fcs_cs_key_payload payload = { 1158 session_id, 1159 RESERVED_AS_ZERO, 1160 RESERVED_AS_ZERO, 1161 key_id 1162 }; 1163 1164 payload_size = sizeof(payload) / MBOX_WORD_BYTE; 1165 1166 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_GET_CS_KEY_INFO, 1167 (uint32_t *) &payload, payload_size, 1168 CMD_CASUAL, (uint32_t *) dst_addr, &resp_len); 1169 1170 if (resp_len > 0) { 1171 inv_dcache_range(dst_addr, (resp_len * MBOX_WORD_BYTE)); /* flush cache before mmio read to avoid reading old values */ 1172 op_status = mmio_read_32(dst_addr) & 1173 FCS_CS_KEY_RESP_STATUS_MASK; 1174 } 1175 1176 if (status < 0) { 1177 *mbox_error = (-status) | (op_status << FCS_CS_KEY_RESP_STATUS_OFFSET); 1178 return INTEL_SIP_SMC_STATUS_ERROR; 1179 } 1180 1181 *dst_size = resp_len * MBOX_WORD_BYTE; 1182 flush_dcache_range(dst_addr, *dst_size); 1183 1184 return INTEL_SIP_SMC_STATUS_OK; 1185 } 1186 1187 int intel_fcs_get_digest_init(uint32_t session_id, uint32_t context_id, 1188 uint32_t key_id, uint32_t param_size, 1189 uint64_t param_data, uint32_t *mbox_error) 1190 { 1191 return intel_fcs_crypto_service_init(session_id, context_id, 1192 key_id, param_size, param_data, 1193 (void *) &fcs_sha_get_digest_param, 1194 mbox_error); 1195 } 1196 1197 int intel_fcs_get_digest_update_finalize(uint32_t smc_fid, uint32_t trans_id, 1198 uint32_t session_id, uint32_t context_id, 1199 uint32_t src_addr, uint32_t src_size, 1200 uint64_t dst_addr, uint32_t *dst_size, 1201 uint8_t is_finalised, uint32_t *mbox_error, 1202 uint32_t smmu_src_addr) 1203 { 1204 int status; 1205 uint32_t i; 1206 uint32_t flag; 1207 uint32_t crypto_header; 1208 uint32_t resp_len; 1209 uint32_t payload[FCS_GET_DIGEST_CMD_MAX_WORD_SIZE] = {0U}; 1210 1211 if (dst_size == NULL || mbox_error == NULL) { 1212 return INTEL_SIP_SMC_STATUS_REJECTED; 1213 } 1214 1215 if (fcs_sha_get_digest_param.session_id != session_id || 1216 fcs_sha_get_digest_param.context_id != context_id) { 1217 return INTEL_SIP_SMC_STATUS_REJECTED; 1218 } 1219 1220 /* Source data must be 8 bytes aligned */ 1221 if (!is_8_bytes_aligned(src_size)) { 1222 return INTEL_SIP_SMC_STATUS_REJECTED; 1223 } 1224 1225 if (!is_address_in_ddr_range(src_addr, src_size) || 1226 !is_address_in_ddr_range(dst_addr, *dst_size)) { 1227 return INTEL_SIP_SMC_STATUS_REJECTED; 1228 } 1229 1230 resp_len = *dst_size / MBOX_WORD_BYTE; 1231 1232 /* Prepare crypto header */ 1233 flag = 0; 1234 1235 if (fcs_sha_get_digest_param.is_updated) { 1236 fcs_sha_get_digest_param.crypto_param_size = 0; 1237 } else { 1238 flag |= FCS_CS_FIELD_FLAG_INIT; 1239 } 1240 1241 if (is_finalised != 0U) { 1242 flag |= FCS_CS_FIELD_FLAG_FINALIZE; 1243 } else { 1244 flag |= FCS_CS_FIELD_FLAG_UPDATE; 1245 fcs_sha_get_digest_param.is_updated = 1; 1246 } 1247 1248 crypto_header = ((flag << FCS_CS_FIELD_FLAG_OFFSET) | 1249 (fcs_sha_get_digest_param.crypto_param_size & 1250 FCS_CS_FIELD_SIZE_MASK)); 1251 1252 /* Prepare command payload */ 1253 i = 0; 1254 payload[i] = fcs_sha_get_digest_param.session_id; 1255 i++; 1256 payload[i] = fcs_sha_get_digest_param.context_id; 1257 i++; 1258 payload[i] = crypto_header; 1259 i++; 1260 1261 if ((crypto_header >> FCS_CS_FIELD_FLAG_OFFSET) & 1262 FCS_CS_FIELD_FLAG_INIT) { 1263 payload[i] = fcs_sha_get_digest_param.key_id; 1264 i++; 1265 /* Crypto parameters */ 1266 payload[i] = fcs_sha_get_digest_param.crypto_param 1267 & INTEL_SIP_SMC_FCS_SHA_MODE_MASK; 1268 payload[i] |= ((fcs_sha_get_digest_param.crypto_param 1269 >> INTEL_SIP_SMC_FCS_DIGEST_SIZE_OFFSET) 1270 & INTEL_SIP_SMC_FCS_DIGEST_SIZE_MASK) 1271 << FCS_SHA_HMAC_CRYPTO_PARAM_SIZE_OFFSET; 1272 i++; 1273 } 1274 /* Data source address and size */ 1275 1276 /* On the Agilex5 platform, we will use the SMMU payload address */ 1277 #if PLATFORM_MODEL == PLAT_SOCFPGA_AGILEX5 1278 payload[i] = smmu_src_addr; 1279 #else 1280 payload[i] = src_addr; 1281 #endif 1282 i++; 1283 payload[i] = src_size; 1284 i++; 1285 1286 status = ((smc_fid == ALTERA_SIP_SMC_ASYNC_FCS_GET_DIGEST_UPDATE) || 1287 (smc_fid == ALTERA_SIP_SMC_ASYNC_FCS_GET_DIGEST_FINALIZE)) ? 1288 mailbox_send_cmd_async_v3(GET_CLIENT_ID(trans_id), 1289 GET_JOB_ID(trans_id), 1290 MBOX_FCS_GET_DIGEST_REQ, 1291 payload, 1292 i, 1293 MBOX_CMD_FLAG_CASUAL, 1294 fcs_cs_get_digest_cb, 1295 (uint32_t *)dst_addr, 1296 2U) : 1297 mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_GET_DIGEST_REQ, 1298 payload, i, CMD_CASUAL, 1299 (uint32_t *) dst_addr, &resp_len); 1300 1301 if (is_finalised != 0U) { 1302 memset((void *)&fcs_sha_get_digest_param, 0, 1303 sizeof(fcs_crypto_service_data)); 1304 } 1305 1306 if (status < 0) { 1307 *mbox_error = -status; 1308 return INTEL_SIP_SMC_STATUS_ERROR; 1309 } 1310 1311 *dst_size = resp_len * MBOX_WORD_BYTE; 1312 flush_dcache_range(dst_addr, *dst_size); 1313 1314 return INTEL_SIP_SMC_STATUS_OK; 1315 } 1316 1317 int intel_fcs_get_digest_smmu_update_finalize(uint32_t session_id, 1318 uint32_t context_id, uint32_t src_addr, 1319 uint32_t src_size, uint64_t dst_addr, 1320 uint32_t *dst_size, uint8_t is_finalised, 1321 uint32_t *mbox_error, uint32_t *send_id) 1322 { 1323 int status; 1324 uint32_t i; 1325 uint32_t flag; 1326 uint32_t crypto_header; 1327 uint32_t resp_len; 1328 uint32_t payload[FCS_GET_DIGEST_CMD_MAX_WORD_SIZE] = {0U}; 1329 1330 /* Source data must be 8 bytes aligned */ 1331 if (dst_size == NULL || mbox_error == NULL || 1332 !is_8_bytes_aligned(src_size)) { 1333 return INTEL_SIP_SMC_STATUS_REJECTED; 1334 } 1335 1336 if (fcs_sha_get_digest_param.session_id != session_id || 1337 fcs_sha_get_digest_param.context_id != context_id) { 1338 return INTEL_SIP_SMC_STATUS_REJECTED; 1339 } 1340 1341 if (!is_address_in_ddr_range(src_addr, src_size) || 1342 !is_address_in_ddr_range(dst_addr, *dst_size)) { 1343 return INTEL_SIP_SMC_STATUS_REJECTED; 1344 } 1345 1346 resp_len = *dst_size / MBOX_WORD_BYTE; 1347 1348 /* Prepare crypto header */ 1349 flag = 0; 1350 1351 if (fcs_sha_get_digest_param.is_updated) { 1352 fcs_sha_get_digest_param.crypto_param_size = 0; 1353 } else { 1354 flag |= FCS_CS_FIELD_FLAG_INIT; 1355 } 1356 1357 if (is_finalised != 0U) { 1358 flag |= FCS_CS_FIELD_FLAG_FINALIZE; 1359 } else { 1360 flag |= FCS_CS_FIELD_FLAG_UPDATE; 1361 fcs_sha_get_digest_param.is_updated = 1; 1362 } 1363 1364 crypto_header = ((flag << FCS_CS_FIELD_FLAG_OFFSET) | 1365 (fcs_sha_get_digest_param.crypto_param_size & 1366 FCS_CS_FIELD_SIZE_MASK)); 1367 1368 /* Prepare command payload */ 1369 i = 0; 1370 payload[i] = fcs_sha_get_digest_param.session_id; 1371 i++; 1372 payload[i] = fcs_sha_get_digest_param.context_id; 1373 i++; 1374 payload[i] = crypto_header; 1375 i++; 1376 1377 if ((crypto_header >> FCS_CS_FIELD_FLAG_OFFSET) & 1378 FCS_CS_FIELD_FLAG_INIT) { 1379 payload[i] = fcs_sha_get_digest_param.key_id; 1380 i++; 1381 /* Crypto parameters */ 1382 payload[i] = fcs_sha_get_digest_param.crypto_param 1383 & INTEL_SIP_SMC_FCS_SHA_MODE_MASK; 1384 payload[i] |= ((fcs_sha_get_digest_param.crypto_param 1385 >> INTEL_SIP_SMC_FCS_DIGEST_SIZE_OFFSET) 1386 & INTEL_SIP_SMC_FCS_DIGEST_SIZE_MASK) 1387 << FCS_SHA_HMAC_CRYPTO_PARAM_SIZE_OFFSET; 1388 i++; 1389 } 1390 /* Data source address and size */ 1391 payload[i] = src_addr; 1392 i++; 1393 payload[i] = src_size; 1394 i++; 1395 1396 status = mailbox_send_cmd_async(send_id, MBOX_FCS_GET_DIGEST_REQ, 1397 payload, i, CMD_INDIRECT); 1398 1399 if (is_finalised != 0U) { 1400 memset((void *)&fcs_sha_get_digest_param, 0, 1401 sizeof(fcs_crypto_service_data)); 1402 } 1403 1404 if (status < 0) { 1405 *mbox_error = -status; 1406 return INTEL_SIP_SMC_STATUS_ERROR; 1407 } 1408 1409 *dst_size = resp_len * MBOX_WORD_BYTE; 1410 flush_dcache_range(dst_addr, *dst_size); 1411 1412 return INTEL_SIP_SMC_STATUS_OK; 1413 } 1414 1415 int intel_fcs_mac_verify_init(uint32_t session_id, uint32_t context_id, 1416 uint32_t key_id, uint32_t param_size, 1417 uint64_t param_data, uint32_t *mbox_error) 1418 { 1419 return intel_fcs_crypto_service_init(session_id, context_id, 1420 key_id, param_size, param_data, 1421 (void *) &fcs_sha_mac_verify_param, 1422 mbox_error); 1423 } 1424 1425 int intel_fcs_mac_verify_update_finalize(uint32_t smc_fid, uint32_t trans_id, 1426 uint32_t session_id, uint32_t context_id, 1427 uint32_t src_addr, uint32_t src_size, 1428 uint64_t dst_addr, uint32_t *dst_size, 1429 uint32_t data_size, uint8_t is_finalised, 1430 uint32_t *mbox_error, uint64_t smmu_src_addr) 1431 { 1432 int status; 1433 uint32_t i; 1434 uint32_t flag; 1435 uint32_t crypto_header; 1436 uint32_t resp_len; 1437 uint32_t payload[FCS_MAC_VERIFY_CMD_MAX_WORD_SIZE] = {0U}; 1438 uintptr_t mac_offset; 1439 uint32_t dst_size_check = 0; 1440 1441 if (dst_size == NULL || mbox_error == NULL) { 1442 return INTEL_SIP_SMC_STATUS_REJECTED; 1443 } 1444 1445 if (fcs_sha_mac_verify_param.session_id != session_id || 1446 fcs_sha_mac_verify_param.context_id != context_id) { 1447 return INTEL_SIP_SMC_STATUS_REJECTED; 1448 } 1449 1450 if (data_size > src_size) { 1451 return INTEL_SIP_SMC_STATUS_REJECTED; 1452 } 1453 1454 if (!is_size_4_bytes_aligned(src_size) || 1455 !is_8_bytes_aligned(data_size)) { 1456 return INTEL_SIP_SMC_STATUS_REJECTED; 1457 } 1458 1459 if (!is_address_in_ddr_range(src_addr, src_size) || 1460 !is_address_in_ddr_range(dst_addr, *dst_size)) { 1461 return INTEL_SIP_SMC_STATUS_REJECTED; 1462 } 1463 1464 dst_size_check = *dst_size; 1465 if ((dst_size_check > FCS_MAX_DATA_SIZE || 1466 dst_size_check < FCS_MIN_DATA_SIZE) || 1467 (src_size > FCS_MAX_DATA_SIZE || 1468 src_size < FCS_MIN_DATA_SIZE)) { 1469 return INTEL_SIP_SMC_STATUS_REJECTED; 1470 } 1471 1472 resp_len = *dst_size / MBOX_WORD_BYTE; 1473 1474 /* Prepare crypto header */ 1475 flag = 0; 1476 1477 if (fcs_sha_mac_verify_param.is_updated) { 1478 fcs_sha_mac_verify_param.crypto_param_size = 0; 1479 } else { 1480 flag |= FCS_CS_FIELD_FLAG_INIT; 1481 } 1482 1483 if (is_finalised) { 1484 flag |= FCS_CS_FIELD_FLAG_FINALIZE; 1485 } else { 1486 flag |= FCS_CS_FIELD_FLAG_UPDATE; 1487 fcs_sha_mac_verify_param.is_updated = 1; 1488 } 1489 1490 crypto_header = ((flag << FCS_CS_FIELD_FLAG_OFFSET) | 1491 (fcs_sha_mac_verify_param.crypto_param_size & 1492 FCS_CS_FIELD_SIZE_MASK)); 1493 1494 /* Prepare command payload */ 1495 i = 0; 1496 payload[i] = fcs_sha_mac_verify_param.session_id; 1497 i++; 1498 payload[i] = fcs_sha_mac_verify_param.context_id; 1499 i++; 1500 payload[i] = crypto_header; 1501 i++; 1502 1503 if ((crypto_header >> FCS_CS_FIELD_FLAG_OFFSET) & 1504 FCS_CS_FIELD_FLAG_INIT) { 1505 payload[i] = fcs_sha_mac_verify_param.key_id; 1506 i++; 1507 /* Crypto parameters */ 1508 payload[i] = ((fcs_sha_mac_verify_param.crypto_param 1509 >> INTEL_SIP_SMC_FCS_DIGEST_SIZE_OFFSET) 1510 & INTEL_SIP_SMC_FCS_DIGEST_SIZE_MASK) 1511 << FCS_SHA_HMAC_CRYPTO_PARAM_SIZE_OFFSET; 1512 i++; 1513 } 1514 1515 /* Data source address and size */ 1516 #if PLATFORM_MODEL == PLAT_SOCFPGA_AGILEX5 1517 payload[i] = (uint32_t)smmu_src_addr; 1518 #else 1519 payload[i] = src_addr; 1520 #endif 1521 i++; 1522 payload[i] = data_size; 1523 i++; 1524 1525 if ((crypto_header >> FCS_CS_FIELD_FLAG_OFFSET) & 1526 FCS_CS_FIELD_FLAG_FINALIZE) { 1527 /* Copy mac data to command */ 1528 mac_offset = src_addr + data_size; 1529 1530 if ((i + ((src_size - data_size) / MBOX_WORD_BYTE)) > 1531 FCS_MAC_VERIFY_CMD_MAX_WORD_SIZE) { 1532 return INTEL_SIP_SMC_STATUS_REJECTED; 1533 } 1534 1535 memcpy_s(&payload[i], (src_size - data_size) / MBOX_WORD_BYTE, 1536 (void *) mac_offset, (src_size - data_size) / MBOX_WORD_BYTE); 1537 1538 i += (src_size - data_size) / MBOX_WORD_BYTE; 1539 } 1540 1541 status = ((smc_fid == ALTERA_SIP_SMC_ASYNC_FCS_MAC_VERIFY_UPDATE) || 1542 (smc_fid == ALTERA_SIP_SMC_ASYNC_FCS_MAC_VERIFY_FINALIZE)) ? 1543 mailbox_send_cmd_async_v3(GET_CLIENT_ID(trans_id), 1544 GET_JOB_ID(trans_id), 1545 MBOX_FCS_MAC_VERIFY_REQ, 1546 payload, 1547 i, 1548 MBOX_CMD_FLAG_CASUAL, 1549 fcs_cs_mac_verify_cb, 1550 (uint32_t *)dst_addr, 1551 2U) : 1552 mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_MAC_VERIFY_REQ, 1553 payload, i, CMD_CASUAL, 1554 (uint32_t *) dst_addr, &resp_len); 1555 1556 if (is_finalised) { 1557 memset((void *)&fcs_sha_mac_verify_param, 0, 1558 sizeof(fcs_crypto_service_data)); 1559 } 1560 1561 if (status < 0) { 1562 *mbox_error = -status; 1563 return INTEL_SIP_SMC_STATUS_ERROR; 1564 } 1565 1566 *dst_size = resp_len * MBOX_WORD_BYTE; 1567 flush_dcache_range(dst_addr, *dst_size); 1568 1569 return INTEL_SIP_SMC_STATUS_OK; 1570 } 1571 1572 int intel_fcs_mac_verify_smmu_update_finalize(uint32_t session_id, 1573 uint32_t context_id, uint32_t src_addr, 1574 uint32_t src_size, uint64_t dst_addr, 1575 uint32_t *dst_size, uint32_t data_size, 1576 uint8_t is_finalised, uint32_t *mbox_error, 1577 uint32_t *send_id) 1578 { 1579 int status; 1580 uint32_t i; 1581 uint32_t flag; 1582 uint32_t crypto_header; 1583 uint32_t resp_len; 1584 uint32_t payload[FCS_MAC_VERIFY_CMD_MAX_WORD_SIZE] = {0U}; 1585 uintptr_t mac_offset; 1586 uint32_t dst_size_check = 0; 1587 /* 1588 * Source data must be 4 bytes aligned 1589 * User data must be 8 bytes aligned 1590 */ 1591 if (dst_size == NULL || mbox_error == NULL || 1592 !is_size_4_bytes_aligned(src_size) || 1593 !is_8_bytes_aligned(data_size)) { 1594 return INTEL_SIP_SMC_STATUS_REJECTED; 1595 } 1596 1597 if (data_size > src_size) { 1598 return INTEL_SIP_SMC_STATUS_REJECTED; 1599 } 1600 1601 if (fcs_sha_mac_verify_param.session_id != session_id || 1602 fcs_sha_mac_verify_param.context_id != context_id) { 1603 return INTEL_SIP_SMC_STATUS_REJECTED; 1604 } 1605 1606 if (!is_address_in_ddr_range(src_addr, src_size) || 1607 !is_address_in_ddr_range(dst_addr, *dst_size)) { 1608 return INTEL_SIP_SMC_STATUS_REJECTED; 1609 } 1610 1611 dst_size_check = *dst_size; 1612 if ((dst_size_check > FCS_MAX_DATA_SIZE || 1613 dst_size_check < FCS_MIN_DATA_SIZE) || 1614 (src_size > FCS_MAX_DATA_SIZE || 1615 src_size < FCS_MIN_DATA_SIZE)) { 1616 return INTEL_SIP_SMC_STATUS_REJECTED; 1617 } 1618 1619 resp_len = *dst_size / MBOX_WORD_BYTE; 1620 1621 /* Prepare crypto header */ 1622 flag = 0; 1623 1624 if (fcs_sha_mac_verify_param.is_updated) { 1625 fcs_sha_mac_verify_param.crypto_param_size = 0; 1626 } else { 1627 flag |= FCS_CS_FIELD_FLAG_INIT; 1628 } 1629 1630 if (is_finalised) { 1631 flag |= FCS_CS_FIELD_FLAG_FINALIZE; 1632 } else { 1633 flag |= FCS_CS_FIELD_FLAG_UPDATE; 1634 fcs_sha_mac_verify_param.is_updated = 1; 1635 } 1636 1637 crypto_header = ((flag << FCS_CS_FIELD_FLAG_OFFSET) | 1638 (fcs_sha_mac_verify_param.crypto_param_size & 1639 FCS_CS_FIELD_SIZE_MASK)); 1640 1641 /* Prepare command payload */ 1642 i = 0; 1643 payload[i] = fcs_sha_mac_verify_param.session_id; 1644 i++; 1645 payload[i] = fcs_sha_mac_verify_param.context_id; 1646 i++; 1647 payload[i] = crypto_header; 1648 i++; 1649 1650 if ((crypto_header >> FCS_CS_FIELD_FLAG_OFFSET) & 1651 FCS_CS_FIELD_FLAG_INIT) { 1652 payload[i] = fcs_sha_mac_verify_param.key_id; 1653 i++; 1654 /* Crypto parameters */ 1655 payload[i] = ((fcs_sha_mac_verify_param.crypto_param 1656 >> INTEL_SIP_SMC_FCS_DIGEST_SIZE_OFFSET) 1657 & INTEL_SIP_SMC_FCS_DIGEST_SIZE_MASK) 1658 << FCS_SHA_HMAC_CRYPTO_PARAM_SIZE_OFFSET; 1659 i++; 1660 } 1661 /* Data source address and size */ 1662 payload[i] = src_addr; 1663 i++; 1664 payload[i] = data_size; 1665 i++; 1666 1667 if ((crypto_header >> FCS_CS_FIELD_FLAG_OFFSET) & 1668 FCS_CS_FIELD_FLAG_FINALIZE) { 1669 /* Copy mac data to command 1670 * Using dst_addr (physical address) to store mac_offset 1671 * mac_offset = MAC data 1672 */ 1673 mac_offset = dst_addr; 1674 1675 if ((i + ((src_size - data_size) / MBOX_WORD_BYTE)) > 1676 FCS_MAC_VERIFY_CMD_MAX_WORD_SIZE) { 1677 return INTEL_SIP_SMC_STATUS_REJECTED; 1678 } 1679 1680 memcpy_s(&payload[i], (src_size - data_size) / MBOX_WORD_BYTE, 1681 (void *) mac_offset, (src_size - data_size) / MBOX_WORD_BYTE); 1682 1683 memset((void *) dst_addr, 0, *dst_size); 1684 1685 i += (src_size - data_size) / MBOX_WORD_BYTE; 1686 } 1687 1688 status = mailbox_send_cmd_async(send_id, MBOX_FCS_MAC_VERIFY_REQ, 1689 payload, i, CMD_INDIRECT); 1690 1691 if (is_finalised) { 1692 memset((void *)&fcs_sha_mac_verify_param, 0, 1693 sizeof(fcs_crypto_service_data)); 1694 } 1695 1696 if (status < 0) { 1697 *mbox_error = -status; 1698 return INTEL_SIP_SMC_STATUS_ERROR; 1699 } 1700 1701 *dst_size = resp_len * MBOX_WORD_BYTE; 1702 flush_dcache_range(dst_addr, *dst_size); 1703 1704 return INTEL_SIP_SMC_STATUS_OK; 1705 } 1706 1707 int intel_fcs_ecdsa_hash_sign_init(uint32_t session_id, uint32_t context_id, 1708 uint32_t key_id, uint32_t param_size, 1709 uint64_t param_data, uint32_t *mbox_error) 1710 { 1711 return intel_fcs_crypto_service_init(session_id, context_id, 1712 key_id, param_size, param_data, 1713 (void *) &fcs_ecdsa_hash_sign_param, 1714 mbox_error); 1715 } 1716 1717 int intel_fcs_ecdsa_hash_sign_finalize(uint32_t smc_fid, uint32_t trans_id, 1718 uint32_t session_id, uint32_t context_id, 1719 uint32_t src_addr, uint32_t src_size, 1720 uint64_t dst_addr, uint32_t *dst_size, 1721 uint32_t *mbox_error) 1722 { 1723 int status; 1724 uint32_t i; 1725 uint32_t payload[FCS_ECDSA_HASH_SIGN_CMD_MAX_WORD_SIZE] = {0U}; 1726 uint32_t resp_len; 1727 uintptr_t hash_data_addr; 1728 uint32_t dst_size_check = 0; 1729 1730 if ((dst_size == NULL) || (mbox_error == NULL)) { 1731 return INTEL_SIP_SMC_STATUS_REJECTED; 1732 } 1733 1734 if (fcs_ecdsa_hash_sign_param.session_id != session_id || 1735 fcs_ecdsa_hash_sign_param.context_id != context_id) { 1736 return INTEL_SIP_SMC_STATUS_REJECTED; 1737 } 1738 1739 if (!is_address_in_ddr_range(src_addr, src_size) || 1740 !is_address_in_ddr_range(dst_addr, *dst_size)) { 1741 return INTEL_SIP_SMC_STATUS_REJECTED; 1742 } 1743 1744 dst_size_check = *dst_size; 1745 if ((dst_size_check > FCS_MAX_DATA_SIZE || 1746 dst_size_check < FCS_MIN_DATA_SIZE) || 1747 (src_size > FCS_MAX_DATA_SIZE || 1748 src_size < FCS_MIN_DATA_SIZE)) { 1749 return INTEL_SIP_SMC_STATUS_REJECTED; 1750 } 1751 1752 resp_len = *dst_size / MBOX_WORD_BYTE; 1753 1754 /* Prepare command payload */ 1755 /* Crypto header */ 1756 i = 0; 1757 payload[i] = fcs_ecdsa_hash_sign_param.session_id; 1758 i++; 1759 payload[i] = fcs_ecdsa_hash_sign_param.context_id; 1760 1761 i++; 1762 payload[i] = fcs_ecdsa_hash_sign_param.crypto_param_size 1763 & FCS_CS_FIELD_SIZE_MASK; 1764 payload[i] |= (FCS_CS_FIELD_FLAG_INIT | FCS_CS_FIELD_FLAG_UPDATE 1765 | FCS_CS_FIELD_FLAG_FINALIZE) 1766 << FCS_CS_FIELD_FLAG_OFFSET; 1767 i++; 1768 payload[i] = fcs_ecdsa_hash_sign_param.key_id; 1769 1770 /* Crypto parameters */ 1771 i++; 1772 payload[i] = fcs_ecdsa_hash_sign_param.crypto_param 1773 & INTEL_SIP_SMC_FCS_ECC_ALGO_MASK; 1774 1775 /* Hash Data */ 1776 i++; 1777 hash_data_addr = src_addr; 1778 1779 if ((i + ((src_size) / MBOX_WORD_BYTE)) > 1780 FCS_ECDSA_HASH_SIGN_CMD_MAX_WORD_SIZE) { 1781 return INTEL_SIP_SMC_STATUS_REJECTED; 1782 } 1783 1784 memcpy_s(&payload[i], src_size / MBOX_WORD_BYTE, 1785 (void *) hash_data_addr, src_size / MBOX_WORD_BYTE); 1786 1787 i += src_size / MBOX_WORD_BYTE; 1788 1789 status = (smc_fid == ALTERA_SIP_SMC_ASYNC_FCS_ECDSA_HASH_SIGN_FINALIZE) ? 1790 mailbox_send_cmd_async_v3(GET_CLIENT_ID(trans_id), 1791 GET_JOB_ID(trans_id), 1792 MBOX_FCS_ECDSA_HASH_SIGN_REQ, 1793 payload, 1794 i, 1795 MBOX_CMD_FLAG_CASUAL, 1796 fcs_cs_hash_sign_req_cb, 1797 (uint32_t *)dst_addr, 1798 2U) : 1799 mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_ECDSA_HASH_SIGN_REQ, 1800 payload, i, CMD_CASUAL, (uint32_t *) dst_addr, 1801 &resp_len); 1802 1803 memset((void *) &fcs_ecdsa_hash_sign_param, 1804 0, sizeof(fcs_crypto_service_data)); 1805 1806 if (status < 0) { 1807 *mbox_error = -status; 1808 return INTEL_SIP_SMC_STATUS_ERROR; 1809 } 1810 1811 *dst_size = resp_len * MBOX_WORD_BYTE; 1812 flush_dcache_range(dst_addr, *dst_size); 1813 1814 return INTEL_SIP_SMC_STATUS_OK; 1815 } 1816 1817 int intel_fcs_ecdsa_hash_sig_verify_init(uint32_t session_id, uint32_t context_id, 1818 uint32_t key_id, uint32_t param_size, 1819 uint64_t param_data, uint32_t *mbox_error) 1820 { 1821 return intel_fcs_crypto_service_init(session_id, context_id, 1822 key_id, param_size, param_data, 1823 (void *) &fcs_ecdsa_hash_sig_verify_param, 1824 mbox_error); 1825 } 1826 1827 int intel_fcs_ecdsa_hash_sig_verify_finalize(uint32_t smc_fid, uint32_t trans_id, 1828 uint32_t session_id, uint32_t context_id, 1829 uint32_t src_addr, uint32_t src_size, 1830 uint64_t dst_addr, uint32_t *dst_size, 1831 uint32_t *mbox_error) 1832 { 1833 int status; 1834 uint32_t i = 0; 1835 uint32_t payload[FCS_ECDSA_HASH_SIG_VERIFY_CMD_MAX_WORD_SIZE] = {0U}; 1836 uint32_t resp_len; 1837 uintptr_t hash_sig_pubkey_addr; 1838 uint32_t dst_size_check = 0; 1839 1840 if ((dst_size == NULL) || (mbox_error == NULL)) { 1841 return INTEL_SIP_SMC_STATUS_REJECTED; 1842 } 1843 1844 if ((fcs_ecdsa_hash_sig_verify_param.session_id != session_id) || 1845 (fcs_ecdsa_hash_sig_verify_param.context_id != context_id)) { 1846 return INTEL_SIP_SMC_STATUS_REJECTED; 1847 } 1848 1849 if (!is_address_in_ddr_range(src_addr, src_size) || 1850 !is_address_in_ddr_range(dst_addr, *dst_size)) { 1851 return INTEL_SIP_SMC_STATUS_REJECTED; 1852 } 1853 1854 dst_size_check = *dst_size; 1855 if ((dst_size_check > FCS_MAX_DATA_SIZE || 1856 dst_size_check < FCS_MIN_DATA_SIZE) || 1857 (src_size > FCS_MAX_DATA_SIZE || 1858 src_size < FCS_MIN_DATA_SIZE)) { 1859 return INTEL_SIP_SMC_STATUS_REJECTED; 1860 } 1861 1862 resp_len = *dst_size / MBOX_WORD_BYTE; 1863 1864 /* Prepare command payload */ 1865 /* Crypto header */ 1866 i = 0; 1867 payload[i] = fcs_ecdsa_hash_sig_verify_param.session_id; 1868 1869 i++; 1870 payload[i] = fcs_ecdsa_hash_sig_verify_param.context_id; 1871 1872 i++; 1873 payload[i] = fcs_ecdsa_hash_sig_verify_param.crypto_param_size 1874 & FCS_CS_FIELD_SIZE_MASK; 1875 payload[i] |= (FCS_CS_FIELD_FLAG_INIT | FCS_CS_FIELD_FLAG_UPDATE 1876 | FCS_CS_FIELD_FLAG_FINALIZE) 1877 << FCS_CS_FIELD_FLAG_OFFSET; 1878 1879 i++; 1880 payload[i] = fcs_ecdsa_hash_sig_verify_param.key_id; 1881 1882 /* Crypto parameters */ 1883 i++; 1884 payload[i] = fcs_ecdsa_hash_sig_verify_param.crypto_param 1885 & INTEL_SIP_SMC_FCS_ECC_ALGO_MASK; 1886 1887 /* Hash Data Word, Signature Data Word and Public Key Data word */ 1888 i++; 1889 hash_sig_pubkey_addr = src_addr; 1890 1891 if ((i + ((src_size) / MBOX_WORD_BYTE)) > 1892 FCS_ECDSA_HASH_SIG_VERIFY_CMD_MAX_WORD_SIZE) { 1893 return INTEL_SIP_SMC_STATUS_REJECTED; 1894 } 1895 1896 memcpy_s(&payload[i], src_size / MBOX_WORD_BYTE, 1897 (void *) hash_sig_pubkey_addr, src_size / MBOX_WORD_BYTE); 1898 1899 i += (src_size / MBOX_WORD_BYTE); 1900 1901 status = (smc_fid == ALTERA_SIP_SMC_ASYNC_FCS_ECDSA_HASH_SIG_VERIFY_FINALIZE) ? 1902 mailbox_send_cmd_async_v3(GET_CLIENT_ID(trans_id), 1903 GET_JOB_ID(trans_id), 1904 MBOX_FCS_ECDSA_HASH_SIG_VERIFY, 1905 payload, 1906 i, 1907 MBOX_CMD_FLAG_CASUAL, 1908 fcs_cs_hash_sig_verify_req_cb, 1909 (uint32_t *)dst_addr, 1910 2U) : 1911 1912 mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_ECDSA_HASH_SIG_VERIFY, 1913 payload, i, CMD_CASUAL, (uint32_t *) dst_addr, 1914 &resp_len); 1915 1916 memset((void *)&fcs_ecdsa_hash_sig_verify_param, 1917 0, sizeof(fcs_crypto_service_data)); 1918 1919 if (status < 0) { 1920 *mbox_error = -status; 1921 return INTEL_SIP_SMC_STATUS_ERROR; 1922 } 1923 1924 *dst_size = resp_len * MBOX_WORD_BYTE; 1925 flush_dcache_range(dst_addr, *dst_size); 1926 1927 return INTEL_SIP_SMC_STATUS_OK; 1928 } 1929 1930 int intel_fcs_ecdsa_sha2_data_sign_init(uint32_t session_id, 1931 uint32_t context_id, uint32_t key_id, 1932 uint32_t param_size, uint64_t param_data, 1933 uint32_t *mbox_error) 1934 { 1935 return intel_fcs_crypto_service_init(session_id, context_id, 1936 key_id, param_size, param_data, 1937 (void *) &fcs_sha2_data_sign_param, 1938 mbox_error); 1939 } 1940 1941 int intel_fcs_ecdsa_sha2_data_sign_update_finalize(uint32_t smc_fid, uint32_t trans_id, 1942 uint32_t session_id, uint32_t context_id, 1943 uint32_t src_addr, uint32_t src_size, 1944 uint64_t dst_addr, uint32_t *dst_size, 1945 uint8_t is_finalised, uint32_t *mbox_error, 1946 uint64_t smmu_src_addr) 1947 { 1948 int status; 1949 int i; 1950 uint32_t flag; 1951 uint32_t crypto_header; 1952 uint32_t payload[FCS_ECDSA_SHA2_DATA_SIGN_CMD_MAX_WORD_SIZE] = {0U}; 1953 uint32_t resp_len; 1954 1955 if ((dst_size == NULL) || (mbox_error == NULL)) { 1956 return INTEL_SIP_SMC_STATUS_REJECTED; 1957 } 1958 1959 if (fcs_sha2_data_sign_param.session_id != session_id || 1960 fcs_sha2_data_sign_param.context_id != context_id) { 1961 return INTEL_SIP_SMC_STATUS_REJECTED; 1962 } 1963 1964 /* Source data must be 8 bytes aligned */ 1965 if (!is_8_bytes_aligned(src_size)) { 1966 return INTEL_SIP_SMC_STATUS_REJECTED; 1967 } 1968 1969 if (!is_address_in_ddr_range(src_addr, src_size) || 1970 !is_address_in_ddr_range(dst_addr, *dst_size)) { 1971 return INTEL_SIP_SMC_STATUS_REJECTED; 1972 } 1973 1974 resp_len = *dst_size / MBOX_WORD_BYTE; 1975 1976 /* Prepare crypto header */ 1977 flag = 0; 1978 if (fcs_sha2_data_sign_param.is_updated) { 1979 fcs_sha2_data_sign_param.crypto_param_size = 0; 1980 } else { 1981 flag |= FCS_CS_FIELD_FLAG_INIT; 1982 } 1983 1984 if (is_finalised != 0U) { 1985 flag |= FCS_CS_FIELD_FLAG_FINALIZE; 1986 } else { 1987 flag |= FCS_CS_FIELD_FLAG_UPDATE; 1988 fcs_sha2_data_sign_param.is_updated = 1; 1989 } 1990 crypto_header = (flag << FCS_CS_FIELD_FLAG_OFFSET) | 1991 fcs_sha2_data_sign_param.crypto_param_size; 1992 1993 /* Prepare command payload */ 1994 i = 0; 1995 payload[i] = fcs_sha2_data_sign_param.session_id; 1996 i++; 1997 payload[i] = fcs_sha2_data_sign_param.context_id; 1998 i++; 1999 payload[i] = crypto_header; 2000 i++; 2001 2002 if ((crypto_header >> FCS_CS_FIELD_FLAG_OFFSET) & 2003 FCS_CS_FIELD_FLAG_INIT) { 2004 payload[i] = fcs_sha2_data_sign_param.key_id; 2005 /* Crypto parameters */ 2006 i++; 2007 payload[i] = fcs_sha2_data_sign_param.crypto_param 2008 & INTEL_SIP_SMC_FCS_ECC_ALGO_MASK; 2009 i++; 2010 } 2011 2012 /* Data source address and size */ 2013 #if PLATFORM_MODEL == PLAT_SOCFPGA_AGILEX5 2014 payload[i] = (uint32_t)smmu_src_addr; 2015 #else 2016 payload[i] = src_addr; 2017 #endif 2018 i++; 2019 payload[i] = src_size; 2020 i++; 2021 2022 status = ((smc_fid == ALTERA_SIP_SMC_ASYNC_FCS_ECDSA_SHA2_DATA_SIGN_UPDATE) || 2023 (smc_fid == ALTERA_SIP_SMC_ASYNC_FCS_ECDSA_SHA2_DATA_SIGN_FINALIZE)) ? 2024 mailbox_send_cmd_async_v3(GET_CLIENT_ID(trans_id), 2025 GET_JOB_ID(trans_id), 2026 MBOX_FCS_ECDSA_SHA2_DATA_SIGN_REQ, 2027 payload, 2028 i, 2029 MBOX_CMD_FLAG_CASUAL, 2030 fcs_cs_data_sign_req_cb, 2031 (uint32_t *)dst_addr, 2032 2U) : 2033 mailbox_send_cmd(MBOX_JOB_ID, 2034 MBOX_FCS_ECDSA_SHA2_DATA_SIGN_REQ, payload, 2035 i, CMD_CASUAL, (uint32_t *) dst_addr, 2036 &resp_len); 2037 2038 if (is_finalised != 0U) { 2039 memset((void *)&fcs_sha2_data_sign_param, 0, 2040 sizeof(fcs_crypto_service_data)); 2041 } 2042 2043 if (status < 0) { 2044 *mbox_error = -status; 2045 return INTEL_SIP_SMC_STATUS_ERROR; 2046 } 2047 2048 *dst_size = resp_len * MBOX_WORD_BYTE; 2049 flush_dcache_range(dst_addr, *dst_size); 2050 2051 return INTEL_SIP_SMC_STATUS_OK; 2052 } 2053 2054 int intel_fcs_ecdsa_sha2_data_sign_smmu_update_finalize(uint32_t session_id, 2055 uint32_t context_id, uint32_t src_addr, 2056 uint32_t src_size, uint64_t dst_addr, 2057 uint32_t *dst_size, uint8_t is_finalised, 2058 uint32_t *mbox_error, uint32_t *send_id) 2059 { 2060 int status; 2061 int i; 2062 uint32_t flag; 2063 uint32_t crypto_header; 2064 uint32_t payload[FCS_ECDSA_SHA2_DATA_SIGN_CMD_MAX_WORD_SIZE] = {0U}; 2065 uint32_t resp_len; 2066 2067 /* Source data must be 8 bytes aligned */ 2068 if ((dst_size == NULL) || (mbox_error == NULL || 2069 !is_8_bytes_aligned(src_size))) { 2070 return INTEL_SIP_SMC_STATUS_REJECTED; 2071 } 2072 2073 if (fcs_sha2_data_sign_param.session_id != session_id || 2074 fcs_sha2_data_sign_param.context_id != context_id) { 2075 return INTEL_SIP_SMC_STATUS_REJECTED; 2076 } 2077 2078 if (!is_address_in_ddr_range(src_addr, src_size) || 2079 !is_address_in_ddr_range(dst_addr, *dst_size)) { 2080 return INTEL_SIP_SMC_STATUS_REJECTED; 2081 } 2082 2083 resp_len = *dst_size / MBOX_WORD_BYTE; 2084 2085 /* Prepare crypto header */ 2086 flag = 0; 2087 if (fcs_sha2_data_sign_param.is_updated) { 2088 fcs_sha2_data_sign_param.crypto_param_size = 0; 2089 } else { 2090 flag |= FCS_CS_FIELD_FLAG_INIT; 2091 } 2092 2093 if (is_finalised != 0U) { 2094 flag |= FCS_CS_FIELD_FLAG_FINALIZE; 2095 } else { 2096 flag |= FCS_CS_FIELD_FLAG_UPDATE; 2097 fcs_sha2_data_sign_param.is_updated = 1; 2098 } 2099 crypto_header = (flag << FCS_CS_FIELD_FLAG_OFFSET) | 2100 fcs_sha2_data_sign_param.crypto_param_size; 2101 2102 /* Prepare command payload */ 2103 i = 0; 2104 payload[i] = fcs_sha2_data_sign_param.session_id; 2105 i++; 2106 payload[i] = fcs_sha2_data_sign_param.context_id; 2107 i++; 2108 payload[i] = crypto_header; 2109 i++; 2110 2111 if ((crypto_header >> FCS_CS_FIELD_FLAG_OFFSET) & 2112 FCS_CS_FIELD_FLAG_INIT) { 2113 payload[i] = fcs_sha2_data_sign_param.key_id; 2114 /* Crypto parameters */ 2115 i++; 2116 payload[i] = fcs_sha2_data_sign_param.crypto_param 2117 & INTEL_SIP_SMC_FCS_ECC_ALGO_MASK; 2118 i++; 2119 } 2120 2121 /* Data source address and size */ 2122 payload[i] = src_addr; 2123 i++; 2124 payload[i] = src_size; 2125 i++; 2126 2127 status = mailbox_send_cmd_async(send_id, 2128 MBOX_FCS_ECDSA_SHA2_DATA_SIGN_REQ, 2129 payload, i, CMD_INDIRECT); 2130 2131 if (is_finalised != 0U) { 2132 memset((void *)&fcs_sha2_data_sign_param, 0, 2133 sizeof(fcs_crypto_service_data)); 2134 } 2135 2136 if (status < 0) { 2137 *mbox_error = -status; 2138 return INTEL_SIP_SMC_STATUS_ERROR; 2139 } 2140 2141 *dst_size = resp_len * MBOX_WORD_BYTE; 2142 flush_dcache_range(dst_addr, *dst_size); 2143 2144 return INTEL_SIP_SMC_STATUS_OK; 2145 } 2146 2147 int intel_fcs_ecdsa_sha2_data_sig_verify_init(uint32_t session_id, 2148 uint32_t context_id, uint32_t key_id, 2149 uint32_t param_size, uint64_t param_data, 2150 uint32_t *mbox_error) 2151 { 2152 return intel_fcs_crypto_service_init(session_id, context_id, 2153 key_id, param_size, param_data, 2154 (void *) &fcs_sha2_data_sig_verify_param, 2155 mbox_error); 2156 } 2157 2158 int intel_fcs_ecdsa_sha2_data_sig_verify_update_finalize(uint32_t smc_fid, uint32_t trans_id, 2159 uint32_t session_id, uint32_t context_id, 2160 uint32_t src_addr, uint32_t src_size, 2161 uint64_t dst_addr, uint32_t *dst_size, 2162 uint32_t data_size, uint8_t is_finalised, 2163 uint32_t *mbox_error, uint64_t smmu_src_addr) 2164 { 2165 int status; 2166 uint32_t i; 2167 uint32_t flag; 2168 uint32_t crypto_header; 2169 uint32_t payload[FCS_ECDSA_SHA2_DATA_SIG_VERIFY_CMD_MAX_WORD_SIZE] = {0U}; 2170 uint32_t resp_len; 2171 uintptr_t sig_pubkey_offset; 2172 uint32_t dst_size_check = 0; 2173 2174 if ((dst_size == NULL) || (mbox_error == NULL)) { 2175 return INTEL_SIP_SMC_STATUS_REJECTED; 2176 } 2177 2178 if (fcs_sha2_data_sig_verify_param.session_id != session_id || 2179 fcs_sha2_data_sig_verify_param.context_id != context_id) { 2180 return INTEL_SIP_SMC_STATUS_REJECTED; 2181 } 2182 2183 if (data_size > src_size) { 2184 return INTEL_SIP_SMC_STATUS_REJECTED; 2185 } 2186 2187 if (!is_size_4_bytes_aligned(src_size)) { 2188 return INTEL_SIP_SMC_STATUS_REJECTED; 2189 } 2190 2191 if (!is_8_bytes_aligned(data_size) || 2192 !is_8_bytes_aligned(src_addr)) { 2193 return INTEL_SIP_SMC_STATUS_REJECTED; 2194 } 2195 2196 if (!is_address_in_ddr_range(src_addr, src_size) || 2197 !is_address_in_ddr_range(dst_addr, *dst_size)) { 2198 return INTEL_SIP_SMC_STATUS_REJECTED; 2199 } 2200 2201 dst_size_check = *dst_size; 2202 if ((dst_size_check > FCS_MAX_DATA_SIZE || 2203 dst_size_check < FCS_MIN_DATA_SIZE) || 2204 (src_size > FCS_MAX_DATA_SIZE || 2205 src_size < FCS_MIN_DATA_SIZE)) { 2206 return INTEL_SIP_SMC_STATUS_REJECTED; 2207 } 2208 2209 resp_len = *dst_size / MBOX_WORD_BYTE; 2210 2211 /* Prepare crypto header */ 2212 flag = 0; 2213 if (fcs_sha2_data_sig_verify_param.is_updated) 2214 fcs_sha2_data_sig_verify_param.crypto_param_size = 0; 2215 else 2216 flag |= FCS_CS_FIELD_FLAG_INIT; 2217 2218 if (is_finalised != 0U) 2219 flag |= FCS_CS_FIELD_FLAG_FINALIZE; 2220 else { 2221 flag |= FCS_CS_FIELD_FLAG_UPDATE; 2222 fcs_sha2_data_sig_verify_param.is_updated = 1; 2223 } 2224 crypto_header = (flag << FCS_CS_FIELD_FLAG_OFFSET) | 2225 fcs_sha2_data_sig_verify_param.crypto_param_size; 2226 2227 /* Prepare command payload */ 2228 i = 0; 2229 payload[i] = fcs_sha2_data_sig_verify_param.session_id; 2230 i++; 2231 payload[i] = fcs_sha2_data_sig_verify_param.context_id; 2232 i++; 2233 payload[i] = crypto_header; 2234 i++; 2235 2236 if ((crypto_header >> FCS_CS_FIELD_FLAG_OFFSET) & 2237 FCS_CS_FIELD_FLAG_INIT) { 2238 payload[i] = fcs_sha2_data_sig_verify_param.key_id; 2239 i++; 2240 /* Crypto parameters */ 2241 payload[i] = fcs_sha2_data_sig_verify_param.crypto_param 2242 & INTEL_SIP_SMC_FCS_ECC_ALGO_MASK; 2243 i++; 2244 } 2245 2246 /* Data source address and size */ 2247 /* On the Agilex5 platform, the SMMU remapped address is used */ 2248 #if PLATFORM_MODEL == PLAT_SOCFPGA_AGILEX5 2249 payload[i] = smmu_src_addr; 2250 #else 2251 payload[i] = src_addr; 2252 #endif 2253 i++; 2254 payload[i] = data_size; 2255 i++; 2256 2257 if ((crypto_header >> FCS_CS_FIELD_FLAG_OFFSET) & 2258 FCS_CS_FIELD_FLAG_FINALIZE) { 2259 /* Signature + Public Key Data */ 2260 sig_pubkey_offset = src_addr + data_size; 2261 2262 if ((i + ((src_size - data_size) / MBOX_WORD_BYTE)) > 2263 FCS_ECDSA_SHA2_DATA_SIG_VERIFY_CMD_MAX_WORD_SIZE) { 2264 return INTEL_SIP_SMC_STATUS_REJECTED; 2265 } 2266 2267 memcpy_s(&payload[i], (src_size - data_size) / MBOX_WORD_BYTE, 2268 (void *) sig_pubkey_offset, (src_size - data_size) / MBOX_WORD_BYTE); 2269 2270 i += (src_size - data_size) / MBOX_WORD_BYTE; 2271 } 2272 2273 status = ((smc_fid == ALTERA_SIP_SMC_ASYNC_FCS_ECDSA_SHA2_DATA_SIG_VERIFY_UPDATE) || 2274 (smc_fid == ALTERA_SIP_SMC_ASYNC_FCS_ECDSA_SHA2_DATA_SIG_VERIFY_FINALIZE)) ? 2275 mailbox_send_cmd_async_v3(GET_CLIENT_ID(trans_id), 2276 GET_JOB_ID(trans_id), 2277 MBOX_FCS_ECDSA_SHA2_DATA_SIGN_VERIFY, 2278 payload, 2279 i, 2280 MBOX_CMD_FLAG_CASUAL, 2281 fcs_cs_data_sig_verify_req_cb, 2282 (uint32_t *)dst_addr, 2283 2U) : 2284 mailbox_send_cmd(MBOX_JOB_ID, 2285 MBOX_FCS_ECDSA_SHA2_DATA_SIGN_VERIFY, payload, i, 2286 CMD_CASUAL, (uint32_t *) dst_addr, &resp_len); 2287 2288 if (is_finalised != 0U) { 2289 memset((void *) &fcs_sha2_data_sig_verify_param, 0, 2290 sizeof(fcs_crypto_service_data)); 2291 } 2292 2293 if (status < 0) { 2294 *mbox_error = -status; 2295 return INTEL_SIP_SMC_STATUS_ERROR; 2296 } 2297 2298 *dst_size = resp_len * MBOX_WORD_BYTE; 2299 flush_dcache_range(dst_addr, *dst_size); 2300 2301 return INTEL_SIP_SMC_STATUS_OK; 2302 } 2303 2304 int intel_fcs_ecdsa_sha2_data_sig_verify_smmu_update_finalize(uint32_t session_id, 2305 uint32_t context_id, uint32_t src_addr, 2306 uint32_t src_size, uint64_t dst_addr, 2307 uint32_t *dst_size, uint32_t data_size, 2308 uint8_t is_finalised, uint32_t *mbox_error, 2309 uint32_t *send_id) 2310 { 2311 int status; 2312 uint32_t i; 2313 uint32_t flag; 2314 uint32_t crypto_header; 2315 uint32_t payload[FCS_ECDSA_SHA2_DATA_SIG_VERIFY_CMD_MAX_WORD_SIZE] = {0U}; 2316 uint32_t resp_len; 2317 uintptr_t sig_pubkey_offset; 2318 uint32_t dst_size_check = 0; 2319 2320 /* 2321 * Source data must be 4 bytes aligned 2322 * Source address must be 8 bytes aligned 2323 * User data must be 8 bytes aligned 2324 */ 2325 if ((dst_size == NULL) || (mbox_error == NULL) || 2326 !is_size_4_bytes_aligned(src_size) || 2327 !is_8_bytes_aligned(src_addr) || 2328 !is_8_bytes_aligned(data_size)) { 2329 return INTEL_SIP_SMC_STATUS_REJECTED; 2330 } 2331 2332 if (fcs_sha2_data_sig_verify_param.session_id != session_id || 2333 fcs_sha2_data_sig_verify_param.context_id != context_id) { 2334 return INTEL_SIP_SMC_STATUS_REJECTED; 2335 } 2336 2337 if (data_size > src_size) { 2338 return INTEL_SIP_SMC_STATUS_REJECTED; 2339 } 2340 2341 if (!is_address_in_ddr_range(src_addr, src_size) || 2342 !is_address_in_ddr_range(dst_addr, *dst_size)) { 2343 return INTEL_SIP_SMC_STATUS_REJECTED; 2344 } 2345 2346 dst_size_check = *dst_size; 2347 if ((dst_size_check > FCS_MAX_DATA_SIZE || 2348 dst_size_check < FCS_MIN_DATA_SIZE) || 2349 (src_size > FCS_MAX_DATA_SIZE || 2350 src_size < FCS_MIN_DATA_SIZE)) { 2351 return INTEL_SIP_SMC_STATUS_REJECTED; 2352 } 2353 2354 resp_len = *dst_size / MBOX_WORD_BYTE; 2355 2356 /* Prepare crypto header */ 2357 flag = 0; 2358 if (fcs_sha2_data_sig_verify_param.is_updated) 2359 fcs_sha2_data_sig_verify_param.crypto_param_size = 0; 2360 else 2361 flag |= FCS_CS_FIELD_FLAG_INIT; 2362 2363 if (is_finalised != 0U) 2364 flag |= FCS_CS_FIELD_FLAG_FINALIZE; 2365 else { 2366 flag |= FCS_CS_FIELD_FLAG_UPDATE; 2367 fcs_sha2_data_sig_verify_param.is_updated = 1; 2368 } 2369 crypto_header = (flag << FCS_CS_FIELD_FLAG_OFFSET) | 2370 fcs_sha2_data_sig_verify_param.crypto_param_size; 2371 2372 /* Prepare command payload */ 2373 i = 0; 2374 payload[i] = fcs_sha2_data_sig_verify_param.session_id; 2375 i++; 2376 payload[i] = fcs_sha2_data_sig_verify_param.context_id; 2377 i++; 2378 payload[i] = crypto_header; 2379 i++; 2380 2381 if ((crypto_header >> FCS_CS_FIELD_FLAG_OFFSET) & 2382 FCS_CS_FIELD_FLAG_INIT) { 2383 payload[i] = fcs_sha2_data_sig_verify_param.key_id; 2384 i++; 2385 /* Crypto parameters */ 2386 payload[i] = fcs_sha2_data_sig_verify_param.crypto_param 2387 & INTEL_SIP_SMC_FCS_ECC_ALGO_MASK; 2388 i++; 2389 } 2390 2391 /* Data source address and size */ 2392 payload[i] = src_addr; 2393 i++; 2394 payload[i] = data_size; 2395 i++; 2396 2397 if ((crypto_header >> FCS_CS_FIELD_FLAG_OFFSET) & 2398 FCS_CS_FIELD_FLAG_FINALIZE) { 2399 /* Copy mac data to command 2400 * Using dst_addr (physical address) to store sig_pubkey_offset 2401 * sig_pubkey_offset is Signature + Public Key Data 2402 */ 2403 sig_pubkey_offset = dst_addr; 2404 2405 if ((i + ((src_size - data_size) / MBOX_WORD_BYTE)) > 2406 FCS_ECDSA_SHA2_DATA_SIG_VERIFY_CMD_MAX_WORD_SIZE) { 2407 return INTEL_SIP_SMC_STATUS_REJECTED; 2408 } 2409 2410 memcpy_s(&payload[i], (src_size - data_size) / MBOX_WORD_BYTE, 2411 (void *) sig_pubkey_offset, (src_size - data_size) / MBOX_WORD_BYTE); 2412 2413 memset((void *) dst_addr, 0, *dst_size); 2414 2415 i += (src_size - data_size) / MBOX_WORD_BYTE; 2416 } 2417 2418 status = mailbox_send_cmd_async(send_id, 2419 MBOX_FCS_ECDSA_SHA2_DATA_SIGN_VERIFY, 2420 payload, i, CMD_INDIRECT); 2421 2422 if (is_finalised != 0U) { 2423 memset((void *) &fcs_sha2_data_sig_verify_param, 0, 2424 sizeof(fcs_crypto_service_data)); 2425 } 2426 2427 if (status < 0) { 2428 *mbox_error = -status; 2429 return INTEL_SIP_SMC_STATUS_ERROR; 2430 } 2431 2432 *dst_size = resp_len * MBOX_WORD_BYTE; 2433 flush_dcache_range(dst_addr, *dst_size); 2434 2435 return INTEL_SIP_SMC_STATUS_OK; 2436 } 2437 2438 int intel_fcs_ecdsa_get_pubkey_init(uint32_t session_id, uint32_t context_id, 2439 uint32_t key_id, uint32_t param_size, 2440 uint64_t param_data, uint32_t *mbox_error) 2441 { 2442 return intel_fcs_crypto_service_init(session_id, context_id, 2443 key_id, param_size, param_data, 2444 (void *) &fcs_ecdsa_get_pubkey_param, 2445 mbox_error); 2446 } 2447 2448 int intel_fcs_ecdsa_get_pubkey_finalize(uint32_t smc_fid, uint32_t trans_id, 2449 uint32_t session_id, uint32_t context_id, 2450 uint64_t dst_addr, uint32_t *dst_size, 2451 uint32_t *mbox_error) 2452 { 2453 int status; 2454 int i; 2455 uint32_t crypto_header; 2456 uint32_t ret_size; 2457 uint32_t payload[FCS_ECDSA_GET_PUBKEY_MAX_WORD_SIZE] = {0U}; 2458 2459 if ((dst_size == NULL) || (mbox_error == NULL)) { 2460 return INTEL_SIP_SMC_STATUS_REJECTED; 2461 } 2462 2463 if (!is_address_in_ddr_range(dst_addr, *dst_size)) { 2464 return INTEL_SIP_SMC_STATUS_REJECTED; 2465 } 2466 2467 if (fcs_ecdsa_get_pubkey_param.session_id != session_id || 2468 fcs_ecdsa_get_pubkey_param.context_id != context_id) { 2469 return INTEL_SIP_SMC_STATUS_REJECTED; 2470 } 2471 2472 ret_size = *dst_size / MBOX_WORD_BYTE; 2473 2474 crypto_header = ((FCS_CS_FIELD_FLAG_INIT | 2475 FCS_CS_FIELD_FLAG_UPDATE | 2476 FCS_CS_FIELD_FLAG_FINALIZE) << 2477 FCS_CS_FIELD_FLAG_OFFSET) | 2478 fcs_ecdsa_get_pubkey_param.crypto_param_size; 2479 i = 0; 2480 /* Prepare command payload */ 2481 payload[i] = session_id; 2482 i++; 2483 payload[i] = context_id; 2484 i++; 2485 payload[i] = crypto_header; 2486 i++; 2487 payload[i] = fcs_ecdsa_get_pubkey_param.key_id; 2488 i++; 2489 payload[i] = (uint32_t) fcs_ecdsa_get_pubkey_param.crypto_param & 2490 INTEL_SIP_SMC_FCS_ECC_ALGO_MASK; 2491 i++; 2492 2493 status = (smc_fid == ALTERA_SIP_SMC_ASYNC_FCS_ECDSA_GET_PUBKEY_FINALIZE) ? 2494 mailbox_send_cmd_async_v3(GET_CLIENT_ID(trans_id), 2495 GET_JOB_ID(trans_id), 2496 MBOX_FCS_ECDSA_GET_PUBKEY, 2497 payload, 2498 i, 2499 MBOX_CMD_FLAG_CASUAL, 2500 fcs_cs_get_public_key_cb, 2501 (uint32_t *)dst_addr, 2502 2U) : 2503 mailbox_send_cmd(MBOX_JOB_ID, 2504 MBOX_FCS_ECDSA_GET_PUBKEY, 2505 payload, i, CMD_CASUAL, 2506 (uint32_t *) dst_addr, &ret_size); 2507 2508 memset((void *) &fcs_ecdsa_get_pubkey_param, 0, 2509 sizeof(fcs_crypto_service_data)); 2510 2511 if (status < 0) { 2512 *mbox_error = -status; 2513 return INTEL_SIP_SMC_STATUS_ERROR; 2514 } 2515 2516 *dst_size = ret_size * MBOX_WORD_BYTE; 2517 flush_dcache_range(dst_addr, *dst_size); 2518 2519 return INTEL_SIP_SMC_STATUS_OK; 2520 } 2521 2522 int intel_fcs_ecdh_request_init(uint32_t session_id, uint32_t context_id, 2523 uint32_t key_id, uint32_t param_size, 2524 uint64_t param_data, uint32_t *mbox_error) 2525 { 2526 return intel_fcs_crypto_service_init(session_id, context_id, 2527 key_id, param_size, param_data, 2528 (void *) &fcs_ecdh_request_param, 2529 mbox_error); 2530 } 2531 2532 int intel_fcs_ecdh_request_finalize(uint32_t smc_fid, uint32_t trans_id, 2533 uint32_t session_id, uint32_t context_id, 2534 uint32_t src_addr, uint32_t src_size, 2535 uint64_t dst_addr, uint32_t *dst_size, 2536 uint32_t *mbox_error) 2537 { 2538 int status; 2539 uint32_t i; 2540 uint32_t payload[FCS_ECDH_REQUEST_CMD_MAX_WORD_SIZE] = {0U}; 2541 uint32_t resp_len; 2542 uintptr_t pubkey; 2543 uint32_t dst_size_check = 0; 2544 2545 if ((dst_size == NULL) || (mbox_error == NULL)) { 2546 return INTEL_SIP_SMC_STATUS_REJECTED; 2547 } 2548 2549 if (fcs_ecdh_request_param.session_id != session_id || 2550 fcs_ecdh_request_param.context_id != context_id) { 2551 return INTEL_SIP_SMC_STATUS_REJECTED; 2552 } 2553 2554 if (!is_address_in_ddr_range(src_addr, src_size) || 2555 !is_address_in_ddr_range(dst_addr, *dst_size)) { 2556 return INTEL_SIP_SMC_STATUS_REJECTED; 2557 } 2558 2559 dst_size_check = *dst_size; 2560 2561 if ((dst_size_check > FCS_MAX_DATA_SIZE || dst_size_check < FCS_MIN_DATA_SIZE) || 2562 (src_size > FCS_MAX_DATA_SIZE || src_size < FCS_MIN_DATA_SIZE)) { 2563 return INTEL_SIP_SMC_STATUS_REJECTED; 2564 } 2565 2566 resp_len = *dst_size / MBOX_WORD_BYTE; 2567 2568 /* Prepare command payload */ 2569 i = 0; 2570 /* Crypto header */ 2571 payload[i] = fcs_ecdh_request_param.session_id; 2572 i++; 2573 payload[i] = fcs_ecdh_request_param.context_id; 2574 i++; 2575 payload[i] = fcs_ecdh_request_param.crypto_param_size 2576 & FCS_CS_FIELD_SIZE_MASK; 2577 payload[i] |= (FCS_CS_FIELD_FLAG_INIT | FCS_CS_FIELD_FLAG_UPDATE 2578 | FCS_CS_FIELD_FLAG_FINALIZE) 2579 << FCS_CS_FIELD_FLAG_OFFSET; 2580 i++; 2581 payload[i] = fcs_ecdh_request_param.key_id; 2582 i++; 2583 /* Crypto parameters */ 2584 payload[i] = fcs_ecdh_request_param.crypto_param 2585 & INTEL_SIP_SMC_FCS_ECC_ALGO_MASK; 2586 i++; 2587 /* Public key data */ 2588 pubkey = src_addr; 2589 2590 if ((i + ((src_size) / MBOX_WORD_BYTE)) > 2591 FCS_ECDH_REQUEST_CMD_MAX_WORD_SIZE) { 2592 return INTEL_SIP_SMC_STATUS_REJECTED; 2593 } 2594 2595 memcpy_s(&payload[i], src_size / MBOX_WORD_BYTE, 2596 (void *) pubkey, src_size / MBOX_WORD_BYTE); 2597 i += src_size / MBOX_WORD_BYTE; 2598 2599 status = (smc_fid == ALTERA_SIP_SMC_ASYNC_FCS_ECDH_REQUEST_FINALIZE) ? 2600 mailbox_send_cmd_async_v3(GET_CLIENT_ID(trans_id), 2601 GET_JOB_ID(trans_id), 2602 MBOX_FCS_ECDH_REQUEST, 2603 payload, 2604 i, 2605 MBOX_CMD_FLAG_CASUAL, 2606 fcs_cs_ecdh_request_cb, 2607 (uint32_t *)dst_addr, 2608 2U) : 2609 mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_ECDH_REQUEST, 2610 payload, i, CMD_CASUAL, (uint32_t *) dst_addr, 2611 &resp_len); 2612 2613 memset((void *)&fcs_ecdh_request_param, 0, 2614 sizeof(fcs_crypto_service_data)); 2615 2616 if (status < 0) { 2617 *mbox_error = -status; 2618 return INTEL_SIP_SMC_STATUS_ERROR; 2619 } 2620 2621 *dst_size = resp_len * MBOX_WORD_BYTE; 2622 flush_dcache_range(dst_addr, *dst_size); 2623 2624 return INTEL_SIP_SMC_STATUS_OK; 2625 } 2626 2627 int intel_fcs_aes_crypt_init(uint32_t session_id, uint32_t context_id, 2628 uint32_t key_id, uint64_t param_addr, 2629 uint32_t param_size, uint32_t *mbox_error) 2630 { 2631 /* ptr to get param_addr value */ 2632 uint64_t *param_addr_ptr; 2633 2634 param_addr_ptr = (uint64_t *) param_addr; 2635 2636 /* Check if mbox_error is not NULL or 0xF or 0x3FF */ 2637 if (mbox_error == NULL || *mbox_error > 0xF || 2638 (*mbox_error != 0 && *mbox_error != 0x3FF)) { 2639 return INTEL_SIP_SMC_STATUS_REJECTED; 2640 } 2641 2642 /* Check if param_addr is not 0 or larger that 0xFFFFFFFFFF */ 2643 if (param_addr == 0 || param_addr > 0xFFFFFFFFFF) { 2644 return INTEL_SIP_SMC_STATUS_REJECTED; 2645 } 2646 2647 /* 2648 * Check if not ECB, CBC and CTR, GCM and GCM-GHASH mode (only for Agilex5), 2649 * addr ptr is NULL. Return "Reject" status 2650 */ 2651 if ((param_addr_ptr == NULL) || 2652 (((*param_addr_ptr & FCS_CRYPTO_BLOCK_MODE_MASK) != FCS_CRYPTO_ECB_MODE) && 2653 ((*param_addr_ptr & FCS_CRYPTO_BLOCK_MODE_MASK) != FCS_CRYPTO_CBC_MODE) && 2654 ((*param_addr_ptr & FCS_CRYPTO_BLOCK_MODE_MASK) != FCS_CRYPTO_CTR_MODE) 2655 #if PLATFORM_MODEL == PLAT_SOCFPGA_AGILEX5 2656 && 2657 ((*param_addr_ptr & FCS_CRYPTO_BLOCK_MODE_MASK) != FCS_CRYPTO_GCM_MODE) && 2658 ((*param_addr_ptr & FCS_CRYPTO_BLOCK_MODE_MASK) != FCS_CRYPTO_GCM_GHASH_MODE) 2659 #endif 2660 )){ 2661 return INTEL_SIP_SMC_STATUS_REJECTED; 2662 } 2663 2664 /* 2665 * Since crypto param size vary between mode. 2666 * Check CBC/CTR here and limit to size 28 bytes 2667 */ 2668 if ((((*param_addr_ptr & FCS_CRYPTO_BLOCK_MODE_MASK) == FCS_CRYPTO_CBC_MODE) || 2669 ((*param_addr_ptr & FCS_CRYPTO_BLOCK_MODE_MASK) == FCS_CRYPTO_CTR_MODE) || 2670 ((*param_addr_ptr & FCS_CRYPTO_BLOCK_MODE_MASK) == FCS_CRYPTO_GCM_MODE) || 2671 ((*param_addr_ptr & FCS_CRYPTO_BLOCK_MODE_MASK) == FCS_CRYPTO_GCM_GHASH_MODE)) && 2672 (param_size > FCS_CRYPTO_CBC_CTR_BUFFER_SIZE)) { 2673 return INTEL_SIP_SMC_STATUS_REJECTED; 2674 } 2675 2676 /* 2677 * Since crypto param size vary between mode. 2678 * Check ECB here and limit to size 12 bytes 2679 */ 2680 if (((*param_addr_ptr & FCS_CRYPTO_BLOCK_MODE_MASK) == FCS_CRYPTO_ECB_MODE) && 2681 (param_size > FCS_CRYPTO_ECB_BUFFER_SIZE)) { 2682 return INTEL_SIP_SMC_STATUS_REJECTED; 2683 } 2684 2685 memset((void *)&fcs_aes_init_payload, 0U, sizeof(fcs_aes_init_payload)); 2686 2687 fcs_aes_init_payload.session_id = session_id; 2688 fcs_aes_init_payload.context_id = context_id; 2689 fcs_aes_init_payload.param_size = param_size; 2690 fcs_aes_init_payload.key_id = key_id; 2691 2692 memcpy_s(fcs_aes_init_payload.crypto_param, param_size / MBOX_WORD_BYTE, 2693 (void *) param_addr, param_size / MBOX_WORD_BYTE); 2694 2695 fcs_aes_init_payload.is_updated = 0; 2696 2697 *mbox_error = 0; 2698 2699 return INTEL_SIP_SMC_STATUS_OK; 2700 } 2701 2702 int intel_fcs_aes_crypt_update_finalize(uint32_t smc_fid, uint32_t trans_id, 2703 uint32_t session_id, uint32_t context_id, 2704 uint64_t src_addr, uint32_t src_size, 2705 uint64_t dst_addr, uint32_t dst_size, 2706 uint32_t padding_size, uint8_t is_finalised, 2707 uint32_t *send_id, uint64_t smmu_src_addr, 2708 uint64_t smmu_dst_addr) 2709 { 2710 int status; 2711 int i; 2712 uint32_t flag; 2713 uint32_t crypto_header; 2714 uint32_t fcs_aes_crypt_payload[FCS_AES_CMD_MAX_WORD_SIZE]; 2715 uint32_t src_addr_sdm = (uint32_t)src_addr; 2716 uint32_t dst_addr_sdm = (uint32_t)dst_addr; 2717 bool is_src_size_aligned; 2718 bool is_dst_size_aligned; 2719 bool is_src_size_valid; 2720 bool is_dst_size_valid; 2721 2722 if (fcs_aes_init_payload.session_id != session_id || 2723 fcs_aes_init_payload.context_id != context_id) { 2724 return INTEL_SIP_SMC_STATUS_REJECTED; 2725 } 2726 2727 /* Default source and destination size align check, 32 bytes alignment. */ 2728 is_src_size_aligned = is_32_bytes_aligned(src_size); 2729 is_dst_size_aligned = is_32_bytes_aligned(dst_size); 2730 is_src_size_valid = FCS_AES_DATA_SIZE_CHECK(src_size); 2731 is_dst_size_valid = FCS_AES_DATA_SIZE_CHECK(dst_size); 2732 2733 /* 2734 * Get the requested block mode. 2735 * On the Agilex5 platform with GCM and GCM-GHASH modes, the source and destination size 2736 * should be in multiples of 16 bytes. For other platforms and other modes, it should be 2737 * in multiples of 32 bytes. 2738 */ 2739 #if PLATFORM_MODEL == PLAT_SOCFPGA_AGILEX5 2740 uint32_t block_mode = fcs_aes_init_payload.crypto_param[0] & FCS_CRYPTO_BLOCK_MODE_MASK; 2741 2742 if ((block_mode == FCS_CRYPTO_GCM_MODE) || 2743 (block_mode == FCS_CRYPTO_GCM_GHASH_MODE)) { 2744 is_src_size_aligned = is_16_bytes_aligned(src_size); 2745 is_dst_size_aligned = is_16_bytes_aligned(dst_size); 2746 /* The size validity here is, should be 0 or multiples of 16 bytes. */ 2747 is_src_size_valid = is_16_bytes_aligned(src_size); 2748 is_dst_size_valid = is_16_bytes_aligned(dst_size); 2749 } 2750 #endif 2751 2752 if ((!is_8_bytes_aligned(src_addr)) || 2753 (!is_src_size_aligned) || 2754 (!is_address_in_ddr_range(src_addr, src_size))) { 2755 return INTEL_SIP_SMC_STATUS_REJECTED; 2756 } 2757 2758 if ((!is_8_bytes_aligned(dst_addr)) || 2759 (!is_dst_size_aligned) || 2760 (!is_address_in_ddr_range(dst_addr, dst_size))) { 2761 return INTEL_SIP_SMC_STATUS_REJECTED; 2762 } 2763 2764 if (!is_src_size_valid || !is_dst_size_valid) 2765 return INTEL_SIP_SMC_STATUS_REJECTED; 2766 2767 /* Prepare crypto header*/ 2768 flag = 0; 2769 if (fcs_aes_init_payload.is_updated) { 2770 fcs_aes_init_payload.param_size = 0; 2771 } else { 2772 flag |= FCS_CS_FIELD_FLAG_INIT; 2773 } 2774 2775 if (is_finalised != 0U) { 2776 flag |= FCS_CS_FIELD_FLAG_FINALIZE; 2777 } else { 2778 flag |= FCS_CS_FIELD_FLAG_UPDATE; 2779 fcs_aes_init_payload.is_updated = 1; 2780 } 2781 crypto_header = (flag << FCS_CS_FIELD_FLAG_OFFSET) | 2782 fcs_aes_init_payload.param_size; 2783 2784 i = 0U; 2785 fcs_aes_crypt_payload[i] = session_id; 2786 i++; 2787 fcs_aes_crypt_payload[i] = context_id; 2788 i++; 2789 fcs_aes_crypt_payload[i] = crypto_header; 2790 i++; 2791 2792 if ((crypto_header >> FCS_CS_FIELD_FLAG_OFFSET) & 2793 (FCS_CS_FIELD_FLAG_INIT)) { 2794 fcs_aes_crypt_payload[i] = fcs_aes_init_payload.key_id; 2795 i++; 2796 2797 if ((i + ((fcs_aes_init_payload.param_size) / MBOX_WORD_BYTE)) > 2798 FCS_AES_CMD_MAX_WORD_SIZE) { 2799 return INTEL_SIP_SMC_STATUS_REJECTED; 2800 } 2801 2802 memcpy_s(&fcs_aes_crypt_payload[i], 2803 fcs_aes_init_payload.param_size / MBOX_WORD_BYTE, 2804 (void *) fcs_aes_init_payload.crypto_param, 2805 fcs_aes_init_payload.param_size / MBOX_WORD_BYTE); 2806 2807 i += fcs_aes_init_payload.param_size / MBOX_WORD_BYTE; 2808 } 2809 2810 /* On the Agilex5 platform, we will use the SMMU payload address */ 2811 #if PLATFORM_MODEL == PLAT_SOCFPGA_AGILEX5 2812 src_addr_sdm = (uint32_t)smmu_src_addr; 2813 dst_addr_sdm = (uint32_t)smmu_dst_addr; 2814 #endif 2815 2816 fcs_aes_crypt_payload[i] = src_addr_sdm; 2817 i++; 2818 fcs_aes_crypt_payload[i] = src_size; 2819 i++; 2820 fcs_aes_crypt_payload[i] = dst_addr_sdm; 2821 i++; 2822 fcs_aes_crypt_payload[i] = dst_size; 2823 i++; 2824 2825 /* Padding data size, only on Agilex5 with GCM and GCM-GHASH modes. */ 2826 #if PLATFORM_MODEL == PLAT_SOCFPGA_AGILEX5 2827 if ((block_mode == FCS_CRYPTO_GCM_MODE) || 2828 (block_mode == FCS_CRYPTO_GCM_GHASH_MODE)) { 2829 fcs_aes_crypt_payload[i] = padding_size; 2830 i++; 2831 } 2832 #endif 2833 2834 status = ((smc_fid == ALTERA_SIP_SMC_ASYNC_FCS_AES_CRYPT_UPDATE) || 2835 (smc_fid == ALTERA_SIP_SMC_ASYNC_FCS_AES_CRYPT_FINALIZE)) ? 2836 mailbox_send_cmd_async_v3(GET_CLIENT_ID(trans_id), 2837 GET_JOB_ID(trans_id), 2838 MBOX_FCS_AES_CRYPT_REQ, 2839 fcs_aes_crypt_payload, 2840 i, 2841 MBOX_CMD_FLAG_INDIRECT, 2842 fcs_cs_aes_cb, 2843 NULL, 2844 0U) : 2845 mailbox_send_cmd_async(send_id, MBOX_FCS_AES_CRYPT_REQ, 2846 fcs_aes_crypt_payload, i, CMD_INDIRECT); 2847 2848 2849 if (is_finalised != 0U) { 2850 memset((void *)&fcs_aes_init_payload, 0, 2851 sizeof(fcs_aes_init_payload)); 2852 } 2853 2854 if (status < 0) { 2855 return INTEL_SIP_SMC_STATUS_ERROR; 2856 } 2857 2858 return INTEL_SIP_SMC_STATUS_OK; 2859 } 2860 2861 int intel_fcs_hkdf_request(uint32_t smc_fid, uint32_t trans_id, 2862 uint32_t session_id, uint32_t step_type, 2863 uint32_t mac_mode, uint32_t src_addr, 2864 uint32_t key_uid, uint32_t op_key_size) 2865 { 2866 int status; 2867 uint32_t i = 0; 2868 uintptr_t inputdata; 2869 uint32_t payload[FCS_HKDF_REQUEST_DATA_SIZE] = {0U}; 2870 2871 if (!is_address_in_ddr_range(src_addr, FCS_HKDF_REQUEST_DATA_SIZE)) { 2872 ERROR("MBOX: %s: source addr not in the DDR range\n", __func__); 2873 return INTEL_SIP_SMC_STATUS_REJECTED; 2874 } 2875 2876 /* Prepare command payload */ 2877 2878 /* Session ID */ 2879 payload[i] = session_id; 2880 i++; 2881 2882 /* Reserved, 8 bytes */ 2883 payload[i] = 0; 2884 i++; 2885 2886 payload[i] = 0; 2887 i++; 2888 2889 /* HKDF step type */ 2890 payload[i] = step_type; 2891 i++; 2892 2893 /* MAC mode/PRF */ 2894 payload[i] = mac_mode; 2895 i++; 2896 2897 /* Complete input data, 1st input data len + its data + 2nd input data len + its data. */ 2898 inputdata = src_addr; 2899 memcpy_s((uint8_t *)&payload[i], FCS_HKDF_KEY_DATA_SIZE / sizeof(uint32_t), 2900 (uint8_t *)inputdata, FCS_HKDF_KEY_DATA_SIZE / sizeof(uint32_t)); 2901 2902 i += FCS_HKDF_KEY_DATA_SIZE / sizeof(uint32_t); 2903 2904 /* Key UID */ 2905 payload[i] = key_uid; 2906 i++; 2907 2908 /* Pointer to size of output key object */ 2909 inputdata = inputdata + FCS_HKDF_KEY_DATA_SIZE; 2910 2911 /* Output Key object */ 2912 memcpy_s(&payload[i], op_key_size / sizeof(uint32_t), (void *)inputdata, 2913 op_key_size / sizeof(uint32_t)); 2914 2915 i += op_key_size / sizeof(uint32_t); 2916 2917 status = mailbox_send_cmd_async_v3(GET_CLIENT_ID(trans_id), 2918 GET_JOB_ID(trans_id), 2919 MBOX_FCS_HKDF_REQUEST, 2920 payload, 2921 i, 2922 MBOX_CMD_FLAG_CASUAL, 2923 fcs_hkdf_request_cb, 2924 NULL, 2925 0U); 2926 2927 if (status < 0) { 2928 ERROR("MBOX: %s: status %d\n", __func__, status); 2929 return INTEL_SIP_SMC_STATUS_ERROR; 2930 } 2931 2932 return INTEL_SIP_SMC_STATUS_OK; 2933 } 2934