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 if (status < 0) { 78 return INTEL_SIP_SMC_STATUS_ERROR; 79 } 80 81 return INTEL_SIP_SMC_STATUS_OK; 82 } 83 84 uint32_t intel_fcs_get_provision_data(uint32_t *send_id) 85 { 86 int status; 87 88 status = mailbox_send_cmd_async(send_id, MBOX_FCS_GET_PROVISION, 89 NULL, 0U, CMD_DIRECT); 90 91 if (status < 0) { 92 return INTEL_SIP_SMC_STATUS_ERROR; 93 } 94 95 return INTEL_SIP_SMC_STATUS_OK; 96 } 97 98 uint32_t intel_fcs_cntr_set_preauth(uint8_t counter_type, int32_t counter_value, 99 uint32_t test_bit, uint32_t *mbox_error) 100 { 101 int status; 102 uint32_t first_word; 103 uint32_t payload_size; 104 105 if ((test_bit != MBOX_TEST_BIT) && 106 (test_bit != 0)) { 107 return INTEL_SIP_SMC_STATUS_REJECTED; 108 } 109 110 if ((counter_type < FCS_BIG_CNTR_SEL) || 111 (counter_type > FCS_SVN_CNTR_3_SEL)) { 112 return INTEL_SIP_SMC_STATUS_REJECTED; 113 } 114 115 if ((counter_type == FCS_BIG_CNTR_SEL) && 116 (counter_value > FCS_BIG_CNTR_VAL_MAX)) { 117 return INTEL_SIP_SMC_STATUS_REJECTED; 118 } 119 120 if ((counter_type >= FCS_SVN_CNTR_0_SEL) && 121 (counter_type <= FCS_SVN_CNTR_3_SEL) && 122 (counter_value > FCS_SVN_CNTR_VAL_MAX)) { 123 return INTEL_SIP_SMC_STATUS_REJECTED; 124 } 125 126 first_word = test_bit | counter_type; 127 fcs_cntr_set_preauth_payload payload = { 128 first_word, 129 counter_value 130 }; 131 132 payload_size = sizeof(payload) / MBOX_WORD_BYTE; 133 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_CNTR_SET_PREAUTH, 134 (uint32_t *) &payload, payload_size, 135 CMD_CASUAL, NULL, NULL); 136 137 if (status < 0) { 138 *mbox_error = -status; 139 return INTEL_SIP_SMC_STATUS_ERROR; 140 } 141 142 return INTEL_SIP_SMC_STATUS_OK; 143 } 144 145 uint32_t intel_fcs_encryption(uint32_t src_addr, uint32_t src_size, 146 uint32_t dst_addr, uint32_t dst_size, uint32_t *send_id) 147 { 148 int status; 149 uint32_t load_size; 150 151 fcs_encrypt_payload payload = { 152 FCS_ENCRYPTION_DATA_0, 153 src_addr, 154 src_size, 155 dst_addr, 156 dst_size }; 157 load_size = sizeof(payload) / MBOX_WORD_BYTE; 158 159 if (!is_address_in_ddr_range(src_addr, src_size) || 160 !is_address_in_ddr_range(dst_addr, dst_size)) { 161 return INTEL_SIP_SMC_STATUS_REJECTED; 162 } 163 164 if (!is_size_4_bytes_aligned(src_size)) { 165 return INTEL_SIP_SMC_STATUS_REJECTED; 166 } 167 168 status = mailbox_send_cmd_async(send_id, MBOX_FCS_ENCRYPT_REQ, 169 (uint32_t *) &payload, load_size, 170 CMD_INDIRECT); 171 inv_dcache_range(dst_addr, dst_size); 172 173 if (status < 0) { 174 return INTEL_SIP_SMC_STATUS_REJECTED; 175 } 176 177 return INTEL_SIP_SMC_STATUS_OK; 178 } 179 180 uint32_t intel_fcs_decryption(uint32_t src_addr, uint32_t src_size, 181 uint32_t dst_addr, uint32_t dst_size, uint32_t *send_id) 182 { 183 int status; 184 uint32_t load_size; 185 uintptr_t id_offset; 186 187 id_offset = src_addr + FCS_OWNER_ID_OFFSET; 188 fcs_decrypt_payload payload = { 189 FCS_DECRYPTION_DATA_0, 190 {mmio_read_32(id_offset), 191 mmio_read_32(id_offset + MBOX_WORD_BYTE)}, 192 src_addr, 193 src_size, 194 dst_addr, 195 dst_size }; 196 load_size = sizeof(payload) / MBOX_WORD_BYTE; 197 198 if (!is_address_in_ddr_range(src_addr, src_size) || 199 !is_address_in_ddr_range(dst_addr, dst_size)) { 200 return INTEL_SIP_SMC_STATUS_REJECTED; 201 } 202 203 if (!is_size_4_bytes_aligned(src_size)) { 204 return INTEL_SIP_SMC_STATUS_REJECTED; 205 } 206 207 status = mailbox_send_cmd_async(send_id, MBOX_FCS_DECRYPT_REQ, 208 (uint32_t *) &payload, load_size, 209 CMD_INDIRECT); 210 inv_dcache_range(dst_addr, dst_size); 211 212 if (status < 0) { 213 return INTEL_SIP_SMC_STATUS_REJECTED; 214 } 215 216 return INTEL_SIP_SMC_STATUS_OK; 217 } 218 219 uint32_t intel_fcs_get_rom_patch_sha384(uint64_t addr, uint64_t *ret_size, 220 uint32_t *mbox_error) 221 { 222 int status; 223 unsigned int resp_len = FCS_SHA384_WORD_SIZE; 224 225 if (!is_address_in_ddr_range(addr, FCS_SHA384_BYTE_SIZE)) { 226 return INTEL_SIP_SMC_STATUS_REJECTED; 227 } 228 229 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_GET_ROM_PATCH_SHA384, NULL, 0U, 230 CMD_CASUAL, (uint32_t *) addr, &resp_len); 231 232 if (status < 0) { 233 *mbox_error = -status; 234 return INTEL_SIP_SMC_STATUS_ERROR; 235 } 236 237 if (resp_len != FCS_SHA384_WORD_SIZE) { 238 *mbox_error = GENERIC_RESPONSE_ERROR; 239 return INTEL_SIP_SMC_STATUS_ERROR; 240 } 241 242 *ret_size = FCS_SHA384_BYTE_SIZE; 243 244 flush_dcache_range(addr, *ret_size); 245 246 return INTEL_SIP_SMC_STATUS_OK; 247 } 248 249 int intel_fcs_sigma_teardown(uint32_t session_id, uint32_t *mbox_error) 250 { 251 int status; 252 253 if ((session_id != PSGSIGMA_SESSION_ID_ONE) && 254 (session_id != PSGSIGMA_UNKNOWN_SESSION)) { 255 return INTEL_SIP_SMC_STATUS_REJECTED; 256 } 257 258 psgsigma_teardown_msg message = { 259 RESERVED_AS_ZERO, 260 PSGSIGMA_TEARDOWN_MAGIC, 261 session_id 262 }; 263 264 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_PSG_SIGMA_TEARDOWN, 265 (uint32_t *) &message, sizeof(message) / MBOX_WORD_BYTE, 266 CMD_CASUAL, NULL, NULL); 267 268 if (status < 0) { 269 *mbox_error = -status; 270 return INTEL_SIP_SMC_STATUS_ERROR; 271 } 272 273 return INTEL_SIP_SMC_STATUS_OK; 274 } 275 276 int intel_fcs_chip_id(uint32_t *id_low, uint32_t *id_high, uint32_t *mbox_error) 277 { 278 int status; 279 uint32_t load_size; 280 uint32_t chip_id[2]; 281 282 load_size = sizeof(chip_id) / MBOX_WORD_BYTE; 283 284 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_CMD_GET_CHIPID, NULL, 285 0U, CMD_CASUAL, (uint32_t *) chip_id, &load_size); 286 287 if (status < 0) { 288 *mbox_error = -status; 289 return INTEL_SIP_SMC_STATUS_ERROR; 290 } 291 292 *id_low = chip_id[0]; 293 *id_high = chip_id[1]; 294 295 return INTEL_SIP_SMC_STATUS_OK; 296 } 297 298 int intel_fcs_attestation_subkey(uint64_t src_addr, uint32_t src_size, 299 uint64_t dst_addr, uint32_t *dst_size, uint32_t *mbox_error) 300 { 301 int status; 302 uint32_t send_size = src_size / MBOX_WORD_BYTE; 303 uint32_t ret_size = *dst_size / MBOX_WORD_BYTE; 304 305 306 if (!is_address_in_ddr_range(src_addr, src_size) || 307 !is_address_in_ddr_range(dst_addr, *dst_size)) { 308 return INTEL_SIP_SMC_STATUS_REJECTED; 309 } 310 311 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_ATTESTATION_SUBKEY, 312 (uint32_t *) src_addr, send_size, CMD_CASUAL, 313 (uint32_t *) dst_addr, &ret_size); 314 315 if (status < 0) { 316 *mbox_error = -status; 317 return INTEL_SIP_SMC_STATUS_ERROR; 318 } 319 320 *dst_size = ret_size * MBOX_WORD_BYTE; 321 flush_dcache_range(dst_addr, *dst_size); 322 323 return INTEL_SIP_SMC_STATUS_OK; 324 } 325 326 int intel_fcs_get_measurement(uint64_t src_addr, uint32_t src_size, 327 uint64_t dst_addr, uint32_t *dst_size, uint32_t *mbox_error) 328 { 329 int status; 330 uint32_t send_size = src_size / MBOX_WORD_BYTE; 331 uint32_t ret_size = *dst_size / MBOX_WORD_BYTE; 332 333 if (!is_address_in_ddr_range(src_addr, src_size) || 334 !is_address_in_ddr_range(dst_addr, *dst_size)) { 335 return INTEL_SIP_SMC_STATUS_REJECTED; 336 } 337 338 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_GET_MEASUREMENT, 339 (uint32_t *) src_addr, send_size, CMD_CASUAL, 340 (uint32_t *) dst_addr, &ret_size); 341 342 if (status < 0) { 343 *mbox_error = -status; 344 return INTEL_SIP_SMC_STATUS_ERROR; 345 } 346 347 *dst_size = ret_size * MBOX_WORD_BYTE; 348 flush_dcache_range(dst_addr, *dst_size); 349 350 return INTEL_SIP_SMC_STATUS_OK; 351 } 352