diff --git a/README.md b/README.md index 3bbbbbd..a06e0a5 100644 --- a/README.md +++ b/README.md @@ -75,30 +75,46 @@ itself**, not only under emulation. ## Status -**The core is complete; the daemon does not run yet.** Everything was ported -out of the research harness that first made the sensor work (`utilities/fpta.c` -in the fp6 repo), one module at a time, each landing with its tests before the -next started. +**It works end to end through fprintd's own clients.** On the Fairphone 6, as a +systemd unit owning `net.reactivated.Fprint`: + +``` +fprintd-enroll -f right-index-finger user ten stages, enroll-completed +fprintd-list user - #0: right-index-finger +fprintd-verify user (wrong finger) verify-no-match, on the first press +fprintd-verify user (enrolled finger) verify-match, on the first press +``` + +Nothing in fprintd was modified; the daemon speaks its interface. | module | what it holds | |---|---| | `:Sfs` | the gpfile frame — the read/write offset split, the `O_TRUNC` guard, root mapping, path-traversal rejection | | `:Rpmb` | request/reply framing, the bytes-transferred out-parameter, JEDEC result codes, chunking, the one-time-programmable key guard | -| `:Ta` | command surface, the 740-byte event context, capture flags, SAVE_DATA masks, enrol/auth payloads, the error table, the verdict rule | -| `:Engine` | baseline calibration, touch edges, enrolment progress, and the accounting | +| `:Ta` | command surface, the 740-byte event context, capture flags, save masks, enrol/auth payloads, the error table, the verdict rule | +| `:Engine` | baseline calibration, touch edges, enrolment progress, the accounting | | `:Store` | the finger name map | +| `:Tee` | QTEE service/op numbers, the listener table, the 13-byte CBOR credentials blob | +| `:Sensor` | the pins, the timings, and the XPU guard | Every constant that was recovered by reverse-engineering carries where it came from, and the tests are written to fail if it is undone rather than to restate -it. Several replay real captures: two SFS containers off the phone, and three -recorded authentication runs. +it. Several replay real captures off the phone. -Next is the I/O shell — the TEE session, the sensor rail, the RPMB device and -the bus — which is the first part that cannot be validated without hardware. +Two policy decisions live in the daemon and both were forced by measurement. +Verification is judged **per press**: any matching frame wins, only rejections +is no-match — both correct presses in the acceptance run had rejected frames +before the one that matched, so a first-frame rule would have failed them. And +the shipped config sets `max_authentication_rescan_times` to 0, because at the +stock budget a wrong finger never yields a terminal frame and a PAM client +waits forever for the `verify-no-match` it needs. -The working reference enrols a finger, keeps it across a reboot, and matches it -with zero false accepts; the port exists to turn that into a service rather -than to rediscover it. +**Not done:** packaging (`provides="fprintd=…"` so this replaces the fprintd +daemon package while `fprintd-pam` stays), the shipped storage policy, polkit +(a caller-uid rule stands in), trustlet-side template removal (deletes drop the +name only), cleanup when a claiming client vanishes from the bus, and the +kernel config change — `CONFIG_QCOMTEE`, which selects the SHM bridge — that +gates any public image. ## Runtime dependencies, not carried here