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, *prev = NULL; 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 return; 100 } else 101 hContext = (TSS_HCONTEXT)hObject; 102 103 for (obj = list->head; obj; prev = obj, obj = obj->next) { 104 if (obj->tspContext != hContext) 105 continue; 106 107 delfamily = (struct tr_delfamily_obj *)obj->data; 108 if (delfamily->familyID == familyID) { 109 *hFamily = obj->handle; 110 break; 111 } 112 } 113 114 pthread_mutex_unlock(&list->lock); 115} 116 117TSS_RESULT 118obj_delfamily_get_tsp_context(TSS_HDELFAMILY hFamily, TSS_HCONTEXT *hContext) 119{ 120 struct tsp_object *obj; 121 122 if ((obj = obj_list_get_obj(&delfamily_list, hFamily)) == NULL) 123 return TSPERR(TSS_E_INVALID_HANDLE); 124 125 *hContext = obj->tspContext; 126 127 obj_list_put(&delfamily_list); 128 129 return TSS_SUCCESS; 130} 131 132TSS_RESULT 133obj_delfamily_set_locked(TSS_HDELFAMILY hFamily, TSS_BOOL state, TSS_BOOL setInTpm) 134{ 135 struct tsp_object *obj; 136 struct tr_delfamily_obj *delfamily; 137 TSS_HTPM hTpm; 138 UINT32 opDataSize; 139 BYTE opData[8]; 140 UINT32 outDataSize; 141 BYTE *outData = NULL; 142 UINT64 offset; 143 TSS_RESULT result = TSS_SUCCESS; 144 145 if ((obj = obj_list_get_obj(&delfamily_list, hFamily)) == NULL) 146 return TSPERR(TSS_E_INVALID_HANDLE); 147 148 delfamily = (struct tr_delfamily_obj *)obj->data; 149 150 if (setInTpm) { 151 if ((result = obj_tpm_get(obj->tspContext, &hTpm))) 152 goto done; 153 154 offset = 0; 155 Trspi_LoadBlob_BOOL(&offset, state, opData); 156 opDataSize = offset; 157 if ((result = do_delegate_manage(hTpm, delfamily->familyID, TPM_FAMILY_ADMIN, 158 opDataSize, opData, &outDataSize, &outData))) 159 goto done; 160 } 161 162 if (state) 163 delfamily->stateFlags |= TSS_DELFAMILY_FLAGS_STATE_LOCKED; 164 else 165 delfamily->stateFlags &= ~TSS_DELFAMILY_FLAGS_STATE_LOCKED; 166 167done: 168 obj_list_put(&delfamily_list); 169 170 free(outData); 171 172 return result; 173} 174 175TSS_RESULT 176obj_delfamily_get_locked(TSS_HDELFAMILY hFamily, TSS_BOOL *state) 177{ 178 struct tsp_object *obj; 179 struct tr_delfamily_obj *delfamily; 180 181 if ((obj = obj_list_get_obj(&delfamily_list, hFamily)) == NULL) 182 return TSPERR(TSS_E_INVALID_HANDLE); 183 184 delfamily = (struct tr_delfamily_obj *)obj->data; 185 186 *state = (delfamily->stateFlags & TSS_DELFAMILY_FLAGS_STATE_LOCKED) ? TRUE : FALSE; 187 188 obj_list_put(&delfamily_list); 189 190 return TSS_SUCCESS; 191} 192 193TSS_RESULT 194obj_delfamily_set_enabled(TSS_HDELFAMILY hFamily, TSS_BOOL state, TSS_BOOL setInTpm) 195{ 196 struct tsp_object *obj; 197 struct tr_delfamily_obj *delfamily; 198 TSS_HTPM hTpm; 199 UINT32 opDataSize; 200 BYTE opData[8]; 201 UINT32 outDataSize; 202 BYTE *outData = NULL; 203 UINT64 offset; 204 TSS_RESULT result = TSS_SUCCESS; 205 206 if ((obj = obj_list_get_obj(&delfamily_list, hFamily)) == NULL) 207 return TSPERR(TSS_E_INVALID_HANDLE); 208 209 delfamily = (struct tr_delfamily_obj *)obj->data; 210 211 if (setInTpm) { 212 if ((result = obj_tpm_get(obj->tspContext, &hTpm))) 213 goto done; 214 215 offset = 0; 216 Trspi_LoadBlob_BOOL(&offset, state, opData); 217 opDataSize = offset; 218 if ((result = do_delegate_manage(hTpm, delfamily->familyID, TPM_FAMILY_ENABLE, 219 opDataSize, opData, &outDataSize, &outData))) 220 goto done; 221 } 222 223 if (state) 224 delfamily->stateFlags |= TSS_DELFAMILY_FLAGS_STATE_ENABLED; 225 else 226 delfamily->stateFlags &= ~TSS_DELFAMILY_FLAGS_STATE_ENABLED; 227 228done: 229 obj_list_put(&delfamily_list); 230 231 free(outData); 232 233 return result; 234} 235 236TSS_RESULT 237obj_delfamily_get_enabled(TSS_HDELFAMILY hFamily, TSS_BOOL *state) 238{ 239 struct tsp_object *obj; 240 struct tr_delfamily_obj *delfamily; 241 242 if ((obj = obj_list_get_obj(&delfamily_list, hFamily)) == NULL) 243 return TSPERR(TSS_E_INVALID_HANDLE); 244 245 delfamily = (struct tr_delfamily_obj *)obj->data; 246 247 *state = (delfamily->stateFlags & TSS_DELFAMILY_FLAGS_STATE_ENABLED) ? TRUE : FALSE; 248 249 obj_list_put(&delfamily_list); 250 251 return TSS_SUCCESS; 252} 253 254TSS_RESULT 255obj_delfamily_set_vercount(TSS_HDELFAMILY hFamily, UINT32 verCount) 256{ 257 struct tsp_object *obj; 258 struct tr_delfamily_obj *delfamily; 259 260 if ((obj = obj_list_get_obj(&delfamily_list, hFamily)) == NULL) 261 return TSPERR(TSS_E_INVALID_HANDLE); 262 263 delfamily = (struct tr_delfamily_obj *)obj->data; 264 265 delfamily->verCount = verCount; 266 267 obj_list_put(&delfamily_list); 268 269 return TSS_SUCCESS; 270} 271 272TSS_RESULT 273obj_delfamily_get_vercount(TSS_HDELFAMILY hFamily, UINT32 *verCount) 274{ 275 struct tsp_object *obj; 276 struct tr_delfamily_obj *delfamily; 277 278 if ((obj = obj_list_get_obj(&delfamily_list, hFamily)) == NULL) 279 return TSPERR(TSS_E_INVALID_HANDLE); 280 281 delfamily = (struct tr_delfamily_obj *)obj->data; 282 283 *verCount = delfamily->verCount; 284 285 obj_list_put(&delfamily_list); 286 287 return TSS_SUCCESS; 288} 289 290TSS_RESULT 291obj_delfamily_set_familyid(TSS_HDELFAMILY hFamily, UINT32 familyID) 292{ 293 struct tsp_object *obj; 294 struct tr_delfamily_obj *delfamily; 295 296 if ((obj = obj_list_get_obj(&delfamily_list, hFamily)) == NULL) 297 return TSPERR(TSS_E_INVALID_HANDLE); 298 299 delfamily = (struct tr_delfamily_obj *)obj->data; 300 301 delfamily->familyID = familyID; 302 303 obj_list_put(&delfamily_list); 304 305 return TSS_SUCCESS; 306} 307 308TSS_RESULT 309obj_delfamily_get_familyid(TSS_HDELFAMILY hFamily, UINT32 *familyID) 310{ 311 struct tsp_object *obj; 312 struct tr_delfamily_obj *delfamily; 313 314 if ((obj = obj_list_get_obj(&delfamily_list, hFamily)) == NULL) 315 return TSPERR(TSS_E_INVALID_HANDLE); 316 317 delfamily = (struct tr_delfamily_obj *)obj->data; 318 319 *familyID = delfamily->familyID; 320 321 obj_list_put(&delfamily_list); 322 323 return TSS_SUCCESS; 324} 325 326TSS_RESULT 327obj_delfamily_set_label(TSS_HDELFAMILY hFamily, BYTE label) 328{ 329 struct tsp_object *obj; 330 struct tr_delfamily_obj *delfamily; 331 332 if ((obj = obj_list_get_obj(&delfamily_list, hFamily)) == NULL) 333 return TSPERR(TSS_E_INVALID_HANDLE); 334 335 delfamily = (struct tr_delfamily_obj *)obj->data; 336 337 delfamily->label = label; 338 339 obj_list_put(&delfamily_list); 340 341 return TSS_SUCCESS; 342} 343 344TSS_RESULT 345obj_delfamily_get_label(TSS_HDELFAMILY hFamily, BYTE *label) 346{ 347 struct tsp_object *obj; 348 struct tr_delfamily_obj *delfamily; 349 350 if ((obj = obj_list_get_obj(&delfamily_list, hFamily)) == NULL) 351 return TSPERR(TSS_E_INVALID_HANDLE); 352 353 delfamily = (struct tr_delfamily_obj *)obj->data; 354 355 *label = delfamily->label; 356 357 obj_list_put(&delfamily_list); 358 359 return TSS_SUCCESS; 360} 361 362