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
delfamily_free(void * data)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
obj_is_delfamily(TSS_HOBJECT hObject)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
obj_delfamily_add(TSS_HCONTEXT hContext,TSS_HOBJECT * phObject)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
obj_delfamily_remove(TSS_HDELFAMILY hFamily,TSS_HOBJECT hObject)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
obj_delfamily_find_by_familyid(TSS_HOBJECT hObject,UINT32 familyID,TSS_HDELFAMILY * hFamily)86 obj_delfamily_find_by_familyid(TSS_HOBJECT hObject, UINT32 familyID, TSS_HDELFAMILY *hFamily)
87 {
88 TSS_HCONTEXT hContext;
89 struct tsp_object *obj;
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 pthread_mutex_unlock(&list->lock);
100 return;
101 }
102 } else
103 hContext = (TSS_HCONTEXT)hObject;
104
105 for (obj = list->head; obj; obj = obj->next) {
106 if (obj->tspContext != hContext)
107 continue;
108
109 delfamily = (struct tr_delfamily_obj *)obj->data;
110 if (delfamily->familyID == familyID) {
111 *hFamily = obj->handle;
112 break;
113 }
114 }
115
116 pthread_mutex_unlock(&list->lock);
117 }
118
119 TSS_RESULT
obj_delfamily_get_tsp_context(TSS_HDELFAMILY hFamily,TSS_HCONTEXT * hContext)120 obj_delfamily_get_tsp_context(TSS_HDELFAMILY hFamily, TSS_HCONTEXT *hContext)
121 {
122 struct tsp_object *obj;
123
124 if ((obj = obj_list_get_obj(&delfamily_list, hFamily)) == NULL)
125 return TSPERR(TSS_E_INVALID_HANDLE);
126
127 *hContext = obj->tspContext;
128
129 obj_list_put(&delfamily_list);
130
131 return TSS_SUCCESS;
132 }
133
134 TSS_RESULT
obj_delfamily_set_locked(TSS_HDELFAMILY hFamily,TSS_BOOL state,TSS_BOOL setInTpm)135 obj_delfamily_set_locked(TSS_HDELFAMILY hFamily, TSS_BOOL state, TSS_BOOL setInTpm)
136 {
137 struct tsp_object *obj;
138 struct tr_delfamily_obj *delfamily;
139 TSS_HTPM hTpm;
140 UINT32 opDataSize;
141 BYTE opData[8];
142 UINT32 outDataSize;
143 BYTE *outData = NULL;
144 UINT64 offset;
145 TSS_RESULT result = TSS_SUCCESS;
146
147 if ((obj = obj_list_get_obj(&delfamily_list, hFamily)) == NULL)
148 return TSPERR(TSS_E_INVALID_HANDLE);
149
150 delfamily = (struct tr_delfamily_obj *)obj->data;
151
152 if (setInTpm) {
153 if ((result = obj_tpm_get(obj->tspContext, &hTpm)))
154 goto done;
155
156 offset = 0;
157 Trspi_LoadBlob_BOOL(&offset, state, opData);
158 opDataSize = offset;
159 if ((result = do_delegate_manage(hTpm, delfamily->familyID, TPM_FAMILY_ADMIN,
160 opDataSize, opData, &outDataSize, &outData)))
161 goto done;
162 }
163
164 if (state)
165 delfamily->stateFlags |= TSS_DELFAMILY_FLAGS_STATE_LOCKED;
166 else
167 delfamily->stateFlags &= ~TSS_DELFAMILY_FLAGS_STATE_LOCKED;
168
169 done:
170 obj_list_put(&delfamily_list);
171
172 free(outData);
173
174 return result;
175 }
176
177 TSS_RESULT
obj_delfamily_get_locked(TSS_HDELFAMILY hFamily,TSS_BOOL * state)178 obj_delfamily_get_locked(TSS_HDELFAMILY hFamily, TSS_BOOL *state)
179 {
180 struct tsp_object *obj;
181 struct tr_delfamily_obj *delfamily;
182
183 if ((obj = obj_list_get_obj(&delfamily_list, hFamily)) == NULL)
184 return TSPERR(TSS_E_INVALID_HANDLE);
185
186 delfamily = (struct tr_delfamily_obj *)obj->data;
187
188 *state = (delfamily->stateFlags & TSS_DELFAMILY_FLAGS_STATE_LOCKED) ? TRUE : FALSE;
189
190 obj_list_put(&delfamily_list);
191
192 return TSS_SUCCESS;
193 }
194
195 TSS_RESULT
obj_delfamily_set_enabled(TSS_HDELFAMILY hFamily,TSS_BOOL state,TSS_BOOL setInTpm)196 obj_delfamily_set_enabled(TSS_HDELFAMILY hFamily, TSS_BOOL state, TSS_BOOL setInTpm)
197 {
198 struct tsp_object *obj;
199 struct tr_delfamily_obj *delfamily;
200 TSS_HTPM hTpm;
201 UINT32 opDataSize;
202 BYTE opData[8];
203 UINT32 outDataSize;
204 BYTE *outData = NULL;
205 UINT64 offset;
206 TSS_RESULT result = TSS_SUCCESS;
207
208 if ((obj = obj_list_get_obj(&delfamily_list, hFamily)) == NULL)
209 return TSPERR(TSS_E_INVALID_HANDLE);
210
211 delfamily = (struct tr_delfamily_obj *)obj->data;
212
213 if (setInTpm) {
214 if ((result = obj_tpm_get(obj->tspContext, &hTpm)))
215 goto done;
216
217 offset = 0;
218 Trspi_LoadBlob_BOOL(&offset, state, opData);
219 opDataSize = offset;
220 if ((result = do_delegate_manage(hTpm, delfamily->familyID, TPM_FAMILY_ENABLE,
221 opDataSize, opData, &outDataSize, &outData)))
222 goto done;
223 }
224
225 if (state)
226 delfamily->stateFlags |= TSS_DELFAMILY_FLAGS_STATE_ENABLED;
227 else
228 delfamily->stateFlags &= ~TSS_DELFAMILY_FLAGS_STATE_ENABLED;
229
230 done:
231 obj_list_put(&delfamily_list);
232
233 free(outData);
234
235 return result;
236 }
237
238 TSS_RESULT
obj_delfamily_get_enabled(TSS_HDELFAMILY hFamily,TSS_BOOL * state)239 obj_delfamily_get_enabled(TSS_HDELFAMILY hFamily, TSS_BOOL *state)
240 {
241 struct tsp_object *obj;
242 struct tr_delfamily_obj *delfamily;
243
244 if ((obj = obj_list_get_obj(&delfamily_list, hFamily)) == NULL)
245 return TSPERR(TSS_E_INVALID_HANDLE);
246
247 delfamily = (struct tr_delfamily_obj *)obj->data;
248
249 *state = (delfamily->stateFlags & TSS_DELFAMILY_FLAGS_STATE_ENABLED) ? TRUE : FALSE;
250
251 obj_list_put(&delfamily_list);
252
253 return TSS_SUCCESS;
254 }
255
256 TSS_RESULT
obj_delfamily_set_vercount(TSS_HDELFAMILY hFamily,UINT32 verCount)257 obj_delfamily_set_vercount(TSS_HDELFAMILY hFamily, UINT32 verCount)
258 {
259 struct tsp_object *obj;
260 struct tr_delfamily_obj *delfamily;
261
262 if ((obj = obj_list_get_obj(&delfamily_list, hFamily)) == NULL)
263 return TSPERR(TSS_E_INVALID_HANDLE);
264
265 delfamily = (struct tr_delfamily_obj *)obj->data;
266
267 delfamily->verCount = verCount;
268
269 obj_list_put(&delfamily_list);
270
271 return TSS_SUCCESS;
272 }
273
274 TSS_RESULT
obj_delfamily_get_vercount(TSS_HDELFAMILY hFamily,UINT32 * verCount)275 obj_delfamily_get_vercount(TSS_HDELFAMILY hFamily, UINT32 *verCount)
276 {
277 struct tsp_object *obj;
278 struct tr_delfamily_obj *delfamily;
279
280 if ((obj = obj_list_get_obj(&delfamily_list, hFamily)) == NULL)
281 return TSPERR(TSS_E_INVALID_HANDLE);
282
283 delfamily = (struct tr_delfamily_obj *)obj->data;
284
285 *verCount = delfamily->verCount;
286
287 obj_list_put(&delfamily_list);
288
289 return TSS_SUCCESS;
290 }
291
292 TSS_RESULT
obj_delfamily_set_familyid(TSS_HDELFAMILY hFamily,UINT32 familyID)293 obj_delfamily_set_familyid(TSS_HDELFAMILY hFamily, UINT32 familyID)
294 {
295 struct tsp_object *obj;
296 struct tr_delfamily_obj *delfamily;
297
298 if ((obj = obj_list_get_obj(&delfamily_list, hFamily)) == NULL)
299 return TSPERR(TSS_E_INVALID_HANDLE);
300
301 delfamily = (struct tr_delfamily_obj *)obj->data;
302
303 delfamily->familyID = familyID;
304
305 obj_list_put(&delfamily_list);
306
307 return TSS_SUCCESS;
308 }
309
310 TSS_RESULT
obj_delfamily_get_familyid(TSS_HDELFAMILY hFamily,UINT32 * familyID)311 obj_delfamily_get_familyid(TSS_HDELFAMILY hFamily, UINT32 *familyID)
312 {
313 struct tsp_object *obj;
314 struct tr_delfamily_obj *delfamily;
315
316 if ((obj = obj_list_get_obj(&delfamily_list, hFamily)) == NULL)
317 return TSPERR(TSS_E_INVALID_HANDLE);
318
319 delfamily = (struct tr_delfamily_obj *)obj->data;
320
321 *familyID = delfamily->familyID;
322
323 obj_list_put(&delfamily_list);
324
325 return TSS_SUCCESS;
326 }
327
328 TSS_RESULT
obj_delfamily_set_label(TSS_HDELFAMILY hFamily,BYTE label)329 obj_delfamily_set_label(TSS_HDELFAMILY hFamily, BYTE label)
330 {
331 struct tsp_object *obj;
332 struct tr_delfamily_obj *delfamily;
333
334 if ((obj = obj_list_get_obj(&delfamily_list, hFamily)) == NULL)
335 return TSPERR(TSS_E_INVALID_HANDLE);
336
337 delfamily = (struct tr_delfamily_obj *)obj->data;
338
339 delfamily->label = label;
340
341 obj_list_put(&delfamily_list);
342
343 return TSS_SUCCESS;
344 }
345
346 TSS_RESULT
obj_delfamily_get_label(TSS_HDELFAMILY hFamily,BYTE * label)347 obj_delfamily_get_label(TSS_HDELFAMILY hFamily, BYTE *label)
348 {
349 struct tsp_object *obj;
350 struct tr_delfamily_obj *delfamily;
351
352 if ((obj = obj_list_get_obj(&delfamily_list, hFamily)) == NULL)
353 return TSPERR(TSS_E_INVALID_HANDLE);
354
355 delfamily = (struct tr_delfamily_obj *)obj->data;
356
357 *label = delfamily->label;
358
359 obj_list_put(&delfamily_list);
360
361 return TSS_SUCCESS;
362 }
363
364