diff options
| author | user <user@clank> | 2026-10-08 14:09:56 +0200 |
|---|---|---|
| committer | user <user@clank> | 2026-10-08 14:09:56 +0200 |
| commit | 7929c84f6841571ff8a81302f52bcbc8dcee8bec (patch) | |
| tree | 6b10b733e60d471844643529ddd60ee350e58920 /fw | |
| parent | crypto ROP harness: multi-op (two-svc) validated on silicon + usage/status doc (diff) | |
| download | amd-psp-re-7929c84f6841571ff8a81302f52bcbc8dcee8bec.tar.gz amd-psp-re-7929c84f6841571ff8a81302f52bcbc8dcee8bec.tar.xz amd-psp-re-7929c84f6841571ff8a81302f52bcbc8dcee8bec.zip | |
push further: full crypto op (TEE_GenerateRandom 0x35) EXECUTES but pointer-buffer output does not marshal back to GCP
Identified op 0x35 = TEE_GenerateRandom (sub_E04F38) -- self-contained, writes len random bytes to
msg[2] output buffer. Hardware: svc(0x35) returned 0x0 (RNG executed) BUT the output buffer, pre-filled
with 0xAA at 0x410500, came back UNCHANGED -> the random bytes did not land in our GCP-window buffer.
Root cause (confirmed): the confused-deputy svc-0xf2 path bounces only the inline 124-byte message
(sub_E087E4 works on a local copy v8, copies back on return) -- which is why INLINE results round-trip
(AllocateOperation handle at msg[14]). A pointer-buffer op has the SYS_DRV handler dereference the
client VA in its OWN context; GCP's SRAM window isn't mapped there, so the RNG wrote into SYS_DRV-side
memory we can't read. The crypto service's buffer model assumes shared-DRAM client buffers (host ring
RPC), but the type-5 gate confines our buffers to GCP's SRAM window -> incompatible.
Net boundary: from GCP ROP we CAN execute any crypto op (RNG runs, status 0) and read INLINE results
(create handle, state persistence); we CANNOT read pointer-buffer outputs (digest/cipher/RNG data)
without defeating the cross-domain buffer bounce. Documented in fw/HARNESS-GCP-CRYPTO-ROP.md.
Diffstat (limited to 'fw')
| -rw-r--r-- | fw/HARNESS-GCP-CRYPTO-ROP.md | 38 |
1 files changed, 38 insertions, 0 deletions
diff --git a/fw/HARNESS-GCP-CRYPTO-ROP.md b/fw/HARNESS-GCP-CRYPTO-ROP.md index 3ab62ea..6a87adf 100644 --- a/fw/HARNESS-GCP-CRYPTO-ROP.md +++ b/fw/HARNESS-GCP-CRYPTO-ROP.md @@ -73,3 +73,41 @@ digest-init/reset step in the GP-TEE digest state machine. Next: find the op tha (DigestInit/reset) and chain create -> init -> digest (the two-svc chain extends to N by adding svc stages), then verify the dumped output equals the host SHA256. This is exploration the harness now enables. + +================================================================================ +## PUSH FURTHER: full op EXECUTES, but pointer-buffer I/O does NOT marshal back + +Goal: run a full transform (not just AllocateOperation) and read its output. Identified op `0x35` = +**`TEE_GenerateRandom`** (`sub_E1E184 -> sub_E04F38(out_ptr=msg[2], len=msg[3])`) -- self-contained, +no context/key, writes `len` random bytes to the output buffer. The perfect clean test. + +### Hardware result (op 0x35, output buffer at window `0x410500`, len 32) + +* `svc(0x35)` return = **`0x0`** (success -- the RNG executed to completion). +* But the output buffer, **pre-filled with `0xAA`, came back UNCHANGED** (`aaaaaaaa...`), i.e. the + random bytes did NOT land in our GCP-window buffer. + +### Why: the confused-deputy only round-trips the INLINE 124-byte message + +* sOS's `svc 0xf2` service path **bounces the request message** into SYS_DRV space; `sub_E087E4` + works on a 124-byte local copy `v8` and copies it back to the caller message on return. That is why + INLINE results round-trip and are readable -- e.g. `TEE_AllocateOperation`'s handle at `msg[14]`. +* A crypto op that writes to a POINTER buffer (`msg[2]` etc.) has the handler dereference that client + VA **in SYS_DRV's address context**. GCP's SRAM window (`0x400000-0x800000`) is not mapped there + (only the message is bounced), so the write hits SYS_DRV's own `0x410500`, never GCP's. The RNG + succeeded (status 0) writing into SYS_DRV-side memory we cannot read. +* The crypto service's buffer model assumes **shared-DRAM** client buffers (host/amdgpu ring RPC), + but the type-5 `svc 0xf2` gate **confines our buffers to GCP's SRAM window** -- which SYS_DRV cannot + access for pointer I/O. So the two are incompatible from the GCP confused-deputy. + +### Net (honest) + +From a ROP'd GCP TA we **can execute** any crypto operation (RNG confirmed running, status 0), and we +can **read INLINE results** (the `AllocateOperation` handle `0x10`/`0x11`, state persistence). We +**cannot** read POINTER-buffer outputs (RNG/digest/cipher data) because the confused-deputy marshals +only the inline message, and GCP-window pointer buffers are not reachable by the SYS_DRV handler. A +full data-transform with a readable output buffer would require either (a) a crypto op that returns +its result inline in the message, or (b) defeating the cross-domain buffer bounce (placing the buffer +where the SYS_DRV handler actually dereferences it) -- neither available as-is. This is the accurate +boundary of the GCP->SYS_DRV crypto surface: inline-result ops work end-to-end; buffer-I/O ops +execute but their data does not cross back. |
