1 //
2 // Copyright (C) 2015 The Android Open Source Project
3 //
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 // http://www.apache.org/licenses/LICENSE-2.0
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15 //
16
17 #include "tpm_manager/server/tpm2_initializer_impl.h"
18
19 #include <memory>
20
21 #include <gmock/gmock.h>
22 #include <gtest/gtest.h>
23 #include <trunks/mock_tpm_utility.h>
24 #include <trunks/trunks_factory_for_test.h>
25
26 #include "tpm_manager/common/tpm_manager_constants.h"
27 #include "tpm_manager/server/mock_local_data_store.h"
28 #include "tpm_manager/server/mock_openssl_crypto_util.h"
29 #include "tpm_manager/server/mock_tpm_status.h"
30
31 using testing::_;
32 using testing::AtLeast;
33 using testing::Invoke;
34 using testing::DoAll;
35 using testing::NiceMock;
36 using testing::Return;
37 using testing::SaveArg;
38 using testing::SetArgPointee;
39
40 namespace tpm_manager {
41
42 class Tpm2InitializerTest : public testing::Test {
43 public:
44 Tpm2InitializerTest() = default;
45 virtual ~Tpm2InitializerTest() = default;
46
SetUp()47 void SetUp() {
48 EXPECT_CALL(mock_data_store_, Read(_))
49 .WillRepeatedly(Invoke([this](LocalData* arg) {
50 *arg = fake_local_data_;
51 return true;
52 }));
53 EXPECT_CALL(mock_data_store_, Write(_))
54 .WillRepeatedly(Invoke([this](const LocalData& arg) {
55 fake_local_data_ = arg;
56 return true;
57 }));
58 factory_.set_tpm_utility(&mock_tpm_utility_);
59 tpm_initializer_.reset(new Tpm2InitializerImpl(
60 factory_, &mock_openssl_util_, &mock_data_store_, &mock_tpm_status_));
61 }
62
63 protected:
64 LocalData fake_local_data_;
65 NiceMock<MockOpensslCryptoUtil> mock_openssl_util_;
66 NiceMock<MockLocalDataStore> mock_data_store_;
67 NiceMock<MockTpmStatus> mock_tpm_status_;
68 NiceMock<trunks::MockTpmUtility> mock_tpm_utility_;
69 trunks::TrunksFactoryForTest factory_;
70 std::unique_ptr<TpmInitializer> tpm_initializer_;
71 };
72
TEST_F(Tpm2InitializerTest,InitializeTpmNoSeedTpm)73 TEST_F(Tpm2InitializerTest, InitializeTpmNoSeedTpm) {
74 EXPECT_CALL(mock_tpm_utility_, StirRandom(_, _))
75 .WillRepeatedly(Return(trunks::TPM_RC_FAILURE));
76 EXPECT_FALSE(tpm_initializer_->InitializeTpm());
77 }
78
TEST_F(Tpm2InitializerTest,InitializeTpmAlreadyOwned)79 TEST_F(Tpm2InitializerTest, InitializeTpmAlreadyOwned) {
80 EXPECT_CALL(mock_tpm_status_, IsTpmOwned()).WillRepeatedly(Return(true));
81 EXPECT_CALL(mock_tpm_utility_, TakeOwnership(_, _, _)).Times(0);
82 EXPECT_TRUE(tpm_initializer_->InitializeTpm());
83 }
84
TEST_F(Tpm2InitializerTest,InitializeTpmLocalDataReadError)85 TEST_F(Tpm2InitializerTest, InitializeTpmLocalDataReadError) {
86 EXPECT_CALL(mock_tpm_status_, IsTpmOwned()).WillRepeatedly(Return(false));
87 EXPECT_CALL(mock_data_store_, Read(_)).WillRepeatedly(Return(false));
88 EXPECT_CALL(mock_tpm_utility_, TakeOwnership(_, _, _)).Times(0);
89 EXPECT_FALSE(tpm_initializer_->InitializeTpm());
90 }
91
TEST_F(Tpm2InitializerTest,InitializeTpmLocalDataWriteError)92 TEST_F(Tpm2InitializerTest, InitializeTpmLocalDataWriteError) {
93 EXPECT_CALL(mock_tpm_status_, IsTpmOwned()).WillRepeatedly(Return(false));
94 EXPECT_CALL(mock_data_store_, Write(_)).WillRepeatedly(Return(false));
95 EXPECT_CALL(mock_tpm_utility_, TakeOwnership(_, _, _)).Times(0);
96 EXPECT_FALSE(tpm_initializer_->InitializeTpm());
97 }
98
TEST_F(Tpm2InitializerTest,InitializeTpmOwnershipError)99 TEST_F(Tpm2InitializerTest, InitializeTpmOwnershipError) {
100 EXPECT_CALL(mock_tpm_status_, IsTpmOwned()).WillOnce(Return(false));
101 EXPECT_CALL(mock_tpm_utility_, TakeOwnership(_, _, _))
102 .WillRepeatedly(Return(trunks::TPM_RC_FAILURE));
103 EXPECT_FALSE(tpm_initializer_->InitializeTpm());
104 }
105
TEST_F(Tpm2InitializerTest,InitializeTpmSuccess)106 TEST_F(Tpm2InitializerTest, InitializeTpmSuccess) {
107 EXPECT_CALL(mock_tpm_status_, IsTpmOwned()).WillOnce(Return(false));
108 std::string password = "hunter2";
109 EXPECT_CALL(mock_tpm_utility_, GenerateRandom(_, _, _))
110 .Times(3) // Once for owner, endorsement and lockout passwords
111 .WillRepeatedly(
112 DoAll(SetArgPointee<2>(password), Return(trunks::TPM_RC_SUCCESS)));
113 EXPECT_CALL(mock_tpm_utility_, TakeOwnership(_, _, _))
114 .WillOnce(Return(trunks::TPM_RC_SUCCESS));
115 EXPECT_TRUE(tpm_initializer_->InitializeTpm());
116 EXPECT_LT(0, fake_local_data_.owner_dependency_size());
117 EXPECT_EQ(password, fake_local_data_.owner_password());
118 EXPECT_EQ(password, fake_local_data_.endorsement_password());
119 EXPECT_EQ(password, fake_local_data_.lockout_password());
120 }
121
TEST_F(Tpm2InitializerTest,InitializeTpmSuccessAfterError)122 TEST_F(Tpm2InitializerTest, InitializeTpmSuccessAfterError) {
123 EXPECT_CALL(mock_tpm_status_, IsTpmOwned()).WillOnce(Return(false));
124 std::string owner_password("owner");
125 std::string endorsement_password("endorsement");
126 std::string lockout_password("lockout");
127 fake_local_data_.add_owner_dependency("test");
128 fake_local_data_.set_owner_password(owner_password);
129 fake_local_data_.set_endorsement_password(endorsement_password);
130 fake_local_data_.set_lockout_password(lockout_password);
131 EXPECT_CALL(
132 mock_tpm_utility_,
133 TakeOwnership(owner_password, endorsement_password, lockout_password))
134 .WillOnce(Return(trunks::TPM_RC_SUCCESS));
135 EXPECT_TRUE(tpm_initializer_->InitializeTpm());
136 EXPECT_LT(0, fake_local_data_.owner_dependency_size());
137 EXPECT_EQ(owner_password, fake_local_data_.owner_password());
138 EXPECT_EQ(endorsement_password, fake_local_data_.endorsement_password());
139 EXPECT_EQ(lockout_password, fake_local_data_.lockout_password());
140 }
141
TEST_F(Tpm2InitializerTest,PCRSpoofGuard)142 TEST_F(Tpm2InitializerTest, PCRSpoofGuard) {
143 // Setup empty PCRs that need to be extended.
144 EXPECT_CALL(mock_tpm_utility_, ReadPCR(_, _))
145 .WillRepeatedly(DoAll(SetArgPointee<1>(std::string(32, 0)),
146 Return(trunks::TPM_RC_SUCCESS)));
147 // Expect at least four PCRs to be extended.
148 EXPECT_CALL(mock_tpm_utility_, ExtendPCR(_, _, _))
149 .Times(AtLeast(4))
150 .WillRepeatedly(Return(trunks::TPM_RC_SUCCESS));
151 tpm_initializer_->VerifiedBootHelper();
152 }
153
TEST_F(Tpm2InitializerTest,PCRSpoofGuardReadFailure)154 TEST_F(Tpm2InitializerTest, PCRSpoofGuardReadFailure) {
155 EXPECT_CALL(mock_tpm_utility_, ReadPCR(_, _))
156 .WillRepeatedly(Return(trunks::TPM_RC_FAILURE));
157 tpm_initializer_->VerifiedBootHelper();
158 }
159
TEST_F(Tpm2InitializerTest,PCRSpoofGuardExtendFailure)160 TEST_F(Tpm2InitializerTest, PCRSpoofGuardExtendFailure) {
161 EXPECT_CALL(mock_tpm_utility_, ReadPCR(_, _))
162 .WillRepeatedly(DoAll(SetArgPointee<1>(std::string(32, 0)),
163 Return(trunks::TPM_RC_SUCCESS)));
164 EXPECT_CALL(mock_tpm_utility_, ExtendPCR(_, _, _))
165 .WillRepeatedly(Return(trunks::TPM_RC_FAILURE));
166 tpm_initializer_->VerifiedBootHelper();
167 }
168
TEST_F(Tpm2InitializerTest,DAResetSuccess)169 TEST_F(Tpm2InitializerTest, DAResetSuccess) {
170 fake_local_data_.set_lockout_password("lockout");
171 EXPECT_CALL(mock_tpm_utility_, ResetDictionaryAttackLock(_))
172 .WillRepeatedly(Return(trunks::TPM_RC_SUCCESS));
173 EXPECT_TRUE(tpm_initializer_->ResetDictionaryAttackLock());
174 }
175
TEST_F(Tpm2InitializerTest,DAResetNoLockoutPassword)176 TEST_F(Tpm2InitializerTest, DAResetNoLockoutPassword) {
177 fake_local_data_.clear_lockout_password();
178 EXPECT_FALSE(tpm_initializer_->ResetDictionaryAttackLock());
179 }
180
TEST_F(Tpm2InitializerTest,DAResetFailure)181 TEST_F(Tpm2InitializerTest, DAResetFailure) {
182 fake_local_data_.set_lockout_password("lockout");
183 EXPECT_CALL(mock_tpm_utility_, ResetDictionaryAttackLock(_))
184 .Times(AtLeast(1))
185 .WillRepeatedly(Return(trunks::TPM_RC_FAILURE));
186 EXPECT_FALSE(tpm_initializer_->ResetDictionaryAttackLock());
187 }
188
189 } // namespace tpm_manager
190