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 #ifndef TPM_MANAGER_SERVER_TPM_MANAGER_SERVICE_H_
18 #define TPM_MANAGER_SERVER_TPM_MANAGER_SERVICE_H_
19 
20 #include <memory>
21 
22 #include <base/callback.h>
23 #include <base/macros.h>
24 #include <base/memory/weak_ptr.h>
25 #include <base/threading/thread.h>
26 #include <brillo/bind_lambda.h>
27 
28 #include "tpm_manager/common/tpm_nvram_interface.h"
29 #include "tpm_manager/common/tpm_ownership_interface.h"
30 #include "tpm_manager/server/local_data_store.h"
31 #include "tpm_manager/server/tpm_initializer.h"
32 #include "tpm_manager/server/tpm_nvram.h"
33 #include "tpm_manager/server/tpm_status.h"
34 
35 namespace tpm_manager {
36 
37 // This class implements the core tpm_manager service. All Tpm access is
38 // asynchronous, except for the initial setup in Initialize().
39 // Usage:
40 //   std::unique_ptr<TpmManagerService> tpm_manager = new TpmManagerService();
41 //   CHECK(tpm_manager->Initialize());
42 //   tpm_manager->GetTpmStatus(...);
43 //
44 // THREADING NOTES:
45 // This class runs a worker thread and delegates all calls to it. This keeps the
46 // public methods non-blocking while allowing complex implementation details
47 // with dependencies on the TPM, network, and filesystem to be coded in a more
48 // readable way. It also serves to serialize method execution which reduces
49 // complexity with TPM state.
50 //
51 // Tasks that run on the worker thread are bound with base::Unretained which is
52 // safe because the thread is owned by this class (so it is guaranteed not to
53 // process a task after destruction). Weak pointers are used to post replies
54 // back to the main thread.
55 class TpmManagerService : public TpmNvramInterface,
56                           public TpmOwnershipInterface {
57  public:
58   // If |wait_for_ownership| is set, TPM initialization will be postponed until
59   // an explicit TakeOwnership request is received. Does not take ownership of
60   // |local_data_store|, |tpm_status| or |tpm_initializer|.
61   explicit TpmManagerService(bool wait_for_ownership,
62                              LocalDataStore* local_data_store,
63                              TpmStatus* tpm_status,
64                              TpmInitializer* tpm_initializer,
65                              TpmNvram* tpm_nvram);
66   ~TpmManagerService() override = default;
67 
68   // Performs initialization tasks. This method must be called before calling
69   // any other method in this class. Returns true on success.
70   bool Initialize();
71 
72   // TpmOwnershipInterface methods.
73   void GetTpmStatus(const GetTpmStatusRequest& request,
74                     const GetTpmStatusCallback& callback) override;
75   void TakeOwnership(const TakeOwnershipRequest& request,
76                      const TakeOwnershipCallback& callback) override;
77   void RemoveOwnerDependency(
78       const RemoveOwnerDependencyRequest& request,
79       const RemoveOwnerDependencyCallback& callback) override;
80 
81   // TpmNvramInterface methods.
82   void DefineNvram(const DefineNvramRequest& request,
83                    const DefineNvramCallback& callback) override;
84   void DestroyNvram(const DestroyNvramRequest& request,
85                     const DestroyNvramCallback& callback) override;
86   void WriteNvram(const WriteNvramRequest& request,
87                   const WriteNvramCallback& callback) override;
88   void ReadNvram(const ReadNvramRequest& request,
89                  const ReadNvramCallback& callback) override;
90   void IsNvramDefined(const IsNvramDefinedRequest& request,
91                       const IsNvramDefinedCallback& callback) override;
92   void IsNvramLocked(const IsNvramLockedRequest& request,
93                      const IsNvramLockedCallback& callback) override;
94   void GetNvramSize(const GetNvramSizeRequest& request,
95                     const GetNvramSizeCallback& callback) override;
96 
97  private:
98   // A relay callback which allows the use of weak pointer semantics for a reply
99   // to TaskRunner::PostTaskAndReply.
100   template<typename ReplyProtobufType>
101   void TaskRelayCallback(
102       const base::Callback<void(const ReplyProtobufType&)> callback,
103       const std::shared_ptr<ReplyProtobufType>& reply);
104 
105   // This templated method posts the provided |TaskType| to the background
106   // thread with the provided |RequestProtobufType|. When |TaskType| finishes
107   // executing, the |ReplyCallbackType| is called with the |ReplyProtobufType|.
108   template<typename ReplyProtobufType,
109            typename RequestProtobufType,
110            typename ReplyCallbackType,
111            typename TaskType>
112   void PostTaskToWorkerThread(RequestProtobufType& request,
113                               ReplyCallbackType& callback,
114                               TaskType task);
115 
116   // Synchronously initializes the TPM according to the current configuration.
117   // If an initialization process was interrupted it will be continued. If the
118   // TPM is already initialized or cannot yet be initialized, this method has no
119   // effect.
120   void InitializeTask();
121 
122   // Blocking implementation of GetTpmStatus that can be executed on the
123   // background worker thread.
124   void GetTpmStatusTask(const GetTpmStatusRequest& request,
125                         const std::shared_ptr<GetTpmStatusReply>& result);
126 
127   // Blocking implementation of TakeOwnership that can be executed on the
128   // background worker thread.
129   void TakeOwnershipTask(const TakeOwnershipRequest& request,
130                          const std::shared_ptr<TakeOwnershipReply>& result);
131 
132   // Blocking implementation of RemoveOwnerDependency that can be executed on
133   // the background worker thread.
134   void RemoveOwnerDependencyTask(
135       const RemoveOwnerDependencyRequest& request,
136       const std::shared_ptr<RemoveOwnerDependencyReply>& result);
137 
138   // Removes a |owner_dependency| from the list of owner dependencies in
139   // |local_data|. If |owner_dependency| is not present in |local_data|,
140   // this method does nothing.
141   static void RemoveOwnerDependency(const std::string& owner_dependency,
142                                     LocalData* local_data);
143 
144   // Blocking implementation of DefineNvram that can be executed on the
145   // background worker thread.
146   void DefineNvramTask(const DefineNvramRequest& request,
147                        const std::shared_ptr<DefineNvramReply>& result);
148 
149   // Blocking implementation of DestroyNvram that can be executed on the
150   // background worker thread.
151   void DestroyNvramTask(const DestroyNvramRequest& request,
152                         const std::shared_ptr<DestroyNvramReply>& result);
153 
154   // Blocking implementation of WriteNvram that can be executed on the
155   // background worker thread.
156   void WriteNvramTask(const WriteNvramRequest& request,
157                       const std::shared_ptr<WriteNvramReply>& result);
158 
159   // Blocking implementation of ReadNvram that can be executed on the
160   // background worker thread.
161   void ReadNvramTask(const ReadNvramRequest& request,
162                      const std::shared_ptr<ReadNvramReply>& result);
163 
164   // Blocking implementation of IsNvramDefined that can be executed on the
165   // background worker thread.
166   void IsNvramDefinedTask(const IsNvramDefinedRequest& request,
167                           const std::shared_ptr<IsNvramDefinedReply>& result);
168 
169   // Blocking implementation of IsNvramLocked that can be executed on the
170   // background worker thread.
171   void IsNvramLockedTask(const IsNvramLockedRequest& request,
172                          const std::shared_ptr<IsNvramLockedReply>& result);
173 
174   // Blocking implementation of GetNvramSize that can be executed on the
175   // background worker thread.
176   void GetNvramSizeTask(const GetNvramSizeRequest& request,
177                         const std::shared_ptr<GetNvramSizeReply>& result);
178 
179   LocalDataStore* local_data_store_;
180   TpmStatus* tpm_status_;
181   TpmInitializer* tpm_initializer_;
182   TpmNvram* tpm_nvram_;
183   // Whether to wait for an explicit call to 'TakeOwnership' before initializing
184   // the TPM. Normally tracks the --wait_for_ownership command line option.
185   bool wait_for_ownership_;
186   // Background thread to allow processing of potentially lengthy TPM requests
187   // in the background.
188   std::unique_ptr<base::Thread> worker_thread_;
189   // Declared last so any weak pointers are destroyed first.
190   base::WeakPtrFactory<TpmManagerService> weak_factory_;
191 
192   DISALLOW_COPY_AND_ASSIGN(TpmManagerService);
193 };
194 
195 }  // namespace tpm_manager
196 
197 #endif  // TPM_MANAGER_SERVER_TPM_MANAGER_SERVICE_H_
198