1 //
2 // Copyright (C) 2016 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/binder_service.h"
18 
19 #include <sysexits.h>
20 
21 #include <base/bind.h>
22 #include <binderwrapper/binder_wrapper.h>
23 
24 #include "tpm_manager/common/tpm_manager.pb.h"
25 #include "tpm_manager/common/tpm_manager_constants.h"
26 
27 namespace {
28 
29 // Sends a |response_proto| to |client| for an arbitrary protobuf type.
30 template <typename ResponseProtobufType>
ResponseHandler(const android::sp<android::tpm_manager::ITpmManagerClient> & client,const ResponseProtobufType & response_proto)31 void ResponseHandler(
32     const android::sp<android::tpm_manager::ITpmManagerClient>& client,
33     const ResponseProtobufType& response_proto) {
34   VLOG(2) << __func__;
35   std::vector<uint8_t> binder_response;
36   binder_response.resize(response_proto.ByteSize());
37   CHECK(response_proto.SerializeToArray(binder_response.data(),
38                                         binder_response.size()))
39       << "BinderService: Failed to serialize protobuf.";
40   android::binder::Status status = client->OnCommandResponse(binder_response);
41   if (!status.isOk()) {
42     LOG(ERROR) << "BinderService: Failed to send response to client: "
43                << status.toString8();
44   }
45 }
46 
47 // Creates an error protobuf for NVRAM commands.
48 template <typename ResponseProtobufType>
CreateNvramErrorResponse(ResponseProtobufType * proto)49 void CreateNvramErrorResponse(ResponseProtobufType* proto) {
50   proto->set_result(tpm_manager::NVRAM_RESULT_IPC_ERROR);
51 }
52 
53 // Creates an error protobuf for ownership commands.
54 template <typename ResponseProtobufType>
CreateOwnershipErrorResponse(ResponseProtobufType * proto)55 void CreateOwnershipErrorResponse(ResponseProtobufType* proto) {
56   proto->set_status(tpm_manager::STATUS_DEVICE_ERROR);
57 }
58 
59 // Calls |method| with a protobuf decoded from |request| using ResponseHandler()
60 // and |client| to handle the response. On error, uses |get_error_response| to
61 // construct a response and sends that to |client|.
62 template <typename RequestProtobufType, typename ResponseProtobufType>
RequestHandler(const std::vector<uint8_t> & request,const base::Callback<void (const RequestProtobufType &,const base::Callback<void (const ResponseProtobufType &)> &)> & method,const base::Callback<void (ResponseProtobufType *)> & get_error_response,const android::sp<android::tpm_manager::ITpmManagerClient> & client)63 void RequestHandler(
64     const std::vector<uint8_t>& request,
65     const base::Callback<
66         void(const RequestProtobufType&,
67              const base::Callback<void(const ResponseProtobufType&)>&)>& method,
68     const base::Callback<void(ResponseProtobufType*)>& get_error_response,
69     const android::sp<android::tpm_manager::ITpmManagerClient>& client) {
70   VLOG(2) << __func__;
71   base::Callback<void(const ResponseProtobufType&)> callback =
72       base::Bind(ResponseHandler<ResponseProtobufType>, client);
73   RequestProtobufType request_proto;
74   if (!request_proto.ParseFromArray(request.data(), request.size())) {
75     LOG(ERROR) << "BinderService: Bad request data.";
76     // Send an error response.
77     ResponseProtobufType response_proto;
78     get_error_response.Run(&response_proto);
79     callback.Run(response_proto);
80     return;
81   }
82   method.Run(request_proto, callback);
83 }
84 
85 }  // namespace
86 
87 namespace tpm_manager {
88 
BinderService(TpmNvramInterface * nvram_service,TpmOwnershipInterface * ownership_service)89 BinderService::BinderService(TpmNvramInterface* nvram_service,
90                              TpmOwnershipInterface* ownership_service)
91     : nvram_service_(nvram_service), ownership_service_(ownership_service) {}
92 
InitForTesting()93 void BinderService::InitForTesting() {
94   nvram_binder_ = new NvramServiceInternal(nvram_service_);
95   ownership_binder_ = new OwnershipServiceInternal(ownership_service_);
96 }
97 
OnInit()98 int BinderService::OnInit() {
99   if (!watcher_.Init()) {
100     LOG(ERROR) << "BinderService: BinderWatcher::Init failed.";
101     return EX_UNAVAILABLE;
102   }
103   nvram_binder_ = new NvramServiceInternal(nvram_service_);
104   ownership_binder_ = new OwnershipServiceInternal(ownership_service_);
105   if (!android::BinderWrapper::GetOrCreateInstance()->RegisterService(
106           kTpmNvramBinderName, android::IInterface::asBinder(nvram_binder_))) {
107     LOG(ERROR) << "BinderService: RegisterService failed (nvram).";
108     return EX_UNAVAILABLE;
109   }
110   if (!android::BinderWrapper::GetOrCreateInstance()->RegisterService(
111           kTpmOwnershipBinderName,
112           android::IInterface::asBinder(ownership_binder_))) {
113     LOG(ERROR) << "BinderService: RegisterService failed (ownership).";
114     return EX_UNAVAILABLE;
115   }
116   LOG(INFO) << "TpmManager: Binder services registered.";
117   return brillo::Daemon::OnInit();
118 }
119 
GetITpmNvram()120 android::tpm_manager::ITpmNvram* BinderService::GetITpmNvram() {
121   return nvram_binder_.get();
122 }
123 
GetITpmOwnership()124 android::tpm_manager::ITpmOwnership* BinderService::GetITpmOwnership() {
125   return ownership_binder_.get();
126 }
127 
NvramServiceInternal(TpmNvramInterface * nvram_service)128 BinderService::NvramServiceInternal::NvramServiceInternal(
129     TpmNvramInterface* nvram_service)
130     : nvram_service_(nvram_service) {}
131 
DefineSpace(const std::vector<uint8_t> & command_proto,const android::sp<android::tpm_manager::ITpmManagerClient> & client)132 android::binder::Status BinderService::NvramServiceInternal::DefineSpace(
133     const std::vector<uint8_t>& command_proto,
134     const android::sp<android::tpm_manager::ITpmManagerClient>& client) {
135   RequestHandler<DefineSpaceRequest, DefineSpaceReply>(
136       command_proto, base::Bind(&TpmNvramInterface::DefineSpace,
137                                 base::Unretained(nvram_service_)),
138       base::Bind(CreateNvramErrorResponse<DefineSpaceReply>), client);
139   return android::binder::Status::ok();
140 }
141 
DestroySpace(const std::vector<uint8_t> & command_proto,const android::sp<android::tpm_manager::ITpmManagerClient> & client)142 android::binder::Status BinderService::NvramServiceInternal::DestroySpace(
143     const std::vector<uint8_t>& command_proto,
144     const android::sp<android::tpm_manager::ITpmManagerClient>& client) {
145   RequestHandler<DestroySpaceRequest, DestroySpaceReply>(
146       command_proto, base::Bind(&TpmNvramInterface::DestroySpace,
147                                 base::Unretained(nvram_service_)),
148       base::Bind(CreateNvramErrorResponse<DestroySpaceReply>), client);
149   return android::binder::Status::ok();
150 }
151 
WriteSpace(const std::vector<uint8_t> & command_proto,const android::sp<android::tpm_manager::ITpmManagerClient> & client)152 android::binder::Status BinderService::NvramServiceInternal::WriteSpace(
153     const std::vector<uint8_t>& command_proto,
154     const android::sp<android::tpm_manager::ITpmManagerClient>& client) {
155   RequestHandler<WriteSpaceRequest, WriteSpaceReply>(
156       command_proto, base::Bind(&TpmNvramInterface::WriteSpace,
157                                 base::Unretained(nvram_service_)),
158       base::Bind(CreateNvramErrorResponse<WriteSpaceReply>), client);
159   return android::binder::Status::ok();
160 }
161 
ReadSpace(const std::vector<uint8_t> & command_proto,const android::sp<android::tpm_manager::ITpmManagerClient> & client)162 android::binder::Status BinderService::NvramServiceInternal::ReadSpace(
163     const std::vector<uint8_t>& command_proto,
164     const android::sp<android::tpm_manager::ITpmManagerClient>& client) {
165   RequestHandler<ReadSpaceRequest, ReadSpaceReply>(
166       command_proto, base::Bind(&TpmNvramInterface::ReadSpace,
167                                 base::Unretained(nvram_service_)),
168       base::Bind(CreateNvramErrorResponse<ReadSpaceReply>), client);
169   return android::binder::Status::ok();
170 }
171 
LockSpace(const std::vector<uint8_t> & command_proto,const android::sp<android::tpm_manager::ITpmManagerClient> & client)172 android::binder::Status BinderService::NvramServiceInternal::LockSpace(
173     const std::vector<uint8_t>& command_proto,
174     const android::sp<android::tpm_manager::ITpmManagerClient>& client) {
175   RequestHandler<LockSpaceRequest, LockSpaceReply>(
176       command_proto, base::Bind(&TpmNvramInterface::LockSpace,
177                                 base::Unretained(nvram_service_)),
178       base::Bind(CreateNvramErrorResponse<LockSpaceReply>), client);
179   return android::binder::Status::ok();
180 }
181 
ListSpaces(const std::vector<uint8_t> & command_proto,const android::sp<android::tpm_manager::ITpmManagerClient> & client)182 android::binder::Status BinderService::NvramServiceInternal::ListSpaces(
183     const std::vector<uint8_t>& command_proto,
184     const android::sp<android::tpm_manager::ITpmManagerClient>& client) {
185   RequestHandler<ListSpacesRequest, ListSpacesReply>(
186       command_proto, base::Bind(&TpmNvramInterface::ListSpaces,
187                                 base::Unretained(nvram_service_)),
188       base::Bind(CreateNvramErrorResponse<ListSpacesReply>), client);
189   return android::binder::Status::ok();
190 }
191 
GetSpaceInfo(const std::vector<uint8_t> & command_proto,const android::sp<android::tpm_manager::ITpmManagerClient> & client)192 android::binder::Status BinderService::NvramServiceInternal::GetSpaceInfo(
193     const std::vector<uint8_t>& command_proto,
194     const android::sp<android::tpm_manager::ITpmManagerClient>& client) {
195   RequestHandler<GetSpaceInfoRequest, GetSpaceInfoReply>(
196       command_proto, base::Bind(&TpmNvramInterface::GetSpaceInfo,
197                                 base::Unretained(nvram_service_)),
198       base::Bind(CreateNvramErrorResponse<GetSpaceInfoReply>), client);
199   return android::binder::Status::ok();
200 }
201 
OwnershipServiceInternal(TpmOwnershipInterface * ownership_service)202 BinderService::OwnershipServiceInternal::OwnershipServiceInternal(
203     TpmOwnershipInterface* ownership_service)
204     : ownership_service_(ownership_service) {}
205 
GetTpmStatus(const std::vector<uint8_t> & command_proto,const android::sp<android::tpm_manager::ITpmManagerClient> & client)206 android::binder::Status BinderService::OwnershipServiceInternal::GetTpmStatus(
207     const std::vector<uint8_t>& command_proto,
208     const android::sp<android::tpm_manager::ITpmManagerClient>& client) {
209   RequestHandler<GetTpmStatusRequest, GetTpmStatusReply>(
210       command_proto, base::Bind(&TpmOwnershipInterface::GetTpmStatus,
211                                 base::Unretained(ownership_service_)),
212       base::Bind(CreateOwnershipErrorResponse<GetTpmStatusReply>), client);
213   return android::binder::Status::ok();
214 }
215 
TakeOwnership(const std::vector<uint8_t> & command_proto,const android::sp<android::tpm_manager::ITpmManagerClient> & client)216 android::binder::Status BinderService::OwnershipServiceInternal::TakeOwnership(
217     const std::vector<uint8_t>& command_proto,
218     const android::sp<android::tpm_manager::ITpmManagerClient>& client) {
219   RequestHandler<TakeOwnershipRequest, TakeOwnershipReply>(
220       command_proto, base::Bind(&TpmOwnershipInterface::TakeOwnership,
221                                 base::Unretained(ownership_service_)),
222       base::Bind(CreateOwnershipErrorResponse<TakeOwnershipReply>), client);
223   return android::binder::Status::ok();
224 }
225 
226 android::binder::Status
RemoveOwnerDependency(const std::vector<uint8_t> & command_proto,const android::sp<android::tpm_manager::ITpmManagerClient> & client)227 BinderService::OwnershipServiceInternal::RemoveOwnerDependency(
228     const std::vector<uint8_t>& command_proto,
229     const android::sp<android::tpm_manager::ITpmManagerClient>& client) {
230   RequestHandler<RemoveOwnerDependencyRequest, RemoveOwnerDependencyReply>(
231       command_proto, base::Bind(&TpmOwnershipInterface::RemoveOwnerDependency,
232                                 base::Unretained(ownership_service_)),
233       base::Bind(CreateOwnershipErrorResponse<RemoveOwnerDependencyReply>),
234       client);
235   return android::binder::Status::ok();
236 }
237 
238 }  // namespace tpm_manager
239