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_nvram_impl.h"
18
19#include <gmock/gmock.h>
20#include <gtest/gtest.h>
21#include <trunks/mock_hmac_session.h>
22#include <trunks/mock_tpm_utility.h>
23#include <trunks/tpm_constants.h>
24#include <trunks/trunks_factory_for_test.h>
25
26#include "tpm_manager/server/mock_local_data_store.h"
27
28namespace {
29const char kTestOwnerPassword[] = "owner";
30}  // namespace
31
32namespace tpm_manager {
33
34using testing::_;
35using testing::DoAll;
36using testing::Mock;
37using testing::NiceMock;
38using testing::Return;
39using testing::SetArgPointee;
40using trunks::TPM_RC_SUCCESS;
41using trunks::TPM_RC_FAILURE;
42
43class Tpm2NvramTest : public testing::Test {
44 public:
45  Tpm2NvramTest() = default;
46  virtual ~Tpm2NvramTest() = default;
47
48  void SetUp() {
49    trunks::TrunksFactoryForTest* factory = new trunks::TrunksFactoryForTest();
50    factory->set_hmac_session(&mock_hmac_session_);
51    factory->set_tpm_utility(&mock_tpm_utility_);
52    tpm_nvram_.reset(new Tpm2NvramImpl(
53        std::unique_ptr<trunks::TrunksFactory>(factory),
54        &mock_data_store_));
55  }
56
57  void InitializeNvram(const std::string& owner_password) {
58    LocalData local_data;
59    local_data.set_owner_password(owner_password);
60    ON_CALL(mock_data_store_, Read(_))
61        .WillByDefault(DoAll(SetArgPointee<0>(local_data),
62                             Return(true)));
63    tpm_nvram_->Initialize();
64    Mock::VerifyAndClearExpectations(&mock_data_store_);
65    Mock::VerifyAndClearExpectations(&mock_hmac_session_);
66    Mock::VerifyAndClearExpectations(&mock_tpm_utility_);
67  }
68
69 protected:
70  NiceMock<trunks::MockHmacSession> mock_hmac_session_;
71  NiceMock<MockLocalDataStore> mock_data_store_;
72  NiceMock<trunks::MockTpmUtility> mock_tpm_utility_;
73  std::unique_ptr<Tpm2NvramImpl> tpm_nvram_;
74};
75
76TEST_F(Tpm2NvramTest, NvramNoOwnerFailure) {
77  uint32_t index = 42;
78  EXPECT_FALSE(tpm_nvram_->DefineNvram(index, 5));
79  EXPECT_FALSE(tpm_nvram_->DestroyNvram(index));
80  EXPECT_FALSE(tpm_nvram_->WriteNvram(index, "data"));
81}
82
83TEST_F(Tpm2NvramTest, DefineNvramSuccess) {
84  InitializeNvram(kTestOwnerPassword);
85  EXPECT_CALL(mock_hmac_session_,
86              SetEntityAuthorizationValue(kTestOwnerPassword));
87  uint32_t index = 42;
88  size_t length = 20;
89  EXPECT_CALL(mock_tpm_utility_, DefineNVSpace(index, length, _))
90      .WillOnce(Return(TPM_RC_SUCCESS));
91  EXPECT_TRUE(tpm_nvram_->DefineNvram(index, length));
92}
93
94TEST_F(Tpm2NvramTest, DefineNvramFailure) {
95  InitializeNvram(kTestOwnerPassword);
96  uint32_t index = 42;
97  size_t length = 20;
98  EXPECT_CALL(mock_tpm_utility_, DefineNVSpace(index, length, _))
99      .WillOnce(Return(TPM_RC_FAILURE));
100  EXPECT_FALSE(tpm_nvram_->DefineNvram(index, length));
101}
102
103TEST_F(Tpm2NvramTest, DestroyNvramSuccess) {
104  InitializeNvram(kTestOwnerPassword);
105  EXPECT_CALL(mock_hmac_session_,
106              SetEntityAuthorizationValue(kTestOwnerPassword));
107  uint32_t index = 42;
108  EXPECT_CALL(mock_tpm_utility_, DestroyNVSpace(index, _))
109      .WillOnce(Return(TPM_RC_SUCCESS));
110  EXPECT_TRUE(tpm_nvram_->DestroyNvram(index));
111}
112
113TEST_F(Tpm2NvramTest, DestroyNvramFailure) {
114  InitializeNvram(kTestOwnerPassword);
115  uint32_t index = 42;
116  EXPECT_CALL(mock_tpm_utility_, DestroyNVSpace(index, _))
117      .WillOnce(Return(TPM_RC_FAILURE));
118  EXPECT_FALSE(tpm_nvram_->DestroyNvram(index));
119}
120
121TEST_F(Tpm2NvramTest, WriteNvramSuccess) {
122  InitializeNvram(kTestOwnerPassword);
123  EXPECT_CALL(mock_hmac_session_,
124              SetEntityAuthorizationValue(kTestOwnerPassword));
125  uint32_t index = 42;
126  std::string data("data");
127  EXPECT_CALL(mock_tpm_utility_, WriteNVSpace(index, 0, data, _))
128      .WillOnce(Return(TPM_RC_SUCCESS));
129  EXPECT_CALL(mock_hmac_session_, SetEntityAuthorizationValue(""));
130  EXPECT_CALL(mock_tpm_utility_, LockNVSpace(index, _))
131      .WillOnce(Return(TPM_RC_SUCCESS));
132  EXPECT_TRUE(tpm_nvram_->WriteNvram(index, data));
133}
134
135TEST_F(Tpm2NvramTest, WriteNvramLockError) {
136  InitializeNvram(kTestOwnerPassword);
137  uint32_t index = 42;
138  EXPECT_CALL(mock_tpm_utility_, WriteNVSpace(index, _, _, _))
139      .WillOnce(Return(TPM_RC_SUCCESS));
140  EXPECT_CALL(mock_tpm_utility_, LockNVSpace(index, _))
141      .WillOnce(Return(TPM_RC_FAILURE));
142  EXPECT_FALSE(tpm_nvram_->WriteNvram(index, "data"));
143}
144
145TEST_F(Tpm2NvramTest, WriteNvramFailure) {
146  InitializeNvram(kTestOwnerPassword);
147  uint32_t index = 42;
148  EXPECT_CALL(mock_tpm_utility_, WriteNVSpace(index, _, _, _))
149      .WillOnce(Return(TPM_RC_FAILURE));
150  EXPECT_FALSE(tpm_nvram_->WriteNvram(index, "data"));
151}
152
153TEST_F(Tpm2NvramTest, ReadNvramSuccess) {
154  uint32_t index = 42;
155  std::string tpm_data("data");
156  size_t size = tpm_data.size();
157  trunks::TPMS_NV_PUBLIC nvram_public;
158  nvram_public.data_size = size;
159  EXPECT_CALL(mock_tpm_utility_, GetNVSpacePublicArea(_, _))
160      .WillOnce(DoAll(SetArgPointee<1>(nvram_public),
161                      Return(TPM_RC_SUCCESS)));
162
163  EXPECT_CALL(mock_hmac_session_, SetEntityAuthorizationValue(""));
164  EXPECT_CALL(mock_tpm_utility_, ReadNVSpace(index, 0, size, _, _))
165      .WillOnce(DoAll(SetArgPointee<3>(tpm_data),
166                      Return(TPM_RC_SUCCESS)));
167  std::string read_data;
168  EXPECT_TRUE(tpm_nvram_->ReadNvram(index, &read_data));
169  EXPECT_EQ(read_data, tpm_data);
170}
171
172TEST_F(Tpm2NvramTest, ReadNvramNonexistant) {
173  uint32_t index = 42;
174  EXPECT_CALL(mock_tpm_utility_, GetNVSpacePublicArea(index, _))
175      .WillOnce(Return(TPM_RC_FAILURE));
176  std::string read_data;
177  EXPECT_FALSE(tpm_nvram_->ReadNvram(index, &read_data));
178}
179
180TEST_F(Tpm2NvramTest, ReadNvramFailure) {
181  uint32_t index = 42;
182  trunks::TPMS_NV_PUBLIC nvram_public;
183  EXPECT_CALL(mock_tpm_utility_, GetNVSpacePublicArea(index, _))
184      .WillOnce(DoAll(SetArgPointee<1>(nvram_public),
185                      Return(TPM_RC_SUCCESS)));
186  EXPECT_CALL(mock_tpm_utility_, ReadNVSpace(index, _, _, _, _))
187      .WillOnce(Return(TPM_RC_FAILURE));
188  std::string read_data;
189  EXPECT_FALSE(tpm_nvram_->ReadNvram(index, &read_data));
190}
191
192TEST_F(Tpm2NvramTest, IsNvramDefinedSuccess) {
193  uint32_t index = 42;
194  EXPECT_CALL(mock_tpm_utility_, GetNVSpacePublicArea(index, _))
195      .WillOnce(Return(TPM_RC_SUCCESS));
196  bool defined;
197  EXPECT_TRUE(tpm_nvram_->IsNvramDefined(index, &defined));
198  EXPECT_TRUE(defined);
199}
200
201TEST_F(Tpm2NvramTest, IsNvramDefinedNonexistant) {
202  uint32_t index = 42;
203  EXPECT_CALL(mock_tpm_utility_, GetNVSpacePublicArea(index, _))
204      .WillOnce(Return(trunks::TPM_RC_HANDLE));
205  bool defined;
206  EXPECT_TRUE(tpm_nvram_->IsNvramDefined(index, &defined));
207  EXPECT_FALSE(defined);
208}
209
210TEST_F(Tpm2NvramTest, IsNvramDefinedFailure) {
211  uint32_t index = 42;
212  EXPECT_CALL(mock_tpm_utility_, GetNVSpacePublicArea(index, _))
213      .WillOnce(Return(TPM_RC_FAILURE));
214  bool defined;
215  EXPECT_FALSE(tpm_nvram_->IsNvramDefined(index, &defined));
216}
217
218TEST_F(Tpm2NvramTest, IsNvramLockedSuccess) {
219  uint32_t index = 42;
220  trunks::TPMS_NV_PUBLIC nvram_public;
221  nvram_public.attributes = trunks::TPMA_NV_WRITELOCKED;
222  EXPECT_CALL(mock_tpm_utility_, GetNVSpacePublicArea(index, _))
223      .WillOnce(DoAll(SetArgPointee<1>(nvram_public),
224                      Return(TPM_RC_SUCCESS)));
225  bool locked;
226  EXPECT_TRUE(tpm_nvram_->IsNvramLocked(index, &locked));
227  EXPECT_TRUE(locked);
228}
229
230TEST_F(Tpm2NvramTest, IsNvramLockedUnlocked) {
231  uint32_t index = 42;
232  trunks::TPMS_NV_PUBLIC nvram_public;
233  nvram_public.attributes = 0;
234  EXPECT_CALL(mock_tpm_utility_, GetNVSpacePublicArea(index, _))
235      .WillOnce(DoAll(SetArgPointee<1>(nvram_public),
236                      Return(TPM_RC_SUCCESS)));
237  bool locked;
238  EXPECT_TRUE(tpm_nvram_->IsNvramLocked(index, &locked));
239  EXPECT_FALSE(locked);
240}
241
242TEST_F(Tpm2NvramTest, IsNvramLockedFailure) {
243  uint32_t index = 42;
244  EXPECT_CALL(mock_tpm_utility_, GetNVSpacePublicArea(index, _))
245      .WillOnce(Return(TPM_RC_FAILURE));
246  bool locked;
247  EXPECT_FALSE(tpm_nvram_->IsNvramLocked(index, &locked));
248}
249
250TEST_F(Tpm2NvramTest, GetNvramSizeSuccess) {
251  uint32_t index = 42;
252  size_t nvram_size = 20;
253  trunks::TPMS_NV_PUBLIC nvram_public;
254  nvram_public.data_size = nvram_size;
255  EXPECT_CALL(mock_tpm_utility_, GetNVSpacePublicArea(index, _))
256      .WillOnce(DoAll(SetArgPointee<1>(nvram_public),
257                      Return(TPM_RC_SUCCESS)));
258  size_t size;
259  EXPECT_TRUE(tpm_nvram_->GetNvramSize(index, &size));
260  EXPECT_EQ(size, nvram_size);
261}
262
263TEST_F(Tpm2NvramTest, GetNvramSizeFailure) {
264  uint32_t index = 42;
265  EXPECT_CALL(mock_tpm_utility_, GetNVSpacePublicArea(index, _))
266      .WillOnce(Return(TPM_RC_FAILURE));
267  size_t size;
268  EXPECT_FALSE(tpm_nvram_->GetNvramSize(index, &size));
269}
270
271}  // namespace tpm_manager
272