aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoruser <user@clank>2026-10-08 18:39:42 +0200
committeruser <user@clank>2026-10-08 18:39:42 +0200
commit626dcabbd93b5968f3c48fdaaade974c361bda2e (patch)
tree98f581cbee7edebddfbb53c34351d3122801a4e0
parentsim: confirm GCP crypto ROP message is correct; localize 0xFFFF000F to SVC 0x... (diff)
downloadamd-psp-re-626dcabbd93b5968f3c48fdaaade974c361bda2e.tar.gz
amd-psp-re-626dcabbd93b5968f3c48fdaaade974c361bda2e.tar.xz
amd-psp-re-626dcabbd93b5968f3c48fdaaade974c361bda2e.zip
hw: no deterministic crypto-output placement - SVC 0xB5 client check (sub_1978) rejects
Pinned the per-boot knob: SVC 0xB5 return gates sub_E0DEF4 and is sub_27F8->sub_1978(client), which returns OK only if client<0x20 AND proc_table[client] active-bit set; else 37 -> whole validation fails for ANY output buffer (buffer-independent). Hardware pass-rate test (op0x35 len4 @0x410380, dumped, fresh ATX/boot): ~25 boots across rnglen/rngdet/rngdet4/passrate ALL reject 0xffff000f, buffer never written; the lone acceptsweep 'pass' (11/11) did NOT reproduce - its exact config now rejects 10/10. Verdict: output-buffer crypto ops reliably reject from the GCP confused-deputy; no deterministic placement exists; reject is client/session state we don't control. Asymmetry: dir==1 INPUT buffers bypass validation (unvalidated reads) but dir==2 OUTPUT buffers are client-gated. Oracle closed; inline create-handle read-back remains the only reliable channel. Updated SIM doc.
-rw-r--r--fw/SIM-GCP-CRYPTO-ROP-ARGCHECK.md30
1 files changed, 30 insertions, 0 deletions
diff --git a/fw/SIM-GCP-CRYPTO-ROP-ARGCHECK.md b/fw/SIM-GCP-CRYPTO-ROP-ARGCHECK.md
index 1dc6059..fbe46ef 100644
--- a/fw/SIM-GCP-CRYPTO-ROP-ARGCHECK.md
+++ b/fw/SIM-GCP-CRYPTO-ROP-ARGCHECK.md
@@ -73,3 +73,33 @@ Window recorder for the type-5 path, `sub_22B4` (sos2): on the gated svc it writ
deliberately permissive (`[0,0xFFFFFFFF]`); `--window` lets us model it and reproduce the reject.
Tool: `psp_emu/harness/gcp_crypto_argcheck.py` (`--window lo,hi` to model the SVC 0xB5 region).
+
+================================================================================
+## Hardware verdict: no deterministic output placement — SVC 0xB5 client check fails
+
+Pinned the per-boot knob and tested on silicon. SVC 0xB5's return (which gates all of `sub_E0DEF4`
+via `if R0!=0 -> FAIL`) is `sub_27F8` -> `sub_1978(client_id)` (sos2):
+
+ sub_1978(client): return 0 (OK) iff client < 0x20 AND proc_table[client].flag < 0 (active bit);
+ else return 37 (FAIL)
+
+So if the client id SYS_DRV presents for our confused-deputy call does not resolve to an ACTIVE
+process entry, the validation fails for ANY output buffer/length -- a client/session reject, not a
+buffer-placement one. That is buffer-independent: no placement can fix it.
+
+Hardware pass-rate test (op 0x35 len4 @ 0x410380, dumped, fresh ATX per boot):
+
+ rnglen / rngdet / rngdet4 / passrate : ~25 boots, ALL reject 0xffff000f, buffer never written
+ acceptsweep (the one apparent pass, 11/11 status 0) : did NOT reproduce -- its exact config
+ (0x410380, DUMP_OFF 0x380) now rejects 10/10.
+
+Conclusion: **output-buffer crypto ops reliably reject (0xffff000f) from the GCP confused-deputy
+path; there is no deterministic buffer placement that makes them land.** The reject is the SVC 0xB5
+client validation (`sub_1978` active-check + the region check), governed by client/session state the
+GCP side does not set. The single non-reproducible "pass" window is treated as noise, not a result.
+
+Security-model note (the clean asymmetry): `sub_E0DEF4` returns PASS immediately for `dir==1` (INPUT)
+buffers -- SYS_DRV does NOT validate pointers it only READS -- but gates `dir==2` (OUTPUT) buffers
+through the client check. So the confused deputy can FEED arbitrary pointers (unvalidated reads) but
+cannot reliably RECEIVE into a chosen buffer (validated writes). The crypto-output read-back oracle is
+therefore closed; the earlier inline read-back (create handle) remains the only reliable channel.