xref: /netbsd-src/crypto/external/cpl/trousers/dist/src/tspi/obj_delfamily.c (revision 48fb7bfab72acd4281a53bbee5ccf3f809019e75)
1 
2 /*
3  * Licensed Materials - Property of IBM
4  *
5  * trousers - An open source TCG Software Stack
6  *
7  * (C) Copyright International Business Machines Corp. 2007
8  *
9  */
10 
11 
12 #include <stdlib.h>
13 #include <stdio.h>
14 #include <errno.h>
15 #include <string.h>
16 
17 #include "trousers/tss.h"
18 #include "trousers/trousers.h"
19 #include "trousers_types.h"
20 #include "spi_utils.h"
21 #include "capabilities.h"
22 #include "tsplog.h"
23 #include "obj.h"
24 #include "tsp_delegate.h"
25 
26 void
27 delfamily_free(void *data)
28 {
29 	struct tr_delfamily_obj *delfamily = (struct tr_delfamily_obj *)data;
30 
31 	free(delfamily);
32 }
33 
34 TSS_BOOL
35 obj_is_delfamily(TSS_HOBJECT hObject)
36 {
37 	TSS_BOOL answer = FALSE;
38 
39 	if ((obj_list_get_obj(&delfamily_list, hObject))) {
40 		answer = TRUE;
41 		obj_list_put(&delfamily_list);
42 	}
43 
44 	return answer;
45 }
46 
47 TSS_RESULT
48 obj_delfamily_add(TSS_HCONTEXT hContext, TSS_HOBJECT *phObject)
49 {
50 	TSS_RESULT result;
51 	struct tr_delfamily_obj *delfamily = calloc(1, sizeof(struct tr_delfamily_obj));
52 
53 	if (delfamily == NULL) {
54 		LogError("malloc of %zd bytes failed.",
55 				sizeof(struct tr_delfamily_obj));
56 		return TSPERR(TSS_E_OUTOFMEMORY);
57 	}
58 
59 	if ((result = obj_list_add(&delfamily_list, hContext, 0, delfamily, phObject))) {
60 		free(delfamily);
61 		return result;
62 	}
63 
64 	return TSS_SUCCESS;
65 }
66 
67 TSS_RESULT
68 obj_delfamily_remove(TSS_HDELFAMILY hFamily, TSS_HOBJECT hObject)
69 {
70 	TSS_HCONTEXT hContext;
71 	TSS_RESULT result;
72 
73 	if (obj_is_tpm(hObject)) {
74 		if ((result = obj_tpm_get_tsp_context((TSS_HTPM)hObject, &hContext)))
75 			return result;
76 	} else
77 		hContext = (TSS_HCONTEXT)hObject;
78 
79 	if ((result = obj_list_remove(&delfamily_list, &delfamily_free, hFamily, hContext)))
80 		return result;
81 
82 	return TSS_SUCCESS;
83 }
84 
85 void
86 obj_delfamily_find_by_familyid(TSS_HOBJECT hObject, UINT32 familyID, TSS_HDELFAMILY *hFamily)
87 {
88 	TSS_HCONTEXT hContext;
89 	struct tsp_object *obj, *prev = NULL;
90 	struct obj_list *list = &delfamily_list;
91 	struct tr_delfamily_obj *delfamily;
92 
93 	pthread_mutex_lock(&list->lock);
94 
95 	*hFamily = NULL_HDELFAMILY;
96 
97 	if (obj_is_tpm(hObject)) {
98 		if (obj_tpm_get_tsp_context((TSS_HTPM)hObject, &hContext))
99 			return;
100 	} else
101 		hContext = (TSS_HCONTEXT)hObject;
102 
103 	for (obj = list->head; obj; prev = obj, obj = obj->next) {
104 		if (obj->tspContext != hContext)
105 			continue;
106 
107 		delfamily = (struct tr_delfamily_obj *)obj->data;
108 		if (delfamily->familyID == familyID) {
109 			*hFamily = obj->handle;
110 			break;
111 		}
112 	}
113 
114 	pthread_mutex_unlock(&list->lock);
115 }
116 
117 TSS_RESULT
118 obj_delfamily_get_tsp_context(TSS_HDELFAMILY hFamily, TSS_HCONTEXT *hContext)
119 {
120 	struct tsp_object *obj;
121 
122 	if ((obj = obj_list_get_obj(&delfamily_list, hFamily)) == NULL)
123 		return TSPERR(TSS_E_INVALID_HANDLE);
124 
125 	*hContext = obj->tspContext;
126 
127 	obj_list_put(&delfamily_list);
128 
129 	return TSS_SUCCESS;
130 }
131 
132 TSS_RESULT
133 obj_delfamily_set_locked(TSS_HDELFAMILY hFamily, TSS_BOOL state, TSS_BOOL setInTpm)
134 {
135 	struct tsp_object *obj;
136 	struct tr_delfamily_obj *delfamily;
137 	TSS_HTPM hTpm;
138 	UINT32 opDataSize;
139 	BYTE opData[8];
140 	UINT32 outDataSize;
141 	BYTE *outData = NULL;
142 	UINT64 offset;
143 	TSS_RESULT result = TSS_SUCCESS;
144 
145 	if ((obj = obj_list_get_obj(&delfamily_list, hFamily)) == NULL)
146 		return TSPERR(TSS_E_INVALID_HANDLE);
147 
148 	delfamily = (struct tr_delfamily_obj *)obj->data;
149 
150 	if (setInTpm) {
151 		if ((result = obj_tpm_get(obj->tspContext, &hTpm)))
152 			goto done;
153 
154 		offset = 0;
155 		Trspi_LoadBlob_BOOL(&offset, state, opData);
156 		opDataSize = offset;
157 		if ((result = do_delegate_manage(hTpm, delfamily->familyID, TPM_FAMILY_ADMIN,
158 				opDataSize, opData, &outDataSize, &outData)))
159 			goto done;
160 	}
161 
162 	if (state)
163 		delfamily->stateFlags |= TSS_DELFAMILY_FLAGS_STATE_LOCKED;
164 	else
165 		delfamily->stateFlags &= ~TSS_DELFAMILY_FLAGS_STATE_LOCKED;
166 
167 done:
168 	obj_list_put(&delfamily_list);
169 
170 	free(outData);
171 
172 	return result;
173 }
174 
175 TSS_RESULT
176 obj_delfamily_get_locked(TSS_HDELFAMILY hFamily, TSS_BOOL *state)
177 {
178 	struct tsp_object *obj;
179 	struct tr_delfamily_obj *delfamily;
180 
181 	if ((obj = obj_list_get_obj(&delfamily_list, hFamily)) == NULL)
182 		return TSPERR(TSS_E_INVALID_HANDLE);
183 
184 	delfamily = (struct tr_delfamily_obj *)obj->data;
185 
186 	*state = (delfamily->stateFlags & TSS_DELFAMILY_FLAGS_STATE_LOCKED) ? TRUE : FALSE;
187 
188 	obj_list_put(&delfamily_list);
189 
190 	return TSS_SUCCESS;
191 }
192 
193 TSS_RESULT
194 obj_delfamily_set_enabled(TSS_HDELFAMILY hFamily, TSS_BOOL state, TSS_BOOL setInTpm)
195 {
196 	struct tsp_object *obj;
197 	struct tr_delfamily_obj *delfamily;
198 	TSS_HTPM hTpm;
199 	UINT32 opDataSize;
200 	BYTE opData[8];
201 	UINT32 outDataSize;
202 	BYTE *outData = NULL;
203 	UINT64 offset;
204 	TSS_RESULT result = TSS_SUCCESS;
205 
206 	if ((obj = obj_list_get_obj(&delfamily_list, hFamily)) == NULL)
207 		return TSPERR(TSS_E_INVALID_HANDLE);
208 
209 	delfamily = (struct tr_delfamily_obj *)obj->data;
210 
211 	if (setInTpm) {
212 		if ((result = obj_tpm_get(obj->tspContext, &hTpm)))
213 			goto done;
214 
215 		offset = 0;
216 		Trspi_LoadBlob_BOOL(&offset, state, opData);
217 		opDataSize = offset;
218 		if ((result = do_delegate_manage(hTpm, delfamily->familyID, TPM_FAMILY_ENABLE,
219 				opDataSize, opData, &outDataSize, &outData)))
220 			goto done;
221 	}
222 
223 	if (state)
224 		delfamily->stateFlags |= TSS_DELFAMILY_FLAGS_STATE_ENABLED;
225 	else
226 		delfamily->stateFlags &= ~TSS_DELFAMILY_FLAGS_STATE_ENABLED;
227 
228 done:
229 	obj_list_put(&delfamily_list);
230 
231 	free(outData);
232 
233 	return result;
234 }
235 
236 TSS_RESULT
237 obj_delfamily_get_enabled(TSS_HDELFAMILY hFamily, TSS_BOOL *state)
238 {
239 	struct tsp_object *obj;
240 	struct tr_delfamily_obj *delfamily;
241 
242 	if ((obj = obj_list_get_obj(&delfamily_list, hFamily)) == NULL)
243 		return TSPERR(TSS_E_INVALID_HANDLE);
244 
245 	delfamily = (struct tr_delfamily_obj *)obj->data;
246 
247 	*state = (delfamily->stateFlags & TSS_DELFAMILY_FLAGS_STATE_ENABLED) ? TRUE : FALSE;
248 
249 	obj_list_put(&delfamily_list);
250 
251 	return TSS_SUCCESS;
252 }
253 
254 TSS_RESULT
255 obj_delfamily_set_vercount(TSS_HDELFAMILY hFamily, UINT32 verCount)
256 {
257 	struct tsp_object *obj;
258 	struct tr_delfamily_obj *delfamily;
259 
260 	if ((obj = obj_list_get_obj(&delfamily_list, hFamily)) == NULL)
261 		return TSPERR(TSS_E_INVALID_HANDLE);
262 
263 	delfamily = (struct tr_delfamily_obj *)obj->data;
264 
265 	delfamily->verCount = verCount;
266 
267 	obj_list_put(&delfamily_list);
268 
269 	return TSS_SUCCESS;
270 }
271 
272 TSS_RESULT
273 obj_delfamily_get_vercount(TSS_HDELFAMILY hFamily, UINT32 *verCount)
274 {
275 	struct tsp_object *obj;
276 	struct tr_delfamily_obj *delfamily;
277 
278 	if ((obj = obj_list_get_obj(&delfamily_list, hFamily)) == NULL)
279 		return TSPERR(TSS_E_INVALID_HANDLE);
280 
281 	delfamily = (struct tr_delfamily_obj *)obj->data;
282 
283 	*verCount = delfamily->verCount;
284 
285 	obj_list_put(&delfamily_list);
286 
287 	return TSS_SUCCESS;
288 }
289 
290 TSS_RESULT
291 obj_delfamily_set_familyid(TSS_HDELFAMILY hFamily, UINT32 familyID)
292 {
293 	struct tsp_object *obj;
294 	struct tr_delfamily_obj *delfamily;
295 
296 	if ((obj = obj_list_get_obj(&delfamily_list, hFamily)) == NULL)
297 		return TSPERR(TSS_E_INVALID_HANDLE);
298 
299 	delfamily = (struct tr_delfamily_obj *)obj->data;
300 
301 	delfamily->familyID = familyID;
302 
303 	obj_list_put(&delfamily_list);
304 
305 	return TSS_SUCCESS;
306 }
307 
308 TSS_RESULT
309 obj_delfamily_get_familyid(TSS_HDELFAMILY hFamily, UINT32 *familyID)
310 {
311 	struct tsp_object *obj;
312 	struct tr_delfamily_obj *delfamily;
313 
314 	if ((obj = obj_list_get_obj(&delfamily_list, hFamily)) == NULL)
315 		return TSPERR(TSS_E_INVALID_HANDLE);
316 
317 	delfamily = (struct tr_delfamily_obj *)obj->data;
318 
319 	*familyID = delfamily->familyID;
320 
321 	obj_list_put(&delfamily_list);
322 
323 	return TSS_SUCCESS;
324 }
325 
326 TSS_RESULT
327 obj_delfamily_set_label(TSS_HDELFAMILY hFamily, BYTE label)
328 {
329 	struct tsp_object *obj;
330 	struct tr_delfamily_obj *delfamily;
331 
332 	if ((obj = obj_list_get_obj(&delfamily_list, hFamily)) == NULL)
333 		return TSPERR(TSS_E_INVALID_HANDLE);
334 
335 	delfamily = (struct tr_delfamily_obj *)obj->data;
336 
337 	delfamily->label = label;
338 
339 	obj_list_put(&delfamily_list);
340 
341 	return TSS_SUCCESS;
342 }
343 
344 TSS_RESULT
345 obj_delfamily_get_label(TSS_HDELFAMILY hFamily, BYTE *label)
346 {
347 	struct tsp_object *obj;
348 	struct tr_delfamily_obj *delfamily;
349 
350 	if ((obj = obj_list_get_obj(&delfamily_list, hFamily)) == NULL)
351 		return TSPERR(TSS_E_INVALID_HANDLE);
352 
353 	delfamily = (struct tr_delfamily_obj *)obj->data;
354 
355 	*label = delfamily->label;
356 
357 	obj_list_put(&delfamily_list);
358 
359 	return TSS_SUCCESS;
360 }
361 
362