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_encryption(uint32_t src_addr, uint32_t src_size, 99 uint32_t dst_addr, uint32_t dst_size, uint32_t *send_id) 100 { 101 int status; 102 uint32_t load_size; 103 104 fcs_encrypt_payload payload = { 105 FCS_ENCRYPTION_DATA_0, 106 src_addr, 107 src_size, 108 dst_addr, 109 dst_size }; 110 load_size = sizeof(payload) / MBOX_WORD_BYTE; 111 112 if (!is_address_in_ddr_range(src_addr, src_size) || 113 !is_address_in_ddr_range(dst_addr, dst_size)) { 114 return INTEL_SIP_SMC_STATUS_REJECTED; 115 } 116 117 if (!is_size_4_bytes_aligned(src_size)) { 118 return INTEL_SIP_SMC_STATUS_REJECTED; 119 } 120 121 status = mailbox_send_cmd_async(send_id, MBOX_FCS_ENCRYPT_REQ, 122 (uint32_t *) &payload, load_size, 123 CMD_INDIRECT); 124 inv_dcache_range(dst_addr, dst_size); 125 126 if (status < 0) { 127 return INTEL_SIP_SMC_STATUS_REJECTED; 128 } 129 130 return INTEL_SIP_SMC_STATUS_OK; 131 } 132 133 uint32_t intel_fcs_decryption(uint32_t src_addr, uint32_t src_size, 134 uint32_t dst_addr, uint32_t dst_size, uint32_t *send_id) 135 { 136 int status; 137 uint32_t load_size; 138 uintptr_t id_offset; 139 140 id_offset = src_addr + FCS_OWNER_ID_OFFSET; 141 fcs_decrypt_payload payload = { 142 FCS_DECRYPTION_DATA_0, 143 {mmio_read_32(id_offset), 144 mmio_read_32(id_offset + MBOX_WORD_BYTE)}, 145 src_addr, 146 src_size, 147 dst_addr, 148 dst_size }; 149 load_size = sizeof(payload) / MBOX_WORD_BYTE; 150 151 if (!is_address_in_ddr_range(src_addr, src_size) || 152 !is_address_in_ddr_range(dst_addr, dst_size)) { 153 return INTEL_SIP_SMC_STATUS_REJECTED; 154 } 155 156 if (!is_size_4_bytes_aligned(src_size)) { 157 return INTEL_SIP_SMC_STATUS_REJECTED; 158 } 159 160 status = mailbox_send_cmd_async(send_id, MBOX_FCS_DECRYPT_REQ, 161 (uint32_t *) &payload, load_size, 162 CMD_INDIRECT); 163 inv_dcache_range(dst_addr, dst_size); 164 165 if (status < 0) { 166 return INTEL_SIP_SMC_STATUS_REJECTED; 167 } 168 169 return INTEL_SIP_SMC_STATUS_OK; 170 } 171 172 uint32_t intel_fcs_get_rom_patch_sha384(uint64_t addr, uint64_t *ret_size, 173 uint32_t *mbox_error) 174 { 175 int status; 176 unsigned int resp_len = FCS_SHA384_WORD_SIZE; 177 178 if (!is_address_in_ddr_range(addr, FCS_SHA384_BYTE_SIZE)) { 179 return INTEL_SIP_SMC_STATUS_REJECTED; 180 } 181 182 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_GET_ROM_PATCH_SHA384, NULL, 0U, 183 CMD_CASUAL, (uint32_t *) addr, &resp_len); 184 185 if (status < 0) { 186 *mbox_error = -status; 187 return INTEL_SIP_SMC_STATUS_ERROR; 188 } 189 190 if (resp_len != FCS_SHA384_WORD_SIZE) { 191 *mbox_error = GENERIC_RESPONSE_ERROR; 192 return INTEL_SIP_SMC_STATUS_ERROR; 193 } 194 195 *ret_size = FCS_SHA384_BYTE_SIZE; 196 197 flush_dcache_range(addr, *ret_size); 198 199 return INTEL_SIP_SMC_STATUS_OK; 200 } 201 202 int intel_fcs_sigma_teardown(uint32_t session_id, uint32_t *mbox_error) 203 { 204 int status; 205 206 if ((session_id != PSGSIGMA_SESSION_ID_ONE) && 207 (session_id != PSGSIGMA_UNKNOWN_SESSION)) { 208 return INTEL_SIP_SMC_STATUS_REJECTED; 209 } 210 211 psgsigma_teardown_msg message = { 212 RESERVED_AS_ZERO, 213 PSGSIGMA_TEARDOWN_MAGIC, 214 session_id 215 }; 216 217 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_PSG_SIGMA_TEARDOWN, 218 (uint32_t *) &message, sizeof(message) / MBOX_WORD_BYTE, 219 CMD_CASUAL, NULL, NULL); 220 221 if (status < 0) { 222 *mbox_error = -status; 223 return INTEL_SIP_SMC_STATUS_ERROR; 224 } 225 226 return INTEL_SIP_SMC_STATUS_OK; 227 } 228 229 int intel_fcs_chip_id(uint32_t *id_low, uint32_t *id_high, uint32_t *mbox_error) 230 { 231 int status; 232 uint32_t load_size; 233 uint32_t chip_id[2]; 234 235 load_size = sizeof(chip_id) / MBOX_WORD_BYTE; 236 237 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_CMD_GET_CHIPID, NULL, 238 0U, CMD_CASUAL, (uint32_t *) chip_id, &load_size); 239 240 if (status < 0) { 241 *mbox_error = -status; 242 return INTEL_SIP_SMC_STATUS_ERROR; 243 } 244 245 *id_low = chip_id[0]; 246 *id_high = chip_id[1]; 247 248 return INTEL_SIP_SMC_STATUS_OK; 249 } 250 251 int intel_fcs_attestation_subkey(uint64_t src_addr, uint32_t src_size, 252 uint64_t dst_addr, uint32_t *dst_size, uint32_t *mbox_error) 253 { 254 int status; 255 uint32_t send_size = src_size / MBOX_WORD_BYTE; 256 uint32_t ret_size = *dst_size / MBOX_WORD_BYTE; 257 258 259 if (!is_address_in_ddr_range(src_addr, src_size) || 260 !is_address_in_ddr_range(dst_addr, *dst_size)) { 261 return INTEL_SIP_SMC_STATUS_REJECTED; 262 } 263 264 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_ATTESTATION_SUBKEY, 265 (uint32_t *) src_addr, send_size, CMD_CASUAL, 266 (uint32_t *) dst_addr, &ret_size); 267 268 if (status < 0) { 269 *mbox_error = -status; 270 return INTEL_SIP_SMC_STATUS_ERROR; 271 } 272 273 *dst_size = ret_size * MBOX_WORD_BYTE; 274 flush_dcache_range(dst_addr, *dst_size); 275 276 return INTEL_SIP_SMC_STATUS_OK; 277 } 278 279 int intel_fcs_get_measurement(uint64_t src_addr, uint32_t src_size, 280 uint64_t dst_addr, uint32_t *dst_size, uint32_t *mbox_error) 281 { 282 int status; 283 uint32_t send_size = src_size / MBOX_WORD_BYTE; 284 uint32_t ret_size = *dst_size / MBOX_WORD_BYTE; 285 286 if (!is_address_in_ddr_range(src_addr, src_size) || 287 !is_address_in_ddr_range(dst_addr, *dst_size)) { 288 return INTEL_SIP_SMC_STATUS_REJECTED; 289 } 290 291 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_GET_MEASUREMENT, 292 (uint32_t *) src_addr, send_size, CMD_CASUAL, 293 (uint32_t *) dst_addr, &ret_size); 294 295 if (status < 0) { 296 *mbox_error = -status; 297 return INTEL_SIP_SMC_STATUS_ERROR; 298 } 299 300 *dst_size = ret_size * MBOX_WORD_BYTE; 301 flush_dcache_range(dst_addr, *dst_size); 302 303 return INTEL_SIP_SMC_STATUS_OK; 304 } 305