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