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 TSS_RESULT
Tspi_ChangeAuth(TSS_HOBJECT hObjectToChange,TSS_HOBJECT hParentObject,TSS_HPOLICY hNewPolicy)29 Tspi_ChangeAuth(TSS_HOBJECT hObjectToChange,      /* in */
30                     TSS_HOBJECT hParentObject,    /* in */
31                     TSS_HPOLICY hNewPolicy)                 /* in */
32 {
33           UINT32 keyToChangeHandle;
34           TSS_RESULT result;
35           TSS_HCONTEXT tspContext;
36 
37           if ((result = obj_policy_get_tsp_context(hNewPolicy, &tspContext)))
38                     return result;
39 
40           /* if the object to change is the TPM object, then the parent should
41            * be NULL.  If the object to change is not the TPM, then the parent
42            * object must be either an rsakey or the TPM */
43           if (obj_is_tpm(hObjectToChange)) {
44                     if (hParentObject != NULL_HOBJECT)
45                               return TSPERR(TSS_E_BAD_PARAMETER);
46           } else if (!obj_is_rsakey(hParentObject) && !obj_is_tpm(hParentObject)) {
47                     return TSPERR(TSS_E_INVALID_HANDLE);
48           }
49 
50           if (obj_is_tpm(hObjectToChange)) {
51                     if ((result = changeauth_owner(tspContext, hObjectToChange, NULL_HTPM, hNewPolicy)))
52                               return result;
53           } else if (obj_is_rsakey(hObjectToChange)) {
54                     if ((result = obj_rsakey_get_tcs_handle(hObjectToChange, &keyToChangeHandle)))
55                               return result;
56 
57                     if (keyToChangeHandle == TPM_KEYHND_SRK) {
58                               if ((result = changeauth_srk(tspContext, hObjectToChange, hParentObject,
59                                                                  hNewPolicy)))
60                                         return result;
61                     } else {
62                               if ((result = changeauth_key(tspContext, hObjectToChange, hParentObject,
63                                                                  hNewPolicy)))
64                                         return result;
65                     }
66           } else if (obj_is_encdata(hObjectToChange)) {
67                     if ((result = changeauth_encdata(tspContext, hObjectToChange, hParentObject,
68                                                              hNewPolicy)))
69                               return result;
70           } else if (obj_is_policy(hObjectToChange) || obj_is_hash(hObjectToChange) ||
71                        obj_is_pcrs(hObjectToChange) || obj_is_context(hObjectToChange)) {
72                     return TSPERR(TSS_E_BAD_PARAMETER);
73           } else {
74                     return TSPERR(TSS_E_INVALID_HANDLE);
75           }
76 
77           if ((result = obj_policy_set_type(hNewPolicy, TSS_POLICY_USAGE)))
78                     return result;
79 
80           return Tspi_Policy_AssignToObject(hNewPolicy, hObjectToChange);
81 
82 }
83 
84 TSS_RESULT
Tspi_ChangeAuthAsym(TSS_HOBJECT hObjectToChange,TSS_HOBJECT hParentObject,TSS_HKEY hIdentKey,TSS_HPOLICY hNewPolicy)85 Tspi_ChangeAuthAsym(TSS_HOBJECT hObjectToChange,  /* in */
86                         TSS_HOBJECT hParentObject,                    /* in */
87                         TSS_HKEY hIdentKey,                           /* in */
88                         TSS_HPOLICY hNewPolicy)             /* in */
89 {
90 #if 0
91           TPM_AUTH auth;
92           UINT64 offset;
93           BYTE hashBlob[0x1000];
94           TCPA_DIGEST digest;
95           TCPA_RESULT result;
96           UINT32 keyHandle;
97           UINT32 idHandle;
98           TSS_HPOLICY hPolicy;
99           TSS_HPOLICY hParentPolicy;
100           UINT32 keyToChangeHandle;
101           TCPA_NONCE antiReplay;
102           UINT32 bytesRequested;
103           UINT64 tempSize;
104           BYTE tempKey[512];
105           TCPA_KEY_PARMS keyParms;
106           /* XXX Wow... */
107           BYTE ephParms[] = { 0, 0, 0x08, 0, 0, 0, 0, 0x02, 0, 0, 0, 0 };
108           UINT32 KeySizeOut;
109           BYTE *KeyDataOut;
110           UINT32 CertifyInfoSize;
111           BYTE *CertifyInfo;
112           UINT32 sigSize;
113           BYTE *sig;
114           UINT32 ephHandle;
115           TPM_CHANGEAUTH_VALIDATE caValidate;
116           TCPA_SECRET newSecret, oldSecret;
117           BYTE seed[20];
118           BYTE a1[256];
119           UINT32 a1Size;
120           TSS_KEY ephemeralKey;
121           TCPA_DIGEST newAuthLink;
122           UINT32 encObjectSize;
123           BYTE *encObject = NULL;
124           UINT32 encDataSizeOut;
125           BYTE *encDataOut;
126           TCPA_NONCE saltNonce;
127           TCPA_DIGEST changeProof;
128           TSS_HPOLICY hOldPolicy;
129           UINT32 caValidSize;
130           UINT32 keyObjectSize;
131           BYTE *keyObject;
132           TSS_KEY keyContainer;
133           TCPA_STORED_DATA dataContainer;
134           BYTE *dataObject;
135           UINT32 dataObjectSize;
136           UINT16 entityType;
137           TSS_BOOL useAuth = TRUE; // XXX
138           TPM_AUTH *pAuth;
139           BYTE dataBlob[1024];
140           TSS_HCONTEXT tspContext;
141           Trspi_HashCtx hashCtx;
142 
143           if ((result = obj_policy_get_tsp_context(hNewPolicy, &tspContext)))
144                     return result;
145 
146           /*  grab all of the needed handles */
147           if ((result = obj_rsakey_get_tcs_handle(hIdentKey, &idHandle)))
148                     return result;
149 
150           /*  get the secret for the parent */
151           if ((result = obj_rsakey_get_policy(hIdentKey, TSS_POLICY_USAGE, &hPolicy, &useAuth)))
152                     return result;
153 
154           /*  get the parent secret */
155           if ((result = Tspi_GetPolicyObject(hParentObject, TSS_POLICY_USAGE, &hParentPolicy)))
156                     return result;
157 
158           if (!obj_is_rsakey(hParentObject) && !obj_is_tpm(hParentObject))
159                     return TSPERR(TSS_E_INVALID_HANDLE);
160 
161           /*  get the keyObject  */
162           if ((result = obj_rsakey_get_tcs_handle(hParentObject, &keyHandle)))
163                     return result;
164 
165           if (obj_is_rsakey(hObjectToChange) ||
166               obj_is_encdata(hObjectToChange)) {
167 
168                     if ((result = obj_rsakey_get_tcs_handle(hObjectToChange, &keyToChangeHandle)))
169                               return result;
170 
171                     if (keyToChangeHandle == TPM_KEYHND_SRK) {
172                               return TSPERR(TSS_E_BAD_PARAMETER);
173                     } else {
174                               /*  generate container for ephemeral key */
175                               keyParms.algorithmID = 1;     /* rsa */
176                               keyParms.encScheme = 3;
177                               keyParms.sigScheme = 1;
178                               keyParms.parmSize = 12;
179                               keyParms.parms = malloc(12);
180                               if (keyParms.parms == NULL) {
181                                         LogError("malloc of %d bytes failed.", 12);
182                                         return TSPERR(TSS_E_OUTOFMEMORY);
183                               }
184                               memcpy(keyParms.parms, ephParms, 12);
185 
186                               tempSize = 0;
187                               Trspi_LoadBlob_KEY_PARMS(&tempSize, tempKey, &keyParms);
188 
189                               /*  generate antireplay nonce */
190                               bytesRequested = 20;
191                               if ((result = get_local_random(tspContext, FALSE, bytesRequested,
192                                                                    (BYTE **)antiReplay.nonce)))
193                                         return result;
194 
195                               /* caluculate auth data */
196                               result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
197                               result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_ChangeAuthAsymStart);
198                               result |= Trspi_HashUpdate(&hashCtx, TCPA_SHA1_160_HASH_LEN,
199                                                                antiReplay.nonce);
200                               result |= Trspi_Hash_KEY_PARMS(&hashCtx, &keyParms);
201                               if ((result |= Trspi_HashFinal(&hashCtx, digest.digest)))
202                                         return result;
203 
204                               if (useAuth) {
205                                         if ((result = secret_PerformAuth_OIAP(hIdentKey,
206                                                                                       TPM_ORD_ChangeAuthAsymStart,
207                                                                                       hPolicy, FALSE, &digest,
208                                                                                       &auth)))
209                                                   return result;
210 
211                                         pAuth = &auth;
212                               } else {
213                                         pAuth = NULL;
214                               }
215 
216                               if ((result = TCSP_ChangeAuthAsymStart(tspContext, idHandle, antiReplay,
217                                                                              tempSize, tempKey, pAuth,
218                                                                              &KeySizeOut, &KeyDataOut,
219                                                                              &CertifyInfoSize, &CertifyInfo,
220                                                                              &sigSize, &sig, &ephHandle)))
221                                         return result;
222 
223                               /* Validate the Auth's */
224                               result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
225                               result |= Trspi_Hash_UINT32(&hashCtx, result);
226                               result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_ChangeAuthAsymStart);
227                               result |= Trspi_HashUpdate(&hashCtx, CertifyInfoSize, CertifyInfo);
228                               result |= Trspi_Hash_UINT32(&hashCtx, sigSize);
229                               result |= Trspi_HashUpdate(&hashCtx, sigSize, sig);
230                               result |= Trspi_Hash_UINT32(&hashCtx, ephHandle);
231                               result |= Trspi_HashUpdate(&hashCtx, KeySizeOut, KeyDataOut);
232                               if ((result |= Trspi_HashFinal(&hashCtx, digest.digest)))
233                                         return result;
234 
235                               if (useAuth) {
236                                         if ((result = obj_policy_validate_auth_oiap(hPolicy, &digest,
237                                                                                               &auth)))
238                                                   return result;
239                               }
240 
241                               /*  generate random data for asymfinish */
242                               if ((result = get_local_random(tspContext, FALSE, bytesRequested,
243                                                                    (BYTE **)&caValidate.n1.nonce)))
244                                         return result;
245 
246                               if ((result = get_local_random(tspContext, FALSE, bytesRequested,
247                                                                    (BYTE **)&antiReplay.nonce)))
248                                         return result;
249 
250                               if ((result = get_local_random(tspContext, FALSE, bytesRequested,
251                                                                    (BYTE **)&seed)))
252                                         return result;
253 
254                               if ((result = Tspi_GetPolicyObject(hObjectToChange, TSS_POLICY_USAGE,
255                                                                         &hOldPolicy)))
256                                         return result;
257 
258                               if ((result = obj_policy_get_secret(hNewPolicy, TR_SECRET_CTX_NEW,
259                                                                           &newSecret)))
260                                         return result;
261                               if ((result = obj_policy_get_secret(hOldPolicy, TR_SECRET_CTX_NOT_NEW,
262                                                                           &oldSecret)))
263                                         return result;
264 
265                               /* Encrypt the ChangeAuthValidate structure with the
266                                * ephemeral key */
267 
268                               memcpy(caValidate.newAuthSecret.authdata, newSecret.authdata, 20);
269 
270                               offset = 0;
271                               Trspi_LoadBlob_CHANGEAUTH_VALIDATE(&offset, hashBlob, &caValidate);
272                               caValidSize = offset;
273 
274                               offset = 0;
275                               if ((result = UnloadBlob_TSS_KEY(&offset, KeyDataOut, &ephemeralKey)))
276                                         return result;
277 
278                               Trspi_RSA_Encrypt(hashBlob, caValidSize, a1, &a1Size,
279                                                ephemeralKey.pubKey.key,
280                                                ephemeralKey.pubKey.keyLength);
281 
282                               free_key_refs(&ephemeralKey);
283 
284                               Trspi_HMAC(TSS_HASH_SHA1, 20, oldSecret.authdata,
285                                                    20, newSecret.authdata,
286                                                    newAuthLink.digest);
287 
288                               if (obj_is_rsakey(hObjectToChange)) {
289                                         if ((result = obj_rsakey_get_blob(hObjectToChange,
290                                                                &keyObjectSize, &keyObject)))
291                                                   return result;
292 
293                                         __tspi_memset(&keyContainer, 0, sizeof(TSS_KEY));
294 
295                                         offset = 0;
296                                         if ((result = UnloadBlob_TSS_KEY(&offset,
297                                                                                  keyObject,
298                                                                                  &keyContainer)))
299                                                   return result;
300 
301                                         encObjectSize = keyContainer.encSize;
302                                         encObject = malloc(encObjectSize);
303                                         if (encObject == NULL) {
304                                                   LogError("malloc of %d bytes failed.",
305                                                                       encObjectSize);
306                                                   free_key_refs(&keyContainer);
307                                                   return TSPERR(TSS_E_OUTOFMEMORY);
308                                         }
309                                         memcpy(encObject, keyContainer.encData,
310                                                             encObjectSize);
311                                         entityType = TCPA_ET_KEY;
312                               } else {
313                                         if ((result = obj_encdata_get_data(hObjectToChange,
314                                                                &dataObjectSize, &dataObject)))
315                                                   return result;
316 
317                                         offset = 0;
318                                         if ((result = Trspi_UnloadBlob_STORED_DATA(&offset,
319                                                                                              dataObject,
320                                                                                              &dataContainer)))
321                                                   return result;
322 
323                                         encObjectSize = dataContainer.encDataSize;
324                                         encObject = malloc(encObjectSize);
325                                         if (encObject == NULL) {
326                                                   LogError("malloc of %d bytes failed.", encObjectSize);
327                                                   free(dataContainer.sealInfo);
328                                                   free(dataContainer.encData);
329                                                   return TSPERR(TSS_E_OUTOFMEMORY);
330                                         }
331                                         memcpy(encObject, dataContainer.encData,
332                                                             encObjectSize);
333                                         entityType = TCPA_ET_DATA;
334                               }
335 
336                               result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
337                               result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_ChangeAuthAsymFinish);
338                               result |= Trspi_Hash_UINT16(&hashCtx, entityType);
339                               result |= Trspi_HashUpdate(&hashCtx, TCPA_SHA1_160_HASH_LEN,
340                                                                newAuthLink.digest);
341                               result |= Trspi_Hash_UINT32(&hashCtx, a1Size);
342                               result |= Trspi_HashUpdate(&hashCtx, a1Size, a1);
343                               result |= Trspi_Hash_UINT32(&hashCtx, encObjectSize);
344                               result |= Trspi_HashUpdate(&hashCtx, encObjectSize, encObject);
345                               if ((result |= Trspi_HashFinal(&hashCtx, digest.digest)))
346                                         return result;
347 
348                               if (useAuth) {
349                                         if ((result = secret_PerformAuth_OIAP(hParentObject,
350                                                                                       TPM_ORD_ChangeAuthAsymFinish,
351                                                                                       hParentPolicy, FALSE,
352                                                                                       &digest, &auth))) {
353                                                   free(encObject);
354                                                   free_key_refs(&keyContainer);
355                                                   return result;
356                                         }
357                                         pAuth = &auth;
358                               } else {
359                                         pAuth = NULL;
360                               }
361 
362                               if ((result = TCSP_ChangeAuthAsymFinish(tspContext, keyHandle, ephHandle,
363                                                                              entityType, newAuthLink, a1Size, a1,
364                                                                              encObjectSize, encObject, pAuth,
365                                                                              &encDataSizeOut, &encDataOut,
366                                                                              &saltNonce, &changeProof))) {
367                                         free_key_refs(&keyContainer);
368                                         free(encObject);
369                                         return result;
370                               }
371 
372                               /* ---  Validate the Auth's */
373                               result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
374                               result |= Trspi_Hash_UINT32(&hashCtx, result);
375                               result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_ChangeAuthAsymFinish);
376                               result |= Trspi_Hash_UINT32(&hashCtx, encDataSizeOut);
377                               result |= Trspi_HashUpdate(&hashCtx, encDataSizeOut, encDataOut);
378                               result |= Trspi_HashUpdate(&hashCtx, TCPA_SHA1_160_HASH_LEN,
379                                                                saltNonce.nonce);
380                               result |= Trspi_HashUpdate(&hashCtx, TCPA_SHA1_160_HASH_LEN,
381                                                                changeProof.digest);
382                               if ((result |= Trspi_HashFinal(&hashCtx, digest.digest)))
383                                         return result;
384 
385                               if (useAuth) {
386                                         if ((result = obj_policy_validate_auth_oiap(hParentPolicy,
387                                                                                           &digest,
388                                                                                           &auth))) {
389                                                   free_key_refs(&keyContainer);
390                                                   free(encObject);
391                                                   return result;
392                                         }
393                               }
394 
395                               if (entityType == TCPA_ET_KEY ||
396                                   entityType == TCPA_ET_KEYHANDLE) {
397                                         memcpy(keyContainer.encData, encDataOut, encDataSizeOut);
398                                         keyContainer.encSize = encDataSizeOut;
399 
400                                         offset = 0;
401                                         LoadBlob_TSS_KEY(&offset, keyObject, &keyContainer);
402                                         free_key_refs(&keyContainer);
403                                         if ((result = obj_rsakey_set_tcpakey(hObjectToChange, offset,
404                                                                                      keyObject))) {
405                                                   free(encObject);
406                                                   return result;
407                                         }
408                               }
409 
410                               if (entityType == TCPA_ET_DATA) {
411                                         memcpy(dataContainer.encData, encDataOut,
412                                                             encDataSizeOut);
413                                         dataContainer.encDataSize = encDataSizeOut;
414 
415                                         offset = 0;
416                                         Trspi_LoadBlob_STORED_DATA(&offset, dataBlob,
417                                                                          &dataContainer);
418                                         free(dataContainer.sealInfo);
419                                         free(dataContainer.encData);
420                                         obj_encdata_set_data(hObjectToChange,
421                                                                offset, dataBlob);
422                               }
423                     }
424           } else
425                     return TSPERR(TSS_E_BAD_PARAMETER);
426 
427           free(encObject);
428 
429           return Tspi_Policy_AssignToObject(hNewPolicy, hObjectToChange);
430 #else
431           return TSPERR(TSS_E_NOTIMPL);
432 #endif
433 }
434 
435