diff options
Diffstat (limited to 'src/tspi/obj_nv.c')
-rw-r--r-- | src/tspi/obj_nv.c | 746 |
1 files changed, 746 insertions, 0 deletions
diff --git a/src/tspi/obj_nv.c b/src/tspi/obj_nv.c new file mode 100644 index 0000000..31a3153 --- /dev/null +++ b/src/tspi/obj_nv.c @@ -0,0 +1,746 @@ +/* + * The Initial Developer of the Original Code is Intel Corporation. + * Portions created by Intel Corporation are Copyright (C) 2007 Intel Corporation. + * All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the Common Public License as published by + * IBM Corporation; either version 1 of the License, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * Common Public License for more details. + * + * You should have received a copy of the Common Public License + * along with this program; if not, a copy can be viewed at + * http://www.opensource.org/licenses/cpl1.0.php. + * + * trousers - An open source TCG Software Stack + * + * Author: james.xu@intel.com Rossey.liu@intel.com + * + */ + +#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_nvstore_add(TSS_HCONTEXT tspContext, TSS_HOBJECT *phObject) +{ + TSS_RESULT result; + struct tr_nvstore_obj *nvstore = calloc(1, sizeof(struct tr_nvstore_obj)); + + if (nvstore == NULL) { + LogError("malloc of %zd bytes failed.", + sizeof(struct tr_nvstore_obj)); + return TSPERR(TSS_E_OUTOFMEMORY); + } + + if ((result = obj_list_add(&nvstore_list, tspContext, 0, nvstore, phObject))) { + free(nvstore); + return result; + } + + return TSS_SUCCESS; +} + +TSS_BOOL +obj_is_nvstore(TSS_HOBJECT hObject) +{ + TSS_BOOL answer = FALSE; + + if ((obj_list_get_obj(&nvstore_list, hObject))) { + answer = TRUE; + obj_list_put(&nvstore_list); + } + + return answer; +} + +void +nvstore_free(void *data) +{ + struct tr_nvstore_obj *nvstore = (struct tr_nvstore_obj *)data; + + free(nvstore); +} + +TSS_RESULT +obj_nvstore_remove(TSS_HOBJECT hObject, TSS_HCONTEXT tspContext) +{ + TSS_RESULT result; + + if ((result = obj_list_remove(&nvstore_list, &nvstore_free, hObject, tspContext))) + return result; + + return TSS_SUCCESS; +} + +TSS_RESULT +obj_nvstore_get_tsp_context(TSS_HNVSTORE hNvstore, TSS_HCONTEXT * tspContext) +{ + struct tsp_object *obj; + + if ((obj = obj_list_get_obj(&nvstore_list, hNvstore)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + *tspContext = obj->tspContext; + + obj_list_put(&nvstore_list); + + return TSS_SUCCESS; +} + +TSS_RESULT +obj_nvstore_set_index(TSS_HNVSTORE hNvstore, UINT32 index) +{ + struct tsp_object *obj; + struct tr_nvstore_obj *nvstore; + TSS_RESULT result=TSS_SUCCESS; + + if ((obj = obj_list_get_obj(&nvstore_list, hNvstore)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + nvstore = (struct tr_nvstore_obj *)obj->data; + + nvstore->nvIndex = index; + + obj_list_put(&nvstore_list); + + return result; +} + +TSS_RESULT +obj_nvstore_get_index(TSS_HNVSTORE hNvstore, UINT32 * index) +{ + struct tsp_object *obj; + struct tr_nvstore_obj *nvstore; + TSS_RESULT result=TSS_SUCCESS; + + if ((obj = obj_list_get_obj(&nvstore_list, hNvstore)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + nvstore = (struct tr_nvstore_obj *)obj->data; + + *index = nvstore->nvIndex; + + obj_list_put(&nvstore_list); + + return result; +} + +TSS_RESULT +obj_nvstore_set_datasize(TSS_HNVSTORE hNvstore, UINT32 datasize) +{ + struct tsp_object *obj; + struct tr_nvstore_obj *nvstore; + TSS_RESULT result=TSS_SUCCESS; + + if ((obj = obj_list_get_obj(&nvstore_list, hNvstore)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + nvstore = (struct tr_nvstore_obj *)obj->data; + + nvstore->dataSize= datasize; + + obj_list_put(&nvstore_list); + + return result; +} + +TSS_RESULT +obj_nvstore_get_datasize(TSS_HNVSTORE hNvstore, UINT32 * datasize) +{ + struct tsp_object *obj; + struct tr_nvstore_obj *nvstore; + TSS_RESULT result=TSS_SUCCESS; + + if ((obj = obj_list_get_obj(&nvstore_list, hNvstore)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + nvstore = (struct tr_nvstore_obj *)obj->data; + + *datasize = nvstore->dataSize; + + obj_list_put(&nvstore_list); + + return result; +} + +TSS_RESULT +obj_nvstore_set_permission(TSS_HNVSTORE hNvstore, UINT32 permission) +{ + struct tsp_object *obj; + struct tr_nvstore_obj *nvstore; + TSS_RESULT result=TSS_SUCCESS; + + if ((obj = obj_list_get_obj(&nvstore_list, hNvstore)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + nvstore = (struct tr_nvstore_obj *)obj->data; + + nvstore->permission.attributes= permission; + + obj_list_put(&nvstore_list); + + return result; +} + +TSS_RESULT +obj_nvstore_get_permission_from_tpm(TSS_HNVSTORE hNvstore, UINT32 * permission) +{ + BYTE nv_data_public[MAX_PUBLIC_DATA_SIZE] = {0}; + UINT32 data_public_size = MAX_PUBLIC_DATA_SIZE; + UINT32 offset; + UINT16 pcrread_sizeOfSelect; + UINT16 pcrwrite_sizeOfSelect; + TPM_NV_ATTRIBUTES nv_attributes_value; + TSS_HCONTEXT tspContext; + TSS_RESULT result; + + if((result = obj_nvstore_get_datapublic(hNvstore, &data_public_size, nv_data_public))) + return result; + + if ((result = obj_nvstore_get_tsp_context(hNvstore, &tspContext))) + return result; + + offset = 0; + offset = sizeof(TPM_STRUCTURE_TAG)+ sizeof(TPM_NV_INDEX); + pcrread_sizeOfSelect = Decode_UINT16(nv_data_public + offset); + + offset = offset + sizeof(UINT16) + pcrread_sizeOfSelect + + sizeof(TPM_LOCALITY_SELECTION) + + sizeof(TPM_COMPOSITE_HASH); + pcrwrite_sizeOfSelect = Decode_UINT16(nv_data_public + offset); + + offset = offset + sizeof(UINT16) + pcrwrite_sizeOfSelect + + sizeof(TPM_LOCALITY_SELECTION) + + sizeof(TPM_COMPOSITE_HASH); + + nv_attributes_value.attributes = Decode_UINT32(nv_data_public + + offset + sizeof(TPM_STRUCTURE_TAG)); + *permission = nv_attributes_value.attributes; + + return result; +} + +TSS_RESULT +obj_nvstore_get_permission(TSS_HNVSTORE hNvstore, UINT32 * permission) +{ + struct tsp_object *obj; + struct tr_nvstore_obj *nvstore; + TSS_RESULT result=TSS_SUCCESS; + + if ((obj = obj_list_get_obj(&nvstore_list, hNvstore)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + nvstore = (struct tr_nvstore_obj *)obj->data; + + *permission = nvstore->permission.attributes; + + obj_list_put(&nvstore_list); + + return result; +} + +TSS_RESULT +obj_nvstore_set_policy(TSS_HNVSTORE hNvstore, TSS_HPOLICY hPolicy) +{ + struct tsp_object *obj; + struct tr_nvstore_obj *nvstore; + UINT32 policyType; + TSS_RESULT result = TSS_SUCCESS; + + if ((result = obj_policy_get_type(hPolicy, &policyType))) + return result; + + if ((obj = obj_list_get_obj(&nvstore_list, hNvstore)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + nvstore = (struct tr_nvstore_obj *)obj->data; + + switch (policyType) { + case TSS_POLICY_USAGE: + nvstore->policy = hPolicy; + break; + default: + result = TSPERR(TSS_E_BAD_PARAMETER); + } + + obj_list_put(&nvstore_list); + + return result; +} + +TSS_RESULT +obj_nvstore_get_policy(TSS_HNVSTORE hNvstore, UINT32 policyType, TSS_HPOLICY *phPolicy) +{ + struct tsp_object *obj; + struct tr_nvstore_obj *nvstore; + TSS_RESULT result=TSS_SUCCESS; + + if ((obj = obj_list_get_obj(&nvstore_list, hNvstore)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + nvstore = (struct tr_nvstore_obj *)obj->data; + + switch (policyType) { + case TSS_POLICY_USAGE: + *phPolicy = nvstore->policy; + break; + default: + result = TSPERR(TSS_E_BAD_PARAMETER); + } + + obj_list_put(&nvstore_list); + + return result; +} + +TSS_RESULT +obj_nvstore_get_datapublic(TSS_HNVSTORE hNvstore, UINT32 *size, BYTE *nv_data_public) +{ + struct tsp_object *obj; + TSS_HCONTEXT hContext; + TSS_HTPM hTpm; + TSS_RESULT result; + struct tr_nvstore_obj *nvstore; + UINT32 uiResultLen; + BYTE *pResult; + UINT32 i; + TPM_BOOL defined_index = FALSE; + + if ((obj = obj_list_get_obj(&nvstore_list, hNvstore)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + hContext = obj->tspContext; + nvstore = (struct tr_nvstore_obj *)obj->data; + + if ((result = obj_tpm_get(hContext, &hTpm))) + goto out; + + if ((result = Tspi_TPM_GetCapability(hTpm, TSS_TPMCAP_NV_LIST, 0, + NULL, &uiResultLen, &pResult))) { + goto out; + } + + for (i = 0; i < uiResultLen/sizeof(UINT32); i++) { + if (nvstore->nvIndex == Decode_UINT32(pResult + i * sizeof(UINT32))) { + defined_index = TRUE; + break; + } + } + + free_tspi(hContext, pResult); + + if (!defined_index) { + result = TSPERR(TPM_E_BADINDEX); + goto out; + } + + if ((result = Tspi_TPM_GetCapability(hTpm, TSS_TPMCAP_NV_INDEX, + sizeof(UINT32), (BYTE *)(&(nvstore->nvIndex)), + &uiResultLen, &pResult))) { + LogDebug("get the index capability error"); + goto out; + } + + if (uiResultLen > *size) { + free_tspi(hContext, pResult); + result = TSPERR(TSS_E_INTERNAL_ERROR); + goto out; + } + *size = uiResultLen; + memcpy(nv_data_public, pResult, uiResultLen); + free_tspi(hContext, pResult); + +out: + obj_list_put(&nvstore_list); + return result; +} + +TSS_RESULT +obj_nvstore_get_readdigestatrelease(TSS_HNVSTORE hNvstore, UINT32 *size, BYTE **data) +{ + BYTE nv_data_public[MAX_PUBLIC_DATA_SIZE]; + UINT32 data_public_size = MAX_PUBLIC_DATA_SIZE; + UINT32 offset; + UINT16 pcrread_sizeOfSelect; + TSS_HCONTEXT tspContext; + TSS_RESULT result; + + if((result = obj_nvstore_get_datapublic(hNvstore, &data_public_size, nv_data_public))) + return result; + + if ((result = obj_nvstore_get_tsp_context(hNvstore, &tspContext))) + return result; + + *size = sizeof(TPM_COMPOSITE_HASH); + *data = calloc_tspi(tspContext, *size); + if (*data == NULL) { + LogError("malloc of %u bytes failed.", *size); + result = TSPERR(TSS_E_OUTOFMEMORY); + return result; + } + + offset = sizeof(TPM_STRUCTURE_TAG)+ sizeof(TPM_NV_INDEX); + pcrread_sizeOfSelect = Decode_UINT16(nv_data_public + offset); + offset = offset + sizeof(UINT16) + pcrread_sizeOfSelect + sizeof(TPM_LOCALITY_SELECTION); + memcpy(*data, nv_data_public + offset, sizeof(TPM_COMPOSITE_HASH)); + + return result; +} + +TSS_RESULT +obj_nvstore_get_readpcrselection(TSS_HNVSTORE hNvstore, UINT32 *size, BYTE **data) +{ + BYTE nv_data_public[MAX_PUBLIC_DATA_SIZE]; + UINT32 data_public_size = MAX_PUBLIC_DATA_SIZE; + UINT32 offset; + UINT16 pcrread_sizeOfSelect; + TSS_HCONTEXT tspContext; + TSS_RESULT result; + + if((result = obj_nvstore_get_datapublic(hNvstore, &data_public_size, nv_data_public))) + return result; + + if ((result = obj_nvstore_get_tsp_context(hNvstore, &tspContext))) + return result; + + offset = sizeof(TPM_STRUCTURE_TAG)+ sizeof(TPM_NV_INDEX); + pcrread_sizeOfSelect = Decode_UINT16(nv_data_public + offset); + + *size = sizeof(UINT16) + pcrread_sizeOfSelect; + *data = calloc_tspi(tspContext, *size); + if (*data == NULL) { + LogError("malloc of %u bytes failed.", *size); + result = TSPERR(TSS_E_OUTOFMEMORY); + return result; + } + + memcpy(*data, nv_data_public + offset, *size); + + return result; +} + +TSS_RESULT +obj_nvstore_get_writedigestatrelease(TSS_HNVSTORE hNvstore, UINT32 *size, BYTE **data) +{ + BYTE nv_data_public[MAX_PUBLIC_DATA_SIZE]; + UINT32 data_public_size = MAX_PUBLIC_DATA_SIZE; + UINT32 offset; + UINT16 pcrread_sizeOfSelect; + TSS_HCONTEXT tspContext; + TSS_RESULT result; + + if ((result = obj_nvstore_get_datapublic(hNvstore, &data_public_size, nv_data_public))) + return result; + + if ((result = obj_nvstore_get_tsp_context(hNvstore, &tspContext))) + return result; + + *size = sizeof(TPM_COMPOSITE_HASH); + *data = calloc_tspi(tspContext, *size); + if (*data == NULL) { + LogError("malloc of %u bytes failed.", *size); + result = TSPERR(TSS_E_OUTOFMEMORY); + return result; + } + + offset = sizeof(TPM_STRUCTURE_TAG)+ sizeof(TPM_NV_INDEX); + pcrread_sizeOfSelect = Decode_UINT16(nv_data_public + offset); + offset = offset + sizeof(UINT16) + pcrread_sizeOfSelect + + sizeof(TPM_LOCALITY_SELECTION) + + sizeof(TPM_COMPOSITE_HASH); + + Decode_UINT16(nv_data_public + offset); + offset = offset + sizeof(UINT16) + pcrread_sizeOfSelect + sizeof(TPM_LOCALITY_SELECTION); + memcpy(*data, nv_data_public + offset, sizeof(TPM_COMPOSITE_HASH)); + + return result; +} + +TSS_RESULT +obj_nvstore_get_writepcrselection(TSS_HNVSTORE hNvstore, UINT32 *size, BYTE **data) +{ + BYTE nv_data_public[MAX_PUBLIC_DATA_SIZE]; + UINT32 data_public_size = MAX_PUBLIC_DATA_SIZE; + UINT32 offset; + UINT16 pcrread_sizeOfSelect; + UINT16 pcrwrite_sizeOfSelect; + TSS_HCONTEXT tspContext; + TSS_RESULT result; + + if((result = obj_nvstore_get_datapublic(hNvstore, &data_public_size, nv_data_public))) + return result; + + if ((result = obj_nvstore_get_tsp_context(hNvstore, &tspContext))) + return result; + + offset = sizeof(TPM_STRUCTURE_TAG)+ sizeof(TPM_NV_INDEX); + pcrread_sizeOfSelect = Decode_UINT16(nv_data_public + offset); + offset = offset + sizeof(UINT16) + pcrread_sizeOfSelect + + sizeof(TPM_LOCALITY_SELECTION) + + sizeof(TPM_COMPOSITE_HASH); + pcrwrite_sizeOfSelect = Decode_UINT16(nv_data_public + offset); + + *size = sizeof(UINT16) + pcrwrite_sizeOfSelect; + *data = calloc_tspi(tspContext, *size); + if (*data == NULL) { + LogError("malloc of %u bytes failed.", *size); + result = TSPERR(TSS_E_OUTOFMEMORY); + return result; + } + + memcpy(*data, nv_data_public + offset, *size); + return result; +} + +TSS_RESULT +obj_nvstore_get_state_readstclear(TSS_HNVSTORE hNvstore, UINT32 * readstclear) +{ + BYTE nv_data_public[MAX_PUBLIC_DATA_SIZE]; + UINT32 data_public_size = MAX_PUBLIC_DATA_SIZE; + UINT32 offset; + UINT16 pcrread_sizeOfSelect; + UINT16 pcrwrite_sizeOfSelect; + TPM_BOOL value; + TSS_RESULT result; + + if ((result = obj_nvstore_get_datapublic(hNvstore, &data_public_size, nv_data_public))) + return result; + + offset = sizeof(TPM_STRUCTURE_TAG)+ sizeof(TPM_NV_INDEX); + pcrread_sizeOfSelect = Decode_UINT16(nv_data_public + offset); + offset = offset + sizeof(UINT16) + pcrread_sizeOfSelect + + sizeof(TPM_LOCALITY_SELECTION) + + sizeof(TPM_COMPOSITE_HASH); + + pcrwrite_sizeOfSelect = Decode_UINT16(nv_data_public + offset); + offset = offset + sizeof(UINT16) + pcrwrite_sizeOfSelect + + sizeof(TPM_LOCALITY_SELECTION) + + sizeof(TPM_COMPOSITE_HASH) + + sizeof(TPM_NV_ATTRIBUTES); + + value = *((TPM_BOOL *)(nv_data_public + offset)); + + *readstclear = value; + + return result; +} + +TSS_RESULT +obj_nvstore_get_state_writedefine(TSS_HNVSTORE hNvstore, UINT32 * writedefine) +{ + BYTE nv_data_public[MAX_PUBLIC_DATA_SIZE]; + UINT32 data_public_size = MAX_PUBLIC_DATA_SIZE; + UINT32 offset; + UINT16 pcrread_sizeOfSelect; + UINT16 pcrwrite_sizeOfSelect; + TPM_BOOL value; + TSS_RESULT result; + + if ((result = obj_nvstore_get_datapublic(hNvstore, &data_public_size, nv_data_public))) + return result; + + offset = sizeof(TPM_STRUCTURE_TAG)+ sizeof(TPM_NV_INDEX); + pcrread_sizeOfSelect = Decode_UINT16(nv_data_public + offset); + offset = offset + sizeof(UINT16) + pcrread_sizeOfSelect + + sizeof(TPM_LOCALITY_SELECTION) + + sizeof(TPM_COMPOSITE_HASH); + + pcrwrite_sizeOfSelect = Decode_UINT16(nv_data_public + offset); + offset = offset + sizeof(UINT16) + pcrwrite_sizeOfSelect + + sizeof(TPM_LOCALITY_SELECTION) + + sizeof(TPM_COMPOSITE_HASH) + + sizeof(TPM_NV_ATTRIBUTES) + + sizeof(TPM_BOOL) + + sizeof(TPM_BOOL); + + value = *((TPM_BOOL *)(nv_data_public + offset)); + + *writedefine = value; + + return result; +} + +TSS_RESULT +obj_nvstore_get_state_writestclear(TSS_HNVSTORE hNvstore, UINT32 * writestclear) +{ + BYTE nv_data_public[MAX_PUBLIC_DATA_SIZE]; + UINT32 data_public_size = MAX_PUBLIC_DATA_SIZE; + UINT32 offset; + UINT16 pcrread_sizeOfSelect; + UINT16 pcrwrite_sizeOfSelect; + TPM_BOOL value; + TSS_RESULT result; + + if ((result = obj_nvstore_get_datapublic(hNvstore, &data_public_size, nv_data_public))) + return result; + + offset = sizeof(TPM_STRUCTURE_TAG)+ sizeof(TPM_NV_INDEX); + pcrread_sizeOfSelect = Decode_UINT16(nv_data_public + offset); + offset = offset + sizeof(UINT16) + pcrread_sizeOfSelect + + sizeof(TPM_LOCALITY_SELECTION) + + sizeof(TPM_COMPOSITE_HASH); + + pcrwrite_sizeOfSelect = Decode_UINT16(nv_data_public + offset); + offset = offset + sizeof(UINT16) + pcrwrite_sizeOfSelect + + sizeof(TPM_LOCALITY_SELECTION) + + sizeof(TPM_COMPOSITE_HASH) + + sizeof(TPM_NV_ATTRIBUTES) + + sizeof(TPM_BOOL); + + value = *((TPM_BOOL *)(nv_data_public + offset)); + *writestclear = value; + + return result; +} + +TSS_RESULT +obj_nvstore_get_readlocalityatrelease(TSS_HNVSTORE hNvstore, UINT32 * readlocalityatrelease) +{ + BYTE nv_data_public[MAX_PUBLIC_DATA_SIZE]; + UINT32 data_public_size = MAX_PUBLIC_DATA_SIZE; + UINT32 offset; + UINT16 pcrread_sizeOfSelect; + TPM_LOCALITY_SELECTION locality_value; + TSS_RESULT result; + + if ((result = obj_nvstore_get_datapublic(hNvstore, &data_public_size, nv_data_public))) + return result; + + offset = sizeof(TPM_STRUCTURE_TAG)+ sizeof(TPM_NV_INDEX); + pcrread_sizeOfSelect = Decode_UINT16(nv_data_public + offset); + offset = offset + sizeof(UINT16) + pcrread_sizeOfSelect; + locality_value = *((TPM_LOCALITY_SELECTION *)(nv_data_public + offset)); + *readlocalityatrelease = locality_value; + + return result; +} + +TSS_RESULT +obj_nvstore_get_writelocalityatrelease(TSS_HNVSTORE hNvstore, UINT32 * writelocalityatrelease) +{ + BYTE nv_data_public[MAX_PUBLIC_DATA_SIZE]; + UINT32 data_public_size = MAX_PUBLIC_DATA_SIZE; + UINT32 offset; + UINT16 pcrread_sizeOfSelect; + UINT16 pcrwrite_sizeOfSelect; + TPM_LOCALITY_SELECTION locality_value; + TSS_RESULT result; + + if ((result = obj_nvstore_get_datapublic(hNvstore, &data_public_size, nv_data_public))) + return result; + + offset = sizeof(TPM_STRUCTURE_TAG)+ sizeof(TPM_NV_INDEX); + pcrread_sizeOfSelect = Decode_UINT16(nv_data_public + offset); + offset = offset + sizeof(UINT16) + pcrread_sizeOfSelect + + sizeof(TPM_LOCALITY_SELECTION) + + sizeof(TPM_COMPOSITE_HASH); + pcrwrite_sizeOfSelect = Decode_UINT16(nv_data_public + offset); + offset = offset + sizeof(UINT16) + pcrwrite_sizeOfSelect; + + locality_value = *((TPM_LOCALITY_SELECTION *)(nv_data_public + offset)); + *writelocalityatrelease = locality_value; + + return result; +} + +TSS_RESULT +obj_nvstore_create_pcrshortinfo(TSS_HNVSTORE hNvstore, + TSS_HPCRS hPcrComposite, + UINT32 *size, + BYTE **data) +{ + struct tsp_object *obj; + BYTE pdata[MAX_PUBLIC_DATA_SIZE]; + UINT32 dataLen; + UINT64 offset; + TSS_HCONTEXT tspContext; + TSS_RESULT result = TSS_SUCCESS; + BYTE* ppbHashData; + UINT32 i; + BYTE digAtRelease[TPM_SHA1_160_HASH_LEN] = { 0, }; + UINT32 tmp_locAtRelease; + TPM_LOCALITY_SELECTION locAtRelease = TPM_LOC_ZERO | TPM_LOC_ONE + | TPM_LOC_TWO | TPM_LOC_THREE| TPM_LOC_FOUR; + BYTE tmp_pcr_select[3] = {0, 0, 0}; + TCPA_PCR_SELECTION pcrSelect = { 3, tmp_pcr_select}; + + if ((obj = obj_list_get_obj(&nvstore_list, hNvstore)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + tspContext = obj->tspContext; + + if (hPcrComposite) { + if ((result = obj_pcrs_get_selection(hPcrComposite, &dataLen, pdata))) { + LogDebug("get_selection error from hReadPcrComposite"); + goto out; + } + + /* the index should not >= 24, so the sizeofselect should not be >3*/ + if (dataLen - sizeof(UINT16) > 3) { + result = TSPERR(TSS_E_BAD_PARAMETER); + goto out; + } + offset = 0; + Trspi_UnloadBlob_PCR_SELECTION(&offset, pdata, &pcrSelect); + + if (pcrSelect.sizeOfSelect != 0) { + if ((result = obj_pcrs_get_digest_at_release(hPcrComposite, + &dataLen, &ppbHashData))) { + LogDebug("get_composite error from hReadPcrComposite"); + goto out; + } + memcpy(digAtRelease, ppbHashData, dataLen); + free_tspi(tspContext, ppbHashData); + } else { + pcrSelect.sizeOfSelect = 3; + pcrSelect.pcrSelect = tmp_pcr_select; + } + + if (pcrSelect.sizeOfSelect < 3) { + for (i = 0; i < pcrSelect.sizeOfSelect; i++) { + tmp_pcr_select[i] = pcrSelect.pcrSelect[i]; + } + pcrSelect.sizeOfSelect = 3; + pcrSelect.pcrSelect = tmp_pcr_select; + } + + if ((result = obj_pcrs_get_locality(hPcrComposite, &tmp_locAtRelease))) + goto out; + locAtRelease = (TPM_LOCALITY_SELECTION)(tmp_locAtRelease & TSS_LOCALITY_MASK); + } + + *size = sizeof(UINT16) + 3 + sizeof(TPM_LOCALITY_SELECTION) + TPM_SHA1_160_HASH_LEN; + *data = calloc_tspi(tspContext, *size); + if (*data == NULL) { + LogError("malloc of %u bytes failed.", *size); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto out; + } + + offset = 0; + Trspi_LoadBlob_PCR_SELECTION(&offset, *data, &pcrSelect); + Trspi_LoadBlob_BYTE(&offset, locAtRelease, *data); + Trspi_LoadBlob(&offset, TPM_SHA1_160_HASH_LEN, *data, digAtRelease); + +out: + obj_list_put(&nvstore_list); + return result; +} + + |