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