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
27namespace {
28
29// Sends a |response_proto| to |client| for an arbitrary protobuf type.
30template <typename ResponseProtobufType>
31void 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.
48template <typename ResponseProtobufType>
49void CreateNvramErrorResponse(ResponseProtobufType* proto) {
50  proto->set_result(tpm_manager::NVRAM_RESULT_IPC_ERROR);
51}
52
53// Creates an error protobuf for ownership commands.
54template <typename ResponseProtobufType>
55void 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|.
62template <typename RequestProtobufType, typename ResponseProtobufType>
63void 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
87namespace tpm_manager {
88
89BinderService::BinderService(TpmNvramInterface* nvram_service,
90                             TpmOwnershipInterface* ownership_service)
91    : nvram_service_(nvram_service), ownership_service_(ownership_service) {}
92
93void BinderService::InitForTesting() {
94  nvram_binder_ = new NvramServiceInternal(nvram_service_);
95  ownership_binder_ = new OwnershipServiceInternal(ownership_service_);
96}
97
98int 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
120android::tpm_manager::ITpmNvram* BinderService::GetITpmNvram() {
121  return nvram_binder_.get();
122}
123
124android::tpm_manager::ITpmOwnership* BinderService::GetITpmOwnership() {
125  return ownership_binder_.get();
126}
127
128BinderService::NvramServiceInternal::NvramServiceInternal(
129    TpmNvramInterface* nvram_service)
130    : nvram_service_(nvram_service) {}
131
132android::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
142android::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
152android::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
162android::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
172android::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
182android::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
192android::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
202BinderService::OwnershipServiceInternal::OwnershipServiceInternal(
203    TpmOwnershipInterface* ownership_service)
204    : ownership_service_(ownership_service) {}
205
206android::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
216android::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
226android::binder::Status
227BinderService::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