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, *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 117 TSS_RESULT 118 obj_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 132 TSS_RESULT 133 obj_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 167 done: 168 obj_list_put(&delfamily_list); 169 170 free(outData); 171 172 return result; 173 } 174 175 TSS_RESULT 176 obj_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 193 TSS_RESULT 194 obj_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 228 done: 229 obj_list_put(&delfamily_list); 230 231 free(outData); 232 233 return result; 234 } 235 236 TSS_RESULT 237 obj_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 254 TSS_RESULT 255 obj_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 272 TSS_RESULT 273 obj_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 290 TSS_RESULT 291 obj_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 308 TSS_RESULT 309 obj_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 326 TSS_RESULT 327 obj_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 344 TSS_RESULT 345 obj_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