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

Unified 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « tpm.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: tpm.cc
diff --git a/tpm.cc b/tpm.cc
index 37c5ab71cb4ebfd4bfbb1ef70bdc89b60599a5c5..b18514596f24f6d7b7ddc10d06d5667b8cb5ead1 100644
--- a/tpm.cc
+++ b/tpm.cc
@@ -24,6 +24,7 @@ const char* kTpmOwnedFile = "/var/lib/.tpm_owned";
const char* kOpenCryptokiPath = "/var/lib/opencryptoki";
const int kTpmConnectRetries = 10;
const int kTpmConnectIntervalMs = 100;
+const char kTpmWellKnownPassword[] = TSS_WELL_KNOWN_SECRET;
Tpm::Tpm()
: context_handle_(0),
@@ -32,7 +33,8 @@ Tpm::Tpm()
owner_password_(),
password_sync_lock_(),
is_disabled_(true),
- is_owned_(false) {
+ is_owned_(false),
+ is_srk_available_(false) {
}
Tpm::~Tpm() {
@@ -49,6 +51,17 @@ bool Tpm::Init() {
if (file_util::PathExists(FilePath(kTpmCheckEnabledFile))) {
is_disabled_ = IsDisabledCheckViaSysfs();
is_owned_ = IsOwnedCheckViaSysfs();
+ } else {
+ TSS_HCONTEXT context_handle;
+ if (OpenAndConnectTpm(&context_handle)) {
+ bool enabled = false;
+ bool owned = false;
+ IsEnabledOwnedCheckViaContext(context_handle, &enabled, &owned);
+ is_disabled_ = !enabled;
+ is_owned_ = owned;
+ Tspi_Context_Close(context_handle);
+ } else {
+ }
}
return true;
}
@@ -164,49 +177,32 @@ bool Tpm::IsOwnedCheckViaSysfs() {
return (contents[0] != '0');
}
-bool Tpm::IsDisabledCheckViaContext(TSS_HCONTEXT context_handle) {
- bool value = true;
- TSS_RESULT result;
- TSS_HTPM tpm_handle;
- if (!GetTpm(context_handle, &tpm_handle)) {
- return value;
- }
+void Tpm::IsEnabledOwnedCheckViaContext(TSS_HCONTEXT context_handle,
+ bool* enabled, bool* owned) {
+ *enabled = false;
+ *owned = false;
- UINT32 cap_length = 0;
- BYTE* cap = NULL;
- if ((result = Tspi_TPM_GetCapability(tpm_handle, TSS_TPMCAP_FLAG,
- 0, NULL, &cap_length, &cap))) {
- LOG(ERROR) << "Error calling Tspi_TPM_GetCapability: " << result;
- return value;
- }
- if (cap_length >= (2 * sizeof(int))) {
- value = (((*(reinterpret_cast<int*>(cap))) & TPM_PF_DISABLE) != 0);
- }
- Tspi_Context_FreeMemory(context_handle, cap);
- return value;
-}
-
-bool Tpm::IsOwnedCheckViaContext(TSS_HCONTEXT context_handle) {
- bool value = true;
TSS_RESULT result;
TSS_HTPM tpm_handle;
if (!GetTpm(context_handle, &tpm_handle)) {
- LOG(ERROR) << "Error calling Tspi_Context_GetTpmObject: " << result;
- return value;
+ return;
}
+ UINT32 sub_cap = TSS_TPMCAP_PROP_OWNER;
UINT32 cap_length = 0;
BYTE* cap = NULL;
- if ((result = Tspi_TPM_GetCapability(tpm_handle, TSS_TPMCAP_FLAG,
- 0, NULL, &cap_length, &cap))) {
- LOG(ERROR) << "Error calling Tspi_TPM_GetCapability: " << result;
- return value;
- }
- if (cap_length >= (2 * sizeof(int))) {
- value = (((*(reinterpret_cast<int*>(cap))) & TPM_PF_OWNERSHIP) != 0);
+ if ((result = Tspi_TPM_GetCapability(tpm_handle, TSS_TPMCAP_PROPERTY,
+ sizeof(sub_cap),
+ reinterpret_cast<BYTE*>(&sub_cap),
+ &cap_length, &cap)) == 0) {
+ if (cap_length >= (sizeof(TSS_BOOL))) {
+ *enabled = true;
+ *owned = ((*(reinterpret_cast<TSS_BOOL*>(cap))) != 0);
+ }
+ Tspi_Context_FreeMemory(context_handle, cap);
+ } else if(ERROR_CODE(result) == TPM_E_DISABLED) {
+ *enabled = false;
}
- Tspi_Context_FreeMemory(context_handle, cap);
- return value;
}
bool Tpm::CreateEndorsementKey(TSS_HCONTEXT context_handle) {
@@ -245,7 +241,7 @@ bool Tpm::IsEndorsementKeyAvailable(TSS_HCONTEXT context_handle) {
TSS_HKEY local_key_handle;
if ((result = Tspi_TPM_GetPubEndorsementKey(tpm_handle, false, NULL,
&local_key_handle))) {
- LOG(ERROR) << "Error calling Tspi_Context_CreateObject: " << result;
+ LOG(ERROR) << "Error calling Tspi_TPM_GetPubEndorsementKey: " << result;
return false;
}
@@ -264,10 +260,8 @@ void Tpm::CreateOwnerPassword(SecureBlob* password) {
password->swap(tpm_password);
}
-bool Tpm::TakeOwnership(TSS_HCONTEXT context_handle, int max_timeout_tries) {
- SecureBlob owner_password;
- CreateOwnerPassword(&owner_password);
-
+bool Tpm::TakeOwnership(TSS_HCONTEXT context_handle, int max_timeout_tries,
+ const SecureBlob& owner_password) {
TSS_RESULT result;
TSS_HTPM tpm_handle;
if (!GetTpmWithAuth(context_handle, owner_password, &tpm_handle)) {
@@ -318,10 +312,6 @@ bool Tpm::TakeOwnership(TSS_HCONTEXT context_handle, int max_timeout_tries) {
Tspi_Context_CloseObject(context_handle, srk_handle);
- password_sync_lock_.Acquire();
- owner_password_.swap(owner_password);
- password_sync_lock_.Release();
-
return true;
}
@@ -337,7 +327,7 @@ bool Tpm::ZeroSrkPassword(TSS_HCONTEXT context_handle,
TSS_UUID SRK_UUID = TSS_UUID_SRK;
if ((result = Tspi_Context_LoadKeyByUUID(context_handle, TSS_PS_TYPE_SYSTEM,
SRK_UUID, &srk_handle))) {
- LOG(ERROR) << "Couldn't load SRK: " << result;
+ LOG(ERROR) << "Error calling Tspi_Context_LoadKeyByUUID: " << result;
return false;
}
@@ -346,7 +336,7 @@ bool Tpm::ZeroSrkPassword(TSS_HCONTEXT context_handle,
TSS_OBJECT_TYPE_POLICY,
TSS_POLICY_USAGE,
&policy_handle))) {
- LOG(ERROR) << "Error creating policy object: " << result;
+ LOG(ERROR) << "Error calling Tspi_Context_CreateObject: " << result;
Tspi_Context_CloseObject(context_handle, srk_handle);
return false;
}
@@ -354,7 +344,7 @@ bool Tpm::ZeroSrkPassword(TSS_HCONTEXT context_handle,
BYTE new_password[0];
if ((result = Tspi_Policy_SetSecret(policy_handle, TSS_SECRET_MODE_PLAIN,
0, new_password))) {
- LOG(ERROR) << "Error setting srk password: " << result;
+ LOG(ERROR) << "Error calling Tspi_Policy_SetSecret: " << result;
Tspi_Context_CloseObject(context_handle, policy_handle);
Tspi_Context_CloseObject(context_handle, srk_handle);
return false;
@@ -363,7 +353,7 @@ bool Tpm::ZeroSrkPassword(TSS_HCONTEXT context_handle,
if ((result = Tspi_ChangeAuth(srk_handle,
tpm_handle,
policy_handle))) {
- LOG(ERROR) << "Error creating policy object: " << result;
+ LOG(ERROR) << "Error calling Tspi_ChangeAuth: " << result;
Tspi_Context_CloseObject(context_handle, policy_handle);
Tspi_Context_CloseObject(context_handle, srk_handle);
return false;
@@ -382,10 +372,59 @@ bool Tpm::UnrestrictSrk(TSS_HCONTEXT context_handle,
return false;
}
- if ((result = Tspi_TPM_SetStatus(tpm_handle,
+ TSS_BOOL current_status = false;
+
+ if ((result = Tspi_TPM_GetStatus(tpm_handle,
TSS_TPMSTATUS_DISABLEPUBSRKREAD,
- false))) {
- LOG(ERROR) << "Error calling Tspi_TPM_SetStatus: " << result;
+ &current_status))) {
+ LOG(ERROR) << "Error calling Tspi_TPM_GetStatus: " << result;
+ return false;
+ }
+
+ // If it is currently owner auth (true), set it to SRK auth
+ if (current_status) {
+ if ((result = Tspi_TPM_SetStatus(tpm_handle,
+ TSS_TPMSTATUS_DISABLEPUBSRKREAD,
+ false))) {
+ LOG(ERROR) << "Error calling Tspi_TPM_SetStatus: " << result;
+ return false;
+ }
+ }
+
+ return true;
+}
+
+bool Tpm::ChangeOwnerPassword(TSS_HCONTEXT context_handle,
+ const SecureBlob& previous_owner_password,
+ const SecureBlob& owner_password) {
+ TSS_RESULT result;
+ TSS_HTPM tpm_handle;
+ if (!GetTpmWithAuth(context_handle, previous_owner_password, &tpm_handle)) {
+ return false;
+ }
+
+ TSS_HPOLICY policy_handle;
+ if ((result = Tspi_Context_CreateObject(context_handle,
+ TSS_OBJECT_TYPE_POLICY,
+ TSS_POLICY_USAGE,
+ &policy_handle))) {
+ LOG(ERROR) << "Error calling Tspi_Context_CreateObject: " << result;
+ return false;
+ }
+
+ if ((result = Tspi_Policy_SetSecret(policy_handle,
+ TSS_SECRET_MODE_PLAIN,
+ owner_password.size(),
+ const_cast<BYTE *>(static_cast<const BYTE *>(
+ owner_password.const_data()))))) {
+ LOG(ERROR) << "Error calling Tspi_Policy_SetSecret: " << result;
+ Tspi_Context_CloseObject(context_handle, policy_handle);
+ return false;
+ }
+
+ if ((result = Tspi_ChangeAuth(tpm_handle, 0, policy_handle))) {
+ LOG(ERROR) << "Error calling Tspi_ChangeAuth: " << result;
+ Tspi_Context_CloseObject(context_handle, policy_handle);
return false;
}
@@ -410,7 +449,6 @@ bool Tpm::GetTpmWithAuth(TSS_HCONTEXT context_handle,
TSS_RESULT result;
TSS_HTPM local_tpm_handle;
if (!GetTpm(context_handle, &local_tpm_handle)) {
- LOG(ERROR) << "Error getting TPM handle";
return false;
}
@@ -433,6 +471,18 @@ bool Tpm::GetTpmWithAuth(TSS_HCONTEXT context_handle,
return true;
}
+bool Tpm::TestTpmAuth(TSS_HTPM tpm_handle) {
+ // Call Tspi_TPM_GetStatus to test the authentication
+ TSS_RESULT result;
+ TSS_BOOL current_status = false;
+ if ((result = Tspi_TPM_GetStatus(tpm_handle,
+ TSS_TPMSTATUS_DISABLED,
+ &current_status))) {
+ return false;
+ }
+ return true;
+}
+
bool Tpm::GetOwnerPassword(chromeos::Blob* owner_password) {
bool result = false;
if (password_sync_lock_.Try()) {
@@ -459,50 +509,79 @@ bool Tpm::InitializeTpm() {
return false;
}
- if (is_owned_) {
- return false;
- }
+ SecureBlob default_owner_password(sizeof(kTpmWellKnownPassword));
+ memcpy(default_owner_password.data(), kTpmWellKnownPassword,
+ sizeof(kTpmWellKnownPassword));
+
+ bool took_ownership = false;
+ if (!is_owned_) {
+ file_util::Delete(FilePath(kOpenCryptokiPath), true);
+ file_util::Delete(FilePath(kTpmOwnedFile), false);
+
+ if (!IsEndorsementKeyAvailable(context_handle_)) {
+ if (!CreateEndorsementKey(context_handle_)) {
+ LOG(ERROR) << "Failed to create endorsement key";
+ return false;
+ }
+ }
- file_util::Delete(FilePath(kOpenCryptokiPath), true);
- file_util::Delete(FilePath(kTpmOwnedFile), false);
+ if (!IsEndorsementKeyAvailable(context_handle_)) {
+ LOG(ERROR) << "Endorsement key is not available";
+ return false;
+ }
- if (!IsEndorsementKeyAvailable(context_handle_)) {
- if (!CreateEndorsementKey(context_handle_)) {
- LOG(ERROR) << "Failed to create endorsement key";
+ if (!TakeOwnership(context_handle_, kMaxTimeoutRetries,
+ default_owner_password)) {
+ LOG(ERROR) << "Take Ownership failed";
return false;
}
- }
- if (!IsEndorsementKeyAvailable(context_handle_)) {
- LOG(ERROR) << "Endorsement key is not available";
- return false;
+ is_owned_ = true;
+ took_ownership = true;
}
- if (!TakeOwnership(context_handle_, kMaxTimeoutRetries)) {
- LOG(ERROR) << "Take Ownership failed";
- return false;
+ // Ensure the SRK is available
+ TSS_HKEY srk_handle;
+ TSS_UUID SRK_UUID = TSS_UUID_SRK;
+ if ((result = Tspi_Context_LoadKeyByUUID(context_handle, TSS_PS_TYPE_SYSTEM,
+ SRK_UUID, &srk_handle))) {
+ is_srk_available_ = false;
+ } else {
+ Tspi_Context_CloseObject(context_handle, srk_handle);
+ is_srk_available_ = true;
}
- SecureBlob owner_password;
- password_sync_lock_.Acquire();
- owner_password.assign(owner_password_.begin(), owner_password_.end());
- password_sync_lock_.Release();
+ // If we can open the TPM with the default password, then we still need to
+ // zero the SRK password and unrestrict it, then change the owner password.
+ TSS_HTPM tpm_handle;
+ if (GetTpmWithAuth(context_handle_, default_owner_password, &tpm_handle) &&
+ TestTpmAuth(tpm_handle)) {
+ if (!ZeroSrkPassword(context_handle_, default_owner_password)) {
+ LOG(ERROR) << "Couldn't zero SRK password";
+ return false;
+ }
- if (!ZeroSrkPassword(context_handle_, owner_password)) {
- LOG(ERROR) << "Couldn't zero SRK password";
- return false;
- }
+ if (!UnrestrictSrk(context_handle_, default_owner_password)) {
+ LOG(ERROR) << "Couldn't unrestrict the SRK";
+ return false;
+ }
+ SecureBlob owner_password;
+ CreateOwnerPassword(&owner_password);
- if (!UnrestrictSrk(context_handle_, owner_password)) {
- LOG(ERROR) << "Couldn't unrestrict the SRK";
- return false;
- }
+ if (!ChangeOwnerPassword(context_handle_, default_owner_password,
+ owner_password)) {
+ LOG(ERROR) << "Couldn't set the owner password";
+ return false;
+ }
- is_owned_ = true;
+ password_sync_lock_.Acquire();
+ owner_password_.assign(owner_password.begin(), owner_password.end());
+ password_sync_lock_.Release();
- file_util::WriteFile(FilePath(kTpmOwnedFile), NULL, 0);
+ file_util::WriteFile(FilePath(kTpmOwnedFile), NULL, 0);
+ }
- return true;
+ return took_ownership;
}
} // namespace tpm_init
« 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