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 |