summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorUtkarsh Sanghi <usanghi@chromium.org>2015-08-31 12:18:55 -0700
committerchrome-bot <chrome-bot@chromium.org>2015-09-09 11:18:01 -0700
commit50e52ff6bcc478118a1cdec27903a5af5061d77b (patch)
tree6b49512635ddd192c10077add62efcf6f5dd9cd7
parent565f88fe8ebdabefe07e5d5cb65ae9bcab509368 (diff)
downloadtpm_manager-50e52ff6bcc478118a1cdec27903a5af5061d77b.tar.gz
tpm_manager: Implement Ownership flow
This CL implements the TakeOwnership IPC interface in TpmManager. This allows clients to take ownership of a Tpm by injecting a random password. Once a Tpm is owned, it can be utilized by ChromeOS. BUG=chromium:521635 TEST=unit and take ownership on DUT Change-Id: Icd4de6b6b1be419dd035e535473929cb8c0ecb16 Reviewed-on: https://chromium-review.googlesource.com/294614 Commit-Ready: Utkarsh Sanghi <usanghi@chromium.org> Tested-by: Utkarsh Sanghi <usanghi@chromium.org> Reviewed-by: Utkarsh Sanghi <usanghi@chromium.org>
-rw-r--r--client/main.cc22
-rw-r--r--common/local_data.proto11
-rw-r--r--server/main.cc12
-rw-r--r--server/openssl_crypto_util.cc26
-rw-r--r--server/openssl_crypto_util.h36
-rw-r--r--server/tpm2_initializer_impl.cc121
-rw-r--r--server/tpm2_initializer_impl.h66
-rw-r--r--server/tpm2_initializer_test.cc138
-rw-r--r--server/tpm_connection.cc35
-rw-r--r--server/tpm_connection.h13
-rw-r--r--server/tpm_initializer_impl.cc246
-rw-r--r--server/tpm_initializer_impl.h80
-rw-r--r--server/tpm_manager-seccomp-amd64.policy3
-rw-r--r--server/tpm_manager_service.cc5
-rw-r--r--server/tpm_manager_service.h12
-rw-r--r--server/tpm_manager_service_test.cc7
-rw-r--r--server/tpm_status_impl.cc2
-rw-r--r--server/tpm_util.h16
-rw-r--r--tpm_manager.gyp5
19 files changed, 831 insertions, 25 deletions
diff --git a/client/main.cc b/client/main.cc
index faa62a5..376e0aa 100644
--- a/client/main.cc
+++ b/client/main.cc
@@ -22,11 +22,14 @@
namespace tpm_manager {
const char kGetTpmStatusCommand[] = "status";
+const char kTakeOwnershipCommand[] = "take_ownership";
const char kUsage[] = R"(
Usage: tpm_manager_client <command> [<args>]
Commands:
status
Prints the current status of the Tpm.
+ take_ownership
+ Takes ownership of the Tpm with a random password.
)";
using ClientLoopBase = chromeos::Daemon;
@@ -69,6 +72,9 @@ class ClientLoop : public ClientLoopBase {
} else if (command_line->HasSwitch(kGetTpmStatusCommand)) {
task = base::Bind(&ClientLoop::HandleGetTpmStatus,
weak_factory_.GetWeakPtr());
+ } else if (command_line->HasSwitch(kTakeOwnershipCommand)) {
+ task = base::Bind(&ClientLoop::HandleTakeOwnership,
+ weak_factory_.GetWeakPtr());
} else {
// Command line arguments did not match any valid commands.
LOG(ERROR) << "No Valid Command selected.";
@@ -95,6 +101,22 @@ class ClientLoop : public ClientLoopBase {
weak_factory_.GetWeakPtr()));
}
+ void PrintTakeOwnershipReply(const TakeOwnershipReply& reply) {
+ if (reply.has_status() && reply.status() == STATUS_NOT_AVAILABLE) {
+ LOG(INFO) << "tpm_managerd is not available.";
+ } else {
+ LOG(INFO) << "TakeOwnershipReply: " << GetProtoDebugString(reply);
+ }
+ Quit();
+ }
+
+ void HandleTakeOwnership() {
+ TakeOwnershipRequest request;
+ tpm_manager_->TakeOwnership(request,
+ base::Bind(&ClientLoop::PrintTakeOwnershipReply,
+ weak_factory_.GetWeakPtr()));
+ }
+
// Pointer to a DBus proxy to tpm_managerd.
std::unique_ptr<tpm_manager::TpmManagerInterface> tpm_manager_;
diff --git a/common/local_data.proto b/common/local_data.proto
index efcca47..509f027 100644
--- a/common/local_data.proto
+++ b/common/local_data.proto
@@ -1,9 +1,20 @@
+// Copyright 2015 The Chromium OS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
option optimize_for = LITE_RUNTIME;
package tpm_manager;
// The format of persistent local TPM management data stored on the device.
+// When Tpm ownership is taken, this protobuf is populated with the passwords
+// used to take ownership, and with a list of clients who have a dependency on
+// the owner password (like Attestation, InstallAttributes and BootLockbox).
+// when all the clients have the owner password injected, this protobuf is
+// cleared of all passwords.
message LocalData {
optional bool owned_by_this_install = 1;
optional bytes owner_password = 2;
repeated string owner_dependency = 3;
+ optional bytes endorsement_password = 4;
+ optional bytes lockout_password = 5;
}
diff --git a/server/main.cc b/server/main.cc
index 50063f3..f7dcc45 100644
--- a/server/main.cc
+++ b/server/main.cc
@@ -18,8 +18,10 @@
#include "tpm_manager/server/tpm_manager_service.h"
#if USE_TPM2
+#include "tpm_manager/server/tpm2_initializer_impl.h"
#include "tpm_manager/server/tpm2_status_impl.h"
#else
+#include "tpm_manager/server/tpm_initializer_impl.h"
#include "tpm_manager/server/tpm_status_impl.h"
#endif
@@ -37,13 +39,20 @@ class TpmManagerDaemon : public chromeos::DBusServiceDaemon {
local_data_store_.reset(new tpm_manager::LocalDataStoreImpl());
#if USE_TPM2
tpm_status_.reset(new tpm_manager::Tpm2StatusImpl);
+ tpm_initializer_.reset(new tpm_manager::Tpm2InitializerImpl(
+ local_data_store_.get(),
+ tpm_status_.get()));
#else
tpm_status_.reset(new tpm_manager::TpmStatusImpl);
+ tpm_initializer_.reset(new tpm_manager::TpmInitializerImpl(
+ local_data_store_.get(),
+ tpm_status_.get()));
#endif
tpm_manager_service_.reset(new tpm_manager::TpmManagerService(
command_line->HasSwitch(kWaitForOwnershipTriggerSwitch),
local_data_store_.get(),
- tpm_status_.get()));
+ tpm_status_.get(),
+ tpm_initializer_.get()));
}
protected:
@@ -66,6 +75,7 @@ class TpmManagerDaemon : public chromeos::DBusServiceDaemon {
private:
std::unique_ptr<tpm_manager::LocalDataStore> local_data_store_;
std::unique_ptr<tpm_manager::TpmStatus> tpm_status_;
+ std::unique_ptr<tpm_manager::TpmInitializer> tpm_initializer_;
std::unique_ptr<tpm_manager::TpmManagerInterface> tpm_manager_service_;
std::unique_ptr<tpm_manager::DBusService> dbus_service_;
diff --git a/server/openssl_crypto_util.cc b/server/openssl_crypto_util.cc
new file mode 100644
index 0000000..0edaf05
--- /dev/null
+++ b/server/openssl_crypto_util.cc
@@ -0,0 +1,26 @@
+// Copyright 2015 The Chromium OS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "tpm_manager/server/openssl_crypto_util.h"
+
+#include <base/logging.h>
+#include <base/stl_util.h>
+#include <openssl/rand.h>
+
+namespace tpm_manager {
+
+bool OpensslCryptoUtil::GetRandomBytes(size_t num_bytes,
+ std::string* random_data) {
+ random_data->resize(num_bytes);
+ unsigned char* random_buffer =
+ reinterpret_cast<unsigned char*>(string_as_array(random_data));
+ if (RAND_bytes(random_buffer, num_bytes) != 1) {
+ LOG(ERROR) << "Error getting random bytes using Openssl.";
+ random_data->clear();
+ return false;
+ }
+ return true;
+}
+
+} // namespace tpm_manager
diff --git a/server/openssl_crypto_util.h b/server/openssl_crypto_util.h
new file mode 100644
index 0000000..f252e57
--- /dev/null
+++ b/server/openssl_crypto_util.h
@@ -0,0 +1,36 @@
+// Copyright 2015 The Chromium OS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef TPM_MANAGER_SERVER_OPENSSL_CRYPTO_UTIL_H_
+#define TPM_MANAGER_SERVER_OPENSSL_CRYPTO_UTIL_H_
+
+#include <string>
+
+#include <base/compiler_specific.h>
+#include <base/macros.h>
+
+namespace tpm_manager {
+
+// This class is used to provide a mockable interface for openssl calls.
+// Example usage:
+// OpensslCryptoUtil util;
+// std::string random_bytes;
+// bool result = util.GetRandomBytes(5, &random_bytes);
+class OpensslCryptoUtil {
+ public:
+ OpensslCryptoUtil() = default;
+ ~OpensslCryptoUtil() = default;
+
+ // This method sets the out argument |random_data| to a string with at
+ // least |num_bytes| of random data and returns true on success.
+ bool GetRandomBytes(size_t num_bytes,
+ std::string* random_data) WARN_UNUSED_RESULT;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(OpensslCryptoUtil);
+};
+
+} // namespace tpm_manager
+
+#endif // TPM_MANAGER_SERVER_OPENSSL_CRYPTO_UTIL_H_
diff --git a/server/tpm2_initializer_impl.cc b/server/tpm2_initializer_impl.cc
new file mode 100644
index 0000000..63b4a66
--- /dev/null
+++ b/server/tpm2_initializer_impl.cc
@@ -0,0 +1,121 @@
+// Copyright 2015 The Chromium OS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "tpm_manager/server/tpm2_initializer_impl.h"
+
+#include <string>
+
+#include <base/logging.h>
+#include <trunks/tpm_utility.h>
+#include <trunks/trunks_factory_impl.h>
+
+#include "tpm_manager/common/local_data.pb.h"
+
+namespace {
+const size_t kDefaultPasswordSize = 20;
+} // namespace
+
+namespace tpm_manager {
+
+Tpm2InitializerImpl::Tpm2InitializerImpl(LocalDataStore* local_data_store,
+ TpmStatus* tpm_status)
+ : trunks_factory_(new trunks::TrunksFactoryImpl()),
+ openssl_util_(new OpensslCryptoUtil()),
+ local_data_store_(local_data_store),
+ tpm_status_(tpm_status) {}
+
+Tpm2InitializerImpl::Tpm2InitializerImpl(trunks::TrunksFactory* factory,
+ OpensslCryptoUtil* openssl_util,
+ LocalDataStore* local_data_store,
+ TpmStatus* tpm_status)
+ : trunks_factory_(factory),
+ openssl_util_(openssl_util),
+ local_data_store_(local_data_store),
+ tpm_status_(tpm_status) {}
+
+bool Tpm2InitializerImpl::InitializeTpm() {
+ if (!SeedTpmRng()) {
+ return false;
+ }
+ if (tpm_status_->IsTpmOwned()) {
+ // Tpm is already owned, so we do not need to do anything.
+ VLOG(1) << "Tpm already owned.";
+ return true;
+ }
+ // First we read the local data. If the |owned_by_this_install| flag is set,
+ // either we did not finish removing owner dependencies or TakeOwnership
+ // failed. In either case, we want to retake ownership with the same
+ // passwords.
+ LocalData local_data;
+ if (!local_data_store_->Read(&local_data)) {
+ LOG(ERROR) << "Error reading local data.";
+ return false;
+ }
+ std::string owner_password;
+ std::string endorsement_password;
+ std::string lockout_password;
+ // TODO(usanghi): Use owner dependency information rather than the
+ // |owned_by_this_install| flag here.
+ if (local_data.owned_by_this_install()) {
+ owner_password.assign(local_data.owner_password());
+ endorsement_password.assign(local_data.endorsement_password());
+ lockout_password.assign(local_data.lockout_password());
+ } else {
+ if (!GetTpmRandomData(kDefaultPasswordSize, &owner_password)) {
+ LOG(ERROR) << "Error generating a random owner password.";
+ return false;
+ }
+ if (!GetTpmRandomData(kDefaultPasswordSize, &endorsement_password)) {
+ LOG(ERROR) << "Error generating a random endorsement password.";
+ return false;
+ }
+ if (!GetTpmRandomData(kDefaultPasswordSize, &lockout_password)) {
+ LOG(ERROR) << "Error generating a random lockout password.";
+ return false;
+ }
+ }
+ // We write the passwords to disk, in case there is an error while taking
+ // ownership.
+ local_data.set_owned_by_this_install(true);
+ local_data.set_owner_password(owner_password);
+ local_data.set_endorsement_password(endorsement_password);
+ local_data.set_lockout_password(lockout_password);
+ // TODO(usanghi): Add ownership dependencies here.
+ if (!local_data_store_->Write(local_data)) {
+ LOG(ERROR) << "Error saving local data.";
+ return false;
+ }
+ trunks::TPM_RC result = trunks_factory_->GetTpmUtility()->TakeOwnership(
+ owner_password, endorsement_password, lockout_password);
+ if (result != trunks::TPM_RC_SUCCESS) {
+ LOG(ERROR) << "Error taking ownership of TPM2.0";
+ return false;
+ }
+ return true;
+}
+
+bool Tpm2InitializerImpl::SeedTpmRng() {
+ std::string random_bytes;
+ if (!openssl_util_->GetRandomBytes(kDefaultPasswordSize, &random_bytes)) {
+ return false;
+ }
+ trunks::TPM_RC result = trunks_factory_->GetTpmUtility()->StirRandom(
+ random_bytes, nullptr /* No Authorization */);
+ if (result != trunks::TPM_RC_SUCCESS) {
+ return false;
+ }
+ return true;
+}
+
+bool Tpm2InitializerImpl::GetTpmRandomData(size_t num_bytes,
+ std::string* random_data) {
+ trunks::TPM_RC result = trunks_factory_->GetTpmUtility()->GenerateRandom(
+ num_bytes, nullptr /* No Authorization */, random_data);
+ if (result != trunks::TPM_RC_SUCCESS) {
+ return false;
+ }
+ return true;
+}
+
+} // namespace tpm_manager
diff --git a/server/tpm2_initializer_impl.h b/server/tpm2_initializer_impl.h
new file mode 100644
index 0000000..a50abea
--- /dev/null
+++ b/server/tpm2_initializer_impl.h
@@ -0,0 +1,66 @@
+// Copyright 2015 The Chromium OS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef TPM_MANAGER_SERVER_TPM2_INITIALIZER_IMPL_H_
+#define TPM_MANAGER_SERVER_TPM2_INITIALIZER_IMPL_H_
+
+#include "tpm_manager/server/tpm_initializer.h"
+
+#include <string>
+#include <memory>
+
+#include <base/macros.h>
+#include <trunks/trunks_factory.h>
+
+#include "tpm_manager/server/local_data_store.h"
+#include "tpm_manager/server/openssl_crypto_util.h"
+#include "tpm_manager/server/tpm_status.h"
+
+namespace tpm_manager {
+
+// This class initializes a Tpm2.0 chip by taking ownership. Example use of
+// this class is:
+// LocalDataStore data_store;
+// Tpm2StatusImpl status;
+// Tpm2InitializerImpl initializer(&data_store, &status);
+// initializer.InitializeTpm();
+// If the tpm is unowned, InitializeTpm injects random owner, endorsement and
+// lockout passwords, intializes the SRK with empty authorization, and persists
+// the passwords to disk until all the owner dependencies are satisfied.
+class Tpm2InitializerImpl : public TpmInitializer {
+ public:
+ // Does not take ownership of |local_data_store| or |tpm_status|.
+ Tpm2InitializerImpl(LocalDataStore* local_data_store,
+ TpmStatus* tpm_status);
+ // Does not take ownership of |openssl_util|, |local_data_store| or
+ // |tpm_status|. Takes ownership of |factory|.
+ Tpm2InitializerImpl(trunks::TrunksFactory* factory,
+ OpensslCryptoUtil* openssl_util,
+ LocalDataStore* local_data_store,
+ TpmStatus* tpm_status);
+ ~Tpm2InitializerImpl() override = default;
+
+ // TpmInitializer methods.
+ bool InitializeTpm() override;
+
+ private:
+ // Seeds the onboard Tpm random number generator with random bytes from
+ // Openssl, if the Tpm RNG has not been seeded yet. Returns true on success.
+ bool SeedTpmRng();
+
+ // Gets random bytes of length |num_bytes| and populates the string at
+ // |random_data|. Returns true on success.
+ bool GetTpmRandomData(size_t num_bytes, std::string* random_data);
+
+ std::unique_ptr<trunks::TrunksFactory> trunks_factory_;
+ OpensslCryptoUtil* openssl_util_;
+ LocalDataStore* local_data_store_;
+ TpmStatus* tpm_status_;
+
+ DISALLOW_COPY_AND_ASSIGN(Tpm2InitializerImpl);
+};
+
+} // namespace tpm_manager
+
+#endif // TPM_MANAGER_SERVER_TPM2_INITIALIZER_IMPL_H_
diff --git a/server/tpm2_initializer_test.cc b/server/tpm2_initializer_test.cc
new file mode 100644
index 0000000..9d1bfd0
--- /dev/null
+++ b/server/tpm2_initializer_test.cc
@@ -0,0 +1,138 @@
+// Copyright 2015 The Chromium OS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "tpm_manager/server/tpm2_initializer_impl.h"
+
+#include <memory>
+
+#include <gmock/gmock.h>
+#include <gtest/gtest.h>
+#include <trunks/mock_tpm_utility.h>
+#include <trunks/trunks_factory_for_test.h>
+
+#include "tpm_manager/server/mock_local_data_store.h"
+#include "tpm_manager/server/mock_openssl_crypto_util.h"
+#include "tpm_manager/server/mock_tpm_status.h"
+
+using testing::_;
+using testing::DoAll;
+using testing::NiceMock;
+using testing::Return;
+using testing::SaveArg;
+using testing::SetArgPointee;
+
+namespace tpm_manager {
+
+class Tpm2InitializerTest : public testing::Test {
+ public:
+ Tpm2InitializerTest() = default;
+ virtual ~Tpm2InitializerTest() = default;
+
+ void SetUp() {
+ trunks::TrunksFactoryForTest* factory = new trunks::TrunksFactoryForTest();
+ factory->set_tpm_utility(&mock_tpm_utility_);
+ tpm_initializer_.reset(new Tpm2InitializerImpl(factory,
+ &mock_openssl_util_,
+ &mock_data_store_,
+ &mock_tpm_status_));
+ }
+
+ protected:
+ NiceMock<MockOpensslCryptoUtil> mock_openssl_util_;
+ NiceMock<MockLocalDataStore> mock_data_store_;
+ NiceMock<MockTpmStatus> mock_tpm_status_;
+ NiceMock<trunks::MockTpmUtility> mock_tpm_utility_;
+ std::unique_ptr<TpmInitializer> tpm_initializer_;
+};
+
+TEST_F(Tpm2InitializerTest, InitializeTpmNoSeedTpm) {
+ EXPECT_CALL(mock_tpm_utility_, StirRandom(_, _))
+ .WillRepeatedly(Return(trunks::TPM_RC_FAILURE));
+ EXPECT_FALSE(tpm_initializer_->InitializeTpm());
+}
+
+TEST_F(Tpm2InitializerTest, InitializeTpmAlreadyOwned) {
+ EXPECT_CALL(mock_tpm_status_, IsTpmOwned())
+ .WillRepeatedly(Return(true));
+ EXPECT_CALL(mock_tpm_utility_, TakeOwnership(_, _, _))
+ .Times(0);
+ EXPECT_TRUE(tpm_initializer_->InitializeTpm());
+}
+
+TEST_F(Tpm2InitializerTest, InitializeTpmLocalDataReadError) {
+ EXPECT_CALL(mock_tpm_status_, IsTpmOwned())
+ .WillRepeatedly(Return(false));
+ EXPECT_CALL(mock_data_store_, Read(_))
+ .WillRepeatedly(Return(false));
+ EXPECT_CALL(mock_tpm_utility_, TakeOwnership(_, _, _))
+ .Times(0);
+ EXPECT_FALSE(tpm_initializer_->InitializeTpm());
+}
+
+TEST_F(Tpm2InitializerTest, InitializeTpmLocalDataWriteError) {
+ EXPECT_CALL(mock_tpm_status_, IsTpmOwned())
+ .WillRepeatedly(Return(false));
+ EXPECT_CALL(mock_data_store_, Write(_))
+ .WillRepeatedly(Return(false));
+ EXPECT_CALL(mock_tpm_utility_, TakeOwnership(_, _, _))
+ .Times(0);
+ EXPECT_FALSE(tpm_initializer_->InitializeTpm());
+}
+
+TEST_F(Tpm2InitializerTest, InitializeTpmOwnershipError) {
+ EXPECT_CALL(mock_tpm_status_, IsTpmOwned())
+ .WillOnce(Return(false));
+ EXPECT_CALL(mock_tpm_utility_, TakeOwnership(_, _, _))
+ .WillRepeatedly(Return(trunks::TPM_RC_FAILURE));
+ EXPECT_FALSE(tpm_initializer_->InitializeTpm());
+}
+
+TEST_F(Tpm2InitializerTest, InitializeTpmSuccess) {
+ EXPECT_CALL(mock_tpm_status_, IsTpmOwned())
+ .WillOnce(Return(false));
+ std::string owner_password;
+ std::string endorsement_password;
+ std::string lockout_password;
+ LocalData local_data;
+ local_data.set_owned_by_this_install(false);
+ EXPECT_CALL(mock_data_store_, Read(_))
+ .WillOnce(DoAll(SetArgPointee<0>(local_data),
+ Return(true)));
+ EXPECT_CALL(mock_tpm_utility_, GenerateRandom(_, _, _))
+ .Times(3) // Once for owner, endorsement and lockout passwords
+ .WillRepeatedly(Return(trunks::TPM_RC_SUCCESS));
+ EXPECT_CALL(mock_tpm_utility_, TakeOwnership(_, _, _))
+ .WillOnce(Return(trunks::TPM_RC_SUCCESS));
+ EXPECT_TRUE(tpm_initializer_->InitializeTpm());
+}
+
+TEST_F(Tpm2InitializerTest, InitializeTpmSuccessAfterError) {
+ EXPECT_CALL(mock_tpm_status_, IsTpmOwned())
+ .WillOnce(Return(false));
+ std::string owner_password("owner");
+ std::string endorsement_password("endorsement");
+ std::string lockout_password("lockout");
+ LocalData local_data;
+ local_data.set_owned_by_this_install(true);
+ local_data.set_owner_password(owner_password);
+ local_data.set_endorsement_password(endorsement_password);
+ local_data.set_lockout_password(lockout_password);
+ EXPECT_CALL(mock_data_store_, Read(_))
+ .WillOnce(DoAll(SetArgPointee<0>(local_data),
+ Return(true)));
+ EXPECT_CALL(mock_data_store_, Write(_))
+ .WillOnce(DoAll(SaveArg<0>(&local_data),
+ Return(true)));
+ EXPECT_EQ(true, local_data.owned_by_this_install());
+ EXPECT_EQ(owner_password, local_data.owner_password());
+ EXPECT_EQ(endorsement_password, local_data.endorsement_password());
+ EXPECT_EQ(lockout_password, local_data.lockout_password());
+ EXPECT_CALL(mock_tpm_utility_, TakeOwnership(owner_password,
+ endorsement_password,
+ lockout_password))
+ .WillOnce(Return(trunks::TPM_RC_SUCCESS));
+ EXPECT_TRUE(tpm_initializer_->InitializeTpm());
+}
+
+} // namespace tpm_manager
diff --git a/server/tpm_connection.cc b/server/tpm_connection.cc
index 7a241a7..ee57f3a 100644
--- a/server/tpm_connection.cc
+++ b/server/tpm_connection.cc
@@ -5,11 +5,14 @@
#include "tpm_manager/server/tpm_connection.h"
#include <base/logging.h>
+#include <base/stl_util.h>
#include <base/threading/platform_thread.h>
#include <base/time/time.h>
#include <trousers/tss.h>
#include <trousers/trousers.h> // NOLINT(build/include_alpha)
+#include "tpm_manager/server/tpm_util.h"
+
namespace {
const int kTpmConnectRetries = 10;
@@ -19,9 +22,12 @@ const int kTpmConnectIntervalMs = 100;
namespace tpm_manager {
-#define TPM_LOG(severity, result) \
- LOG(severity) << "TPM error 0x" << std::hex << result \
- << " (" << Trspi_Error_String(result) << "): "
+TSS_HCONTEXT TpmConnection::GetContext() {
+ if (!ConnectContextIfNeeded()) {
+ return 0;
+ }
+ return context_.value();
+}
TSS_HTPM TpmConnection::GetTpm() {
if (!ConnectContextIfNeeded()) {
@@ -37,11 +43,28 @@ TSS_HTPM TpmConnection::GetTpm() {
return tpm_handle;
}
-TSS_HCONTEXT TpmConnection::GetContext() {
- if (!ConnectContextIfNeeded()) {
+TSS_HTPM TpmConnection::GetTpmWithAuth(const std::string& owner_password) {
+ TSS_HTPM tpm_handle = GetTpm();
+ if (tpm_handle == 0) {
return 0;
}
- return context_.value();
+ TSS_RESULT result;
+ TSS_HPOLICY tpm_usage_policy;
+ if (TPM_ERROR(result = Tspi_GetPolicyObject(tpm_handle,
+ TSS_POLICY_USAGE,
+ &tpm_usage_policy))) {
+ TPM_LOG(ERROR, result) << "Error calling Tspi_GetPolicyObject";
+ return false;
+ }
+ if (TPM_ERROR(result = Tspi_Policy_SetSecret(
+ tpm_usage_policy,
+ TSS_SECRET_MODE_PLAIN,
+ owner_password.size(),
+ reinterpret_cast<BYTE *>(const_cast<char*>(owner_password.data()))))) {
+ TPM_LOG(ERROR, result) << "Error calling Tspi_Policy_SetSecret";
+ return false;
+ }
+ return tpm_handle;
}
bool TpmConnection::ConnectContextIfNeeded() {
diff --git a/server/tpm_connection.h b/server/tpm_connection.h
index a0f8fe5..833a972 100644
--- a/server/tpm_connection.h
+++ b/server/tpm_connection.h
@@ -5,10 +5,11 @@
#ifndef TPM_MANAGER_SERVER_TPM_CONNECTION_H_
#define TPM_MANAGER_SERVER_TPM_CONNECTION_H_
+#include <string>
+
#include <base/macros.h>
#include <trousers/scoped_tss_type.h>
-
namespace tpm_manager {
class TpmConnection {
@@ -16,14 +17,18 @@ class TpmConnection {
TpmConnection() = default;
~TpmConnection() = default;
- // This method tries to get a handle to the TPM. Returns 0 on failure.
- TSS_HTPM GetTpm();
-
// This method returns a handle to the current Tpm context.
// Note: this method still retains ownership of the context. If this class
// is deleted, the context handle will be invalidated. Returns 0 on failure.
TSS_HCONTEXT GetContext();
+ // This method tries to get a handle to the TPM. Returns 0 on failure.
+ TSS_HTPM GetTpm();
+
+ // This method tries to get a handle to the TPM and with the given owner
+ // password. Returns 0 on failure.
+ TSS_HTPM GetTpmWithAuth(const std::string& owner_password);
+
private:
// This method connects to the Tpm. Returns true on success.
bool ConnectContextIfNeeded();
diff --git a/server/tpm_initializer_impl.cc b/server/tpm_initializer_impl.cc
new file mode 100644
index 0000000..a33d5b6
--- /dev/null
+++ b/server/tpm_initializer_impl.cc
@@ -0,0 +1,246 @@
+// Copyright 2015 The Chromium OS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "tpm_manager/server/tpm_initializer_impl.h"
+
+#include <string>
+
+#include <base/logging.h>
+#include <base/stl_util.h>
+#include <trousers/scoped_tss_type.h>
+
+#include "tpm_manager/server/local_data_store.h"
+#include "tpm_manager/server/tpm_connection.h"
+#include "tpm_manager/server/tpm_status.h"
+#include "tpm_manager/server/tpm_util.h"
+
+namespace {
+
+const char kDefaultOwnerPassword[] = TSS_WELL_KNOWN_SECRET;
+const size_t kDefaultPasswordSize = 20;
+const int kMaxOwnershipTimeoutRetries = 5;
+const char* kWellKnownSrkSecret = "well_known_srk_secret";
+
+} // namespace
+
+namespace tpm_manager {
+
+TpmInitializerImpl::TpmInitializerImpl(LocalDataStore* local_data_store,
+ TpmStatus* tpm_status)
+ : local_data_store_(local_data_store),
+ tpm_status_(tpm_status) {}
+
+bool TpmInitializerImpl::InitializeTpm() {
+ if (tpm_status_->IsTpmOwned() && !TestTpmAuth(kDefaultOwnerPassword)) {
+ // Tpm is already owned, so we do not need to do anything.
+ VLOG(1) << "Tpm already owned.";
+ return true;
+ }
+ TSS_HTPM tpm_handle = tpm_connection_.GetTpm();
+ if (tpm_handle == 0) {
+ return false;
+ }
+ if (!InitializeEndorsementKey(tpm_handle) ||
+ !TakeOwnership(tpm_handle) ||
+ !InitializeSrk(tpm_handle)) {
+ return false;
+ }
+ std::string owner_password;
+ if (!openssl_util_.GetRandomBytes(kDefaultPasswordSize, &owner_password)) {
+ return false;
+ }
+ LocalData local_data;
+ local_data.set_owned_by_this_install(true);
+ local_data.set_owner_password(owner_password);
+ // TODO(usanghi): Add ownership dependencies here.
+ if (!local_data_store_->Write(local_data)) {
+ LOG(ERROR) << "Error saving local data.";
+ return false;
+ }
+ if (!ChangeOwnerPassword(tpm_handle, owner_password)) {
+ return false;
+ }
+ return true;
+}
+
+bool TpmInitializerImpl::InitializeEndorsementKey(TSS_HTPM tpm_handle) {
+ trousers::ScopedTssKey local_key_handle(tpm_connection_.GetContext());
+ TSS_RESULT result = Tspi_TPM_GetPubEndorsementKey(tpm_handle,
+ false,
+ nullptr,
+ local_key_handle.ptr());
+ if (TPM_ERROR(result) == TPM_SUCCESS) {
+ // In this case the EK already exists, so we can return true here.
+ return true;
+ }
+ // At this point the EK does not exist, so we create it.
+ TSS_FLAG init_flags = TSS_KEY_TYPE_LEGACY | TSS_KEY_SIZE_2048;
+ if (TPM_ERROR(result = Tspi_Context_CreateObject(tpm_connection_.GetContext(),
+ TSS_OBJECT_TYPE_RSAKEY,
+ init_flags,
+ local_key_handle.ptr()))) {
+ TPM_LOG(ERROR, result) << "Error calling Tspi_Context_CreateObject";
+ return false;
+ }
+ if (TPM_ERROR(result = Tspi_TPM_CreateEndorsementKey(tpm_handle,
+ local_key_handle,
+ NULL))) {
+ TPM_LOG(ERROR, result) << "Error calling Tspi_TPM_CreateEndorsementKey";
+ return false;
+ }
+ return true;
+}
+
+bool TpmInitializerImpl::TakeOwnership(TSS_HTPM tpm_handle) {
+ if (TestTpmAuth(kDefaultOwnerPassword)) {
+ VLOG(1) << "The Tpm already has the default owner password.";
+ return true;
+ }
+ TSS_RESULT result;
+ trousers::ScopedTssKey srk_handle(tpm_connection_.GetContext());
+ TSS_FLAG init_flags = TSS_KEY_TSP_SRK | TSS_KEY_AUTHORIZATION;
+ if (TPM_ERROR(result = Tspi_Context_CreateObject(tpm_connection_.GetContext(),
+ TSS_OBJECT_TYPE_RSAKEY,
+ init_flags,
+ srk_handle.ptr()))) {
+ TPM_LOG(ERROR, result) << "Error calling Tspi_Context_CreateObject";
+ return false;
+ }
+ TSS_HPOLICY srk_usage_policy;
+ if (TPM_ERROR(result = Tspi_GetPolicyObject(srk_handle,
+ TSS_POLICY_USAGE,
+ &srk_usage_policy))) {
+ TPM_LOG(ERROR, result) << "Error calling Tspi_GetPolicyObject";
+ return false;
+ }
+ if (TPM_ERROR(result = Tspi_Policy_SetSecret(
+ srk_usage_policy,
+ TSS_SECRET_MODE_PLAIN,
+ strlen(kWellKnownSrkSecret),
+ const_cast<BYTE *>(reinterpret_cast<const BYTE *>(
+ kWellKnownSrkSecret))))) {
+ TPM_LOG(ERROR, result) << "Error calling Tspi_Policy_SetSecret";
+ return false;
+ }
+ // Tspi_TPM_TakeOwnership can potentailly take a long time to complete,
+ // so we retry if there is a timeout in any layer. I chose 5, because the
+ // longest TakeOwnership call that I have seen took ~2min, and the default
+ // TSS timeout is 30s. This means that after 5 calls, it is quite likely that
+ // this call will succeed.
+ int retry_count = 0;
+ do {
+ result = Tspi_TPM_TakeOwnership(tpm_handle, srk_handle, 0);
+ retry_count++;
+ } while (((result == TDDL_E_TIMEOUT) ||
+ (result == (TSS_LAYER_TDDL | TDDL_E_TIMEOUT)) ||
+ (result == (TSS_LAYER_TDDL | TDDL_E_IOERROR))) &&
+ (retry_count < kMaxOwnershipTimeoutRetries));
+ if (result) {
+ TPM_LOG(ERROR, result)
+ << "Error calling Tspi_TPM_TakeOwnership, attempts: " << retry_count;
+ return false;
+ }
+ return true;
+}
+
+bool TpmInitializerImpl::InitializeSrk(TSS_HTPM tpm_handle) {
+ TSS_RESULT result;
+ trousers::ScopedTssKey srk_handle(tpm_connection_.GetContext());
+ TSS_UUID SRK_UUID = TSS_UUID_SRK;
+ if (TPM_ERROR(result = Tspi_Context_LoadKeyByUUID(
+ tpm_connection_.GetContext(),
+ TSS_PS_TYPE_SYSTEM,
+ SRK_UUID,
+ srk_handle.ptr()))) {
+ TPM_LOG(ERROR, result) << "Error calling Tspi_Context_LoadKeyByUUID";
+ return false;
+ }
+
+ trousers::ScopedTssPolicy policy_handle(tpm_connection_.GetContext());
+ if (TPM_ERROR(result = Tspi_Context_CreateObject(tpm_connection_.GetContext(),
+ TSS_OBJECT_TYPE_POLICY,
+ TSS_POLICY_USAGE,
+ policy_handle.ptr()))) {
+ TPM_LOG(ERROR, result) << "Error calling Tspi_Context_CreateObject";
+ return false;
+ }
+ BYTE new_password[0];
+ if (TPM_ERROR(result = Tspi_Policy_SetSecret(policy_handle,
+ TSS_SECRET_MODE_PLAIN,
+ 0,
+ new_password))) {
+ TPM_LOG(ERROR, result) << "Error calling Tspi_Policy_SetSecret";
+ return false;
+ }
+
+ if (TPM_ERROR(result = Tspi_ChangeAuth(srk_handle,
+ tpm_handle,
+ policy_handle))) {
+ TPM_LOG(ERROR, result) << "Error calling Tspi_ChangeAuth";
+ return false;
+ }
+ TSS_BOOL is_srk_restricted = false;
+ if (TPM_ERROR(result = Tspi_TPM_GetStatus(tpm_handle,
+ TSS_TPMSTATUS_DISABLEPUBSRKREAD,
+ &is_srk_restricted))) {
+ TPM_LOG(ERROR, result) << "Error calling Tspi_TPM_GetStatus";
+ return false;
+ }
+ // If the SRK is restricted, we unrestrict it.
+ if (is_srk_restricted) {
+ if (TPM_ERROR(result = Tspi_TPM_SetStatus(tpm_handle,
+ TSS_TPMSTATUS_DISABLEPUBSRKREAD,
+ false))) {
+ TPM_LOG(ERROR, result) << "Error calling Tspi_TPM_SetStatus";
+ return false;
+ }
+ }
+ return true;
+}
+
+bool TpmInitializerImpl::ChangeOwnerPassword(
+ TSS_HTPM tpm_handle, const std::string& owner_password) {
+ TSS_RESULT result;
+ trousers::ScopedTssPolicy policy_handle(tpm_connection_.GetContext());
+ if (TPM_ERROR(result = Tspi_Context_CreateObject(tpm_connection_.GetContext(),
+ TSS_OBJECT_TYPE_POLICY,
+ TSS_POLICY_USAGE,
+ policy_handle.ptr()))) {
+ TPM_LOG(ERROR, result) << "Error calling Tspi_Context_CreateObject";
+ return false;
+ }
+ std::string mutable_owner_password(owner_password);
+ if (TPM_ERROR(result = Tspi_Policy_SetSecret(policy_handle,
+ TSS_SECRET_MODE_PLAIN,
+ owner_password.size(),
+ reinterpret_cast<BYTE *>(string_as_array(&mutable_owner_password))))) {
+ TPM_LOG(ERROR, result) << "Error calling Tspi_Policy_SetSecret";
+ return false;
+ }
+
+ if (TPM_ERROR(result = Tspi_ChangeAuth(tpm_handle, 0, policy_handle))) {
+ TPM_LOG(ERROR, result) << "Error calling Tspi_ChangeAuth";
+ return false;
+ }
+
+ return true;
+}
+
+bool TpmInitializerImpl::TestTpmAuth(const std::string& owner_password) {
+ TSS_HTPM tpm_handle = tpm_connection_.GetTpmWithAuth(owner_password);
+ if (tpm_handle == 0) {
+ return false;
+ }
+ // Call Tspi_TPM_GetStatus to test the |owner_password| provided.
+ TSS_RESULT result;
+ TSS_BOOL current_status = false;
+ if (TPM_ERROR(result = Tspi_TPM_GetStatus(tpm_handle,
+ TSS_TPMSTATUS_DISABLED,
+ &current_status))) {
+ return false;
+ }
+ return true;
+}
+
+} // namespace tpm_manager
diff --git a/server/tpm_initializer_impl.h b/server/tpm_initializer_impl.h
new file mode 100644
index 0000000..58adf55
--- /dev/null
+++ b/server/tpm_initializer_impl.h
@@ -0,0 +1,80 @@
+// Copyright 2015 The Chromium OS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef TPM_MANAGER_SERVER_TPM_INITIALIZER_IMPL_H_
+#define TPM_MANAGER_SERVER_TPM_INITIALIZER_IMPL_H_
+
+#include <string>
+
+#include <base/macros.h>
+#include <trousers/tss.h>
+#include <trousers/trousers.h> // NOLINT(build/include_alpha)
+
+#include "tpm_manager/server/openssl_crypto_util.h"
+#include "tpm_manager/server/tpm_connection.h"
+#include "tpm_manager/server/tpm_initializer.h"
+
+namespace tpm_manager {
+
+class LocalDataStore;
+class TpmStatus;
+
+// This class initializes a Tpm1.2 chip by taking ownership. Example use of
+// this class is:
+// LocalDataStore data_store;
+// TpmStatusImpl status;
+// TpmInitializerImpl initializer(&data_store, &status);
+// initializer.InitializeTpm();
+// If the tpm is unowned, InitializeTpm injects a random owner password,
+// initializes and unrestricts the SRK, and persists the owner password to disk
+// until all the owner dependencies are satisfied.
+class TpmInitializerImpl : public TpmInitializer {
+ public:
+ // Does not take ownership of |local_data_store| or |tpm_status|.
+ TpmInitializerImpl(LocalDataStore* local_data_store,
+ TpmStatus* tpm_status);
+ ~TpmInitializerImpl() override = default;
+
+ // TpmInitializer methods.
+ bool InitializeTpm() override;
+
+ private:
+ // This method checks if an EndorsementKey exists on the Tpm and creates it
+ // if not. Returns true on success, else false. |tpm_handle| is a handle to
+ // the Tpm with the owner_password injected.
+ bool InitializeEndorsementKey(TSS_HTPM tpm_handle);
+
+ // This method takes ownership of the Tpm with the default TSS password.
+ // Returns true on success, else false. |tpm_handle| is a handle to the Tpm
+ // with the owner_password injected.
+ bool TakeOwnership(TSS_HTPM tpm_handle);
+
+ // This method initializes the SRK if it does not exist, zero's the SRK
+ // password and unrestricts its usage. Returns true on success, else false.
+ // |tpm_handle| is a handle to the Tpm with the owner_password injected.
+ bool InitializeSrk(TSS_HTPM tpm_handle);
+
+ // This method changes the Tpm owner password from the default TSS password
+ // to the password provided in the |owner_password| argument.
+ // Returns true on success, else false. |tpm_handle| is a handle to the Tpm
+ // with the old owner_password injected.
+ bool ChangeOwnerPassword(TSS_HTPM tpm_handle,
+ const std::string& owner_password);
+
+ // This method return true iff the provided |owner_password| is the current
+ // owner password in the Tpm. This method can also return false if there was
+ // an error communicating with the Tpm.
+ bool TestTpmAuth(const std::string& owner_password);
+
+ OpensslCryptoUtil openssl_util_;
+ TpmConnection tpm_connection_;
+ LocalDataStore* local_data_store_;
+ TpmStatus* tpm_status_;
+
+ DISALLOW_COPY_AND_ASSIGN(TpmInitializerImpl);
+};
+
+} // namespace tpm_manager
+
+#endif // TPM_MANAGER_SERVER_TPM_INITIALIZER_IMPL_H_
diff --git a/server/tpm_manager-seccomp-amd64.policy b/server/tpm_manager-seccomp-amd64.policy
index 4326566..641bce6 100644
--- a/server/tpm_manager-seccomp-amd64.policy
+++ b/server/tpm_manager-seccomp-amd64.policy
@@ -58,5 +58,6 @@ mprotect: 1
munmap: 1
clone: 1
-#This is attempted but apparently not necessary; return EPERM.
+# These calls are attempted but apparently not necessary; return EPERM.
prctl: return 1
+ioctl: return 1
diff --git a/server/tpm_manager_service.cc b/server/tpm_manager_service.cc
index 57f33d9..f7077d4 100644
--- a/server/tpm_manager_service.cc
+++ b/server/tpm_manager_service.cc
@@ -12,9 +12,11 @@ namespace tpm_manager {
TpmManagerService::TpmManagerService(bool wait_for_ownership,
LocalDataStore* local_data_store,
- TpmStatus* tpm_status)
+ TpmStatus* tpm_status,
+ TpmInitializer* tpm_initializer)
: local_data_store_(local_data_store),
tpm_status_(tpm_status),
+ tpm_initializer_(tpm_initializer),
wait_for_ownership_(wait_for_ownership),
weak_factory_(this) {
}
@@ -106,6 +108,7 @@ void TpmManagerService::TakeOwnershipTask(
result->set_status(STATUS_UNEXPECTED_DEVICE_ERROR);
return;
}
+ result->set_status(STATUS_SUCCESS);
}
} // namespace tpm_manager
diff --git a/server/tpm_manager_service.h b/server/tpm_manager_service.h
index 1fcb367..d715816 100644
--- a/server/tpm_manager_service.h
+++ b/server/tpm_manager_service.h
@@ -43,10 +43,11 @@ class TpmManagerService : public TpmManagerInterface {
public:
// If |wait_for_ownership| is set, TPM initialization will be postponed until
// an explicit TakeOwnership request is received. Does not take ownership of
- // |local_data_store| or |tpm_status|.
+ // |local_data_store|, |tpm_status| or |tpm_initializer|.
explicit TpmManagerService(bool wait_for_ownership,
LocalDataStore* local_data_store,
- TpmStatus* tpm_status);
+ TpmStatus* tpm_status,
+ TpmInitializer* tpm_initializer);
~TpmManagerService() override = default;
// TpmManagerInterface methods.
@@ -56,11 +57,6 @@ class TpmManagerService : public TpmManagerInterface {
void TakeOwnership(const TakeOwnershipRequest& request,
const TakeOwnershipCallback& callback) override;
- // Mutators useful for injecting dependencies for testing.
- void set_tpm_initializer(TpmInitializer* initializer) {
- tpm_initializer_ = initializer;
- }
-
private:
// A relay callback which allows the use of weak pointer semantics for a reply
// to TaskRunner::PostTaskAndReply.
@@ -88,8 +84,8 @@ class TpmManagerService : public TpmManagerInterface {
void InitializeTask();
LocalDataStore* local_data_store_;
- TpmInitializer* tpm_initializer_{nullptr};
TpmStatus* tpm_status_;
+ TpmInitializer* tpm_initializer_;
// Whether to wait for an explicit call to 'TakeOwnership' before initializing
// the TPM. Normally tracks the --wait_for_ownership command line option.
bool wait_for_ownership_;
diff --git a/server/tpm_manager_service_test.cc b/server/tpm_manager_service_test.cc
index 1aafe5f..d1c36fb 100644
--- a/server/tpm_manager_service_test.cc
+++ b/server/tpm_manager_service_test.cc
@@ -28,7 +28,8 @@ class TpmManagerServiceTest : public testing::Test {
void SetUp() override {
service_.reset(new TpmManagerService(true /*wait_for_ownership*/,
&mock_local_data_store_,
- &mock_tpm_status_));
+ &mock_tpm_status_,
+ &mock_tpm_initializer_));
SetupService();
}
@@ -53,7 +54,6 @@ class TpmManagerServiceTest : public testing::Test {
}
void SetupService() {
- service_->set_tpm_initializer(&mock_tpm_initializer_);
CHECK(service_->Initialize());
}
@@ -74,7 +74,8 @@ class TpmManagerServiceTest_NoWaitForOwnership : public TpmManagerServiceTest {
void SetUp() override {
service_.reset(new TpmManagerService(false /*wait_for_ownership*/,
&mock_local_data_store_,
- &mock_tpm_status_));
+ &mock_tpm_status_,
+ &mock_tpm_initializer_));
}
};
diff --git a/server/tpm_status_impl.cc b/server/tpm_status_impl.cc
index 4948761..f390e68 100644
--- a/server/tpm_status_impl.cc
+++ b/server/tpm_status_impl.cc
@@ -6,7 +6,7 @@
#include <vector>
-#include <base/stl_util.h>
+#include <base/logging.h>
#include <trousers/tss.h>
#include <trousers/trousers.h> // NOLINT(build/include_alpha)
diff --git a/server/tpm_util.h b/server/tpm_util.h
new file mode 100644
index 0000000..3b7c93b
--- /dev/null
+++ b/server/tpm_util.h
@@ -0,0 +1,16 @@
+// Copyright 2015 The Chromium OS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef TPM_MANAGER_SERVER_TPM_UTIL_H_
+#define TPM_MANAGER_SERVER_TPM_UTIL_H_
+
+namespace tpm_manager {
+
+#define TPM_LOG(severity, result) \
+ LOG(severity) << "TPM error 0x" << std::hex << result \
+ << " (" << Trspi_Error_String(result) << "): "
+
+} // namespace tpm_manager
+
+#endif // TPM_MANAGER_SERVER_TPM_UTIL_H_
diff --git a/tpm_manager.gyp b/tpm_manager.gyp
index d0c6a8c..1f213ad 100644
--- a/tpm_manager.gyp
+++ b/tpm_manager.gyp
@@ -9,6 +9,7 @@
'deps': [ # This is a list of pkg-config dependencies
'libchrome-<(libbase_ver)',
'libchromeos-<(libbase_ver)',
+ 'openssl',
'protobuf-lite',
],
},
@@ -61,12 +62,14 @@
'sources': [
'server/dbus_service.cc',
'server/local_data_store_impl.cc',
+ 'server/openssl_crypto_util.cc',
'server/tpm_manager_service.cc',
],
'conditions': [
['USE_tpm2 == 1', {
'sources': [
'server/tpm2_status_impl.cc',
+ 'server/tpm2_initializer_impl.cc',
],
'all_dependent_settings': {
'libraries': [
@@ -78,6 +81,7 @@
'sources': [
'server/tpm_connection.cc',
'server/tpm_status_impl.cc',
+ 'server/tpm_initializer_impl.cc',
],
'all_dependent_settings': {
'libraries': [
@@ -143,6 +147,7 @@
'../trunks/mock_tpm_utility.cc',
'../trunks/trunks_factory_for_test.cc',
'server/tpm2_status_test.cc',
+ 'server/tpm2_initializer_test.cc',
],
}],
],