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. 2005, 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
25 TSS_RESULT
obj_encdata_add(TSS_HCONTEXT tspContext,UINT32 type,TSS_HOBJECT * phObject)26 obj_encdata_add(TSS_HCONTEXT tspContext, UINT32 type, TSS_HOBJECT *phObject)
27 {
28 TSS_RESULT result;
29 struct tr_encdata_obj *encdata = calloc(1, sizeof(struct tr_encdata_obj));
30
31 if (encdata == NULL) {
32 LogError("malloc of %zd bytes failed.",
33 sizeof(struct tr_encdata_obj));
34 return TSPERR(TSS_E_OUTOFMEMORY);
35 }
36
37 /* add usage policy */
38 if ((result = obj_context_get_policy(tspContext, TSS_POLICY_USAGE,
39 &encdata->usagePolicy))) {
40 free(encdata);
41 return result;
42 }
43
44 encdata->type = type;
45
46 if ((result = obj_list_add(&encdata_list, tspContext, 0, encdata, phObject))) {
47 free(encdata);
48 return result;
49 }
50
51 return TSS_SUCCESS;
52 }
53
54 TSS_BOOL
obj_is_encdata(TSS_HOBJECT hObject)55 obj_is_encdata(TSS_HOBJECT hObject)
56 {
57 TSS_BOOL answer = FALSE;
58
59 if ((obj_list_get_obj(&encdata_list, hObject))) {
60 answer = TRUE;
61 obj_list_put(&encdata_list);
62 }
63
64 return answer;
65 }
66
67 TSS_RESULT
obj_encdata_get_tsp_context(TSS_HENCDATA hEncdata,TSS_HCONTEXT * tspContext)68 obj_encdata_get_tsp_context(TSS_HENCDATA hEncdata, TSS_HCONTEXT *tspContext)
69 {
70 struct tsp_object *obj;
71
72 if ((obj = obj_list_get_obj(&encdata_list, hEncdata)) == NULL)
73 return TSPERR(TSS_E_INVALID_HANDLE);
74
75 *tspContext = obj->tspContext;
76
77 obj_list_put(&encdata_list);
78
79 return TSS_SUCCESS;
80 }
81
82 TSS_RESULT
obj_encdata_get_policy(TSS_HENCDATA hEncData,UINT32 policyType,TSS_HPOLICY * phPolicy)83 obj_encdata_get_policy(TSS_HENCDATA hEncData, UINT32 policyType, TSS_HPOLICY *phPolicy)
84 {
85 struct tsp_object *obj;
86 struct tr_encdata_obj *encdata;
87 TSS_RESULT result = TSS_SUCCESS;
88
89 if ((obj = obj_list_get_obj(&encdata_list, hEncData)) == NULL)
90 return TSPERR(TSS_E_INVALID_HANDLE);
91
92 encdata = (struct tr_encdata_obj *)obj->data;
93
94 switch (policyType) {
95 case TSS_POLICY_USAGE:
96 *phPolicy = encdata->usagePolicy;
97 break;
98 default:
99 result = TSPERR(TSS_E_BAD_PARAMETER);
100 }
101
102 obj_list_put(&encdata_list);
103
104 return result;
105 }
106
107 TSS_RESULT
obj_encdata_set_policy(TSS_HENCDATA hEncData,TSS_HPOLICY hPolicy)108 obj_encdata_set_policy(TSS_HENCDATA hEncData, TSS_HPOLICY hPolicy)
109 {
110 struct tsp_object *obj;
111 struct tr_encdata_obj *encdata;
112 UINT32 policyType;
113 TSS_RESULT result = TSS_SUCCESS;
114
115 if ((result = obj_policy_get_type(hPolicy, &policyType)))
116 return result;
117
118 if ((obj = obj_list_get_obj(&encdata_list, hEncData)) == NULL)
119 return TSPERR(TSS_E_INVALID_HANDLE);
120
121 encdata = (struct tr_encdata_obj *)obj->data;
122
123 switch (policyType) {
124 case TSS_POLICY_USAGE:
125 encdata->usagePolicy = hPolicy;
126 break;
127 default:
128 result = TSPERR(TSS_E_BAD_PARAMETER);
129 }
130
131 obj_list_put(&encdata_list);
132
133 return result;
134 }
135
136 TSS_RESULT
obj_encdata_get_data(TSS_HENCDATA hEncData,UINT32 * size,BYTE ** data)137 obj_encdata_get_data(TSS_HENCDATA hEncData, UINT32 *size, BYTE **data)
138 {
139 struct tsp_object *obj;
140 struct tr_encdata_obj *encdata;
141 TSS_RESULT result = TSS_SUCCESS;
142
143 if ((obj = obj_list_get_obj(&encdata_list, hEncData)) == NULL)
144 return TSPERR(TSS_E_INVALID_HANDLE);
145
146 encdata = (struct tr_encdata_obj *)obj->data;
147
148 if (encdata->encryptedDataLength == 0) {
149 result = TSPERR(TSS_E_INVALID_OBJ_ACCESS);
150 goto done;
151 } else {
152 *data = calloc_tspi(obj->tspContext, encdata->encryptedDataLength);
153 if (*data == NULL) {
154 LogError("malloc of %d bytes failed.",
155 encdata->encryptedDataLength);
156 result = TSPERR(TSS_E_OUTOFMEMORY);
157 goto done;
158 }
159 *size = encdata->encryptedDataLength;
160 memcpy(*data, encdata->encryptedData, *size);
161 }
162
163 done:
164 obj_list_put(&encdata_list);
165
166 return result;
167 }
168
169 TSS_RESULT
obj_encdata_get_pcr_digest(TSS_HENCDATA hEncData,TSS_FLAG pcrInfoType,TSS_FLAG dir,UINT32 * size,BYTE ** data)170 obj_encdata_get_pcr_digest(TSS_HENCDATA hEncData,
171 TSS_FLAG pcrInfoType,
172 TSS_FLAG dir,
173 UINT32 *size,
174 BYTE **data)
175 {
176 struct tsp_object *obj;
177 struct tr_encdata_obj *encdata;
178 TSS_RESULT result = TSS_SUCCESS;
179 TPM_DIGEST *digest;
180 UINT64 offset;
181
182 if ((obj = obj_list_get_obj(&encdata_list, hEncData)) == NULL)
183 return TSPERR(TSS_E_INVALID_HANDLE);
184
185 encdata = (struct tr_encdata_obj *)obj->data;
186
187 if (pcrInfoType != encdata->pcrInfoType) {
188 result = TSPERR(TSS_E_INVALID_OBJ_ACCESS);
189 goto done;
190 }
191
192 switch (pcrInfoType) {
193 case TSS_PCRS_STRUCT_INFO:
194 if (dir == TSS_TSPATTRIB_ENCDATAPCR_DIGEST_ATCREATION)
195 digest = &encdata->pcrInfo.info11.digestAtCreation;
196 else if (dir == TSS_TSPATTRIB_ENCDATAPCR_DIGEST_ATRELEASE)
197 digest = &encdata->pcrInfo.info11.digestAtRelease;
198 else {
199 result = TSPERR(TSS_E_BAD_PARAMETER);
200 goto done;
201 }
202 break;
203 case TSS_PCRS_STRUCT_INFO_LONG:
204 if (dir == TSS_TSPATTRIB_ENCDATAPCRLONG_DIGEST_ATCREATION)
205 digest = &encdata->pcrInfo.infolong.digestAtCreation;
206 else if (dir == TSS_TSPATTRIB_ENCDATAPCRLONG_DIGEST_ATRELEASE)
207 digest = &encdata->pcrInfo.infolong.digestAtRelease;
208 else {
209 result = TSPERR(TSS_E_BAD_PARAMETER);
210 goto done;
211 }
212 break;
213 default:
214 result = TSPERR(TSS_E_INVALID_OBJ_ACCESS);
215 goto done;
216 }
217
218 *size = sizeof(TPM_DIGEST);
219
220 if ((*data = calloc_tspi(obj->tspContext, *size)) == NULL) {
221 LogError("malloc of %u bytes failed.", *size);
222 *size = 0;
223 result = TSPERR(TSS_E_OUTOFMEMORY);
224 goto done;
225 }
226
227 offset = 0;
228 Trspi_LoadBlob_DIGEST(&offset, *data, digest);
229 done:
230 obj_list_put(&encdata_list);
231
232 return result;
233 }
234
235 TSS_RESULT
obj_encdata_get_pcr_locality(TSS_HENCDATA hEncData,TSS_FLAG dir,UINT32 * locality)236 obj_encdata_get_pcr_locality(TSS_HENCDATA hEncData, TSS_FLAG dir, UINT32 *locality)
237 {
238 struct tsp_object *obj;
239 struct tr_encdata_obj *encdata;
240 TSS_RESULT result = TSS_SUCCESS;
241
242 if ((obj = obj_list_get_obj(&encdata_list, hEncData)) == NULL)
243 return TSPERR(TSS_E_INVALID_HANDLE);
244
245 encdata = (struct tr_encdata_obj *)obj->data;
246
247 if (encdata->pcrInfoType == TSS_PCRS_STRUCT_INFO_LONG) {
248 if (dir == TSS_TSPATTRIB_ENCDATAPCRLONG_LOCALITY_ATCREATION)
249 *locality = encdata->pcrInfo.infolong.localityAtCreation;
250 else if (dir == TSS_TSPATTRIB_ENCDATAPCRLONG_LOCALITY_ATRELEASE)
251 *locality = encdata->pcrInfo.infolong.localityAtRelease;
252 else
253 result = TSPERR(TSS_E_BAD_PARAMETER);
254 } else
255 result = TSPERR(TSS_E_INVALID_OBJ_ACCESS);
256
257 obj_list_put(&encdata_list);
258
259 return result;
260 }
261
262 TSS_RESULT
obj_encdata_get_pcr_selection(TSS_HENCDATA hEncData,TSS_FLAG pcrInfoType,TSS_FLAG dir,UINT32 * size,BYTE ** data)263 obj_encdata_get_pcr_selection(TSS_HENCDATA hEncData,
264 TSS_FLAG pcrInfoType,
265 TSS_FLAG dir,
266 UINT32 *size,
267 BYTE **data)
268 {
269 struct tsp_object *obj;
270 struct tr_encdata_obj *encdata;
271 TSS_RESULT result = TSS_SUCCESS;
272 TPM_PCR_SELECTION *selection = NULL;
273 UINT64 offset;
274
275 if ((obj = obj_list_get_obj(&encdata_list, hEncData)) == NULL)
276 return TSPERR(TSS_E_INVALID_HANDLE);
277
278 encdata = (struct tr_encdata_obj *)obj->data;
279
280 if (pcrInfoType != encdata->pcrInfoType) {
281 result = TSPERR(TSS_E_INVALID_OBJ_ACCESS);
282 goto done;
283 }
284
285 switch (pcrInfoType) {
286 case TSS_PCRS_STRUCT_INFO:
287 if (dir == TSS_TSPATTRIB_ENCDATAPCR_SELECTION)
288 selection = &encdata->pcrInfo.info11.pcrSelection;
289 break;
290 case TSS_PCRS_STRUCT_INFO_LONG:
291 if (dir == TSS_TSPATTRIB_ENCDATAPCRLONG_CREATION_SELECTION)
292 selection = &encdata->pcrInfo.infolong.creationPCRSelection;
293 else if (dir == TSS_TSPATTRIB_ENCDATAPCRLONG_RELEASE_SELECTION)
294 selection = &encdata->pcrInfo.infolong.releasePCRSelection;
295 else {
296 result = TSPERR(TSS_E_INTERNAL_ERROR);
297 goto done;
298 }
299 break;
300 default:
301 result = TSPERR(TSS_E_INVALID_OBJ_ACCESS);
302 goto done;
303 }
304
305 if (selection == NULL) {
306 result = TSPERR(TSS_E_INVALID_OBJ_ACCESS);
307 goto done;
308 }
309
310 *size = sizeof(UINT16) + selection->sizeOfSelect;
311
312 if ((*data = calloc_tspi(obj->tspContext, *size)) == NULL) {
313 LogError("malloc of %u bytes failed.", *size);
314 *size = 0;
315 result = TSPERR(TSS_E_OUTOFMEMORY);
316 goto done;
317 }
318
319 offset = 0;
320 Trspi_LoadBlob_PCR_SELECTION(&offset, *data, selection);
321 done:
322 obj_list_put(&encdata_list);
323
324 return result;
325 }
326
327 TSS_RESULT
obj_encdata_set_pcr_info(TSS_HENCDATA hEncData,UINT32 pcrInfoType,BYTE * info_blob)328 obj_encdata_set_pcr_info(TSS_HENCDATA hEncData, UINT32 pcrInfoType, BYTE *info_blob)
329 {
330 struct tsp_object *obj;
331 struct tr_encdata_obj *encdata;
332 TSS_RESULT result = TSS_SUCCESS;
333 UINT64 offset = 0;
334
335 if ((obj = obj_list_get_obj(&encdata_list, hEncData)) == NULL)
336 return TSPERR(TSS_E_INVALID_HANDLE);
337
338 encdata = (struct tr_encdata_obj *)obj->data;
339
340 switch (pcrInfoType) {
341 case TSS_PCRS_STRUCT_INFO_LONG:
342 result = Trspi_UnloadBlob_PCR_INFO_LONG(&offset, info_blob,
343 &encdata->pcrInfo.infolong);
344 break;
345 case TSS_PCRS_STRUCT_INFO:
346 result = Trspi_UnloadBlob_PCR_INFO(&offset, info_blob,
347 &encdata->pcrInfo.info11);
348 break;
349 default:
350 result = TSPERR(TSS_E_INVALID_OBJ_ACCESS);
351 goto done;
352 }
353
354 encdata->pcrInfoType = pcrInfoType;
355
356 /* XXX are we using this anywhere? */
357 obj->flags |= TSS_OBJ_FLAG_PCRS;
358 done:
359 obj_list_put(&encdata_list);
360
361 return result;
362 }
363
364 TSS_RESULT
obj_encdata_set_data(TSS_HENCDATA hEncData,UINT32 size,BYTE * data)365 obj_encdata_set_data(TSS_HENCDATA hEncData, UINT32 size, BYTE *data)
366 {
367 struct tsp_object *obj;
368 struct tr_encdata_obj *encdata;
369 TSS_RESULT result = TSS_SUCCESS;
370
371 if ((obj = obj_list_get_obj(&encdata_list, hEncData)) == NULL)
372 return TSPERR(TSS_E_INVALID_HANDLE);
373
374 encdata = (struct tr_encdata_obj *)obj->data;
375
376 free(encdata->encryptedData);
377 encdata->encryptedData = NULL;
378 encdata->encryptedDataLength = 0;
379
380 if (size > 0) {
381 if ((encdata->encryptedData = malloc(size)) == NULL) {
382 LogError("malloc of %u bytes failed.", size);
383 result = TSPERR(TSS_E_OUTOFMEMORY);
384 goto done;
385 }
386 encdata->encryptedDataLength = size;
387 memcpy(encdata->encryptedData, data, size);
388 }
389
390 done:
391 obj_list_put(&encdata_list);
392
393 return result;
394 }
395
396 void
encdata_free(void * data)397 encdata_free(void *data)
398 {
399 struct tr_encdata_obj *encdata = (struct tr_encdata_obj *)data;
400
401 free(encdata->encryptedData);
402
403 switch (encdata->pcrInfoType) {
404 case TSS_PCRS_STRUCT_INFO:
405 free(encdata->pcrInfo.info11.pcrSelection.pcrSelect);
406 break;
407 case TSS_PCRS_STRUCT_INFO_LONG:
408 free(encdata->pcrInfo.infolong.creationPCRSelection.pcrSelect);
409 free(encdata->pcrInfo.infolong.releasePCRSelection.pcrSelect);
410 break;
411 default:
412 /* no PCR data was set */
413 break;
414 }
415
416 free(encdata);
417 }
418
419 /* remove an individual encdata object from the encdata list with handle
420 * equal to hObject */
421 TSS_RESULT
obj_encdata_remove(TSS_HOBJECT hObject,TSS_HCONTEXT tspContext)422 obj_encdata_remove(TSS_HOBJECT hObject, TSS_HCONTEXT tspContext)
423 {
424 TSS_RESULT result;
425
426 if ((result = obj_list_remove(&encdata_list, &encdata_free, hObject, tspContext)))
427 return result;
428
429 return TSS_SUCCESS;
430 }
431
432 void
obj_encdata_remove_policy_refs(TSS_HPOLICY hPolicy,TSS_HCONTEXT tspContext)433 obj_encdata_remove_policy_refs(TSS_HPOLICY hPolicy, TSS_HCONTEXT tspContext)
434 {
435 struct tsp_object *obj;
436 struct obj_list *list = &encdata_list;
437 struct tr_encdata_obj *encdata;
438
439 pthread_mutex_lock(&list->lock);
440
441 for (obj = list->head; obj; obj = obj->next) {
442 if (obj->tspContext != tspContext)
443 continue;
444
445 encdata = (struct tr_encdata_obj *)obj->data;
446 if (encdata->usagePolicy == hPolicy)
447 encdata->usagePolicy = NULL_HPOLICY;
448 }
449
450 pthread_mutex_unlock(&list->lock);
451 }
452
453 #ifdef TSS_BUILD_SEALX
454 TSS_RESULT
obj_encdata_set_seal_protect_mode(TSS_HENCDATA hEncData,UINT32 protectMode)455 obj_encdata_set_seal_protect_mode(TSS_HENCDATA hEncData, UINT32 protectMode)
456 {
457 struct tsp_object *obj;
458 struct tr_encdata_obj *encdata;
459
460 if ((obj = obj_list_get_obj(&encdata_list, hEncData)) == NULL)
461 return TSPERR(TSS_E_INVALID_HANDLE);
462
463 encdata = (struct tr_encdata_obj *)obj->data;
464
465 encdata->protectMode = protectMode;
466
467 obj_list_put(&encdata_list);
468
469 return TSS_SUCCESS;
470 }
471
472 TSS_RESULT
obj_encdata_get_seal_protect_mode(TSS_HENCDATA hEncData,UINT32 * protectMode)473 obj_encdata_get_seal_protect_mode(TSS_HENCDATA hEncData, UINT32 *protectMode)
474 {
475 struct tsp_object *obj;
476 struct tr_encdata_obj *encdata;
477
478 if ((obj = obj_list_get_obj(&encdata_list, hEncData)) == NULL)
479 return TSPERR(TSS_E_INVALID_HANDLE);
480
481 encdata = (struct tr_encdata_obj *)obj->data;
482
483 *protectMode = encdata->protectMode;
484
485 obj_list_put(&encdata_list);
486
487 return TSS_SUCCESS;
488 }
489 #endif
490
491