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  FINGERPRINT_LISTEN_SERVICE_NAME "fingerprintlisten"
18 #define  FINGERPRINT_TXT_FILENAME "/data/fingerprint.txt"
19 
20 #define LOG_TAG "FingerprintHal"
21 #define MAX_NUM_FINGERS 32
22 
23 #include <errno.h>
24 #include <endian.h>
25 #include <inttypes.h>
26 #include <malloc.h>
27 #include <string.h>
28 #include <cutils/log.h>
29 #include <hardware/hardware.h>
30 #include <hardware/fingerprint.h>
31 #include <hardware/qemud.h>
32 
33 typedef enum worker_state_t {
34     STATE_ENROLL = 1,
35     STATE_SCAN = 2,
36     STATE_IDLE = 3,
37     STATE_EXIT = 4
38 } worker_state_t;
39 
40 typedef struct worker_thread_t {
41     pthread_t thread;
42     pthread_mutex_t mutex;
43     int request;
44     worker_state_t state;
45     int fingerid;
46     int finger_is_on;
47     int all_fingerids[MAX_NUM_FINGERS];
48     uint64_t all_secureids[MAX_NUM_FINGERS];
49     uint64_t all_authenids[MAX_NUM_FINGERS];
50     int num_fingers_enrolled;
51     FILE *fp_write;;
52 } worker_thread_t;
53 
54 typedef struct emu_fingerprint_hal_device_t {
55     fingerprint_device_t device; //inheritance
56     worker_thread_t listener;
57     uint64_t op_id;
58     uint64_t challenge;
59     uint64_t secure_user_id;
60     uint64_t user_id;
61     uint64_t authenticator_id;
62     pthread_mutex_t lock;
63 } emu_fingerprint_hal_device_t;
64 
get_64bit_rand()65 static uint64_t get_64bit_rand() {
66     return (((uint64_t) rand()) << 32) | ((uint64_t) rand());
67 }
68 
destroyListenerThread(emu_fingerprint_hal_device_t * dev)69 static void destroyListenerThread(emu_fingerprint_hal_device_t* dev)
70 {
71     pthread_join(dev->listener.thread, NULL);
72     pthread_mutex_destroy(&dev->listener.mutex);
73 }
74 
finger_already_enrolled(emu_fingerprint_hal_device_t * dev)75 bool finger_already_enrolled(emu_fingerprint_hal_device_t* dev) {
76     int i;
77     for (i = 0; i < dev->listener.num_fingers_enrolled; ++ i) {
78         if (dev->listener.fingerid == dev->listener.all_fingerids[i % MAX_NUM_FINGERS]) {
79             dev->secure_user_id = dev->listener.all_secureids[i % MAX_NUM_FINGERS];
80             dev->authenticator_id = dev->listener.all_authenids[i % MAX_NUM_FINGERS];
81             return true;
82         }
83     }
84     return false;
85 }
86 
save_fingerid(FILE * fp,int fingerid,uint64_t secureid,uint64_t authenid)87 static void save_fingerid(FILE* fp, int fingerid, uint64_t secureid, uint64_t authenid) {
88     if (!fp) return;
89     fprintf(fp, " %d %" PRIu64 " %" PRIu64, fingerid, secureid, authenid);
90     fflush(fp);
91 }
92 
listener_send_notice(emu_fingerprint_hal_device_t * dev)93 static void listener_send_notice(emu_fingerprint_hal_device_t* dev)
94 {
95     fingerprint_msg_t message = {0};
96     bool is_authentication = false;
97     bool is_valid_finger = false;
98     pthread_mutex_lock(&dev->listener.mutex);
99     if (dev->listener.state == STATE_ENROLL) {
100         message.type = FINGERPRINT_TEMPLATE_ENROLLING;
101         message.data.enroll.finger.fid = dev->listener.fingerid;
102         message.data.enroll.samples_remaining = 0;
103         dev->authenticator_id = get_64bit_rand();
104         dev->listener.state = STATE_SCAN;
105         if (!finger_already_enrolled(dev)) {
106             dev->listener.all_fingerids[dev->listener.num_fingers_enrolled % MAX_NUM_FINGERS] = dev->listener.fingerid;
107             dev->listener.all_secureids[dev->listener.num_fingers_enrolled % MAX_NUM_FINGERS] = dev->secure_user_id;
108             dev->listener.all_authenids[dev->listener.num_fingers_enrolled % MAX_NUM_FINGERS] = dev->authenticator_id;
109             ++ dev->listener.num_fingers_enrolled;
110             save_fingerid(dev->listener.fp_write, dev->listener.fingerid, dev->secure_user_id, dev->authenticator_id);
111             is_valid_finger = true;
112         }
113     } else {
114         is_authentication = true;
115         is_valid_finger = finger_already_enrolled(dev);
116         message.type = FINGERPRINT_AUTHENTICATED;
117         message.data.authenticated.finger.gid = 0;
118         message.data.authenticated.finger.fid = is_valid_finger ? dev->listener.fingerid : 0;
119         message.data.authenticated.hat.version = HW_AUTH_TOKEN_VERSION;
120         message.data.authenticated.hat.authenticator_type = htobe32(HW_AUTH_FINGERPRINT);
121         message.data.authenticated.hat.challenge = dev->op_id;
122         message.data.authenticated.hat.authenticator_id = dev->authenticator_id;
123         message.data.authenticated.hat.user_id = dev->secure_user_id;
124         struct timespec ts;
125         clock_gettime(CLOCK_MONOTONIC, &ts);
126         message.data.authenticated.hat.timestamp =
127             htobe64((uint64_t)ts.tv_sec * 1000 + ts.tv_nsec / 1000000);
128     }
129     pthread_mutex_unlock(&dev->listener.mutex);
130 
131     pthread_mutex_lock(&dev->lock);
132     if (is_authentication) {
133         fingerprint_msg_t acquired_message = {0};
134         acquired_message.type = FINGERPRINT_ACQUIRED;
135         message.data.acquired.acquired_info = FINGERPRINT_ACQUIRED_GOOD;
136         dev->device.notify(&acquired_message);
137     }
138     if (is_valid_finger || is_authentication) {
139         dev->device.notify(&message);
140     }
141     pthread_mutex_unlock(&dev->lock);
142 }
143 
listenerFunction(void * data)144 static void* listenerFunction(void* data)
145 {
146     emu_fingerprint_hal_device_t* dev = (emu_fingerprint_hal_device_t*) data;
147 
148     int fd = qemud_channel_open(FINGERPRINT_LISTEN_SERVICE_NAME);
149     if (fd < 0) {
150         ALOGE("listener cannot open fingerprint listener service exit");
151         return NULL;
152     }
153 
154     const char* cmd = "listen";
155     if (qemud_channel_send(fd, cmd, strlen(cmd)) < 0) {
156         ALOGE("cannot write fingerprint 'listen' to host");
157         return NULL;
158     }
159 
160     int i;
161     for (i = 0; i < MAX_NUM_FINGERS; ++ i) {
162         dev->listener.all_fingerids[i] = 0;
163     }
164     //read registered fingerprint ids from /data/local/fingerprint.txt
165     //TODO: store it in a better location
166     dev->listener.num_fingers_enrolled = 0;
167     FILE* fp_stored = fopen(FINGERPRINT_TXT_FILENAME, "r");
168     if (fp_stored) {
169         while (1) {
170             int fingerid = 0;
171             uint64_t secureid = 0;
172             uint64_t authenid = 0;
173             if(fscanf(fp_stored, "%d %" SCNu64 " %" SCNu64, &fingerid, &secureid, &authenid) == 3) {
174                 dev->listener.all_fingerids[dev->listener.num_fingers_enrolled % MAX_NUM_FINGERS] = fingerid;
175                 dev->listener.all_secureids[dev->listener.num_fingers_enrolled % MAX_NUM_FINGERS] = secureid;
176                 dev->listener.all_authenids[dev->listener.num_fingers_enrolled % MAX_NUM_FINGERS] = authenid;
177                 ++ dev->listener.num_fingers_enrolled;
178             } else {
179                 break;
180             }
181         }
182         fclose(fp_stored);
183     }
184 
185     dev->listener.fp_write = fopen(FINGERPRINT_TXT_FILENAME, "a");
186 
187     char buffer[128];
188     int fingerid=-1;
189     int size;
190     while (1) {
191         //simply listen in blocking mode
192         if ((size = qemud_channel_recv(fd, buffer, sizeof buffer - 1)) >0) {
193             buffer[size] = '\0';
194             if (sscanf(buffer, "on:%d", &fingerid) == 1) {
195                 if (fingerid > 0 ) {
196                     dev->listener.fingerid = fingerid;
197                     dev->listener.finger_is_on = 1;
198                     ALOGD("got finger %d", fingerid);
199                     listener_send_notice(dev);
200                     ALOGD("send notice finger %d", fingerid);
201                 }
202                 else {
203                     ALOGE("finger id should be positive");
204                 }
205             } else if (strncmp("off", buffer, 3) == 0) {
206                 dev->listener.finger_is_on = 0;
207                 ALOGD("finger off %d", fingerid);
208             } else {
209                 ALOGE("error: '%s'", buffer);
210             }
211         } else {
212             ALOGE("receive failure");
213             // return NULL;
214         }
215         //TODO: check for request to exit thread
216     }
217 
218     ALOGD("listener exit");
219     return NULL;
220 }
221 
createListenerThread(emu_fingerprint_hal_device_t * dev)222 static void createListenerThread(emu_fingerprint_hal_device_t* dev)
223 {
224     pthread_mutex_init(&dev->listener.mutex, NULL);
225     pthread_create(&dev->listener.thread, NULL, listenerFunction, dev);
226 }
227 
fingerprint_close(hw_device_t * dev)228 static int fingerprint_close(hw_device_t *dev)
229 {
230     if (dev) {
231         destroyListenerThread((emu_fingerprint_hal_device_t*) dev);
232         free(dev);
233         return 0;
234     } else {
235         return -1;
236     }
237 }
238 
setListenerState(emu_fingerprint_hal_device_t * dev,worker_state_t state)239 static void setListenerState(emu_fingerprint_hal_device_t* dev, worker_state_t state) {
240     pthread_mutex_lock(&dev->listener.mutex);
241     dev->listener.state = state;
242     pthread_mutex_unlock(&dev->listener.mutex);
243 }
244 
fingerprint_get_auth_id(struct fingerprint_device __unused * device)245 static uint64_t fingerprint_get_auth_id(struct fingerprint_device __unused *device) {
246     emu_fingerprint_hal_device_t* dev = (emu_fingerprint_hal_device_t*) device;
247     return dev->authenticator_id;
248 }
249 
fingerprint_set_active_group(struct fingerprint_device __unused * device,uint32_t gid,const char * path)250 static int fingerprint_set_active_group(struct fingerprint_device __unused *device, uint32_t gid,
251         const char *path) {
252     // TODO: implements me
253     return 0;
254 }
255 
fingerprint_authenticate(struct fingerprint_device __unused * device,uint64_t __unused operation_id,__unused uint32_t gid)256 static int fingerprint_authenticate(struct fingerprint_device __unused *device,
257     uint64_t __unused operation_id, __unused uint32_t gid)
258 {
259     ALOGD("fingerprint_authenticate");
260 
261     emu_fingerprint_hal_device_t* dev = (emu_fingerprint_hal_device_t*) device;
262     pthread_mutex_lock(&dev->lock);
263     dev->op_id = operation_id;
264     pthread_mutex_unlock(&dev->lock);
265     setListenerState(dev, STATE_SCAN);
266     return 0;
267 }
268 
fingerprint_enroll(struct fingerprint_device * device,const hw_auth_token_t * hat,uint32_t __unused gid,uint32_t __unused timeout_sec)269 static int fingerprint_enroll(struct fingerprint_device *device,
270         const hw_auth_token_t *hat,
271         uint32_t __unused gid,
272         uint32_t __unused timeout_sec) {
273     ALOGD("fingerprint_enroll");
274     emu_fingerprint_hal_device_t* dev = (emu_fingerprint_hal_device_t*) device;
275     if (hat && hat->challenge == dev->challenge) {
276         dev->secure_user_id = hat->user_id;
277     } else {
278         ALOGW("%s: invalid or null auth token", __func__);
279     }
280 
281     if (hat->version != HW_AUTH_TOKEN_VERSION) {
282         return -EPROTONOSUPPORT;
283     }
284     if (hat->challenge != dev->challenge && !(hat->authenticator_type & HW_AUTH_FINGERPRINT)) {
285         return -EPERM;
286     }
287 
288     dev->user_id = hat->user_id;
289 
290     // TODO: store enrolled fingerprints, authenticator id, and secure_user_id
291     setListenerState(dev, STATE_ENROLL);
292     return 0;
293 
294 }
295 
fingerprint_pre_enroll(struct fingerprint_device * device)296 static uint64_t fingerprint_pre_enroll(struct fingerprint_device *device) {
297     ALOGD("fingerprint_pre_enroll");
298     emu_fingerprint_hal_device_t* dev = (emu_fingerprint_hal_device_t*) device;
299     dev->challenge = get_64bit_rand();
300     return dev->challenge;
301 }
302 
fingerprint_cancel(struct fingerprint_device __unused * device)303 static int fingerprint_cancel(struct fingerprint_device __unused *device) {
304     ALOGD("fingerprint_cancel");
305     emu_fingerprint_hal_device_t* dev = (emu_fingerprint_hal_device_t*) device;
306     setListenerState(dev, STATE_IDLE);
307     return 0;
308 }
309 
fingerprint_enumerate(struct fingerprint_device * device,fingerprint_finger_id_t * results,uint32_t * max_size)310 static int fingerprint_enumerate(struct fingerprint_device *device,
311         fingerprint_finger_id_t *results, uint32_t *max_size) {
312     // TODO: implement me
313     return 0;
314 }
315 
fingerprint_remove(struct fingerprint_device __unused * dev,uint32_t __unused gid,uint32_t __unused fid)316 static int fingerprint_remove(struct fingerprint_device __unused *dev,
317         uint32_t __unused gid, uint32_t __unused fid) {
318     // TODO: implement enroll and remove, and set dev->authenticator_id = 0 when no FPs enrolled
319     return FINGERPRINT_ERROR;
320 }
321 
set_notify_callback(struct fingerprint_device * device,fingerprint_notify_t notify)322 static int set_notify_callback(struct fingerprint_device *device,
323                                 fingerprint_notify_t notify) {
324     ALOGD("set_notify");
325     emu_fingerprint_hal_device_t* dev =(emu_fingerprint_hal_device_t*) device;
326     pthread_mutex_lock(&dev->lock);
327     device->notify = notify;
328     pthread_mutex_unlock(&dev->lock);
329     return 0;
330 }
331 
fingerprint_open(const hw_module_t * module,const char __unused * id,hw_device_t ** device)332 static int fingerprint_open(const hw_module_t* module, const char __unused *id,
333                             hw_device_t** device)
334 {
335     if (device == NULL) {
336         ALOGE("NULL device on open");
337         return -EINVAL;
338     } else {
339         ALOGD("fingerprint open\n");
340     }
341 
342     emu_fingerprint_hal_device_t *dev = malloc(sizeof(emu_fingerprint_hal_device_t));
343     memset(dev, 0, sizeof(emu_fingerprint_hal_device_t));
344 
345     dev->device.common.tag = HARDWARE_DEVICE_TAG;
346     dev->device.common.version = HARDWARE_MODULE_API_VERSION(2, 0);
347     dev->device.common.module = (struct hw_module_t*) module;
348     dev->device.common.close = fingerprint_close;
349     dev->device.pre_enroll = fingerprint_pre_enroll;
350     dev->device.enroll = fingerprint_enroll;
351     dev->device.get_authenticator_id = fingerprint_get_auth_id;
352     dev->device.set_active_group = fingerprint_set_active_group;
353     dev->device.authenticate = fingerprint_authenticate;
354     dev->device.cancel = fingerprint_cancel;
355     dev->device.enumerate = fingerprint_enumerate;
356     dev->device.remove = fingerprint_remove;
357     dev->device.set_notify = set_notify_callback;
358     dev->device.notify = NULL;
359 
360     dev->authenticator_id = 0xdeadbeef;
361 
362     pthread_mutex_init(&dev->lock, NULL);
363     createListenerThread(dev);
364     *device = (hw_device_t*) dev;
365     return 0;
366 }
367 
368 static struct hw_module_methods_t fingerprint_module_methods = {
369     .open = fingerprint_open,
370 };
371 
372 fingerprint_module_t HAL_MODULE_INFO_SYM = {
373     .common = {
374         .tag                = HARDWARE_MODULE_TAG,
375         .module_api_version = FINGERPRINT_MODULE_API_VERSION_2_0,
376         .hal_api_version    = HARDWARE_HAL_API_VERSION,
377         .id                 = FINGERPRINT_HARDWARE_MODULE_ID,
378         .name               = "Emulator Fingerprint HAL",
379         .author             = "The Android Open Source Project",
380         .methods            = &fingerprint_module_methods,
381     },
382 };
383