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