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 
versal_puf_error(uint8_t err)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  */
versal_puf_register(struct versal_puf_data * buf,struct versal_puf_cfg * cfg)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  */
versal_puf_regenerate(struct versal_puf_data * buf,struct versal_puf_cfg * cfg)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  */
versal_puf_clear_id(void)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 */
versal_puf_check_api(enum versal_puf_api id)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