3
* Licensed Materials - Property of IBM
5
* trousers - An open source TCG Software Stack
7
* (C) Copyright International Business Machines Corp. 2004-2006
16
#include <sys/types.h>
20
#include "trousers/tss.h"
21
#include "trousers/trousers.h"
22
#include "trousers_types.h"
23
#include "trousers_types.h"
24
#include "spi_utils.h"
25
#include "capabilities.h"
31
get_num_pcrs(TSS_HCONTEXT tspContext)
34
static UINT16 ret = 0;
42
subCap = endian32(TPM_CAP_PROP_PCR);
43
if ((result = TCS_API(tspContext)->GetTPMCapability(tspContext, TPM_CAP_PROPERTY,
44
sizeof(UINT32), (BYTE *)&subCap,
46
if ((resp = (BYTE *)getenv("TSS_DEFAULT_NUM_PCRS")) == NULL)
47
return TSS_DEFAULT_NUM_PCRS;
49
/* don't set ret here, next time we may be connected */
50
return atoi((char *)resp);
53
ret = (UINT16)Decode_UINT32(resp);
60
pcrs_calc_composite(TPM_PCR_SELECTION *select, TPM_PCRVALUE *arrayOfPcrs, TPM_DIGEST *digestOut)
67
UINT64 sizeOffset = 0;
69
if (select->sizeOfSelect > 0) {
71
Trspi_LoadBlob_PCR_SELECTION(&sizeOffset, hashBlob, select);
72
offset = sizeOffset + 4;
74
for (size = 0; size < select->sizeOfSelect; size++) {
75
for (index = 0, mask = 1; index < 8; index++, mask = mask << 1) {
76
if (select->pcrSelect[size] & mask) {
77
memcpy(&hashBlob[(numPCRs * TPM_SHA1_160_HASH_LEN) + offset],
78
arrayOfPcrs[index + (size << 3)].digest,
79
TPM_SHA1_160_HASH_LEN);
86
offset += (numPCRs * TPM_SHA1_160_HASH_LEN);
87
UINT32ToArray(numPCRs * TPM_SHA1_160_HASH_LEN, &hashBlob[sizeOffset]);
89
return Trspi_Hash(TSS_HASH_SHA1, offset, hashBlob, digestOut->digest);
93
return TSPERR(TSS_E_INTERNAL_ERROR);
97
pcrs_sanity_check_selection(TSS_HCONTEXT tspContext,
98
struct tr_pcrs_obj *pcrs,
99
TPM_PCR_SELECTION *select)
101
UINT16 num_pcrs, bytes_to_hold;
103
if ((num_pcrs = get_num_pcrs(tspContext)) == 0)
104
return TSPERR(TSS_E_INTERNAL_ERROR);
106
bytes_to_hold = num_pcrs / 8;
108
/* Is the current select object going to be interpretable by the TPM?
109
* If the select object is of a size greater than the one the TPM
110
* wants, just calculate the composite hash and let the TPM return an
111
* error code to the user. If its less than the size of the one the
112
* TPM wants, add extra zero bytes until its the right size. */
113
if (bytes_to_hold > select->sizeOfSelect) {
114
if ((select->pcrSelect = realloc(select->pcrSelect, bytes_to_hold)) == NULL) {
115
LogError("malloc of %hu bytes failed.", bytes_to_hold);
116
return TSPERR(TSS_E_OUTOFMEMORY);
118
/* set the newly allocated bytes to 0 */
119
memset(&select->pcrSelect[select->sizeOfSelect], 0,
120
bytes_to_hold - select->sizeOfSelect);
121
select->sizeOfSelect = bytes_to_hold;
123
/* realloc the pcr array as well */
124
if ((pcrs->pcrs = realloc(pcrs->pcrs,
125
(bytes_to_hold * 8) * TPM_SHA1_160_HASH_LEN)) == NULL) {
126
LogError("malloc of %d bytes failed.",
127
(bytes_to_hold * 8) * TPM_SHA1_160_HASH_LEN);
128
return TSPERR(TSS_E_OUTOFMEMORY);
135
for (i = 0; i < select->sizeOfSelect * 8; i++) {
136
if (select->pcrSelect[i/8] & (1 << (i % 8))) {
137
LogDebug("PCR%d: Selected", i);
138
LogBlobData(APPID, TPM_SHA1_160_HASH_LEN,
139
(unsigned char *)&pcrs->pcrs[i]);
141
LogDebug("PCR%d: Not Selected", i);