Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(13)

Side by Side Diff: tpm.cc

Issue 3118014: Update TPM initialization to better handle errors. (Closed) Base URL: http://src.chromium.org/git/tpm_init.git
Patch Set: Created 10 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « tpm.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 <trousers/tss.h> 13 #include <trousers/tss.h>
14 #include <trousers/trousers.h> 14 #include <trousers/trousers.h>
15 15
16 namespace tpm_init { 16 namespace tpm_init {
17 17
18 const char* kWellKnownSrkTmp = "1234567890"; 18 const char* kWellKnownSrkTmp = "1234567890";
19 const int kOwnerPasswordLength = 12; 19 const int kOwnerPasswordLength = 12;
20 const int kMaxTimeoutRetries = 5; 20 const int kMaxTimeoutRetries = 5;
21 const char* kTpmCheckEnabledFile = "/sys/class/misc/tpm0/device/enabled"; 21 const char* kTpmCheckEnabledFile = "/sys/class/misc/tpm0/device/enabled";
22 const char* kTpmCheckOwnedFile = "/sys/class/misc/tpm0/device/owned"; 22 const char* kTpmCheckOwnedFile = "/sys/class/misc/tpm0/device/owned";
23 const char* kTpmOwnedFile = "/var/lib/.tpm_owned"; 23 const char* kTpmOwnedFile = "/var/lib/.tpm_owned";
24 const char* kOpenCryptokiPath = "/var/lib/opencryptoki"; 24 const char* kOpenCryptokiPath = "/var/lib/opencryptoki";
25 const int kTpmConnectRetries = 10; 25 const int kTpmConnectRetries = 10;
26 const int kTpmConnectIntervalMs = 100; 26 const int kTpmConnectIntervalMs = 100;
27 const char kTpmWellKnownPassword[] = TSS_WELL_KNOWN_SECRET;
27 28
28 Tpm::Tpm() 29 Tpm::Tpm()
29 : context_handle_(0), 30 : context_handle_(0),
30 default_crypto_(new Crypto()), 31 default_crypto_(new Crypto()),
31 crypto_(default_crypto_.get()), 32 crypto_(default_crypto_.get()),
32 owner_password_(), 33 owner_password_(),
33 password_sync_lock_(), 34 password_sync_lock_(),
34 is_disabled_(true), 35 is_disabled_(true),
35 is_owned_(false) { 36 is_owned_(false),
37 is_srk_available_(false) {
36 } 38 }
37 39
38 Tpm::~Tpm() { 40 Tpm::~Tpm() {
39 Disconnect(); 41 Disconnect();
40 } 42 }
41 43
42 bool Tpm::Init() { 44 bool Tpm::Init() {
43 // Checking disabled and owned either via sysfs or via TSS calls will block if 45 // Checking disabled and owned either via sysfs or via TSS calls will block if
44 // ownership is being taken by another thread or process. So for this to work 46 // ownership is being taken by another thread or process. So for this to work
45 // well, Tpm::Init() needs to be called before InitializeTpm() is called. At 47 // well, Tpm::Init() needs to be called before InitializeTpm() is called. At
46 // that point, the public API for Tpm only checks these booleans, so other 48 // that point, the public API for Tpm only checks these booleans, so other
47 // threads can check without being blocked. InitializeTpm() will reset the 49 // threads can check without being blocked. InitializeTpm() will reset the
48 // is_owned_ bit on success. 50 // is_owned_ bit on success.
49 if (file_util::PathExists(FilePath(kTpmCheckEnabledFile))) { 51 if (file_util::PathExists(FilePath(kTpmCheckEnabledFile))) {
50 is_disabled_ = IsDisabledCheckViaSysfs(); 52 is_disabled_ = IsDisabledCheckViaSysfs();
51 is_owned_ = IsOwnedCheckViaSysfs(); 53 is_owned_ = IsOwnedCheckViaSysfs();
54 } else {
55 TSS_HCONTEXT context_handle;
56 if (OpenAndConnectTpm(&context_handle)) {
57 bool enabled = false;
58 bool owned = false;
59 IsEnabledOwnedCheckViaContext(context_handle, &enabled, &owned);
60 is_disabled_ = !enabled;
61 is_owned_ = owned;
62 Tspi_Context_Close(context_handle);
63 } else {
64 }
52 } 65 }
53 return true; 66 return true;
54 } 67 }
55 68
56 bool Tpm::Connect() { 69 bool Tpm::Connect() {
57 if (context_handle_ == 0) { 70 if (context_handle_ == 0) {
58 TSS_HCONTEXT context_handle; 71 TSS_HCONTEXT context_handle;
59 if (!OpenAndConnectTpm(&context_handle)) { 72 if (!OpenAndConnectTpm(&context_handle)) {
60 return false; 73 return false;
61 } 74 }
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
157 std::string contents; 170 std::string contents;
158 if (!file_util::ReadFileToString(FilePath(kTpmCheckOwnedFile), &contents)) { 171 if (!file_util::ReadFileToString(FilePath(kTpmCheckOwnedFile), &contents)) {
159 return false; 172 return false;
160 } 173 }
161 if (contents.size() < 1) { 174 if (contents.size() < 1) {
162 return false; 175 return false;
163 } 176 }
164 return (contents[0] != '0'); 177 return (contents[0] != '0');
165 } 178 }
166 179
167 bool Tpm::IsDisabledCheckViaContext(TSS_HCONTEXT context_handle) { 180 void Tpm::IsEnabledOwnedCheckViaContext(TSS_HCONTEXT context_handle,
168 bool value = true; 181 bool* enabled, bool* owned) {
182 *enabled = false;
183 *owned = false;
184
169 TSS_RESULT result; 185 TSS_RESULT result;
170 TSS_HTPM tpm_handle; 186 TSS_HTPM tpm_handle;
171 if (!GetTpm(context_handle, &tpm_handle)) { 187 if (!GetTpm(context_handle, &tpm_handle)) {
172 return value; 188 return;
173 } 189 }
174 190
191 UINT32 sub_cap = TSS_TPMCAP_PROP_OWNER;
175 UINT32 cap_length = 0; 192 UINT32 cap_length = 0;
176 BYTE* cap = NULL; 193 BYTE* cap = NULL;
177 if ((result = Tspi_TPM_GetCapability(tpm_handle, TSS_TPMCAP_FLAG, 194 if ((result = Tspi_TPM_GetCapability(tpm_handle, TSS_TPMCAP_PROPERTY,
178 0, NULL, &cap_length, &cap))) { 195 sizeof(sub_cap),
179 LOG(ERROR) << "Error calling Tspi_TPM_GetCapability: " << result; 196 reinterpret_cast<BYTE*>(&sub_cap),
180 return value; 197 &cap_length, &cap)) == 0) {
198 if (cap_length >= (sizeof(TSS_BOOL))) {
199 *enabled = true;
200 *owned = ((*(reinterpret_cast<TSS_BOOL*>(cap))) != 0);
201 }
202 Tspi_Context_FreeMemory(context_handle, cap);
203 } else if(ERROR_CODE(result) == TPM_E_DISABLED) {
204 *enabled = false;
181 } 205 }
182 if (cap_length >= (2 * sizeof(int))) {
183 value = (((*(reinterpret_cast<int*>(cap))) & TPM_PF_DISABLE) != 0);
184 }
185 Tspi_Context_FreeMemory(context_handle, cap);
186 return value;
187 }
188
189 bool Tpm::IsOwnedCheckViaContext(TSS_HCONTEXT context_handle) {
190 bool value = true;
191 TSS_RESULT result;
192 TSS_HTPM tpm_handle;
193 if (!GetTpm(context_handle, &tpm_handle)) {
194 LOG(ERROR) << "Error calling Tspi_Context_GetTpmObject: " << result;
195 return value;
196 }
197
198 UINT32 cap_length = 0;
199 BYTE* cap = NULL;
200 if ((result = Tspi_TPM_GetCapability(tpm_handle, TSS_TPMCAP_FLAG,
201 0, NULL, &cap_length, &cap))) {
202 LOG(ERROR) << "Error calling Tspi_TPM_GetCapability: " << result;
203 return value;
204 }
205 if (cap_length >= (2 * sizeof(int))) {
206 value = (((*(reinterpret_cast<int*>(cap))) & TPM_PF_OWNERSHIP) != 0);
207 }
208 Tspi_Context_FreeMemory(context_handle, cap);
209 return value;
210 } 206 }
211 207
212 bool Tpm::CreateEndorsementKey(TSS_HCONTEXT context_handle) { 208 bool Tpm::CreateEndorsementKey(TSS_HCONTEXT context_handle) {
213 TSS_RESULT result; 209 TSS_RESULT result;
214 TSS_HTPM tpm_handle; 210 TSS_HTPM tpm_handle;
215 if (!GetTpm(context_handle, &tpm_handle)) { 211 if (!GetTpm(context_handle, &tpm_handle)) {
216 return false; 212 return false;
217 } 213 }
218 214
219 TSS_HKEY local_key_handle; 215 TSS_HKEY local_key_handle;
(...skipping 18 matching lines...) Expand all
238 bool Tpm::IsEndorsementKeyAvailable(TSS_HCONTEXT context_handle) { 234 bool Tpm::IsEndorsementKeyAvailable(TSS_HCONTEXT context_handle) {
239 TSS_RESULT result; 235 TSS_RESULT result;
240 TSS_HTPM tpm_handle; 236 TSS_HTPM tpm_handle;
241 if (!GetTpm(context_handle, &tpm_handle)) { 237 if (!GetTpm(context_handle, &tpm_handle)) {
242 return false; 238 return false;
243 } 239 }
244 240
245 TSS_HKEY local_key_handle; 241 TSS_HKEY local_key_handle;
246 if ((result = Tspi_TPM_GetPubEndorsementKey(tpm_handle, false, NULL, 242 if ((result = Tspi_TPM_GetPubEndorsementKey(tpm_handle, false, NULL,
247 &local_key_handle))) { 243 &local_key_handle))) {
248 LOG(ERROR) << "Error calling Tspi_Context_CreateObject: " << result; 244 LOG(ERROR) << "Error calling Tspi_TPM_GetPubEndorsementKey: " << result;
249 return false; 245 return false;
250 } 246 }
251 247
252 Tspi_Context_CloseObject(context_handle, local_key_handle); 248 Tspi_Context_CloseObject(context_handle, local_key_handle);
253 249
254 return true; 250 return true;
255 } 251 }
256 252
257 void Tpm::CreateOwnerPassword(SecureBlob* password) { 253 void Tpm::CreateOwnerPassword(SecureBlob* password) {
258 SecureBlob random(kOwnerPasswordLength); 254 SecureBlob random(kOwnerPasswordLength);
259 crypto_->GetSecureRandom(static_cast<unsigned char*>(random.data()), 255 crypto_->GetSecureRandom(static_cast<unsigned char*>(random.data()),
260 random.size()); 256 random.size());
261 SecureBlob tpm_password(kOwnerPasswordLength); 257 SecureBlob tpm_password(kOwnerPasswordLength);
262 crypto_->AsciiEncodeToBuffer(random, static_cast<char*>(tpm_password.data()), 258 crypto_->AsciiEncodeToBuffer(random, static_cast<char*>(tpm_password.data()),
263 tpm_password.size()); 259 tpm_password.size());
264 password->swap(tpm_password); 260 password->swap(tpm_password);
265 } 261 }
266 262
267 bool Tpm::TakeOwnership(TSS_HCONTEXT context_handle, int max_timeout_tries) { 263 bool Tpm::TakeOwnership(TSS_HCONTEXT context_handle, int max_timeout_tries,
268 SecureBlob owner_password; 264 const SecureBlob& owner_password) {
269 CreateOwnerPassword(&owner_password);
270
271 TSS_RESULT result; 265 TSS_RESULT result;
272 TSS_HTPM tpm_handle; 266 TSS_HTPM tpm_handle;
273 if (!GetTpmWithAuth(context_handle, owner_password, &tpm_handle)) { 267 if (!GetTpmWithAuth(context_handle, owner_password, &tpm_handle)) {
274 return false; 268 return false;
275 } 269 }
276 270
277 TSS_HKEY srk_handle; 271 TSS_HKEY srk_handle;
278 TSS_FLAG init_flags = TSS_KEY_TSP_SRK | TSS_KEY_AUTHORIZATION; 272 TSS_FLAG init_flags = TSS_KEY_TSP_SRK | TSS_KEY_AUTHORIZATION;
279 if ((result = Tspi_Context_CreateObject(context_handle, 273 if ((result = Tspi_Context_CreateObject(context_handle,
280 TSS_OBJECT_TYPE_RSAKEY, 274 TSS_OBJECT_TYPE_RSAKEY,
(...skipping 30 matching lines...) Expand all
311 305
312 if (result) { 306 if (result) {
313 LOG(ERROR) << "Error calling Tspi_TPM_TakeOwnership: " << result 307 LOG(ERROR) << "Error calling Tspi_TPM_TakeOwnership: " << result
314 << ", attempts: " << retry_count; 308 << ", attempts: " << retry_count;
315 Tspi_Context_CloseObject(context_handle, srk_handle); 309 Tspi_Context_CloseObject(context_handle, srk_handle);
316 return false; 310 return false;
317 } 311 }
318 312
319 Tspi_Context_CloseObject(context_handle, srk_handle); 313 Tspi_Context_CloseObject(context_handle, srk_handle);
320 314
321 password_sync_lock_.Acquire();
322 owner_password_.swap(owner_password);
323 password_sync_lock_.Release();
324
325 return true; 315 return true;
326 } 316 }
327 317
328 bool Tpm::ZeroSrkPassword(TSS_HCONTEXT context_handle, 318 bool Tpm::ZeroSrkPassword(TSS_HCONTEXT context_handle,
329 const SecureBlob& owner_password) { 319 const SecureBlob& owner_password) {
330 TSS_RESULT result; 320 TSS_RESULT result;
331 TSS_HTPM tpm_handle; 321 TSS_HTPM tpm_handle;
332 if (!GetTpmWithAuth(context_handle, owner_password, &tpm_handle)) { 322 if (!GetTpmWithAuth(context_handle, owner_password, &tpm_handle)) {
333 return false; 323 return false;
334 } 324 }
335 325
336 TSS_HKEY srk_handle; 326 TSS_HKEY srk_handle;
337 TSS_UUID SRK_UUID = TSS_UUID_SRK; 327 TSS_UUID SRK_UUID = TSS_UUID_SRK;
338 if ((result = Tspi_Context_LoadKeyByUUID(context_handle, TSS_PS_TYPE_SYSTEM, 328 if ((result = Tspi_Context_LoadKeyByUUID(context_handle, TSS_PS_TYPE_SYSTEM,
339 SRK_UUID, &srk_handle))) { 329 SRK_UUID, &srk_handle))) {
340 LOG(ERROR) << "Couldn't load SRK: " << result; 330 LOG(ERROR) << "Error calling Tspi_Context_LoadKeyByUUID: " << result;
341 return false; 331 return false;
342 } 332 }
343 333
344 TSS_HPOLICY policy_handle; 334 TSS_HPOLICY policy_handle;
345 if ((result = Tspi_Context_CreateObject(context_handle, 335 if ((result = Tspi_Context_CreateObject(context_handle,
346 TSS_OBJECT_TYPE_POLICY, 336 TSS_OBJECT_TYPE_POLICY,
347 TSS_POLICY_USAGE, 337 TSS_POLICY_USAGE,
348 &policy_handle))) { 338 &policy_handle))) {
349 LOG(ERROR) << "Error creating policy object: " << result; 339 LOG(ERROR) << "Error calling Tspi_Context_CreateObject: " << result;
350 Tspi_Context_CloseObject(context_handle, srk_handle); 340 Tspi_Context_CloseObject(context_handle, srk_handle);
351 return false; 341 return false;
352 } 342 }
353 343
354 BYTE new_password[0]; 344 BYTE new_password[0];
355 if ((result = Tspi_Policy_SetSecret(policy_handle, TSS_SECRET_MODE_PLAIN, 345 if ((result = Tspi_Policy_SetSecret(policy_handle, TSS_SECRET_MODE_PLAIN,
356 0, new_password))) { 346 0, new_password))) {
357 LOG(ERROR) << "Error setting srk password: " << result; 347 LOG(ERROR) << "Error calling Tspi_Policy_SetSecret: " << result;
358 Tspi_Context_CloseObject(context_handle, policy_handle); 348 Tspi_Context_CloseObject(context_handle, policy_handle);
359 Tspi_Context_CloseObject(context_handle, srk_handle); 349 Tspi_Context_CloseObject(context_handle, srk_handle);
360 return false; 350 return false;
361 } 351 }
362 352
363 if ((result = Tspi_ChangeAuth(srk_handle, 353 if ((result = Tspi_ChangeAuth(srk_handle,
364 tpm_handle, 354 tpm_handle,
365 policy_handle))) { 355 policy_handle))) {
366 LOG(ERROR) << "Error creating policy object: " << result; 356 LOG(ERROR) << "Error calling Tspi_ChangeAuth: " << result;
367 Tspi_Context_CloseObject(context_handle, policy_handle); 357 Tspi_Context_CloseObject(context_handle, policy_handle);
368 Tspi_Context_CloseObject(context_handle, srk_handle); 358 Tspi_Context_CloseObject(context_handle, srk_handle);
369 return false; 359 return false;
370 } 360 }
371 361
372 Tspi_Context_CloseObject(context_handle, policy_handle); 362 Tspi_Context_CloseObject(context_handle, policy_handle);
373 Tspi_Context_CloseObject(context_handle, srk_handle); 363 Tspi_Context_CloseObject(context_handle, srk_handle);
374 return true; 364 return true;
375 } 365 }
376 366
377 bool Tpm::UnrestrictSrk(TSS_HCONTEXT context_handle, 367 bool Tpm::UnrestrictSrk(TSS_HCONTEXT context_handle,
378 const SecureBlob& owner_password) { 368 const SecureBlob& owner_password) {
379 TSS_RESULT result; 369 TSS_RESULT result;
380 TSS_HTPM tpm_handle; 370 TSS_HTPM tpm_handle;
381 if (!GetTpmWithAuth(context_handle, owner_password, &tpm_handle)) { 371 if (!GetTpmWithAuth(context_handle, owner_password, &tpm_handle)) {
382 return false; 372 return false;
383 } 373 }
384 374
385 if ((result = Tspi_TPM_SetStatus(tpm_handle, 375 TSS_BOOL current_status = false;
376
377 if ((result = Tspi_TPM_GetStatus(tpm_handle,
386 TSS_TPMSTATUS_DISABLEPUBSRKREAD, 378 TSS_TPMSTATUS_DISABLEPUBSRKREAD,
387 false))) { 379 &current_status))) {
388 LOG(ERROR) << "Error calling Tspi_TPM_SetStatus: " << result; 380 LOG(ERROR) << "Error calling Tspi_TPM_GetStatus: " << result;
389 return false; 381 return false;
390 } 382 }
391 383
384 // If it is currently owner auth (true), set it to SRK auth
385 if (current_status) {
386 if ((result = Tspi_TPM_SetStatus(tpm_handle,
387 TSS_TPMSTATUS_DISABLEPUBSRKREAD,
388 false))) {
389 LOG(ERROR) << "Error calling Tspi_TPM_SetStatus: " << result;
390 return false;
391 }
392 }
393
394 return true;
395 }
396
397 bool Tpm::ChangeOwnerPassword(TSS_HCONTEXT context_handle,
398 const SecureBlob& previous_owner_password,
399 const SecureBlob& owner_password) {
400 TSS_RESULT result;
401 TSS_HTPM tpm_handle;
402 if (!GetTpmWithAuth(context_handle, previous_owner_password, &tpm_handle)) {
403 return false;
404 }
405
406 TSS_HPOLICY policy_handle;
407 if ((result = Tspi_Context_CreateObject(context_handle,
408 TSS_OBJECT_TYPE_POLICY,
409 TSS_POLICY_USAGE,
410 &policy_handle))) {
411 LOG(ERROR) << "Error calling Tspi_Context_CreateObject: " << result;
412 return false;
413 }
414
415 if ((result = Tspi_Policy_SetSecret(policy_handle,
416 TSS_SECRET_MODE_PLAIN,
417 owner_password.size(),
418 const_cast<BYTE *>(static_cast<const BYTE *>(
419 owner_password.const_data()))))) {
420 LOG(ERROR) << "Error calling Tspi_Policy_SetSecret: " << result;
421 Tspi_Context_CloseObject(context_handle, policy_handle);
422 return false;
423 }
424
425 if ((result = Tspi_ChangeAuth(tpm_handle, 0, policy_handle))) {
426 LOG(ERROR) << "Error calling Tspi_ChangeAuth: " << result;
427 Tspi_Context_CloseObject(context_handle, policy_handle);
428 return false;
429 }
430
392 return true; 431 return true;
393 } 432 }
394 433
395 bool Tpm::GetTpm(TSS_HCONTEXT context_handle, TSS_HTPM* tpm_handle) { 434 bool Tpm::GetTpm(TSS_HCONTEXT context_handle, TSS_HTPM* tpm_handle) {
396 TSS_RESULT result; 435 TSS_RESULT result;
397 TSS_HTPM local_tpm_handle; 436 TSS_HTPM local_tpm_handle;
398 if ((result = Tspi_Context_GetTpmObject(context_handle, &local_tpm_handle))) { 437 if ((result = Tspi_Context_GetTpmObject(context_handle, &local_tpm_handle))) {
399 LOG(ERROR) << "Error calling Tspi_Context_GetTpmObject: " << result; 438 LOG(ERROR) << "Error calling Tspi_Context_GetTpmObject: " << result;
400 return false; 439 return false;
401 } 440 }
402 441
403 *tpm_handle = local_tpm_handle; 442 *tpm_handle = local_tpm_handle;
404 return true; 443 return true;
405 } 444 }
406 445
407 bool Tpm::GetTpmWithAuth(TSS_HCONTEXT context_handle, 446 bool Tpm::GetTpmWithAuth(TSS_HCONTEXT context_handle,
408 const SecureBlob& owner_password, 447 const SecureBlob& owner_password,
409 TSS_HTPM* tpm_handle) { 448 TSS_HTPM* tpm_handle) {
410 TSS_RESULT result; 449 TSS_RESULT result;
411 TSS_HTPM local_tpm_handle; 450 TSS_HTPM local_tpm_handle;
412 if (!GetTpm(context_handle, &local_tpm_handle)) { 451 if (!GetTpm(context_handle, &local_tpm_handle)) {
413 LOG(ERROR) << "Error getting TPM handle";
414 return false; 452 return false;
415 } 453 }
416 454
417 TSS_HPOLICY tpm_usage_policy; 455 TSS_HPOLICY tpm_usage_policy;
418 if ((result = Tspi_GetPolicyObject(local_tpm_handle, TSS_POLICY_USAGE, 456 if ((result = Tspi_GetPolicyObject(local_tpm_handle, TSS_POLICY_USAGE,
419 &tpm_usage_policy))) { 457 &tpm_usage_policy))) {
420 LOG(ERROR) << "Error calling Tspi_GetPolicyObject: " << result; 458 LOG(ERROR) << "Error calling Tspi_GetPolicyObject: " << result;
421 return false; 459 return false;
422 } 460 }
423 461
424 if ((result = Tspi_Policy_SetSecret(tpm_usage_policy, TSS_SECRET_MODE_PLAIN, 462 if ((result = Tspi_Policy_SetSecret(tpm_usage_policy, TSS_SECRET_MODE_PLAIN,
425 owner_password.size(), 463 owner_password.size(),
426 const_cast<BYTE *>(static_cast<const BYTE *>( 464 const_cast<BYTE *>(static_cast<const BYTE *>(
427 owner_password.const_data()))))) { 465 owner_password.const_data()))))) {
428 LOG(ERROR) << "Error calling Tspi_Policy_SetSecret: " << result; 466 LOG(ERROR) << "Error calling Tspi_Policy_SetSecret: " << result;
429 return false; 467 return false;
430 } 468 }
431 469
432 *tpm_handle = local_tpm_handle; 470 *tpm_handle = local_tpm_handle;
433 return true; 471 return true;
434 } 472 }
435 473
474 bool Tpm::TestTpmAuth(TSS_HTPM tpm_handle) {
475 // Call Tspi_TPM_GetStatus to test the authentication
476 TSS_RESULT result;
477 TSS_BOOL current_status = false;
478 if ((result = Tspi_TPM_GetStatus(tpm_handle,
479 TSS_TPMSTATUS_DISABLED,
480 &current_status))) {
481 return false;
482 }
483 return true;
484 }
485
436 bool Tpm::GetOwnerPassword(chromeos::Blob* owner_password) { 486 bool Tpm::GetOwnerPassword(chromeos::Blob* owner_password) {
437 bool result = false; 487 bool result = false;
438 if (password_sync_lock_.Try()) { 488 if (password_sync_lock_.Try()) {
439 if (owner_password_.size() != 0) { 489 if (owner_password_.size() != 0) {
440 owner_password->assign(owner_password_.begin(), owner_password_.end()); 490 owner_password->assign(owner_password_.begin(), owner_password_.end());
441 result = true; 491 result = true;
442 } 492 }
443 password_sync_lock_.Release(); 493 password_sync_lock_.Release();
444 } 494 }
445 return result; 495 return result;
446 } 496 }
447 497
448 bool Tpm::InitializeTpm() { 498 bool Tpm::InitializeTpm() {
449 if (!IsConnected()) { 499 if (!IsConnected()) {
450 Connect(); 500 Connect();
451 } 501 }
452 502
453 if (!IsConnected()) { 503 if (!IsConnected()) {
454 LOG(ERROR) << "Failed to connect to TPM"; 504 LOG(ERROR) << "Failed to connect to TPM";
455 return false; 505 return false;
456 } 506 }
457 507
458 if (is_disabled_) { 508 if (is_disabled_) {
459 return false; 509 return false;
460 } 510 }
461 511
462 if (is_owned_) { 512 SecureBlob default_owner_password(sizeof(kTpmWellKnownPassword));
463 return false; 513 memcpy(default_owner_password.data(), kTpmWellKnownPassword,
514 sizeof(kTpmWellKnownPassword));
515
516 bool took_ownership = false;
517 if (!is_owned_) {
518 file_util::Delete(FilePath(kOpenCryptokiPath), true);
519 file_util::Delete(FilePath(kTpmOwnedFile), false);
520
521 if (!IsEndorsementKeyAvailable(context_handle_)) {
522 if (!CreateEndorsementKey(context_handle_)) {
523 LOG(ERROR) << "Failed to create endorsement key";
524 return false;
525 }
526 }
527
528 if (!IsEndorsementKeyAvailable(context_handle_)) {
529 LOG(ERROR) << "Endorsement key is not available";
530 return false;
531 }
532
533 if (!TakeOwnership(context_handle_, kMaxTimeoutRetries,
534 default_owner_password)) {
535 LOG(ERROR) << "Take Ownership failed";
536 return false;
537 }
538
539 is_owned_ = true;
540 took_ownership = true;
464 } 541 }
465 542
466 file_util::Delete(FilePath(kOpenCryptokiPath), true); 543 // Ensure the SRK is available
467 file_util::Delete(FilePath(kTpmOwnedFile), false); 544 TSS_HKEY srk_handle;
545 TSS_UUID SRK_UUID = TSS_UUID_SRK;
546 if ((result = Tspi_Context_LoadKeyByUUID(context_handle, TSS_PS_TYPE_SYSTEM,
547 SRK_UUID, &srk_handle))) {
548 is_srk_available_ = false;
549 } else {
550 Tspi_Context_CloseObject(context_handle, srk_handle);
551 is_srk_available_ = true;
552 }
468 553
469 if (!IsEndorsementKeyAvailable(context_handle_)) { 554 // If we can open the TPM with the default password, then we still need to
470 if (!CreateEndorsementKey(context_handle_)) { 555 // zero the SRK password and unrestrict it, then change the owner password.
471 LOG(ERROR) << "Failed to create endorsement key"; 556 TSS_HTPM tpm_handle;
557 if (GetTpmWithAuth(context_handle_, default_owner_password, &tpm_handle) &&
558 TestTpmAuth(tpm_handle)) {
559 if (!ZeroSrkPassword(context_handle_, default_owner_password)) {
560 LOG(ERROR) << "Couldn't zero SRK password";
472 return false; 561 return false;
473 } 562 }
563
564 if (!UnrestrictSrk(context_handle_, default_owner_password)) {
565 LOG(ERROR) << "Couldn't unrestrict the SRK";
566 return false;
567 }
568 SecureBlob owner_password;
569 CreateOwnerPassword(&owner_password);
570
571 if (!ChangeOwnerPassword(context_handle_, default_owner_password,
572 owner_password)) {
573 LOG(ERROR) << "Couldn't set the owner password";
574 return false;
575 }
576
577 password_sync_lock_.Acquire();
578 owner_password_.assign(owner_password.begin(), owner_password.end());
579 password_sync_lock_.Release();
580
581 file_util::WriteFile(FilePath(kTpmOwnedFile), NULL, 0);
474 } 582 }
475 583
476 if (!IsEndorsementKeyAvailable(context_handle_)) { 584 return took_ownership;
477 LOG(ERROR) << "Endorsement key is not available";
478 return false;
479 }
480
481 if (!TakeOwnership(context_handle_, kMaxTimeoutRetries)) {
482 LOG(ERROR) << "Take Ownership failed";
483 return false;
484 }
485
486 SecureBlob owner_password;
487 password_sync_lock_.Acquire();
488 owner_password.assign(owner_password_.begin(), owner_password_.end());
489 password_sync_lock_.Release();
490
491 if (!ZeroSrkPassword(context_handle_, owner_password)) {
492 LOG(ERROR) << "Couldn't zero SRK password";
493 return false;
494 }
495
496 if (!UnrestrictSrk(context_handle_, owner_password)) {
497 LOG(ERROR) << "Couldn't unrestrict the SRK";
498 return false;
499 }
500
501 is_owned_ = true;
502
503 file_util::WriteFile(FilePath(kTpmOwnedFile), NULL, 0);
504
505 return true;
506 } 585 }
507 586
508 } // namespace tpm_init 587 } // namespace tpm_init
OLDNEW
« no previous file with comments | « tpm.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698