diff options
Diffstat (limited to 'src/tspi/obj_encdata.c')
-rw-r--r-- | src/tspi/obj_encdata.c | 485 |
1 files changed, 485 insertions, 0 deletions
diff --git a/src/tspi/obj_encdata.c b/src/tspi/obj_encdata.c new file mode 100644 index 0000000..0931bcb --- /dev/null +++ b/src/tspi/obj_encdata.c @@ -0,0 +1,485 @@ + +/* + * Licensed Materials - Property of IBM + * + * trousers - An open source TCG Software Stack + * + * (C) Copyright International Business Machines Corp. 2005, 2007 + * + */ + + +#include <stdlib.h> +#include <stdio.h> +#include <errno.h> +#include <string.h> + +#include "trousers/tss.h" +#include "trousers/trousers.h" +#include "trousers_types.h" +#include "spi_utils.h" +#include "capabilities.h" +#include "tsplog.h" +#include "obj.h" + +TSS_RESULT +obj_encdata_add(TSS_HCONTEXT tspContext, UINT32 type, TSS_HOBJECT *phObject) +{ + TSS_RESULT result; + struct tr_encdata_obj *encdata = calloc(1, sizeof(struct tr_encdata_obj)); + + if (encdata == NULL) { + LogError("malloc of %zd bytes failed.", + sizeof(struct tr_encdata_obj)); + return TSPERR(TSS_E_OUTOFMEMORY); + } + + /* add usage policy */ + if ((result = obj_context_get_policy(tspContext, TSS_POLICY_USAGE, + &encdata->usagePolicy))) { + free(encdata); + return result; + } + + encdata->type = type; + + if ((result = obj_list_add(&encdata_list, tspContext, 0, encdata, phObject))) { + free(encdata); + return result; + } + + return TSS_SUCCESS; +} + +TSS_BOOL +obj_is_encdata(TSS_HOBJECT hObject) +{ + TSS_BOOL answer = FALSE; + + if ((obj_list_get_obj(&encdata_list, hObject))) { + answer = TRUE; + obj_list_put(&encdata_list); + } + + return answer; +} + +TSS_RESULT +obj_encdata_get_tsp_context(TSS_HENCDATA hEncdata, TSS_HCONTEXT *tspContext) +{ + struct tsp_object *obj; + + if ((obj = obj_list_get_obj(&encdata_list, hEncdata)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + *tspContext = obj->tspContext; + + obj_list_put(&encdata_list); + + return TSS_SUCCESS; +} + +TSS_RESULT +obj_encdata_get_policy(TSS_HENCDATA hEncData, UINT32 policyType, TSS_HPOLICY *phPolicy) +{ + struct tsp_object *obj; + struct tr_encdata_obj *encdata; + TSS_RESULT result = TSS_SUCCESS; + + if ((obj = obj_list_get_obj(&encdata_list, hEncData)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + encdata = (struct tr_encdata_obj *)obj->data; + + switch (policyType) { + case TSS_POLICY_USAGE: + *phPolicy = encdata->usagePolicy; + break; + default: + result = TSPERR(TSS_E_BAD_PARAMETER); + } + + obj_list_put(&encdata_list); + + return result; +} + +TSS_RESULT +obj_encdata_set_policy(TSS_HENCDATA hEncData, TSS_HPOLICY hPolicy) +{ + struct tsp_object *obj; + struct tr_encdata_obj *encdata; + UINT32 policyType; + TSS_RESULT result = TSS_SUCCESS; + + if ((result = obj_policy_get_type(hPolicy, &policyType))) + return result; + + if ((obj = obj_list_get_obj(&encdata_list, hEncData)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + encdata = (struct tr_encdata_obj *)obj->data; + + switch (policyType) { + case TSS_POLICY_USAGE: + encdata->usagePolicy = hPolicy; + break; + default: + result = TSPERR(TSS_E_BAD_PARAMETER); + } + + obj_list_put(&encdata_list); + + return result; +} + +TSS_RESULT +obj_encdata_get_data(TSS_HENCDATA hEncData, UINT32 *size, BYTE **data) +{ + struct tsp_object *obj; + struct tr_encdata_obj *encdata; + TSS_RESULT result = TSS_SUCCESS; + + if ((obj = obj_list_get_obj(&encdata_list, hEncData)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + encdata = (struct tr_encdata_obj *)obj->data; + + if (encdata->encryptedDataLength == 0) { + result = TSPERR(TSS_E_INVALID_OBJ_ACCESS); + goto done; + } else { + *data = calloc_tspi(obj->tspContext, encdata->encryptedDataLength); + if (*data == NULL) { + LogError("malloc of %d bytes failed.", + encdata->encryptedDataLength); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto done; + } + *size = encdata->encryptedDataLength; + memcpy(*data, encdata->encryptedData, *size); + } + +done: + obj_list_put(&encdata_list); + + return result; +} + +TSS_RESULT +obj_encdata_get_pcr_digest(TSS_HENCDATA hEncData, + TSS_FLAG pcrInfoType, + TSS_FLAG dir, + UINT32 *size, + BYTE **data) +{ + struct tsp_object *obj; + struct tr_encdata_obj *encdata; + TSS_RESULT result = TSS_SUCCESS; + TPM_DIGEST *digest; + UINT64 offset; + + if ((obj = obj_list_get_obj(&encdata_list, hEncData)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + encdata = (struct tr_encdata_obj *)obj->data; + + if (pcrInfoType != encdata->pcrInfoType) { + result = TSPERR(TSS_E_INVALID_OBJ_ACCESS); + goto done; + } + + switch (pcrInfoType) { + case TSS_PCRS_STRUCT_INFO: + if (dir == TSS_TSPATTRIB_ENCDATAPCR_DIGEST_ATCREATION) + digest = &encdata->pcrInfo.info11.digestAtCreation; + else if (dir == TSS_TSPATTRIB_ENCDATAPCR_DIGEST_ATRELEASE) + digest = &encdata->pcrInfo.info11.digestAtRelease; + else { + result = TSPERR(TSS_E_BAD_PARAMETER); + goto done; + } + break; + case TSS_PCRS_STRUCT_INFO_LONG: + if (dir == TSS_TSPATTRIB_ENCDATAPCRLONG_DIGEST_ATCREATION) + digest = &encdata->pcrInfo.infolong.digestAtCreation; + else if (dir == TSS_TSPATTRIB_ENCDATAPCRLONG_DIGEST_ATRELEASE) + digest = &encdata->pcrInfo.infolong.digestAtRelease; + else { + result = TSPERR(TSS_E_BAD_PARAMETER); + goto done; + } + break; + default: + result = TSPERR(TSS_E_INVALID_OBJ_ACCESS); + goto done; + } + + *size = sizeof(TPM_DIGEST); + + if ((*data = calloc_tspi(obj->tspContext, *size)) == NULL) { + LogError("malloc of %u bytes failed.", *size); + *size = 0; + result = TSPERR(TSS_E_OUTOFMEMORY); + goto done; + } + + offset = 0; + Trspi_LoadBlob_DIGEST(&offset, *data, digest); +done: + obj_list_put(&encdata_list); + + return result; +} + +TSS_RESULT +obj_encdata_get_pcr_locality(TSS_HENCDATA hEncData, TSS_FLAG dir, UINT32 *locality) +{ + struct tsp_object *obj; + struct tr_encdata_obj *encdata; + TSS_RESULT result = TSS_SUCCESS; + + if ((obj = obj_list_get_obj(&encdata_list, hEncData)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + encdata = (struct tr_encdata_obj *)obj->data; + + if (encdata->pcrInfoType == TSS_PCRS_STRUCT_INFO_LONG) { + if (dir == TSS_TSPATTRIB_ENCDATAPCRLONG_LOCALITY_ATCREATION) + *locality = encdata->pcrInfo.infolong.localityAtCreation; + else if (dir == TSS_TSPATTRIB_ENCDATAPCRLONG_LOCALITY_ATRELEASE) + *locality = encdata->pcrInfo.infolong.localityAtRelease; + else + result = TSPERR(TSS_E_BAD_PARAMETER); + } else + result = TSPERR(TSS_E_INVALID_OBJ_ACCESS); + + obj_list_put(&encdata_list); + + return result; +} + +TSS_RESULT +obj_encdata_get_pcr_selection(TSS_HENCDATA hEncData, + TSS_FLAG pcrInfoType, + TSS_FLAG dir, + UINT32 *size, + BYTE **data) +{ + struct tsp_object *obj; + struct tr_encdata_obj *encdata; + TSS_RESULT result = TSS_SUCCESS; + TPM_PCR_SELECTION *selection = NULL; + UINT64 offset; + + if ((obj = obj_list_get_obj(&encdata_list, hEncData)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + encdata = (struct tr_encdata_obj *)obj->data; + + if (pcrInfoType != encdata->pcrInfoType) { + result = TSPERR(TSS_E_INVALID_OBJ_ACCESS); + goto done; + } + + switch (pcrInfoType) { + case TSS_PCRS_STRUCT_INFO: + if (dir == TSS_TSPATTRIB_ENCDATAPCR_SELECTION) + selection = &encdata->pcrInfo.info11.pcrSelection; + break; + case TSS_PCRS_STRUCT_INFO_LONG: + if (dir == TSS_TSPATTRIB_ENCDATAPCRLONG_CREATION_SELECTION) + selection = &encdata->pcrInfo.infolong.creationPCRSelection; + else if (dir == TSS_TSPATTRIB_ENCDATAPCRLONG_RELEASE_SELECTION) + selection = &encdata->pcrInfo.infolong.releasePCRSelection; + else { + result = TSPERR(TSS_E_INTERNAL_ERROR); + goto done; + } + break; + default: + result = TSPERR(TSS_E_INVALID_OBJ_ACCESS); + goto done; + } + + *size = sizeof(UINT16) + selection->sizeOfSelect; + + if ((*data = calloc_tspi(obj->tspContext, *size)) == NULL) { + LogError("malloc of %u bytes failed.", *size); + *size = 0; + result = TSPERR(TSS_E_OUTOFMEMORY); + goto done; + } + + offset = 0; + Trspi_LoadBlob_PCR_SELECTION(&offset, *data, selection); +done: + obj_list_put(&encdata_list); + + return result; +} + +TSS_RESULT +obj_encdata_set_pcr_info(TSS_HENCDATA hEncData, UINT32 pcrInfoType, BYTE *info_blob) +{ + struct tsp_object *obj; + struct tr_encdata_obj *encdata; + TSS_RESULT result = TSS_SUCCESS; + UINT64 offset = 0; + + if ((obj = obj_list_get_obj(&encdata_list, hEncData)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + encdata = (struct tr_encdata_obj *)obj->data; + + switch (pcrInfoType) { + case TSS_PCRS_STRUCT_INFO_LONG: + result = Trspi_UnloadBlob_PCR_INFO_LONG(&offset, info_blob, + &encdata->pcrInfo.infolong); + break; + case TSS_PCRS_STRUCT_INFO: + result = Trspi_UnloadBlob_PCR_INFO(&offset, info_blob, + &encdata->pcrInfo.info11); + break; + default: + result = TSPERR(TSS_E_INVALID_OBJ_ACCESS); + goto done; + } + + encdata->pcrInfoType = pcrInfoType; + + /* XXX are we using this anywhere? */ + obj->flags |= TSS_OBJ_FLAG_PCRS; +done: + obj_list_put(&encdata_list); + + return result; +} + +TSS_RESULT +obj_encdata_set_data(TSS_HENCDATA hEncData, UINT32 size, BYTE *data) +{ + struct tsp_object *obj; + struct tr_encdata_obj *encdata; + TSS_RESULT result = TSS_SUCCESS; + + if ((obj = obj_list_get_obj(&encdata_list, hEncData)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + encdata = (struct tr_encdata_obj *)obj->data; + + free(encdata->encryptedData); + encdata->encryptedData = NULL; + encdata->encryptedDataLength = 0; + + if (size > 0) { + if ((encdata->encryptedData = malloc(size)) == NULL) { + LogError("malloc of %u bytes failed.", size); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto done; + } + encdata->encryptedDataLength = size; + memcpy(encdata->encryptedData, data, size); + } + +done: + obj_list_put(&encdata_list); + + return result; +} + +void +encdata_free(void *data) +{ + struct tr_encdata_obj *encdata = (struct tr_encdata_obj *)data; + + free(encdata->encryptedData); + + switch (encdata->pcrInfoType) { + case TSS_PCRS_STRUCT_INFO: + free(encdata->pcrInfo.info11.pcrSelection.pcrSelect); + break; + case TSS_PCRS_STRUCT_INFO_LONG: + free(encdata->pcrInfo.infolong.creationPCRSelection.pcrSelect); + free(encdata->pcrInfo.infolong.releasePCRSelection.pcrSelect); + break; + default: + /* no PCR data was set */ + break; + } + + free(encdata); +} + +/* remove an individual encdata object from the encdata list with handle + * equal to hObject */ +TSS_RESULT +obj_encdata_remove(TSS_HOBJECT hObject, TSS_HCONTEXT tspContext) +{ + TSS_RESULT result; + + if ((result = obj_list_remove(&encdata_list, &encdata_free, hObject, tspContext))) + return result; + + return TSS_SUCCESS; +} + +void +obj_encdata_remove_policy_refs(TSS_HPOLICY hPolicy, TSS_HCONTEXT tspContext) +{ + struct tsp_object *obj; + struct obj_list *list = &encdata_list; + struct tr_encdata_obj *encdata; + + pthread_mutex_lock(&list->lock); + + for (obj = list->head; obj; obj = obj->next) { + if (obj->tspContext != tspContext) + continue; + + encdata = (struct tr_encdata_obj *)obj->data; + if (encdata->usagePolicy == hPolicy) + encdata->usagePolicy = NULL_HPOLICY; + } + + pthread_mutex_unlock(&list->lock); +} + +#ifdef TSS_BUILD_SEALX +TSS_RESULT +obj_encdata_set_seal_protect_mode(TSS_HENCDATA hEncData, UINT32 protectMode) +{ + struct tsp_object *obj; + struct tr_encdata_obj *encdata; + + if ((obj = obj_list_get_obj(&encdata_list, hEncData)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + encdata = (struct tr_encdata_obj *)obj->data; + + encdata->protectMode = protectMode; + + obj_list_put(&encdata_list); + + return TSS_SUCCESS; +} + +TSS_RESULT +obj_encdata_get_seal_protect_mode(TSS_HENCDATA hEncData, UINT32 *protectMode) +{ + struct tsp_object *obj; + struct tr_encdata_obj *encdata; + + if ((obj = obj_list_get_obj(&encdata_list, hEncData)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + encdata = (struct tr_encdata_obj *)obj->data; + + *protectMode = encdata->protectMode; + + obj_list_put(&encdata_list); + + return TSS_SUCCESS; +} +#endif + |