Add 53xc family driver (confirmed working for USB PID 0x533c) - #76
Add 53xc family driver (confirmed working for USB PID 0x533c)#76daemonhorn wants to merge 1 commit into
Conversation
Reverse-engineered from the closed libfprint-tod blob shipped for Ubuntu/Canonical OEM images (libfprint-2-tod1-goodix, "53xc" TOD module), plus a live USB capture of that blob's own traffic against real 0x533c hardware. Reuses this repo's existing wire protocol (goodix.py) entirely -- only the model-specific constants (PSK, DEVICE_CONFIG, sensor dimensions) and three protocol-quirk workarounds are new. This chip doesn't reply with a fixed [ack][data] pair for reset, mcu_switch_to_fdt_mode, write_sensor_register, or mcu_get_image's ack -- responses were observed in both orders and sometimes duplicated. tolerant_* helpers classify each read by decoded command instead of assuming position, used only for those commands; everything else goes through the existing Device methods unmodified. Confirmed against real hardware for PID 0x533c only (produces a real, non-degenerate 108x88 image via run_533c.py). 0x530c/0x538c share the same firmware/command set per the same .so but weren't tested -- the five other named DEVICE_CONFIG templates found alongside "MilanFn" in that binary are documented but unused here. PSK writing is intentionally not implemented: this unit's PSK was already correctly provisioned from the factory, and its COMMAND_PRESET_PSK_WRITE_R success convention was found to be inverted relative to every other model in this repo (documented in the driver as a note for anyone implementing it later). Full methodology and static-analysis findings: https://github.com/daemonhorn/goodix-533c-re Closes/references goodix-fp-linux-dev#31.
Submodule now tracks daemonhorn/goodix-fp-dump's add-53xc-533c-support branch, carrying driver_53xc.py + run_533c.py -- a cleaned-up, consolidated version of this session's capture_full_milanfn.py, built to mirror the existing driver_53xd.py/driver_53x5.py conventions. Verified against real hardware again after the rewrite (fixed one regression: firmware_version()/check_psk() must not be called before this chip's first reset, same ordering-quirk root cause discovered earlier for other commands). Opened goodix-fp-linux-dev/goodix-fp-dump#76 and commented on issue #31 with a pointer to it. Updated README/NOTES to reflect the finished result instead of the original open-questions framing.
|
Closing this in favor of the existing, more complete work already open for this device: #75 (stacked on #72 and #73). I found this driver independently before searching PRs and only discovered the overlap after opening this one. #75 does everything this PR does and more -- it derives TLS session keys and decrypts application data in-process (no dependency on how Sorry for the noise -- didn't mean to duplicate effort. I've left a comment on #75 with a couple of findings from my own static analysis + live-capture work that might still be useful there (independent confirmation of PSK/sensor-size on a second physical unit, and a PSK-write ACK-convention quirk). Full writeup at https://github.com/daemonhorn/goodix-533c-re if useful. |
Summary
Adds
driver_53xc.py+run_533c.pyfor the Goodix "53xc" GTLS sensorfamily (USB PIDs
0x530c/0x533c/0x538c), reverse-engineered from theclosed
libfprint-tod-goodix-53xcblob shipped for Ubuntu/Canonical OEMimages, cross-checked against a live USB capture of that blob's own
traffic against real hardware.
Confirmed working end-to-end against real
0x533chardware:nop → reset → PSK check → TLS-PSK handshake → upload_config_mcu → mcu_switch_to_fdt_mode → write_sensor_register → mcu_get_image, decodingto a real, non-degenerate 108x88 image (no finger present -- this is the
sensor's calibration/"clear" read, same as the 53xd driver's
clear-0.pgmstep).
References/reopens #31 ("Device 27c6:538c compatibility?", closed
wontfix) --
0x538cand0x530cshare the same firmware/command set inthe same
.soper static analysis (five other namedDEVICE_CONFIGtemplates exist alongside the "MilanFn" one used here), but their PSK/
config constants weren't extracted or tested against real hardware, so
this PR only claims support for
0x533c.What's new vs. the existing model drivers
This chip reuses the repo's existing wire protocol (
goodix.py) as-is --only the model-specific constants are new, plus one real protocol quirk:
reset,mcu_switch_to_fdt_mode,write_sensor_register, andmcu_get_image's ACK do not arrive in the fixed[ack][data]order everyother model in this repo assumes -- this firmware was observed sending
both orders and sometimes duplicate packets.
driver_53xc.pyadds smalltolerant_*wrapper functions that classify each USB read by its decodedcommand rather than assumed position, used only for those four commands;
everything else (
nop,preset_psk_read,read_sensor_register,read_otp,upload_config_mcu, ...) goes through the existinggoodix.Devicemethods unmodified.goodix.pyitself is untouched.Also notable (documented as comments in the driver, not exercised by
default):
factory (confirmed via a live vendor-driver capture that never calls
COMMAND_PRESET_PSK_WRITE_R) -- so PSK writing isn't implemented here.If it's needed for another unit: this chip's
COMMAND_PRESET_PSK_WRITE_Rsuccess convention is inverted relative to every other model in this
repo (
message[0] == 0x01means success, not0x00).SENSOR_WIDTH/SENSOR_HEIGHT(108x88) were not found as a firmwareconstant via static analysis. They're strongly corroborated from the
live capture instead -- reshaping the decoded pixel data at each of 12
plausible width/height factorizations, only width=108 produces a
coherent 2D shape (a rounded vignette matching a capacitive sensor's
physical active area); every other candidate is pure banding with no 2D
structure. This also exactly matches
driver_53x5.py's ownSENSOR_WIDTH/SENSOR_HEIGHT, suggesting this sensor family may sharethat physical die. Flagged in-code as "likely, not certain."
Full write-up, static analysis, and the TLS/openssl debugging history
(including why
openssl s_serverneeds-ign_eofhere) is athttps://github.com/daemonhorn/goodix-533c-re -- happy to fold any of that
into this repo's own documentation if maintainers would find it useful
rather than just linking out.
Test plan
run_533c.pyagainst real27c6:533chardware; completeswithout exceptions and writes
clear-0.pgm.not blank/noise) across multiple repeated runs.
0x530c/0x538c, finger-present capture(only the no-touch calibration read was exercised).