1 // SPDX-License-Identifier: BSD-2-Clause 2 /* 3 * Copyright (C) 2022 Foundries.io Ltd 4 * Jorge Ramirez-Ortiz <jorge@foundries.io> 5 */ 6 7 #include <arm.h> 8 #include <confine_array_index.h> 9 #include <drivers/versal_mbox.h> 10 #include <drivers/versal_nvm.h> 11 #include <drivers/versal_puf.h> 12 #include <initcall.h> 13 #include <mm/core_memprot.h> 14 #include <string.h> 15 #include <tee/cache.h> 16 17 /* Protocol API with the remote processor */ 18 #define VERSAL_PUF_MODULE_SHIFT 8 19 #define VERSAL_PUF_MODULE 12 20 #define PUF_API_ID(_id) ((VERSAL_PUF_MODULE << VERSAL_PUF_MODULE_SHIFT) | (_id)) 21 22 enum versal_puf_error { 23 /* Registration */ 24 ERROR_INVALID_PARAM = 0x02, 25 ERROR_INVALID_SYNDROME_MODE = 0x03, 26 ERROR_SYNDROME_WORD_WAIT_TIMEOUT = 0x04, 27 ERROR_PUF_DONE_WAIT_TIMEOUT = 0x07, 28 ERROR_REGISTRATION_INVALID = 0x08, 29 SHUTTER_GVF_MISMATCH = 0x09, 30 ERROR_SYN_DATA_ERROR = 0x0A, 31 IRO_FREQ_WRITE_MISMATCH = 0x0B, 32 /* Regeneration */ 33 ERROR_CHASH_NOT_PROGRAMMED = 0x10, 34 ERROR_PUF_STATUS_DONE_TIMEOUT = 0x11, 35 ERROR_INVALID_REGENERATION_TYPE = 0x12, 36 ERROR_INVALID_PUF_OPERATION = 0x13, 37 ERROR_REGENERATION_INVALID = 0x14, 38 ERROR_REGEN_PUF_HD_INVALID = 0x15, 39 ERROR_INVALID_READ_HD_INPUT = 0x16, 40 ERROR_PUF_DONE_KEY_NT_RDY = 0x17, 41 ERROR_PUF_DONE_ID_NT_RDY = 0x18, 42 ERROR_PUF_ID_ZERO_TIMEOUT = 0x19, 43 }; 44 45 #define VERSAL_PUF_ERROR(m) { .error = (m), .name = TO_STR(m) } 46 47 static const char *versal_puf_error(uint8_t err) 48 { 49 struct { 50 enum versal_puf_error error; 51 const char *name; 52 } elist[] = { 53 /* Registration */ 54 VERSAL_PUF_ERROR(ERROR_INVALID_PARAM), 55 VERSAL_PUF_ERROR(ERROR_INVALID_SYNDROME_MODE), 56 VERSAL_PUF_ERROR(ERROR_SYNDROME_WORD_WAIT_TIMEOUT), 57 VERSAL_PUF_ERROR(ERROR_PUF_DONE_WAIT_TIMEOUT), 58 VERSAL_PUF_ERROR(ERROR_REGISTRATION_INVALID), 59 VERSAL_PUF_ERROR(SHUTTER_GVF_MISMATCH), 60 VERSAL_PUF_ERROR(ERROR_SYN_DATA_ERROR), 61 VERSAL_PUF_ERROR(IRO_FREQ_WRITE_MISMATCH), 62 /* Regeneration */ 63 VERSAL_PUF_ERROR(ERROR_CHASH_NOT_PROGRAMMED), 64 VERSAL_PUF_ERROR(ERROR_PUF_STATUS_DONE_TIMEOUT), 65 VERSAL_PUF_ERROR(ERROR_INVALID_REGENERATION_TYPE), 66 VERSAL_PUF_ERROR(ERROR_INVALID_PUF_OPERATION), 67 VERSAL_PUF_ERROR(ERROR_REGENERATION_INVALID), 68 VERSAL_PUF_ERROR(ERROR_REGEN_PUF_HD_INVALID), 69 VERSAL_PUF_ERROR(ERROR_INVALID_READ_HD_INPUT), 70 VERSAL_PUF_ERROR(ERROR_PUF_DONE_KEY_NT_RDY), 71 VERSAL_PUF_ERROR(ERROR_PUF_DONE_ID_NT_RDY), 72 VERSAL_PUF_ERROR(ERROR_PUF_ID_ZERO_TIMEOUT), 73 }; 74 size_t error = 0; 75 size_t index = 0; 76 77 if (err <= ERROR_PUF_ID_ZERO_TIMEOUT && err >= ERROR_INVALID_PARAM) { 78 index = err - ERROR_INVALID_PARAM; 79 80 /* Spectre gadget protection: array index is external event */ 81 error = confine_array_index(index, ARRAY_SIZE(elist)); 82 if (elist[error].name) 83 return elist[error].name; 84 85 return "Invalid"; 86 } 87 88 return "Unknown"; 89 } 90 91 /* 92 * Register the Physical Unclonable Function (prior operating with it) 93 * 94 * This must happen during the device provisioning phase and can be done from 95 * the Secure World via this interface or from an earlier firmware. 96 */ 97 TEE_Result versal_puf_register(struct versal_puf_data *buf, 98 struct versal_puf_cfg *cfg) 99 { 100 struct versal_puf_data_req req __aligned_puf = { }; 101 struct versal_mbox_mem request = { 102 .alloc_len = sizeof(req), 103 .len = sizeof(req), 104 .buf = &req, 105 }; 106 struct versal_mbox_mem efuse_syn_data_addr = { }; 107 struct versal_mbox_mem syndrome_data_addr = { }; 108 struct versal_mbox_mem puf_id_addr = { }; 109 struct versal_mbox_mem hash_addr = { }; 110 struct versal_mbox_mem aux_addr = { }; 111 struct versal_ipi_cmd arg = { }; 112 TEE_Result ret = TEE_SUCCESS; 113 uint32_t err = 0; 114 115 versal_mbox_alloc(sizeof(buf->puf_id), buf->puf_id, &puf_id_addr); 116 versal_mbox_alloc(sizeof(buf->chash), &buf->chash, &hash_addr); 117 versal_mbox_alloc(sizeof(buf->aux), &buf->aux, &aux_addr); 118 versal_mbox_alloc(sizeof(buf->efuse_syn_data), buf->efuse_syn_data, 119 &efuse_syn_data_addr); 120 versal_mbox_alloc(sizeof(buf->syndrome_data), buf->syndrome_data, 121 &syndrome_data_addr); 122 123 arg.ibuf[0].mem = request; 124 arg.ibuf[1].mem = syndrome_data_addr; 125 arg.ibuf[2].mem = hash_addr; 126 arg.ibuf[3].mem = aux_addr; 127 arg.ibuf[4].mem = puf_id_addr; 128 arg.ibuf[5].mem = efuse_syn_data_addr; 129 130 req.efuse_syn_data_addr = virt_to_phys(efuse_syn_data_addr.buf); 131 req.syndrome_data_addr = virt_to_phys(syndrome_data_addr.buf); 132 req.puf_id_addr = virt_to_phys(puf_id_addr.buf); 133 req.hash_addr = virt_to_phys(hash_addr.buf); 134 req.aux_addr = virt_to_phys(aux_addr.buf); 135 136 req.global_var_filter = cfg->global_var_filter; 137 req.shutter_value = cfg->shutter_value; 138 req.puf_operation = cfg->puf_operation; 139 req.read_option = cfg->read_option; 140 req.reg_mode = cfg->reg_mode; 141 142 arg.data[0] = PUF_API_ID(VERSAL_PUF_REGISTER); 143 reg_pair_from_64(virt_to_phys(arg.ibuf[0].mem.buf), 144 &arg.data[2], &arg.data[1]); 145 146 if (versal_mbox_notify(&arg, NULL, &err)) { 147 EMSG("Versal, failed to register the PUF [%s]", 148 versal_puf_error(err)); 149 150 ret = TEE_ERROR_GENERIC; 151 } 152 153 /* Return the generated data */ 154 memcpy(buf->puf_id, puf_id_addr.buf, sizeof(buf->puf_id)); 155 memcpy(&buf->chash, hash_addr.buf, sizeof(buf->chash)); 156 memcpy(&buf->aux, aux_addr.buf, sizeof(buf->aux)); 157 memcpy(buf->efuse_syn_data, efuse_syn_data_addr.buf, 158 sizeof(buf->efuse_syn_data)); 159 memcpy(buf->syndrome_data, syndrome_data_addr.buf, 160 sizeof(buf->syndrome_data)); 161 162 free(syndrome_data_addr.buf); 163 free(hash_addr.buf); 164 free(aux_addr.buf); 165 free(puf_id_addr.buf); 166 free(efuse_syn_data_addr.buf); 167 168 return ret; 169 } 170 171 /* 172 * Re-seed the PUF circuitry so it can re-generate the Key Encryption Key. 173 * 174 * Depending on the configuration options it might use eFused data instead of 175 * the helper data provided via the interface. 176 */ 177 TEE_Result versal_puf_regenerate(struct versal_puf_data *buf, 178 struct versal_puf_cfg *cfg) 179 { 180 struct versal_puf_data_req req __aligned_puf = { }; 181 struct versal_mbox_mem request = { 182 .alloc_len = sizeof(req), 183 .len = sizeof(req), 184 .buf = &req, 185 }; 186 struct versal_mbox_mem efuse_syn_data_addr = { }; 187 struct versal_mbox_mem syndrome_data_addr = { }; 188 struct versal_mbox_mem puf_id_addr = { }; 189 struct versal_mbox_mem hash_addr = { }; 190 struct versal_mbox_mem aux_addr = { }; 191 struct versal_ipi_cmd arg = { }; 192 TEE_Result ret = TEE_SUCCESS; 193 uint32_t err = 0; 194 195 versal_mbox_alloc(sizeof(buf->puf_id), buf->puf_id, &puf_id_addr); 196 versal_mbox_alloc(sizeof(buf->chash), &buf->chash, &hash_addr); 197 versal_mbox_alloc(sizeof(buf->aux), &buf->aux, &aux_addr); 198 versal_mbox_alloc(sizeof(buf->efuse_syn_data), buf->efuse_syn_data, 199 &efuse_syn_data_addr); 200 versal_mbox_alloc(sizeof(buf->syndrome_data), buf->syndrome_data, 201 &syndrome_data_addr); 202 203 arg.ibuf[0].mem = request; 204 arg.ibuf[1].mem = syndrome_data_addr; 205 arg.ibuf[2].mem = hash_addr; 206 arg.ibuf[3].mem = aux_addr; 207 arg.ibuf[4].mem = puf_id_addr; 208 arg.ibuf[5].mem = efuse_syn_data_addr; 209 210 req.efuse_syn_data_addr = virt_to_phys(efuse_syn_data_addr.buf); 211 req.syndrome_addr = virt_to_phys(syndrome_data_addr.buf); 212 req.puf_id_addr = virt_to_phys(puf_id_addr.buf); 213 req.hash_addr = virt_to_phys(hash_addr.buf); 214 req.aux_addr = virt_to_phys(aux_addr.buf); 215 216 req.global_var_filter = cfg->global_var_filter; 217 req.shutter_value = cfg->shutter_value; 218 req.puf_operation = cfg->puf_operation; 219 req.read_option = cfg->read_option; 220 req.reg_mode = cfg->reg_mode; 221 222 arg.data[0] = PUF_API_ID(VERSAL_PUF_REGENERATE); 223 reg_pair_from_64(virt_to_phys(arg.ibuf[0].mem.buf), 224 &arg.data[2], &arg.data[1]); 225 226 if (versal_mbox_notify(&arg, NULL, &err)) { 227 EMSG("Versal, failed to regenerate the PUF [%s]", 228 versal_puf_error(err)); 229 230 ret = TEE_ERROR_GENERIC; 231 } 232 233 /* Return the updated PUF_ID */ 234 memcpy(buf->puf_id, puf_id_addr.buf, sizeof(buf->puf_id)); 235 236 free(syndrome_data_addr.buf); 237 free(hash_addr.buf); 238 free(aux_addr.buf); 239 free(puf_id_addr.buf); 240 free(efuse_syn_data_addr.buf); 241 242 return ret; 243 } 244 245 /* 246 * Clear/Hide the PUF Unique ID 247 * 248 * The fully accessible (non-secret) Unique ID is generated from the PUF 249 */ 250 TEE_Result versal_puf_clear_id(void) 251 { 252 struct versal_ipi_cmd arg = { }; 253 254 arg.data[0] = PUF_API_ID(VERSAL_PUF_CLEAR_ID); 255 256 if (versal_mbox_notify(&arg, NULL, NULL)) { 257 EMSG("Versal, failed to clear the PUF_ID"); 258 259 return TEE_ERROR_GENERIC; 260 } 261 262 return TEE_SUCCESS; 263 } 264 265 /* Check that the API id is available to the client */ 266 TEE_Result versal_puf_check_api(enum versal_puf_api id) 267 { 268 struct versal_ipi_cmd arg = { }; 269 270 arg.data[0] = PUF_API_ID(VERSAL_PUF_API_FEATURES); 271 arg.data[1] = id; 272 273 if (versal_mbox_notify(&arg, NULL, NULL)) 274 return TEE_ERROR_GENERIC; 275 276 return TEE_SUCCESS; 277 } 278