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_types.h"
18#include "tcs_tsp.h"
19#include "tcs_utils.h"
20#include "tcs_int_literals.h"
21#include "capabilities.h"
22#include "tcslog.h"
23#include "tcsps.h"
24#include "req_mgr.h"
25
26
27TSS_RESULT
28TCSP_LoadKeyByBlob_Internal(TCS_CONTEXT_HANDLE hContext,	/* in */
29			    TCS_KEY_HANDLE hUnwrappingKey,	/* in */
30			    UINT32 cWrappedKeyBlobSize,		/* in */
31			    BYTE * rgbWrappedKeyBlob,		/* in */
32			    TPM_AUTH * pAuth,			/* in, out */
33			    TCS_KEY_HANDLE * phKeyTCSI,		/* out */
34			    TCS_KEY_HANDLE * phKeyHMAC)		/* out */
35{
36	return LoadKeyByBlob_Internal(TPM_ORD_LoadKey, hContext, hUnwrappingKey,
37				      cWrappedKeyBlobSize, rgbWrappedKeyBlob, pAuth, phKeyTCSI,
38				      phKeyHMAC);
39}
40
41TSS_RESULT
42TCSP_LoadKey2ByBlob_Internal(TCS_CONTEXT_HANDLE hContext,	/* in */
43			     TCS_KEY_HANDLE hUnwrappingKey,	/* in */
44			     UINT32 cWrappedKeyBlobSize,	/* in */
45			     BYTE * rgbWrappedKeyBlob,		/* in */
46			     TPM_AUTH * pAuth,			/* in, out */
47			     TCS_KEY_HANDLE * phKeyTCSI)	/* out */
48{
49	return LoadKeyByBlob_Internal(TPM_ORD_LoadKey2, hContext, hUnwrappingKey,
50				      cWrappedKeyBlobSize, rgbWrappedKeyBlob, pAuth, phKeyTCSI,
51				      NULL);
52}
53
54TSS_RESULT
55LoadKeyByBlob_Internal(UINT32 ord,	/* The ordinal to use, LoadKey or LoadKey2 */
56		       TCS_CONTEXT_HANDLE hContext,	/* in */
57		       TCS_KEY_HANDLE hUnwrappingKey,	/* in */
58		       UINT32 cWrappedKeyBlobSize,		/* in */
59		       BYTE * rgbWrappedKeyBlob,		/* in */
60		       TPM_AUTH * pAuth,			/* in, out */
61		       TCS_KEY_HANDLE * phKeyTCSI,		/* out */
62		       TCS_KEY_HANDLE * phKeyHMAC)		/* out */
63{
64	UINT64 offset;
65	TSS_RESULT result;
66	UINT32 paramSize;
67	TPM_KEY_HANDLE parentSlot, newSlot;
68	TCS_KEY_HANDLE newHandle = NULL_TCS_HANDLE;
69	TSS_BOOL canLoad;
70	TSS_KEY key;
71	BYTE txBlob[TSS_TPM_TXBLOB_SIZE];
72
73	if ((result = ctx_verify_context(hContext)))
74		return result;
75
76	LogDebugFn("Enter");
77	LogDebugUnrollKey(rgbWrappedKeyBlob);
78
79	if ((result = get_slot(hContext, hUnwrappingKey, &parentSlot)))
80		return result;
81
82	offset = 0;
83	memset(&key, 0, sizeof(TSS_KEY));
84	if ((result = UnloadBlob_TSS_KEY(&offset, rgbWrappedKeyBlob, &key)))
85		return result;
86
87	if (!pAuth) {
88		LogDebugFn("Checking if LoadKeyByBlob can be avoided by using existing key");
89
90		if ((newHandle = mc_get_handle_by_pub(&key.pubKey, hUnwrappingKey))) {
91			LogDebugFn("tcs key handle exists");
92
93			newSlot = mc_get_slot_by_handle(newHandle);
94			if (newSlot && (isKeyLoaded(newSlot) == TRUE)) {
95				LogDebugFn("Don't need to reload this key.");
96				*phKeyTCSI = newHandle;
97				if (phKeyHMAC)
98					*phKeyHMAC = newSlot;
99				return TSS_SUCCESS;
100			}
101		}
102	}
103
104        LogDebugFn("calling canILoadThisKey");
105	if ((result = canILoadThisKey(&(key.algorithmParms), &canLoad)))
106		goto error;
107
108	if (canLoad == FALSE) {
109		LogDebugFn("calling evictFirstKey");
110		/* Evict a key that isn't the parent */
111		if ((result = evictFirstKey(hUnwrappingKey)))
112			goto error;
113	}
114
115	offset = 0;
116	if ((result = tpm_rqu_build(ord, &offset, txBlob, parentSlot, cWrappedKeyBlobSize,
117				    rgbWrappedKeyBlob, pAuth, NULL)))
118		goto error;
119
120	LogDebugFn("Submitting request to the TPM");
121	if ((result = req_mgr_submit_req(txBlob)))
122		goto error;
123
124	if ((result = UnloadBlob_Header(txBlob, &paramSize))) {
125		LogDebugFn("UnloadBlob_Header failed: rc=0x%x", result);
126		goto error;
127	}
128
129	if ((result = tpm_rsp_parse(ord, txBlob, paramSize, &newSlot, pAuth)))
130		goto error;
131
132	if ((result = load_key_final(hContext, hUnwrappingKey, &newHandle, rgbWrappedKeyBlob,
133				     newSlot)))
134		goto error;
135
136	/* Setup the outHandles */
137	*phKeyTCSI = newHandle;
138	if (phKeyHMAC)
139		*phKeyHMAC = newSlot;
140
141	LogDebugFn("Key handles for loadKeyByBlob slot:%.8X tcshandle:%.8X", newSlot, newHandle);
142error:
143	auth_mgr_release_auth(pAuth, NULL, hContext);
144	return result;
145}
146
147TSS_RESULT
148TCSP_EvictKey_Internal(TCS_CONTEXT_HANDLE hContext,	/* in */
149		       TCS_KEY_HANDLE hKey)		/* in */
150{
151	TSS_RESULT result;
152	TCPA_KEY_HANDLE tpm_handle;
153
154	if ((result = ctx_verify_context(hContext)))
155		return result;
156
157	tpm_handle = mc_get_slot_by_handle(hKey);
158	if (tpm_handle == NULL_TPM_HANDLE)
159		return TSS_SUCCESS;	/*let's call this success if the key is already evicted */
160
161	if ((result = internal_EvictByKeySlot(tpm_handle)))
162		return result;
163
164	result = mc_set_slot_by_slot(tpm_handle, NULL_TPM_HANDLE);
165
166	return result;
167}
168
169TSS_RESULT
170TCSP_CreateWrapKey_Internal(TCS_CONTEXT_HANDLE hContext,	/* in */
171			    TCS_KEY_HANDLE hWrappingKey,	/* in */
172			    TCPA_ENCAUTH KeyUsageAuth,		/* in */
173			    TCPA_ENCAUTH KeyMigrationAuth,	/* in */
174			    UINT32 keyInfoSize,			/* in */
175			    BYTE * keyInfo,			/* in */
176			    UINT32 * keyDataSize,		/* out */
177			    BYTE ** keyData,			/* out */
178			    TPM_AUTH * pAuth)			/* in, out */
179{
180	UINT64 offset = 0;
181	UINT32 paramSize;
182	TSS_RESULT result;
183	TCPA_KEY_HANDLE parentSlot;
184	BYTE txBlob[TSS_TPM_TXBLOB_SIZE];
185
186	LogDebug("Entering Create Wrap Key");
187
188	if ((result = ctx_verify_context(hContext)))
189		goto done;
190
191	if (pAuth) {
192		if ((result = auth_mgr_check(hContext, &pAuth->AuthHandle)))
193			goto done;
194	}
195
196	/* Since hWrappingKey must already be loaded, we can fail immediately if
197	 * mc_get_slot_by_handle_lock() fails.*/
198	parentSlot = mc_get_slot_by_handle_lock(hWrappingKey);
199	if (parentSlot == NULL_TPM_HANDLE) {
200		result = TCSERR(TSS_E_FAIL);
201		goto done;
202	}
203
204	if ((result = tpm_rqu_build(TPM_ORD_CreateWrapKey, &offset, txBlob, parentSlot,
205				    KeyUsageAuth.authdata, KeyMigrationAuth.authdata, keyInfoSize,
206				    keyInfo, pAuth)))
207		goto done;
208
209	if ((result = req_mgr_submit_req(txBlob)))
210		goto done;
211
212	result = UnloadBlob_Header(txBlob, &paramSize);
213	if (!result) {
214		result = tpm_rsp_parse(TPM_ORD_CreateWrapKey, txBlob, paramSize, keyDataSize,
215				       keyData, pAuth);
216	}
217	LogResult("Create Wrap Key", result);
218
219done:
220	auth_mgr_release_auth(pAuth, NULL, hContext);
221	return result;
222}
223
224TSS_RESULT
225TCSP_GetPubKey_Internal(TCS_CONTEXT_HANDLE hContext,	/* in */
226			TCS_KEY_HANDLE hKey,		/* in */
227			TPM_AUTH * pAuth,		/* in, out */
228			UINT32 * pcPubKeySize,		/* out */
229			BYTE ** prgbPubKey)		/* out */
230{
231	UINT64 offset = 0;
232	UINT32 paramSize;
233	TSS_RESULT result;
234	TCPA_KEY_HANDLE keySlot;
235	BYTE txBlob[TSS_TPM_TXBLOB_SIZE];
236
237	LogDebug("Entering Get pub key");
238	if ((result = ctx_verify_context(hContext)))
239		goto done;
240
241	if (pAuth != NULL) {
242		LogDebug("Auth Used");
243		if ((result = auth_mgr_check(hContext, &pAuth->AuthHandle)))
244			goto done;
245	} else {
246		LogDebug("No Auth");
247	}
248
249	if (ensureKeyIsLoaded(hContext, hKey, &keySlot)) {
250		result = TCSERR(TCS_E_KM_LOADFAILED);
251		goto done;
252	}
253
254	LogDebug("GetPubKey: handle: 0x%x, slot: 0x%x", hKey, keySlot);
255	if ((result = tpm_rqu_build(TPM_ORD_GetPubKey, &offset, txBlob, keySlot, pAuth)))
256		goto done;
257
258	if ((result = req_mgr_submit_req(txBlob)))
259		goto done;
260
261	offset = 10;
262	result = UnloadBlob_Header(txBlob, &paramSize);
263
264	if (!result) {
265		result = tpm_rsp_parse(TPM_ORD_GetPubKey, txBlob, paramSize, pcPubKeySize,
266				       prgbPubKey, pAuth);
267	}
268	LogResult("Get Public Key", result);
269done:
270	auth_mgr_release_auth(pAuth, NULL, hContext);
271	return result;
272}
273
274TSS_RESULT
275TCSP_OwnerReadInternalPub_Internal(TCS_CONTEXT_HANDLE hContext,	/* in */
276				   TCS_KEY_HANDLE hKey,	/* in */
277				   TPM_AUTH * pOwnerAuth,	/* in, out */
278				   UINT32 * punPubKeySize,	/* out */
279				   BYTE ** ppbPubKeyData)	/* out */
280{
281	UINT64 offset = 0;
282	UINT32 paramSize;
283	TSS_RESULT result;
284	BYTE txBlob[TSS_TPM_TXBLOB_SIZE];
285
286	LogDebug("Entering OwnerReadInternalPub");
287	if ((result = ctx_verify_context(hContext)))
288		goto done;
289
290	LogDebug("OwnerReadInternalPub: handle: 0x%x", hKey);
291	if (hKey != TPM_KH_SRK && hKey != TPM_KH_EK) {
292		result = TCSERR(TSS_E_FAIL);
293		LogDebug("OwnerReadInternalPub - Unsupported Key Handle");
294		goto done;
295	}
296
297	if ((result = auth_mgr_check(hContext, &pOwnerAuth->AuthHandle)))
298		goto done;
299
300	if ((result = tpm_rqu_build(TPM_ORD_OwnerReadInternalPub, &offset, txBlob, hKey,
301				    pOwnerAuth)))
302		goto done;
303
304	if ((result = req_mgr_submit_req(txBlob)))
305		goto done;
306
307	result = UnloadBlob_Header(txBlob, &paramSize);
308	if (!result) {
309		result = tpm_rsp_parse(TPM_ORD_OwnerReadInternalPub, txBlob, paramSize,
310				       punPubKeySize, ppbPubKeyData, pOwnerAuth);
311	}
312	LogResult("OwnerReadInternalPub", result);
313done:
314	auth_mgr_release_auth(pOwnerAuth, NULL, hContext);
315	return result;
316}
317
318TSS_RESULT
319TCSP_KeyControlOwner_Internal(TCS_CONTEXT_HANDLE hContext,	/* in */
320			      TCS_KEY_HANDLE hTcsKey,		/* in */
321			      UINT32 ulPubKeyLength,		/* in */
322			      BYTE* rgbPubKey,			/* in */
323			      UINT32 attribName,		/* in */
324			      TSS_BOOL attribValue,		/* in */
325			      TPM_AUTH* pOwnerAuth,		/* in,out */
326			      TSS_UUID* pUuidData)		/* out */
327{
328	UINT64 offset = 0;
329	UINT32 paramSize;
330	TSS_RESULT result;
331	TPM_KEY_HANDLE hTpmKey;
332	BYTE txBlob[TSS_TPM_TXBLOB_SIZE];
333
334	LogDebugFn("Enter");
335	if ((result = ctx_verify_context(hContext))) {
336		LogDebug("Invalid TSS Context");
337		goto done;
338	}
339
340	if ((result = get_slot_lite(hContext, hTcsKey, &hTpmKey))) {
341		LogDebug("Can't get TPM Keyhandle for TCS key 0x%x", hTcsKey);
342		goto done;
343	}
344	LogDebugFn("TCS hKey=0x%x, TPM hKey=0x%x", hTcsKey, hTpmKey);
345
346	if ((result = auth_mgr_check(hContext, &pOwnerAuth->AuthHandle))) {
347		LogDebug("Owner Authentication failed");
348		goto done;
349	}
350
351	if ((result = mc_find_next_ownerevict_uuid(pUuidData))) {
352		LogDebugFn("mc_find_next_ownerevict_uuid failed: rc=0x%x", result);
353		goto done;
354	}
355
356	if ((result = tpm_rqu_build(TPM_ORD_KeyControlOwner, &offset, txBlob, hTpmKey,
357				    ulPubKeyLength, rgbPubKey, attribName, attribValue,
358				    pOwnerAuth))) {
359		LogDebugFn("rqu build failed");
360		goto done;
361	}
362
363	if ((result = req_mgr_submit_req(txBlob))) {
364	        LogDebugFn("Request submission failed");
365		goto done;
366	}
367
368	if ((result = UnloadBlob_Header(txBlob, &paramSize))) {
369		LogDebugFn("UnloadBlob_Header failed: rc=0x%x", result);
370		goto done;
371	}
372
373	if ((result = tpm_rsp_parse(TPM_ORD_KeyControlOwner, txBlob, paramSize, pOwnerAuth))) {
374		LogDebugFn("tpm_rsp_parse failed: rc=0x%x", result);
375		goto done;
376	}
377
378	if ((result = mc_set_uuid(hTcsKey, pUuidData))){
379		LogDebugFn("mc_set_uuid failed: rc=0x%x", result);
380		goto done;
381	}
382
383	LogResult("KeyControlOwner", result);
384done:
385	auth_mgr_release_auth(pOwnerAuth, NULL, hContext);
386	return result;
387}
388
389