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 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 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 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 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 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 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 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 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 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 *size = sizeof(UINT16) + selection->sizeOfSelect; 306 307 if ((*data = calloc_tspi(obj->tspContext, *size)) == NULL) { 308 LogError("malloc of %u bytes failed.", *size); 309 *size = 0; 310 result = TSPERR(TSS_E_OUTOFMEMORY); 311 goto done; 312 } 313 314 offset = 0; 315 Trspi_LoadBlob_PCR_SELECTION(&offset, *data, selection); 316 done: 317 obj_list_put(&encdata_list); 318 319 return result; 320 } 321 322 TSS_RESULT 323 obj_encdata_set_pcr_info(TSS_HENCDATA hEncData, UINT32 pcrInfoType, BYTE *info_blob) 324 { 325 struct tsp_object *obj; 326 struct tr_encdata_obj *encdata; 327 TSS_RESULT result = TSS_SUCCESS; 328 UINT64 offset = 0; 329 330 if ((obj = obj_list_get_obj(&encdata_list, hEncData)) == NULL) 331 return TSPERR(TSS_E_INVALID_HANDLE); 332 333 encdata = (struct tr_encdata_obj *)obj->data; 334 335 switch (pcrInfoType) { 336 case TSS_PCRS_STRUCT_INFO_LONG: 337 result = Trspi_UnloadBlob_PCR_INFO_LONG(&offset, info_blob, 338 &encdata->pcrInfo.infolong); 339 break; 340 case TSS_PCRS_STRUCT_INFO: 341 result = Trspi_UnloadBlob_PCR_INFO(&offset, info_blob, 342 &encdata->pcrInfo.info11); 343 break; 344 default: 345 result = TSPERR(TSS_E_INVALID_OBJ_ACCESS); 346 goto done; 347 } 348 349 encdata->pcrInfoType = pcrInfoType; 350 351 /* XXX are we using this anywhere? */ 352 obj->flags |= TSS_OBJ_FLAG_PCRS; 353 done: 354 obj_list_put(&encdata_list); 355 356 return result; 357 } 358 359 TSS_RESULT 360 obj_encdata_set_data(TSS_HENCDATA hEncData, UINT32 size, BYTE *data) 361 { 362 struct tsp_object *obj; 363 struct tr_encdata_obj *encdata; 364 TSS_RESULT result = TSS_SUCCESS; 365 366 if ((obj = obj_list_get_obj(&encdata_list, hEncData)) == NULL) 367 return TSPERR(TSS_E_INVALID_HANDLE); 368 369 encdata = (struct tr_encdata_obj *)obj->data; 370 371 free(encdata->encryptedData); 372 encdata->encryptedData = NULL; 373 encdata->encryptedDataLength = 0; 374 375 if (size > 0) { 376 if ((encdata->encryptedData = malloc(size)) == NULL) { 377 LogError("malloc of %u bytes failed.", size); 378 result = TSPERR(TSS_E_OUTOFMEMORY); 379 goto done; 380 } 381 encdata->encryptedDataLength = size; 382 memcpy(encdata->encryptedData, data, size); 383 } 384 385 done: 386 obj_list_put(&encdata_list); 387 388 return result; 389 } 390 391 void 392 encdata_free(void *data) 393 { 394 struct tr_encdata_obj *encdata = (struct tr_encdata_obj *)data; 395 396 free(encdata->encryptedData); 397 398 switch (encdata->pcrInfoType) { 399 case TSS_PCRS_STRUCT_INFO: 400 free(encdata->pcrInfo.info11.pcrSelection.pcrSelect); 401 break; 402 case TSS_PCRS_STRUCT_INFO_LONG: 403 free(encdata->pcrInfo.infolong.creationPCRSelection.pcrSelect); 404 free(encdata->pcrInfo.infolong.releasePCRSelection.pcrSelect); 405 break; 406 default: 407 /* no PCR data was set */ 408 break; 409 } 410 411 free(encdata); 412 } 413 414 /* remove an individual encdata object from the encdata list with handle 415 * equal to hObject */ 416 TSS_RESULT 417 obj_encdata_remove(TSS_HOBJECT hObject, TSS_HCONTEXT tspContext) 418 { 419 TSS_RESULT result; 420 421 if ((result = obj_list_remove(&encdata_list, &encdata_free, hObject, tspContext))) 422 return result; 423 424 return TSS_SUCCESS; 425 } 426 427 void 428 obj_encdata_remove_policy_refs(TSS_HPOLICY hPolicy, TSS_HCONTEXT tspContext) 429 { 430 struct tsp_object *obj, *prev = NULL; 431 struct obj_list *list = &encdata_list; 432 struct tr_encdata_obj *encdata; 433 434 pthread_mutex_lock(&list->lock); 435 436 for (obj = list->head; obj; prev = obj, obj = obj->next) { 437 if (obj->tspContext != tspContext) 438 continue; 439 440 encdata = (struct tr_encdata_obj *)obj->data; 441 if (encdata->usagePolicy == hPolicy) 442 encdata->usagePolicy = NULL_HPOLICY; 443 } 444 445 pthread_mutex_unlock(&list->lock); 446 } 447 448 #ifdef TSS_BUILD_SEALX 449 TSS_RESULT 450 obj_encdata_set_seal_protect_mode(TSS_HENCDATA hEncData, UINT32 protectMode) 451 { 452 struct tsp_object *obj; 453 struct tr_encdata_obj *encdata; 454 455 if ((obj = obj_list_get_obj(&encdata_list, hEncData)) == NULL) 456 return TSPERR(TSS_E_INVALID_HANDLE); 457 458 encdata = (struct tr_encdata_obj *)obj->data; 459 460 encdata->protectMode = protectMode; 461 462 obj_list_put(&encdata_list); 463 464 return TSS_SUCCESS; 465 } 466 467 TSS_RESULT 468 obj_encdata_get_seal_protect_mode(TSS_HENCDATA hEncData, UINT32 *protectMode) 469 { 470 struct tsp_object *obj; 471 struct tr_encdata_obj *encdata; 472 473 if ((obj = obj_list_get_obj(&encdata_list, hEncData)) == NULL) 474 return TSPERR(TSS_E_INVALID_HANDLE); 475 476 encdata = (struct tr_encdata_obj *)obj->data; 477 478 *protectMode = encdata->protectMode; 479 480 obj_list_put(&encdata_list); 481 482 return TSS_SUCCESS; 483 } 484 #endif 485 486