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