Drop 'Regression: Issue #N' / 'Bug #N' numbering, 'dead while loop',
'the old code', 'This catches the bug where' and similar changelog-style
language from test comments. Keep concise descriptions of what each test
validates. Also simplify data-loader test headers and the verify
interrupt comment.
Remove ~400KB of compiled-in .inc blob files and replace with a runtime
data loader that reads HMAC-SHA256 verified .bin files from disk at
device open time.
New components:
- validity_data.h/c: Runtime data file loader with HMAC-SHA256 integrity
verification. Searches /usr/share/libfprint/validity/ and
/usr/local/share/libfprint/validity/ for per-device and common data
files. Skipped entirely in emulation mode.
Changes to existing code:
- validity.c: New OPEN_LOAD_DATA SSM state loads device and common data
files between firmware info reception and init sequence. Populates TLS
key pointers from loaded data. Frees data stores on close.
- validity_hal.h/c: Simplified device_table to vid/pid/flash_layout only
(all blob pointers and partition_sig removed from structs).
- validity_pair.c/h: Updated make_cert, build_partition_flash_cmd,
build_tls_flash to take data parameters instead of using compiled-in
arrays. Reset/DBE blob accessors use data store.
- validity_tls.c/h: Removed 4 static key arrays, added pointer fields
to ValidityTlsState populated from loaded data.
- validity_db.c/h, validity_fwext.c/h: Updated get_write_enable_blob
to take FpiDeviceValidity* and access data store.
- validity_enroll.c: Updated all 5 callers for new signatures.
Deleted files:
- validity_blobs_0090.inc, validity_blobs_0097.inc,
validity_blobs_009a.inc, validity_blobs_009d.inc (~400KB)
- validity_pair_constants.inc (~6KB)
Tests (171 total, all passing):
- 15 data loader tests covering: empty store, double-free safety,
valid/corrupt/too-small/nonexistent file loading, tag enum,
load_device with missing dir/missing mandatory file/valid files/
corrupt HMAC, load_common with missing/valid files, enroll
db_write_enable accessor with empty and populated stores.
- All existing unit and integration tests updated and passing.
The data files are distributed separately via the
libfprint-validity-data package.
Apply uncrustify formatting to all validity driver and test files
to pass the CI test_indent check.
Fix two pre-existing test failures:
- test-validity-capture: LED command blobs are 125 bytes, not 128
- test-validity-enroll: add 2-byte length prefix to test data to
match parser's expected format, fix empty-data assertion (parser
returns FALSE for data_len < 2)
All 41 tests pass, 0 failures.
Add init_hardcoded and init_clean_slate transmission to the open SSM.
Four new states (OPEN_SEND/RECV_INIT_HARDCODED, OPEN_SEND/RECV_INIT_
CLEAN_SLATE) between GET_FW_INFO and UPLOAD_FWEXT, matching the
python-validity send_init() flow. init_hardcoded is always sent;
clean_slate only when fwext is not loaded. Skipped in emulation mode.
Remove dead crt_hardcoded[] (420 bytes, G_GNUC_UNUSED) from
validity_tls.c — this CA cert data now lives exclusively in
validity_pair_constants.inc.
Expose enrollment response parser for unit testing:
- EnrollmentUpdateResult struct and ENROLLMENT_MAGIC_LEN moved to
validity.h
- parse_enrollment_update_response() and enrollment_update_result_clear()
no longer static
Remove in-tree doc/ directory — documentation lives in
../validity-artifacts/docs/.
Tests: 9 new enrollment parser test cases, 0 regressions.
Result: 41 OK, 0 Fail, 2 Skipped.
Add HAL (validity_hal.h/c) with per-device lookup table for 4 PIDs
(0090, 0097, 009a, 009d). Each entry holds init_hardcoded, clean_slate,
reset_blob, db_write_enable blobs and a flash layout with partition
table + RSA signature.
Add device pairing SSM (validity_pair.h/c) — a 30-state machine that
runs as a child of the open SSM when the sensor has no TLS partitions.
Phases: raw USB keygen + partition flash, TLS handshake, erase 5
partitions, write 4096-byte TLS flash image, reboot.
Integration:
- OPEN_PAIR state in open SSM (between FWEXT and TLS_READ_FLASH)
- Skipped in emulation, no-fwext, or already-paired cases
- Post-reboot returns FP_DEVICE_ERROR_REMOVED for fprintd retry
Migration:
- validity_db.c and validity_fwext.c now use HAL lookups
- Removed hardcoded validity_blob_dbe_009a.inc
Tests: 24 new test cases (10 HAL + 14 pairing), 0 regressions.
Result: 40 OK, 0 Fail, 2 Skipped.
Add core fingerprint operations: enrollment, verification, identification,
print listing, print deletion, and storage clearing.
New files:
- validity_db.h/c: On-chip template database operations — command builders
for all DB commands (0x45-0x4B, 0x47-0x48, 0x51, 0x5E, 0x60, 0x62, 0x63,
0x64, 0x68, 0x69, 0x6B), response parsers for DB info/user storage/user/
record value/record children/new record ID, identity builder (UUID→VCSFW
binary), finger data builder, and db_write_enable blob accessor.
- validity_enroll.c: 31-state enrollment SSM with interrupt-driven finger
detection (EP 0x83), capture command orchestration via build_cmd_02(),
enrollment session management (create/update/commit), DB record creation
(user + finger), and LED glow feedback.
- validity_verify.c: 17-state verify/identify SSM with match command
dispatching (cmd 0x5E for verify, cmd 0x60 for identify), 6-state list
SSM for enumerating enrolled prints via GPtrArray, 8-state delete SSM,
and clear_storage stub.
Modified files:
- validity.h: Added DB header include, 5 new state enums (CalibState,
EnrollState, VerifyState, ListState, DeleteState), new struct fields
for enrollment/verification/list/delete state, function declarations.
- validity.c: Replaced all operation stubs with real implementations,
added cleanup for new fields in dev_close, wired all FpDevice methods.
- meson.build: Added 3 new source files to driver.
- tests/meson.build: Added test-validity-db executable.
- tests/validity/custom.py: Updated feature assertions (STORAGE,
STORAGE_LIST, STORAGE_CLEAR now enabled).
Tests: 29 new unit tests in test-validity-db.c covering all command
builders, response parsers, identity/finger data builders, and blob
accessor. All 37 tests pass (0 fail, 2 skip).
Implement the capture command building infrastructure ported from
python-validity's sensor.py and timeslot.py. This provides all the
algorithms needed to construct sensor capture commands for calibration,
enrollment, and identification modes.
New components:
- TLV chunk parsing (split/merge) for capture programs
- Timeslot DSP instruction decoder (16 opcodes, 1-3 bytes each)
- Timeslot table patching (Call repeat multiplication, factory cal)
- Line Update Type 1 algorithm for 0xb5-class sensors
- build_cmd_02(): main capture command builder
- Factory bits parsing (subtag 3 cal values, subtag 7 cal data)
- Frame averaging with multi-line deinterlacing
- Calibration data processing (scale/accumulate/clip)
- Clean slate format with SHA256 verification
- Bitpack compression for factory calibration values
- Finger ID mapping (FpFinger <-> VCSFW subtype 1-10)
- LED control commands (glow_start_scan, glow_end_scan)
- CaptureProg lookup table for firmware 6.x type-1 devices
- OPEN_CAPTURE_SETUP state in the open SSM
27 unit tests covering all components.
Full test suite: 36 OK, 0 Fail, 2 Skipped.
Implement the firmware extension (fwext) upload module for
Validity/Synaptics VCSFW sensors. When the sensor reports no
firmware loaded (GET_FW_INFO returns status 0xB004), the driver
uploads the .xpfwext firmware file using the following sequence:
1. WRITE_HW_REG32 (0x08) to prepare hardware register
2. READ_HW_REG32 (0x07) to verify register state
3. Load .xpfwext file from filesystem search paths
4. For each 4KB chunk:
a. Send db_write_enable blob (encrypted auth token)
b. WRITE_FLASH (0x41) with chunk payload
c. CLEANUP (0x1A) to commit chunk
5. WRITE_FW_SIG (0x42) to upload RSA signature
6. GET_FW_INFO (0x43) to verify successful upload
7. REBOOT (0x05 0x02 0x00) to activate new firmware
Architecture: Uses the NULL-callback subsm pattern where SEND
states call vcsfw_cmd_send(self, ssm, cmd, len, NULL) and RECV
states read self->cmd_response_status/data directly. This avoids
the double-advance bug with fpi_ssm_start_subsm auto-advancing
the parent.
New files:
- validity_fwext.h: Structures, SSM state enum, API declarations
- validity_fwext.c: Upload SSM, file parser, command builders
- validity_blob_dbe_009a.inc: db_write_enable blob for 06cb:009a
- test-validity-fwext.c: 19 unit tests covering all pure functions
Modified files:
- validity.h: Add cmd_response_status field to FpiDeviceValidity
- validity.c: Add OPEN_UPLOAD_FWEXT state to open sequence
- vcsfw_protocol.c: Save status in cmd_receive_cb for RECV states
- meson.build: Add validity_fwext.c to driver sources
Test results: 34 OK, 0 Fail, 2 Skipped
Add a new "validity" driver for Validity/Synaptics fingerprint sensors
that use the VCSFW protocol (as opposed to BMKT). This is iteration 1
of a multi-phase effort to bring native libfprint support to these
widely-deployed sensors found in ThinkPad T480/T480s/T580/X1 Carbon
Gen6 and many other laptops.
This initial iteration implements:
- VCSFW command/response transport layer over USB bulk endpoints
- GET_VERSION command parsing (firmware version, product ID, build)
- Synchronous probe and async open/close state machines
- Stub implementations for enroll/verify/identify (return NOT_SUPPORTED)
- umockdev replay test with real hardware capture
Supported USB IDs (VCSFW protocol):
- 138a:0090 (Validity VFS7500)
- 138a:0097 (Validity VFS5011)
- 06cb:009a (Synaptics Metallica MIS Touch)
- 138a:009d (Validity VFS7552)
These were previously (incorrectly) claimed by the synaptics driver
which uses the BMKT protocol.
Re-record the umockdev USB capture to include the new
GOODIX_VERIFY_WAIT_FINGER_UP state's USB exchanges during
verify and identify operations.
Captured on a Goodix MOC sensor (27c6:609c, Framework Laptop 13)
with FP_DEVICE_EMULATION=1 as required by the test framework.
When memory sanitizers are set, tests may fail because we are indirectly
LD_PRELOAD'ing (through umockdev). While we could ensure that sanitizer
libraries are loaded first, it's just something we don't care because we
don't want to test the launcher wrappers themselves.
So, let's just ignore the link order and live with it
Valgrind tests may be slow, leading the devices to be considered hot.
We don't disable this for other tests, since we may still want to be
sure that the logic is fine for normal usage
On Chimera Linux, which uses FreeBSD's userland tools, the original call
fails with the following error:
mktemp: mkstemp failed on /tmp/libfprint-XXXXXX.hwdb: Invalid argument
Moving the X's to the end of the template passed to `mktemp` fixes the
error, and also works with GNU's `mktemp`.