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/tpm_manager_service.h" 18 19 #include <base/callback.h> 20 #include <base/command_line.h> 21 #include <brillo/bind_lambda.h> 22 23 namespace tpm_manager { 24 25 TpmManagerService::TpmManagerService(bool wait_for_ownership, 26 LocalDataStore* local_data_store, 27 TpmStatus* tpm_status, 28 TpmInitializer* tpm_initializer, 29 TpmNvram* tpm_nvram) 30 : local_data_store_(local_data_store), 31 tpm_status_(tpm_status), 32 tpm_initializer_(tpm_initializer), 33 tpm_nvram_(tpm_nvram), 34 wait_for_ownership_(wait_for_ownership), 35 weak_factory_(this) {} 36 37 bool TpmManagerService::Initialize() { 38 worker_thread_.reset(new base::Thread("TpmManager Service Worker")); 39 worker_thread_->StartWithOptions( 40 base::Thread::Options(base::MessageLoop::TYPE_IO, 0)); 41 base::Closure task = 42 base::Bind(&TpmManagerService::InitializeTask, base::Unretained(this)); 43 worker_thread_->task_runner()->PostNonNestableTask(FROM_HERE, task); 44 VLOG(1) << "Worker thread started."; 45 return true; 46 } 47 48 void TpmManagerService::InitializeTask() { 49 VLOG(1) << "Initializing service..."; 50 if (!tpm_status_->IsTpmEnabled()) { 51 LOG(WARNING) << __func__ << ": TPM is disabled."; 52 return; 53 } 54 tpm_initializer_->VerifiedBootHelper(); 55 if (!wait_for_ownership_) { 56 VLOG(1) << "Initializing TPM."; 57 if (!tpm_initializer_->InitializeTpm()) { 58 LOG(WARNING) << __func__ << ": TPM initialization failed."; 59 return; 60 } 61 } 62 } 63 64 void TpmManagerService::GetTpmStatus(const GetTpmStatusRequest& request, 65 const GetTpmStatusCallback& callback) { 66 PostTaskToWorkerThread<GetTpmStatusReply>( 67 request, callback, &TpmManagerService::GetTpmStatusTask); 68 } 69 70 void TpmManagerService::GetTpmStatusTask( 71 const GetTpmStatusRequest& request, 72 const std::shared_ptr<GetTpmStatusReply>& reply) { 73 VLOG(1) << __func__; 74 reply->set_enabled(tpm_status_->IsTpmEnabled()); 75 reply->set_owned(tpm_status_->IsTpmOwned()); 76 LocalData local_data; 77 if (local_data_store_ && local_data_store_->Read(&local_data)) { 78 *reply->mutable_local_data() = local_data; 79 } 80 int counter; 81 int threshold; 82 bool lockout; 83 int lockout_time_remaining; 84 if (tpm_status_->GetDictionaryAttackInfo(&counter, &threshold, &lockout, 85 &lockout_time_remaining)) { 86 reply->set_dictionary_attack_counter(counter); 87 reply->set_dictionary_attack_threshold(threshold); 88 reply->set_dictionary_attack_lockout_in_effect(lockout); 89 reply->set_dictionary_attack_lockout_seconds_remaining( 90 lockout_time_remaining); 91 } 92 reply->set_status(STATUS_SUCCESS); 93 } 94 95 void TpmManagerService::TakeOwnership(const TakeOwnershipRequest& request, 96 const TakeOwnershipCallback& callback) { 97 PostTaskToWorkerThread<TakeOwnershipReply>( 98 request, callback, &TpmManagerService::TakeOwnershipTask); 99 } 100 101 void TpmManagerService::TakeOwnershipTask( 102 const TakeOwnershipRequest& request, 103 const std::shared_ptr<TakeOwnershipReply>& reply) { 104 VLOG(1) << __func__; 105 if (!tpm_status_->IsTpmEnabled()) { 106 reply->set_status(STATUS_NOT_AVAILABLE); 107 return; 108 } 109 if (!tpm_initializer_->InitializeTpm()) { 110 reply->set_status(STATUS_DEVICE_ERROR); 111 return; 112 } 113 reply->set_status(STATUS_SUCCESS); 114 } 115 116 void TpmManagerService::RemoveOwnerDependency( 117 const RemoveOwnerDependencyRequest& request, 118 const RemoveOwnerDependencyCallback& callback) { 119 PostTaskToWorkerThread<RemoveOwnerDependencyReply>( 120 request, callback, &TpmManagerService::RemoveOwnerDependencyTask); 121 } 122 123 void TpmManagerService::RemoveOwnerDependencyTask( 124 const RemoveOwnerDependencyRequest& request, 125 const std::shared_ptr<RemoveOwnerDependencyReply>& reply) { 126 VLOG(1) << __func__; 127 LocalData local_data; 128 if (!local_data_store_->Read(&local_data)) { 129 reply->set_status(STATUS_DEVICE_ERROR); 130 return; 131 } 132 RemoveOwnerDependency(request.owner_dependency(), &local_data); 133 if (!local_data_store_->Write(local_data)) { 134 reply->set_status(STATUS_DEVICE_ERROR); 135 return; 136 } 137 reply->set_status(STATUS_SUCCESS); 138 } 139 140 void TpmManagerService::RemoveOwnerDependency( 141 const std::string& owner_dependency, 142 LocalData* local_data) { 143 google::protobuf::RepeatedPtrField<std::string>* dependencies = 144 local_data->mutable_owner_dependency(); 145 for (int i = 0; i < dependencies->size(); i++) { 146 if (dependencies->Get(i) == owner_dependency) { 147 dependencies->SwapElements(i, (dependencies->size() - 1)); 148 dependencies->RemoveLast(); 149 break; 150 } 151 } 152 if (dependencies->empty()) { 153 local_data->clear_owner_password(); 154 local_data->clear_endorsement_password(); 155 local_data->clear_lockout_password(); 156 } 157 } 158 159 void TpmManagerService::DefineSpace(const DefineSpaceRequest& request, 160 const DefineSpaceCallback& callback) { 161 PostTaskToWorkerThread<DefineSpaceReply>(request, callback, 162 &TpmManagerService::DefineSpaceTask); 163 } 164 165 void TpmManagerService::DefineSpaceTask( 166 const DefineSpaceRequest& request, 167 const std::shared_ptr<DefineSpaceReply>& reply) { 168 VLOG(1) << __func__; 169 std::vector<NvramSpaceAttribute> attributes; 170 for (int i = 0; i < request.attributes_size(); ++i) { 171 attributes.push_back(request.attributes(i)); 172 } 173 reply->set_result( 174 tpm_nvram_->DefineSpace(request.index(), request.size(), attributes, 175 request.authorization_value(), request.policy())); 176 } 177 178 void TpmManagerService::DestroySpace(const DestroySpaceRequest& request, 179 const DestroySpaceCallback& callback) { 180 PostTaskToWorkerThread<DestroySpaceReply>( 181 request, callback, &TpmManagerService::DestroySpaceTask); 182 } 183 184 void TpmManagerService::DestroySpaceTask( 185 const DestroySpaceRequest& request, 186 const std::shared_ptr<DestroySpaceReply>& reply) { 187 VLOG(1) << __func__; 188 reply->set_result(tpm_nvram_->DestroySpace(request.index())); 189 } 190 191 void TpmManagerService::WriteSpace(const WriteSpaceRequest& request, 192 const WriteSpaceCallback& callback) { 193 PostTaskToWorkerThread<WriteSpaceReply>(request, callback, 194 &TpmManagerService::WriteSpaceTask); 195 } 196 197 void TpmManagerService::WriteSpaceTask( 198 const WriteSpaceRequest& request, 199 const std::shared_ptr<WriteSpaceReply>& reply) { 200 VLOG(1) << __func__; 201 std::string authorization_value = request.authorization_value(); 202 if (request.use_owner_authorization()) { 203 authorization_value = GetOwnerPassword(); 204 if (authorization_value.empty()) { 205 reply->set_result(NVRAM_RESULT_ACCESS_DENIED); 206 return; 207 } 208 } 209 reply->set_result(tpm_nvram_->WriteSpace(request.index(), request.data(), 210 authorization_value)); 211 } 212 213 void TpmManagerService::ReadSpace(const ReadSpaceRequest& request, 214 const ReadSpaceCallback& callback) { 215 PostTaskToWorkerThread<ReadSpaceReply>(request, callback, 216 &TpmManagerService::ReadSpaceTask); 217 } 218 219 void TpmManagerService::ReadSpaceTask( 220 const ReadSpaceRequest& request, 221 const std::shared_ptr<ReadSpaceReply>& reply) { 222 VLOG(1) << __func__; 223 std::string authorization_value = request.authorization_value(); 224 if (request.use_owner_authorization()) { 225 authorization_value = GetOwnerPassword(); 226 if (authorization_value.empty()) { 227 reply->set_result(NVRAM_RESULT_ACCESS_DENIED); 228 return; 229 } 230 } 231 reply->set_result(tpm_nvram_->ReadSpace( 232 request.index(), reply->mutable_data(), authorization_value)); 233 } 234 235 void TpmManagerService::LockSpace(const LockSpaceRequest& request, 236 const LockSpaceCallback& callback) { 237 PostTaskToWorkerThread<LockSpaceReply>(request, callback, 238 &TpmManagerService::LockSpaceTask); 239 } 240 241 void TpmManagerService::LockSpaceTask( 242 const LockSpaceRequest& request, 243 const std::shared_ptr<LockSpaceReply>& reply) { 244 VLOG(1) << __func__; 245 std::string authorization_value = request.authorization_value(); 246 if (request.use_owner_authorization()) { 247 authorization_value = GetOwnerPassword(); 248 if (authorization_value.empty()) { 249 reply->set_result(NVRAM_RESULT_ACCESS_DENIED); 250 return; 251 } 252 } 253 reply->set_result(tpm_nvram_->LockSpace(request.index(), request.lock_read(), 254 request.lock_write(), 255 authorization_value)); 256 } 257 258 void TpmManagerService::ListSpaces(const ListSpacesRequest& request, 259 const ListSpacesCallback& callback) { 260 PostTaskToWorkerThread<ListSpacesReply>(request, callback, 261 &TpmManagerService::ListSpacesTask); 262 } 263 264 void TpmManagerService::ListSpacesTask( 265 const ListSpacesRequest& request, 266 const std::shared_ptr<ListSpacesReply>& reply) { 267 VLOG(1) << __func__; 268 std::vector<uint32_t> index_list; 269 reply->set_result(tpm_nvram_->ListSpaces(&index_list)); 270 if (reply->result() == NVRAM_RESULT_SUCCESS) { 271 for (auto index : index_list) { 272 reply->add_index_list(index); 273 } 274 } 275 } 276 277 void TpmManagerService::GetSpaceInfo(const GetSpaceInfoRequest& request, 278 const GetSpaceInfoCallback& callback) { 279 PostTaskToWorkerThread<GetSpaceInfoReply>( 280 request, callback, &TpmManagerService::GetSpaceInfoTask); 281 } 282 283 void TpmManagerService::GetSpaceInfoTask( 284 const GetSpaceInfoRequest& request, 285 const std::shared_ptr<GetSpaceInfoReply>& reply) { 286 VLOG(1) << __func__; 287 std::vector<NvramSpaceAttribute> attributes; 288 size_t size = 0; 289 bool is_read_locked = false; 290 bool is_write_locked = false; 291 NvramSpacePolicy policy = NVRAM_POLICY_NONE; 292 reply->set_result(tpm_nvram_->GetSpaceInfo(request.index(), &size, 293 &is_read_locked, &is_write_locked, 294 &attributes, &policy)); 295 if (reply->result() == NVRAM_RESULT_SUCCESS) { 296 reply->set_size(size); 297 reply->set_is_read_locked(is_read_locked); 298 reply->set_is_write_locked(is_write_locked); 299 for (auto attribute : attributes) { 300 reply->add_attributes(attribute); 301 } 302 reply->set_policy(policy); 303 } 304 } 305 306 std::string TpmManagerService::GetOwnerPassword() { 307 LocalData local_data; 308 if (local_data_store_ && local_data_store_->Read(&local_data)) { 309 return local_data.owner_password(); 310 } 311 LOG(ERROR) << "TPM owner password requested but not available."; 312 return std::string(); 313 } 314 315 template <typename ReplyProtobufType> 316 void TpmManagerService::TaskRelayCallback( 317 const base::Callback<void(const ReplyProtobufType&)> callback, 318 const std::shared_ptr<ReplyProtobufType>& reply) { 319 callback.Run(*reply); 320 } 321 322 template <typename ReplyProtobufType, 323 typename RequestProtobufType, 324 typename ReplyCallbackType, 325 typename TaskType> 326 void TpmManagerService::PostTaskToWorkerThread(RequestProtobufType& request, 327 ReplyCallbackType& callback, 328 TaskType task) { 329 auto result = std::make_shared<ReplyProtobufType>(); 330 base::Closure background_task = 331 base::Bind(task, base::Unretained(this), request, result); 332 base::Closure reply = 333 base::Bind(&TpmManagerService::TaskRelayCallback<ReplyProtobufType>, 334 weak_factory_.GetWeakPtr(), callback, result); 335 worker_thread_->task_runner()->PostTaskAndReply(FROM_HERE, background_task, 336 reply); 337 } 338 339 } // namespace tpm_manager 340