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 28TSS_RESULT 29Tspi_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 84TSS_RESULT 85Tspi_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