| Commit message (Collapse) | Author | Age |
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Tried to identify what legitimately produces the word RAS receives as 0, by
reading sOS's init parameter block around 0x202D24 -- [r4+1] (the 0xff gate that
decides whether params get filled at all), [r4+4], [r5+0x30], and the assembled
block at the send.
Every read fails with a Unicorn error: these are sOS virtual addresses and
uc.mem_read does not resolve them in that hook context. The measurement says
nothing about the firmware, so nothing is concluded from it in either direction.
Recorded rather than discarded, because the failure mode is non-obvious and the
next person would otherwise spend the same effort rediscovering it. The next
attempt needs the VA->PA resolution first, which the harnesses already do
elsewhere for TA address spaces.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Ruled out the timeout reading first: both TAs execute during the send (HDCP 9
blocks, RAS 13), so RAS runs its handler and answers rather than going silent.
Mechanism, from RAS's own code:
00402c6c bl #0x402ed0
00402c70 cbz r0, #0x402c94 ; callee returned 0 -> error
00402c94 ldr r0, [pc, #0x30] ; lit = 0xffff000b
0x402ed0 scans its argument for the first nonzero nibble and requires it to be
5, 6 or 7. RAS receives r0 = 0 as its first argument -- passed in, not read from
memory (r0=0x0, r1=0x412010, r2=0x412008) -- so the callee returns 0 at once.
The experiment needed its own control, and that turned out to matter. Forcing r0
at the function entry changed nothing, which reads as "hypothesis refuted":
baseline 0xffff000b
force r0 AFTER the call, at 0x402C70 0x00000000 <- success
force r0 at entry, 0x402C64 0xffff000b <- no effect
The middle row is the positive control: reg_write from a code hook does affect
this TA, and supplying a nonzero value at the decision point makes the whole
LOAD_TA succeed. The entry-site null is an artefact of writing a register at a
translation-block boundary. Without that control I would have recorded a false
refutation.
So RAS's image loads and verifies, and its init declines only because one input
word arrives as 0. This is an emulator environment gap, not a firmware defect,
and it is deliberately NOT patched -- a forced register here would be precisely
the "stub returning 0 is a silent lie" failure mode this project avoids. The
remaining work is finding what legitimately produces the value; the card runs
RAS 27.0.2.5 successfully, so it is observable on hardware.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Continuing past 0x202CF2, tee_load_ta's sl == 2 arm checks a typeword against
0x4154, then sends command 3 (init/create) via ta_send_command at 0x202D4C and
takes its return as the status. Measured for both TAs:
HDCP typeword 0x4154 ok, ta_send_command -> 0x0 ring 0x00000000
RAS typeword 0x4154 ok, ta_send_command -> 0xffff000b ring 0xffff000b
Both pass the gate, both reach the send; the host's status is that return
verbatim. Full chain:
ring LOAD_TA -> tee_cmd_dispatch (tbb @0x202922, cmd 1 -> 0x2029AC)
-> tee_load_ta @0x202C24
-> bl_load_ta_image SUCCEEDS for both, r4 == 0
-> ta_send_command(cmd 3) HDCP 0x0, RAS 0xffff000b <- origin
So RAS's image loads and verifies fine and the failure is the init handshake
with the loaded TA. That agrees with the independent observation in this same
harness that RAS's init gate at VA 0x4060E0 reads 0x00 while HDCP's reads 0x90.
The remaining question is therefore not "why does LOAD_TA reject RAS" but "why
does the RAS TA fail its init", a TA-side environment question -- the load trace
shows sysdrv_rpc_3104/3105/1005 involvement.
Recorded one caveat rather than glossing it: ta_send_command returning
0xffff000b does not prove the TA authored that code; it may be a timeout. The
cheap discriminator is whether RAS's command handler executes during the send.
Suite green.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Differentially traced HDCP (loads) against RAS (0xffff000b), fresh build each,
filtering the idle spin loop that swamps the trace with 343k blocks of phase
drift.
Refuted "RAS is already loaded at boot": HDCP is equally loaded and succeeds.
Refuted "RAS trips the size guard at 0x2041F2", which was the natural reading of
the ta_prop_get_heap_pages trace. bl_load_ta_image has exactly one site setting
error 0xb, reached from a page-count check and an available-memory check.
Hooking both shows RAS never reaches it and the two TAs pass identically:
combined field 0x6 against a 0x400 limit, need 0xf000, avail 0x3e0000, FITS.
The runs are block-identical for 186 blocks and part at 0x2047F0,
bl_load_ta_image's continuation test. r4 == 0 for BOTH, so the loader succeeds
for RAS as well; HDCP loops back to +0x9c for a further segment while RAS falls
out to 0x20480E and returns. In tee_load_ta the error branch at 0x202CCE is not
taken for RAS, confirming a zero return, and RAS proceeds through the sl == 2
arm to 0x202CF2.
So 0xffff000b is produced after the image loader, on tee_load_ta's path through
0x202CF2, with sl discriminating RAS from HDCP. The image loads fine; something
downstream rejects it.
Also worth recording: this trace was truncated twice by hook ranges ending
exactly at the addresses that mattered (0x2029A0, then 0x204000), each time
producing a plausible but wrong divergence point. Widening the range changed the
answer both times.
|
|
|
With Ring.response() reading the correct address, LOAD_TA over the host ring can
finally be evaluated, and the picture is different again:
RAS image status 0xffff000b session 0
HDCP image status 0x00000000 session 0 <- SUCCEEDS
RAS, 0x40 bytes corrupted status 0x34 (52) <- signature failure
all-zero image status 0x2d (45)
Four distinct outcomes, so the path discriminates. LOAD_TA over the ring WORKS:
HDCP loads with status 0. The earlier "LOAD_TA registers no session" was the
stale readback, and the follow-on "LOAD_TA fails" holds only for RAS. The 0x34
matches the signature-verification failure code load_asd.py reports for a
bit-flipped image, so verification is live and correct.
It is also not "already loaded": HDCP is equally loaded at boot and succeeds.
Located where it fails. tee_cmd_dispatch reaches cmd 1 via tbb [pc, r6] at
0x202922 (table 0x202926, cmd 1 -> 0x2029AC); the handler calls tee_load_ta at
0x202C24 and takes its return as the status, so 0xffff000b originates inside
tee_load_ta. The sOS trace during the failing load runs through TA manifest
parsing -- ta_prop_get, ta_prop_get_heap_pages, ta_prop_get_appid, bl_rpc_probe,
sysdrv_rpc_3104/3105/1005 -- which points at a resource or property condition
specific to RAS's manifest rather than image validity.
What this unblocks: HDCP loads and returns a session over the ring, so the
INVOKE_CMD path can now be exercised end to end in full_system against a TA that
loads. That was what blocked command-coverage work, and it no longer depends on
solving RAS first.
Suite green.
|