summaryrefslogtreecommitdiff
path: root/soft/SoftGateKeeperDevice.cpp (plain)
blob: ea5268895e5c24ffd5e86a271e4b9f7eefdcd1fb
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#include <assert.h>
18#include <errno.h>
19#include <stdio.h>
20#include "SoftGateKeeper.h"
21#include "SoftGateKeeperDevice.h"
22
23namespace android {
24
25SoftGateKeeperDevice::SoftGateKeeperDevice(const hw_module_t *module) {
26 assert(reinterpret_cast<gatekeeper_device_t *>(this) == &deviceSoft);
27 assert(reinterpret_cast<hw_device_t *>(this) == &(deviceSoft.common));
28
29 memset(&deviceSoft, 0, sizeof(deviceSoft));
30 deviceSoft.common.tag = HARDWARE_DEVICE_TAG;
31 deviceSoft.common.version = 1;
32 deviceSoft.common.module = const_cast<hw_module_t *>(module);
33 deviceSoft.common.close = close_device;
34
35 deviceSoft.enroll = enroll;
36 deviceSoft.verify = verify;
37 deviceSoft.delete_user = nullptr;
38 deviceSoft.delete_all_users = nullptr;
39
40 implSoft.reset(new SoftGateKeeper());
41}
42
43int SoftGateKeeperDevice::close_device(hw_device_t* dev) {
44 delete reinterpret_cast<SoftGateKeeperDevice *>(dev);
45 return 0;
46}
47
48SoftGateKeeperDevice::~SoftGateKeeperDevice() {
49
50}
51
52hw_device_t* SoftGateKeeperDevice::sw_device() {
53 return &deviceSoft.common;
54}
55
56int SoftGateKeeperDevice::Enroll(uint32_t uid,
57 const uint8_t *current_password_handle, uint32_t current_password_handle_length,
58 const uint8_t *current_password, uint32_t current_password_length,
59 const uint8_t *desired_password, uint32_t desired_password_length,
60 uint8_t **enrolled_password_handle, uint32_t *enrolled_password_handle_length) {
61
62 SizedBuffer desired_password_buffer(desired_password_length);
63 memcpy(desired_password_buffer.buffer.get(), desired_password, desired_password_length);
64
65 SizedBuffer current_password_handle_buffer(current_password_handle_length);
66 if (current_password_handle) {
67 memcpy(current_password_handle_buffer.buffer.get(), current_password_handle,
68 current_password_handle_length);
69 }
70
71 SizedBuffer current_password_buffer(current_password_length);
72 if (current_password) {
73 memcpy(current_password_buffer.buffer.get(), current_password, current_password_length);
74 }
75
76 EnrollRequest request(uid, &current_password_handle_buffer, &desired_password_buffer,
77 &current_password_buffer);
78 EnrollResponse response;
79
80 implSoft->Enroll(request, &response);
81
82 if (response.error == ERROR_RETRY) {
83 return response.retry_timeout;
84 } else if (response.error != ERROR_NONE) {
85 return -EINVAL;
86 }
87
88 *enrolled_password_handle = response.enrolled_password_handle.buffer.release();
89 *enrolled_password_handle_length = response.enrolled_password_handle.length;
90 return 0;
91}
92
93int SoftGateKeeperDevice::Verify(uint32_t uid,
94 uint64_t challenge, const uint8_t *enrolled_password_handle,
95 uint32_t enrolled_password_handle_length, const uint8_t *provided_password,
96 uint32_t provided_password_length, uint8_t **auth_token, uint32_t *auth_token_length,
97 bool *request_reenroll) {
98
99 SizedBuffer password_handle_buffer(enrolled_password_handle_length);
100 memcpy(password_handle_buffer.buffer.get(), enrolled_password_handle,
101 enrolled_password_handle_length);
102 SizedBuffer provided_password_buffer(provided_password_length);
103 memcpy(provided_password_buffer.buffer.get(), provided_password, provided_password_length);
104
105 VerifyRequest request(uid, challenge, &password_handle_buffer, &provided_password_buffer);
106 VerifyResponse response;
107
108 implSoft->Verify(request, &response);
109
110 if (response.error == ERROR_RETRY) {
111 return response.retry_timeout;
112 } else if (response.error != ERROR_NONE) {
113 return -EINVAL;
114 }
115
116 if (auth_token != NULL && auth_token_length != NULL) {
117 *auth_token = response.auth_token.buffer.release();
118 *auth_token_length = response.auth_token.length;
119 }
120
121 if (request_reenroll != NULL) {
122 *request_reenroll = response.request_reenroll;
123 }
124
125 return 0;
126}
127
128static inline SoftGateKeeperDevice *convert_device(const gatekeeper_device *dev) {
129 return reinterpret_cast<SoftGateKeeperDevice *>(const_cast<gatekeeper_device *>(dev));
130}
131
132/* static */
133int SoftGateKeeperDevice::enroll(const struct gatekeeper_device *dev, uint32_t uid,
134 const uint8_t *current_password_handle, uint32_t current_password_handle_length,
135 const uint8_t *current_password, uint32_t current_password_length,
136 const uint8_t *desired_password, uint32_t desired_password_length,
137 uint8_t **enrolled_password_handle, uint32_t *enrolled_password_handle_length) {
138
139 if (dev == NULL ||
140 enrolled_password_handle == NULL || enrolled_password_handle_length == NULL ||
141 desired_password == NULL || desired_password_length == 0)
142 return -EINVAL;
143
144 // Current password and current password handle go together
145 if (current_password_handle == NULL || current_password_handle_length == 0 ||
146 current_password == NULL || current_password_length == 0) {
147 current_password_handle = NULL;
148 current_password_handle_length = 0;
149 current_password = NULL;
150 current_password_length = 0;
151 }
152
153 return convert_device(dev)->Enroll(uid, current_password_handle, current_password_handle_length,
154 current_password, current_password_length, desired_password, desired_password_length,
155 enrolled_password_handle, enrolled_password_handle_length);
156
157}
158
159/* static */
160int SoftGateKeeperDevice::verify(const struct gatekeeper_device *dev, uint32_t uid,
161 uint64_t challenge, const uint8_t *enrolled_password_handle,
162 uint32_t enrolled_password_handle_length, const uint8_t *provided_password,
163 uint32_t provided_password_length, uint8_t **auth_token, uint32_t *auth_token_length,
164 bool *request_reenroll) {
165
166 if (dev == NULL || enrolled_password_handle == NULL ||
167 provided_password == NULL) {
168 return -EINVAL;
169 }
170
171 return convert_device(dev)->Verify(uid, challenge, enrolled_password_handle,
172 enrolled_password_handle_length, provided_password, provided_password_length,
173 auth_token, auth_token_length, request_reenroll);
174}
175} // namespace android
176