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 bool is_size_4_bytes_aligned(uint32_t size) 15 { 16 if ((size % MBOX_WORD_BYTE) != 0U) { 17 return false; 18 } else { 19 return true; 20 } 21 } 22 23 uint32_t intel_fcs_random_number_gen(uint64_t addr, uint64_t *ret_size, 24 uint32_t *mbox_error) 25 { 26 int status; 27 unsigned int i; 28 unsigned int resp_len = FCS_RANDOM_WORD_SIZE; 29 uint32_t random_data[FCS_RANDOM_WORD_SIZE] = {0U}; 30 31 if (!is_address_in_ddr_range(addr, FCS_RANDOM_BYTE_SIZE)) { 32 return INTEL_SIP_SMC_STATUS_REJECTED; 33 } 34 35 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_RANDOM_GEN, NULL, 0U, 36 CMD_CASUAL, random_data, &resp_len); 37 38 if (status < 0) { 39 *mbox_error = -status; 40 return INTEL_SIP_SMC_STATUS_ERROR; 41 } 42 43 if (resp_len != FCS_RANDOM_WORD_SIZE) { 44 *mbox_error = GENERIC_RESPONSE_ERROR; 45 return INTEL_SIP_SMC_STATUS_ERROR; 46 } 47 48 *ret_size = FCS_RANDOM_BYTE_SIZE; 49 50 for (i = 0U; i < FCS_RANDOM_WORD_SIZE; i++) { 51 mmio_write_32(addr, random_data[i]); 52 addr += MBOX_WORD_BYTE; 53 } 54 55 flush_dcache_range(addr - *ret_size, *ret_size); 56 57 return INTEL_SIP_SMC_STATUS_OK; 58 } 59 60 uint32_t intel_fcs_send_cert(uint64_t addr, uint64_t size, 61 uint32_t *send_id) 62 { 63 int status; 64 65 if (!is_address_in_ddr_range(addr, size)) { 66 return INTEL_SIP_SMC_STATUS_REJECTED; 67 } 68 69 if (!is_size_4_bytes_aligned(size)) { 70 return INTEL_SIP_SMC_STATUS_REJECTED; 71 } 72 73 status = mailbox_send_cmd_async(send_id, MBOX_CMD_VAB_SRC_CERT, 74 (uint32_t *)addr, size / MBOX_WORD_BYTE, 75 CMD_DIRECT); 76 77 flush_dcache_range(addr, size); 78 79 if (status < 0) { 80 return INTEL_SIP_SMC_STATUS_ERROR; 81 } 82 83 return INTEL_SIP_SMC_STATUS_OK; 84 } 85 86 uint32_t intel_fcs_get_provision_data(uint32_t *send_id) 87 { 88 int status; 89 90 status = mailbox_send_cmd_async(send_id, MBOX_FCS_GET_PROVISION, 91 NULL, 0U, CMD_DIRECT); 92 93 if (status < 0) { 94 return INTEL_SIP_SMC_STATUS_ERROR; 95 } 96 97 return INTEL_SIP_SMC_STATUS_OK; 98 } 99 100 uint32_t intel_fcs_cntr_set_preauth(uint8_t counter_type, int32_t counter_value, 101 uint32_t test_bit, uint32_t *mbox_error) 102 { 103 int status; 104 uint32_t first_word; 105 uint32_t payload_size; 106 107 if ((test_bit != MBOX_TEST_BIT) && 108 (test_bit != 0)) { 109 return INTEL_SIP_SMC_STATUS_REJECTED; 110 } 111 112 if ((counter_type < FCS_BIG_CNTR_SEL) || 113 (counter_type > FCS_SVN_CNTR_3_SEL)) { 114 return INTEL_SIP_SMC_STATUS_REJECTED; 115 } 116 117 if ((counter_type == FCS_BIG_CNTR_SEL) && 118 (counter_value > FCS_BIG_CNTR_VAL_MAX)) { 119 return INTEL_SIP_SMC_STATUS_REJECTED; 120 } 121 122 if ((counter_type >= FCS_SVN_CNTR_0_SEL) && 123 (counter_type <= FCS_SVN_CNTR_3_SEL) && 124 (counter_value > FCS_SVN_CNTR_VAL_MAX)) { 125 return INTEL_SIP_SMC_STATUS_REJECTED; 126 } 127 128 first_word = test_bit | counter_type; 129 fcs_cntr_set_preauth_payload payload = { 130 first_word, 131 counter_value 132 }; 133 134 payload_size = sizeof(payload) / MBOX_WORD_BYTE; 135 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_CNTR_SET_PREAUTH, 136 (uint32_t *) &payload, payload_size, 137 CMD_CASUAL, NULL, NULL); 138 139 if (status < 0) { 140 *mbox_error = -status; 141 return INTEL_SIP_SMC_STATUS_ERROR; 142 } 143 144 return INTEL_SIP_SMC_STATUS_OK; 145 } 146 147 uint32_t intel_fcs_encryption(uint32_t src_addr, uint32_t src_size, 148 uint32_t dst_addr, uint32_t dst_size, uint32_t *send_id) 149 { 150 int status; 151 uint32_t load_size; 152 153 fcs_encrypt_payload payload = { 154 FCS_ENCRYPTION_DATA_0, 155 src_addr, 156 src_size, 157 dst_addr, 158 dst_size }; 159 load_size = sizeof(payload) / MBOX_WORD_BYTE; 160 161 if (!is_address_in_ddr_range(src_addr, src_size) || 162 !is_address_in_ddr_range(dst_addr, dst_size)) { 163 return INTEL_SIP_SMC_STATUS_REJECTED; 164 } 165 166 if (!is_size_4_bytes_aligned(src_size)) { 167 return INTEL_SIP_SMC_STATUS_REJECTED; 168 } 169 170 status = mailbox_send_cmd_async(send_id, MBOX_FCS_ENCRYPT_REQ, 171 (uint32_t *) &payload, load_size, 172 CMD_INDIRECT); 173 inv_dcache_range(dst_addr, dst_size); 174 175 if (status < 0) { 176 return INTEL_SIP_SMC_STATUS_REJECTED; 177 } 178 179 return INTEL_SIP_SMC_STATUS_OK; 180 } 181 182 uint32_t intel_fcs_decryption(uint32_t src_addr, uint32_t src_size, 183 uint32_t dst_addr, uint32_t dst_size, uint32_t *send_id) 184 { 185 int status; 186 uint32_t load_size; 187 uintptr_t id_offset; 188 189 id_offset = src_addr + FCS_OWNER_ID_OFFSET; 190 fcs_decrypt_payload payload = { 191 FCS_DECRYPTION_DATA_0, 192 {mmio_read_32(id_offset), 193 mmio_read_32(id_offset + MBOX_WORD_BYTE)}, 194 src_addr, 195 src_size, 196 dst_addr, 197 dst_size }; 198 load_size = sizeof(payload) / MBOX_WORD_BYTE; 199 200 if (!is_address_in_ddr_range(src_addr, src_size) || 201 !is_address_in_ddr_range(dst_addr, dst_size)) { 202 return INTEL_SIP_SMC_STATUS_REJECTED; 203 } 204 205 if (!is_size_4_bytes_aligned(src_size)) { 206 return INTEL_SIP_SMC_STATUS_REJECTED; 207 } 208 209 status = mailbox_send_cmd_async(send_id, MBOX_FCS_DECRYPT_REQ, 210 (uint32_t *) &payload, load_size, 211 CMD_INDIRECT); 212 inv_dcache_range(dst_addr, dst_size); 213 214 if (status < 0) { 215 return INTEL_SIP_SMC_STATUS_REJECTED; 216 } 217 218 return INTEL_SIP_SMC_STATUS_OK; 219 } 220 221 uint32_t intel_fcs_get_rom_patch_sha384(uint64_t addr, uint64_t *ret_size, 222 uint32_t *mbox_error) 223 { 224 int status; 225 unsigned int resp_len = FCS_SHA384_WORD_SIZE; 226 227 if (!is_address_in_ddr_range(addr, FCS_SHA384_BYTE_SIZE)) { 228 return INTEL_SIP_SMC_STATUS_REJECTED; 229 } 230 231 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_GET_ROM_PATCH_SHA384, NULL, 0U, 232 CMD_CASUAL, (uint32_t *) addr, &resp_len); 233 234 if (status < 0) { 235 *mbox_error = -status; 236 return INTEL_SIP_SMC_STATUS_ERROR; 237 } 238 239 if (resp_len != FCS_SHA384_WORD_SIZE) { 240 *mbox_error = GENERIC_RESPONSE_ERROR; 241 return INTEL_SIP_SMC_STATUS_ERROR; 242 } 243 244 *ret_size = FCS_SHA384_BYTE_SIZE; 245 246 flush_dcache_range(addr, *ret_size); 247 248 return INTEL_SIP_SMC_STATUS_OK; 249 } 250 251 int intel_fcs_sigma_teardown(uint32_t session_id, uint32_t *mbox_error) 252 { 253 int status; 254 255 if ((session_id != PSGSIGMA_SESSION_ID_ONE) && 256 (session_id != PSGSIGMA_UNKNOWN_SESSION)) { 257 return INTEL_SIP_SMC_STATUS_REJECTED; 258 } 259 260 psgsigma_teardown_msg message = { 261 RESERVED_AS_ZERO, 262 PSGSIGMA_TEARDOWN_MAGIC, 263 session_id 264 }; 265 266 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_PSG_SIGMA_TEARDOWN, 267 (uint32_t *) &message, sizeof(message) / MBOX_WORD_BYTE, 268 CMD_CASUAL, NULL, NULL); 269 270 if (status < 0) { 271 *mbox_error = -status; 272 return INTEL_SIP_SMC_STATUS_ERROR; 273 } 274 275 return INTEL_SIP_SMC_STATUS_OK; 276 } 277 278 int intel_fcs_chip_id(uint32_t *id_low, uint32_t *id_high, uint32_t *mbox_error) 279 { 280 int status; 281 uint32_t load_size; 282 uint32_t chip_id[2]; 283 284 load_size = sizeof(chip_id) / MBOX_WORD_BYTE; 285 286 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_CMD_GET_CHIPID, NULL, 287 0U, CMD_CASUAL, (uint32_t *) chip_id, &load_size); 288 289 if (status < 0) { 290 *mbox_error = -status; 291 return INTEL_SIP_SMC_STATUS_ERROR; 292 } 293 294 *id_low = chip_id[0]; 295 *id_high = chip_id[1]; 296 297 return INTEL_SIP_SMC_STATUS_OK; 298 } 299 300 int intel_fcs_attestation_subkey(uint64_t src_addr, uint32_t src_size, 301 uint64_t dst_addr, uint32_t *dst_size, uint32_t *mbox_error) 302 { 303 int status; 304 uint32_t send_size = src_size / MBOX_WORD_BYTE; 305 uint32_t ret_size = *dst_size / MBOX_WORD_BYTE; 306 307 308 if (!is_address_in_ddr_range(src_addr, src_size) || 309 !is_address_in_ddr_range(dst_addr, *dst_size)) { 310 return INTEL_SIP_SMC_STATUS_REJECTED; 311 } 312 313 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_ATTESTATION_SUBKEY, 314 (uint32_t *) src_addr, send_size, CMD_CASUAL, 315 (uint32_t *) dst_addr, &ret_size); 316 317 if (status < 0) { 318 *mbox_error = -status; 319 return INTEL_SIP_SMC_STATUS_ERROR; 320 } 321 322 *dst_size = ret_size * MBOX_WORD_BYTE; 323 flush_dcache_range(dst_addr, *dst_size); 324 325 return INTEL_SIP_SMC_STATUS_OK; 326 } 327 328 int intel_fcs_get_measurement(uint64_t src_addr, uint32_t src_size, 329 uint64_t dst_addr, uint32_t *dst_size, uint32_t *mbox_error) 330 { 331 int status; 332 uint32_t send_size = src_size / MBOX_WORD_BYTE; 333 uint32_t ret_size = *dst_size / MBOX_WORD_BYTE; 334 335 if (!is_address_in_ddr_range(src_addr, src_size) || 336 !is_address_in_ddr_range(dst_addr, *dst_size)) { 337 return INTEL_SIP_SMC_STATUS_REJECTED; 338 } 339 340 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_GET_MEASUREMENT, 341 (uint32_t *) src_addr, send_size, CMD_CASUAL, 342 (uint32_t *) dst_addr, &ret_size); 343 344 if (status < 0) { 345 *mbox_error = -status; 346 return INTEL_SIP_SMC_STATUS_ERROR; 347 } 348 349 *dst_size = ret_size * MBOX_WORD_BYTE; 350 flush_dcache_range(dst_addr, *dst_size); 351 352 return INTEL_SIP_SMC_STATUS_OK; 353 } 354 355 int intel_fcs_get_attestation_cert(uint32_t cert_request, uint64_t dst_addr, 356 uint32_t *dst_size, uint32_t *mbox_error) 357 { 358 int status; 359 uint32_t ret_size = *dst_size / MBOX_WORD_BYTE; 360 361 if (mbox_error == NULL) { 362 return INTEL_SIP_SMC_STATUS_REJECTED; 363 } 364 365 if (cert_request < FCS_ALIAS_CERT || 366 cert_request > 367 (FCS_ALIAS_CERT | 368 FCS_DEV_ID_SELF_SIGN_CERT | 369 FCS_DEV_ID_ENROLL_CERT | 370 FCS_ENROLL_SELF_SIGN_CERT | 371 FCS_PLAT_KEY_CERT)) { 372 return INTEL_SIP_SMC_STATUS_REJECTED; 373 } 374 375 if (!is_address_in_ddr_range(dst_addr, *dst_size)) { 376 return INTEL_SIP_SMC_STATUS_REJECTED; 377 } 378 379 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_GET_ATTESTATION_CERT, 380 (uint32_t *) &cert_request, 1U, CMD_CASUAL, 381 (uint32_t *) dst_addr, &ret_size); 382 383 if (status < 0) { 384 *mbox_error = -status; 385 return INTEL_SIP_SMC_STATUS_ERROR; 386 } 387 388 *dst_size = ret_size * MBOX_WORD_BYTE; 389 flush_dcache_range(dst_addr, *dst_size); 390 391 return INTEL_SIP_SMC_STATUS_OK; 392 } 393 394 int intel_fcs_create_cert_on_reload(uint32_t cert_request, 395 uint32_t *mbox_error) 396 { 397 int status; 398 399 if (mbox_error == NULL) { 400 return INTEL_SIP_SMC_STATUS_REJECTED; 401 } 402 403 if (cert_request < FCS_ALIAS_CERT || 404 cert_request > 405 (FCS_ALIAS_CERT | 406 FCS_DEV_ID_SELF_SIGN_CERT | 407 FCS_DEV_ID_ENROLL_CERT | 408 FCS_ENROLL_SELF_SIGN_CERT | 409 FCS_PLAT_KEY_CERT)) { 410 return INTEL_SIP_SMC_STATUS_REJECTED; 411 } 412 413 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_CREATE_CERT_ON_RELOAD, 414 (uint32_t *) &cert_request, 1U, CMD_CASUAL, 415 NULL, NULL); 416 417 if (status < 0) { 418 *mbox_error = -status; 419 return INTEL_SIP_SMC_STATUS_ERROR; 420 } 421 422 return INTEL_SIP_SMC_STATUS_OK; 423 } 424