Linux fingerprint support for the Focal-systems FT9201 USB reader
(2808:93a9, sold as a standalone Windows Hello dongle), as a
libfprint driver.
The sensor is a tiny 96×96 optical reader. libfprint's built-in matcher does a
poor job on an image that small, so this driver instead reuses FocalTech's own
matching engine — the ftWbioEngineAdapter.dll from their signed Windows
driver — running it natively on Linux with a small in-process PE loader. No Wine,
no Windows, no cloud.
This repo is also a reusable method, not just one driver. The technique — running a vendor's Windows matching engine natively on Linux, no Wine — generalizes to other "Windows Hello only" readers, including ones that ship an SDCP secure channel (the Synaptics/Goodix/ELAN/EgisTec-class crypto sensors), via the optional
src/crypto_shims.cmodule. The FT9201 is the worked example; the in-process loader, the WinBio bridge, and the crypto-bypass layer carry over to the next device. See PORTING.md for the step-by-step method and what to reuse as-is.
Working end-to-end on real hardware: enroll and verify through fprintd /
command-line tools, and in KDE/GNOME once installed. It matches your finger
using the vendor's real algorithm.
Developed and tested against
this exact reader (ASIN B0DK7LQZGH) —
the FT9348W variant of 2808:93a9.
Caveats:
- Tested only on that FT9348W variant of the
2808:93a9device. - The matcher is a proprietary blob we call into; we can't fix bugs inside it.
- x86-64 only (the DLL and loader are 64-bit).
- The USB init + firmware-boot sequence was reverse-engineered from FocalTech's own drivers; the 8051 MCU firmware is uploaded, then a specific register-config sequence starts it.
- Each capture (96×96) is center-cropped to the 64×80 the engine expects.
ft_engine.cis a ~450-line loader that mapsftWbioEngineAdapter.dllinto memory, provides the ~90kernel32functions it imports, sets up a fake Windows TEB, and calls the engine's WinBio interface for enroll/verify.- The loader maps code read-execute and data read-write from an in-memory file,
so no page is ever writable and executable. That means it runs under
fprintd's defaultMemoryDenyWriteExecutehardening — you do not have to disable any security settings.
See docs/how-it-works.md for the full technical writeup.
Build tools + libfprint's build dependencies. On Fedora/Nobara:
sudo dnf install git meson ninja-build gcc cabextract python3 \
glib2-devel gusb-devel nss-devel pixman-devel gobject-introspection-devel \
libgudev-devel systemd-devel
(Debian/Ubuntu: the equivalents — libglib2.0-dev libgusb-dev libnss3-dev libpixman-1-dev libgudev-1.0-dev libsystemd-dev, plus cabextract.)
git clone https://github.com/OMGrant/ft9201-libfprint
cd ft9201-libfprint
scripts/fetch-blobs.sh # pull the vendor DLL + MCU firmware (see note below)
scripts/build.sh # clone pinned libfprint, graft the driver in, build
Try it without installing anything:
FT9201_ENGINE_DLL=$PWD/blobs/ftWbioEngineAdapter.dll \
LD_LIBRARY_PATH=libfprint/build/libfprint \
libfprint/build/examples/enroll
Install it for KDE/GNOME/login (side-by-side; your distro's libfprint is left alone, no hardening disabled):
sudo scripts/install.sh
fprintd-enroll
Undo everything: sudo scripts/install.sh --uninstall.
This repo contains no proprietary binaries. Two files are FocalTech's and are
fetched from existing public sources at build time by scripts/fetch-blobs.sh:
| File | What it is | Where it comes from |
|---|---|---|
ftWbioEngineAdapter.dll |
the matching engine | FocalTech's signed Windows driver on the Microsoft Update Catalog |
FT9348W MCU firmware (src/ft9201_fw.h) |
8051 firmware the sensor runs | extracted (symbol FOCALFP_9348_FW_APP) from the public ft9201-static blob |
If either download URL has moved, you only need those two files:
ftWbioEngineAdapter.dll— search the Microsoft Update Catalog for "FocalTech Electronics Biometric" (driver 1.0.3.58, matches hardware IDUSB\VID_2808&PID_93A9). Download the.cab, extract withcabextract, and dropftWbioEngineAdapter.dllintoblobs/.- MCU firmware — get any copy of the FocalTech Linux libfprint blob that
contains the
FOCALFP_9348_FW_APPsymbol (e.g. fromft9201-static) and runpython3 scripts/extract-firmware.py <that-libfprint-2.so> src/ft9201_fw.h.
Then re-run scripts/build.sh.
- USB protocol originally reverse-engineered by banianitc/ft9201-fingerprint-driver.
- Firmware and the init/boot sequence cross-referenced against FocalTech's Linux blob via mrrbrilliant/ft9201-static.
- Built on libfprint.
The reusable method and crypto-sensor path additionally build on the work of:
- uunicorn — whose synaWudfBioUsb-sandbox and wine fork are the harness for tracing a vendor's Windows biometric driver under Wine, which is how a crypto sensor's command protocol gets recovered without a Windows box.
- Marco Trevisan (3v1n0), a libfprint maintainer — who pointed the way to that Wine-tracing approach, and whose push to improve libfprint's own matching upstream frames why the vendor-matcher route exists at all.
- championswimmer/libfprint-eh577 — prior art for the EgisTec EH577 sensor family.
This isn't the only approach — the alternatives differ mainly in how they reuse FocalTech's matcher (they all do; the tiny sensor rules out generic matching).
- Romk-a/ft9201-linux-setup — a
Debian/Ubuntu (Astra Linux) guide that installs FocalTech's prebuilt
proprietary Linux "TOD" driver (from
ryenyuku/libfprint-ft9201; Fedora
RPMs have existed too) and binary-patches its USB-ID table (
9338→93a9).- How it compares: that route is less work — install a
.deb, patch two bytes, no reverse-engineering. But it needs TOD-enabled libfprint (Debian/Ubuntu-family; not on stock Fedora/Arch), it replaces your entire systemlibfprintwith an old, fully-closed build, and you have to fight the package manager to keep it pinned. This project instead ships an open driver, installs side-by-side (your distro's libfprint is untouched), runs on mainline libfprint with no TOD, and loads only the isolated vendor matcher DLL — which is what all the reverse-engineering bought. - Short version: on Debian/Ubuntu, the TOD route is the easy button; on Fedora/Arch, or if you want it open and non-invasive, use this.
- How it compares: that route is less work — install a
- Kernel drivers exist (banianitc — the protocol reference this project reverse-engineered from, bm16ton/ft92010x9338) but they don't integrate with libfprint/fprintd, so there's no login/PAM support.
The proprietary Linux TOD driver those .deb/RPM packages redistribute appears to
have been a FocalTech/GPD release for the GPD Win 4 that was later pulled from
official distribution — which is why it now survives only as community re-hosts.
(Note also that some GPD Win 4 units ship a different sensor entirely, a Chipsailing
CS9711, not this FocalTech part.)
- championswimmer/libfprint-eh577
— a Linux driver effort for the EgisTec EH577 (
1c7a:0577), another press-type "Windows Hello only" reader (52×72 active sensor). Different vendor and USB protocol, but the same match-on-host shape: its Windows package ships a vendor engine adapter DLL (EgisTouchFPEngine0577.dll, no VBS enclave), so the method in PORTING.md applies to it too. - OMGrant/eh577-libfprint — this method carried end-to-end to the EgisTec EH577 and published as a working driver. The §3b crypto techniques were validated against its SDCP builds; the distributed driver targets a pre-SDCP Catalog build (a pure-software matcher — see §3b's note on build selection), enrolling and verifying real fingers on Linux.
The driver and loader (src/, scripts/) are LGPL-2.1-or-later, matching
libfprint. The FocalTech DLL and firmware are their own property and are not
distributed here — you fetch them yourself. This project is an interoperability
tool for hardware you own; it does not include or relicense any FocalTech code.
