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-2006
8  *
9  */
10 
11 
12 #include <stdlib.h>
13 #include <stdio.h>
14 #include <string.h>
15 #include <time.h>
16 #include <errno.h>
17 
18 #include "trousers/tss.h"
19 #include "trousers/trousers.h"
20 #include "trousers_types.h"
21 #include "trousers_types.h"
22 #include "spi_utils.h"
23 #include "capabilities.h"
24 #include "tsplog.h"
25 #include "obj.h"
26 #include "authsess.h"
27 
28 
29 TSS_RESULT
Trspi_UnloadBlob_STORED_DATA(UINT64 * offset,BYTE * blob,TCPA_STORED_DATA * data)30 Trspi_UnloadBlob_STORED_DATA(UINT64 *offset, BYTE *blob, TCPA_STORED_DATA *data)
31 {
32 	Trspi_UnloadBlob_TCPA_VERSION(offset, blob, &data->ver);
33 	Trspi_UnloadBlob_UINT32(offset, &data->sealInfoSize, blob);
34 
35 	if (data->sealInfoSize > 0) {
36 		data->sealInfo = malloc(data->sealInfoSize);
37 		if (data->sealInfo == NULL) {
38 			LogError("malloc of %d bytes failed.", data->sealInfoSize);
39 			return TSPERR(TSS_E_OUTOFMEMORY);
40 		}
41 		Trspi_UnloadBlob(offset, data->sealInfoSize, blob, data->sealInfo);
42 	} else {
43 		data->sealInfo = NULL;
44 	}
45 
46 	Trspi_UnloadBlob_UINT32(offset, &data->encDataSize, blob);
47 
48 	if (data->encDataSize > 0) {
49 		data->encData = malloc(data->encDataSize);
50 		if (data->encData == NULL) {
51 			LogError("malloc of %d bytes failed.", data->encDataSize);
52 			free(data->sealInfo);
53 			data->sealInfo = NULL;
54 			return TSPERR(TSS_E_OUTOFMEMORY);
55 		}
56 
57 		Trspi_UnloadBlob(offset, data->encDataSize, blob, data->encData);
58 	} else {
59 		data->encData = NULL;
60 	}
61 
62 	return TSS_SUCCESS;
63 }
64 
65 void
Trspi_LoadBlob_STORED_DATA(UINT64 * offset,BYTE * blob,TCPA_STORED_DATA * data)66 Trspi_LoadBlob_STORED_DATA(UINT64 *offset, BYTE *blob, TCPA_STORED_DATA *data)
67 {
68 	Trspi_LoadBlob_TCPA_VERSION(offset, blob, data->ver);
69 	Trspi_LoadBlob_UINT32(offset, data->sealInfoSize, blob);
70 	Trspi_LoadBlob(offset, data->sealInfoSize, blob, data->sealInfo);
71 	Trspi_LoadBlob_UINT32(offset, data->encDataSize, blob);
72 	Trspi_LoadBlob(offset, data->encDataSize, blob, data->encData);
73 }
74 
75 TSS_RESULT
changeauth_owner(TSS_HCONTEXT tspContext,TSS_HOBJECT hObjectToChange,TSS_HOBJECT hParentObject,TSS_HPOLICY hNewPolicy)76 changeauth_owner(TSS_HCONTEXT tspContext,
77 		 TSS_HOBJECT hObjectToChange,
78 		 TSS_HOBJECT hParentObject,
79 		 TSS_HPOLICY hNewPolicy)
80 {
81 	TPM_DIGEST digest;
82 	TSS_RESULT result;
83 	Trspi_HashCtx hashCtx;
84 	struct authsess *xsap = NULL;
85 
86 	if ((result = authsess_xsap_init(tspContext, hObjectToChange, hNewPolicy,
87 					TSS_AUTH_POLICY_REQUIRED, TPM_ORD_ChangeAuthOwner,
88 					TPM_ET_OWNER, &xsap)))
89 		return result;
90 
91 	/* calculate auth data */
92 	result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
93 	result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_ChangeAuthOwner);
94 	result |= Trspi_Hash_UINT16(&hashCtx, TCPA_PID_ADCP);
95 	result |= Trspi_Hash_ENCAUTH(&hashCtx, xsap->encAuthUse.authdata);
96 	result |= Trspi_Hash_UINT16(&hashCtx, TCPA_ET_OWNER);
97 	if ((result |= Trspi_HashFinal(&hashCtx, digest.digest)))
98 		goto error;
99 
100 	if ((result = authsess_xsap_hmac(xsap, &digest)))
101 		goto error;
102 
103 	if ((result = TCS_API(tspContext)->ChangeAuthOwner(tspContext, TCPA_PID_ADCP,
104 							   &xsap->encAuthUse, TPM_ET_OWNER,
105 							   xsap->pAuth)))
106 		goto error;
107 
108 	result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
109 	result |= Trspi_Hash_UINT32(&hashCtx, TPM_SUCCESS);
110 	result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_ChangeAuthOwner);
111 	if ((result |= Trspi_HashFinal(&hashCtx, digest.digest)))
112 		goto error;
113 
114 	result = authsess_xsap_verify(xsap, &digest);
115 error:
116 	authsess_free(xsap);
117 
118 	return result;
119 }
120 
121 TSS_RESULT
changeauth_srk(TSS_HCONTEXT tspContext,TSS_HOBJECT hObjectToChange,TSS_HOBJECT hParentObject,TSS_HPOLICY hNewPolicy)122 changeauth_srk(TSS_HCONTEXT tspContext,
123 	       TSS_HOBJECT hObjectToChange,
124 	       TSS_HOBJECT hParentObject,
125 	       TSS_HPOLICY hNewPolicy)
126 {
127 	TPM_DIGEST digest;
128 	TSS_RESULT result;
129 	Trspi_HashCtx hashCtx;
130 	struct authsess *xsap = NULL;
131 
132 
133 	if ((result = authsess_xsap_init(tspContext, hParentObject, hNewPolicy,
134 					 TSS_AUTH_POLICY_REQUIRED, TPM_ORD_ChangeAuthOwner,
135 					 TPM_ET_OWNER, &xsap)))
136 		return result;
137 
138 	/* calculate auth data */
139 	result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
140 	result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_ChangeAuthOwner);
141 	result |= Trspi_Hash_UINT16(&hashCtx, TCPA_PID_ADCP);
142 	result |= Trspi_Hash_ENCAUTH(&hashCtx, xsap->encAuthUse.authdata);
143 	result |= Trspi_Hash_UINT16(&hashCtx, TCPA_ET_SRK);
144 	if ((result |= Trspi_HashFinal(&hashCtx, digest.digest)))
145 		goto error;
146 
147 	if ((result = authsess_xsap_hmac(xsap, &digest)))
148 		goto error;
149 
150 	if ((result = TCS_API(tspContext)->ChangeAuthOwner(tspContext, TCPA_PID_ADCP,
151 							   &xsap->encAuthUse, TPM_ET_SRK,
152 							   xsap->pAuth)))
153 		goto error;
154 
155 	/* Validate the Auths */
156 	result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
157 	result |= Trspi_Hash_UINT32(&hashCtx, TPM_SUCCESS);
158 	result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_ChangeAuthOwner);
159 	if ((result |= Trspi_HashFinal(&hashCtx, digest.digest)))
160 		goto error;
161 
162 	result = authsess_xsap_verify(xsap, &digest);
163 error:
164 	authsess_free(xsap);
165 
166 	return result;
167 }
168 
169 TSS_RESULT
changeauth_encdata(TSS_HCONTEXT tspContext,TSS_HOBJECT hObjectToChange,TSS_HOBJECT hParentObject,TSS_HPOLICY hNewPolicy)170 changeauth_encdata(TSS_HCONTEXT tspContext,
171 		   TSS_HOBJECT hObjectToChange,
172 		   TSS_HOBJECT hParentObject,
173 		   TSS_HPOLICY hNewPolicy)
174 {
175 	TPM_DIGEST digest;
176 	TSS_RESULT result;
177 	Trspi_HashCtx hashCtx;
178 	TSS_HPOLICY hPolicy;
179 	TCS_KEY_HANDLE keyHandle;
180 	UINT64 offset;
181 	struct authsess *xsap = NULL;
182 	TPM_STORED_DATA storedData;
183 	UINT32 dataBlobLength, newEncSize;
184 	BYTE *dataBlob, *newEncData;
185 	TPM_AUTH auth2;
186 
187 	/*  get the secret for the parent */
188 	if ((result = obj_encdata_get_policy(hObjectToChange, TSS_POLICY_USAGE, &hPolicy)))
189 		return result;
190 
191 	/*  get the data Object  */
192 	if ((result = obj_encdata_get_data(hObjectToChange, &dataBlobLength, &dataBlob)))
193 		return result;
194 
195 	offset = 0;
196 	if ((result = Trspi_UnloadBlob_STORED_DATA(&offset, dataBlob, &storedData)))
197 		return result;
198 
199 	if ((result = obj_rsakey_get_tcs_handle(hParentObject, &keyHandle)))
200 		return result;
201 
202 	if ((result = authsess_xsap_init(tspContext, hParentObject, hNewPolicy,
203 					 TSS_AUTH_POLICY_REQUIRED, TPM_ORD_ChangeAuth,
204 					 TPM_ET_KEYHANDLE, &xsap)))
205 		return result;
206 
207 	/* caluculate auth data */
208 	result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
209 	result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_ChangeAuth);
210 	result |= Trspi_Hash_UINT16(&hashCtx, TPM_PID_ADCP);
211 	result |= Trspi_Hash_ENCAUTH(&hashCtx, xsap->encAuthUse.authdata);
212 	result |= Trspi_Hash_UINT16(&hashCtx, TPM_ET_DATA);
213 	result |= Trspi_Hash_UINT32(&hashCtx, storedData.encDataSize);
214 	result |= Trspi_HashUpdate(&hashCtx, storedData.encDataSize, storedData.encData);
215 	if ((result |= Trspi_HashFinal(&hashCtx, digest.digest)))
216 		goto error;
217 
218 	if ((result = authsess_xsap_hmac(xsap, &digest)))
219 		goto error;
220 
221 	if ((result = secret_PerformAuth_OIAP(hObjectToChange, TPM_ORD_ChangeAuth,
222 					hPolicy, FALSE, &digest, &auth2)))
223 		goto error;
224 
225 	if ((result = TCS_API(tspContext)->ChangeAuth(tspContext, keyHandle, TPM_PID_ADCP,
226 						      &xsap->encAuthUse, TPM_ET_DATA,
227 						      storedData.encDataSize, storedData.encData,
228 						      xsap->pAuth, &auth2, &newEncSize,
229 						      &newEncData)))
230 		goto error;
231 
232 	/* Validate the Auths */
233 	result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
234 	result |= Trspi_Hash_UINT32(&hashCtx, TPM_SUCCESS);
235 	result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_ChangeAuth);
236 	result |= Trspi_Hash_UINT32(&hashCtx, newEncSize);
237 	result |= Trspi_HashUpdate(&hashCtx, newEncSize, newEncData);
238 	if ((result |= Trspi_HashFinal(&hashCtx, digest.digest)))
239 		goto error;
240 
241 	if ((result = authsess_xsap_verify(xsap, &digest)))
242 		goto error;
243 
244 	if ((result = obj_policy_validate_auth_oiap(hPolicy, &digest, &auth2)))
245 		goto error;
246 
247 	memcpy(storedData.encData, newEncData, newEncSize);
248 	free(newEncData);
249 	storedData.encDataSize = newEncSize;
250 
251 	offset = 0;
252 	Trspi_LoadBlob_STORED_DATA(&offset, dataBlob, &storedData);
253 
254 	result = obj_encdata_set_data(hObjectToChange, offset, dataBlob);
255 
256 error:
257 	authsess_free(xsap);
258 	free(storedData.sealInfo);
259 	free(storedData.encData);
260 
261 	return result;
262 
263 }
264 
265 TSS_RESULT
changeauth_key(TSS_HCONTEXT tspContext,TSS_HOBJECT hObjectToChange,TSS_HOBJECT hParentObject,TSS_HPOLICY hNewPolicy)266 changeauth_key(TSS_HCONTEXT tspContext,
267 	       TSS_HOBJECT hObjectToChange,
268 	       TSS_HOBJECT hParentObject,
269 	       TSS_HPOLICY hNewPolicy)
270 {
271 	TPM_DIGEST digest;
272 	Trspi_HashCtx hashCtx;
273 	TSS_RESULT result;
274 	TSS_KEY keyToChange;
275 	TCS_KEY_HANDLE keyHandle;
276 	struct authsess *xsap = NULL;
277 	UINT32 objectLength;
278 	TSS_HPOLICY hPolicy;
279 	BYTE *keyBlob;
280 	UINT32 newEncSize;
281 	BYTE *newEncData;
282 	TPM_AUTH auth2;
283 	UINT64 offset;
284 
285 
286 	if ((result = obj_rsakey_get_blob(hObjectToChange, &objectLength, &keyBlob)))
287 		return result;
288 
289 	offset = 0;
290 	if ((result = UnloadBlob_TSS_KEY(&offset, keyBlob, &keyToChange))) {
291 		LogDebug("UnloadBlob_TSS_KEY failed. "
292 				"result=0x%x", result);
293 		return result;
294 	}
295 
296 	if ((result = obj_rsakey_get_policy(hObjectToChange, TSS_POLICY_USAGE, &hPolicy, NULL)))
297 		return result;
298 
299 	if ((result = obj_rsakey_get_tcs_handle(hParentObject, &keyHandle)))
300 		return result;
301 
302 	if ((result = authsess_xsap_init(tspContext, hParentObject, hNewPolicy,
303 					 TSS_AUTH_POLICY_REQUIRED, TPM_ORD_ChangeAuth,
304 					 keyHandle == TPM_KEYHND_SRK ?
305 					 TPM_ET_SRK : TPM_ET_KEYHANDLE, &xsap)))
306 		return result;
307 
308 	/* caluculate auth data */
309 	result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
310 	result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_ChangeAuth);
311 	result |= Trspi_Hash_UINT16(&hashCtx, TCPA_PID_ADCP);
312 	result |= Trspi_Hash_ENCAUTH(&hashCtx, xsap->encAuthUse.authdata);
313 	result |= Trspi_Hash_UINT16(&hashCtx, TCPA_ET_KEY);
314 	result |= Trspi_Hash_UINT32(&hashCtx, keyToChange.encSize);
315 	result |= Trspi_HashUpdate(&hashCtx, keyToChange.encSize,
316 			keyToChange.encData);
317 	if ((result |= Trspi_HashFinal(&hashCtx, digest.digest)))
318 		goto error;
319 
320 	if ((result = authsess_xsap_hmac(xsap, &digest)))
321 		goto error;
322 
323 	if ((result = secret_PerformAuth_OIAP(hObjectToChange, TPM_ORD_ChangeAuth,
324 					hPolicy, FALSE, &digest, &auth2)))
325 		goto error;
326 
327 	if ((result = TCS_API(tspContext)->ChangeAuth(tspContext, keyHandle, TPM_PID_ADCP,
328 						      &xsap->encAuthUse, TPM_ET_KEY,
329 						      keyToChange.encSize, keyToChange.encData,
330 						      xsap->pAuth, &auth2, &newEncSize,
331 						      &newEncData)))
332 		goto error;
333 
334 	/* Validate the Auths */
335 	result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
336 	result |= Trspi_Hash_UINT32(&hashCtx, result);
337 	result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_ChangeAuth);
338 	result |= Trspi_Hash_UINT32(&hashCtx, newEncSize);
339 	result |= Trspi_HashUpdate(&hashCtx, newEncSize, newEncData);
340 	if ((result |= Trspi_HashFinal(&hashCtx, digest.digest)))
341 		goto error;
342 
343 	if ((result = authsess_xsap_verify(xsap, &digest)))
344 		goto error;
345 
346 	if ((result = obj_policy_validate_auth_oiap(hPolicy, &digest, &auth2)))
347 		return result;
348 
349 	memcpy(keyToChange.encData, newEncData, newEncSize);
350 	free(newEncData);
351 
352 	offset = 0;
353 	LoadBlob_TSS_KEY(&offset, keyBlob, &keyToChange);
354 	objectLength = offset;
355 
356 	result = obj_rsakey_set_tcpakey(hObjectToChange, objectLength, keyBlob);
357 error:
358 	authsess_free(xsap);
359 
360 	return result;
361 }
362 
363 
364 #ifdef TSS_BUILD_TRANSPORT
365 TSS_RESULT
Transport_ChangeAuth(TSS_HCONTEXT tspContext,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)366 Transport_ChangeAuth(TSS_HCONTEXT tspContext,	/* in */
367 		     TCS_KEY_HANDLE parentHandle,	/* in */
368 		     TCPA_PROTOCOL_ID protocolID,	/* in */
369 		     TCPA_ENCAUTH *newAuth,	/* in */
370 		     TCPA_ENTITY_TYPE entityType,	/* in */
371 		     UINT32 encDataSize,	/* in */
372 		     BYTE * encData,	/* in */
373 		     TPM_AUTH * ownerAuth,	/* in, out */
374 		     TPM_AUTH * entityAuth,	/* in, out */
375 		     UINT32 * outDataSize,	/* out */
376 		     BYTE ** outData)	/* out */
377 {
378 	TSS_RESULT result;
379 	UINT32 handlesLen, dataLen, decLen;
380 	TCS_HANDLE *handles, handle;
381 	BYTE *dec = NULL;
382 	TPM_DIGEST pubKeyHash;
383 	Trspi_HashCtx hashCtx;
384 	UINT64 offset;
385 	BYTE *data;
386 
387 	if ((result = obj_context_transport_init(tspContext)))
388 		return result;
389 
390 	LogDebugFn("Executing in a transport session");
391 
392 	if ((result = obj_tcskey_get_pubkeyhash(parentHandle, pubKeyHash.digest)))
393 		return result;
394 
395 	result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
396 	result |= Trspi_Hash_DIGEST(&hashCtx, pubKeyHash.digest);
397 	if ((result |= Trspi_HashFinal(&hashCtx, pubKeyHash.digest)))
398 		return result;
399 
400 	handlesLen = 1;
401 	handle = parentHandle;
402 	handles = &handle;
403 
404 	dataLen = sizeof(TCPA_PROTOCOL_ID) + sizeof(TCPA_ENCAUTH)
405 					   + sizeof(TCPA_ENTITY_TYPE)
406 					   + sizeof(UINT32)
407 					   + encDataSize;
408 	if ((data = malloc(dataLen)) == NULL) {
409 		LogError("malloc of %u bytes failed", dataLen);
410 		return TSPERR(TSS_E_OUTOFMEMORY);
411 	}
412 
413 	offset = 0;
414 	Trspi_LoadBlob_UINT16(&offset, protocolID, data);
415 	Trspi_LoadBlob(&offset, sizeof(TCPA_ENCAUTH), data, newAuth->authdata);
416 	Trspi_LoadBlob_UINT16(&offset, entityType, data);
417 	Trspi_LoadBlob_UINT32(&offset, encDataSize, data);
418 	Trspi_LoadBlob(&offset, encDataSize, data, encData);
419 
420 	if ((result = obj_context_transport_execute(tspContext, TPM_ORD_ChangeAuth, dataLen, data,
421 						    &pubKeyHash, &handlesLen, &handles,
422 						    ownerAuth, entityAuth, &decLen, &dec))) {
423 		free(data);
424 		return result;
425 	}
426 	free(data);
427 
428 	offset = 0;
429 	Trspi_UnloadBlob_UINT32(&offset, outDataSize, dec);
430 
431 	if ((*outData = malloc(*outDataSize)) == NULL) {
432 		free(dec);
433 		LogError("malloc of %u bytes failed", *outDataSize);
434 		*outDataSize = 0;
435 		return TSPERR(TSS_E_OUTOFMEMORY);
436 	}
437 	Trspi_UnloadBlob(&offset, *outDataSize, dec, *outData);
438 
439 	free(dec);
440 
441 	return result;
442 }
443 
444 TSS_RESULT
Transport_ChangeAuthOwner(TSS_HCONTEXT tspContext,TCPA_PROTOCOL_ID protocolID,TCPA_ENCAUTH * newAuth,TCPA_ENTITY_TYPE entityType,TPM_AUTH * ownerAuth)445 Transport_ChangeAuthOwner(TSS_HCONTEXT tspContext,	/* in */
446 			  TCPA_PROTOCOL_ID protocolID,	/* in */
447 			  TCPA_ENCAUTH *newAuth,	/* in */
448 			  TCPA_ENTITY_TYPE entityType,	/* in */
449 			  TPM_AUTH * ownerAuth)	/* in, out */
450 {
451 	TSS_RESULT result;
452 	UINT32 handlesLen = 0;
453 	UINT64 offset;
454 	BYTE data[sizeof(TCPA_PROTOCOL_ID) + sizeof(TCPA_ENCAUTH) + sizeof(TCPA_ENTITY_TYPE)];
455 
456 	if ((result = obj_context_transport_init(tspContext)))
457 		return result;
458 
459 	LogDebugFn("Executing in a transport session");
460 
461 	offset = 0;
462 	Trspi_LoadBlob_UINT16(&offset, protocolID, data);
463 	Trspi_LoadBlob(&offset, sizeof(TCPA_ENCAUTH), data, newAuth->authdata);
464 	Trspi_LoadBlob_UINT16(&offset, entityType, data);
465 
466 	return obj_context_transport_execute(tspContext, TPM_ORD_ChangeAuthOwner, sizeof(data),
467 					     data, NULL, &handlesLen, NULL, ownerAuth, NULL, NULL,
468 					     NULL);
469 }
470 #endif
471