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