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 
27 TSS_RESULT
TCSP_LoadKeyByBlob_Internal(TCS_CONTEXT_HANDLE hContext,TCS_KEY_HANDLE hUnwrappingKey,UINT32 cWrappedKeyBlobSize,BYTE * rgbWrappedKeyBlob,TPM_AUTH * pAuth,TCS_KEY_HANDLE * phKeyTCSI,TCS_KEY_HANDLE * phKeyHMAC)28 TCSP_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 
41 TSS_RESULT
TCSP_LoadKey2ByBlob_Internal(TCS_CONTEXT_HANDLE hContext,TCS_KEY_HANDLE hUnwrappingKey,UINT32 cWrappedKeyBlobSize,BYTE * rgbWrappedKeyBlob,TPM_AUTH * pAuth,TCS_KEY_HANDLE * phKeyTCSI)42 TCSP_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 
54 TSS_RESULT
LoadKeyByBlob_Internal(UINT32 ord,TCS_CONTEXT_HANDLE hContext,TCS_KEY_HANDLE hUnwrappingKey,UINT32 cWrappedKeyBlobSize,BYTE * rgbWrappedKeyBlob,TPM_AUTH * pAuth,TCS_KEY_HANDLE * phKeyTCSI,TCS_KEY_HANDLE * phKeyHMAC)55 LoadKeyByBlob_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);
142 error:
143 	auth_mgr_release_auth(pAuth, NULL, hContext);
144 	return result;
145 }
146 
147 TSS_RESULT
TCSP_EvictKey_Internal(TCS_CONTEXT_HANDLE hContext,TCS_KEY_HANDLE hKey)148 TCSP_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 
169 TSS_RESULT
TCSP_CreateWrapKey_Internal(TCS_CONTEXT_HANDLE hContext,TCS_KEY_HANDLE hWrappingKey,TCPA_ENCAUTH KeyUsageAuth,TCPA_ENCAUTH KeyMigrationAuth,UINT32 keyInfoSize,BYTE * keyInfo,UINT32 * keyDataSize,BYTE ** keyData,TPM_AUTH * pAuth)170 TCSP_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 
219 done:
220 	auth_mgr_release_auth(pAuth, NULL, hContext);
221 	return result;
222 }
223 
224 TSS_RESULT
TCSP_GetPubKey_Internal(TCS_CONTEXT_HANDLE hContext,TCS_KEY_HANDLE hKey,TPM_AUTH * pAuth,UINT32 * pcPubKeySize,BYTE ** prgbPubKey)225 TCSP_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);
269 done:
270 	auth_mgr_release_auth(pAuth, NULL, hContext);
271 	return result;
272 }
273 
274 TSS_RESULT
TCSP_OwnerReadInternalPub_Internal(TCS_CONTEXT_HANDLE hContext,TCS_KEY_HANDLE hKey,TPM_AUTH * pOwnerAuth,UINT32 * punPubKeySize,BYTE ** ppbPubKeyData)275 TCSP_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);
313 done:
314 	auth_mgr_release_auth(pOwnerAuth, NULL, hContext);
315 	return result;
316 }
317 
318 TSS_RESULT
TCSP_KeyControlOwner_Internal(TCS_CONTEXT_HANDLE hContext,TCS_KEY_HANDLE hTcsKey,UINT32 ulPubKeyLength,BYTE * rgbPubKey,UINT32 attribName,TSS_BOOL attribValue,TPM_AUTH * pOwnerAuth,TSS_UUID * pUuidData)319 TCSP_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);
384 done:
385 	auth_mgr_release_auth(pOwnerAuth, NULL, hContext);
386 	return result;
387 }
388 
389