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 
25 TSS_RESULT
Tspi_Hash_TickStampBlob(TSS_HHASH hHash,TSS_HKEY hIdentKey,TSS_VALIDATION * pValidationData)26 Tspi_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 
154 TSS_RESULT
Tspi_TPM_ReadCurrentTicks(TSS_HTPM hTPM,TPM_CURRENT_TICKS * tickCount)155 Tspi_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