Skip to content

Add driver for Goodix 53x5 series (27c6:5395, 27c6:5335, 27c6:5385)#35

Open
W3D3 wants to merge 6 commits into
goodix-fp-linux-dev:masterfrom
W3D3:goodix53x5-driver
Open

Add driver for Goodix 53x5 series (27c6:5395, 27c6:5335, 27c6:5385)#35
W3D3 wants to merge 6 commits into
goodix-fp-linux-dev:masterfrom
W3D3:goodix53x5-driver

Conversation

@W3D3
Copy link
Copy Markdown

@W3D3 W3D3 commented Apr 7, 2026

This PR adds a driver for the Goodix 53x5 fingerprint sensor family, covering the following USB IDs:

USB ID Device
27c6:5395 GF5288 HTSEC (confirmed working)
27c6:5335 GF3208 (same firmware protocol)
27c6:5385 GF5288 (same firmware protocol)

These sensors are found in a number of recent laptops and are currently listed as
unsupported in the hwdb whitelist. This driver adds full enroll and verify support.

Protocol overview

The sensor communicates over USB bulk transfers using a Goodix-proprietary framing
protocol. The notable aspects are:

  • GTLS (Goodix TLS): a TLS 1.2-style encrypted transport layer using a
    device-specific pre-shared key (PSK). The PSK is all-zero bytes on these consumer
    devices. Key derivation uses HMAC-SHA256 (TLS PRF style); image payloads are
    encrypted with AES-128-CBC.
  • Image encryption: the image payload uses an interleaved GEA + AES block
    structure (15 blocks). NSS is used for AES-CBC decryption and HMAC-SHA256.
  • 12-bit pixel depth: the sensor outputs 108×88 pixels at 12-bit depth packed
    as 6 bytes → 4 pixels.
  • Image upscaling: the raw 108×88 image is too small for MINDTCT to reliably
    find 10+ minutiae (required minimum for Bozorth3 matching). The image is upscaled
    2× to 216×176 using fpi_image_resize (pixman) before being handed to the
    minutiae detector.
  • FDT (Finger Detection Technology): hardware finger-on/finger-off detection
    using calibrated threshold values derived from per-device OTP data.
  • OTP calibration: DAC values, FDT delta thresholds and touch-code are parsed
    from the device's OTP region on every open, using a custom CRC-8.

Build dependencies

Two additional dependencies are required beyond the standard libfprint set:

  • nss: AES-128-CBC decryption and HMAC-SHA256 for the GTLS protocol (same as uru4000)
  • pixman-1: bilinear image upscaling via fpi_image_resize

The pixman-1 dependency is pulled in via the aes3k helper entry in
driver_helper_mapping in meson.build (the existing mechanism used by
aes3500/aes4000). A comment is added there to explain the rationale.

Testing

Tested on a Dell laptop with a 27c6:5395 sensor:

  • Full enroll (5 captures) completes successfully
  • Verify returns verify-match with a score consistently above threshold
  • PAM authentication (sudo, login, lock screen) works correctly

References

Based on the reference Python implementation by the goodix-fp-dump contributors:
https://github.com/goodix-fp-linux-dev/goodix-fp-dump


Note for reviewers:

  1. The aes3k / pixman dependency mechanism is a side-effect of the current
    helper mapping design. If preferred, meson.build could be extended with an
    explicit pixman helper entry - happy to do that as a follow-up or as part
    of this PR.
  2. Only 27c6:5395 has been directly tested. The 27c6:5335 and 27c6:5385 IDs use
    the same firmware protocol (confirmed from the reference implementation) but
    have not been tested with physical hardware.

W3D3 added 6 commits April 5, 2026 23:40
Add a new FpImageDevice driver for the Goodix 53x5 family fingerprint
sensor (USB ID 27c6:5395, silicon die GF5288 "HTSEC").

This is a raw-image-capture device using a proprietary GTLS encryption
protocol, distinct from the existing goodixmoc Match-on-Chip driver.

Protocol highlights:
- Device presents as CDC ACM; both interfaces must be claimed to detach
  the cdc_acm kernel driver, followed by a USB reset
- Every command receives an ACK (cat=0xB, cmd=0x0) before the reply
- GTLS handshake: 3-step PSK-based using HMAC-SHA256 P_SHA256 PRF,
  derives AES-128 key/IV, HMAC key and per-session counters
- Encrypted image: 8-byte header + 15 interleaved blocks (even=GEA
  stream cipher, odd=AES-128-CBC) + 32-byte HMAC-SHA256 trailer
- GEA CRC uses a custom byte-pair-swap u32 encoding (not standard LE)
- AES decryption uses NSS PK11 (same dependency as the uru4000 driver)
- Sensor: 108x88 pixels, 12-bit depth, PSK = all-zero 32 bytes

Initialization flow: ping -> firmware version -> reset -> chip ID ->
OTP (calibration params) -> PSK hash check/write -> GTLS handshake ->
config upload -> two calibration image captures (advancing the HMAC
server counter) -> FDT cross-check -> sleep.

Capture flow: EC power on -> FDT finger-down arm -> wait for finger ->
manual FDT -> get image -> decrypt/decode -> report to libfprint.
- Upscale captured image 2× via fpi_image_resize so MINDTCT finds
  enough minutiae for Bozorth3 matching (≥10 required); set img_width
  and img_height to scaled dimensions; add GOODIX53X5_ENLARGE_FACTOR=2
  to proto header
- Add 'aes3k' helper to driver_helper_mapping so pixman-1 is linked
  (required by fpi_image_resize)
- Fix capture-loop race: report finger-off status in capture_ssm_done()
  after SSM teardown, not from inside the CAPTURE_EC_OFF_PARSE state
  handler, to avoid starting a new SSM before fpi_ssm_next_state()
  returns
- Remove /tmp file dumps of session key and encrypted image (security),
  remove verbose per-frame hex dumps of crypto material; keep concise
  per-message and per-handshake debug lines
Add a goodix53x5 section with 27c6:5335, 27c6:5385, and 27c6:5395
and remove those IDs from the 'Known unsupported devices' block.
The three USB IDs (27c6:5335, 27c6:5385, 27c6:5395) were still in the
whitelist_id_table[] of 'known unsupported' devices in
fprint-list-udev-hwdb.c. During the Nix build the test tool runs with
G_DEBUG=fatal-warnings, so the duplicate-ID warning becomes SIGTRAP
(exit 133) and the build fails. Remove the three IDs from the whitelist.

Also move the goodix53x5 section in autosuspend.hwdb to its correct
alphabetical position (before goodixmoc) and reorder entries to match
the id_table declaration order (5395, 5335, 5385).
- Remove INSTALL-GOODIX53X5.md (NixOS/personal-fork-specific content)
- Remove dead fdt_event_data field from _FpiDeviceGoodix53x5 struct
- Remove dead delta_img field from Goodix53x5CalibParams struct
- Fix broken reference URL: nickel-org/goodix-fp-dump → goodix-fp-linux-dev/goodix-fp-dump
- Remove verbose per-capture recv_buf byte dump from fp_dbg
- Remove per-message fp_dbg in goodix53x5_parse_message (fires on every ACK)
- Add comment in meson.build explaining why aes3k helper is used (pixman dependency)
Run scripts/uncrustify.sh to bring the four driver files in line with
the rest of the codebase style.
@W3D3 W3D3 changed the title Add support for the Goodix 53x5 driver goodix53x5: add driver for Goodix 53x5 series (27c6:5395, 27c6:5335, 27c6:5385) Apr 7, 2026
@W3D3 W3D3 changed the title goodix53x5: add driver for Goodix 53x5 series (27c6:5395, 27c6:5335, 27c6:5385) Add driver for Goodix 53x5 series (27c6:5395, 27c6:5335, 27c6:5385) Apr 7, 2026
@W3D3 W3D3 marked this pull request as ready for review April 8, 2026 14:18
@W3D3
Copy link
Copy Markdown
Author

W3D3 commented Apr 8, 2026

Full disclosure: This is vibe-coded and I am nowhere near good enough in C to critically judge the code, but I am pretty sure I am not the only one that has had enough of not having access to my fingerprint sensor on Linux that I wanted to share this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant