goodixtls55x4: support GF3268 (fw _10056) sensors, fix PSK provisioning + TLS handshake - #3
Open
jedbillyb wants to merge 14 commits into
Open
goodixtls55x4: support GF3268 (fw _10056) sensors, fix PSK provisioning + TLS handshake#3jedbillyb wants to merge 14 commits into
jedbillyb wants to merge 14 commits into
Conversation
doctest ships header-only with no pkg-config file on some distros (e.g. Void Linux), which makes the required dependency lookup fail and blocks meson setup for the whole project. Mark it not-required and only build the sigfm-tests executable when doctest is found, so the library still configures while users who have doctest keep the test target.
The firmware check required the exact string GF3268_RTSEC_APP_10041 and rejected otherwise-identical sensors shipping a newer minor revision (e.g. GF3268_RTSEC_APP_10056). Compare against the GF3268_RTSEC_APP_ prefix so the whole family is accepted.
The activation SSM only read the device PMK hash and failed if it did not match goodix_55x4_psk_0. A sensor last provisioned by another OS (e.g. Windows) reports a different hash and could never activate. Follow goodix-fp-dump's approach: when the stored hash differs, write the known white-box PSK (flags 0xbb010003) via a new ACTIVATE_WRITE_PSK state and continue. Once provisioned the device reports the expected hash, so the check passes and the write is skipped on subsequent activations.
goodix_send_preset_psk_write built its payload with the 12-byte GoodixPresetPsk struct but never initialised the trailing offset field, sending garbage on the wire, and passed sizeof(payload) (the pointer size, 8) plus length as the protocol length, truncating the key by the difference. The device therefore stored a wrong, non-deterministic PMK hash. Build the payload explicitly as flags + length + psk and send the correct total length.
The TLS server used cipher list "ALL", which excludes PSK cipher suites, and on modern OpenSSL the default security level rejects the PSK ciphers the sensor offers, so SSL_accept failed with "cipher operation failed". Set "PSK:@SECLEVEL=0" on the sensor's TLS context and SSL object. This only affects the local in-process TLS-PSK channel to the fingerprint sensor (a socketpair), not any other OpenSSL usage.
Raise the minimum match count from 5 to 15, tighten Lowe's ratio from 0.75 to 0.70, and raise the goodixtls55x4 bz3 match-score threshold from 24*3 to 24*5 so different fingers are less likely to be accepted. On a 55b4 unit the enrolled finger scores ~579 and a different finger scores 0 against the bz3 threshold. These values are subjective and this commit is separable from the rest of the series.
pam_fprintd deactivates and re-verifies on every failed scan, and the driver was running the full activate sequence (chip enable, fw check, PSK read, reset, MCU config) plus a fresh TLS handshake on each one, with a sleep + TLS shutdown on the way out. That down-up cycle was ~3s per retry. Track an "active" (warm) flag: set it once the TLS session is up, make deactivate a no-op that completes immediately, and make activate skip the whole sequence + handshake while warm (reusing the cached background frame too). The real teardown still happens on device close (dev_deinit), and the flag is reset on open/close so each fresh claim cold-handshakes once. Result: only the first scan per claim pays the handshake; subsequent retries are near-instant.
…ies" This reverts commit d10eb07.
The binding constraint on a marginal press was sigfm's min_match, not bz3_threshold: sigfm_match_score() returns 0 outright when fewer than min_match keypoints survive the ratio test, or when fewer than min_match consistent angle pairs are found, so bz3_threshold never gets consulted. Lowering bz3 alone had stopped helping for that reason. sigfm min_match 15 -> 10 (hard keypoint/angle floor) sigfm distance_match 0.70 -> 0.78 (Lowe ratio, accept more matches) bz3_threshold 24*5 -> 16 (final score gate) nr_enroll_stages 10 -> 24 (restores the tuned value) nr_enroll_stages is restored to 24 to match the existing enrolled template, so no re-enroll is required. bz3/min_match/distance are verify-time only. These constants were previously carried as uncommitted working-tree edits and were lost; committing them so a checkout cannot silently revert to the finicky values.
Still rejecting too many genuine presses at min_match=10. Reader contention was ruled out (fprintd-verify blocks waiting for a finger rather than failing to claim), so the matcher is the limiter. sigfm min_match 10 -> 6 sigfm distance_match 0.78 -> 0.82 bz3_threshold 16 -> 10 Verify-time only, no re-enroll. This trades false-reject for false-accept; if false accepts appear, raise min_match first.
Records what each knob does, which symptom each one addresses, how to measure real match scores instead of guessing, and the ldconfig backup trap that made a day of tuning silently no-op.
An unenrolled finger unlocked the machine at min_match=6 / distance=0.82 / bz3=10. Raise to 12 / 0.74 / 48: still well short of the 15 / 0.70 / 120 that rejected too many genuine presses, but no longer accepting the wrong finger. Record both observed points in TUNING.md so neither has to be rediscovered. Also re-apply the warm TLS session reverted in 0d1081f, with the auto-recovery it was missing. The driver tore down TLS and re-ran the full activate sequence on every pam_fprintd retry -- about 3s per attempt, which is the delay after a wrong finger. It now stays warm within a claim. The original was reverted because a warm session goes stale when the sensor re-enumerates after idle, so every later scan failed instantly and looped forever. scan_complete now clears the warm flag on any scan failure, so a stale session costs one cold re-activate and heals itself.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Makes the goodixtls55x4 driver work end-to-end on a
27c6:55b4sensor reporting firmwareGF3268_RTSEC_APP_10056that was previously provisioned by Windows, built against OpenSSL 3.x (Void Linux). Out of the box activation failed at every stage; each fix is a separate commit.sigfm-testsconditional on doctest. doctest ships header-only with no pkg-config file on some distros, so therequiredlookup fails and blocksmeson setup. Marked not-required and gated the test target ondoctest.found(), so the library configures without it while people who have doctest keep the tests.GF3268_RTSEC_APP_family. The check required exactly_10041and rejected otherwise-identical sensors on a newer minor revision (_10056). Now compares the prefix.flags 0xbb010003) and continue. Once provisioned the check matches and the write is skipped.goodix_send_preset_psk_write. This function appears never to have been exercised: it used the 12-byteGoodixPresetPskstruct leaving theoffsetfield uninitialised (garbage on the wire), and passedsizeof(payload)(pointer size, 8) as the length, truncating the key. Reframed asflags + length + payload. Standalone commit, independent of the 55b4 work."ALL"excludes PSK suites and modern OpenSSL's default security level rejects them, soSSL_acceptfailed with "cipher operation failed". Set"PSK:@SECLEVEL=0". This applies only to the in-process TLS-PSK channel to the sensor (a localsocketpair); it is not a global OpenSSL or system-wide change and does not affect any other TLS.min_match5→15, Lowe's ratio 0.75→0.70, bz3 threshold 24×3→24×5. On my unit the enrolled finger scores ~579 and a different finger scores 0 against the threshold.Tested: full enroll + verify via the example binaries and via
fprintd(TTY login + swaylock) on Void Linux.