• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 <memory>
20 #include <string>
21 
22 #include <base/logging.h>
23 #include <trunks/error_codes.h>
24 #include <trunks/tpm_constants.h>
25 #include <trunks/tpm_utility.h>
26 #include <trunks/trunks_factory_impl.h>
27 
28 namespace tpm_manager {
29 
30 using trunks::GetErrorString;
31 using trunks::TPM_RC;
32 using trunks::TPM_RC_SUCCESS;
33 
Tpm2NvramImpl(LocalDataStore * local_data_store)34 Tpm2NvramImpl::Tpm2NvramImpl(LocalDataStore* local_data_store)
35     : trunks_factory_(new trunks::TrunksFactoryImpl()),
36       local_data_store_(local_data_store),
37       initialized_(false),
38       trunks_session_(trunks_factory_->GetHmacSession()),
39       trunks_utility_(trunks_factory_->GetTpmUtility()) {}
40 
Tpm2NvramImpl(std::unique_ptr<trunks::TrunksFactory> factory,LocalDataStore * local_data_store)41 Tpm2NvramImpl::Tpm2NvramImpl(std::unique_ptr<trunks::TrunksFactory> factory,
42                              LocalDataStore* local_data_store)
43     : trunks_factory_(std::move(factory)),
44       local_data_store_(local_data_store),
45       initialized_(false),
46       trunks_session_(trunks_factory_->GetHmacSession()),
47       trunks_utility_(trunks_factory_->GetTpmUtility()) {}
48 
Initialize()49 bool Tpm2NvramImpl::Initialize() {
50   if (initialized_) {
51     return true;
52   }
53   TPM_RC result = trunks_utility_->StartSession(trunks_session_.get());
54   if (result != TPM_RC_SUCCESS) {
55     LOG(ERROR) << "Error starting an authorization session with trunks: "
56                << GetErrorString(result);
57     return false;
58   }
59   LocalData local_data;
60   if (!local_data_store_->Read(&local_data)) {
61     LOG(ERROR) << "Error reading local tpm data.";
62     return false;
63   }
64   if (!local_data.owner_password().empty()) {
65     owner_password_.assign(local_data.owner_password());
66     initialized_ = true;
67   }
68   return true;
69 }
70 
InitializeWithOwnerPassword()71 bool Tpm2NvramImpl::InitializeWithOwnerPassword() {
72   if (!Initialize()) {
73     return false;
74   }
75   if (owner_password_.empty()) {
76     LOG(ERROR) << "Error owner password not available.";
77     return false;
78   }
79   trunks_session_->SetEntityAuthorizationValue(owner_password_);
80   return true;
81 }
82 
DefineNvram(uint32_t index,size_t length)83 bool Tpm2NvramImpl::DefineNvram(uint32_t index, size_t length) {
84   if (!InitializeWithOwnerPassword()) {
85     return false;
86   }
87   TPM_RC result = trunks_utility_->DefineNVSpace(
88       index, length, trunks_session_->GetDelegate());
89   if (result != TPM_RC_SUCCESS) {
90     LOG(ERROR) << "Error defining nvram space: " << GetErrorString(result);
91     return false;
92   }
93   return true;
94 }
95 
DestroyNvram(uint32_t index)96 bool Tpm2NvramImpl::DestroyNvram(uint32_t index) {
97   if (!InitializeWithOwnerPassword()) {
98     return false;
99   }
100   TPM_RC result = trunks_utility_->DestroyNVSpace(
101       index, trunks_session_->GetDelegate());
102   if (result != TPM_RC_SUCCESS) {
103     LOG(ERROR) << "Error destroying nvram space:" << GetErrorString(result);
104     return false;
105   }
106   return true;
107 }
108 
WriteNvram(uint32_t index,const std::string & data)109 bool Tpm2NvramImpl::WriteNvram(uint32_t index, const std::string& data) {
110   if (!InitializeWithOwnerPassword()) {
111     return false;
112   }
113   TPM_RC result = trunks_utility_->WriteNVSpace(index,
114                                                 0,  // offset
115                                                 data,
116                                                 trunks_session_->GetDelegate());
117   if (result != TPM_RC_SUCCESS) {
118     LOG(ERROR) << "Error writing to nvram space: " << GetErrorString(result);
119     return false;
120   }
121   result = trunks_utility_->LockNVSpace(index, trunks_session_->GetDelegate());
122   if (result != TPM_RC_SUCCESS) {
123     LOG(ERROR) << "Error locking nvram space: " << GetErrorString(result);
124     return false;
125   }
126   return true;
127 }
128 
ReadNvram(uint32_t index,std::string * data)129 bool Tpm2NvramImpl::ReadNvram(uint32_t index, std::string* data) {
130   if (!Initialize()) {
131     return false;
132   }
133   size_t nvram_size;
134   if (!GetNvramSize(index, &nvram_size)) {
135     LOG(ERROR) << "Error getting size of nvram space.";
136     return false;
137   }
138   trunks_session_->SetEntityAuthorizationValue("");
139   TPM_RC result = trunks_utility_->ReadNVSpace(index,
140                                                0,  // offset
141                                                nvram_size,
142                                                data,
143                                                trunks_session_->GetDelegate());
144   if (result != TPM_RC_SUCCESS) {
145     LOG(ERROR) << "Error reading nvram space: " << GetErrorString(result);
146     return false;
147   }
148   return true;
149 }
150 
IsNvramDefined(uint32_t index,bool * defined)151 bool Tpm2NvramImpl::IsNvramDefined(uint32_t index, bool* defined) {
152   trunks::TPMS_NV_PUBLIC nvram_public;
153   TPM_RC result = trunks_utility_->GetNVSpacePublicArea(index, &nvram_public);
154   if (trunks::GetFormatOneError(result) == trunks::TPM_RC_HANDLE) {
155     *defined = false;
156   } else if (result == TPM_RC_SUCCESS) {
157     *defined = true;
158   } else {
159     LOG(ERROR) << "Error reading NV space for index " << index
160                << " with error: " << GetErrorString(result);
161     return false;
162   }
163   return true;
164 }
165 
IsNvramLocked(uint32_t index,bool * locked)166 bool Tpm2NvramImpl::IsNvramLocked(uint32_t index, bool* locked) {
167   trunks::TPMS_NV_PUBLIC nvram_public;
168   TPM_RC result = trunks_utility_->GetNVSpacePublicArea(index, &nvram_public);
169   if (result != TPM_RC_SUCCESS) {
170     LOG(ERROR) << "Error reading NV space for index " << index
171                << " with error: " << GetErrorString(result);
172     return false;
173   }
174   *locked = ((nvram_public.attributes & trunks::TPMA_NV_WRITELOCKED) != 0);
175   return true;
176 }
177 
GetNvramSize(uint32_t index,size_t * size)178 bool Tpm2NvramImpl::GetNvramSize(uint32_t index, size_t* size) {
179   trunks::TPMS_NV_PUBLIC nvram_public;
180   TPM_RC result = trunks_utility_->GetNVSpacePublicArea(index, &nvram_public);
181   if (result != TPM_RC_SUCCESS) {
182     LOG(ERROR) << "Error reading NV space for index " << index
183                << " with error: " << GetErrorString(result);
184     return false;
185   }
186   *size = nvram_public.data_size;
187   return true;
188 }
189 
190 }  // namespace tpm_manager
191