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. 2007 8 * 9 */ 10 11 12 #include <stdlib.h> 13 #include <stdio.h> 14 #include <string.h> 15 #include <inttypes.h> 16 17 #include "trousers/tss.h" 18 #include "trousers/trousers.h" 19 #include "trousers_types.h" 20 #include "spi_utils.h" 21 #include "obj.h" 22 #include "tsplog.h" 23 24 25 TSS_RESULT 26 Tspi_TPM_CMKSetRestrictions(TSS_HTPM hTpm, /* in */ 27 TSS_CMK_DELEGATE CmkDelegate) /* in */ 28 { 29 TSS_HCONTEXT hContext; 30 TSS_HPOLICY hPolicy; 31 Trspi_HashCtx hashCtx; 32 TPM_DIGEST digest; 33 TPM_AUTH ownerAuth; 34 TSS_RESULT result; 35 36 if ((result = obj_tpm_get_tsp_context(hTpm, &hContext))) 37 return result; 38 39 if ((result = obj_tpm_get_policy(hTpm, TSS_POLICY_USAGE, &hPolicy))) 40 return result; 41 42 result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); 43 result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_CMK_SetRestrictions); 44 result |= Trspi_Hash_UINT32(&hashCtx, CmkDelegate); 45 if ((result |= Trspi_HashFinal(&hashCtx, digest.digest))) 46 return result; 47 48 if ((result = secret_PerformAuth_OIAP(hTpm, TPM_ORD_CMK_SetRestrictions, 49 hPolicy, FALSE, &digest, &ownerAuth))) 50 return result; 51 52 if ((result = RPC_CMK_SetRestrictions(hContext, CmkDelegate, &ownerAuth))) 53 return result; 54 55 result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); 56 result |= Trspi_Hash_UINT32(&hashCtx, result); 57 result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_CMK_SetRestrictions); 58 if ((result |= Trspi_HashFinal(&hashCtx, digest.digest))) 59 return result; 60 61 if ((result = obj_policy_validate_auth_oiap(hPolicy, &digest, &ownerAuth))) 62 return result; 63 64 return result; 65 } 66 67 TSS_RESULT 68 Tspi_TPM_CMKApproveMA(TSS_HTPM hTpm, /* in */ 69 TSS_HMIGDATA hMaAuthData) /* in */ 70 { 71 TSS_HCONTEXT hContext; 72 TSS_HPOLICY hPolicy; 73 UINT32 blobSize; 74 BYTE *blob; 75 TPM_DIGEST msaDigest; 76 TPM_HMAC msaHmac; 77 Trspi_HashCtx hashCtx; 78 TPM_DIGEST digest; 79 TPM_AUTH ownerAuth; 80 TSS_RESULT result; 81 82 if ((result = obj_tpm_get_tsp_context(hTpm, &hContext))) 83 return result; 84 85 if ((result = obj_tpm_get_policy(hTpm, TSS_POLICY_USAGE, &hPolicy))) 86 return result; 87 88 if ((result = obj_migdata_get_msa_digest(hMaAuthData, &blobSize, &blob))) 89 return result; 90 memcpy(msaDigest.digest, blob, sizeof(msaDigest.digest)); 91 free_tspi(hContext, blob); 92 93 result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); 94 result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_CMK_ApproveMA); 95 result |= Trspi_Hash_DIGEST(&hashCtx, msaDigest.digest); 96 if ((result |= Trspi_HashFinal(&hashCtx, digest.digest))) 97 return result; 98 99 if ((result = secret_PerformAuth_OIAP(hTpm, TPM_ORD_CMK_ApproveMA, 100 hPolicy, FALSE, &digest, &ownerAuth))) 101 return result; 102 103 if ((result = RPC_CMK_ApproveMA(hContext, msaDigest, &ownerAuth, &msaHmac))) 104 return result; 105 106 result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); 107 result |= Trspi_Hash_UINT32(&hashCtx, result); 108 result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_CMK_ApproveMA); 109 result |= Trspi_Hash_HMAC(&hashCtx, msaHmac.digest); 110 if ((result |= Trspi_HashFinal(&hashCtx, digest.digest))) 111 return result; 112 113 if ((result = obj_policy_validate_auth_oiap(hPolicy, &digest, &ownerAuth))) 114 return result; 115 116 if ((result = obj_migdata_set_msa_hmac(hMaAuthData, sizeof(msaHmac.digest), msaHmac.digest))) 117 return result; 118 119 return result; 120 } 121 122 TSS_RESULT 123 Tspi_TPM_CMKCreateTicket(TSS_HTPM hTpm, /* in */ 124 TSS_HKEY hVerifyKey, /* in */ 125 TSS_HMIGDATA hSigData) /* in */ 126 { 127 TSS_HCONTEXT hContext; 128 TSS_HPOLICY hPolicy; 129 UINT32 pubKeySize; 130 BYTE *pubKey = NULL; 131 UINT32 blobSize; 132 BYTE *blob; 133 TPM_DIGEST sigData; 134 UINT32 sigSize; 135 BYTE *sig = NULL; 136 TPM_HMAC sigTicket; 137 Trspi_HashCtx hashCtx; 138 TPM_DIGEST digest; 139 TPM_AUTH ownerAuth; 140 TSS_RESULT result; 141 142 if ((result = obj_tpm_get_tsp_context(hTpm, &hContext))) 143 return result; 144 145 if ((result = obj_tpm_get_policy(hTpm, TSS_POLICY_USAGE, &hPolicy))) 146 return result; 147 148 if ((result = obj_rsakey_get_pub_blob(hVerifyKey, &pubKeySize, &pubKey))) 149 return result; 150 151 if ((result = obj_migdata_get_sig_data(hSigData, &blobSize, &blob))) 152 goto done; 153 memcpy(sigData.digest, blob, sizeof(sigData.digest)); 154 free_tspi(hContext, blob); 155 156 if ((result = obj_migdata_get_sig_value(hSigData, &sigSize, &sig))) 157 goto done; 158 159 result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); 160 result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_CMK_CreateTicket); 161 result |= Trspi_HashUpdate(&hashCtx, pubKeySize, pubKey); 162 result |= Trspi_Hash_DIGEST(&hashCtx, sigData.digest); 163 result |= Trspi_Hash_UINT32(&hashCtx, sigSize); 164 result |= Trspi_HashUpdate(&hashCtx, sigSize, sig); 165 if ((result |= Trspi_HashFinal(&hashCtx, digest.digest))) 166 goto done; 167 168 if ((result = secret_PerformAuth_OIAP(hTpm, TPM_ORD_CMK_CreateTicket, 169 hPolicy, FALSE, &digest, &ownerAuth))) 170 goto done; 171 172 if ((result = RPC_CMK_CreateTicket(hContext, pubKeySize, pubKey, sigData, sigSize, sig, 173 &ownerAuth, &sigTicket))) 174 goto done; 175 176 result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); 177 result |= Trspi_Hash_UINT32(&hashCtx, result); 178 result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_CMK_CreateTicket); 179 result |= Trspi_Hash_HMAC(&hashCtx, sigTicket.digest); 180 if ((result |= Trspi_HashFinal(&hashCtx, digest.digest))) 181 goto done; 182 183 if ((result = obj_policy_validate_auth_oiap(hPolicy, &digest, &ownerAuth))) 184 goto done; 185 186 if ((result = obj_migdata_set_sig_ticket(hSigData, sizeof(sigTicket.digest), sigTicket.digest))) 187 goto done; 188 189 done: 190 free_tspi(hContext, pubKey); 191 free_tspi(hContext, sig); 192 193 return result; 194 } 195 196 TSS_RESULT 197 Tspi_Key_CMKCreateBlob(TSS_HKEY hKeyToMigrate, /* in */ 198 TSS_HKEY hParentKey, /* in */ 199 TSS_HMIGDATA hMigrationData, /* in */ 200 UINT32* pulRandomLength, /* out */ 201 BYTE** prgbRandom) /* out */ 202 { 203 TSS_HCONTEXT hContext; 204 TSS_HPOLICY hPolicy; 205 TSS_BOOL usageAuth; 206 TCS_KEY_HANDLE tcsKeyHandle; 207 TSS_MIGRATE_SCHEME migScheme; 208 UINT32 migTicketSize; 209 BYTE *migTicket = NULL; 210 TPM_MIGRATIONKEYAUTH tpmMigKeyAuth; 211 UINT32 msaListSize, restrictTicketSize, sigTicketSize, blobSize; 212 BYTE *msaList = NULL, *restrictTicket = NULL, *blob = NULL; 213 BYTE *sigTicket = NULL; 214 UINT32 pubBlobSize; 215 BYTE *pubBlob = NULL; 216 TPM_DIGEST srcPubKeyDigest; 217 TSS_KEY tssKey; 218 UINT32 randomDataSize, outDataSize, newBlobSize; 219 BYTE *randomData = NULL, *outData = NULL, *newBlob = NULL; 220 Trspi_HashCtx hashCtx; 221 TPM_DIGEST digest; 222 TPM_AUTH parentAuth, *pAuth; 223 UINT64 offset; 224 TSS_RESULT result; 225 226 __tspi_memset(&tssKey, 0, sizeof(tssKey)); 227 228 if (!pulRandomLength || !prgbRandom) 229 return TSPERR(TSS_E_BAD_PARAMETER); 230 231 if (!obj_rsakey_is_cmk(hKeyToMigrate)) 232 return TSPERR(TSS_E_BAD_PARAMETER); 233 234 if ((result = obj_rsakey_get_tsp_context(hKeyToMigrate, &hContext))) 235 return result; 236 237 if ((result = obj_rsakey_get_policy(hParentKey, TSS_POLICY_USAGE, &hPolicy, &usageAuth))) 238 return result; 239 240 if ((result = obj_rsakey_get_tcs_handle(hParentKey, &tcsKeyHandle))) 241 return result; 242 243 if ((result = obj_migdata_get_ticket_blob(hMigrationData, &migTicketSize, &migTicket))) 244 return result; 245 246 /* Just to get the migration scheme... */ 247 offset = 0; 248 if ((result = Trspi_UnloadBlob_MIGRATIONKEYAUTH(&offset, migTicket, &tpmMigKeyAuth))) 249 goto done; 250 /* ... so free everything now */ 251 free(tpmMigKeyAuth.migrationKey.algorithmParms.parms); 252 free(tpmMigKeyAuth.migrationKey.pubKey.key); 253 migScheme = tpmMigKeyAuth.migrationScheme; 254 255 if ((result = obj_rsakey_get_pub_blob(hKeyToMigrate, &pubBlobSize, &pubBlob))) 256 goto done; 257 if ((result = obj_migdata_calc_pubkey_digest(pubBlobSize, pubBlob, &srcPubKeyDigest))) 258 goto done; 259 260 if ((result = obj_migdata_get_msa_list_blob(hMigrationData, &msaListSize, &msaList))) 261 goto done; 262 263 if (tpmMigKeyAuth.migrationScheme == TPM_MS_RESTRICT_APPROVE_DOUBLE) { 264 if ((result = obj_migdata_get_cmk_auth_blob(hMigrationData, &restrictTicketSize, 265 &restrictTicket))) 266 goto done; 267 if ((result = obj_migdata_get_sig_ticket(hMigrationData, &sigTicketSize, 268 &sigTicket))) 269 goto done; 270 } else { 271 restrictTicketSize = 0; 272 sigTicketSize = 0; 273 } 274 275 if ((result = obj_rsakey_get_blob(hKeyToMigrate, &blobSize, &blob))) 276 goto done; 277 278 offset = 0; 279 if ((result = UnloadBlob_TSS_KEY(&offset, blob, &tssKey))) 280 goto done; 281 282 if (usageAuth) { 283 pAuth = &parentAuth; 284 285 result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); 286 result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_CMK_CreateBlob); 287 result |= Trspi_Hash_UINT16(&hashCtx, migScheme); 288 result |= Trspi_HashUpdate(&hashCtx, migTicketSize, migTicket); 289 result |= Trspi_Hash_DIGEST(&hashCtx, srcPubKeyDigest.digest); 290 result |= Trspi_Hash_UINT32(&hashCtx, msaListSize); 291 result |= Trspi_HashUpdate(&hashCtx, msaListSize, msaList); 292 result |= Trspi_Hash_UINT32(&hashCtx, restrictTicketSize); 293 result |= Trspi_HashUpdate(&hashCtx, restrictTicketSize, restrictTicket); 294 result |= Trspi_Hash_UINT32(&hashCtx, sigTicketSize); 295 result |= Trspi_HashUpdate(&hashCtx, sigTicketSize, sigTicket); 296 result |= Trspi_Hash_UINT32(&hashCtx, tssKey.encSize); 297 result |= Trspi_HashUpdate(&hashCtx, tssKey.encSize, tssKey.encData); 298 if ((result |= Trspi_HashFinal(&hashCtx, digest.digest))) 299 goto done; 300 301 if ((result = secret_PerformAuth_OIAP(hParentKey, TPM_ORD_CMK_CreateBlob, 302 hPolicy, FALSE, &digest, pAuth))) 303 goto done; 304 } else 305 pAuth = NULL; 306 307 if ((result = RPC_CMK_CreateBlob(hContext, tcsKeyHandle, migScheme, 308 migTicketSize, migTicket, srcPubKeyDigest, msaListSize, msaList, 309 restrictTicketSize, restrictTicket, sigTicketSize, sigTicket, 310 tssKey.encSize, tssKey.encData, pAuth, &randomDataSize, &randomData, 311 &outDataSize, &outData))) 312 goto done; 313 314 if (pAuth) { 315 result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); 316 result |= Trspi_Hash_UINT32(&hashCtx, result); 317 result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_CMK_CreateBlob); 318 result |= Trspi_Hash_UINT32(&hashCtx, randomDataSize); 319 result |= Trspi_HashUpdate(&hashCtx, randomDataSize, randomData); 320 result |= Trspi_Hash_UINT32(&hashCtx, outDataSize); 321 result |= Trspi_HashUpdate(&hashCtx, outDataSize, outData); 322 if ((result |= Trspi_HashFinal(&hashCtx, digest.digest))) 323 goto done; 324 } 325 326 if ((result = obj_policy_validate_auth_oiap(hPolicy, &digest, pAuth))) 327 goto done; 328 329 /* Create the migdata key blob */ 330 free(tssKey.encData); 331 tssKey.encSize = outDataSize; 332 tssKey.encData = outData; 333 /* Set outData to null since it will now be freed during key ref freeing */ 334 outData = NULL; 335 336 offset = 0; 337 LoadBlob_TSS_KEY(&offset, NULL, &tssKey); 338 339 newBlobSize = offset; 340 if ((newBlob = malloc(newBlobSize)) == NULL) { 341 LogError("malloc of %u bytes failed.", newBlobSize); 342 result = TSPERR(TSS_E_OUTOFMEMORY); 343 goto done; 344 } 345 offset = 0; 346 LoadBlob_TSS_KEY(&offset, newBlob, &tssKey); 347 348 if ((result = obj_migdata_set_blob(hMigrationData, newBlobSize, newBlob))) 349 goto done; 350 351 if ((*prgbRandom = calloc_tspi(hContext, randomDataSize)) == NULL) { 352 LogError("malloc of %u bytes failed.", randomDataSize); 353 result = TSPERR(TSS_E_OUTOFMEMORY); 354 goto done; 355 } 356 memcpy(*prgbRandom, randomData, randomDataSize); 357 *pulRandomLength = randomDataSize; 358 359 done: 360 free_tspi(hContext, migTicket); 361 free_tspi(hContext, pubBlob); 362 free_tspi(hContext, msaList); 363 free_tspi(hContext, restrictTicket); 364 free_tspi(hContext, sigTicket); 365 free_tspi(hContext, blob); 366 free(randomData); 367 free(outData); 368 free(newBlob); 369 free_key_refs(&tssKey); 370 371 return result; 372 } 373 374 TSS_RESULT 375 Tspi_Key_CMKConvertMigration(TSS_HKEY hKeyToMigrate, /* in */ 376 TSS_HKEY hParentKey, /* in */ 377 TSS_HMIGDATA hMigrationData, /* in */ 378 UINT32 ulRandomLength, /* in */ 379 BYTE* rgbRandom) /* in */ 380 { 381 TSS_HCONTEXT hContext; 382 TSS_HPOLICY hPolicy; 383 TSS_BOOL usageAuth; 384 TCS_KEY_HANDLE tcsKeyHandle; 385 TPM_CMK_AUTH restrictTicket; 386 UINT32 blobSize; 387 BYTE *blob; 388 TPM_HMAC sigTicket; 389 UINT32 migDataSize, msaListSize; 390 BYTE *migData = NULL, *msaList = NULL; 391 UINT32 outDataSize; 392 BYTE *outData = NULL; 393 Trspi_HashCtx hashCtx; 394 TPM_DIGEST digest; 395 TPM_AUTH parentAuth, *pAuth; 396 TSS_RESULT result; 397 398 if ((result = obj_rsakey_get_tsp_context(hKeyToMigrate, &hContext))) 399 return result; 400 401 if ((result = obj_rsakey_get_policy(hParentKey, TSS_POLICY_USAGE, &hPolicy, &usageAuth))) 402 return result; 403 404 if ((result = obj_rsakey_get_tcs_handle(hParentKey, &tcsKeyHandle))) 405 return result; 406 407 if ((result = obj_migdata_get_cmk_auth(hMigrationData, &restrictTicket))) 408 return result; 409 410 if ((result = obj_migdata_get_sig_ticket(hMigrationData, &blobSize, &blob))) 411 return result; 412 memcpy(sigTicket.digest, blob, sizeof(sigTicket.digest)); 413 free_tspi(hContext, blob); 414 415 if ((result = obj_migdata_get_blob(hMigrationData, &migDataSize, &migData))) 416 goto done; 417 418 if ((result = obj_migdata_get_msa_list_blob(hMigrationData, &msaListSize, &msaList))) 419 goto done; 420 421 if (usageAuth) { 422 pAuth = &parentAuth; 423 424 result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); 425 result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_CMK_ConvertMigration); 426 result |= Trspi_HashUpdate(&hashCtx, sizeof(restrictTicket), 427 (BYTE *)&restrictTicket); 428 result |= Trspi_Hash_HMAC(&hashCtx, sigTicket.digest); 429 result |= Trspi_HashUpdate(&hashCtx, migDataSize, migData); 430 result |= Trspi_Hash_UINT32(&hashCtx, msaListSize); 431 result |= Trspi_HashUpdate(&hashCtx, msaListSize, msaList); 432 result |= Trspi_Hash_UINT32(&hashCtx, ulRandomLength); 433 result |= Trspi_HashUpdate(&hashCtx, ulRandomLength, rgbRandom); 434 if ((result |= Trspi_HashFinal(&hashCtx, digest.digest))) 435 goto done; 436 437 if ((result = secret_PerformAuth_OIAP(hParentKey, TPM_ORD_CMK_ConvertMigration, 438 hPolicy, FALSE, &digest, pAuth))) 439 goto done; 440 } else 441 pAuth = NULL; 442 443 if ((result = RPC_CMK_ConvertMigration(hContext, tcsKeyHandle, restrictTicket, sigTicket, 444 migDataSize, migData, msaListSize, msaList, ulRandomLength, rgbRandom, 445 pAuth, &outDataSize, &outData))) 446 goto done; 447 448 if (pAuth) { 449 result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); 450 result |= Trspi_Hash_UINT32(&hashCtx, result); 451 result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_CMK_ConvertMigration); 452 result |= Trspi_Hash_UINT32(&hashCtx, outDataSize); 453 result |= Trspi_HashUpdate(&hashCtx, outDataSize, outData); 454 if ((result |= Trspi_HashFinal(&hashCtx, digest.digest))) 455 goto done; 456 } 457 458 if ((result = obj_policy_validate_auth_oiap(hPolicy, &digest, pAuth))) 459 goto done; 460 461 /* Set the key object to the now migrated key */ 462 if ((result = obj_rsakey_set_tcpakey(hKeyToMigrate, migDataSize, migData))) 463 goto done; 464 if ((result = obj_rsakey_set_privkey(hKeyToMigrate, TRUE, outDataSize, outData))) 465 goto done; 466 result = obj_rsakey_set_tcs_handle(hKeyToMigrate, 0); 467 468 done: 469 free_tspi(hContext, migData); 470 free_tspi(hContext, msaList); 471 free(outData); 472 473 return result; 474 } 475 476