| # biod: Biometrics Daemon |
| |
| ## Introduction |
| |
| The biometrics daemon (biod for short) handles pulling in biometrics data from |
| Chrome OS device sensors, like a fingerprint scanner, and processing the data |
| using closed and open source userspace drivers. In addition, it is Chrome's |
| point of contact for enrolling these biometric data and for unlocking the device |
| upon successful authentication. |
| |
|  |
| |
| ## Installation and Basic Usage |
| |
| If your board overlay doesn't already install biod for you, these instructions |
| apply if you'd like to install it manually. All these command run inside the |
| CrOS chroot, unless otherwise noted. |
| |
| 1. Add a line with **USE="${USE} biod"** in the make.conf file of your overlay |
| (i.e. ~/trunk/src/overlays/overlay-${BOARD}/make.conf inside the CrOS |
| chroot). |
| 2. Cros work on start the biod: **cros_workon-${BOARD} start biod** |
| 3. Build: **cros_workon_make --board=${BOARD} --install biod** |
| 4. Deploy: **cros deploy ${DUT_IP_ADDR} biod** |
| 5. On the device: **start biod** |
| |
| (TEMPORARY, as of 12/21/2016) A few other things worth checking: |
| |
| 1. In **(dut) /etc**, check that both **passwd** and **group** file contain |
| **biod**. If not, copy both files from **(chroot) /build/${BOARD}/etc**. |
| |
| Assuming you don't see any errors up to this point, you can confirm everything |
| is running with the following diagnostic tests. Each of these is run on the CrOS |
| device your are testing with. |
| |
| 1. Check for biod log files under /var/log/biod/biod.LATEST (this one is opened |
| by the biod process) or /var/log/biod.out (this one is the stdout of biod |
| redirected by upstart/init). |
| 2. Check that **dbus-send --system --dest=org.freedesktop.DBus |
| --type=method_call --print-reply /org/freedesktop/DBus |
| org.freedesktop.DBus.ListNames** returns an array with |
| "org.chromium.BiometricsDaemon" in it. If this command fails entirely, your |
| DBus daemon is broken. If the BiometricsDaemon entry is missing, biod is not |
| connected to the DBus, likely because it lacked permissions to claim the bus |
| name or it crashed. |
| 3. Check the output of **biod_client_tool list <hash of user id>**. It should |
| show you all biometric devices and their enrollments for a specific user. If |
| that command doesn't exist, your biod deployment is broken, perhaps because |
| it's old. If the command does run but has errors resembling |
| "ServiceUnknown", it failed to connect to biod for some reason. If you see |
| proper output but the biometric device you expected to be there is missing, |
| there is likely some kind of error in the logs mentioned above you should |
| check. |
| |
| You should always see the FakeBiometric device and you can use that for |
| exercising biod without requiring any special biometric hardware. The |
| "biometric" device in this case is emulated with a tool called |
| **fake_biometric_tool** that should be installed along with biod. Use that in |
| combination with **biod_client_tool enroll** and **biod_client_tool |
| authenticate** to check that the DBus communication is working properly. If you |
| have a real biometric device you'd like to test with biod, those |
| **biod_client_tool** commands should still work with your actual biometric |
| device, without requiring any usage of the fake biometric suite. See those |
| commands' associated **--help** for more information on their usage. |
| |
| ## D-Bus API |
| |
| Service Name: org.chromium.BiometricsDaemon |
| |
| **Root Object: **/org/chromium/BiometricsDaemon |
| |
| The root object implements the org.freedesktop.DBus.ObjectManager interface |
| which should be used to enumerate the available Biometric devices. Each |
| Biometric device implements the org.chromium.BiometricsDaemon.BiometricsManager |
| interface, which is used to retrieve previously made records or to start an |
| Enroll or Authenticate session. Enroll sessions are for making new records. |
| Authenticate sessions are for authenticating scanned biometric data against |
| those previously made records. Each session object is useful for ending the |
| session, but signals still go through the BiometricsManager object to avoid a |
| race condition between starting a session and connecting to the session's |
| signals. Something to note about the session objects is that they will |
| automatically be ended when the D-Bus client that created them (whomever called |
| StartEnrollSession or StartAuthSession). This is to prevent the |
| BiometricsManager from entering a stuck state in case the client crashes and |
| nobody comes around to end the session. This shouldn't be an issue unless one |
| expects the session to continue after the D-Bus client disconnects, for example |
| while testing out biod using dbus-send or other single shot command line dbus |
| tool. Each BiometricsManager can have only one session running concurrently. |
| |
| The 'UINT32 scan_result' values are meant to be instructions to the user on how |
| to get a better scan. They are as follows (Note: Pretty much ripped off from |
| AOSP's fingerprint_acquired_info in fingerprint.h) |
| |
| * 0 = Success (the sensor captured good data) |
| * 1 = Partial (sensor needs more data) |
| * 2 = Insufficient (too little detail for recognition) |
| * 3 = Sensor Dirty |
| * 4 = Too Slow (tell user to speed up) |
| * 5 = Too Fast (tell user to slow down) |
| * 6 = Immobile (tell user to move a little to get more data) |
| |
| **Interfaces:** org.chromium.BiometricsDaemon.BiometricsManager |
| |
| Methods StartEnrollSession(in STRING user_id, in STRING label, out OBJECTPATH |
| enroll_session) |
| |
| The user_id refers to the sanitized user name returned by |
| [SanitizeUserName](https://chromium.googlesource.com/aosp/platform/external/libbrillo/+/release-R56-9000.B/brillo/cryptohome.h#50) |
| in libbrillo. |
| |
| The label is an arbitrary string chosen to be human readable by the user. |
| |
| The returned enroll object path implements the |
| org.chromium.BiometricsDaemon.EnrollSession interface, but EnrollScanDone and |
| SessionFailed signals still come from this BiometricsManager. GetRecords(out |
| ARRAY<OBJECTPATH> records) |
| |
| Each returned object path implements the org.chromium.BiometricsDaemon.Record |
| interface. DestroyAllRecords() StartAuthSession(out OBJECTPATH auth_session) |
| |
| The returned object path implements the |
| org.chromium.BiometricsDaemon.AuthSession interface, but AuthScanDone and |
| SessionFailed signals still come from this BiometricsManager. Signals |
| EnrollScanDone(UINT32 scan_result, BOOL complete) |
| |
| If complete is true, the enrollment was successfully finished and saved |
| |
| AuthScanDone(UINT32 scan_result, std::unordered_map<std::string, |
| std::vector<std::string>> matches) |
| |
| The returned matches are a map from user id to a list of biometric record ids. |
| The user ids are the same ones given to StartEnrollSession in previous enroll |
| sessions. Each user in the list have one or more records that indicate a match. |
| Note that a piece of biometric data could be registered multiple times under the |
| same or different users. SessionFailed() |
| |
| General failure of enroll session and/or authenticate session that can not be |
| recovered from Properties UINT32 Type |
| |
| Type has one of the following values: |
| |
| * 0 = Unknown |
| * 1 = Fingerprint |
| |
| org.chromium.BiometricsDaemon.AuthSession Methods End() |
| |
| Ends the authenticate session and destroys this object path. Generally, the |
| client should call this at some point because authentication sessions do not end |
| on their own, unless there is some error. |
| |
| org.chromium.BiometricsDaemon.EnrollSession Methods Cancel() |
| |
| Ends the enroll session without storing the enrollment and destroys this object |
| path. Generally, the client **should not** call this as the Enroll session will |
| end automatically once enough data is collected. Exceptions to this rule being |
| that there was some error on the client side, the user explicitly canceled the |
| session, or the client has determined the user to have given up, perhaps after |
| some timeout has elapsed. |
| |
| org.chromium.BiometricsDaemon.Record Methods Remove() |
| |
| Deletes this record object from memory and persistent storage. It will no longer |
| participate in any future Authenticate sessions. SetLabel(in STRING label) |
| |
| Sets the human readable label of this Record object. Properties STRING Label |
| |
| Read only property that gets the previously set (by either StartEnrollSession or |
| SetLabel) human readable label of this record object. |
| |
| **Example Usage** |
| |
| The symbol **<-** means chrome sends the command to |
| org.chromium.BiometricsDaemon The symbol **->** is either a response or a signal |
| from org.chromium.BiometricsDaemon |
| |
| 1. Logged in user clicks enroll in UI: |
| <- Object:/org/chromium/BiometricsDaemon |
| Method:org.freedesktop.DBus.ObjectManager.GetManagedObjects -> \[ |
| "/org/chromium/BiometricsDaemon/BiometricsManager0" \] <- |
| Object:/org/chromium/BiometricsDaemon/BiometricsManager0 |
| Method:org.chromium.BiometricsDaemon.BiometricsManager.StartEnrollSession "<user |
| id hash>" "Data 1" -> |
| "/org/chromium/BiometricsDaemon/BiometricsManager0/EnrollSession" |
| |
| 2. User presses finger onto sensor |
| |
| -> org.chromium.BiometricsDaemon.BiometricsManager.EnrollScanDone (Success) |
| false |
| |
| 3. Chrome UI shows encouraging message about that scan to user 4. User presses |
| finger again but too quickly |
| |
| -> org.chromium.BiometricsDaemon.BiometricsManager.EnrollScanDone (Too Fast) |
| false |
| |
| 5. Chrome UI shows a stern message about how the user's finger is too fast. |
| |
| 6. \[...\] Continued until biod determines there is enough data |
| |
| -> org.chromium.BiometricsDaemon.BiometricsManager.EnrollScanDone (Success) true |
| |
| 7. Chrome displays successful enrollment message 8. Logged in user locks screen |
| |
| <- Object:/org/chromium/BiometricsDaemon/BiometricsManager0 |
| Method:org.chromium.BiometricsDaemon.BiometricsManager.StartAuthSession -> |
| /org/chromium/BiometricsDaemon/BiometricsManager0/AuthSession |
| |
| 9. User does a scan with dirty sensor and lock screen informs the user of this |
| |
| -> org.chromium.BiometricsDaemon.BiometricsManager.AuthScanDone (Sensor Dirty) |
| \[empty array\] |
| |
| 10. User cleans sensor and tries again with success \*/ |
| |
| -> org.chromium.BiometricsDaemon.BiometricsManager.AuthScanDone (Success) |
| \["unordered_map<string user_id, vector<string record_id>>"\] |
| |
| 11. Lock screen lets user in |