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