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 /**
18 * This is a very basic implementation of fingerprint to allow testing on the emulator. It
19 * is *not* meant to be the final implementation on real devices. For example, it does *not*
20 * implement all of the required features, such as secure template storage and recognition
21 * inside a Trusted Execution Environment (TEE). However, this file is a reasonable starting
22 * point as developers add fingerprint support to their platform. See inline comments and
23 * recommendations for details.
24 *
25 * Please see the Android Compatibility Definition Document (CDD) for a full list of requirements
26 * and suggestions.
27 */
28 #define LOG_TAG "FingerprintHal"
29
30 #include <errno.h>
31 #include <endian.h>
32 #include <inttypes.h>
33 #include <malloc.h>
34 #include <string.h>
35 #include <cutils/log.h>
36 #include <hardware/hardware.h>
37 #include <hardware/fingerprint.h>
38 #include "qemud.h"
39
40 #include <poll.h>
41
42 #define FINGERPRINT_LISTEN_SERVICE_NAME "fingerprintlisten"
43 #define FINGERPRINT_FILENAME "emufp.bin"
44 #define AUTHENTICATOR_ID_FILENAME "emuauthid.bin"
45 #define MAX_COMM_CHARS 128
46 #define MAX_COMM_ERRORS 8
47 // Typical devices will allow up to 5 fingerprints per user to maintain performance of
48 // t < 500ms for recognition. This is the total number of fingerprints we'll store.
49 #define MAX_NUM_FINGERS 20
50 #define MAX_FID_VALUE 0x7FFFFFFF // Arbitrary limit
51
52 /**
53 * Most devices will have an internal state machine resembling this. There are 3 basic states, as
54 * shown below. When device is not authenticating or enrolling, it is expected to be in
55 * the idle state.
56 *
57 * Note that this is completely independent of device wake state. If the hardware device was in
58 * the "scan" state when the device drops into power collapse, it should resume scanning when power
59 * is restored. This is to facilitate rapid touch-to-unlock from keyguard.
60 */
61 typedef enum worker_state_t {
62 STATE_IDLE = 0,
63 STATE_ENROLL,
64 STATE_SCAN,
65 STATE_EXIT
66 } worker_state_t;
67
68 typedef struct worker_thread_t {
69 pthread_t thread;
70 worker_state_t state;
71 uint64_t secureid[MAX_NUM_FINGERS];
72 uint64_t fingerid[MAX_NUM_FINGERS];
73 char fp_filename[PATH_MAX];
74 char authid_filename[PATH_MAX];
75 } worker_thread_t;
76
77 typedef struct qemu_fingerprint_device_t {
78 fingerprint_device_t device; // "inheritance"
79 worker_thread_t listener;
80 uint64_t op_id;
81 uint64_t challenge;
82 uint64_t user_id;
83 uint64_t group_id;
84 uint64_t secure_user_id;
85 uint64_t authenticator_id;
86 int qchanfd;
87 pthread_mutex_t lock;
88 } qemu_fingerprint_device_t;
89
90 /******************************************************************************/
91
92 static FILE* openForWrite(const char* filename);
93
saveFingerprint(worker_thread_t * listener,int idx)94 static void saveFingerprint(worker_thread_t* listener, int idx) {
95 ALOGD("----------------> %s -----------------> idx %d", __FUNCTION__, idx);
96
97 // Save fingerprints to file
98 FILE* fp = openForWrite(listener->fp_filename);
99 if (fp == NULL) {
100 ALOGE("Could not open fingerprints storage at %s; "
101 "fingerprints won't be saved",
102 listener->fp_filename);
103 perror("Failed to open file");
104 return;
105 }
106
107 ALOGD("Write fingerprint[%d] (0x%" PRIx64 ",0x%" PRIx64 ")", idx,
108 listener->secureid[idx], listener->fingerid[idx]);
109
110 if (fseek(fp, (idx) * sizeof(uint64_t), SEEK_SET) < 0) {
111 ALOGE("Failed while seeking for fingerprint[%d] in emulator storage",
112 idx);
113 fclose(fp);
114 return;
115 }
116 int ns = fwrite(&listener->secureid[idx], sizeof(uint64_t), 1, fp);
117
118 if (fseek(fp, (MAX_NUM_FINGERS + idx) * sizeof(uint64_t), SEEK_SET) < 0) {
119 ALOGE("Failed while seeking for fingerprint[%d] in emulator storage",
120 idx);
121 fclose(fp);
122 return;
123 }
124 int nf = fwrite(&listener->fingerid[idx], sizeof(uint64_t), 1, fp);
125 if (ns != 1 || ns !=1)
126 ALOGW("Corrupt emulator fingerprints storage; could not save "
127 "fingerprints");
128
129 fclose(fp);
130
131 return;
132 }
133
openForWrite(const char * filename)134 static FILE* openForWrite(const char* filename) {
135
136 if (!filename) return NULL;
137
138 FILE* fp = fopen(filename, "r+"); // write but don't truncate
139 if (fp == NULL) {
140 fp = fopen(filename, "w");
141 if (fp) {
142 uint64_t zero = 0;
143 int i = 0;
144 for (i = 0; i < 2*MAX_NUM_FINGERS; ++i) {
145 fwrite(&zero, sizeof(uint64_t), 1, fp);
146 }
147
148 //the last one is for authenticator id
149 fwrite(&zero, sizeof(uint64_t), 1, fp);
150 }
151 }
152 return fp;
153 }
154
saveAuthenticatorId(const char * filename,uint64_t authenid)155 static void saveAuthenticatorId(const char* filename, uint64_t authenid) {
156 ALOGD("----------------> %s ----------------->", __FUNCTION__);
157 FILE* fp = openForWrite(filename);
158 if (!fp) {
159 ALOGE("Failed to open emulator storage file to save authenticator id");
160 return;
161 }
162
163 rewind(fp);
164
165 int na = fwrite(&authenid, sizeof(authenid), 1, fp);
166 if (na != 1) {
167 ALOGE("Failed while writing authenticator id in emulator storage");
168 }
169
170 ALOGD("Save authenticator id (0x%" PRIx64 ")", authenid);
171
172 fclose(fp);
173 }
174
loadAuthenticatorId(const char * authid_filename,uint64_t * pauthenid)175 static void loadAuthenticatorId(const char* authid_filename, uint64_t* pauthenid) {
176 ALOGD("----------------> %s ----------------->", __FUNCTION__);
177 FILE* fp = fopen(authid_filename, "r");
178 if (fp == NULL) {
179 ALOGE("Could not load authenticator id from storage at %s; "
180 "it has not yet been created.",
181 authid_filename);
182 perror("Failed to open/create file");
183 return;
184 }
185
186 rewind(fp);
187
188 int na = fread(pauthenid, sizeof(*pauthenid), 1, fp);
189 if (na != 1)
190 ALOGW("Corrupt emulator authenticator id storage (read %d)", na);
191
192 ALOGD("Read authenticator id (0x%" PRIx64 ")", *pauthenid);
193
194 fclose(fp);
195
196 return;
197 }
198
loadFingerprints(worker_thread_t * listener)199 static void loadFingerprints(worker_thread_t* listener) {
200 ALOGD("----------------> %s ----------------->", __FUNCTION__);
201 FILE* fp = fopen(listener->fp_filename, "r");
202 if (fp == NULL) {
203 ALOGE("Could not load fingerprints from storage at %s; "
204 "it has not yet been created.",
205 listener->fp_filename);
206 perror("Failed to open/create file");
207 return;
208 }
209
210 int ns = fread(listener->secureid, MAX_NUM_FINGERS * sizeof(uint64_t), 1,
211 fp);
212 int nf = fread(listener->fingerid, MAX_NUM_FINGERS * sizeof(uint64_t), 1,
213 fp);
214 if (ns != 1 || nf != 1)
215 ALOGW("Corrupt emulator fingerprints storage (read %d+%db)", ns, nf);
216
217 int i = 0;
218 for (i = 0; i < MAX_NUM_FINGERS; i++)
219 ALOGD("Read fingerprint %d (0x%" PRIx64 ",0x%" PRIx64 ")", i,
220 listener->secureid[i], listener->fingerid[i]);
221
222 fclose(fp);
223
224 return;
225 }
226
227 /******************************************************************************/
228
get_64bit_rand()229 static uint64_t get_64bit_rand() {
230 // This should use a cryptographically-secure random number generator like arc4random().
231 // It should be generated inside of the TEE where possible. Here we just use something
232 // very simple.
233 ALOGD("----------------> %s ----------------->", __FUNCTION__);
234 uint64_t r = (((uint64_t)rand()) << 32) | ((uint64_t)rand());
235 return r != 0 ? r : 1;
236 }
237
fingerprint_get_auth_id(struct fingerprint_device * device)238 static uint64_t fingerprint_get_auth_id(struct fingerprint_device* device) {
239 // This should return the authentication_id generated when the fingerprint template database
240 // was created. Though this isn't expected to be secret, it is reasonable to expect it to be
241 // cryptographically generated to avoid replay attacks.
242 qemu_fingerprint_device_t* qdev = (qemu_fingerprint_device_t*)device;
243 ALOGD("----------------> %s ----------------->", __FUNCTION__);
244 uint64_t authenticator_id = 0;
245 pthread_mutex_lock(&qdev->lock);
246 authenticator_id = qdev->authenticator_id;
247 pthread_mutex_unlock(&qdev->lock);
248
249 ALOGD("----------------> %s auth id %" PRIx64 "----------------->", __FUNCTION__, authenticator_id);
250 return authenticator_id;
251 }
252
fingerprint_set_active_group(struct fingerprint_device * device,uint32_t gid,const char * path)253 static int fingerprint_set_active_group(struct fingerprint_device *device, uint32_t gid,
254 const char *path) {
255 ALOGD("----------------> %s -----------------> path %s", __FUNCTION__, path);
256 qemu_fingerprint_device_t* qdev = (qemu_fingerprint_device_t*)device;
257 pthread_mutex_lock(&qdev->lock);
258 qdev->group_id = gid;
259 snprintf(qdev->listener.fp_filename, sizeof(qdev->listener.fp_filename),
260 "%s/%s", path, FINGERPRINT_FILENAME);
261 snprintf(qdev->listener.authid_filename, sizeof(qdev->listener.authid_filename),
262 "%s/%s", path, AUTHENTICATOR_ID_FILENAME);
263 uint64_t authenticator_id = 0;
264 loadFingerprints(&qdev->listener);
265 loadAuthenticatorId(qdev->listener.authid_filename, &authenticator_id);
266 if (authenticator_id == 0) {
267 // firs time, create an authenticator id
268 authenticator_id = get_64bit_rand();
269 // save it to disk
270 saveAuthenticatorId(qdev->listener.authid_filename, authenticator_id);
271 }
272
273 qdev->authenticator_id = authenticator_id;
274 pthread_mutex_unlock(&qdev->lock);
275
276 return 0;
277 }
278
279 /**
280 * If fingerprints are enrolled, then this function is expected to put the sensor into a
281 * "scanning" state where it's actively scanning and recognizing fingerprint features.
282 * Actual authentication must happen in TEE and should be monitored in a separate thread
283 * since this function is expected to return immediately.
284 */
fingerprint_authenticate(struct fingerprint_device * device,uint64_t operation_id,__unused uint32_t gid)285 static int fingerprint_authenticate(struct fingerprint_device *device,
286 uint64_t operation_id, __unused uint32_t gid)
287 {
288 qemu_fingerprint_device_t* qdev = (qemu_fingerprint_device_t*)device;
289
290 pthread_mutex_lock(&qdev->lock);
291 qdev->op_id = operation_id;
292 qdev->listener.state = STATE_SCAN;
293 pthread_mutex_unlock(&qdev->lock);
294
295 return 0;
296 }
297
298 /**
299 * This is expected to put the sensor into an "enroll" state where it's actively scanning and
300 * working towards a finished fingerprint database entry. Authentication must happen in
301 * a separate thread since this function is expected to return immediately.
302 *
303 * Note: This method should always generate a new random authenticator_id.
304 *
305 * Note: As with fingerprint_authenticate(), this would run in TEE on a real device.
306 */
fingerprint_enroll(struct fingerprint_device * device,const hw_auth_token_t * hat,uint32_t __unused gid,uint32_t __unused timeout_sec)307 static int fingerprint_enroll(struct fingerprint_device *device,
308 const hw_auth_token_t *hat,
309 uint32_t __unused gid,
310 uint32_t __unused timeout_sec) {
311 ALOGD("fingerprint_enroll");
312 qemu_fingerprint_device_t* dev = (qemu_fingerprint_device_t*)device;
313 if (!hat) {
314 ALOGW("%s: null auth token", __func__);
315 return -EPROTONOSUPPORT;
316 }
317 if (hat->challenge == dev->challenge) {
318 // The secure_user_id retrieved from the auth token should be stored
319 // with the enrolled fingerprint template and returned in the auth result
320 // for a successful authentication with that finger.
321 dev->secure_user_id = hat->user_id;
322 } else {
323 ALOGW("%s: invalid auth token", __func__);
324 }
325
326 if (hat->version != HW_AUTH_TOKEN_VERSION) {
327 return -EPROTONOSUPPORT;
328 }
329 if (hat->challenge != dev->challenge && !(hat->authenticator_type & HW_AUTH_FINGERPRINT)) {
330 return -EPERM;
331 }
332
333 dev->user_id = hat->user_id;
334
335 pthread_mutex_lock(&dev->lock);
336 dev->listener.state = STATE_ENROLL;
337 pthread_mutex_unlock(&dev->lock);
338
339 // fingerprint id, authenticator id, and secure_user_id
340 // will be stored by worked thread
341
342 return 0;
343
344 }
345
346 /**
347 * The pre-enrollment step is simply to get an authentication token that can be wrapped and
348 * verified at a later step. The primary purpose is to return a token that protects against
349 * spoofing and replay attacks. It is passed to password authentication where it is wrapped and
350 * propagated to the enroll step.
351 */
fingerprint_pre_enroll(struct fingerprint_device * device)352 static uint64_t fingerprint_pre_enroll(struct fingerprint_device *device) {
353 ALOGD("----------------> %s ----------------->", __FUNCTION__);
354 uint64_t challenge = 0;
355 qemu_fingerprint_device_t* qdev = (qemu_fingerprint_device_t*)device;
356
357 // The challenge will typically be a cryptographically-secure key
358 // coming from the TEE so it can be verified at a later step. For now we just generate a
359 // random value.
360 challenge = get_64bit_rand();
361
362 pthread_mutex_lock(&qdev->lock);
363 qdev->challenge = challenge;
364 pthread_mutex_unlock(&qdev->lock);
365
366 return challenge;
367 }
368
fingerprint_post_enroll(struct fingerprint_device * device)369 static int fingerprint_post_enroll(struct fingerprint_device* device) {
370 ALOGD("----------------> %s ----------------->", __FUNCTION__);
371 qemu_fingerprint_device_t* qdev = (qemu_fingerprint_device_t*)device;
372
373 pthread_mutex_lock(&qdev->lock);
374 qdev->challenge = 0;
375 pthread_mutex_unlock(&qdev->lock);
376
377 return 0;
378 }
379
380 /**
381 * Cancel is called by the framework to cancel an outstanding event. This should *not* be called
382 * by the driver since it will cause the framework to stop listening for fingerprints.
383 */
fingerprint_cancel(struct fingerprint_device * device)384 static int fingerprint_cancel(struct fingerprint_device *device) {
385 ALOGD("----------------> %s ----------------->", __FUNCTION__);
386 qemu_fingerprint_device_t* qdev = (qemu_fingerprint_device_t*)device;
387
388 pthread_mutex_lock(&qdev->lock);
389 qdev->listener.state = STATE_IDLE;
390 pthread_mutex_unlock(&qdev->lock);
391
392 fingerprint_msg_t msg = {0, {0}};
393 msg.type = FINGERPRINT_ERROR;
394 msg.data.error = FINGERPRINT_ERROR_CANCELED;
395 qdev->device.notify(&msg);
396
397 return 0;
398 }
399
fingerprint_enumerate(struct fingerprint_device * device)400 static int fingerprint_enumerate(struct fingerprint_device *device) {
401 ALOGD("----------------> %s ----------------->", __FUNCTION__);
402 if (device == NULL) {
403 ALOGE("Cannot enumerate saved fingerprints with uninitialized params");
404 return -1;
405 }
406
407 qemu_fingerprint_device_t* qdev = (qemu_fingerprint_device_t*)device;
408 int template_count = 0;
409 for (int i = 0; i < MAX_NUM_FINGERS; i++) {
410 if (qdev->listener.secureid[i] != 0 ||
411 qdev->listener.fingerid[i] != 0) {
412 ALOGD("ENUM: Fingerprint [%d] = 0x%" PRIx64 ",%" PRIx64, i,
413 qdev->listener.secureid[i], qdev->listener.fingerid[i]);
414 template_count++;
415 }
416 }
417 fingerprint_msg_t message = {0, {0}};
418 message.type = FINGERPRINT_TEMPLATE_ENUMERATING;
419 message.data.enumerated.finger.gid = qdev->group_id;
420
421 if(template_count == 0) {
422 message.data.enumerated.remaining_templates = 0;
423 message.data.enumerated.finger.fid = 0;
424 qdev->device.notify(&message);
425 }
426 else {
427 for (int i = 0; i < MAX_NUM_FINGERS; i++) {
428 if (qdev->listener.secureid[i] != 0 ||
429 qdev->listener.fingerid[i] != 0) {
430 template_count--;
431 message.data.enumerated.remaining_templates = template_count;
432 message.data.enumerated.finger.fid = qdev->listener.fingerid[i];
433 qdev->device.notify(&message);
434 }
435 }
436 }
437
438 return 0;
439 }
440
fingerprint_remove(struct fingerprint_device * device,uint32_t __unused gid,uint32_t fid)441 static int fingerprint_remove(struct fingerprint_device *device,
442 uint32_t __unused gid, uint32_t fid) {
443 int idx = 0;
444 fingerprint_msg_t msg = {0, {0}};
445 ALOGD("----------------> %s -----------------> fid %d", __FUNCTION__, fid);
446 if (device == NULL) {
447 ALOGE("Can't remove fingerprint (gid=%d, fid=%d); "
448 "device not initialized properly",
449 gid, fid);
450 return -1;
451 }
452
453 qemu_fingerprint_device_t* qdev = (qemu_fingerprint_device_t*)device;
454
455 if (fid == 0) {
456 // Delete all fingerprints
457 // I'll do this one at a time, so I am not
458 // holding the mutext during the notification
459 bool listIsEmpty;
460 do {
461 pthread_mutex_lock(&qdev->lock);
462 listIsEmpty = true; // Haven't seen a valid entry yet
463 for (idx = 0; idx < MAX_NUM_FINGERS; idx++) {
464 uint32_t theFid = qdev->listener.fingerid[idx];
465 if (theFid != 0) {
466 // Delete this entry
467 qdev->listener.secureid[idx] = 0;
468 qdev->listener.fingerid[idx] = 0;
469 saveFingerprint(&qdev->listener, idx);
470
471 // Send a notification that we deleted this one
472 pthread_mutex_unlock(&qdev->lock);
473 msg.type = FINGERPRINT_TEMPLATE_REMOVED;
474 msg.data.removed.finger.fid = theFid;
475 device->notify(&msg);
476
477 // Because we released the mutex, the list
478 // may have changed. Restart the 'for' loop
479 // after reacquiring the mutex.
480 listIsEmpty = false;
481 break;
482 }
483 } // end for (idx < MAX_NUM_FINGERS)
484 } while (!listIsEmpty);
485 qdev->listener.state = STATE_IDLE;
486 pthread_mutex_unlock(&qdev->lock);
487 msg.type = FINGERPRINT_TEMPLATE_REMOVED;
488 msg.data.removed.finger.fid = 0;
489 device->notify(&msg);
490 } else {
491 // Delete one fingerprint
492 // Look for this finger ID in our table.
493 pthread_mutex_lock(&qdev->lock);
494 for (idx = 0; idx < MAX_NUM_FINGERS; idx++) {
495 if (qdev->listener.fingerid[idx] == fid &&
496 qdev->listener.secureid[idx] != 0) {
497 // Found it!
498 break;
499 }
500 }
501 if (idx >= MAX_NUM_FINGERS) {
502 qdev->listener.state = STATE_IDLE;
503 pthread_mutex_unlock(&qdev->lock);
504 ALOGE("Fingerprint ID %d not found", fid);
505 return FINGERPRINT_ERROR;
506 }
507
508 qdev->listener.secureid[idx] = 0;
509 qdev->listener.fingerid[idx] = 0;
510 saveFingerprint(&qdev->listener, idx);
511
512 qdev->listener.state = STATE_IDLE;
513 pthread_mutex_unlock(&qdev->lock);
514
515 msg.type = FINGERPRINT_TEMPLATE_REMOVED;
516 msg.data.removed.finger.fid = fid;
517 device->notify(&msg);
518 }
519
520 return 0;
521 }
522
set_notify_callback(struct fingerprint_device * device,fingerprint_notify_t notify)523 static int set_notify_callback(struct fingerprint_device *device,
524 fingerprint_notify_t notify) {
525 ALOGD("----------------> %s ----------------->", __FUNCTION__);
526 if (device == NULL || notify == NULL) {
527 ALOGE("Failed to set notify callback @ %p for fingerprint device %p",
528 device, notify);
529 return -1;
530 }
531
532 qemu_fingerprint_device_t* qdev = (qemu_fingerprint_device_t*)device;
533 pthread_mutex_lock(&qdev->lock);
534 qdev->listener.state = STATE_IDLE;
535 device->notify = notify;
536 pthread_mutex_unlock(&qdev->lock);
537 ALOGD("fingerprint callback notification set");
538
539 return 0;
540 }
541
is_valid_fid(qemu_fingerprint_device_t * qdev,uint64_t fid)542 static bool is_valid_fid(qemu_fingerprint_device_t* qdev, uint64_t fid) {
543 int idx = 0;
544 if (0 == fid) { return false; }
545 for (idx = 0; idx < MAX_NUM_FINGERS; idx++) {
546 if (qdev->listener.fingerid[idx] == fid) {
547 return true;
548 }
549 }
550 return false;
551 }
552
send_scan_notice(qemu_fingerprint_device_t * qdev,int fid)553 static void send_scan_notice(qemu_fingerprint_device_t* qdev, int fid) {
554 ALOGD("----------------> %s ----------------->", __FUNCTION__);
555
556 // acquired message
557 fingerprint_msg_t acqu_msg = {0, {0}};
558 acqu_msg.type = FINGERPRINT_ACQUIRED;
559 acqu_msg.data.acquired.acquired_info = FINGERPRINT_ACQUIRED_GOOD;
560
561 // authenticated message
562 fingerprint_msg_t auth_msg = {0, {0}};
563 auth_msg.type = FINGERPRINT_AUTHENTICATED;
564 auth_msg.data.authenticated.finger.fid = is_valid_fid(qdev, fid) ? fid : 0;
565 auth_msg.data.authenticated.finger.gid = 0; // unused
566 auth_msg.data.authenticated.hat.version = HW_AUTH_TOKEN_VERSION;
567 auth_msg.data.authenticated.hat.authenticator_type =
568 htobe32(HW_AUTH_FINGERPRINT);
569 auth_msg.data.authenticated.hat.challenge = qdev->op_id;
570 auth_msg.data.authenticated.hat.authenticator_id = qdev->authenticator_id;
571 auth_msg.data.authenticated.hat.user_id = qdev->secure_user_id;
572 struct timespec ts;
573 clock_gettime(CLOCK_MONOTONIC, &ts);
574 auth_msg.data.authenticated.hat.timestamp =
575 htobe64((uint64_t)ts.tv_sec * 1000 + ts.tv_nsec / 1000000);
576
577 // pthread_mutex_lock(&qdev->lock);
578 qdev->device.notify(&acqu_msg);
579 qdev->device.notify(&auth_msg);
580 // pthread_mutex_unlock(&qdev->lock);
581
582 return;
583 }
584
send_enroll_notice(qemu_fingerprint_device_t * qdev,int fid)585 static void send_enroll_notice(qemu_fingerprint_device_t* qdev, int fid) {
586 ALOGD("----------------> %s -----------------> fid %d", __FUNCTION__, fid);
587
588 if (fid == 0) {
589 ALOGD("Fingerprint ID is zero (invalid)");
590 return;
591 }
592 if (qdev->secure_user_id == 0) {
593 ALOGD("Secure user ID is zero (invalid)");
594 return;
595 }
596
597 // Find an available entry in the table
598 pthread_mutex_lock(&qdev->lock);
599 int idx = 0;
600 for (idx = 0; idx < MAX_NUM_FINGERS; idx++) {
601 if (qdev->listener.secureid[idx] == 0 ||
602 qdev->listener.fingerid[idx] == 0) {
603 // This entry is available
604 break;
605 }
606 }
607 if (idx >= MAX_NUM_FINGERS) {
608 qdev->listener.state = STATE_SCAN;
609 pthread_mutex_unlock(&qdev->lock);
610 ALOGD("Fingerprint ID table is full");
611 return;
612 }
613
614 qdev->listener.secureid[idx] = qdev->secure_user_id;
615 qdev->listener.fingerid[idx] = fid;
616 saveFingerprint(&qdev->listener, idx);
617
618 qdev->listener.state = STATE_SCAN;
619 pthread_mutex_unlock(&qdev->lock);
620
621 // LOCKED notification?
622 fingerprint_msg_t msg = {0, {0}};
623 msg.type = FINGERPRINT_TEMPLATE_ENROLLING;
624 msg.data.enroll.finger.fid = fid;
625 msg.data.enroll.samples_remaining = 0;
626 qdev->device.notify(&msg);
627
628 return;
629 }
630
getListenerState(qemu_fingerprint_device_t * dev)631 static worker_state_t getListenerState(qemu_fingerprint_device_t* dev) {
632 ALOGV("----------------> %s ----------------->", __FUNCTION__);
633 worker_state_t state = STATE_IDLE;
634
635 pthread_mutex_lock(&dev->lock);
636 state = dev->listener.state;
637 pthread_mutex_unlock(&dev->lock);
638
639 return state;
640 }
641
642 /**
643 * This a very simple event loop for the fingerprint sensor. For a given state (enroll, scan),
644 * this would receive events from the sensor and forward them to fingerprintd using the
645 * notify() method.
646 *
647 * In this simple example, we open a qemu channel (a pipe) where the developer can inject events to
648 * exercise the API and test application code.
649 *
650 * The scanner should remain in the scanning state until either an error occurs or the operation
651 * completes.
652 *
653 * Recoverable errors such as EINTR should be handled locally; they should not
654 * be propagated unless there's something the user can do about it (e.g. "clean sensor"). Such
655 * messages should go through the onAcquired() interface.
656 *
657 * If an unrecoverable error occurs, an acquired message (e.g. ACQUIRED_PARTIAL) should be sent,
658 * followed by an error message (e.g. FINGERPRINT_ERROR_UNABLE_TO_PROCESS).
659 *
660 * Note that this event loop would typically run in TEE since it must interact with the sensor
661 * hardware and handle raw fingerprint data and encrypted templates. It is expected that
662 * this code monitors the TEE for resulting events, such as enrollment and authentication status.
663 * Here we just have a very simple event loop that monitors a qemu channel for pseudo events.
664 */
listenerFunction(void * data)665 static void* listenerFunction(void* data) {
666 ALOGD("----------------> %s ----------------->", __FUNCTION__);
667 qemu_fingerprint_device_t* qdev = (qemu_fingerprint_device_t*)data;
668
669 int fd = qemud_channel_open(FINGERPRINT_LISTEN_SERVICE_NAME);
670 pthread_mutex_lock(&qdev->lock);
671 qdev->qchanfd = fd;
672 if (qdev->qchanfd < 0) {
673 ALOGE("listener cannot open fingerprint listener service exit");
674 pthread_mutex_unlock(&qdev->lock);
675 return NULL;
676 }
677 qdev->listener.state = STATE_IDLE;
678 pthread_mutex_unlock(&qdev->lock);
679
680 const char* cmd = "listen";
681 if (qemud_channel_send(qdev->qchanfd, cmd, strlen(cmd)) < 0) {
682 ALOGE("cannot write fingerprint 'listen' to host");
683 goto done_quiet;
684 }
685
686 int comm_errors = 0;
687 struct pollfd pfd = {
688 .fd = qdev->qchanfd,
689 .events = POLLIN,
690 };
691 while (1) {
692 int size = 0;
693 int fid = 0;
694 char buffer[MAX_COMM_CHARS] = {0};
695 bool disconnected = false;
696 while (1) {
697 if (getListenerState(qdev) == STATE_EXIT) {
698 ALOGD("Received request to exit listener thread");
699 goto done;
700 }
701
702 // Reset revents before poll() (just to be safe)
703 pfd.revents = 0;
704
705 // Poll qemud channel for 5 seconds
706 // TODO: Eliminate the timeout so that polling can be interrupted
707 // instantly. One possible solution is to follow the example of
708 // android::Looper ($AOSP/system/core/include/utils/Looper.h and
709 // $AOSP/system/core/libutils/Looper.cpp), which makes use of an
710 // additional file descriptor ("wake event fd").
711 int nfds = poll(&pfd, 1, 5000);
712 if (nfds < 0) {
713 ALOGE("Could not poll qemud channel: %s", strerror(errno));
714 goto done;
715 }
716
717 if (!nfds) {
718 // poll() timed out - try again
719 continue;
720 }
721
722 // assert(nfds == 1)
723 if (pfd.revents & POLLIN) {
724 // Input data being available doesn't rule out a disconnection
725 disconnected = pfd.revents & (POLLERR | POLLHUP);
726 break; // Exit inner while loop
727 } else {
728 // Some event(s) other than "input data available" occurred,
729 // i.e. POLLERR or POLLHUP, indicating a disconnection
730 ALOGW("Lost connection to qemud channel");
731 goto done;
732 }
733 }
734
735 // Shouldn't block since we were just notified of a POLLIN event
736 if ((size = qemud_channel_recv(qdev->qchanfd, buffer,
737 sizeof(buffer) - 1)) > 0) {
738 buffer[size] = '\0';
739 if (sscanf(buffer, "on:%d", &fid) == 1) {
740 if (fid > 0 && fid <= MAX_FID_VALUE) {
741 switch (qdev->listener.state) {
742 case STATE_ENROLL:
743 send_enroll_notice(qdev, fid);
744 break;
745 case STATE_SCAN:
746 send_scan_notice(qdev, fid);
747 break;
748 default:
749 ALOGE("fingerprint event listener at unexpected "
750 "state 0%x",
751 qdev->listener.state);
752 }
753 } else {
754 ALOGE("fingerprintid %d not in valid range [%d, %d] and "
755 "will be "
756 "ignored",
757 fid, 1, MAX_FID_VALUE);
758 continue;
759 }
760 } else if (strncmp("off", buffer, 3) == 0) {
761 // TODO: Nothing to do here ? Looks valid
762 ALOGD("fingerprint ID %d off", fid);
763 } else {
764 ALOGE("Invalid command '%s' to fingerprint listener", buffer);
765 }
766
767 if (disconnected) {
768 ALOGW("Connection to qemud channel has been lost");
769 break;
770 }
771 } else {
772 ALOGE("fingerprint listener receive failure");
773 if (comm_errors > MAX_COMM_ERRORS)
774 break;
775 }
776 }
777
778 done:
779 ALOGD("Listener exit with %d receive errors", comm_errors);
780 done_quiet:
781 close(qdev->qchanfd);
782 return NULL;
783 }
784
fingerprint_close(hw_device_t * device)785 static int fingerprint_close(hw_device_t* device) {
786 ALOGD("----------------> %s ----------------->", __FUNCTION__);
787 if (device == NULL) {
788 ALOGE("fingerprint hw device is NULL");
789 return -1;
790 }
791
792 qemu_fingerprint_device_t* qdev = (qemu_fingerprint_device_t*)device;
793 pthread_mutex_lock(&qdev->lock);
794 // Ask listener thread to exit
795 qdev->listener.state = STATE_EXIT;
796 pthread_mutex_unlock(&qdev->lock);
797
798 pthread_join(qdev->listener.thread, NULL);
799 pthread_mutex_destroy(&qdev->lock);
800 free(qdev);
801
802 return 0;
803 }
804
fingerprint_open(const hw_module_t * module,const char __unused * id,hw_device_t ** device)805 static int fingerprint_open(const hw_module_t* module, const char __unused *id,
806 hw_device_t** device)
807 {
808
809 ALOGD("----------------> %s ----------------->", __FUNCTION__);
810 if (device == NULL) {
811 ALOGE("NULL device on open");
812 return -EINVAL;
813 }
814
815 qemu_fingerprint_device_t* qdev = (qemu_fingerprint_device_t*)calloc(
816 1, sizeof(qemu_fingerprint_device_t));
817 if (qdev == NULL) {
818 ALOGE("Insufficient memory for virtual fingerprint device");
819 return -ENOMEM;
820 }
821
822
823 qdev->device.common.tag = HARDWARE_DEVICE_TAG;
824 qdev->device.common.version = HARDWARE_MODULE_API_VERSION(2, 1);
825 qdev->device.common.module = (struct hw_module_t*)module;
826 qdev->device.common.close = fingerprint_close;
827
828 qdev->device.pre_enroll = fingerprint_pre_enroll;
829 qdev->device.enroll = fingerprint_enroll;
830 qdev->device.post_enroll = fingerprint_post_enroll;
831 qdev->device.get_authenticator_id = fingerprint_get_auth_id;
832 qdev->device.set_active_group = fingerprint_set_active_group;
833 qdev->device.authenticate = fingerprint_authenticate;
834 qdev->device.cancel = fingerprint_cancel;
835 qdev->device.enumerate = fingerprint_enumerate;
836 qdev->device.remove = fingerprint_remove;
837 qdev->device.set_notify = set_notify_callback;
838 qdev->device.notify = NULL;
839
840 // init and create listener thread
841 pthread_mutex_init(&qdev->lock, NULL);
842 if (pthread_create(&qdev->listener.thread, NULL, listenerFunction, qdev) !=
843 0)
844 return -1;
845
846 // "Inheritance" / casting
847 *device = &qdev->device.common;
848
849 return 0;
850 }
851
852 static struct hw_module_methods_t fingerprint_module_methods = {
853 .open = fingerprint_open,
854 };
855
856 fingerprint_module_t HAL_MODULE_INFO_SYM = {
857 .common = {
858 .tag = HARDWARE_MODULE_TAG,
859 .module_api_version = FINGERPRINT_MODULE_API_VERSION_2_1,
860 .hal_api_version = HARDWARE_HAL_API_VERSION,
861 .id = FINGERPRINT_HARDWARE_MODULE_ID,
862 .name = "Emulator Fingerprint HAL",
863 .author = "The Android Open Source Project",
864 .methods = &fingerprint_module_methods,
865 },
866 };
867