xref: /netbsd-src/crypto/external/cpl/trousers/dist/src/tspi/obj_encdata.c (revision 1023804e3833a0bd94414f2545512128f6502c74)
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