summaryrefslogtreecommitdiff
path: root/src/tspi/obj_encdata.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/tspi/obj_encdata.c')
-rw-r--r--src/tspi/obj_encdata.c485
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
+