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 26void 27delfamily_free(void *data) 28{ 29 struct tr_delfamily_obj *delfamily = (struct tr_delfamily_obj *)data; 30 31 free(delfamily); 32} 33 34TSS_BOOL 35obj_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 47TSS_RESULT 48obj_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 67TSS_RESULT 68obj_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 85void 86obj_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 119TSS_RESULT 120obj_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 134TSS_RESULT 135obj_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 169done: 170 obj_list_put(&delfamily_list); 171 172 free(outData); 173 174 return result; 175} 176 177TSS_RESULT 178obj_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 195TSS_RESULT 196obj_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 230done: 231 obj_list_put(&delfamily_list); 232 233 free(outData); 234 235 return result; 236} 237 238TSS_RESULT 239obj_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 256TSS_RESULT 257obj_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 274TSS_RESULT 275obj_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 292TSS_RESULT 293obj_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 310TSS_RESULT 311obj_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 328TSS_RESULT 329obj_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 346TSS_RESULT 347obj_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