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 #define LOG_TAG "TrustyGateKeeper"
18 
19 #include <android-base/logging.h>
20 #include <limits>
21 
22 #include "trusty_gatekeeper.h"
23 #include "trusty_gatekeeper_ipc.h"
24 #include "gatekeeper_ipc.h"
25 
26 using ::android::hardware::hidl_vec;
27 using ::android::hardware::Return;
28 using ::android::hardware::gatekeeper::V1_0::GatekeeperStatusCode;
29 using ::gatekeeper::EnrollRequest;
30 using ::gatekeeper::EnrollResponse;
31 using ::gatekeeper::ERROR_INVALID;
32 using ::gatekeeper::ERROR_MEMORY_ALLOCATION_FAILED;
33 using ::gatekeeper::ERROR_NONE;
34 using ::gatekeeper::ERROR_RETRY;
35 using ::gatekeeper::SizedBuffer;
36 using ::gatekeeper::VerifyRequest;
37 using ::gatekeeper::VerifyResponse;
38 
39 namespace gatekeeper {
40 
41 constexpr const uint32_t SEND_BUF_SIZE = 8192;
42 constexpr const uint32_t RECV_BUF_SIZE = 8192;
43 
TrustyGateKeeperDevice()44 TrustyGateKeeperDevice::TrustyGateKeeperDevice() {
45     int rc = trusty_gatekeeper_connect();
46     if (rc < 0) {
47         LOG(ERROR) << "Error initializing trusty session: " << rc;
48     }
49 
50     error_ = rc;
51 }
52 
~TrustyGateKeeperDevice()53 TrustyGateKeeperDevice::~TrustyGateKeeperDevice() {
54     trusty_gatekeeper_disconnect();
55 }
56 
hidl_vec2sized_buffer(const hidl_vec<uint8_t> & vec)57 SizedBuffer hidl_vec2sized_buffer(const hidl_vec<uint8_t>& vec) {
58     if (vec.size() == 0 || vec.size() > std::numeric_limits<uint32_t>::max()) return {};
59     auto buffer = new uint8_t[vec.size()];
60     std::copy(vec.begin(), vec.end(), buffer);
61     return {buffer, static_cast<uint32_t>(vec.size())};
62 }
63 
enroll(uint32_t uid,const hidl_vec<uint8_t> & currentPasswordHandle,const hidl_vec<uint8_t> & currentPassword,const hidl_vec<uint8_t> & desiredPassword,enroll_cb _hidl_cb)64 Return<void> TrustyGateKeeperDevice::enroll(uint32_t uid,
65                                             const hidl_vec<uint8_t>& currentPasswordHandle,
66                                             const hidl_vec<uint8_t>& currentPassword,
67                                             const hidl_vec<uint8_t>& desiredPassword,
68                                             enroll_cb _hidl_cb) {
69     if (error_ != 0) {
70         _hidl_cb({GatekeeperStatusCode::ERROR_GENERAL_FAILURE, 0, {}});
71         return {};
72     }
73 
74     if (desiredPassword.size() == 0) {
75         _hidl_cb({GatekeeperStatusCode::ERROR_GENERAL_FAILURE, 0, {}});
76         return {};
77     }
78 
79     EnrollRequest request(uid, hidl_vec2sized_buffer(currentPasswordHandle),
80                           hidl_vec2sized_buffer(desiredPassword),
81                           hidl_vec2sized_buffer(currentPassword));
82     EnrollResponse response;
83     auto error = Send(request, &response);
84     if (error != ERROR_NONE) {
85         _hidl_cb({GatekeeperStatusCode::ERROR_GENERAL_FAILURE, 0, {}});
86     } else if (response.error == ERROR_RETRY) {
87         _hidl_cb({GatekeeperStatusCode::ERROR_RETRY_TIMEOUT, response.retry_timeout, {}});
88     } else if (response.error != ERROR_NONE) {
89         _hidl_cb({GatekeeperStatusCode::ERROR_GENERAL_FAILURE, 0, {}});
90     } else {
91         hidl_vec<uint8_t> new_handle(response.enrolled_password_handle.Data<uint8_t>(),
92                                      response.enrolled_password_handle.Data<uint8_t>() +
93                                              response.enrolled_password_handle.size());
94         _hidl_cb({GatekeeperStatusCode::STATUS_OK, response.retry_timeout, new_handle});
95     }
96     return {};
97 }
98 
verify(uint32_t uid,uint64_t challenge,const::android::hardware::hidl_vec<uint8_t> & enrolledPasswordHandle,const::android::hardware::hidl_vec<uint8_t> & providedPassword,verify_cb _hidl_cb)99 Return<void> TrustyGateKeeperDevice::verify(
100         uint32_t uid, uint64_t challenge,
101         const ::android::hardware::hidl_vec<uint8_t>& enrolledPasswordHandle,
102         const ::android::hardware::hidl_vec<uint8_t>& providedPassword, verify_cb _hidl_cb) {
103     if (error_ != 0) {
104         _hidl_cb({GatekeeperStatusCode::ERROR_GENERAL_FAILURE, 0, {}});
105         return {};
106     }
107 
108     if (enrolledPasswordHandle.size() == 0) {
109         _hidl_cb({GatekeeperStatusCode::ERROR_GENERAL_FAILURE, 0, {}});
110         return {};
111     }
112 
113     VerifyRequest request(uid, challenge, hidl_vec2sized_buffer(enrolledPasswordHandle),
114                           hidl_vec2sized_buffer(providedPassword));
115     VerifyResponse response;
116 
117     auto error = Send(request, &response);
118     if (error != ERROR_NONE) {
119         _hidl_cb({GatekeeperStatusCode::ERROR_GENERAL_FAILURE, 0, {}});
120     } else if (response.error == ERROR_RETRY) {
121         _hidl_cb({GatekeeperStatusCode::ERROR_RETRY_TIMEOUT, response.retry_timeout, {}});
122     } else if (response.error != ERROR_NONE) {
123         _hidl_cb({GatekeeperStatusCode::ERROR_GENERAL_FAILURE, 0, {}});
124     } else {
125         hidl_vec<uint8_t> auth_token(
126                 response.auth_token.Data<uint8_t>(),
127                 response.auth_token.Data<uint8_t>() + response.auth_token.size());
128 
129         _hidl_cb({response.request_reenroll ? GatekeeperStatusCode::STATUS_REENROLL
130                                             : GatekeeperStatusCode::STATUS_OK,
131                   response.retry_timeout, auth_token});
132     }
133     return {};
134 }
135 
deleteUser(uint32_t uid,deleteUser_cb _hidl_cb)136 Return<void> TrustyGateKeeperDevice::deleteUser(uint32_t uid, deleteUser_cb _hidl_cb) {
137     if (error_ != 0) {
138         _hidl_cb({GatekeeperStatusCode::ERROR_GENERAL_FAILURE, 0, {}});
139         return {};
140     }
141 
142     DeleteUserRequest request(uid);
143     DeleteUserResponse response;
144     auto error = Send(request, &response);
145 
146     if (error != ERROR_NONE) {
147         _hidl_cb({GatekeeperStatusCode::ERROR_GENERAL_FAILURE, 0, {}});
148     } else if (response.error == ERROR_NOT_IMPLEMENTED) {
149         _hidl_cb({GatekeeperStatusCode::ERROR_NOT_IMPLEMENTED, 0, {}});
150     } else if (response.error != ERROR_NONE) {
151         _hidl_cb({GatekeeperStatusCode::ERROR_GENERAL_FAILURE, 0, {}});
152     } else {
153         _hidl_cb({GatekeeperStatusCode::STATUS_OK, response.retry_timeout, {}});
154     }
155     return {};
156 }
157 
deleteAllUsers(deleteAllUsers_cb _hidl_cb)158 Return<void> TrustyGateKeeperDevice::deleteAllUsers(deleteAllUsers_cb _hidl_cb) {
159     if (error_ != 0) {
160         _hidl_cb({GatekeeperStatusCode::ERROR_GENERAL_FAILURE, 0, {}});
161         return {};
162     }
163 
164     DeleteAllUsersRequest request;
165     DeleteAllUsersResponse response;
166     auto error = Send(request, &response);
167 
168     if (error != ERROR_NONE) {
169         _hidl_cb({GatekeeperStatusCode::ERROR_GENERAL_FAILURE, 0, {}});
170     } else if (response.error == ERROR_NOT_IMPLEMENTED) {
171         _hidl_cb({GatekeeperStatusCode::ERROR_NOT_IMPLEMENTED, 0, {}});
172     } else if (response.error != ERROR_NONE) {
173         _hidl_cb({GatekeeperStatusCode::ERROR_GENERAL_FAILURE, 0, {}});
174     } else {
175         _hidl_cb({GatekeeperStatusCode::STATUS_OK, response.retry_timeout, {}});
176     }
177 
178     return {};
179 }
180 
Send(uint32_t command,const GateKeeperMessage & request,GateKeeperMessage * response)181 gatekeeper_error_t TrustyGateKeeperDevice::Send(uint32_t command, const GateKeeperMessage& request,
182         GateKeeperMessage *response) {
183     uint32_t request_size = request.GetSerializedSize();
184     if (request_size > SEND_BUF_SIZE)
185         return ERROR_INVALID;
186     uint8_t send_buf[SEND_BUF_SIZE];
187     request.Serialize(send_buf, send_buf + request_size);
188 
189     // Send it
190     uint8_t recv_buf[RECV_BUF_SIZE];
191     uint32_t response_size = RECV_BUF_SIZE;
192     int rc = trusty_gatekeeper_call(command, send_buf, request_size, recv_buf, &response_size);
193     if (rc < 0) {
194         LOG(ERROR) << "error (" << rc << ") calling gatekeeper TA";
195         return ERROR_INVALID;
196     }
197 
198     const gatekeeper_message *msg = reinterpret_cast<gatekeeper_message *>(recv_buf);
199     const uint8_t *payload = msg->payload;
200 
201     return response->Deserialize(payload, payload + response_size);
202 }
203 
204 };
205