1259fa1be39c0a35ec374fe127ba49d1c5ed5eb18Utkarsh Sanghi//
2259fa1be39c0a35ec374fe127ba49d1c5ed5eb18Utkarsh Sanghi// Copyright (C) 2015 The Android Open Source Project
3259fa1be39c0a35ec374fe127ba49d1c5ed5eb18Utkarsh Sanghi//
4259fa1be39c0a35ec374fe127ba49d1c5ed5eb18Utkarsh Sanghi// Licensed under the Apache License, Version 2.0 (the "License");
5259fa1be39c0a35ec374fe127ba49d1c5ed5eb18Utkarsh Sanghi// you may not use this file except in compliance with the License.
6259fa1be39c0a35ec374fe127ba49d1c5ed5eb18Utkarsh Sanghi// You may obtain a copy of the License at
7259fa1be39c0a35ec374fe127ba49d1c5ed5eb18Utkarsh Sanghi//
8259fa1be39c0a35ec374fe127ba49d1c5ed5eb18Utkarsh Sanghi//      http://www.apache.org/licenses/LICENSE-2.0
9259fa1be39c0a35ec374fe127ba49d1c5ed5eb18Utkarsh Sanghi//
10259fa1be39c0a35ec374fe127ba49d1c5ed5eb18Utkarsh Sanghi// Unless required by applicable law or agreed to in writing, software
11259fa1be39c0a35ec374fe127ba49d1c5ed5eb18Utkarsh Sanghi// distributed under the License is distributed on an "AS IS" BASIS,
12259fa1be39c0a35ec374fe127ba49d1c5ed5eb18Utkarsh Sanghi// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13259fa1be39c0a35ec374fe127ba49d1c5ed5eb18Utkarsh Sanghi// See the License for the specific language governing permissions and
14259fa1be39c0a35ec374fe127ba49d1c5ed5eb18Utkarsh Sanghi// limitations under the License.
15259fa1be39c0a35ec374fe127ba49d1c5ed5eb18Utkarsh Sanghi//
162863c75955f0e50df2ad29587a29b4d5b06779bUtkarsh Sanghi
172863c75955f0e50df2ad29587a29b4d5b06779bUtkarsh Sanghi#include "tpm_manager/server/tpm_manager_service.h"
182863c75955f0e50df2ad29587a29b4d5b06779bUtkarsh Sanghi
192863c75955f0e50df2ad29587a29b4d5b06779bUtkarsh Sanghi#include <base/callback.h>
20f22a3bdbc5f53e4177608b591d5612da2512d070Darren Krahn#include <base/command_line.h>
21a08ddea5f4b861ddf1f4e91bb9c4c34e23dc0ba9Alex Vakulenko#include <brillo/bind_lambda.h>
222863c75955f0e50df2ad29587a29b4d5b06779bUtkarsh Sanghi
232863c75955f0e50df2ad29587a29b4d5b06779bUtkarsh Sanghinamespace tpm_manager {
242863c75955f0e50df2ad29587a29b4d5b06779bUtkarsh Sanghi
25e6419641bfebd76cbe5fffe3877c068af6b1c396Utkarsh SanghiTpmManagerService::TpmManagerService(bool wait_for_ownership,
26c8573194d35f6b6c5033aedbef1ef5b07771792bUtkarsh Sanghi                                     LocalDataStore* local_data_store,
2750e52ff6bcc478118a1cdec27903a5af5061d77bUtkarsh Sanghi                                     TpmStatus* tpm_status,
2837fb0f8c79ba0780b9a9b68082fd67dcc3ccb55dUtkarsh Sanghi                                     TpmInitializer* tpm_initializer,
2937fb0f8c79ba0780b9a9b68082fd67dcc3ccb55dUtkarsh Sanghi                                     TpmNvram* tpm_nvram)
30e6419641bfebd76cbe5fffe3877c068af6b1c396Utkarsh Sanghi    : local_data_store_(local_data_store),
31c8573194d35f6b6c5033aedbef1ef5b07771792bUtkarsh Sanghi      tpm_status_(tpm_status),
3250e52ff6bcc478118a1cdec27903a5af5061d77bUtkarsh Sanghi      tpm_initializer_(tpm_initializer),
3337fb0f8c79ba0780b9a9b68082fd67dcc3ccb55dUtkarsh Sanghi      tpm_nvram_(tpm_nvram),
34e6419641bfebd76cbe5fffe3877c068af6b1c396Utkarsh Sanghi      wait_for_ownership_(wait_for_ownership),
3537fb0f8c79ba0780b9a9b68082fd67dcc3ccb55dUtkarsh Sanghi      weak_factory_(this) {}
362863c75955f0e50df2ad29587a29b4d5b06779bUtkarsh Sanghi
372863c75955f0e50df2ad29587a29b4d5b06779bUtkarsh Sanghibool TpmManagerService::Initialize() {
382863c75955f0e50df2ad29587a29b4d5b06779bUtkarsh Sanghi  worker_thread_.reset(new base::Thread("TpmManager Service Worker"));
392863c75955f0e50df2ad29587a29b4d5b06779bUtkarsh Sanghi  worker_thread_->StartWithOptions(
402863c75955f0e50df2ad29587a29b4d5b06779bUtkarsh Sanghi      base::Thread::Options(base::MessageLoop::TYPE_IO, 0));
414dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn  base::Closure task =
424dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn      base::Bind(&TpmManagerService::InitializeTask, base::Unretained(this));
43f22a3bdbc5f53e4177608b591d5612da2512d070Darren Krahn  worker_thread_->task_runner()->PostNonNestableTask(FROM_HERE, task);
44a94133441da308b30c6fe18cc4e2b866498ee401Darren Krahn  VLOG(1) << "Worker thread started.";
452863c75955f0e50df2ad29587a29b4d5b06779bUtkarsh Sanghi  return true;
462863c75955f0e50df2ad29587a29b4d5b06779bUtkarsh Sanghi}
472863c75955f0e50df2ad29587a29b4d5b06779bUtkarsh Sanghi
48f22a3bdbc5f53e4177608b591d5612da2512d070Darren Krahnvoid TpmManagerService::InitializeTask() {
49a94133441da308b30c6fe18cc4e2b866498ee401Darren Krahn  VLOG(1) << "Initializing service...";
50f22a3bdbc5f53e4177608b591d5612da2512d070Darren Krahn  if (!tpm_status_->IsTpmEnabled()) {
51f22a3bdbc5f53e4177608b591d5612da2512d070Darren Krahn    LOG(WARNING) << __func__ << ": TPM is disabled.";
52f22a3bdbc5f53e4177608b591d5612da2512d070Darren Krahn    return;
53f22a3bdbc5f53e4177608b591d5612da2512d070Darren Krahn  }
54a94133441da308b30c6fe18cc4e2b866498ee401Darren Krahn  tpm_initializer_->VerifiedBootHelper();
55f22a3bdbc5f53e4177608b591d5612da2512d070Darren Krahn  if (!wait_for_ownership_) {
56f22a3bdbc5f53e4177608b591d5612da2512d070Darren Krahn    VLOG(1) << "Initializing TPM.";
57f22a3bdbc5f53e4177608b591d5612da2512d070Darren Krahn    if (!tpm_initializer_->InitializeTpm()) {
58f22a3bdbc5f53e4177608b591d5612da2512d070Darren Krahn      LOG(WARNING) << __func__ << ": TPM initialization failed.";
59f22a3bdbc5f53e4177608b591d5612da2512d070Darren Krahn      return;
60f22a3bdbc5f53e4177608b591d5612da2512d070Darren Krahn    }
61f22a3bdbc5f53e4177608b591d5612da2512d070Darren Krahn  }
62f22a3bdbc5f53e4177608b591d5612da2512d070Darren Krahn}
63f22a3bdbc5f53e4177608b591d5612da2512d070Darren Krahn
642863c75955f0e50df2ad29587a29b4d5b06779bUtkarsh Sanghivoid TpmManagerService::GetTpmStatus(const GetTpmStatusRequest& request,
652863c75955f0e50df2ad29587a29b4d5b06779bUtkarsh Sanghi                                     const GetTpmStatusCallback& callback) {
6637fb0f8c79ba0780b9a9b68082fd67dcc3ccb55dUtkarsh Sanghi  PostTaskToWorkerThread<GetTpmStatusReply>(
6737fb0f8c79ba0780b9a9b68082fd67dcc3ccb55dUtkarsh Sanghi      request, callback, &TpmManagerService::GetTpmStatusTask);
682863c75955f0e50df2ad29587a29b4d5b06779bUtkarsh Sanghi}
692863c75955f0e50df2ad29587a29b4d5b06779bUtkarsh Sanghi
702863c75955f0e50df2ad29587a29b4d5b06779bUtkarsh Sanghivoid TpmManagerService::GetTpmStatusTask(
712863c75955f0e50df2ad29587a29b4d5b06779bUtkarsh Sanghi    const GetTpmStatusRequest& request,
72a94133441da308b30c6fe18cc4e2b866498ee401Darren Krahn    const std::shared_ptr<GetTpmStatusReply>& reply) {
73f22a3bdbc5f53e4177608b591d5612da2512d070Darren Krahn  VLOG(1) << __func__;
74a94133441da308b30c6fe18cc4e2b866498ee401Darren Krahn  reply->set_enabled(tpm_status_->IsTpmEnabled());
75a94133441da308b30c6fe18cc4e2b866498ee401Darren Krahn  reply->set_owned(tpm_status_->IsTpmOwned());
76f22a3bdbc5f53e4177608b591d5612da2512d070Darren Krahn  LocalData local_data;
77c8573194d35f6b6c5033aedbef1ef5b07771792bUtkarsh Sanghi  if (local_data_store_ && local_data_store_->Read(&local_data)) {
78a94133441da308b30c6fe18cc4e2b866498ee401Darren Krahn    *reply->mutable_local_data() = local_data;
79f22a3bdbc5f53e4177608b591d5612da2512d070Darren Krahn  }
80f22a3bdbc5f53e4177608b591d5612da2512d070Darren Krahn  int counter;
81f22a3bdbc5f53e4177608b591d5612da2512d070Darren Krahn  int threshold;
82f22a3bdbc5f53e4177608b591d5612da2512d070Darren Krahn  bool lockout;
83f22a3bdbc5f53e4177608b591d5612da2512d070Darren Krahn  int lockout_time_remaining;
84f22a3bdbc5f53e4177608b591d5612da2512d070Darren Krahn  if (tpm_status_->GetDictionaryAttackInfo(&counter, &threshold, &lockout,
85f22a3bdbc5f53e4177608b591d5612da2512d070Darren Krahn                                           &lockout_time_remaining)) {
86a94133441da308b30c6fe18cc4e2b866498ee401Darren Krahn    reply->set_dictionary_attack_counter(counter);
87a94133441da308b30c6fe18cc4e2b866498ee401Darren Krahn    reply->set_dictionary_attack_threshold(threshold);
88a94133441da308b30c6fe18cc4e2b866498ee401Darren Krahn    reply->set_dictionary_attack_lockout_in_effect(lockout);
89a94133441da308b30c6fe18cc4e2b866498ee401Darren Krahn    reply->set_dictionary_attack_lockout_seconds_remaining(
90f22a3bdbc5f53e4177608b591d5612da2512d070Darren Krahn        lockout_time_remaining);
91f22a3bdbc5f53e4177608b591d5612da2512d070Darren Krahn  }
92a94133441da308b30c6fe18cc4e2b866498ee401Darren Krahn  reply->set_status(STATUS_SUCCESS);
93f22a3bdbc5f53e4177608b591d5612da2512d070Darren Krahn}
94f22a3bdbc5f53e4177608b591d5612da2512d070Darren Krahn
95f22a3bdbc5f53e4177608b591d5612da2512d070Darren Krahnvoid TpmManagerService::TakeOwnership(const TakeOwnershipRequest& request,
96f22a3bdbc5f53e4177608b591d5612da2512d070Darren Krahn                                      const TakeOwnershipCallback& callback) {
9737fb0f8c79ba0780b9a9b68082fd67dcc3ccb55dUtkarsh Sanghi  PostTaskToWorkerThread<TakeOwnershipReply>(
9837fb0f8c79ba0780b9a9b68082fd67dcc3ccb55dUtkarsh Sanghi      request, callback, &TpmManagerService::TakeOwnershipTask);
99f22a3bdbc5f53e4177608b591d5612da2512d070Darren Krahn}
100f22a3bdbc5f53e4177608b591d5612da2512d070Darren Krahn
101f22a3bdbc5f53e4177608b591d5612da2512d070Darren Krahnvoid TpmManagerService::TakeOwnershipTask(
102f22a3bdbc5f53e4177608b591d5612da2512d070Darren Krahn    const TakeOwnershipRequest& request,
103a94133441da308b30c6fe18cc4e2b866498ee401Darren Krahn    const std::shared_ptr<TakeOwnershipReply>& reply) {
104f22a3bdbc5f53e4177608b591d5612da2512d070Darren Krahn  VLOG(1) << __func__;
105f22a3bdbc5f53e4177608b591d5612da2512d070Darren Krahn  if (!tpm_status_->IsTpmEnabled()) {
106a94133441da308b30c6fe18cc4e2b866498ee401Darren Krahn    reply->set_status(STATUS_NOT_AVAILABLE);
107f22a3bdbc5f53e4177608b591d5612da2512d070Darren Krahn    return;
108f22a3bdbc5f53e4177608b591d5612da2512d070Darren Krahn  }
109f22a3bdbc5f53e4177608b591d5612da2512d070Darren Krahn  if (!tpm_initializer_->InitializeTpm()) {
110a94133441da308b30c6fe18cc4e2b866498ee401Darren Krahn    reply->set_status(STATUS_DEVICE_ERROR);
111f22a3bdbc5f53e4177608b591d5612da2512d070Darren Krahn    return;
112f22a3bdbc5f53e4177608b591d5612da2512d070Darren Krahn  }
113a94133441da308b30c6fe18cc4e2b866498ee401Darren Krahn  reply->set_status(STATUS_SUCCESS);
1142863c75955f0e50df2ad29587a29b4d5b06779bUtkarsh Sanghi}
1152863c75955f0e50df2ad29587a29b4d5b06779bUtkarsh Sanghi
116bbdb1b1f93626766baf7e293c7a9e532933531c3Utkarsh Sanghivoid TpmManagerService::RemoveOwnerDependency(
117bbdb1b1f93626766baf7e293c7a9e532933531c3Utkarsh Sanghi    const RemoveOwnerDependencyRequest& request,
118bbdb1b1f93626766baf7e293c7a9e532933531c3Utkarsh Sanghi    const RemoveOwnerDependencyCallback& callback) {
119bbdb1b1f93626766baf7e293c7a9e532933531c3Utkarsh Sanghi  PostTaskToWorkerThread<RemoveOwnerDependencyReply>(
120bbdb1b1f93626766baf7e293c7a9e532933531c3Utkarsh Sanghi      request, callback, &TpmManagerService::RemoveOwnerDependencyTask);
121bbdb1b1f93626766baf7e293c7a9e532933531c3Utkarsh Sanghi}
122bbdb1b1f93626766baf7e293c7a9e532933531c3Utkarsh Sanghi
123bbdb1b1f93626766baf7e293c7a9e532933531c3Utkarsh Sanghivoid TpmManagerService::RemoveOwnerDependencyTask(
124bbdb1b1f93626766baf7e293c7a9e532933531c3Utkarsh Sanghi    const RemoveOwnerDependencyRequest& request,
125a94133441da308b30c6fe18cc4e2b866498ee401Darren Krahn    const std::shared_ptr<RemoveOwnerDependencyReply>& reply) {
126bbdb1b1f93626766baf7e293c7a9e532933531c3Utkarsh Sanghi  VLOG(1) << __func__;
1273d4bda022ae92db15a5b28ad9b22b8cede3fa7eaUtkarsh Sanghi  LocalData local_data;
1283d4bda022ae92db15a5b28ad9b22b8cede3fa7eaUtkarsh Sanghi  if (!local_data_store_->Read(&local_data)) {
129a94133441da308b30c6fe18cc4e2b866498ee401Darren Krahn    reply->set_status(STATUS_DEVICE_ERROR);
1303d4bda022ae92db15a5b28ad9b22b8cede3fa7eaUtkarsh Sanghi    return;
1313d4bda022ae92db15a5b28ad9b22b8cede3fa7eaUtkarsh Sanghi  }
1323d4bda022ae92db15a5b28ad9b22b8cede3fa7eaUtkarsh Sanghi  RemoveOwnerDependency(request.owner_dependency(), &local_data);
1333d4bda022ae92db15a5b28ad9b22b8cede3fa7eaUtkarsh Sanghi  if (!local_data_store_->Write(local_data)) {
134a94133441da308b30c6fe18cc4e2b866498ee401Darren Krahn    reply->set_status(STATUS_DEVICE_ERROR);
1353d4bda022ae92db15a5b28ad9b22b8cede3fa7eaUtkarsh Sanghi    return;
1363d4bda022ae92db15a5b28ad9b22b8cede3fa7eaUtkarsh Sanghi  }
137a94133441da308b30c6fe18cc4e2b866498ee401Darren Krahn  reply->set_status(STATUS_SUCCESS);
1383d4bda022ae92db15a5b28ad9b22b8cede3fa7eaUtkarsh Sanghi}
1393d4bda022ae92db15a5b28ad9b22b8cede3fa7eaUtkarsh Sanghi
1403d4bda022ae92db15a5b28ad9b22b8cede3fa7eaUtkarsh Sanghivoid TpmManagerService::RemoveOwnerDependency(
1414dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn    const std::string& owner_dependency,
1424dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn    LocalData* local_data) {
1433d4bda022ae92db15a5b28ad9b22b8cede3fa7eaUtkarsh Sanghi  google::protobuf::RepeatedPtrField<std::string>* dependencies =
1443d4bda022ae92db15a5b28ad9b22b8cede3fa7eaUtkarsh Sanghi      local_data->mutable_owner_dependency();
1453d4bda022ae92db15a5b28ad9b22b8cede3fa7eaUtkarsh Sanghi  for (int i = 0; i < dependencies->size(); i++) {
1463d4bda022ae92db15a5b28ad9b22b8cede3fa7eaUtkarsh Sanghi    if (dependencies->Get(i) == owner_dependency) {
1473d4bda022ae92db15a5b28ad9b22b8cede3fa7eaUtkarsh Sanghi      dependencies->SwapElements(i, (dependencies->size() - 1));
1483d4bda022ae92db15a5b28ad9b22b8cede3fa7eaUtkarsh Sanghi      dependencies->RemoveLast();
1493d4bda022ae92db15a5b28ad9b22b8cede3fa7eaUtkarsh Sanghi      break;
1503d4bda022ae92db15a5b28ad9b22b8cede3fa7eaUtkarsh Sanghi    }
1513d4bda022ae92db15a5b28ad9b22b8cede3fa7eaUtkarsh Sanghi  }
1523d4bda022ae92db15a5b28ad9b22b8cede3fa7eaUtkarsh Sanghi  if (dependencies->empty()) {
1533d4bda022ae92db15a5b28ad9b22b8cede3fa7eaUtkarsh Sanghi    local_data->clear_owner_password();
1543d4bda022ae92db15a5b28ad9b22b8cede3fa7eaUtkarsh Sanghi    local_data->clear_endorsement_password();
1553d4bda022ae92db15a5b28ad9b22b8cede3fa7eaUtkarsh Sanghi    local_data->clear_lockout_password();
1563d4bda022ae92db15a5b28ad9b22b8cede3fa7eaUtkarsh Sanghi  }
157bbdb1b1f93626766baf7e293c7a9e532933531c3Utkarsh Sanghi}
158bbdb1b1f93626766baf7e293c7a9e532933531c3Utkarsh Sanghi
159a94133441da308b30c6fe18cc4e2b866498ee401Darren Krahnvoid TpmManagerService::DefineSpace(const DefineSpaceRequest& request,
160a94133441da308b30c6fe18cc4e2b866498ee401Darren Krahn                                    const DefineSpaceCallback& callback) {
161a94133441da308b30c6fe18cc4e2b866498ee401Darren Krahn  PostTaskToWorkerThread<DefineSpaceReply>(request, callback,
162a94133441da308b30c6fe18cc4e2b866498ee401Darren Krahn                                           &TpmManagerService::DefineSpaceTask);
16337fb0f8c79ba0780b9a9b68082fd67dcc3ccb55dUtkarsh Sanghi}
16437fb0f8c79ba0780b9a9b68082fd67dcc3ccb55dUtkarsh Sanghi
165a94133441da308b30c6fe18cc4e2b866498ee401Darren Krahnvoid TpmManagerService::DefineSpaceTask(
166a94133441da308b30c6fe18cc4e2b866498ee401Darren Krahn    const DefineSpaceRequest& request,
167a94133441da308b30c6fe18cc4e2b866498ee401Darren Krahn    const std::shared_ptr<DefineSpaceReply>& reply) {
16837fb0f8c79ba0780b9a9b68082fd67dcc3ccb55dUtkarsh Sanghi  VLOG(1) << __func__;
169a94133441da308b30c6fe18cc4e2b866498ee401Darren Krahn  std::vector<NvramSpaceAttribute> attributes;
170a94133441da308b30c6fe18cc4e2b866498ee401Darren Krahn  for (int i = 0; i < request.attributes_size(); ++i) {
171a94133441da308b30c6fe18cc4e2b866498ee401Darren Krahn    attributes.push_back(request.attributes(i));
17237fb0f8c79ba0780b9a9b68082fd67dcc3ccb55dUtkarsh Sanghi  }
173a94133441da308b30c6fe18cc4e2b866498ee401Darren Krahn  reply->set_result(
174a94133441da308b30c6fe18cc4e2b866498ee401Darren Krahn      tpm_nvram_->DefineSpace(request.index(), request.size(), attributes,
175a94133441da308b30c6fe18cc4e2b866498ee401Darren Krahn                              request.authorization_value(), request.policy()));
17637fb0f8c79ba0780b9a9b68082fd67dcc3ccb55dUtkarsh Sanghi}
17737fb0f8c79ba0780b9a9b68082fd67dcc3ccb55dUtkarsh Sanghi
178a94133441da308b30c6fe18cc4e2b866498ee401Darren Krahnvoid TpmManagerService::DestroySpace(const DestroySpaceRequest& request,
179a94133441da308b30c6fe18cc4e2b866498ee401Darren Krahn                                     const DestroySpaceCallback& callback) {
180a94133441da308b30c6fe18cc4e2b866498ee401Darren Krahn  PostTaskToWorkerThread<DestroySpaceReply>(
181a94133441da308b30c6fe18cc4e2b866498ee401Darren Krahn      request, callback, &TpmManagerService::DestroySpaceTask);
18237fb0f8c79ba0780b9a9b68082fd67dcc3ccb55dUtkarsh Sanghi}
18337fb0f8c79ba0780b9a9b68082fd67dcc3ccb55dUtkarsh Sanghi
184a94133441da308b30c6fe18cc4e2b866498ee401Darren Krahnvoid TpmManagerService::DestroySpaceTask(
185a94133441da308b30c6fe18cc4e2b866498ee401Darren Krahn    const DestroySpaceRequest& request,
186a94133441da308b30c6fe18cc4e2b866498ee401Darren Krahn    const std::shared_ptr<DestroySpaceReply>& reply) {
18737fb0f8c79ba0780b9a9b68082fd67dcc3ccb55dUtkarsh Sanghi  VLOG(1) << __func__;
188a94133441da308b30c6fe18cc4e2b866498ee401Darren Krahn  reply->set_result(tpm_nvram_->DestroySpace(request.index()));
18937fb0f8c79ba0780b9a9b68082fd67dcc3ccb55dUtkarsh Sanghi}
19037fb0f8c79ba0780b9a9b68082fd67dcc3ccb55dUtkarsh Sanghi
191a94133441da308b30c6fe18cc4e2b866498ee401Darren Krahnvoid TpmManagerService::WriteSpace(const WriteSpaceRequest& request,
192a94133441da308b30c6fe18cc4e2b866498ee401Darren Krahn                                   const WriteSpaceCallback& callback) {
193a94133441da308b30c6fe18cc4e2b866498ee401Darren Krahn  PostTaskToWorkerThread<WriteSpaceReply>(request, callback,
194a94133441da308b30c6fe18cc4e2b866498ee401Darren Krahn                                          &TpmManagerService::WriteSpaceTask);
19537fb0f8c79ba0780b9a9b68082fd67dcc3ccb55dUtkarsh Sanghi}
19637fb0f8c79ba0780b9a9b68082fd67dcc3ccb55dUtkarsh Sanghi
197a94133441da308b30c6fe18cc4e2b866498ee401Darren Krahnvoid TpmManagerService::WriteSpaceTask(
198a94133441da308b30c6fe18cc4e2b866498ee401Darren Krahn    const WriteSpaceRequest& request,
199a94133441da308b30c6fe18cc4e2b866498ee401Darren Krahn    const std::shared_ptr<WriteSpaceReply>& reply) {
20037fb0f8c79ba0780b9a9b68082fd67dcc3ccb55dUtkarsh Sanghi  VLOG(1) << __func__;
201a94133441da308b30c6fe18cc4e2b866498ee401Darren Krahn  std::string authorization_value = request.authorization_value();
202a94133441da308b30c6fe18cc4e2b866498ee401Darren Krahn  if (request.use_owner_authorization()) {
203a94133441da308b30c6fe18cc4e2b866498ee401Darren Krahn    authorization_value = GetOwnerPassword();
204a94133441da308b30c6fe18cc4e2b866498ee401Darren Krahn    if (authorization_value.empty()) {
205a94133441da308b30c6fe18cc4e2b866498ee401Darren Krahn      reply->set_result(NVRAM_RESULT_ACCESS_DENIED);
206a94133441da308b30c6fe18cc4e2b866498ee401Darren Krahn      return;
207a94133441da308b30c6fe18cc4e2b866498ee401Darren Krahn    }
20837fb0f8c79ba0780b9a9b68082fd67dcc3ccb55dUtkarsh Sanghi  }
209a94133441da308b30c6fe18cc4e2b866498ee401Darren Krahn  reply->set_result(tpm_nvram_->WriteSpace(request.index(), request.data(),
210a94133441da308b30c6fe18cc4e2b866498ee401Darren Krahn                                           authorization_value));
21137fb0f8c79ba0780b9a9b68082fd67dcc3ccb55dUtkarsh Sanghi}
21237fb0f8c79ba0780b9a9b68082fd67dcc3ccb55dUtkarsh Sanghi
213a94133441da308b30c6fe18cc4e2b866498ee401Darren Krahnvoid TpmManagerService::ReadSpace(const ReadSpaceRequest& request,
214a94133441da308b30c6fe18cc4e2b866498ee401Darren Krahn                                  const ReadSpaceCallback& callback) {
215a94133441da308b30c6fe18cc4e2b866498ee401Darren Krahn  PostTaskToWorkerThread<ReadSpaceReply>(request, callback,
216a94133441da308b30c6fe18cc4e2b866498ee401Darren Krahn                                         &TpmManagerService::ReadSpaceTask);
21737fb0f8c79ba0780b9a9b68082fd67dcc3ccb55dUtkarsh Sanghi}
21837fb0f8c79ba0780b9a9b68082fd67dcc3ccb55dUtkarsh Sanghi
219a94133441da308b30c6fe18cc4e2b866498ee401Darren Krahnvoid TpmManagerService::ReadSpaceTask(
220a94133441da308b30c6fe18cc4e2b866498ee401Darren Krahn    const ReadSpaceRequest& request,
221a94133441da308b30c6fe18cc4e2b866498ee401Darren Krahn    const std::shared_ptr<ReadSpaceReply>& reply) {
22237fb0f8c79ba0780b9a9b68082fd67dcc3ccb55dUtkarsh Sanghi  VLOG(1) << __func__;
223a94133441da308b30c6fe18cc4e2b866498ee401Darren Krahn  std::string authorization_value = request.authorization_value();
224a94133441da308b30c6fe18cc4e2b866498ee401Darren Krahn  if (request.use_owner_authorization()) {
225a94133441da308b30c6fe18cc4e2b866498ee401Darren Krahn    authorization_value = GetOwnerPassword();
226a94133441da308b30c6fe18cc4e2b866498ee401Darren Krahn    if (authorization_value.empty()) {
227a94133441da308b30c6fe18cc4e2b866498ee401Darren Krahn      reply->set_result(NVRAM_RESULT_ACCESS_DENIED);
228a94133441da308b30c6fe18cc4e2b866498ee401Darren Krahn      return;
229a94133441da308b30c6fe18cc4e2b866498ee401Darren Krahn    }
23037fb0f8c79ba0780b9a9b68082fd67dcc3ccb55dUtkarsh Sanghi  }
231a94133441da308b30c6fe18cc4e2b866498ee401Darren Krahn  reply->set_result(tpm_nvram_->ReadSpace(
232a94133441da308b30c6fe18cc4e2b866498ee401Darren Krahn      request.index(), reply->mutable_data(), authorization_value));
23337fb0f8c79ba0780b9a9b68082fd67dcc3ccb55dUtkarsh Sanghi}
23437fb0f8c79ba0780b9a9b68082fd67dcc3ccb55dUtkarsh Sanghi
235a94133441da308b30c6fe18cc4e2b866498ee401Darren Krahnvoid TpmManagerService::LockSpace(const LockSpaceRequest& request,
236a94133441da308b30c6fe18cc4e2b866498ee401Darren Krahn                                  const LockSpaceCallback& callback) {
237a94133441da308b30c6fe18cc4e2b866498ee401Darren Krahn  PostTaskToWorkerThread<LockSpaceReply>(request, callback,
238a94133441da308b30c6fe18cc4e2b866498ee401Darren Krahn                                         &TpmManagerService::LockSpaceTask);
23937fb0f8c79ba0780b9a9b68082fd67dcc3ccb55dUtkarsh Sanghi}
24037fb0f8c79ba0780b9a9b68082fd67dcc3ccb55dUtkarsh Sanghi
241a94133441da308b30c6fe18cc4e2b866498ee401Darren Krahnvoid TpmManagerService::LockSpaceTask(
242a94133441da308b30c6fe18cc4e2b866498ee401Darren Krahn    const LockSpaceRequest& request,
243a94133441da308b30c6fe18cc4e2b866498ee401Darren Krahn    const std::shared_ptr<LockSpaceReply>& reply) {
24437fb0f8c79ba0780b9a9b68082fd67dcc3ccb55dUtkarsh Sanghi  VLOG(1) << __func__;
245a94133441da308b30c6fe18cc4e2b866498ee401Darren Krahn  std::string authorization_value = request.authorization_value();
246a94133441da308b30c6fe18cc4e2b866498ee401Darren Krahn  if (request.use_owner_authorization()) {
247a94133441da308b30c6fe18cc4e2b866498ee401Darren Krahn    authorization_value = GetOwnerPassword();
248a94133441da308b30c6fe18cc4e2b866498ee401Darren Krahn    if (authorization_value.empty()) {
249a94133441da308b30c6fe18cc4e2b866498ee401Darren Krahn      reply->set_result(NVRAM_RESULT_ACCESS_DENIED);
250a94133441da308b30c6fe18cc4e2b866498ee401Darren Krahn      return;
251a94133441da308b30c6fe18cc4e2b866498ee401Darren Krahn    }
25237fb0f8c79ba0780b9a9b68082fd67dcc3ccb55dUtkarsh Sanghi  }
253a94133441da308b30c6fe18cc4e2b866498ee401Darren Krahn  reply->set_result(tpm_nvram_->LockSpace(request.index(), request.lock_read(),
254a94133441da308b30c6fe18cc4e2b866498ee401Darren Krahn                                          request.lock_write(),
255a94133441da308b30c6fe18cc4e2b866498ee401Darren Krahn                                          authorization_value));
25637fb0f8c79ba0780b9a9b68082fd67dcc3ccb55dUtkarsh Sanghi}
25737fb0f8c79ba0780b9a9b68082fd67dcc3ccb55dUtkarsh Sanghi
258a94133441da308b30c6fe18cc4e2b866498ee401Darren Krahnvoid TpmManagerService::ListSpaces(const ListSpacesRequest& request,
259a94133441da308b30c6fe18cc4e2b866498ee401Darren Krahn                                   const ListSpacesCallback& callback) {
260a94133441da308b30c6fe18cc4e2b866498ee401Darren Krahn  PostTaskToWorkerThread<ListSpacesReply>(request, callback,
261a94133441da308b30c6fe18cc4e2b866498ee401Darren Krahn                                          &TpmManagerService::ListSpacesTask);
26237fb0f8c79ba0780b9a9b68082fd67dcc3ccb55dUtkarsh Sanghi}
26337fb0f8c79ba0780b9a9b68082fd67dcc3ccb55dUtkarsh Sanghi
264a94133441da308b30c6fe18cc4e2b866498ee401Darren Krahnvoid TpmManagerService::ListSpacesTask(
265a94133441da308b30c6fe18cc4e2b866498ee401Darren Krahn    const ListSpacesRequest& request,
266a94133441da308b30c6fe18cc4e2b866498ee401Darren Krahn    const std::shared_ptr<ListSpacesReply>& reply) {
26737fb0f8c79ba0780b9a9b68082fd67dcc3ccb55dUtkarsh Sanghi  VLOG(1) << __func__;
268a94133441da308b30c6fe18cc4e2b866498ee401Darren Krahn  std::vector<uint32_t> index_list;
269a94133441da308b30c6fe18cc4e2b866498ee401Darren Krahn  reply->set_result(tpm_nvram_->ListSpaces(&index_list));
270a94133441da308b30c6fe18cc4e2b866498ee401Darren Krahn  if (reply->result() == NVRAM_RESULT_SUCCESS) {
271a94133441da308b30c6fe18cc4e2b866498ee401Darren Krahn    for (auto index : index_list) {
272a94133441da308b30c6fe18cc4e2b866498ee401Darren Krahn      reply->add_index_list(index);
273a94133441da308b30c6fe18cc4e2b866498ee401Darren Krahn    }
27437fb0f8c79ba0780b9a9b68082fd67dcc3ccb55dUtkarsh Sanghi  }
27537fb0f8c79ba0780b9a9b68082fd67dcc3ccb55dUtkarsh Sanghi}
27637fb0f8c79ba0780b9a9b68082fd67dcc3ccb55dUtkarsh Sanghi
277a94133441da308b30c6fe18cc4e2b866498ee401Darren Krahnvoid TpmManagerService::GetSpaceInfo(const GetSpaceInfoRequest& request,
278a94133441da308b30c6fe18cc4e2b866498ee401Darren Krahn                                     const GetSpaceInfoCallback& callback) {
279a94133441da308b30c6fe18cc4e2b866498ee401Darren Krahn  PostTaskToWorkerThread<GetSpaceInfoReply>(
280a94133441da308b30c6fe18cc4e2b866498ee401Darren Krahn      request, callback, &TpmManagerService::GetSpaceInfoTask);
28137fb0f8c79ba0780b9a9b68082fd67dcc3ccb55dUtkarsh Sanghi}
28237fb0f8c79ba0780b9a9b68082fd67dcc3ccb55dUtkarsh Sanghi
283a94133441da308b30c6fe18cc4e2b866498ee401Darren Krahnvoid TpmManagerService::GetSpaceInfoTask(
284a94133441da308b30c6fe18cc4e2b866498ee401Darren Krahn    const GetSpaceInfoRequest& request,
285a94133441da308b30c6fe18cc4e2b866498ee401Darren Krahn    const std::shared_ptr<GetSpaceInfoReply>& reply) {
28637fb0f8c79ba0780b9a9b68082fd67dcc3ccb55dUtkarsh Sanghi  VLOG(1) << __func__;
287a94133441da308b30c6fe18cc4e2b866498ee401Darren Krahn  std::vector<NvramSpaceAttribute> attributes;
288a94133441da308b30c6fe18cc4e2b866498ee401Darren Krahn  size_t size = 0;
289a94133441da308b30c6fe18cc4e2b866498ee401Darren Krahn  bool is_read_locked = false;
290a94133441da308b30c6fe18cc4e2b866498ee401Darren Krahn  bool is_write_locked = false;
291a94133441da308b30c6fe18cc4e2b866498ee401Darren Krahn  NvramSpacePolicy policy = NVRAM_POLICY_NONE;
292a94133441da308b30c6fe18cc4e2b866498ee401Darren Krahn  reply->set_result(tpm_nvram_->GetSpaceInfo(request.index(), &size,
293a94133441da308b30c6fe18cc4e2b866498ee401Darren Krahn                                             &is_read_locked, &is_write_locked,
294a94133441da308b30c6fe18cc4e2b866498ee401Darren Krahn                                             &attributes, &policy));
295a94133441da308b30c6fe18cc4e2b866498ee401Darren Krahn  if (reply->result() == NVRAM_RESULT_SUCCESS) {
296a94133441da308b30c6fe18cc4e2b866498ee401Darren Krahn    reply->set_size(size);
297a94133441da308b30c6fe18cc4e2b866498ee401Darren Krahn    reply->set_is_read_locked(is_read_locked);
298a94133441da308b30c6fe18cc4e2b866498ee401Darren Krahn    reply->set_is_write_locked(is_write_locked);
299a94133441da308b30c6fe18cc4e2b866498ee401Darren Krahn    for (auto attribute : attributes) {
300a94133441da308b30c6fe18cc4e2b866498ee401Darren Krahn      reply->add_attributes(attribute);
301a94133441da308b30c6fe18cc4e2b866498ee401Darren Krahn    }
302a94133441da308b30c6fe18cc4e2b866498ee401Darren Krahn    reply->set_policy(policy);
303a94133441da308b30c6fe18cc4e2b866498ee401Darren Krahn  }
304a94133441da308b30c6fe18cc4e2b866498ee401Darren Krahn}
305a94133441da308b30c6fe18cc4e2b866498ee401Darren Krahn
306a94133441da308b30c6fe18cc4e2b866498ee401Darren Krahnstd::string TpmManagerService::GetOwnerPassword() {
307a94133441da308b30c6fe18cc4e2b866498ee401Darren Krahn  LocalData local_data;
308a94133441da308b30c6fe18cc4e2b866498ee401Darren Krahn  if (local_data_store_ && local_data_store_->Read(&local_data)) {
309a94133441da308b30c6fe18cc4e2b866498ee401Darren Krahn    return local_data.owner_password();
31037fb0f8c79ba0780b9a9b68082fd67dcc3ccb55dUtkarsh Sanghi  }
311a94133441da308b30c6fe18cc4e2b866498ee401Darren Krahn  LOG(ERROR) << "TPM owner password requested but not available.";
312a94133441da308b30c6fe18cc4e2b866498ee401Darren Krahn  return std::string();
31337fb0f8c79ba0780b9a9b68082fd67dcc3ccb55dUtkarsh Sanghi}
31437fb0f8c79ba0780b9a9b68082fd67dcc3ccb55dUtkarsh Sanghi
3154dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahntemplate <typename ReplyProtobufType>
31637fb0f8c79ba0780b9a9b68082fd67dcc3ccb55dUtkarsh Sanghivoid TpmManagerService::TaskRelayCallback(
31737fb0f8c79ba0780b9a9b68082fd67dcc3ccb55dUtkarsh Sanghi    const base::Callback<void(const ReplyProtobufType&)> callback,
31837fb0f8c79ba0780b9a9b68082fd67dcc3ccb55dUtkarsh Sanghi    const std::shared_ptr<ReplyProtobufType>& reply) {
31937fb0f8c79ba0780b9a9b68082fd67dcc3ccb55dUtkarsh Sanghi  callback.Run(*reply);
32037fb0f8c79ba0780b9a9b68082fd67dcc3ccb55dUtkarsh Sanghi}
32137fb0f8c79ba0780b9a9b68082fd67dcc3ccb55dUtkarsh Sanghi
3224dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahntemplate <typename ReplyProtobufType,
3234dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn          typename RequestProtobufType,
3244dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn          typename ReplyCallbackType,
3254dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn          typename TaskType>
32637fb0f8c79ba0780b9a9b68082fd67dcc3ccb55dUtkarsh Sanghivoid TpmManagerService::PostTaskToWorkerThread(RequestProtobufType& request,
32737fb0f8c79ba0780b9a9b68082fd67dcc3ccb55dUtkarsh Sanghi                                               ReplyCallbackType& callback,
32837fb0f8c79ba0780b9a9b68082fd67dcc3ccb55dUtkarsh Sanghi                                               TaskType task) {
32937fb0f8c79ba0780b9a9b68082fd67dcc3ccb55dUtkarsh Sanghi  auto result = std::make_shared<ReplyProtobufType>();
3304dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn  base::Closure background_task =
3314dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn      base::Bind(task, base::Unretained(this), request, result);
3324dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn  base::Closure reply =
3334dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn      base::Bind(&TpmManagerService::TaskRelayCallback<ReplyProtobufType>,
3344dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn                 weak_factory_.GetWeakPtr(), callback, result);
3354dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn  worker_thread_->task_runner()->PostTaskAndReply(FROM_HERE, background_task,
33637fb0f8c79ba0780b9a9b68082fd67dcc3ccb55dUtkarsh Sanghi                                                  reply);
33737fb0f8c79ba0780b9a9b68082fd67dcc3ccb55dUtkarsh Sanghi}
33837fb0f8c79ba0780b9a9b68082fd67dcc3ccb55dUtkarsh Sanghi
3392863c75955f0e50df2ad29587a29b4d5b06779bUtkarsh Sanghi}  // namespace tpm_manager
340