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