tpm_utility_test.cc revision 52e2a45f585fbe34032eae5b094a092afdf217ca
1// Copyright 2014 The Chromium OS Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include <gmock/gmock.h>
6#include <gtest/gtest.h>
7
8#include "trunks/mock_tpm.h"
9#include "trunks/mock_tpm_state.h"
10#include "trunks/tpm_utility_impl.h"
11#include "trunks/trunks_factory_for_test.h"
12
13using testing::_;
14using testing::DoAll;
15using testing::NiceMock;
16using testing::Return;
17using testing::SetArgPointee;
18
19namespace trunks {
20
21// A test fixture for TpmUtility tests.
22class TpmUtilityTest : public testing::Test {
23 public:
24  TpmUtilityTest() {}
25  virtual ~TpmUtilityTest() {}
26  void SetUp() {
27    factory_.set_tpm_state(&mock_tpm_state_);
28    factory_.set_tpm(&mock_tpm_);
29  }
30 protected:
31  TrunksFactoryForTest factory_;
32  NiceMock<MockTpmState> mock_tpm_state_;
33  NiceMock<MockTpm> mock_tpm_;
34};
35
36TEST_F(TpmUtilityTest, StartupSuccess) {
37  TpmUtilityImpl utility(factory_);
38  EXPECT_EQ(TPM_RC_SUCCESS, utility.Startup());
39}
40
41TEST_F(TpmUtilityTest, StartupAlreadyStarted) {
42  EXPECT_CALL(mock_tpm_, StartupSync(_, _))
43      .WillRepeatedly(Return(TPM_RC_INITIALIZE));
44  TpmUtilityImpl utility(factory_);
45  EXPECT_EQ(TPM_RC_SUCCESS, utility.Startup());
46}
47
48TEST_F(TpmUtilityTest, StartupFailure) {
49  EXPECT_CALL(mock_tpm_, StartupSync(_, _))
50      .WillRepeatedly(Return(TPM_RC_FAILURE));
51  TpmUtilityImpl utility(factory_);
52  EXPECT_EQ(TPM_RC_FAILURE, utility.Startup());
53}
54
55TEST_F(TpmUtilityTest, StartupSelfTestFailure) {
56  EXPECT_CALL(mock_tpm_, SelfTestSync(_, _))
57      .WillRepeatedly(Return(TPM_RC_FAILURE));
58  TpmUtilityImpl utility(factory_);
59  EXPECT_EQ(TPM_RC_FAILURE, utility.Startup());
60}
61
62TEST_F(TpmUtilityTest, InitializeTpmAlreadyInit) {
63  TpmUtilityImpl utility(factory_);
64  EXPECT_EQ(TPM_RC_SUCCESS, utility.InitializeTpm());
65}
66
67TEST_F(TpmUtilityTest, InitializeTpmSuccess) {
68  TpmUtilityImpl utility(factory_);
69  // Setup a hierarchy that needs to be disabled.
70  EXPECT_CALL(mock_tpm_state_, IsPlatformHierarchyEnabled())
71      .WillOnce(Return(true));
72  EXPECT_EQ(TPM_RC_SUCCESS, utility.InitializeTpm());
73}
74
75TEST_F(TpmUtilityTest, InitializeTpmBadAuth) {
76  TpmUtilityImpl utility(factory_);
77  // Setup a hierarchy that needs to be disabled.
78  EXPECT_CALL(mock_tpm_state_, IsPlatformHierarchyEnabled())
79      .WillOnce(Return(true));
80  // Reject attempts to set platform auth.
81  EXPECT_CALL(mock_tpm_, HierarchyChangeAuthSync(TPM_RH_PLATFORM, _, _, _))
82      .WillRepeatedly(Return(TPM_RC_FAILURE));
83  EXPECT_EQ(TPM_RC_FAILURE, utility.InitializeTpm());
84}
85
86TEST_F(TpmUtilityTest, InitializeTpmDisablePHFails) {
87  TpmUtilityImpl utility(factory_);
88  // Setup a hierarchy that needs to be disabled.
89  EXPECT_CALL(mock_tpm_state_, IsPlatformHierarchyEnabled())
90      .WillOnce(Return(true));
91  // Reject attempts to disable the platform hierarchy.
92  EXPECT_CALL(mock_tpm_, HierarchyControlSync(_, _, TPM_RH_PLATFORM, _, _))
93      .WillRepeatedly(Return(TPM_RC_FAILURE));
94  EXPECT_EQ(TPM_RC_FAILURE, utility.InitializeTpm());
95}
96
97TEST_F(TpmUtilityTest, StirRandomSuccess) {
98  TpmUtilityImpl utility(factory_);
99  std::string entropy_data("large test data", 100);
100  EXPECT_CALL(mock_tpm_, StirRandomSync(_, _))
101      .WillOnce(Return(TPM_RC_SUCCESS));
102  EXPECT_EQ(TPM_RC_SUCCESS, utility.StirRandom(entropy_data));
103}
104
105TEST_F(TpmUtilityTest, StirRandomFails) {
106  TpmUtilityImpl utility(factory_);
107  std::string entropy_data("test data");
108  EXPECT_CALL(mock_tpm_, StirRandomSync(_, _))
109      .WillOnce(Return(TPM_RC_FAILURE));
110  EXPECT_EQ(TPM_RC_FAILURE, utility.StirRandom(entropy_data));
111}
112
113TEST_F(TpmUtilityTest, GenerateRandomSuccess) {
114  TpmUtilityImpl utility(factory_);
115  // This number is larger than the max bytes the GetRandom call can return.
116  // Therefore we expect software to make multiple calls to fill this many
117  // bytes.
118  int num_bytes = 72;
119  std::string random_data;
120  TPM2B_DIGEST large_random;
121  large_random.size = 32;
122  TPM2B_DIGEST small_random;
123  small_random.size = 8;
124
125  EXPECT_CALL(mock_tpm_, GetRandomSync(_, _, _))
126      .Times(2)
127      .WillRepeatedly(DoAll(SetArgPointee<1>(large_random),
128                            Return(TPM_RC_SUCCESS)));
129  EXPECT_CALL(mock_tpm_, GetRandomSync(8, _, _))
130      .WillOnce(DoAll(SetArgPointee<1>(small_random),
131                      Return(TPM_RC_SUCCESS)));
132  EXPECT_EQ(TPM_RC_SUCCESS, utility.GenerateRandom(num_bytes, &random_data));
133  EXPECT_EQ(num_bytes, random_data.size());
134}
135
136TEST_F(TpmUtilityTest, GenerateRandomFails) {
137  TpmUtilityImpl utility(factory_);
138  int num_bytes = 5;
139  std::string random_data;
140  EXPECT_CALL(mock_tpm_, GetRandomSync(_, _, _))
141      .WillOnce(Return(TPM_RC_FAILURE));
142  EXPECT_EQ(TPM_RC_FAILURE, utility.GenerateRandom(num_bytes, &random_data));
143}
144
145TEST_F(TpmUtilityTest, ExtendPCRSuccess) {
146  TpmUtilityImpl utility(factory_);
147  EXPECT_EQ(TPM_RC_SUCCESS, utility.ExtendPCR(1, "test digest"));
148}
149
150TEST_F(TpmUtilityTest, ExtendPCRFail) {
151  TpmUtilityImpl utility(factory_);
152  int pcr_index = 0;
153  TPM_HANDLE pcr_handle = HR_PCR + pcr_index;
154  EXPECT_CALL(mock_tpm_, PCR_ExtendSync(pcr_handle, _, _, _))
155      .WillOnce(Return(TPM_RC_FAILURE));
156  EXPECT_EQ(TPM_RC_FAILURE, utility.ExtendPCR(pcr_index, "test digest"));
157}
158
159TEST_F(TpmUtilityTest, ExtendPCRBadParam) {
160  TpmUtilityImpl utility(factory_);
161  EXPECT_EQ(TPM_RC_FAILURE, utility.ExtendPCR(-1, "test digest"));
162}
163
164TEST_F(TpmUtilityTest, ReadPCRSuccess) {
165  TpmUtilityImpl utility(factory_);
166  // The |pcr_index| is chosen to match the structure for |pcr_select|.
167  // If you change |pcr_index|, remember to change |pcr_select|.
168  int pcr_index = 1;
169  std::string pcr_value;
170  TPML_PCR_SELECTION pcr_select;
171  pcr_select.count = 1;
172  pcr_select.pcr_selections[0].hash = TPM_ALG_SHA256;
173  pcr_select.pcr_selections[0].sizeof_select = 1;
174  pcr_select.pcr_selections[0].pcr_select[0] = 2;
175  TPML_DIGEST pcr_values;
176  pcr_values.count = 1;
177  EXPECT_CALL(mock_tpm_, PCR_ReadSync(_, _, _, _, _))
178      .WillOnce(DoAll(SetArgPointee<2>(pcr_select),
179                      SetArgPointee<3>(pcr_values),
180                      Return(TPM_RC_SUCCESS)));
181  EXPECT_EQ(TPM_RC_SUCCESS, utility.ReadPCR(pcr_index, &pcr_value));
182}
183
184TEST_F(TpmUtilityTest, ReadPCRFail) {
185  TpmUtilityImpl utility(factory_);
186  std::string pcr_value;
187  EXPECT_CALL(mock_tpm_, PCR_ReadSync(_, _, _, _, _))
188      .WillOnce(Return(TPM_RC_FAILURE));
189  EXPECT_EQ(TPM_RC_FAILURE, utility.ReadPCR(1, &pcr_value));
190}
191
192TEST_F(TpmUtilityTest, ReadPCRBadReturn) {
193  TpmUtilityImpl utility(factory_);
194  std::string pcr_value;
195  EXPECT_CALL(mock_tpm_, PCR_ReadSync(_, _, _, _, _))
196      .WillOnce(Return(TPM_RC_SUCCESS));
197  EXPECT_EQ(TPM_RC_FAILURE, utility.ReadPCR(1, &pcr_value));
198}
199
200TEST_F(TpmUtilityTest, TakeOwnershipSuccess) {
201  TpmUtilityImpl utility(factory_);
202  EXPECT_CALL(mock_tpm_state_, IsOwnerPasswordSet())
203      .WillRepeatedly(Return(false));
204  EXPECT_CALL(mock_tpm_state_, IsEndorsementPasswordSet())
205      .WillRepeatedly(Return(false));
206  EXPECT_CALL(mock_tpm_state_, IsLockoutPasswordSet())
207      .WillRepeatedly(Return(false));
208  EXPECT_CALL(mock_tpm_, HierarchyChangeAuthSync(TPM_RH_OWNER, _, _, _))
209      .Times(1);
210  EXPECT_CALL(mock_tpm_, HierarchyChangeAuthSync(TPM_RH_ENDORSEMENT, _, _, _))
211      .Times(1);
212  EXPECT_CALL(mock_tpm_, HierarchyChangeAuthSync(TPM_RH_LOCKOUT, _, _, _))
213      .Times(1);
214  EXPECT_EQ(TPM_RC_SUCCESS, utility.TakeOwnership("a", "b", "c"));
215}
216
217TEST_F(TpmUtilityTest, TakeOwnershipAlreadyDone) {
218  TpmUtilityImpl utility(factory_);
219  EXPECT_CALL(mock_tpm_state_, IsOwnerPasswordSet())
220      .WillRepeatedly(Return(true));
221  EXPECT_CALL(mock_tpm_state_, IsEndorsementPasswordSet())
222      .WillRepeatedly(Return(true));
223  EXPECT_CALL(mock_tpm_state_, IsLockoutPasswordSet())
224      .WillRepeatedly(Return(true));
225  EXPECT_CALL(mock_tpm_, HierarchyChangeAuthSync(_, _, _, _))
226      .Times(0);
227  EXPECT_EQ(TPM_RC_SUCCESS, utility.TakeOwnership("a", "b", "c"));
228}
229
230TEST_F(TpmUtilityTest, TakeOwnershipPartial) {
231  TpmUtilityImpl utility(factory_);
232  EXPECT_CALL(mock_tpm_state_, IsOwnerPasswordSet())
233      .WillRepeatedly(Return(true));
234  EXPECT_CALL(mock_tpm_state_, IsEndorsementPasswordSet())
235      .WillOnce(Return(false));
236  EXPECT_CALL(mock_tpm_state_, IsLockoutPasswordSet())
237      .WillRepeatedly(Return(true));
238  EXPECT_CALL(mock_tpm_, HierarchyChangeAuthSync(TPM_RH_OWNER, _, _, _))
239      .Times(0);
240  EXPECT_CALL(mock_tpm_, HierarchyChangeAuthSync(TPM_RH_ENDORSEMENT, _, _, _))
241      .Times(1);
242  EXPECT_CALL(mock_tpm_, HierarchyChangeAuthSync(TPM_RH_LOCKOUT, _, _, _))
243      .Times(0);
244  EXPECT_EQ(TPM_RC_SUCCESS, utility.TakeOwnership("a", "b", "c"));
245}
246
247TEST_F(TpmUtilityTest, TakeOwnershipOwnerFailure) {
248  TpmUtilityImpl utility(factory_);
249  EXPECT_CALL(mock_tpm_state_, IsOwnerPasswordSet())
250      .WillRepeatedly(Return(false));
251  EXPECT_CALL(mock_tpm_state_, IsEndorsementPasswordSet())
252      .WillRepeatedly(Return(false));
253  EXPECT_CALL(mock_tpm_state_, IsLockoutPasswordSet())
254      .WillRepeatedly(Return(false));
255  // Reject attempts to set owner auth.
256  EXPECT_CALL(mock_tpm_, HierarchyChangeAuthSync(TPM_RH_OWNER, _, _, _))
257      .WillRepeatedly(Return(TPM_RC_FAILURE));
258  EXPECT_CALL(mock_tpm_, HierarchyChangeAuthSync(TPM_RH_ENDORSEMENT, _, _, _))
259      .WillRepeatedly(Return(TPM_RC_SUCCESS));
260  EXPECT_CALL(mock_tpm_, HierarchyChangeAuthSync(TPM_RH_LOCKOUT, _, _, _))
261      .WillRepeatedly(Return(TPM_RC_SUCCESS));
262  EXPECT_EQ(TPM_RC_FAILURE, utility.TakeOwnership("a", "b", "c"));
263}
264
265TEST_F(TpmUtilityTest, TakeOwnershipEndorsementFailure) {
266  TpmUtilityImpl utility(factory_);
267  EXPECT_CALL(mock_tpm_state_, IsOwnerPasswordSet())
268      .WillRepeatedly(Return(false));
269  EXPECT_CALL(mock_tpm_state_, IsEndorsementPasswordSet())
270      .WillRepeatedly(Return(false));
271  EXPECT_CALL(mock_tpm_state_, IsLockoutPasswordSet())
272      .WillRepeatedly(Return(false));
273  // Reject attempts to set endorsement auth.
274  EXPECT_CALL(mock_tpm_, HierarchyChangeAuthSync(TPM_RH_OWNER, _, _, _))
275      .WillRepeatedly(Return(TPM_RC_SUCCESS));
276  EXPECT_CALL(mock_tpm_, HierarchyChangeAuthSync(TPM_RH_ENDORSEMENT, _, _, _))
277      .WillRepeatedly(Return(TPM_RC_FAILURE));
278  EXPECT_CALL(mock_tpm_, HierarchyChangeAuthSync(TPM_RH_LOCKOUT, _, _, _))
279      .WillRepeatedly(Return(TPM_RC_SUCCESS));
280  EXPECT_EQ(TPM_RC_FAILURE, utility.TakeOwnership("a", "b", "c"));
281}
282
283TEST_F(TpmUtilityTest, TakeOwnershipLockoutFailure) {
284  TpmUtilityImpl utility(factory_);
285  EXPECT_CALL(mock_tpm_state_, IsOwnerPasswordSet())
286      .WillRepeatedly(Return(false));
287  EXPECT_CALL(mock_tpm_state_, IsEndorsementPasswordSet())
288      .WillRepeatedly(Return(false));
289  EXPECT_CALL(mock_tpm_state_, IsLockoutPasswordSet())
290      .WillRepeatedly(Return(false));
291  // Reject attempts to set lockout auth.
292  EXPECT_CALL(mock_tpm_, HierarchyChangeAuthSync(TPM_RH_OWNER, _, _, _))
293      .WillRepeatedly(Return(TPM_RC_SUCCESS));
294  EXPECT_CALL(mock_tpm_, HierarchyChangeAuthSync(TPM_RH_ENDORSEMENT, _, _, _))
295      .WillRepeatedly(Return(TPM_RC_SUCCESS));
296  EXPECT_CALL(mock_tpm_, HierarchyChangeAuthSync(TPM_RH_LOCKOUT, _, _, _))
297      .WillRepeatedly(Return(TPM_RC_FAILURE));
298  EXPECT_EQ(TPM_RC_FAILURE, utility.TakeOwnership("a", "b", "c"));
299}
300
301TEST_F(TpmUtilityTest, RootKeysSuccess) {
302  TpmUtilityImpl utility(factory_);
303  EXPECT_EQ(TPM_RC_SUCCESS, utility.CreateStorageRootKeys("password"));
304}
305
306TEST_F(TpmUtilityTest, RootKeysHandleConsistency) {
307  TpmUtilityImpl utility(factory_);
308  TPM_HANDLE test_handle = 42;
309  EXPECT_CALL(mock_tpm_, CreatePrimarySyncShort(_, _, _, _, _, _, _, _, _, _))
310      .WillRepeatedly(DoAll(SetArgPointee<3>(test_handle),
311                            Return(TPM_RC_SUCCESS)));
312  EXPECT_CALL(mock_tpm_, EvictControlSync(_, _, test_handle, _, _, _, _))
313      .WillRepeatedly(Return(TPM_RC_SUCCESS));
314  EXPECT_EQ(TPM_RC_SUCCESS, utility.CreateStorageRootKeys("password"));
315}
316
317TEST_F(TpmUtilityTest, RootKeysCreateFailure) {
318  TpmUtilityImpl utility(factory_);
319  EXPECT_CALL(mock_tpm_, CreatePrimarySyncShort(_, _, _, _, _, _, _, _, _, _))
320      .WillRepeatedly(Return(TPM_RC_FAILURE));
321  EXPECT_EQ(TPM_RC_FAILURE, utility.CreateStorageRootKeys("password"));
322}
323
324TEST_F(TpmUtilityTest, RootKeysPersistFailure) {
325  TpmUtilityImpl utility(factory_);
326  EXPECT_CALL(mock_tpm_, EvictControlSync(_, _, _, _, _, _, _))
327      .WillRepeatedly(Return(TPM_RC_FAILURE));
328  EXPECT_EQ(TPM_RC_FAILURE, utility.CreateStorageRootKeys("password"));
329}
330
331}  // namespace trunks
332