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