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
8  *
9  */
10 
11 
12 #include <stdlib.h>
13 #include <stdio.h>
14 #include <string.h>
15 #include <inttypes.h>
16 
17 #include "trousers/tss.h"
18 #include "trousers_types.h"
19 #include "tcs_tsp.h"
20 #include "tcsps.h"
21 #include "tcs_utils.h"
22 #include "tcs_int_literals.h"
23 #include "capabilities.h"
24 #include "tcslog.h"
25 #include "req_mgr.h"
26 #include "tcsd_wrap.h"
27 #include "tcsd.h"
28 
29 
30 TSS_RESULT
TCSP_ChangeAuth_Internal(TCS_CONTEXT_HANDLE contextHandle,TCS_KEY_HANDLE parentHandle,TCPA_PROTOCOL_ID protocolID,TCPA_ENCAUTH newAuth,TCPA_ENTITY_TYPE entityType,UINT32 encDataSize,BYTE * encData,TPM_AUTH * ownerAuth,TPM_AUTH * entityAuth,UINT32 * outDataSize,BYTE ** outData)31 TCSP_ChangeAuth_Internal(TCS_CONTEXT_HANDLE contextHandle,	/* in */
32 			 TCS_KEY_HANDLE parentHandle,	/* in */
33 			 TCPA_PROTOCOL_ID protocolID,	/* in */
34 			 TCPA_ENCAUTH newAuth,	/* in */
35 			 TCPA_ENTITY_TYPE entityType,	/* in */
36 			 UINT32 encDataSize,	/* in */
37 			 BYTE *encData,	/* in */
38 			 TPM_AUTH *ownerAuth,	/* in, out */
39 			 TPM_AUTH *entityAuth,	/* in, out */
40 			 UINT32 *outDataSize,	/* out */
41 			 BYTE **outData	/* out */
42     )
43 {
44 	UINT64 offset = 0;
45 	UINT32 paramSize;
46 	TSS_RESULT result;
47 	TCPA_KEY_HANDLE keySlot;
48 	TCS_KEY_HANDLE tcsKeyHandleToEvict;
49 	BYTE txBlob[TSS_TPM_TXBLOB_SIZE];
50 
51 	LogDebug("Entering Changeauth");
52 	if ((result = ctx_verify_context(contextHandle)))
53 		goto done;
54 
55 	if ((result = auth_mgr_check(contextHandle, &ownerAuth->AuthHandle)))
56 		goto done;
57 	if ((result = auth_mgr_check(contextHandle, &entityAuth->AuthHandle)))
58 		goto done;
59 
60 	if ((result = ensureKeyIsLoaded(contextHandle, parentHandle, &keySlot)))
61 		goto done;
62 
63 	if ((result = tpm_rqu_build(TPM_ORD_ChangeAuth, &offset, txBlob, keySlot, protocolID,
64 				    newAuth.authdata, entityType, encDataSize, encData, ownerAuth,
65 				    entityAuth)))
66 		goto done;
67 
68 	if ((result = req_mgr_submit_req(txBlob)))
69 		goto done;
70 
71 	result = UnloadBlob_Header(txBlob, &paramSize);
72 	if (!result) {
73 		result = tpm_rsp_parse(TPM_ORD_ChangeAuth, txBlob, paramSize, outDataSize, outData,
74 				       ownerAuth, entityAuth);
75 
76 		/* if the malloc above failed, terminate the 2 new auth handles and exit */
77 		if (result)
78 			goto done;
79 
80 		/*
81 		 * Check if ET is a key.  If it is, we need to
82 		 *	1 - Evict the key if loaded
83 		 *	2 - update the mem cache entry
84 		 */
85 		if (entityType == TCPA_ET_KEYHANDLE || entityType == TCPA_ET_KEY) {
86 			LogDebug("entity type is a key. Check if mem cache needs updating...");
87 			tcsKeyHandleToEvict = mc_get_handle_by_encdata(encData);
88 			LogDebug("tcsKeyHandle being evicted is %.8X", tcsKeyHandleToEvict);
89 			/*---	If it was found in knowledge, replace it */
90 			if (tcsKeyHandleToEvict != 0) {
91 				internal_EvictByKeySlot(keySlot);
92 				mc_update_encdata(encData, *outData);
93 			}
94 
95 		}
96 	}
97 	LogResult("ChangeAuth", result);
98 done:
99 	auth_mgr_release_auth(ownerAuth, entityAuth, contextHandle);
100 	return result;
101 }
102 
103 TSS_RESULT
TCSP_ChangeAuthOwner_Internal(TCS_CONTEXT_HANDLE hContext,TCPA_PROTOCOL_ID protocolID,TCPA_ENCAUTH newAuth,TCPA_ENTITY_TYPE entityType,TPM_AUTH * ownerAuth)104 TCSP_ChangeAuthOwner_Internal(TCS_CONTEXT_HANDLE hContext,	/* in */
105 			      TCPA_PROTOCOL_ID protocolID,	/* in */
106 			      TCPA_ENCAUTH newAuth,	/* in */
107 			      TCPA_ENTITY_TYPE entityType,	/* in */
108 			      TPM_AUTH * ownerAuth	/* in, out */
109     )
110 {
111 	UINT64 offset = 0;
112 	UINT32 paramSize;
113 	TSS_RESULT result;
114 	BYTE txBlob[TSS_TPM_TXBLOB_SIZE];
115 
116 	LogDebug("Entering ChangeAuthOwner");
117 
118 	if ((result = ctx_verify_context(hContext)))
119 		goto done;
120 
121 	if ((result = auth_mgr_check(hContext, &ownerAuth->AuthHandle)))
122 		goto done;
123 
124 	if ((result = tpm_rqu_build(TPM_ORD_ChangeAuthOwner, &offset, txBlob, protocolID,
125 				    newAuth.authdata, entityType, ownerAuth)))
126 		goto done;
127 
128 	if ((result = req_mgr_submit_req(txBlob)))
129 		goto done;
130 
131 	result = UnloadBlob_Header(txBlob, &paramSize);
132 	if (!result) {
133 		result = tpm_rsp_parse(TPM_ORD_ChangeAuthOwner, txBlob, paramSize, ownerAuth);
134 	}
135 
136 	LogResult("ChangeAuthOwner", result);
137 done:
138 	auth_mgr_release_auth(ownerAuth, NULL, hContext);
139 	return result;
140 }
141 
142 TSS_RESULT
TCSP_ChangeAuthAsymStart_Internal(TCS_CONTEXT_HANDLE hContext,TCS_KEY_HANDLE idHandle,TCPA_NONCE antiReplay,UINT32 KeySizeIn,BYTE * KeyDataIn,TPM_AUTH * pAuth,UINT32 * KeySizeOut,BYTE ** KeyDataOut,UINT32 * CertifyInfoSize,BYTE ** CertifyInfo,UINT32 * sigSize,BYTE ** sig,TCS_KEY_HANDLE * ephHandle)143 TCSP_ChangeAuthAsymStart_Internal(TCS_CONTEXT_HANDLE hContext,	/* in */
144 				  TCS_KEY_HANDLE idHandle,	/* in */
145 				  TCPA_NONCE antiReplay,	/* in */
146 				  UINT32 KeySizeIn,	/* in */
147 				  BYTE * KeyDataIn,	/* in */
148 				  TPM_AUTH * pAuth,	/* in, out */
149 				  UINT32 * KeySizeOut,	/* out */
150 				  BYTE ** KeyDataOut,	/* out */
151 				  UINT32 * CertifyInfoSize,	/* out */
152 				  BYTE ** CertifyInfo,	/* out */
153 				  UINT32 * sigSize,	/* out */
154 				  BYTE ** sig,	/* out */
155 				  TCS_KEY_HANDLE * ephHandle	/* out */
156     )
157 {
158 #if 0
159 #warning Locking trouble in evictFirstKey
160 	UINT64 offset;
161 	UINT32 paramSize;
162 	TSS_RESULT result;
163 	UINT32 keySlot;
164 	TCPA_CERTIFY_INFO certifyInfo;
165 	TSS_KEY tempKey;
166 	UINT32 tempSize;
167 	TCPA_KEY_PARMS keyParmsContainer;
168 	TSS_BOOL canLoad;
169 	BYTE txBlob[TSS_TPM_TXBLOB_SIZE];
170 
171 	LogDebug("Entering ChangeAuthAsymStart");
172 	if ((result = ctx_verify_context(hContext)))
173 		goto done;
174 
175 	if (pAuth != NULL) {
176 		LogDebug("Auth Command");
177 		if ((result = auth_mgr_check(hContext, pAuth->AuthHandle)))
178 			goto done;
179 	} else {
180 		LogDebug("No Auth");
181 	}
182 
183 	if ((result = ensureKeyIsLoaded(hContext, idHandle, &keySlot)))
184 		goto done;
185 
186 	LogDebug("Checking for room to load the eph key");
187 	offset = 0;
188 	if ((result = UnloadBlob_KEY_PARMS(&offset, KeyDataIn, &keyParmsContainer)))
189 		goto done;
190 
191 	/* if we can't load the key, evict keys until we can */
192 	if ((result = canILoadThisKey(&keyParmsContainer, &canLoad)))
193 		goto done;
194 
195 	while (canLoad == FALSE) {
196 		/* Evict a key that isn't the parent */
197 		if ((result = evictFirstKey(idHandle)))
198 			goto done;
199 
200 		if ((result = canILoadThisKey(&keyParmsContainer, &canLoad)))
201 			goto done;
202 	}
203 
204 	offset = 10;
205 	LoadBlob_UINT32(&offset, keySlot, txBlob);
206 	LoadBlob(&offset, TCPA_NONCE_SIZE, txBlob, antiReplay.nonce);
207 /*	LoadBlob_KEY_PARMS( &offset, txBlob, &tempKeyParms ); */
208 /*	LoadBlob_UINT32( &offset, KeySizeIn, txBlob ); */
209 	LoadBlob(&offset, KeySizeIn, txBlob, KeyDataIn);
210 
211 	if (pAuth != NULL) {
212 		LoadBlob_Auth(&offset, txBlob, pAuth);
213 		LoadBlob_Header(TPM_TAG_RQU_AUTH1_COMMAND, offset,
214 				TPM_ORD_ChangeAuthAsymStart, txBlob);
215 	} else {
216 		LoadBlob_Header(TPM_TAG_RQU_COMMAND, offset,
217 				TPM_ORD_ChangeAuthAsymStart, txBlob);
218 	}
219 
220 	if ((result = req_mgr_submit_req(txBlob)))
221 		goto done;
222 
223 	offset = 10;
224 	result = UnloadBlob_Header(txBlob, &paramSize);
225 	if (result == 0) {
226 		UnloadBlob_CERTIFY_INFO(&offset, txBlob, &certifyInfo);
227 		*CertifyInfoSize = offset - 10;
228 		*CertifyInfo = malloc(*CertifyInfoSize);
229 		if (*CertifyInfo == NULL) {
230 			LogError("malloc of %u bytes failed.", *CertifyInfoSize);
231 			result = TCSERR(TSS_E_OUTOFMEMORY);
232 			goto done;
233 		}
234 		memcpy(*CertifyInfo, &txBlob[offset - *CertifyInfoSize],
235 		       *CertifyInfoSize);
236 		UnloadBlob_UINT32(&offset, sigSize, txBlob);
237 		*sig = malloc(*sigSize);
238 		if (*sig == NULL) {
239 			LogError("malloc of %u bytes failed.", *sigSize);
240 			result = TCSERR(TSS_E_OUTOFMEMORY);
241 			goto done;
242 		}
243 		UnloadBlob(&offset, *sigSize, txBlob, *sig);
244 		UnloadBlob_UINT32(&offset, ephHandle, txBlob);
245 		tempSize = offset;
246 		UnloadBlob_TSS_KEY(&offset, txBlob, &tempKey);
247 		*KeySizeOut = offset - tempSize;
248 		*KeyDataOut = malloc(*KeySizeOut);
249 		if (*KeyDataOut == NULL) {
250 			LogError("malloc of %u bytes failed.", *KeySizeOut);
251 			result = TCSERR(TSS_E_OUTOFMEMORY);
252 			goto done;
253 		}
254 		memcpy(*KeyDataOut, &txBlob[offset - *KeySizeOut], *KeySizeOut);
255 		if (pAuth != NULL)
256 			UnloadBlob_Auth(&offset, txBlob, pAuth);
257 	}
258 
259 	LogResult("ChangeAuthAsymStart", result);
260 done:
261 	auth_mgr_release_auth(pAuth, NULL, hContext);
262 	return result;
263 #else
264 	return TCSERR(TSS_E_NOTIMPL);
265 #endif
266 }
267 
268 TSS_RESULT
TCSP_ChangeAuthAsymFinish_Internal(TCS_CONTEXT_HANDLE hContext,TCS_KEY_HANDLE parentHandle,TCS_KEY_HANDLE ephHandle,TCPA_ENTITY_TYPE entityType,TCPA_HMAC newAuthLink,UINT32 newAuthSize,BYTE * encNewAuth,UINT32 encDataSizeIn,BYTE * encDataIn,TPM_AUTH * ownerAuth,UINT32 * encDataSizeOut,BYTE ** encDataOut,TCPA_SALT_NONCE * saltNonce,TCPA_DIGEST * changeProof)269 TCSP_ChangeAuthAsymFinish_Internal(TCS_CONTEXT_HANDLE hContext,	/* in */
270 				   TCS_KEY_HANDLE parentHandle,	/* in */
271 				   TCS_KEY_HANDLE ephHandle,	/* in */
272 				   TCPA_ENTITY_TYPE entityType,	/* in */
273 				   TCPA_HMAC newAuthLink,	/* in */
274 				   UINT32 newAuthSize,	/* in */
275 				   BYTE * encNewAuth,	/* in */
276 				   UINT32 encDataSizeIn,	/* in */
277 				   BYTE * encDataIn,	/* in */
278 				   TPM_AUTH * ownerAuth,	/* in, out */
279 				   UINT32 * encDataSizeOut,	/* out */
280 				   BYTE ** encDataOut,	/* out */
281 				   TCPA_SALT_NONCE * saltNonce,	/* out */
282 				   TCPA_DIGEST * changeProof	/* out */
283     )
284 {
285 #if 0
286 	UINT64 offset;
287 	UINT32 paramSize;
288 	TSS_RESULT result;
289 	UINT32 keySlot;
290 #if 0
291 	TCPA_CERTIFY_INFO certifyInfo;
292 	TSS_KEY tempKey;
293 	UINT32 tempSize;
294 	TSS_UUID *uuidKeyToEvict;
295 #endif
296 	TCS_KEY_HANDLE tcsKeyHandleToEvict;
297 	BYTE txBlob[TSS_TPM_TXBLOB_SIZE];
298 
299 	LogDebug("Entering ChangeAuthAsymFinish");
300 	if ((result = ctx_verify_context(hContext)))
301 		goto done;
302 
303 	if (ownerAuth != NULL) {
304 		LogDebug("Auth used");
305 		if ((result = auth_mgr_check(hContext, &ownerAuth->AuthHandle)))
306 			goto done;
307 	} else {
308 		LogDebug("No Auth");
309 	}
310 	if ((result = ensureKeyIsLoaded(hContext, parentHandle, &keySlot)))
311 		goto done;
312 
313 	offset = 10;
314 	LoadBlob_UINT32(&offset, keySlot, txBlob);
315 	LoadBlob_UINT32(&offset, ephHandle, txBlob);
316 	LoadBlob_UINT16(&offset, entityType, txBlob);
317 	LoadBlob(&offset, 20, txBlob, newAuthLink.digest);
318 	LoadBlob_UINT32(&offset, newAuthSize, txBlob);
319 	LoadBlob(&offset, newAuthSize, txBlob, encNewAuth);
320 	LoadBlob_UINT32(&offset, encDataSizeIn, txBlob);
321 	LoadBlob(&offset, encDataSizeIn, txBlob, encDataIn);
322 
323 	if (ownerAuth != NULL) {
324 		LoadBlob_Auth(&offset, txBlob, ownerAuth);
325 		LoadBlob_Header(TPM_TAG_RQU_AUTH1_COMMAND, offset,
326 				TPM_ORD_ChangeAuthAsymFinish, txBlob);
327 	} else {
328 		LoadBlob_Header(TPM_TAG_RQU_COMMAND, offset,
329 				TPM_ORD_ChangeAuthAsymFinish, txBlob);
330 	}
331 
332 	if ((result = req_mgr_submit_req(txBlob)))
333 		goto done;
334 
335 	offset = 10;
336 	result = UnloadBlob_Header(txBlob, &paramSize);
337 	if (!result) {
338 		UnloadBlob_UINT32(&offset, encDataSizeOut, txBlob);
339 		*encDataOut = calloc(1, *encDataSizeOut);
340 		if (*encDataOut == NULL) {
341 			LogError("malloc of %u bytes failed.", *encDataSizeOut);
342 			result = TCSERR(TSS_E_OUTOFMEMORY);
343 			goto done;
344 		}
345 		UnloadBlob(&offset, *encDataSizeOut, txBlob, *encDataOut);
346 		UnloadBlob(&offset, 20, txBlob, saltNonce->nonce);
347 		UnloadBlob(&offset, 20, txBlob, changeProof->digest);
348 		if (ownerAuth != NULL)
349 			UnloadBlob_Auth(&offset, txBlob, ownerAuth);
350 
351 		/* Check if ET is a key.  If it is, we need to
352 		 *	1 - Evict the key if loaded
353 		 *	2 - update the mem cache entry
354 		 */
355 		if (entityType == TCPA_ET_KEYHANDLE ||
356 		    entityType == TCPA_ET_KEY) {
357 			tcsKeyHandleToEvict = mc_get_handle_by_encdata(encDataIn);
358 			/* If it was found in mem cache, replace it */
359 			if (tcsKeyHandleToEvict != 0) {
360 				key_mgr_evict(hContext, tcsKeyHandleToEvict);
361 				mc_update_encdata(encDataIn, *encDataOut);
362 			}
363 		}
364 	}
365 
366 	LogResult("ChangeAuthAsymFinish", result);
367 done:
368 	auth_mgr_release_auth(ownerAuth, NULL, hContext);
369 	return result;
370 #else
371 	return TCSERR(TSS_E_NOTIMPL);
372 #endif
373 }
374 
375