"""Smoke tests: images load, ARM/Thumb detection works, leaf routines execute.""" import os, sys sys.path.insert(0, os.path.join(os.path.dirname(__file__), "..")) from pspemu import Component, consts def test_load_all(): for name in ("hdcp", "asd", "dtm", "sys_drv"): c = Component(name) assert c.entry, name print(f" {name:8s} entry={c.entry:#x} regions={len(c.cmap.regions)}") def test_mode_detection(): """Call-site voting must classify the mixed ARM/Thumb leaf routines.""" c = Component("hdcp") assert c.mode_of(consts.HDCP["ta_memcpy"]) is False, "ta_memcpy must be ARM" assert c.mode_of(consts.HDCP["ta_memclr"]) is True, "ta_memclr must be Thumb" assert c.mode_of(consts.HDCP["subcmd12_rxinfo"]) is True assert c.mode_of(consts.HDCP["verify_mac"]) is True print(" ta_memcpy=ARM ta_memclr=Thumb subcmd12=Thumb verify_mac=Thumb") def test_memcpy_leaf(): c = Component("hdcp") src, dst = c.alloc(64), c.alloc(64) c.write(src, bytes(range(64))) c.run_function(consts.HDCP["ta_memcpy"], (dst, src, 32)) assert c.read(dst, 32) == bytes(range(32)), "ta_memcpy mismatch" assert c.read(dst + 32, 8) == b"\x00" * 8, "ta_memcpy overran" print(" ta_memcpy: 32 bytes copied, no overrun") def test_memclr_leaf(): c = Component("hdcp") d = c.alloc(64) c.write(d, b"\xAA" * 64) c.run_function(consts.HDCP["ta_memclr"], (d, 16)) assert c.read(d, 16) == b"\x00" * 16, "memclr failed" assert c.read(d + 16, 8) == b"\xAA" * 8, "memclr overran" print(" ta_memclr: 16 bytes cleared, no overrun") def test_write_tracer(): """The tracer must recover a copy's exact extent (core investigative tool).""" c = Component("hdcp") src, dst = c.alloc(256), c.alloc(256) c.write(src, bytes(i & 0xFF for i in range(256))) tr = c.trace_writes([(dst, dst + 256, "dst")]) c.run_function(consts.HDCP["ta_memcpy"], (dst, src, 100)) ext = tr.extent(dst, dst + 256) assert ext is not None, "no writes traced" lo, hi, n = ext assert lo == dst and hi == dst + 100, f"extent {lo-dst}..{hi-dst} != 0..100" print(f" tracer recovered exact extent: +{lo-dst}..+{hi-dst} ({n} writes)") def test_ccp_sha224_and_error_names(): """SHA-224 (CCP SHA type 2) and the CCP command-error table. Type 2 came from AMD's own ccp.h rather than from observation -- no firmware we hold requests SHA-224 -- so it is verified against hashlib here instead of being trusted. Empty and multi-block inputs are both covered, since the padding path is where a borrowed constant would most plausibly be wrong. """ import hashlib, struct from pspemu.ccp import SHA_TYPES, SHA_NAMED_UNIMPLEMENTED, cmd_error_name name, ctxlen, blocksz, fmt, compress, dlen = SHA_TYPES[2] assert (name, dlen) == ("SHA-224", 28), f"unexpected SHA-224 entry {name}/{dlen}" iv = [0xc1059ed8, 0x367cd507, 0x3070dd17, 0xf70e5939, 0xffc00b31, 0x68581511, 0x64f98fa7, 0xbefa4fa4] for msg in (b"", b"abc", b"the quick brown fox" * 7, bytes(range(256))): data = msg + b"\x80" data += b"\x00" * ((blocksz - (len(msg) + 1 + 8)) % blocksz) data += (len(msg) * 8).to_bytes(8, "big") state = list(iv) for i in range(0, len(data), blocksz): state = compress(state, data[i:i + blocksz]) got = struct.pack(fmt, *state)[:dlen] assert got == hashlib.sha224(msg).digest(), f"SHA-224 mismatch at len {len(msg)}" print(f" SHA-224 matches hashlib on 4 inputs (0..256 bytes)") assert cmd_error_name(0x14) == "IDMA_PROTECTION_FAULT" assert cmd_error_name(0x24) == "ODMA_PROTECTION_FAULT" assert cmd_error_name(0x00) == "NONE" assert "UNKNOWN" in cmd_error_name(0x99), "out-of-table code must be flagged" assert SHA_NAMED_UNIMPLEMENTED == {1: "SHA-1"}, "SHA-1 must stay named-but-unimplemented" print(" CCP error names resolve; unknown codes flagged, not invented") if __name__ == "__main__": fails = 0 for fn in (test_load_all, test_mode_detection, test_memcpy_leaf, test_memclr_leaf, test_write_tracer, test_ccp_sha224_and_error_names): print(fn.__name__) try: fn(); print(" PASS") except Exception as e: fails += 1; print(f" FAIL: {e}") sys.exit(1 if fails else 0)