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 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 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 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 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 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 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 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 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