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. 2004-2007
8 *
9 */
10
11
12#include <stdlib.h>
13#include <stdio.h>
14#include <string.h>
15
16#include "trousers/tss.h"
17#include "trousers/trousers.h"
18#include "trousers_types.h"
19#include "spi_utils.h"
20#include "capabilities.h"
21#include "tsplog.h"
22#include "obj.h"
23
24
25TSS_RESULT
26Tspi_Hash_TickStampBlob(TSS_HHASH       hHash,			/* in */
27			TSS_HKEY        hIdentKey,		/* in */
28			TSS_VALIDATION* pValidationData)	/* in */
29{
30	TSS_RESULT result;
31	TSS_HCONTEXT tspContext;
32	TCS_KEY_HANDLE tcsKey;
33	TSS_HPOLICY hPolicy;
34	TPM_DIGEST digest;
35	TSS_BOOL usesAuth;
36	TPM_AUTH auth, *pAuth;
37	UINT32 hashLen, sigLen, tcLen, signInfoLen;
38	BYTE *hash, *sig, *tc, *signInfo = NULL;
39	UINT64 offset;
40	Trspi_HashCtx hashCtx;
41
42	if (pValidationData == NULL)
43		return TSPERR(TSS_E_BAD_PARAMETER);
44
45	if ((result = obj_hash_get_tsp_context(hHash, &tspContext)))
46		return result;
47
48	if (pValidationData->ulExternalDataLength != sizeof(TPM_NONCE))
49		return TSPERR(TSS_E_BAD_PARAMETER);
50
51	if ((result = obj_hash_get_value(hHash, &hashLen, &hash)))
52		return result;
53
54	if (hashLen != sizeof(TPM_DIGEST)) {
55		free_tspi(tspContext, hash);
56		return TSPERR(TSS_E_HASH_INVALID_LENGTH);
57	}
58
59	if ((result = obj_rsakey_get_policy(hIdentKey, TSS_POLICY_USAGE, &hPolicy, &usesAuth)))
60		return result;
61
62	if ((result = obj_rsakey_get_tcs_handle(hIdentKey, &tcsKey)))
63		return result;
64
65	if (usesAuth) {
66		result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
67		result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_TickStampBlob);
68		result |= Trspi_HashUpdate(&hashCtx, sizeof(TPM_NONCE),
69					   pValidationData->rgbExternalData);
70		result |= Trspi_HashUpdate(&hashCtx, sizeof(TPM_DIGEST), hash);
71		if ((result |= Trspi_HashFinal(&hashCtx, digest.digest))) {
72			free_tspi(tspContext, hash);
73			return result;
74		}
75
76		if ((result = secret_PerformAuth_OIAP(hIdentKey, TPM_ORD_TickStampBlob, hPolicy,
77						      FALSE, &digest, &auth))) {
78			free_tspi(tspContext, hash);
79			return result;
80		}
81		pAuth = &auth;
82	} else
83		pAuth = NULL;
84
85	if ((result = TCS_API(tspContext)->TickStampBlob(tspContext, tcsKey,
86						(TPM_NONCE *)pValidationData->rgbExternalData,
87						(TPM_DIGEST *)hash, pAuth, &sigLen, &sig, &tcLen,
88						&tc))) {
89		free_tspi(tspContext, hash);
90		return result;
91	}
92
93	if (usesAuth) {
94		result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
95		result |= Trspi_Hash_UINT32(&hashCtx, result);
96		result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_TickStampBlob);
97		result |= Trspi_HashUpdate(&hashCtx, tcLen, tc);
98		result |= Trspi_Hash_UINT32(&hashCtx, sigLen);
99		result |= Trspi_HashUpdate(&hashCtx, sigLen, sig);
100		if ((result |= Trspi_HashFinal(&hashCtx, digest.digest))) {
101			free_tspi(tspContext, hash);
102			free(sig);
103			free(tc);
104			return result;
105		}
106
107		if ((result = obj_policy_validate_auth_oiap(hPolicy, &digest, pAuth))) {
108			free_tspi(tspContext, hash);
109			free(sig);
110			free(tc);
111			return result;
112		}
113	}
114
115	/*                 tag       fixed      replay          length(Data)                 Data        */
116	signInfoLen = sizeof(UINT16) + 4 + sizeof(TPM_NONCE) + sizeof(UINT32) + sizeof(TPM_DIGEST) + tcLen;
117	if ((signInfo = calloc_tspi(tspContext, signInfoLen)) == NULL) {
118		free_tspi(tspContext, hash);
119		free(sig);
120		free(tc);
121		return TSPERR(TSS_E_INTERNAL_ERROR);
122	}
123
124	offset = 0;
125	Trspi_LoadBlob_UINT16(&offset, TPM_TAG_SIGNINFO, signInfo);
126	Trspi_LoadBlob_BYTE(&offset, 'T', signInfo);
127	Trspi_LoadBlob_BYTE(&offset, 'S', signInfo);
128	Trspi_LoadBlob_BYTE(&offset, 'T', signInfo);
129	Trspi_LoadBlob_BYTE(&offset, 'P', signInfo);
130	Trspi_LoadBlob(&offset, sizeof(TPM_NONCE), signInfo, pValidationData->rgbExternalData);
131	Trspi_LoadBlob_UINT32(&offset, sizeof(TPM_DIGEST) + tcLen, signInfo);
132	Trspi_LoadBlob(&offset, sizeof(TPM_DIGEST), signInfo, hash);
133	Trspi_LoadBlob(&offset, (size_t)tcLen, signInfo, tc);
134
135	free(tc);
136	free_tspi(tspContext, hash);
137
138	pValidationData->rgbData = signInfo;
139	pValidationData->ulDataLength = signInfoLen;
140
141	/* tag sig so that it can be free'd by the app through Tspi_Context_FreeMemory */
142	if ((result = __tspi_add_mem_entry(tspContext, sig))) {
143		free_tspi(tspContext, signInfo);
144		free(sig);
145		return result;
146	}
147
148	pValidationData->rgbValidationData = sig;
149	pValidationData->ulValidationDataLength = sigLen;
150
151	return TSS_SUCCESS;
152}
153
154TSS_RESULT
155Tspi_TPM_ReadCurrentTicks(TSS_HTPM           hTPM,	/* in */
156			  TPM_CURRENT_TICKS* tickCount)	/* out */
157{
158	TSS_RESULT result;
159	TSS_HCONTEXT tspContext;
160	UINT32 tcLen;
161	BYTE *tc;
162	UINT64 offset;
163
164	if (tickCount == NULL)
165		return TSPERR(TSS_E_BAD_PARAMETER);
166
167	if ((result = obj_tpm_get_tsp_context(hTPM, &tspContext)))
168		return result;
169
170	if ((result = TCS_API(tspContext)->ReadCurrentTicks(tspContext, &tcLen, &tc)))
171		return result;
172
173	offset = 0;
174	Trspi_UnloadBlob_CURRENT_TICKS(&offset, tc, tickCount);
175	free(tc);
176
177	return result;
178}
179