The whole storage path now works from the daemon. On the phone, against the
real store:
listener 0x7000 sb=516096 -> result=0 REGISTERED
listener 0x2000 sb=25600 -> result=0 REGISTERED
SET_ACTIVE_GROUP gid=60 path='/data/vendor_de/0/fpdata'
gpfile READ .../1lPrxAL0vXRvWPeDkW2c off=4096 len=252114
...
CMD 0x2005 -> result=0 rc=1
templates loaded: 1
QTEE read a 252114-byte enrolled template through our gpfile listener, verified
it, and loaded it. Since QTEE unlinks any container whose keyed integrity tag
fails, a load is proof the framing is right -- the read/write offset split, the
container chunking, and the RPMB anti-rollback read that has to succeed before
QTEE will trust any of it.
RPMB is served too: SECURITY PROTOCOL IN/OUT against the RPMB well-known LUN,
retrying the unit attention the LUN raises once after a reset. Writes are
refused unless asked for, because they advance a counter that cannot be moved
back, and key programming is refused unconditionally.
The store was served READ-ONLY throughout, which is the point. A listener that
serves bytes at the wrong offset does not merely fail: QTEE deletes the
container it cannot verify, and that is an enrolled fingerprint gone. Read-only
makes a wrong build harmless, so it is the default and writing is opt-in.
Two ordering facts, both of which produce -2 with no storage read at all --
indistinguishable from a broken listener:
* a template reload needs the device init chain to have run FIRST, because
that chain allocates the per-slot array the reload writes through;
* SET_ACTIVE_GROUP's second field is a NAMESPACE path, not a filesystem one
and not the gid again. The trustlet hashes it into the group's directory
name, so it has to match what the store was written under.
Also: a positive rc is not an error code. ENUMERATE returns the template count
there, and running that through the error table printed "unknown" for a good
answer.