aboutsummaryrefslogtreecommitdiffstats
path: root/fw/AUDIT-ASD-163-1A3-1A4-HDCP2-STATE-SETTERS.md
blob: 3256c4c73ecc61eae9eb40443a16be2e55ef6ba4 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
# ASD `.163` `0x1A3`/`0x1A4`: selected channel-state stores and HDCP2 callers

**Signed-static + synthetic dispatch only.** Neither opcode was invoked on
the card; no live HDCP channel, cross-client effect, or register restoration
oracle was established. Do not infer arbitrary fabric writes from a scalar
stored in a private record.

`0x1A3 → sub_D0B2A8` stores unrestricted `msg[2]` at channel `+84`;
`0x1A4 → sub_D0B2C4` stores it at `+80`. Each checks `msg[1] <=31` and
channel active flag at `+4 == 1`, but neither compares caller identity to a
channel owner. The fields are in the shared table based at `0xD33510`.
`python3 psp_emu/harness/probe_asd163_1a3_1a4_scalar_setters.py` passed
signed dispatcher tests: channel 5 selected stores of `0xDEADBEEF` and
`0xFFFFFFFF`, unchanged active channel 6, rejected channel 32 and inactive
channel 5. These are **synthetic private records**, not other processes.

Signed HDCP `.57` actually emits these opcodes via service-2 `SVC 0xF2`:
wrappers `0x40452A`/`0x40454C` store `{opcode, channel, scalar}`. HDCP2
session creation (`0x401E98`) and repeater ReceiverID handling (`0x402B64`)
call `0x1A3`; HDCP2 certificate handling (`0x40246C`) calls `0x1A4`.
This verifies **producer provenance**, not that `.57` is the active card
client, that GCP knows a second client's channel, or that its state can
safely be restored.

`+80` is read as channel type/status by `asd_link_sub_113A0` (`0x161`):
it returns that word to a checked four-byte caller output and branches on
values 1/2, returning 7 for other values rather than using the arbitrary
value as a pointer. It is also consumed by `sub_D0B320` and related link
logic. `+84` is passed to link-control callback slots 755/757 on selected
paths. `sub_D0AEB0` (free `0x1A2`) passes its selected record's `+84`
to slot 755 for type-5 channels; `sub_D0B07C` (free `0x1A6`) passes the
**stored peer's** `+84` to slot 755 only after its active/ASIC gates.
For signed ASIC-20 assignments in `sub_D08DAC`, slot 755 is the
`asd_pipe_enable` veneer (`0xD04E4B → 0xD07470`), and slot 757 is the
`sub_D07534` veneer (`0xD04E4F`); the latter uses record/fixed-register
state, not an arbitrary caller-selected fabric address. Raw slot-755
descendant disassembly shows the saved scalar controlling **mode-2 bit
selection**, not a chosen fabric address: `asd_reg_offsets_init_19600`
(`0xD07134`) compares saved `R7` to 2 at `0xD07198/0xD071B8` and
`0xD07226/0xD07244/0xD07266/0xD07284` to set or clear bit 5 or 21
before signed fixed-register helper calls. `asd_scan_pipe_regs`
(`0xD07350`) compares saved `R11` to 2 at `0xD07402` before a
`sub_D114F0` register helper call. Signed `SVC 0x56` sites there are
wait loops; this trace does **not** equate callback argument `+84` with
a CPU-MMU pointer or PSP fabric address.

This is a **conditional fixed-register mode-control lead**, not a
hardware-confirmed change: an actual active other-client channel, its
ASIC callback path and independent register-effect/restoration oracle are
missing. Other ASIC variants and the complete helper/fabric side effects
are not closed. No arbitrary register poke, HDCP bypass, or cross-client
tamper impact is claimed.