aboutsummaryrefslogtreecommitdiffstats
path: root/fw
diff options
context:
space:
mode:
authoruser <user@clank>2026-10-08 14:09:56 +0200
committeruser <user@clank>2026-10-08 14:09:56 +0200
commit7929c84f6841571ff8a81302f52bcbc8dcee8bec (patch)
tree6b10b733e60d471844643529ddd60ee350e58920 /fw
parentcrypto ROP harness: multi-op (two-svc) validated on silicon + usage/status doc (diff)
downloadamd-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.md38
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.