3
* Licensed Materials - Property of IBM
5
* trousers - An open source TCG Software Stack
7
* (C) Copyright International Business Machines Corp. 2004-2006
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"
29
Tspi_ChangeAuth(TSS_HOBJECT hObjectToChange, /* in */
30
TSS_HOBJECT hParentObject, /* in */
31
TSS_HPOLICY hNewPolicy) /* in */
33
UINT32 keyToChangeHandle;
35
TSS_HCONTEXT tspContext;
37
if ((result = obj_policy_get_tsp_context(hNewPolicy, &tspContext)))
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);
50
if (obj_is_tpm(hObjectToChange)) {
51
if ((result = changeauth_owner(tspContext, hObjectToChange, NULL_HTPM, hNewPolicy)))
53
} else if (obj_is_rsakey(hObjectToChange)) {
54
if ((result = obj_rsakey_get_tcs_handle(hObjectToChange, &keyToChangeHandle)))
57
if (keyToChangeHandle == TPM_KEYHND_SRK) {
58
if ((result = changeauth_srk(tspContext, hObjectToChange, hParentObject,
62
if ((result = changeauth_key(tspContext, hObjectToChange, hParentObject,
66
} else if (obj_is_encdata(hObjectToChange)) {
67
if ((result = changeauth_encdata(tspContext, hObjectToChange, hParentObject,
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);
74
return TSPERR(TSS_E_INVALID_HANDLE);
77
if ((result = obj_policy_set_type(hNewPolicy, TSS_POLICY_USAGE)))
80
return Tspi_Policy_AssignToObject(hNewPolicy, hObjectToChange);
85
Tspi_ChangeAuthAsym(TSS_HOBJECT hObjectToChange, /* in */
86
TSS_HOBJECT hParentObject, /* in */
87
TSS_HKEY hIdentKey, /* in */
88
TSS_HPOLICY hNewPolicy) /* in */
93
BYTE hashBlob[0x1000];
99
TSS_HPOLICY hParentPolicy;
100
UINT32 keyToChangeHandle;
101
TCPA_NONCE antiReplay;
102
UINT32 bytesRequested;
105
TCPA_KEY_PARMS keyParms;
107
BYTE ephParms[] = { 0, 0, 0x08, 0, 0, 0, 0, 0x02, 0, 0, 0, 0 };
110
UINT32 CertifyInfoSize;
115
TPM_CHANGEAUTH_VALIDATE caValidate;
116
TCPA_SECRET newSecret, oldSecret;
120
TSS_KEY ephemeralKey;
121
TCPA_DIGEST newAuthLink;
122
UINT32 encObjectSize;
123
BYTE *encObject = NULL;
124
UINT32 encDataSizeOut;
126
TCPA_NONCE saltNonce;
127
TCPA_DIGEST changeProof;
128
TSS_HPOLICY hOldPolicy;
130
UINT32 keyObjectSize;
132
TSS_KEY keyContainer;
133
TCPA_STORED_DATA dataContainer;
135
UINT32 dataObjectSize;
137
TSS_BOOL useAuth = TRUE; // XXX
140
TSS_HCONTEXT tspContext;
141
Trspi_HashCtx hashCtx;
143
if ((result = obj_policy_get_tsp_context(hNewPolicy, &tspContext)))
146
/* grab all of the needed handles */
147
if ((result = obj_rsakey_get_tcs_handle(hIdentKey, &idHandle)))
150
/* get the secret for the parent */
151
if ((result = obj_rsakey_get_policy(hIdentKey, TSS_POLICY_USAGE, &hPolicy, &useAuth)))
154
/* get the parent secret */
155
if ((result = Tspi_GetPolicyObject(hParentObject, TSS_POLICY_USAGE, &hParentPolicy)))
158
if (!obj_is_rsakey(hParentObject) && !obj_is_tpm(hParentObject))
159
return TSPERR(TSS_E_INVALID_HANDLE);
161
/* get the keyObject */
162
if ((result = obj_rsakey_get_tcs_handle(hParentObject, &keyHandle)))
165
if (obj_is_rsakey(hObjectToChange) ||
166
obj_is_encdata(hObjectToChange)) {
168
if ((result = obj_rsakey_get_tcs_handle(hObjectToChange, &keyToChangeHandle)))
171
if (keyToChangeHandle == TPM_KEYHND_SRK) {
172
return TSPERR(TSS_E_BAD_PARAMETER);
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);
184
memcpy(keyParms.parms, ephParms, 12);
187
Trspi_LoadBlob_KEY_PARMS(&tempSize, tempKey, &keyParms);
189
/* generate antireplay nonce */
191
if ((result = get_local_random(tspContext, FALSE, bytesRequested,
192
(BYTE **)antiReplay.nonce)))
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,
200
result |= Trspi_Hash_KEY_PARMS(&hashCtx, &keyParms);
201
if ((result |= Trspi_HashFinal(&hashCtx, digest.digest)))
205
if ((result = secret_PerformAuth_OIAP(hIdentKey,
206
TPM_ORD_ChangeAuthAsymStart,
207
hPolicy, FALSE, &digest,
216
if ((result = TCSP_ChangeAuthAsymStart(tspContext, idHandle, antiReplay,
217
tempSize, tempKey, pAuth,
218
&KeySizeOut, &KeyDataOut,
219
&CertifyInfoSize, &CertifyInfo,
220
&sigSize, &sig, &ephHandle)))
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)))
236
if ((result = obj_policy_validate_auth_oiap(hPolicy, &digest,
241
/* generate random data for asymfinish */
242
if ((result = get_local_random(tspContext, FALSE, bytesRequested,
243
(BYTE **)&caValidate.n1.nonce)))
246
if ((result = get_local_random(tspContext, FALSE, bytesRequested,
247
(BYTE **)&antiReplay.nonce)))
250
if ((result = get_local_random(tspContext, FALSE, bytesRequested,
254
if ((result = Tspi_GetPolicyObject(hObjectToChange, TSS_POLICY_USAGE,
258
if ((result = obj_policy_get_secret(hNewPolicy, TR_SECRET_CTX_NEW,
261
if ((result = obj_policy_get_secret(hOldPolicy, TR_SECRET_CTX_NOT_NEW,
265
/* Encrypt the ChangeAuthValidate structure with the
268
memcpy(caValidate.newAuthSecret.authdata, newSecret.authdata, 20);
271
Trspi_LoadBlob_CHANGEAUTH_VALIDATE(&offset, hashBlob, &caValidate);
272
caValidSize = offset;
275
if ((result = UnloadBlob_TSS_KEY(&offset, KeyDataOut, &ephemeralKey)))
278
Trspi_RSA_Encrypt(hashBlob, caValidSize, a1, &a1Size,
279
ephemeralKey.pubKey.key,
280
ephemeralKey.pubKey.keyLength);
282
free_key_refs(&ephemeralKey);
284
Trspi_HMAC(TSS_HASH_SHA1, 20, oldSecret.authdata,
285
20, newSecret.authdata,
288
if (obj_is_rsakey(hObjectToChange)) {
289
if ((result = obj_rsakey_get_blob(hObjectToChange,
290
&keyObjectSize, &keyObject)))
293
memset(&keyContainer, 0, sizeof(TSS_KEY));
296
if ((result = UnloadBlob_TSS_KEY(&offset,
301
encObjectSize = keyContainer.encSize;
302
encObject = malloc(encObjectSize);
303
if (encObject == NULL) {
304
LogError("malloc of %d bytes failed.",
306
free_key_refs(&keyContainer);
307
return TSPERR(TSS_E_OUTOFMEMORY);
309
memcpy(encObject, keyContainer.encData,
311
entityType = TCPA_ET_KEY;
313
if ((result = obj_encdata_get_data(hObjectToChange,
314
&dataObjectSize, &dataObject)))
318
if ((result = Trspi_UnloadBlob_STORED_DATA(&offset,
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);
331
memcpy(encObject, dataContainer.encData,
333
entityType = TCPA_ET_DATA;
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,
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)))
349
if ((result = secret_PerformAuth_OIAP(hParentObject,
350
TPM_ORD_ChangeAuthAsymFinish,
351
hParentPolicy, FALSE,
354
free_key_refs(&keyContainer);
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);
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,
380
result |= Trspi_HashUpdate(&hashCtx, TCPA_SHA1_160_HASH_LEN,
382
if ((result |= Trspi_HashFinal(&hashCtx, digest.digest)))
386
if ((result = obj_policy_validate_auth_oiap(hParentPolicy,
389
free_key_refs(&keyContainer);
395
if (entityType == TCPA_ET_KEY ||
396
entityType == TCPA_ET_KEYHANDLE) {
397
memcpy(keyContainer.encData, encDataOut, encDataSizeOut);
398
keyContainer.encSize = encDataSizeOut;
401
LoadBlob_TSS_KEY(&offset, keyObject, &keyContainer);
402
free_key_refs(&keyContainer);
403
if ((result = obj_rsakey_set_tcpakey(hObjectToChange, offset,
410
if (entityType == TCPA_ET_DATA) {
411
memcpy(dataContainer.encData, encDataOut,
413
dataContainer.encDataSize = encDataSizeOut;
416
Trspi_LoadBlob_STORED_DATA(&offset, dataBlob,
418
free(dataContainer.sealInfo);
419
free(dataContainer.encData);
420
obj_encdata_set_data(hObjectToChange,
425
return TSPERR(TSS_E_BAD_PARAMETER);
429
return Tspi_Policy_AssignToObject(hNewPolicy, hObjectToChange);
431
return TSPERR(TSS_E_NOTIMPL);