dump: fingerprint handoff, and the protocol is recovered
STATE moved to 2026-08-09. One instrument is waiting on a finger; everything else about the enrol lifecycle is reachable in RAM today.
This commit is contained in:
parent
34cc8e97f9
commit
b78342a337
2 changed files with 159 additions and 12 deletions
49
STATE.md
49
STATE.md
|
|
@ -4,10 +4,10 @@ Souveraine is an OS, an agent substrate, and the name of an agent.
|
|||
Ani + Aster = Annie (primary consciousness + subconscious = composite).
|
||||
Hard constraint everywhere: no GNOME or KDE library dependencies.
|
||||
|
||||
This repo is the umbrella: cross-repo docs, decisions, session dumps, and
|
||||
this state file. Component repos keep their own repo-local PAF/ docs; what
|
||||
crosses repo boundaries lives here. Update this file when component state
|
||||
moves; it is the resume anchor.
|
||||
This repo is the root: cross-repo docs, decisions, session dumps, and the
|
||||
canonical PAF device spine. Component repos hold code and a pointer back here;
|
||||
they do not keep a second living architecture. Update this file when component
|
||||
state moves; it is the resume anchor.
|
||||
|
||||
**Shell-surface migration checklist: `SHELL-SURFACES.md`.** Walk it before any
|
||||
substrate cutover (`ii` → `souveraine`, later `souveraine` → viewtop). The
|
||||
|
|
@ -18,9 +18,34 @@ stale the same way for the same reason. The packages are now cured
|
|||
archive, so `pacman -Sl souveraine-aarch64` is the manifest. The surface gap
|
||||
(a souveraine overlay host for the subconscious views) is still open.
|
||||
|
||||
Last updated: 2026-08-04 (viewtop now packages and publishes like everything
|
||||
else; window capture, titles and borders fixed; the accelerometer claim is
|
||||
gone).
|
||||
Last updated: 2026-08-09 (the fingerprint TA's command protocol is recovered;
|
||||
see below and `docs/DUMP-fingerprint-2026-08-09.md`).
|
||||
|
||||
## 2026-08-09 — fingerprint: the protocol is recovered
|
||||
|
||||
`fpctzappfingerprint` is not stripped, so its dispatch tables resolve to real
|
||||
function names. Eight targets; **10 is sensor, 11 is bio** and bio carries the
|
||||
whole enrol/identify/enumerate/delete lifecycle. Recovered statically from the
|
||||
vendor image on disk — no device, no Android, no Frida. Tables and wire format:
|
||||
`Pixel3Arch/docs/fpc-ta-protocol.md`.
|
||||
|
||||
TASK-44's remaining question — *does a finger raise an edge* — now has a direct
|
||||
instrument instead of a correlational one: target 10 command 1 is
|
||||
`fpc_ta_check_finger_lost`. `tools/fp-finger.py`, also at `~/fp-finger.py` on
|
||||
the phone. **It needs a human finger; that is the only reason it has not run.**
|
||||
|
||||
Storage is confined to targets 2 and 12, so targets 10 and 11 cannot block on a
|
||||
listener — the enrol lifecycle runs in RAM today, with persistence deferred.
|
||||
Keep target 2, target 12's remove path and target 5 (production test) off the
|
||||
daily driver: a parked TZ blocks every QSEECOM caller until reboot.
|
||||
|
||||
Five fingerprint tools that existed only on the phone since 2026-08-01 are now
|
||||
in `Pixel3Arch/tools/`.
|
||||
|
||||
Separate strand, same session: the SDM845 boot-chain exploit trio is evaluated
|
||||
in `Pixel3Arch/docs/secure-world-references.md`. blueline's `hyp` is
|
||||
Google-signed rather than QTI-signed, so EL2 is reachable per-boot over USB but
|
||||
never persistently.
|
||||
|
||||
## 2026-08-04 — on the phone, verified
|
||||
|
||||
|
|
@ -255,11 +280,11 @@ Branch `experimental/session-trust-phase1` @ `c96f95b`.
|
|||
(moved Jul 15; deletion committed `0f50a3e`).
|
||||
|
||||
### Pixel3Arch (`~/Projects/Pixel3Arch`)
|
||||
`main` @ `862202a`. Repo == phone for deployed config as of 2026-07-16.
|
||||
- Mic: hexagonrpcd now serves the ADSP audio PD (verified live — fluence/ECNS
|
||||
opens succeed at boot). Open blocker is the SLIM IRQ-read NACK loop
|
||||
(~1090 hits/boot); state in `PAF/audio.md`. Capture route moved to
|
||||
MultiMedia2.
|
||||
Implementation repo; this block is a 2026-07-16 deployment snapshot, not the
|
||||
current phone status. The living hardware record is `PAF/` here in
|
||||
SouveraineOS.
|
||||
- Audio now works: HiFi speaker/microphone, STT capture, and real two-way calls.
|
||||
The old SLIM failures and their fixes remain in `PAF/audio.md` as history.
|
||||
- MMS: works end-to-end via the `netsvcs` APN (`PAF/mms.md`). Open: mmsd-tng
|
||||
has session-autostart via hyprland.lua but no systemd unit.
|
||||
- USB: usb-signaller 0.3.1 built + staged; the RUNNING phone still uses
|
||||
|
|
|
|||
122
docs/DUMP-fingerprint-2026-08-09.md
Normal file
122
docs/DUMP-fingerprint-2026-08-09.md
Normal file
|
|
@ -0,0 +1,122 @@
|
|||
# DUMP — fingerprint, 2026-08-09
|
||||
|
||||
Handoff. TASK-44 is the owner and carries the design; this is what moved today
|
||||
and what to do first when you sit down.
|
||||
|
||||
## What moved
|
||||
|
||||
**The TA's command protocol is recovered.** `fpctzappfingerprint` is not
|
||||
stripped — every handler logs `__func__` — so its dispatch tables resolve to
|
||||
real names. Eight targets; the two that matter are **10 (sensor)** and
|
||||
**11 (bio)**, and bio carries the whole lifecycle: `begin_enrol`, `enrol`,
|
||||
`end_enrol`, `identify`, `get_template_ids`, `delete_template`,
|
||||
`set_active_fingerprint_set`, `load_empty_db`, `get_template_db_id`.
|
||||
|
||||
Full tables, wire format, method: **`Pixel3Arch/docs/fpc-ta-protocol.md`.**
|
||||
|
||||
Done statically, from `~/pixel3-work/los-vendor/vendor.img` with `debugfs`. No
|
||||
device, no Android, no Frida. The Frida-tracing plan from earlier in the
|
||||
session was unnecessary.
|
||||
|
||||
**It cross-checks against your own work.** The router's `-201` / `-210` /
|
||||
`-211` are `INPUT` / `CONFIG` / `NOT_INITIALIZED` in the table `fp-go.py`
|
||||
already carried from the HAL disassembly on 2026-08-01. Two binaries, two
|
||||
methods, weeks apart, same numbers.
|
||||
|
||||
**Two labels in TASK-44 were wrong.** Sensor command 3 is `wakeup_setup`
|
||||
("arm" is right in effect). Command 5 is **`deep_sleep`**, not "idle" — the
|
||||
part is asleep between events, not idling.
|
||||
|
||||
## Do this first
|
||||
|
||||
```
|
||||
ssh pixel
|
||||
sudo ~/fp-finger.py load 120 # or pass a resident app_id
|
||||
```
|
||||
|
||||
Arms once, then polls **target 10 command 1 `check_finger_lost`** at 10 Hz for
|
||||
two minutes. Touch whenever — no window to hit.
|
||||
|
||||
This answers the question TASK-44 has been stuck on since 2026-08-01. Every
|
||||
prior instrument counted edges and needed a human to vouch that a touch
|
||||
happened; this one asks the application. **A `ret` that moves only while your
|
||||
finger is on the reader is the answer.**
|
||||
|
||||
It brackets each query with the interrupt count, so the call's own edge is in a
|
||||
separate column from spontaneous ones — the 1444-event trap. If the `own`
|
||||
column accounts for everything, the sensor is not talking to you and you will
|
||||
see it immediately.
|
||||
|
||||
If `ret` never moves, try `qualify_capture` (10/4) next: the part may only
|
||||
report finger state during a capture rather than as a standing query.
|
||||
|
||||
## Then, in order
|
||||
|
||||
1. **RAM-only enrol and identify.** 11/6 `load_empty_db` → 11/9
|
||||
`set_active_fingerprint_set` (set id at `+12`) → 11/0 `begin_enrol` → 11/1
|
||||
`enrol` per capture → 11/2 `end_enrol` → 11/3 `identify`. Nothing persists
|
||||
yet, and nothing here can block.
|
||||
2. **Persistence.** Target 2 only, through a listener. See the safety note.
|
||||
3. **`souveraine-fpd`.** The daemon. TASK-44 §"Where it plugs in".
|
||||
|
||||
## Safety, and it is narrow
|
||||
|
||||
The application's only persistence is `qsee_fts_*`, and the call graph says
|
||||
**only targets 2 and 12 can reach it**. Targets 10 and 11 cannot, so neither
|
||||
can block on a listener.
|
||||
|
||||
- **Safe on the daily driver:** all of target 10, all of target 11.
|
||||
- **Not on the daily driver:** target 2 (fs) and target 12's `remove_file` —
|
||||
these can leave TZ parked, and a parked TZ blocks *every* QSEECOM caller
|
||||
until a reboot, not just yours. Target 5 is 19 production-test commands with
|
||||
a 529-byte payload and the build manifest lists `prodtestlib` and
|
||||
`sensor_settings`; treat it as the destructive group. Both want the spare.
|
||||
|
||||
`delete_template` and `load_empty_db` are harmless while nothing persists.
|
||||
They become destructive the moment target 2 works — **wire the guard before
|
||||
the listener, not after.**
|
||||
|
||||
## Also landed
|
||||
|
||||
- **Five fingerprint tools were phone-only** and are now in `Pixel3Arch/tools/`:
|
||||
`fp-arm.py`, `fp-bringup.py`, `fp-go.py`, `fp-load.py`, `fp-sweep.py`. They
|
||||
had lived only in `~` on the device since 2026-08-01 and a reprovision would
|
||||
have taken them. The three already tracked still hash-match the phone.
|
||||
- **References cloned** to `Pixel3Arch/references/biometrics/` (gitignored):
|
||||
`fprintd`, `libfprint` with `wrobelda/goodix-qsee` fetched as a branch,
|
||||
`sailfish-fpd-community`, `biometryd`, `qsee-supplicant`,
|
||||
`goodix-fp-spi-linux`, both wrobelda kernel series, Google's own
|
||||
`fpc1020_platform_tee.c` and `sdm845-b1c1-fingerprint.dtsi`, and the
|
||||
extracted TA and HAL.
|
||||
- **There is no API to design** — fprintd, gazed, sailfish-fpd and biometryd
|
||||
are the same interface four times. TASK-44 maps every call onto a TA command.
|
||||
- **The boot-chain trio** (katana / sdm845-payloads / QHEEStub) is a separate
|
||||
strand: `Pixel3Arch/docs/secure-world-references.md`. blueline's `hyp` is
|
||||
Google-signed not QTI-signed, so QHEEStub's precondition holds, but
|
||||
qtestsign only works where firmware secure boot is off — so EL2 is per-boot
|
||||
over USB, never persistent. `bootxbl` is the piece worth having now; it turns
|
||||
a broken boot chain from a brick into a recovery.
|
||||
|
||||
## Traps recorded today
|
||||
|
||||
- **Do not blind-dump `/sys/bus/nvmem/devices/qfprom0/nvmem` on a live phone.**
|
||||
Did it, and `cdc_ncm` transmit-queue watchdogs and a dead tether followed.
|
||||
Possibly coincident with the known stale-usb0 hijack — not separable after
|
||||
the fact, and not worth separating. The fuse question belongs in EDL, on a
|
||||
device that is not the daily driver.
|
||||
- **A call graph that loses jump-table case blocks reports no SPI anywhere.**
|
||||
That is how the bug announces itself; the corrected graph resolves
|
||||
`qsee_spi_*` for exactly the sensor commands. Recorded in the protocol doc
|
||||
because the next session will rebuild this graph.
|
||||
- **`llvm-objdump` 22 has no `-b binary`.** Use `aarch64-linux-gnu-objdump -D
|
||||
-b binary -m aarch64`.
|
||||
|
||||
## Open, and honest about it
|
||||
|
||||
- Attribution — the one measurement above. Needs a finger.
|
||||
- Whether enrolment demands a Gatekeeper-signed `hw_auth_token` (target 3). It
|
||||
would return an error rather than block, so it costs a result, not a reboot.
|
||||
- `linux-firmware` carries no fingerprint TA on sdm845, sm8250 or sm8150. TAs
|
||||
are per-device extracts, so this can be *enabled* on a phone whose vendor
|
||||
image you hold and cannot be *packaged* for anyone else. Say so out loud
|
||||
rather than discovering it at release.
|
||||
Loading…
Reference in a new issue