1*4d7e907cSAndroid Build Coastguard Worker /*
2*4d7e907cSAndroid Build Coastguard Worker * Copyright (C) 2016 The Android Open Source Project
3*4d7e907cSAndroid Build Coastguard Worker *
4*4d7e907cSAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License");
5*4d7e907cSAndroid Build Coastguard Worker * you may not use this file except in compliance with the License.
6*4d7e907cSAndroid Build Coastguard Worker * You may obtain a copy of the License at
7*4d7e907cSAndroid Build Coastguard Worker *
8*4d7e907cSAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0
9*4d7e907cSAndroid Build Coastguard Worker *
10*4d7e907cSAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software
11*4d7e907cSAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS,
12*4d7e907cSAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*4d7e907cSAndroid Build Coastguard Worker * See the License for the specific language governing permissions and
14*4d7e907cSAndroid Build Coastguard Worker * limitations under the License.
15*4d7e907cSAndroid Build Coastguard Worker */
16*4d7e907cSAndroid Build Coastguard Worker #define LOG_TAG "android.hardware.gatekeeper-service.nonsecure"
17*4d7e907cSAndroid Build Coastguard Worker
18*4d7e907cSAndroid Build Coastguard Worker #include <endian.h>
19*4d7e907cSAndroid Build Coastguard Worker
20*4d7e907cSAndroid Build Coastguard Worker #include <android-base/logging.h>
21*4d7e907cSAndroid Build Coastguard Worker
22*4d7e907cSAndroid Build Coastguard Worker #include "GateKeeper.h"
23*4d7e907cSAndroid Build Coastguard Worker
24*4d7e907cSAndroid Build Coastguard Worker using ::gatekeeper::EnrollRequest;
25*4d7e907cSAndroid Build Coastguard Worker using ::gatekeeper::EnrollResponse;
26*4d7e907cSAndroid Build Coastguard Worker using ::gatekeeper::ERROR_NONE;
27*4d7e907cSAndroid Build Coastguard Worker using ::gatekeeper::ERROR_RETRY;
28*4d7e907cSAndroid Build Coastguard Worker using ::gatekeeper::SizedBuffer;
29*4d7e907cSAndroid Build Coastguard Worker using ::gatekeeper::VerifyRequest;
30*4d7e907cSAndroid Build Coastguard Worker using ::gatekeeper::VerifyResponse;
31*4d7e907cSAndroid Build Coastguard Worker
32*4d7e907cSAndroid Build Coastguard Worker namespace aidl::android::hardware::gatekeeper {
33*4d7e907cSAndroid Build Coastguard Worker
vec2sized_buffer(const std::vector<uint8_t> & vec)34*4d7e907cSAndroid Build Coastguard Worker SizedBuffer vec2sized_buffer(const std::vector<uint8_t>& vec) {
35*4d7e907cSAndroid Build Coastguard Worker if (vec.size() == 0 || vec.size() > std::numeric_limits<uint32_t>::max()) {
36*4d7e907cSAndroid Build Coastguard Worker return {};
37*4d7e907cSAndroid Build Coastguard Worker }
38*4d7e907cSAndroid Build Coastguard Worker auto unused = new uint8_t[vec.size()];
39*4d7e907cSAndroid Build Coastguard Worker std::copy(vec.begin(), vec.end(), unused);
40*4d7e907cSAndroid Build Coastguard Worker return {unused, static_cast<uint32_t>(vec.size())};
41*4d7e907cSAndroid Build Coastguard Worker }
42*4d7e907cSAndroid Build Coastguard Worker
sizedBuffer2AidlHWToken(SizedBuffer & buffer,android::hardware::security::keymint::HardwareAuthToken * aidlToken)43*4d7e907cSAndroid Build Coastguard Worker void sizedBuffer2AidlHWToken(SizedBuffer& buffer,
44*4d7e907cSAndroid Build Coastguard Worker android::hardware::security::keymint::HardwareAuthToken* aidlToken) {
45*4d7e907cSAndroid Build Coastguard Worker const hw_auth_token_t* authToken =
46*4d7e907cSAndroid Build Coastguard Worker reinterpret_cast<const hw_auth_token_t*>(buffer.Data<uint8_t>());
47*4d7e907cSAndroid Build Coastguard Worker aidlToken->challenge = authToken->challenge;
48*4d7e907cSAndroid Build Coastguard Worker aidlToken->userId = authToken->user_id;
49*4d7e907cSAndroid Build Coastguard Worker aidlToken->authenticatorId = authToken->authenticator_id;
50*4d7e907cSAndroid Build Coastguard Worker // these are in network order: translate to host
51*4d7e907cSAndroid Build Coastguard Worker aidlToken->authenticatorType =
52*4d7e907cSAndroid Build Coastguard Worker static_cast<android::hardware::security::keymint::HardwareAuthenticatorType>(
53*4d7e907cSAndroid Build Coastguard Worker be32toh(authToken->authenticator_type));
54*4d7e907cSAndroid Build Coastguard Worker aidlToken->timestamp.milliSeconds = be64toh(authToken->timestamp);
55*4d7e907cSAndroid Build Coastguard Worker aidlToken->mac.insert(aidlToken->mac.begin(), std::begin(authToken->hmac),
56*4d7e907cSAndroid Build Coastguard Worker std::end(authToken->hmac));
57*4d7e907cSAndroid Build Coastguard Worker }
58*4d7e907cSAndroid Build Coastguard Worker
SoftGateKeeperDevice(::gatekeeper::SoftGateKeeper & impl)59*4d7e907cSAndroid Build Coastguard Worker SoftGateKeeperDevice::SoftGateKeeperDevice(::gatekeeper::SoftGateKeeper& impl) : impl_(impl) {}
60*4d7e907cSAndroid Build Coastguard Worker
enroll(int32_t uid,const std::vector<uint8_t> & currentPasswordHandle,const std::vector<uint8_t> & currentPassword,const std::vector<uint8_t> & desiredPassword,GatekeeperEnrollResponse * rsp)61*4d7e907cSAndroid Build Coastguard Worker ::ndk::ScopedAStatus SoftGateKeeperDevice::enroll(int32_t uid,
62*4d7e907cSAndroid Build Coastguard Worker const std::vector<uint8_t>& currentPasswordHandle,
63*4d7e907cSAndroid Build Coastguard Worker const std::vector<uint8_t>& currentPassword,
64*4d7e907cSAndroid Build Coastguard Worker const std::vector<uint8_t>& desiredPassword,
65*4d7e907cSAndroid Build Coastguard Worker GatekeeperEnrollResponse* rsp) {
66*4d7e907cSAndroid Build Coastguard Worker if (desiredPassword.size() == 0) {
67*4d7e907cSAndroid Build Coastguard Worker LOG(ERROR) << "Desired password size is 0";
68*4d7e907cSAndroid Build Coastguard Worker return ndk::ScopedAStatus(AStatus_fromServiceSpecificError(ERROR_GENERAL_FAILURE));
69*4d7e907cSAndroid Build Coastguard Worker }
70*4d7e907cSAndroid Build Coastguard Worker
71*4d7e907cSAndroid Build Coastguard Worker if (currentPasswordHandle.size() > 0) {
72*4d7e907cSAndroid Build Coastguard Worker if (currentPasswordHandle.size() != sizeof(::gatekeeper::password_handle_t)) {
73*4d7e907cSAndroid Build Coastguard Worker LOG(ERROR) << "Password handle has wrong length";
74*4d7e907cSAndroid Build Coastguard Worker return ndk::ScopedAStatus(AStatus_fromServiceSpecificError(ERROR_GENERAL_FAILURE));
75*4d7e907cSAndroid Build Coastguard Worker }
76*4d7e907cSAndroid Build Coastguard Worker }
77*4d7e907cSAndroid Build Coastguard Worker
78*4d7e907cSAndroid Build Coastguard Worker EnrollRequest request(uid, vec2sized_buffer(currentPasswordHandle),
79*4d7e907cSAndroid Build Coastguard Worker vec2sized_buffer(desiredPassword), vec2sized_buffer(currentPassword));
80*4d7e907cSAndroid Build Coastguard Worker EnrollResponse response;
81*4d7e907cSAndroid Build Coastguard Worker impl_.Enroll(request, &response);
82*4d7e907cSAndroid Build Coastguard Worker if (response.error == ERROR_RETRY) {
83*4d7e907cSAndroid Build Coastguard Worker LOG(ERROR) << "Enroll response has a retry error";
84*4d7e907cSAndroid Build Coastguard Worker *rsp = {ERROR_RETRY_TIMEOUT, static_cast<int32_t>(response.retry_timeout), 0, {}};
85*4d7e907cSAndroid Build Coastguard Worker return ndk::ScopedAStatus::ok();
86*4d7e907cSAndroid Build Coastguard Worker } else if (response.error != ERROR_NONE) {
87*4d7e907cSAndroid Build Coastguard Worker LOG(ERROR) << "Enroll response has an error: " << response.error;
88*4d7e907cSAndroid Build Coastguard Worker return ndk::ScopedAStatus(AStatus_fromServiceSpecificError(ERROR_GENERAL_FAILURE));
89*4d7e907cSAndroid Build Coastguard Worker } else {
90*4d7e907cSAndroid Build Coastguard Worker const ::gatekeeper::password_handle_t* password_handle =
91*4d7e907cSAndroid Build Coastguard Worker response.enrolled_password_handle.Data<::gatekeeper::password_handle_t>();
92*4d7e907cSAndroid Build Coastguard Worker *rsp = {STATUS_OK,
93*4d7e907cSAndroid Build Coastguard Worker 0,
94*4d7e907cSAndroid Build Coastguard Worker static_cast<int64_t>(password_handle->user_id),
95*4d7e907cSAndroid Build Coastguard Worker {response.enrolled_password_handle.Data<uint8_t>(),
96*4d7e907cSAndroid Build Coastguard Worker (response.enrolled_password_handle.Data<uint8_t>() +
97*4d7e907cSAndroid Build Coastguard Worker response.enrolled_password_handle.size())}};
98*4d7e907cSAndroid Build Coastguard Worker }
99*4d7e907cSAndroid Build Coastguard Worker return ndk::ScopedAStatus::ok();
100*4d7e907cSAndroid Build Coastguard Worker }
101*4d7e907cSAndroid Build Coastguard Worker
verify(int32_t uid,int64_t challenge,const std::vector<uint8_t> & enrolledPasswordHandle,const std::vector<uint8_t> & providedPassword,GatekeeperVerifyResponse * rsp)102*4d7e907cSAndroid Build Coastguard Worker ::ndk::ScopedAStatus SoftGateKeeperDevice::verify(
103*4d7e907cSAndroid Build Coastguard Worker int32_t uid, int64_t challenge, const std::vector<uint8_t>& enrolledPasswordHandle,
104*4d7e907cSAndroid Build Coastguard Worker const std::vector<uint8_t>& providedPassword, GatekeeperVerifyResponse* rsp) {
105*4d7e907cSAndroid Build Coastguard Worker if (enrolledPasswordHandle.size() == 0) {
106*4d7e907cSAndroid Build Coastguard Worker LOG(ERROR) << "Enrolled password size is 0";
107*4d7e907cSAndroid Build Coastguard Worker return ndk::ScopedAStatus(AStatus_fromServiceSpecificError(ERROR_GENERAL_FAILURE));
108*4d7e907cSAndroid Build Coastguard Worker }
109*4d7e907cSAndroid Build Coastguard Worker
110*4d7e907cSAndroid Build Coastguard Worker if (enrolledPasswordHandle.size() > 0) {
111*4d7e907cSAndroid Build Coastguard Worker if (enrolledPasswordHandle.size() != sizeof(::gatekeeper::password_handle_t)) {
112*4d7e907cSAndroid Build Coastguard Worker LOG(ERROR) << "Password handle has wrong length";
113*4d7e907cSAndroid Build Coastguard Worker return ndk::ScopedAStatus(AStatus_fromServiceSpecificError(ERROR_GENERAL_FAILURE));
114*4d7e907cSAndroid Build Coastguard Worker }
115*4d7e907cSAndroid Build Coastguard Worker }
116*4d7e907cSAndroid Build Coastguard Worker
117*4d7e907cSAndroid Build Coastguard Worker VerifyRequest request(uid, challenge, vec2sized_buffer(enrolledPasswordHandle),
118*4d7e907cSAndroid Build Coastguard Worker vec2sized_buffer(providedPassword));
119*4d7e907cSAndroid Build Coastguard Worker VerifyResponse response;
120*4d7e907cSAndroid Build Coastguard Worker impl_.Verify(request, &response);
121*4d7e907cSAndroid Build Coastguard Worker
122*4d7e907cSAndroid Build Coastguard Worker if (response.error == ERROR_RETRY) {
123*4d7e907cSAndroid Build Coastguard Worker LOG(ERROR) << "Verify request response gave retry error";
124*4d7e907cSAndroid Build Coastguard Worker *rsp = {ERROR_RETRY_TIMEOUT, static_cast<int32_t>(response.retry_timeout), {}};
125*4d7e907cSAndroid Build Coastguard Worker return ndk::ScopedAStatus::ok();
126*4d7e907cSAndroid Build Coastguard Worker } else if (response.error != ERROR_NONE) {
127*4d7e907cSAndroid Build Coastguard Worker LOG(ERROR) << "Verify request response gave error: " << response.error;
128*4d7e907cSAndroid Build Coastguard Worker return ndk::ScopedAStatus(AStatus_fromServiceSpecificError(ERROR_GENERAL_FAILURE));
129*4d7e907cSAndroid Build Coastguard Worker } else {
130*4d7e907cSAndroid Build Coastguard Worker // On Success, return GatekeeperVerifyResponse with Success Status, timeout{0} and
131*4d7e907cSAndroid Build Coastguard Worker // valid HardwareAuthToken.
132*4d7e907cSAndroid Build Coastguard Worker *rsp = {response.request_reenroll ? STATUS_REENROLL : STATUS_OK, 0, {}};
133*4d7e907cSAndroid Build Coastguard Worker // Convert the hw_auth_token_t to HardwareAuthToken in the response.
134*4d7e907cSAndroid Build Coastguard Worker sizedBuffer2AidlHWToken(response.auth_token, &rsp->hardwareAuthToken);
135*4d7e907cSAndroid Build Coastguard Worker }
136*4d7e907cSAndroid Build Coastguard Worker return ndk::ScopedAStatus::ok();
137*4d7e907cSAndroid Build Coastguard Worker }
138*4d7e907cSAndroid Build Coastguard Worker
deleteUser(int32_t)139*4d7e907cSAndroid Build Coastguard Worker ::ndk::ScopedAStatus SoftGateKeeperDevice::deleteUser(int32_t /*uid*/) {
140*4d7e907cSAndroid Build Coastguard Worker LOG(ERROR) << "deleteUser is unimplemented";
141*4d7e907cSAndroid Build Coastguard Worker return ndk::ScopedAStatus(AStatus_fromServiceSpecificError(ERROR_NOT_IMPLEMENTED));
142*4d7e907cSAndroid Build Coastguard Worker }
143*4d7e907cSAndroid Build Coastguard Worker
deleteAllUsers()144*4d7e907cSAndroid Build Coastguard Worker ::ndk::ScopedAStatus SoftGateKeeperDevice::deleteAllUsers() {
145*4d7e907cSAndroid Build Coastguard Worker LOG(ERROR) << "deleteAllUsers is unimplemented";
146*4d7e907cSAndroid Build Coastguard Worker return ndk::ScopedAStatus(AStatus_fromServiceSpecificError(ERROR_NOT_IMPLEMENTED));
147*4d7e907cSAndroid Build Coastguard Worker }
148*4d7e907cSAndroid Build Coastguard Worker
149*4d7e907cSAndroid Build Coastguard Worker } // namespace aidl::android::hardware::gatekeeper
150