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 <string.h>
14 
15 #include "trousers/tss.h"
16 #include "trousers/trousers.h"
17 #include "trousers_types.h"
18 #include "spi_utils.h"
19 #include "capabilities.h"
20 #include "tsplog.h"
21 #include "obj.h"
22 
23 
24 void
free_key_refs(TSS_KEY * key)25 free_key_refs(TSS_KEY *key)
26 {
27 	free(key->algorithmParms.parms);
28 	key->algorithmParms.parms = NULL;
29 	key->algorithmParms.parmSize = 0;
30 
31 	free(key->pubKey.key);
32 	key->pubKey.key = NULL;
33 	key->pubKey.keyLength = 0;
34 
35 	free(key->encData);
36 	key->encData = NULL;
37 	key->encSize = 0;
38 
39 	free(key->PCRInfo);
40 	key->PCRInfo = NULL;
41 	key->PCRInfoSize = 0;
42 }
43 
44 void
LoadBlob_TSS_KEY(UINT64 * offset,BYTE * blob,TSS_KEY * key)45 LoadBlob_TSS_KEY(UINT64 *offset, BYTE *blob, TSS_KEY *key)
46 {
47 	if (key->hdr.key12.tag == TPM_TAG_KEY12)
48 		Trspi_LoadBlob_KEY12(offset, blob, (TPM_KEY12 *)key);
49 	else
50 		Trspi_LoadBlob_KEY(offset, blob, (TCPA_KEY *)key);
51 }
52 
53 TSS_RESULT
UnloadBlob_TSS_KEY(UINT64 * offset,BYTE * blob,TSS_KEY * key)54 UnloadBlob_TSS_KEY(UINT64 *offset, BYTE *blob, TSS_KEY *key)
55 {
56 	UINT16 tag;
57 	UINT64 keyOffset = *offset;
58 	TSS_RESULT result;
59 
60 	Trspi_UnloadBlob_UINT16(&keyOffset, &tag, blob);
61 	if (tag == TPM_TAG_KEY12)
62 		result = Trspi_UnloadBlob_KEY12(offset, blob, (TPM_KEY12 *)key);
63 	else
64 		result = Trspi_UnloadBlob_KEY(offset, blob, (TCPA_KEY *)key);
65 
66 	return result;
67 }
68 
69 TSS_RESULT
Hash_TSS_KEY(Trspi_HashCtx * c,TSS_KEY * key)70 Hash_TSS_KEY(Trspi_HashCtx *c, TSS_KEY *key)
71 {
72 	TSS_RESULT result;
73 
74 	if (key->hdr.key12.tag == TPM_TAG_KEY12)
75 		result = Trspi_Hash_KEY12(c, (TPM_KEY12 *)key);
76 	else
77 		result = Trspi_Hash_KEY(c, (TCPA_KEY *)key);
78 
79 	return result;
80 }
81 
82 void
LoadBlob_TSS_PRIVKEY_DIGEST(UINT64 * offset,BYTE * blob,TSS_KEY * key)83 LoadBlob_TSS_PRIVKEY_DIGEST(UINT64 *offset, BYTE *blob, TSS_KEY *key)
84 {
85 	if (key->hdr.key12.tag == TPM_TAG_KEY12)
86 		Trspi_LoadBlob_PRIVKEY_DIGEST12(offset, blob, (TPM_KEY12 *)key);
87 	else
88 		Trspi_LoadBlob_PRIVKEY_DIGEST(offset, blob, (TCPA_KEY *)key);
89 }
90 
91 TSS_RESULT
Hash_TSS_PRIVKEY_DIGEST(Trspi_HashCtx * c,TSS_KEY * key)92 Hash_TSS_PRIVKEY_DIGEST(Trspi_HashCtx *c, TSS_KEY *key)
93 {
94 	TSS_RESULT result;
95 
96 	if (key->hdr.key12.tag == TPM_TAG_KEY12)
97 		result = Trspi_Hash_PRIVKEY_DIGEST12(c, (TPM_KEY12 *)key);
98 	else
99 		result = Trspi_Hash_PRIVKEY_DIGEST(c, (TCPA_KEY *)key);
100 
101 	return result;
102 }
103 
104 #ifdef TSS_BUILD_TRANSPORT
105 TSS_RESULT
Transport_EvictKey(TSS_HCONTEXT tspContext,TCS_KEY_HANDLE hKey)106 Transport_EvictKey(TSS_HCONTEXT tspContext,
107 		   TCS_KEY_HANDLE hKey)
108 {
109 	TSS_RESULT result;
110 	UINT32 handlesLen;
111 	TCS_HANDLE *handles, handle;
112 	TPM_DIGEST pubKeyHash;
113 	Trspi_HashCtx hashCtx;
114 
115 
116 	if ((result = obj_context_transport_init(tspContext)))
117 		return result;
118 
119 	LogDebugFn("Executing in a transport session");
120 
121 	if ((result = obj_tcskey_get_pubkeyhash(hKey, pubKeyHash.digest)))
122 		return result;
123 
124 	result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
125 	result |= Trspi_Hash_DIGEST(&hashCtx, pubKeyHash.digest);
126 	if ((result |= Trspi_HashFinal(&hashCtx, pubKeyHash.digest)))
127 		return result;
128 
129 	handlesLen = 1;
130 	handle = hKey;
131 	handles = &handle;
132 
133 	result = obj_context_transport_execute(tspContext, TPM_ORD_EvictKey, 0, NULL, &pubKeyHash,
134 					       &handlesLen, &handles, NULL, NULL, NULL, NULL);
135 
136 	return result;
137 }
138 
139 TSS_RESULT
Transport_GetPubKey(TSS_HCONTEXT tspContext,TCS_KEY_HANDLE hKey,TPM_AUTH * pAuth,UINT32 * pcPubKeySize,BYTE ** prgbPubKey)140 Transport_GetPubKey(TSS_HCONTEXT tspContext,
141 		    TCS_KEY_HANDLE hKey,
142 		    TPM_AUTH *pAuth,
143 		    UINT32 *pcPubKeySize,
144 		    BYTE **prgbPubKey)
145 {
146 	TSS_RESULT result;
147 	UINT32 handlesLen, decLen;
148 	TCS_HANDLE *handles, handle;
149 	BYTE *dec = NULL;
150 	TPM_DIGEST pubKeyHash;
151 	Trspi_HashCtx hashCtx;
152 
153 
154 	if ((result = obj_context_transport_init(tspContext)))
155 		return result;
156 
157 	LogDebugFn("Executing in a transport session");
158 
159 	if ((result = obj_tcskey_get_pubkeyhash(hKey, pubKeyHash.digest)))
160 		return result;
161 
162 	result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
163 	result |= Trspi_Hash_DIGEST(&hashCtx, pubKeyHash.digest);
164 	if ((result |= Trspi_HashFinal(&hashCtx, pubKeyHash.digest)))
165 		return result;
166 
167 	handlesLen = 1;
168 	handle = hKey;
169 	handles = &handle;
170 
171 	if ((result = obj_context_transport_execute(tspContext, TPM_ORD_GetPubKey, 0, NULL,
172 						    &pubKeyHash, &handlesLen, &handles, pAuth, NULL,
173 						    &decLen, &dec)))
174 		return result;
175 
176 	*prgbPubKey = dec;
177 	*pcPubKeySize = decLen;
178 
179 	return result;
180 }
181 
182 TSS_RESULT
Transport_CreateWrapKey(TSS_HCONTEXT tspContext,TCS_KEY_HANDLE hWrappingKey,TPM_ENCAUTH * KeyUsageAuth,TPM_ENCAUTH * KeyMigrationAuth,UINT32 keyInfoSize,BYTE * keyInfo,UINT32 * keyDataSize,BYTE ** keyData,TPM_AUTH * pAuth)183 Transport_CreateWrapKey(TSS_HCONTEXT tspContext,	/* in */
184 			TCS_KEY_HANDLE hWrappingKey,	/* in */
185 			TPM_ENCAUTH *KeyUsageAuth,	/* in */
186 			TPM_ENCAUTH *KeyMigrationAuth,	/* in */
187 			UINT32 keyInfoSize,		/* in */
188 			BYTE * keyInfo,			/* in */
189 			UINT32 * keyDataSize,		/* out */
190 			BYTE ** keyData,		/* out */
191 			TPM_AUTH * pAuth)		/* in, out */
192 {
193 	TSS_RESULT result;
194 	UINT32 handlesLen, decLen;
195 	TCS_HANDLE *handles, handle;
196 	BYTE *dec = NULL;
197 	TPM_DIGEST pubKeyHash;
198 	Trspi_HashCtx hashCtx;
199 	UINT64 offset;
200 	BYTE *data;
201 
202 
203 	if ((result = obj_context_transport_init(tspContext)))
204 		return result;
205 
206 	LogDebugFn("Executing in a transport session");
207 
208 	if ((result = obj_tcskey_get_pubkeyhash(hWrappingKey, pubKeyHash.digest)))
209 		return result;
210 
211 	result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
212 	result |= Trspi_Hash_DIGEST(&hashCtx, pubKeyHash.digest);
213 	if ((result |= Trspi_HashFinal(&hashCtx, pubKeyHash.digest)))
214 		return result;
215 
216 	handlesLen = 1;
217 	handle = hWrappingKey;
218 	handles = &handle;
219 
220 	if ((data = malloc(2 * sizeof(TPM_ENCAUTH) + keyInfoSize)) == NULL) {
221 		LogError("malloc of %zd bytes failed", 2 * sizeof(TPM_ENCAUTH) + keyInfoSize);
222 		return TSPERR(TSS_E_OUTOFMEMORY);
223 	}
224 
225 	offset = 0;
226 	Trspi_LoadBlob(&offset, sizeof(TPM_ENCAUTH), data, KeyUsageAuth->authdata);
227 	Trspi_LoadBlob(&offset, sizeof(TPM_ENCAUTH), data, KeyMigrationAuth->authdata);
228 	Trspi_LoadBlob(&offset, keyInfoSize, data, keyInfo);
229 
230 	if ((result = obj_context_transport_execute(tspContext, TPM_ORD_CreateWrapKey,
231 						    (2 * sizeof(TPM_ENCAUTH) + keyInfoSize), data,
232 						    &pubKeyHash, &handlesLen, &handles, pAuth, NULL,
233 						    &decLen, &dec)))
234 		goto done;
235 
236 	*keyDataSize = decLen;
237 	*keyData = dec;
238 done:
239 	free(data);
240 
241 	return result;
242 }
243 
244 TSS_RESULT
Transport_LoadKeyByBlob(TSS_HCONTEXT tspContext,TCS_KEY_HANDLE hParentKey,UINT32 ulBlobLength,BYTE * rgbBlobData,TPM_AUTH * pAuth,TCS_KEY_HANDLE * phKey,TPM_KEY_HANDLE * phSlot)245 Transport_LoadKeyByBlob(TSS_HCONTEXT     tspContext,
246 			TCS_KEY_HANDLE   hParentKey,
247 			UINT32           ulBlobLength,
248 			BYTE*            rgbBlobData,
249 			TPM_AUTH*        pAuth,
250 			TCS_KEY_HANDLE*  phKey,
251 			TPM_KEY_HANDLE*  phSlot)
252 {
253 	TSS_RESULT result;
254 	UINT32 handlesLen, decLen;
255 	TCS_HANDLE *handles, handle;
256 	BYTE *dec = NULL;
257 	TPM_DIGEST pubKeyHash;
258 	Trspi_HashCtx hashCtx;
259 
260 
261 	if ((result = obj_context_transport_init(tspContext)))
262 		return result;
263 
264 	LogDebugFn("Executing in a transport session");
265 
266 	if ((result = obj_tcskey_get_pubkeyhash(hParentKey, pubKeyHash.digest)))
267 		return result;
268 
269 	result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
270 	result |= Trspi_Hash_DIGEST(&hashCtx, pubKeyHash.digest);
271 	if ((result |= Trspi_HashFinal(&hashCtx, pubKeyHash.digest)))
272 		return result;
273 
274 	handlesLen = 1;
275 	handle = hParentKey;
276 	handles = &handle;
277 
278 	if ((result = obj_context_transport_execute(tspContext, TPM_ORD_LoadKey2, ulBlobLength,
279 						    rgbBlobData, &pubKeyHash, &handlesLen,
280 						    &handles, pAuth, NULL, &decLen, &dec)))
281 		return result;
282 
283 	if (handlesLen == 1)
284 		*phKey = *(TCS_KEY_HANDLE *)handles;
285 	else
286 		result = TSPERR(TSS_E_INTERNAL_ERROR);
287 
288 	free(dec);
289 
290 	return result;
291 }
292 
293 /* This function both encrypts the handle of the pubkey being requested and requires the hash
294  * of that pubkey for the transport log when logging is enabled. */
295 TSS_RESULT
Transport_OwnerReadInternalPub(TSS_HCONTEXT tspContext,TCS_KEY_HANDLE hKey,TPM_AUTH * pOwnerAuth,UINT32 * punPubKeySize,BYTE ** ppbPubKeyData)296 Transport_OwnerReadInternalPub(TSS_HCONTEXT tspContext,   /* in */
297 			       TCS_KEY_HANDLE hKey,           /* in */
298 			       TPM_AUTH* pOwnerAuth,          /* in, out */
299 			       UINT32* punPubKeySize, /* out */
300 			       BYTE** ppbPubKeyData)          /* out */
301 {
302 	UINT64 offset;
303 	TSS_RESULT result;
304 	UINT32 handlesLen = 0, decLen;
305 	TPM_DIGEST pubKeyHash;
306 	Trspi_HashCtx hashCtx;
307 	BYTE *dec = NULL, data[sizeof(TCS_KEY_HANDLE)];
308 
309 
310 	if ((result = obj_context_transport_init(tspContext)))
311 		return result;
312 
313 	LogDebugFn("Executing in a transport session");
314 
315 	if ((result = obj_tcskey_get_pubkeyhash(hKey, pubKeyHash.digest)))
316 		return result;
317 
318 	result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
319 	result |= Trspi_Hash_DIGEST(&hashCtx, pubKeyHash.digest);
320 	if ((result |= Trspi_HashFinal(&hashCtx, pubKeyHash.digest)))
321 		return result;
322 
323 	offset = 0;
324 	Trspi_LoadBlob_UINT32(&offset, hKey, data);
325 
326 	if ((result = obj_context_transport_execute(tspContext, TPM_ORD_OwnerReadInternalPub,
327 						    sizeof(data), data, &pubKeyHash, &handlesLen,
328 						    NULL, pOwnerAuth, NULL, &decLen, &dec)))
329 		return result;
330 
331 	*punPubKeySize = decLen;
332 	*ppbPubKeyData = dec;
333 
334 	return result;
335 }
336 #endif
337 
338