Serve QTEE's storage: the enrolled template loads
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.
This commit is contained in:
parent
6c4622afff
commit
03023284ba
3 changed files with 432 additions and 7 deletions
|
|
@ -202,6 +202,23 @@ int main() {
|
|||
Check(tokenZero, "the 69-byte auth token is all zero");
|
||||
}
|
||||
|
||||
// ---- SET_ACTIVE_GROUP: a gid and a NAMESPACE path, not a file path
|
||||
{
|
||||
auto sag = BuildSetActiveGroup(60);
|
||||
Check(Get32(sag, SetActiveGroupGidOff) == 60, "gid at +0");
|
||||
std::string path;
|
||||
for (std::size_t i = SetActiveGroupPathOff; i < sag.size() - 1; i++)
|
||||
path.push_back(static_cast<char>(std::to_integer<unsigned char>(sag[i])));
|
||||
Check(path == "/data/vendor_de/0/fpdata", "the Android namespace path");
|
||||
Check(sag.back() == std::byte{0}, "NUL-terminated");
|
||||
Check(sag.size() == SetActiveGroupPathOff + GroupNamespacePath.size() + 1,
|
||||
"length is 4 + path + NUL");
|
||||
// The path is a key the trustlet hashes into the group directory name,
|
||||
// so it is not ours to invent. A gid rendered as text is not it.
|
||||
Check(GroupNamespacePath != "60", "the second field is not the gid again");
|
||||
Check(GroupNamespacePath.starts_with('/'), "it looks like a path because it is one");
|
||||
}
|
||||
|
||||
// ---- Responses: the payload starts at +0x10, and forgetting that reads
|
||||
// a confident zero.
|
||||
{
|
||||
|
|
|
|||
Loading…
Reference in a new issue