aboutsummaryrefslogtreecommitdiffstats
path: root/fw/AUDIT-ASD-163-207-ASIC20-CALLBACK-OUTPUT.md
blob: 8d7a9ab1aa94a6a3b53be315cc4cd310ba7938bf (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
53
54
# ASD `.163` service-2 `0x207`: ASIC-20 callback stores one validated dword

**Scoped signed callback audit and synthetic control, not a live
private-pointer disclosure.** Immediate `asd_svc_op_207`
(`0xD0DF9C`) validates exactly **four output bytes** at `msg[1]`,
then calls callback slot `0xD397B0+0x3C` if nonnull. Signed startup
`sub_D0E75C → sub_D0E10C` installs thunk `0xD0C351` at that slot
for ASIC variant **20** (the variant measured on the card in
separate read-only work). Its signed descendant
`asd_get_pair_D49838` (`0xD0C440`) loads a pointer from ASD-private
`0xD39848`, loads **one** dword from that pointer, and stores it at
caller output offset **zero only**. The misleading `get_pair` name
must not be used to infer an eight-byte output. The callback return
is ignored by the leaf after the nonnull precheck.

`psp_emu/harness/probe_asd163_207_asic20_output.py` passed on
signed `.163` dispatch with a **planted synthetic** ASIC-20 slot and
source pointer. A GCP-owned validated output received exactly four
public marker bytes; its next 12 sentinel bytes were unchanged.
An ASD-private output pointer was rejected with status 2 before
callback invocation. Both config words were restored **only in
emulator memory**. No natural ASD-private pointer content or
hardware read was sampled.

**Additional signed startup trace (no card read):** the original
ELF has no IDA-mapped BSS beyond `0xD29100`, so a direct IDA xref
to `0xD39848` is unavailable. Following code/data literals instead
resolved `off_D0C47C = 0xD39848` and
`dword_D0C438 = 0x030109EC`. The ASIC-20 branch of `sub_D0E10C`
installs Thumb pointer `0xD0C355` (`sub_D0C354`) in the callback
at `0xD397B0+0x24`. **Correction to the earlier scoped scan:**
`sub_D0E75C` directly calls that callback as
`v6 = *((... )v5+9); v6()` after successful variant setup;
that indirect invocation was overlooked. `sub_D0C354 →
asd_set_pair_D49838` sets private `0xD39848` to the **fixed**
CPU-address value `0x030109EC` and the adjacent word to
`0x03010AE8`. ASIC-20 `0x207` then dereferences the first fixed
address and writes one dword into a validated caller buffer.
The two pointers are not taken from the `0x207` request.
Older local emulator notes already identified `0x030109EC` as
**C2PMSG_59** (`psp_emu/pspemu/memmap.py`,
`psp_out/FUZZING-EMULATED.md`); this startup trace resolves *how*
that fixed source is installed in signed `.163`, not a newly
identified arbitrary target. The register's live content and
security meaning are not established by the emulator's label.

This establishes a signed natural *writer path*, **conditional on
startup succeeding through that callback**. It does not establish
the live pointer value, the Navi31 meaning or permissions of those
CPU-window addresses, a card `0x207` return, or confidentiality
impact. Other variants and dynamic reinitialization remain open.
The isolated synthetic source pointer is not proof of GCP control
of an ASD-private read target. GCP's separate `0x404` read remains
the established disclosure route. No card `0x207` request was made.