{"id":50974352,"url":"https://github.com/alexys829/elan-0c77-libfprint","last_synced_at":"2026-06-19T06:01:59.831Z","repository":{"id":364357269,"uuid":"1267564632","full_name":"Alexys829/elan-0c77-libfprint","owner":"Alexys829","description":"Make the ELAN 04f3:0c77 (ELAN:ARM-M4) fingerprint reader work on Linux — libfprint elanmoc patches, prebuilt .debs and a guide. Tested on ASUS ExpertBook / Ubuntu 26.04.","archived":false,"fork":false,"pushed_at":"2026-06-12T17:16:02.000Z","size":411,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-06-12T19:10:35.430Z","etag":null,"topics":["asus-expertbook","elan","elanmoc","fingerprint","fprintd","libfprint","linux","match-on-chip","ubuntu"],"latest_commit_sha":null,"homepage":null,"language":"Shell","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"lgpl-2.1","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Alexys829.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-06-12T16:52:05.000Z","updated_at":"2026-06-12T17:15:49.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/Alexys829/elan-0c77-libfprint","commit_stats":null,"previous_names":["alexys829/elan-0c77-libfprint"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/Alexys829/elan-0c77-libfprint","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Alexys829%2Felan-0c77-libfprint","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Alexys829%2Felan-0c77-libfprint/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Alexys829%2Felan-0c77-libfprint/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Alexys829%2Felan-0c77-libfprint/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Alexys829","download_url":"https://codeload.github.com/Alexys829/elan-0c77-libfprint/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Alexys829%2Felan-0c77-libfprint/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34519052,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-19T02:00:06.005Z","response_time":61,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["asus-expertbook","elan","elanmoc","fingerprint","fprintd","libfprint","linux","match-on-chip","ubuntu"],"created_at":"2026-06-19T06:01:57.973Z","updated_at":"2026-06-19T06:01:59.815Z","avatar_url":"https://github.com/Alexys829.png","language":"Shell","funding_links":[],"categories":[],"sub_categories":[],"readme":"# libfprint support for the ELAN `04f3:0c77` fingerprint sensor\n\n![status: working](https://img.shields.io/badge/status-working-brightgreen)\n![license: LGPL-2.1+](https://img.shields.io/badge/license-LGPL--2.1%2B-blue)\n![tested: Ubuntu 26.04](https://img.shields.io/badge/tested-Ubuntu%2026.04-orange)\n[![latest release](https://img.shields.io/github/v/release/Alexys829/elan-0c77-libfprint)](https://github.com/Alexys829/elan-0c77-libfprint/releases/latest)\n\nPatches that make the **ELAN `04f3:0c77`** fingerprint reader\n(\"ELAN:ARM-M4\", Match-on-Chip, firmware `0x312` / 3.18) work on Linux. The reader\nships in some **ASUS ExpertBook** laptops and is **not** supported by stock\nlibfprint. These patches teach libfprint's `elanmoc` driver to drive it: **enroll,\nverify and PAM fingerprint login all work**.\n\nTested on **Ubuntu 26.04 (resolute), libfprint 1.95.1+tod1**. The patches are small\nand re-apply cleanly on other versions — see [Build from source](#build-from-source).\n\n\u003e No proprietary blob is required. There is **no** `libfprint-2-tod1-elan` package\n\u003e (it has never existed in the Ubuntu archive); ignore any guide that tells you to\n\u003e install one.\n\n## Compatibility\n\n| Item | Value |\n|---|---|\n| USB ID | `04f3:0c77` |\n| Chip | ELAN:ARM-M4, Match-on-Chip |\n| Firmware | `0x312` (3.18) |\n| Laptop | ASUS ExpertBook (and likely siblings with the same module) |\n| Tested on | Ubuntu 26.04, libfprint `1.95.1+tod1` |\n| Other versions | Use [Build from source](#build-from-source) — the patches re-apply cleanly |\n\nThe prebuilt `.deb`s ([Releases](https://github.com/Alexys829/elan-0c77-libfprint/releases/latest)\nor [`prebuilt/`](prebuilt/)) match libfprint **1.95.1+tod1** only; on any other version,\nbuild from source.\n\n---\n\n## Table of contents\n\n- [Quick start](#quick-start)\n- [Install (prebuilt .deb)](#install-prebuilt-deb)\n- [Build from source](#build-from-source)\n- [Hold the packages (important)](#hold-the-packages-important)\n- [Enroll a finger and enable fingerprint login](#enroll-a-finger-and-enable-fingerprint-login)\n- [Increase the number of retries](#increase-the-number-of-retries)\n- [Fingerprint for sudo](#fingerprint-for-sudo)\n- [Keyring / password managers](#keyring--password-managers)\n- [Dual boot with Windows (important)](#dual-boot-with-windows-important)\n- [How it works](#how-it-works)\n- [Troubleshooting](#troubleshooting)\n- [Uninstall](#uninstall)\n- [Upstreaming](#upstreaming)\n- [Credits \u0026 license](#credits--license)\n\n---\n\n## Quick start\n\nIf you run **Ubuntu 26.04** (libfprint `1.95.1+tod1` — check with `dpkg -l libfprint-2-2`):\n\n```bash\n./install.sh            # installs the prebuilt .debs and holds them\nfprintd-enroll          # register a finger\nfprintd-verify          # should print: verify-match\nsudo pam-auth-update    # tick \"Fingerprint authentication\" for login/sudo\n```\n\nOn any other libfprint version, use [`./build.sh`](#build-from-source) instead.\n\n## Install (prebuilt .deb)\n\n**From a clone** — `install.sh` installs the two `.deb` files from\n[`prebuilt/`](prebuilt/), pins them with `apt-mark hold` so updates can't overwrite\nthem, and restarts `fprintd`:\n\n```bash\ngit clone https://github.com/Alexys829/elan-0c77-libfprint.git\ncd elan-0c77-libfprint\n./install.sh\n```\n\n**Without cloning** — grab the two packages from the\n[latest release](https://github.com/Alexys829/elan-0c77-libfprint/releases/latest)\nand install them directly:\n\n```bash\ngh release download -R Alexys829/elan-0c77-libfprint \\\n  -p 'libfprint-2-2_*.deb' -p 'libfprint-2-tod1_*.deb'\nsudo dpkg -i libfprint-2-2_*.deb libfprint-2-tod1_*.deb\nsudo apt-mark hold libfprint-2-2 libfprint-2-tod1\nsudo systemctl restart fprintd\n```\n\nThe prebuilt packages only match libfprint **1.95.1+tod1**. If your version differs,\n`dpkg` will refuse or the ABI won't match — build from source instead.\n\n## Build from source\n\nRobust on any release: it fetches your distro's libfprint source, re-applies the\npatches and rebuilds matching `.deb` files.\n\n```bash\n./build.sh                       # produces .debs in ~/elan-0c77-build/\nsudo dpkg -i ~/elan-0c77-build/libfprint-2-2_*.deb \\\n             ~/elan-0c77-build/libfprint-2-tod1_*.deb\nsudo apt-mark hold libfprint-2-2 libfprint-2-tod1\nsudo systemctl restart fprintd\n```\n\n`build.sh` enables `deb-src` sources, installs the build dependencies, applies the\nquilt patches from [`patches/`](patches/), and builds with the test suite disabled\n(the unrelated `udev-hwdb` test fails and would otherwise abort the build).\n\nSet `DEBEMAIL` / `DEBFULLNAME` first if you want your name in the changelog entry.\n\n## Hold the packages (important)\n\nWithout a hold, the next `apt upgrade` reinstalls the stock libfprint and the sensor\n**stops working**:\n\n```bash\nsudo apt-mark hold libfprint-2-2 libfprint-2-tod1\n```\n\nTo update libfprint later, `unhold`, upgrade, then rebuild from source and re-hold:\n\n```bash\nsudo apt-mark unhold libfprint-2-2 libfprint-2-tod1\n```\n\n## Enroll a finger and enable fingerprint login\n\n```bash\nfprintd-enroll          # press/lift the finger at each prompt (~10 times)\nfprintd-verify          # expect: Verify result: verify-match (done)\nsudo pam-auth-update    # tick \"Fingerprint authentication\" (space), then OK\n```\n\nAfter `pam-auth-update`, the graphical login, the lock screen and `sudo` accept the\nfingerprint, falling back to the password if you don't use it.\n\n## Increase the number of retries\n\nBy default the PAM profile allows **a single** attempt (`max-tries=1`). To raise it to\n5 permanently (survives package updates, because it edits the pam-auth-update template):\n\n```bash\nsudo sed -i 's/max-tries=1 timeout=10 # debug/max-tries=5 timeout=15/' /usr/share/pam-configs/fprintd\nsudo pam-auth-update --force\ngrep fprintd /etc/pam.d/common-auth      # verify: max-tries=5 timeout=15\n```\n\n`max-tries` = failed scans before falling back to the password; `timeout` = seconds to\nwait for a finger per request.\n\n## Fingerprint for sudo\n\nWorks automatically once `pam-auth-update` has enabled fingerprint auth: `sudo` includes\n`common-auth`, which contains `pam_fprintd`. Test it:\n\n```bash\nsudo -k \u0026\u0026 sudo echo \"authenticated by fingerprint\"\n```\n\n## Keyring / password managers\n\nUnlocking the **login keyring** (KWallet on KDE, GNOME Keyring on GNOME) with the\nfingerprint alone is **not possible by design**: the keyring is encrypted with a key\nderived from your *password*, and a fingerprint carries no such secret. If you log in\nwith the finger, the keyring stays locked until you type the password once.\n\nFor biometric unlock of a **password manager**, the ones that work on Linux are those\nwhose desktop app uses system authentication (polkit → PAM → fprintd), e.g.\n**Bitwarden** and **1Password** — the browser extension unlocks through the desktop app.\n**NordPass** does **not** offer biometric unlock on Linux (only Windows/macOS/mobile),\nso there it's master password / PIN only.\n\n## Dual boot with Windows (important)\n\nEvery time you use **Windows Hello**, Windows leaves the chip in *VBS WBF mode*\n(protected), in which any Linux verify fails with chip code `0xfd \"finger not enrolled\"`\n— even against a template Windows itself matches. The hardware is fine, the mode is\nwrong. The patches send `set_mode 0x00` (normal WBF) on every device open, so Linux\nself-corrects; if the first verify after Windows misbehaves, **just try again**.\n\nManual reset (needs the [elanpoc](https://github.com/depau/elanpoc) tool):\n\n```bash\n# 40 ff 14 = set-mode, 00 = normal WBF. Expected reply: \"40 00\".\nuv run elanfp raw -e 3 40 ff 14 00\n```\n\n## How it works\n\nThe chip speaks the `elanmoc` protocol, but firmware `0x312` uses a different opcode\nsubset from the upstream-supported `0c7d`+ sensors. The protocol was confirmed against\n[depau/elanpoc](https://github.com/depau/elanpoc), a userspace PoC that talks to the\nchip directly. Key differences handled by the patches:\n\n| Operation | Upstream elanmoc | This chip (`0c77`) |\n|---|---|---|\n| verify | `40 ff 73` | `40 ff 03` |\n| remove-all (clear) | `40 ff 98` | `40 ff 99` |\n| re-enroll check | `40 ff 22` | not supported → skipped when empty |\n| get-userid after match | `40 ff 73` | not supported → skipped, report match directly |\n| sensor mode at open / verify | set-mode `0x03` | set-mode **`0x00`** (normal WBF) |\n\nThe two non-obvious fixes:\n\n1. **Normal WBF mode.** Windows leaves the chip in VBS WBF mode where the on-chip\n   matcher refuses userspace verifies (`0xfd`). Sending set-mode (`40 ff 14`) value\n   `0x00` puts it back into normal mode so enroll/verify match.\n2. **No get-userid after match.** After a successful match the stock driver issues a\n   get-userid command to learn which finger matched; this FW doesn't implement it, so\n   the read times out after 5 s and then crashes\n   (`fpi_ssm_mark_failed: assertion 'machine != NULL' failed`). For this device the\n   on-chip match is authoritative, so the result is reported directly.\n\nThe PID is tagged `driver_data = ELANMOC_PROTO_V2`; every change is gated on that flag,\nso other ELAN PIDs are unaffected.\n\nSee [`patches/`](patches/) for the six quilt patches (order in\n[`patches/series`](patches/series)).\n\n## Troubleshooting\n\n- **`fprintd-verify` seems to hang** — it's waiting for a finger. Press and lift, more\n  than once if needed.\n- **Always \"no-match\" with the correct finger** — the chip is probably in VBS mode after\n  Windows; see [Dual boot](#dual-boot-with-windows-important). Restart `fprintd` or run\n  the manual reset.\n- **`Device was already claimed`** — a previous verify process is stuck:\n  `sudo systemctl restart fprintd`.\n- **Stopped working after `apt upgrade`** — the hold was dropped; reinstall the `.debs`\n  and re-run `apt-mark hold`, or rebuild with `build.sh`.\n- **Sensor missing from `lsusb`** — enable it in the BIOS/UEFI.\n\n## Uninstall\n\nRevert to the stock Ubuntu libfprint:\n\n```bash\n./uninstall.sh\n```\n\nThis removes the hold and reinstalls the official packages from the archive.\n\n## Upstreaming\n\nThese patches hardcode the behaviour behind a single PID flag. Proper upstreaming would\ngeneralise `ELANMOC_PROTO_V2` (mode + opcode subset) and submit it to\n[libfprint](https://gitlab.freedesktop.org/libfprint/libfprint). Contributions welcome.\n\n## Credits \u0026 license\n\n- Protocol reverse-engineering reference: [depau/elanpoc](https://github.com/depau/elanpoc)\n  and the `elanmoc2` work in [depau/libfprint](https://gitlab.freedesktop.org/depau/libfprint).\n- libfprint is **LGPL-2.1-or-later**; these patches modify that code and are provided\n  under the same license. See [LICENSE](LICENSE).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Falexys829%2Felan-0c77-libfprint","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Falexys829%2Felan-0c77-libfprint","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Falexys829%2Felan-0c77-libfprint/lists"}