Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2009-2010 The Chromium OS Authors. All rights reserved. | 1 // Copyright (c) 2009-2010 The Chromium OS Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 // Contains the implementation of class Tpm | 5 // Contains the implementation of class Tpm |
| 6 | 6 |
| 7 #include "tpm.h" | 7 #include "tpm.h" |
| 8 | 8 |
| 9 #include <base/file_util.h> | 9 #include <base/file_util.h> |
| 10 #include <base/platform_thread.h> | 10 #include <base/platform_thread.h> |
| 11 #include <base/time.h> | 11 #include <base/time.h> |
| 12 #include <openssl/rsa.h> | 12 #include <openssl/rsa.h> |
| 13 #include <stdio.h> | 13 #include <stdio.h> |
| 14 #include <stdlib.h> | 14 #include <stdlib.h> |
| 15 #include <sys/stat.h> | 15 #include <sys/stat.h> |
| 16 #include <trousers/tss.h> | 16 #include <trousers/tss.h> |
| 17 #include <trousers/trousers.h> | 17 #include <trousers/trousers.h> |
| 18 | 18 |
| 19 #include "crypto.h" | 19 #include "crypto.h" |
| 20 #include "mount.h" | 20 #include "mount.h" |
| 21 #include "platform.h" | 21 #include "platform.h" |
| 22 #include "scoped_tss_type.h" | |
| 22 | 23 |
| 23 namespace cryptohome { | 24 namespace cryptohome { |
| 24 | 25 |
| 25 #define TPM_LOG(severity, result) \ | 26 #define TPM_LOG(severity, result) \ |
| 26 LOG(severity) << "TPM error 0x" << std::hex << result \ | 27 LOG(severity) << "TPM error 0x" << std::hex << result \ |
| 27 << " (" << Trspi_Error_String(result) << "): " | 28 << " (" << Trspi_Error_String(result) << "): " |
| 28 | 29 |
| 29 const unsigned char kDefaultSrkAuth[] = { }; | 30 const unsigned char kDefaultSrkAuth[] = { }; |
| 30 const unsigned int kDefaultTpmRsaKeyBits = 2048; | 31 const unsigned int kDefaultTpmRsaKeyBits = 2048; |
| 31 const unsigned int kDefaultDiscardableWrapPasswordLength = 32; | 32 const unsigned int kDefaultDiscardableWrapPasswordLength = 32; |
| (...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 206 void Tpm::DisconnectContext(TSS_HCONTEXT context_handle) { | 207 void Tpm::DisconnectContext(TSS_HCONTEXT context_handle) { |
| 207 if (context_handle) { | 208 if (context_handle) { |
| 208 Tspi_Context_Close(context_handle); | 209 Tspi_Context_Close(context_handle); |
| 209 } | 210 } |
| 210 } | 211 } |
| 211 | 212 |
| 212 void Tpm::GetStatus(bool check_crypto, Tpm::TpmStatusInfo* status) { | 213 void Tpm::GetStatus(bool check_crypto, Tpm::TpmStatusInfo* status) { |
| 213 memset(status, 0, sizeof(Tpm::TpmStatusInfo)); | 214 memset(status, 0, sizeof(Tpm::TpmStatusInfo)); |
| 214 status->ThisInstanceHasContext = (context_handle_ != 0); | 215 status->ThisInstanceHasContext = (context_handle_ != 0); |
| 215 status->ThisInstanceHasKeyHandle = (key_handle_ != 0); | 216 status->ThisInstanceHasKeyHandle = (key_handle_ != 0); |
| 216 TSS_HCONTEXT context_handle = 0; | 217 ScopedTssContext context_handle; |
| 217 do { | 218 // Check if we can connect |
| 218 // Check if we can connect | 219 TSS_RESULT result; |
| 219 TSS_RESULT result; | 220 if (!OpenAndConnectTpm(context_handle.ptr(), &result)) { |
| 220 if (!OpenAndConnectTpm(&context_handle, &result)) { | 221 status->LastTpmError = result; |
| 222 return; | |
| 223 } | |
| 224 status->CanConnect = true; | |
| 225 | |
| 226 // Check the Storage Root Key | |
| 227 ScopedTssType<TSS_HKEY> srk_handle(context_handle); | |
| 228 if (!LoadSrk(context_handle, srk_handle.ptr(), &result)) { | |
| 229 status->LastTpmError = result; | |
| 230 return; | |
| 231 } | |
| 232 status->CanLoadSrk = true; | |
| 233 | |
| 234 // Check the SRK public key | |
| 235 unsigned int size_n; | |
| 236 ScopedTssMemory public_srk(context_handle); | |
| 237 if (TPM_ERROR(result = | |
| 238 Tspi_Key_GetPubKey(srk_handle, &size_n, public_srk.ptr()))) { | |
| 239 status->LastTpmError = result; | |
| 240 return; | |
| 241 } | |
| 242 status->CanLoadSrkPublicKey = true; | |
| 243 | |
| 244 // Check the Cryptohome key | |
| 245 ScopedTssType<TSS_HKEY> key_handle(context_handle); | |
| 246 if (!LoadCryptohomeKey(context_handle, key_handle.ptr(), &result)) { | |
| 247 status->LastTpmError = result; | |
| 248 return; | |
| 249 } | |
| 250 status->HasCryptohomeKey = true; | |
| 251 | |
| 252 if (check_crypto) { | |
| 253 // Check encryption (we don't care about the contents, just whether or not | |
| 254 // there was an error) | |
| 255 SecureBlob data(16); | |
| 256 SecureBlob password(16); | |
| 257 SecureBlob salt(8); | |
| 258 SecureBlob data_out(16); | |
| 259 memset(data.data(), 'A', data.size()); | |
| 260 memset(password.data(), 'B', password.size()); | |
| 261 memset(salt.data(), 'C', salt.size()); | |
| 262 memset(data_out.data(), 'D', data_out.size()); | |
| 263 if (!EncryptBlob(context_handle, key_handle, data, password, | |
| 264 13, salt, &data_out, &result)) { | |
| 221 status->LastTpmError = result; | 265 status->LastTpmError = result; |
| 222 break; | 266 return; |
| 223 } | 267 } |
| 224 status->CanConnect = true; | 268 status->CanEncrypt = true; |
| 225 | 269 |
| 226 // Check the Storage Root Key | 270 // Check decryption (we don't care about the contents, just whether or not |
| 227 TSS_HKEY srk_handle; | 271 // there was an error) |
| 228 if (!LoadSrk(context_handle, &srk_handle, &result)) { | 272 if (!DecryptBlob(context_handle, key_handle, data_out, password, |
| 273 13, salt, &data, &result)) { | |
| 229 status->LastTpmError = result; | 274 status->LastTpmError = result; |
| 230 break; | 275 return; |
| 231 } | 276 } |
| 232 status->CanLoadSrk = true; | 277 status->CanDecrypt = true; |
| 233 | |
| 234 // Check the SRK public key | |
| 235 unsigned int size_n; | |
| 236 BYTE *public_srk; | |
| 237 if ((result = Tspi_Key_GetPubKey(srk_handle, &size_n, &public_srk))) { | |
| 238 Tspi_Context_CloseObject(context_handle, srk_handle); | |
| 239 status->LastTpmError = result; | |
| 240 break; | |
| 241 } | |
| 242 Tspi_Context_FreeMemory(context_handle, public_srk); | |
| 243 Tspi_Context_CloseObject(context_handle, srk_handle); | |
| 244 status->CanLoadSrkPublicKey = true; | |
| 245 | |
| 246 // Check the Cryptohome key | |
| 247 TSS_HKEY key_handle; | |
| 248 if (!LoadCryptohomeKey(context_handle, &key_handle, &result)) { | |
| 249 status->LastTpmError = result; | |
| 250 break; | |
| 251 } | |
| 252 status->HasCryptohomeKey = true; | |
| 253 | |
| 254 if (check_crypto) { | |
| 255 // Check encryption (we don't care about the contents, just whether or not | |
| 256 // there was an error) | |
| 257 SecureBlob data(16); | |
| 258 SecureBlob password(16); | |
| 259 SecureBlob salt(8); | |
| 260 SecureBlob data_out(16); | |
| 261 memset(data.data(), 'A', data.size()); | |
| 262 memset(password.data(), 'B', password.size()); | |
| 263 memset(salt.data(), 'C', salt.size()); | |
| 264 memset(data_out.data(), 'D', data_out.size()); | |
| 265 if (!EncryptBlob(context_handle, key_handle, data, password, | |
| 266 13, salt, &data_out, &result)) { | |
| 267 Tspi_Context_CloseObject(context_handle, key_handle); | |
| 268 status->LastTpmError = result; | |
| 269 break; | |
| 270 } | |
| 271 status->CanEncrypt = true; | |
| 272 | |
| 273 // Check decryption (we don't care about the contents, just whether or not | |
| 274 // there was an error) | |
| 275 if (!DecryptBlob(context_handle, key_handle, data_out, password, | |
| 276 13, salt, &data, &result)) { | |
| 277 Tspi_Context_CloseObject(context_handle, key_handle); | |
| 278 status->LastTpmError = result; | |
| 279 break; | |
| 280 } | |
| 281 status->CanDecrypt = true; | |
| 282 } | |
| 283 Tspi_Context_CloseObject(context_handle, key_handle); | |
| 284 } while (false); | |
| 285 | |
| 286 if (context_handle) { | |
| 287 Tspi_Context_Close(context_handle); | |
| 288 } | 278 } |
| 289 } | 279 } |
| 290 | 280 |
| 291 bool Tpm::CreateCryptohomeKey(TSS_HCONTEXT context_handle, bool create_in_tpm, | 281 bool Tpm::CreateCryptohomeKey(TSS_HCONTEXT context_handle, bool create_in_tpm, |
| 292 TSS_RESULT* result) { | 282 TSS_RESULT* result) { |
| 293 *result = TSS_SUCCESS; | 283 *result = TSS_SUCCESS; |
| 294 | 284 |
| 295 // Load the Storage Root Key | 285 // Load the Storage Root Key |
| 296 TSS_HKEY srk_handle; | 286 ScopedTssType<TSS_HKEY> srk_handle(context_handle); |
| 297 if (!LoadSrk(context_handle, &srk_handle, result)) { | 287 if (!LoadSrk(context_handle, srk_handle.ptr(), result)) { |
| 298 return false; | 288 return false; |
| 299 } | 289 } |
| 300 | 290 |
| 301 // Make sure we can get the public key for the SRK. If not, then the TPM | 291 // Make sure we can get the public key for the SRK. If not, then the TPM |
| 302 // is not available. | 292 // is not available. |
| 303 unsigned int size_n; | 293 unsigned int size_n; |
| 304 BYTE *public_srk; | 294 ScopedTssMemory public_srk(context_handle); |
| 305 if ((*result = Tspi_Key_GetPubKey(srk_handle, &size_n, &public_srk))) { | 295 if (TPM_ERROR(*result = |
| 306 Tspi_Context_CloseObject(context_handle, srk_handle); | 296 Tspi_Key_GetPubKey(srk_handle, &size_n, public_srk.ptr()))) { |
| 307 return false; | 297 return false; |
| 308 } | 298 } |
| 309 Tspi_Context_FreeMemory(context_handle, public_srk); | |
| 310 | 299 |
| 311 // Create the key object | 300 // Create the key object |
| 312 TSS_FLAG init_flags = TSS_KEY_TYPE_LEGACY | TSS_KEY_VOLATILE; | 301 TSS_FLAG init_flags = TSS_KEY_TYPE_LEGACY | TSS_KEY_VOLATILE; |
| 313 if (!create_in_tpm) { | 302 if (!create_in_tpm) { |
| 314 init_flags |= TSS_KEY_MIGRATABLE; | 303 init_flags |= TSS_KEY_MIGRATABLE; |
| 315 switch(rsa_key_bits_) { | 304 switch(rsa_key_bits_) { |
| 316 case 2048: | 305 case 2048: |
| 317 init_flags |= TSS_KEY_SIZE_2048; | 306 init_flags |= TSS_KEY_SIZE_2048; |
| 318 break; | 307 break; |
| 319 case 1024: | 308 case 1024: |
| 320 init_flags |= TSS_KEY_SIZE_1024; | 309 init_flags |= TSS_KEY_SIZE_1024; |
| 321 break; | 310 break; |
| 322 case 512: | 311 case 512: |
| 323 init_flags |= TSS_KEY_SIZE_512; | 312 init_flags |= TSS_KEY_SIZE_512; |
| 324 break; | 313 break; |
| 325 default: | 314 default: |
| 326 LOG(INFO) << "Key size is unknown."; | 315 LOG(INFO) << "Key size is unknown."; |
| 327 Tspi_Context_CloseObject(context_handle, srk_handle); | |
| 328 return false; | 316 return false; |
| 329 } | 317 } |
| 330 } | 318 } |
| 331 TSS_HKEY local_key_handle; | 319 ScopedTssKey local_key_handle(context_handle); |
| 332 if ((*result = Tspi_Context_CreateObject(context_handle, | 320 if (TPM_ERROR(*result = Tspi_Context_CreateObject(context_handle, |
| 333 TSS_OBJECT_TYPE_RSAKEY, | 321 TSS_OBJECT_TYPE_RSAKEY, |
| 334 init_flags, &local_key_handle))) { | 322 init_flags, |
| 323 local_key_handle.ptr()))) { | |
| 335 TPM_LOG(ERROR, *result) << "Error calling Tspi_Context_CreateObject"; | 324 TPM_LOG(ERROR, *result) << "Error calling Tspi_Context_CreateObject"; |
| 336 Tspi_Context_CloseObject(context_handle, srk_handle); | |
| 337 return false; | 325 return false; |
| 338 } | 326 } |
| 339 | 327 |
| 340 // Set the attributes | 328 // Set the attributes |
| 341 UINT32 sig_scheme = TSS_SS_RSASSAPKCS1V15_DER; | 329 UINT32 sig_scheme = TSS_SS_RSASSAPKCS1V15_DER; |
| 342 if ((*result = Tspi_SetAttribUint32(local_key_handle, TSS_TSPATTRIB_KEY_INFO, | 330 if (TPM_ERROR(*result = Tspi_SetAttribUint32(local_key_handle, |
| 343 TSS_TSPATTRIB_KEYINFO_SIGSCHEME, | 331 TSS_TSPATTRIB_KEY_INFO, |
| 344 sig_scheme))) { | 332 TSS_TSPATTRIB_KEYINFO_SIGSCHEME, |
| 333 sig_scheme))) { | |
| 345 TPM_LOG(ERROR, *result) << "Error calling Tspi_SetAttribUint32"; | 334 TPM_LOG(ERROR, *result) << "Error calling Tspi_SetAttribUint32"; |
| 346 Tspi_Context_CloseObject(context_handle, srk_handle); | |
| 347 Tspi_Context_CloseObject(context_handle, local_key_handle); | |
| 348 return false; | 335 return false; |
| 349 } | 336 } |
| 350 | 337 |
| 351 UINT32 enc_scheme = TSS_ES_RSAESPKCSV15; | 338 UINT32 enc_scheme = TSS_ES_RSAESPKCSV15; |
| 352 if ((*result = Tspi_SetAttribUint32(local_key_handle, TSS_TSPATTRIB_KEY_INFO, | 339 if (TPM_ERROR(*result = Tspi_SetAttribUint32(local_key_handle, |
| 353 TSS_TSPATTRIB_KEYINFO_ENCSCHEME, | 340 TSS_TSPATTRIB_KEY_INFO, |
| 354 enc_scheme))) { | 341 TSS_TSPATTRIB_KEYINFO_ENCSCHEME, |
| 342 enc_scheme))) { | |
| 355 TPM_LOG(ERROR, *result) << "Error calling Tspi_SetAttribUint32"; | 343 TPM_LOG(ERROR, *result) << "Error calling Tspi_SetAttribUint32"; |
| 356 Tspi_Context_CloseObject(context_handle, srk_handle); | |
| 357 Tspi_Context_CloseObject(context_handle, local_key_handle); | |
| 358 return false; | 344 return false; |
| 359 } | 345 } |
| 360 | 346 |
| 361 // Create a new system-wide key for cryptohome | 347 // Create a new system-wide key for cryptohome |
| 362 if (create_in_tpm) { | 348 if (create_in_tpm) { |
| 363 if ((*result = Tspi_Key_CreateKey(local_key_handle, srk_handle, 0))) { | 349 if (TPM_ERROR(*result = |
| 350 Tspi_Key_CreateKey(local_key_handle, srk_handle, 0))) { | |
|
gauravsh
2011/03/29 20:52:44
nit: just indent this as you do the previous if's
Will Drewry
2011/03/29 20:54:59
Done.
Will Drewry
2011/03/29 21:14:30
Done.
| |
| 364 TPM_LOG(ERROR, *result) << "Error calling Tspi_Key_CreateKey"; | 351 TPM_LOG(ERROR, *result) << "Error calling Tspi_Key_CreateKey"; |
| 365 Tspi_Context_CloseObject(context_handle, srk_handle); | |
| 366 Tspi_Context_CloseObject(context_handle, local_key_handle); | |
| 367 return false; | 352 return false; |
| 368 } | 353 } |
| 369 } else { | 354 } else { |
| 370 TSS_HPOLICY policy_handle; | 355 ScopedTssPolicy policy_handle(context_handle); |
| 371 if ((*result = Tspi_Context_CreateObject(context_handle, | 356 if (TPM_ERROR(*result = Tspi_Context_CreateObject(context_handle, |
| 372 TSS_OBJECT_TYPE_POLICY, | 357 TSS_OBJECT_TYPE_POLICY, |
| 373 TSS_POLICY_MIGRATION, | 358 TSS_POLICY_MIGRATION, |
| 374 &policy_handle))) { | 359 policy_handle.ptr()))) { |
| 375 TPM_LOG(ERROR, *result) << "Error creating policy object"; | 360 TPM_LOG(ERROR, *result) << "Error creating policy object"; |
| 376 Tspi_Context_CloseObject(context_handle, srk_handle); | |
| 377 Tspi_Context_CloseObject(context_handle, local_key_handle); | |
| 378 return false; | 361 return false; |
| 379 } | 362 } |
| 380 | 363 |
| 381 // Set a random migration policy password, and discard it. The key will not | 364 // Set a random migration policy password, and discard it. The key will not |
| 382 // be migrated, but to create the key outside of the TPM, we have to do it | 365 // be migrated, but to create the key outside of the TPM, we have to do it |
| 383 // this way. | 366 // this way. |
| 384 SecureBlob migration_password(kDefaultDiscardableWrapPasswordLength); | 367 SecureBlob migration_password(kDefaultDiscardableWrapPasswordLength); |
| 385 crypto_->GetSecureRandom( | 368 crypto_->GetSecureRandom( |
| 386 static_cast<unsigned char*>(migration_password.data()), | 369 static_cast<unsigned char*>(migration_password.data()), |
| 387 migration_password.size()); | 370 migration_password.size()); |
| 388 if ((*result = Tspi_Policy_SetSecret(policy_handle, TSS_SECRET_MODE_PLAIN, | 371 if (TPM_ERROR(*result = Tspi_Policy_SetSecret(policy_handle, |
| 389 migration_password.size(), | 372 TSS_SECRET_MODE_PLAIN, |
| 390 static_cast<BYTE*>(migration_password.data())))) { | 373 migration_password.size(), |
| 374 static_cast<BYTE*>(migration_password.data())))) { | |
| 391 TPM_LOG(ERROR, *result) << "Error setting migration policy password"; | 375 TPM_LOG(ERROR, *result) << "Error setting migration policy password"; |
| 392 Tspi_Context_CloseObject(context_handle, policy_handle); | |
| 393 Tspi_Context_CloseObject(context_handle, srk_handle); | |
| 394 Tspi_Context_CloseObject(context_handle, local_key_handle); | |
| 395 return false; | 376 return false; |
| 396 } | 377 } |
| 397 | 378 |
| 398 if ((*result = Tspi_Policy_AssignToObject(policy_handle, | 379 if (TPM_ERROR(*result = Tspi_Policy_AssignToObject(policy_handle, |
| 399 local_key_handle))) { | 380 local_key_handle))) { |
| 400 TPM_LOG(ERROR, *result) << "Error assigning migration policy"; | 381 TPM_LOG(ERROR, *result) << "Error assigning migration policy"; |
| 401 Tspi_Context_CloseObject(context_handle, policy_handle); | |
| 402 Tspi_Context_CloseObject(context_handle, srk_handle); | |
| 403 Tspi_Context_CloseObject(context_handle, local_key_handle); | |
| 404 return false; | 382 return false; |
| 405 } | 383 } |
| 406 | 384 |
| 407 SecureBlob n; | 385 SecureBlob n; |
| 408 SecureBlob p; | 386 SecureBlob p; |
| 409 if (!crypto_->CreateRsaKey(rsa_key_bits_, &n, &p)) { | 387 if (!crypto_->CreateRsaKey(rsa_key_bits_, &n, &p)) { |
| 410 LOG(ERROR) << "Error creating RSA key"; | 388 LOG(ERROR) << "Error creating RSA key"; |
| 411 Tspi_Context_CloseObject(context_handle, srk_handle); | |
| 412 Tspi_Context_CloseObject(context_handle, local_key_handle); | |
| 413 return false; | 389 return false; |
| 414 } | 390 } |
| 415 | 391 |
| 416 if ((*result = Tspi_SetAttribData(local_key_handle, | 392 if (TPM_ERROR(*result = Tspi_SetAttribData(local_key_handle, |
| 417 TSS_TSPATTRIB_RSAKEY_INFO, | 393 TSS_TSPATTRIB_RSAKEY_INFO, |
| 418 TSS_TSPATTRIB_KEYINFO_RSA_MODULUS, | 394 TSS_TSPATTRIB_KEYINFO_RSA_MODULUS, |
| 419 n.size(), | 395 n.size(), |
| 420 static_cast<BYTE *>(n.data())))) { | 396 static_cast<BYTE *>(n.data())))) { |
| 421 TPM_LOG(ERROR, *result) << "Error setting RSA modulus"; | 397 TPM_LOG(ERROR, *result) << "Error setting RSA modulus"; |
| 422 Tspi_Context_CloseObject(context_handle, srk_handle); | |
| 423 Tspi_Context_CloseObject(context_handle, local_key_handle); | |
| 424 return false; | 398 return false; |
| 425 } | 399 } |
| 426 | 400 |
| 427 if ((*result = Tspi_SetAttribData(local_key_handle, TSS_TSPATTRIB_KEY_BLOB, | 401 if (TPM_ERROR(*result = Tspi_SetAttribData(local_key_handle, |
| 428 TSS_TSPATTRIB_KEYBLOB_PRIVATE_KEY, | 402 TSS_TSPATTRIB_KEY_BLOB, |
| 429 p.size(), | 403 TSS_TSPATTRIB_KEYBLOB_PRIVATE_KEY, |
| 430 static_cast<BYTE *>(p.data())))) { | 404 p.size(), |
| 405 static_cast<BYTE *>(p.data())))) { | |
| 431 TPM_LOG(ERROR, *result) << "Error setting private key"; | 406 TPM_LOG(ERROR, *result) << "Error setting private key"; |
| 432 Tspi_Context_CloseObject(context_handle, srk_handle); | |
| 433 Tspi_Context_CloseObject(context_handle, local_key_handle); | |
| 434 return false; | 407 return false; |
| 435 } | 408 } |
| 436 | 409 |
| 437 if ((*result = Tspi_Key_WrapKey(local_key_handle, srk_handle, 0))) { | 410 if (TPM_ERROR(*result = |
| 411 Tspi_Key_WrapKey(local_key_handle, srk_handle, 0))) { | |
| 438 TPM_LOG(ERROR, *result) << "Error wrapping RSA key"; | 412 TPM_LOG(ERROR, *result) << "Error wrapping RSA key"; |
| 439 Tspi_Context_CloseObject(context_handle, srk_handle); | |
| 440 Tspi_Context_CloseObject(context_handle, local_key_handle); | |
| 441 return false; | 413 return false; |
| 442 } | 414 } |
| 443 } | 415 } |
| 444 | 416 |
| 445 if (!SaveCryptohomeKey(context_handle, local_key_handle, result)) { | 417 if (!SaveCryptohomeKey(context_handle, local_key_handle, result)) { |
| 446 LOG(ERROR) << "Couldn't save cryptohome key"; | 418 LOG(ERROR) << "Couldn't save cryptohome key"; |
| 447 Tspi_Context_CloseObject(context_handle, srk_handle); | |
| 448 Tspi_Context_CloseObject(context_handle, local_key_handle); | |
| 449 return false; | 419 return false; |
| 450 } | 420 } |
| 451 | 421 |
| 452 Tspi_Context_CloseObject(context_handle, srk_handle); | |
| 453 Tspi_Context_CloseObject(context_handle, local_key_handle); | |
| 454 | |
| 455 LOG(INFO) << "Created new cryptohome key."; | 422 LOG(INFO) << "Created new cryptohome key."; |
| 456 return true; | 423 return true; |
| 457 } | 424 } |
| 458 | 425 |
| 459 bool Tpm::LoadCryptohomeKey(TSS_HCONTEXT context_handle, | 426 bool Tpm::LoadCryptohomeKey(TSS_HCONTEXT context_handle, |
| 460 TSS_HKEY* key_handle, TSS_RESULT* result) { | 427 TSS_HKEY* key_handle, TSS_RESULT* result) { |
| 461 // Load the Storage Root Key | 428 // Load the Storage Root Key |
| 462 TSS_HKEY srk_handle; | 429 ScopedTssKey srk_handle(context_handle); |
| 463 if (!LoadSrk(context_handle, &srk_handle, result)) { | 430 if (!LoadSrk(context_handle, srk_handle.ptr(), result)) { |
| 464 return false; | 431 return false; |
| 465 } | 432 } |
| 466 | 433 |
| 467 // Make sure we can get the public key for the SRK. If not, then the TPM | 434 // Make sure we can get the public key for the SRK. If not, then the TPM |
| 468 // is not available. | 435 // is not available. |
| 469 unsigned int size_n; | 436 unsigned int size_n; |
| 470 BYTE *public_srk; | 437 ScopedTssMemory public_srk(context_handle); |
| 471 if ((*result = Tspi_Key_GetPubKey(srk_handle, &size_n, &public_srk))) { | 438 if (TPM_ERROR(*result = |
| 472 Tspi_Context_CloseObject(context_handle, srk_handle); | 439 Tspi_Key_GetPubKey(srk_handle, &size_n, public_srk.ptr()))) { |
| 473 return false; | 440 return false; |
| 474 } | 441 } |
| 475 Tspi_Context_FreeMemory(context_handle, public_srk); | |
| 476 | 442 |
| 477 // First, try loading the key from the key file | 443 // First, try loading the key from the key file |
| 478 SecureBlob raw_key; | 444 SecureBlob raw_key; |
| 479 if (Mount::LoadFileBytes(FilePath(key_file_), &raw_key)) { | 445 if (Mount::LoadFileBytes(FilePath(key_file_), &raw_key)) { |
| 480 if ((*result = Tspi_Context_LoadKeyByBlob(context_handle, | 446 if (TPM_ERROR(*result = Tspi_Context_LoadKeyByBlob( |
| 481 srk_handle, | 447 context_handle, |
| 482 raw_key.size(), | 448 srk_handle, |
| 483 const_cast<BYTE*>(static_cast<const BYTE*>(raw_key.const_data())), | 449 raw_key.size(), |
| 484 key_handle))) { | 450 const_cast<BYTE*>(static_cast<const BYTE*>( |
| 451 raw_key.const_data())), | |
| 452 key_handle))) { | |
| 485 // If the error is expected to be transient, return now. | 453 // If the error is expected to be transient, return now. |
| 486 if (IsTransient(*result)) { | 454 if (IsTransient(*result)) { |
| 487 Tspi_Context_CloseObject(context_handle, srk_handle); | |
| 488 return false; | 455 return false; |
| 489 } | 456 } |
| 490 } else { | 457 } else { |
| 491 SecureBlob pub_key; | 458 SecureBlob pub_key; |
| 492 // Make sure that we can get the public key | 459 // Make sure that we can get the public key |
| 493 if (GetPublicKeyBlob(context_handle, *key_handle, &pub_key, result)) { | 460 if (GetPublicKeyBlob(context_handle, *key_handle, &pub_key, result)) { |
| 494 Tspi_Context_CloseObject(context_handle, srk_handle); | |
| 495 return true; | 461 return true; |
| 496 } | 462 } |
| 497 // Otherwise, close the key and fall through | 463 // Otherwise, close the key and fall through |
| 498 Tspi_Context_CloseObject(context_handle, *key_handle); | 464 Tspi_Context_CloseObject(context_handle, *key_handle); |
| 499 if (IsTransient(*result)) { | 465 if (IsTransient(*result)) { |
| 500 Tspi_Context_CloseObject(context_handle, srk_handle); | |
| 501 return false; | 466 return false; |
| 502 } | 467 } |
| 503 } | 468 } |
| 504 } | 469 } |
| 505 | 470 |
| 506 // Then try loading the key by the UUID (this is a legacy upgrade path) | 471 // Then try loading the key by the UUID (this is a legacy upgrade path) |
| 507 if ((*result = Tspi_Context_LoadKeyByUUID(context_handle, | 472 if (TPM_ERROR(*result = Tspi_Context_LoadKeyByUUID(context_handle, |
| 508 TSS_PS_TYPE_SYSTEM, | 473 TSS_PS_TYPE_SYSTEM, |
| 509 kCryptohomeWellKnownUuid, | 474 kCryptohomeWellKnownUuid, |
| 510 key_handle))) { | 475 key_handle))) { |
| 511 // If the error is expected to be transient, return now. | 476 // If the error is expected to be transient, return now. |
| 512 if (IsTransient(*result)) { | 477 if (IsTransient(*result)) { |
| 513 Tspi_Context_CloseObject(context_handle, srk_handle); | |
| 514 return false; | 478 return false; |
| 515 } | 479 } |
| 516 } else { | 480 } else { |
| 517 SecureBlob pub_key; | 481 SecureBlob pub_key; |
| 518 // Make sure that we can get the public key | 482 // Make sure that we can get the public key |
| 519 if (GetPublicKeyBlob(context_handle, *key_handle, &pub_key, result)) { | 483 if (GetPublicKeyBlob(context_handle, *key_handle, &pub_key, result)) { |
| 520 // Save the cryptohome key to the well-known location | 484 // Save the cryptohome key to the well-known location |
| 521 if (!SaveCryptohomeKey(context_handle, *key_handle, result)) { | 485 if (!SaveCryptohomeKey(context_handle, *key_handle, result)) { |
| 522 LOG(ERROR) << "Couldn't save cryptohome key"; | 486 LOG(ERROR) << "Couldn't save cryptohome key"; |
| 523 Tspi_Context_CloseObject(context_handle, *key_handle); | 487 Tspi_Context_CloseObject(context_handle, *key_handle); |
| 524 Tspi_Context_CloseObject(context_handle, srk_handle); | |
| 525 return false; | 488 return false; |
| 526 } | 489 } |
| 527 Tspi_Context_CloseObject(context_handle, srk_handle); | |
| 528 return true; | 490 return true; |
| 529 } | 491 } |
| 530 Tspi_Context_CloseObject(context_handle, *key_handle); | 492 Tspi_Context_CloseObject(context_handle, *key_handle); |
| 531 } | 493 } |
| 532 | 494 |
| 533 Tspi_Context_CloseObject(context_handle, srk_handle); | |
| 534 return false; | 495 return false; |
| 535 } | 496 } |
| 536 | 497 |
| 537 bool Tpm::LoadOrCreateCryptohomeKey(TSS_HCONTEXT context_handle, | 498 bool Tpm::LoadOrCreateCryptohomeKey(TSS_HCONTEXT context_handle, |
| 538 bool create_in_tpm, | 499 bool create_in_tpm, |
| 539 TSS_HKEY* key_handle, | 500 TSS_HKEY* key_handle, |
| 540 TSS_RESULT* result) { | 501 TSS_RESULT* result) { |
| 541 *result = TSS_SUCCESS; | 502 *result = TSS_SUCCESS; |
| 542 | 503 |
| 543 // Try to load the cryptohome key. | 504 // Try to load the cryptohome key. |
| (...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 641 return -1; | 602 return -1; |
| 642 } | 603 } |
| 643 | 604 |
| 644 return GetMaxRsaKeyCountForContext(context_handle_); | 605 return GetMaxRsaKeyCountForContext(context_handle_); |
| 645 } | 606 } |
| 646 | 607 |
| 647 unsigned int Tpm::GetMaxRsaKeyCountForContext(TSS_HCONTEXT context_handle) { | 608 unsigned int Tpm::GetMaxRsaKeyCountForContext(TSS_HCONTEXT context_handle) { |
| 648 unsigned int count = 0; | 609 unsigned int count = 0; |
| 649 TSS_RESULT result; | 610 TSS_RESULT result; |
| 650 TSS_HTPM tpm_handle; | 611 TSS_HTPM tpm_handle; |
| 651 if ((result = Tspi_Context_GetTpmObject(context_handle, &tpm_handle))) { | 612 if (TPM_ERROR(result = |
|
gauravsh
2011/03/29 20:52:44
nit: indent this as you indent the others
Will Drewry
2011/03/29 20:54:59
it is - i think it's another rietveld optical illu
gauravsh
2011/03/29 20:58:45
It is? All the red and green (the CL, not the tree
Will Drewry
2011/03/29 21:14:30
Done.
| |
| 613 Tspi_Context_GetTpmObject(context_handle, &tpm_handle))) { | |
| 652 TPM_LOG(ERROR, result) << "Error calling Tspi_Context_GetTpmObject"; | 614 TPM_LOG(ERROR, result) << "Error calling Tspi_Context_GetTpmObject"; |
| 653 return count; | 615 return count; |
| 654 } | 616 } |
| 655 | 617 |
| 656 UINT32 cap_length = 0; | 618 UINT32 cap_length = 0; |
| 657 BYTE* cap = NULL; | 619 ScopedTssMemory cap(context_handle); |
| 658 UINT32 subcap = TSS_TPMCAP_PROP_MAXKEYS; | 620 UINT32 subcap = TSS_TPMCAP_PROP_MAXKEYS; |
| 659 if ((result = Tspi_TPM_GetCapability(tpm_handle, TSS_TPMCAP_PROPERTY, | 621 if (TPM_ERROR(result = Tspi_TPM_GetCapability(tpm_handle, |
| 660 sizeof(subcap), | 622 TSS_TPMCAP_PROPERTY, |
| 661 reinterpret_cast<BYTE*>(&subcap), | 623 sizeof(subcap), |
| 662 &cap_length, &cap))) { | 624 reinterpret_cast<BYTE*>( |
| 625 &subcap), | |
| 626 &cap_length, cap.ptr()))) { | |
| 663 TPM_LOG(ERROR, result) << "Error calling Tspi_TPM_GetCapability"; | 627 TPM_LOG(ERROR, result) << "Error calling Tspi_TPM_GetCapability"; |
| 664 return count; | 628 return count; |
| 665 } | 629 } |
| 666 if (cap_length == sizeof(unsigned int)) { | 630 if (cap_length == sizeof(unsigned int)) { |
| 667 count = *(reinterpret_cast<unsigned int*>(cap)); | 631 count = *(reinterpret_cast<unsigned int*>(*cap)); |
| 668 } | 632 } |
| 669 Tspi_Context_FreeMemory(context_handle, cap); | |
| 670 return count; | 633 return count; |
| 671 } | 634 } |
| 672 | 635 |
| 673 bool Tpm::OpenAndConnectTpm(TSS_HCONTEXT* context_handle, TSS_RESULT* result) { | 636 bool Tpm::OpenAndConnectTpm(TSS_HCONTEXT* context_handle, TSS_RESULT* result) { |
| 674 TSS_RESULT local_result; | 637 TSS_RESULT local_result; |
| 675 TSS_HCONTEXT local_context_handle = 0; | 638 ScopedTssContext local_context_handle; |
| 676 if ((local_result = Tspi_Context_Create(&local_context_handle))) { | 639 if (TPM_ERROR(local_result = |
| 640 Tspi_Context_Create(local_context_handle.ptr()))) { | |
| 677 TPM_LOG(ERROR, local_result) << "Error calling Tspi_Context_Create"; | 641 TPM_LOG(ERROR, local_result) << "Error calling Tspi_Context_Create"; |
| 678 if (result) | 642 if (result) |
| 679 *result = local_result; | 643 *result = local_result; |
| 680 return false; | 644 return false; |
| 681 } | 645 } |
| 682 | 646 |
| 683 for (unsigned int i = 0; i < kTpmConnectRetries; i++) { | 647 for (unsigned int i = 0; i < kTpmConnectRetries; i++) { |
| 684 if ((local_result = Tspi_Context_Connect(local_context_handle, NULL))) { | 648 if (TPM_ERROR(local_result = |
|
gauravsh
2011/03/29 20:52:44
nit: indent this as you indent the others.
Will Drewry
2011/03/29 20:54:59
Same here!
Will Drewry
2011/03/29 21:14:30
Done.
| |
| 649 Tspi_Context_Connect(local_context_handle, NULL))) { | |
| 685 // If there was a communications failure, try sleeping a bit here--it may | 650 // If there was a communications failure, try sleeping a bit here--it may |
| 686 // be that tcsd is still starting | 651 // be that tcsd is still starting |
| 687 if (ERROR_CODE(local_result) == TSS_E_COMM_FAILURE) { | 652 if (ERROR_CODE(local_result) == TSS_E_COMM_FAILURE) { |
| 688 PlatformThread::Sleep(kTpmConnectIntervalMs); | 653 PlatformThread::Sleep(kTpmConnectIntervalMs); |
| 689 } else { | 654 } else { |
| 690 TPM_LOG(ERROR, local_result) << "Error calling Tspi_Context_Connect"; | 655 TPM_LOG(ERROR, local_result) << "Error calling Tspi_Context_Connect"; |
| 691 Tspi_Context_Close(local_context_handle); | |
| 692 if (result) | 656 if (result) |
| 693 *result = local_result; | 657 *result = local_result; |
| 694 return false; | 658 return false; |
| 695 } | 659 } |
| 696 } else { | 660 } else { |
| 697 break; | 661 break; |
| 698 } | 662 } |
| 699 } | 663 } |
| 700 | 664 |
| 701 if (local_result) { | 665 if (TPM_ERROR(local_result)) { |
| 702 TPM_LOG(ERROR, local_result) << "Error calling Tspi_Context_Connect"; | 666 TPM_LOG(ERROR, local_result) << "Error calling Tspi_Context_Connect"; |
| 703 Tspi_Context_Close(local_context_handle); | |
| 704 if (result) | 667 if (result) |
| 705 *result = local_result; | 668 *result = local_result; |
| 706 return false; | 669 return false; |
| 707 } | 670 } |
| 708 | 671 |
| 709 *context_handle = local_context_handle; | 672 *context_handle = local_context_handle.release(); |
| 710 if (result) | 673 if (result) |
| 711 *result = local_result; | 674 *result = local_result; |
| 712 return (local_context_handle != 0); | 675 return (*context_handle != 0); |
| 713 } | 676 } |
| 714 | 677 |
| 715 bool Tpm::Encrypt(const chromeos::Blob& data, const chromeos::Blob& password, | 678 bool Tpm::Encrypt(const chromeos::Blob& data, const chromeos::Blob& password, |
| 716 unsigned int password_rounds, const chromeos::Blob& salt, | 679 unsigned int password_rounds, const chromeos::Blob& salt, |
| 717 SecureBlob* data_out, Tpm::TpmRetryAction* retry_action) { | 680 SecureBlob* data_out, Tpm::TpmRetryAction* retry_action) { |
| 718 *retry_action = Tpm::RetryNone; | 681 *retry_action = Tpm::RetryNone; |
| 719 if (!IsConnected()) { | 682 if (!IsConnected()) { |
| 720 if (!Connect(retry_action)) { | 683 if (!Connect(retry_action)) { |
| 721 return false; | 684 return false; |
| 722 } | 685 } |
| (...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 807 TSS_HKEY key_handle, | 770 TSS_HKEY key_handle, |
| 808 const chromeos::Blob& data, | 771 const chromeos::Blob& data, |
| 809 const chromeos::Blob& password, | 772 const chromeos::Blob& password, |
| 810 unsigned int password_rounds, | 773 unsigned int password_rounds, |
| 811 const chromeos::Blob& salt, | 774 const chromeos::Blob& salt, |
| 812 SecureBlob* data_out, | 775 SecureBlob* data_out, |
| 813 TSS_RESULT* result) { | 776 TSS_RESULT* result) { |
| 814 *result = TSS_SUCCESS; | 777 *result = TSS_SUCCESS; |
| 815 | 778 |
| 816 TSS_FLAG init_flags = TSS_ENCDATA_SEAL; | 779 TSS_FLAG init_flags = TSS_ENCDATA_SEAL; |
| 817 TSS_HKEY enc_handle; | 780 ScopedTssKey enc_handle(context_handle); |
| 818 if ((*result = Tspi_Context_CreateObject(context_handle, | 781 if (TPM_ERROR(*result = Tspi_Context_CreateObject(context_handle, |
| 819 TSS_OBJECT_TYPE_ENCDATA, | 782 TSS_OBJECT_TYPE_ENCDATA, |
| 820 init_flags, &enc_handle))) { | 783 init_flags, |
| 784 enc_handle.ptr()))) { | |
| 821 TPM_LOG(ERROR, *result) << "Error calling Tspi_Context_CreateObject"; | 785 TPM_LOG(ERROR, *result) << "Error calling Tspi_Context_CreateObject"; |
| 822 return false; | 786 return false; |
| 823 } | 787 } |
| 824 | 788 |
| 825 // TODO(fes): Check RSA key modulus size, return an error or block input | 789 // TODO(fes): Check RSA key modulus size, return an error or block input |
| 826 | 790 |
| 827 if ((*result = Tspi_Data_Bind(enc_handle, key_handle, data.size(), | 791 if (TPM_ERROR(*result = Tspi_Data_Bind(enc_handle, key_handle, data.size(), |
| 828 const_cast<BYTE *>(&data[0])))) { | 792 const_cast<BYTE *>(&data[0])))) { |
| 829 TPM_LOG(ERROR, *result) << "Error calling Tspi_Data_Bind"; | 793 TPM_LOG(ERROR, *result) << "Error calling Tspi_Data_Bind"; |
| 830 Tspi_Context_CloseObject(context_handle, enc_handle); | |
| 831 return false; | 794 return false; |
| 832 } | 795 } |
| 833 | 796 |
| 834 unsigned char* enc_data = NULL; | |
| 835 UINT32 enc_data_length = 0; | 797 UINT32 enc_data_length = 0; |
| 836 if ((*result = Tspi_GetAttribData(enc_handle, TSS_TSPATTRIB_ENCDATA_BLOB, | 798 ScopedTssMemory enc_data(context_handle); |
| 837 TSS_TSPATTRIB_ENCDATABLOB_BLOB, | 799 if (TPM_ERROR(*result = Tspi_GetAttribData(enc_handle, |
| 838 &enc_data_length, &enc_data))) { | 800 TSS_TSPATTRIB_ENCDATA_BLOB, |
| 801 TSS_TSPATTRIB_ENCDATABLOB_BLOB, | |
| 802 &enc_data_length, | |
| 803 enc_data.ptr()))) { | |
| 839 TPM_LOG(ERROR, *result) << "Error calling Tspi_GetAttribData"; | 804 TPM_LOG(ERROR, *result) << "Error calling Tspi_GetAttribData"; |
| 840 Tspi_Context_CloseObject(context_handle, enc_handle); | |
| 841 return false; | 805 return false; |
| 842 } | 806 } |
| 843 | 807 |
| 844 SecureBlob local_data(enc_data_length); | 808 SecureBlob local_data(enc_data_length); |
| 845 memcpy(local_data.data(), enc_data, enc_data_length); | 809 memcpy(local_data.data(), enc_data, enc_data_length); |
| 846 Tspi_Context_FreeMemory(context_handle, enc_data); | 810 // We're done with enc_* so let's free it now. |
| 847 Tspi_Context_CloseObject(context_handle, enc_handle); | 811 enc_data.reset(); |
| 812 enc_handle.reset(); | |
| 848 | 813 |
| 849 SecureBlob aes_key; | 814 SecureBlob aes_key; |
| 850 SecureBlob iv; | 815 SecureBlob iv; |
| 851 if (!crypto_->PasskeyToAesKey(password, | 816 if (!crypto_->PasskeyToAesKey(password, |
| 852 salt, | 817 salt, |
| 853 password_rounds, | 818 password_rounds, |
| 854 &aes_key, | 819 &aes_key, |
| 855 &iv)) { | 820 &iv)) { |
| 856 LOG(ERROR) << "Failure converting passkey to key"; | 821 LOG(ERROR) << "Failure converting passkey to key"; |
| 857 return false; | 822 return false; |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 915 LOG(ERROR) << "AES decryption failed."; | 880 LOG(ERROR) << "AES decryption failed."; |
| 916 return false; | 881 return false; |
| 917 } | 882 } |
| 918 PLOG_IF(FATAL, passkey_part.size() != aes_block_size) | 883 PLOG_IF(FATAL, passkey_part.size() != aes_block_size) |
| 919 << "Output block size error: " << passkey_part.size() << ", expected: " | 884 << "Output block size error: " << passkey_part.size() << ", expected: " |
| 920 << aes_block_size; | 885 << aes_block_size; |
| 921 SecureBlob local_data(data.begin(), data.end()); | 886 SecureBlob local_data(data.begin(), data.end()); |
| 922 memcpy(&local_data[offset], passkey_part.data(), passkey_part.size()); | 887 memcpy(&local_data[offset], passkey_part.data(), passkey_part.size()); |
| 923 | 888 |
| 924 TSS_FLAG init_flags = TSS_ENCDATA_SEAL; | 889 TSS_FLAG init_flags = TSS_ENCDATA_SEAL; |
| 925 TSS_HKEY enc_handle; | 890 ScopedTssKey enc_handle(context_handle); |
| 926 if ((*result = Tspi_Context_CreateObject(context_handle, | 891 if (TPM_ERROR(*result = Tspi_Context_CreateObject(context_handle, |
| 927 TSS_OBJECT_TYPE_ENCDATA, | 892 TSS_OBJECT_TYPE_ENCDATA, |
| 928 init_flags, &enc_handle))) { | 893 init_flags, |
| 894 enc_handle.ptr()))) { | |
| 929 TPM_LOG(ERROR, *result) << "Error calling Tspi_Context_CreateObject"; | 895 TPM_LOG(ERROR, *result) << "Error calling Tspi_Context_CreateObject"; |
| 930 return false; | 896 return false; |
| 931 } | 897 } |
| 932 | 898 |
| 933 if ((*result = Tspi_SetAttribData(enc_handle, | 899 if (TPM_ERROR(*result = Tspi_SetAttribData(enc_handle, |
| 934 TSS_TSPATTRIB_ENCDATA_BLOB, TSS_TSPATTRIB_ENCDATABLOB_BLOB, | 900 TSS_TSPATTRIB_ENCDATA_BLOB, |
| 935 local_data.size(), | 901 TSS_TSPATTRIB_ENCDATABLOB_BLOB, |
| 936 static_cast<BYTE *>(const_cast<void*>(local_data.const_data()))))) { | 902 local_data.size(), |
| 903 static_cast<BYTE *>( | |
| 904 const_cast<void*>( | |
| 905 local_data.const_data()))))) { | |
| 937 TPM_LOG(ERROR, *result) << "Error calling Tspi_SetAttribData"; | 906 TPM_LOG(ERROR, *result) << "Error calling Tspi_SetAttribData"; |
| 938 Tspi_Context_CloseObject(context_handle, enc_handle); | |
| 939 return false; | 907 return false; |
| 940 } | 908 } |
| 941 | 909 |
| 942 unsigned char* dec_data = NULL; | 910 ScopedTssMemory dec_data(context_handle); |
| 943 UINT32 dec_data_length = 0; | 911 UINT32 dec_data_length = 0; |
| 944 if ((*result = Tspi_Data_Unbind(enc_handle, key_handle, &dec_data_length, | 912 if (TPM_ERROR(*result = Tspi_Data_Unbind(enc_handle, key_handle, |
| 945 &dec_data))) { | 913 &dec_data_length, dec_data.ptr()))) { |
| 946 TPM_LOG(ERROR, *result) << "Error calling Tspi_Data_Unbind"; | 914 TPM_LOG(ERROR, *result) << "Error calling Tspi_Data_Unbind"; |
| 947 Tspi_Context_CloseObject(context_handle, enc_handle); | |
| 948 return false; | 915 return false; |
| 949 } | 916 } |
| 950 | 917 |
| 951 data_out->resize(dec_data_length); | 918 data_out->resize(dec_data_length); |
| 952 memcpy(data_out->data(), dec_data, dec_data_length); | 919 memcpy(data_out->data(), dec_data, dec_data_length); |
| 953 chromeos::SecureMemset(dec_data, 0, dec_data_length); | 920 chromeos::SecureMemset(dec_data, 0, dec_data_length); |
| 954 Tspi_Context_FreeMemory(context_handle, dec_data); | |
| 955 | |
| 956 Tspi_Context_CloseObject(context_handle, enc_handle); | |
| 957 | 921 |
| 958 return true; | 922 return true; |
| 959 } | 923 } |
| 960 | 924 |
| 961 bool Tpm::GetKeyBlob(TSS_HCONTEXT context_handle, TSS_HKEY key_handle, | 925 bool Tpm::GetKeyBlob(TSS_HCONTEXT context_handle, TSS_HKEY key_handle, |
| 962 SecureBlob* data_out, TSS_RESULT* result) { | 926 SecureBlob* data_out, TSS_RESULT* result) { |
| 963 *result = TSS_SUCCESS; | 927 *result = TSS_SUCCESS; |
| 964 | 928 |
| 965 BYTE* blob; | 929 ScopedTssMemory blob(context_handle); |
| 966 UINT32 blob_size; | 930 UINT32 blob_size; |
| 967 if ((*result = Tspi_GetAttribData(key_handle, TSS_TSPATTRIB_KEY_BLOB, | 931 if (TPM_ERROR(*result = Tspi_GetAttribData(key_handle, TSS_TSPATTRIB_KEY_BLOB, |
| 968 TSS_TSPATTRIB_KEYBLOB_BLOB, | 932 TSS_TSPATTRIB_KEYBLOB_BLOB, |
| 969 &blob_size, &blob))) { | 933 &blob_size, blob.ptr()))) { |
| 970 TPM_LOG(ERROR, *result) << "Couldn't get key blob"; | 934 TPM_LOG(ERROR, *result) << "Couldn't get key blob"; |
| 971 return false; | 935 return false; |
| 972 } | 936 } |
| 973 | 937 |
| 974 SecureBlob local_data(blob_size); | 938 SecureBlob local_data(blob_size); |
| 975 memcpy(local_data.data(), blob, blob_size); | 939 memcpy(local_data.data(), blob, blob_size); |
| 976 chromeos::SecureMemset(blob, 0, blob_size); | 940 chromeos::SecureMemset(blob, 0, blob_size); |
| 977 Tspi_Context_FreeMemory(context_handle, blob); | |
| 978 data_out->swap(local_data); | 941 data_out->swap(local_data); |
| 979 return true; | 942 return true; |
| 980 } | 943 } |
| 981 | 944 |
| 982 bool Tpm::GetPublicKeyBlob(TSS_HCONTEXT context_handle, TSS_HKEY key_handle, | 945 bool Tpm::GetPublicKeyBlob(TSS_HCONTEXT context_handle, TSS_HKEY key_handle, |
| 983 SecureBlob* data_out, TSS_RESULT* result) { | 946 SecureBlob* data_out, TSS_RESULT* result) { |
| 984 *result = TSS_SUCCESS; | 947 *result = TSS_SUCCESS; |
| 985 | 948 |
| 986 BYTE *blob; | 949 ScopedTssMemory blob(context_handle); |
| 987 UINT32 blob_size; | 950 UINT32 blob_size; |
| 988 if ((*result = Tspi_Key_GetPubKey(key_handle, &blob_size, &blob))) { | 951 if (TPM_ERROR(*result = |
| 952 Tspi_Key_GetPubKey(key_handle, &blob_size, blob.ptr()))) { | |
| 989 TPM_LOG(ERROR, *result) << "Error calling Tspi_Key_GetPubKey"; | 953 TPM_LOG(ERROR, *result) << "Error calling Tspi_Key_GetPubKey"; |
| 990 return false; | 954 return false; |
| 991 } | 955 } |
| 992 | 956 |
| 993 SecureBlob local_data(blob_size); | 957 SecureBlob local_data(blob_size); |
| 994 memcpy(local_data.data(), blob, blob_size); | 958 memcpy(local_data.data(), blob, blob_size); |
| 995 chromeos::SecureMemset(blob, 0, blob_size); | 959 chromeos::SecureMemset(blob, 0, blob_size); |
| 996 Tspi_Context_FreeMemory(context_handle, blob); | |
| 997 data_out->swap(local_data); | 960 data_out->swap(local_data); |
| 998 return true; | 961 return true; |
| 999 } | 962 } |
| 1000 | 963 |
| 1001 bool Tpm::LoadKeyBlob(TSS_HCONTEXT context_handle, const SecureBlob& blob, | 964 bool Tpm::LoadKeyBlob(TSS_HCONTEXT context_handle, const SecureBlob& blob, |
| 1002 TSS_HKEY* key_handle, TSS_RESULT* result) { | 965 TSS_HKEY* key_handle, TSS_RESULT* result) { |
| 1003 *result = TSS_SUCCESS; | 966 *result = TSS_SUCCESS; |
| 1004 | 967 |
| 1005 TSS_HKEY srk_handle; | 968 ScopedTssKey srk_handle(context_handle); |
| 1006 if (!LoadSrk(context_handle, &srk_handle, result)) { | 969 if (!LoadSrk(context_handle, srk_handle.ptr(), result)) { |
| 1007 return false; | 970 return false; |
| 1008 } | 971 } |
| 1009 | 972 |
| 1010 TSS_HKEY local_key_handle = 0; | 973 ScopedTssKey local_key_handle(context_handle); |
| 1011 if ((*result = Tspi_Context_LoadKeyByBlob(context_handle, | 974 if (TPM_ERROR(*result = Tspi_Context_LoadKeyByBlob(context_handle, |
| 1012 srk_handle, | 975 srk_handle, |
| 1013 blob.size(), | 976 blob.size(), |
| 1014 const_cast<BYTE*>(static_cast<const BYTE*>(blob.const_data())), | 977 const_cast<BYTE*>( |
| 1015 &local_key_handle))) { | 978 static_cast<const BYTE*>( |
| 979 blob.const_data())), | |
| 980 local_key_handle.ptr()))) { | |
| 1016 TPM_LOG(ERROR, *result) << "Error calling Tspi_Context_LoadKeyByBlob"; | 981 TPM_LOG(ERROR, *result) << "Error calling Tspi_Context_LoadKeyByBlob"; |
| 1017 Tspi_Context_CloseObject(context_handle, srk_handle); | |
| 1018 return false; | 982 return false; |
| 1019 } | 983 } |
| 1020 | 984 |
| 1021 Tspi_Context_CloseObject(context_handle, srk_handle); | |
| 1022 | |
| 1023 unsigned int size_n; | 985 unsigned int size_n; |
| 1024 BYTE *public_key; | 986 ScopedTssMemory public_key(context_handle); |
| 1025 if ((*result = Tspi_Key_GetPubKey(local_key_handle, &size_n, &public_key))) { | 987 if (TPM_ERROR(*result = |
| 988 Tspi_Key_GetPubKey(local_key_handle, &size_n, public_key.ptr()))) { | |
| 1026 TPM_LOG(ERROR, *result) << "Error calling Tspi_Key_GetPubKey"; | 989 TPM_LOG(ERROR, *result) << "Error calling Tspi_Key_GetPubKey"; |
| 1027 Tspi_Context_CloseObject(context_handle, local_key_handle); | |
| 1028 return false; | 990 return false; |
| 1029 } | 991 } |
| 1030 Tspi_Context_FreeMemory(context_handle, public_key); | |
| 1031 | 992 |
| 1032 *key_handle = local_key_handle; | 993 *key_handle = local_key_handle.release(); |
| 1033 return true; | 994 return true; |
| 1034 } | 995 } |
| 1035 | 996 |
| 1036 bool Tpm::LoadSrk(TSS_HCONTEXT context_handle, TSS_HKEY* srk_handle, | 997 bool Tpm::LoadSrk(TSS_HCONTEXT context_handle, TSS_HKEY* srk_handle, |
| 1037 TSS_RESULT* result) { | 998 TSS_RESULT* result) { |
| 1038 *result = TSS_SUCCESS; | 999 *result = TSS_SUCCESS; |
| 1039 | 1000 |
| 1040 // Load the Storage Root Key | 1001 // Load the Storage Root Key |
| 1041 TSS_UUID SRK_UUID = TSS_UUID_SRK; | 1002 TSS_UUID SRK_UUID = TSS_UUID_SRK; |
| 1042 TSS_HKEY local_srk_handle; | 1003 ScopedTssKey local_srk_handle(context_handle); |
| 1043 if ((*result = Tspi_Context_LoadKeyByUUID(context_handle, TSS_PS_TYPE_SYSTEM, | 1004 if (TPM_ERROR(*result = Tspi_Context_LoadKeyByUUID(context_handle, |
| 1044 SRK_UUID, &local_srk_handle))) { | 1005 TSS_PS_TYPE_SYSTEM, |
| 1006 SRK_UUID, | |
| 1007 local_srk_handle.ptr()))) { | |
| 1045 return false; | 1008 return false; |
| 1046 } | 1009 } |
| 1047 | 1010 |
| 1048 // Check if the SRK wants a password | 1011 // Check if the SRK wants a password |
| 1049 UINT32 srk_authusage; | 1012 UINT32 srk_authusage; |
| 1050 if ((*result = Tspi_GetAttribUint32(local_srk_handle, TSS_TSPATTRIB_KEY_INFO, | 1013 if (TPM_ERROR(*result = Tspi_GetAttribUint32(local_srk_handle, |
| 1051 TSS_TSPATTRIB_KEYINFO_AUTHUSAGE, | 1014 TSS_TSPATTRIB_KEY_INFO, |
| 1052 &srk_authusage))) { | 1015 TSS_TSPATTRIB_KEYINFO_AUTHUSAGE, |
| 1053 Tspi_Context_CloseObject(context_handle, local_srk_handle); | 1016 &srk_authusage))) { |
| 1054 return false; | 1017 return false; |
| 1055 } | 1018 } |
| 1056 | 1019 |
| 1057 // Give it the password if needed | 1020 // Give it the password if needed |
| 1058 if (srk_authusage) { | 1021 if (srk_authusage) { |
| 1059 TSS_HPOLICY srk_usage_policy; | 1022 TSS_HPOLICY srk_usage_policy; |
| 1060 if ((*result = Tspi_GetPolicyObject(local_srk_handle, TSS_POLICY_USAGE, | 1023 if (TPM_ERROR(*result = Tspi_GetPolicyObject(local_srk_handle, |
| 1061 &srk_usage_policy))) { | 1024 TSS_POLICY_USAGE, |
| 1062 Tspi_Context_CloseObject(context_handle, local_srk_handle); | 1025 &srk_usage_policy))) { |
| 1063 return false; | 1026 return false; |
| 1064 } | 1027 } |
| 1065 | 1028 |
| 1066 if ((*result = Tspi_Policy_SetSecret(srk_usage_policy, | 1029 *result = Tspi_Policy_SetSecret(srk_usage_policy, |
| 1067 TSS_SECRET_MODE_PLAIN, | 1030 TSS_SECRET_MODE_PLAIN, |
| 1068 srk_auth_.size(), | 1031 srk_auth_.size(), |
| 1069 const_cast<BYTE *>(static_cast<const BYTE *>( | 1032 const_cast<BYTE *>( |
| 1070 srk_auth_.const_data()))))) { | 1033 static_cast<const BYTE *>( |
| 1071 Tspi_Context_CloseObject(context_handle, local_srk_handle); | 1034 srk_auth_.const_data()))); |
| 1035 if (TPM_ERROR(*result)) { | |
| 1072 return false; | 1036 return false; |
| 1073 } | 1037 } |
| 1074 } | 1038 } |
| 1075 | 1039 |
| 1076 *srk_handle = local_srk_handle; | 1040 *srk_handle = local_srk_handle.release(); |
| 1077 return true; | 1041 return true; |
| 1078 } | 1042 } |
| 1079 | 1043 |
| 1080 bool Tpm::IsDisabledCheckViaSysfs() { | 1044 bool Tpm::IsDisabledCheckViaSysfs() { |
| 1081 std::string contents; | 1045 std::string contents; |
| 1082 if (!file_util::ReadFileToString(FilePath(kTpmCheckEnabledFile), &contents)) { | 1046 if (!file_util::ReadFileToString(FilePath(kTpmCheckEnabledFile), &contents)) { |
| 1083 return false; | 1047 return false; |
| 1084 } | 1048 } |
| 1085 if (contents.size() < 1) { | 1049 if (contents.size() < 1) { |
| 1086 return false; | 1050 return false; |
| (...skipping 18 matching lines...) Expand all Loading... | |
| 1105 *owned = false; | 1069 *owned = false; |
| 1106 | 1070 |
| 1107 TSS_RESULT result; | 1071 TSS_RESULT result; |
| 1108 TSS_HTPM tpm_handle; | 1072 TSS_HTPM tpm_handle; |
| 1109 if (!GetTpm(context_handle, &tpm_handle)) { | 1073 if (!GetTpm(context_handle, &tpm_handle)) { |
| 1110 return; | 1074 return; |
| 1111 } | 1075 } |
| 1112 | 1076 |
| 1113 UINT32 sub_cap = TSS_TPMCAP_PROP_OWNER; | 1077 UINT32 sub_cap = TSS_TPMCAP_PROP_OWNER; |
| 1114 UINT32 cap_length = 0; | 1078 UINT32 cap_length = 0; |
| 1115 BYTE* cap = NULL; | 1079 ScopedTssMemory cap(context_handle); |
| 1116 if ((result = Tspi_TPM_GetCapability(tpm_handle, TSS_TPMCAP_PROPERTY, | 1080 if (TPM_ERROR(result = Tspi_TPM_GetCapability(tpm_handle, TSS_TPMCAP_PROPERTY, |
| 1117 sizeof(sub_cap), | 1081 sizeof(sub_cap), |
| 1118 reinterpret_cast<BYTE*>(&sub_cap), | 1082 reinterpret_cast<BYTE*>(&sub_cap), |
| 1119 &cap_length, &cap)) == 0) { | 1083 &cap_length, cap.ptr())) == 0) { |
| 1120 if (cap_length >= (sizeof(TSS_BOOL))) { | 1084 if (cap_length >= (sizeof(TSS_BOOL))) { |
| 1121 *enabled = true; | 1085 *enabled = true; |
| 1122 *owned = ((*(reinterpret_cast<TSS_BOOL*>(cap))) != 0); | 1086 *owned = ((*(reinterpret_cast<TSS_BOOL*>(*cap))) != 0); |
| 1123 } | 1087 } |
| 1124 Tspi_Context_FreeMemory(context_handle, cap); | |
| 1125 } else if(ERROR_CODE(result) == TPM_E_DISABLED) { | 1088 } else if(ERROR_CODE(result) == TPM_E_DISABLED) { |
| 1126 *enabled = false; | 1089 *enabled = false; |
| 1127 } | 1090 } |
| 1128 } | 1091 } |
| 1129 | 1092 |
| 1130 bool Tpm::CreateEndorsementKey(TSS_HCONTEXT context_handle) { | 1093 bool Tpm::CreateEndorsementKey(TSS_HCONTEXT context_handle) { |
| 1131 TSS_RESULT result; | 1094 TSS_RESULT result; |
| 1132 TSS_HTPM tpm_handle; | 1095 TSS_HTPM tpm_handle; |
| 1133 if (!GetTpm(context_handle, &tpm_handle)) { | 1096 if (!GetTpm(context_handle, &tpm_handle)) { |
| 1134 return false; | 1097 return false; |
| 1135 } | 1098 } |
| 1136 | 1099 |
| 1137 TSS_HKEY local_key_handle; | 1100 ScopedTssKey local_key_handle(context_handle); |
| 1138 TSS_FLAG init_flags = TSS_KEY_TYPE_LEGACY | TSS_KEY_SIZE_2048; | 1101 TSS_FLAG init_flags = TSS_KEY_TYPE_LEGACY | TSS_KEY_SIZE_2048; |
| 1139 if ((result = Tspi_Context_CreateObject(context_handle, | 1102 if (TPM_ERROR(result = Tspi_Context_CreateObject(context_handle, |
| 1140 TSS_OBJECT_TYPE_RSAKEY, | 1103 TSS_OBJECT_TYPE_RSAKEY, |
| 1141 init_flags, &local_key_handle))) { | 1104 init_flags, |
| 1105 local_key_handle.ptr()))) { | |
| 1142 TPM_LOG(ERROR, result) << "Error calling Tspi_Context_CreateObject"; | 1106 TPM_LOG(ERROR, result) << "Error calling Tspi_Context_CreateObject"; |
| 1143 return false; | 1107 return false; |
| 1144 } | 1108 } |
| 1145 | 1109 |
| 1146 if ((result = Tspi_TPM_CreateEndorsementKey(tpm_handle, local_key_handle, | 1110 if (TPM_ERROR(result = Tspi_TPM_CreateEndorsementKey(tpm_handle, |
| 1147 NULL))) { | 1111 local_key_handle, |
| 1112 NULL))) { | |
| 1148 TPM_LOG(ERROR, result) << "Error calling Tspi_TPM_CreateEndorsementKey"; | 1113 TPM_LOG(ERROR, result) << "Error calling Tspi_TPM_CreateEndorsementKey"; |
| 1149 Tspi_Context_CloseObject(context_handle, local_key_handle); | |
| 1150 return false; | 1114 return false; |
| 1151 } | 1115 } |
| 1152 | 1116 |
| 1153 return true; | 1117 return true; |
| 1154 } | 1118 } |
| 1155 | 1119 |
| 1156 bool Tpm::IsEndorsementKeyAvailable(TSS_HCONTEXT context_handle) { | 1120 bool Tpm::IsEndorsementKeyAvailable(TSS_HCONTEXT context_handle) { |
| 1157 TSS_RESULT result; | 1121 TSS_RESULT result; |
| 1158 TSS_HTPM tpm_handle; | 1122 TSS_HTPM tpm_handle; |
| 1159 if (!GetTpm(context_handle, &tpm_handle)) { | 1123 if (!GetTpm(context_handle, &tpm_handle)) { |
| 1160 return false; | 1124 return false; |
| 1161 } | 1125 } |
| 1162 | 1126 |
| 1163 TSS_HKEY local_key_handle; | 1127 ScopedTssKey local_key_handle(context_handle); |
| 1164 if ((result = Tspi_TPM_GetPubEndorsementKey(tpm_handle, false, NULL, | 1128 if (TPM_ERROR(result = Tspi_TPM_GetPubEndorsementKey(tpm_handle, false, NULL, |
| 1165 &local_key_handle))) { | 1129 local_key_handle.ptr()))) { |
| 1166 TPM_LOG(ERROR, result) << "Error calling Tspi_TPM_GetPubEndorsementKey"; | 1130 TPM_LOG(ERROR, result) << "Error calling Tspi_TPM_GetPubEndorsementKey"; |
| 1167 return false; | 1131 return false; |
| 1168 } | 1132 } |
| 1169 | 1133 |
| 1170 Tspi_Context_CloseObject(context_handle, local_key_handle); | |
| 1171 | |
| 1172 return true; | 1134 return true; |
| 1173 } | 1135 } |
| 1174 | 1136 |
| 1175 void Tpm::CreateOwnerPassword(SecureBlob* password) { | 1137 void Tpm::CreateOwnerPassword(SecureBlob* password) { |
| 1176 // Generate a random owner password. The default is a 12-character, | 1138 // Generate a random owner password. The default is a 12-character, |
| 1177 // hex-encoded password created from 6 bytes of random data. | 1139 // hex-encoded password created from 6 bytes of random data. |
| 1178 SecureBlob random(kOwnerPasswordLength / 2); | 1140 SecureBlob random(kOwnerPasswordLength / 2); |
| 1179 crypto_->GetSecureRandom(static_cast<unsigned char*>(random.data()), | 1141 crypto_->GetSecureRandom(static_cast<unsigned char*>(random.data()), |
| 1180 random.size()); | 1142 random.size()); |
| 1181 SecureBlob tpm_password(kOwnerPasswordLength); | 1143 SecureBlob tpm_password(kOwnerPasswordLength); |
| 1182 crypto_->AsciiEncodeToBuffer(random, static_cast<char*>(tpm_password.data()), | 1144 crypto_->AsciiEncodeToBuffer(random, static_cast<char*>(tpm_password.data()), |
| 1183 tpm_password.size()); | 1145 tpm_password.size()); |
| 1184 password->swap(tpm_password); | 1146 password->swap(tpm_password); |
| 1185 } | 1147 } |
| 1186 | 1148 |
| 1187 bool Tpm::TakeOwnership(TSS_HCONTEXT context_handle, int max_timeout_tries, | 1149 bool Tpm::TakeOwnership(TSS_HCONTEXT context_handle, int max_timeout_tries, |
| 1188 const SecureBlob& owner_password) { | 1150 const SecureBlob& owner_password) { |
| 1189 TSS_RESULT result; | 1151 TSS_RESULT result; |
| 1190 TSS_HTPM tpm_handle; | 1152 TSS_HTPM tpm_handle; |
| 1191 if (!GetTpmWithAuth(context_handle, owner_password, &tpm_handle)) { | 1153 if (!GetTpmWithAuth(context_handle, owner_password, &tpm_handle)) { |
| 1192 return false; | 1154 return false; |
| 1193 } | 1155 } |
| 1194 | 1156 |
| 1195 TSS_HKEY srk_handle; | 1157 ScopedTssKey srk_handle(context_handle); |
| 1196 TSS_FLAG init_flags = TSS_KEY_TSP_SRK | TSS_KEY_AUTHORIZATION; | 1158 TSS_FLAG init_flags = TSS_KEY_TSP_SRK | TSS_KEY_AUTHORIZATION; |
| 1197 if ((result = Tspi_Context_CreateObject(context_handle, | 1159 if (TPM_ERROR(result = Tspi_Context_CreateObject(context_handle, |
| 1198 TSS_OBJECT_TYPE_RSAKEY, | 1160 TSS_OBJECT_TYPE_RSAKEY, |
| 1199 init_flags, &srk_handle))) { | 1161 init_flags, srk_handle.ptr()))) { |
| 1200 TPM_LOG(ERROR, result) << "Error calling Tspi_Context_CreateObject"; | 1162 TPM_LOG(ERROR, result) << "Error calling Tspi_Context_CreateObject"; |
| 1201 return false; | 1163 return false; |
| 1202 } | 1164 } |
| 1203 | 1165 |
| 1204 TSS_HPOLICY srk_usage_policy; | 1166 TSS_HPOLICY srk_usage_policy; |
| 1205 if ((result = Tspi_GetPolicyObject(srk_handle, TSS_POLICY_USAGE, | 1167 if (TPM_ERROR(result = Tspi_GetPolicyObject(srk_handle, TSS_POLICY_USAGE, |
| 1206 &srk_usage_policy))) { | 1168 &srk_usage_policy))) { |
| 1207 TPM_LOG(ERROR, result) << "Error calling Tspi_GetPolicyObject"; | 1169 TPM_LOG(ERROR, result) << "Error calling Tspi_GetPolicyObject"; |
| 1208 Tspi_Context_CloseObject(context_handle, srk_handle); | |
| 1209 return false; | 1170 return false; |
| 1210 } | 1171 } |
| 1211 | 1172 |
| 1212 if ((result = Tspi_Policy_SetSecret(srk_usage_policy, | 1173 if (TPM_ERROR(result = Tspi_Policy_SetSecret(srk_usage_policy, |
| 1213 TSS_SECRET_MODE_PLAIN, | 1174 TSS_SECRET_MODE_PLAIN, |
| 1214 strlen(kWellKnownSrkTmp), | 1175 strlen(kWellKnownSrkTmp), |
| 1215 const_cast<BYTE *>(reinterpret_cast<const BYTE *>(kWellKnownSrkTmp))))) { | 1176 const_cast<BYTE *>(reinterpret_cast<const BYTE *>(kWellKnownSrkTmp))))) { |
| 1216 TPM_LOG(ERROR, result) << "Error calling Tspi_Policy_SetSecret"; | 1177 TPM_LOG(ERROR, result) << "Error calling Tspi_Policy_SetSecret"; |
| 1217 Tspi_Context_CloseObject(context_handle, srk_handle); | |
| 1218 return false; | 1178 return false; |
| 1219 } | 1179 } |
| 1220 | 1180 |
| 1221 int retry_count = 0; | 1181 int retry_count = 0; |
| 1222 do { | 1182 do { |
| 1223 result = Tspi_TPM_TakeOwnership(tpm_handle, srk_handle, 0); | 1183 result = Tspi_TPM_TakeOwnership(tpm_handle, srk_handle, 0); |
| 1224 retry_count++; | 1184 retry_count++; |
| 1225 } while(((result == TDDL_E_TIMEOUT) || | 1185 } while(((result == TDDL_E_TIMEOUT) || |
| 1226 (result == (TSS_LAYER_TDDL | TDDL_E_TIMEOUT)) || | 1186 (result == (TSS_LAYER_TDDL | TDDL_E_TIMEOUT)) || |
| 1227 (result == (TSS_LAYER_TDDL | TDDL_E_IOERROR))) && | 1187 (result == (TSS_LAYER_TDDL | TDDL_E_IOERROR))) && |
| 1228 (retry_count < max_timeout_tries)); | 1188 (retry_count < max_timeout_tries)); |
| 1229 | 1189 |
| 1230 if (result) { | 1190 if (result) { |
| 1231 TPM_LOG(ERROR, result) | 1191 TPM_LOG(ERROR, result) |
| 1232 << "Error calling Tspi_TPM_TakeOwnership, attempts: " << retry_count; | 1192 << "Error calling Tspi_TPM_TakeOwnership, attempts: " << retry_count; |
| 1233 Tspi_Context_CloseObject(context_handle, srk_handle); | |
| 1234 return false; | 1193 return false; |
| 1235 } | 1194 } |
| 1236 | 1195 |
| 1237 Tspi_Context_CloseObject(context_handle, srk_handle); | |
| 1238 | |
| 1239 return true; | 1196 return true; |
| 1240 } | 1197 } |
| 1241 | 1198 |
| 1242 bool Tpm::ZeroSrkPassword(TSS_HCONTEXT context_handle, | 1199 bool Tpm::ZeroSrkPassword(TSS_HCONTEXT context_handle, |
| 1243 const SecureBlob& owner_password) { | 1200 const SecureBlob& owner_password) { |
| 1244 TSS_RESULT result; | 1201 TSS_RESULT result; |
| 1245 TSS_HTPM tpm_handle; | 1202 TSS_HTPM tpm_handle; |
| 1246 if (!GetTpmWithAuth(context_handle, owner_password, &tpm_handle)) { | 1203 if (!GetTpmWithAuth(context_handle, owner_password, &tpm_handle)) { |
| 1247 return false; | 1204 return false; |
| 1248 } | 1205 } |
| 1249 | 1206 |
| 1250 TSS_HKEY srk_handle; | 1207 ScopedTssKey srk_handle(context_handle); |
| 1251 TSS_UUID SRK_UUID = TSS_UUID_SRK; | 1208 TSS_UUID SRK_UUID = TSS_UUID_SRK; |
| 1252 if ((result = Tspi_Context_LoadKeyByUUID(context_handle, TSS_PS_TYPE_SYSTEM, | 1209 if (TPM_ERROR(result = Tspi_Context_LoadKeyByUUID(context_handle, |
| 1253 SRK_UUID, &srk_handle))) { | 1210 TSS_PS_TYPE_SYSTEM, |
| 1211 SRK_UUID, | |
| 1212 srk_handle.ptr()))) { | |
| 1254 TPM_LOG(ERROR, result) << "Error calling Tspi_Context_LoadKeyByUUID"; | 1213 TPM_LOG(ERROR, result) << "Error calling Tspi_Context_LoadKeyByUUID"; |
| 1255 return false; | 1214 return false; |
| 1256 } | 1215 } |
| 1257 | 1216 |
| 1258 TSS_HPOLICY policy_handle; | 1217 ScopedTssPolicy policy_handle(context_handle); |
| 1259 if ((result = Tspi_Context_CreateObject(context_handle, | 1218 if (TPM_ERROR(result = Tspi_Context_CreateObject(context_handle, |
| 1260 TSS_OBJECT_TYPE_POLICY, | 1219 TSS_OBJECT_TYPE_POLICY, |
| 1261 TSS_POLICY_USAGE, | 1220 TSS_POLICY_USAGE, |
| 1262 &policy_handle))) { | 1221 policy_handle.ptr()))) { |
| 1263 TPM_LOG(ERROR, result) << "Error calling Tspi_Context_CreateObject"; | 1222 TPM_LOG(ERROR, result) << "Error calling Tspi_Context_CreateObject"; |
| 1264 Tspi_Context_CloseObject(context_handle, srk_handle); | |
| 1265 return false; | 1223 return false; |
| 1266 } | 1224 } |
| 1267 | 1225 |
| 1268 BYTE new_password[0]; | 1226 BYTE new_password[0]; |
| 1269 if ((result = Tspi_Policy_SetSecret(policy_handle, TSS_SECRET_MODE_PLAIN, | 1227 if (TPM_ERROR(result = Tspi_Policy_SetSecret(policy_handle, |
| 1270 0, new_password))) { | 1228 TSS_SECRET_MODE_PLAIN, |
| 1229 0, | |
| 1230 new_password))) { | |
| 1271 TPM_LOG(ERROR, result) << "Error calling Tspi_Policy_SetSecret"; | 1231 TPM_LOG(ERROR, result) << "Error calling Tspi_Policy_SetSecret"; |
| 1272 Tspi_Context_CloseObject(context_handle, policy_handle); | |
| 1273 Tspi_Context_CloseObject(context_handle, srk_handle); | |
| 1274 return false; | 1232 return false; |
| 1275 } | 1233 } |
| 1276 | 1234 |
| 1277 if ((result = Tspi_ChangeAuth(srk_handle, | 1235 if (TPM_ERROR(result = Tspi_ChangeAuth(srk_handle, |
| 1278 tpm_handle, | 1236 tpm_handle, |
| 1279 policy_handle))) { | 1237 policy_handle))) { |
| 1280 TPM_LOG(ERROR, result) << "Error calling Tspi_ChangeAuth"; | 1238 TPM_LOG(ERROR, result) << "Error calling Tspi_ChangeAuth"; |
| 1281 Tspi_Context_CloseObject(context_handle, policy_handle); | |
| 1282 Tspi_Context_CloseObject(context_handle, srk_handle); | |
| 1283 return false; | 1239 return false; |
| 1284 } | 1240 } |
| 1285 | 1241 |
| 1286 Tspi_Context_CloseObject(context_handle, policy_handle); | |
| 1287 Tspi_Context_CloseObject(context_handle, srk_handle); | |
| 1288 return true; | 1242 return true; |
| 1289 } | 1243 } |
| 1290 | 1244 |
| 1291 bool Tpm::UnrestrictSrk(TSS_HCONTEXT context_handle, | 1245 bool Tpm::UnrestrictSrk(TSS_HCONTEXT context_handle, |
| 1292 const SecureBlob& owner_password) { | 1246 const SecureBlob& owner_password) { |
| 1293 TSS_RESULT result; | 1247 TSS_RESULT result; |
| 1294 TSS_HTPM tpm_handle; | 1248 TSS_HTPM tpm_handle; |
| 1295 if (!GetTpmWithAuth(context_handle, owner_password, &tpm_handle)) { | 1249 if (!GetTpmWithAuth(context_handle, owner_password, &tpm_handle)) { |
| 1296 return false; | 1250 return false; |
| 1297 } | 1251 } |
| 1298 | 1252 |
| 1299 TSS_BOOL current_status = false; | 1253 TSS_BOOL current_status = false; |
| 1300 | 1254 |
| 1301 if ((result = Tspi_TPM_GetStatus(tpm_handle, | 1255 if (TPM_ERROR(result = Tspi_TPM_GetStatus(tpm_handle, |
| 1302 TSS_TPMSTATUS_DISABLEPUBSRKREAD, | 1256 TSS_TPMSTATUS_DISABLEPUBSRKREAD, |
| 1303 ¤t_status))) { | 1257 ¤t_status))) { |
| 1304 TPM_LOG(ERROR, result) << "Error calling Tspi_TPM_GetStatus"; | 1258 TPM_LOG(ERROR, result) << "Error calling Tspi_TPM_GetStatus"; |
| 1305 return false; | 1259 return false; |
| 1306 } | 1260 } |
| 1307 | 1261 |
| 1308 // If it is currently owner auth (true), set it to SRK auth | 1262 // If it is currently owner auth (true), set it to SRK auth |
| 1309 if (current_status) { | 1263 if (current_status) { |
| 1310 if ((result = Tspi_TPM_SetStatus(tpm_handle, | 1264 if (TPM_ERROR(result = Tspi_TPM_SetStatus(tpm_handle, |
| 1311 TSS_TPMSTATUS_DISABLEPUBSRKREAD, | 1265 TSS_TPMSTATUS_DISABLEPUBSRKREAD, |
| 1312 false))) { | 1266 false))) { |
| 1313 TPM_LOG(ERROR, result) << "Error calling Tspi_TPM_SetStatus"; | 1267 TPM_LOG(ERROR, result) << "Error calling Tspi_TPM_SetStatus"; |
| 1314 return false; | 1268 return false; |
| 1315 } | 1269 } |
| 1316 } | 1270 } |
| 1317 | 1271 |
| 1318 return true; | 1272 return true; |
| 1319 } | 1273 } |
| 1320 | 1274 |
| 1321 bool Tpm::ChangeOwnerPassword(TSS_HCONTEXT context_handle, | 1275 bool Tpm::ChangeOwnerPassword(TSS_HCONTEXT context_handle, |
| 1322 const SecureBlob& previous_owner_password, | 1276 const SecureBlob& previous_owner_password, |
| 1323 const SecureBlob& owner_password) { | 1277 const SecureBlob& owner_password) { |
| 1324 TSS_RESULT result; | 1278 TSS_RESULT result; |
| 1325 TSS_HTPM tpm_handle; | 1279 TSS_HTPM tpm_handle; |
| 1326 if (!GetTpmWithAuth(context_handle, previous_owner_password, &tpm_handle)) { | 1280 if (!GetTpmWithAuth(context_handle, previous_owner_password, &tpm_handle)) { |
| 1327 return false; | 1281 return false; |
| 1328 } | 1282 } |
| 1329 | 1283 |
| 1330 TSS_HPOLICY policy_handle; | 1284 ScopedTssPolicy policy_handle(context_handle); |
| 1331 if ((result = Tspi_Context_CreateObject(context_handle, | 1285 if (TPM_ERROR(result = Tspi_Context_CreateObject(context_handle, |
| 1332 TSS_OBJECT_TYPE_POLICY, | 1286 TSS_OBJECT_TYPE_POLICY, |
| 1333 TSS_POLICY_USAGE, | 1287 TSS_POLICY_USAGE, |
| 1334 &policy_handle))) { | 1288 policy_handle.ptr()))) { |
| 1335 TPM_LOG(ERROR, result) << "Error calling Tspi_Context_CreateObject"; | 1289 TPM_LOG(ERROR, result) << "Error calling Tspi_Context_CreateObject"; |
| 1336 return false; | 1290 return false; |
| 1337 } | 1291 } |
| 1338 | 1292 |
| 1339 if ((result = Tspi_Policy_SetSecret(policy_handle, | 1293 if (TPM_ERROR(result = Tspi_Policy_SetSecret(policy_handle, |
| 1340 TSS_SECRET_MODE_PLAIN, | 1294 TSS_SECRET_MODE_PLAIN, |
| 1341 owner_password.size(), | 1295 owner_password.size(), |
| 1342 const_cast<BYTE *>(static_cast<const BYTE *>( | 1296 const_cast<BYTE *>(static_cast<const BYTE *>( |
| 1343 owner_password.const_data()))))) { | 1297 owner_password.const_data()))))) { |
| 1344 TPM_LOG(ERROR, result) << "Error calling Tspi_Policy_SetSecret"; | 1298 TPM_LOG(ERROR, result) << "Error calling Tspi_Policy_SetSecret"; |
| 1345 Tspi_Context_CloseObject(context_handle, policy_handle); | |
| 1346 return false; | 1299 return false; |
| 1347 } | 1300 } |
| 1348 | 1301 |
| 1349 if ((result = Tspi_ChangeAuth(tpm_handle, 0, policy_handle))) { | 1302 if (TPM_ERROR(result = Tspi_ChangeAuth(tpm_handle, 0, policy_handle))) { |
| 1350 TPM_LOG(ERROR, result) << "Error calling Tspi_ChangeAuth"; | 1303 TPM_LOG(ERROR, result) << "Error calling Tspi_ChangeAuth"; |
| 1351 Tspi_Context_CloseObject(context_handle, policy_handle); | |
| 1352 return false; | 1304 return false; |
| 1353 } | 1305 } |
| 1354 | 1306 |
| 1355 Tspi_Context_CloseObject(context_handle, policy_handle); | |
| 1356 return true; | 1307 return true; |
| 1357 } | 1308 } |
| 1358 | 1309 |
| 1359 bool Tpm::LoadOwnerPassword(const TpmStatus& tpm_status, | 1310 bool Tpm::LoadOwnerPassword(const TpmStatus& tpm_status, |
| 1360 chromeos::Blob* owner_password) { | 1311 chromeos::Blob* owner_password) { |
| 1361 if (!(tpm_status.flags() & TpmStatus::OWNED_BY_THIS_INSTALL)) { | 1312 if (!(tpm_status.flags() & TpmStatus::OWNED_BY_THIS_INSTALL)) { |
| 1362 return false; | 1313 return false; |
| 1363 } | 1314 } |
| 1364 if ((tpm_status.flags() & TpmStatus::USES_WELL_KNOWN_OWNER)) { | 1315 if ((tpm_status.flags() & TpmStatus::USES_WELL_KNOWN_OWNER)) { |
| 1365 SecureBlob default_owner_password(sizeof(kTpmWellKnownPassword)); | 1316 SecureBlob default_owner_password(sizeof(kTpmWellKnownPassword)); |
| 1366 memcpy(default_owner_password.data(), kTpmWellKnownPassword, | 1317 memcpy(default_owner_password.data(), kTpmWellKnownPassword, |
| 1367 sizeof(kTpmWellKnownPassword)); | 1318 sizeof(kTpmWellKnownPassword)); |
| 1368 owner_password->swap(default_owner_password); | 1319 owner_password->swap(default_owner_password); |
| 1369 return true; | 1320 return true; |
| 1370 } | 1321 } |
| 1371 if (!(tpm_status.flags() & TpmStatus::USES_RANDOM_OWNER) || | 1322 if (!(tpm_status.flags() & TpmStatus::USES_RANDOM_OWNER) || |
| 1372 !tpm_status.has_owner_password()) { | 1323 !tpm_status.has_owner_password()) { |
| 1373 return false; | 1324 return false; |
| 1374 } | 1325 } |
| 1375 | 1326 |
| 1376 TSS_HCONTEXT context_handle; | 1327 ScopedTssContext context_handle; |
| 1377 if ((context_handle = ConnectContext()) == 0) { | 1328 if ((*(context_handle.ptr()) = ConnectContext()) == 0) { |
| 1378 return false; | 1329 return false; |
| 1379 } | 1330 } |
| 1380 | 1331 |
| 1381 TSS_RESULT result; | 1332 TSS_RESULT result; |
| 1382 TSS_HKEY srk_handle; | 1333 ScopedTssKey srk_handle(context_handle); |
| 1383 if (!LoadSrk(context_handle, &srk_handle, &result)) { | 1334 if (!LoadSrk(context_handle, srk_handle.ptr(), &result)) { |
| 1384 LOG(ERROR) << "Error loading the SRK"; | 1335 LOG(ERROR) << "Error loading the SRK"; |
| 1385 Tspi_Context_Close(context_handle); | |
| 1386 return false; | 1336 return false; |
| 1387 } | 1337 } |
| 1388 | 1338 |
| 1389 TSS_FLAG init_flags = TSS_ENCDATA_SEAL; | 1339 TSS_FLAG init_flags = TSS_ENCDATA_SEAL; |
| 1390 TSS_HKEY enc_handle; | 1340 ScopedTssKey enc_handle(context_handle); |
| 1391 if ((result = Tspi_Context_CreateObject(context_handle, | 1341 if (TPM_ERROR(result = Tspi_Context_CreateObject(context_handle, |
| 1392 TSS_OBJECT_TYPE_ENCDATA, | 1342 TSS_OBJECT_TYPE_ENCDATA, |
| 1393 init_flags, &enc_handle))) { | 1343 init_flags, |
| 1344 enc_handle.ptr()))) { | |
| 1394 TPM_LOG(ERROR, result) << "Error calling Tspi_Context_CreateObject"; | 1345 TPM_LOG(ERROR, result) << "Error calling Tspi_Context_CreateObject"; |
| 1395 Tspi_Context_CloseObject(context_handle, srk_handle); | |
| 1396 Tspi_Context_Close(context_handle); | |
| 1397 return false; | 1346 return false; |
| 1398 } | 1347 } |
| 1399 | 1348 |
| 1400 SecureBlob local_owner_password(tpm_status.owner_password().length()); | 1349 SecureBlob local_owner_password(tpm_status.owner_password().length()); |
| 1401 tpm_status.owner_password().copy( | 1350 tpm_status.owner_password().copy( |
| 1402 static_cast<char*>(local_owner_password.data()), | 1351 static_cast<char*>(local_owner_password.data()), |
| 1403 tpm_status.owner_password().length(), 0); | 1352 tpm_status.owner_password().length(), 0); |
| 1404 | 1353 |
| 1405 if ((result = Tspi_SetAttribData(enc_handle, | 1354 if (TPM_ERROR(result = Tspi_SetAttribData(enc_handle, |
| 1406 TSS_TSPATTRIB_ENCDATA_BLOB, | 1355 TSS_TSPATTRIB_ENCDATA_BLOB, |
| 1407 TSS_TSPATTRIB_ENCDATABLOB_BLOB, | 1356 TSS_TSPATTRIB_ENCDATABLOB_BLOB, |
| 1408 local_owner_password.size(), | 1357 local_owner_password.size(), |
| 1409 static_cast<BYTE *>(local_owner_password.data())))) { | 1358 static_cast<BYTE *>(local_owner_password.data())))) { |
| 1410 TPM_LOG(ERROR, result) << "Error calling Tspi_SetAttribData"; | 1359 TPM_LOG(ERROR, result) << "Error calling Tspi_SetAttribData"; |
| 1411 Tspi_Context_CloseObject(context_handle, enc_handle); | |
| 1412 Tspi_Context_CloseObject(context_handle, srk_handle); | |
| 1413 Tspi_Context_Close(context_handle); | |
| 1414 return false; | 1360 return false; |
| 1415 } | 1361 } |
| 1416 | 1362 |
| 1417 unsigned char* dec_data = NULL; | 1363 ScopedTssMemory dec_data(context_handle); |
| 1418 UINT32 dec_data_length = 0; | 1364 UINT32 dec_data_length = 0; |
| 1419 if ((result = Tspi_Data_Unseal(enc_handle, srk_handle, &dec_data_length, | 1365 if (TPM_ERROR(result = Tspi_Data_Unseal(enc_handle, |
| 1420 &dec_data))) { | 1366 srk_handle, |
| 1367 &dec_data_length, | |
| 1368 dec_data.ptr()))) { | |
| 1421 TPM_LOG(ERROR, result) << "Error calling Tspi_Data_Unseal"; | 1369 TPM_LOG(ERROR, result) << "Error calling Tspi_Data_Unseal"; |
| 1422 Tspi_Context_CloseObject(context_handle, enc_handle); | |
| 1423 Tspi_Context_CloseObject(context_handle, srk_handle); | |
| 1424 Tspi_Context_Close(context_handle); | |
| 1425 return false; | 1370 return false; |
| 1426 } | 1371 } |
| 1427 | 1372 |
| 1428 Tspi_Context_CloseObject(context_handle, enc_handle); | |
| 1429 | |
| 1430 SecureBlob local_data(dec_data_length); | 1373 SecureBlob local_data(dec_data_length); |
| 1431 memcpy(static_cast<char*>(local_data.data()), dec_data, dec_data_length); | 1374 memcpy(static_cast<char*>(local_data.data()), dec_data, dec_data_length); |
| 1432 Tspi_Context_FreeMemory(context_handle, dec_data); | |
| 1433 | |
| 1434 Tspi_Context_CloseObject(context_handle, srk_handle); | |
| 1435 Tspi_Context_Close(context_handle); | |
| 1436 | |
| 1437 owner_password->swap(local_data); | 1375 owner_password->swap(local_data); |
| 1438 | 1376 |
| 1439 return true; | 1377 return true; |
| 1440 } | 1378 } |
| 1441 | 1379 |
| 1442 bool Tpm::StoreOwnerPassword(const chromeos::Blob& owner_password, | 1380 bool Tpm::StoreOwnerPassword(const chromeos::Blob& owner_password, |
| 1443 TpmStatus* tpm_status) { | 1381 TpmStatus* tpm_status) { |
| 1444 TSS_HCONTEXT context_handle; | 1382 ScopedTssContext context_handle; |
| 1445 if ((context_handle = ConnectContext()) == 0) { | 1383 if ((*(context_handle.ptr()) = ConnectContext()) == 0) { |
| 1446 return false; | 1384 return false; |
| 1447 } | 1385 } |
| 1448 | 1386 |
| 1449 TSS_RESULT result; | 1387 TSS_RESULT result; |
| 1450 TSS_HKEY srk_handle; | 1388 ScopedTssKey srk_handle(context_handle); |
| 1451 if (!LoadSrk(context_handle, &srk_handle, &result)) { | 1389 if (!LoadSrk(context_handle, srk_handle.ptr(), &result)) { |
| 1452 LOG(ERROR) << "Error loading the SRK"; | 1390 LOG(ERROR) << "Error loading the SRK"; |
| 1453 DisconnectContext(context_handle); | |
| 1454 return false; | 1391 return false; |
| 1455 } | 1392 } |
| 1456 | 1393 |
| 1457 // Check the SRK public key | 1394 // Check the SRK public key |
| 1458 unsigned int size_n; | 1395 unsigned int size_n; |
| 1459 BYTE *public_srk; | 1396 ScopedTssMemory public_srk(context_handle); |
| 1460 if ((result = Tspi_Key_GetPubKey(srk_handle, &size_n, &public_srk))) { | 1397 if (TPM_ERROR(result = |
| 1398 Tspi_Key_GetPubKey(srk_handle, &size_n, public_srk.ptr()))) { | |
| 1461 TPM_LOG(ERROR, result) << "Unable to get the SRK public key"; | 1399 TPM_LOG(ERROR, result) << "Unable to get the SRK public key"; |
| 1462 Tspi_Context_CloseObject(context_handle, srk_handle); | |
| 1463 DisconnectContext(context_handle); | |
| 1464 return false; | 1400 return false; |
| 1465 } | 1401 } |
| 1466 Tspi_Context_FreeMemory(context_handle, public_srk); | |
| 1467 | 1402 |
| 1468 TSS_HTPM tpm_handle; | 1403 TSS_HTPM tpm_handle; |
| 1469 if (!GetTpm(context_handle, &tpm_handle)) { | 1404 if (!GetTpm(context_handle, &tpm_handle)) { |
| 1470 LOG(ERROR) << "Unable to get a handle to the TPM"; | 1405 LOG(ERROR) << "Unable to get a handle to the TPM"; |
| 1471 Tspi_Context_CloseObject(context_handle, srk_handle); | |
| 1472 DisconnectContext(context_handle); | |
| 1473 return false; | 1406 return false; |
| 1474 } | 1407 } |
| 1475 | 1408 |
| 1476 // Use PCR0 when sealing the data so that the owner password is only | 1409 // Use PCR0 when sealing the data so that the owner password is only |
| 1477 // available in the current boot mode. This helps protect the password from | 1410 // available in the current boot mode. This helps protect the password from |
| 1478 // offline attacks until it has been presented and cleared. | 1411 // offline attacks until it has been presented and cleared. |
| 1479 TSS_HPCRS pcrs_handle; | 1412 ScopedTssPcrs pcrs_handle(context_handle); |
| 1480 if ((result = Tspi_Context_CreateObject(context_handle, TSS_OBJECT_TYPE_PCRS, | 1413 if (TPM_ERROR(result = Tspi_Context_CreateObject(context_handle, |
| 1481 0, &pcrs_handle))) { | 1414 TSS_OBJECT_TYPE_PCRS, |
| 1415 0, | |
| 1416 pcrs_handle.ptr()))) { | |
| 1482 TPM_LOG(ERROR, result) << "Error calling Tspi_Context_CreateObject"; | 1417 TPM_LOG(ERROR, result) << "Error calling Tspi_Context_CreateObject"; |
| 1483 Tspi_Context_CloseObject(context_handle, srk_handle); | |
| 1484 DisconnectContext(context_handle); | |
| 1485 return false; | 1418 return false; |
| 1486 } | 1419 } |
| 1487 | 1420 |
| 1488 UINT32 pcr_len; | 1421 UINT32 pcr_len; |
| 1489 BYTE* pcr_value; | 1422 ScopedTssMemory pcr_value(context_handle); |
| 1490 Tspi_TPM_PcrRead(tpm_handle, 0, &pcr_len, &pcr_value); | 1423 Tspi_TPM_PcrRead(tpm_handle, 0, &pcr_len, pcr_value.ptr()); |
| 1491 Tspi_PcrComposite_SetPcrValue(pcrs_handle, 0, pcr_len, pcr_value); | 1424 Tspi_PcrComposite_SetPcrValue(pcrs_handle, 0, pcr_len, pcr_value); |
| 1492 Tspi_Context_FreeMemory(context_handle, pcr_value); | |
| 1493 | 1425 |
| 1494 TSS_FLAG init_flags = TSS_ENCDATA_SEAL; | 1426 TSS_FLAG init_flags = TSS_ENCDATA_SEAL; |
| 1495 TSS_HKEY enc_handle; | 1427 ScopedTssKey enc_handle(context_handle); |
| 1496 if ((result = Tspi_Context_CreateObject(context_handle, | 1428 if (TPM_ERROR(result = Tspi_Context_CreateObject(context_handle, |
| 1497 TSS_OBJECT_TYPE_ENCDATA, | 1429 TSS_OBJECT_TYPE_ENCDATA, |
| 1498 init_flags, &enc_handle))) { | 1430 init_flags, |
| 1431 enc_handle.ptr()))) { | |
| 1499 TPM_LOG(ERROR, result) << "Error calling Tspi_Context_CreateObject"; | 1432 TPM_LOG(ERROR, result) << "Error calling Tspi_Context_CreateObject"; |
| 1500 Tspi_Context_CloseObject(context_handle, pcrs_handle); | |
| 1501 Tspi_Context_CloseObject(context_handle, srk_handle); | |
| 1502 DisconnectContext(context_handle); | |
| 1503 return false; | 1433 return false; |
| 1504 } | 1434 } |
| 1505 | 1435 |
| 1506 if ((result = Tspi_Data_Seal(enc_handle, srk_handle, owner_password.size(), | 1436 if (TPM_ERROR(result = Tspi_Data_Seal(enc_handle, |
| 1507 const_cast<BYTE *>(&owner_password[0]), | 1437 srk_handle, |
| 1508 pcrs_handle))) { | 1438 owner_password.size(), |
| 1439 const_cast<BYTE *>(&owner_password[0]), | |
| 1440 pcrs_handle))) { | |
| 1509 TPM_LOG(ERROR, result) << "Error calling Tspi_Data_Seal"; | 1441 TPM_LOG(ERROR, result) << "Error calling Tspi_Data_Seal"; |
| 1510 Tspi_Context_CloseObject(context_handle, pcrs_handle); | |
| 1511 Tspi_Context_CloseObject(context_handle, enc_handle); | |
| 1512 Tspi_Context_CloseObject(context_handle, srk_handle); | |
| 1513 DisconnectContext(context_handle); | |
| 1514 return false; | 1442 return false; |
| 1515 } | 1443 } |
| 1516 Tspi_Context_CloseObject(context_handle, pcrs_handle); | |
| 1517 | 1444 |
| 1518 unsigned char* enc_data = NULL; | 1445 ScopedTssMemory enc_data(context_handle); |
| 1519 UINT32 enc_data_length = 0; | 1446 UINT32 enc_data_length = 0; |
| 1520 if ((result = Tspi_GetAttribData(enc_handle, TSS_TSPATTRIB_ENCDATA_BLOB, | 1447 if (TPM_ERROR(result = Tspi_GetAttribData(enc_handle, |
| 1521 TSS_TSPATTRIB_ENCDATABLOB_BLOB, | 1448 TSS_TSPATTRIB_ENCDATA_BLOB, |
| 1522 &enc_data_length, &enc_data))) { | 1449 TSS_TSPATTRIB_ENCDATABLOB_BLOB, |
| 1450 &enc_data_length, | |
| 1451 enc_data.ptr()))) { | |
| 1523 TPM_LOG(ERROR, result) << "Error calling Tspi_GetAttribData"; | 1452 TPM_LOG(ERROR, result) << "Error calling Tspi_GetAttribData"; |
| 1524 Tspi_Context_CloseObject(context_handle, enc_handle); | |
| 1525 Tspi_Context_CloseObject(context_handle, srk_handle); | |
| 1526 DisconnectContext(context_handle); | |
| 1527 return false; | 1453 return false; |
| 1528 } | 1454 } |
| 1529 Tspi_Context_CloseObject(context_handle, enc_handle); | |
| 1530 | 1455 |
| 1531 tpm_status->set_owner_password(enc_data, enc_data_length); | 1456 tpm_status->set_owner_password(enc_data, enc_data_length); |
| 1532 | |
| 1533 Tspi_Context_FreeMemory(context_handle, enc_data); | |
| 1534 Tspi_Context_CloseObject(context_handle, srk_handle); | |
| 1535 DisconnectContext(context_handle); | |
| 1536 | |
| 1537 return true; | 1457 return true; |
| 1538 } | 1458 } |
| 1539 | 1459 |
| 1540 bool Tpm::GetTpm(TSS_HCONTEXT context_handle, TSS_HTPM* tpm_handle) { | 1460 bool Tpm::GetTpm(TSS_HCONTEXT context_handle, TSS_HTPM* tpm_handle) { |
| 1541 TSS_RESULT result; | 1461 TSS_RESULT result; |
| 1542 TSS_HTPM local_tpm_handle; | 1462 TSS_HTPM local_tpm_handle; |
| 1543 if ((result = Tspi_Context_GetTpmObject(context_handle, &local_tpm_handle))) { | 1463 if (TPM_ERROR(result = |
| 1464 Tspi_Context_GetTpmObject(context_handle, &local_tpm_handle))) { | |
| 1544 TPM_LOG(ERROR, result) << "Error calling Tspi_Context_GetTpmObject"; | 1465 TPM_LOG(ERROR, result) << "Error calling Tspi_Context_GetTpmObject"; |
| 1545 return false; | 1466 return false; |
| 1546 } | 1467 } |
| 1547 | 1468 |
| 1548 *tpm_handle = local_tpm_handle; | 1469 *tpm_handle = local_tpm_handle; |
| 1549 return true; | 1470 return true; |
| 1550 } | 1471 } |
| 1551 | 1472 |
| 1552 bool Tpm::GetTpmWithAuth(TSS_HCONTEXT context_handle, | 1473 bool Tpm::GetTpmWithAuth(TSS_HCONTEXT context_handle, |
| 1553 const SecureBlob& owner_password, | 1474 const SecureBlob& owner_password, |
| 1554 TSS_HTPM* tpm_handle) { | 1475 TSS_HTPM* tpm_handle) { |
| 1555 TSS_RESULT result; | 1476 TSS_RESULT result; |
| 1556 TSS_HTPM local_tpm_handle; | 1477 TSS_HTPM local_tpm_handle; |
| 1557 if (!GetTpm(context_handle, &local_tpm_handle)) { | 1478 if (!GetTpm(context_handle, &local_tpm_handle)) { |
| 1558 return false; | 1479 return false; |
| 1559 } | 1480 } |
| 1560 | 1481 |
| 1561 TSS_HPOLICY tpm_usage_policy; | 1482 TSS_HPOLICY tpm_usage_policy; |
| 1562 if ((result = Tspi_GetPolicyObject(local_tpm_handle, TSS_POLICY_USAGE, | 1483 if (TPM_ERROR(result = Tspi_GetPolicyObject(local_tpm_handle, |
| 1563 &tpm_usage_policy))) { | 1484 TSS_POLICY_USAGE, |
| 1485 &tpm_usage_policy))) { | |
| 1564 TPM_LOG(ERROR, result) << "Error calling Tspi_GetPolicyObject"; | 1486 TPM_LOG(ERROR, result) << "Error calling Tspi_GetPolicyObject"; |
| 1565 return false; | 1487 return false; |
| 1566 } | 1488 } |
| 1567 | 1489 |
| 1568 if ((result = Tspi_Policy_SetSecret(tpm_usage_policy, TSS_SECRET_MODE_PLAIN, | 1490 if (TPM_ERROR(result = Tspi_Policy_SetSecret( |
| 1569 owner_password.size(), | 1491 tpm_usage_policy, |
| 1570 const_cast<BYTE *>(static_cast<const BYTE *>( | 1492 TSS_SECRET_MODE_PLAIN, |
| 1571 owner_password.const_data()))))) { | 1493 owner_password.size(), |
| 1494 const_cast<BYTE *>(static_cast<const BYTE *>( | |
| 1495 owner_password.const_data()))))) { | |
| 1572 TPM_LOG(ERROR, result) << "Error calling Tspi_Policy_SetSecret"; | 1496 TPM_LOG(ERROR, result) << "Error calling Tspi_Policy_SetSecret"; |
| 1573 return false; | 1497 return false; |
| 1574 } | 1498 } |
| 1575 | 1499 |
| 1576 *tpm_handle = local_tpm_handle; | 1500 *tpm_handle = local_tpm_handle; |
| 1577 return true; | 1501 return true; |
| 1578 } | 1502 } |
| 1579 | 1503 |
| 1580 bool Tpm::TestTpmAuth(TSS_HTPM tpm_handle) { | 1504 bool Tpm::TestTpmAuth(TSS_HTPM tpm_handle) { |
| 1581 // Call Tspi_TPM_GetStatus to test the authentication | 1505 // Call Tspi_TPM_GetStatus to test the authentication |
| 1582 TSS_RESULT result; | 1506 TSS_RESULT result; |
| 1583 TSS_BOOL current_status = false; | 1507 TSS_BOOL current_status = false; |
| 1584 if ((result = Tspi_TPM_GetStatus(tpm_handle, | 1508 if (TPM_ERROR(result = Tspi_TPM_GetStatus(tpm_handle, |
| 1585 TSS_TPMSTATUS_DISABLED, | 1509 TSS_TPMSTATUS_DISABLED, |
| 1586 ¤t_status))) { | 1510 ¤t_status))) { |
| 1587 return false; | 1511 return false; |
| 1588 } | 1512 } |
| 1589 return true; | 1513 return true; |
| 1590 } | 1514 } |
| 1591 | 1515 |
| 1592 bool Tpm::GetOwnerPassword(chromeos::Blob* owner_password) { | 1516 bool Tpm::GetOwnerPassword(chromeos::Blob* owner_password) { |
| 1593 bool result = false; | 1517 bool result = false; |
| 1594 if (password_sync_lock_.Try()) { | 1518 if (password_sync_lock_.Try()) { |
| 1595 if (owner_password_.size() != 0) { | 1519 if (owner_password_.size() != 0) { |
| 1596 owner_password->assign(owner_password_.begin(), owner_password_.end()); | 1520 owner_password->assign(owner_password_.begin(), owner_password_.end()); |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 1610 } | 1534 } |
| 1611 | 1535 |
| 1612 if (OUT_took_ownership) { | 1536 if (OUT_took_ownership) { |
| 1613 *OUT_took_ownership = false; | 1537 *OUT_took_ownership = false; |
| 1614 } | 1538 } |
| 1615 | 1539 |
| 1616 if (is_disabled_) { | 1540 if (is_disabled_) { |
| 1617 return false; | 1541 return false; |
| 1618 } | 1542 } |
| 1619 | 1543 |
| 1620 TSS_HCONTEXT context_handle = ConnectContext(); | 1544 ScopedTssContext context_handle; |
| 1621 | 1545 if (!(*(context_handle.ptr()) = ConnectContext())) { |
| 1622 if (!context_handle) { | |
| 1623 LOG(ERROR) << "Failed to connect to TPM"; | 1546 LOG(ERROR) << "Failed to connect to TPM"; |
| 1624 return false; | 1547 return false; |
| 1625 } | 1548 } |
| 1626 | 1549 |
| 1627 SecureBlob default_owner_password(sizeof(kTpmWellKnownPassword)); | 1550 SecureBlob default_owner_password(sizeof(kTpmWellKnownPassword)); |
| 1628 memcpy(default_owner_password.data(), kTpmWellKnownPassword, | 1551 memcpy(default_owner_password.data(), kTpmWellKnownPassword, |
| 1629 sizeof(kTpmWellKnownPassword)); | 1552 sizeof(kTpmWellKnownPassword)); |
| 1630 | 1553 |
| 1631 bool took_ownership = false; | 1554 bool took_ownership = false; |
| 1632 if (!is_owned_) { | 1555 if (!is_owned_) { |
| 1633 is_being_owned_ = true; | 1556 is_being_owned_ = true; |
| 1634 file_util::Delete(FilePath(kOpenCryptokiPath), true); | 1557 file_util::Delete(FilePath(kOpenCryptokiPath), true); |
| 1635 file_util::Delete(FilePath(kTpmOwnedFile), false); | 1558 file_util::Delete(FilePath(kTpmOwnedFile), false); |
| 1636 file_util::Delete(FilePath(kTpmStatusFile), false); | 1559 file_util::Delete(FilePath(kTpmStatusFile), false); |
| 1637 | 1560 |
| 1638 if (!IsEndorsementKeyAvailable(context_handle)) { | 1561 if (!IsEndorsementKeyAvailable(context_handle)) { |
| 1639 if (!CreateEndorsementKey(context_handle)) { | 1562 if (!CreateEndorsementKey(context_handle)) { |
| 1640 LOG(ERROR) << "Failed to create endorsement key"; | 1563 LOG(ERROR) << "Failed to create endorsement key"; |
| 1641 is_being_owned_ = false; | 1564 is_being_owned_ = false; |
| 1642 DisconnectContext(context_handle); | |
| 1643 return false; | 1565 return false; |
| 1644 } | 1566 } |
| 1645 } | 1567 } |
| 1646 | 1568 |
| 1647 if (!IsEndorsementKeyAvailable(context_handle)) { | 1569 if (!IsEndorsementKeyAvailable(context_handle)) { |
| 1648 LOG(ERROR) << "Endorsement key is not available"; | 1570 LOG(ERROR) << "Endorsement key is not available"; |
| 1649 is_being_owned_ = false; | 1571 is_being_owned_ = false; |
| 1650 DisconnectContext(context_handle); | |
| 1651 return false; | 1572 return false; |
| 1652 } | 1573 } |
| 1653 | 1574 |
| 1654 if (!TakeOwnership(context_handle, kMaxTimeoutRetries, | 1575 if (!TakeOwnership(context_handle, kMaxTimeoutRetries, |
| 1655 default_owner_password)) { | 1576 default_owner_password)) { |
| 1656 LOG(ERROR) << "Take Ownership failed"; | 1577 LOG(ERROR) << "Take Ownership failed"; |
| 1657 is_being_owned_ = false; | 1578 is_being_owned_ = false; |
| 1658 DisconnectContext(context_handle); | |
| 1659 return false; | 1579 return false; |
| 1660 } | 1580 } |
| 1661 | 1581 |
| 1662 is_owned_ = true; | 1582 is_owned_ = true; |
| 1663 took_ownership = true; | 1583 took_ownership = true; |
| 1664 | 1584 |
| 1665 tpm_status.set_flags(TpmStatus::OWNED_BY_THIS_INSTALL | | 1585 tpm_status.set_flags(TpmStatus::OWNED_BY_THIS_INSTALL | |
| 1666 TpmStatus::USES_WELL_KNOWN_OWNER); | 1586 TpmStatus::USES_WELL_KNOWN_OWNER); |
| 1667 tpm_status.clear_owner_password(); | 1587 tpm_status.clear_owner_password(); |
| 1668 StoreTpmStatus(tpm_status); | 1588 StoreTpmStatus(tpm_status); |
| 1669 } | 1589 } |
| 1670 | 1590 |
| 1671 if (OUT_took_ownership) { | 1591 if (OUT_took_ownership) { |
| 1672 *OUT_took_ownership = took_ownership; | 1592 *OUT_took_ownership = took_ownership; |
| 1673 } | 1593 } |
| 1674 | 1594 |
| 1675 // Ensure the SRK is available | 1595 // Ensure the SRK is available |
| 1676 TSS_RESULT result; | 1596 TSS_RESULT result; |
| 1677 TSS_HKEY srk_handle; | 1597 TSS_HKEY srk_handle; |
| 1678 TSS_UUID SRK_UUID = TSS_UUID_SRK; | 1598 TSS_UUID SRK_UUID = TSS_UUID_SRK; |
| 1679 if ((result = Tspi_Context_LoadKeyByUUID(context_handle, TSS_PS_TYPE_SYSTEM, | 1599 if (TPM_ERROR(result = Tspi_Context_LoadKeyByUUID(context_handle, |
| 1680 SRK_UUID, &srk_handle))) { | 1600 TSS_PS_TYPE_SYSTEM, |
| 1601 SRK_UUID, | |
| 1602 &srk_handle))) { | |
| 1681 is_srk_available_ = false; | 1603 is_srk_available_ = false; |
| 1682 } else { | 1604 } else { |
| 1683 Tspi_Context_CloseObject(context_handle, srk_handle); | 1605 Tspi_Context_CloseObject(context_handle, srk_handle); |
| 1684 is_srk_available_ = true; | 1606 is_srk_available_ = true; |
| 1685 } | 1607 } |
| 1686 | 1608 |
| 1687 // If we can open the TPM with the default password, then we still need to | 1609 // If we can open the TPM with the default password, then we still need to |
| 1688 // zero the SRK password and unrestrict it, then change the owner password. | 1610 // zero the SRK password and unrestrict it, then change the owner password. |
| 1689 TSS_HTPM tpm_handle; | 1611 TSS_HTPM tpm_handle; |
| 1690 if (!file_util::PathExists(FilePath(kTpmOwnedFile)) && | 1612 if (!file_util::PathExists(FilePath(kTpmOwnedFile)) && |
| 1691 GetTpmWithAuth(context_handle, default_owner_password, &tpm_handle) && | 1613 GetTpmWithAuth(context_handle, default_owner_password, &tpm_handle) && |
| 1692 TestTpmAuth(tpm_handle)) { | 1614 TestTpmAuth(tpm_handle)) { |
| 1693 if (!ZeroSrkPassword(context_handle, default_owner_password)) { | 1615 if (!ZeroSrkPassword(context_handle, default_owner_password)) { |
| 1694 LOG(ERROR) << "Couldn't zero SRK password"; | 1616 LOG(ERROR) << "Couldn't zero SRK password"; |
| 1695 is_being_owned_ = false; | 1617 is_being_owned_ = false; |
| 1696 DisconnectContext(context_handle); | |
| 1697 return false; | 1618 return false; |
| 1698 } | 1619 } |
| 1699 | 1620 |
| 1700 if (!UnrestrictSrk(context_handle, default_owner_password)) { | 1621 if (!UnrestrictSrk(context_handle, default_owner_password)) { |
| 1701 LOG(ERROR) << "Couldn't unrestrict the SRK"; | 1622 LOG(ERROR) << "Couldn't unrestrict the SRK"; |
| 1702 is_being_owned_ = false; | 1623 is_being_owned_ = false; |
| 1703 DisconnectContext(context_handle); | |
| 1704 return false; | 1624 return false; |
| 1705 } | 1625 } |
| 1706 | 1626 |
| 1707 SecureBlob owner_password; | 1627 SecureBlob owner_password; |
| 1708 CreateOwnerPassword(&owner_password); | 1628 CreateOwnerPassword(&owner_password); |
| 1709 | 1629 |
| 1710 tpm_status.set_flags(TpmStatus::OWNED_BY_THIS_INSTALL | | 1630 tpm_status.set_flags(TpmStatus::OWNED_BY_THIS_INSTALL | |
| 1711 TpmStatus::USES_RANDOM_OWNER); | 1631 TpmStatus::USES_RANDOM_OWNER); |
| 1712 if (!StoreOwnerPassword(owner_password, &tpm_status)) { | 1632 if (!StoreOwnerPassword(owner_password, &tpm_status)) { |
| 1713 tpm_status.clear_owner_password(); | 1633 tpm_status.clear_owner_password(); |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 1726 // If we fall through here, then the TPM owned file doesn't exist, but we | 1646 // If we fall through here, then the TPM owned file doesn't exist, but we |
| 1727 // couldn't auth with the well-known password. In this case, we must assume | 1647 // couldn't auth with the well-known password. In this case, we must assume |
| 1728 // that the TPM has already been owned and set to a random password, so | 1648 // that the TPM has already been owned and set to a random password, so |
| 1729 // touch the TPM owned file. | 1649 // touch the TPM owned file. |
| 1730 if (!file_util::PathExists(FilePath(kTpmOwnedFile))) { | 1650 if (!file_util::PathExists(FilePath(kTpmOwnedFile))) { |
| 1731 file_util::WriteFile(FilePath(kTpmOwnedFile), NULL, 0); | 1651 file_util::WriteFile(FilePath(kTpmOwnedFile), NULL, 0); |
| 1732 } | 1652 } |
| 1733 } | 1653 } |
| 1734 | 1654 |
| 1735 is_being_owned_ = false; | 1655 is_being_owned_ = false; |
| 1736 DisconnectContext(context_handle); | |
| 1737 return true; | 1656 return true; |
| 1738 } | 1657 } |
| 1739 | 1658 |
| 1740 bool Tpm::GetRandomData(size_t length, chromeos::Blob* data) { | 1659 bool Tpm::GetRandomData(size_t length, chromeos::Blob* data) { |
| 1741 TSS_HCONTEXT context_handle; | 1660 ScopedTssContext context_handle; |
| 1742 if ((context_handle = ConnectContext()) == 0) { | 1661 if ((*(context_handle.ptr()) = ConnectContext()) == 0) { |
| 1743 LOG(ERROR) << "Could not open the TPM"; | 1662 LOG(ERROR) << "Could not open the TPM"; |
| 1744 return false; | 1663 return false; |
| 1745 } | 1664 } |
| 1746 | 1665 |
| 1747 TSS_HTPM tpm_handle; | 1666 TSS_HTPM tpm_handle; |
| 1748 if (!GetTpm(context_handle, &tpm_handle)) { | 1667 if (!GetTpm(context_handle, &tpm_handle)) { |
| 1749 LOG(ERROR) << "Could not get a handle to the TPM."; | 1668 LOG(ERROR) << "Could not get a handle to the TPM."; |
| 1750 DisconnectContext(context_handle); | |
| 1751 return false; | 1669 return false; |
| 1752 } | 1670 } |
| 1753 | 1671 |
| 1754 TSS_RESULT result; | 1672 TSS_RESULT result; |
| 1755 SecureBlob random(length); | 1673 SecureBlob random(length); |
| 1756 BYTE* tpm_data = NULL; | 1674 ScopedTssMemory tpm_data(context_handle); |
| 1757 if ((result = Tspi_TPM_GetRandom(tpm_handle, random.size(), &tpm_data))) { | 1675 result = Tspi_TPM_GetRandom(tpm_handle, random.size(), tpm_data.ptr()); |
| 1676 if (TPM_ERROR(result)) { | |
| 1758 TPM_LOG(ERROR, result) << "Could not get random data from the TPM"; | 1677 TPM_LOG(ERROR, result) << "Could not get random data from the TPM"; |
| 1759 DisconnectContext(context_handle); | |
| 1760 return false; | 1678 return false; |
| 1761 } | 1679 } |
| 1762 memcpy(random.data(), tpm_data, random.size()); | 1680 memcpy(random.data(), tpm_data, random.size()); |
| 1763 chromeos::SecureMemset(tpm_data, 0, random.size()); | 1681 chromeos::SecureMemset(tpm_data, 0, random.size()); |
| 1764 Tspi_Context_FreeMemory(context_handle, tpm_data); | |
| 1765 DisconnectContext(context_handle); | |
| 1766 data->swap(random); | 1682 data->swap(random); |
| 1767 return true; | 1683 return true; |
| 1768 } | 1684 } |
| 1769 | 1685 |
| 1770 void Tpm::ClearStoredOwnerPassword() { | 1686 void Tpm::ClearStoredOwnerPassword() { |
| 1771 TpmStatus tpm_status; | 1687 TpmStatus tpm_status; |
| 1772 if (LoadTpmStatus(&tpm_status)) { | 1688 if (LoadTpmStatus(&tpm_status)) { |
| 1773 if (tpm_status.has_owner_password()) { | 1689 if (tpm_status.has_owner_password()) { |
| 1774 tpm_status.clear_owner_password(); | 1690 tpm_status.clear_owner_password(); |
| 1775 StoreTpmStatus(tpm_status); | 1691 StoreTpmStatus(tpm_status); |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1834 | 1750 |
| 1835 if (data_written != final_blob.size()) { | 1751 if (data_written != final_blob.size()) { |
| 1836 platform.SetMask(old_mask); | 1752 platform.SetMask(old_mask); |
| 1837 return false; | 1753 return false; |
| 1838 } | 1754 } |
| 1839 platform.SetMask(old_mask); | 1755 platform.SetMask(old_mask); |
| 1840 return true; | 1756 return true; |
| 1841 } | 1757 } |
| 1842 | 1758 |
| 1843 } // namespace cryptohome | 1759 } // namespace cryptohome |
| OLD | NEW |