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