Home | History | Annotate | Line # | Download | only in tspi
      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;
     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
    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
    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
    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
    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
    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
    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
    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
    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
    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
    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
    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